diff --git a/docs/zh/05-get-started/01-docker.md b/docs/zh/05-get-started/01-docker.md
index 14db62218fc95a05bbb0e773303d00621529111a..2edabad3c950eb7ef1361221eef56bed1046909a 100644
--- a/docs/zh/05-get-started/01-docker.md
+++ b/docs/zh/05-get-started/01-docker.md
@@ -111,7 +111,7 @@ TDengine REST API 详情请参考[官方文档](/reference/rest-api/)。
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能。
- taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照 [taosBenchmark 参考手册](../reference/taosbenchmark)。
+ taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照 [taosBenchmark 参考手册](../../reference/taosbenchmark)。
## 体验查询
diff --git a/docs/zh/05-get-started/03-package.md b/docs/zh/05-get-started/03-package.md
index 6ac7567a057c2bc7c38b9776205a2aa2f50a11c3..6dbf74f8bcc3442018d259c9781999182fdc579d 100644
--- a/docs/zh/05-get-started/03-package.md
+++ b/docs/zh/05-get-started/03-package.md
@@ -245,7 +245,7 @@ select * from t;
Query OK, 2 row(s) in set (0.003128s)
```
-除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [这里](../reference/taos-shell/)
+除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在 Linux 或 Windows 机器上运行,更多细节请参考 [这里](../../reference/taos-shell/)
## 使用 taosBenchmark 体验写入速度
diff --git a/docs/zh/12-taos-sql/06-select.md b/docs/zh/12-taos-sql/06-select.md
index 84fcda232db1bda567e810bb014a99c8dbc25328..75f149d0aeba924635bbccd6607ed9d820155a8d 100644
--- a/docs/zh/12-taos-sql/06-select.md
+++ b/docs/zh/12-taos-sql/06-select.md
@@ -218,7 +218,7 @@ GROUP BY 子句中的表达式可以包含表或视图中的任何列,这些
PARTITION BY 子句是 TDengine 特色语法,按 part_list 对数据进行切分,在每个切分的分片中进行计算。
-详见 [TDengine 特色查询](./distinguished)
+详见 [TDengine 特色查询](../distinguished)
## ORDER BY
diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md
index 876aaa553e2e67e8fddc3eb63ac277e2ed3857cc..f4d45558329f381e4fef2c6953bb6145d3cd3649 100644
--- a/docs/zh/12-taos-sql/10-function.md
+++ b/docs/zh/12-taos-sql/10-function.md
@@ -16,15 +16,15 @@ toc_max_heading_level: 4
SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的绝对值
+**功能说明**:获得指定字段的绝对值。
-**返回结果类型**:如果输入值为整数,输出值是 UBIGINT 类型。如果输入值是 FLOAT/DOUBLE 数据类型,输出值是 DOUBLE 数据类型。
+**返回结果类型**:与指定字段的原始数据类型一致。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -34,15 +34,15 @@ SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的反余弦结果
+**功能说明**:获得指定字段的反余弦结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -52,15 +52,15 @@ SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的反正弦结果
+**功能说明**:获得指定字段的反正弦结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -71,15 +71,15 @@ SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的反正切结果
+**功能说明**:获得指定字段的反正切结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -90,20 +90,17 @@ SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:获得指定列的向上取整数的结果。
+**功能说明**:获得指定字段的向上取整数的结果。
-**返回结果类型**:与指定列的原始数据类型一致。例如,如果指定列的原始数据类型为 Float,那么返回的数据类型也为 Float;如果指定列的原始数据类型为 Double,那么返回的数据类型也为 Double。
+**返回结果类型**:与指定字段的原始数据类型一致。
**适用数据类型**:数值类型。
-**适用于**: 普通表、超级表。
+**适用于**: 表和超级表。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**使用说明**:
-
-- 支持 +、-、\*、/ 运算,如 ceil(col1) + ceil(col2)。
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
+**使用说明**: 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
#### COS
@@ -111,15 +108,15 @@ SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的余弦结果
+**功能说明**:获得指定字段的余弦结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -129,24 +126,24 @@ SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:获得指定列的向下取整数的结果。
+**功能说明**:获得指定字段的向下取整数的结果。
其他使用说明参见 CEIL 函数描述。
#### LOG
```sql
-SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LOG(field_name[, base]) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列对于底数 base 的对数
+**功能说明**:获得指定字段对于底数 base 的对数。如果 base 参数省略,则返回指定字段的自然对数值。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -157,15 +154,15 @@ SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的指数为 power 的幂
+**功能说明**:获得指定字段的指数为 power 的幂。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -176,7 +173,7 @@ SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:获得指定列的四舍五入的结果。
+**功能说明**:获得指定字段的四舍五入的结果。
其他使用说明参见 CEIL 函数描述。
@@ -186,15 +183,15 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的正弦结果
+**功能说明**:获得指定字段的正弦结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -204,15 +201,15 @@ SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的平方根
+**功能说明**:获得指定字段的平方根。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -222,15 +219,15 @@ SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列的正切结果
+**功能说明**:获得指定字段的正切结果。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:DOUBLE。
**适用数据类型**:数值类型。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
@@ -246,13 +243,13 @@ SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:以字符计数的字符串长度。
-**返回结果类型**:INT。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:BIGINT。
-**适用数据类型**:VARCHAR, NCHAR
+**适用数据类型**:VARCHAR, NCHAR。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### CONCAT
@@ -262,13 +259,13 @@ SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHER
**功能说明**:字符串连接函数。
-**返回结果类型**:如果所有参数均为 VARCHAR 类型,则结果类型为 VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:如果所有参数均为 VARCHAR 类型,则结果类型为 VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果参数包含NULL值,则输出值为NULL。
**适用数据类型**:VARCHAR, NCHAR。 该函数最小参数个数为2个,最大参数个数为8个。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### CONCAT_WS
@@ -279,13 +276,13 @@ SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | st
**功能说明**:带分隔符的字符串连接函数。
-**返回结果类型**:如果所有参数均为VARCHAR类型,则结果类型为VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果输入值为NULL,输出值为NULL。如果separator值不为NULL,其他输入为NULL,输出为空串。
+**返回结果类型**:如果所有参数均为VARCHAR类型,则结果类型为VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果参数包含NULL值,则输出值为NULL。
**适用数据类型**:VARCHAR, NCHAR。 该函数最小参数个数为3个,最大参数个数为9个。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### LENGTH
@@ -296,13 +293,13 @@ SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:以字节计数的字符串长度。
-**返回结果类型**:INT。
+**返回结果类型**:BIGINT。
**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### LOWER
@@ -313,13 +310,13 @@ SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:将字符串参数值转换为全小写字母。
-**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:与输入字段的原始类型相同。
-**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
+**适用数据类型**:VARCHAR, NCHAR。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### LTRIM
@@ -330,13 +327,13 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:返回清除左边空格后的字符串。
-**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:与输入字段的原始类型相同。
-**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
+**适用数据类型**:VARCHAR, NCHAR。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### RTRIM
@@ -347,13 +344,13 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:返回清除右边空格后的字符串。
-**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:与输入字段的原始类型相同。
-**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
+**适用数据类型**:VARCHAR, NCHAR。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### SUBSTR
@@ -362,15 +359,15 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。
+**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。如果输入参数 len 被忽略,返回的子串包含从 pos 开始的整个字串。
-**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:与输入字段的原始类型相同。
-**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。输入参数pos可以为正数,也可以为负数。如果pos是正数,表示开始位置从字符串开头正数计算。如果pos为负数,表示开始位置从字符串结尾倒数计算。如果输入参数len被忽略,返回的子串包含从pos开始的整个字串。
+**适用数据类型**:VARCHAR, NCHAR。输入参数 pos 可以为正数,也可以为负数。如果 pos 是正数,表示开始位置从字符串开头正数计算。如果 pos 为负数,表示开始位置从字符串结尾倒数计算。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
#### UPPER
@@ -381,13 +378,13 @@ SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:将字符串参数值转换为全大写字母。
-**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
+**返回结果类型**:与输入字段的原始类型相同。
-**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
+**适用数据类型**:VARCHAR, NCHAR。
**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表和超级表
+**适用于**: 表和超级表。
### 转换函数
@@ -400,16 +397,19 @@ SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:数据类型转换函数,输入参数 expression 支持普通列、常量、标量函数及它们之间的四则运算,只适用于 select 子句中。
+**功能说明**:数据类型转换函数,返回 expression 转换为 type_name 指定的类型后的结果。只适用于 select 子句中。
+
+**返回结果类型**:CAST 中指定的类型(type_name)。
-**返回结果类型**:CAST 中指定的类型(type_name),可以是 BIGINT、BIGINT UNSIGNED、BINARY、VARCHAR、NCHAR和TIMESTAMP。
+**适用数据类型**:输入参数 expression 的类型可以是BLOB、MEDIUMBLOB和JSON外的所有类型。
-**适用数据类型**:输入参数 expression 的类型可以是BLOB、MEDIUMBLOB和JSON外的所有类型
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+**适用于**: 表和超级表。
**使用说明**:
- 对于不能支持的类型转换会直接报错。
-- 如果输入值为NULL则输出值也为NULL。
- 对于类型支持但某些值无法正确转换的情况对应的转换后的值以转换函数输出为准。目前可能遇到的几种情况:
1)字符串类型转换数值类型时可能出现的无效字符情况,例如"a"可能转为0,但不会报错。
2)转换到数值类型时,数值大于type_name可表示的范围时,则会溢出,但不会报错。
@@ -418,20 +418,23 @@ SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
#### TO_ISO8601
```sql
-SELECT TO_ISO8601(ts_val | ts_col) FROM { tb_name | stb_name } [WHERE clause];
+SELECT TO_ISO8601(ts[, timezone]) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:将 UNIX 时间戳转换成为 ISO8601 标准的日期时间格式,并附加客户端时区信息。
+**功能说明**:将 UNIX 时间戳转换成为 ISO8601 标准的日期时间格式,并附加时区信息。timezone 参数允许用户为输出结果指定附带任意时区信息。如果 timezone 参数省略,输出结果附带当前客户端的系统时区信息。
**返回结果数据类型**:VARCHAR 类型。
-**适用数据类型**:UNIX 时间戳常量或是 TIMESTAMP 类型的列
+**适用数据类型**:INTEGER, TIMESTAMP。
-**适用于**:表、超级表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+**适用于**: 表和超级表。
**使用说明**:
-- 如果输入是 UNIX 时间戳常量,返回格式精度由时间戳的位数决定;
+- timezone 参数允许输入的时区格式为: [z/Z, +/-hhmm, +/-hh, +/-hh:mm]。例如,TO_ISO8601(1, "+00:00")。
+- 如果输入是表示 UNIX 时间戳的整形,返回格式精度由时间戳的位数决定;
- 如果输入是 TIMSTAMP 类型的列,返回格式的时间戳精度与当前 DATABASE 设置的时间精度一致。
@@ -443,32 +446,34 @@ SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
**功能说明**: 将字符串常量转换为 JSON 类型。
-**返回结果数据类型**: JSON
+**返回结果数据类型**: JSON。
**适用数据类型**: JSON 字符串,形如 '{ "literal" : literal }'。'{}'表示空值。键必须为字符串字面量,值可以为数值字面量、字符串字面量、布尔字面量或空值字面量。str_literal中不支持转义符。
-**适用于**: 表和超级表
-
**嵌套子查询支持**:适用于内层查询和外层查询。
+**适用于**: 表和超级表。
+
#### TO_UNIXTIMESTAMP
```sql
-SELECT TO_UNIXTIMESTAMP(datetime_string | ts_col) FROM { tb_name | stb_name } [WHERE clause];
+SELECT TO_UNIXTIMESTAMP(datetime_string) FROM { tb_name | stb_name } [WHERE clause];
```
**功能说明**:将日期时间格式的字符串转换成为 UNIX 时间戳。
-**返回结果数据类型**:长整型 INT64。
+**返回结果数据类型**:BIGINT。
-**应用字段**:字符串常量或是 VARCHAR/NCHAR 类型的列。
+**应用字段**:VARCHAR, NCHAR。
-**适用于**:表、超级表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+**适用于**:表和超级表。
**使用说明**:
-- 输入的日期时间字符串须符合 ISO8601/RFC3339 标准,无法转换的字符串格式将返回 0。
+- 输入的日期时间字符串须符合 ISO8601/RFC3339 标准,无法转换的字符串格式将返回 NULL。
- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
@@ -488,11 +493,13 @@ INSERT INTO tb_name VALUES (NOW(), ...);
**功能说明**:返回客户端当前系统时间。
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**返回结果数据类型**:TIMESTAMP。
**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
+
+**嵌套子查询支持**:适用于内层查询和外层查询。
**使用说明**:
@@ -504,40 +511,42 @@ INSERT INTO tb_name VALUES (NOW(), ...);
#### TIMEDIFF
```sql
-SELECT TIMEDIFF(ts_val1 | datetime_string1 | ts_col1, ts_val2 | datetime_string2 | ts_col2 [, time_unit]) FROM { tb_name | stb_name } [WHERE clause];
+SELECT TIMEDIFF(ts | datetime_string1, ts | datetime_string2 [, time_unit]) FROM { tb_name | stb_name } [WHERE clause];
```
**功能说明**:计算两个时间戳之间的差值,并近似到时间单位 time_unit 指定的精度。
-**返回结果数据类型**:长整型 INT64。
+**返回结果数据类型**:BIGINT。输入包含不符合时间日期格式字符串则返回 NULL。
-**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
+**应用字段**:表示 UNIX 时间戳的 BIGINT, TIMESTAMP 类型,或符合日期时间格式的 VARCHAR, NCHAR 类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
+
+**嵌套子查询支持**:适用于内层查询和外层查询。
**使用说明**:
- 支持的时间单位 time_unit 如下:
- 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
+ 1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
- 如果时间单位 time_unit 未指定, 返回的时间差值精度与当前 DATABASE 设置的时间精度一致。
#### TIMETRUNCATE
```sql
-SELECT TIMETRUNCATE(ts_val | datetime_string | ts_col, time_unit) FROM { tb_name | stb_name } [WHERE clause];
+SELECT TIMETRUNCATE(ts | datetime_string , time_unit) FROM { tb_name | stb_name } [WHERE clause];
```
**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**返回结果数据类型**:TIMESTAMP。
-**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
+**应用字段**:表示 UNIX 时间戳的 BIGINT, TIMESTAMP 类型,或符合日期时间格式的 VARCHAR, NCHAR 类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
**使用说明**:
- 支持的时间单位 time_unit 如下:
- 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
+ 1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
@@ -549,11 +558,11 @@ SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
**功能说明**:返回客户端当前时区信息。
-**返回结果数据类型**:VARCHAR 类型。
+**返回结果数据类型**:VARCHAR。
**应用字段**:无
-**适用于**:表、超级表。
+**适用于**:表和超级表。
#### TODAY
@@ -566,11 +575,11 @@ INSERT INTO tb_name VALUES (TODAY(), ...);
**功能说明**:返回客户端当日零时的系统时间。
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**返回结果数据类型**:TIMESTAMP。
**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
**使用说明**:
@@ -591,13 +600,13 @@ TDengine 支持针对数据的聚合查询。提供如下聚合函数。
SELECT AVG(field_name) FROM tb_name [WHERE clause];
```
-**功能说明**:统计表/超级表中某列的平均值。
+**功能说明**:统计指定字段的平均值。
-**返回数据类型**:双精度浮点数 Double。
+**返回数据类型**:DOUBLE。
**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
### COUNT
@@ -606,19 +615,18 @@ SELECT AVG(field_name) FROM tb_name [WHERE clause];
SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
```
-**功能说明**:统计表/超级表中记录行数或某列的非空值个数。
+**功能说明**:统计指定字段的记录行数。
-**返回数据类型**:长整型 INT64。
+**返回数据类型**:BIGINT。
-**适用数据类型**:应用全部字段。
+**适用数据类型**:全部类型字段。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
**使用说明**:
- 可以使用星号(\*)来替代具体的字段,使用星号(\*)返回全部记录数量。
-- 针对同一表的(不包含 NULL 值)字段查询结果均相同。
-- 如果统计对象是具体的列,则返回该列中非 NULL 值的记录数量。
+- 如果统计字段是具体的列,则返回该列中非 NULL 值的记录数量。
### ELAPSED
@@ -629,17 +637,18 @@ SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE
**功能说明**:elapsed函数表达了统计周期内连续的时间长度,和twa函数配合使用可以计算统计曲线下的面积。在通过INTERVAL子句指定窗口的情况下,统计在给定时间范围内的每个窗口内有数据覆盖的时间范围;如果没有INTERVAL子句,则返回整个给定时间范围内的有数据覆盖的时间范围。注意,ELAPSED返回的并不是时间范围的绝对值,而是绝对值除以time_unit所得到的单位个数。
-**返回结果类型**:Double
+**返回结果类型**:DOUBLE。
-**适用数据类型**:Timestamp类型
+**适用数据类型**:TIMESTAMP。
**支持的版本**:2.6.0.0 及以后的版本。
**适用于**: 表,超级表,嵌套查询的外层查询
**说明**:
-- field_name参数只能是表的第一列,即timestamp主键列。
-- 按time_unit参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit参数未指定时,以数据库的时间分辨率为时间单位。
+- field_name参数只能是表的第一列,即 TIMESTAMP 类型的主键列。
+- 按time_unit参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit 参数未指定时,以数据库的时间分辨率为时间单位。支持的时间单位 time_unit 如下:
+ 1b(纳秒), 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天), 1w(周)。
- 可以和interval组合使用,返回每个时间窗口的时间戳差值。需要特别注意的是,除第一个时间窗口和最后一个时间窗口外,中间窗口的时间戳差值均为窗口长度。
- order by asc/desc不影响差值的计算结果。
- 对于超级表,需要和group by tbname子句组合使用,不可以直接使用。
@@ -668,11 +677,11 @@ SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause]
SELECT MODE(field_name) FROM tb_name [WHERE clause];
```
-**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出空。
+**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出NULL。
-**返回数据类型**:同应用的字段。
+**返回数据类型**:与输入数据类型一致。
-**适用数据类型**: 数值类型。
+**适用数据类型**:全部类型字段。
**适用于**:表和超级表。
@@ -683,11 +692,11 @@ SELECT MODE(field_name) FROM tb_name [WHERE clause];
SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:统计表/超级表中某列的最大值和最小值之差。
+**功能说明**:统计表中某列的最大值和最小值之差。
-**返回数据类型**:双精度浮点数。
+**返回数据类型**:DOUBLE。
-**适用数据类型**:数值类型或TIMESTAMP类型。
+**适用数据类型**:INTEGER, TIMESTAMP。
**适用于**:表和超级表。
@@ -700,7 +709,7 @@ SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
**功能说明**:统计表中某列的均方差。
-**返回数据类型**:双精度浮点数 Double。
+**返回数据类型**:DOUBLE。
**适用数据类型**:数值类型。
@@ -715,7 +724,7 @@ SELECT SUM(field_name) FROM tb_name [WHERE clause];
**功能说明**:统计表/超级表中某列的和。
-**返回数据类型**:双精度浮点数 Double 和长整型 INT64。
+**返回数据类型**:DOUBLE, BIGINT。
**适用数据类型**:数值类型。
@@ -729,10 +738,10 @@ SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
**功能说明**:
- - 采用 hyperloglog 算法,返回某列的基数。该算法在数据量很大的情况下,可以明显降低内存的占用,但是求出来的基数是个估算值,标准误差(标准误差是多次实验,每次的平均数的标准差,不是与真实结果的误差)为 0.81%。
+ - 采用 hyperloglog 算法,返回某列的基数。该算法在数据量很大的情况下,可以明显降低内存的占用,求出来的基数是个估算值,标准误差(标准误差是多次实验,每次的平均数的标准差,不是与真实结果的误差)为 0.81%。
- 在数据量较少的时候该算法不是很准确,可以使用 select count(data) from (select unique(col) as data from table) 的方法。
-**返回结果类型**:整形。
+**返回结果类型**:INTEGER。
**适用数据类型**:任何类型。
@@ -747,7 +756,7 @@ SELECT HISTOGRAM(field_name,bin_type, bin_description, normalized) FROM tb_nam
**功能说明**:统计数据按照用户指定区间的分布。
-**返回结果类型**:如归一化参数 normalized 设置为 1,返回结果为双精度浮点类型 DOUBLE,否则为长整形 INT64。
+**返回结果类型**:如归一化参数 normalized 设置为 1,返回结果为 DOUBLE 类型,否则为 BIGINT 类型。
**适用数据类型**:数值型字段。
@@ -782,11 +791,15 @@ FROM { tb_name | stb_name } [WHERE clause]
**功能说明**:统计表/超级表中指定列的值的近似百分比分位数,与 PERCENTILE 函数相似,但是返回近似结果。
-**返回数据类型**: 双精度浮点数 Double。
+**返回数据类型**: DOUBLE。
-**适用数据类型**:数值类型。P值范围是[0,100],当为0时等同于MIN,为100时等同于MAX。如果不指定 algo_type 则使用默认算法 。
+**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
+
+**说明**:
+- P值范围是[0,100],当为0时等同于MIN,为100时等同于MAX。
+- algo_type 取值为 "default" 或 "t-digest"。 输入为 "default" 时函数使用基于直方图算法进行计算。输入为 "t-digest" 时使用t-digest算法计算分位数的近似结果。如果不指定 algo_type 则使用 "default" 算法。
### BOTTOM
@@ -930,7 +943,7 @@ SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
**功能说明**:统计表中某列的值百分比分位数。
-**返回数据类型**: 双精度浮点数 Double。
+**返回数据类型**: DOUBLE。
**应用字段**:数值类型。
@@ -951,7 +964,7 @@ SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
**返回数据类型**:同应用的字段。
-**适用数据类型**:适合于除时间主列外的任何类型。
+**适用数据类型**:适合于除时间主键列外的任何类型。
**适用于**:表、超级表。
@@ -968,7 +981,7 @@ SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
**使用说明**:
@@ -1009,13 +1022,13 @@ SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
**嵌套子查询支持**: 适用于内层查询和外层查询。
-**适用于**:表和超级表
+**适用于**:表和超级表。
**使用说明**:
- 不支持 +、-、*、/ 运算,如 csum(col1) + csum(col2)。
- 只能与聚合(Aggregation)函数一起使用。 该函数可以应用在普通表和超级表上。
- - 使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
+ - 使用在超级表上的时候,需要搭配 PARTITION BY tbname使用,将结果强制规约到单个时间线。
### DERIVATIVE
@@ -1026,13 +1039,13 @@ SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHER
**功能说明**:统计表中某列数值的单位变化率。其中单位时间区间的长度可以通过 time_interval 参数指定,最小可以是 1 秒(1s);ignore_negative 参数的值可以是 0 或 1,为 1 时表示忽略负值。
-**返回数据类型**:双精度浮点数。
+**返回数据类型**:DOUBLE。
**适用数据类型**:数值类型。
-**适用于**:表、超级表
+**适用于**:表和超级表。
-**使用说明**: DERIVATIVE 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
+**使用说明**: DERIVATIVE 函数可以在由 PARTITION BY 划分出单独时间线的情况下用于超级表(也即 PARTITION BY tbname)。
### DIFF
@@ -1047,7 +1060,7 @@ SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHER
**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
**使用说明**: 输出结果行数是范围内总行数减一,第一行没有结果输出。
@@ -1060,11 +1073,12 @@ SELECT IRATE(field_name) FROM tb_name WHERE clause;
**功能说明**:计算瞬时增长率。使用时间区间中最后两个样本数据来计算瞬时增长速率;如果这两个值呈递减关系,那么只取最后一个数用于计算,而不是使用二者差值。
-**返回数据类型**:双精度浮点数 Double。
+**返回数据类型**:DOUBLE。
**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
+
### MAVG
@@ -1074,19 +1088,19 @@ SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
**功能说明**: 计算连续 k 个值的移动平均数(moving average)。如果输入行数小于 k,则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。
- **返回结果类型**: 返回双精度浮点数类型。
+ **返回结果类型**: DOUBLE。
**适用数据类型**: 数值类型。
**嵌套子查询支持**: 适用于内层查询和外层查询。
- **适用于**:表和超级表
+ **适用于**:表和超级表。
**使用说明**:
- 不支持 +、-、*、/ 运算,如 mavg(col1, k1) + mavg(col2, k1);
- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用;
- - 使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
+ - 使用在超级表上的时候,需要搭配 PARTITION BY tbname使用,将结果强制规约到单个时间线。
### SAMPLE
@@ -1102,12 +1116,12 @@ SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
**嵌套子查询支持**: 适用于内层查询和外层查询。
- **适用于**:表和超级表
+ **适用于**:表和超级表。
**使用说明**:
- 不能参与表达式计算;该函数可以应用在普通表和超级表上;
- - 使用在超级表上的时候,需要搭配 Group by tbname 使用,将结果强制规约到单个时间线。
+ - 使用在超级表上的时候,需要搭配 PARTITION by tbname 使用,将结果强制规约到单个时间线。
### STATECOUNT
@@ -1119,10 +1133,10 @@ SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clau
**参数范围**:
-- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
+- oper : "LT" (小于)、"GT"(大于)、"LE"(小于等于)、"GE"(大于等于)、"NE"(不等于)、"EQ"(等于),不区分大小写。
- val : 数值型
-**返回结果类型**:整形。
+**返回结果类型**:INTEGER。
**适用数据类型**:数值类型。
@@ -1132,7 +1146,7 @@ SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clau
**使用说明**:
-- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
+- 该函数可以应用在普通表上,在由 PARTITION BY 划分出单独时间线的情况下用于超级表(也即 PARTITION BY tbname)
- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
@@ -1146,11 +1160,11 @@ SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [W
**参数范围**:
-- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
+- oper : "LT" (小于)、"GT"(大于)、"LE"(小于等于)、"GE"(大于等于)、"NE"(不等于)、"EQ"(等于),不区分大小写。
- val : 数值型
- unit : 时间长度的单位,范围[1s、1m、1h ],不足一个单位舍去。默认为 1s。
-**返回结果类型**:整形。
+**返回结果类型**:INTEGER。
**适用数据类型**:数值类型。
@@ -1160,7 +1174,7 @@ SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [W
**使用说明**:
-- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
+- 该函数可以应用在普通表上,在由 PARTITION BY 划分出单独时间线的情况下用于超级表(也即 PARTITION BY tbname)
- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
@@ -1172,13 +1186,13 @@ SELECT TWA(field_name) FROM tb_name WHERE clause;
**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。
-**返回数据类型**:双精度浮点数 Double。
+**返回数据类型**:DOUBLE。
**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
-**使用说明**: TWA 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
+**使用说明**: TWA 函数可以在由 PARTITION BY 划分出单独时间线的情况下用于超级表(也即 PARTITION BY tbname)。
## 系统信息函数
diff --git a/docs/zh/12-taos-sql/26-udf.md b/docs/zh/12-taos-sql/26-udf.md
index 7b5acbfcad4bcba56ad3259c2aa2589a8a73adb7..bd8d61a5844241efae9eee99a73c65afd3d0926f 100644
--- a/docs/zh/12-taos-sql/26-udf.md
+++ b/docs/zh/12-taos-sql/26-udf.md
@@ -19,7 +19,7 @@ library_path:包含UDF函数实现的动态链接库的绝对路径,是在
OUTPUTTYPE:标识此函数的返回类型。
BUFSIZE:中间结果的缓冲区大小,单位是字节。不设置则默认为0。最大不可超过512字节。
-关于如何开发自定义函数,请参考 [UDF使用说明](../develop/udf)。
+关于如何开发自定义函数,请参考 [UDF使用说明](../../develop/udf)。
## 删除自定义函数
diff --git a/docs/zh/14-reference/12-config/index.md b/docs/zh/14-reference/12-config/index.md
index 2d1866d5dd1874164d03ffdfb382010c8345ad63..eeea28e5ecd5cee096debcdaa3e847394dd740ea 100644
--- a/docs/zh/14-reference/12-config/index.md
+++ b/docs/zh/14-reference/12-config/index.md
@@ -80,21 +80,16 @@ taos --dump-config
| 补充说明 | RESTful 服务在 2.4.0.0 之前(不含)由 taosd 提供,默认端口为 6041; 在 2.4.0.0 及后续版本由 taosAdapter,默认端口为 6041 |
:::note
-确保集群中所有主机在端口 6030-6042 上的 TCP/UDP 协议能够互通。(详细的端口情况请参见下表)
+确保集群中所有主机在端口 6030 上的 TCP 协议能够互通。(详细的端口情况请参见下表)
:::
| 协议 | 默认端口 | 用途说明 | 修改方法 |
| :--- | :-------- | :---------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
-| TCP | 6030 | 客户端与服务端之间通讯。 | 由配置文件设置 serverPort 决定。 |
-| TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
-| TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 |
+| TCP | 6030 | 客户端与服务端之间通讯,多节点集群的节点间通讯。 | 由配置文件设置 serverPort 决定。 |
| TCP | 6041 | 客户端与服务端之间的 RESTful 通讯。 | 随 serverPort 端口变化。注意 taosAdapter 配置或有不同,请参考相应[文档](/reference/taosadapter/)。 |
-| TCP | 6042 | Arbitrator 的服务端口。 | 随 Arbitrator 启动参数设置变化。 |
| TCP | 6043 | TaosKeeper 监控服务端口。 | 随 TaosKeeper 启动参数设置变化。 |
| TCP | 6044 | 支持 StatsD 的数据接入端口。 | 随 taosAdapter 启动参数设置变化(2.3.0.1+以上版本)。 |
| UDP | 6045 | 支持 collectd 数据接入端口。 | 随 taosAdapter 启动参数设置变化(2.3.0.1+以上版本)。 |
| TCP | 6060 | 企业版内 Monitor 服务的网络端口。 | |
-| UDP | 6030-6034 | 客户端与服务端之间通讯。 | 随 serverPort 端口变化。 |
-| UDP | 6035-6039 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。
### maxShellConns
@@ -105,26 +100,6 @@ taos --dump-config
| 取值范围 | 10-50000000 |
| 缺省值 | 5000 |
-### maxConnections
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 一个数据库连接所容许的 dnode 连接数 |
-| 取值范围 | 1-100000 |
-| 缺省值 | 5000 |
-| 补充说明 | 实际测试下来,如果默认没有配,选 50 个 worker thread 会产生 Network unavailable |
-
-### rpcForceTcp
-
-| 属性 | 说明 |
-| -------- | --------------------------------------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | 强制使用 TCP 传输 |
-| 取值范围 | 0: 不开启 1: 开启 |
-| 缺省值 | 0 |
-| 补充说明 | 在网络比较差的环境中,建议开启。
2.0 版本新增。 |
-
## 监控相关
### monitor
@@ -132,10 +107,26 @@ taos --dump-config
| 属性 | 说明 |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| 适用范围 | 仅服务端适用 |
-| 含义 | 服务器内部的系统监控开关。监控主要负责收集物理节点的负载状况,包括 CPU、内存、硬盘、网络带宽、HTTP 请求量的监控记录,记录信息存储在`LOG`库中。 |
+| 含义 | 服务器内部的系统监控开关。监控主要负责收集物理节点的负载状况,包括 CPU、内存、硬盘、网络带宽的监控记录,监控信息将通过 HTTP 协议发送给由 `monitorFqdn` 和 `monitorProt` 指定的 TaosKeeper 监控服务 |
| 取值范围 | 0:关闭监控服务, 1:激活监控服务。 |
| 缺省值 | 1 |
+### monitorFqdn
+
+| 属性 | 说明 |
+| -------- | -------------------------------------------- |
+| 适用范围 | 仅服务端适用 |
+| 含义 | TaosKeeper 监控服务的 FQDN |
+| 缺省值 | 无 |
+
+### monitorPort
+
+| 属性 | 说明 |
+| -------- | -------------------------------------------- |
+| 适用范围 | 仅服务端适用 |
+| 含义 | TaosKeeper 监控服务的端口号 |
+| 缺省值 | 6043 |
+
### monitorInterval
| 属性 | 说明 |
@@ -143,9 +134,10 @@ taos --dump-config
| 适用范围 | 仅服务端适用 |
| 含义 | 监控数据库记录系统参数(CPU/内存)的时间间隔 |
| 单位 | 秒 |
-| 取值范围 | 1-600 |
+| 取值范围 | 1-200000 |
| 缺省值 | 30 |
+
### telemetryReporting
| 属性 | 说明 |
@@ -167,19 +159,10 @@ taos --dump-config
| 缺省值 | 无 |
| 补充说明 | 计算规则可以根据实际应用可能的最大并发数和表的数字相乘,再乘 170 。
(2.0.15 以前的版本中,此参数的单位是字节) |
-### ratioOfQueryCores
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 设置查询线程的最大数量。 |
-| 缺省值 | 1 |
-| 补充说明 | 最小值 0 表示只有 1 个查询线程
最大值 2 表示最大建立 2 倍 CPU 核数的查询线程。
默认为 1,表示最大和 CPU 核数相等的查询线程。
该值可以为小数,即 0.5 表示最大建立 CPU 核数一半的查询线程。 |
-
### maxNumOfDistinctRes
| 属性 | 说明 |
-| -------- | -------------------------------- | --- |
+| -------- | -------------------------------- |
| 适用范围 | 仅服务端适用 |
| 含义 | 允许返回的 distinct 结果最大行数 |
| 取值范围 | 默认值为 10 万,最大值 1 亿 |
@@ -301,96 +284,6 @@ charset 的有效值是 UTF-8。
| 含义 | 数据文件目录,所有的数据文件都将写入该目录 |
| 缺省值 | /var/lib/taos |
-### cache
-
-| 属性 | 说明 |
-| -------- | ------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 内存块的大小 |
-| 单位 | MB |
-| 缺省值 | 16 |
-
-### blocks
-
-| 属性 | 说明 |
-| -------- | ----------------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 每个 vnode(tsdb)中有多少 cache 大小的内存块。因此一个 vnode 的用的内存大小粗略为(cache \* blocks) |
-| 缺省值 | 6 |
-
-### days
-
-| 属性 | 说明 |
-| -------- | -------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 数据文件存储数据的时间跨度 |
-| 单位 | 天 |
-| 缺省值 | 10 |
-
-### keep
-
-| 属性 | 说明 |
-| -------- | -------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 数据保留的天数 |
-| 单位 | 天 |
-| 缺省值 | 3650 |
-
-### minRows
-
-| 属性 | 说明 |
-| -------- | ---------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 文件块中记录的最小条数 |
-| 缺省值 | 100 |
-
-### maxRows
-
-| 属性 | 说明 |
-| -------- | ---------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 文件块中记录的最大条数 |
-| 缺省值 | 4096 |
-
-### walLevel
-
-| 属性 | 说明 |
-| -------- | --------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | WAL 级别 |
-| 取值范围 | 0: 不写WAL;
1:写 WAL, 但不执行 fsync
2:写 WAL, 而且执行 fsync |
-| 缺省值 | 1 |
-
-### fsync
-
-| 属性 | 说明 |
-| -------- | -------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 当 WAL 设置为 2 时,执行 fsync 的周期 |
-| 单位 | 毫秒 |
-| 取值范围 | 最小为 0,表示每次写入,立即执行 fsync
最大为 180000(三分钟) |
-| 缺省值 | 3000 |
-
-### update
-
-| 属性 | 说明 |
-| -------- | ---------------------------------------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 允许更新已存在的数据行 |
-| 取值范围 | 0:不允许更新
1:允许整行更新
2:允许部分列更新。(2.1.7.0 版本开始此参数支持设为 2,在此之前取值只能是 [0, 1]) |
-| 缺省值 | 0 |
-| 补充说明 | 2.0.8.0 版本之前,不支持此参数。 |
-
-### cacheLast
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 是否在内存中缓存子表的最近数据 |
-| 取值范围 | 0:关闭
1:缓存子表最近一行数据
2:缓存子表每一列的最近的非 NULL 值
3:同时打开缓存最近行和列功能。(2.1.2.0 版本开始此参数支持 0 ~ 3 的取值范围,在此之前取值只能是 [0, 1]) |
-| 缺省值 | 0 |
-| 补充说明 | 2.1.2.0 版本之前、2.0.20.7 版本之前在 taos.cfg 文件中不支持此参数。 |
-
### minimalTmpDirGB
| 属性 | 说明 |
@@ -409,110 +302,19 @@ charset 的有效值是 UTF-8。
| 单位 | GB |
| 缺省值 | 2.0 |
-### vnodeBak
-
-| 属性 | 说明 |
-| -------- | -------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 删除 vnode 时是否备份 vnode 目录 |
-| 取值范围 | 0:否,1:是 |
-| 缺省值 | 1 |
-
## 集群相关
-### numOfMnodes
-
-| 属性 | 说明 |
-| -------- | ------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 系统中管理节点个数 |
-| 缺省值 | 3 |
-
-### replica
-
-| 属性 | 说明 |
-| -------- | ------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 副本个数 |
-| 取值范围 | 1-3 |
-| 缺省值 | 1 |
-
-### quorum
-
-| 属性 | 说明 |
-| -------- | -------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 多副本环境下指令执行的确认数要求 |
-| 取值范围 | 1,2 |
-| 缺省值 | 1 |
-
-### role
+### supportVnodes
| 属性 | 说明 |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 适用范围 | 仅服务端适用 |
-| 含义 | dnode 的可选角色 |
-| 取值范围 | 0:any(既可作为 mnode,也可分配 vnode)
1:mgmt(只能作为 mnode,不能分配 vnode)
2:dnode(不能作为 mnode,只能分配 vnode) |
-| 缺省值 | 0 |
-
-### balance
-
-| 属性 | 说明 |
-| -------- | ---------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 是否启动负载均衡 |
-| 取值范围 | 0,1 |
-| 缺省值 | 1 |
-
-### balanceInterval
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 管理节点在正常运行状态下,检查负载均衡的时间间隔 |
-| 单位 | 秒 |
-| 取值范围 | 1-30000 |
-| 缺省值 | 300 |
-
-### arbitrator
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 系统中裁决器的 endpoint,其格式如 firstEp |
-| 缺省值 | 空 |
+| 含义 | dnode 支持的最大 vnode 数目 |
+| 取值范围 | 0-4096 |
+| 缺省值 | 256 |
## 时间相关
-### precision
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------- |
-| 适用范围 | 仅服务端 |
-| 含义 | 创建数据库时使用的时间精度 |
-| 取值范围 | ms: millisecond; us: microsecond ; ns: nanosecond |
-| 缺省值 | ms |
-
-### rpcTimer
-
-| 属性 | 说明 |
-| -------- | -------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | rpc 重试时长 |
-| 单位 | 毫秒 |
-| 取值范围 | 100-3000 |
-| 缺省值 | 300 |
-
-### rpcMaxTime
-
-| 属性 | 说明 |
-| -------- | -------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | rpc 等待应答最大时长 |
-| 单位 | 秒 |
-| 取值范围 | 100-7200 |
-| 缺省值 | 600 |
-
### statusInterval
| 属性 | 说明 |
@@ -533,105 +335,8 @@ charset 的有效值是 UTF-8。
| 取值范围 | 1-120 |
| 缺省值 | 3 |
-### tableMetaKeepTimer
-
-| 属性 | 说明 |
-| -------- | --------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 表的元数据 cache 时长 |
-| 单位 | 秒 |
-| 取值范围 | 1-8640000 |
-| 缺省值 | 7200 |
-
-### maxTmrCtrl
-
-| 属性 | 说明 |
-| -------- | -------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | 定时器个数 |
-| 单位 | 个 |
-| 取值范围 | 8-2048 |
-| 缺省值 | 512 |
-
-### offlineThreshold
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | dnode 离线阈值,超过该时间将导致 dnode 离线 |
-| 单位 | 秒 |
-| 取值范围 | 5-7200000 |
-| 缺省值 | 86400\*10(10 天) |
-
## 性能调优
-### numOfThreadsPerCore
-
-| 属性 | 说明 |
-| -------- | ----------------------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | 每个 CPU 核生成的队列消费者线程数量 |
-| 缺省值 | 1.0 |
-
-### ratioOfQueryThreads
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 设置查询线程的最大数量 |
-| 取值范围 | 0:表示只有 1 个查询线程
1:表示最大和 CPU 核数相等的查询线程
2:表示最大建立 2 倍 CPU 核数的查询线程。 |
-| 缺省值 | 1 |
-| 补充说明 | 该值可以为小数,即 0.5 表示最大建立 CPU 核数一半的查询线程。 |
-
-### maxVgroupsPerDb
-
-| 属性 | 说明 |
-| -------- | ------------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 每个 DB 中 能够使用的最大 vnode 个数 |
-| 取值范围 | 0-8192 |
-| 缺省值 | 0 |
-
-### maxTablesPerVnode
-
-| 属性 | 说明 |
-| -------- | --------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 每个 vnode 中能够创建的最大表个数 |
-| 缺省值 | 1000000 |
-
-### minTablesPerVnode
-
-| 属性 | 说明 |
-| -------- | --------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 每个 vnode 中必须创建表的最小数量 |
-| 缺省值 | 1000 |
-
-### tableIncStepPerVnode
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 每个 vnode 中超过最小表数,i.e. minTablesPerVnode, 后递增步长 |
-| 缺省值 | 1000 |
-
-### maxNumOfOrderedRes
-
-| 属性 | 说明 |
-| -------- | -------------------------------------- |
-| 适用范围 | 服务端和客户端均适用 |
-| 含义 | 支持超级表时间排序允许的最多记录数限制 |
-| 缺省值 | 10 万 |
-
-### mnodeEqualVnodeNum
-
-| 属性 | 说明 |
-| -------- | ------------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 将一个 mnode 等同于 vnode 消耗的个数 |
-| 缺省值 | 4 |
-
### numOfCommitThreads
| 属性 | 说明 |
@@ -642,23 +347,6 @@ charset 的有效值是 UTF-8。
## 压缩相关
-### comp
-
-| 属性 | 说明 |
-| -------- | ----------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 文件压缩标志位 |
-| 取值范围 | 0:关闭,1:一阶段压缩,2:两阶段压缩 |
-| 缺省值 | 2 |
-
-### tsdbMetaCompactRatio
-
-| 属性 | 说明 |
-| -------- | -------------------------------------------------------------- |
-| 含义 | tsdb meta 文件中冗余数据超过多少阈值,开启 meta 文件的压缩功能 |
-| 取值范围 | 0:不开启,[1-100]:冗余数据比例 |
-| 缺省值 | 0 |
-
### compressMsgSize
| 属性 | 说明 |
@@ -710,135 +398,6 @@ charset 的有效值是 UTF-8。
| 缺省值 | 0.0000000000000001 |
| 补充说明 | 小于此值的浮点数尾数部分将被截取 |
-## 连续查询相关
-
-### stream
-
-| 属性 | 说明 |
-| -------- | ------------------------------ |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 是否启用连续查询(流计算功能) |
-| 取值范围 | 0:不允许
1:允许 |
-| 缺省值 | 1 |
-
-### minSlidingTime
-
-| 属性 | 说明 |
-| -------- | ----------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 最小滑动窗口时长 |
-| 单位 | 毫秒 |
-| 取值范围 | 10-1000000 |
-| 缺省值 | 10 |
-| 补充说明 | 支持 us 补值后,这个值就是 1us 了。 |
-
-### minIntervalTime
-
-| 属性 | 说明 |
-| -------- | -------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 时间窗口最小值 |
-| 单位 | 毫秒 |
-| 取值范围 | 1-1000000 |
-| 缺省值 | 10 |
-
-### maxStreamCompDelay
-
-| 属性 | 说明 |
-| -------- | -------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 连续查询启动最大延迟 |
-| 单位 | 毫秒 |
-| 取值范围 | 10-1000000000 |
-| 缺省值 | 20000 |
-
-### maxFirstStreamCompDelay
-
-| 属性 | 说明 |
-| -------- | -------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 第一次连续查询启动最大延迟 |
-| 单位 | 毫秒 |
-| 取值范围 | 10-1000000000 |
-| 缺省值 | 10000 |
-
-### retryStreamCompDelay
-
-| 属性 | 说明 |
-| -------- | -------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 连续查询重试等待间隔 |
-| 单位 | 毫秒 |
-| 取值范围 | 10-1000000000 |
-| 缺省值 | 10 |
-
-### streamCompDelayRatio
-
-| 属性 | 说明 |
-| -------- | ---------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 连续查询的延迟时间计算系数,实际延迟时间为本参数乘以计算时间窗口 |
-| 取值范围 | 0.1-0.9 |
-| 缺省值 | 0.1 |
-
-:::info
-为避免多个 stream 同时执行占用太多系统资源,程序中对 stream 的执行时间人为增加了一些随机的延时。
maxFirstStreamCompDelay 是 stream 第一次执行前最少要等待的时间。
streamCompDelayRatio 是延迟时间的计算系数,它乘以查询的 interval 后为延迟时间基准。
maxStreamCompDelay 是延迟时间基准的上限。
实际延迟时间为一个不超过延迟时间基准的随机值。
stream 某次计算失败后需要重试,retryStreamCompDelay 是重试的等待时间基准。
实际重试等待时间为不超过等待时间基准的随机值。
-
-:::
-
-## HTTP 相关
-
-:::note
-HTTP 服务在 2.4.0.0(不含)以前的版本中由 taosd 提供,在 2.4.0.0 以后(含)由 taosAdapter 提供。
-本节的配置参数仅在 2.4.0.0(不含)以前的版本中生效。如果您使用的是 2.4.0.0(含)及以后的版本请参考[文档](/reference/taosadapter/)。
-
-:::
-
-### http
-
-| 属性 | 说明 |
-| -------- | --------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 服务器内部的 http 服务开关。 |
-| 取值范围 | 0:关闭 http 服务, 1:激活 http 服务。 |
-| 缺省值 | 1 |
-
-### httpEnableRecordSql
-
-| 属性 | 说明 |
-| -------- | --------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 记录通过 RESTFul 接口,产生的 SQL 调用。 |
-| 缺省值 | 0 |
-| 补充说明 | 生成的文件(httpnote.0/httpnote.1),与服务端日志所在目录相同。 |
-
-### httpMaxThreads
-
-| 属性 | 说明 |
-| -------- | ------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | RESTFul 接口的线程数。taosAdapter 配置或有不同,请参考相应[文档](/reference/taosadapter/)。 |
-| 缺省值 | 2 |
-
-### restfulRowLimit
-
-| 属性 | 说明 |
-| -------- | ----------------------------------------------------------------------------------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | RESTFul 接口单次返回的记录条数。taosAdapter 配置或有不同,请参考相应[文档](/reference/taosadapter/)。 |
-| 缺省值 | 10240 |
-| 补充说明 | 最大 10,000,000 |
-
-### httpDBNameMandatory
-
-| 属性 | 说明 |
-| -------- | ---------------------------- |
-| 适用范围 | 仅服务端适用 |
-| 含义 | 是否在 URL 中输入 数据库名称 |
-| 取值范围 | 0:不开启,1:开启 |
-| 缺省值 | 0 |
-| 补充说明 | 2.3 版本新增。 |
-
## 日志相关
### logDir
diff --git a/docs/zh/17-operation/01-pkg-install.md b/docs/zh/17-operation/01-pkg-install.md
index f814ee70b77db1a775dda951bab413da03d57561..0680f7609543322d1b74f4ca89df56d14fb705f7 100644
--- a/docs/zh/17-operation/01-pkg-install.md
+++ b/docs/zh/17-operation/01-pkg-install.md
@@ -10,7 +10,7 @@ import TabItem from "@theme/TabItem";
## 安装
-关于安装,请参考 [使用安装包立即开始](../get-started/package)
+关于安装,请参考 [使用安装包立即开始](../../get-started/package)
diff --git a/docs/zh/17-operation/02-planning.mdx b/docs/zh/17-operation/02-planning.mdx
index c45181f4168442cbdcab37fa2aed5b675844771c..0d63c4eaf365036cbba1d838ba6ee860a894724d 100644
--- a/docs/zh/17-operation/02-planning.mdx
+++ b/docs/zh/17-operation/02-planning.mdx
@@ -16,7 +16,7 @@ title: 容量规划
- pagesize
- cachesize
-关于这些参数的详细说明请参考 [数据库管理](../taos-sql/database)。
+关于这些参数的详细说明请参考 [数据库管理](../../taos-sql/database)。
一个数据库所需要的内存大小等于
@@ -24,7 +24,7 @@ title: 容量规划
vgroups * replica * (buffer + pages * pagesize + cachesize)
```
-但要注意的是这些内存并不需要由单一服务器提供,而是由整个集群中所有数据节点共同负担,相当于由这些数据节点所在的服务器共同负担。如果集群中有不止一个数据库,则所需内存要累加,并由集群中所有服务器共同负担。更复杂的场景是如果集群中的数据节点并非在最初就一次性全部建立,而是随着使用中系统负载的增加逐步增加服务器并增加数据节点,则新创建的数据库会导致新旧数据节点上的负载并不均衡,此时简单的理论计算并不能直接使用,要结合各数据节点的负载情况。
+但要注意的是这些内存并不需要由单一服务器提供,而是由整个集群中所有数据节点共同负担,相当于由这些数据节点所在的服务器共同负担。如果集群中有不止一个数据库,则所需内存要累加。更复杂的场景是如果集群中的数据节点并非在最初就一次性全部建立,而是随着使用中系统负载的增加逐步增加服务器并增加数据节点,则新创建的数据库会导致新旧数据节点上的负载并不均衡,此时简单的理论计算并不能直接使用,要结合各数据节点的负载情况。
## 客户端内存需求
@@ -51,7 +51,7 @@ CPU 的需求取决于如下两方面:
- **数据插入** TDengine 单核每秒能至少处理一万个插入请求。每个插入请求可以带多条记录,一次插入一条记录与插入 10 条记录,消耗的计算资源差别很小。因此每次插入,条数越大,插入效率越高。如果一个插入请求带 200 条以上记录,单核就能达到每秒插入 100 万条记录的速度。但对前端数据采集的要求越高,因为需要缓存记录,然后一批插入。
- **查询需求** TDengine 提供高效的查询,但是每个场景的查询差异很大,查询频次变化也很大,难以给出客观数字。需要用户针对自己的场景,写一些查询语句,才能确定。
-因此仅对数据插入而言,CPU 是可以估算出来的,但查询所耗的计算资源无法估算。在实际运营过程中,不建议 CPU 使用率超过 50%,超过后,需要增加新的节点,以获得更多计算资源。
+因此仅对数据插入而言,CPU 是可以估算出来的,但查询所耗的计算资源无法估算。在实际运行过程中,不建议 CPU 使用率超过 50%,超过后,需要增加新的节点,以获得更多计算资源。
## 存储需求
diff --git a/docs/zh/17-operation/03-tolerance.md b/docs/zh/17-operation/03-tolerance.md
index 2be914c6b25da9c509fb2bcd85342ef3aa50fd8b..2cfd4b6484acdcb617cd91ed694d2f4c0f010e93 100644
--- a/docs/zh/17-operation/03-tolerance.md
+++ b/docs/zh/17-operation/03-tolerance.md
@@ -27,4 +27,4 @@ TDengine 集群的节点数必须大于等于副本数,否则创建表时将
当 TDengine 集群中的节点部署在不同的物理机上,并设置多个副本数时,就实现了系统的高可靠性,无需再使用其他软件或工具。TDengine 企业版还可以将副本部署在不同机房,从而实现异地容灾。
-另外一种灾备方式是通过 `taosX` 将一个 TDengine 集群的数据同步复制到物理上位于不同数据中心的另一个 TDengine 集群。其详细使用方法请参考 [taosX 参考手册](../reference/taosX)
+另外一种灾备方式是通过 `taosX` 将一个 TDengine 集群的数据同步复制到物理上位于不同数据中心的另一个 TDengine 集群。其详细使用方法请参考 [taosX 参考手册](../../reference/taosX)
diff --git a/include/common/tglobal.h b/include/common/tglobal.h
index ac998b807e2c6124c12d36867b268a799e9f2d9d..a3aa657e60722bd6fc32be5b492a20a7e560414d 100644
--- a/include/common/tglobal.h
+++ b/include/common/tglobal.h
@@ -102,11 +102,6 @@ extern int32_t tsQuerySmaOptimize;
// client
extern int32_t tsMinSlidingTime;
extern int32_t tsMinIntervalTime;
-extern int32_t tsMaxStreamComputDelay;
-extern int32_t tsStreamCompStartDelay;
-extern int32_t tsRetryStreamCompDelay;
-extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
-extern int64_t tsMaxRetentWindow;
// build info
extern char version[];
diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c
index cb1f3ca91c6e36c3e5d2282c3990c308f1d11e06..c7b7da9adceaaaefec4f03b85d051f36d0bc8474 100644
--- a/source/common/src/tglobal.c
+++ b/source/common/src/tglobal.c
@@ -118,20 +118,6 @@ int32_t tsMaxNumOfDistinctResults = 1000 * 10000;
// 1 database precision unit for interval time range, changed accordingly
int32_t tsMinIntervalTime = 1;
-// 20sec, the maximum value of stream computing delay, changed accordingly
-int32_t tsMaxStreamComputDelay = 20000;
-
-// 10sec, the first stream computing delay time after system launched successfully, changed accordingly
-int32_t tsStreamCompStartDelay = 10000;
-
-// the stream computing delay time after executing failed, change accordingly
-int32_t tsRetryStreamCompDelay = 10 * 1000;
-
-// The delayed computing ration. 10% of the whole computing time window by default.
-float tsStreamComputDelayRatio = 0.1f;
-
-int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
-
// the maximum allowed query buffer size during query processing for each data node.
// -1 no limit (default)
// 0 no query allowed, queries are disabled
@@ -330,7 +316,7 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
if (cfgAddString(pCfg, "fqdn", defaultFqdn, 1) != 0) return -1;
if (cfgAddInt32(pCfg, "serverPort", defaultServerPort, 1, 65056, 1) != 0) return -1;
if (cfgAddDir(pCfg, "tempDir", tsTempDir, 1) != 0) return -1;
- if (cfgAddFloat(pCfg, "minimalTempDirGB", 1.0f, 0.001f, 10000000, 1) != 0) return -1;
+ if (cfgAddFloat(pCfg, "minimalTmpDirGB", 1.0f, 0.001f, 10000000, 1) != 0) return -1;
if (cfgAddInt32(pCfg, "shellActivityTimer", tsShellActivityTimer, 1, 120, 1) != 0) return -1;
if (cfgAddInt32(pCfg, "compressMsgSize", tsCompressMsgSize, -1, 100000000, 1) != 0) return -1;
if (cfgAddInt32(pCfg, "compressColData", tsCompressColData, -1, 100000000, 1) != 0) return -1;
@@ -383,10 +369,6 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
if (cfgAddInt32(pCfg, "minIntervalTime", tsMinIntervalTime, 1, 1000000, 0) != 0) return -1;
if (cfgAddInt32(pCfg, "maxNumOfDistinctRes", tsMaxNumOfDistinctResults, 10 * 10000, 10000 * 10000, 0) != 0) return -1;
if (cfgAddInt32(pCfg, "countAlwaysReturnValue", tsCountAlwaysReturnValue, 0, 1, 0) != 0) return -1;
- if (cfgAddInt32(pCfg, "maxStreamCompDelay", tsMaxStreamComputDelay, 10, 1000000000, 0) != 0) return -1;
- if (cfgAddInt32(pCfg, "maxFirstStreamCompDelay", tsStreamCompStartDelay, 1000, 1000000000, 0) != 0) return -1;
- if (cfgAddInt32(pCfg, "retryStreamCompDelay", tsRetryStreamCompDelay, 10, 1000000000, 0) != 0) return -1;
- if (cfgAddFloat(pCfg, "streamCompDelayRatio", tsStreamComputDelayRatio, 0.1, 0.9, 0) != 0) return -1;
if (cfgAddInt32(pCfg, "queryBufferSize", tsQueryBufferSize, -1, 500000000000, 0) != 0) return -1;
if (cfgAddBool(pCfg, "retrieveBlockingModel", tsRetrieveBlockingModel, 0) != 0) return -1;
if (cfgAddBool(pCfg, "printAuth", tsPrintAuth, 0) != 0) return -1;
@@ -532,7 +514,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
tstrncpy(tsTempDir, cfgGetItem(pCfg, "tempDir")->str, PATH_MAX);
taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
- tsTempSpace.reserved = cfgGetItem(pCfg, "minimalTempDirGB")->fval;
+ tsTempSpace.reserved = cfgGetItem(pCfg, "minimalTmpDirGB")->fval;
if (taosMulMkDir(tsTempDir) != 0) {
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
return -1;
@@ -579,10 +561,6 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
tsMinIntervalTime = cfgGetItem(pCfg, "minIntervalTime")->i32;
tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32;
tsCountAlwaysReturnValue = cfgGetItem(pCfg, "countAlwaysReturnValue")->i32;
- tsMaxStreamComputDelay = cfgGetItem(pCfg, "maxStreamCompDelay")->i32;
- tsStreamCompStartDelay = cfgGetItem(pCfg, "maxFirstStreamCompDelay")->i32;
- tsRetryStreamCompDelay = cfgGetItem(pCfg, "retryStreamCompDelay")->i32;
- tsStreamComputDelayRatio = cfgGetItem(pCfg, "streamCompDelayRatio")->fval;
tsQueryBufferSize = cfgGetItem(pCfg, "queryBufferSize")->i32;
tsRetrieveBlockingModel = cfgGetItem(pCfg, "retrieveBlockingModel")->bval;
tsPrintAuth = cfgGetItem(pCfg, "printAuth")->bval;
@@ -758,10 +736,6 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
tsMaxShellConns = cfgGetItem(pCfg, "maxShellConns")->i32;
} else if (strcasecmp("maxNumOfDistinctRes", name) == 0) {
tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32;
- } else if (strcasecmp("maxStreamCompDelay", name) == 0) {
- tsMaxStreamComputDelay = cfgGetItem(pCfg, "maxStreamCompDelay")->i32;
- } else if (strcasecmp("maxFirstStreamCompDelay", name) == 0) {
- tsStreamCompStartDelay = cfgGetItem(pCfg, "maxFirstStreamCompDelay")->i32;
}
break;
}
@@ -772,8 +746,8 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
break;
}
case 'i': {
- if (strcasecmp("minimalTempDirGB", name) == 0) {
- tsTempSpace.reserved = cfgGetItem(pCfg, "minimalTempDirGB")->fval;
+ if (strcasecmp("minimalTmpDirGB", name) == 0) {
+ tsTempSpace.reserved = cfgGetItem(pCfg, "minimalTmpDirGB")->fval;
} else if (strcasecmp("minimalDataDirGB", name) == 0) {
tsDataSpace.reserved = cfgGetItem(pCfg, "minimalDataDirGB")->fval;
} else if (strcasecmp("minSlidingTime", name) == 0) {
@@ -883,9 +857,7 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
break;
}
case 'r': {
- if (strcasecmp("retryStreamCompDelay", name) == 0) {
- tsRetryStreamCompDelay = cfgGetItem(pCfg, "retryStreamCompDelay")->i32;
- } else if (strcasecmp("retrieveBlockingModel", name) == 0) {
+ if (strcasecmp("retrieveBlockingModel", name) == 0) {
tsRetrieveBlockingModel = cfgGetItem(pCfg, "retrieveBlockingModel")->bval;
} else if (strcasecmp("rpcQueueMemoryAllowed", name) == 0) {
tsRpcQueueMemoryAllowed = cfgGetItem(pCfg, "rpcQueueMemoryAllowed")->i64;
@@ -913,8 +885,6 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
tsNumOfSupportVnodes = cfgGetItem(pCfg, "supportVnodes")->i32;
} else if (strcasecmp("statusInterval", name) == 0) {
tsStatusInterval = cfgGetItem(pCfg, "statusInterval")->i32;
- } else if (strcasecmp("streamCompDelayRatio", name) == 0) {
- tsStreamComputDelayRatio = cfgGetItem(pCfg, "streamCompDelayRatio")->fval;
} else if (strcasecmp("slaveQuery", name) == 0) {
tsEnableSlaveQuery = cfgGetItem(pCfg, "slaveQuery")->bval;
} else if (strcasecmp("snodeShmSize", name) == 0) {
diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c
index e259dde29c86a7559d8d4dd5f256a81dc137727b..4e6a450d35d01d7c41a80bbb7ae1fc5d1c21b127 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCache.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCache.c
@@ -46,11 +46,6 @@ void tsdbCloseCache(SLRUCache *pCache) {
}
}
-static void getTableCacheKeyS(tb_uid_t uid, const char *cacheType, char *key, int *len) {
- snprintf(key, 30, "%" PRIi64 "%s", uid, cacheType);
- *len = strlen(key);
-}
-
static void getTableCacheKey(tb_uid_t uid, int cacheType, char *key, int *len) {
if (cacheType == 0) { // last_row
*(uint64_t *)key = (uint64_t)uid;
@@ -245,8 +240,6 @@ int32_t tsdbCacheInsertLast(SLRUCache *pCache, tb_uid_t uid, STSRow *row, STsdb
char key[32] = {0};
int keyLen = 0;
- // ((void)(row));
-
// getTableCacheKey(uid, "l", key, &keyLen);
getTableCacheKey(uid, 1, key, &keyLen);
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
@@ -323,26 +316,10 @@ static tb_uid_t getTableSuidByUid(tb_uid_t uid, STsdb *pTsdb) {
static int32_t getTableDelDataFromDelIdx(SDelFReader *pDelReader, SDelIdx *pDelIdx, SArray *aDelData) {
int32_t code = 0;
- // SMapData delDataMap;
- // SDelData delData;
-
if (pDelIdx) {
- // tMapDataReset(&delDataMap);
-
- // code = tsdbReadDelData(pDelReader, pDelIdx, &delDataMap, NULL);
code = tsdbReadDelData(pDelReader, pDelIdx, aDelData, NULL);
- if (code) goto _err;
- /*
- for (int32_t iDelData = 0; iDelData < delDataMap.nItem; ++iDelData) {
- code = tMapDataGetItemByIdx(&delDataMap, iDelData, &delData, tGetDelData);
- if (code) goto _err;
-
- taosArrayPush(aDelData, &delData);
- }
- */
}
-_err:
return code;
}
@@ -444,18 +421,16 @@ typedef struct SFSNextRowIter {
SArray *aDFileSet;
SDataFReader *pDataFReader;
SArray *aBlockIdx;
- // SMapData blockIdxMap;
- // SBlockIdx blockIdx;
- SBlockIdx *pBlockIdx;
- SMapData blockMap;
- int32_t nBlock;
- int32_t iBlock;
- SBlock block;
- SBlockData blockData;
- SBlockData *pBlockData;
- int32_t nRow;
- int32_t iRow;
- TSDBROW row;
+ SBlockIdx *pBlockIdx;
+ SMapData blockMap;
+ int32_t nBlock;
+ int32_t iBlock;
+ SBlock block;
+ SBlockData blockData;
+ SBlockData *pBlockData;
+ int32_t nRow;
+ int32_t iRow;
+ TSDBROW row;
} SFSNextRowIter;
static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
@@ -629,41 +604,8 @@ typedef struct SMemNextRowIter {
} SMemNextRowIter;
static int32_t getNextRowFromMem(void *iter, TSDBROW **ppRow) {
- // static int32_t getNextRowFromMem(void *iter, SArray *pRowArray) {
SMemNextRowIter *state = (SMemNextRowIter *)iter;
int32_t code = 0;
- /*
- if (!state->iterOpened) {
- if (state->pMem != NULL) {
- tsdbTbDataIterOpen(state->pMem, NULL, 1, &state->iter);
-
- state->iterOpened = true;
-
- TSDBROW *pMemRow = tsdbTbDataIterGet(&state->iter);
- if (pMemRow) {
- state->curRow = pMemRow;
- } else {
- return code;
- }
- } else {
- return code;
- }
- }
-
- taosArrayPush(pRowArray, state->curRow);
- while (tsdbTbDataIterNext(&state->iter)) {
- TSDBROW *row = tsdbTbDataIterGet(&state->iter);
-
- if (TSDBROW_TS(row) < TSDBROW_TS(state->curRow)) {
- state->curRow = row;
- break;
- } else {
- taosArrayPush(pRowArray, row);
- }
- }
-
- return code;
- */
switch (state->state) {
case SMEMNEXTROW_ENTER: {
if (state->pMem != NULL) {
@@ -702,44 +644,44 @@ _err:
return code;
}
-static int32_t tsRowFromTsdbRow(STSchema *pTSchema, TSDBROW *pRow, STSRow **ppRow) {
- int32_t code = 0;
-
- SColVal *pColVal = &(SColVal){0};
-
- if (pRow->type == 0) {
- *ppRow = tdRowDup(pRow->pTSRow);
- } else {
- SArray *pArray = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
- if (pArray == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _exit;
- }
-
- TSDBKEY key = TSDBROW_KEY(pRow);
- STColumn *pTColumn = &pTSchema->columns[0];
- *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.ts = key.ts});
-
- if (taosArrayPush(pArray, pColVal) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _exit;
- }
-
- for (int16_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
- tsdbRowGetColVal(pRow, pTSchema, iCol, pColVal);
- if (taosArrayPush(pArray, pColVal) == NULL) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- goto _exit;
- }
- }
-
- code = tdSTSRowNew(pArray, pTSchema, ppRow);
- if (code) goto _exit;
- }
-
-_exit:
- return code;
-}
+/* static int32_t tsRowFromTsdbRow(STSchema *pTSchema, TSDBROW *pRow, STSRow **ppRow) { */
+/* int32_t code = 0; */
+
+/* SColVal *pColVal = &(SColVal){0}; */
+
+/* if (pRow->type == 0) { */
+/* *ppRow = tdRowDup(pRow->pTSRow); */
+/* } else { */
+/* SArray *pArray = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal)); */
+/* if (pArray == NULL) { */
+/* code = TSDB_CODE_OUT_OF_MEMORY; */
+/* goto _exit; */
+/* } */
+
+/* TSDBKEY key = TSDBROW_KEY(pRow); */
+/* STColumn *pTColumn = &pTSchema->columns[0]; */
+/* *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.ts = key.ts}); */
+
+/* if (taosArrayPush(pArray, pColVal) == NULL) { */
+/* code = TSDB_CODE_OUT_OF_MEMORY; */
+/* goto _exit; */
+/* } */
+
+/* for (int16_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) { */
+/* tsdbRowGetColVal(pRow, pTSchema, iCol, pColVal); */
+/* if (taosArrayPush(pArray, pColVal) == NULL) { */
+/* code = TSDB_CODE_OUT_OF_MEMORY; */
+/* goto _exit; */
+/* } */
+/* } */
+
+/* code = tdSTSRowNew(pArray, pTSchema, ppRow); */
+/* if (code) goto _exit; */
+/* } */
+
+/* _exit: */
+/* return code; */
+/* } */
static bool tsdbKeyDeleted(TSDBKEY *key, SArray *pSkyline, int64_t *iSkyline) {
bool deleted = false;
@@ -768,10 +710,8 @@ static bool tsdbKeyDeleted(TSDBKEY *key, SArray *pSkyline, int64_t *iSkyline) {
}
typedef int32_t (*_next_row_fn_t)(void *iter, TSDBROW **ppRow);
-// typedef int32_t (*_next_row_fn_t)(void *iter, SArray *pRowArray);
typedef int32_t (*_next_row_clear_fn_t)(void *iter);
-// typedef struct TsdbNextRowState {
typedef struct {
TSDBROW *pRow;
bool stop;
@@ -782,7 +722,6 @@ typedef struct {
} TsdbNextRowState;
typedef struct {
- // STsdb *pTsdb;
SArray *pSkyline;
int64_t iSkyline;
@@ -793,10 +732,8 @@ typedef struct {
TSDBROW memRow, imemRow, fsRow;
TsdbNextRowState input[3];
- // SMemTable *pMemTable;
- // SMemTable *pIMemTable;
- STsdbReadSnap *pReadSnap;
- STsdb *pTsdb;
+ STsdbReadSnap *pReadSnap;
+ STsdb *pTsdb;
} CacheNextRowIter;
static int32_t nextRowIterOpen(CacheNextRowIter *pIter, tb_uid_t uid, STsdb *pTsdb) {
@@ -967,7 +904,7 @@ _err:
return code;
}
-static int32_t mergeLastRow2(tb_uid_t uid, STsdb *pTsdb, bool *dup, STSRow **ppRow) {
+static int32_t mergeLastRow(tb_uid_t uid, STsdb *pTsdb, bool *dup, STSRow **ppRow) {
int32_t code = 0;
STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1);
@@ -978,8 +915,6 @@ static int32_t mergeLastRow2(tb_uid_t uid, STsdb *pTsdb, bool *dup, STSRow **ppR
SArray *pColArray = taosArrayInit(nCol, sizeof(SColVal));
SColVal *pColVal = &(SColVal){0};
- // tb_uid_t suid = getTableSuidByUid(uid, pTsdb);
-
TSKEY lastRowTs = TSKEY_MAX;
CacheNextRowIter iter = {0};
@@ -1066,7 +1001,7 @@ _err:
return code;
}
-static int32_t mergeLast2(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
+static int32_t mergeLast(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
int32_t code = 0;
STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1);
@@ -1077,8 +1012,6 @@ static int32_t mergeLast2(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
SArray *pColArray = taosArrayInit(nCol, sizeof(SLastCol));
SColVal *pColVal = &(SColVal){0};
- // tb_uid_t suid = getTableSuidByUid(uid, pTsdb);
-
TSKEY lastRowTs = TSKEY_MAX;
CacheNextRowIter iter = {0};
@@ -1124,12 +1057,7 @@ static int32_t mergeLast2(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
continue;
}
}
- /*
- if ((TSDBROW_TS(pRow) < lastRowTs)) {
- // goto build the result ts row
- break;
- }
- */
+
// merge into pColArray
setNoneCol = false;
for (iCol = noneCol; iCol < nCol; ++iCol) {
@@ -1139,7 +1067,6 @@ static int32_t mergeLast2(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
tsdbRowGetColVal(pRow, pTSchema, iCol, pColVal);
if ((tColVal->isNone || tColVal->isNull) && (!pColVal->isNone && !pColVal->isNull)) {
taosArraySet(pColArray, iCol, &(SLastCol){.ts = rowTs, .colVal = *pColVal});
- //} else if (tColVal->isNone && pColVal->isNone && !setNoneCol) {
} else if ((tColVal->isNone || tColVal->isNull) && (pColVal->isNone || pColVal->isNull) && !setNoneCol) {
noneCol = iCol;
setNoneCol = true;
@@ -1148,521 +1075,36 @@ static int32_t mergeLast2(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
} while (setNoneCol);
// build the result ts row here
- //*dup = false;
if (taosArrayGetSize(pColArray) <= 0) {
*ppLastArray = NULL;
taosArrayDestroy(pColArray);
} else {
*ppLastArray = pColArray;
}
- /* if (taosArrayGetSize(pColArray) == nCol) {
- code = tdSTSRowNew(pColArray, pTSchema, ppRow);
- if (code) goto _err;
- } else {
- *ppRow = NULL;
- }*/
nextRowIterClose(&iter);
- // taosArrayDestroy(pColArray);
taosMemoryFreeClear(pTSchema);
return code;
_err:
nextRowIterClose(&iter);
- // taosArrayDestroy(pColArray);
taosMemoryFreeClear(pTSchema);
return code;
}
-// static int32_t mergeLastRow(tb_uid_t uid, STsdb *pTsdb, bool *dup, STSRow **ppRow) {
-// int32_t code = 0;
-// SArray *pSkyline = NULL;
-
-// STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1);
-// int16_t nCol = pTSchema->numOfCols;
-// SArray *pColArray = taosArrayInit(nCol, sizeof(SColVal));
-
-// tb_uid_t suid = getTableSuidByUid(uid, pTsdb);
-
-// STbData *pMem = NULL;
-// if (pTsdb->mem) {
-// tsdbGetTbDataFromMemTable(pTsdb->mem, suid, uid, &pMem);
-// }
-
-// STbData *pIMem = NULL;
-// if (pTsdb->imem) {
-// tsdbGetTbDataFromMemTable(pTsdb->imem, suid, uid, &pIMem);
-// }
-
-// *ppRow = NULL;
-
-// pSkyline = taosArrayInit(32, sizeof(TSDBKEY));
-
-// SDelIdx delIdx;
-
-// SDelFile *pDelFile = tsdbFSStateGetDelFile(pTsdb->pFS->cState);
-// if (pDelFile) {
-// SDelFReader *pDelFReader;
-
-// code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb, NULL);
-// if (code) goto _err;
-
-// code = getTableDelIdx(pDelFReader, suid, uid, &delIdx);
-// if (code) goto _err;
-
-// code = getTableDelSkyline(pMem, pIMem, pDelFReader, &delIdx, pSkyline);
-// if (code) goto _err;
-
-// tsdbDelFReaderClose(&pDelFReader);
-// } else {
-// code = getTableDelSkyline(pMem, pIMem, NULL, NULL, pSkyline);
-// if (code) goto _err;
-// }
-
-// int64_t iSkyline = taosArrayGetSize(pSkyline) - 1;
-
-// SBlockIdx idx = {.suid = suid, .uid = uid};
-
-// SFSNextRowIter fsState = {0};
-// fsState.state = SFSNEXTROW_FS;
-// fsState.pTsdb = pTsdb;
-// fsState.pBlockIdxExp = &idx;
-
-// SMemNextRowIter memState = {0};
-// SMemNextRowIter imemState = {0};
-// TSDBROW memRow, imemRow, fsRow;
-
-// TsdbNextRowState input[3] = {{&memRow, true, false, &memState, getNextRowFromMem, NULL},
-// {&imemRow, true, false, &imemState, getNextRowFromMem, NULL},
-// {&fsRow, false, true, &fsState, getNextRowFromFS, clearNextRowFromFS}};
-
-// if (pMem) {
-// memState.pMem = pMem;
-// memState.state = SMEMNEXTROW_ENTER;
-// input[0].stop = false;
-// input[0].next = true;
-// }
-// if (pIMem) {
-// imemState.pMem = pIMem;
-// imemState.state = SMEMNEXTROW_ENTER;
-// input[1].stop = false;
-// input[1].next = true;
-// }
-
-// int16_t nilColCount = nCol - 1; // count of null & none cols
-// int iCol = 0; // index of first nil col index from left to right
-// bool setICol = false;
-
-// do {
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].next && !input[i].stop) {
-// if (input[i].pRow == NULL) {
-// code = input[i].nextRowFn(input[i].iter, &input[i].pRow);
-// if (code) goto _err;
-
-// if (input[i].pRow == NULL) {
-// input[i].stop = true;
-// input[i].next = false;
-// }
-// }
-// }
-// }
-
-// if (input[0].stop && input[1].stop && input[2].stop) {
-// break;
-// }
-
-// // select maxpoint(s) from mem, imem, fs
-// TSDBROW *max[3] = {0};
-// int iMax[3] = {-1, -1, -1};
-// int nMax = 0;
-// TSKEY maxKey = TSKEY_MIN;
-
-// for (int i = 0; i < 3; ++i) {
-// if (!input[i].stop && input[i].pRow != NULL) {
-// TSDBKEY key = TSDBROW_KEY(input[i].pRow);
-
-// // merging & deduplicating on client side
-// if (maxKey <= key.ts) {
-// if (maxKey < key.ts) {
-// nMax = 0;
-// maxKey = key.ts;
-// }
-
-// iMax[nMax] = i;
-// max[nMax++] = input[i].pRow;
-// }
-// }
-// }
-
-// // delete detection
-// TSDBROW *merge[3] = {0};
-// int iMerge[3] = {-1, -1, -1};
-// int nMerge = 0;
-// for (int i = 0; i < nMax; ++i) {
-// TSDBKEY maxKey = TSDBROW_KEY(max[i]);
-
-// bool deleted = tsdbKeyDeleted(&maxKey, pSkyline, &iSkyline);
-// if (!deleted) {
-// iMerge[nMerge] = i;
-// merge[nMerge++] = max[i];
-// }
-
-// input[iMax[i]].next = deleted;
-// }
-
-// // merge if nMerge > 1
-// if (nMerge > 0) {
-// *dup = false;
-
-// if (nMerge == 1) {
-// code = tsRowFromTsdbRow(pTSchema, merge[nMerge - 1], ppRow);
-// if (code) goto _err;
-// } else {
-// // merge 2 or 3 rows
-// SRowMerger merger = {0};
-
-// tRowMergerInit(&merger, merge[0], pTSchema);
-// for (int i = 1; i < nMerge; ++i) {
-// tRowMerge(&merger, merge[i]);
-// }
-// tRowMergerGetRow(&merger, ppRow);
-// tRowMergerClear(&merger);
-// }
-// }
-
-// } while (1);
-
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].nextRowClearFn) {
-// input[i].nextRowClearFn(input[i].iter);
-// }
-// }
-// if (pSkyline) {
-// taosArrayDestroy(pSkyline);
-// }
-// taosMemoryFreeClear(pTSchema);
-
-// return code;
-// _err:
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].nextRowClearFn) {
-// input[i].nextRowClearFn(input[i].iter);
-// }
-// }
-// if (pSkyline) {
-// taosArrayDestroy(pSkyline);
-// }
-// taosMemoryFreeClear(pTSchema);
-// tsdbError("vgId:%d merge last_row failed since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
-// return code;
-// }
-
-// static int32_t mergeLast(tb_uid_t uid, STsdb *pTsdb, STSRow **ppRow) {
-// static int32_t mergeLast(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray) {
-// int32_t code = 0;
-// SArray *pSkyline = NULL;
-// STSRow *pRow = NULL;
-// STSRow **ppRow = &pRow;
-
-// STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1);
-// int16_t nCol = pTSchema->numOfCols;
-// // SArray *pColArray = taosArrayInit(nCol, sizeof(SColVal));
-// SArray *pColArray = taosArrayInit(nCol, sizeof(SLastCol));
-
-// tb_uid_t suid = getTableSuidByUid(uid, pTsdb);
-
-// STbData *pMem = NULL;
-// if (pTsdb->mem) {
-// tsdbGetTbDataFromMemTable(pTsdb->mem, suid, uid, &pMem);
-// }
-
-// STbData *pIMem = NULL;
-// if (pTsdb->imem) {
-// tsdbGetTbDataFromMemTable(pTsdb->imem, suid, uid, &pIMem);
-// }
-
-// *ppLastArray = NULL;
-
-// pSkyline = taosArrayInit(32, sizeof(TSDBKEY));
-
-// SDelIdx delIdx;
-
-// SDelFile *pDelFile = tsdbFSStateGetDelFile(pTsdb->pFS->cState);
-// if (pDelFile) {
-// SDelFReader *pDelFReader;
-
-// code = tsdbDelFReaderOpen(&pDelFReader, pDelFile, pTsdb, NULL);
-// if (code) goto _err;
-
-// code = getTableDelIdx(pDelFReader, suid, uid, &delIdx);
-// if (code) goto _err;
-
-// code = getTableDelSkyline(pMem, pIMem, pDelFReader, &delIdx, pSkyline);
-// if (code) goto _err;
-
-// tsdbDelFReaderClose(&pDelFReader);
-// } else {
-// code = getTableDelSkyline(pMem, pIMem, NULL, NULL, pSkyline);
-// if (code) goto _err;
-// }
-
-// int64_t iSkyline = taosArrayGetSize(pSkyline) - 1;
-
-// SBlockIdx idx = {.suid = suid, .uid = uid};
-
-// SFSNextRowIter fsState = {0};
-// fsState.state = SFSNEXTROW_FS;
-// fsState.pTsdb = pTsdb;
-// fsState.pBlockIdxExp = &idx;
-
-// SMemNextRowIter memState = {0};
-// SMemNextRowIter imemState = {0};
-// TSDBROW memRow, imemRow, fsRow;
-
-// TsdbNextRowState input[3] = {{&memRow, true, false, &memState, getNextRowFromMem, NULL},
-// {&imemRow, true, false, &imemState, getNextRowFromMem, NULL},
-// {&fsRow, false, true, &fsState, getNextRowFromFS, clearNextRowFromFS}};
-
-// if (pMem) {
-// memState.pMem = pMem;
-// memState.state = SMEMNEXTROW_ENTER;
-// input[0].stop = false;
-// input[0].next = true;
-// }
-// if (pIMem) {
-// imemState.pMem = pIMem;
-// imemState.state = SMEMNEXTROW_ENTER;
-// input[1].stop = false;
-// input[1].next = true;
-// }
-
-// int16_t nilColCount = nCol - 1; // count of null & none cols
-// int iCol = 0; // index of first nil col index from left to right
-// bool setICol = false;
-
-// do {
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].next && !input[i].stop) {
-// code = input[i].nextRowFn(input[i].iter, &input[i].pRow);
-// if (code) goto _err;
-
-// if (input[i].pRow == NULL) {
-// input[i].stop = true;
-// input[i].next = false;
-// }
-// }
-// }
-
-// if (input[0].stop && input[1].stop && input[2].stop) {
-// break;
-// }
-
-// // select maxpoint(s) from mem, imem, fs
-// TSDBROW *max[3] = {0};
-// int iMax[3] = {-1, -1, -1};
-// int nMax = 0;
-// TSKEY maxKey = TSKEY_MIN;
-
-// for (int i = 0; i < 3; ++i) {
-// if (!input[i].stop && input[i].pRow != NULL) {
-// TSDBKEY key = TSDBROW_KEY(input[i].pRow);
-
-// // merging & deduplicating on client side
-// if (maxKey <= key.ts) {
-// if (maxKey < key.ts) {
-// nMax = 0;
-// maxKey = key.ts;
-// }
-
-// iMax[nMax] = i;
-// max[nMax++] = input[i].pRow;
-// }
-// }
-// }
-
-// // delete detection
-// TSDBROW *merge[3] = {0};
-// int iMerge[3] = {-1, -1, -1};
-// int nMerge = 0;
-// for (int i = 0; i < nMax; ++i) {
-// TSDBKEY maxKey = TSDBROW_KEY(max[i]);
-
-// bool deleted = tsdbKeyDeleted(&maxKey, pSkyline, &iSkyline);
-// if (!deleted) {
-// iMerge[nMerge] = iMax[i];
-// merge[nMerge++] = max[i];
-// }
-
-// input[iMax[i]].next = deleted;
-// }
-
-// // merge if nMerge > 1
-// if (nMerge > 0) {
-// if (nMerge == 1) {
-// code = tsRowFromTsdbRow(pTSchema, merge[nMerge - 1], ppRow);
-// if (code) goto _err;
-// } else {
-// // merge 2 or 3 rows
-// SRowMerger merger = {0};
-
-// tRowMergerInit(&merger, merge[0], pTSchema);
-// for (int i = 1; i < nMerge; ++i) {
-// tRowMerge(&merger, merge[i]);
-// }
-// tRowMergerGetRow(&merger, ppRow);
-// tRowMergerClear(&merger);
-// }
-// } else {
-// /* *ppRow = NULL; */
-// /* return code; */
-// continue;
-// }
-
-// if (iCol == 0) {
-// STColumn *pTColumn = &pTSchema->columns[0];
-// SColVal *pColVal = &(SColVal){0};
-
-// *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.ts = maxKey});
-
-// // if (taosArrayPush(pColArray, pColVal) == NULL) {
-// if (taosArrayPush(pColArray, &(SLastCol){.ts = maxKey, .colVal = *pColVal}) == NULL) {
-// code = TSDB_CODE_OUT_OF_MEMORY;
-// goto _err;
-// }
-
-// ++iCol;
-
-// setICol = false;
-// for (int16_t i = iCol; i < nCol; ++i) {
-// // tsdbRowGetColVal(*ppRow, pTSchema, i, pColVal);
-// tTSRowGetVal(*ppRow, pTSchema, i, pColVal);
-// // if (taosArrayPush(pColArray, pColVal) == NULL) {
-// if (taosArrayPush(pColArray, &(SLastCol){.ts = maxKey, .colVal = *pColVal}) == NULL) {
-// code = TSDB_CODE_OUT_OF_MEMORY;
-// goto _err;
-// }
-
-// if (pColVal->isNull || pColVal->isNone) {
-// for (int j = 0; j < nMerge; ++j) {
-// SColVal jColVal = {0};
-// tsdbRowGetColVal(merge[j], pTSchema, i, &jColVal);
-// if (jColVal.isNull || jColVal.isNone) {
-// input[iMerge[j]].next = true;
-// }
-// }
-// if (!setICol) {
-// iCol = i;
-// setICol = true;
-// }
-// } else {
-// --nilColCount;
-// }
-// }
-
-// if (*ppRow) {
-// taosMemoryFreeClear(*ppRow);
-// }
-
-// continue;
-// }
-
-// setICol = false;
-// for (int16_t i = iCol; i < nCol; ++i) {
-// SColVal colVal = {0};
-// tTSRowGetVal(*ppRow, pTSchema, i, &colVal);
-// TSKEY rowTs = (*ppRow)->ts;
-
-// // SColVal *tColVal = (SColVal *)taosArrayGet(pColArray, i);
-// SLastCol *tTsVal = (SLastCol *)taosArrayGet(pColArray, i);
-// SColVal *tColVal = &tTsVal->colVal;
-
-// if (!colVal.isNone && !colVal.isNull) {
-// if (tColVal->isNull || tColVal->isNone) {
-// // taosArraySet(pColArray, i, &colVal);
-// taosArraySet(pColArray, i, &(SLastCol){.ts = rowTs, .colVal = colVal});
-// --nilColCount;
-// }
-// } else {
-// if ((tColVal->isNull || tColVal->isNone) && !setICol) {
-// iCol = i;
-// setICol = true;
-
-// for (int j = 0; j < nMerge; ++j) {
-// SColVal jColVal = {0};
-// tsdbRowGetColVal(merge[j], pTSchema, i, &jColVal);
-// if (jColVal.isNull || jColVal.isNone) {
-// input[iMerge[j]].next = true;
-// }
-// }
-// }
-// }
-// }
-
-// if (*ppRow) {
-// taosMemoryFreeClear(*ppRow);
-// }
-// } while (nilColCount > 0);
-
-// // if () new ts row from pColArray if non empty
-// /* if (taosArrayGetSize(pColArray) == nCol) { */
-// /* code = tdSTSRowNew(pColArray, pTSchema, ppRow); */
-// /* if (code) goto _err; */
-// /* } */
-// /* taosArrayDestroy(pColArray); */
-// if (taosArrayGetSize(pColArray) <= 0) {
-// *ppLastArray = NULL;
-// taosArrayDestroy(pColArray);
-// } else {
-// *ppLastArray = pColArray;
-// }
-// if (*ppRow) {
-// taosMemoryFreeClear(*ppRow);
-// }
-
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].nextRowClearFn) {
-// input[i].nextRowClearFn(input[i].iter);
-// }
-// }
-// if (pSkyline) {
-// taosArrayDestroy(pSkyline);
-// }
-// taosMemoryFreeClear(pTSchema);
-
-// return code;
-// _err:
-// taosArrayDestroy(pColArray);
-// if (*ppRow) {
-// taosMemoryFreeClear(*ppRow);
-// }
-// for (int i = 0; i < 3; ++i) {
-// if (input[i].nextRowClearFn) {
-// input[i].nextRowClearFn(input[i].iter);
-// }
-// }
-// if (pSkyline) {
-// taosArrayDestroy(pSkyline);
-// }
-// taosMemoryFreeClear(pTSchema);
-// tsdbError("vgId:%d merge last_row failed since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
-// return code;
-// }
-
int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUHandle **handle) {
int32_t code = 0;
char key[32] = {0};
int keyLen = 0;
- // getTableCacheKey(uid, "lr", key, &keyLen);
+ // getTableCacheKeyS(uid, "lr", key, &keyLen);
getTableCacheKey(uid, 0, key, &keyLen);
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
if (h) {
- //*ppRow = (STSRow *)taosLRUCacheValue(pCache, h);
} else {
STSRow *pRow = NULL;
bool dup = false; // which is always false for now
- code = mergeLastRow2(uid, pTsdb, &dup, &pRow);
+ code = mergeLastRow(uid, pTsdb, &dup, &pRow);
// if table's empty or error, return code of -1
if (code < 0 || pRow == NULL) {
if (!dup && pRow) {
@@ -1680,9 +1122,7 @@ int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUH
code = -1;
}
- // tsdbCacheInsertLastrow(pCache, pTsdb, uid, pRow, dup);
h = taosLRUCacheLookup(pCache, key, keyLen);
- //*ppRow = (STSRow *)taosLRUCacheValue(pCache, h);
}
*handle = h;
@@ -1719,18 +1159,13 @@ int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUHand
char key[32] = {0};
int keyLen = 0;
- // getTableCacheKey(uid, "l", key, &keyLen);
+ // getTableCacheKeyS(uid, "l", key, &keyLen);
getTableCacheKey(uid, 1, key, &keyLen);
LRUHandle *h = taosLRUCacheLookup(pCache, key, keyLen);
if (h) {
- //*ppRow = (STSRow *)taosLRUCacheValue(pCache, h);
-
} else {
- // STSRow *pRow = NULL;
- // code = mergeLast(uid, pTsdb, &pRow);
SArray *pLastArray = NULL;
- // code = mergeLast(uid, pTsdb, &pLastArray);
- code = mergeLast2(uid, pTsdb, &pLastArray);
+ code = mergeLast(uid, pTsdb, &pLastArray);
// if table's empty or error, return code of -1
// if (code < 0 || pRow == NULL) {
if (code < 0 || pLastArray == NULL) {
@@ -1746,7 +1181,6 @@ int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, STsdb *pTsdb, LRUHand
}
h = taosLRUCacheLookup(pCache, key, keyLen);
- //*ppRow = (STSRow *)taosLRUCacheValue(pCache, h);
}
*handle = h;
diff --git a/source/libs/executor/src/joinoperator.c b/source/libs/executor/src/joinoperator.c
index 7b3c590f07469009511987abf8f5075973657961..8902804fab478e906484be5d54d0cd636d18b814 100644
--- a/source/libs/executor/src/joinoperator.c
+++ b/source/libs/executor/src/joinoperator.c
@@ -116,7 +116,8 @@ void destroyMergeJoinOperator(void* param, int32_t numOfOutput) {
}
static void mergeJoinJoinLeftRight(struct SOperatorInfo* pOperator, SSDataBlock* pRes, int32_t currRow,
- SSDataBlock* pLeftBlock, int32_t leftPos, SSDataBlock* pRightBlock, int32_t rightPos) {
+ SSDataBlock* pLeftBlock, int32_t leftPos, SSDataBlock* pRightBlock,
+ int32_t rightPos) {
SJoinOperatorInfo* pJoinInfo = pOperator->info;
for (int32_t i = 0; i < pOperator->exprSupp.numOfExprs; ++i) {
@@ -129,7 +130,7 @@ static void mergeJoinJoinLeftRight(struct SOperatorInfo* pOperator, SSDataBlock*
int32_t rowIndex = -1;
SColumnInfoData* pSrc = NULL;
- if (pJoinInfo->pLeft->info.blockId == blockId) {
+ if (pLeftBlock->info.blockId == blockId) {
pSrc = taosArrayGet(pLeftBlock->pDataBlock, slotId);
rowIndex = leftPos;
} else {
@@ -144,7 +145,128 @@ static void mergeJoinJoinLeftRight(struct SOperatorInfo* pOperator, SSDataBlock*
colDataAppend(pDst, currRow, p, false);
}
}
+}
+typedef struct SRowLocation {
+ SSDataBlock* pDataBlock;
+ int32_t pos;
+} SRowLocation;
+
+// pBlock[tsSlotId][startPos, endPos) == timestamp,
+static int32_t mergeJoinGetBlockRowsEqualTs(SSDataBlock* pBlock, int16_t tsSlotId, int32_t startPos, int64_t timestamp,
+ int32_t* pEndPos, SArray* rowLocations, SArray* createdBlocks) {
+ int32_t numRows = pBlock->info.rows;
+ ASSERT(startPos < numRows);
+ SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, tsSlotId);
+
+ int32_t i = startPos;
+ for (; i < numRows; ++i) {
+ char* pNextVal = colDataGetData(pCol, i);
+ if (timestamp != *(int64_t*)pNextVal) {
+ break;
+ }
+ }
+ int32_t endPos = i;
+ *pEndPos = endPos;
+
+ if (endPos - startPos == 0) {
+ return 0;
+ }
+
+ SSDataBlock* block = pBlock;
+ bool createdNewBlock = false;
+ if (endPos == numRows) {
+ block = blockDataExtractBlock(pBlock, startPos, endPos-startPos);
+ taosArrayPush(createdBlocks, &block);
+ createdNewBlock = true;
+ }
+ SRowLocation location = {0};
+ for (int32_t j = startPos; j < endPos; ++j) {
+ location.pDataBlock = block;
+ location.pos = ( createdNewBlock ? j - startPos : j);
+ taosArrayPush(rowLocations, &location);
+ }
+ return 0;
+}
+
+// whichChild == 0, left child of join; whichChild ==1, right child of join
+static int32_t mergeJoinGetDownStreamRowsEqualTimeStamp(SOperatorInfo* pOperator, int32_t whichChild, int16_t tsSlotId,
+ SSDataBlock* startDataBlock, int32_t startPos,
+ int64_t timestamp, SArray* rowLocations,
+ SArray* createdBlocks) {
+ ASSERT(whichChild == 0 || whichChild == 1);
+
+ SJoinOperatorInfo* pJoinInfo = pOperator->info;
+ int32_t endPos = -1;
+ SSDataBlock* dataBlock = startDataBlock;
+ mergeJoinGetBlockRowsEqualTs(dataBlock, tsSlotId, startPos, timestamp, &endPos, rowLocations, createdBlocks);
+ while (endPos == dataBlock->info.rows) {
+ SOperatorInfo* ds = pOperator->pDownstream[whichChild];
+ dataBlock = ds->fpSet.getNextFn(ds);
+ if (whichChild == 0) {
+ pJoinInfo->leftPos = 0;
+ pJoinInfo->pLeft = dataBlock;
+ } else if (whichChild == 1) {
+ pJoinInfo->rightPos = 0;
+ pJoinInfo->pRight = dataBlock;
+ }
+
+ if (dataBlock == NULL) {
+ setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED);
+ endPos = -1;
+ break;
+ }
+
+ mergeJoinGetBlockRowsEqualTs(dataBlock, tsSlotId, 0, timestamp, &endPos, rowLocations, createdBlocks);
+ }
+ if (endPos != -1) {
+ if (whichChild == 0) {
+ pJoinInfo->leftPos = endPos;
+ } else if (whichChild == 1) {
+ pJoinInfo->rightPos = endPos;
+ }
+ }
+ return 0;
+}
+
+static int32_t mergeJoinJoinDownstreamTsRanges(SOperatorInfo* pOperator, int64_t timestamp, SSDataBlock* pRes,
+ int32_t* nRows) {
+ SJoinOperatorInfo* pJoinInfo = pOperator->info;
+ SArray* leftRowLocations = taosArrayInit(8, sizeof(SRowLocation));
+ SArray* leftCreatedBlocks = taosArrayInit(8, POINTER_BYTES);
+
+ SArray* rightRowLocations = taosArrayInit(8, sizeof(SRowLocation));
+ SArray* rightCreatedBlocks = taosArrayInit(8, POINTER_BYTES);
+
+ mergeJoinGetDownStreamRowsEqualTimeStamp(pOperator, 0, pJoinInfo->leftCol.slotId, pJoinInfo->pLeft,
+ pJoinInfo->leftPos, timestamp, leftRowLocations, leftCreatedBlocks);
+ mergeJoinGetDownStreamRowsEqualTimeStamp(pOperator, 1, pJoinInfo->rightCol.slotId, pJoinInfo->pRight,
+ pJoinInfo->rightPos, timestamp, rightRowLocations, rightCreatedBlocks);
+
+ size_t leftNumJoin = taosArrayGetSize(leftRowLocations);
+ size_t rightNumJoin = taosArrayGetSize(rightRowLocations);
+ for (int32_t i = 0; i < leftNumJoin; ++i) {
+ for (int32_t j = 0; j < rightNumJoin; ++j) {
+ SRowLocation* leftRow = taosArrayGet(leftRowLocations, i);
+ SRowLocation* rightRow = taosArrayGet(rightRowLocations, j);
+ mergeJoinJoinLeftRight(pOperator, pRes, *nRows, leftRow->pDataBlock, leftRow->pos, rightRow->pDataBlock,
+ rightRow->pos);
+ ++*nRows;
+ }
+ }
+ for (int i = 0; i < taosArrayGetSize(rightCreatedBlocks); ++i) {
+ SSDataBlock* pBlock = taosArrayGetP(rightCreatedBlocks, i);
+ blockDataDestroy(pBlock);
+ }
+ taosArrayDestroy(rightCreatedBlocks);
+ taosArrayDestroy(rightRowLocations);
+ for (int i = 0; i < taosArrayGetSize(leftCreatedBlocks); ++i) {
+ SSDataBlock* pBlock = taosArrayGetP(leftCreatedBlocks, i);
+ blockDataDestroy(pBlock);
+ }
+ taosArrayDestroy(leftCreatedBlocks);
+ taosArrayDestroy(leftRowLocations);
+ return TSDB_CODE_SUCCESS;
}
static bool mergeJoinGetNextTimestamp(SOperatorInfo* pOperator, int64_t* pLeftTs, int64_t* pRightTs) {
@@ -195,18 +317,15 @@ static void doMergeJoinImpl(struct SOperatorInfo* pOperator, SSDataBlock* pRes)
while (1) {
int64_t leftTs = 0;
int64_t rightTs = 0;
- bool hasNextTs = mergeJoinGetNextTimestamp(pOperator, &leftTs, &rightTs);
+ bool hasNextTs = mergeJoinGetNextTimestamp(pOperator, &leftTs, &rightTs);
if (!hasNextTs) {
break;
}
if (leftTs == rightTs) {
- mergeJoinJoinLeftRight(pOperator, pRes, nrows,
- pJoinInfo->pLeft, pJoinInfo->leftPos, pJoinInfo->pRight, pJoinInfo->rightPos);
- pJoinInfo->leftPos += 1;
- pJoinInfo->rightPos += 1;
-
- nrows += 1;
+ mergeJoinJoinLeftRight(pOperator, pRes, nrows, pJoinInfo->pLeft, pJoinInfo->leftPos, pJoinInfo->pRight,
+ pJoinInfo->rightPos);
+ mergeJoinJoinDownstreamTsRanges(pOperator, leftTs, pRes, &nrows);
} else if (asc && leftTs < rightTs || !asc && leftTs > rightTs) {
pJoinInfo->leftPos += 1;
diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c
index 9a82b194a983b7d3ea188046924298cf1563738e..ed1580ed911e107dc4a8c8dcdb6179c8b1d466e5 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -2098,9 +2098,11 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot);
switch (pSliceInfo->fillType) {
- case TSDB_FILL_NULL:
+ case TSDB_FILL_NULL: {
colDataAppendNULL(pDst, rows);
+ pResBlock->info.rows += 1;
break;
+ }
case TSDB_FILL_SET_VALUE: {
SVariant* pVar = &pSliceInfo->pFillColInfo[j].fillVal;
@@ -2118,9 +2120,11 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
GET_TYPED_DATA(v, int64_t, pVar->nType, &pVar->i);
colDataAppend(pDst, rows, (char*)&v, false);
}
- } break;
+ pResBlock->info.rows += 1;
+ break;
+ }
- case TSDB_FILL_LINEAR:
+ case TSDB_FILL_LINEAR: {
#if 0
if (pCtx->start.key == INT64_MIN || pCtx->start.key > pCtx->startTs
|| pCtx->end.key == INT64_MIN || pCtx->end.key < pCtx->startTs) {
@@ -2151,17 +2155,22 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
}
}
#endif
+ // TODO: pResBlock->info.rows += 1;
break;
-
+ }
case TSDB_FILL_PREV: {
SGroupKeys* pkey = taosArrayGet(pSliceInfo->pPrevRow, srcSlot);
colDataAppend(pDst, rows, pkey->pData, false);
- } break;
+ pResBlock->info.rows += 1;
+ break;
+ }
case TSDB_FILL_NEXT: {
char* p = colDataGetData(pSrc, rowIndex);
colDataAppend(pDst, rows, p, colDataIsNull_s(pSrc, rowIndex));
- } break;
+ pResBlock->info.rows += 1;
+ break;
+ }
case TSDB_FILL_NONE:
default:
@@ -2169,7 +2178,6 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
}
}
- pResBlock->info.rows += 1;
}
static int32_t initPrevRowsKeeper(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) {
@@ -2221,6 +2229,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) {
SInterval* pInterval = &pSliceInfo->interval;
SOperatorInfo* downstream = pOperator->pDownstream[0];
+ blockDataCleanup(pResBlock);
+
int32_t numOfRows = 0;
while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
diff --git a/tests/script/tsim/parser/join_multivnode.sim b/tests/script/tsim/parser/join_multivnode.sim
index c33fa85fa255c732e7b358e2d9014d520a6beaac..f1204326d3c9de769b1fa68b4ce6c725478a18bf 100644
--- a/tests/script/tsim/parser/join_multivnode.sim
+++ b/tests/script/tsim/parser/join_multivnode.sim
@@ -98,6 +98,11 @@ while $i < $tbNum
endw
print ===============multivnode projection join.sim
+sql select join_mt0.ts,join_mt0.ts,join_mt0.t1 from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts;
+print ===> rows $row
+if $row != 9000 then
+ print expect 9000, actual: $row
+endi
sql select join_mt0.ts,join_mt0.ts,join_mt0.t1 from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts and join_mt0.t1=join_mt1.t1;
print ===> rows $row
if $row != 3000 then
diff --git a/tests/system-test/2-query/join.py b/tests/system-test/2-query/join.py
index 2348873a34283572116e6eb97760733d400c6914..9d30e1946a16c487f22e43fe03461d559dc7c945 100644
--- a/tests/system-test/2-query/join.py
+++ b/tests/system-test/2-query/join.py
@@ -377,11 +377,11 @@ class TDTestCase:
tdSql.query("select ct1.c_int from db.ct1 as ct1 join db1.ct1 as cy1 on ct1.ts=cy1.ts")
tdSql.checkRows(self.rows)
tdSql.query("select ct1.c_int from db.stb1 as ct1 join db1.ct1 as cy1 on ct1.ts=cy1.ts")
- tdSql.checkRows(self.rows)
+ tdSql.checkRows(self.rows + int(self.rows * 0.6 //3)+ int(self.rows * 0.8 // 4))
tdSql.query("select ct1.c_int from db.nt1 as ct1 join db1.nt1 as cy1 on ct1.ts=cy1.ts")
tdSql.checkRows(self.rows + 3)
tdSql.query("select ct1.c_int from db.stb1 as ct1 join db1.stb1 as cy1 on ct1.ts=cy1.ts")
- tdSql.checkRows(self.rows * 3 + 6)
+ tdSql.checkRows(50)
tdSql.query("select count(*) from db.ct1")
tdSql.checkData(0, 0, self.rows)
diff --git a/tests/system-test/7-tmq/tmq_taosx.py b/tests/system-test/7-tmq/tmq_taosx.py
index a4b662efcbd302cce4f78522d67bc3e90df058c0..4dc55d6b67ea23c7c210764cfc0977b031d1d863 100644
--- a/tests/system-test/7-tmq/tmq_taosx.py
+++ b/tests/system-test/7-tmq/tmq_taosx.py
@@ -43,9 +43,10 @@ class TDTestCase:
tdLog.exit("compare error: %s != %s"%src, dst)
else:
break
-
+
tdSql.execute('use db_taosx')
- tdSql.query("select * from ct3 order by c1 desc")
+
+ tdSql.query("select * from ct3 order by c1 desc")
tdSql.checkRows(2)
tdSql.checkData(0, 1, 51)
tdSql.checkData(0, 4, 940)
@@ -63,12 +64,12 @@ class TDTestCase:
tdSql.checkData(0, 3, "a")
tdSql.checkData(1, 4, None)
- tdSql.query("select * from n1")
+ tdSql.query("select * from n1 order by cc3 desc")
tdSql.checkRows(2)
tdSql.checkData(0, 1, "eeee")
tdSql.checkData(1, 2, 940)
- tdSql.query("select * from jt order by i desc;")
+ tdSql.query("select * from jt order by i desc")
tdSql.checkRows(2)
tdSql.checkData(0, 1, 11)
tdSql.checkData(0, 2, None)