提交 fc3d921b 编写于 作者: A Alex Duan

Merge branch 'develop' into feature/TS-238-D

...@@ -32,7 +32,7 @@ TDengine 是一款高性能、分布式、支持 SQL 的时序数据库。而且 ...@@ -32,7 +32,7 @@ TDengine 是一款高性能、分布式、支持 SQL 的时序数据库。而且
## TDengine 总体适用场景 ## TDengine 总体适用场景
作为一个 IoT 大数据平台,TDengine 的典型适用场景是在 IoT 范畴,而且用户有一定的数据量。本文后续的介绍主要针对这个范畴里面的系统。范畴之外的系统,比如 CRM,ERP 等,不在本文讨论范围内 作为一个高性能、分布式、支持 SQL 的时序数据库,TDengine 的典型适用场景包括但不限于 IoT 和 DevOps,尤其是在大数据量的情况下。本文后续的介绍主要针对这些应用场景
### 数据源特点和需求 ### 数据源特点和需求
......
...@@ -9,7 +9,7 @@ TDengine 采用关系型数据模型,需要建库、建表。因此对于一 ...@@ -9,7 +9,7 @@ TDengine 采用关系型数据模型,需要建库、建表。因此对于一
## 创建库 ## 创建库
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除 SQL 标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如: 不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除 SQL 标准的选项外,还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
```sql ```sql
CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1; CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1;
...@@ -27,7 +27,7 @@ USE power; ...@@ -27,7 +27,7 @@ USE power;
:::note :::note
- 任何一张表或超级表是属于一个库的,在创建表之前,必须先创建库。 - 任何一张表或超级表必须属于某个库,在创建表之前,必须先创建库。
- 处于两个不同库的表是不能进行 JOIN 操作的。 - 处于两个不同库的表是不能进行 JOIN 操作的。
- 创建并插入记录、查询历史记录的时候,均需要指定时间戳。 - 创建并插入记录、查询历史记录的时候,均需要指定时间戳。
...@@ -45,9 +45,9 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG ...@@ -45,9 +45,9 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG
这一指令中的 STABLE 关键字,在 2.0.15 之前的版本中需写作 TABLE 。 这一指令中的 STABLE 关键字,在 2.0.15 之前的版本中需写作 TABLE 。
::: :::
与创建普通表一样,创建表时,需要提供表名(示例中为 meters),表结构 Schema,即数据列的定义。第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase),数据类型可以为整型、浮点型、字符串等。除此之外,还需要提供标签的 schema (示例中为 location, groupId),标签的数据类型可以为整型、浮点型、字符串等。采集点的静态属性往往可以作为标签,比如采集点的地理位置、设备型号、设备组 ID、管理员 ID 等等。标签的 schema 可以事后增加、删除、修改。具体定义以及细节请见 [TAOS SQL 的超级表管理](/reference/taos-sql/stable) 章节。 与创建普通表一样,创建超级表时,需要提供表名(示例中为 meters),表结构 Schema,即数据列的定义。第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase),数据类型可以为整型、浮点型、字符串等。除此之外,还需要提供标签的 schema (示例中为 location, groupId),标签的数据类型可以为整型、浮点型、字符串等。采集点的静态属性往往可以作为标签,比如采集点的地理位置、设备型号、设备组 ID、管理员 ID 等等。标签的 schema 可以事后增加、删除、修改。具体定义以及细节请见 [TAOS SQL 的超级表管理](/reference/taos-sql/stable) 章节。
每一种类型的数据采集点需要建立一个超级表,因此一个物联网系统,往往会有多个超级表。对于电网,我们就需要对智能电表、变压器、母线、开关等都建立一个超级表。在物联网中,一个设备就可能有多个数据采集点(比如一台风力发电的风机,有的采集点采集电流、电压等电参数,有的采集点采集温度、湿度、风向等环境参数),这个时候,对这一类型的设备,需要建立多张超级表。一张超级表里包含的采集物理量必须是同时采集的(时间戳是一致的)。 每一种类型的数据采集点需要建立一个超级表,因此一个物联网系统,往往会有多个超级表。对于电网,我们就需要对智能电表、变压器、母线、开关等都建立一个超级表。在物联网中,一个设备就可能有多个数据采集点(比如一台风力发电的风机,有的采集点采集电流、电压等电参数,有的采集点采集温度、湿度、风向等环境参数),这个时候,对这一类型的设备,需要建立多张超级表。
一张超级表最多容许 1024 列,如果一个采集点采集的物理量个数超过 1024,需要建多张超级表来处理。一个系统可以有多个 DB,一个 DB 里可以有一到多个超级表。(从 2.1.7.0 版本开始,列数限制由 1024 列放宽到了 4096 列。) 一张超级表最多容许 1024 列,如果一个采集点采集的物理量个数超过 1024,需要建多张超级表来处理。一个系统可以有多个 DB,一个 DB 里可以有一到多个超级表。(从 2.1.7.0 版本开始,列数限制由 1024 列放宽到了 4096 列。)
......
...@@ -85,7 +85,7 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, ...@@ -85,7 +85,7 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
:::note :::note
1. 无论 RESTFful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。 1. 无论 RESTful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库, 所以在上面示例中使用了`dbName.tbName`指定表名。 2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库, 所以在上面示例中使用了`dbName.tbName`指定表名。
::: :::
......
...@@ -13,6 +13,8 @@ import NodeLine from "./_js_line.mdx"; ...@@ -13,6 +13,8 @@ import NodeLine from "./_js_line.mdx";
import CsLine from "./_cs_line.mdx"; import CsLine from "./_cs_line.mdx";
import CLine from "./_c_line.mdx"; import CLine from "./_c_line.mdx";
## InfluxDB Line 协议介绍
## 示例代码 ## 示例代码
<Tabs defaultValue="java" groupId="lang"> <Tabs defaultValue="java" groupId="lang">
......
...@@ -147,7 +147,7 @@ Query OK, 5 row(s) in set (0.001521s) ...@@ -147,7 +147,7 @@ Query OK, 5 row(s) in set (0.001521s)
:::note :::note
1. 无论 RESTFful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。 1. 无论 RESTful 方式建立连接还是本地驱动方式建立连接,以上示例代码都能正常工作。
2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库。 2. 唯一需要注意的是:由于 RESTful 接口无状态, 不能使用 `use db` 语句来切换数据库。
::: :::
......
...@@ -11,20 +11,20 @@ TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/ ...@@ -11,20 +11,20 @@ TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/
## 配置 Grafana ## 配置 Grafana
TDengine 的 Grafana 插件托管在 GitHub,可从 <https://github.com/taosdata/grafanaplugin/releases/latest> 下载,当前最新版本为 3.1.3 TDengine 的 Grafana 插件托管在 GitHub,可从 <https://github.com/taosdata/grafanaplugin/releases/latest> 下载,当前最新版本为 3.1.4
推荐使用 [`grafana-cli` 命令行工具](https://grafana.com/docs/grafana/latest/administration/cli/) 进行插件安装。 推荐使用 [`grafana-cli` 命令行工具](https://grafana.com/docs/grafana/latest/administration/cli/) 进行插件安装。
```bash ```bash
sudo -u grafana grafana-cli \ sudo -u grafana grafana-cli \
--pluginUrl https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip \ --pluginUrl https://github.com/taosdata/grafanaplugin/releases/download/v3.1.4/tdengine-datasource-3.1.4.zip \
plugins install tdengine-datasource plugins install tdengine-datasource
``` ```
或者下载到本地并解压到 Grafana 插件目录。 或者下载到本地并解压到 Grafana 插件目录。
```bash ```bash
GF_VERSION=3.1.3 GF_VERSION=3.1.4
wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/tdengine-datasource-$GF_VERSION.zip wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/tdengine-datasource-$GF_VERSION.zip
``` ```
...@@ -44,7 +44,7 @@ allow_loading_unsigned_plugins = tdengine-datasource ...@@ -44,7 +44,7 @@ allow_loading_unsigned_plugins = tdengine-datasource
在 Docker 环境下,可以使用如下的环境变量设置自动安装并设置 TDengine 插件: 在 Docker 环境下,可以使用如下的环境变量设置自动安装并设置 TDengine 插件:
```bash ```bash
GF_INSTALL_PLUGINS=https://github.com/taosdata/grafanaplugin/releases/download/v3.1.3/tdengine-datasource-3.1.3.zip;tdengine-datasource GF_INSTALL_PLUGINS=https://github.com/taosdata/grafanaplugin/releases/download/v3.1.4/tdengine-datasource-3.1.4.zip;tdengine-datasource
GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=tdengine-datasource GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=tdengine-datasource
``` ```
......
...@@ -7,7 +7,7 @@ title: collectd 写入 ...@@ -7,7 +7,7 @@ title: collectd 写入
TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 collectd 的多种应用的数据写入。 TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 collectd 的多种应用的数据写入。
/etc/collectd/collectd.conf 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `/etc/collectd/collectd.conf` 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
LoadPlugin network LoadPlugin network
...@@ -22,4 +22,4 @@ LoadPlugin network ...@@ -22,4 +22,4 @@ LoadPlugin network
sudo systemctl start collectd sudo systemctl start collectd
``` ```
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。 taosAdapter 相关配置参数请参考 `taosadapter --help` 命令输出以及相关文档。
...@@ -8,7 +8,7 @@ title: StatsD 直接写入 ...@@ -8,7 +8,7 @@ title: StatsD 直接写入
TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 StatsD 的多种应用的数据写入。 TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 StatsD 的多种应用的数据写入。
config.js 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `config.js` 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
backends 部分添加 "./backends/repeater" backends 部分添加 "./backends/repeater"
...@@ -25,6 +25,5 @@ port: 8125 ...@@ -25,6 +25,5 @@ port: 8125
} }
``` ```
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。 taosAdapter 相关配置参数请参考 `taosadapter --help` 命令输出以及相关文档。
icinga2 可以收集监控和性能数据并写入 OpenTSDB,taosAdapter 可以支持接收 icinga2 的数据并写入到 TDengine 中。
...@@ -3,6 +3,13 @@ sidebar_label: icinga2 ...@@ -3,6 +3,13 @@ sidebar_label: icinga2
title: icinga2 写入 title: icinga2 写入
--- ---
安装 icinga2
请参考[官方文档](https://icinga.com/docs/icinga-2/latest/doc/02-installation/)
TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 icinga2 的多种应用的数据写入。
icinga2 可以收集监控和性能数据并写入 OpenTSDB,taosAdapter 可以支持接收 icinga2 的数据并写入到 TDengine 中。
- 参考链接 `https://icinga.com/docs/icinga-2/latest/doc/14-features/#opentsdb-writer` 使能 opentsdb-writer - 参考链接 `https://icinga.com/docs/icinga-2/latest/doc/14-features/#opentsdb-writer` 使能 opentsdb-writer
- 使能 taosAdapter 配置项 opentsdb_telnet.enable - 使能 taosAdapter 配置项 opentsdb_telnet.enable
- 修改配置文件 /etc/icinga2/features-enabled/opentsdb.conf - 修改配置文件 /etc/icinga2/features-enabled/opentsdb.conf
...@@ -14,4 +21,4 @@ object OpenTsdbWriter "opentsdb" { ...@@ -14,4 +21,4 @@ object OpenTsdbWriter "opentsdb" {
} }
``` ```
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。 taosAdapter 相关配置参数请参考 `taosadapter --help` 命令输出以及相关文档。
\ No newline at end of file
...@@ -3,9 +3,14 @@ sidebar_label: TCollector ...@@ -3,9 +3,14 @@ sidebar_label: TCollector
title: TCollector 写入 title: TCollector 写入
--- ---
TCollector 是一个在客户侧收集本地收集器并发送数据到 OpenTSDB 的进程,taosAdaapter 可以支持接收 TCollector 的数据并写入到 TDengine 中。 安装 TCollector
请参考[官方文档](http://opentsdb.net/docs/build/html/user_guide/utilities/tcollector.html#installation-of-tcollector)
使能 taosAdapter 配置项 opentsdb_telnet.enable TDengine 新版本(2.3.0.0+)包含一个 taosAdapter 独立程序,负责接收包括 TCollector 的多种应用的数据写入。
TCollector 是一个在客户侧收集本地收集器并发送数据到 OpenTSDB 的进程,taosAdapter 可以支持接收 TCollector 的数据并写入到 TDengine 中。
使能 taosAdapter 配置项 `opentsdb_telnet.enable`
修改 TCollector 配置文件,修改 OpenTSDB 宿主机地址为 taosAdapter 被部署的地址,并修改端口号为 taosAdapter 使用的端口(默认 6049)。 修改 TCollector 配置文件,修改 OpenTSDB 宿主机地址为 taosAdapter 被部署的地址,并修改端口号为 taosAdapter 使用的端口(默认 6049)。
taosAdapter 相关配置参数请参考 taosadapter --help 命令输出以及相关文档。 taosAdapter 相关配置参数请参考 `taosadapter --help` 命令输出以及相关文档。
...@@ -6,11 +6,11 @@ title: 集群部署 ...@@ -6,11 +6,11 @@ title: 集群部署
### 第零步 ### 第零步
规划集群所有物理节点的 FQDN,将规划好的 FQDN 分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的 IP 与 FQDN 的对应添加好。【如部署了 DNS,请联系网络管理员在 DNS 上做好相关配置】 规划集群所有物理节点的 FQDN,将规划好的 FQDN 分别添加到每个物理节点的 /etc/hostname;修改每个物理节点的 /etc/hosts,将所有集群物理节点的 IP 与 FQDN 的对应添加好。【如部署了 DNS,请联系网络管理员在 DNS 上做好相关配置】
### 第一步 ### 第一步
如果搭建集群的物理节点中,存有之前的测试数据、装过 1.X 的版本,或者装过其他版本的 TDengine,请先将其删除,并清空所有数据(如果需要保留原有数据,请联系涛思交付团队进行旧版本升级、数据迁移),具体步骤请参考博客《TDengine 多种安装包的安装和卸载》 如果搭建集群的物理节点中,存有之前的测试数据、装过 1.X 的版本,或者装过其他版本的 TDengine,请先将其删除,并清空所有数据(如果需要保留原有数据,请联系涛思交付团队进行旧版本升级、数据迁移),具体步骤请参考博客[《TDengine 多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html)
:::note :::note
因为 FQDN 的信息会写进文件,如果之前没有配置或者更改 FQDN,且启动了 TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/\*); 因为 FQDN 的信息会写进文件,如果之前没有配置或者更改 FQDN,且启动了 TDengine。请一定在确保数据无用或者备份的前提下,清理一下之前的数据(rm -rf /var/lib/taos/\*);
...@@ -26,15 +26,15 @@ title: 集群部署 ...@@ -26,15 +26,15 @@ title: 集群部署
### 第三步 ### 第三步
在所有物理节点安装 TDengine,且版本必须是一致的,但不要启动 taosd。安装时,提示输入是否要加入一个已经存在的 TDengine 集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的 FQDN:端口号(默认 6030) 在所有物理节点安装 TDengine,且版本必须是一致的,但不要启动 taosd。安装时,提示输入是否要加入一个已经存在的 TDengine 集群时,第一个物理节点直接回车创建新集群,后续物理节点则输入该集群任何一个在线的物理节点的 FQDN:端口号(默认 6030)
### 第四步 ### 第四步
检查所有数据节点,以及应用程序所在物理节点的网络设置: 检查所有数据节点,以及应用程序所在物理节点的网络设置:
每个物理节点上执行命令 `hostname -f`,查看和确认所有节点的 hostname 是不相同的(应用驱动所在节点无需做此项检查) 每个物理节点上执行命令 `hostname -f`,查看和确认所有节点的 hostname 是不相同的(应用驱动所在节点无需做此项检查)
每个物理节点上执行 ping host,其中 host 是其他物理节点的 hostname,看能否 ping 通其它物理节点;如果不能 ping 通,需要检查网络设置,或/etc/hosts 文件(Windows 系统默认路径为 C:\Windows\system32\drivers\etc\hosts),或 DNS 的配置。如果无法 ping 通,是无法组成集群的; 每个物理节点上执行 ping host,其中 host 是其他物理节点的 hostname,看能否 ping 通其它物理节点;如果不能 ping 通,需要检查网络设置,或 /etc/hosts 文件(Windows 系统默认路径为 C:\Windows\system32\drivers\etc\hosts),或 DNS 的配置。如果无法 ping 通,是无法组成集群的;
从应用运行的物理节点,ping taosd 运行的数据节点,如果无法 ping 通,应用是无法连接 taosd 的,请检查应用所在物理节点的 DNS 设置或 hosts 文件; 从应用运行的物理节点,ping taosd 运行的数据节点,如果无法 ping 通,应用是无法连接 taosd 的,请检查应用所在物理节点的 DNS 设置或 hosts 文件;
...@@ -42,19 +42,19 @@ title: 集群部署 ...@@ -42,19 +42,19 @@ title: 集群部署
### 第五步 ### 第五步
修改 TDengine 的配置文件(所有节点的文件/etc/taos/taos.cfg 都需要修改)。假设准备启动的第一个数据节点 End Point 为 h1.taosdata.com:6030,其与集群配置相关参数如下: 修改 TDengine 的配置文件(所有节点的文件 /etc/taos/taos.cfg 都需要修改)。假设准备启动的第一个数据节点 End Point 为 h1.taosdata.com:6030,其与集群配置相关参数如下:
```c ```c
// firstEp 是每个数据节点首次启动后连接的第一个数据节点 // firstEp 是每个数据节点首次启动后连接的第一个数据节点
firstEp h1.taosdata.com:6030 firstEp h1.taosdata.com:6030
// 必须配置为本数据节点的FQDN,如果本机只有一个hostname, 可注释掉本项 // 必须配置为本数据节点的 FQDN,如果本机只有一个 hostname,可注释掉本项
fqdn h1.taosdata.com fqdn h1.taosdata.com
// 配置本数据节点的端口号,缺省是6030 // 配置本数据节点的端口号,缺省是 6030
serverPort 6030 serverPort 6030
// 副本数为偶数的时候,需要配置,请参考《Arbitrator的使用》的部分 // 副本数为偶数的时候,需要配置,请参考《Arbitrator 的使用》的部分
arbitrator ha.taosdata.com:6042 arbitrator ha.taosdata.com:6042
``` ```
...@@ -83,7 +83,7 @@ arbitrator ha.taosdata.com:6042 ...@@ -83,7 +83,7 @@ arbitrator ha.taosdata.com:6042
### 启动第一个数据节点 ### 启动第一个数据节点
按照《立即开始》里的步骤,启动第一个数据节点,例如 h1.taosdata.com,然后执行 taos, 启动 taos shell,从 shell 里执行命令"SHOW dnodes;",如下所示: 按照《立即开始》里的步骤,启动第一个数据节点,例如 h1.taosdata.com,然后执行 taos,启动 taos shell,从 shell 里执行命令“SHOW DNODES”,如下所示:
``` ```
Welcome to the TDengine shell from Linux, Client Version:2.0.0.0 Welcome to the TDengine shell from Linux, Client Version:2.0.0.0
...@@ -100,7 +100,7 @@ Query OK, 1 row(s) in set (0.006385s) ...@@ -100,7 +100,7 @@ Query OK, 1 row(s) in set (0.006385s)
taos> taos>
``` ```
上述命令里,可以看到这个刚启动的这个数据节点的 End Point 是:h1.taos.com:6030,就是这个新集群的 firstEp。 上述命令里,可以看到刚启动的数据节点的 End Point 是:h1.taos.com:6030,就是这个新集群的 firstEp。
### 启动后续数据节点 ### 启动后续数据节点
...@@ -114,7 +114,7 @@ taos> ...@@ -114,7 +114,7 @@ taos>
CREATE DNODE "h2.taos.com:6030"; CREATE DNODE "h2.taos.com:6030";
``` ```
将新数据节点的 End Point (准备工作中第四步获知的) 添加进集群的 EP 列表。"fqdn:port"需要用双引号引起来,否则出错。请注意将示例的“h2.taos.com:6030" 替换为这个新数据节点的 End Point。 将新数据节点的 End Point(准备工作中第四步获知的)添加进集群的 EP 列表。“fqdn:port”需要用双引号引起来,否则出错。请注意将示例的“h2.taos.com:6030” 替换为这个新数据节点的 End Point。
然后执行命令 然后执行命令
...@@ -124,8 +124,8 @@ SHOW DNODES; ...@@ -124,8 +124,8 @@ SHOW DNODES;
查看新节点是否被成功加入。如果该被加入的数据节点处于离线状态,请做两个检查: 查看新节点是否被成功加入。如果该被加入的数据节点处于离线状态,请做两个检查:
查看该数据节点的 taosd 是否正常工作,如果没有正常运行,需要先检查为什么 查看该数据节点的 taosd 是否正常工作,如果没有正常运行,需要先检查为什么?
查看该数据节点 taosd 日志文件 taosdlog.0 里前面几行日志(一般在/var/log/taos 目录),看日志里输出的该数据节点 fqdn 以及端口号是否为刚添加的 End Point。如果不一致,需要将正确的 End Point 添加进去。 查看该数据节点 taosd 日志文件 taosdlog.0 里前面几行日志(一般在 /var/log/taos 目录),看日志里输出的该数据节点 fqdn 以及端口号是否为刚添加的 End Point。如果不一致,需要将正确的 End Point 添加进去。
按照上述步骤可以源源不断的将新的数据节点加入到集群。 按照上述步骤可以源源不断的将新的数据节点加入到集群。
:::tip :::tip
......
...@@ -6,17 +6,21 @@ title: 集群管理 ...@@ -6,17 +6,21 @@ title: 集群管理
上面已经介绍如何从零开始搭建集群。集群组建完后,还可以随时添加新的数据节点进行扩容,或删除数据节点,并检查集群当前状态。 上面已经介绍如何从零开始搭建集群。集群组建完后,还可以随时添加新的数据节点进行扩容,或删除数据节点,并检查集群当前状态。
提示: :::note
以下所有执行命令的操作需要先登陆进 TDengine 系统,必要时请使用 root 权限。 以下所有执行命令的操作需要先登陆进 TDengine 系统,必要时请使用 root 权限。
添加数据节点
:::
## 添加数据节点
执行 CLI 程序 taos,执行: 执行 CLI 程序 taos,执行:
```sql ```sql
CREATE DNODE "fqdn:port"; CREATE DNODE "fqdn:port";
``` ```
将新数据节点的 End Point 添加进集群的 EP 列表。"fqdn:port"需要用双引号引起来,否则出错。一个数据节点对外服务的 fqdn 和 port 可以通过配置文件 taos.cfg 进行配置,缺省是自动获取。【强烈不建议用自动获取方式来配置 FQDN,可能导致生成的数据节点的 End Point 不是所期望的】 将新数据节点的 End Point 添加进集群的 EP 列表。“fqdn:port“需要用双引号引起来,否则出错。一个数据节点对外服务的 fqdn 和 port 可以通过配置文件 taos.cfg 进行配置,缺省是自动获取。【强烈不建议用自动获取方式来配置 FQDN,可能导致生成的数据节点的 End Point 不是所期望的】
## 删除数据节点 ## 删除数据节点
...@@ -26,11 +30,11 @@ CREATE DNODE "fqdn:port"; ...@@ -26,11 +30,11 @@ CREATE DNODE "fqdn:port";
DROP DNODE "fqdn:port | dnodeID"; DROP DNODE "fqdn:port | dnodeID";
``` ```
通过"fqdn:port"或"dnodeID"来指定一个具体的节点都是可以的。其中 fqdn 是被删除的节点的 FQDN,port 是其对外服务器的端口号;dnodeID 可以通过 SHOW DNODES 获得。 通过“fqdn:port”或“dnodeID”来指定一个具体的节点都是可以的。其中 fqdn 是被删除的节点的 FQDN,port 是其对外服务器的端口号;dnodeID 可以通过 SHOW DNODES 获得。
:::warning :::warning
一个数据节点一旦被 drop 之后,不能重新加入集群。需要将此节点重新部署(清空数据文件夹)。集群在完成 drop dnode 操作之前,会将该 dnode 的数据迁移走。 数据节点一旦被 drop 之后,不能重新加入集群。需要将此节点重新部署(清空数据文件夹)。集群在完成 drop dnode 操作之前,会将该 dnode 的数据迁移走。
请注意 drop dnode 和 停止 taosd 进程是两个不同的概念,不要混淆:因为删除 dnode 之前要执行迁移数据的操作,因此被删除的 dnode 必须保持在线状态。待删除操作结束之后,才能停止 taosd 进程。 请注意 drop dnode 和 停止 taosd 进程是两个不同的概念,不要混淆:因为删除 dnode 之前要执行迁移数据的操作,因此被删除的 dnode 必须保持在线状态。待删除操作结束之后,才能停止 taosd 进程。
一个数据节点被 drop 之后,其他节点都会感知到这个 dnodeID 的删除操作,任何集群中的节点都不会再接收此 dnodeID 的请求。 一个数据节点被 drop 之后,其他节点都会感知到这个 dnodeID 的删除操作,任何集群中的节点都不会再接收此 dnodeID 的请求。
dnodeID 是集群自动分配的,不得人工指定。它在生成时是递增的,不会重复。 dnodeID 是集群自动分配的,不得人工指定。它在生成时是递增的,不会重复。
...@@ -51,8 +55,8 @@ ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>"; ...@@ -51,8 +55,8 @@ ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>";
:::warning :::warning
只有在集群的自动负载均衡选项关闭时(balance 设置为 0),才允许手动迁移。 只有在集群的自动负载均衡选项关闭时(balance 设置为 0),才允许手动迁移。
只有处于正常工作状态的 vnode 才能被迁移:master/slave当处于 offline/unsynced/syncing 状态时,是不能迁移的。 只有处于正常工作状态的 vnode 才能被迁移:master/slave当处于 offline/unsynced/syncing 状态时,是不能迁移的。
迁移前,务必核实目标 dnode 的资源足够:CPU、内存、硬盘。 迁移前,务必核实目标 dnode 的资源足够:CPU、内存、硬盘。
::: :::
...@@ -65,11 +69,11 @@ ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>"; ...@@ -65,11 +69,11 @@ ALTER DNODE <source-dnodeId> BALANCE "VNODE:<vgId>-DNODE:<dest-dnodeId>";
SHOW DNODES; SHOW DNODES;
``` ```
它将列出集群中所有的 dnode,每个 dnode 的 ID,end_point(fqdn:port),状态(ready, offline 等),vnode 数目,还未使用的 vnode 数目等信息。在添加或删除一个数据节点后,可以使用该命令查看。 它将列出集群中所有的 dnode,每个 dnode 的 ID,end_point(fqdn:port),状态(ready,offline 等),vnode 数目,还未使用的 vnode 数目等信息。在添加或删除一个数据节点后,可以使用该命令查看。
## 查看虚拟节点组 ## 查看虚拟节点组
为充分利用多核技术,并提供 scalability,数据需要分片处理。因此 TDengine 会将一个 DB 的数据切分成多份,存放在多个 vnode 里。这些 vnode 可能分布在多个数据节点 dnode 里,这样就实现了水平扩展。一个 vnode 仅仅属于一个 DB,但一个 DB 可以有多个 vnode。vnode 是 mnode 根据当前系统资源的情况,自动进行分配的,无需任何人工干预。 为充分利用多核技术,并提供 scalability,数据需要分片处理。因此 TDengine 会将一个 DB 的数据切分成多份,存放在多个 vnode 里。这些 vnode 可能分布在多个数据节点 dnode 里,这样就实现了水平扩展。一个 vnode 仅仅属于一个 DB,但一个 DB 可以有多个 vnode。vnode 所在的数据节点是 mnode 根据当前系统资源的情况,自动进行分配的,无需任何人工干预。
执行 CLI 程序 taos,执行: 执行 CLI 程序 taos,执行:
......
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
title: 高可用与负载均衡 title: 高可用与负载均衡
--- ---
## vnode 的高可用性 ## Vnode 的高可用性
TDengine 通过多副本的机制来提供系统的高可用性,包括 vnode 和 mnode 的高可用性。 TDengine 通过多副本的机制来提供系统的高可用性,包括 vnode 和 mnode 的高可用性。
vnode 的副本数是与 DB 关联的,一个集群里可以有多个 DB,根据运营的需求,每个 DB 可以配置不同的副本数。创建数据库时,通过参数 replica 指定副本数(缺省为 1)。如果副本数为 1,系统的可靠性无法保证,只要数据所在的节点宕机,就将无法提供服务。集群的节点数必须大于等于副本数,否则创建表时将返回错误"more dnodes are needed"。比如下面的命令将创建副本数为 3 的数据库 demo: vnode 的副本数是与 DB 关联的,一个集群里可以有多个 DB,根据运营的需求,每个 DB 可以配置不同的副本数。创建数据库时,通过参数 replica 指定副本数(缺省为 1)。如果副本数为 1,系统的可靠性无法保证,只要数据所在的节点宕机,就将无法提供服务。集群的节点数必须大于等于副本数,否则创建表时将返回错误“more dnodes are needed”。比如下面的命令将创建副本数为 3 的数据库 demo:
```sql ```sql
CREATE DATABASE demo replica 3; CREATE DATABASE demo replica 3;
``` ```
一个 DB 里的数据会被切片分到多个 vnode group,vnode group 里的 vnode 数目就是 DB 的副本数,同一个 vnode group 里各 vnode 的数据是完全一致的。为保证高可用性,vnode group 里的 vnode 一定要分布在不同的数据节点 dnode 里(实际部署时,需要在不同的物理机上),只要一个 vgroup 里超过半数的 vnode 处于工作状态,这个 vgroup 就能正常的对外服务。 一个 DB 里的数据会被切片分到多个 vnode group,vnode group 里的 vnode 数目就是 DB 的副本数,同一个 vnode group 里各 vnode 的数据是完全一致的。为保证高可用性,vnode group 里的 vnode 一定要分布在不同的数据节点 dnode 里(实际部署时,需要在不同的物理机上),只要一个 vnode group 里超过半数的 vnode 处于工作状态,这个 vnode group 就能正常的对外服务。
一个数据节点 dnode 里可能有多个 DB 的数据,因此一个 dnode 离线时,可能会影响到多个 DB。如果一个 vnode group 里的一半或一半以上的 vnode 不工作,那么该 vnode group 就无法对外服务,无法插入或读取数据,这样会影响到它所属的 DB 的一部分表的读写操作。 一个数据节点 dnode 里可能有多个 DB 的数据,因此一个 dnode 离线时,可能会影响到多个 DB。如果一个 vnode group 里的一半或一半以上的 vnode 不工作,那么该 vnode group 就无法对外服务,无法插入或读取数据,这样会影响到它所属的 DB 的一部分表的读写操作。
...@@ -20,7 +20,7 @@ CREATE DATABASE demo replica 3; ...@@ -20,7 +20,7 @@ CREATE DATABASE demo replica 3;
## Mnode 的高可用性 ## Mnode 的高可用性
TDengine 集群是由 mnode (taosd 的一个模块,管理节点) 负责管理的,为保证 mnode 的高可用,可以配置多个 mnode 副本,副本数由系统配置参数 numOfMnodes 决定,有效范围为 1-3。为保证元数据的强一致性,mnode 副本之间是通过同步的方式进行数据复制的。 TDengine 集群是由 mnode(taosd 的一个模块,管理节点)负责管理的,为保证 mnode 的高可用,可以配置多个 mnode 副本,副本数由系统配置参数 numOfMnodes 决定,有效范围为 1-3。为保证元数据的强一致性,mnode 副本之间是通过同步的方式进行数据复制的。
一个集群有多个数据节点 dnode,但一个 dnode 至多运行一个 mnode 实例。多个 dnode 情况下,哪个 dnode 可以作为 mnode 呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过 CLI 程序 taos,在 TDengine 的 console 里,执行如下命令: 一个集群有多个数据节点 dnode,但一个 dnode 至多运行一个 mnode 实例。多个 dnode 情况下,哪个 dnode 可以作为 mnode 呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过 CLI 程序 taos,在 TDengine 的 console 里,执行如下命令:
...@@ -28,12 +28,12 @@ TDengine 集群是由 mnode (taosd 的一个模块,管理节点) 负责管理 ...@@ -28,12 +28,12 @@ TDengine 集群是由 mnode (taosd 的一个模块,管理节点) 负责管理
SHOW MNODES; SHOW MNODES;
``` ```
来查看 mnode 列表,该列表将列出 mnode 所处的 dnode 的 End Point 和角色(master, slave, unsynced 或 offline)。当集群中第一个数据节点启动时,该数据节点一定会运行一个 mnode 实例,否则该数据节点 dnode 无法正常工作,因为一个系统是必须有至少一个 mnode 的。如果 numOfMnodes 配置为 2,启动第二个 dnode 时,该 dnode 也将运行一个 mnode 实例。 来查看 mnode 列表,该列表将列出 mnode 所处的 dnode 的 End Point 和角色(master,slave,unsynced 或 offline)。当集群中第一个数据节点启动时,该数据节点一定会运行一个 mnode 实例,否则该数据节点 dnode 无法正常工作,因为一个系统是必须有至少一个 mnode 的。如果 numOfMnodes 配置为 2,启动第二个 dnode 时,该 dnode 也将运行一个 mnode 实例。
为保证 mnode 服务的高可用性,numOfMnodes 必须设置为 2 或更大。因为 mnode 保存的元数据必须是强一致的,如果 numOfMnodes 大于 2,复制参数 quorum 自动设为 2,也就是说,至少要保证有两个副本写入数据成功,才通知客户端应用写入成功。 为保证 mnode 服务的高可用性,numOfMnodes 必须设置为 2 或更大。因为 mnode 保存的元数据必须是强一致的,如果 numOfMnodes 大于 2,复制参数 quorum 自动设为 2,也就是说,至少要保证有两个副本写入数据成功,才通知客户端应用写入成功。
:::note :::note
一个 TDengine 高可用系统,无论是 vnode 还是 mnode, 都必须配置多个副本。 一个 TDengine 高可用系统,无论是 vnode 还是 mnode都必须配置多个副本。
::: :::
...@@ -47,7 +47,7 @@ SHOW MNODES; ...@@ -47,7 +47,7 @@ SHOW MNODES;
当上述三种情况发生时,系统将启动各个数据节点的负载计算,从而决定如何挪动。 当上述三种情况发生时,系统将启动各个数据节点的负载计算,从而决定如何挪动。
:::tip :::tip
负载均衡由参数 balance 控制,它决定是否启动自动负载均衡, 0 表示禁用, 1 表示启用自动负载均衡。\*\* 负载均衡由参数 balance 控制,它决定是否启动自动负载均衡,0 表示禁用,1 表示启用自动负载均衡。
::: :::
...@@ -55,7 +55,7 @@ SHOW MNODES; ...@@ -55,7 +55,7 @@ SHOW MNODES;
如果一个数据节点离线,TDengine 集群将自动检测到。有如下两种情况: 如果一个数据节点离线,TDengine 集群将自动检测到。有如下两种情况:
该数据节点离线超过一定时间(taos.cfg 里配置参数 offlineThreshold 控制时长),系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重新上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。 该数据节点离线超过一定时间(taos.cfg 里配置参数 offlineThreshold 控制时长,系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重新上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
离线后,在 offlineThreshold 的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。 离线后,在 offlineThreshold 的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。
...@@ -79,7 +79,7 @@ Arbitrator 的执行程序名为 tarbitrator。该程序对系统资源几乎没 ...@@ -79,7 +79,7 @@ Arbitrator 的执行程序名为 tarbitrator。该程序对系统资源几乎没
修改每个 taosd 实例的配置文件,在 taos.cfg 里将参数 arbitrator 设置为 tarbitrator 程序所对应的 End Point。(如果该参数配置了,当副本数为偶数时,系统将自动连接配置的 Arbitrator。如果副本数为奇数,即使配置了 Arbitrator,系统也不会去建立连接。) 修改每个 taosd 实例的配置文件,在 taos.cfg 里将参数 arbitrator 设置为 tarbitrator 程序所对应的 End Point。(如果该参数配置了,当副本数为偶数时,系统将自动连接配置的 Arbitrator。如果副本数为奇数,即使配置了 Arbitrator,系统也不会去建立连接。)
在配置文件中配置了的 Arbitrator,会出现在 SHOW DNODES; 指令的返回结果中,对应的 role 列的值会是“arb”。 在配置文件中配置了的 Arbitrator,会出现在 SHOW DNODES 指令的返回结果中,对应的 role 列的值会是“arb”。
查看集群 Arbitrator 的状态【2.0.14.0 以后支持】 查看集群 Arbitrator 的状态【2.0.14.0 以后支持】
```sql ```sql
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
title: 安装、卸载、启动和停止 title: 安装、卸载、启动和停止
--- ---
TDengine 开源版本提供 deb 和 rpm 格式安装包,用户可以根据自己的运行环境选择合适的安装包。其中 deb 支持 Debian/Ubuntu 等系统,rpm 支持 CentOS/RHEL/SUSE 等系统。同时我们也为企业用户提供 tar.gz 格式安装包。 TDengine 开源版本提供 deb 和 rpm 格式安装包,用户可以根据自己的运行环境选择合适的安装包。其中 deb 支持 Debian/Ubuntu 及衍生系统,rpm 支持 CentOS/RHEL/SUSE 及衍生系统。同时我们也为企业用户提供 tar.gz 格式安装包。
## deb 包的安装和卸载 ## deb 包的安装和卸载
### 安装 deb ### 安装 deb
1、从官网下载获得 deb 安装包,比如 TDengine-server-2.0.0.0-Linux-x64.deb; 1、从官网下载获得 deb 安装包,例如 TDengine-server-2.4.0.7-Linux-x64.deb;
2、进入到 TDengine-server-2.0.0.0-Linux-x64.deb 安装包所在目录,执行如下的安装命令: 2、进入到 TDengine-server-2.4.0.7-Linux-x64.deb 安装包所在目录,执行如下的安装命令:
``` ```
$ sudo dpkg -i TDengine-server-2.4.0.7-Linux-x64.deb $ sudo dpkg -i TDengine-server-2.4.0.7-Linux-x64.deb
...@@ -20,7 +20,7 @@ Unpacking tdengine (2.4.0.7) over (2.4.0.7) ... ...@@ -20,7 +20,7 @@ Unpacking tdengine (2.4.0.7) over (2.4.0.7) ...
Setting up tdengine (2.4.0.7) ... Setting up tdengine (2.4.0.7) ...
Start to install TDengine... Start to install TDengine...
System hostname is: shuduo-1804 System hostname is: ubuntu-1804
Enter FQDN:port (like h1.taosdata.com:6030) of an existing TDengine cluster node to join Enter FQDN:port (like h1.taosdata.com:6030) of an existing TDengine cluster node to join
OR leave it blank to build one: OR leave it blank to build one:
...@@ -30,7 +30,7 @@ Created symlink /etc/systemd/system/multi-user.target.wants/taosd.service → /e ...@@ -30,7 +30,7 @@ Created symlink /etc/systemd/system/multi-user.target.wants/taosd.service → /e
To configure TDengine : edit /etc/taos/taos.cfg To configure TDengine : edit /etc/taos/taos.cfg
To start TDengine : sudo systemctl start taosd To start TDengine : sudo systemctl start taosd
To access TDengine : taos -h shuduo-1804 to login into TDengine server To access TDengine : taos -h ubuntu-1804 to login into TDengine server
TDengine is installed successfully! TDengine is installed successfully!
...@@ -55,8 +55,8 @@ TDengine is removed successfully! ...@@ -55,8 +55,8 @@ TDengine is removed successfully!
### 安装 rpm ### 安装 rpm
1、从官网下载获得 rpm 安装包,比如 TDengine-server-2.0.0.0-Linux-x64.rpm; 1、从官网下载获得 rpm 安装包,例如 TDengine-server-2.4.0.7-Linux-x64.rpm;
2、进入到 TDengine-server-2.0.0.0-Linux-x64.rpm 安装包所在目录,执行如下的安装命令: 2、进入到 TDengine-server-2.4.0.7-Linux-x64.rpm 安装包所在目录,执行如下的安装命令:
``` ```
$ sudo rpm -ivh TDengine-server-2.4.0.7-Linux-x64.rpm $ sudo rpm -ivh TDengine-server-2.4.0.7-Linux-x64.rpm
...@@ -95,7 +95,7 @@ TDengine is removed successfully! ...@@ -95,7 +95,7 @@ TDengine is removed successfully!
### 安装 tar.gz 安装包 ### 安装 tar.gz 安装包
1、从官网下载获得 tar.gz 安装包,如 TDengine-server-2.4.0.7-Linux-x64.tar.gz; 1、从官网下载获得 tar.gz 安装包,如 TDengine-server-2.4.0.7-Linux-x64.tar.gz;
2、进入到 TDengine-server-2.4.0.7-Linux-x64.tar.gz 安装包所在目录,先解压文件后,进入子目录,执行其中的 install.sh 安装脚本: 2、进入到 TDengine-server-2.4.0.7-Linux-x64.tar.gz 安装包所在目录,先解压文件后,进入子目录,执行其中的 install.sh 安装脚本:
``` ```
...@@ -135,7 +135,7 @@ Nginx for TDengine is updated successfully! ...@@ -135,7 +135,7 @@ Nginx for TDengine is updated successfully!
To configure TDengine : edit /etc/taos/taos.cfg To configure TDengine : edit /etc/taos/taos.cfg
To configure Taos Adapter (if has) : edit /etc/taos/taosadapter.toml To configure Taos Adapter (if has) : edit /etc/taos/taosadapter.toml
To start TDengine : sudo systemctl start taosd To start TDengine : sudo systemctl start taosd
To access TDengine : use taos -h shuduo-1804 in shell OR from http://127.0.0.1:6060 To access TDengine : use taos -h ubuntu-1804 in shell OR from http://127.0.0.1:6060
TDengine is updated successfully! TDengine is updated successfully!
Install taoskeeper as a standalone service Install taoskeeper as a standalone service
......
...@@ -11,8 +11,11 @@ title: 诊断及其他 ...@@ -11,8 +11,11 @@ title: 诊断及其他
诊断步骤: 诊断步骤:
1. 如拟诊断的端口范围与服务器 taosd 实例的端口范围相同,须先停掉 taosd 实例 1. 如拟诊断的端口范围与服务器 taosd 实例的端口范围相同,须先停掉 taosd 实例
2. 服务端命令行输入:`taos -n server -P <port>` 以服务端身份启动对端口 port 为基准端口的监听 2. 服务端命令行输入:`taos -n server -P <port> -l <pktlen>` 以服务端身份启动对端口 port 为基准端口的监听
3. 客户端命令行输入:`taos -n client -h <fqdn of server> -P <port>` 以客户端身份启动对指定的服务器、指定的端口发送测试包 3. 客户端命令行输入:`taos -n client -h <fqdn of server> -P <port> -l <pktlen>` 以客户端身份启动对指定的服务器、指定的端口发送测试包
-l <pktlen\>: 测试网络包的大小(单位:字节)。最小值是 11、最大值是 64000,默认值为 1000。
注:两端命令行中指定的测试包长度必须一致,否则测试显示失败。
服务端运行正常的话会输出以下信息: 服务端运行正常的话会输出以下信息:
...@@ -96,7 +99,7 @@ taos -n sync -P 6042 -h <fqdn of server> ...@@ -96,7 +99,7 @@ taos -n sync -P 6042 -h <fqdn of server>
-h:所要连接的服务端的 FQDN 或 ip 地址。如果不设置这一项,会使用本机 taos.cfg 文件中 FQDN 参数的设置作为默认值。 -h:所要连接的服务端的 FQDN 或 ip 地址。如果不设置这一项,会使用本机 taos.cfg 文件中 FQDN 参数的设置作为默认值。
-P:所连接服务端的网络端口。默认值为 6030。 -P:所连接服务端的网络端口。默认值为 6030。
-N:诊断过程中使用的网络包总数。最小值是 1、最大值是 10000,默认值为 100。 -N:诊断过程中使用的网络包总数。最小值是 1、最大值是 10000,默认值为 100。
-l:单个网络包的大小(单位:字节)。最小值是 1024、最大值是 1024 _ 1024 _ 1024,默认值为 1000 -l:单个网络包的大小(单位:字节)。最小值是 1024、最大值是 1024 `*` 1024 `*` 1024,默认值为 1024
-S:网络封包的类型。可以是 TCP 或 UDP,默认值为 TCP。 -S:网络封包的类型。可以是 TCP 或 UDP,默认值为 TCP。
## FQDN 解析速度诊断 ## FQDN 解析速度诊断
......
此差异已折叠。
此差异已折叠。
...@@ -8,10 +8,10 @@ title: 支持的数据类型 ...@@ -8,10 +8,10 @@ title: 支持的数据类型
- 时间格式为 `YYYY-MM-DD HH:mm:ss.MS`,默认时间分辨率为毫秒。比如:`2017-08-12 18:25:58.128` - 时间格式为 `YYYY-MM-DD HH:mm:ss.MS`,默认时间分辨率为毫秒。比如:`2017-08-12 18:25:58.128`
- 内部函数 now 是客户端的当前时间 - 内部函数 now 是客户端的当前时间
- 插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间 - 插入记录时,如果时间戳为 now,插入数据时使用提交这条记录的客户端的当前时间
- Epoch Time:时间戳也可以是一个长整数,表示从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的毫秒数(相应地,如果所在 Database 的时间精度设置为“微秒”,则长整型格式的时间戳含义也就对应于从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的微秒数;纳秒精度的逻辑也是类似的。) - Epoch Time:时间戳也可以是一个长整数,表示从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的毫秒数(相应地,如果所在 Database 的时间精度设置为“微秒”,则长整型格式的时间戳含义也就对应于从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始的微秒数;纳秒精度逻辑类似。)
- 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降采样操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。 - 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降采样操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n (自然月) 和 y (自然年)。
TDengine 缺省的时间戳是毫秒精度,但通过在 `CREATE DATABASE` 时传递的 PRECISION 参数就可以支持微秒和纳秒。(从 2.1.5.0 版本开始支持纳秒精度) TDengine 缺省的时间戳精度是毫秒,但通过在 `CREATE DATABASE` 时传递的 PRECISION 参数也可以支持微秒和纳秒。(从 2.1.5.0 版本开始支持纳秒精度)
``` ```
CREATE DATABASE db_name PRECISION 'ns'; CREATE DATABASE db_name PRECISION 'ns';
...@@ -23,15 +23,15 @@ CREATE DATABASE db_name PRECISION 'ns'; ...@@ -23,15 +23,15 @@ CREATE DATABASE db_name PRECISION 'ns';
| --- | :-------: | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --- | :-------: | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒和纳秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18.0 版本开始,已经去除了这一时间范围限制)(从 2.1.5.0 版本开始支持纳秒精度) | | 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒和纳秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18.0 版本开始,已经去除了这一时间范围限制)(从 2.1.5.0 版本开始支持纳秒精度) |
| 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL | | 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL |
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用 NULL | | 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用 NULL |
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | | 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
| 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] | | 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] |
| 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,总共固定占用 20 bytes 的空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 | | 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,总共固定占用 20 bytes 的空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 |
| 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用 NULL | | 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用 NULL |
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用 NULL | | 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用 NULL |
| 9 | BOOL | 1 | 布尔型,{true, false} | | 9 | BOOL | 1 | 布尔型,{true, false} |
| 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | | 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 |
| 11 | JSON | | json 数据类型, 只有 tag 类型可以是 json 格式 | | 11 | JSON | | json 数据类型, 只有 tag 可以是 json 格式 |
<!-- REPLACE_OPEN_TO_ENTERPRISE__COLUMN_TYPE_ADDONS --> <!-- REPLACE_OPEN_TO_ENTERPRISE__COLUMN_TYPE_ADDONS -->
...@@ -41,7 +41,7 @@ TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小 ...@@ -41,7 +41,7 @@ TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小
::: :::
:::note :::note
虽然 Binary 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 Binary 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 nchar 类型进行保存。如果强行使用 Binary 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏等情况。 虽然 BINARY 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 BINARY 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 NCHAR 类型进行保存。如果强行使用 BINARY 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏等情况。
::: :::
......
...@@ -3,8 +3,11 @@ sidebar_label: 超级表管理 ...@@ -3,8 +3,11 @@ sidebar_label: 超级表管理
title: 超级表 STable 管理 title: 超级表 STable 管理
--- ---
:::note
注意:在 2.0.15.0 及以后的版本中,开始支持 STABLE 保留字。也即,在本节后文的指令说明中,CREATE、DROP、ALTER 三个指令在老版本中保留字需写作 TABLE 而不是 STABLE。 在 2.0.15.0 及以后的版本中开始支持 STABLE 保留字。也即,在本节后文的指令说明中,CREATE、DROP、ALTER 三个指令在 2.0.15.0 之前的版本中 STABLE 保留字需写作 TABLE。
:::
## 创建超级表 ## 创建超级表
......
...@@ -221,42 +221,43 @@ Query OK, 1 row(s) in set (0.000081s) ...@@ -221,42 +221,43 @@ Query OK, 1 row(s) in set (0.000081s)
## \_block_dist 函数 ## \_block_dist 函数
用于获得指定的(超级)表的数据块分布信息 **功能说明**: 用于获得指定的(超级)表的数据块分布信息
```txt title="语法" ```txt title="语法"
SELECT _block_dist() FROM { tb_name | stb_name } SELECT _block_dist() FROM { tb_name | stb_name }
``` ```
返回结果类型:字符串。 **返回结果类型**:字符串。
适用数据类型:不能输入任何参数。 **适用数据类型**:不能输入任何参数。
嵌套子查询支持:不支持子查询或嵌套查询。 **嵌套子查询支持**:不支持子查询或嵌套查询。
返回 FROM 子句中输入的表或超级表的数据块分布情况。不支持查询条件。 **返回结果**:
返回的结果是该表或超级表的数据块所包含的行数的数据分布直方图。 - 返回 FROM 子句中输入的表或超级表的数据块分布情况。不支持查询条件。
- 返回的结果是该表或超级表的数据块所包含的行数的数据分布直方图。
```txt title="返回结果" ```txt title="返回结果"
summary: summary:
5th=[392], 10th=[392], 20th=[392], 30th=[392], 40th=[792], 50th=[792] 60th=[792], 70th=[792], 80th=[792], 90th=[792], 95th=[792], 99th=[792] Min=[392(Rows)] Max=[800(Rows)] Avg=[666(Rows)] Stddev=[2.17] Rows=[2000], Blocks=[3], Size=[5.440(Kb)] Comp=[0.23] RowsInMem=[0] SeekHeaderTime=[1(us)] 5th=[392], 10th=[392], 20th=[392], 30th=[392], 40th=[792], 50th=[792] 60th=[792], 70th=[792], 80th=[792], 90th=[792], 95th=[792], 99th=[792] Min=[392(Rows)] Max=[800(Rows)] Avg=[666(Rows)] Stddev=[2.17] Rows=[2000], Blocks=[3], Size=[5.440(Kb)] Comp=[0.23] RowsInMem=[0] SeekHeaderTime=[1(us)]
``` ```
上述信息的说明如下: **上述信息的说明如下**:
1. 查询的(超级)表所包含的存储在文件中的数据块(data block)中所包含的数据行的数量分布直方图信息:5%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 95%, 99% 的数值; - 查询的(超级)表所包含的存储在文件中的数据块(data block)中所包含的数据行的数量分布直方图信息:5%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 95%, 99% 的数值;
2. 所有数据块中,包含行数最少的数据块所包含的行数量, 其中的 Min 指标 392 行。 - 所有数据块中,包含行数最少的数据块所包含的行数量, 其中的 Min 指标 392 行。
3. 所有数据块中,包含行数最多的数据块所包含的行数量, 其中的 Max 指标 800 行。 - 所有数据块中,包含行数最多的数据块所包含的行数量, 其中的 Max 指标 800 行。
4. 所有数据块行数的算数平均值 666 行(其中的 Avg 项)。 - 所有数据块行数的算数平均值 666 行(其中的 Avg 项)。
5. 所有数据块中行数分布的均方差为 2.17 ( stddev )。 - 所有数据块中行数分布的均方差为 2.17 ( stddev )。
6. 数据块包含的行的总数为 2000 行(Rows)。 - 数据块包含的行的总数为 2000 行(Rows)。
7. 数据块总数是 3 个数据块 (Blocks)。 - 数据块总数是 3 个数据块 (Blocks)。
8. 数据块占用磁盘空间大小 5.44 Kb (size)。 - 数据块占用磁盘空间大小 5.44 Kb (size)。
9. 压缩后的数据块的大小除以原始数据的所获得的压缩比例: 23%(Comp),及压缩后的数据规模是原始数据规模的 23%。 - 压缩后的数据块的大小除以原始数据的所获得的压缩比例: 23%(Comp),及压缩后的数据规模是原始数据规模的 23%。
10. 内存中存在的数据行数是 0,表示内存中没有数据缓存。 - 内存中存在的数据行数是 0,表示内存中没有数据缓存。
11. 获取数据块信息的过程中读取头文件的时间开销 1 微秒(SeekHeaderTime)。 - 获取数据块信息的过程中读取头文件的时间开销 1 微秒(SeekHeaderTime)。
支持版本:指定计算算法的功能从 2.1.0.x 版本开始,2.1.0.0 之前的版本不支持指定使用算法的功能。 **支持版本**:指定计算算法的功能从 2.1.0.x 版本开始,2.1.0.0 之前的版本不支持指定使用算法的功能。
## TAOS SQL 中特殊关键词 ## TAOS SQL 中特殊关键词
...@@ -322,18 +323,20 @@ Query OK, 1 row(s) in set (0.001091s) ...@@ -322,18 +323,20 @@ Query OK, 1 row(s) in set (0.001091s)
| like | match a wildcard string | **`binary`** **`nchar`** | | like | match a wildcard string | **`binary`** **`nchar`** |
| match/nmatch | filter regex | **`binary`** **`nchar`** | | match/nmatch | filter regex | **`binary`** **`nchar`** |
1. <\> 算子也可以写为 != ,请注意,这个算子不能用于数据表第一列的 timestamp 字段。 **使用说明**:
2. like 算子使用通配符字符串进行匹配检查。
- <\> 算子也可以写为 != ,请注意,这个算子不能用于数据表第一列的 timestamp 字段。
- like 算子使用通配符字符串进行匹配检查。
- 在通配符字符串中:'%'(百分号)匹配 0 到任意个字符;'\_'(下划线)匹配单个任意 ASCII 字符。 - 在通配符字符串中:'%'(百分号)匹配 0 到任意个字符;'\_'(下划线)匹配单个任意 ASCII 字符。
- 如果希望匹配字符串中原本就带有的 \_(下划线)字符,那么可以在通配符字符串中写作 `\_`,也即加一个反斜线来进行转义。(从 2.2.0.0 版本开始支持) - 如果希望匹配字符串中原本就带有的 \_(下划线)字符,那么可以在通配符字符串中写作 `\_`,也即加一个反斜线来进行转义。(从 2.2.0.0 版本开始支持)
- 通配符字符串最长不能超过 20 字节。(从 2.1.6.1 版本开始,通配符字符串的长度放宽到了 100 字节,并可以通过 taos.cfg 中的 maxWildCardsLength 参数来配置这一长度限制。但不建议使用太长的通配符字符串,将有可能严重影响 LIKE 操作的执行性能。) - 通配符字符串最长不能超过 20 字节。(从 2.1.6.1 版本开始,通配符字符串的长度放宽到了 100 字节,并可以通过 taos.cfg 中的 maxWildCardsLength 参数来配置这一长度限制。但不建议使用太长的通配符字符串,将有可能严重影响 LIKE 操作的执行性能。)
3. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。 - 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
- 从 2.3.0.0 版本开始,已支持完整的同一列和/或不同列间的 AND/OR 运算。 - 从 2.3.0.0 版本开始,已支持完整的同一列和/或不同列间的 AND/OR 运算。
4. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如: `((value > 20 AND value < 30) OR (value < 12))` - 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如: `((value > 20 AND value < 30) OR (value < 12))`
- 从 2.3.0.0 版本开始,允许使用多个时间过滤条件,但首列时间戳的过滤运算结果只能包含一个区间。 - 从 2.3.0.0 版本开始,允许使用多个时间过滤条件,但首列时间戳的过滤运算结果只能包含一个区间。
5. 从 2.0.17.0 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。 - 从 2.0.17.0 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。
6. 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}``{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功;TIMESTAMP 类型支持非主键的列。 - 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}``{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功;TIMESTAMP 类型支持非主键的列。
7. 从 2.3.0.0 版本开始,条件过滤开始支持正则表达式,关键字 match/nmatch,不区分大小写。 - 从 2.3.0.0 版本开始,条件过滤开始支持正则表达式,关键字 match/nmatch,不区分大小写。
## 正则表达式过滤 ## 正则表达式过滤
...@@ -375,14 +378,18 @@ WHERE t1.ts = t2.ts AND t1.deviceid = t2.deviceid AND t1.status=0; ...@@ -375,14 +378,18 @@ WHERE t1.ts = t2.ts AND t1.deviceid = t2.deviceid AND t1.status=0;
类似地,也可以对多个子查询的查询结果进行 JOIN 操作。 类似地,也可以对多个子查询的查询结果进行 JOIN 操作。
注意,JOIN 操作存在如下限制要求: :::note
JOIN语句存在如下限制要求:
1. 参与一条语句中 JOIN 操作的表/超级表最多可以有 10 个。 - 参与一条语句中 JOIN 操作的表/超级表最多可以有 10 个。
2. 在包含 JOIN 操作的查询语句中不支持 FILL。 - 在包含 JOIN 操作的查询语句中不支持 FILL。
3. 暂不支持参与 JOIN 操作的表之间聚合后的四则运算。 - 暂不支持参与 JOIN 操作的表之间聚合后的四则运算。
4. 不支持只对其中一部分表做 GROUP BY。 - 不支持只对其中一部分表做 GROUP BY。
5. JOIN 查询的不同表的过滤条件之间不能为 OR。 - JOIN 查询的不同表的过滤条件之间不能为 OR。
6. JOIN 查询要求连接条件不能是普通列,只能针对标签和主时间字段列(第一列)。 - JOIN 查询要求连接条件不能是普通列,只能针对标签和主时间字段列(第一列)。
:::
## 嵌套查询 ## 嵌套查询
...@@ -396,17 +403,17 @@ SELECT ... FROM (SELECT ... FROM ...) ...; ...@@ -396,17 +403,17 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
:::info :::info
1. 目前仅支持一层嵌套,也即不能在子查询中再嵌入子查询。 - 目前仅支持一层嵌套,也即不能在子查询中再嵌入子查询。
2. 内层查询的返回结果将作为“虚拟表”供外层查询使用,此虚拟表可以使用 AS 语法做重命名,以便于外层查询中方便引用。 - 内层查询的返回结果将作为“虚拟表”供外层查询使用,此虚拟表可以使用 AS 语法做重命名,以便于外层查询中方便引用。
3. 目前不能在“连续查询”功能中使用子查询。 - 目前不能在“连续查询”功能中使用子查询。
4. 在内层和外层查询中,都支持普通的表间/超级表间 JOIN。内层查询的计算结果也可以再参与数据子表的 JOIN 操作。 - 在内层和外层查询中,都支持普通的表间/超级表间 JOIN。内层查询的计算结果也可以再参与数据子表的 JOIN 操作。
5. 目前内层查询、外层查询均不支持 UNION 操作。 - 目前内层查询、外层查询均不支持 UNION 操作。
6. 内层查询支持的功能特性与非嵌套的查询语句能力是一致的。 - 内层查询支持的功能特性与非嵌套的查询语句能力是一致的。
- 内层查询的 ORDER BY 子句一般没有意义,建议避免这样的写法以免无谓的资源消耗。 - 内层查询的 ORDER BY 子句一般没有意义,建议避免这样的写法以免无谓的资源消耗。
7. 与非嵌套的查询语句相比,外层查询所能支持的功能特性存在如下限制: - 与非嵌套的查询语句相比,外层查询所能支持的功能特性存在如下限制:
- 计算函数部分: - 计算函数部分:
_. 如果内层查询的结果数据未提供时间戳,那么计算过程依赖时间戳的函数在外层会无法正常工作。例如:TOP, BOTTOM, FIRST, LAST, DIFF。 - 如果内层查询的结果数据未提供时间戳,那么计算过程依赖时间戳的函数在外层会无法正常工作。例如:TOP, BOTTOM, FIRST, LAST, DIFF。
_. 计算过程需要两遍扫描的函数,在外层查询中无法正常工作。例如:此类函数包括:STDDEV, PERCENTILE。 - 计算过程需要两遍扫描的函数,在外层查询中无法正常工作。例如:此类函数包括:STDDEV, PERCENTILE。
- 外层查询中不支持 IN 算子,但在内层中可以使用。 - 外层查询中不支持 IN 算子,但在内层中可以使用。
- 外层查询不支持 GROUP BY。 - 外层查询不支持 GROUP BY。
......
...@@ -27,4 +27,4 @@ title: 转义字符说明 ...@@ -27,4 +27,4 @@ title: 转义字符说明
2. 反引号``标识符: 保持原样,不转义 2. 反引号``标识符: 保持原样,不转义
2. 数据里有转义字符 2. 数据里有转义字符
1. 遇到上面定义的转义字符会转义(%和\_见下面说明),如果没有匹配的转义字符会忽略掉转义符\。 1. 遇到上面定义的转义字符会转义(%和\_见下面说明),如果没有匹配的转义字符会忽略掉转义符\。
2. 对于%和*,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`%和`\_`表示字符里本身的%和*,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_ 2. 对于%和\_,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`%和`\_`表示字符里本身的%和\_,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_
...@@ -4,7 +4,7 @@ title: TAOS SQL ...@@ -4,7 +4,7 @@ title: TAOS SQL
本文档说明 TAOS SQL 支持的语法规则、主要查询功能、支持的 SQL 查询函数,以及常用技巧等内容。阅读本文档需要读者具有基本的 SQL 语言的基础。 本文档说明 TAOS SQL 支持的语法规则、主要查询功能、支持的 SQL 查询函数,以及常用技巧等内容。阅读本文档需要读者具有基本的 SQL 语言的基础。
TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供类似于标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供 SQL 标准的语法。此外,由于 TDengine 针对的时序性结构化数据不提供删除功能,因此在 TAO SQL 中不提供数据删除的相关功能。 TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供与标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供标准的 SQL 语法。此外,由于 TDengine 针对的时序性结构化数据不提供删除功能,因此在 TAO SQL 中不提供数据删除的相关功能。
TAOS SQL 不支持关键字的缩写,例如 DESCRIBE 不能缩写为 DESC。 TAOS SQL 不支持关键字的缩写,例如 DESCRIBE 不能缩写为 DESC。
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
title: 连接器 title: 连接器
--- ---
TDengine 提供了丰富的应用程序开发接口,其中包括 C/C++、Java、Python、Go、Node.js、C# 、RESTful 等,便于用户快速开发应用。 TDengine 提供了丰富的应用程序开发接口,其中包括支持使用 C/C++、Java、Python、Go、Node.js、C# 等多种语言的连接器,包括使用 taos 客户端驱动接口和 RESTful 接口,便于用户快速开发自己的应用。
![image-connecotr](/img/connector.png) ![image-connector](/img/connector.png)
## 支持的系统 ## 支持的系统
...@@ -60,13 +60,13 @@ import Tabs from "@theme/Tabs"; ...@@ -60,13 +60,13 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem"; import TabItem from "@theme/TabItem";
import InstallOnWindows from "./_linux_install.mdx"; import InstallOnWindows from "./_linux_install.mdx";
import InstallOnLinux from "./_windows_install.mdx"; import InstallOnLinux from "./_windows_install.mdx";
import VarifyWindows from "./_varify_linux.mdx"; import VerifyWindows from "./_verify_linux.mdx";
import VarifyLinux from "./_varify_windows.mdx"; import VerifyLinux from "./_verify_windows.mdx";
## 安装客户端驱动 ## 安装客户端驱动
:::info :::info
只有在没有安装 TDengine 服务端软件的系统上使用非 RESTFful 连接器才需要安装客户端驱动。 只有在没有安装 TDengine 服务端软件的系统上使用非 RESTful 连接器才需要安装客户端驱动。
::: :::
...@@ -87,9 +87,10 @@ import VarifyLinux from "./_varify_windows.mdx"; ...@@ -87,9 +87,10 @@ import VarifyLinux from "./_varify_windows.mdx";
<Tabs defaultValue="linux" groupId="os"> <Tabs defaultValue="linux" groupId="os">
<TabItem value="linux" label="Linux"> <TabItem value="linux" label="Linux">
<VarifyLinux /> <VerifyLinux />
</TabItem> </TabItem>
<TabItem value="windows" label="Windows"> <TabItem value="windows" label="Windows">
<VarifyWindows /> <VerifyWindows />
</TabItem> </TabItem>
</Tabs> </Tabs>
在 Linux shell 下直接执行 taos,应该就能正常连接到 TDegine 服务,进入到 taos shell 界面,示例如下: 在 Linux shell 下直接执行 taos,应该就能正常连接到 TDegine 服务,进入到 taos shell 界面,示例如下:
```sql ```sql
$ taos $ taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases; taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB)| blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
========================================================================================================================================================================================================================= =========================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16| 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1| 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.001198s) Query OK, 2 row(s) in set (0.001198s)
taos> taos>
``` ```
在 cmd 下进入到 c:\TDengine 目录下直接执行 taos.exe,应该就能正常链接到 tdegine 服务,进入到 taos shell 界面,示例如下: 在 cmd 下进入到 c:\TDengine 目录下直接执行 taos.exe,应该就能正常链接到 tdegine 服务,进入到 taos shell 界面,示例如下:
```sql ```sql
C:\TDengine>taos C:\TDengine>taos
Welcome to the TDengine shell from Linux, Client Version:2.0.5.0 Welcome to the TDengine shell from Linux, Client Version:2.0.5.0
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved. Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
taos> show databases; taos> show databases;
name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status | name | created_time | ntables | vgroups | replica | quorum | days | keep1,keep2,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
=================================================================================================================================================================================================================================================================== ===================================================================================================================================================================================================================================================================
test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready | test | 2020-10-14 10:35:48.617 | 10 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready | log | 2020-10-12 09:08:21.651 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
Query OK, 2 row(s) in set (0.045000s) Query OK, 2 row(s) in set (0.045000s)
taos> taos>
``` ```
--- ---
sidebar_position: 1 sidebar_position: 1
sidebar_label: C/C++
title: C/C++ Connector title: C/C++ Connector
--- ---
......
--- ---
sidebar_position: 4 sidebar_position: 4
sidebar_label: Go
title: Go Connector title: Go Connector
--- ---
......
--- ---
sidebar_position: 2 sidebar_position: 2
sidebar_label: Java
title: Java Connector title: Java Connector
--- ---
...@@ -67,11 +68,11 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES( ...@@ -67,11 +68,11 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES(
| taos-jdbcdriver 版本 | TDengine 2.0.x.x 版本 | TDengine 2.2.x.x 版本 | TDengine 2.4.x.x 版本 | JDK 版本 | | taos-jdbcdriver 版本 | TDengine 2.0.x.x 版本 | TDengine 2.2.x.x 版本 | TDengine 2.4.x.x 版本 | JDK 版本 |
| -------------------- | --------------------- | --------------------- | --------------------- | -------- | | -------------------- | --------------------- | --------------------- | --------------------- | -------- |
| 2.0.38 | X | X | 2.4.0.12 以上 | 1.8.x | | 2.0.38 | X | X | 2.4.0.14 及以上 | 1.8.x |
| 2.0.37 | X | X | 2.4.0.6 以上 | 1.8.x | | 2.0.37 | X | X | 2.4.0.6 及以上 | 1.8.x |
| 2.0.36 | X | 2.2.2.11 以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x | | 2.0.36 | X | 2.2.2.11 及以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.35 | X | 2.2.2.11 以上 | 2.3.0.0 - 2.4.0.5 | 1.8.x | | 2.0.35 | X | 2.2.2.11 及以上 | 2.3.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.33 - 2.0.34 | 2.0.3.0 以上 | 2.2.0.0 以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x | | 2.0.33 - 2.0.34 | 2.0.3.0 及以上 | 2.2.0.0 及以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.31 - 2.0.32 | 2.1.3.0 - 2.1.7.7 | X | X | 1.8.x | | 2.0.31 - 2.0.32 | 2.1.3.0 - 2.1.7.7 | X | X | 1.8.x |
| 2.0.22 - 2.0.30 | 2.0.18.0 - 2.1.2.1 | X | X | 1.8.x | | 2.0.22 - 2.0.30 | 2.0.18.0 - 2.1.2.1 | X | X | 1.8.x |
| 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.4 | X | X | 1.8.x | | 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.4 | X | X | 1.8.x |
...@@ -170,7 +171,7 @@ Connection conn = DriverManager.getConnection(jdbcUrl); ...@@ -170,7 +171,7 @@ Connection conn = DriverManager.getConnection(jdbcUrl);
连接开启批量拉取方式: 连接开启批量拉取方式:
``` ```java
String url = "jdbc:TAOS-RS://taosdemo.com:6041/?user=root&password=taosdata";Properties properties = new Properties(); String url = "jdbc:TAOS-RS://taosdemo.com:6041/?user=root&password=taosdata";Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD, "true"); properties.setProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD, "true");
Connection connection = DriverManager.getConnection(url, properties); Connection connection = DriverManager.getConnection(url, properties);
......
--- ---
sidebar_position: 5 sidebar_position: 6
sidebar_label: Node.js
title: Node.js Connector title: Node.js Connector
--- ---
......
--- ---
sidebar_position: 3 sidebar_position: 3
sidebar_label: Python
title: Python Connector title: Python Connector
--- ---
......
--- ---
sidebar_position: 5
sidebar_label: Rust
title: Rust Connector title: Rust Connector
--- ---
......
...@@ -7,7 +7,6 @@ title: 文件目录结构 ...@@ -7,7 +7,6 @@ title: 文件目录结构
| 目录/文件 | 说明 | | 目录/文件 | 说明 |
| ------------------------- | -------------------------------------------------------------------- | | ------------------------- | -------------------------------------------------------------------- |
| /usr/local/taos/bin | TDengine 可执行文件目录。其中的执行文件都会软链接到/usr/bin 目录下。 | | /usr/local/taos/bin | TDengine 可执行文件目录。其中的执行文件都会软链接到/usr/bin 目录下。 |
| /usr/local/taos/connector | TDengine 各种连接器目录。 |
| /usr/local/taos/driver | TDengine 动态链接库目录。会软链接到/usr/lib 目录下。 | | /usr/local/taos/driver | TDengine 动态链接库目录。会软链接到/usr/lib 目录下。 |
| /usr/local/taos/examples | TDengine 各种语言应用示例目录。 | | /usr/local/taos/examples | TDengine 各种语言应用示例目录。 |
| /usr/local/taos/include | TDengine 对外提供的 C 语言接口的头文件。 | | /usr/local/taos/include | TDengine 对外提供的 C 语言接口的头文件。 |
...@@ -23,7 +22,13 @@ TDengine 的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下 ...@@ -23,7 +22,13 @@ TDengine 的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
- _taos_:TDengine Shell 可执行文件 - _taos_:TDengine Shell 可执行文件
- _taosdump_:数据导入导出工具 - _taosdump_:数据导入导出工具
- _taosBenchmark_:TDengine 测试工具 - _taosBenchmark_:TDengine 测试工具
- remove.sh:卸载 TDengine 的脚本,请谨慎执行,链接到/usr/bin 目录下的**rmtaos**命令。会删除 TDengine 的安装目录/usr/local/taos,但会保留/etc/taos、/var/lib/taos、/var/log/taos。 - _remove.sh_:卸载 TDengine 的脚本,请谨慎执行,链接到/usr/bin 目录下的**rmtaos**命令。会删除 TDengine 的安装目录/usr/local/taos,但会保留/etc/taos、/var/lib/taos、/var/log/taos。
- _taosadapter_: 提供 RESTful 服务和接受其他多种软件写入请求的服务端可执行文件
- _tarbitrator_: 提供双节点集群部署的仲裁功能
- _run_taosd_and_taosadapter.sh_:同时启动 taosd 和 taosAdapter 的脚本
- _TDinsight.sh_:用于下载 TDinsight 并安装的脚本
- _set_core.sh_:用于方便调试设置系统生成 core dump 文件的脚本
- _taosd-dump-cfg.gdb_:用于方便调试 taosd 的 gdb 执行脚本
:::note :::note
2.4.0.0 版本之后的 taosBenchmark 和 taosdump 需要安装独立安装包 taosTools。 2.4.0.0 版本之后的 taosBenchmark 和 taosdump 需要安装独立安装包 taosTools。
......
...@@ -36,7 +36,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -36,7 +36,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 安装 TDengine ### 安装 TDengine
从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。 从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。
## 数据链路设置 ## 数据链路设置
...@@ -52,7 +52,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -52,7 +52,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 配置 collectd ### 配置 collectd
/etc/collectd/collectd.conf 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `/etc/collectd/collectd.conf` 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
LoadPlugin network LoadPlugin network
...@@ -65,7 +65,7 @@ sudo systemctl start collectd ...@@ -65,7 +65,7 @@ sudo systemctl start collectd
### 配置 StatsD ### 配置 StatsD
config.js 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值: `config.js` 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 taosAdapter 配置的实际值:
``` ```
backends 部分添加 "./backends/repeater" backends 部分添加 "./backends/repeater"
......
...@@ -57,11 +57,11 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES( ...@@ -57,11 +57,11 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES(
| taos-jdbcdriver 版本 | TDengine 2.0.x.x 版本 | TDengine 2.2.x.x 版本 | TDengine 2.4.x.x 版本 | JDK 版本 | | taos-jdbcdriver 版本 | TDengine 2.0.x.x 版本 | TDengine 2.2.x.x 版本 | TDengine 2.4.x.x 版本 | JDK 版本 |
| -------------------- | --------------------- | --------------------- | --------------------- | -------- | | -------------------- | --------------------- | --------------------- | --------------------- | -------- |
| 2.0.38 | X | X | 2.4.0.12 以上 | 1.8.x | | 2.0.38 | X | X | 2.4.0.14 及以上 | 1.8.x |
| 2.0.37 | X | X | 2.4.0.6 以上 | 1.8.x | | 2.0.37 | X | X | 2.4.0.6 及以上 | 1.8.x |
| 2.0.36 | X | 2.2.2.11 以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x | | 2.0.36 | X | 2.2.2.11 及以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.35 | X | 2.2.2.11 以上 | 2.3.0.0 - 2.4.0.5 | 1.8.x | | 2.0.35 | X | 2.2.2.11 及以上 | 2.3.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.33 - 2.0.34 | 2.0.3.0 以上 | 2.2.0.0 以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x | | 2.0.33 - 2.0.34 | 2.0.3.0 及以上 | 2.2.0.0 及以上 | 2.4.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.31 - 2.0.32 | 2.1.3.0 - 2.1.7.7 | X | X | 1.8.x | | 2.0.31 - 2.0.32 | 2.1.3.0 - 2.1.7.7 | X | X | 1.8.x |
| 2.0.22 - 2.0.30 | 2.0.18.0 - 2.1.2.1 | X | X | 1.8.x | | 2.0.22 - 2.0.30 | 2.0.18.0 - 2.1.2.1 | X | X | 1.8.x |
| 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.4 | X | X | 1.8.x | | 2.0.12 - 2.0.21 | 2.0.8.0 - 2.0.17.4 | X | X | 1.8.x |
......
...@@ -1128,6 +1128,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 ...@@ -1128,6 +1128,8 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
返回结果数据类型:同应用的字段。 返回结果数据类型:同应用的字段。
应用字段:适合于除时间主列外的任何类型字段。 应用字段:适合于除时间主列外的任何类型字段。
支持的版本:2.6.0.x 之后的版本。
说明:由于返回数据量未知,考虑到内存因素,为了函数可以正常返回结果,建议不重复的数据量在10万级别,否则会报错。 说明:由于返回数据量未知,考虑到内存因素,为了函数可以正常返回结果,建议不重复的数据量在10万级别,否则会报错。
......
...@@ -33,7 +33,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如 ...@@ -33,7 +33,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
### 安装 TDengine ### 安装 TDengine
从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。 从涛思数据官网[下载](http://taosdata.com/cn/all-downloads/)页面下载最新 TDengine-server 2.3.0.0 或以上版本安装。
## 数据链路设置 ## 数据链路设置
......
...@@ -56,7 +56,7 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES( ...@@ -56,7 +56,7 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('beijing') VALUES(
| taos-jdbcdriver version | TDengine 2.0.x.x version | TDengine 2.2.x.x version | TDengine 2.4.x.x version | JDK version | | taos-jdbcdriver version | TDengine 2.0.x.x version | TDengine 2.2.x.x version | TDengine 2.4.x.x version | JDK version |
| ----------------------- | ------------------------ | ------------------------ | ------------------------ | ----------- | | ----------------------- | ------------------------ | ------------------------ | ------------------------ | ----------- |
| 2.0.38 | X | X | 2.4.0.12 or later | 1.8.x | | 2.0.38 | X | X | 2.4.0.14 or later | 1.8.x |
| 2.0.37 | X | X | 2.4.0.6 or later | 1.8.x | | 2.0.37 | X | X | 2.4.0.6 or later | 1.8.x |
| 2.0.36 | X | 2.2.2.11 or later | 2.4.0.0 - 2.4.0.5 | 1.8.x | | 2.0.36 | X | 2.2.2.11 or later | 2.4.0.0 - 2.4.0.5 | 1.8.x |
| 2.0.35 | X | 2.2.2.11 or later | 2.3.0.0 - 2.4.0.5 | 1.8.x | | 2.0.35 | X | 2.2.2.11 or later | 2.3.0.0 - 2.4.0.5 | 1.8.x |
......
...@@ -282,6 +282,8 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) { ...@@ -282,6 +282,8 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) {
return TSDB_BINARY_OP_DIVIDE; return TSDB_BINARY_OP_DIVIDE;
case TK_REM: case TK_REM:
return TSDB_BINARY_OP_REMAINDER; return TSDB_BINARY_OP_REMAINDER;
case TK_BITAND:
return TSDB_BINARY_OP_BITAND;
case TK_LIKE: case TK_LIKE:
return TSDB_RELATION_LIKE; return TSDB_RELATION_LIKE;
case TK_MATCH: case TK_MATCH:
...@@ -10720,6 +10722,23 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -10720,6 +10722,23 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
} }
} }
if (pSqlExpr->tokenId == TK_BITAND && pSqlExpr->pLeft != NULL && pSqlExpr->pRight != NULL) {
// for example: col type is "bool" but expr "col & 1" received
uint8_t colType = pLeft->pSchema->type;
SStrToken *exprToken = &pSqlExpr->pRight->exprToken;
if (pSqlExpr->pLeft->type == SQL_NODE_TABLE_COLUMN && pSqlExpr->pRight->type == SQL_NODE_VALUE) {
if (colType == TSDB_DATA_TYPE_BOOL) {
if ((exprToken->n != 4 || strncasecmp(exprToken->z, "true", 4)) && (exprToken->n != 5 || strncasecmp(exprToken->z, "false", 5))) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (IS_SIGNED_NUMERIC_TYPE(colType) || IS_UNSIGNED_NUMERIC_TYPE(colType)) {
if ((exprToken->n == 4 && strncasecmp(exprToken->z, "true", 4) == 0) || (exprToken->n == 5 || strncasecmp(exprToken->z, "false", 5) == 0)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
}
}
if (pSqlExpr->pRight != NULL) { if (pSqlExpr->pRight != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid); int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
...@@ -10757,9 +10776,11 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -10757,9 +10776,11 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
if (pLeft->_node.optr == TSDB_RELATION_ARROW){ if (pLeft->_node.optr == TSDB_RELATION_ARROW){
pLeft = pLeft->_node.pLeft; pLeft = pLeft->_node.pLeft;
} }
if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->nodeType == TSQL_NODE_COL && if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->nodeType == TSQL_NODE_COL) {
(pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL || pLeft->pSchema->type == TSDB_DATA_TYPE_JSON)) { if (((*pExpr)->_node.optr != TSDB_BINARY_OP_BITAND && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) ||
return TSDB_CODE_TSC_INVALID_OPERATION; pLeft->pSchema->type == TSDB_DATA_TYPE_JSON) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} }
} }
} }
......
...@@ -126,6 +126,9 @@ _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) { ...@@ -126,6 +126,9 @@ _arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index); typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index);
void* getVectorValueAddr_BOOL(void *src, int32_t index) {
return (void*)((bool *)src + index);
}
void* getVectorValueAddr_TINYINT(void *src, int32_t index) { void* getVectorValueAddr_TINYINT(void *src, int32_t index) {
return (void*)((int8_t *)src + index); return (void*)((int8_t *)src + index);
} }
...@@ -159,7 +162,9 @@ void* getVectorValueAddr_DOUBLE(void *src, int32_t index) { ...@@ -159,7 +162,9 @@ void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) { _arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
_arithmetic_getVectorValueAddr_fn_t p = NULL; _arithmetic_getVectorValueAddr_fn_t p = NULL;
if(srcType==TSDB_DATA_TYPE_TINYINT) { if (srcType == TSDB_DATA_TYPE_BOOL) {
p = getVectorValueAddr_BOOL;
}else if(srcType == TSDB_DATA_TYPE_TINYINT) {
p = getVectorValueAddr_TINYINT; p = getVectorValueAddr_TINYINT;
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) { }else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
p = getVectorValueAddr_UTINYINT; p = getVectorValueAddr_UTINYINT;
...@@ -469,6 +474,271 @@ void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right, ...@@ -469,6 +474,271 @@ void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right,
} }
} }
void vectorBitand(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
int32_t i = (_ord == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
int32_t step = (_ord == TSDB_ORDER_ASC) ? 1 : -1;
char *output = out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
if (len1 == (len2)) {
for (; i >= 0 && i < (len2); i += step) {
if (isNull(getVectorValueAddrFnLeft(left, i), _left_type) || isNull(getVectorValueAddrFnRight(right, i), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*((bool *) left + i)) & (*((bool *) right + i));
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*((int8_t *) left + i)) & (*((int8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*((int16_t *) left + i)) & (*((int16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*((int32_t *) left + i)) & (*((int32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*((int64_t *) left + i)) & (*((int64_t *) right + i));
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*((uint8_t *) left + i)) & (*((uint8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*((uint16_t *) left + i)) & (*((uint16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*((uint32_t *) left + i)) & (*((uint32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*((uint64_t *) left + i)) & (*((uint64_t *) right + i));
output += sizeof(int64_t);
break;
}
}
} else if (len1 == 1) {
for (; i >= 0 && i < (len2); i += step) {
if (isNull(getVectorValueAddrFnLeft(left, 0), _left_type) || isNull(getVectorValueAddrFnRight(right, i), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*(bool *) left) & (*((bool *) right + i));
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*(int8_t *) left) & (*((int8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*(int16_t *) left) & (*((int16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*(int32_t *) left) & (*((int32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*(int64_t *) left) & (*((int64_t *) right + i));
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*(uint8_t *) left) & (*((uint8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*(uint16_t *) left) & (*((uint16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*(uint32_t *) left) & (*((uint32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*(uint64_t *) left) & (*((uint64_t *) right + i));
output += sizeof(int64_t);
break;
}
}
} else if ((len2) == 1) {
for (; i >= 0 && i < len1; i += step) {
if (isNull(getVectorValueAddrFnLeft(left, i), _left_type) || isNull(getVectorValueAddrFnRight(right, 0), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*((bool *) left + i)) & (*(bool *) right);
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*((int8_t *) left + i)) & (*(int8_t *) right);
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*((int16_t *) left + i)) & (*(int16_t *) right);
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*((int32_t *) left + i)) & (*(int32_t *) right);
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*((int64_t *) left + i)) & (*(int64_t *) right);
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*((uint8_t *) left + i)) & (*(uint8_t *) right);
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*((uint16_t *) left + i)) & (*(uint16_t *) right);
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*((uint32_t *) left + i)) & (*(uint32_t *) right);
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*((uint64_t *) left + i)) & (*(uint64_t *) right);
output += sizeof(int64_t);
break;
}
}
}
}
_arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) { _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
switch (arithmeticOptr) { switch (arithmeticOptr) {
case TSDB_BINARY_OP_ADD: case TSDB_BINARY_OP_ADD:
...@@ -481,6 +751,8 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) { ...@@ -481,6 +751,8 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
return vectorDivide; return vectorDivide;
case TSDB_BINARY_OP_REMAINDER: case TSDB_BINARY_OP_REMAINDER:
return vectorRemainder; return vectorRemainder;
case TSDB_BINARY_OP_BITAND:
return vectorBitand;
default: default:
assert(0); assert(0);
return NULL; return NULL;
......
...@@ -107,11 +107,13 @@ int32_t exprTreeValidateFunctionNode(char* msgbuf, tExprNode *pExpr) { ...@@ -107,11 +107,13 @@ int32_t exprTreeValidateFunctionNode(char* msgbuf, tExprNode *pExpr) {
} }
int32_t exprTreeValidateExprNode(tExprNode *pExpr) { int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
int16_t leftType = pExpr->_node.pLeft->resultType;
int16_t rightType = pExpr->_node.pRight->resultType;
int16_t resultType = leftType;
if (pExpr->_node.optr == TSDB_BINARY_OP_ADD || pExpr->_node.optr == TSDB_BINARY_OP_SUBTRACT || if (pExpr->_node.optr == TSDB_BINARY_OP_ADD || pExpr->_node.optr == TSDB_BINARY_OP_SUBTRACT ||
pExpr->_node.optr == TSDB_BINARY_OP_MULTIPLY || pExpr->_node.optr == TSDB_BINARY_OP_DIVIDE || pExpr->_node.optr == TSDB_BINARY_OP_MULTIPLY || pExpr->_node.optr == TSDB_BINARY_OP_DIVIDE ||
pExpr->_node.optr == TSDB_BINARY_OP_REMAINDER) { pExpr->_node.optr == TSDB_BINARY_OP_REMAINDER) {
int16_t leftType = pExpr->_node.pLeft->resultType;
int16_t rightType = pExpr->_node.pRight->resultType;
if ((!IS_NUMERIC_TYPE(leftType) && !IS_TIMESTAMP_TYPE(leftType)) || if ((!IS_NUMERIC_TYPE(leftType) && !IS_TIMESTAMP_TYPE(leftType)) ||
(!IS_NUMERIC_TYPE(rightType) && !IS_TIMESTAMP_TYPE(rightType))) { (!IS_NUMERIC_TYPE(rightType) && !IS_TIMESTAMP_TYPE(rightType))) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
...@@ -133,6 +135,171 @@ int32_t exprTreeValidateExprNode(tExprNode *pExpr) { ...@@ -133,6 +135,171 @@ int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes; pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (pExpr->_node.optr == TSDB_BINARY_OP_BITAND) {
if ((leftType != TSDB_DATA_TYPE_BOOL && !IS_SIGNED_NUMERIC_TYPE(leftType) && !IS_UNSIGNED_NUMERIC_TYPE(leftType)) ||
(rightType != TSDB_DATA_TYPE_BOOL && !IS_SIGNED_NUMERIC_TYPE(rightType) && !IS_UNSIGNED_NUMERIC_TYPE(rightType)))
{
return TSDB_CODE_TSC_INVALID_OPERATION;
}
uint8_t schemaType;
// now leftType and rightType are both numeric
if (pExpr->_node.pLeft->nodeType == TSQL_NODE_COL && pExpr->_node.pRight->nodeType == TSQL_NODE_COL) {
if (leftType != rightType) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (pExpr->_node.pLeft->nodeType == TSQL_NODE_COL) {
if (pExpr->_node.pRight->nodeType != TSQL_NODE_VALUE) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else {
schemaType = pExpr->_node.pLeft->pSchema->type;
int64_t sVal = pExpr->_node.pRight->pVal->i64;
uint64_t uVal = pExpr->_node.pRight->pVal->u64;
switch (schemaType) {
case TSDB_DATA_TYPE_BOOL:
if ((pExpr->_node.pRight->pVal->nType != TSDB_DATA_TYPE_BOOL) ||
(pExpr->_node.pRight->pVal->i64 != 0 &&
pExpr->_node.pRight->pVal->i64 != 1 &&
pExpr->_node.pRight->pVal->i64 != TSDB_DATA_BOOL_NULL))
{
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_TINYINT:
if (sVal < -128 || sVal > 127) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_SMALLINT:
if (sVal < -32768 || sVal > 32767) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_INT:
if (sVal < INT32_MIN || sVal > INT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_BIGINT:
if (sVal < INT64_MIN || sVal > INT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UTINYINT:
if (uVal > 255) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_USMALLINT:
if (uVal > 65535) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UINT:
if (uVal > UINT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UBIGINT:
if (uVal > UINT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
}
pExpr->_node.pRight->pSchema->type = schemaType;
pExpr->_node.pRight->pVal->nType = schemaType;
pExpr->_node.pRight->resultType = schemaType;
pExpr->_node.pRight->resultBytes = tDataTypes[schemaType].bytes;
}
} else {
if (pExpr->_node.pLeft->nodeType != TSQL_NODE_VALUE) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else {
schemaType = pExpr->_node.pRight->pSchema->type;
int64_t sVal = pExpr->_node.pLeft->pVal->i64;
uint64_t uVal = pExpr->_node.pLeft->pVal->u64;
switch (schemaType) {
case TSDB_DATA_TYPE_BOOL:
if ((pExpr->_node.pLeft->pVal->nType != TSDB_DATA_TYPE_BOOL) ||
(pExpr->_node.pLeft->pVal->i64 != 0 &&
pExpr->_node.pLeft->pVal->i64 != 1 &&
pExpr->_node.pLeft->pVal->i64 != TSDB_DATA_BOOL_NULL))
{
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_TINYINT:
if (sVal < -128 || sVal > 127) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_SMALLINT:
if (sVal < -32768 || sVal > 32767) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 2;
break;
case TSDB_DATA_TYPE_INT:
if (sVal < INT32_MIN || sVal > INT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 4;
break;
case TSDB_DATA_TYPE_BIGINT:
if (sVal < INT64_MIN || sVal > INT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 8;
break;
case TSDB_DATA_TYPE_UTINYINT:
if (uVal > 255) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_USMALLINT:
if (uVal > 65535) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 2;
break;
case TSDB_DATA_TYPE_UINT:
if (uVal > UINT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 4;
break;
case TSDB_DATA_TYPE_UBIGINT:
if (uVal > UINT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 8;
break;
}
pExpr->_node.pLeft->pSchema->type = schemaType;
pExpr->_node.pLeft->pVal->nType = schemaType;
pExpr->_node.pLeft->resultType = schemaType;
pExpr->_node.pLeft->resultBytes = tDataTypes[schemaType].bytes;
}
resultType = schemaType;
}
if (resultType == TSDB_DATA_TYPE_BOOL) {
pExpr->resultType = TSDB_DATA_TYPE_BOOL;
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
} else {
pExpr->resultType = resultType;
pExpr->resultBytes = tDataTypes[resultType].bytes;
}
return TSDB_CODE_SUCCESS;
} else { } else {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -536,7 +703,11 @@ void exprTreeExprNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOperandI ...@@ -536,7 +703,11 @@ void exprTreeExprNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOperandI
if(leftType == TSDB_DATA_TYPE_TIMESTAMP || rightType == TSDB_DATA_TYPE_TIMESTAMP) { if(leftType == TSDB_DATA_TYPE_TIMESTAMP || rightType == TSDB_DATA_TYPE_TIMESTAMP) {
output->type = TSDB_DATA_TYPE_BIGINT; output->type = TSDB_DATA_TYPE_BIGINT;
} else { } else {
output->type = TSDB_DATA_TYPE_DOUBLE; if (pExpr->_node.optr == TSDB_BINARY_OP_BITAND) {
output->type = leftType; // rightType must be the same as leftType
} else {
output->type = TSDB_DATA_TYPE_DOUBLE;
}
} }
output->bytes = tDataTypes[output->type].bytes; output->bytes = tDataTypes[output->type].bytes;
......
...@@ -183,10 +183,11 @@ do { \ ...@@ -183,10 +183,11 @@ do { \
#define TSDB_BINARY_OP_MULTIPLY 32 #define TSDB_BINARY_OP_MULTIPLY 32
#define TSDB_BINARY_OP_DIVIDE 33 #define TSDB_BINARY_OP_DIVIDE 33
#define TSDB_BINARY_OP_REMAINDER 34 #define TSDB_BINARY_OP_REMAINDER 34
#define TSDB_BINARY_OP_BITAND 35
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN)) #define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER)) #define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_BITAND))
#define TS_PATH_DELIMITER_LEN 1 #define TS_PATH_DELIMITER_LEN 1
......
...@@ -87,6 +87,7 @@ TAOS *shellInit(SShellArguments *_args) { ...@@ -87,6 +87,7 @@ TAOS *shellInit(SShellArguments *_args) {
} }
if (con == NULL) { if (con == NULL) {
printf("\033[31mfailed to connect to db, reason:%s\033[0m\n", taos_errstr(con));
fflush(stdout); fflush(stdout);
return con; return con;
} }
......
Subproject commit bae99633455cde5a4fd6435efe65cf24f13b805e Subproject commit bf6c766986c61ff4fc80421fdea682a8fd4b5b32
...@@ -801,6 +801,7 @@ expr(A) ::= expr(X) MINUS expr(Y). {A = tSqlExprCreate(X, Y, TK_MINUS); } ...@@ -801,6 +801,7 @@ expr(A) ::= expr(X) MINUS expr(Y). {A = tSqlExprCreate(X, Y, TK_MINUS); }
expr(A) ::= expr(X) STAR expr(Y). {A = tSqlExprCreate(X, Y, TK_STAR); } expr(A) ::= expr(X) STAR expr(Y). {A = tSqlExprCreate(X, Y, TK_STAR); }
expr(A) ::= expr(X) SLASH expr(Y). {A = tSqlExprCreate(X, Y, TK_DIVIDE);} expr(A) ::= expr(X) SLASH expr(Y). {A = tSqlExprCreate(X, Y, TK_DIVIDE);}
expr(A) ::= expr(X) REM expr(Y). {A = tSqlExprCreate(X, Y, TK_REM); } expr(A) ::= expr(X) REM expr(Y). {A = tSqlExprCreate(X, Y, TK_REM); }
expr(A) ::= expr(X) BITAND expr(Y). {A = tSqlExprCreate(X, Y, TK_BITAND);}
// like expression // like expression
expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); } expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); }
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册