diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8fe6cc69e05e47b9d9ecfd1b8534d215f597e033..b78b89690858b91a95273b67272b72b9dd771b0f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,7 @@ endif(${BUILD_TEST})
add_subdirectory(source)
add_subdirectory(tools)
add_subdirectory(tests)
-add_subdirectory(example)
+add_subdirectory(examples/c)
# docs
add_subdirectory(docs)
diff --git a/cmake/cmake.define b/cmake/cmake.define
index 5637c666b99294a536288741948877450cdb9eb5..8d71870e7d8ce3e554dd9c6810ea3829e5e9511a 100644
--- a/cmake/cmake.define
+++ b/cmake/cmake.define
@@ -46,7 +46,7 @@ ENDIF ()
IF (TD_WINDOWS)
MESSAGE("${Yellow} set compiler flag for Windows! ${ColourReset}")
- SET(COMMON_FLAGS "/w /D_WIN32 /Zi")
+ SET(COMMON_FLAGS "/w /D_WIN32 /DWIN32 /Zi")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
# IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
# SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
diff --git a/docs-cn/12-taos-sql/07-function.md b/docs-cn/12-taos-sql/07-function.md
index 2349e6aa3c02eb62fba1fc7e4eef15e08e3924d1..7674967f09fb0c9e3069097dbc2bf35e93256992 100644
--- a/docs-cn/12-taos-sql/07-function.md
+++ b/docs-cn/12-taos-sql/07-function.md
@@ -1,933 +1,682 @@
---
-sidebar_label: SQL 函数
-title: SQL 函数
+sidebar_label: 函数
+title: 函数
+toc_max_heading_level: 4
---
-## 聚合函数
+## 单行函数
-TDengine 支持针对数据的聚合查询。提供支持的聚合和选择函数如下:
+单行函数为查询结果中的每一行返回一个结果行。
-### COUNT
+### 数学函数
-```
-SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
-```
+#### ABS
-**功能说明**:统计表/超级表中记录行数或某列的非空值个数。
+```sql
+ SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
-**返回数据类型**:长整型 INT64。
+**功能说明**:获得指定列的绝对值
-**应用字段**:应用全部字段。
+**返回结果类型**:如果输入值为整数,输出值是 UBIGINT 类型。如果输入值是 FLOAT/DOUBLE 数据类型,输出值是 DOUBLE 数据类型。
-**适用于**:表、超级表。
+**适用数据类型**:数值类型。
-**使用说明**:
+**嵌套子查询支持**:适用于内层查询和外层查询。
-- 可以使用星号(\*)来替代具体的字段,使用星号(\*)返回全部记录数量。
-- 针对同一表的(不包含 NULL 值)字段查询结果均相同。
-- 如果统计对象是具体的列,则返回该列中非 NULL 值的记录数量。
+**适用于**: 表和超级表
-**示例**:
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-```
-taos> SELECT COUNT(*), COUNT(voltage) FROM meters;
- count(*) | count(voltage) |
-================================================
- 9 | 9 |
-Query OK, 1 row(s) in set (0.004475s)
+#### ACOS
-taos> SELECT COUNT(*), COUNT(voltage) FROM d1001;
- count(*) | count(voltage) |
-================================================
- 3 | 3 |
-Query OK, 1 row(s) in set (0.001075s)
+```sql
+ SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-### AVG
-
-```
-SELECT AVG(field_name) FROM tb_name [WHERE clause];
-```
+**功能说明**:获得指定列的反余弦结果
-**功能说明**:统计表/超级表中某列的平均值。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**返回数据类型**:双精度浮点数 Double。
+**适用数据类型**:数值类型。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 字段。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**:表、超级表。
+**适用于**: 表和超级表
-**示例**:
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-```
-taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM meters;
- avg(current) | avg(voltage) | avg(phase) |
-====================================================================================
- 11.466666751 | 220.444444444 | 0.293333333 |
-Query OK, 1 row(s) in set (0.004135s)
+#### ASIN
-taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM d1001;
- avg(current) | avg(voltage) | avg(phase) |
-====================================================================================
- 11.733333588 | 219.333333333 | 0.316666673 |
-Query OK, 1 row(s) in set (0.000943s)
+```sql
+ SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-### TWA
-
-```
-SELECT TWA(field_name) FROM tb_name WHERE clause;
-```
+**功能说明**:获得指定列的反正弦结果
-**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**返回数据类型**:双精度浮点数 Double。
+**适用数据类型**:数值类型。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**:表、超级表。
+**适用于**: 表和超级表
-**使用说明**:
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 从 2.1.3.0 版本开始,TWA 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
-### IRATE
+#### ATAN
-```
-SELECT IRATE(field_name) FROM tb_name WHERE clause;
+```sql
+ SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:计算瞬时增长率。使用时间区间中最后两个样本数据来计算瞬时增长速率;如果这两个值呈递减关系,那么只取最后一个数用于计算,而不是使用二者差值。
+**功能说明**:获得指定列的反正切结果
-**返回数据类型**:双精度浮点数 Double。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**使用说明**:
+**适用于**: 表和超级表
-- 从 2.1.3.0 版本开始此函数可用,IRATE 可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-### SUM
+
+#### CEIL
```
-SELECT SUM(field_name) FROM tb_name [WHERE clause];
+SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:统计表/超级表中某列的和。
+**功能说明**:获得指定列的向上取整数的结果。
-**返回数据类型**:双精度浮点数 Double 和长整型 INT64。
+**返回结果类型**:与指定列的原始数据类型一致。例如,如果指定列的原始数据类型为 Float,那么返回的数据类型也为 Float;如果指定列的原始数据类型为 Double,那么返回的数据类型也为 Double。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:数值类型。
-**适用于**:表、超级表。
+**适用于**: 普通表、超级表。
-**示例**:
+**嵌套子查询支持**:适用于内层查询和外层查询。
-```
-taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM meters;
- sum(current) | sum(voltage) | sum(phase) |
-================================================================================
- 103.200000763 | 1984 | 2.640000001 |
-Query OK, 1 row(s) in set (0.001702s)
+**使用说明**:
-taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM d1001;
- sum(current) | sum(voltage) | sum(phase) |
-================================================================================
- 35.200000763 | 658 | 0.950000018 |
-Query OK, 1 row(s) in set (0.000980s)
-```
+- 支持 +、-、\*、/ 运算,如 ceil(col1) + ceil(col2)。
+- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-### STDDEV
+#### COS
-```
-SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
+```sql
+ SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:统计表中某列的均方差。
+**功能说明**:获得指定列的余弦结果
-**返回数据类型**:双精度浮点数 Double。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:数值类型。
-**适用于**:表、超级表(从 2.0.15.1 版本开始)
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+**适用于**: 表和超级表
-**示例**:
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
+
+#### FLOOR
```
-taos> SELECT STDDEV(current) FROM d1001;
- stddev(current) |
-============================
- 1.020892909 |
-Query OK, 1 row(s) in set (0.000915s)
+SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-### LEASTSQUARES
+**功能说明**:获得指定列的向下取整数的结果。
+ 其他使用说明参见 CEIL 函数描述。
-```
-SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
+#### LOG
+
+```sql
+ SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:统计表中某列的值是主键(时间戳)的拟合直线方程。start_val 是自变量初始值,step_val 是自变量的步长值。
+**功能说明**:获得指定列对于底数 base 的对数
-**返回数据类型**:字符串表达式(斜率, 截距)。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:数值类型。
-**适用于**:表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**示例**:
+**适用于**: 表和超级表
-```
-taos> SELECT LEASTSQUARES(current, 1, 1) FROM d1001;
- leastsquares(current, 1, 1) |
-=====================================================
-{slop:1.000000, intercept:9.733334} |
-Query OK, 1 row(s) in set (0.000921s)
-```
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-### MODE
-```
-SELECT MODE(field_name) FROM tb_name [WHERE clause];
-```
+#### POW
-**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出空。不能匹配标签、时间戳输出。
+```sql
+ SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
+```
-**返回数据类型**:同应用的字段。
+**功能说明**:获得指定列的指数为 power 的幂
-**应用字段**:适合于除时间主列外的任何类型字段。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**使用说明**:由于返回数据量未知,考虑到内存因素,为了函数可以正常返回结果,建议不重复的数据量在 10 万级别,否则会报错。
+**适用数据类型**:数值类型。
-**支持的版本**:2.6.0.0 及以后的版本。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**示例**:
+**适用于**: 表和超级表
-```
-taos> select voltage from d002;
- voltage |
-========================
- 1 |
- 1 |
- 2 |
- 19 |
-Query OK, 4 row(s) in set (0.003545s)
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-taos> select mode(voltage) from d002;
- mode(voltage) |
-========================
- 1 |
-Query OK, 1 row(s) in set (0.019393s)
-```
-### HYPERLOGLOG
+#### ROUND
```
-SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
+SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:
- - 采用 hyperloglog 算法,返回某列的基数。该算法在数据量很大的情况下,可以明显降低内存的占用,但是求出来的基数是个估算值,标准误差(标准误差是多次实验,每次的平均数的标准差,不是与真实结果的误差)为 0.81%。
- - 在数据量较少的时候该算法不是很准确,可以使用 select count(data) from (select unique(col) as data from table) 的方法。
+**功能说明**:获得指定列的四舍五入的结果。
+ 其他使用说明参见 CEIL 函数描述。
-**返回结果类型**:整形。
-**应用字段**:适合于任何类型字段。
+#### SIN
-**支持的版本**:2.6.0.0 及以后的版本。
+```sql
+ SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
-**示例**:
+**功能说明**:获得指定列的正弦结果
-```
-taos> select dbig from shll;
- dbig |
-========================
- 1 |
- 1 |
- 1 |
- NULL |
- 2 |
- 19 |
- NULL |
- 9 |
-Query OK, 8 row(s) in set (0.003755s)
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-taos> select hyperloglog(dbig) from shll;
- hyperloglog(dbig)|
-========================
- 4 |
-Query OK, 1 row(s) in set (0.008388s)
-```
+**适用数据类型**:数值类型。
-### HISTOGRAM
+**嵌套子查询支持**:适用于内层查询和外层查询。
-```
-SELECT HISTOGRAM(field_name,bin_type, bin_description, normalized) FROM tb_name [WHERE clause];
-```
+**适用于**: 表和超级表
-**功能说明**:统计数据按照用户指定区间的分布。
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-**返回结果类型**:如归一化参数 normalized 设置为 1,返回结果为双精度浮点类型 DOUBLE,否则为长整形 INT64。
+#### SQRT
-**应用字段**:数值型字段。
+```sql
+ SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
-**支持的版本**:2.6.0.0 及以后的版本。
+**功能说明**:获得指定列的平方根
-**适用于**: 表和超级表。
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**说明**:
-1. bin_type 用户指定的分桶类型, 有效输入类型为"user_input“, ”linear_bin", "log_bin"。
-2. bin_description 描述如何生成分桶区间,针对三种桶类型,分别为以下描述格式(均为 JSON 格式字符串):
- - "user_input": "[1, 3, 5, 7]"
- 用户指定 bin 的具体数值。
-
- - "linear_bin": "{"start": 0.0, "width": 5.0, "count": 5, "infinity": true}"
- "start" 表示数据起始点,"width" 表示每次 bin 偏移量, "count" 为 bin 的总数,"infinity" 表示是否添加(-inf, inf)作为区间起点跟终点,
- 生成区间为[-inf, 0.0, 5.0, 10.0, 15.0, 20.0, +inf]。
-
- - "log_bin": "{"start":1.0, "factor": 2.0, "count": 5, "infinity": true}"
- "start" 表示数据起始点,"factor" 表示按指数递增的因子,"count" 为 bin 的总数,"infinity" 表示是否添加(-inf, inf)作为区间起点跟终点,
- 生成区间为[-inf, 1.0, 2.0, 4.0, 8.0, 16.0, +inf]。
-3. normalized 是否将返回结果归一化到 0~1 之间 。有效输入为 0 和 1。
+**适用数据类型**:数值类型。
-**示例**:
+**嵌套子查询支持**:适用于内层查询和外层查询。
-```mysql
-taos> SELECT HISTOGRAM(voltage, "user_input", "[1,3,5,7]", 1) FROM meters;
- histogram(voltage, "user_input", "[1,3,5,7]", 1) |
- =======================================================
- {"lower_bin":1, "upper_bin":3, "count":0.333333} |
- {"lower_bin":3, "upper_bin":5, "count":0.333333} |
- {"lower_bin":5, "upper_bin":7, "count":0.333333} |
- Query OK, 3 row(s) in set (0.004273s)
-
-taos> SELECT HISTOGRAM(voltage, 'linear_bin', '{"start": 1, "width": 3, "count": 3, "infinity": false}', 0) FROM meters;
- histogram(voltage, 'linear_bin', '{"start": 1, "width": 3, " |
- ===================================================================
- {"lower_bin":1, "upper_bin":4, "count":3} |
- {"lower_bin":4, "upper_bin":7, "count":3} |
- {"lower_bin":7, "upper_bin":10, "count":3} |
- Query OK, 3 row(s) in set (0.004887s)
-
-taos> SELECT HISTOGRAM(voltage, 'log_bin', '{"start": 1, "factor": 3, "count": 3, "infinity": true}', 0) FROM meters;
- histogram(voltage, 'log_bin', '{"start": 1, "factor": 3, "count" |
- ===================================================================
- {"lower_bin":-inf, "upper_bin":1, "count":3} |
- {"lower_bin":1, "upper_bin":3, "count":2} |
- {"lower_bin":3, "upper_bin":9, "count":6} |
- {"lower_bin":9, "upper_bin":27, "count":3} |
- {"lower_bin":27, "upper_bin":inf, "count":1} |
-```
+**适用于**: 表和超级表
-### ELAPSED
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-```mysql
-SELECT ELAPSED(field_name[, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
+#### TAN
+
+```sql
+ SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:elapsed函数表达了统计周期内连续的时间长度,和twa函数配合使用可以计算统计曲线下的面积。在通过INTERVAL子句指定窗口的情况下,统计在给定时间范围内的每个窗口内有数据覆盖的时间范围;如果没有INTERVAL子句,则返回整个给定时间范围内的有数据覆盖的时间范围。注意,ELAPSED返回的并不是时间范围的绝对值,而是绝对值除以time_unit所得到的单位个数。
+**功能说明**:获得指定列的正切结果
-**返回结果类型**:Double
+**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-**应用字段**:Timestamp类型
+**适用数据类型**:数值类型。
-**支持的版本**:2.6.0.0 及以后的版本。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**: 表,超级表,嵌套查询的外层查询
+**适用于**: 表和超级表
-**说明**:
-- field_name参数只能是表的第一列,即timestamp主键列。
-- 按time_unit参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit参数未指定时,以数据库的时间分辨率为时间单位。
-- 可以和interval组合使用,返回每个时间窗口的时间戳差值。需要特别注意的是,除第一个时间窗口和最后一个时间窗口外,中间窗口的时间戳差值均为窗口长度。
-- order by asc/desc不影响差值的计算结果。
-- 对于超级表,需要和group by tbname子句组合使用,不可以直接使用。
-- 对于普通表,不支持和group by子句组合使用。
-- 对于嵌套查询,仅当内层查询会输出隐式时间戳列时有效。例如select elapsed(ts) from (select diff(value) from sub1)语句,diff函数会让内层查询输出隐式时间戳列,此为主键列,可以用于elapsed函数的第一个参数。相反,例如select elapsed(ts) from (select * from sub1) 语句,ts列输出到外层时已经没有了主键列的含义,无法使用elapsed函数。此外,elapsed函数作为一个与时间线强依赖的函数,形如select elapsed(ts) from (select diff(value) from st group by tbname)尽管会返回一条计算结果,但并无实际意义,这种用法后续也将被限制。
-- 不支持与leastsquares、diff、derivative、top、bottom、last_row、interp等函数混合使用。
+**使用说明**:只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-## 选择函数
+### 字符串函数
-在使用所有的选择函数的时候,可以同时指定输出 ts 列或标签列(包括 tbname),这样就可以方便地知道被选出的值是源于哪个数据行的。
+字符串函数的输入参数为字符串类型,返回结果为数值类型或字符串类型。
-### MIN
+#### CHAR_LENGTH
```
-SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
+ SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:统计表/超级表中某列的值最小值。
-
-**返回数据类型**:同应用的字段。
-
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**功能说明**:以字符计数的字符串长度。
-**适用于**:表、超级表。
+**返回结果类型**:INT。如果输入值为NULL,输出值为NULL。
-**示例**:
+**适用数据类型**:VARCHAR, NCHAR
-```
-taos> SELECT MIN(current), MIN(voltage) FROM meters;
- min(current) | min(voltage) |
-======================================
- 10.20000 | 218 |
-Query OK, 1 row(s) in set (0.001765s)
+**嵌套子查询支持**:适用于内层查询和外层查询。
-taos> SELECT MIN(current), MIN(voltage) FROM d1001;
- min(current) | min(voltage) |
-======================================
- 10.30000 | 218 |
-Query OK, 1 row(s) in set (0.000950s)
-```
+**适用于**: 表和超级表
-### MAX
+#### CONCAT
+```sql
+ SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
```
-SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
-
-**功能说明**:统计表/超级表中某列的值最大值。
-**返回数据类型**:同应用的字段。
+**功能说明**:字符串连接函数。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**返回结果类型**:如果所有参数均为 VARCHAR 类型,则结果类型为 VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果输入值为NULL,输出值为NULL。
-**适用于**:表、超级表。
+**适用数据类型**:VARCHAR, NCHAR。 该函数最小参数个数为2个,最大参数个数为8个。
-**示例**:
+**嵌套子查询支持**:适用于内层查询和外层查询。
-```
-taos> SELECT MAX(current), MAX(voltage) FROM meters;
- max(current) | max(voltage) |
-======================================
- 13.40000 | 223 |
-Query OK, 1 row(s) in set (0.001123s)
+**适用于**: 表和超级表
-taos> SELECT MAX(current), MAX(voltage) FROM d1001;
- max(current) | max(voltage) |
-======================================
- 12.60000 | 221 |
-Query OK, 1 row(s) in set (0.000987s)
-```
-### FIRST
+#### CONCAT_WS
```
-SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
+ SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:统计表/超级表中某列的值最先写入的非 NULL 值。
+**功能说明**:带分隔符的字符串连接函数。
-**返回数据类型**:同应用的字段。
+**返回结果类型**:如果所有参数均为VARCHAR类型,则结果类型为VARCHAR。如果参数包含NCHAR类型,则结果类型为NCHAR。如果输入值为NULL,输出值为NULL。如果separator值不为NULL,其他输入为NULL,输出为空串。
-**应用字段**:所有字段。
+**适用数据类型**:VARCHAR, NCHAR。 该函数最小参数个数为3个,最大参数个数为9个。
-**适用于**:表、超级表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**使用说明**:
+**适用于**: 表和超级表
-- 如果要返回各个列的首个(时间戳最小)非 NULL 值,可以使用 FIRST(\*);
-- 如果结果集中的某列全部为 NULL 值,则该列的返回结果也是 NULL;
-- 如果结果集中所有列全部为 NULL 值,则不返回结果。
-**示例**:
+#### LENGTH
```
-taos> SELECT FIRST(*) FROM meters;
- first(ts) | first(current) | first(voltage) | first(phase) |
-=========================================================================================
-2018-10-03 14:38:04.000 | 10.20000 | 220 | 0.23000 |
-Query OK, 1 row(s) in set (0.004767s)
-
-taos> SELECT FIRST(current) FROM d1002;
- first(current) |
-=======================
- 10.20000 |
-Query OK, 1 row(s) in set (0.001023s)
+ SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-### LAST
+**功能说明**:以字节计数的字符串长度。
-```
-SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
+**返回结果类型**:INT。
-**功能说明**:统计表/超级表中某列的值最后写入的非 NULL 值。
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
-**返回数据类型**:同应用的字段。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**应用字段**:所有字段。
+**适用于**: 表和超级表
-**适用于**:表、超级表。
-**使用说明**:
+#### LOWER
-- 如果要返回各个列的最后(时间戳最大)一个非 NULL 值,可以使用 LAST(\*);
-- 如果结果集中的某列全部为 NULL 值,则该列的返回结果也是 NULL;如果结果集中所有列全部为 NULL 值,则不返回结果。
-- 在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。
+```
+ SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
+```
+**功能说明**:将字符串参数值转换为全小写字母。
-**示例**:
+**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
-```
-taos> SELECT LAST(*) FROM meters;
- last(ts) | last(current) | last(voltage) | last(phase) |
-========================================================================================
-2018-10-03 14:38:16.800 | 12.30000 | 221 | 0.31000 |
-Query OK, 1 row(s) in set (0.001452s)
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
-taos> SELECT LAST(current) FROM d1002;
- last(current) |
-=======================
- 10.30000 |
-Query OK, 1 row(s) in set (0.000843s)
-```
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+**适用于**: 表和超级表
-### TOP
+
+#### LTRIM
```
-SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
+ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**: 统计表/超级表中某列的值最大 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
+**功能说明**:返回清除左边空格后的字符串。
-**返回数据类型**:同应用的字段。
+**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
-**适用于**:表、超级表。
-
-**使用说明**:
-
-- *k*值取值范围 1≤*k*≤100;
-- 系统同时返回该记录关联的时间戳列;
-- 限制:TOP 函数不支持 FILL 子句。
-
-**示例**:
+**嵌套子查询支持**:适用于内层查询和外层查询。
-```
-taos> SELECT TOP(current, 3) FROM meters;
- ts | top(current, 3) |
-=================================================
-2018-10-03 14:38:15.000 | 12.60000 |
-2018-10-03 14:38:16.600 | 13.40000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 3 row(s) in set (0.001548s)
+**适用于**: 表和超级表
-taos> SELECT TOP(current, 2) FROM d1001;
- ts | top(current, 2) |
-=================================================
-2018-10-03 14:38:15.000 | 12.60000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 2 row(s) in set (0.000810s)
-```
-### BOTTOM
+#### RTRIM
```
-SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
+ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:统计表/超级表中某列的值最小 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
+**功能说明**:返回清除右边空格后的字符串。
-**返回数据类型**:同应用的字段。
+**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
-**适用于**:表、超级表。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**使用说明**:
+**适用于**: 表和超级表
-- *k*值取值范围 1≤*k*≤100;
-- 系统同时返回该记录关联的时间戳列;
-- 限制:BOTTOM 函数不支持 FILL 子句。
-**示例**:
+#### SUBSTR
```
-taos> SELECT BOTTOM(voltage, 2) FROM meters;
- ts | bottom(voltage, 2) |
-===============================================
-2018-10-03 14:38:15.000 | 218 |
-2018-10-03 14:38:16.650 | 218 |
-Query OK, 2 row(s) in set (0.001332s)
-
-taos> SELECT BOTTOM(current, 2) FROM d1001;
- ts | bottom(current, 2) |
-=================================================
-2018-10-03 14:38:05.000 | 10.30000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 2 row(s) in set (0.000793s)
+ SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
```
-### PERCENTILE
-
-```
-SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
-```
+**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。
-**功能说明**:统计表中某列的值百分比分位数。
+**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
-**返回数据类型**: 双精度浮点数 Double。
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。输入参数pos可以为正数,也可以为负数。如果pos是正数,表示开始位置从字符串开头正数计算。如果pos为负数,表示开始位置从字符串结尾倒数计算。如果输入参数len被忽略,返回的子串包含从pos开始的整个字串。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**适用于**:表。
+**适用于**: 表和超级表
-**使用说明**:*P*值取值范围 0≤*P*≤100,为 0 的时候等同于 MIN,为 100 的时候等同于 MAX。
-**示例**:
+#### UPPER
```
-taos> SELECT PERCENTILE(current, 20) FROM d1001;
-percentile(current, 20) |
-============================
- 11.100000191 |
-Query OK, 1 row(s) in set (0.000787s)
+ SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-### APERCENTILE
+**功能说明**:将字符串参数值转换为全大写字母。
-```
-SELECT APERCENTILE(field_name, P[, algo_type])
-FROM { tb_name | stb_name } [WHERE clause]
-```
+**返回结果类型**:同输入类型。如果输入值为NULL,输出值为NULL。
-**功能说明**:统计表/超级表中指定列的值百分比分位数,与 PERCENTILE 函数相似,但是返回近似结果。
+**适用数据类型**:输入参数是 VARCHAR 类型或者 NCHAR 类型的字符串或者列。
-**返回数据类型**: 双精度浮点数 Double。
+**嵌套子查询支持**:适用于内层查询和外层查询。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用于**: 表和超级表
-**适用于**:表、超级表。
-**使用说明**
+### 转换函数
-- **P**值有效取值范围 0≤P≤100,为 0 的时候等同于 MIN,为 100 的时候等同于 MAX;
-- **algo_type**的有效输入:**default** 和 **t-digest**
-- 用于指定计算近似分位数的算法。可不提供第三个参数的输入,此时将使用 default 的算法进行计算,即 apercentile(column_name, 50, "default") 与 apercentile(column_name, 50) 等价。
-- 当使用“t-digest”参数的时候,将使用 t-digest 方式采样计算近似分位数。但该参数指定计算算法的功能从 2.2.0.x 版本开始支持,2.2.0.0 之前的版本不支持指定使用算法的功能。
+转换函数将值从一种数据类型转换为另一种数据类型。
-**嵌套子查询支持**:适用于内层查询和外层查询。
+#### CAST
+```sql
+ SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
```
-taos> SELECT APERCENTILE(current, 20) FROM d1001;
-apercentile(current, 20) |
-============================
- 10.300000191 |
-Query OK, 1 row(s) in set (0.000645s)
-taos> select apercentile (count, 80, 'default') from stb1;
- apercentile (c0, 80, 'default') |
-==================================
- 601920857.210056424 |
-Query OK, 1 row(s) in set (0.012363s)
+**功能说明**:数据类型转换函数,输入参数 expression 支持普通列、常量、标量函数及它们之间的四则运算,只适用于 select 子句中。
-taos> select apercentile (count, 80, 't-digest') from stb1;
- apercentile (c0, 80, 't-digest') |
-===================================
- 605869120.966666579 |
-Query OK, 1 row(s) in set (0.011639s)
-```
+**返回结果类型**:CAST 中指定的类型(type_name),可以是 BIGINT、BIGINT UNSIGNED、BINARY、VARCHAR、NCHAR和TIMESTAMP。
-### LAST_ROW
+**适用数据类型**:输入参数 expression 的类型可以是BLOB、MEDIUMBLOB和JSON外的所有类型
-```
-SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
+**使用说明**:
+
+- 对于不能支持的类型转换会直接报错。
+- 如果输入值为NULL则输出值也为NULL。
+- 对于类型支持但某些值无法正确转换的情况对应的转换后的值以转换函数输出为准。目前可能遇到的几种情况:
+ 1)字符串类型转换数值类型时可能出现的无效字符情况,例如"a"可能转为0,但不会报错。
+ 2)转换到数值类型时,数值大于type_name可表示的范围时,则会溢出,但不会报错。
+ 3)转换到字符串类型时,如果转换后长度超过type_name的长度,则会截断,但不会报错。
+
+#### TO_ISO8601
+
+```sql
+SELECT TO_ISO8601(ts_val | ts_col) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:返回表/超级表的最后一条记录。
+**功能说明**:将 UNIX 时间戳转换成为 ISO8601 标准的日期时间格式,并附加客户端时区信息。
-**返回数据类型**:同应用的字段。
+**返回结果数据类型**:VARCHAR 类型。
-**应用字段**:所有字段。
+**适用数据类型**:UNIX 时间戳常量或是 TIMESTAMP 类型的列
**适用于**:表、超级表。
**使用说明**:
-- 在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。
-- 不能与 INTERVAL 一起使用。
+- 如果输入是 UNIX 时间戳常量,返回格式精度由时间戳的位数决定;
+- 如果输入是 TIMSTAMP 类型的列,返回格式的时间戳精度与当前 DATABASE 设置的时间精度一致。
-**示例**:
-```
- taos> SELECT LAST_ROW(current) FROM meters;
- last_row(current) |
- =======================
- 12.30000 |
- Query OK, 1 row(s) in set (0.001238s)
+#### TO_JSON
- taos> SELECT LAST_ROW(current) FROM d1002;
- last_row(current) |
- =======================
- 10.30000 |
- Query OK, 1 row(s) in set (0.001042s)
+```sql
+SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
```
-### INTERP [2.3.1 及之后的版本]
+**功能说明**: 将字符串常量转换为 JSON 类型。
-```
-SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] [ RANGE(timestamp1,timestamp2) ] [EVERY(interval)] [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
+**返回结果数据类型**: JSON
+
+**适用数据类型**: JSON 字符串,形如 '{ "literal" : literal }'。'{}'表示空值。键必须为字符串字面量,值可以为数值字面量、字符串字面量、布尔字面量或空值字面量。str_literal中不支持转义符。
+
+**适用于**: 表和超级表
+
+**嵌套子查询支持**:适用于内层查询和外层查询。
+
+
+#### TO_UNIXTIMESTAMP
+
+```sql
+SELECT TO_UNIXTIMESTAMP(datetime_string | ts_col) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:返回表/超级表的指定时间截面指定列的记录值(插值)。
+**功能说明**:将日期时间格式的字符串转换成为 UNIX 时间戳。
-**返回数据类型**:同字段类型。
+**返回结果数据类型**:长整型 INT64。
-**应用字段**:数值型字段。
+**应用字段**:字符串常量或是 VARCHAR/NCHAR 类型的列。
-**适用于**:表、超级表、嵌套查询。
+**适用于**:表、超级表。
+**使用说明**:
-**使用说明**
+- 输入的日期时间字符串须符合 ISO8601/RFC3339 标准,无法转换的字符串格式将返回 0。
+- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
-- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
-- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
-- INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1<=timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。如果没有指定 RANGE,那么满足过滤条件的输入数据中第一条记录的 timestamp 即为 timestamp1,最后一条记录的 timestamp 即为 timestamp2,同样也满足 timestamp1 <= timestamp2。
-- INTERP 根据 EVERY 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(EVERY 值)进行插值。如果没有指定 EVERY,则默认窗口大小为无穷大,即从 timestamp1 开始只有一个窗口。
-- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值,如果没有 FILL 字段则默认不插值,即输出为原始记录值或不输出(原始记录不存在)。
-- INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 group by tbname 一起使用,当作用嵌套查询外层时内层子查询不能含 GROUP BY 信息。
-- INTERP 的插值结果不受 ORDER BY timestamp 的影响,ORDER BY timestamp 只影响输出结果的排序。
-**SQL示例(基于文档中广泛使用的电表 schema )**:
+### 时间和日期函数
-- 单点线性插值
+时间和日期函数对时间戳类型进行操作。
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:40:00','2017-7-14 18:40:00') FILL(LINEAR);
-```
+所有返回当前时间的函数,如NOW、TODAY和TIMEZONE,在一条SQL语句中不论出现多少次都只会被计算一次。
-- 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行取值(不插值)
+#### NOW
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s);
+```sql
+SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
+SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
+INSERT INTO tb_name VALUES (NOW(), ...);
```
-- 在2017-07-14 18:00:00到2017-07-14 19:00:00间每隔5秒钟进行线性插值
+**功能说明**:返回客户端当前系统时间。
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
-```
+**返回结果数据类型**:TIMESTAMP 时间戳类型。
-- 在所有时间范围内每隔 5 秒钟进行向后插值
+**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
-```
- taos> SELECT INTERP(current) FROM t1 EVERY(5s) FILL(NEXT);
-```
+**适用于**:表、超级表。
-- 根据 2017-07-14 17:00:00 到 2017-07-14 20:00:00 间的数据进行从 2017-07-14 18:00:00 到 2017-07-14 19:00:00 间每隔 5 秒钟进行线性插值
+**使用说明**:
-```
- taos> SELECT INTERP(current) FROM t1 where ts >= '2017-07-14 17:00:00' and ts <= '2017-07-14 20:00:00' RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
-```
+- 支持时间加减操作,如 NOW() + 1s, 支持的时间单位如下:
+ b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。
+- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
-### INTERP [2.3.1 之前的版本]
-```
-SELECT INTERP(field_name) FROM { tb_name | stb_name } WHERE ts='timestamp' [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
+#### 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];
```
-**功能说明**:返回表/超级表的指定时间截面、指定字段的记录。
+**功能说明**:计算两个时间戳之间的差值,并近似到时间单位 time_unit 指定的精度。
-**返回数据类型**:同字段类型。
+**返回结果数据类型**:长整型 INT64。
-**应用字段**:数值型字段。
+**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
**适用于**:表、超级表。
-**使用说明**:
+**使用说明**:
+- 支持的时间单位 time_unit 如下:
+ 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
+- 如果时间单位 time_unit 未指定, 返回的时间差值精度与当前 DATABASE 设置的时间精度一致。
-- 从 2.0.15.0 及以后版本可用
-- INTERP 必须指定时间断面,如果该时间断面不存在直接对应的数据,那么会根据 FILL 参数的设定进行插值。此外,条件语句里面可附带筛选条件,例如标签、tbname。
-- INTERP 查询要求查询的时间区间必须位于数据集合(表)的所有记录的时间范围之内。如果给定的时间戳位于时间范围之外,即使有插值指令,仍然不返回结果。
-- 单个 INTERP 函数查询只能够针对一个时间点进行查询,如果需要返回等时间间隔的断面数据,可以通过 INTERP 配合 EVERY 的方式来进行查询处理(而不是使用 INTERVAL),其含义是每隔固定长度的时间进行插值
-**示例**:
+#### TIMETRUNCATE
-```
- taos> SELECT INTERP(*) FROM meters WHERE ts='2017-7-14 18:40:00.004';
- interp(ts) | interp(current) | interp(voltage) | interp(phase) |
- ==========================================================================================
- 2017-07-14 18:40:00.004 | 9.84020 | 216 | 0.32222 |
- Query OK, 1 row(s) in set (0.002652s)
+```sql
+SELECT TIMETRUNCATE(ts_val | datetime_string | ts_col, time_unit) FROM { tb_name | stb_name } [WHERE clause];
```
-如果给定的时间戳无对应的数据,在不指定插值生成策略的情况下,不会返回结果,如果指定了插值策略,会根据插值策略返回结果。
+**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
-```
- taos> SELECT INTERP(*) FROM meters WHERE tbname IN ('d636') AND ts='2017-7-14 18:40:00.005';
- Query OK, 0 row(s) in set (0.004022s)
+**返回结果数据类型**:TIMESTAMP 时间戳类型。
- taos> SELECT INTERP(*) FROM meters WHERE tbname IN ('d636') AND ts='2017-7-14 18:40:00.005' FILL(PREV);
- interp(ts) | interp(current) | interp(voltage) | interp(phase) |
- ==========================================================================================
- 2017-07-14 18:40:00.005 | 9.88150 | 217 | 0.32500 |
- Query OK, 1 row(s) in set (0.003056s)
-```
+**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
-如下所示代码表示在时间区间 `['2017-7-14 18:40:00', '2017-7-14 18:40:00.014']` 中每隔 5 毫秒 进行一次断面计算。
+**适用于**:表、超级表。
-```
- taos> SELECT INTERP(current) FROM d636 WHERE ts>='2017-7-14 18:40:00' AND ts<='2017-7-14 18:40:00.014' EVERY(5a);
- ts | interp(current) |
- =================================================
- 2017-07-14 18:40:00.000 | 10.04179 |
- 2017-07-14 18:40:00.010 | 10.16123 |
- Query OK, 2 row(s) in set (0.003487s)
-```
+**使用说明**:
+- 支持的时间单位 time_unit 如下:
+ 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
+- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
-### TAIL
-```
-SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
+#### TIMEZONE
+
+```sql
+SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:返回跳过最后 offset_val 个,然后取连续 k 个记录,不忽略 NULL 值。offset_val 可以不输入。此时返回最后的 k 个记录。当有 offset_val 输入的情况下,该函数功能等效于 `order by ts desc LIMIT k OFFSET offset_val`。
+**功能说明**:返回客户端当前时区信息。
-**参数范围**:k: [1,100] offset_val: [0,100]。
+**返回结果数据类型**:VARCHAR 类型。
-**返回结果数据类型**:同应用的字段。
+**应用字段**:无
-**应用字段**:适合于除时间主列外的任何类型字段。
+**适用于**:表、超级表。
-**支持版本**:2.6.0.0 及之后的版本。
-**示例**:
+#### TODAY
+```sql
+SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
+SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
+INSERT INTO tb_name VALUES (TODAY(), ...);
```
-taos> select ts,dbig from tail2;
- ts | dbig |
-==================================================
-2021-10-15 00:31:33.000 | 1 |
-2021-10-17 00:31:31.000 | NULL |
-2021-12-24 00:31:34.000 | 2 |
-2022-01-01 08:00:05.000 | 19 |
-2022-01-01 08:00:06.000 | NULL |
-2022-01-01 08:00:07.000 | 9 |
-Query OK, 6 row(s) in set (0.001952s)
-taos> select tail(dbig,2,2) from tail2;
-ts | tail(dbig,2,2) |
-==================================================
-2021-12-24 00:31:34.000 | 2 |
-2022-01-01 08:00:05.000 | 19 |
-Query OK, 2 row(s) in set (0.002307s)
-```
+**功能说明**:返回客户端当日零时的系统时间。
-### UNIQUE
+**返回结果数据类型**:TIMESTAMP 时间戳类型。
-```
-SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
-```
+**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
-**功能说明**:返回该列的数值首次出现的值。该函数功能与 distinct 相似,但是可以匹配标签和时间戳信息。可以针对除时间列以外的字段进行查询,可以匹配标签和时间戳,其中的标签和时间戳是第一次出现时刻的标签和时间戳。
+**适用于**:表、超级表。
-**返回结果数据类型**:同应用的字段。
+**使用说明**:
+
+- 支持时间加减操作,如 TODAY() + 1s, 支持的时间单位如下:
+ b(纳秒),u(微秒),a(毫秒),s(秒),m(分),h(小时),d(天),w(周)。
+- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
-**应用字段**:适合于除时间类型以外的字段。
-**支持版本**:2.6.0.0 及之后的版本。
+## 聚合函数
-**使用说明**:
+聚合函数为查询结果集的每一个分组返回单个结果行。可以由 GROUP BY 或窗口切分子句指定分组,如果没有,则整个查询结果集视为一个分组。
-- 该函数可以应用在普通表和超级表上。不能和窗口操作一起使用,例如 interval/state_window/session_window 。
-- 由于返回数据量未知,考虑到内存因素,为了函数可以正常返回结果,建议不重复的数据量在 10 万级别,否则会报错。
+TDengine 支持针对数据的聚合查询。提供如下聚合函数。
-**示例**:
+### AVG
```
-taos> select ts,voltage from unique1;
- ts | voltage |
-==================================================
-2021-10-17 00:31:31.000 | 1 |
-2022-01-24 00:31:31.000 | 1 |
-2021-10-17 00:31:31.000 | 1 |
-2021-12-24 00:31:31.000 | 2 |
-2022-01-01 08:00:01.000 | 19 |
-2021-10-17 00:31:31.000 | NULL |
-2022-01-01 08:00:02.000 | NULL |
-2022-01-01 08:00:03.000 | 9 |
-Query OK, 8 row(s) in set (0.003018s)
-
-taos> select unique(voltage) from unique1;
-ts | unique(voltage) |
-==================================================
-2021-10-17 00:31:31.000 | 1 |
-2021-10-17 00:31:31.000 | NULL |
-2021-12-24 00:31:31.000 | 2 |
-2022-01-01 08:00:01.000 | 19 |
-2022-01-01 08:00:03.000 | 9 |
-Query OK, 5 row(s) in set (0.108458s)
+SELECT AVG(field_name) FROM tb_name [WHERE clause];
```
-## 计算函数
+**功能说明**:统计表/超级表中某列的平均值。
-### DIFF
+**返回数据类型**:双精度浮点数 Double。
- ```sql
- SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
- ```
+**适用数据类型**:数值类型。
-**功能说明**:统计表中某列的值与前一行对应值的差。 ignore_negative 取值为 0|1 , 可以不填,默认值为 0. 不忽略负值。ignore_negative 为 1 时表示忽略负数。
+**适用于**:表、超级表。
+
+
+### COUNT
+
+```
+SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
+```
+
+**功能说明**:统计表/超级表中记录行数或某列的非空值个数。
-**返回结果数据类型**:同应用字段。
+**返回数据类型**:长整型 INT64。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:应用全部字段。
**适用于**:表、超级表。
**使用说明**:
-- 输出结果行数是范围内总行数减一,第一行没有结果输出。
-- 从 2.1.3.0 版本开始,DIFF 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
-- 从 2.6.0 开始,DIFF 函数支持 ignore_negative 参数
+- 可以使用星号(\*)来替代具体的字段,使用星号(\*)返回全部记录数量。
+- 针对同一表的(不包含 NULL 值)字段查询结果均相同。
+- 如果统计对象是具体的列,则返回该列中非 NULL 值的记录数量。
-**示例**:
- ```sql
- taos> SELECT DIFF(current) FROM d1001;
- ts | diff(current) |
- =================================================
- 2018-10-03 14:38:15.000 | 2.30000 |
- 2018-10-03 14:38:16.800 | -0.30000 |
- Query OK, 2 row(s) in set (0.001162s)
- ```
+### ELAPSED
-### DERIVATIVE
+```mysql
+SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
+```
+
+**功能说明**:elapsed函数表达了统计周期内连续的时间长度,和twa函数配合使用可以计算统计曲线下的面积。在通过INTERVAL子句指定窗口的情况下,统计在给定时间范围内的每个窗口内有数据覆盖的时间范围;如果没有INTERVAL子句,则返回整个给定时间范围内的有数据覆盖的时间范围。注意,ELAPSED返回的并不是时间范围的绝对值,而是绝对值除以time_unit所得到的单位个数。
+
+**返回结果类型**:Double
+
+**适用数据类型**:Timestamp类型
+
+**支持的版本**:2.6.0.0 及以后的版本。
+
+**适用于**: 表,超级表,嵌套查询的外层查询
+
+**说明**:
+- field_name参数只能是表的第一列,即timestamp主键列。
+- 按time_unit参数指定的时间单位返回,最小是数据库的时间分辨率。time_unit参数未指定时,以数据库的时间分辨率为时间单位。
+- 可以和interval组合使用,返回每个时间窗口的时间戳差值。需要特别注意的是,除第一个时间窗口和最后一个时间窗口外,中间窗口的时间戳差值均为窗口长度。
+- order by asc/desc不影响差值的计算结果。
+- 对于超级表,需要和group by tbname子句组合使用,不可以直接使用。
+- 对于普通表,不支持和group by子句组合使用。
+- 对于嵌套查询,仅当内层查询会输出隐式时间戳列时有效。例如select elapsed(ts) from (select diff(value) from sub1)语句,diff函数会让内层查询输出隐式时间戳列,此为主键列,可以用于elapsed函数的第一个参数。相反,例如select elapsed(ts) from (select * from sub1) 语句,ts列输出到外层时已经没有了主键列的含义,无法使用elapsed函数。此外,elapsed函数作为一个与时间线强依赖的函数,形如select elapsed(ts) from (select diff(value) from st group by tbname)尽管会返回一条计算结果,但并无实际意义,这种用法后续也将被限制。
+- 不支持与leastsquares、diff、derivative、top、bottom、last_row、interp等函数混合使用。
+
+### LEASTSQUARES
```
-SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
+SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
```
-**功能说明**:统计表中某列数值的单位变化率。其中单位时间区间的长度可以通过 time_interval 参数指定,最小可以是 1 秒(1s);ignore_negative 参数的值可以是 0 或 1,为 1 时表示忽略负值。
-
-**返回数据类型**:双精度浮点数。
+**功能说明**:统计表中某列的值是主键(时间戳)的拟合直线方程。start_val 是自变量初始值,step_val 是自变量的步长值。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**返回数据类型**:字符串表达式(斜率, 截距)。
-**适用于**:表、超级表
+**适用数据类型**:field_name 必须是数值类型。
-**使用说明**:
+**适用于**:表。
-- 从 2.1.3.0 及以后版本可用;输出结果行数是范围内总行数减一,第一行没有结果输出。
-- DERIVATIVE 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
-**示例**:
+### MODE
```
-taos> select derivative(current, 10m, 0) from t1;
- ts | derivative(current, 10m, 0) |
-========================================================
- 2021-08-20 10:11:22.790 | 0.500000000 |
- 2021-08-20 11:11:22.791 | 0.166666620 |
- 2021-08-20 12:11:22.791 | 0.000000000 |
- 2021-08-20 13:11:22.792 | 0.166666620 |
- 2021-08-20 14:11:22.792 | -0.666666667 |
-Query OK, 5 row(s) in set (0.004883s)
+SELECT MODE(field_name) FROM tb_name [WHERE clause];
```
+**功能说明**:返回出现频率最高的值,若存在多个频率相同的最高值,输出空。
+
+**返回数据类型**:同应用的字段。
+
+**适用数据类型**: 数值类型。
+
+**适用于**:表和超级表。
+
+
### SPREAD
```
@@ -938,945 +687,531 @@ SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
**返回数据类型**:双精度浮点数。
-**应用字段**:不能应用在 binary、nchar、bool 类型字段。
+**适用数据类型**:数值类型或TIMESTAMP类型。
-**适用于**:表、超级表。
+**适用于**:表和超级表。
-**使用说明**:可用于 TIMESTAMP 字段,此时表示记录的时间覆盖范围。
-**示例**:
+### STDDEV
```
-taos> SELECT SPREAD(voltage) FROM meters;
- spread(voltage) |
-============================
- 5.000000000 |
-Query OK, 1 row(s) in set (0.001792s)
-
-taos> SELECT SPREAD(voltage) FROM d1001;
- spread(voltage) |
-============================
- 3.000000000 |
-Query OK, 1 row(s) in set (0.000836s)
+SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
```
-### CEIL
+**功能说明**:统计表中某列的均方差。
-```
-SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
-
-**功能说明**:获得指定列的向上取整数的结果。
-
-**返回结果类型**:与指定列的原始数据类型一致。例如,如果指定列的原始数据类型为 Float,那么返回的数据类型也为 Float;如果指定列的原始数据类型为 Double,那么返回的数据类型也为 Double。
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列,无论 tag 列的类型是什么类型。
-
-**适用于**: 普通表、超级表。
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 支持 +、-、\*、/ 运算,如 ceil(col1) + ceil(col2)。
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-
-### FLOOR
-
-```
-SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
-
-**功能说明**:获得指定列的向下取整数的结果。
- 其他使用说明参见 CEIL 函数描述。
-
-### ROUND
-
-```
-SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
-
-**功能说明**:获得指定列的四舍五入的结果。
- 其他使用说明参见 CEIL 函数描述。
-
-### CSUM
-
-```sql
- SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
-```
-
- **功能说明**:累加和(Cumulative sum),输出行与输入行数相同。
-
- **返回结果类型**: 输入列如果是整数类型返回值为长整型 (int64_t),浮点数返回值为双精度浮点数(Double)。无符号整数类型返回值为无符号长整型(uint64_t)。 返回结果中同时带有每行记录对应的时间戳。
-
- **适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在标签之上。
-
- **嵌套子查询支持**: 适用于内层查询和外层查询。
-
- **使用说明**:
-
- - 不支持 +、-、*、/ 运算,如 csum(col1) + csum(col2)。
- - 只能与聚合(Aggregation)函数一起使用。 该函数可以应用在普通表和超级表上。
- - 使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
-
-**支持版本**: 从2.3.0.x开始支持
-
-### MAVG
-
-```sql
- SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
-```
-
- **功能说明**: 计算连续 k 个值的移动平均数(moving average)。如果输入行数小于 k,则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。
-
- **返回结果类型**: 返回双精度浮点数类型。
+**返回数据类型**:双精度浮点数 Double。
- **适用数据类型**: 不能应用在 timestamp、binary、nchar、bool 类型上;在超级表查询中使用时,不能应用在标签之上。
+**适用数据类型**:数值类型。
- **嵌套子查询支持**: 适用于内层查询和外层查询。
-
- **使用说明**:
-
- - 不支持 +、-、*、/ 运算,如 mavg(col1, k1) + mavg(col2, k1);
- - 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用;
- - 该函数可以应用在普通表和超级表上;使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
+**适用于**:表和超级表。
-**支持版本**: 从2.3.0.x开始支持
-### SAMPLE
+### SUM
-```sql
- SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
```
-
- **功能说明**: 获取数据的 k 个采样值。参数 k 的合法输入范围是 1≤ k ≤ 1000。
-
- **返回结果类型**: 同原始数据类型, 返回结果中带有该行记录的时间戳。
-
- **适用数据类型**: 在超级表查询中使用时,不能应用在标签之上。
-
- **嵌套子查询支持**: 适用于内层查询和外层查询。
-
- **使用说明**:
-
- - 不能参与表达式计算;该函数可以应用在普通表和超级表上;
- - 使用在超级表上的时候,需要搭配 Group by tbname 使用,将结果强制规约到单个时间线。
-
-**支持版本**: 从2.3.0.x开始支持
-
-### ASIN
-
-```sql
- SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT SUM(field_name) FROM tb_name [WHERE clause];
```
-**功能说明**:获得指定列的反正弦结果
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**功能说明**:统计表/超级表中某列的和。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
+**返回数据类型**:双精度浮点数 Double 和长整型 INT64。
-**嵌套子查询支持**:适用于内层查询和外层查询。
+**适用数据类型**:数值类型。
-**使用说明**:
+**适用于**:表和超级表。
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-### ACOS
+### HYPERLOGLOG
-```sql
- SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**功能说明**:获得指定列的反余弦结果
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### ATAN
-
-```sql
- SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:获得指定列的反正切结果
+**功能说明**:
+ - 采用 hyperloglog 算法,返回某列的基数。该算法在数据量很大的情况下,可以明显降低内存的占用,但是求出来的基数是个估算值,标准误差(标准误差是多次实验,每次的平均数的标准差,不是与真实结果的误差)为 0.81%。
+ - 在数据量较少的时候该算法不是很准确,可以使用 select count(data) from (select unique(col) as data from table) 的方法。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回结果类型**:整形。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
+**适用数据类型**:任何类型。
-**嵌套子查询支持**:适用于内层查询和外层查询。
+**适用于**:表和超级表。
-**使用说明**:
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### SIN
+### HISTOGRAM
-```sql
- SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**功能说明**:获得指定列的正弦结果
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### COS
-
-```sql
- SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT HISTOGRAM(field_name,bin_type, bin_description, normalized) FROM tb_name [WHERE clause];
```
-**功能说明**:获得指定列的余弦结果
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### TAN
+**功能说明**:统计数据按照用户指定区间的分布。
-```sql
- SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
-```
+**返回结果类型**:如归一化参数 normalized 设置为 1,返回结果为双精度浮点类型 DOUBLE,否则为长整形 INT64。
-**功能说明**:获得指定列的正切结果
+**适用数据类型**:数值型字段。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**适用于**: 表和超级表。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
+**详细说明**:
+1. bin_type 用户指定的分桶类型, 有效输入类型为"user_input“, ”linear_bin", "log_bin"。
+2. bin_description 描述如何生成分桶区间,针对三种桶类型,分别为以下描述格式(均为 JSON 格式字符串):
+ - "user_input": "[1, 3, 5, 7]"
+ 用户指定 bin 的具体数值。
+
+ - "linear_bin": "{"start": 0.0, "width": 5.0, "count": 5, "infinity": true}"
+ "start" 表示数据起始点,"width" 表示每次 bin 偏移量, "count" 为 bin 的总数,"infinity" 表示是否添加(-inf, inf)作为区间起点跟终点,
+ 生成区间为[-inf, 0.0, 5.0, 10.0, 15.0, 20.0, +inf]。
+
+ - "log_bin": "{"start":1.0, "factor": 2.0, "count": 5, "infinity": true}"
+ "start" 表示数据起始点,"factor" 表示按指数递增的因子,"count" 为 bin 的总数,"infinity" 表示是否添加(-inf, inf)作为区间起点跟终点,
+ 生成区间为[-inf, 1.0, 2.0, 4.0, 8.0, 16.0, +inf]。
+3. normalized 是否将返回结果归一化到 0~1 之间 。有效输入为 0 和 1。
-**嵌套子查询支持**:适用于内层查询和外层查询。
-**使用说明**:
+## 选择函数
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
+选择函数根据语义在查询结果集中选择一行或多行结果返回。用户可以同时指定输出 ts 列或其他列(包括 tbname 和标签列),这样就可以方便地知道被选出的值是源于哪个数据行的。
-### POW
+### APERCENTILE
-```sql
- SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**功能说明**:获得指定列的指数为 power 的幂
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### LOG
-
-```sql
- SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
+SELECT APERCENTILE(field_name, P[, algo_type])
+FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:获得指定列对于底数 base 的对数
-
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**功能说明**:统计表/超级表中指定列的值的近似百分比分位数,与 PERCENTILE 函数相似,但是返回近似结果。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
+**返回数据类型**: 双精度浮点数 Double。
-**使用说明**:
+**适用数据类型**:数值类型。P值范围是[0,100],当为0时等同于MIN,为100时等同于MAX。如果不指定 algo_type 则使用默认算法 。
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
+**适用于**:表、超级表。
-### ABS
+### BOTTOM
-```sql
- SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**功能说明**:获得指定列的绝对值
-
-**返回结果类型**:如果输入值为整数,输出值是 UBIGINT 类型。如果输入值是 FLOAT/DOUBLE 数据类型,输出值是 DOUBLE 数据类型。
-
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
-
-**嵌套子查询支持**:适用于内层查询和外层查询。
-
-**使用说明**:
-
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
-
-### SQRT
-
-```sql
- SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:获得指定列的平方根
+**功能说明**:统计表/超级表中某列的值最小 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
-**返回结果类型**:DOUBLE。如果输入值为 NULL,输出值也为 NULL
+**返回数据类型**:同应用的字段。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上;在超级表查询中使用时,不能应用在 tag 列
+**适用数据类型**:数值类型。
-**嵌套子查询支持**:适用于内层查询和外层查询。
+**适用于**:表和超级表。
-**使用说明**:
+**使用说明**:
-- 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
-- 该函数可以应用在普通表和超级表上。
-- 版本2.6.0.x后支持
+- *k*值取值范围 1≤*k*≤100;
+- 系统同时返回该记录关联的时间戳列;
+- 限制:BOTTOM 函数不支持 FILL 子句。
-### CAST
+### FIRST
-```sql
- SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**功能说明**:数据类型转换函数,输入参数 expression 支持普通列、常量、标量函数及它们之间的四则运算,不支持 tag 列,只适用于 select 子句中。
-
-**返回结果类型**:CAST 中指定的类型(type_name)。
-
-**适用数据类型**:
-
-- 输入参数 expression 的类型可以是除 JSON 外目前所有类型字段(BOOL/TINYINT/SMALLINT/INT/BIGINT/FLOAT/DOUBLE/BINARY(M)/TIMESTAMP/NCHAR(M)/TINYINT UNSIGNED/SMALLINT UNSIGNED/INT UNSIGNED/BIGINT UNSIGNED);
-- 输出目标类型只支持 BIGINT/BINARY(N)/TIMESTAMP/NCHAR(N)/BIGINT UNSIGNED。
-
-**使用说明**:
-
-- 对于不能支持的类型转换会直接报错。
-- 如果输入值为NULL则输出值也为NULL。
-- 对于类型支持但某些值无法正确转换的情况对应的转换后的值以转换函数输出为准。目前可能遇到的几种情况:
- 1)BINARY/NCHAR转BIGINT/BIGINT UNSIGNED时可能出现的无效字符情况,例如"a"可能转为0。
- 2)有符号数或TIMESTAMP转BIGINT UNSIGNED可能遇到的溢出问题。
- 3)BIGINT UNSIGNED转BIGINT可能遇到的溢出问题。
- 4)FLOAT/DOUBLE转BIGINT/BIGINT UNSIGNED可能遇到的溢出问题。
-- 版本2.6.0.x后支持
-
-### CONCAT
-
-```sql
- SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
+SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:字符串连接函数。
-
-**返回结果类型**:同输入参数类型,BINARY 或者 NCHAR。
-
-**适用数据类型**:输入参数或者全部是 BINARY 格式的字符串或者列,或者全部是 NCHAR 格式的字符串或者列。不能应用在 TAG 列。
-
-**使用说明**:
-
-- 如果输入值为NULL,输出值为NULL。
-- 该函数最小参数个数为2个,最大参数个数为8个。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
-
-### CONCAT_WS
-
-```
- SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
-```
+**功能说明**:统计表/超级表中某列的值最先写入的非 NULL 值。
-**功能说明**:带分隔符的字符串连接函数。
+**返回数据类型**:同应用的字段。
-**返回结果类型**:同输入参数类型,BINARY 或者 NCHAR。
+**适用数据类型**:所有字段。
-**适用数据类型**:输入参数或者全部是 BINARY 格式的字符串或者列,或者全部是 NCHAR 格式的字符串或者列。不能应用在 TAG 列。
+**适用于**:表和超级表。
-**使用说明**:
+**使用说明**:
-- 如果separator值为NULL,输出值为NULL。如果separator值不为NULL,其他输入为NULL,输出为空串
-- 该函数最小参数个数为3个,最大参数个数为9个。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
+- 如果要返回各个列的首个(时间戳最小)非 NULL 值,可以使用 FIRST(\*);
+- 如果结果集中的某列全部为 NULL 值,则该列的返回结果也是 NULL;
+- 如果结果集中所有列全部为 NULL 值,则不返回结果。
-### LENGTH
+### INTERP
```
- SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] [ RANGE(timestamp1,timestamp2) ] [EVERY(interval)] [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
```
-**功能说明**:以字节计数的字符串长度。
-
-**返回结果类型**:INT。
-
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
-
-**使用说明**
-
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
+**功能说明**:返回指定时间截面指定列的记录值或插值。
-### CHAR_LENGTH
-
-```
- SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
-```
-
-**功能说明**:以字符计数的字符串长度。
+**返回数据类型**:同字段类型。
-**返回结果类型**:INT。
+**适用数据类型**:数值类型。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**适用于**:表、超级表。
**使用说明**
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
+- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
+- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
+- INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1<=timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。如果没有指定 RANGE,那么满足过滤条件的输入数据中第一条记录的 timestamp 即为 timestamp1,最后一条记录的 timestamp 即为 timestamp2,同样也满足 timestamp1 <= timestamp2。
+- INTERP 根据 EVERY 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(EVERY 值)进行插值。如果没有指定 EVERY,则默认窗口大小为无穷大,即从 timestamp1 开始只有一个窗口。
+- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值,如果没有 FILL 字段则默认不插值,即输出为原始记录值或不输出(原始记录不存在)。
+- INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 group by tbname 一起使用,当作用嵌套查询外层时内层子查询不能含 GROUP BY 信息。
+- INTERP 的插值结果不受 ORDER BY timestamp 的影响,ORDER BY timestamp 只影响输出结果的排序。
-### LOWER
+### LAST
```
- SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:将字符串参数值转换为全小写字母。
+**功能说明**:统计表/超级表中某列的值最后写入的非 NULL 值。
-**返回结果类型**:同输入类型。
+**返回数据类型**:同应用的字段。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**适用数据类型**:所有字段。
-**使用说明**:
+**适用于**:表和超级表。
+
+**使用说明**:
+
+- 如果要返回各个列的最后(时间戳最大)一个非 NULL 值,可以使用 LAST(\*);
+- 如果结果集中的某列全部为 NULL 值,则该列的返回结果也是 NULL;如果结果集中所有列全部为 NULL 值,则不返回结果。
+- 在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
-### UPPER
+### LAST_ROW
```
- SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
```
-**功能说明**:将字符串参数值转换为全大写字母。
+**功能说明**:返回表/超级表的最后一条记录。
+
+**返回数据类型**:同应用的字段。
-**返回结果类型**:同输入类型。
+**适用数据类型**:所有字段。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**适用于**:表和超级表。
**使用说明**:
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
+- 在用于超级表时,时间戳完全一样且同为最大的数据行可能有多个,那么会从中随机返回一条,而并不保证多次运行所挑选的数据行必然一致。
+- 不能与 INTERVAL 一起使用。
-### LTRIM
+### MAX
```
- SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:返回清除左边空格后的字符串。
+**功能说明**:统计表/超级表中某列的值最大值。
-**返回结果类型**:同输入类型。
+**返回数据类型**:同应用的字段。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**适用数据类型**:数值类型。
-**使用说明**:
+**适用于**:表和超级表。
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
-### RTRIM
+### MIN
```
- SELECT RTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
```
-**功能说明**:返回清除右边空格后的字符串。
+**功能说明**:统计表/超级表中某列的值最小值。
-**返回结果类型**:同输入类型。
+**返回数据类型**:同应用的字段。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**适用数据类型**:数值类型。
-**使用说明**:
+**适用于**:表和超级表。
-- 如果输入值为NULL,输出值为NULL。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
-### SUBSTR
+### PERCENTILE
```
- SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
+SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
```
-**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。
+**功能说明**:统计表中某列的值百分比分位数。
-**返回结果类型**:同输入类型。
+**返回数据类型**: 双精度浮点数 Double。
-**适用数据类型**:输入参数是 BINARY 类型或者 NCHAR 类型的字符串或者列。不能应用在 TAG 列。
+**应用字段**:数值类型。
-**使用说明**:
+**适用于**:表。
+
+**使用说明**:*P*值取值范围 0≤*P*≤100,为 0 的时候等同于 MIN,为 100 的时候等同于 MAX。
-- 如果输入值为NULL,输出值为NULL。
-- 输入参数pos可以为正数,也可以为负数。如果pos是正数,表示开始位置从字符串开头正数计算。如果pos为负数,表示开始位置从字符串结尾倒数计算。如果输入参数len被忽略,返回的子串包含从pos开始的整个字串。
-- 该函数可以应用在普通表和超级表上。
-- 该函数适用于内层查询和外层查询。
-- 版本2.6.0.x后支持
-### 四则运算
+### TAIL
```
-SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name } [WHERE clause];
+SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
```
-**功能说明**:统计表/超级表中某列或多列间的值加、减、乘、除、取余计算结果。
+**功能说明**:返回跳过最后 offset_val 个,然后取连续 k 个记录,不忽略 NULL 值。offset_val 可以不输入。此时返回最后的 k 个记录。当有 offset_val 输入的情况下,该函数功能等效于 `order by ts desc LIMIT k OFFSET offset_val`。
-**返回数据类型**:双精度浮点数。
+**参数范围**:k: [1,100] offset_val: [0,100]。
+
+**返回数据类型**:同应用的字段。
-**应用字段**:不能应用在 timestamp、binary、nchar、bool 类型字段。
+**适用数据类型**:适合于除时间主列外的任何类型。
**适用于**:表、超级表。
-**使用说明**:
-- 支持两列或多列之间进行计算,可使用括号控制计算优先级;
-- NULL 字段不参与计算,如果参与计算的某行中包含 NULL,该行的计算结果为 NULL。
+### TOP
```
-taos> SELECT current + voltage * phase FROM d1001;
-(current+(voltage*phase)) |
-============================
- 78.190000713 |
- 84.540003240 |
- 80.810000718 |
-Query OK, 3 row(s) in set (0.001046s)
+SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
```
-### STATECOUNT
+**功能说明**: 统计表/超级表中某列的值最大 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
-```
-SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
-```
+**返回数据类型**:同应用的字段。
-**功能说明**:返回满足某个条件的连续记录的个数,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加 1,条件为 false 则重置为-1,如果数据为 NULL,跳过该条数据。
+**适用数据类型**:数值类型。
-**参数范围**:
+**适用于**:表、超级表。
-- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
-- val : 数值型
+**使用说明**:
-**返回结果类型**:整形。
+- *k*值取值范围 1≤*k*≤100;
+- 系统同时返回该记录关联的时间戳列;
+- 限制:TOP 函数不支持 FILL 子句。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上。
+### UNIQUE
-**嵌套子查询支持**:不支持应用在子查询上。
+```
+SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
+```
-**支持的版本**:2.6 开始的版本。
+**功能说明**:返回该列的数值首次出现的值。该函数功能与 distinct 相似,但是可以匹配标签和时间戳信息。可以针对除时间列以外的字段进行查询,可以匹配标签和时间戳,其中的标签和时间戳是第一次出现时刻的标签和时间戳。
-**使用说明**:
+**返回数据类型**:同应用的字段。
-- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
-- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
+**适用数据类型**:适合于除时间类型以外的字段。
-**示例**:
+**适用于**: 表和超级表。
-```
-taos> select ts,dbig from statef2;
- ts | dbig |
-========================================================
-2021-10-15 00:31:33.000000000 | 1 |
-2021-10-17 00:31:31.000000000 | NULL |
-2021-12-24 00:31:34.000000000 | 2 |
-2022-01-01 08:00:05.000000000 | 19 |
-2022-01-01 08:00:06.000000000 | NULL |
-2022-01-01 08:00:07.000000000 | 9 |
-Query OK, 6 row(s) in set (0.002977s)
-taos> select stateCount(dbig,GT,2) from statef2;
-ts | dbig | statecount(dbig,gt,2) |
-================================================================================
-2021-10-15 00:31:33.000000000 | 1 | -1 |
-2021-10-17 00:31:31.000000000 | NULL | NULL |
-2021-12-24 00:31:34.000000000 | 2 | -1 |
-2022-01-01 08:00:05.000000000 | 19 | 1 |
-2022-01-01 08:00:06.000000000 | NULL | NULL |
-2022-01-01 08:00:07.000000000 | 9 | 2 |
-Query OK, 6 row(s) in set (0.002791s)
-```
+## 时序数据特有函数
-### STATEDURATION
+时序数据特有函数是 TDengine 为了满足时序数据的查询场景而量身定做出来的。在通用数据库中,实现类似功能通常需要复杂的查询语法,且效率很低。TDengine 以函数的方式内置了这些功能,最大程度的减轻了用户的使用成本。
+
+### CSUM
```sql
-SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
+ SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:返回满足某个条件的连续记录的时间长度,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加上两个记录之间的时间长度(第一个满足条件的记录时间长度记为 0),条件为 false 则重置为-1,如果数据为 NULL,跳过该条数据。
-
-**参数范围**:
-
-- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
-- val : 数值型
-- unit : 时间长度的单位,范围[1s、1m、1h ],不足一个单位舍去。默认为 1s。
+**功能说明**:累加和(Cumulative sum),输出行与输入行数相同。
-**返回结果类型**:整形。
+**返回结果类型**: 输入列如果是整数类型返回值为长整型 (int64_t),浮点数返回值为双精度浮点数(Double)。无符号整数类型返回值为无符号长整型(uint64_t)。 返回结果中同时带有每行记录对应的时间戳。
-**适用数据类型**:不能应用在 timestamp、binary、nchar、bool 类型字段上。
+**适用数据类型**:数值类型。
-**嵌套子查询支持**:不支持应用在子查询上。
+**嵌套子查询支持**: 适用于内层查询和外层查询。
-**支持的版本**:2.6 开始的版本。
+**适用于**:表和超级表
-**使用说明**:
+**使用说明**:
+
+ - 不支持 +、-、*、/ 运算,如 csum(col1) + csum(col2)。
+ - 只能与聚合(Aggregation)函数一起使用。 该函数可以应用在普通表和超级表上。
+ - 使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
-- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
-- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
-**示例**:
+### DERIVATIVE
```
-taos> select ts,dbig from statef2;
- ts | dbig |
-========================================================
-2021-10-15 00:31:33.000000000 | 1 |
-2021-10-17 00:31:31.000000000 | NULL |
-2021-12-24 00:31:34.000000000 | 2 |
-2022-01-01 08:00:05.000000000 | 19 |
-2022-01-01 08:00:06.000000000 | NULL |
-2022-01-01 08:00:07.000000000 | 9 |
-Query OK, 6 row(s) in set (0.002407s)
-
-taos> select stateDuration(dbig,GT,2) from statef2;
-ts | dbig | stateduration(dbig,gt,2) |
-===================================================================================
-2021-10-15 00:31:33.000000000 | 1 | -1 |
-2021-10-17 00:31:31.000000000 | NULL | NULL |
-2021-12-24 00:31:34.000000000 | 2 | -1 |
-2022-01-01 08:00:05.000000000 | 19 | 0 |
-2022-01-01 08:00:06.000000000 | NULL | NULL |
-2022-01-01 08:00:07.000000000 | 9 | 2 |
-Query OK, 6 row(s) in set (0.002613s)
+SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
```
-## 时间函数
-
-从 2.6.0.0 版本开始,TDengine 查询引擎支持以下时间相关函数:
+**功能说明**:统计表中某列数值的单位变化率。其中单位时间区间的长度可以通过 time_interval 参数指定,最小可以是 1 秒(1s);ignore_negative 参数的值可以是 0 或 1,为 1 时表示忽略负值。
-### NOW
+**返回数据类型**:双精度浮点数。
-```sql
-SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
-SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
-INSERT INTO tb_name VALUES (NOW(), ...);
-```
+**适用数据类型**:数值类型。
-**功能说明**:返回客户端当前系统时间。
+**适用于**:表、超级表
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**使用说明**: DERIVATIVE 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
-**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
-**适用于**:表、超级表。
+### DIFF
-**使用说明**:
+ ```sql
+ SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
+ ```
-- 支持时间加减操作,如 NOW() + 1s, 支持的时间单位如下:
- b(纳秒)、u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。
-- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
+**功能说明**:统计表中某列的值与前一行对应值的差。 ignore_negative 取值为 0|1 , 可以不填,默认值为 0. 不忽略负值。ignore_negative 为 1 时表示忽略负数。
-**示例**:
+**返回数据类型**:同应用字段。
-```sql
-taos> SELECT NOW() FROM meters;
- now() |
-==========================
- 2022-02-02 02:02:02.456 |
-Query OK, 1 row(s) in set (0.002093s)
+**适用数据类型**:数值类型。
-taos> SELECT NOW() + 1h FROM meters;
- now() + 1h |
-==========================
- 2022-02-02 03:02:02.456 |
-Query OK, 1 row(s) in set (0.002093s)
+**适用于**:表、超级表。
-taos> SELECT COUNT(voltage) FROM d1001 WHERE ts < NOW();
- count(voltage) |
-=============================
- 5 |
-Query OK, 5 row(s) in set (0.004475s)
+**使用说明**: 输出结果行数是范围内总行数减一,第一行没有结果输出。
-taos> INSERT INTO d1001 VALUES (NOW(), 10.2, 219, 0.32);
-Query OK, 1 of 1 row(s) in database (0.002210s)
-```
-### TODAY
+### IRATE
-```sql
-SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
-SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
-INSERT INTO tb_name VALUES (TODAY(), ...);
+```
+SELECT IRATE(field_name) FROM tb_name WHERE clause;
```
-**功能说明**:返回客户端当日零时的系统时间。
+**功能说明**:计算瞬时增长率。使用时间区间中最后两个样本数据来计算瞬时增长速率;如果这两个值呈递减关系,那么只取最后一个数用于计算,而不是使用二者差值。
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**返回数据类型**:双精度浮点数 Double。
-**应用字段**:在 WHERE 或 INSERT 语句中使用时只能作用于 TIMESTAMP 类型的字段。
+**适用数据类型**:数值类型。
**适用于**:表、超级表。
-**使用说明**:
+### MAVG
-- 支持时间加减操作,如 TODAY() + 1s, 支持的时间单位如下:
- b(纳秒),u(微秒),a(毫秒),s(秒),m(分),h(小时),d(天),w(周)。
-- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
+```sql
+ SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
+```
-**示例**:
+ **功能说明**: 计算连续 k 个值的移动平均数(moving average)。如果输入行数小于 k,则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。
-```sql
-taos> SELECT TODAY() FROM meters;
- today() |
-==========================
- 2022-02-02 00:00:00.000 |
-Query OK, 1 row(s) in set (0.002093s)
+ **返回结果类型**: 返回双精度浮点数类型。
+
+ **适用数据类型**: 数值类型。
-taos> SELECT TODAY() + 1h FROM meters;
- today() + 1h |
-==========================
- 2022-02-02 01:00:00.000 |
-Query OK, 1 row(s) in set (0.002093s)
+ **嵌套子查询支持**: 适用于内层查询和外层查询。
-taos> SELECT COUNT(voltage) FROM d1001 WHERE ts < TODAY();
- count(voltage) |
-=============================
- 5 |
-Query OK, 5 row(s) in set (0.004475s)
+ **适用于**:表和超级表
-taos> INSERT INTO d1001 VALUES (TODAY(), 10.2, 219, 0.32);
-Query OK, 1 of 1 row(s) in database (0.002210s)
-```
+ **使用说明**:
+
+ - 不支持 +、-、*、/ 运算,如 mavg(col1, k1) + mavg(col2, k1);
+ - 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用;
+ - 使用在超级表上的时候,需要搭配 Group by tbname使用,将结果强制规约到单个时间线。
-### TIMEZONE
+### SAMPLE
```sql
-SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
+ SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
```
-**功能说明**:返回客户端当前时区信息。
+ **功能说明**: 获取数据的 k 个采样值。参数 k 的合法输入范围是 1≤ k ≤ 1000。
-**返回结果数据类型**:BINARY 类型。
+ **返回结果类型**: 同原始数据类型, 返回结果中带有该行记录的时间戳。
-**应用字段**:无
+ **适用数据类型**: 在超级表查询中使用时,不能应用在标签之上。
-**适用于**:表、超级表。
+ **嵌套子查询支持**: 适用于内层查询和外层查询。
-**示例**:
+ **适用于**:表和超级表
-```sql
-taos> SELECT TIMEZONE() FROM meters;
- timezone() |
-=================================
- UTC (UTC, +0000) |
-Query OK, 1 row(s) in set (0.002093s)
-```
+ **使用说明**:
+
+ - 不能参与表达式计算;该函数可以应用在普通表和超级表上;
+ - 使用在超级表上的时候,需要搭配 Group by tbname 使用,将结果强制规约到单个时间线。
-### TO_ISO8601
+### STATECOUNT
-```sql
-SELECT TO_ISO8601(ts_val | ts_col) FROM { tb_name | stb_name } [WHERE clause];
+```
+SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:将 UNIX 时间戳转换成为 ISO8601 标准的日期时间格式,并附加客户端时区信息。
+**功能说明**:返回满足某个条件的连续记录的个数,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加 1,条件为 false 则重置为-1,如果数据为 NULL,跳过该条数据。
-**返回结果数据类型**:BINARY 类型。
+**参数范围**:
-**应用字段**:UNIX 时间戳常量或是 TIMESTAMP 类型的列
+- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
+- val : 数值型
-**适用于**:表、超级表。
+**返回结果类型**:整形。
-**使用说明**:
+**适用数据类型**:数值类型。
-- 如果输入是 UNIX 时间戳常量,返回格式精度由时间戳的位数决定;
-- 如果输入是 TIMSTAMP 类型的列,返回格式的时间戳精度与当前 DATABASE 设置的时间精度一致。
+**嵌套子查询支持**:不支持应用在子查询上。
-**示例**:
+**适用于**:表和超级表。
-```sql
-taos> SELECT TO_ISO8601(1643738400) FROM meters;
- to_iso8601(1643738400) |
-==============================
- 2022-02-02T02:00:00+0800 |
+**使用说明**:
-taos> SELECT TO_ISO8601(ts) FROM meters;
- to_iso8601(ts) |
-==============================
- 2022-02-02T02:00:00+0800 |
- 2022-02-02T02:00:00+0800 |
- 2022-02-02T02:00:00+0800 |
-```
+- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
+- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
-### TO_UNIXTIMESTAMP
+
+### STATEDURATION
```sql
-SELECT TO_UNIXTIMESTAMP(datetime_string | ts_col) FROM { tb_name | stb_name } [WHERE clause];
+SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
```
-**功能说明**:将日期时间格式的字符串转换成为 UNIX 时间戳。
+**功能说明**:返回满足某个条件的连续记录的时间长度,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加上两个记录之间的时间长度(第一个满足条件的记录时间长度记为 0),条件为 false 则重置为-1,如果数据为 NULL,跳过该条数据。
-**返回结果数据类型**:长整型 INT64。
+**参数范围**:
+
+- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
+- val : 数值型
+- unit : 时间长度的单位,范围[1s、1m、1h ],不足一个单位舍去。默认为 1s。
-**应用字段**:字符串常量或是 BINARY/NCHAR 类型的列。
+**返回结果类型**:整形。
-**适用于**:表、超级表。
+**适用数据类型**:数值类型。
-**使用说明**:
+**嵌套子查询支持**:不支持应用在子查询上。
-- 输入的日期时间字符串须符合 ISO8601/RFC3339 标准,无法转换的字符串格式将返回 0。
-- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
+**适用于**:表和超级表。
-**示例**:
+**使用说明**:
-```sql
-taos> SELECT TO_UNIXTIMESTAMP("2022-02-02T02:00:00.000Z") FROM meters;
-to_unixtimestamp("2022-02-02T02:00:00.000Z") |
-==============================================
- 1643767200000 |
+- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
+- 不能和窗口操作一起使用,例如 interval/state_window/session_window。
-taos> SELECT TO_UNIXTIMESTAMP(col_binary) FROM meters;
- to_unixtimestamp(col_binary) |
-========================================
- 1643767200000 |
- 1643767200000 |
- 1643767200000 |
-```
-### TIMETRUNCATE
+### TWA
-```sql
-SELECT TIMETRUNCATE(ts_val | datetime_string | ts_col, time_unit) FROM { tb_name | stb_name } [WHERE clause];
+```
+SELECT TWA(field_name) FROM tb_name WHERE clause;
```
-**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
+**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。
-**返回结果数据类型**:TIMESTAMP 时间戳类型。
+**返回数据类型**:双精度浮点数 Double。
-**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
+**适用数据类型**:数值类型。
**适用于**:表、超级表。
-**使用说明**:
-- 支持的时间单位 time_unit 如下:
- 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
-- 返回的时间戳精度与当前 DATABASE 设置的时间精度一致。
+**使用说明**: TWA 函数可以在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)。
-**示例**:
-```sql
-taos> SELECT TIMETRUNCATE(1643738522000, 1h) FROM meters;
- timetruncate(1643738522000, 1h) |
-===================================
- 2022-02-02 02:00:00.000 |
-Query OK, 1 row(s) in set (0.001499s)
+## 系统信息函数
-taos> SELECT TIMETRUNCATE("2022-02-02 02:02:02", 1h) FROM meters;
- timetruncate("2022-02-02 02:02:02", 1h) |
-===========================================
- 2022-02-02 02:00:00.000 |
-Query OK, 1 row(s) in set (0.003903s)
+### DATABASE
-taos> SELECT TIMETRUNCATE(ts, 1h) FROM meters;
- timetruncate(ts, 1h) |
-==========================
- 2022-02-02 02:00:00.000 |
- 2022-02-02 02:00:00.000 |
- 2022-02-02 02:00:00.000 |
-Query OK, 3 row(s) in set (0.003903s)
+```
+SELECT DATABASE();
```
-### TIMEDIFF
+**说明**:返回当前登录的数据库。如果登录的时候没有指定默认数据库,且没有使用USE命令切换数据库,则返回NULL。
-```sql
-SELECT TIMEDIFF(ts_val1 | datetime_string1 | ts_col1, ts_val2 | datetime_string2 | ts_col2 [, time_unit]) FROM { tb_name | stb_name } [WHERE clause];
-```
-**功能说明**:计算两个时间戳之间的差值,并近似到时间单位 time_unit 指定的精度。
+### CLIENT_VERSION
-**返回结果数据类型**:长整型 INT64。
+```
+SELECT CLIENT_VERSION();
+```
-**应用字段**:UNIX 时间戳,日期时间格式的字符串,或者 TIMESTAMP 类型的列。
+**说明**:返回客户端版本。
-**适用于**:表、超级表。
+### SERVER_VERSION
-**使用说明**:
-- 支持的时间单位 time_unit 如下:
- 1u(微秒),1a(毫秒),1s(秒),1m(分),1h(小时),1d(天)。
-- 如果时间单位 time_unit 未指定, 返回的时间差值精度与当前 DATABASE 设置的时间精度一致。
+```
+SELECT SERVER_VERSION();
+```
-**支持的版本**:2.6.0.0 及以后的版本。
+**说明**:返回服务端版本。
-**示例**:
+### SERVER_STATUS
-```sql
-taos> SELECT TIMEDIFF(1643738400000, 1643742000000) FROM meters;
- timediff(1643738400000, 1643742000000) |
-=========================================
- 3600000 |
-Query OK, 1 row(s) in set (0.002553s)
-taos> SELECT TIMEDIFF(1643738400000, 1643742000000, 1h) FROM meters;
- timediff(1643738400000, 1643742000000, 1h) |
-=============================================
- 1 |
-Query OK, 1 row(s) in set (0.003726s)
-
-taos> SELECT TIMEDIFF("2022-02-02 03:00:00", "2022-02-02 02:00:00", 1h) FROM meters;
- timediff("2022-02-02 03:00:00", "2022-02-02 02:00:00", 1h) |
-=============================================================
- 1 |
-Query OK, 1 row(s) in set (0.001937s)
-
-taos> SELECT TIMEDIFF(ts_col1, ts_col2, 1h) FROM meters;
- timediff(ts_col1, ts_col2, 1h) |
-===================================
- 1 |
-Query OK, 1 row(s) in set (0.001937s)
```
+SELECT SERVER_VERSION();
+```
+
+**说明**:返回服务端当前的状态。
diff --git a/docs-cn/12-taos-sql/12-keywords/index.md b/docs-cn/12-taos-sql/12-keywords.md
similarity index 97%
rename from docs-cn/12-taos-sql/12-keywords/index.md
rename to docs-cn/12-taos-sql/12-keywords.md
index 0b9ec4de862fc6b6ade11e733a0f7b169a79a324..5c68e5da7e8c537e7514c5f9cfba43084d72189b 100644
--- a/docs-cn/12-taos-sql/12-keywords/index.md
+++ b/docs-cn/12-taos-sql/12-keywords.md
@@ -86,17 +86,20 @@ title: TDengine 参数限制与保留关键字
| CONNS | ID | NOTNULL | STABLE | WAL |
| COPY | IF | NOW | STABLES | WHERE |
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
-| _WSTOP | _WDURATION |
+| _WSTOP | _WDURATION | _ROWTS |
## 特殊说明
### TBNAME
`TBNAME` 可以视为超级表中一个特殊的标签,代表子表的表名。
获取一个超级表所有的子表名及相关的标签信息:
+
```mysql
SELECT TBNAME, location FROM meters;
+```
统计超级表下辖子表数量:
+
```mysql
SELECT COUNT(TBNAME) FROM meters;
```
@@ -119,10 +122,10 @@ taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2;
Query OK, 1 row(s) in set (0.001091s)
```
### _QSTART/_QSTOP/_QDURATION
-表示查询过滤窗口的起始,结束以及持续时间 (从2.6.0.0版本开始支持)
+表示查询过滤窗口的起始,结束以及持续时间。
### _WSTART/_WSTOP/_WDURATION
-窗口切分聚合查询(例如 interval/session window/state window)中表示每个切分窗口的起始,结束以及持续时间(从 2.6.0.0 版本开始支持)
+窗口切分聚合查询(例如 interval/session window/state window)中表示每个切分窗口的起始,结束以及持续时间。
-### _c0
-表示表或超级表的第一列
\ No newline at end of file
+### _c0/_ROWTS
+_c0 _ROWTS 等价,表示表或超级表的第一列
diff --git a/docs-cn/12-taos-sql/12-keywords/_category_.yml b/docs-cn/12-taos-sql/12-keywords/_category_.yml
deleted file mode 100644
index 67738650a4564477f017542aea81767b3de72922..0000000000000000000000000000000000000000
--- a/docs-cn/12-taos-sql/12-keywords/_category_.yml
+++ /dev/null
@@ -1 +0,0 @@
-label: 参数限制与保留关键字
\ No newline at end of file
diff --git a/docs-cn/12-taos-sql/13-operators.md b/docs-cn/12-taos-sql/13-operators.md
new file mode 100644
index 0000000000000000000000000000000000000000..22b78455fb35e9ebe5978b30505819e1a2b678c8
--- /dev/null
+++ b/docs-cn/12-taos-sql/13-operators.md
@@ -0,0 +1,66 @@
+---
+sidebar_label: 运算符
+title: 运算符
+---
+
+## 算术运算符
+
+| # | **运算符** | **支持的类型** | **说明** |
+| --- | :--------: | -------------- | -------------------------- |
+| 1 | +, - | 数值类型 | 表达正数和负数,一元运算符 |
+| 2 | +, - | 数值类型 | 表示加法和减法,二元运算符 |
+| 3 | \*, / | 数值类型 | 表示乘法和除法,二元运算符 |
+| 4 | % | 数值类型 | 表示取余运算,二元运算符 |
+
+## 位运算符
+
+| # | **运算符** | **支持的类型** | **说明** |
+| --- | :--------: | -------------- | ------------------ |
+| 1 | & | 数值类型 | 按位与,二元运算符 |
+| 2 | \| | 数值类型 | 按位或,二元运算符 |
+
+## JSON 运算符
+
+`->` 运算符可以对 JSON 类型的列按键取值。`->` 左侧是列标识符,右侧是键的字符串常量,如 `col->'name'`,返回键 `'name'` 的值。
+
+## 集合运算符
+
+集合运算符将两个查询的结果合并为一个结果。包含集合运算符的查询称之为复合查询。复合查询中每条查询的选择列表中的相应表达式在数量上必须匹配,且结果类型以第一条查询为准,后续查询的结果类型必须可转换到第一条查询的结果类型,转换规则同 CAST 函数。
+
+TDengine 支持 `UNION ALL` 和 `UNION` 操作符。UNION ALL 将查询返回的结果集合并返回,并不去重。UNION 将查询返回的结果集合并并去重后返回。在同一个 SQL 语句中,集合操作符最多支持 100 个。
+
+## 比较运算符
+
+| # | **运算符** | **支持的类型** | **说明** |
+| --- | :---------------: | -------------------------------------------------------------------- | -------------------- |
+| 1 | = | 除 BLOB、MEDIUMBLOB 和 JSON 外的所有类型 | 相等 |
+| 2 | <\>, != | 除 BLOB、MEDIUMBLOB 和 JSON 外的所有类型,且不可以为表的时间戳主键列 | 不相等 |
+| 3 | \>, < | 除 BLOB、MEDIUMBLOB 和 JSON 外的所有类型 | 大于,小于 |
+| 4 | \>=, <= | 除 BLOB、MEDIUMBLOB 和 JSON 外的所有类型 | 大于等于,小于等于 |
+| 5 | IS [NOT] NULL | 所有类型 | 是否为空值 |
+| 6 | [NOT] BETWEEN AND | 除 BOOL、BLOB、MEDIUMBLOB 和 JSON 外的所有类型 | 闭区间比较 |
+| 7 | IN | 除 BLOB、MEDIUMBLOB 和 JSON 外的所有类型,且不可以为表的时间戳主键列 | 与列表内的任意值相等 |
+| 8 | LIKE | BINARY、NCHAR 和 VARCHAR | 通配符匹配 |
+| 9 | MATCH, NMATCH | BINARY、NCHAR 和 VARCHAR | 正则表达式匹配 |
+| 10 | CONTAINS | JSON | JSON 中是否存在某键 |
+
+LIKE 条件使用通配符字符串进行匹配检查,规则如下:
+
+- '%'(百分号)匹配 0 到任意个字符;'\_'(下划线)匹配单个任意 ASCII 字符。
+- 如果希望匹配字符串中原本就带有的 \_(下划线)字符,那么可以在通配符字符串中写作 \_,即加一个反斜线来进行转义。
+- 通配符字符串最长不能超过 100 字节。不建议使用太长的通配符字符串,否则将有可能严重影响 LIKE 操作的执行性能。
+
+MATCH 条件和 NMATCH 条件使用正则表达式进行匹配,规则如下:
+
+- 支持符合 POSIX 规范的正则表达式,具体规范内容可参见 Regular Expressions。
+- 只能针对子表名(即 tbname)、字符串类型的标签值进行正则表达式过滤,不支持普通列的过滤。
+- 正则匹配字符串长度不能超过 128 字节。可以通过参数 maxRegexStringLen 设置和调整最大允许的正则匹配字符串,该参数是客户端配置参数,需要重启客户端才能生效
+
+## 逻辑运算符
+
+| # | **运算符** | **支持的类型** | **说明** |
+| --- | :--------: | -------------- | --------------------------------------------------------------------------- |
+| 1 | AND | BOOL | 逻辑与,如果两个条件均为 TRUE, 则返回 TRUE。如果任一为 FALSE,则返回 FALSE |
+| 2 | OR | BOOL | 逻辑或,如果任一条件为 TRUE, 则返回 TRUE。如果两者都是 FALSE,则返回 FALSE |
+
+TDengine 在计算逻辑条件时,会进行短路径优化,即对于 AND,第一个条件为 FALSE,则不再计算第二个条件,直接返回 FALSE;对于 OR,第一个条件为 TRUE,则不再计算第二个条件,直接返回 TRUE。
diff --git a/docs-cn/14-reference/03-connector/cpp.mdx b/docs-cn/14-reference/03-connector/cpp.mdx
index aba1d6c717dfec9228f38e89f90cbf1be0021045..aecf9fde12dfae8026d5f838d6467340a891f372 100644
--- a/docs-cn/14-reference/03-connector/cpp.mdx
+++ b/docs-cn/14-reference/03-connector/cpp.mdx
@@ -114,7 +114,6 @@ TDengine 客户端驱动的安装请参考 [安装指南](/reference/connector#
订阅和消费
```c
-{{#include examples/c/subscribe.c}}
```
diff --git a/docs-cn/14-reference/06-taosdump.md b/docs-cn/14-reference/06-taosdump.md
index 7131493ec9439225d8047288ed86026c887f0aac..3a9f2e9acd215be102991a1d91fba285ef6315bb 100644
--- a/docs-cn/14-reference/06-taosdump.md
+++ b/docs-cn/14-reference/06-taosdump.md
@@ -38,7 +38,7 @@ taosdump 有两种安装方式:
:::tip
- taosdump 1.4.1 之后的版本提供 `-I` 参数,用于解析 avro 文件 schema 和数据,如果指定 `-s` 参数将只解析 schema。
-- taosdump 1.4.2 之后的备份使用 `-B` 参数指定的批次数,默认值为 16384,如果在某些环境下由于网络速度或磁盘性能不足导致 "Error actual dump .. batch .." 可以通过 `-B` 参数挑战为更小的值进行尝试。
+- taosdump 1.4.2 之后的备份使用 `-B` 参数指定的批次数,默认值为 16384,如果在某些环境下由于网络速度或磁盘性能不足导致 "Error actual dump .. batch .." 可以通过 `-B` 参数调整为更小的值进行尝试。
:::
diff --git a/docs-cn/20-third-party/01-grafana.mdx b/docs-cn/20-third-party/01-grafana.mdx
index 328bd6bb4595a6d205cff45539d69e868d33d488..40b5c0ff4f2de8ff9eeb3afa61728ca7a899f5ea 100644
--- a/docs-cn/20-third-party/01-grafana.mdx
+++ b/docs-cn/20-third-party/01-grafana.mdx
@@ -18,21 +18,22 @@ TDengine 能够与开源数据可视化系统 [Grafana](https://www.grafana.com/
## 配置 Grafana
-TDengine 的 Grafana 插件托管在 GitHub,可从 下载,当前最新版本为 3.1.4。
-
-推荐使用 [`grafana-cli` 命令行工具](https://grafana.com/docs/grafana/latest/administration/cli/) 进行插件安装。
+使用 [`grafana-cli` 命令行工具](https://grafana.com/docs/grafana/latest/administration/cli/) 进行插件[安装](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation)。
```bash
-sudo -u grafana grafana-cli \
- --pluginUrl https://github.com/taosdata/grafanaplugin/releases/download/v3.1.7/tdengine-datasource-3.1.7.zip \
- plugins install tdengine-datasource
+grafana-cli plugins install tdengine-datasource
+# with sudo
+sudo -u grafana grafana-cli plugins install tdengine-datasource
```
-或者下载到本地并解压到 Grafana 插件目录。
+或者从 [GitHub](https://github.com/taosdata/grafanaplugin/releases/tag/latest) 或 [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) 下载 .zip 文件到本地并解压到 Grafana 插件目录。命令行下载示例如下:
```bash
-GF_VERSION=3.1.7
+GF_VERSION=3.2.2
+# from GitHub
wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/tdengine-datasource-$GF_VERSION.zip
+# from Grafana
+wget -O tdengine-datasource-$GF_VERSION.zip https://grafana.com/api/plugins/tdengine-datasource/versions/$GF_VERSION/download
```
以 CentOS 7.2 操作系统为例,将插件包解压到 /var/lib/grafana/plugins 目录下,重新启动 grafana 即可。
@@ -41,28 +42,17 @@ wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/td
sudo unzip tdengine-datasource-$GF_VERSION.zip -d /var/lib/grafana/plugins/
```
-:::note
-3.1.6 和更早版本未签名,会在 Grafana 7.3+ / 8.x 版本签名检查时失败导致无法加载插件,需要在 grafana.ini 文件中修改配置如下:
-
-```ini
-[plugins]
-allow_loading_unsigned_plugins = tdengine-datasource
-```
-
-:::
-
-在 Docker 环境下,可以使用如下的环境变量设置自动安装并设置 TDengine 插件:
+如果 Grafana 在 Docker 环境下运行,可以使用如下的环境变量设置自动安装 TDengine 数据源插件:
```bash
-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_INSTALL_PLUGINS=tdengine-datasource
```
## 使用 Grafana
### 配置数据源
-用户可以直接通过 http://localhost:3000 的网址,登录 Grafana 服务器(用户名/密码:admin/admin),通过左侧 `Configuration -> Data Sources` 可以添加数据源,如下图所示:
+用户可以直接通过 的网址,登录 Grafana 服务器(用户名/密码:admin/admin),通过左侧 `Configuration -> Data Sources` 可以添加数据源,如下图所示:

@@ -74,7 +64,7 @@ GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=tdengine-datasource

-- Host: TDengine 集群中提供 REST 服务 (在 2.4 之前由 taosd 提供, 从 2.4 开始由 taosAdapter 提供)的组件所在服务器的 IP 地址与 TDengine REST 服务的端口号(6041),默认 http://localhost:6041。
+- Host: TDengine 集群中提供 REST 服务 (在 2.4 之前由 taosd 提供, 从 2.4 开始由 taosAdapter 提供)的组件所在服务器的 IP 地址与 TDengine REST 服务的端口号(6041),默认 。
- User:TDengine 用户名。
- Password:TDengine 用户密码。
diff --git a/docs-en/12-taos-sql/07-function.md b/docs-en/12-taos-sql/07-function.md
index 3589efe9cdd618110203a8439ba03eaaf315f48c..129b7eb0c35b4409e8003855fb4facacb8e0c830 100644
--- a/docs-en/12-taos-sql/07-function.md
+++ b/docs-en/12-taos-sql/07-function.md
@@ -1,1963 +1,1253 @@
---
title: Functions
+toc_max_heading_level: 4
---
-## Aggregate Functions
-
-Aggregate queries are supported in TDengine by the following aggregate functions and selection functions.
-
-### COUNT
+## Single-Row Functions
-```
-SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
-```
+Single-Row functions return a result row for each row in the query result.
-**Description**: Get the number of rows or the number of non-null values in a table or a super table.
+### Numeric Functions
-**Return value type**: Long integer INT64
+#### ABS
-**Applicable column types**: All
+```sql
+SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
-**Applicable table types**: table, super table, sub table
+**Description**: The absolute of a specific column.
-**More explanation**:
+**Return value type**: UBIGINT if the input value is integer; DOUBLE if the input value is FLOAT/DOUBLE.
-- Wildcard (\*) is used to represent all columns. The `COUNT` function is used to get the total number of all rows.
-- The number of non-NULL values will be returned if this function is used on a specific column.
+**Applicable data types**: Numeric types.
-**Examples**:
+**Applicable table types**: table, STable.
-```
-taos> SELECT COUNT(*), COUNT(voltage) FROM meters;
- count(*) | count(voltage) |
-================================================
- 9 | 9 |
-Query OK, 1 row(s) in set (0.004475s)
+**Applicable nested query**: Inner query and Outer query.
-taos> SELECT COUNT(*), COUNT(voltage) FROM d1001;
- count(*) | count(voltage) |
-================================================
- 3 | 3 |
-Query OK, 1 row(s) in set (0.001075s)
-```
+**More explanations**:
+- Can't be used with aggregate functions.
-### AVG
+#### ACOS
-```
-SELECT AVG(field_name) FROM tb_name [WHERE clause];
+```sql
+SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: Get the average value of a column in a table or STable
+**Description**: The anti-cosine of a specific column
-**Return value type**: Double precision floating number
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: Numeric types.
**Applicable table types**: table, STable
-**Examples**:
-
-```
-taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM meters;
- avg(current) | avg(voltage) | avg(phase) |
-====================================================================================
- 11.466666751 | 220.444444444 | 0.293333333 |
-Query OK, 1 row(s) in set (0.004135s)
+**Applicable nested query**: Inner query and Outer query
-taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM d1001;
- avg(current) | avg(voltage) | avg(phase) |
-====================================================================================
- 11.733333588 | 219.333333333 | 0.316666673 |
-Query OK, 1 row(s) in set (0.000943s)
-```
+**More explanations**:
+- Can't be used with aggregate functions
-### TWA
+#### ASIN
-```
-SELECT TWA(field_name) FROM tb_name WHERE clause;
+```sql
+SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: Time weighted average on a specific column within a time range
+**Description**: The anti-sine of a specific column
-**Return value type**: Double precision floating number
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: Numeric types.
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Inner query and Outer query
-- Since version 2.1.3.0, function TWA can be used on stable with `GROUP BY`, i.e. timelines generated by `GROUP BY tbname` on a STable.
+**More explanations**:
+- Can't be used with aggregate functions
-### IRATE
+#### ATAN
-```
-SELECT IRATE(field_name) FROM tb_name WHERE clause;
+```sql
+SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: instantaneous rate on a specific column. The last two samples in the specified time range are used to calculate instantaneous rate. If the last sample value is smaller, then only the last sample value is used instead of the difference between the last two sample values.
+**Description**: anti-tangent of a specific column
-**Return value type**: Double precision floating number
+**Description**: The anti-cosine of a specific column
+
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: Numeric types.
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Inner query and Outer query
-- Since version 2.1.3.0, function IRATE can be used on stble with `GROUP BY`, i.e. timelines generated by `GROUP BY tbname` on a STable.
+**More explanations**:
+- Can't be used with aggregate functions
-### SUM
+#### CEIL
```
-SELECT SUM(field_name) FROM tb_name [WHERE clause];
+SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The sum of a specific column in a table or STable
+**Description**: The rounded up value of a specific column
-**Return value type**: Double precision floating number or long integer
+**Return value type**: Same as the column being used
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: Numeric types.
**Applicable table types**: table, STable
-**Examples**:
-
-```
-taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM meters;
- sum(current) | sum(voltage) | sum(phase) |
-================================================================================
- 103.200000763 | 1984 | 2.640000001 |
-Query OK, 1 row(s) in set (0.001702s)
+**Applicable nested query**: Inner query and outer query
-taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM d1001;
- sum(current) | sum(voltage) | sum(phase) |
-================================================================================
- 35.200000763 | 658 | 0.950000018 |
-Query OK, 1 row(s) in set (0.000980s)
-```
+**More explanations**:
+- Arithmetic operation can be performed on the result of `ceil` function
+- Can't be used with aggregate functions
-### STDDEV
+#### COS
-```
-SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
+```sql
+SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: Standard deviation of a specific column in a table or STable
+**Description**: The cosine of a specific column
-**Return value type**: Double precision floating number
+**Description**: The anti-cosine of a specific column
+
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: Numeric types.
-**Applicable table types**: table, STable (since version 2.0.15.1)
+**Applicable table types**: table, STable
-**Examples**:
+**Applicable nested query**: Inner query and Outer query
-```
-taos> SELECT STDDEV(current) FROM d1001;
- stddev(current) |
-============================
- 1.020892909 |
-Query OK, 1 row(s) in set (0.000915s)
-```
+**More explanations**:
+- Can't be used with aggregate functions
-### LEASTSQUARES
+#### FLOOR
```
-SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
+SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The linear regression function of the specified column and the timestamp column (primary key), `start_val` is the initial value and `step_val` is the step value.
-
-**Return value type**: A string in the format of "(slope, intercept)"
-
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
-
-**Applicable table types**: table only
-
-**Examples**:
+**Description**: The rounded down value of a specific column
-```
-taos> SELECT LEASTSQUARES(current, 1, 1) FROM d1001;
- leastsquares(current, 1, 1) |
-=====================================================
-{slop:1.000000, intercept:9.733334} |
-Query OK, 1 row(s) in set (0.000921s)
-```
+**More explanations**: The restrictions are same as those of the `CEIL` function.
-### MODE
+#### LOG
-```
-SELECT MODE(field_name) FROM tb_name [WHERE clause];
+```sql
+SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**:The value which has the highest frequency of occurrence. NULL is returned if there are multiple values which have highest frequency of occurrence. It can't be used on timestamp column or tags.
+**Description**: The log of a specific with `base` as the radix
-**Return value type**:Same as the data type of the column being operated upon
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable column types**:Data types except for timestamp
+**Applicable data types**: Numeric types.
-**More explanations**:Considering the number of returned result set is unpredictable, it's suggested to limit the number of unique values to 100,000, otherwise error will be returned.
+**Applicable table types**: table, STable
-**Applicable version**:Since version 2.6.0.0
+**Applicable nested query**: Inner query and Outer query
-**Examples**:
+**More explanations**:
+- Can't be used with aggregate functions
-```
-taos> select voltage from d002;
- voltage |
-========================
- 1 |
- 1 |
- 2 |
- 19 |
-Query OK, 4 row(s) in set (0.003545s)
+#### POW
-taos> select mode(voltage) from d002;
- mode(voltage) |
-========================
- 1 |
-Query OK, 1 row(s) in set (0.019393s)
+```sql
+SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
```
-### HYPERLOGLOG
-
-```
-SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Description**: The power of a specific column with `power` as the index
-**Description**:The cardinal number of a specific column is returned by using hyperloglog algorithm.
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Return value type**:Integer
+**Applicable data types**: Numeric types.
-**Applicable column types**:Any data type
+**Applicable table types**: table, STable
-**More explanations**: The benefit of using hyperloglog algorithm is that the memory usage is under control when the data volume is huge. However, when the data volume is very small, the result may be not accurate, it's recommented to use `select count(data) from (select unique(col) as data from table)` in this case.
+**Applicable nested query**: Inner query and Outer query
-**Applicable versions**:Since version 2.6.0.0
+**More explanations**:
+- Can't be used with aggregate functions
-**Examples**:
+#### ROUND
```
-taos> select dbig from shll;
- dbig |
-========================
- 1 |
- 1 |
- 1 |
- NULL |
- 2 |
- 19 |
- NULL |
- 9 |
-Query OK, 8 row(s) in set (0.003755s)
-
-taos> select hyperloglog(dbig) from shll;
- hyperloglog(dbig)|
-========================
- 4 |
-Query OK, 1 row(s) in set (0.008388s)
+SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-### HISTOGRAM
+**Description**: The rounded value of a specific column.
-```
-SELECT HISTOGRAM(field_name,bin_type, bin_description, normalized) FROM tb_name [WHERE clause];
+**More explanations**: The restrictions are same as `CEIL` function.
+
+#### SIN
+
+```sql
+SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**:Returns count of data points in user-specified ranges.
+**Description**: The sine of a specific column
-**Return value type**:Double or INT64, depends on normalized parameter settings.
+**Description**: The anti-cosine of a specific column
-**Applicable column type**:Numerical types.
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable versions**:Since version 2.6.0.0.
+**Applicable data types**: Numeric types.
**Applicable table types**: table, STable
-**Explanations**:
+**Applicable nested query**: Inner query and Outer query
-1. bin_type: parameter to indicate the bucket type, valid inputs are: "user_input", "linear_bin", "log_bin"。
-2. bin_description: parameter to describe how to generate buckets,can be in the following JSON formats for each bin_type respectively:
+**More explanations**:
+- Can't be used with aggregate functions
- - "user_input": "[1, 3, 5, 7]": User specified bin values.
+#### SQRT
- - "linear_bin": "{"start": 0.0, "width": 5.0, "count": 5, "infinity": true}"
- "start" - bin starting point.
- "width" - bin offset.
- "count" - number of bins generated.
- "infinity" - whether to add(-inf, inf)as start/end point in generated set of bins.
- The above "linear_bin" descriptor generates a set of bins: [-inf, 0.0, 5.0, 10.0, 15.0, 20.0, +inf].
+```sql
+SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
- - "log_bin": "{"start":1.0, "factor": 2.0, "count": 5, "infinity": true}"
- "start" - bin starting point.
- "factor" - exponential factor of bin offset.
- "count" - number of bins generated.
- "infinity" - whether to add(-inf, inf)as start/end point in generated range of bins.
- The above "log_bin" descriptor generates a set of bins:[-inf, 1.0, 2.0, 4.0, 8.0, 16.0, +inf].
+**Description**: The square root of a specific column
-3. normalized: setting to 1/0 to turn on/off result normalization.
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Example**:
+**Applicable data types**: Numeric types.
-```mysql
-taos> SELECT HISTOGRAM(voltage, "user_input", "[1,3,5,7]", 1) FROM meters;
- histogram(voltage, "user_input", "[1,3,5,7]", 1) |
- =======================================================
- {"lower_bin":1, "upper_bin":3, "count":0.333333} |
- {"lower_bin":3, "upper_bin":5, "count":0.333333} |
- {"lower_bin":5, "upper_bin":7, "count":0.333333} |
- Query OK, 3 row(s) in set (0.004273s)
-
-taos> SELECT HISTOGRAM(voltage, 'linear_bin', '{"start": 1, "width": 3, "count": 3, "infinity": false}', 0) FROM meters;
- histogram(voltage, 'linear_bin', '{"start": 1, "width": 3, " |
- ===================================================================
- {"lower_bin":1, "upper_bin":4, "count":3} |
- {"lower_bin":4, "upper_bin":7, "count":3} |
- {"lower_bin":7, "upper_bin":10, "count":3} |
- Query OK, 3 row(s) in set (0.004887s)
-
-taos> SELECT HISTOGRAM(voltage, 'log_bin', '{"start": 1, "factor": 3, "count": 3, "infinity": true}', 0) FROM meters;
- histogram(voltage, 'log_bin', '{"start": 1, "factor": 3, "count" |
- ===================================================================
- {"lower_bin":-inf, "upper_bin":1, "count":3} |
- {"lower_bin":1, "upper_bin":3, "count":2} |
- {"lower_bin":3, "upper_bin":9, "count":6} |
- {"lower_bin":9, "upper_bin":27, "count":3} |
- {"lower_bin":27, "upper_bin":inf, "count":1} |
-```
+**Applicable table types**: table, STable
-### ELAPSED
+**Applicable nested query**: Inner query and Outer query
-```mysql
-SELECT ELAPSED(field_name[, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
+**More explanations**:
+- Can't be used with aggregate functions
+
+#### TAN
+
+```sql
+SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**:`elapsed` function can be used to calculate the continuous time length in which there is valid data. If it's used with `INTERVAL` clause, the returned result is the calcualted time length within each time window. If it's used without `INTERVAL` caluse, the returned result is the calculated time length within the specified time range. Please be noted that the return value of `elapsed` is the number of `time_unit` in the calculated time length.
+**Description**: The tangent of a specific column
-**Return value type**:Double
+**Description**: The anti-cosine of a specific column
-**Applicable Column type**:Timestamp
+**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-**Applicable versions**:Sicne version 2.6.0.0
+**Applicable data types**: Numeric types.
-**Applicable tables**: table, STable, outter in nested query
+**Applicable table types**: table, STable
-**Explanations**:
-- `field_name` parameter can only be the first column of a table, i.e. timestamp primary key.
-- The minimum value of `time_unit` is the time precision of the database. If `time_unit` is not specified, the time precision of the database is used as the default ime unit.
-- It can be used with `INTERVAL` to get the time valid time length of each time window. Please be noted that the return value is same as the time window for all time windows except for the first and the last time window.
-- `order by asc/desc` has no effect on the result.
-- `group by tbname` must be used together when `elapsed` is used against a STable.
-- `group by` must NOT be used together when `elapsed` is used against a table or sub table.
-- When used in nested query, it's only applicable when the inner query outputs an implicit timestamp column as the primary key. For example, `select elapsed(ts) from (select diff(value) from sub1)` is legal usage while `select elapsed(ts) from (select * from sub1)` is not.
-- It can't be used with `leastsquares`, `diff`, `derivative`, `top`, `bottom`, `last_row`, `interp`.
+**Applicable nested query**: Inner query and Outer query
+
+**More explanations**:
+- Can't be used with aggregate functions
-## Selection Functions
+### String Functions
-When any select function is used, timestamp column or tag columns including `tbname` can be specified to show that the selected value are from which rows.
+String functiosn take strings as input and output numbers or strings.
-### MIN
+#### CHAR_LENGTH
```
-SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
+SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The minimum value of a specific column in a table or STable
+**Description**: The length in number of characters of a string
-**Return value type**: Same as the data type of the column being operated upon
+**Return value type**: Integer
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR or NCHAR
**Applicable table types**: table, STable
-**Examples**:
+**Applicable nested query**: Inner query and Outer query
-```
-taos> SELECT MIN(current), MIN(voltage) FROM meters;
- min(current) | min(voltage) |
-======================================
- 10.20000 | 218 |
-Query OK, 1 row(s) in set (0.001765s)
+**More explanations**
-taos> SELECT MIN(current), MIN(voltage) FROM d1001;
- min(current) | min(voltage) |
-======================================
- 10.30000 | 218 |
-Query OK, 1 row(s) in set (0.000950s)
-```
+- If the input value is NULL, the output is NULL too
-### MAX
+#### CONCAT
-```
-SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
+```sql
+SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The maximum value of a specific column of a table or STable
+**Description**: The concatenation result of two or more strings, the number of strings to be concatenated is at least 2 and at most 8
-**Return value type**: Same as the data type of the column being operated upon
+**Return value type**: If all input strings are VARCHAR type, the result is VARCHAR type too. If any one of input strings is NCHAR type, then the result is NCHAR.
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR, NCHAR. At least 2 input strings are requird, and at most 8 input strings are allowed.
**Applicable table types**: table, STable
-**Examples**:
-
-```
-taos> SELECT MAX(current), MAX(voltage) FROM meters;
- max(current) | max(voltage) |
-======================================
- 13.40000 | 223 |
-Query OK, 1 row(s) in set (0.001123s)
-
-taos> SELECT MAX(current), MAX(voltage) FROM d1001;
- max(current) | max(voltage) |
-======================================
- 12.60000 | 221 |
-Query OK, 1 row(s) in set (0.000987s)
-```
+**Applicable nested query**: Inner query and Outer query
-### FIRST
+#### CONCAT_WS
```
-SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
+SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The first non-null value of a specific column in a table or STable
+**Description**: The concatenation result of two or more strings with separator, the number of strings to be concatenated is at least 3 and at most 9
-**Return value type**: Same as the column being operated upon
+**Return value type**: If all input strings are VARCHAR type, the result is VARCHAR type too. If any one of input strings is NCHAR type, then the result is NCHAR.
-**Applicable column types**: Any data type
+**Applicable data types**: VARCHAR, NCHAR. At least 3 input strings are requird, and at most 9 input strings are allowed.
**Applicable table types**: table, STable
+**Applicable nested query**: Inner query and Outer query
+
**More explanations**:
-- FIRST(\*) can be used to get the first non-null value of all columns
-- NULL will be returned if all the values of the specified column are all NULL
-- A result will NOT be returned if all the columns in the result set are all NULL
+- If the value of `separator` is NULL, the output is NULL. If the value of `separator` is not NULL but other input are all NULL, the output is empty string.
-**Examples**:
+#### LENGTH
```
-taos> SELECT FIRST(*) FROM meters;
- first(ts) | first(current) | first(voltage) | first(phase) |
-=========================================================================================
-2018-10-03 14:38:04.000 | 10.20000 | 220 | 0.23000 |
-Query OK, 1 row(s) in set (0.004767s)
-
-taos> SELECT FIRST(current) FROM d1002;
- first(current) |
-=======================
- 10.20000 |
-Query OK, 1 row(s) in set (0.001023s)
+SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-### LAST
+**Description**: The length in bytes of a string
-```
-SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Return value type**: Integer
-**Description**: The last non-NULL value of a specific column in a table or STable
+**Applicable data types**: VARCHAR or NCHAR
+**Applicable table types**: table, STable
-**Return value type**: Same as the column being operated upon
+**Applicable nested query**: Inner query and Outer query
-**Applicable column types**: Any data type
+**More explanations**
-**Applicable table types**: table, STable
+- If the input value is NULL, the output is NULL too
-**More explanations**:
-
-- LAST(\*) can be used to get the last non-NULL value of all columns
-- If the values of a column in the result set are all NULL, NULL is returned for that column; if all columns in the result are all NULL, no result will be returned.
-- When it's used on a STable, if there are multiple values with the timestamp in the result set, one of them will be returned randomly and it's not guaranteed that the same value is returned if the same query is run multiple times.
-
-**Examples**:
-
-```
-taos> SELECT LAST(*) FROM meters;
- last(ts) | last(current) | last(voltage) | last(phase) |
-========================================================================================
-2018-10-03 14:38:16.800 | 12.30000 | 221 | 0.31000 |
-Query OK, 1 row(s) in set (0.001452s)
+#### LOWER
-taos> SELECT LAST(current) FROM d1002;
- last(current) |
-=======================
- 10.30000 |
-Query OK, 1 row(s) in set (0.000843s)
```
-
-### TOP
-
-```
-SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
+SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The greatest _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
+**Description**: Convert the input string to lower case
-**Return value type**: Same as the column being operated upon
+**Return value type**: Same as input
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR or NCHAR
**Applicable table types**: table, STable
-**More explanations**:
-
-- _k_ must be in range [1,100]
-- The timestamp associated with the selected values are returned too
-- Can't be used with `FILL`
-
-**Examples**:
+**Applicable nested query**: Inner query and Outer query
-```
-taos> SELECT TOP(current, 3) FROM meters;
- ts | top(current, 3) |
-=================================================
-2018-10-03 14:38:15.000 | 12.60000 |
-2018-10-03 14:38:16.600 | 13.40000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 3 row(s) in set (0.001548s)
+**More explanations**
-taos> SELECT TOP(current, 2) FROM d1001;
- ts | top(current, 2) |
-=================================================
-2018-10-03 14:38:15.000 | 12.60000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 2 row(s) in set (0.000810s)
-```
+- If the input value is NULL, the output is NULL too
-### BOTTOM
+#### LTRIM
```
-SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
+SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The least _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
+**Description**: Remove the left leading blanks of a string
-**Return value type**: Same as the column being operated upon
+**Return value type**: Same as input
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR or NCHAR
**Applicable table types**: table, STable
-**More explanations**:
-
-- _k_ must be in range [1,100]
-- The timestamp associated with the selected values are returned too
-- Can't be used with `FILL`
-
-**Examples**:
+**Applicable nested query**: Inner query and Outer query
-```
-taos> SELECT BOTTOM(voltage, 2) FROM meters;
- ts | bottom(voltage, 2) |
-===============================================
-2018-10-03 14:38:15.000 | 218 |
-2018-10-03 14:38:16.650 | 218 |
-Query OK, 2 row(s) in set (0.001332s)
+**More explanations**
-taos> SELECT BOTTOM(current, 2) FROM d1001;
- ts | bottom(current, 2) |
-=================================================
-2018-10-03 14:38:05.000 | 10.30000 |
-2018-10-03 14:38:16.800 | 12.30000 |
-Query OK, 2 row(s) in set (0.000793s)
-```
+- If the input value is NULL, the output is NULL too
-### PERCENTILE
+#### RTRIM
```
-SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
+SELECT RTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The value whose rank in a specific column matches the specified percentage. If such a value matching the specified percentage doesn't exist in the column, an interpolation value will be returned.
+**Description**: Remove the right tailing blanks of a string
-**Return value type**: Double precision floating point
+**Return value type**: Same as input
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR or NCHAR
-**Applicable table types**: table
+**Applicable table types**: table, STable
-**More explanations**: _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
+**Applicable nested query**: Inner query and Outer query
-**Examples**:
+**More explanations**
-```
-taos> SELECT PERCENTILE(current, 20) FROM d1001;
-percentile(current, 20) |
-============================
- 11.100000191 |
-Query OK, 1 row(s) in set (0.000787s)
-```
+- If the input value is NULL, the output is NULL too
-### APERCENTILE
+#### SUBSTR
```
-SELECT APERCENTILE(field_name, P[, algo_type])
-FROM { tb_name | stb_name } [WHERE clause]
+SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: Similar to `PERCENTILE`, but a simulated result is returned
+**Description**: The sub-string starting from `pos` with length of `len` from the original string `str`
-**Return value type**: Double precision floating point
+**Return value type**: Same as input
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable data types**: VARCHAR or NCHAR
**Applicable table types**: table, STable
-**More explanations**
-
-- _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
-- **algo_type** can only be input as `default` or `t-digest`, if it's not specified `default` will be used, i.e. `apercentile(column_name, 50)` is same as `apercentile(column_name, 50, "default")`.
-- When `t-digest` is used, `t-digest` sampling is used to calculate. It can be used from version 2.2.0.0.
-
-**Nested query**: It can be used in both the outer query and inner query in a nested query.
-
-```
-taos> SELECT APERCENTILE(current, 20) FROM d1001;
-apercentile(current, 20) |
-============================
- 10.300000191 |
-Query OK, 1 row(s) in set (0.000645s)
+**Applicable nested query**: Inner query and Outer query
-taos> select apercentile (count, 80, 'default') from stb1;
- apercentile (c0, 80, 'default') |
-==================================
- 601920857.210056424 |
-Query OK, 1 row(s) in set (0.012363s)
+**More explanations**:
-taos> select apercentile (count, 80, 't-digest') from stb1;
- apercentile (c0, 80, 't-digest') |
-===================================
- 605869120.966666579 |
-Query OK, 1 row(s) in set (0.011639s)
-```
+- If the input is NULL, the output is NULL
+- Parameter `pos` can be an positive or negative integer; If it's positive, the starting position will be counted from the beginning of the string; if it's negative, the starting position will be counted from the end of the string.
+- If `len` is not specified, it means from `pos` to the end.
-### LAST_ROW
+#### UPPER
```
-SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
+SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The last row of a table or STable
+**Description**: Convert the input string to upper case
-**Return value type**: Same as the column being operated upon
+**Return value type**: Same as input
-**Applicable column types**: Any data type
+**Applicable data types**: VARCHAR or NCHAR
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Inner query and Outer query
-- When it's used against a STable, multiple rows with the same and largest timestamp may exist, in this case one of them is returned randomly and it's not guaranteed that the result is same if the query is run multiple times.
-- Can't be used with `INTERVAL`.
+**More explanations**
-**Examples**:
+- If the input value is NULL, the output is NULL too
-```
- taos> SELECT LAST_ROW(current) FROM meters;
- last_row(current) |
- =======================
- 12.30000 |
- Query OK, 1 row(s) in set (0.001238s)
+### Conversion Functions
- taos> SELECT LAST_ROW(current) FROM d1002;
- last_row(current) |
- =======================
- 10.30000 |
- Query OK, 1 row(s) in set (0.001042s)
-```
+This kind of functions convert from one data type to another one.
-### INTERP [Since version 2.3.1]
+#### CAST
-```
-SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] [ RANGE(timestamp1,timestamp2) ] [EVERY(interval)] [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
+```sql
+SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The value that matches the specified timestamp range is returned, if existing; or an interpolation value is returned.
-
-**Return value type**: Same as the column being operated upon
-
-**Applicable column types**: Numeric data types
-
-**Applicable table types**: table, STable, nested query
+**Description**: It's used for type casting. The input parameter `expression` can be data columns, constants, scalar functions or arithmetic between them.
-**More explanations**
+**Return value type**: The type specified by parameter `type_name`
-- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
-- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
-- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1<=timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified. If `RANGE` is not specified, then the timestamp of the first row that matches the filter condition is treated as timestamp1, the timestamp of the last row that matches the filter condition is treated as timestamp2.
-- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY`. Starting from timestamp1, one interpolation is performed for every time interval specified `EVERY` parameter. If `EVERY` parameter is not used, the time windows will be considered as no ending timestamp, i.e. there is only one time window from timestamp1.
-- Interpolation is performed based on `FILL` parameter. No interpolation is performed if `FILL` is not used, that means either the original data that matches is returned or nothing is returned.
-- `INTERP` can only be used to interpolate in single timeline. So it must be used with `group by tbname` when it's used on a STable. It can't be used with `GROUP BY` when it's used in the inner query of a nested query.
-- The result of `INTERP` is not influenced by `ORDER BY TIMESTAMP`, which impacts the output order only..
+**Applicable data types**:
-**Examples**: Based on the `meters` schema used throughout the documents
+- Parameter `expression` can be any data type except for JSON
+- The output data type specified by `type_name` can only be one of BIGINT/VARCHAR(N)/TIMESTAMP/NCHAR(N)/BIGINT UNSIGNED
-- Single point linear interpolation between "2017-07-14 18:40:00" and "2017-07-14 18:40:00:
+**More explanations**:
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:40:00','2017-7-14 18:40:00') FILL(LINEAR);
-```
+- Error will be reported for unsupported type casting
+- NULL will be returned if the input value is NULL
+- Some values of some supported data types may not be casted, below are known issues:
+ 1)When casting VARCHAR/NCHAR to BIGINT/BIGINT UNSIGNED, some characters may be treated as illegal, for example "a" may be converted to 0.
+ 2)There may be overflow when casting singed integer or TIMESTAMP to unsigned BIGINT
+ 3)There may be overflow when casting unsigned BIGINT to BIGINT
+ 4)There may be overflow when casting FLOAT/DOUBLE to BIGINT or UNSIGNED BIGINT
-- Get original data every 5 seconds, no interpolation, between "2017-07-14 18:00:00" and "2017-07-14 19:00:00:
+#### TO_ISO8601
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s);
+```sql
+SELECT TO_ISO8601(ts_val | ts_col) FROM { tb_name | stb_name } [WHERE clause];
```
-- Linear interpolation every 5 seconds between "2017-07-14 18:00:00" and "2017-07-14 19:00:00:
+**Description**: The ISO8601 date/time format converted from a UNIX timestamp, plus the timezone of the client side system
-```
- taos> SELECT INTERP(current) FROM t1 RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
-```
+**Return value type**: VARCHAR
-- Backward interpolation every 5 seconds
+**Applicable column types**: TIMESTAMP, constant or a column
-```
- taos> SELECT INTERP(current) FROM t1 EVERY(5s) FILL(NEXT);
-```
+**Applicable table types**: table, STable
-- Linear interpolation every 5 seconds between "2017-07-14 17:00:00" and "2017-07-14 20:00:00"
+**More explanations**:
-```
- taos> SELECT INTERP(current) FROM t1 where ts >= '2017-07-14 17:00:00' and ts <= '2017-07-14 20:00:00' RANGE('2017-7-14 18:00:00','2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR);
-```
+- If the input is UNIX timestamp constant, the precision of the returned value is determined by the digits of the input timestamp
+- If the input is a column of TIMESTAMP type, The precision of the returned value is same as the precision set for the current data base in use
-### INTERP [Since version 2.0.15.0]
+#### TO_JSON
-```
-SELECT INTERP(field_name) FROM { tb_name | stb_name } WHERE ts='timestamp' [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
+```sql
+SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The value of a specific column that matches the specified time slice
+**Description**: Convert a JSON string to a JSON body。
-**Return value type**: Same as the column being operated upon
+**Return value type**: JSON
-**Applicable column types**: Numeric data type
+**Applicable column types**: JSON string, in the format like '{ "literal" : literal }'. '{}' is NULL value. keys in the string must be string constants, values can be constants of numeric types, bool, string or NULL. Escaping characters are not allowed in the JSON string.
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Inner query and Outer query.
-- Time slice must be specified. If there is no data matching the specified time slice, interpolation is performed based on `FILL` parameter. Conditions such as tags or `tbname` can be used `Where` clause can be used to filter data.
-- The timestamp specified must be within the time range of the data rows of the table or STable. If it is beyond the valid time range, nothing is returned even with `FILL` parameter.
-- `INTERP` can be used to query only single time point once. `INTERP` can be used with `EVERY` to get the interpolation value every time interval.
-- **Examples**:
+#### TO_UNIXTIMESTAMP
-```
- taos> SELECT INTERP(*) FROM meters WHERE ts='2017-7-14 18:40:00.004';
- interp(ts) | interp(current) | interp(voltage) | interp(phase) |
- ==========================================================================================
- 2017-07-14 18:40:00.004 | 9.84020 | 216 | 0.32222 |
- Query OK, 1 row(s) in set (0.002652s)
+```sql
+SELECT TO_UNIXTIMESTAMP(datetime_string | ts_col) FROM { tb_name | stb_name } [WHERE clause];
```
-If there is no data corresponding to the specified timestamp, an interpolation value is returned if interpolation policy is specified by `FILL` parameter; or nothing is returned.
+**Description**: UNIX timestamp converted from a string of date/time format
-```
- taos> SELECT INTERP(*) FROM meters WHERE tbname IN ('d636') AND ts='2017-7-14 18:40:00.005';
- Query OK, 0 row(s) in set (0.004022s)
+**Return value type**: Long integer
- taos> SELECT INTERP(*) FROM meters WHERE tbname IN ('d636') AND ts='2017-7-14 18:40:00.005' FILL(PREV);
- interp(ts) | interp(current) | interp(voltage) | interp(phase) |
- ==========================================================================================
- 2017-07-14 18:40:00.005 | 9.88150 | 217 | 0.32500 |
- Query OK, 1 row(s) in set (0.003056s)
-```
+**Applicable column types**: Constant or column of VARCHAR/NCHAR
-Interpolation is performed every 5 milliseconds between `['2017-7-14 18:40:00', '2017-7-14 18:40:00.014']`
+**Applicable table types**: table, STable
-```
- taos> SELECT INTERP(current) FROM d636 WHERE ts>='2017-7-14 18:40:00' AND ts<='2017-7-14 18:40:00.014' EVERY(5a);
- ts | interp(current) |
- =================================================
- 2017-07-14 18:40:00.000 | 10.04179 |
- 2017-07-14 18:40:00.010 | 10.16123 |
- Query OK, 2 row(s) in set (0.003487s)
-```
+**More explanations**:
-### TAIL
+- The input string must be compatible with ISO8601/RFC3339 standard, 0 will be returned if the string can't be converted
+- The precision of the returned timestamp is same as the precision set for the current data base in use
-```
-SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
-```
+### DateTime Functions
-**Description**: The next _k_ rows are returned after skipping the last `offset_val` rows, NULL values are not ignored. `offset_val` is optional parameter. When it's not specified, the last _k_ rows are returned. When `offset_val` is used, the effect is same as `order by ts desc LIMIT k OFFSET offset_val`.
+This kind of functiosn oeprate on timestamp data. NOW(), TODAY() and TIMEZONE() are executed only once even though they may occurr multiple times in a single SQL statement.
-**Parameter value range**: k: [1,100] offset_val: [0,100]
+#### NOW
-**Return value type**: Same as the column being operated upon
+```sql
+SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
+SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
+INSERT INTO tb_name VALUES (NOW(), ...);
+```
-**Applicable column types**: Any data type except form timestamp, i.e. the primary key
+**Description**: The current time of the client side system
-**Applicable versions**: Since version 2.6.0.0
+**Return value type**: TIMESTAMP
-**Examples**:
+**Applicable column types**: TIMESTAMP only
-```
-taos> select ts,dbig from tail2;
- ts | dbig |
-==================================================
-2021-10-15 00:31:33.000 | 1 |
-2021-10-17 00:31:31.000 | NULL |
-2021-12-24 00:31:34.000 | 2 |
-2022-01-01 08:00:05.000 | 19 |
-2022-01-01 08:00:06.000 | NULL |
-2022-01-01 08:00:07.000 | 9 |
-Query OK, 6 row(s) in set (0.001952s)
+**Applicable table types**: table, STable
-taos> select tail(dbig,2,2) from tail2;
-ts | tail(dbig,2,2) |
-==================================================
-2021-12-24 00:31:34.000 | 2 |
-2022-01-01 08:00:05.000 | 19 |
-Query OK, 2 row(s) in set (0.002307s)
-```
+**More explanations**:
-### UNIQUE
+- Add and Subtract operation can be performed, for example NOW() + 1s, the time unit can be:
+ b(nanosecond), u(microsecond), a(millisecond)), s(second), m(minute), h(hour), d(day), w(week)
+- The precision of the returned timestamp is same as the precision set for the current data base in use
-```
-SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
+#### 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];
```
-**Description**: The values that occur the first time in the specified column. The effect is similar to `distinct` keyword, but it can also be used to match tags or timestamp.
+**Description**: The difference between two timestamps, and rounded to the time unit specified by `time_unit`
-**Return value type**: Same as the column or tag being operated upon
+**Return value type**: Long Integer
-**Applicable column types**: Any data types except for timestamp
+**Applicable column types**: UNIX timestamp constant, string constant of date/time format, or a column of TIMESTAMP type
-**Applicable versions**: Since version 2.6.0.0
+**Applicable table types**: table, STable
**More explanations**:
-- It can be used against table or STable, but can't be used together with time window, like `interval`, `state_window` or `session_window` .
-- Considering the number of result sets is unpredictable, it's suggested to limit the distinct values under 100,000 to control the memory usage, otherwise error will be returned.
-
-**Examples**:
-
-```
-taos> select ts,voltage from unique1;
- ts | voltage |
-==================================================
-2021-10-17 00:31:31.000 | 1 |
-2022-01-24 00:31:31.000 | 1 |
-2021-10-17 00:31:31.000 | 1 |
-2021-12-24 00:31:31.000 | 2 |
-2022-01-01 08:00:01.000 | 19 |
-2021-10-17 00:31:31.000 | NULL |
-2022-01-01 08:00:02.000 | NULL |
-2022-01-01 08:00:03.000 | 9 |
-Query OK, 8 row(s) in set (0.003018s)
-
-taos> select unique(voltage) from unique1;
-ts | unique(voltage) |
-==================================================
-2021-10-17 00:31:31.000 | 1 |
-2021-10-17 00:31:31.000 | NULL |
-2021-12-24 00:31:31.000 | 2 |
-2022-01-01 08:00:01.000 | 19 |
-2022-01-01 08:00:03.000 | 9 |
-Query OK, 5 row(s) in set (0.108458s)
-```
-
-## Scalar functions
+- Time unit specified by `time_unit` can be:
+ 1u(microsecond),1a(millisecond),1s(second),1m(minute),1h(hour),1d(day).
+- The precision of the returned timestamp is same as the precision set for the current data base in use
-### DIFF
+#### TIMETRUNCATE
```sql
-SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
+SELECT TIMETRUNCATE(ts_val | datetime_string | ts_col, time_unit) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The different of each row with its previous row for a specific column. `ignore_negative` can be specified as 0 or 1, the default value is 1 if it's not specified. `1` means negative values are ignored.
+**Description**: Truncate the input timestamp with unit specified by `time_unit`
-**Return value type**: Same as the column being operated upon
+**Return value type**: TIMESTAMP
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable column types**: UNIX timestamp constant, string constant of date/time format, or a column of timestamp
**Applicable table types**: table, STable
**More explanations**:
-- The number of result rows is the number of rows subtracted by one, no output for the first row
-- Since version 2.1.30, `DIFF` can be used on STable with `GROUP by tbname`
-- Since version 2.6.0, `ignore_negative` parameter is supported
+- Time unit specified by `time_unit` can be:
+ 1u(microsecond),1a(millisecond),1s(second),1m(minute),1h(hour),1d(day).
+- The precision of the returned timestamp is same as the precision set for the current data base in use
-**Examples**:
+#### TIMEZONE
```sql
-taos> SELECT DIFF(current) FROM d1001;
- ts | diff(current) |
-=================================================
-2018-10-03 14:38:15.000 | 2.30000 |
-2018-10-03 14:38:16.800 | -0.30000 |
-Query OK, 2 row(s) in set (0.001162s)
+SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
```
-### DERIVATIVE
+**Description**: The timezone of the client side system
-```
-SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
+**Return value type**: VARCHAR
+
+**Applicable column types**: None
+
+**Applicable table types**: table, STable
+
+#### TODAY
+
+```sql
+SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
+SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
+INSERT INTO tb_name VALUES (TODAY(), ...);
```
-**Description**: The derivative of a specific column. The time rage can be specified by parameter `time_interval`, the minimum allowed time range is 1 second (1s); the value of `ignore_negative` can be 0 or 1, 1 means negative values are ignored.
+**Description**: The timestamp of 00:00:00 of the client side system
-**Return value type**: Double precision floating point
+**Return value type**: TIMESTAMP
-**Applicable column types**: Data types except for timestamp, binary, nchar and bool
+**Applicable column types**: TIMESTAMP only
**Applicable table types**: table, STable
**More explanations**:
-- It is available from version 2.1.3.0, the number of result rows is the number of total rows in the time range subtracted by one, no output for the first row.
-- It can be used together with `GROUP BY tbname` against a STable.
+- Add and Subtract operation can be performed, for example NOW() + 1s, the time unit can be:
+ b(nanosecond), u(microsecond), a(millisecond)), s(second), m(minute), h(hour), d(day), w(week)
+- The precision of the returned timestamp is same as the precision set for the current data base in use
-**Examples**:
+## Aggregate Functions
-```
-taos> select derivative(current, 10m, 0) from t1;
- ts | derivative(current, 10m, 0) |
-========================================================
- 2021-08-20 10:11:22.790 | 0.500000000 |
- 2021-08-20 11:11:22.791 | 0.166666620 |
- 2021-08-20 12:11:22.791 | 0.000000000 |
- 2021-08-20 13:11:22.792 | 0.166666620 |
- 2021-08-20 14:11:22.792 | -0.666666667 |
-Query OK, 5 row(s) in set (0.004883s)
-```
+Aggregate functions return single result row for each group in the query result set. Groups are determined by `GROUP BY` clause or time window clause if they are used; or the whole result is considered a group if neither of them is used.
-### SPREAD
+### AVG
```
-SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
+SELECT AVG(field_name) FROM tb_name [WHERE clause];
```
-**Description**: The difference between the max and the min of a specific column
+**Description**: Get the average value of a column in a table or STable
-**Return value type**: Double precision floating point
+**Return value type**: Double precision floating number
-**Applicable column types**: Data types except for binary, nchar, and bool
+**Applicable column types**: Numeric type
**Applicable table types**: table, STable
-**More explanations**: Can be used on a column of TIMESTAMP type, the result is the time range size.
-
-**Examples**:
-
-```
-taos> SELECT SPREAD(voltage) FROM meters;
- spread(voltage) |
-============================
- 5.000000000 |
-Query OK, 1 row(s) in set (0.001792s)
-
-taos> SELECT SPREAD(voltage) FROM d1001;
- spread(voltage) |
-============================
- 3.000000000 |
-Query OK, 1 row(s) in set (0.000836s)
-```
-
-### CEIL
+### COUNT
```
-SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
+SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
```
-**Description**: The rounded up value of a specific column
-
-**Return value type**: Same as the column being used
+**Description**: Get the number of rows or the number of non-null values in a table or a super table.
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
+**Return value type**: Long integer INT64
-**Applicable table types**: table, STable
+**Applicable column types**: All
-**Applicable nested query**: Inner query and outer query
+**Applicable table types**: table, super table, sub table
-**More explanations**:
+**More explanation**:
-- Can't be used on any tags of any type
-- Arithmetic operation can be performed on the result of `ceil` function
-- Can't be used with aggregate functions
+- Wildcard (\*) is used to represent all columns. The `COUNT` function is used to get the total number of all rows.
+- The number of non-NULL values will be returned if this function is used on a specific column.
-### FLOOR
+### ELAPSED
-```
-SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
+```mysql
+SELECT ELAPSED(field_name[, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
```
-**Description**: The rounded down value of a specific column
+**Description**:`elapsed` function can be used to calculate the continuous time length in which there is valid data. If it's used with `INTERVAL` clause, the returned result is the calcualted time length within each time window. If it's used without `INTERVAL` caluse, the returned result is the calculated time length within the specified time range. Please be noted that the return value of `elapsed` is the number of `time_unit` in the calculated time length.
-**More explanations**: The restrictions are same as those of the `CEIL` function.
+**Return value type**:Double
-### ROUND
+**Applicable Column type**:Timestamp
-```
-SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Applicable tables**: table, STable, outter in nested query
-**Description**: The rounded value of a specific column.
+**Explanations**:
-**More explanations**: The restrictions are same as `CEIL` function.
+- `field_name` parameter can only be the first column of a table, i.e. timestamp primary key.
+- The minimum value of `time_unit` is the time precision of the database. If `time_unit` is not specified, the time precision of the database is used as the default ime unit.
+- It can be used with `INTERVAL` to get the time valid time length of each time window. Please be noted that the return value is same as the time window for all time windows except for the first and the last time window.
+- `order by asc/desc` has no effect on the result.
+- `group by tbname` must be used together when `elapsed` is used against a STable.
+- `group by` must NOT be used together when `elapsed` is used against a table or sub table.
+- When used in nested query, it's only applicable when the inner query outputs an implicit timestamp column as the primary key. For example, `select elapsed(ts) from (select diff(value) from sub1)` is legal usage while `select elapsed(ts) from (select * from sub1)` is not.
+- It can't be used with `leastsquares`, `diff`, `derivative`, `top`, `bottom`, `last_row`, `interp`.
-### CSUM
+### LEASTSQUARES
-```sql
- SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: The cumulative sum of each row for a specific column. The number of output rows is same as that of the input rows.
-
-**Return value type**: Long integer for integers; Double for floating points. Timestamp is returned for each row.
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, and bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**More explanations**:
-
-- Can't be used on tags when it's used on STable
-- Arithmetic operation can't be performed on the result of `csum` function
-- Can only be used with aggregate functions
-- `Group by tbname` must be used together on a STable to force the result on a single timeline
-
-**Applicable versions**: Since 2.3.0.x
-
-### MAVG
-
-```sql
- SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
```
-**Description**: The moving average of continuous _k_ values of a specific column. If the number of input rows is less than _k_, nothing is returned. The applicable range is _k_ is [1,1000].
-
-**Return value type**: Double precision floating point
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, and bool
-
-**Applicable nested query**: Inner query and Outer query
+**Description**: The linear regression function of the specified column and the timestamp column (primary key), `start_val` is the initial value and `step_val` is the step value.
-**Applicable table types**: table, STable
+**Return value type**: A string in the format of "(slope, intercept)"
-**More explanations**:
+**Applicable column types**: Numeric types
-- Arithmetic operation can't be performed on the result of `MAVG`.
-- Can only be used with data columns, can't be used with tags.
-- Can't be used with aggregate functions.
-- Must be used with `GROUP BY tbname` when it's used on a STable to force the result on each single timeline.
-
-**Applicable versions**: Since 2.3.0.x
+**Applicable table types**: table only
-### SAMPLE
+### MODE
-```sql
- SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: _k_ sampling values of a specific column. The applicable range of _k_ is [1,10000]
-
-**Return value type**: Same as the column being operated plus the associated timestamp
-
-**Applicable data types**: Any data type except for tags of STable
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**More explanations**:
-
-- Arithmetic operation can't be operated on the result of `SAMPLE` function
-- Must be used with `Group by tbname` when it's used on a STable to force the result on each single timeline
-
-**Applicable versions**: Since 2.3.0.x
-
-### ASIN
-
-```sql
-SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT MODE(field_name) FROM tb_name [WHERE clause];
```
-**Description**: The anti-sine of a specific column
-
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
+**Description**:The value which has the highest frequency of occurrence. NULL is returned if there are multiple values which have highest frequency of occurrence. It can't be used on timestamp column.
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
+**Return value type**:Same as the data type of the column being operated upon
-**More explanations**:
+**Applicable column types**:Data types except for timestamp
-- Can't be used with tags
-- Can't be used with aggregate functions
+**More explanations**:Considering the number of returned result set is unpredictable, it's suggested to limit the number of unique values to 100,000, otherwise error will be returned.
-### ACOS
+### SPREAD
-```sql
-SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: The anti-cosine of a specific column
-
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### ATAN
-
-```sql
-SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: anti-tangent of a specific column
-
-**Description**: The anti-cosine of a specific column
+**Description**: The difference between the max and the min of a specific column
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
+**Return value type**: Double precision floating point
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
+**More explanations**: Can be used on a column of TIMESTAMP type, the result is the time range size.
-### SIN
+### STDDEV
-```sql
-SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: The sine of a specific column
-
-**Description**: The anti-cosine of a specific column
-
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### COS
-
-```sql
-SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
```
-**Description**: The cosine of a specific column
-
-**Description**: The anti-cosine of a specific column
+**Description**: Standard deviation of a specific column in a table or STable
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
+**Return value type**: Double precision floating number
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### TAN
+### SUM
-```sql
-SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: The tangent of a specific column
-
-**Description**: The anti-cosine of a specific column
-
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### POW
-
-```sql
-SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
+SELECT SUM(field_name) FROM tb_name [WHERE clause];
```
-**Description**: The power of a specific column with `power` as the index
+**Description**: The sum of a specific column in a table or STable
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
+**Return value type**: Double precision floating number or long integer
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### LOG
+### HYPERLOGLOG
-```sql
-SELECT LOG(field_name, base) FROM { tb_name | stb_name } [WHERE clause]
```
-
-**Description**: The log of a specific with `base` as the radix
-
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### ABS
-
-```sql
-SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
+SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The absolute of a specific column
-
-**Return value type**: UBIGINT if the input value is integer; DOUBLE if the input value is FLOAT/DOUBLE
-
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
-
-**Applicable table types**: table, STable
-
-**Applicable nested query**: Inner query and Outer query
+**Description**:The cardinal number of a specific column is returned by using hyperloglog algorithm.
-**Applicable versions**: From 2.6.0.0
+**Return value type**:Integer
-**More explanations**:
+**Applicable column types**:Any data type
-- Can't be used with tags
-- Can't be used with aggregate functions
+**More explanations**: The benefit of using hyperloglog algorithm is that the memory usage is under control when the data volume is huge. However, when the data volume is very small, the result may be not accurate, it's recommented to use `select count(data) from (select unique(col) as data from table)` in this case.
-### SQRT
+### HISTOGRAM
-```sql
-SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
+SELECT HISTOGRAM(field_name,bin_type, bin_description, normalized) FROM tb_name [WHERE clause];
```
-**Description**: The square root of a specific column
+**Description**:Returns count of data points in user-specified ranges.
-**Return value type**: Double if the input value is not NULL; or NULL if the input value is NULL
+**Return value type**:Double or INT64, depends on normalized parameter settings.
-**Applicable data types**: Data types except for timestamp, binary, nchar, bool
+**Applicable column type**:Numerical types.
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**:
-
-- Can't be used with tags
-- Can't be used with aggregate functions
-
-### CAST
+**Explanations**:
-```sql
-SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
-```
+1. bin_type: parameter to indicate the bucket type, valid inputs are: "user_input", "linear_bin", "log_bin"。
+2. bin_description: parameter to describe how to generate buckets,can be in the following JSON formats for each bin_type respectively:
-**Description**: It's used for type casting. The input parameter `expression` can be data columns, constants, scalar functions or arithmetic between them. Can't be used with tags, and can only be used in `select` clause.
+ - "user_input": "[1, 3, 5, 7]": User specified bin values.
-**Return value type**: The type specified by parameter `type_name`
+ - "linear_bin": "{"start": 0.0, "width": 5.0, "count": 5, "infinity": true}"
+ "start" - bin starting point.
+ "width" - bin offset.
+ "count" - number of bins generated.
+ "infinity" - whether to add(-inf, inf)as start/end point in generated set of bins.
+ The above "linear_bin" descriptor generates a set of bins: [-inf, 0.0, 5.0, 10.0, 15.0, 20.0, +inf].
-**Applicable data types**:
+ - "log_bin": "{"start":1.0, "factor": 2.0, "count": 5, "infinity": true}"
+ "start" - bin starting point.
+ "factor" - exponential factor of bin offset.
+ "count" - number of bins generated.
+ "infinity" - whether to add(-inf, inf)as start/end point in generated range of bins.
+ The above "log_bin" descriptor generates a set of bins:[-inf, 1.0, 2.0, 4.0, 8.0, 16.0, +inf].
-- Parameter `expression` can be any data type except for JSON, more specifically it can be any of BOOL/TINYINT/SMALLINT/INT/BIGINT/FLOAT/DOUBLE/BINARY(M)/TIMESTAMP/NCHAR(M)/TINYINT UNSIGNED/SMALLINT UNSIGNED/INT UNSIGNED/BIGINT UNSIGNED
-- The output data type specified by `type_name` can only be one of BIGINT/BINARY(N)/TIMESTAMP/NCHAR(N)/BIGINT UNSIGNED
+3. normalized: setting to 1/0 to turn on/off result normalization.
-**Applicable versions**: From 2.6.0.0
+## Selector Functions
-**More explanations**:
+Selector functiosn choose one or more rows in the query result set to retrun according toe the semantics. You can specify to output ts column and other columns including tbname and tags so that you can easily know which rows the selected values belong to.
-- Error will be reported for unsupported type casting
-- NULL will be returned if the input value is NULL
-- Some values of some supported data types may not be casted, below are known issues:
- 1)When casting BINARY/NCHAR to BIGINT/BIGINT UNSIGNED, some characters may be treated as illegal, for example "a" may be converted to 0.
- 2)There may be overflow when casting singed integer or TIMESTAMP to unsigned BIGINT
- 3)There may be overflow when casting unsigned BIGINT to BIGINT
- 4)There may be overflow when casting FLOAT/DOUBLE to BIGINT or UNSIGNED BIGINT
-
-### CONCAT
+### APERCENTILE
-```sql
-SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
+```
+SELECT APERCENTILE(field_name, P[, algo_type])
+FROM { tb_name | stb_name } [WHERE clause]
```
-**Description**: The concatenation result of two or more strings, the number of strings to be concatenated is at least 2 and at most 8
+**Description**: Similar to `PERCENTILE`, but a simulated result is returned
-**Return value type**: Same as the columns being operated, BINARY or NCHAR; or NULL if all the input are NULL
+**Return value type**: Double precision floating point
-**Applicable data types**: The input data must be in either all BINARY or in all NCHAR; can't be used on tag columns
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
+**More explanations**
-**Applicable versions**: From 2.6.0.0
+- _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
+- **algo_type** can only be input as `default` or `t-digest`, if it's not specified `default` will be used, i.e. `apercentile(column_name, 50)` is same as `apercentile(column_name, 50, "default")`.
+- When `t-digest` is used, `t-digest` sampling is used to calculate.
-### CONCAT_WS
+**Nested query**: It can be used in both the outer query and inner query in a nested query.
+
+### BOTTOM
```
-SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
+SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The concatenation result of two or more strings with separator, the number of strings to be concatenated is at least 3 and at most 9
+**Description**: The least _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
-**Return value type**: Same as the columns being operated, BINARY or NCHAR; or NULL if all the input are NULL
+**Return value type**: Same as the column being operated upon
-**Applicable data types**: The input data must be in either all BINARY or in all NCHAR; can't be used on tag columns
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
**More explanations**:
-- If the value of `separator` is NULL, the output is NULL. If the value of `separator` is not NULL but other input are all NULL, the output is empty string.
+- _k_ must be in range [1,100]
+- The timestamp associated with the selected values are returned too
+- Can't be used with `FILL`
-### LENGTH
+### FIRST
```
-SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The length in bytes of a string
+**Description**: The first non-null value of a specific column in a table or STable
-**Return value type**: Integer
+**Return value type**: Same as the column being operated upon
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+**Applicable column types**: Any data type
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**
+**More explanations**:
-- If the input value is NULL, the output is NULL too
+- FIRST(\*) can be used to get the first non-null value of all columns
+- NULL will be returned if all the values of the specified column are all NULL
+- A result will NOT be returned if all the columns in the result set are all NULL
-### CHAR_LENGTH
+### INTERP
```
-SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] [ RANGE(timestamp1,timestamp2) ] [EVERY(interval)] [FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})];
```
-**Description**: The length in number of characters of a string
-
-**Return value type**: Integer
-
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+**Description**: The value that matches the specified timestamp range is returned, if existing; or an interpolation value is returned.
-**Applicable table types**: table, STable
+**Return value type**: Same as the column being operated upon
-**Applicable nested query**: Inner query and Outer query
+**Applicable column types**: Numeric data types
-**Applicable versions**: From 2.6.0.0
+**Applicable table types**: table, STable, nested query
**More explanations**
-- If the input value is NULL, the output is NULL too
+- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
+- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
+- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1<=timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified. If `RANGE` is not specified, then the timestamp of the first row that matches the filter condition is treated as timestamp1, the timestamp of the last row that matches the filter condition is treated as timestamp2.
+- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY`. Starting from timestamp1, one interpolation is performed for every time interval specified `EVERY` parameter. If `EVERY` parameter is not used, the time windows will be considered as no ending timestamp, i.e. there is only one time window from timestamp1.
+- Interpolation is performed based on `FILL` parameter. No interpolation is performed if `FILL` is not used, that means either the original data that matches is returned or nothing is returned.
+- `INTERP` can only be used to interpolate in single timeline. So it must be used with `group by tbname` when it's used on a STable. It can't be used with `GROUP BY` when it's used in the inner query of a nested query.
+- The result of `INTERP` is not influenced by `ORDER BY TIMESTAMP`, which impacts the output order only..
-### LOWER
+### LAST
```
-SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: Convert the input string to lower case
+**Description**: The last non-NULL value of a specific column in a table or STable
-**Return value type**: Same as input
+**Return value type**: Same as the column being operated upon
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+**Applicable column types**: Any data type
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**
+**More explanations**:
-- If the input value is NULL, the output is NULL too
+- LAST(\*) can be used to get the last non-NULL value of all columns
+- If the values of a column in the result set are all NULL, NULL is returned for that column; if all columns in the result are all NULL, no result will be returned.
+- When it's used on a STable, if there are multiple values with the timestamp in the result set, one of them will be returned randomly and it's not guaranteed that the same value is returned if the same query is run multiple times.
-### UPPER
+### LAST_ROW
```
-SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
```
-**Description**: Convert the input string to upper case
+**Description**: The last row of a table or STable
-**Return value type**: Same as input
+**Return value type**: Same as the column being operated upon
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+**Applicable column types**: Any data type
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
-
-**More explanations**
+**More explanations**:
-- If the input value is NULL, the output is NULL too
+- When it's used against a STable, multiple rows with the same and largest timestamp may exist, in this case one of them is returned randomly and it's not guaranteed that the result is same if the query is run multiple times.
+- Can't be used with `INTERVAL`.
-### LTRIM
+### MAX
```
-SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
-```
-
-**Description**: Remove the left leading blanks of a string
-
-**Return value type**: Same as input
-
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
-
-**Applicable table types**: table, STable
+SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
+```
-**Applicable nested query**: Inner query and Outer query
+**Description**: The maximum value of a specific column of a table or STable
-**Applicable versions**: From 2.6.0.0
+**Return value type**: Same as the data type of the column being operated upon
-**More explanations**
+**Applicable column types**: Numeric types
-- If the input value is NULL, the output is NULL too
+**Applicable table types**: table, STable
-### RTRIM
+### MIN
```
-SELECT RTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
+SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
```
-**Description**: Remove the right tailing blanks of a string
+**Description**: The minimum value of a specific column in a table or STable
-**Return value type**: Same as input
+**Return value type**: Same as the data type of the column being operated upon
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Inner query and Outer query
-
-**Applicable versions**: From 2.6.0.0
+### PERCENTILE
-**More explanations**
+```
+SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
+```
-- If the input value is NULL, the output is NULL too
+**Description**: The value whose rank in a specific column matches the specified percentage. If such a value matching the specified percentage doesn't exist in the column, an interpolation value will be returned.
-### SUBSTR
+**Return value type**: Double precision floating point
-```
-SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
-```
+**Applicable column types**: Numeric types
-**Description**: The sub-string starting from `pos` with length of `len` from the original string `str`
+**Applicable table types**: table
-**Return value type**: Same as input
+**More explanations**: _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
-**Applicable data types**: BINARY or NCHAR, can't be used on tags
+### TAIL
-**Applicable table types**: table, STable
+```
+SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
+```
-**Applicable nested query**: Inner query and Outer query
+**Description**: The next _k_ rows are returned after skipping the last `offset_val` rows, NULL values are not ignored. `offset_val` is optional parameter. When it's not specified, the last _k_ rows are returned. When `offset_val` is used, the effect is same as `order by ts desc LIMIT k OFFSET offset_val`.
-**Applicable versions**: From 2.6.0.0
+**Parameter value range**: k: [1,100] offset_val: [0,100]
-**More explanations**:
+**Return value type**: Same as the column being operated upon
-- If the input is NULL, the output is NULL
-- Parameter `pos` can be an positive or negative integer; If it's positive, the starting position will be counted from the beginning of the string; if it's negative, the starting position will be counted from the end of the string.
-- If `len` is not specified, it means from `pos` to the end.
+**Applicable column types**: Any data type except form timestamp, i.e. the primary key
-### Arithmetic Operations
+### TOP
```
-SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name } [WHERE clause];
+SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
```
-**Description**: The sum, difference, product, quotient, or remainder between one or more columns
+**Description**: The greatest _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
-**Return value type**: Double precision floating point
+**Return value type**: Same as the column being operated upon
-**Applicable column types**: Data types except for timestamp, binary, nchar, bool
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
**More explanations**:
-- Arithmetic operations can be performed on two or more columns, Parentheses `()` can be used to control the order of precedence.
-- NULL doesn't participate in the operation i.e. if one of the operands is NULL then result is NULL.
+- _k_ must be in range [1,100]
+- The timestamp associated with the selected values are returned too
+- Can't be used with `FILL`
-**Examples**:
+### UNIQUE
```
-taos> SELECT current + voltage * phase FROM d1001;
-(current+(voltage*phase)) |
-============================
- 78.190000713 |
- 84.540003240 |
- 80.810000718 |
-Query OK, 3 row(s) in set (0.001046s)
+SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
```
-### STATECOUNT
+**Description**: The values that occur the first time in the specified column. The effect is similar to `distinct` keyword, but it can also be used to match tags or timestamp.
-```
-SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Return value type**: Same as the column or tag being operated upon
-**Description**: The number of continuous rows satisfying the specified conditions for a specific column. The result is shown as an extra column for each row. If the specified condition is evaluated as true, the number is increased by 1; otherwise the number is reset to -1. If the input value is NULL, then the corresponding row is skipped.
+**Applicable column types**: Any data types except for timestamp
-**Applicable parameter values**:
+**More explanations**:
-- oper : Can be one of LT (lower than), GT (greater than), LE (lower than or euqal to), GE (greater than or equal to), NE (not equal to), EQ (equal to), the value is case insensitive
-- val : Numeric types
+- It can be used against table or STable, but can't be used together with time window, like `interval`, `state_window` or `session_window` .
+- Considering the number of result sets is unpredictable, it's suggested to limit the distinct values under 100,000 to control the memory usage, otherwise error will be returned.
-**Return value type**: Integer
+## Time-Series Specific Functions
-**Applicable data types**: Data types excpet for timestamp, binary, nchar, bool
+TDengine provides a set of time-series specific functions to better meet the requirements in querying time-series data. In general databases, similar functionalities can only be achieved with much more complex syntax and much worse performance. TDengine provides these functionalities in builtin functions so that the burden on user side is minimized.
-**Applicable table types**: table, STable
+### CSUM
-**Applicable nested query**: Outer query only
+```sql
+ SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
+```
-**Applicable versions**: From 2.6.0.0
+**Description**: The cumulative sum of each row for a specific column. The number of output rows is same as that of the input rows.
-**More explanations**:
+**Return value type**: Long integer for integers; Double for floating points. Timestamp is returned for each row.
-- Must be used together with `GROUP BY tbname` when it's used on a STable to force the result into each single timeline]
-- Can't be used with window operation, like interval/state_window/session_window
+**Applicable data types**: Numeric types
-**Examples**:
+**Applicable table types**: table, STable
-```
-taos> select ts,dbig from statef2;
- ts | dbig |
-========================================================
-2021-10-15 00:31:33.000000000 | 1 |
-2021-10-17 00:31:31.000000000 | NULL |
-2021-12-24 00:31:34.000000000 | 2 |
-2022-01-01 08:00:05.000000000 | 19 |
-2022-01-01 08:00:06.000000000 | NULL |
-2022-01-01 08:00:07.000000000 | 9 |
-Query OK, 6 row(s) in set (0.002977s)
+**Applicable nested query**: Inner query and Outer query
-taos> select stateCount(dbig,GT,2) from statef2;
-ts | dbig | statecount(dbig,gt,2) |
-================================================================================
-2021-10-15 00:31:33.000000000 | 1 | -1 |
-2021-10-17 00:31:31.000000000 | NULL | NULL |
-2021-12-24 00:31:34.000000000 | 2 | -1 |
-2022-01-01 08:00:05.000000000 | 19 | 1 |
-2022-01-01 08:00:06.000000000 | NULL | NULL |
-2022-01-01 08:00:07.000000000 | 9 | 2 |
-Query OK, 6 row(s) in set (0.002791s)
-```
+**More explanations**:
+- Arithmetic operation can't be performed on the result of `csum` function
+- Can only be used with aggregate functions
+- `Group by tbname` must be used together on a STable to force the result on a single timeline
-### STATEDURATION
+### DERIVATIVE
```
-SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
+SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
```
-**Description**: The length of time range in which all rows satisfy the specified condition for a specific column. The result is shown as an extra column for each row. The length for the first row that satisfies the condition is 0. Next, if the condition is evaluated as true for a row, the time interval between current row and its previous row is added up to the time range; otherwise the time range length is reset to -1. If the value of the column is NULL, the corresponding row is skipped.
-
-**Applicable parameter values**:
-
-- oper : Can be one of LT (lower than), GT (greater than), LE (lower than or euqal to), GE (greater than or equal to), NE (not equal to), EQ (equal to), the value is case insensitive
-- val : Numeric types
-- unit: The unit of time interval, can be [1s, 1m, 1h], default is 1s
+**Description**: The derivative of a specific column. The time rage can be specified by parameter `time_interval`, the minimum allowed time range is 1 second (1s); the value of `ignore_negative` can be 0 or 1, 1 means negative values are ignored.
-**Return value type**: Integer
+**Return value type**: Double precision floating point
-**Applicable data types**: Data types excpet for timestamp, binary, nchar, bool
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
-**Applicable nested query**: Outer query only
-
-**Applicable versions**: From 2.6.0.0
-
**More explanations**:
-- Must be used together with `GROUP BY tbname` when it's used on a STable to force the result into each single timeline]
-- Can't be used with window operation, like interval/state_window/session_window
+- The number of result rows is the number of total rows in the time range subtracted by one, no output for the first row.
+- It can be used together with `GROUP BY tbname` against a STable.
-**Examples**:
+### DIFF
+```sql
+SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
```
-taos> select ts,dbig from statef2;
- ts | dbig |
-========================================================
-2021-10-15 00:31:33.000000000 | 1 |
-2021-10-17 00:31:31.000000000 | NULL |
-2021-12-24 00:31:34.000000000 | 2 |
-2022-01-01 08:00:05.000000000 | 19 |
-2022-01-01 08:00:06.000000000 | NULL |
-2022-01-01 08:00:07.000000000 | 9 |
-Query OK, 6 row(s) in set (0.002407s)
-taos> select stateDuration(dbig,GT,2) from statef2;
-ts | dbig | stateduration(dbig,gt,2) |
-===================================================================================
-2021-10-15 00:31:33.000000000 | 1 | -1 |
-2021-10-17 00:31:31.000000000 | NULL | NULL |
-2021-12-24 00:31:34.000000000 | 2 | -1 |
-2022-01-01 08:00:05.000000000 | 19 | 0 |
-2022-01-01 08:00:06.000000000 | NULL | NULL |
-2022-01-01 08:00:07.000000000 | 9 | 2 |
-Query OK, 6 row(s) in set (0.002613s)
-```
+**Description**: The different of each row with its previous row for a specific column. `ignore_negative` can be specified as 0 or 1, the default value is 1 if it's not specified. `1` means negative values are ignored.
-## Time Functions
+**Return value type**: Same as the column being operated upon
-Since version 2.6.0.0, below time related functions can be used in TDengine.
+**Applicable column types**: Numeric types
-### NOW
+**Applicable table types**: table, STable
-```sql
-SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
-SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
-INSERT INTO tb_name VALUES (NOW(), ...);
+**More explanations**:
+
+- The number of result rows is the number of rows subtracted by one, no output for the first row
+- It can be used on STable with `GROUP by tbname`
+
+### IRATE
+
+```
+SELECT IRATE(field_name) FROM tb_name WHERE clause;
```
-**Description**: The current time of the client side system
+**Description**: instantaneous rate on a specific column. The last two samples in the specified time range are used to calculate instantaneous rate. If the last sample value is smaller, then only the last sample value is used instead of the difference between the last two sample values.
-**Return value type**: TIMESTAMP
+**Return value type**: Double precision floating number
-**Applicable column types**: TIMESTAMP only
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
**More explanations**:
-- Add and Subtract operation can be performed, for example NOW() + 1s, the time unit can be:
- b(nanosecond), u(microsecond), a(millisecond)), s(second), m(minute), h(hour), d(day), w(week)
-- The precision of the returned timestamp is same as the precision set for the current data base in use
+- It can be used on stble with `GROUP BY`, i.e. timelines generated by `GROUP BY tbname` on a STable.
-**Examples**:
+### MAVG
```sql
-taos> SELECT NOW() FROM meters;
- now() |
-==========================
- 2022-02-02 02:02:02.456 |
-Query OK, 1 row(s) in set (0.002093s)
-
-taos> SELECT NOW() + 1h FROM meters;
- now() + 1h |
-==========================
- 2022-02-02 03:02:02.456 |
-Query OK, 1 row(s) in set (0.002093s)
-
-taos> SELECT COUNT(voltage) FROM d1001 WHERE ts < NOW();
- count(voltage) |
-=============================
- 5 |
-Query OK, 5 row(s) in set (0.004475s)
-
-taos> INSERT INTO d1001 VALUES (NOW(), 10.2, 219, 0.32);
-Query OK, 1 of 1 row(s) in database (0.002210s)
+ SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
```
-### TODAY
-
-```sql
-SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
-SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
-INSERT INTO tb_name VALUES (TODAY(), ...);
-```
+**Description**: The moving average of continuous _k_ values of a specific column. If the number of input rows is less than _k_, nothing is returned. The applicable range of _k_ is [1,1000].
-**Description**: The timestamp of 00:00:00 of the client side system
+**Return value type**: Double precision floating point
-**Return value type**: TIMESTAMP
+**Applicable data types**: Numeric types
-**Applicable column types**: TIMESTAMP only
+**Applicable nested query**: Inner query and Outer query
**Applicable table types**: table, STable
**More explanations**:
-- Add and Subtract operation can be performed, for example NOW() + 1s, the time unit can be:
- b(nanosecond), u(microsecond), a(millisecond)), s(second), m(minute), h(hour), d(day), w(week)
-- The precision of the returned timestamp is same as the precision set for the current data base in use
+- Arithmetic operation can't be performed on the result of `MAVG`.
+- Can't be used with aggregate functions.
+- Must be used with `GROUP BY tbname` when it's used on a STable to force the result on each single timeline.
-**Examples**:
+### SAMPLE
```sql
-taos> SELECT TODAY() FROM meters;
- today() |
-==========================
- 2022-02-02 00:00:00.000 |
-Query OK, 1 row(s) in set (0.002093s)
-
-taos> SELECT TODAY() + 1h FROM meters;
- today() + 1h |
-==========================
- 2022-02-02 01:00:00.000 |
-Query OK, 1 row(s) in set (0.002093s)
-
-taos> SELECT COUNT(voltage) FROM d1001 WHERE ts < TODAY();
- count(voltage) |
-=============================
- 5 |
-Query OK, 5 row(s) in set (0.004475s)
-
-taos> INSERT INTO d1001 VALUES (TODAY(), 10.2, 219, 0.32);
-Query OK, 1 of 1 row(s) in database (0.002210s)
+ SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
```
-### TIMEZONE
+**Description**: _k_ sampling values of a specific column. The applicable range of _k_ is [1,10000]
-```sql
-SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
-```
+**Return value type**: Same as the column being operated plus the associated timestamp
-**Description**: The timezone of the client side system
+**Applicable data types**: Any data type except for tags of STable
-**Return value type**: BINARY
+**Applicable table types**: table, STable
-**Applicable column types**: None
+**Applicable nested query**: Inner query and Outer query
-**Applicable table types**: table, STable
+**More explanations**:
-**Examples**:
+- Arithmetic operation can't be operated on the result of `SAMPLE` function
+- Must be used with `Group by tbname` when it's used on a STable to force the result on each single timeline
-```sql
-taos> SELECT TIMEZONE() FROM meters;
- timezone() |
-=================================
- UTC (UTC, +0000) |
-Query OK, 1 row(s) in set (0.002093s)
+### STATECOUNT
+
+```
+SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
```
-### TO_ISO8601
+**Description**: The number of continuous rows satisfying the specified conditions for a specific column. The result is shown as an extra column for each row. If the specified condition is evaluated as true, the number is increased by 1; otherwise the number is reset to -1. If the input value is NULL, then the corresponding row is skipped.
-```sql
-SELECT TO_ISO8601(ts_val | ts_col) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Applicable parameter values**:
-**Description**: The ISO8601 date/time format converted from a UNIX timestamp, plus the timezone of the client side system
+- oper : Can be one of LT (lower than), GT (greater than), LE (lower than or euqal to), GE (greater than or equal to), NE (not equal to), EQ (equal to), the value is case insensitive
+- val : Numeric types
-**Return value type**: BINARY
+**Return value type**: Integer
-**Applicable column types**: TIMESTAMP, constant or a column
+**Applicable data types**: Numeric types
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Outer query only
-- If the input is UNIX timestamp constant, the precision of the returned value is determined by the digits of the input timestamp
-- If the input is a column of TIMESTAMP type, The precision of the returned value is same as the precision set for the current data base in use
+**More explanations**:
-**Examples**:
+- Must be used together with `GROUP BY tbname` when it's used on a STable to force the result into each single timeline]
+- Can't be used with window operation, like interval/state_window/session_window
-```sql
-taos> SELECT TO_ISO8601(1643738400) FROM meters;
- to_iso8601(1643738400) |
-==============================
- 2022-02-02T02:00:00+0800 |
+### STATEDURATION
-taos> SELECT TO_ISO8601(ts) FROM meters;
- to_iso8601(ts) |
-==============================
- 2022-02-02T02:00:00+0800 |
- 2022-02-02T02:00:00+0800 |
- 2022-02-02T02:00:00+0800 |
+```
+SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
```
-### TO_UNIXTIMESTAMP
+**Description**: The length of time range in which all rows satisfy the specified condition for a specific column. The result is shown as an extra column for each row. The length for the first row that satisfies the condition is 0. Next, if the condition is evaluated as true for a row, the time interval between current row and its previous row is added up to the time range; otherwise the time range length is reset to -1. If the value of the column is NULL, the corresponding row is skipped.
-```sql
-SELECT TO_UNIXTIMESTAMP(datetime_string | ts_col) FROM { tb_name | stb_name } [WHERE clause];
-```
+**Applicable parameter values**:
-**Description**: UNIX timestamp converted from a string of date/time format
+- oper : Can be one of LT (lower than), GT (greater than), LE (lower than or euqal to), GE (greater than or equal to), NE (not equal to), EQ (equal to), the value is case insensitive
+- val : Numeric types
+- unit: The unit of time interval, can be [1s, 1m, 1h], default is 1s
-**Return value type**: Long integer
+**Return value type**: Integer
-**Applicable column types**: Constant or column of BINARY/NCHAR
+**Applicable data types**: Numeric types
**Applicable table types**: table, STable
-**More explanations**:
+**Applicable nested query**: Outer query only
-- The input string must be compatible with ISO8601/RFC3339 standard, 0 will be returned if the string can't be converted
-- The precision of the returned timestamp is same as the precision set for the current data base in use
+**More explanations**:
-**Examples**:
+- Must be used together with `GROUP BY tbname` when it's used on a STable to force the result into each single timeline]
+- Can't be used with window operation, like interval/state_window/session_window
-```sql
-taos> SELECT TO_UNIXTIMESTAMP("2022-02-02T02:00:00.000Z") FROM meters;
-to_unixtimestamp("2022-02-02T02:00:00.000Z") |
-==============================================
- 1643767200000 |
+### TWA
-taos> SELECT TO_UNIXTIMESTAMP(col_binary) FROM meters;
- to_unixtimestamp(col_binary) |
-========================================
- 1643767200000 |
- 1643767200000 |
- 1643767200000 |
```
-
-### TIMETRUNCATE
-
-```sql
-SELECT TIMETRUNCATE(ts_val | datetime_string | ts_col, time_unit) FROM { tb_name | stb_name } [WHERE clause];
+SELECT TWA(field_name) FROM tb_name WHERE clause;
```
-**Description**: Truncate the input timestamp with unit specified by `time_unit`\
+**Description**: Time weighted average on a specific column within a time range
-**Return value type**: TIMESTAMP\
+**Return value type**: Double precision floating number
-**Applicable column types**: UNIX timestamp constant, string constant of date/time format, or a column of timestamp
+**Applicable column types**: Numeric types
**Applicable table types**: table, STable
**More explanations**:
-- Time unit specified by `time_unit` can be:
- 1u(microsecond),1a(millisecond),1s(second),1m(minute),1h(hour),1d(day).
-- The precision of the returned timestamp is same as the precision set for the current data base in use
-
-**Examples**:
+- It can be used on stable with `GROUP BY`, i.e. timelines generated by `GROUP BY tbname` on a STable.
-```sql
-taos> SELECT TIMETRUNCATE(1643738522000, 1h) FROM meters;
- timetruncate(1643738522000, 1h) |
-===================================
- 2022-02-02 02:00:00.000 |
-Query OK, 1 row(s) in set (0.001499s)
+## System Information Functions
-taos> SELECT TIMETRUNCATE("2022-02-02 02:02:02", 1h) FROM meters;
- timetruncate("2022-02-02 02:02:02", 1h) |
-===========================================
- 2022-02-02 02:00:00.000 |
-Query OK, 1 row(s) in set (0.003903s)
+### DATABASE
-taos> SELECT TIMETRUNCATE(ts, 1h) FROM meters;
- timetruncate(ts, 1h) |
-==========================
- 2022-02-02 02:00:00.000 |
- 2022-02-02 02:00:00.000 |
- 2022-02-02 02:00:00.000 |
-Query OK, 3 row(s) in set (0.003903s)
```
-
-### 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 DATABASE();
```
-**Description**: The difference between two timestamps, and rounded to the time unit specified by `time_unit`
+**Description**:Return the current database being used. If the user doesn't specify database when logon and doesn't use `USE` SQL command to switch the datbase, this function returns NULL.
-**Return value type**: Long Integer
+### CLIENT_VERSION
-**Applicable column types**: UNIX timestamp constant, string constant of date/time format, or a column of TIMESTAMP type
+```
+SELECT CLIENT_VERSION();
+```
-**Applicable table types**: table, STable
+**Description**:Return the client version.
-**More explanations**:
+### SERVER_VERSION
-- Time unit specified by `time_unit` can be:
- 1u(microsecond),1a(millisecond),1s(second),1m(minute),1h(hour),1d(day).
-- The precision of the returned timestamp is same as the precision set for the current data base in use
+```
+SELECT SERVER_VERSION();
+```
-**Applicable versions**:Since version 2.6.0.0
+**Description**:Returns the server version.
-**Examples**:
+### SERVER_STATUS
-```sql
-taos> SELECT TIMEDIFF(1643738400000, 1643742000000) FROM meters;
- timediff(1643738400000, 1643742000000) |
-=========================================
- 3600000 |
-Query OK, 1 row(s) in set (0.002553s)
-taos> SELECT TIMEDIFF(1643738400000, 1643742000000, 1h) FROM meters;
- timediff(1643738400000, 1643742000000, 1h) |
-=============================================
- 1 |
-Query OK, 1 row(s) in set (0.003726s)
-
-taos> SELECT TIMEDIFF("2022-02-02 03:00:00", "2022-02-02 02:00:00", 1h) FROM meters;
- timediff("2022-02-02 03:00:00", "2022-02-02 02:00:00", 1h) |
-=============================================================
- 1 |
-Query OK, 1 row(s) in set (0.001937s)
-
-taos> SELECT TIMEDIFF(ts_col1, ts_col2, 1h) FROM meters;
- timediff(ts_col1, ts_col2, 1h) |
-===================================
- 1 |
-Query OK, 1 row(s) in set (0.001937s)
```
+SELECT SERVER_VERSION();
+```
+
+**Description**:Returns the server's status.
diff --git a/docs-en/12-taos-sql/12-keywords.md b/docs-en/12-taos-sql/12-keywords.md
index 56a82a02a1fada712141f3572b761e0cd18576c6..ed0c96b4e4d94dd70da1c3778f4129bd34daed62 100644
--- a/docs-en/12-taos-sql/12-keywords.md
+++ b/docs-en/12-taos-sql/12-keywords.md
@@ -47,15 +47,16 @@ There are about 200 keywords reserved by TDengine, they can't be used as the nam
| CONNS | ID | NOTNULL | STable | WAL |
| COPY | IF | NOW | STableS | WHERE |
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
-| _WSTOP | _WDURATION |
+| _WSTOP | _WDURATION | _ROWTS |
## Explanations
### TBNAME
-`TBNAME` can be considered as a special tag, which represents the name of the subtable, in STable.
+`TBNAME` can be considered as a special tag, which represents the name of the subtable, in a STable.
Get the table name and tag values of all subtables in a STable.
```mysql
SELECT TBNAME, location FROM meters;
+```
Count the number of subtables in a STable.
```mysql
@@ -80,10 +81,10 @@ taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2;
Query OK, 1 row(s) in set (0.001091s)
```
### _QSTART/_QSTOP/_QDURATION
-The start, stop and duration of a query time window (Since version 2.6.0.0).
+The start, stop and duration of a query time window.
### _WSTART/_WSTOP/_WDURATION
-The start, stop and duration of aggegate query by time window, like interval, session window, state window (Since version 2.6.0.0).
+The start, stop and duration of aggegate query by time window, like interval, session window, state window.
-### _c0
-The first column of a table or STable.
\ No newline at end of file
+### _c0/_ROWTS
+_c0 is equal to _ROWTS, it means the first column of a table or STable.
diff --git a/docs-en/12-taos-sql/13-operators.md b/docs-en/12-taos-sql/13-operators.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ca9ec49430a66384400bc41cd08562b3d5d28c7
--- /dev/null
+++ b/docs-en/12-taos-sql/13-operators.md
@@ -0,0 +1,66 @@
+---
+sidebar_label: Operators
+title: Operators
+---
+
+## Arithmetic Operators
+
+| # | **Operator** | **Data Types** | **Description** |
+| --- | :----------: | -------------- | --------------------------------------------------------- |
+| 1 | +, - | Numeric Types | Representing positive or negative numbers, unary operator |
+| 2 | +, - | Numeric Types | Addition and substraction, binary operator |
+| 3 | \*, / | Numeric Types | Multiplication and division, binary oeprator |
+| 4 | % | Numeric Types | Taking the remainder, binary operator |
+
+## Bitwise Operators
+
+| # | **Operator** | **Data Types** | **Description** |
+| --- | :----------: | -------------- | ----------------------------- |
+| 1 | & | Numeric Types | Bitewise AND, binary operator |
+| 2 | \| | Numeric Types | Bitewise OR, binary operator |
+
+## JSON Operator
+
+`->` operator can be used to get the value of a key in a column of JSON type, the left oeprand is the column name, the right operand is a string constant. For example, `col->'name'` returns the value of key `'name'`.
+
+## Set Operator
+
+Set operators are used to combine the results of two queries into single result. A query including set operators is called a combined query. The number of rows in each result in a combined query must be same, and the type is determined by the first query's result, the type of the following queriess result must be able to be converted to the type of the first query's result, the conversion rule is same as `CAST` function.
+
+TDengine provides 2 set operators: `UNION ALL` and `UNION`. `UNION ALL` combines the results without removing duplicate data. `UNION` combines the results and remove duplicate data rows. In single SQL statement, at most 100 set operators can be used.
+
+## Comparsion Operator
+
+| # | **Operator** | **Data Types** | **Description** |
+| --- | :---------------: | ------------------------------------------------------------------- | ----------------------------------------------- |
+| 1 | = | Except for BLOB, MEDIUMBLOB and JSON | Equal |
+| 2 | <\>, != | Except for BLOB, MEDIUMBLOB, JSON and primary key of timestamp type | Not equal |
+| 3 | \>, < | Except for BLOB, MEDIUMBLOB and JSON | Greater than, less than |
+| 4 | \>=, <= | Except for BLOB, MEDIUMBLOB and JSON | Greater than or equal to, less than or equal to |
+| 5 | IS [NOT] NULL | Any types | Is NULL or NOT |
+| 6 | [NOT] BETWEEN AND | Except for BLOB, MEDIUMBLOB and JSON | In a value range or not |
+| 7 | IN | Except for BLOB, MEDIUMBLOB, JSON and primary key of timestamp type | In a list of values or not |
+| 8 | LIKE | BINARY, NCHAR and VARCHAR | Wildcard matching |
+| 9 | MATCH, NMATCH | BINARY, NCHAR and VARCHAR | Regular expression matching |
+| 10 | CONTAINS | JSON | If A key exists in JSON |
+
+`LIKE` operator uses wildcard to match a string, the rules are:
+
+- '%' matches 0 to any number of characters; '\_' matches any single ASCII character.
+- \_ can be used to match a `_` in the string, i.e. using escape character backslash `\`
+- Wildcard string is 100 bytes at most. Longer a wildcard string is, worse the performance of LIKE operator is.
+
+`MATCH` and `NMATCH` operators use regular expressions to match a string, the rules are:
+
+- Regular expressions of POSIX standard are supported.
+- Only `tbname`, i.e. table name of sub tables, and tag columns of string types can be matched with regular expression, data columns are not supported.
+- Regular expression string is 128 bytes at most, and can be adjusted by setting parameter `maxRegexStringLen`, which is a client side configuration and needs to restart the client to take effect.
+
+## Logical Operators
+
+| # | **Operator** | **Data Types** | **Description** |
+| --- | :----------: | -------------- | ---------------------------------------------------------------------------------------- |
+| 1 | AND | BOOL | Logical AND, return TRUE if both conditions are TRUE; return FALSE if any one is FALSE. |
+| 2 | OR | BOOL | Logical OR, return TRUE if any condition is TRUE; return FALSE if both are FALSE |
+
+TDengine uses shortcircut optimization when performing logical operations. For AND operator, if the first condition is evaluated to FALSE, then the second one is not evaluated. For OR operator, if the first condition is evaluated to TRUE, then the second one is not evaluated.
diff --git a/docs-en/14-reference/03-connector/cpp.mdx b/docs-en/14-reference/03-connector/cpp.mdx
index d13a74384ccc99b4200f89cdba98e5ba902e41f8..d549413012d1f17edf4711ae51a56ba5696fcbe3 100644
--- a/docs-en/14-reference/03-connector/cpp.mdx
+++ b/docs-en/14-reference/03-connector/cpp.mdx
@@ -114,7 +114,6 @@ This section shows sample code for standard access methods to TDengine clusters
Subscribe and consume
```c
-{{#include examples/c/subscribe.c}}
```
diff --git a/docs-en/20-third-party/01-grafana.mdx b/docs-en/20-third-party/01-grafana.mdx
index b3cab6271001feb56714f808906cb78ba1098593..1a84e02c665d2e49deca35a20b137b205736def5 100644
--- a/docs-en/20-third-party/01-grafana.mdx
+++ b/docs-en/20-third-party/01-grafana.mdx
@@ -9,7 +9,8 @@ You can learn more about using the TDengine plugin on [GitHub](https://github.co
## Prerequisites
-In order for Grafana to add the TDengine data source successfully, the following preparation is required:
+In order for Grafana to add the TDengine data source successfully, the following preparations are required:
+
1. The TDengine cluster is deployed and functioning properly
2. taosAdapter is installed and running properly. Please refer to the taosAdapter manual for details.
@@ -19,41 +20,34 @@ TDengine currently supports Grafana versions 7.0 and above. Users can go to the
## Configuring Grafana
-You can download The Grafana plugin for TDengine from . The current latest version is 3.1.4.
-
-Recommend using the [``grafana-cli`` command-line tool](https://grafana.com/docs/grafana/latest/administration/cli/) for plugin installation.
+Follow the installation steps in [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) with the [``grafana-cli`` command-line tool](https://grafana.com/docs/grafana/latest/administration/cli/) for plugin installation.
```bash
-sudo -u grafana grafana-cli \
- --pluginUrl https://github.com/taosdata/grafanaplugin/releases/download/v3.1.4/tdengine-datasource-3.1.4.zip \
- plugins install tdengine-datasource
+grafana-cli plugins install tdengine-datasource
+# with sudo
+sudo -u grafana grafana-cli plugins install tdengine-datasource
```
-Or download it locally and extract it to the Grafana plugin directory.
+Alternatively, you can manually download the .zip file from [GitHub](https://github.com/taosdata/grafanaplugin/releases/tag/latest) or [Grafana](https://grafana.com/grafana/plugins/tdengine-datasource/?tab=installation) and unpack it into your grafana plugins directory.
```bash
-GF_VERSION=3.1.4
+GF_VERSION=3.2.2
+# from GitHub
wget https://github.com/taosdata/grafanaplugin/releases/download/v$GF_VERSION/tdengine-datasource-$GF_VERSION.zip
+# from Grafana
+wget -O tdengine-datasource-$GF_VERSION.zip https://grafana.com/api/plugins/tdengine-datasource/versions/$GF_VERSION/download
```
-In CentOS 7.2 for example, extract the plugin package to /var/lib/grafana/plugins directory, and restart grafana.
+Take CentOS 7.2 for example, extract the plugin package to /var/lib/grafana/plugins directory, and restart grafana.
```bash
sudo unzip tdengine-datasource-$GF_VERSION.zip -d /var/lib/grafana/plugins/
```
-Grafana versions 7.3+ / 8.x do signature checks on plugins, so you also need to add the following line to the grafana.ini file to use the plugin correctly.
-
-```ini
-[plugins]
-allow_loading_unsigned_plugins = tdengine-datasource
-```
-
-The TDengine plugin can be automatically installed and set up using the following environment variable settings in a Docker environment.
+If Grafana is running in a Docker environment, the TDengine plugin can be automatically installed and set up using the following environment variable settings:
```bash
-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_INSTALL_PLUGINS=tdengine-datasource
```
## Using Grafana
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
deleted file mode 100644
index 365b1b7172f394111c5e75b113a9ce1e1ce8822b..0000000000000000000000000000000000000000
--- a/example/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-add_executable(tmq "")
-add_executable(tstream "")
-add_executable(demoapi "")
-
-target_sources(tmq
- PRIVATE
- "src/tmq.c"
-)
-
-target_sources(tstream
- PRIVATE
- "src/tstream.c"
-)
-
-target_sources(demoapi
- PRIVATE
- "src/demoapi.c"
-)
-
-target_link_libraries(tmq
- taos_static
-)
-
-target_link_libraries(tstream
- taos_static
-)
-
-target_link_libraries(demoapi
- taos_static
-)
-
-target_include_directories(tmq
- PUBLIC "${TD_SOURCE_DIR}/include/os"
- PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
-)
-
-target_include_directories(tstream
- PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
-)
-
-target_include_directories(demoapi
- PUBLIC "${TD_SOURCE_DIR}/include/client"
- PUBLIC "${TD_SOURCE_DIR}/include/os"
- PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
-)
-
-SET_TARGET_PROPERTIES(tmq PROPERTIES OUTPUT_NAME tmq)
-SET_TARGET_PROPERTIES(tstream PROPERTIES OUTPUT_NAME tstream)
-SET_TARGET_PROPERTIES(demoapi PROPERTIES OUTPUT_NAME demoapi)
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index 17a9257c499c6a1efd24fb23b47a9e9835ad7ade..4a9007acecaa679dc716c5665eea7f0cd1e34dbb 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -3,20 +3,70 @@ PROJECT(TDengine)
IF (TD_LINUX)
INCLUDE_DIRECTORIES(. ${TD_SOURCE_DIR}/src/inc ${TD_SOURCE_DIR}/src/client/inc ${TD_SOURCE_DIR}/inc)
AUX_SOURCE_DIRECTORY(. SRC)
- ADD_EXECUTABLE(demo apitest.c)
- TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
- ADD_EXECUTABLE(sml schemaless.c)
- TARGET_LINK_LIBRARIES(sml taos_static trpc tutil pthread )
- ADD_EXECUTABLE(subscribe subscribe.c)
- TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
- ADD_EXECUTABLE(epoll epoll.c)
- TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
+ # ADD_EXECUTABLE(demo apitest.c)
+ #TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
+ #ADD_EXECUTABLE(sml schemaless.c)
+ #TARGET_LINK_LIBRARIES(sml taos_static trpc tutil pthread )
+ #ADD_EXECUTABLE(subscribe subscribe.c)
+ #TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
+ #ADD_EXECUTABLE(epoll epoll.c)
+ #TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
+
+ add_executable(tmq "")
+ add_executable(stream_demo "")
+ add_executable(demoapi "")
+
+ target_sources(tmq
+ PRIVATE
+ "tmq.c"
+ )
+
+ target_sources(stream_demo
+ PRIVATE
+ "stream_demo.c"
+ )
+
+ target_sources(demoapi
+ PRIVATE
+ "demoapi.c"
+ )
+
+ target_link_libraries(tmq
+ taos_static
+ )
+
+ target_link_libraries(stream_demo
+ taos_static
+ )
+
+ target_link_libraries(demoapi
+ taos_static
+ )
+
+ target_include_directories(tmq
+ PUBLIC "${TD_SOURCE_DIR}/include/os"
+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
+ )
+
+ target_include_directories(stream_demo
+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
+ )
+
+ target_include_directories(demoapi
+ PUBLIC "${TD_SOURCE_DIR}/include/client"
+ PUBLIC "${TD_SOURCE_DIR}/include/os"
+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
+ )
+
+ SET_TARGET_PROPERTIES(tmq PROPERTIES OUTPUT_NAME tmq)
+ SET_TARGET_PROPERTIES(stream_demo PROPERTIES OUTPUT_NAME stream_demo)
+ SET_TARGET_PROPERTIES(demoapi PROPERTIES OUTPUT_NAME demoapi)
ENDIF ()
IF (TD_DARWIN)
INCLUDE_DIRECTORIES(. ${TD_SOURCE_DIR}/src/inc ${TD_SOURCE_DIR}/src/client/inc ${TD_SOURCE_DIR}/inc)
AUX_SOURCE_DIRECTORY(. SRC)
- ADD_EXECUTABLE(demo demo.c)
- TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread lua)
- ADD_EXECUTABLE(epoll epoll.c)
- TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
+ #ADD_EXECUTABLE(demo demo.c)
+ #TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread lua)
+ #ADD_EXECUTABLE(epoll epoll.c)
+ #TARGET_LINK_LIBRARIES(epoll taos_static trpc tutil pthread lua)
ENDIF ()
diff --git a/example/src/demoapi.c b/examples/c/demoapi.c
similarity index 100%
rename from example/src/demoapi.c
rename to examples/c/demoapi.c
diff --git a/example/src/tstream.c b/examples/c/stream_demo.c
similarity index 100%
rename from example/src/tstream.c
rename to examples/c/stream_demo.c
diff --git a/examples/c/subscribe.c b/examples/c/subscribe.c
deleted file mode 100644
index 66d64d295ce5c2700088842dd2c3ce013225f3bd..0000000000000000000000000000000000000000
--- a/examples/c/subscribe.c
+++ /dev/null
@@ -1,263 +0,0 @@
-// sample code for TDengine subscribe/consume API
-// to compile: gcc -o subscribe subscribe.c -ltaos
-
-#include
-#include
-#include
-#include
-#include "../../../include/client/taos.h" // include TDengine header file
-
-int nTotalRows;
-
-void print_result(TAOS_RES* res, int blockFetch) {
- TAOS_ROW row = NULL;
- int num_fields = taos_num_fields(res);
- TAOS_FIELD* fields = taos_fetch_fields(res);
- int nRows = 0;
-
- if (blockFetch) {
- nRows = taos_fetch_block(res, &row);
- //for (int i = 0; i < nRows; i++) {
- // taos_print_row(buf, row + i, fields, num_fields);
- // puts(buf);
- //}
- } else {
- while ((row = taos_fetch_row(res))) {
- char buf[4096] = {0};
- taos_print_row(buf, row, fields, num_fields);
- puts(buf);
- nRows++;
- }
- }
-
- nTotalRows += nRows;
- printf("%d rows consumed.\n", nRows);
-}
-
-
-void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
- print_result(res, *(int*)param);
-}
-
-
-void check_row_count(int line, TAOS_RES* res, int expected) {
- int actual = 0;
- TAOS_ROW row;
- while ((row = taos_fetch_row(res))) {
- actual++;
- }
- if (actual != expected) {
- printf("line %d: row count mismatch, expected: %d, actual: %d\n", line, expected, actual);
- } else {
- printf("line %d: %d rows consumed as expected\n", line, actual);
- }
-}
-
-
-void do_query(TAOS* taos, const char* sql) {
- TAOS_RES* res = taos_query(taos, sql);
- taos_free_result(res);
-}
-
-
-void run_test(TAOS* taos) {
- do_query(taos, "drop database if exists test;");
-
- usleep(100000);
- do_query(taos, "create database test;");
- usleep(100000);
- do_query(taos, "use test;");
-
- usleep(100000);
- do_query(taos, "create table meters(ts timestamp, a int) tags(area int);");
-
- do_query(taos, "create table t0 using meters tags(0);");
- do_query(taos, "create table t1 using meters tags(1);");
- do_query(taos, "create table t2 using meters tags(2);");
- do_query(taos, "create table t3 using meters tags(3);");
- do_query(taos, "create table t4 using meters tags(4);");
- do_query(taos, "create table t5 using meters tags(5);");
- do_query(taos, "create table t6 using meters tags(6);");
- do_query(taos, "create table t7 using meters tags(7);");
- do_query(taos, "create table t8 using meters tags(8);");
- do_query(taos, "create table t9 using meters tags(9);");
-
- do_query(taos, "insert into t0 values('2020-01-01 00:00:00.000', 0);");
- do_query(taos, "insert into t0 values('2020-01-01 00:01:00.000', 0);");
- do_query(taos, "insert into t0 values('2020-01-01 00:02:00.000', 0);");
- do_query(taos, "insert into t1 values('2020-01-01 00:00:00.000', 0);");
- do_query(taos, "insert into t1 values('2020-01-01 00:01:00.000', 0);");
- do_query(taos, "insert into t1 values('2020-01-01 00:02:00.000', 0);");
- do_query(taos, "insert into t1 values('2020-01-01 00:03:00.000', 0);");
- do_query(taos, "insert into t2 values('2020-01-01 00:00:00.000', 0);");
- do_query(taos, "insert into t2 values('2020-01-01 00:01:00.000', 0);");
- do_query(taos, "insert into t2 values('2020-01-01 00:01:01.000', 0);");
- do_query(taos, "insert into t2 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t3 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t4 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t5 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t6 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t7 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t8 values('2020-01-01 00:01:02.000', 0);");
- do_query(taos, "insert into t9 values('2020-01-01 00:01:02.000', 0);");
-
- // super tables subscription
- usleep(1000000);
-
- TAOS_SUB* tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
- TAOS_RES* res = taos_consume(tsub);
- check_row_count(__LINE__, res, 18);
-
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 0);
-
- do_query(taos, "insert into t0 values('2020-01-01 00:02:00.001', 0);");
- do_query(taos, "insert into t8 values('2020-01-01 00:01:03.000', 0);");
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 2);
-
- do_query(taos, "insert into t2 values('2020-01-01 00:01:02.001', 0);");
- do_query(taos, "insert into t1 values('2020-01-01 00:03:00.001', 0);");
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 2);
-
- do_query(taos, "insert into t1 values('2020-01-01 00:03:00.002', 0);");
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 1);
-
- // keep progress information and restart subscription
- taos_unsubscribe(tsub, 1);
- do_query(taos, "insert into t0 values('2020-01-01 00:04:00.000', 0);");
- tsub = taos_subscribe(taos, 1, "test", "select * from meters;", NULL, NULL, 0);
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 24);
-
- // keep progress information and continue previous subscription
- taos_unsubscribe(tsub, 1);
- tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 0);
-
- // don't keep progress information and continue previous subscription
- taos_unsubscribe(tsub, 0);
- tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 24);
-
- // single meter subscription
-
- taos_unsubscribe(tsub, 0);
- tsub = taos_subscribe(taos, 0, "test", "select * from t0;", NULL, NULL, 0);
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 5);
-
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 0);
-
- do_query(taos, "insert into t0 values('2020-01-01 00:04:00.001', 0);");
- res = taos_consume(tsub);
- check_row_count(__LINE__, res, 1);
-
- taos_unsubscribe(tsub, 0);
-}
-
-
-int main(int argc, char *argv[]) {
- const char* host = "127.0.0.1";
- const char* user = "root";
- const char* passwd = "taosdata";
- const char* sql = "select * from meters;";
- const char* topic = "test-multiple";
- int async = 1, restart = 0, keep = 1, test = 0, blockFetch = 0;
-
- for (int i = 1; i < argc; i++) {
- if (strncmp(argv[i], "-h=", 3) == 0) {
- host = argv[i] + 3;
- continue;
- }
- if (strncmp(argv[i], "-u=", 3) == 0) {
- user = argv[i] + 3;
- continue;
- }
- if (strncmp(argv[i], "-p=", 3) == 0) {
- passwd = argv[i] + 3;
- continue;
- }
- if (strcmp(argv[i], "-sync") == 0) {
- async = 0;
- continue;
- }
- if (strcmp(argv[i], "-restart") == 0) {
- restart = 1;
- continue;
- }
- if (strcmp(argv[i], "-single") == 0) {
- sql = "select * from t0;";
- topic = "test-single";
- continue;
- }
- if (strcmp(argv[i], "-nokeep") == 0) {
- keep = 0;
- continue;
- }
- if (strncmp(argv[i], "-sql=", 5) == 0) {
- sql = argv[i] + 5;
- topic = "test-custom";
- continue;
- }
- if (strcmp(argv[i], "-test") == 0) {
- test = 1;
- continue;
- }
- if (strcmp(argv[i], "-block-fetch") == 0) {
- blockFetch = 1;
- continue;
- }
- }
-
- TAOS* taos = taos_connect(host, user, passwd, "", 0);
- if (taos == NULL) {
- printf("failed to connect to db, reason:%s\n", taos_errstr(taos));
- exit(1);
- }
-
- if (test) {
- run_test(taos);
- taos_close(taos);
- exit(0);
- }
-
- taos_select_db(taos, "test");
- TAOS_SUB* tsub = NULL;
- if (async) {
- // create an asynchronized subscription, the callback function will be called every 1s
- tsub = taos_subscribe(taos, restart, topic, sql, subscribe_callback, &blockFetch, 1000);
- } else {
- // create an synchronized subscription, need to call 'taos_consume' manually
- tsub = taos_subscribe(taos, restart, topic, sql, NULL, NULL, 0);
- }
-
- if (tsub == NULL) {
- printf("failed to create subscription.\n");
- exit(0);
- }
-
- if (async) {
- getchar();
- } else while(1) {
- TAOS_RES* res = taos_consume(tsub);
- if (res == NULL) {
- printf("failed to consume data.");
- break;
- } else {
- print_result(res, blockFetch);
- getchar();
- }
- }
-
- printf("total rows consumed: %d\n", nTotalRows);
- taos_unsubscribe(tsub, keep);
- taos_close(taos);
-
- return 0;
-}
diff --git a/example/src/tmq.c b/examples/c/tmq.c
similarity index 84%
rename from example/src/tmq.c
rename to examples/c/tmq.c
index 913096ee90294cf65ba81d605ed3e7d4f2fa803c..2e8aa21da7a2bdd83e4a995beccb99ac40228a48 100644
--- a/example/src/tmq.c
+++ b/examples/c/tmq.c
@@ -24,6 +24,7 @@ static void msg_process(TAOS_RES* msg) {
char buf[1024];
/*memset(buf, 0, 1024);*/
printf("topic: %s\n", tmq_get_topic_name(msg));
+ printf("db: %s\n", tmq_get_db_name(msg));
printf("vg: %d\n", tmq_get_vgroup_id(msg));
while (1) {
TAOS_ROW row = taos_fetch_row(msg);
@@ -106,7 +107,7 @@ int32_t create_topic() {
}
taos_free_result(pRes);
- /*pRes = taos_query(pConn, "create topic topic_ctb_column as abc1");*/
+ /*pRes = taos_query(pConn, "create topic topic_ctb_column as database abc1");*/
pRes = taos_query(pConn, "create topic topic_ctb_column as select ts, c1, c2, c3 from st1");
if (taos_errno(pRes) != 0) {
printf("failed to create topic topic_ctb_column, reason:%s\n", taos_errstr(pRes));
@@ -165,7 +166,6 @@ tmq_t* build_consumer() {
tmq_conf_set(conf, "group.id", "tg2");
tmq_conf_set(conf, "td.connect.user", "root");
tmq_conf_set(conf, "td.connect.pass", "taosdata");
- /*tmq_conf_set(conf, "td.connect.db", "abc1");*/
tmq_conf_set(conf, "msg.with.table.name", "true");
tmq_conf_set(conf, "enable.auto.commit", "false");
tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
@@ -191,20 +191,18 @@ void basic_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
return;
}
int32_t cnt = 0;
- /*clock_t startTime = clock();*/
while (running) {
TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 0);
if (tmqmessage) {
cnt++;
+ msg_process(tmqmessage);
+ /*if (cnt >= 2) break;*/
/*printf("get data\n");*/
- /*msg_process(tmqmessage);*/
taos_free_result(tmqmessage);
/*} else {*/
/*break;*/
}
}
- /*clock_t endTime = clock();*/
- /*printf("log cnt: %d %f s\n", cnt, (double)(endTime - startTime) / CLOCKS_PER_SEC);*/
err = tmq_consumer_close(tmq);
if (err)
@@ -253,39 +251,6 @@ void sync_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
fprintf(stderr, "%% Consumer closed\n");
}
-void perf_loop(tmq_t* tmq, tmq_list_t* topics) {
- tmq_resp_err_t err;
-
- if ((err = tmq_subscribe(tmq, topics))) {
- fprintf(stderr, "%% Failed to start consuming topics: %s\n", tmq_err2str(err));
- printf("subscribe err\n");
- return;
- }
- int32_t batchCnt = 0;
- int32_t skipLogNum = 0;
- clock_t startTime = clock();
- while (running) {
- TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 500);
- if (tmqmessage) {
- batchCnt++;
- /*skipLogNum += tmqGetSkipLogNum(tmqmessage);*/
- /*msg_process(tmqmessage);*/
- taos_free_result(tmqmessage);
- } else {
- break;
- }
- }
- clock_t endTime = clock();
- printf("log batch cnt: %d, skip log cnt: %d, time used:%f s\n", batchCnt, skipLogNum,
- (double)(endTime - startTime) / CLOCKS_PER_SEC);
-
- err = tmq_consumer_close(tmq);
- if (err)
- fprintf(stderr, "%% Failed to close consumer: %s\n", tmq_err2str(err));
- else
- fprintf(stderr, "%% Consumer closed\n");
-}
-
int main(int argc, char* argv[]) {
if (argc > 1) {
printf("env init\n");
@@ -296,7 +261,6 @@ int main(int argc, char* argv[]) {
}
tmq_t* tmq = build_consumer();
tmq_list_t* topic_list = build_topic_list();
- /*perf_loop(tmq, topic_list);*/
- /*basic_consume_loop(tmq, topic_list);*/
- sync_consume_loop(tmq, topic_list);
+ basic_consume_loop(tmq, topic_list);
+ /*sync_consume_loop(tmq, topic_list);*/
}
diff --git a/include/client/taos.h b/include/client/taos.h
index 0b8c67aa794363ff851c69e5848978c78c6a4abc..b65091f52bdd218138891970f079158033cb2d69 100644
--- a/include/client/taos.h
+++ b/include/client/taos.h
@@ -85,6 +85,14 @@ typedef struct taosField {
int32_t bytes;
} TAOS_FIELD;
+typedef struct TAOS_FIELD_E {
+ char name[65];
+ int8_t type;
+ uint8_t precision;
+ uint8_t scale;
+ int32_t bytes;
+} TAOS_FIELD_E;
+
#ifdef WINDOWS
#define DLL_EXPORT __declspec(dllexport)
#else
@@ -134,7 +142,10 @@ DLL_EXPORT TAOS_STMT *taos_stmt_init(TAOS *taos);
DLL_EXPORT int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
DLL_EXPORT int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags);
DLL_EXPORT int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name);
+DLL_EXPORT int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags);
DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name);
+DLL_EXPORT int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields);
+DLL_EXPORT int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields);
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
@@ -230,7 +241,7 @@ DLL_EXPORT const char *tmq_err2str(tmq_resp_err_t);
DLL_EXPORT tmq_resp_err_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list);
DLL_EXPORT tmq_resp_err_t tmq_unsubscribe(tmq_t *tmq);
DLL_EXPORT tmq_resp_err_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics);
-DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t wait_time);
+DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout);
DLL_EXPORT tmq_resp_err_t tmq_consumer_close(tmq_t *tmq);
DLL_EXPORT tmq_resp_err_t tmq_commit_sync(tmq_t *tmq, const tmq_topic_vgroup_list_t *offsets);
DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const tmq_topic_vgroup_list_t *offsets, tmq_commit_cb *cb, void *param);
@@ -258,6 +269,7 @@ DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_comm
/* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */
DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res);
+DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res);
DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res);
DLL_EXPORT const char *tmq_get_table_name(TAOS_RES *res);
diff --git a/include/common/taosdef.h b/include/common/taosdef.h
index d39c7a121593e6feeb5cfbf104d07642bdbfaff7..516df71b0b886872fc1676bb058c9dc91ea9c3cb 100644
--- a/include/common/taosdef.h
+++ b/include/common/taosdef.h
@@ -97,6 +97,7 @@ extern char *qtypeStr[];
#undef TD_DEBUG_PRINT_ROW
#undef TD_DEBUG_PRINT_TSDB_LOAD_DCOLS
+#undef TD_DEBUG_PRINT_TAG
#ifdef __cplusplus
}
diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h
index ef931ed3b1c52b7bdc9d12da77f3bdc8ad1f7837..10bc6a61764f6500305e0712650e93d55255c58a 100644
--- a/include/common/tdataformat.h
+++ b/include/common/tdataformat.h
@@ -18,6 +18,7 @@
#include "os.h"
#include "talgo.h"
+#include "tarray.h"
#include "tencode.h"
#include "ttypes.h"
#include "tutil.h"
@@ -29,6 +30,7 @@ extern "C" {
typedef struct SSchema SSchema;
typedef struct STColumn STColumn;
typedef struct STSchema STSchema;
+typedef struct SValue SValue;
typedef struct SColVal SColVal;
typedef struct STSRow2 STSRow2;
typedef struct STSRowBuilder STSRowBuilder;
@@ -39,32 +41,37 @@ typedef struct STag STag;
int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t nCols, STSchema **ppTSchema);
void tTSchemaDestroy(STSchema *pTSchema);
-// SColVal
-#define ColValNONE ((SColVal){.type = COL_VAL_NONE, .nData = 0, .pData = NULL})
-#define ColValNULL ((SColVal){.type = COL_VAL_NULL, .nData = 0, .pData = NULL})
-#define ColValDATA(nData, pData) ((SColVal){.type = COL_VAL_DATA, .nData = (nData), .pData = (pData)})
-
// STSRow2
+#define COL_VAL_NONE(CID) ((SColVal){.cid = (CID), .isNone = 1})
+#define COL_VAL_NULL(CID) ((SColVal){.cid = (CID), .isNull = 1})
+#define COL_VAL_VALUE(CID, V) ((SColVal){.cid = (CID), .value = (V)})
+
+int32_t tTSRowClone(const STSRow2 *pRow, STSRow2 **ppRow);
+void tTSRowFree(STSRow2 *pRow);
+void tTSRowGet(STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal);
+int32_t tTSRowToArray(STSRow2 *pRow, STSchema *pTSchema, SArray **ppArray);
int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow);
int32_t tGetTSRow(uint8_t *p, STSRow2 *pRow);
-int32_t tTSRowDup(const STSRow2 *pRow, STSRow2 **ppRow);
-void tTSRowFree(STSRow2 *pRow);
-int32_t tTSRowGet(const STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal);
// STSRowBuilder
+#if 0
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, int32_t nCols, SSchema *pSchema);
void tTSRowBuilderClear(STSRowBuilder *pBuilder);
void tTSRowBuilderReset(STSRowBuilder *pBuilder);
int32_t tTSRowBuilderPut(STSRowBuilder *pBuilder, int32_t cid, uint8_t *pData, uint32_t nData);
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow);
+#endif
// STag
-int32_t tTagNew(STagVal *pTagVals, int16_t nTag, STag **ppTag);
+int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag);
void tTagFree(STag *pTag);
-int32_t tTagSet(STag *pTag, SSchema *pSchema, int32_t nCols, int iCol, uint8_t *pData, uint32_t nData, STag **ppTag);
-void tTagGet(STag *pTag, int16_t cid, int8_t type, uint8_t **ppData, uint32_t *nData);
+bool tTagGet(const STag *pTag, STagVal *pTagVal);
+char* tTagValToData(const STagVal *pTagVal, bool isJson);
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag);
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag);
+int32_t tTagToValArray(const STag *pTag, SArray **ppArray);
+void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove
+void debugCheckTags(STag *pTag); // TODO: remove
// STRUCT =================
struct STColumn {
@@ -87,7 +94,9 @@ struct STSchema {
#define TSROW_HAS_NONE ((uint8_t)0x1)
#define TSROW_HAS_NULL ((uint8_t)0x2U)
#define TSROW_HAS_VAL ((uint8_t)0x4U)
-#define TSROW_KV_ROW ((uint8_t)0x10U)
+#define TSROW_KV_SMALL ((uint8_t)0x10U)
+#define TSROW_KV_MID ((uint8_t)0x20U)
+#define TSROW_KV_BIG ((uint8_t)0x40U)
struct STSRow2 {
TSKEY ts;
uint8_t flags;
@@ -110,20 +119,60 @@ struct STSRowBuilder {
STSRow2 row;
};
-typedef enum { COL_VAL_NONE = 0, COL_VAL_NULL = 1, COL_VAL_DATA = 2 } EColValT;
+struct SValue {
+ union {
+ int8_t i8; // TSDB_DATA_TYPE_BOOL||TSDB_DATA_TYPE_TINYINT
+ uint8_t u8; // TSDB_DATA_TYPE_UTINYINT
+ int16_t i16; // TSDB_DATA_TYPE_SMALLINT
+ uint16_t u16; // TSDB_DATA_TYPE_USMALLINT
+ int32_t i32; // TSDB_DATA_TYPE_INT
+ uint32_t u32; // TSDB_DATA_TYPE_UINT
+ int64_t i64; // TSDB_DATA_TYPE_BIGINT
+ uint64_t u64; // TSDB_DATA_TYPE_UBIGINT
+ TSKEY ts; // TSDB_DATA_TYPE_TIMESTAMP
+ float f; // TSDB_DATA_TYPE_FLOAT
+ double d; // TSDB_DATA_TYPE_DOUBLE
+ struct {
+ uint32_t nData;
+ uint8_t *pData;
+ };
+ };
+};
+
struct SColVal {
- EColValT type;
- uint32_t nData;
- uint8_t *pData;
+ int16_t cid;
+ int8_t isNone;
+ int8_t isNull;
+ SValue value;
};
+#pragma pack(push, 1)
struct STagVal {
- int16_t cid;
- int8_t type;
- uint32_t nData;
- uint8_t *pData;
+ union {
+ int16_t cid;
+ char *pKey;
+ };
+ int8_t type;
+ union {
+ int64_t i64;
+ struct {
+ uint32_t nData;
+ uint8_t *pData;
+ };
+ };
};
+#define TD_TAG_JSON ((int8_t)0x40) // distinguish JSON string and JSON value with the highest bit
+#define TD_TAG_LARGE ((int8_t)0x20)
+struct STag {
+ int8_t flags;
+ int16_t len;
+ int16_t nTag;
+ int32_t ver;
+ int8_t idx[];
+};
+#pragma pack(pop)
+
#if 1 //================================================================================================================================================
// Imported since 3.0 and use bitmap to demonstrate None/Null/Norm, while use Null/Norm below 3.0 without of bitmap.
#define TD_SUPPORT_BITMAP
@@ -366,109 +415,6 @@ SDataCols *tdFreeDataCols(SDataCols *pCols);
int32_t tdMergeDataCols(SDataCols *target, SDataCols *source, int32_t rowsToMerge, int32_t *pOffset, bool update,
TDRowVerT maxVer);
-// ----------------- K-V data row structure
-/* |<-------------------------------------- len -------------------------------------------->|
- * |<----- header ----->|<--------------------------- body -------------------------------->|
- * +----------+----------+---------------------------------+---------------------------------+
- * | uint16_t | int16_t | | |
- * +----------+----------+---------------------------------+---------------------------------+
- * | len | ncols | cols index | data part |
- * +----------+----------+---------------------------------+---------------------------------+
- */
-typedef void *SKVRow;
-
-typedef struct {
- int16_t colId;
- uint16_t offset;
-} SColIdx;
-
-#define TD_KV_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t))
-
-#define kvRowLen(r) (*(uint16_t *)(r))
-#define kvRowNCols(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(uint16_t)))
-#define kvRowSetLen(r, len) kvRowLen(r) = (len)
-#define kvRowSetNCols(r, n) kvRowNCols(r) = (n)
-#define kvRowColIdx(r) (SColIdx *)POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE)
-#define kvRowValues(r) POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * kvRowNCols(r))
-#define kvRowCpy(dst, r) memcpy((dst), (r), kvRowLen(r))
-#define kvRowColVal(r, colIdx) POINTER_SHIFT(kvRowValues(r), (colIdx)->offset)
-#define kvRowColIdxAt(r, i) (kvRowColIdx(r) + (i))
-#define kvRowFree(r) taosMemoryFreeClear(r)
-#define kvRowEnd(r) POINTER_SHIFT(r, kvRowLen(r))
-#define kvRowValLen(r) (kvRowLen(r) - TD_KV_ROW_HEAD_SIZE - sizeof(SColIdx) * kvRowNCols(r))
-#define kvRowTKey(r) (*(TKEY *)(kvRowValues(r)))
-#define kvRowKey(r) tdGetKey(kvRowTKey(r))
-#define kvRowKeys(r) POINTER_SHIFT(r, *(uint16_t *)POINTER_SHIFT(r, TD_KV_ROW_HEAD_SIZE + sizeof(int16_t)))
-#define kvRowDeleted(r) TKEY_IS_DELETED(kvRowTKey(r))
-
-SKVRow tdKVRowDup(SKVRow row);
-int32_t tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value);
-int32_t tdEncodeKVRow(void **buf, SKVRow row);
-void *tdDecodeKVRow(void *buf, SKVRow *row);
-void tdSortKVRowByColIdx(SKVRow row);
-
-static FORCE_INLINE int32_t comparTagId(const void *key1, const void *key2) {
- if (*(int16_t *)key1 > ((SColIdx *)key2)->colId) {
- return 1;
- } else if (*(int16_t *)key1 < ((SColIdx *)key2)->colId) {
- return -1;
- } else {
- return 0;
- }
-}
-
-static FORCE_INLINE void *tdGetKVRowValOfCol(const SKVRow row, int16_t colId) {
- void *ret = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_EQ);
- if (ret == NULL) return NULL;
- return kvRowColVal(row, (SColIdx *)ret);
-}
-
-static FORCE_INLINE void *tdGetKVRowIdxOfCol(SKVRow row, int16_t colId) {
- return taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_EQ);
-}
-
-// ----------------- K-V data row builder
-typedef struct {
- int16_t tCols;
- int16_t nCols;
- SColIdx *pColIdx;
- uint16_t alloc;
- uint16_t size;
- void *buf;
-} SKVRowBuilder;
-
-int32_t tdInitKVRowBuilder(SKVRowBuilder *pBuilder);
-void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder);
-void tdResetKVRowBuilder(SKVRowBuilder *pBuilder);
-SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder);
-
-static FORCE_INLINE int32_t tdAddColToKVRow(SKVRowBuilder *pBuilder, col_id_t colId, const void *value, int32_t tlen) {
- if (pBuilder->nCols >= pBuilder->tCols) {
- pBuilder->tCols *= 2;
- SColIdx *pColIdx = (SColIdx *)taosMemoryRealloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols);
- if (pColIdx == NULL) return -1;
- pBuilder->pColIdx = pColIdx;
- }
-
- pBuilder->pColIdx[pBuilder->nCols].colId = colId;
- pBuilder->pColIdx[pBuilder->nCols].offset = pBuilder->size;
-
- pBuilder->nCols++;
-
- if (tlen > pBuilder->alloc - pBuilder->size) {
- while (tlen > pBuilder->alloc - pBuilder->size) {
- pBuilder->alloc *= 2;
- }
- void *buf = taosMemoryRealloc(pBuilder->buf, pBuilder->alloc);
- if (buf == NULL) return -1;
- pBuilder->buf = buf;
- }
-
- memcpy(POINTER_SHIFT(pBuilder->buf, pBuilder->size), value, tlen);
- pBuilder->size += tlen;
-
- return 0;
-}
#endif
#ifdef __cplusplus
@@ -476,3 +422,4 @@ static FORCE_INLINE int32_t tdAddColToKVRow(SKVRowBuilder *pBuilder, col_id_t co
#endif
#endif /*_TD_COMMON_DATA_FORMAT_H_*/
+
diff --git a/include/common/tmsg.h b/include/common/tmsg.h
index c4abfffc615e9c7e2d054d488a27a4c5992e64f0..64d29653dde1282e4409e368af75b8ec78b26437 100644
--- a/include/common/tmsg.h
+++ b/include/common/tmsg.h
@@ -244,7 +244,7 @@ typedef struct {
const void* pMsg;
} SSubmitMsgIter;
-int32_t tInitSubmitMsgIter(SSubmitReq* pMsg, SSubmitMsgIter* pIter);
+int32_t tInitSubmitMsgIter(const SSubmitReq* pMsg, SSubmitMsgIter* pIter);
int32_t tGetSubmitMsgNext(SSubmitMsgIter* pIter, SSubmitBlk** pPBlock);
int32_t tInitSubmitBlkIter(SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock, SSubmitBlkIter* pIter);
STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
@@ -287,7 +287,7 @@ typedef struct SSchema {
char name[TSDB_COL_NAME_LEN];
} SSchema;
-#define COL_IS_SET(FLG) ((FLG) & (COL_SET_VAL | COL_SET_NULL) != 0)
+#define COL_IS_SET(FLG) (((FLG) & (COL_SET_VAL | COL_SET_NULL)) != 0)
#define COL_CLR_SET(FLG) ((FLG) &= (~(COL_SET_VAL | COL_SET_NULL)))
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == COL_SMA_ON)
@@ -784,19 +784,24 @@ typedef struct {
int32_t tSerializeSQnodeListReq(void* buf, int32_t bufLen, SQnodeListReq* pReq);
int32_t tDeserializeSQnodeListReq(void* buf, int32_t bufLen, SQnodeListReq* pReq);
+typedef struct SQueryNodeAddr {
+ int32_t nodeId; // vgId or qnodeId
+ SEpSet epSet;
+} SQueryNodeAddr;
+
+typedef struct {
+ SQueryNodeAddr addr;
+ uint64_t load;
+} SQueryNodeLoad;
+
typedef struct {
- SArray* addrsList; // SArray
+ SArray* qnodeList; // SArray
} SQnodeListRsp;
int32_t tSerializeSQnodeListRsp(void* buf, int32_t bufLen, SQnodeListRsp* pRsp);
int32_t tDeserializeSQnodeListRsp(void* buf, int32_t bufLen, SQnodeListRsp* pRsp);
void tFreeSQnodeListRsp(SQnodeListRsp* pRsp);
-typedef struct SQueryNodeAddr {
- int32_t nodeId; // vgId or qnodeId
- SEpSet epSet;
-} SQueryNodeAddr;
-
typedef struct {
SArray* pArray; // Array of SUseDbRsp
} SUseDbBatchRsp;
@@ -919,6 +924,20 @@ typedef struct {
int32_t syncState;
} SMnodeLoad;
+typedef struct {
+ int32_t dnodeId;
+ int64_t numOfProcessedQuery;
+ int64_t numOfProcessedCQuery;
+ int64_t numOfProcessedFetch;
+ int64_t numOfProcessedDrop;
+ int64_t numOfProcessedHb;
+ int64_t cacheDataSize;
+ int64_t numOfQueryInQueue;
+ int64_t numOfFetchInQueue;
+ int64_t timeInQueryQueue;
+ int64_t timeInFetchQueue;
+} SQnodeLoad;
+
typedef struct {
int32_t sver; // software version
int64_t dnodeVer; // dnode table version in sdb
@@ -930,6 +949,7 @@ typedef struct {
int32_t numOfSupportVnodes;
char dnodeEp[TSDB_EP_LEN];
SMnodeLoad mload;
+ SQnodeLoad qload;
SClusterCfg clusterCfg;
SArray* pVloads; // array of SVnodeLoad
} SStatusReq;
@@ -974,7 +994,6 @@ typedef struct {
typedef struct {
int32_t vgId;
- int32_t dnodeId;
char db[TSDB_DB_FNAME_LEN];
int64_t dbUid;
int32_t vgVersion;
@@ -997,15 +1016,14 @@ typedef struct {
int8_t compression;
int8_t strict;
int8_t cacheLastRow;
+ int8_t isTsma;
+ int8_t standby;
int8_t replica;
int8_t selfIndex;
SReplica replicas[TSDB_MAX_REPLICA];
int32_t numOfRetensions;
SArray* pRetensions; // SRetention
-
- // for tsma
- int8_t isTsma;
-
+ void* pTsma;
} SCreateVnodeReq;
int32_t tSerializeSCreateVnodeReq(void* buf, int32_t bufLen, SCreateVnodeReq* pReq);
@@ -1043,8 +1061,8 @@ typedef struct {
int8_t walLevel;
int8_t strict;
int8_t cacheLastRow;
- int8_t replica;
int8_t selfIndex;
+ int8_t replica;
SReplica replicas[TSDB_MAX_REPLICA];
} SAlterVnodeReq;
@@ -1102,6 +1120,14 @@ typedef struct {
SSchema* pSchemas;
} STableMetaRsp;
+typedef struct {
+ STableMetaRsp* pMeta;
+} SMAlterStbRsp;
+
+int32_t tEncodeSMAlterStbRsp(SEncoder *pEncoder, const SMAlterStbRsp *pRsp);
+int32_t tDecodeSMAlterStbRsp(SDecoder *pDecoder, SMAlterStbRsp *pRsp);
+void tFreeSMAlterStbRsp(SMAlterStbRsp* pRsp);
+
int32_t tSerializeSTableMetaRsp(void* buf, int32_t bufLen, STableMetaRsp* pRsp);
int32_t tDeserializeSTableMetaRsp(void* buf, int32_t bufLen, STableMetaRsp* pRsp);
void tFreeSTableMetaRsp(STableMetaRsp* pRsp);
@@ -1432,8 +1458,10 @@ typedef struct {
int32_t code;
} STaskDropRsp;
-#define STREAM_TRIGGER_AT_ONCE 1
-#define STREAM_TRIGGER_WINDOW_CLOSE 2
+#define STREAM_TRIGGER_AT_ONCE_SMA 0
+#define STREAM_TRIGGER_AT_ONCE 1
+#define STREAM_TRIGGER_WINDOW_CLOSE 2
+#define STREAM_TRIGGER_WINDOW_CLOSE_SMA 3
typedef struct {
char name[TSDB_TABLE_FNAME_LEN];
@@ -1465,15 +1493,22 @@ typedef struct {
int64_t streamId;
} SMVCreateStreamRsp, SMSCreateStreamRsp;
+enum {
+ TOPIC_SUB_TYPE__DB = 1,
+ TOPIC_SUB_TYPE__TABLE,
+ TOPIC_SUB_TYPE__COLUMN,
+};
+
typedef struct {
char name[TSDB_TOPIC_FNAME_LEN]; // accout.topic
int8_t igExists;
- int8_t withTbName;
- int8_t withSchema;
- int8_t withTag;
+ int8_t subType;
char* sql;
- char* ast;
- char subscribeDbName[TSDB_DB_NAME_LEN];
+ char subDbName[TSDB_DB_FNAME_LEN];
+ union {
+ char* ast;
+ char subStbName[TSDB_TABLE_FNAME_LEN];
+ };
} SCMCreateTopicReq;
int32_t tSerializeSCMCreateTopicReq(void* buf, int32_t bufLen, const SCMCreateTopicReq* pReq);
@@ -1740,6 +1775,15 @@ typedef struct SVCreateTbReq {
int tEncodeSVCreateTbReq(SEncoder* pCoder, const SVCreateTbReq* pReq);
int tDecodeSVCreateTbReq(SDecoder* pCoder, SVCreateTbReq* pReq);
+static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) {
+ taosMemoryFreeClear(req->name);
+ if (req->type == TSDB_CHILD_TABLE) {
+ taosMemoryFreeClear(req->ctb.pTag);
+ } else if (req->type == TSDB_NORMAL_TABLE) {
+ taosMemoryFreeClear(req->ntb.schemaRow.pSchema);
+ }
+}
+
typedef struct {
int32_t nReqs;
union {
@@ -1837,7 +1881,8 @@ int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);
int32_t tDecodeSVAlterTbReq(SDecoder* pDecoder, SVAlterTbReq* pReq);
typedef struct {
- int32_t code;
+ int32_t code;
+ STableMetaRsp* pMeta;
} SVAlterTbRsp;
int32_t tEncodeSVAlterTbRsp(SEncoder* pEncoder, const SVAlterTbRsp* pRsp);
@@ -1930,6 +1975,7 @@ typedef struct {
int8_t killConnection;
int8_t align[3];
SEpSet epSet;
+ SArray* pQnodeList;
} SQueryHbRspBasic;
typedef struct {
@@ -2009,7 +2055,10 @@ static FORCE_INLINE void tFreeClientKv(void* pKv) {
static FORCE_INLINE void tFreeClientHbRsp(void* pRsp) {
SClientHbRsp* rsp = (SClientHbRsp*)pRsp;
- taosMemoryFreeClear(rsp->query);
+ if (rsp->query) {
+ taosArrayDestroy(rsp->query->pQnodeList);
+ taosMemoryFreeClear(rsp->query);
+ }
if (rsp->info) taosArrayDestroyEx(rsp->info, tFreeClientKv);
}
@@ -2137,11 +2186,6 @@ static FORCE_INLINE void* taosDecodeSMqMsg(void* buf, SMqHbMsg* pMsg) {
return buf;
}
-enum {
- TOPIC_SUB_TYPE__DB = 1,
- TOPIC_SUB_TYPE__TABLE,
-};
-
typedef struct {
SMsgHead head;
int64_t leftForVer;
@@ -2161,10 +2205,8 @@ typedef struct {
int64_t newConsumerId;
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
int8_t subType;
- int8_t withTbName;
- int8_t withSchema;
- int8_t withTag;
char* qmsg;
+ int64_t suid;
} SMqRebVgReq;
static FORCE_INLINE int32_t tEncodeSMqRebVgReq(void** buf, const SMqRebVgReq* pReq) {
@@ -2175,11 +2217,10 @@ static FORCE_INLINE int32_t tEncodeSMqRebVgReq(void** buf, const SMqRebVgReq* pR
tlen += taosEncodeFixedI64(buf, pReq->newConsumerId);
tlen += taosEncodeString(buf, pReq->subKey);
tlen += taosEncodeFixedI8(buf, pReq->subType);
- tlen += taosEncodeFixedI8(buf, pReq->withTbName);
- tlen += taosEncodeFixedI8(buf, pReq->withSchema);
- tlen += taosEncodeFixedI8(buf, pReq->withTag);
- if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
+ if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) {
tlen += taosEncodeString(buf, pReq->qmsg);
+ } else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
+ tlen += taosEncodeFixedI64(buf, pReq->suid);
}
return tlen;
}
@@ -2191,11 +2232,10 @@ static FORCE_INLINE void* tDecodeSMqRebVgReq(const void* buf, SMqRebVgReq* pReq)
buf = taosDecodeFixedI64(buf, &pReq->newConsumerId);
buf = taosDecodeStringTo(buf, pReq->subKey);
buf = taosDecodeFixedI8(buf, &pReq->subType);
- buf = taosDecodeFixedI8(buf, &pReq->withTbName);
- buf = taosDecodeFixedI8(buf, &pReq->withSchema);
- buf = taosDecodeFixedI8(buf, &pReq->withTag);
- if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
+ if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) {
buf = taosDecodeString(buf, &pReq->qmsg);
+ } else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) {
+ buf = taosDecodeFixedI64(buf, &pReq->suid);
}
return (void*)buf;
}
@@ -2259,6 +2299,7 @@ typedef struct {
int8_t intervalUnit; // MACRO: TIME_UNIT_XXX
int8_t slidingUnit; // MACRO: TIME_UNIT_XXX
int8_t timezoneInt; // sma data expired if timezone changes.
+ int32_t dstVgId;
char indexName[TSDB_INDEX_NAME_LEN];
int32_t exprLen;
int32_t tagsFilterLen;
@@ -2353,6 +2394,17 @@ static int32_t tDecodeTSmaWrapper(SDecoder* pDecoder, STSmaWrapper* pReq) {
return 0;
}
+typedef struct {
+ int64_t tsmaIndexUid;
+ STimeWindow queryWindow;
+} SVGetTsmaExpWndsReq;
+
+typedef struct {
+ int64_t tsmaIndexUid;
+ int32_t numExpWnds;
+ TSKEY* expWndsStartTs;
+} SVGetTsmaExpWndsRsp;
+
typedef struct {
int idx;
} SMCreateFullTextReq;
@@ -2401,7 +2453,7 @@ typedef struct {
int32_t epoch;
uint64_t reqId;
int64_t consumerId;
- int64_t waitTime;
+ int64_t timeout;
int64_t currentOffset;
} SMqPollReq;
@@ -2428,7 +2480,7 @@ static FORCE_INLINE void* tDecodeSMqSubVgEp(void* buf, SMqSubVgEp* pVgEp) {
typedef struct {
char topic[TSDB_TOPIC_FNAME_LEN];
- int8_t isSchemaAdaptive;
+ char db[TSDB_DB_FNAME_LEN];
SArray* vgs; // SArray
SSchemaWrapper schema;
} SMqSubTopicEp;
@@ -2436,7 +2488,7 @@ typedef struct {
static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp) {
int32_t tlen = 0;
tlen += taosEncodeString(buf, pTopicEp->topic);
- tlen += taosEncodeFixedI8(buf, pTopicEp->isSchemaAdaptive);
+ tlen += taosEncodeString(buf, pTopicEp->db);
int32_t sz = taosArrayGetSize(pTopicEp->vgs);
tlen += taosEncodeFixedI32(buf, sz);
for (int32_t i = 0; i < sz; i++) {
@@ -2449,7 +2501,7 @@ static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp
static FORCE_INLINE void* tDecodeSMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp) {
buf = taosDecodeStringTo(buf, pTopicEp->topic);
- buf = taosDecodeFixedI8(buf, &pTopicEp->isSchemaAdaptive);
+ buf = taosDecodeStringTo(buf, pTopicEp->db);
int32_t sz;
buf = taosDecodeFixedI32(buf, &sz);
pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp));
@@ -2527,6 +2579,12 @@ static FORCE_INLINE void* tDecodeSMqDataBlkRsp(const void* buf, SMqDataBlkRsp* p
buf = taosDecodeFixedI8(buf, &pRsp->withTbName);
buf = taosDecodeFixedI8(buf, &pRsp->withSchema);
buf = taosDecodeFixedI8(buf, &pRsp->withTag);
+ if (pRsp->withTbName) {
+ pRsp->blockTbName = taosArrayInit(pRsp->blockNum, sizeof(void*));
+ }
+ if (pRsp->withSchema) {
+ pRsp->blockSchema = taosArrayInit(pRsp->blockNum, sizeof(void*));
+ }
for (int32_t i = 0; i < pRsp->blockNum; i++) {
int32_t bLen = 0;
@@ -2536,20 +2594,14 @@ static FORCE_INLINE void* tDecodeSMqDataBlkRsp(const void* buf, SMqDataBlkRsp* p
taosArrayPush(pRsp->blockDataLen, &bLen);
taosArrayPush(pRsp->blockData, &data);
if (pRsp->withSchema) {
- pRsp->blockSchema = taosArrayInit(pRsp->blockNum, sizeof(void*));
SSchemaWrapper* pSW = (SSchemaWrapper*)taosMemoryMalloc(sizeof(SSchemaWrapper));
buf = taosDecodeSSchemaWrapper(buf, pSW);
taosArrayPush(pRsp->blockSchema, &pSW);
- } else {
- pRsp->blockSchema = NULL;
}
if (pRsp->withTbName) {
- pRsp->blockTbName = taosArrayInit(pRsp->blockNum, sizeof(void*));
char* name = NULL;
buf = taosDecodeString(buf, &name);
taosArrayPush(pRsp->blockTbName, &name);
- } else {
- pRsp->blockTbName = NULL;
}
}
}
@@ -2616,6 +2668,23 @@ typedef struct {
int32_t tEncodeSVSubmitReq(SEncoder* pCoder, const SVSubmitReq* pReq);
int32_t tDecodeSVSubmitReq(SDecoder* pCoder, SVSubmitReq* pReq);
+// TDMT_VND_DELETE
+typedef struct {
+ TSKEY sKey;
+ TSKEY eKey;
+
+ // super table
+ char* stbName;
+
+ // child/normal
+ char* tbName;
+} SVDeleteReq;
+
+typedef struct {
+ int32_t code;
+ // TODO
+} SVDeleteRsp;
+
#pragma pack(pop)
#ifdef __cplusplus
diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h
index 51a15c1489cf94d755dfdda386edae8c2ae4a708..860674b34361a42bb8b6ef2267d32b191b1c78d0 100644
--- a/include/common/tmsgdef.h
+++ b/include/common/tmsgdef.h
@@ -144,7 +144,6 @@ enum {
TD_DEF_MSG_TYPE(TDMT_MND_CREATE_TOPIC, "mnode-create-topic", SMCreateTopicReq, SMCreateTopicRsp)
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_TOPIC, "mnode-alter-topic", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_DROP_TOPIC, "mnode-drop-topic", NULL, NULL)
- TD_DEF_MSG_TYPE(TDMT_MND_DROP_CGROUP, "mnode-drop-cgroup", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_SUBSCRIBE, "mnode-subscribe", SCMSubscribeReq, SCMSubscribeRsp)
TD_DEF_MSG_TYPE(TDMT_MND_MQ_ASK_EP, "mnode-mq-ask-ep", SMqAskEpReq, SMqAskEpRsp)
TD_DEF_MSG_TYPE(TDMT_MND_MQ_TIMER, "mnode-mq-tmr", SMTimerReq, NULL)
@@ -206,6 +205,7 @@ enum {
TD_DEF_MSG_TYPE(TDMT_VND_CANCEL_SMA, "vnode-cancel-sma", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_DROP_SMA, "vnode-drop-sma", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT_RSMA, "vnode-submit-rsma", SSubmitReq, SSubmitRsp)
+ TD_DEF_MSG_TYPE(TDMT_VND_GET_TSMA_EXP_WNDS, "vnode-get-tsma-expired-windows", SVGetTsmaExpWndsReq, SVGetTsmaExpWndsRsp)
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_TIMEOUT, "vnode-sync-timeout", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_PING, "vnode-sync-ping", NULL, NULL)
@@ -222,9 +222,11 @@ enum {
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_APPLY_MSG, "vnode-sync-apply-msg", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_VND_SYNC_CONFIG_CHANGE, "vnode-sync-config-change", NULL, NULL)
- TD_DEF_MSG_TYPE(TDMT_VND_SYNC_VNODE, "vnode-sync-vnode", NULL, NULL)
- TD_DEF_MSG_TYPE(TDMT_VND_ALTER_VNODE, "vnode-alter-vnode", NULL, NULL)
- TD_DEF_MSG_TYPE(TDMT_VND_COMPACT_VNODE, "vnode-compact-vnode", NULL, NULL)
+ TD_DEF_MSG_TYPE(TDMT_VND_ALTER_CONFIG, "vnode-alter-config", NULL, NULL)
+ TD_DEF_MSG_TYPE(TDMT_VND_ALTER_REPLICA, "vnode-alter-replica", NULL, NULL)
+ TD_DEF_MSG_TYPE(TDMT_VND_COMPACT, "vnode-compact", NULL, NULL)
+
+ TD_DEF_MSG_TYPE(TDMT_VND_DELETE, "vnode-delete-data", SVDeleteReq, SVDeleteRsp)
// Requests handled by QNODE
TD_NEW_MSG_SEG(TDMT_QND_MSG)
@@ -253,6 +255,7 @@ enum {
TD_DEF_MSG_TYPE(TDMT_MON_BM_INFO, "monitor-binfo", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MON_VM_LOAD, "monitor-vload", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MON_MM_LOAD, "monitor-mload", NULL, NULL)
+ TD_DEF_MSG_TYPE(TDMT_MON_QM_LOAD, "monitor-qload", NULL, NULL)
#if defined(TD_MSG_NUMBER_)
TDMT_MAX
diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h
index 2fc524eeac39eefba6ce87c39d7bf4746fd83de1..c3b0e54f3da416ccc2e2b2dbd6c05ec356a50a30 100644
--- a/include/common/ttokendef.h
+++ b/include/common/ttokendef.h
@@ -127,134 +127,131 @@
#define TK_BLOB 109
#define TK_VARBINARY 110
#define TK_DECIMAL 111
-#define TK_DELAY 112
-#define TK_FILE_FACTOR 113
-#define TK_NK_FLOAT 114
-#define TK_ROLLUP 115
-#define TK_TTL 116
-#define TK_SMA 117
-#define TK_SHOW 118
-#define TK_DATABASES 119
-#define TK_TABLES 120
-#define TK_STABLES 121
-#define TK_MNODES 122
-#define TK_MODULES 123
-#define TK_QNODES 124
-#define TK_FUNCTIONS 125
-#define TK_INDEXES 126
-#define TK_ACCOUNTS 127
-#define TK_APPS 128
-#define TK_CONNECTIONS 129
-#define TK_LICENCE 130
-#define TK_GRANTS 131
-#define TK_QUERIES 132
-#define TK_SCORES 133
-#define TK_TOPICS 134
-#define TK_VARIABLES 135
-#define TK_BNODES 136
-#define TK_SNODES 137
-#define TK_CLUSTER 138
-#define TK_TRANSACTIONS 139
-#define TK_LIKE 140
-#define TK_INDEX 141
-#define TK_FULLTEXT 142
-#define TK_FUNCTION 143
-#define TK_INTERVAL 144
-#define TK_TOPIC 145
-#define TK_AS 146
-#define TK_CGROUP 147
-#define TK_WITH 148
-#define TK_SCHEMA 149
-#define TK_DESC 150
-#define TK_DESCRIBE 151
-#define TK_RESET 152
-#define TK_QUERY 153
-#define TK_CACHE 154
-#define TK_EXPLAIN 155
-#define TK_ANALYZE 156
-#define TK_VERBOSE 157
-#define TK_NK_BOOL 158
-#define TK_RATIO 159
-#define TK_COMPACT 160
-#define TK_VNODES 161
-#define TK_IN 162
-#define TK_OUTPUTTYPE 163
-#define TK_AGGREGATE 164
-#define TK_BUFSIZE 165
-#define TK_STREAM 166
-#define TK_INTO 167
-#define TK_TRIGGER 168
-#define TK_AT_ONCE 169
-#define TK_WINDOW_CLOSE 170
-#define TK_WATERMARK 171
-#define TK_KILL 172
-#define TK_CONNECTION 173
-#define TK_TRANSACTION 174
-#define TK_MERGE 175
-#define TK_VGROUP 176
-#define TK_REDISTRIBUTE 177
-#define TK_SPLIT 178
-#define TK_SYNCDB 179
-#define TK_NULL 180
-#define TK_NK_QUESTION 181
-#define TK_NK_ARROW 182
-#define TK_ROWTS 183
-#define TK_TBNAME 184
-#define TK_QSTARTTS 185
-#define TK_QENDTS 186
-#define TK_WSTARTTS 187
-#define TK_WENDTS 188
-#define TK_WDURATION 189
-#define TK_CAST 190
-#define TK_NOW 191
-#define TK_TODAY 192
-#define TK_TIMEZONE 193
-#define TK_COUNT 194
-#define TK_FIRST 195
-#define TK_LAST 196
-#define TK_LAST_ROW 197
-#define TK_BETWEEN 198
-#define TK_IS 199
-#define TK_NK_LT 200
-#define TK_NK_GT 201
-#define TK_NK_LE 202
-#define TK_NK_GE 203
-#define TK_NK_NE 204
-#define TK_MATCH 205
-#define TK_NMATCH 206
-#define TK_CONTAINS 207
-#define TK_JOIN 208
-#define TK_INNER 209
-#define TK_SELECT 210
-#define TK_DISTINCT 211
-#define TK_WHERE 212
-#define TK_PARTITION 213
-#define TK_BY 214
-#define TK_SESSION 215
-#define TK_STATE_WINDOW 216
-#define TK_SLIDING 217
-#define TK_FILL 218
-#define TK_VALUE 219
-#define TK_NONE 220
-#define TK_PREV 221
-#define TK_LINEAR 222
-#define TK_NEXT 223
-#define TK_GROUP 224
-#define TK_HAVING 225
-#define TK_ORDER 226
-#define TK_SLIMIT 227
-#define TK_SOFFSET 228
-#define TK_LIMIT 229
-#define TK_OFFSET 230
-#define TK_ASC 231
-#define TK_NULLS 232
-#define TK_ID 233
-#define TK_NK_BITNOT 234
-#define TK_INSERT 235
-#define TK_VALUES 236
-#define TK_IMPORT 237
-#define TK_NK_SEMI 238
-#define TK_FILE 239
+#define TK_FILE_FACTOR 112
+#define TK_NK_FLOAT 113
+#define TK_ROLLUP 114
+#define TK_TTL 115
+#define TK_SMA 116
+#define TK_SHOW 117
+#define TK_DATABASES 118
+#define TK_TABLES 119
+#define TK_STABLES 120
+#define TK_MNODES 121
+#define TK_MODULES 122
+#define TK_QNODES 123
+#define TK_FUNCTIONS 124
+#define TK_INDEXES 125
+#define TK_ACCOUNTS 126
+#define TK_APPS 127
+#define TK_CONNECTIONS 128
+#define TK_LICENCE 129
+#define TK_GRANTS 130
+#define TK_QUERIES 131
+#define TK_SCORES 132
+#define TK_TOPICS 133
+#define TK_VARIABLES 134
+#define TK_BNODES 135
+#define TK_SNODES 136
+#define TK_CLUSTER 137
+#define TK_TRANSACTIONS 138
+#define TK_LIKE 139
+#define TK_INDEX 140
+#define TK_FULLTEXT 141
+#define TK_FUNCTION 142
+#define TK_INTERVAL 143
+#define TK_TOPIC 144
+#define TK_AS 145
+#define TK_CONSUMER 146
+#define TK_GROUP 147
+#define TK_DESC 148
+#define TK_DESCRIBE 149
+#define TK_RESET 150
+#define TK_QUERY 151
+#define TK_CACHE 152
+#define TK_EXPLAIN 153
+#define TK_ANALYZE 154
+#define TK_VERBOSE 155
+#define TK_NK_BOOL 156
+#define TK_RATIO 157
+#define TK_COMPACT 158
+#define TK_VNODES 159
+#define TK_IN 160
+#define TK_OUTPUTTYPE 161
+#define TK_AGGREGATE 162
+#define TK_BUFSIZE 163
+#define TK_STREAM 164
+#define TK_INTO 165
+#define TK_TRIGGER 166
+#define TK_AT_ONCE 167
+#define TK_WINDOW_CLOSE 168
+#define TK_WATERMARK 169
+#define TK_KILL 170
+#define TK_CONNECTION 171
+#define TK_TRANSACTION 172
+#define TK_MERGE 173
+#define TK_VGROUP 174
+#define TK_REDISTRIBUTE 175
+#define TK_SPLIT 176
+#define TK_SYNCDB 177
+#define TK_NULL 178
+#define TK_NK_QUESTION 179
+#define TK_NK_ARROW 180
+#define TK_ROWTS 181
+#define TK_TBNAME 182
+#define TK_QSTARTTS 183
+#define TK_QENDTS 184
+#define TK_WSTARTTS 185
+#define TK_WENDTS 186
+#define TK_WDURATION 187
+#define TK_CAST 188
+#define TK_NOW 189
+#define TK_TODAY 190
+#define TK_TIMEZONE 191
+#define TK_COUNT 192
+#define TK_FIRST 193
+#define TK_LAST 194
+#define TK_LAST_ROW 195
+#define TK_BETWEEN 196
+#define TK_IS 197
+#define TK_NK_LT 198
+#define TK_NK_GT 199
+#define TK_NK_LE 200
+#define TK_NK_GE 201
+#define TK_NK_NE 202
+#define TK_MATCH 203
+#define TK_NMATCH 204
+#define TK_CONTAINS 205
+#define TK_JOIN 206
+#define TK_INNER 207
+#define TK_SELECT 208
+#define TK_DISTINCT 209
+#define TK_WHERE 210
+#define TK_PARTITION 211
+#define TK_BY 212
+#define TK_SESSION 213
+#define TK_STATE_WINDOW 214
+#define TK_SLIDING 215
+#define TK_FILL 216
+#define TK_VALUE 217
+#define TK_NONE 218
+#define TK_PREV 219
+#define TK_LINEAR 220
+#define TK_NEXT 221
+#define TK_HAVING 222
+#define TK_ORDER 223
+#define TK_SLIMIT 224
+#define TK_SOFFSET 225
+#define TK_LIMIT 226
+#define TK_OFFSET 227
+#define TK_ASC 228
+#define TK_NULLS 229
+#define TK_ID 230
+#define TK_NK_BITNOT 231
+#define TK_INSERT 232
+#define TK_VALUES 233
+#define TK_IMPORT 234
+#define TK_NK_SEMI 235
+#define TK_FILE 236
#define TK_NK_SPACE 300
#define TK_NK_COMMENT 301
diff --git a/include/dnode/qnode/qnode.h b/include/dnode/qnode/qnode.h
index 90a952939577fc9cd945d0dc9fd8bde8d906667f..7d342c4ba12fba1edb74cd7ce3d093e1dea037b3 100644
--- a/include/dnode/qnode/qnode.h
+++ b/include/dnode/qnode/qnode.h
@@ -25,20 +25,6 @@ extern "C" {
/* ------------------------ TYPES EXPOSED ------------------------ */
typedef struct SQnode SQnode;
-typedef struct {
- int64_t numOfProcessedQuery;
- int64_t numOfProcessedCQuery;
- int64_t numOfProcessedFetch;
- int64_t numOfProcessedDrop;
- int64_t memSizeInCache;
- int64_t dataSizeSend;
- int64_t dataSizeRecv;
- int64_t numOfQueryInQueue;
- int64_t numOfFetchInQueue;
- int64_t waitTimeInQueryQUeue;
- int64_t waitTimeInFetchQUeue;
-} SQnodeLoad;
-
typedef struct {
SMsgCb msgCb;
} SQnodeOpt;
diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h
index 8027b9394e0fd42c4c1d20a051868495130642f5..f0e642bc9af8060d0b6bc0380f2c85284f307642 100644
--- a/include/libs/catalog/catalog.h
+++ b/include/libs/catalog/catalog.h
@@ -183,7 +183,7 @@ int32_t catalogGetTableMeta(SCatalog* pCatalog, void * pTransporter, const SEpSe
*/
int32_t catalogGetSTableMeta(SCatalog* pCatalog, void * pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta);
-int32_t catalogUpdateSTableMeta(SCatalog* pCatalog, STableMetaRsp *rspMsg);
+int32_t catalogUpdateTableMeta(SCatalog* pCatalog, STableMetaRsp *rspMsg);
/**
diff --git a/include/libs/executor/dataSinkMgt.h b/include/libs/executor/dataSinkMgt.h
index 339743f153968a2ae6910ac68735bbf295925041..2cc9caca6fa4d8e4dd4bd6a8d7b490e7baaf2c34 100644
--- a/include/libs/executor/dataSinkMgt.h
+++ b/include/libs/executor/dataSinkMgt.h
@@ -32,6 +32,10 @@ extern "C" {
struct SDataSink;
struct SSDataBlock;
+typedef struct SDataSinkStat {
+ uint64_t cachedSize;
+} SDataSinkStat;
+
typedef struct SDataSinkMgtCfg {
uint32_t maxDataBlockNum; // todo: this should be numOfRows?
uint32_t maxDataBlockNumPerQuery;
@@ -62,6 +66,8 @@ typedef struct SOutputData {
*/
int32_t dsCreateDataSinker(const SDataSinkNode* pDataSink, DataSinkHandle* pHandle);
+int32_t dsDataSinkGetCacheSize(SDataSinkStat *pStat);
+
/**
* Put the result set returned by the executor into datasinker.
* @param handle
@@ -88,6 +94,8 @@ void dsGetDataLength(DataSinkHandle handle, int32_t* pLen, bool* pQueryEnd);
*/
int32_t dsGetDataBlock(DataSinkHandle handle, SOutputData* pOutput);
+int32_t dsGetCacheSize(DataSinkHandle handle, uint64_t *pSize);
+
/**
* After dsGetStatus returns DS_NEED_SCHEDULE, the caller need to put this into the work queue.
* @param ahandle
diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h
index 922136b590cb007c6acd040c7ce81d135c0dad4f..f3e28936afc1b1556502eacd08f6b1e699abc198 100644
--- a/include/libs/function/functionMgt.h
+++ b/include/libs/function/functionMgt.h
@@ -156,6 +156,9 @@ bool fmIsDynamicScanOptimizedFunc(int32_t funcId);
bool fmIsMultiResFunc(int32_t funcId);
bool fmIsRepeatScanFunc(int32_t funcId);
bool fmIsUserDefinedFunc(int32_t funcId);
+bool fmIsDistExecFunc(int32_t funcId);
+
+int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
typedef enum EFuncDataRequired {
FUNC_DATA_REQUIRED_DATA_LOAD = 1,
diff --git a/include/libs/index/index.h b/include/libs/index/index.h
index c3d31ffe3853d76d6ab6803dfc10f54dad2445c6..180c7e7216153f0cdfd5b4240de89bc586fd9b88 100644
--- a/include/libs/index/index.h
+++ b/include/libs/index/index.h
@@ -194,6 +194,7 @@ void indexInit();
/* index filter */
typedef struct SIndexMetaArg {
void* metaHandle;
+ void* metaEx;
uint64_t suid;
} SIndexMetaArg;
diff --git a/include/libs/monitor/monitor.h b/include/libs/monitor/monitor.h
index 9d8cf61b0646c764cee7056152f7873caa61b14f..39e8042b931ecbee48fbe389ab1160c613636f28 100644
--- a/include/libs/monitor/monitor.h
+++ b/include/libs/monitor/monitor.h
@@ -171,6 +171,7 @@ void tFreeSMonVmInfo(SMonVmInfo *pInfo);
typedef struct {
SMonSysInfo sys;
SMonLogs log;
+ SQnodeLoad load;
} SMonQmInfo;
int32_t tSerializeSMonQmInfo(void *buf, int32_t bufLen, SMonQmInfo *pInfo);
@@ -210,6 +211,10 @@ typedef struct {
int32_t tSerializeSMonMloadInfo(void *buf, int32_t bufLen, SMonMloadInfo *pInfo);
int32_t tDeserializeSMonMloadInfo(void *buf, int32_t bufLen, SMonMloadInfo *pInfo);
+int32_t tSerializeSQnodeLoad(void *buf, int32_t bufLen, SQnodeLoad *pInfo);
+int32_t tDeserializeSQnodeLoad(void *buf, int32_t bufLen, SQnodeLoad *pInfo);
+
+
typedef struct {
const char *server;
uint16_t port;
diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h
index 7bd3a40c7199f204bd14e5af3231e59d5b7383be..82924bef3f206911b803ace70ea15435dc29e882 100644
--- a/include/libs/nodes/cmdnodes.h
+++ b/include/libs/nodes/cmdnodes.h
@@ -80,8 +80,7 @@ typedef struct SAlterDatabaseStmt {
typedef struct STableOptions {
ENodeType type;
char comment[TSDB_TB_COMMENT_LEN];
- int32_t delay;
- float filesFactor;
+ double filesFactor;
SNodeList* pRollupFuncs;
int32_t ttl;
SNodeList* pSma;
@@ -239,20 +238,13 @@ typedef struct SDropComponentNodeStmt {
int32_t dnodeId;
} SDropComponentNodeStmt;
-typedef struct STopicOptions {
- ENodeType type;
- bool withTable;
- bool withSchema;
- bool withTag;
-} STopicOptions;
-
typedef struct SCreateTopicStmt {
- ENodeType type;
- char topicName[TSDB_TABLE_NAME_LEN];
- char subscribeDbName[TSDB_DB_NAME_LEN];
- bool ignoreExists;
- SNode* pQuery;
- STopicOptions* pOptions;
+ ENodeType type;
+ char topicName[TSDB_TABLE_NAME_LEN];
+ char subDbName[TSDB_DB_NAME_LEN];
+ char subSTbName[TSDB_TABLE_NAME_LEN];
+ bool ignoreExists;
+ SNode* pQuery;
} SCreateTopicStmt;
typedef struct SDropTopicStmt {
diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h
index 38602667252e429eb9840c75d2c23b98139df184..41c196c916b3cdef97bc68205b8b2ee0f0e472aa 100644
--- a/include/libs/nodes/nodes.h
+++ b/include/libs/nodes/nodes.h
@@ -95,7 +95,6 @@ typedef enum ENodeType {
QUERY_NODE_INDEX_OPTIONS,
QUERY_NODE_EXPLAIN_OPTIONS,
QUERY_NODE_STREAM_OPTIONS,
- QUERY_NODE_TOPIC_OPTIONS,
QUERY_NODE_LEFT_VALUE,
// Statement nodes are used in parser and planner module.
@@ -190,6 +189,7 @@ typedef enum ENodeType {
QUERY_NODE_LOGIC_PLAN_PROJECT,
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
+ QUERY_NODE_LOGIC_PLAN_MERGE,
QUERY_NODE_LOGIC_PLAN_WINDOW,
QUERY_NODE_LOGIC_PLAN_FILL,
QUERY_NODE_LOGIC_PLAN_SORT,
@@ -207,6 +207,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_JOIN,
QUERY_NODE_PHYSICAL_PLAN_AGG,
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
+ QUERY_NODE_PHYSICAL_PLAN_MERGE,
QUERY_NODE_PHYSICAL_PLAN_SORT,
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL,
diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h
index 2648a468dd3fa82fe91825d60b739387d9255bd7..5892bffac2f20c0cc177cb9937256f82e45a6956 100644
--- a/include/libs/nodes/plannodes.h
+++ b/include/libs/nodes/plannodes.h
@@ -59,6 +59,7 @@ typedef struct SScanLogicNode {
int8_t triggerType;
int64_t watermark;
int16_t tsColId;
+ double filesFactor;
} SScanLogicNode;
typedef struct SJoinLogicNode {
@@ -94,9 +95,15 @@ typedef struct SVnodeModifLogicNode {
typedef struct SExchangeLogicNode {
SLogicNode node;
int32_t srcGroupId;
- uint8_t precision;
} SExchangeLogicNode;
+typedef struct SMergeLogicNode {
+ SLogicNode node;
+ SNodeList* pMergeKeys;
+ int32_t numOfChannels;
+ int32_t srcGroupId;
+} SMergeLogicNode;
+
typedef enum EWindowType { WINDOW_TYPE_INTERVAL = 1, WINDOW_TYPE_SESSION, WINDOW_TYPE_STATE } EWindowType;
typedef struct SWindowLogicNode {
@@ -113,6 +120,7 @@ typedef struct SWindowLogicNode {
SNode* pStateExpr;
int8_t triggerType;
int64_t watermark;
+ double filesFactor;
} SWindowLogicNode;
typedef struct SFillLogicNode {
@@ -222,6 +230,7 @@ typedef struct STableScanPhysiNode {
int8_t triggerType;
int64_t watermark;
int16_t tsColId;
+ double filesFactor;
} STableScanPhysiNode;
typedef STableScanPhysiNode STableSeqScanPhysiNode;
@@ -265,6 +274,13 @@ typedef struct SExchangePhysiNode {
SNodeList* pSrcEndPoints; // element is SDownstreamSource, scheduler fill by calling qSetSuplanExecutionNode
} SExchangePhysiNode;
+typedef struct SMergePhysiNode {
+ SPhysiNode node;
+ SNodeList* pMergeKeys;
+ int32_t numOfChannels;
+ int32_t srcGroupId;
+} SMergePhysiNode;
+
typedef struct SWinodwPhysiNode {
SPhysiNode node;
SNodeList* pExprs; // these are expression list of parameter expression of function
@@ -272,6 +288,7 @@ typedef struct SWinodwPhysiNode {
SNode* pTspk; // timestamp primary key
int8_t triggerType;
int64_t watermark;
+ double filesFactor;
} SWinodwPhysiNode;
typedef struct SIntervalPhysiNode {
diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h
index ab5e10dc2ab632b57f9d6f313291d8cb5b04c6b0..e4af78892baaf3757ab58be41fec776e2cb7186f 100644
--- a/include/libs/nodes/querynodes.h
+++ b/include/libs/nodes/querynodes.h
@@ -331,8 +331,8 @@ typedef struct SQuery {
int8_t precision;
SCmdMsgInfo* pCmdMsg;
int32_t msgType;
- SArray* pDbList;
SArray* pTableList;
+ SArray* pDbList;
bool showRewrite;
int32_t placeholderNum;
SArray* pPlaceholderValues;
diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h
index 06272b81514cec2a294da513ec2a57447ad74ef1..ca825b9e2fb460b6aa35110c89535071a50cac52 100644
--- a/include/libs/parser/parser.h
+++ b/include/libs/parser/parser.h
@@ -77,8 +77,8 @@ int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery);
int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, int32_t colIdx,
int32_t rowNum);
-int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD** fields);
-int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD** fields);
+int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields);
+int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields);
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tName, TAOS_MULTI_BIND* bind,
char* msgBuf, int32_t msgBufLen);
void destroyBoundColumnInfo(void* pBoundInfo);
diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h
index c4f71e57a8174c62cf331e4afec35604786282a0..6e14445ac7abc12eb4ccca7a9f08f3e7ff43ddb8 100644
--- a/include/libs/planner/planner.h
+++ b/include/libs/planner/planner.h
@@ -36,6 +36,7 @@ typedef struct SPlanContext {
int64_t watermark;
char* pMsg;
int32_t msgLen;
+ double filesFactor;
} SPlanContext;
// Create the physical plan for the query, according to the AST.
diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h
index 296b18e8dea7524244dcd8ade1a1149bfe97533d..45a7e9a29f3457a68e9998659237a9e0d70d39ab 100644
--- a/include/libs/qcom/query.h
+++ b/include/libs/qcom/query.h
@@ -56,6 +56,11 @@ typedef struct STableComInfo {
int32_t rowSize; // row size of the schema
} STableComInfo;
+typedef struct SQueryExecRes {
+ int32_t msgType;
+ void* res;
+} SQueryExecRes;
+
typedef struct SIndexMeta {
#ifdef WINDOWS
size_t avoidCompilationErrors;
@@ -192,6 +197,7 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STabl
char* jobTaskStatusStr(int32_t status);
SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* name);
+void destroyQueryExecRes(SQueryExecRes* pRes);
extern int32_t (*queryBuildMsg[TDMT_MAX])(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallocFp)(int32_t));
extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t msgSize);
@@ -204,7 +210,8 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_VND_TB_NOT_EXIST || \
(_code) == TSDB_CODE_PAR_INVALID_COLUMNS_NUM || (_code) == TSDB_CODE_PAR_INVALID_COLUMN || \
- (_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code == TSDB_CODE_PAR_VALUE_TOO_LONG))
+ (_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code == TSDB_CODE_PAR_VALUE_TOO_LONG) || \
+ (_code == TSDB_CODE_PAR_INVALID_DROP_COL))
#define NEED_CLIENT_REFRESH_VG_ERROR(_code) \
((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID)
#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) ((_code) == TSDB_CODE_TDB_TABLE_RECREATED)
diff --git a/include/libs/qworker/qworker.h b/include/libs/qworker/qworker.h
index 5942d00cb212002d5309cec4cba253dc7e3d7388..91cf975a56660cd13a9fac992cb59c79bd2362b4 100644
--- a/include/libs/qworker/qworker.h
+++ b/include/libs/qworker/qworker.h
@@ -22,7 +22,7 @@ extern "C" {
#include "tmsgcb.h"
#include "trpc.h"
-
+#include "executor.h"
enum {
NODE_TYPE_VNODE = 1,
@@ -40,13 +40,19 @@ typedef struct SQWorkerCfg {
} SQWorkerCfg;
typedef struct {
- uint64_t numOfStartTask;
- uint64_t numOfStopTask;
- uint64_t numOfRecvedFetch;
- uint64_t numOfSentHb;
- uint64_t numOfSentFetch;
- uint64_t numOfTaskInQueue;
+ uint64_t cacheDataSize;
+
+ uint64_t queryProcessed;
+ uint64_t cqueryProcessed;
+ uint64_t fetchProcessed;
+ uint64_t dropProcessed;
+ uint64_t hbProcessed;
+
+ uint64_t numOfQueryInQueue;
uint64_t numOfFetchInQueue;
+ uint64_t timeInQueryQueue;
+ uint64_t timeInFetchQueue;
+
uint64_t numOfErrors;
} SQWorkerStat;
@@ -68,7 +74,7 @@ int32_t qWorkerProcessHbMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, int64_
void qWorkerDestroy(void **qWorkerMgmt);
-int64_t qWorkerGetWaitTimeInQueue(void *qWorkerMgmt, EQueueType type);
+int32_t qWorkerGetStat(SReadHandle *handle, void *qWorkerMgmt, SQWorkerStat *pStat);
#ifdef __cplusplus
}
diff --git a/include/libs/scheduler/scheduler.h b/include/libs/scheduler/scheduler.h
index 0d32cce20b6e489249fa79080e6144754c17218b..331b78769029fb97764f81ce6bb646f28854918a 100644
--- a/include/libs/scheduler/scheduler.h
+++ b/include/libs/scheduler/scheduler.h
@@ -56,7 +56,7 @@ typedef struct SQueryProfileSummary {
typedef struct SQueryResult {
int32_t code;
uint64_t numOfRows;
- void *res;
+ SQueryExecRes res;
} SQueryResult;
typedef struct STaskInfo {
diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h
index 8aaf9a79dc5af256cfe089d8fc5f7b12856d2e71..f7ad7b4ed8dcecb65bec074480e36226f583727b 100644
--- a/include/libs/stream/tstream.h
+++ b/include/libs/stream/tstream.h
@@ -61,11 +61,8 @@ enum {
};
typedef struct {
- int8_t type;
-
- int32_t sourceVg;
- int64_t sourceVer;
-
+ int8_t type;
+ int64_t ver;
int32_t* dataRef;
SSubmitReq* data;
} SStreamDataSubmit;
@@ -83,6 +80,37 @@ typedef struct {
int8_t type;
} SStreamCheckpoint;
+typedef struct {
+ STaosQueue* queue;
+ STaosQall* qall;
+ void* qItem;
+ int8_t failed;
+} SStreamQ;
+
+static FORCE_INLINE void* streamQCurItem(SStreamQ* queue) {
+ //
+ return queue->qItem;
+}
+
+static FORCE_INLINE void* streamQNextItem(SStreamQ* queue) {
+ int8_t failed = atomic_load_8(&queue->failed);
+ if (failed) {
+ ASSERT(queue->qItem != NULL);
+ return streamQCurItem(queue);
+ } else {
+ taosGetQitem(queue->qall, &queue->qItem);
+ if (queue->qItem == NULL) {
+ taosReadAllQitems(queue->queue, queue->qall);
+ taosGetQitem(queue->qall, &queue->qItem);
+ }
+ return streamQCurItem(queue);
+ }
+}
+
+static FORCE_INLINE void streamQSetFail(SStreamQ* queue) { atomic_store_8(&queue->failed, 1); }
+
+static FORCE_INLINE void streamQSetSuccess(SStreamQ* queue) { atomic_store_8(&queue->failed, 0); }
+
static FORCE_INLINE SStreamDataSubmit* streamDataSubmitNew(SSubmitReq* pReq) {
SStreamDataSubmit* pDataSubmit = (SStreamDataSubmit*)taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM);
if (pDataSubmit == NULL) return NULL;
@@ -111,6 +139,8 @@ static FORCE_INLINE void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit)
}
}
+SStreamDataSubmit* streamSubmitRefClone(SStreamDataSubmit* pSubmit);
+
int32_t streamDataBlockEncode(void** buf, const SStreamDataBlock* pOutput);
void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput);
@@ -209,8 +239,6 @@ struct SStreamTask {
int32_t nodeId;
SEpSet epSet;
- // source preprocess
-
// exec
STaskExec exec;
@@ -318,8 +346,6 @@ int32_t streamDequeueOutput(SStreamTask* pTask, void** output);
int32_t streamTaskRun(SStreamTask* pTask);
-int32_t streamTaskHandleInput(SStreamTask* pTask, void* data);
-
int32_t streamTaskProcessRunReq(SStreamTask* pTask, SMsgCb* pMsgCb);
int32_t streamProcessDispatchReq(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchReq* pReq, SRpcMsg* pMsg);
int32_t streamProcessDispatchRsp(SStreamTask* pTask, SMsgCb* pMsgCb, SStreamDispatchRsp* pRsp);
diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h
index e541c214deba8e9b9ad3cc4e95cc2d2224f3c5a3..95af8ac30666b67b0a933477ff8ca0764d2d0a43 100644
--- a/include/libs/wal/wal.h
+++ b/include/libs/wal/wal.h
@@ -184,6 +184,7 @@ int32_t walRollback(SWal *, int64_t ver);
// notify that previous logs can be pruned safely
int32_t walBeginSnapshot(SWal *, int64_t ver);
int32_t walEndSnapshot(SWal *);
+void walRestoreFromSnapshot(SWal *, int64_t ver);
// int32_t walDataCorrupted(SWal*);
// read
diff --git a/include/os/osDir.h b/include/os/osDir.h
index a4c686e2807ee3d1fb9a8a0e1e05066d1b616c0b..9019d4f80240b2335824cb5626488bf4d0957f06 100644
--- a/include/os/osDir.h
+++ b/include/os/osDir.h
@@ -33,8 +33,19 @@ extern "C" {
#ifdef WINDOWS
#define TD_TMP_DIR_PATH "C:\\Windows\\Temp\\"
+#define TD_CFG_DIR_PATH "C:\\TDengine\\cfg\\"
+#define TD_DATA_DIR_PATH "C:\\TDengine\\data\\"
+#define TD_LOG_DIR_PATH "C:\\TDengine\\log\\"
+#elif defined(_TD_DARWIN_64)
+#define TD_TMP_DIR_PATH "/tmp/taosd/"
+#define TD_CFG_DIR_PATH "/usr/local/etc/taos/"
+#define TD_DATA_DIR_PATH "/usr/local/var/lib/taos/"
+#define TD_LOG_DIR_PATH "/usr/local/var/log/taos/"
#else
#define TD_TMP_DIR_PATH "/tmp/"
+#define TD_CFG_DIR_PATH "/etc/taos/"
+#define TD_DATA_DIR_PATH "/var/lib/taos/"
+#define TD_LOG_DIR_PATH "/var/log/taos/"
#endif
typedef struct TdDir *TdDirPtr;
diff --git a/include/util/taoserror.h b/include/util/taoserror.h
index 65cfe8de0be9e387cecba70141c0bab513d6fc63..4550bccbedc3b53e6882ad05f11d41677674f474 100644
--- a/include/util/taoserror.h
+++ b/include/util/taoserror.h
@@ -70,6 +70,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_NEED_RETRY TAOS_DEF_ERROR_CODE(0, 0x0028)
#define TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE TAOS_DEF_ERROR_CODE(0, 0x0029)
#define TSDB_CODE_INVALID_TIMESTAMP TAOS_DEF_ERROR_CODE(0, 0x0030)
+#define TSDB_CODE_MSG_DECODE_ERROR TAOS_DEF_ERROR_CODE(0, 0x0031)
#define TSDB_CODE_REF_NO_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0040)
#define TSDB_CODE_REF_FULL TAOS_DEF_ERROR_CODE(0, 0x0041)
@@ -84,6 +85,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_RPC_NETWORK_UNAVAIL TAOS_DEF_ERROR_CODE(0, 0x0102)
#define TSDB_CODE_RPC_FQDN_ERROR TAOS_DEF_ERROR_CODE(0, 0x0103)
#define TSDB_CODE_RPC_PORT_EADDRINUSE TAOS_DEF_ERROR_CODE(0, 0x0104)
+#define TSDB_CODE_RPC_INDIRECT_NETWORK_UNAVAIL TAOS_DEF_ERROR_CODE(0, 0x0105)
//client
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200)
@@ -182,7 +184,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_MND_BNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0356)
#define TSDB_CODE_MND_BNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0357)
#define TSDB_CODE_MND_TOO_FEW_MNODES TAOS_DEF_ERROR_CODE(0, 0x0358)
-#define TSDB_CODE_MND_MNODE_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0359)
+#define TSDB_CODE_MND_TOO_MANY_MNODES TAOS_DEF_ERROR_CODE(0, 0x0359)
#define TSDB_CODE_MND_CANT_DROP_MASTER TAOS_DEF_ERROR_CODE(0, 0x035A)
// mnode-acct
diff --git a/include/util/tdef.h b/include/util/tdef.h
index 7c1f46ce69715431e073f2e5d0af473aa66c8a6f..0ae22d195395f6225dddf33c52a99046ad41354d 100644
--- a/include/util/tdef.h
+++ b/include/util/tdef.h
@@ -209,7 +209,7 @@ typedef enum ELogicConditionType {
#define TSDB_INDEX_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_INDEX_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
#define TSDB_TYPE_STR_MAX_LEN 32
#define TSDB_TABLE_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
-#define TSDB_TOPIC_FNAME_LEN TSDB_TABLE_FNAME_LEN
+#define TSDB_TOPIC_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
#define TSDB_STREAM_FNAME_LEN TSDB_TABLE_FNAME_LEN
#define TSDB_SUBSCRIBE_KEY_LEN (TSDB_CGROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2)
#define TSDB_PARTITION_KEY_LEN (TSDB_SUBSCRIBE_KEY_LEN + 20)
@@ -253,7 +253,7 @@ typedef enum ELogicConditionType {
#define TSDB_TRANS_STAGE_LEN 12
#define TSDB_TRANS_TYPE_LEN 16
-#define TSDB_TRANS_ERROR_LEN 64
+#define TSDB_TRANS_ERROR_LEN 512
#define TSDB_STEP_NAME_LEN 32
#define TSDB_STEP_DESC_LEN 128
@@ -342,11 +342,8 @@ typedef enum ELogicConditionType {
#define TSDB_DEFAULT_DB_SCHEMALESS TSDB_DB_SCHEMALESS_OFF
#define TSDB_MIN_ROLLUP_FILE_FACTOR 0
-#define TSDB_MAX_ROLLUP_FILE_FACTOR 1
+#define TSDB_MAX_ROLLUP_FILE_FACTOR 10
#define TSDB_DEFAULT_ROLLUP_FILE_FACTOR 0.1
-#define TSDB_MIN_ROLLUP_DELAY 1
-#define TSDB_MAX_ROLLUP_DELAY 10
-#define TSDB_DEFAULT_ROLLUP_DELAY 2
#define TSDB_MIN_TABLE_TTL 0
#define TSDB_DEFAULT_TABLE_TTL 0
diff --git a/include/util/tencode.h b/include/util/tencode.h
index cbacd59fa7873c4cb05b8fdaefb321ae3f854e5b..a13afd44480eef8397befb42c2fe2a12c322b01e 100644
--- a/include/util/tencode.h
+++ b/include/util/tencode.h
@@ -378,14 +378,16 @@ static FORCE_INLINE int32_t tDecodeDouble(SDecoder* pCoder, double* val) {
}
static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len) {
- if (tDecodeU32v(pCoder, len) < 0) return -1;
+ uint32_t length = 0;
+ if (tDecodeU32v(pCoder, &length) < 0) return -1;
+ if (len) *len = length;
- if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, *len)) return -1;
+ if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, length)) return -1;
if (val) {
*val = (uint8_t*)TD_CODER_CURRENT(pCoder);
}
- TD_CODER_MOVE_POS(pCoder, *len);
+ TD_CODER_MOVE_POS(pCoder, length);
return 0;
}
@@ -410,14 +412,16 @@ static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val) {
}
static FORCE_INLINE int32_t tDecodeBinaryAlloc(SDecoder* pCoder, void** val, uint64_t* len) {
- if (tDecodeU64v(pCoder, len) < 0) return -1;
+ uint64_t length = 0;
+ if (tDecodeU64v(pCoder, &length) < 0) return -1;
+ if (len) *len = length;
- if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, *len)) return -1;
- *val = taosMemoryMalloc(*len);
+ if (TD_CODER_CHECK_CAPACITY_FAILED(pCoder, length)) return -1;
+ *val = taosMemoryMalloc(length);
if (*val == NULL) return -1;
- memcpy(*val, TD_CODER_CURRENT(pCoder), *len);
+ memcpy(*val, TD_CODER_CURRENT(pCoder), length);
- TD_CODER_MOVE_POS(pCoder, *len);
+ TD_CODER_MOVE_POS(pCoder, length);
return 0;
}
@@ -530,6 +534,26 @@ static FORCE_INLINE int32_t tPutI64(uint8_t* p, int64_t v) {
return sizeof(int64_t);
}
+static FORCE_INLINE int32_t tPutFloat(uint8_t* p, float f) {
+ union {
+ uint32_t ui;
+ float f;
+ } v;
+ v.f = f;
+
+ return tPutU32(p, v.ui);
+}
+
+static FORCE_INLINE int32_t tPutDouble(uint8_t* p, double d) {
+ union {
+ uint64_t ui;
+ double d;
+ } v;
+ v.d = d;
+
+ return tPutU64(p, v.ui);
+}
+
static FORCE_INLINE int32_t tPutU16v(uint8_t* p, uint16_t v) { tPutV(p, v); }
static FORCE_INLINE int32_t tPutI16v(uint8_t* p, int16_t v) { return tPutU16v(p, ZIGZAGE(int16_t, v)); }
@@ -619,6 +643,34 @@ static FORCE_INLINE int32_t tGetI64v(uint8_t* p, int64_t* v) {
return n;
}
+static FORCE_INLINE int32_t tGetFloat(uint8_t* p, float* f) {
+ int32_t n = 0;
+
+ union {
+ uint32_t ui;
+ float f;
+ } v;
+
+ n = tGetU32(p, &v.ui);
+
+ *f = v.f;
+ return n;
+}
+
+static FORCE_INLINE int32_t tGetDouble(uint8_t* p, double* d) {
+ int32_t n = 0;
+
+ union {
+ uint64_t ui;
+ double d;
+ } v;
+
+ n = tGetU64(p, &v.ui);
+
+ *d = v.d;
+ return n;
+}
+
// =====================
static FORCE_INLINE int32_t tPutBinary(uint8_t* p, uint8_t* pData, uint32_t nData) {
int n = 0;
@@ -642,6 +694,11 @@ static FORCE_INLINE int32_t tGetBinary(uint8_t* p, uint8_t** ppData, uint32_t* n
return n;
}
+static FORCE_INLINE int32_t tPutCStr(uint8_t* p, char* pData) {
+ return tPutBinary(p, (uint8_t*)pData, strlen(pData) + 1);
+}
+static FORCE_INLINE int32_t tGetCStr(uint8_t* p, char** ppData) { return tGetBinary(p, (uint8_t**)ppData, NULL); }
+
#ifdef __cplusplus
}
#endif
diff --git a/include/util/ttimer.h b/include/util/ttimer.h
index 10222596319f445c980e5a03b9ded91a3ca9ce4e..4111a8ca28375cbcf45f60512da06802eeb22669 100644
--- a/include/util/ttimer.h
+++ b/include/util/ttimer.h
@@ -31,16 +31,16 @@ extern int32_t taosTmrThreads;
void *taosTmrInit(int32_t maxTmr, int32_t resoultion, int32_t longest, const char *label);
+void taosTmrCleanUp(void *handle);
+
tmr_h taosTmrStart(TAOS_TMR_CALLBACK fp, int32_t mseconds, void *param, void *handle);
bool taosTmrStop(tmr_h tmrId);
-bool taosTmrStopA(tmr_h *timerId);
+bool taosTmrStopA(tmr_h *tmrId);
bool taosTmrReset(TAOS_TMR_CALLBACK fp, int32_t mseconds, void *param, void *handle, tmr_h *pTmrId);
-void taosTmrCleanUp(void *handle);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h
index d9f33510088cf228215edf0f77368334edd4b956..a2305dd45d5818b37cb0a26c0bcd1b47830b0496 100644
--- a/source/client/inc/clientInt.h
+++ b/source/client/inc/clientInt.h
@@ -119,6 +119,8 @@ typedef struct SHeartBeatInfo {
struct SAppInstInfo {
int64_t numOfConns;
SCorEpSet mgmtEp;
+ TdThreadMutex qnodeMutex;
+ SArray* pQnodeList;
SInstanceSummary summary;
SList* pConnList; // STscObj linked list
uint64_t clusterId;
@@ -160,6 +162,7 @@ typedef struct SResultColumn {
} SResultColumn;
typedef struct SReqResultInfo {
+ SQueryExecRes execRes;
const char* pRspMsg;
const char* pData;
TAOS_FIELD* fields; // todo, column names are not needed.
@@ -189,6 +192,7 @@ typedef struct SRequestSendRecvBody {
typedef struct {
int8_t resType;
char topic[TSDB_TOPIC_FNAME_LEN];
+ char db[TSDB_DB_FNAME_LEN];
int32_t vgId;
SSchemaWrapper schema;
int32_t resIter;
@@ -217,7 +221,8 @@ typedef struct SRequestObj {
void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4);
void doSetOneRowPtr(SReqResultInfo* pResultInfo);
void setResPrecision(SReqResultInfo* pResInfo, int32_t precision);
-int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4);
+int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4,
+ bool freeAfterUse);
void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols);
void doFreeReqResultInfo(SReqResultInfo* pResInfo);
@@ -239,7 +244,7 @@ static FORCE_INLINE SReqResultInfo* tmqGetNextResInfo(TAOS_RES* res, bool conver
taosMemoryFreeClear(msg->resInfo.length);
taosMemoryFreeClear(msg->resInfo.convertBuf);
}
- setQueryResultFromRsp(&msg->resInfo, pRetrieve, convertUcs4);
+ setQueryResultFromRsp(&msg->resInfo, pRetrieve, convertUcs4, false);
return &msg->resInfo;
}
return NULL;
@@ -290,7 +295,7 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen);
int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb);
-int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList);
+int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray** pNodeList);
int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest);
@@ -315,8 +320,9 @@ void hbMgrInitMqHbRspHandle();
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res);
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList);
-int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** res);
+int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList);
int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest);
+int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList);
#ifdef __cplusplus
}
diff --git a/source/client/inc/clientStmt.h b/source/client/inc/clientStmt.h
index f0c9dcd67dd8e3b05775003221ddf86681da37ab..936fb92fc4019842485e7051abf161aee8a7d858 100644
--- a/source/client/inc/clientStmt.h
+++ b/source/client/inc/clientStmt.h
@@ -116,8 +116,11 @@ int stmtAffectedRowsOnce(TAOS_STMT *stmt);
int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
int stmtSetTbName(TAOS_STMT *stmt, const char *tbName);
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags);
+int stmtGetTagFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields);
+int stmtGetColFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields);
int stmtIsInsert(TAOS_STMT *stmt, int *insert);
int stmtGetParamNum(TAOS_STMT *stmt, int *nums);
+int stmtGetParam(TAOS_STMT *stmt, int idx, int *type, int *bytes);
int stmtAddBatch(TAOS_STMT *stmt);
TAOS_RES *stmtUseResult(TAOS_STMT *stmt);
int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx);
diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c
index 669b2bc97eb3e6fab04701aebbf80402432b44c1..4f5f23b68be93ca3449ddbc2ffd3522c1d1cd27c 100644
--- a/source/client/src/clientEnv.c
+++ b/source/client/src/clientEnv.c
@@ -234,6 +234,8 @@ static void doDestroyRequest(void *p) {
taosArrayDestroy(pRequest->tableList);
taosArrayDestroy(pRequest->dbList);
+ destroyQueryExecRes(&pRequest->body.resInfo.execRes);
+
deregisterRequest(pRequest);
taosMemoryFreeClear(pRequest);
}
diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c
index a9c5cd06f668ba625dee6d13c44261ef2badf8bb..09c3d269c703d6e2dc78cbef49a7790c98f34245 100644
--- a/source/client/src/clientHb.c
+++ b/source/client/src/clientHb.c
@@ -120,7 +120,7 @@ static int32_t hbProcessStbInfoRsp(void *value, int32_t valueLen, struct SCatalo
return TSDB_CODE_TSC_INVALID_VALUE;
}
- catalogUpdateSTableMeta(pCatalog, rsp);
+ catalogUpdateTableMeta(pCatalog, rsp);
}
}
@@ -160,6 +160,10 @@ static int32_t hbQueryHbRspHandle(SAppHbMgr *pAppHbMgr, SClientHbRsp *pRsp) {
taos_close(pTscObj);
}
+ if (pRsp->query->pQnodeList) {
+ updateQnodeList(pTscObj->pAppInfo, pRsp->query->pQnodeList);
+ }
+
releaseTscObj(pRsp->connKey.tscRid);
}
}
diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c
index eb4c4cb59feac8c8a0db6cd85f45f3482b31e96f..c4bf3b50bf08a805391a0755d81e0f1d76d6459c 100644
--- a/source/client/src/clientImpl.c
+++ b/source/client/src/clientImpl.c
@@ -118,6 +118,7 @@ TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass,
if (pInst == NULL) {
p = taosMemoryCalloc(1, sizeof(struct SAppInstInfo));
p->mgmtEp = epSet;
+ taosThreadMutexInit(&p->qnodeMutex, NULL);
p->pTransporter = openTransporter(user, secretEncrypt, tsNumOfCores);
p->pAppHbMgr = appHbMgrInit(p, key);
taosHashPut(appInfo.pInstMap, key, strlen(key), &p, POINTER_BYTES);
@@ -202,7 +203,7 @@ int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
SRetrieveTableRsp* pRsp = NULL;
int32_t code = qExecCommand(pQuery->pRoot, &pRsp);
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
- code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false);
+ code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, false);
}
return code;
}
@@ -228,7 +229,61 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
return TSDB_CODE_SUCCESS;
}
-int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList) {
+int compareQueryNodeLoad(const void* elem1, const void* elem2) {
+ SQueryNodeLoad* node1 = (SQueryNodeLoad*)elem1;
+ SQueryNodeLoad* node2 = (SQueryNodeLoad*)elem2;
+
+ if (node1->load < node2->load) {
+ return -1;
+ }
+
+ return node1->load > node2->load;
+}
+
+int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList) {
+ taosThreadMutexLock(&pInfo->qnodeMutex);
+ if (pInfo->pQnodeList) {
+ taosArrayDestroy(pInfo->pQnodeList);
+ pInfo->pQnodeList = NULL;
+ }
+
+ if (pNodeList) {
+ pInfo->pQnodeList = taosArrayDup(pNodeList);
+ taosArraySort(pInfo->pQnodeList, compareQueryNodeLoad);
+ }
+ taosThreadMutexUnlock(&pInfo->qnodeMutex);
+
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t getQnodeList(SRequestObj* pRequest, SArray** pNodeList) {
+ SAppInstInfo* pInfo = pRequest->pTscObj->pAppInfo;
+ int32_t code = 0;
+
+ taosThreadMutexLock(&pInfo->qnodeMutex);
+ if (pInfo->pQnodeList) {
+ *pNodeList = taosArrayDup(pInfo->pQnodeList);
+ }
+ taosThreadMutexUnlock(&pInfo->qnodeMutex);
+
+ if (NULL == *pNodeList) {
+ SEpSet mgmtEpSet = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
+ SCatalog* pCatalog = NULL;
+ code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
+ if (TSDB_CODE_SUCCESS == code) {
+ *pNodeList = taosArrayInit(5, sizeof(SQueryNodeLoad));
+ code = catalogGetQnodeList(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, &mgmtEpSet, *pNodeList);
+ }
+
+ if (TSDB_CODE_SUCCESS == code && *pNodeList) {
+ code = updateQnodeList(pInfo, *pNodeList);
+ }
+ }
+
+ return code;
+}
+
+int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray** pNodeList) {
pRequest->type = pQuery->msgType;
SPlanContext cxt = {.queryId = pRequest->requestId,
.acctId = pRequest->pTscObj->acctId,
@@ -237,14 +292,10 @@ int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArra
.showRewrite = pQuery->showRewrite,
.pMsg = pRequest->msgBuf,
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE};
- SEpSet mgmtEpSet = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
- SCatalog* pCatalog = NULL;
- int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
- if (TSDB_CODE_SUCCESS == code) {
- code = catalogGetQnodeList(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, &mgmtEpSet, pNodeList);
- }
+
+ int32_t code = getQnodeList(pRequest, pNodeList);
if (TSDB_CODE_SUCCESS == code) {
- code = qCreateQueryPlan(&cxt, pPlan, pNodeList);
+ code = qCreateQueryPlan(&cxt, pPlan, *pNodeList);
}
return code;
}
@@ -289,28 +340,29 @@ void setResPrecision(SReqResultInfo* pResInfo, int32_t precision) {
pResInfo->precision = precision;
}
-int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** pRes) {
+int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
-
+
tsem_init(&schdRspSem, 0, 0);
SQueryResult res = {.code = 0, .numOfRows = 0};
int32_t code = schedulerAsyncExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr,
pRequest->metric.start, schdExecCallback, &res);
+
+ pRequest->body.resInfo.execRes = res.res;
+
while (true) {
if (code != TSDB_CODE_SUCCESS) {
if (pRequest->body.queryJob != 0) {
schedulerFreeJob(pRequest->body.queryJob);
}
- *pRes = res.res;
-
pRequest->code = code;
terrno = code;
return pRequest->code;
} else {
tsem_wait(&schdRspSem);
-
+
if (res.code) {
code = res.code;
} else {
@@ -327,27 +379,25 @@ int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNod
}
}
- *pRes = res.res;
-
pRequest->code = res.code;
terrno = res.code;
return pRequest->code;
}
-
-int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList, void** pRes) {
+int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
SQueryResult res = {.code = 0, .numOfRows = 0};
int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr,
pRequest->metric.start, &res);
+
+ pRequest->body.resInfo.execRes = res.res;
+
if (code != TSDB_CODE_SUCCESS) {
if (pRequest->body.queryJob != 0) {
schedulerFreeJob(pRequest->body.queryJob);
}
- *pRes = res.res;
-
pRequest->code = code;
terrno = code;
return pRequest->code;
@@ -361,92 +411,118 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
}
}
- *pRes = res.res;
-
pRequest->code = res.code;
terrno = res.code;
return pRequest->code;
}
int32_t getQueryPlan(SRequestObj* pRequest, SQuery* pQuery, SArray** pNodeList) {
- *pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
- return getPlan(pRequest, pQuery, &pRequest->body.pDag, *pNodeList);
+ return getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList);
}
-int32_t validateSversion(SRequestObj* pRequest, void* res) {
- SArray* pArray = NULL;
+int32_t handleSubmitExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet *epset) {
int32_t code = 0;
-
- if (TDMT_VND_SUBMIT == pRequest->type) {
- SSubmitRsp* pRsp = (SSubmitRsp*)res;
- if (pRsp->nBlocks <= 0) {
- return TSDB_CODE_SUCCESS;
- }
-
- pArray = taosArrayInit(pRsp->nBlocks, sizeof(STbSVersion));
- if (NULL == pArray) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_OUT_OF_MEMORY;
+ SArray* pArray = NULL;
+ SSubmitRsp* pRsp = (SSubmitRsp*)res;
+ if (pRsp->nBlocks <= 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ pArray = taosArrayInit(pRsp->nBlocks, sizeof(STbSVersion));
+ if (NULL == pArray) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+
+ for (int32_t i = 0; i < pRsp->nBlocks; ++i) {
+ SSubmitBlkRsp* blk = pRsp->pBlocks + i;
+ if (NULL == blk->tblFName || 0 == blk->tblFName[0]) {
+ continue;
}
+
+ STbSVersion tbSver = {.tbFName = blk->tblFName, .sver = blk->sver};
+ taosArrayPush(pArray, &tbSver);
+ }
- for (int32_t i = 0; i < pRsp->nBlocks; ++i) {
- SSubmitBlkRsp* blk = pRsp->pBlocks + i;
- if (NULL == blk->tblFName || 0 == blk->tblFName[0]) {
- continue;
- }
+ code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, epset, pArray);
- STbSVersion tbSver = {.tbFName = blk->tblFName, .sver = blk->sver};
- taosArrayPush(pArray, &tbSver);
- }
- } else if (TDMT_VND_QUERY == pRequest->type) {
- SArray* pTbArray = (SArray*)res;
- int32_t tbNum = taosArrayGetSize(pTbArray);
- if (tbNum <= 0) {
- return TSDB_CODE_SUCCESS;
- }
+_return:
- pArray = taosArrayInit(tbNum, sizeof(STbSVersion));
- if (NULL == pArray) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_OUT_OF_MEMORY;
- }
+ taosArrayDestroy(pArray);
+ return code;
+}
- for (int32_t i = 0; i < tbNum; ++i) {
- STbVerInfo* tbInfo = taosArrayGet(pTbArray, i);
- STbSVersion tbSver = {.tbFName = tbInfo->tbFName, .sver = tbInfo->sversion, .tver = tbInfo->tversion};
- taosArrayPush(pArray, &tbSver);
- }
+int32_t handleQueryExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet *epset) {
+ int32_t code = 0;
+ SArray* pArray = NULL;
+ SArray* pTbArray = (SArray*)res;
+ int32_t tbNum = taosArrayGetSize(pTbArray);
+ if (tbNum <= 0) {
+ return TSDB_CODE_SUCCESS;
+ }
+
+ pArray = taosArrayInit(tbNum, sizeof(STbSVersion));
+ if (NULL == pArray) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+
+ for (int32_t i = 0; i < tbNum; ++i) {
+ STbVerInfo* tbInfo = taosArrayGet(pTbArray, i);
+ STbSVersion tbSver = {.tbFName = tbInfo->tbFName, .sver = tbInfo->sversion, .tver = tbInfo->tversion};
+ taosArrayPush(pArray, &tbSver);
}
- SCatalog* pCatalog = NULL;
- CHECK_CODE_GOTO(catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog), _return);
-
- SEpSet epset = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
-
- code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, &epset, pArray);
+ code = catalogChkTbMetaVersion(pCatalog, pRequest->pTscObj->pAppInfo->pTransporter, epset, pArray);
_return:
taosArrayDestroy(pArray);
+ return code;
+}
- return code;
+int32_t handleAlterTbExecRes(void* res, SCatalog* pCatalog) {
+ return catalogUpdateTableMeta(pCatalog, (STableMetaRsp*)res);
}
-void freeRequestRes(SRequestObj* pRequest, void* res) {
- if (NULL == pRequest || NULL == res) {
- return;
+int32_t handleExecRes(SRequestObj* pRequest) {
+ if (NULL == pRequest->body.resInfo.execRes.res) {
+ return TSDB_CODE_SUCCESS;
}
-
- if (TDMT_VND_SUBMIT == pRequest->type) {
- tFreeSSubmitRsp((SSubmitRsp*)res);
- } else if (TDMT_VND_QUERY == pRequest->type) {
- taosArrayDestroy((SArray*)res);
+
+ int32_t code = 0;
+ SCatalog* pCatalog = NULL;
+ code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
+ if (code) {
+ return code;
+ }
+
+ SEpSet epset = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp);
+ SQueryExecRes* pRes = &pRequest->body.resInfo.execRes;
+
+ switch (pRes->msgType) {
+ case TDMT_VND_ALTER_TABLE:
+ case TDMT_MND_ALTER_STB: {
+ code = handleAlterTbExecRes(pRes->res, pCatalog);
+ break;
+ }
+ case TDMT_VND_SUBMIT: {
+ code = handleSubmitExecRes(pRequest, pRes->res, pCatalog, &epset);
+ break;
+ }
+ case TDMT_VND_QUERY: {
+ code = handleQueryExecRes(pRequest, pRes->res, pCatalog, &epset);
+ break;
+ }
+ default:
+ tscError("invalid exec result for request type %d", pRequest->type);
+ return TSDB_CODE_APP_ERROR;
}
+
+ return code;
}
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code, bool keepQuery, void** res) {
- void* pRes = NULL;
-
if (TSDB_CODE_SUCCESS == code) {
switch (pQuery->execMode) {
case QUERY_EXEC_MODE_LOCAL:
@@ -456,13 +532,10 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code
code = execDdlQuery(pRequest, pQuery);
break;
case QUERY_EXEC_MODE_SCHEDULE: {
- SArray* pNodeList = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
- code = getPlan(pRequest, pQuery, &pRequest->body.pDag, pNodeList);
+ SArray* pNodeList = NULL;
+ code = getPlan(pRequest, pQuery, &pRequest->body.pDag, &pNodeList);
if (TSDB_CODE_SUCCESS == code) {
- code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList, &pRes);
- if (NULL != pRes) {
- code = validateSversion(pRequest, pRes);
- }
+ code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList);
}
taosArrayDestroy(pNodeList);
break;
@@ -479,15 +552,15 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, int32_t code
qDestroyQuery(pQuery);
}
+ handleExecRes(pRequest);
+
if (NULL != pRequest && TSDB_CODE_SUCCESS != code) {
pRequest->code = terrno;
}
if (res) {
- *res = pRes;
- } else {
- freeRequestRes(pRequest, pRes);
- pRes = NULL;
+ *res = pRequest->body.resInfo.execRes.res;
+ pRequest->body.resInfo.execRes.res = NULL;
}
return pRequest;
@@ -733,7 +806,7 @@ void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg,
if (NULL == pEpSet) {
return;
}
-
+
switch (pSendInfo->target.type) {
case TARGET_TYPE_MNODE:
if (NULL == pTscObj) {
@@ -741,7 +814,7 @@ void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg,
return;
}
- updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, pEpSet);
+ updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, pEpSet);
break;
case TARGET_TYPE_VNODE: {
if (NULL == pTscObj) {
@@ -750,12 +823,13 @@ void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg,
}
SCatalog* pCatalog = NULL;
- int32_t code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCatalog);
+ int32_t code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCatalog);
if (code != TSDB_CODE_SUCCESS) {
- tscError("fail to get catalog handle, clusterId:%" PRIx64 ", error %s", pTscObj->pAppInfo->clusterId, tstrerror(code));
+ tscError("fail to get catalog handle, clusterId:%" PRIx64 ", error %s", pTscObj->pAppInfo->clusterId,
+ tstrerror(code));
return;
}
-
+
catalogUpdateVgEpSet(pCatalog, pSendInfo->target.dbFName, pSendInfo->target.vgId, pEpSet);
break;
}
@@ -765,12 +839,11 @@ void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg,
}
}
-
void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->info.ahandle;
assert(pMsg->info.ahandle != NULL);
SRequestObj* pRequest = NULL;
- STscObj* pTscObj = NULL;
+ STscObj* pTscObj = NULL;
if (pSendInfo->requestObjRefId != 0) {
SRequestObj* pRequest = (SRequestObj*)taosAcquireRef(clientReqRefPool, pSendInfo->requestObjRefId);
@@ -897,7 +970,8 @@ void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertU
return NULL;
}
- pRequest->code = setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResInfo->pData, convertUcs4);
+ pRequest->code =
+ setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResInfo->pData, convertUcs4, true);
if (pRequest->code != TSDB_CODE_SUCCESS) {
pResultInfo->numOfRows = 0;
return NULL;
@@ -919,9 +993,8 @@ void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertU
return pResultInfo->row;
}
-
void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4) {
- //return doAsyncFetchRows(pRequest, setupOneRowPtr, convertUcs4);
+ // return doAsyncFetchRows(pRequest, setupOneRowPtr, convertUcs4);
assert(pRequest != NULL);
SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
@@ -939,7 +1012,8 @@ void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4)
return NULL;
}
- pRequest->code = setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResInfo->pData, convertUcs4);
+ pRequest->code =
+ setQueryResultFromRsp(&pRequest->body.resInfo, (SRetrieveTableRsp*)pResInfo->pData, convertUcs4, true);
if (pRequest->code != TSDB_CODE_SUCCESS) {
pResultInfo->numOfRows = 0;
return NULL;
@@ -983,27 +1057,20 @@ static char* parseTagDatatoJson(void* p) {
goto end;
}
- int16_t nCols = kvRowNCols(p);
+ SArray* pTagVals = NULL;
+ if (tTagToValArray((const STag*)p, &pTagVals) != 0) {
+ goto end;
+ }
+
+ int16_t nCols = taosArrayGetSize(pTagVals);
char tagJsonKey[256] = {0};
for (int j = 0; j < nCols; ++j) {
- SColIdx* pColIdx = kvRowColIdxAt(p, j);
- char* val = (char*)(kvRowColVal(p, pColIdx));
- if (j == 0) {
- if (*val == TSDB_DATA_TYPE_NULL) {
- string = taosMemoryCalloc(1, 8);
- sprintf(string, "%s", TSDB_DATA_NULL_STR_L);
- goto end;
- }
- continue;
- }
-
+ STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j);
// json key encode by binary
memset(tagJsonKey, 0, sizeof(tagJsonKey));
- memcpy(tagJsonKey, varDataVal(val), varDataLen(val));
+ memcpy(tagJsonKey, pTagVal->pKey, strlen(pTagVal->pKey));
// json value
- val += varDataTLen(val);
- char* realData = POINTER_SHIFT(val, CHAR_BYTES);
- char type = *val;
+ char type = pTagVal->type;
if (type == TSDB_DATA_TYPE_NULL) {
cJSON* value = cJSON_CreateNull();
if (value == NULL) {
@@ -1012,11 +1079,12 @@ static char* parseTagDatatoJson(void* p) {
cJSON_AddItemToObject(json, tagJsonKey, value);
} else if (type == TSDB_DATA_TYPE_NCHAR) {
cJSON* value = NULL;
- if (varDataLen(realData) > 0) {
- char* tagJsonValue = taosMemoryCalloc(varDataLen(realData), 1);
- int32_t length = taosUcs4ToMbs((TdUcs4*)varDataVal(realData), varDataLen(realData), tagJsonValue);
+ if (pTagVal->nData > 0) {
+ char* tagJsonValue = taosMemoryCalloc(pTagVal->nData, 1);
+ int32_t length = taosUcs4ToMbs((TdUcs4*)pTagVal->pData, pTagVal->nData, tagJsonValue);
if (length < 0) {
- tscError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, val);
+ tscError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
+ pTagVal->pData);
taosMemoryFree(tagJsonValue);
goto end;
}
@@ -1025,7 +1093,7 @@ static char* parseTagDatatoJson(void* p) {
if (value == NULL) {
goto end;
}
- } else if (varDataLen(realData) == 0) {
+ } else if (pTagVal->nData == 0) {
value = cJSON_CreateString("");
} else {
ASSERT(0);
@@ -1033,22 +1101,14 @@ static char* parseTagDatatoJson(void* p) {
cJSON_AddItemToObject(json, tagJsonKey, value);
} else if (type == TSDB_DATA_TYPE_DOUBLE) {
- double jsonVd = *(double*)(realData);
+ double jsonVd = *(double*)(&pTagVal->i64);
cJSON* value = cJSON_CreateNumber(jsonVd);
if (value == NULL) {
goto end;
}
cJSON_AddItemToObject(json, tagJsonKey, value);
- // }else if(type == TSDB_DATA_TYPE_BIGINT){
- // int64_t jsonVd = *(int64_t*)(realData);
- // cJSON* value = cJSON_CreateNumber((double)jsonVd);
- // if (value == NULL)
- // {
- // goto end;
- // }
- // cJSON_AddItemToObject(json, tagJsonKey, value);
} else if (type == TSDB_DATA_TYPE_BOOL) {
- char jsonVd = *(char*)(realData);
+ char jsonVd = *(char*)(&pTagVal->i64);
cJSON* value = cJSON_CreateBool(jsonVd);
if (value == NULL) {
goto end;
@@ -1113,7 +1173,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
if (jsonInnerType == TSDB_DATA_TYPE_NULL) {
sprintf(varDataVal(dst), "%s", TSDB_DATA_NULL_STR_L);
varDataSetLen(dst, strlen(varDataVal(dst)));
- } else if (jsonInnerType == TSDB_DATA_TYPE_JSON) {
+ } else if (jsonInnerType == TD_TAG_JSON) {
char* jsonString = parseTagDatatoJson(jsonInnerData);
STR_TO_VARSTR(dst, jsonString);
taosMemoryFree(jsonString);
@@ -1132,10 +1192,6 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
double jsonVd = *(double*)(jsonInnerData);
sprintf(varDataVal(dst), "%.9lf", jsonVd);
varDataSetLen(dst, strlen(varDataVal(dst)));
- } else if (jsonInnerType == TSDB_DATA_TYPE_BIGINT) {
- int64_t jsonVd = *(int64_t*)(jsonInnerData);
- sprintf(varDataVal(dst), "%" PRId64, jsonVd);
- varDataSetLen(dst, strlen(varDataVal(dst)));
} else if (jsonInnerType == TSDB_DATA_TYPE_BOOL) {
sprintf(varDataVal(dst), "%s", (*((char*)jsonInnerData) == 1) ? "true" : "false");
varDataSetLen(dst, strlen(varDataVal(dst)));
@@ -1246,11 +1302,12 @@ void resetConnectDB(STscObj* pTscObj) {
taosThreadMutexUnlock(&pTscObj->mutex);
}
-int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4) {
+int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4,
+ bool freeAfterUse) {
assert(pResultInfo != NULL && pRsp != NULL);
- taosMemoryFreeClear(pResultInfo->pRspMsg);
-
+ if (freeAfterUse) taosMemoryFreeClear(pResultInfo->pRspMsg);
+
pResultInfo->pRspMsg = (const char*)pRsp;
pResultInfo->pData = (void*)pRsp->data;
pResultInfo->numOfRows = htonl(pRsp->numOfRows);
diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c
index 53eb443b36b05393b22667a6f623892008f14ebb..e144885e9efc4b3eca7c806996b77ad416d70161 100644
--- a/source/client/src/clientMain.c
+++ b/source/client/src/clientMain.c
@@ -666,8 +666,39 @@ int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
return stmtSetTbName(stmt, name);
}
+int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
+ if (stmt == NULL || tags == NULL) {
+ tscError("NULL parameter for %s", __FUNCTION__);
+ terrno = TSDB_CODE_INVALID_PARA;
+ return terrno;
+ }
+
+ return stmtSetTbTags(stmt, tags);
+}
+
+
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
+int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int* fieldNum, TAOS_FIELD_E** fields) {
+ if (stmt == NULL || NULL == fieldNum) {
+ tscError("NULL parameter for %s", __FUNCTION__);
+ terrno = TSDB_CODE_INVALID_PARA;
+ return terrno;
+ }
+
+ return stmtGetTagFields(stmt, fieldNum, fields);
+}
+
+int taos_stmt_get_col_fields(TAOS_STMT *stmt, int* fieldNum, TAOS_FIELD_E** fields) {
+ if (stmt == NULL || NULL == fieldNum) {
+ tscError("NULL parameter for %s", __FUNCTION__);
+ terrno = TSDB_CODE_INVALID_PARA;
+ return terrno;
+ }
+
+ return stmtGetColFields(stmt, fieldNum, fields);
+}
+
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
if (stmt == NULL || bind == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
@@ -772,6 +803,16 @@ int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
return stmtGetParamNum(stmt, nums);
}
+int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
+ if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
+ tscError("invalid parameter for %s", __FUNCTION__);
+ terrno = TSDB_CODE_INVALID_PARA;
+ return terrno;
+ }
+
+ return stmtGetParam(stmt, idx, type, bytes);
+}
+
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
if (stmt == NULL) {
tscError("NULL parameter for %s", __FUNCTION__);
diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c
index f15315fe6055127f13b15849f897d8edda5a381b..9de3ee1d0f1a8a529c7177329543e3379cdc6cbb 100644
--- a/source/client/src/clientMsgHandler.c
+++ b/source/client/src/clientMsgHandler.c
@@ -223,10 +223,33 @@ int32_t processDropDbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
return code;
}
+int32_t processAlterStbRsp(void* param, const SDataBuf* pMsg, int32_t code) {
+ SRequestObj* pRequest = param;
+ if (code != TSDB_CODE_SUCCESS) {
+ setErrno(pRequest, code);
+ tsem_post(&pRequest->body.rspSem);
+ return code;
+ }
+
+ SMAlterStbRsp alterRsp = {0};
+ SDecoder coder = {0};
+ tDecoderInit(&coder, pMsg->pData, pMsg->len);
+ tDecodeSMAlterStbRsp(&coder, &alterRsp);
+ tDecoderClear(&coder);
+
+ pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB;
+ pRequest->body.resInfo.execRes.res = alterRsp.pMeta;
+
+ tsem_post(&pRequest->body.rspSem);
+ return code;
+}
+
+
void initMsgHandleFp() {
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CONNECT)] = processConnectRsp;
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_DB)] = processCreateDbRsp;
handleRequestRspFp[TMSG_INDEX(TDMT_MND_USE_DB)] = processUseDbRsp;
handleRequestRspFp[TMSG_INDEX(TDMT_MND_CREATE_STB)] = processCreateTableRsp;
handleRequestRspFp[TMSG_INDEX(TDMT_MND_DROP_DB)] = processDropDbRsp;
+ handleRequestRspFp[TMSG_INDEX(TDMT_MND_ALTER_STB)] = processAlterStbRsp;
}
diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c
index 01d785ef73107778c818437c18d98c778d1f8893..3adb3684da1164363a1ffda4c26130643efc5f78 100644
--- a/source/client/src/clientStmt.c
+++ b/source/client/src/clientStmt.c
@@ -17,7 +17,7 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
}
break;
case STMT_SETTAGS:
- if (STMT_STATUS_NE(SETTBNAME)) {
+ if (STMT_STATUS_NE(SETTBNAME) && STMT_STATUS_NE(FETCH_FIELDS)) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
break;
@@ -540,6 +540,8 @@ int stmtSetTbName(TAOS_STMT* stmt, const char* tbName) {
if (pStmt->bInfo.needParse) {
strncpy(pStmt->bInfo.tbName, tbName, sizeof(pStmt->bInfo.tbName) - 1);
pStmt->bInfo.tbName[sizeof(pStmt->bInfo.tbName) - 1] = 0;
+
+ STMT_ERR_RET(stmtParseSql(pStmt));
}
return TSDB_CODE_SUCCESS;
@@ -550,10 +552,6 @@ int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) {
STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTAGS));
- if (pStmt->bInfo.needParse) {
- STMT_ERR_RET(stmtParseSql(pStmt));
- }
-
if (pStmt->bInfo.inExecCache) {
return TSDB_CODE_SUCCESS;
}
@@ -571,7 +569,7 @@ int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) {
return TSDB_CODE_SUCCESS;
}
-int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) {
+int stmtFetchTagFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD_E** fields) {
if (STMT_TYPE_QUERY == pStmt->sql.type) {
tscError("invalid operation to get query tag fileds");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
@@ -589,7 +587,7 @@ int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fiel
return TSDB_CODE_SUCCESS;
}
-int32_t stmtFetchColFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) {
+int stmtFetchColFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD_E** fields) {
if (STMT_TYPE_QUERY == pStmt->sql.type) {
tscError("invalid operation to get query column fileds");
STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR);
@@ -852,6 +850,71 @@ int stmtIsInsert(TAOS_STMT* stmt, int* insert) {
return TSDB_CODE_SUCCESS;
}
+int stmtGetTagFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields) {
+ STscStmt* pStmt = (STscStmt*)stmt;
+
+ if (STMT_TYPE_QUERY == pStmt->sql.type) {
+ STMT_RET(TSDB_CODE_TSC_STMT_API_ERROR);
+ }
+
+ STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
+
+ if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
+ STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
+ pStmt->bInfo.needParse = false;
+ }
+
+ if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
+ taos_free_result(pStmt->exec.pRequest);
+ pStmt->exec.pRequest = NULL;
+ }
+
+ if (NULL == pStmt->exec.pRequest) {
+ STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
+ }
+
+ if (pStmt->bInfo.needParse) {
+ STMT_ERR_RET(stmtParseSql(pStmt));
+ }
+
+ STMT_ERR_RET(stmtFetchTagFields(stmt, nums, fields));
+
+ return TSDB_CODE_SUCCESS;
+}
+
+int stmtGetColFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields) {
+ STscStmt* pStmt = (STscStmt*)stmt;
+
+ if (STMT_TYPE_QUERY == pStmt->sql.type) {
+ STMT_RET(TSDB_CODE_TSC_STMT_API_ERROR);
+ }
+
+ STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
+
+ if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
+ STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
+ pStmt->bInfo.needParse = false;
+ }
+
+ if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
+ taos_free_result(pStmt->exec.pRequest);
+ pStmt->exec.pRequest = NULL;
+ }
+
+ if (NULL == pStmt->exec.pRequest) {
+ STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
+ }
+
+ if (pStmt->bInfo.needParse) {
+ STMT_ERR_RET(stmtParseSql(pStmt));
+ }
+
+ STMT_ERR_RET(stmtFetchColFields(stmt, nums, fields));
+
+ return TSDB_CODE_SUCCESS;
+}
+
+
int stmtGetParamNum(TAOS_STMT* stmt, int* nums) {
STscStmt* pStmt = (STscStmt*)stmt;
@@ -884,6 +947,50 @@ int stmtGetParamNum(TAOS_STMT* stmt, int* nums) {
return TSDB_CODE_SUCCESS;
}
+int stmtGetParam(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
+ STscStmt* pStmt = (STscStmt*)stmt;
+
+ if (STMT_TYPE_QUERY == pStmt->sql.type) {
+ STMT_RET(TSDB_CODE_TSC_STMT_API_ERROR);
+ }
+
+ STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS));
+
+ if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 &&
+ STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
+ pStmt->bInfo.needParse = false;
+ }
+
+ if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
+ taos_free_result(pStmt->exec.pRequest);
+ pStmt->exec.pRequest = NULL;
+ }
+
+ if (NULL == pStmt->exec.pRequest) {
+ STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest));
+ }
+
+ if (pStmt->bInfo.needParse) {
+ STMT_ERR_RET(stmtParseSql(pStmt));
+ }
+
+ int32_t nums = 0;
+ TAOS_FIELD_E *pField = NULL;
+ STMT_ERR_RET(stmtFetchColFields(stmt, &nums, &pField));
+ if (idx >= nums) {
+ tscError("idx %d is too big", idx);
+ taosMemoryFree(pField);
+ STMT_ERR_RET(TSDB_CODE_INVALID_PARA);
+ }
+
+ *type = pField[idx].type;
+ *bytes = pField[idx].bytes;
+
+ taosMemoryFree(pField);
+
+ return TSDB_CODE_SUCCESS;
+}
+
TAOS_RES* stmtUseResult(TAOS_STMT* stmt) {
STscStmt* pStmt = (STscStmt*)stmt;
diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c
index dfa56f80c457783eb58255f3a0d494936b475bad..c2170631c2c90ca1d7322a4210f7763c6a703c57 100644
--- a/source/client/src/tmq.c
+++ b/source/client/src/tmq.c
@@ -143,6 +143,7 @@ typedef struct {
typedef struct {
// subscribe info
char* topicName;
+ char db[TSDB_DB_FNAME_LEN];
SArray* vgs; // SArray
@@ -1039,6 +1040,7 @@ bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
topic.schema = pTopicEp->schema;
taosHashClear(pHash);
topic.topicName = strdup(pTopicEp->topic);
+ tstrncpy(topic.db, pTopicEp->db, TSDB_DB_FNAME_LEN);
tscDebug("consumer %ld update topic: %s", tmq->consumerId, topic.topicName);
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
@@ -1243,7 +1245,7 @@ tmq_resp_err_t tmq_seek(tmq_t* tmq, const tmq_topic_vgroup_t* offset) {
return TMQ_RESP_ERR__FAIL;
}
-SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic* pTopic, SMqClientVg* pVg) {
+SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t timeout, SMqClientTopic* pTopic, SMqClientVg* pVg) {
int64_t reqOffset;
if (pVg->currentOffset >= 0) {
reqOffset = pVg->currentOffset;
@@ -1269,7 +1271,7 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic*
strcpy(pReq->subKey + tlen + 1, pTopic->topicName);
pReq->withTbName = tmq->withTbName;
- pReq->waitTime = waitTime;
+ pReq->timeout = timeout;
pReq->consumerId = tmq->consumerId;
pReq->epoch = tmq->epoch;
pReq->currentOffset = reqOffset;
@@ -1283,7 +1285,8 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic*
SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper) {
SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj));
pRspObj->resType = RES_TYPE__TMQ;
- strncpy(pRspObj->topic, pWrapper->topicHandle->topicName, TSDB_TOPIC_FNAME_LEN);
+ tstrncpy(pRspObj->topic, pWrapper->topicHandle->topicName, TSDB_TOPIC_FNAME_LEN);
+ tstrncpy(pRspObj->db, pWrapper->topicHandle->db, TSDB_DB_FNAME_LEN);
pRspObj->vgId = pWrapper->vgHandle->vgId;
pRspObj->resIter = -1;
memcpy(&pRspObj->rsp, &pWrapper->msg, sizeof(SMqDataBlkRsp));
@@ -1297,7 +1300,7 @@ SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper) {
return pRspObj;
}
-int32_t tmqPollImpl(tmq_t* tmq, int64_t waitTime) {
+int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
/*printf("call poll\n");*/
for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) {
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
@@ -1318,7 +1321,7 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t waitTime) {
#endif
}
atomic_store_32(&pVg->vgSkipCnt, 0);
- SMqPollReq* pReq = tmqBuildConsumeReqImpl(tmq, waitTime, pTopic, pVg);
+ SMqPollReq* pReq = tmqBuildConsumeReqImpl(tmq, timeout, pTopic, pVg);
if (pReq == NULL) {
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
tsem_post(&tmq->rspSem);
@@ -1388,7 +1391,7 @@ int32_t tmqHandleNoPollRsp(tmq_t* tmq, SMqRspWrapper* rspWrapper, bool* pReset)
return 0;
}
-SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t waitTime, bool pollIfReset) {
+SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
while (1) {
SMqRspWrapper* rspWrapper = NULL;
taosGetQitem(tmq->qall, (void**)&rspWrapper);
@@ -1428,17 +1431,17 @@ SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t waitTime, bool pollIfReset) {
taosFreeQitem(rspWrapper);
if (pollIfReset && reset) {
tscDebug("consumer %ld reset and repoll", tmq->consumerId);
- tmqPollImpl(tmq, waitTime);
+ tmqPollImpl(tmq, timeout);
}
}
}
}
-TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t wait_time) {
+TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
SMqRspObj* rspObj;
int64_t startTime = taosGetTimestampMs();
- rspObj = tmqHandleAllRsp(tmq, wait_time, false);
+ rspObj = tmqHandleAllRsp(tmq, timeout, false);
if (rspObj) {
return (TAOS_RES*)rspObj;
}
@@ -1450,16 +1453,16 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t wait_time) {
while (1) {
tmqHandleAllDelayedTask(tmq);
- if (tmqPollImpl(tmq, wait_time) < 0) return NULL;
+ if (tmqPollImpl(tmq, timeout) < 0) return NULL;
- rspObj = tmqHandleAllRsp(tmq, wait_time, false);
+ rspObj = tmqHandleAllRsp(tmq, timeout, false);
if (rspObj) {
return (TAOS_RES*)rspObj;
}
- if (wait_time != 0) {
+ if (timeout != 0) {
int64_t endTime = taosGetTimestampMs();
int64_t leftTime = endTime - startTime;
- if (leftTime > wait_time) {
+ if (leftTime > timeout) {
tscDebug("consumer %ld (epoch %d) timeout, no rsp", tmq->consumerId, tmq->epoch);
return NULL;
}
@@ -1474,10 +1477,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t wait_time) {
tmq_resp_err_t tmq_consumer_close(tmq_t* tmq) {
if (tmq->status == TMQ_CONSUMER_STATUS__READY) {
tmq_resp_err_t rsp = tmq_commit_sync(tmq, NULL);
- if (rsp == TMQ_RESP_ERR__SUCCESS) {
- // TODO: free resources
- return TMQ_RESP_ERR__SUCCESS;
- } else {
+ if (rsp == TMQ_RESP_ERR__FAIL) {
return TMQ_RESP_ERR__FAIL;
}
@@ -1485,10 +1485,7 @@ tmq_resp_err_t tmq_consumer_close(tmq_t* tmq) {
rsp = tmq_subscribe(tmq, lst);
tmq_list_destroy(lst);
- if (rsp == TMQ_RESP_ERR__SUCCESS) {
- // TODO: free resources
- return TMQ_RESP_ERR__SUCCESS;
- } else {
+ if (rsp == TMQ_RESP_ERR__FAIL) {
return TMQ_RESP_ERR__FAIL;
}
}
@@ -1512,6 +1509,15 @@ const char* tmq_get_topic_name(TAOS_RES* res) {
}
}
+const char* tmq_get_db_name(TAOS_RES* res) {
+ if (TD_RES_TMQ(res)) {
+ SMqRspObj* pRspObj = (SMqRspObj*)res;
+ return strchr(pRspObj->db, '.') + 1;
+ } else {
+ return NULL;
+ }
+}
+
int32_t tmq_get_vgroup_id(TAOS_RES* res) {
if (TD_RES_TMQ(res)) {
SMqRspObj* pRspObj = (SMqRspObj*)res;
diff --git a/source/common/src/systable.c b/source/common/src/systable.c
index 38a6bafe9a5ea2c795b82899e6a6ce91f3ad545d..b163ac32bf55bbae00d3213f8f11c42411c2fe70 100644
--- a/source/common/src/systable.c
+++ b/source/common/src/systable.c
@@ -36,6 +36,7 @@ static const SSysDbTableSchema mnodesSchema[] = {
{.name = "id", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
{.name = "endpoint", .bytes = TSDB_EP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "role", .bytes = 12 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
+ {.name = "status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
};
@@ -215,7 +216,6 @@ static const SSysDbTableSchema transSchema[] = {
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
{.name = "stage", .bytes = TSDB_TRANS_STAGE_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "db", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
- {.name = "type", .bytes = TSDB_TRANS_TYPE_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
{.name = "failed_times", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
{.name = "last_exec_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
{.name = "last_error", .bytes = (TSDB_TRANS_ERROR_LEN - 1) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c
index 17b7a5ea88d887a597c02bf4b1dc35c3816b9ba7..f77b823f3c7d8a9e3f62e98e0f967f9d66ad83d3 100644
--- a/source/common/src/tdatablock.c
+++ b/source/common/src/tdatablock.c
@@ -116,22 +116,23 @@ int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t currentRow, con
int32_t type = pColumnInfoData->info.type;
if (IS_VAR_DATA_TYPE(type)) {
- int32_t dataLen = varDataTLen(pData);
+ int32_t dataLen = 0;
if (type == TSDB_DATA_TYPE_JSON) {
if (*pData == TSDB_DATA_TYPE_NULL) {
- dataLen = 0;
+ dataLen = CHAR_BYTES;
} else if (*pData == TSDB_DATA_TYPE_NCHAR) {
- dataLen = varDataTLen(pData + CHAR_BYTES);
+ dataLen = varDataTLen(pData + CHAR_BYTES) + CHAR_BYTES;
} else if (*pData == TSDB_DATA_TYPE_DOUBLE) {
- dataLen = DOUBLE_BYTES;
+ dataLen = DOUBLE_BYTES + CHAR_BYTES;
} else if (*pData == TSDB_DATA_TYPE_BOOL) {
- dataLen = CHAR_BYTES;
- } else if (*pData == TSDB_DATA_TYPE_JSON) {
- dataLen = kvRowLen(pData + CHAR_BYTES);
+ dataLen = CHAR_BYTES + CHAR_BYTES;
+ } else if (*pData == TD_TAG_JSON) { // json string
+ dataLen = ((STag*)(pData))->len;
} else {
ASSERT(0);
}
- dataLen += CHAR_BYTES;
+ }else {
+ dataLen = varDataTLen(pData);
}
SVarColAttr* pAttr = &pColumnInfoData->varmeta;
@@ -1653,6 +1654,11 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, bool createTb, int64_t suid,
const char* stbFullName, int32_t vgId) {
SSubmitReq* ret = NULL;
+ SArray* tagArray = taosArrayInit(1, sizeof(STagVal));
+ if(!tagArray) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return NULL;
+ }
// cal size
int32_t cap = sizeof(SSubmitReq);
@@ -1674,18 +1680,33 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
createTbReq.type = TSDB_CHILD_TABLE;
createTbReq.ctb.suid = suid;
- SKVRowBuilder kvRowBuilder = {0};
- if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
- ASSERT(0);
+
+
+ STagVal tagVal = {.cid = 1,
+ .type = TSDB_DATA_TYPE_UBIGINT,
+ .pData = (uint8_t*)&pDataBlock->info.groupId,
+ .nData = sizeof(uint64_t)};
+ STag* pTag = NULL;
+ taosArrayClear(tagArray);
+ taosArrayPush(tagArray, &tagVal);
+ tTagNew(tagArray, 1, false, &pTag);
+ if (!pTag) {
+ tdDestroySVCreateTbReq(&createTbReq);
+ taosArrayDestroy(tagArray);
+ return NULL;
}
- tdAddColToKVRow(&kvRowBuilder, 1, &pDataBlock->info.groupId, sizeof(uint64_t));
- createTbReq.ctb.pTag = tdGetKVRowFromBuilder(&kvRowBuilder);
- tdDestroyKVRowBuilder(&kvRowBuilder);
+ createTbReq.ctb.pTag = (uint8_t*)pTag;
int32_t code;
tEncodeSize(tEncodeSVCreateTbReq, &createTbReq, schemaLen, code);
- if (code < 0) return NULL;
- taosMemoryFree(cname);
+
+ tdDestroySVCreateTbReq(&createTbReq);
+
+ if (code < 0) {
+ tdDestroySVCreateTbReq(&createTbReq);
+ taosArrayDestroy(tagArray);
+ return NULL;
+ }
}
cap += sizeof(SSubmitBlk) + schemaLen + rows * maxLen;
@@ -1728,22 +1749,42 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
createTbReq.type = TSDB_CHILD_TABLE;
createTbReq.ctb.suid = suid;
- SKVRowBuilder kvRowBuilder = {0};
- if (tdInitKVRowBuilder(&kvRowBuilder) < 0) {
- ASSERT(0);
+ STagVal tagVal = {.cid = 1,
+ .type = TSDB_DATA_TYPE_UBIGINT,
+ .pData = (uint8_t*)&pDataBlock->info.groupId,
+ .nData = sizeof(uint64_t)};
+ taosArrayClear(tagArray);
+ taosArrayPush(tagArray, &tagVal);
+ STag* pTag = NULL;
+ tTagNew(tagArray, 1, false, &pTag);
+ if (!pTag) {
+ tdDestroySVCreateTbReq(&createTbReq);
+ taosArrayDestroy(tagArray);
+ taosMemoryFreeClear(ret);
+ return NULL;
}
- tdAddColToKVRow(&kvRowBuilder, 1, &pDataBlock->info.groupId, sizeof(uint64_t));
- createTbReq.ctb.pTag = tdGetKVRowFromBuilder(&kvRowBuilder);
- tdDestroyKVRowBuilder(&kvRowBuilder);
+ createTbReq.ctb.pTag = (uint8_t*)pTag;
int32_t code;
tEncodeSize(tEncodeSVCreateTbReq, &createTbReq, schemaLen, code);
- if (code < 0) return NULL;
+ if (code < 0) {
+ tdDestroySVCreateTbReq(&createTbReq);
+ taosArrayDestroy(tagArray);
+ taosMemoryFreeClear(ret);
+ return NULL;
+ }
SEncoder encoder = {0};
tEncoderInit(&encoder, blockData, schemaLen);
- if (tEncodeSVCreateTbReq(&encoder, &createTbReq) < 0) return NULL;
+ code = tEncodeSVCreateTbReq(&encoder, &createTbReq);
tEncoderClear(&encoder);
+ tdDestroySVCreateTbReq(&createTbReq);
+
+ if (code < 0) {
+ taosArrayDestroy(tagArray);
+ taosMemoryFreeClear(ret);
+ return NULL;
+ }
}
blkHead->schemaLen = htonl(schemaLen);
@@ -1778,6 +1819,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
}
ret->length = htonl(ret->length);
+ taosArrayDestroy(tagArray);
return ret;
}
diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c
index e8d7e3ac0933532a4ad4f55509df575d2eaa177b..65daee650840a5bea69b2c0dcb687ea76b4dc705 100644
--- a/source/common/src/tdataformat.c
+++ b/source/common/src/tdataformat.c
@@ -19,31 +19,15 @@
#include "tdatablock.h"
#include "tlog.h"
-typedef struct SKVIdx {
- int32_t cid;
- int32_t offset;
-} SKVIdx;
+static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson);
#pragma pack(push, 1)
typedef struct {
int16_t nCols;
- SKVIdx idx[];
+ uint8_t idx[];
} STSKVRow;
#pragma pack(pop)
-typedef struct STagIdx {
- int16_t cid;
- uint16_t offset;
-} STagIdx;
-
-#pragma pack(push, 1)
-struct STag {
- uint16_t len;
- uint16_t nTag;
- STagIdx idx[];
-};
-#pragma pack(pop)
-
#define TSROW_IS_KV_ROW(r) ((r)->flags & TSROW_KV_ROW)
#define BIT1_SIZE(n) (((n)-1) / 8 + 1)
#define BIT2_SIZE(n) (((n)-1) / 4 + 1)
@@ -54,171 +38,551 @@ struct STag {
static FORCE_INLINE int tSKVIdxCmprFn(const void *p1, const void *p2);
-// STSRow2
-int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow) {
+// SValue
+static FORCE_INLINE int32_t tPutValue(uint8_t *p, SValue *pValue, int8_t type) {
int32_t n = 0;
- n += tPutI64(p ? p + n : p, pRow->ts);
- n += tPutI8(p ? p + n : p, pRow->flags);
- n += tPutI32v(p ? p + n : p, pRow->sver);
+ if (IS_VAR_DATA_TYPE(type)) {
+ n += tPutBinary(p ? p + n : p, pValue->pData, pValue->nData);
+ } else {
+ switch (type) {
+ case TSDB_DATA_TYPE_BOOL:
+ n += tPutI8(p ? p + n : p, pValue->i8 ? 1 : 0);
+ break;
+ case TSDB_DATA_TYPE_TINYINT:
+ n += tPutI8(p ? p + n : p, pValue->i8);
+ break;
+ case TSDB_DATA_TYPE_SMALLINT:
+ n += tPutI16(p ? p + n : p, pValue->i16);
+ break;
+ case TSDB_DATA_TYPE_INT:
+ n += tPutI32(p ? p + n : p, pValue->i32);
+ break;
+ case TSDB_DATA_TYPE_BIGINT:
+ n += tPutI64(p ? p + n : p, pValue->i64);
+ break;
+ case TSDB_DATA_TYPE_FLOAT:
+ n += tPutFloat(p ? p + n : p, pValue->f);
+ break;
+ case TSDB_DATA_TYPE_DOUBLE:
+ n += tPutDouble(p ? p + n : p, pValue->d);
+ break;
+ case TSDB_DATA_TYPE_TIMESTAMP:
+ n += tPutI64(p ? p + n : p, pValue->ts);
+ break;
+ case TSDB_DATA_TYPE_UTINYINT:
+ n += tPutU8(p ? p + n : p, pValue->u8);
+ break;
+ case TSDB_DATA_TYPE_USMALLINT:
+ n += tPutU16(p ? p + n : p, pValue->u16);
+ break;
+ case TSDB_DATA_TYPE_UINT:
+ n += tPutU32(p ? p + n : p, pValue->u32);
+ break;
+ case TSDB_DATA_TYPE_UBIGINT:
+ n += tPutU64(p ? p + n : p, pValue->u64);
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
- ASSERT(pRow->flags & 0xf);
+ return n;
+}
- switch (pRow->flags & 0xf) {
- case TSROW_HAS_NONE:
- case TSROW_HAS_NULL:
- break;
- default:
- n += tPutBinary(p ? p + n : p, pRow->pData, pRow->nData);
- break;
+static FORCE_INLINE int32_t tGetValue(uint8_t *p, SValue *pValue, int8_t type) {
+ int32_t n = 0;
+
+ if (IS_VAR_DATA_TYPE(type)) {
+ n += tGetBinary(p, &pValue->pData, pValue ? &pValue->nData : NULL);
+ } else {
+ switch (type) {
+ case TSDB_DATA_TYPE_BOOL:
+ n += tGetI8(p, &pValue->i8);
+ break;
+ case TSDB_DATA_TYPE_TINYINT:
+ n += tGetI8(p, &pValue->i8);
+ break;
+ case TSDB_DATA_TYPE_SMALLINT:
+ n += tGetI16(p, &pValue->i16);
+ break;
+ case TSDB_DATA_TYPE_INT:
+ n += tGetI32(p, &pValue->i32);
+ break;
+ case TSDB_DATA_TYPE_BIGINT:
+ n += tGetI64(p, &pValue->i64);
+ break;
+ case TSDB_DATA_TYPE_FLOAT:
+ n += tGetFloat(p, &pValue->f);
+ break;
+ case TSDB_DATA_TYPE_DOUBLE:
+ n += tGetDouble(p, &pValue->d);
+ break;
+ case TSDB_DATA_TYPE_TIMESTAMP:
+ n += tGetI64(p, &pValue->ts);
+ break;
+ case TSDB_DATA_TYPE_UTINYINT:
+ n += tGetU8(p, &pValue->u8);
+ break;
+ case TSDB_DATA_TYPE_USMALLINT:
+ n += tGetU16(p, &pValue->u16);
+ break;
+ case TSDB_DATA_TYPE_UINT:
+ n += tGetU32(p, &pValue->u32);
+ break;
+ case TSDB_DATA_TYPE_UBIGINT:
+ n += tGetU64(p, &pValue->u64);
+ break;
+ default:
+ ASSERT(0);
+ }
}
return n;
}
-int32_t tGetTSRow(uint8_t *p, STSRow2 *pRow) {
- int32_t n = 0;
- uint8_t flags;
+// STSRow2 ========================================================================
+static void tTupleTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow2 *pRow) {
+ int32_t nColVal = taosArrayGetSize(pArray);
+ STColumn *pTColumn;
+ SColVal *pColVal;
+
+ ASSERT(nColVal > 0);
+
+ pRow->sver = pTSchema->version;
+
+ // ts
+ pTColumn = &pTSchema->columns[0];
+ pColVal = (SColVal *)taosArrayGet(pArray, 0);
+
+ ASSERT(pTColumn->colId == 0 && pColVal->cid == 0);
+ ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
+
+ pRow->ts = pColVal->value.ts;
+
+ // other fields
+ int32_t iColVal = 1;
+ int32_t bidx;
+ uint32_t nv = 0;
+ uint8_t *pb = NULL;
+ uint8_t *pf = NULL;
+ uint8_t *pv = NULL;
+ uint8_t flags = 0;
+ for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
+ bidx = iColumn - 1;
+ pTColumn = &pTSchema->columns[iColumn];
+
+ if (iColVal < nColVal) {
+ pColVal = (SColVal *)taosArrayGet(pArray, iColVal);
+ } else {
+ pColVal = NULL;
+ }
+
+ if (pColVal) {
+ if (pColVal->cid == pTColumn->colId) {
+ iColVal++;
+ if (pColVal->isNone) {
+ goto _set_none;
+ } else if (pColVal->isNull) {
+ goto _set_null;
+ } else {
+ goto _set_value;
+ }
+ } else if (pColVal->cid > pTColumn->colId) {
+ goto _set_none;
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ goto _set_none;
+ }
- n += tGetI64(p + n, pRow ? &pRow->ts : NULL);
- n += tGetI8(p + n, pRow ? &pRow->flags : &flags);
- n += tGetI32v(p + n, pRow ? &pRow->sver : NULL);
+ _set_none:
+ flags |= TSROW_HAS_NONE;
+ // SET_BIT2(pb, bidx, 0); (todo)
+ continue;
- if (pRow) flags = pRow->flags;
+ _set_null:
+ flags != TSROW_HAS_NULL;
+ // SET_BIT2(pb, bidx, 1); (todo)
+ continue;
+
+ _set_value:
+ flags != TSROW_HAS_VAL;
+ // SET_BIT2(pb, bidx, 2); (todo)
+ if (IS_VAR_DATA_TYPE(pTColumn->type)) {
+ // nv += tPutColVal(pv ? pv + nv : pv, pColVal, pTColumn->type, 1);
+ } else {
+ // tPutColVal(pf ? pf + pTColumn->offset : pf, pColVal, pTColumn->type, 1);
+ }
+ continue;
+ }
+
+ ASSERT(flags);
switch (flags & 0xf) {
case TSROW_HAS_NONE:
case TSROW_HAS_NULL:
+ pRow->nData = 0;
+ break;
+ case TSROW_HAS_VAL:
+ pRow->nData = pTSchema->flen + nv;
+ break;
+ case TSROW_HAS_NULL | TSROW_HAS_NONE:
+ pRow->nData = BIT1_SIZE(pTSchema->numOfCols - 1);
+ break;
+ case TSROW_HAS_VAL | TSROW_HAS_NONE:
+ case TSROW_HAS_VAL | TSROW_HAS_NULL:
+ pRow->nData = BIT1_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + nv;
+ break;
+ case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
+ pRow->nData = BIT2_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + nv;
break;
default:
- n += tGetBinary(p + n, pRow ? &pRow->pData : NULL, pRow ? &pRow->nData : NULL);
break;
}
+}
- return n;
+static void tMapTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow2 *pRow) {
+ int32_t nColVal = taosArrayGetSize(pArray);
+ STColumn *pTColumn;
+ SColVal *pColVal;
+
+ ASSERT(nColVal > 0);
+
+ pRow->sver = pTSchema->version;
+
+ // ts
+ pTColumn = &pTSchema->columns[0];
+ pColVal = (SColVal *)taosArrayGet(pArray, 0);
+
+ ASSERT(pTColumn->colId == 0 && pColVal->cid == 0);
+ ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP);
+
+ pRow->ts = pColVal->value.ts;
+
+ // other fields
+ int32_t iColVal = 1;
+ uint32_t nv = 0;
+ uint8_t *pv = NULL;
+ uint8_t *pidx = NULL;
+ uint8_t flags = 0;
+ int16_t nCol = 0;
+ for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
+ pTColumn = &pTSchema->columns[iColumn];
+
+ if (iColVal < nColVal) {
+ pColVal = (SColVal *)taosArrayGet(pArray, iColVal);
+ } else {
+ pColVal = NULL;
+ }
+
+ if (pColVal) {
+ if (pColVal->cid == pTColumn->colId) {
+ iColVal++;
+ if (pColVal->isNone) {
+ goto _set_none;
+ } else if (pColVal->isNull) {
+ goto _set_null;
+ } else {
+ goto _set_value;
+ }
+ } else if (pColVal->cid > pTColumn->colId) {
+ goto _set_none;
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ goto _set_none;
+ }
+
+ _set_none:
+ flags |= TSROW_HAS_NONE;
+ continue;
+
+ _set_null:
+ flags != TSROW_HAS_NULL;
+ pidx[nCol++] = nv;
+ // nv += tPutColVal(pv ? pv + nv : pv, pColVal, pTColumn->type, 0);
+ continue;
+
+ _set_value:
+ flags != TSROW_HAS_VAL;
+ pidx[nCol++] = nv;
+ // nv += tPutColVal(pv ? pv + nv : pv, pColVal, pTColumn->type, 0);
+ continue;
+ }
+
+ if (nv <= UINT8_MAX) {
+ // small
+ } else if (nv <= UINT16_MAX) {
+ // mid
+ } else {
+ // large
+ }
+}
+
+// try-decide-build
+int32_t tTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow2 **ppRow) {
+ int32_t code = 0;
+ STSRow2 rowT = {0};
+ STSRow2 rowM = {0};
+
+ // try
+ tTupleTSRowNew(pArray, pTSchema, &rowT);
+ tMapTSRowNew(pArray, pTSchema, &rowM);
+
+ // decide & build
+ if (rowT.nData <= rowM.nData) {
+ tTupleTSRowNew(pArray, pTSchema, &rowT);
+ } else {
+ tMapTSRowNew(pArray, pTSchema, &rowM);
+ }
+
+ return code;
}
-int32_t tTSRowDup(const STSRow2 *pRow, STSRow2 **ppRow) {
- (*ppRow) = taosMemoryMalloc(sizeof(*pRow) + pRow->nData);
+int32_t tTSRowClone(const STSRow2 *pRow, STSRow2 **ppRow) {
+ int32_t code = 0;
+
+ (*ppRow) = (STSRow2 *)taosMemoryMalloc(sizeof(**ppRow));
if (*ppRow == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
}
+ **ppRow = *pRow;
+ (*ppRow)->pData = NULL;
- (*ppRow)->ts = pRow->ts;
- (*ppRow)->flags = pRow->flags;
- (*ppRow)->sver = pRow->sver;
- (*ppRow)->nData = pRow->nData;
if (pRow->nData) {
- (*ppRow)->pData = (uint8_t *)(&(*ppRow)[1]);
+ (*ppRow)->pData = taosMemoryMalloc(pRow->nData);
+ if ((*ppRow)->pData == NULL) {
+ taosMemoryFree(*ppRow);
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
memcpy((*ppRow)->pData, pRow->pData, pRow->nData);
- } else {
- (*ppRow)->pData = NULL;
}
- return 0;
+_exit:
+ return code;
}
void tTSRowFree(STSRow2 *pRow) {
- if (pRow) taosMemoryFree(pRow);
+ if (pRow) {
+ if (pRow->pData) taosMemoryFree(pRow->pData);
+ taosMemoryFree(pRow);
+ }
}
-int32_t tTSRowGet(const STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
- uint32_t n;
- uint8_t *p;
- uint8_t v;
- int32_t bidx = iCol - 1;
+void tTSRowGet(STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
+ uint8_t isTuple = (pRow->flags & 0xf0 == 0) ? 1 : 0;
STColumn *pTColumn = &pTSchema->columns[iCol];
- STSKVRow *pTSKVRow;
- SKVIdx *pKVIdx;
+ uint8_t flags = pRow->flags & (uint8_t)0xf;
+ SValue value;
- ASSERT(iCol != 0);
- ASSERT(pTColumn->colId != 0);
+ ASSERT(iCol < pTSchema->numOfCols);
+ ASSERT(flags);
+ ASSERT(pRow->sver == pTSchema->version);
- ASSERT(pRow->flags & 0xf != 0);
- switch (pRow->flags & 0xf) {
- case TSROW_HAS_NONE:
- *pColVal = ColValNONE;
- return 0;
- case TSROW_HAS_NULL:
- *pColVal = ColValNULL;
- return 0;
+ if (iCol == 0) {
+ value.ts = pRow->ts;
+ goto _return_value;
}
- if (TSROW_IS_KV_ROW(pRow)) {
- ASSERT((pRow->flags & 0xf) != TSROW_HAS_VAL);
+ if (flags == TSROW_HAS_NONE) {
+ goto _return_none;
+ } else if (flags == TSROW_HAS_NONE) {
+ goto _return_null;
+ }
- pTSKVRow = (STSKVRow *)pRow->pData;
- pKVIdx =
- bsearch(&((SKVIdx){.cid = pTColumn->colId}), pTSKVRow->idx, pTSKVRow->nCols, sizeof(SKVIdx), tSKVIdxCmprFn);
- if (pKVIdx == NULL) {
- *pColVal = ColValNONE;
- } else if (pKVIdx->offset < 0) {
- *pColVal = ColValNULL;
- } else {
- p = pRow->pData + sizeof(STSKVRow) + sizeof(SKVIdx) * pTSKVRow->nCols + pKVIdx->offset;
- pColVal->type = COL_VAL_DATA;
- tGetBinary(p, &pColVal->pData, &pColVal->nData);
- }
- } else {
- // get bitmap
- p = pRow->pData;
- switch (pRow->flags & 0xf) {
+ ASSERT(pRow->nData && pRow->pData);
+
+ if (isTuple) {
+ uint8_t *pb = pRow->pData;
+ uint8_t *pf = NULL;
+ uint8_t *pv = NULL;
+ uint8_t *p;
+ uint8_t b;
+
+ // bit
+ switch (flags) {
+ case TSROW_HAS_VAL:
+ pf = pb;
+ break;
case TSROW_HAS_NULL | TSROW_HAS_NONE:
- v = GET_BIT1(p, bidx);
- if (v == 0) {
- *pColVal = ColValNONE;
+ b = GET_BIT1(pb, iCol - 1);
+ if (b == 0) {
+ goto _return_none;
} else {
- *pColVal = ColValNULL;
+ goto _return_null;
}
- return 0;
case TSROW_HAS_VAL | TSROW_HAS_NONE:
- v = GET_BIT1(p, bidx);
- if (v == 1) {
- p = p + BIT1_SIZE(pTSchema->numOfCols - 1);
- break;
+ b = GET_BIT1(pb, iCol - 1);
+ if (b == 0) {
+ goto _return_none;
} else {
- *pColVal = ColValNONE;
- return 0;
+ pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
+ break;
}
case TSROW_HAS_VAL | TSROW_HAS_NULL:
- v = GET_BIT1(p, bidx);
- if (v == 1) {
- p = p + BIT1_SIZE(pTSchema->numOfCols - 1);
- break;
+ b = GET_BIT1(pb, iCol - 1);
+ if (b == 0) {
+ goto _return_null;
} else {
- *pColVal = ColValNULL;
- return 0;
+ pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1);
+ break;
}
case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
- v = GET_BIT2(p, bidx);
- if (v == 0) {
- *pColVal = ColValNONE;
- return 0;
- } else if (v == 1) {
- *pColVal = ColValNULL;
- return 0;
- } else if (v == 2) {
- p = p + BIT2_SIZE(pTSchema->numOfCols - 1);
- break;
+ b = GET_BIT2(pb, iCol - 1);
+ if (b == 0) {
+ goto _return_none;
+ } else if (b == 1) {
+ goto _return_null;
} else {
- ASSERT(0);
+ pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1);
+ break;
}
default:
- break;
+ ASSERT(0);
}
- // get real value
- p = p + pTColumn->offset;
- pColVal->type = COL_VAL_DATA;
+ ASSERT(pf);
+
+ p = pf + pTColumn->offset;
if (IS_VAR_DATA_TYPE(pTColumn->type)) {
- tGetBinary(p + pTSchema->flen + *(int32_t *)p, &pColVal->pData, &pColVal->nData);
+ pv = pf + pTSchema->flen;
+ p = pv + *(VarDataOffsetT *)p;
+ }
+ tGetValue(p, &value, pTColumn->type);
+ goto _return_value;
+ } else {
+ STSKVRow *pRowK = (STSKVRow *)pRow->pData;
+ int16_t lidx = 0;
+ int16_t ridx = pRowK->nCols - 1;
+ uint8_t *p;
+ int16_t midx;
+ uint32_t n;
+ int16_t cid;
+
+ ASSERT(pRowK->nCols > 0);
+
+ if (pRow->flags & TSROW_KV_SMALL) {
+ p = pRow->pData + sizeof(STSKVRow) + sizeof(uint8_t) * pRowK->nCols;
+ } else if (pRow->flags & TSROW_KV_MID) {
+ p = pRow->pData + sizeof(STSKVRow) + sizeof(uint16_t) * pRowK->nCols;
+ } else if (pRow->flags & TSROW_KV_BIG) {
+ p = pRow->pData + sizeof(STSKVRow) + sizeof(uint32_t) * pRowK->nCols;
} else {
- pColVal->pData = p;
- pColVal->nData = pTColumn->bytes;
+ ASSERT(0);
+ }
+ while (lidx <= ridx) {
+ midx = (lidx + ridx) / 2;
+
+ if (pRow->flags & TSROW_KV_SMALL) {
+ n = ((uint8_t *)pRowK->idx)[midx];
+ } else if (pRow->flags & TSROW_KV_MID) {
+ n = ((uint16_t *)pRowK->idx)[midx];
+ } else {
+ n = ((uint32_t *)pRowK->idx)[midx];
+ }
+
+ n += tGetI16v(p + n, &cid);
+
+ if (TABS(cid) == pTColumn->colId) {
+ if (cid < 0) {
+ goto _return_null;
+ } else {
+ n += tGetValue(p + n, &value, pTColumn->type);
+ goto _return_value;
+ }
+
+ return;
+ } else if (TABS(cid) > pTColumn->colId) {
+ ridx = midx - 1;
+ } else {
+ lidx = midx + 1;
+ }
}
+
+ // not found, return NONE
+ goto _return_none;
}
- return 0;
+_return_none:
+ *pColVal = COL_VAL_NONE(pTColumn->colId);
+ return;
+
+_return_null:
+ *pColVal = COL_VAL_NULL(pTColumn->colId);
+ return;
+
+_return_value:
+ *pColVal = COL_VAL_VALUE(pTColumn->colId, value);
+ return;
+}
+
+int32_t tTSRowToArray(STSRow2 *pRow, STSchema *pTSchema, SArray **ppArray) {
+ int32_t code = 0;
+ SColVal cv;
+
+ (*ppArray) = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal));
+ if (*ppArray == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _exit;
+ }
+
+ for (int32_t iColumn = 0; iColumn < pTSchema->numOfCols; iColumn++) {
+ tTSRowGet(pRow, pTSchema, iColumn, &cv);
+ taosArrayPush(*ppArray, &cv);
+ }
+
+_exit:
+ return code;
+}
+
+int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow) {
+ int32_t n = 0;
+
+ n += tPutI64(p ? p + n : p, pRow->ts);
+ n += tPutI8(p ? p + n : p, pRow->flags);
+ n += tPutI32v(p ? p + n : p, pRow->sver);
+
+ ASSERT(pRow->flags & 0xf);
+
+ switch (pRow->flags & 0xf) {
+ case TSROW_HAS_NONE:
+ case TSROW_HAS_NULL:
+ ASSERT(pRow->nData == 0);
+ ASSERT(pRow->pData == NULL);
+ break;
+ default:
+ ASSERT(pRow->nData && pRow->pData);
+ n += tPutBinary(p ? p + n : p, pRow->pData, pRow->nData);
+ break;
+ }
+
+ return n;
+}
+
+int32_t tGetTSRow(uint8_t *p, STSRow2 *pRow) {
+ int32_t n = 0;
+
+ n += tGetI64(p + n, &pRow->ts);
+ n += tGetI8(p + n, &pRow->flags);
+ n += tGetI32v(p + n, &pRow->sver);
+
+ ASSERT(pRow->flags);
+ switch (pRow->flags & 0xf) {
+ case TSROW_HAS_NONE:
+ case TSROW_HAS_NULL:
+ pRow->nData = 0;
+ pRow->pData = NULL;
+ break;
+ default:
+ n += tGetBinary(p + n, &pRow->pData, &pRow->nData);
+ break;
+ }
+
+ return n;
}
// STSchema
@@ -262,6 +626,7 @@ void tTSchemaDestroy(STSchema *pTSchema) {
}
// STSRowBuilder
+#if 0
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, int32_t nCols, SSchema *pSchema) {
if (tTSchemaCreate(sver, pSchema, nCols, &pBuilder->pTSchema) < 0) return -1;
@@ -443,7 +808,6 @@ static void setBitMap(uint8_t *p, STSchema *pTSchema, uint8_t flags) {
}
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
int32_t nDataTP, nDataKV;
- uint32_t flags;
STSKVRow *pTSKVRow = (STSKVRow *)pBuilder->pKVBuf;
int32_t nCols = pBuilder->pTSchema->numOfCols;
@@ -457,7 +821,7 @@ int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
pBuilder->row.flags |= TSROW_HAS_NONE;
}
- ASSERT(pBuilder->row.flags & 0xf != 0);
+ ASSERT((pBuilder->row.flags & 0xf) != 0);
*(ppRow) = &pBuilder->row;
switch (pBuilder->row.flags & 0xf) {
case TSROW_HAS_NONE:
@@ -487,7 +851,7 @@ int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
if (nDataKV < nDataTP) {
// generate KV row
- ASSERT(pBuilder->row.flags & 0xf != TSROW_HAS_VAL);
+ ASSERT((pBuilder->row.flags & 0xf) != TSROW_HAS_VAL);
pBuilder->row.flags |= TSROW_KV_ROW;
pBuilder->row.nData = nDataKV;
@@ -503,12 +867,12 @@ int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
pBuilder->row.nData = nDataTP;
uint8_t *p;
- uint8_t flags = pBuilder->row.flags & 0xf;
+ uint8_t flags = (pBuilder->row.flags & 0xf);
if (flags == TSROW_HAS_VAL) {
pBuilder->row.pData = pBuilder->pTPBuf + pBuilder->szBitMap2;
} else {
- if (flags == TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE) {
+ if (flags == (TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE)) {
pBuilder->row.pData = pBuilder->pTPBuf;
} else {
pBuilder->row.pData = pBuilder->pTPBuf + pBuilder->szBitMap2 - pBuilder->szBitMap1;
@@ -520,133 +884,375 @@ int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
return 0;
}
+#endif
-static FORCE_INLINE int tTagIdxCmprFn(const void *p1, const void *p2) {
- STagIdx *pTagIdx1 = (STagIdx *)p1;
- STagIdx *pTagIdx2 = (STagIdx *)p2;
- if (pTagIdx1->cid < pTagIdx1->cid) {
+static int tTagValCmprFn(const void *p1, const void *p2) {
+ if (((STagVal *)p1)->cid < ((STagVal *)p2)->cid) {
return -1;
- } else if (pTagIdx1->cid > pTagIdx1->cid) {
+ } else if (((STagVal *)p1)->cid > ((STagVal *)p2)->cid) {
return 1;
}
+
return 0;
}
-int32_t tTagNew(STagVal *pTagVals, int16_t nTag, STag **ppTag) {
- STagVal *pTagVal;
- uint8_t *p;
- int32_t n;
- uint16_t tsize = sizeof(STag) + sizeof(STagIdx) * nTag;
+static int tTagValJsonCmprFn(const void *p1, const void *p2) {
+ return strcmp(((STagVal *)p1)[0].pKey, ((STagVal *)p2)[0].pKey);
+}
- for (int16_t iTag = 0; iTag < nTag; iTag++) {
- pTagVal = &pTagVals[iTag];
+static void debugPrintTagVal(int8_t type, const void *val, int32_t vlen, const char *tag, int32_t ln) {
+ switch (type) {
+ case TSDB_DATA_TYPE_JSON:
+ case TSDB_DATA_TYPE_VARCHAR:
+ case TSDB_DATA_TYPE_NCHAR: {
+ char tmpVal[32] = {0};
+ strncpy(tmpVal, val, vlen > 31 ? 31 : vlen);
+ printf("%s:%d type:%d vlen:%d, val:\"%s\"\n", tag, ln, (int32_t)type, vlen, tmpVal);
+ } break;
+ case TSDB_DATA_TYPE_FLOAT:
+ printf("%s:%d type:%d vlen:%d, val:%f\n", tag, ln, (int32_t)type, vlen, *(float *)val);
+ break;
+ case TSDB_DATA_TYPE_DOUBLE:
+ printf("%s:%d type:%d vlen:%d, val:%lf\n", tag, ln, (int32_t)type, vlen, *(double *)val);
+ break;
+ case TSDB_DATA_TYPE_BOOL:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
+ break;
+ case TSDB_DATA_TYPE_TINYINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
+ break;
+ case TSDB_DATA_TYPE_SMALLINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi16 "\n", tag, ln, (int32_t)type, vlen, *(int16_t *)val);
+ break;
+ case TSDB_DATA_TYPE_INT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi32 "\n", tag, ln, (int32_t)type, vlen, *(int32_t *)val);
+ break;
+ case TSDB_DATA_TYPE_BIGINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
+ break;
+ case TSDB_DATA_TYPE_TIMESTAMP:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi64 "\n", tag, ln, (int32_t)type, vlen, *(int64_t *)val);
+ break;
+ case TSDB_DATA_TYPE_UTINYINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIu8 "\n", tag, ln, (int32_t)type, vlen, *(uint8_t *)val);
+ break;
+ case TSDB_DATA_TYPE_USMALLINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIu16 "\n", tag, ln, (int32_t)type, vlen, *(uint16_t *)val);
+ break;
+ case TSDB_DATA_TYPE_UINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIu32 "\n", tag, ln, (int32_t)type, vlen, *(uint32_t *)val);
+ break;
+ case TSDB_DATA_TYPE_UBIGINT:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIu64 "\n", tag, ln, (int32_t)type, vlen, *(uint64_t *)val);
+ break;
+ case TSDB_DATA_TYPE_NULL:
+ printf("%s:%d type:%d vlen:%d, val:%" PRIi8 "\n", tag, ln, (int32_t)type, vlen, *(int8_t *)val);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
- if (IS_VAR_DATA_TYPE(pTagVal->type)) {
- tsize += tPutBinary(NULL, pTagVal->pData, pTagVal->nData);
+// if (isLarge) {
+// p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
+// } else {
+// p = (uint8_t *)&pTag->idx[pTag->nTag];
+// }
+
+// (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
+// if (*ppArray == NULL) {
+// code = TSDB_CODE_OUT_OF_MEMORY;
+// goto _err;
+// }
+
+// for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
+// if (isLarge) {
+// offset = ((int16_t *)pTag->idx)[iTag];
+// } else {
+// offset = pTag->idx[iTag];
+// }
+
+void debugPrintSTag(STag *pTag, const char *tag, int32_t ln) {
+ int8_t isJson = pTag->flags & TD_TAG_JSON;
+ int8_t isLarge = pTag->flags & TD_TAG_LARGE;
+ uint8_t *p = NULL;
+ int16_t offset = 0;
+
+ if (isLarge) {
+ p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
+ } else {
+ p = (uint8_t *)&pTag->idx[pTag->nTag];
+ }
+ printf("%s:%d >>> STAG === %s:%s, len: %d, nTag: %d, sver:%d\n", tag, ln, isJson ? "json" : "normal",
+ isLarge ? "large" : "small", (int32_t)pTag->len, (int32_t)pTag->nTag, pTag->ver);
+ for (uint16_t n = 0; n < pTag->nTag; ++n) {
+ if (isLarge) {
+ offset = ((int16_t *)pTag->idx)[n];
+ } else {
+ offset = pTag->idx[n];
+ }
+ STagVal tagVal = {0};
+ if (isJson) {
+ tagVal.pKey = (char *)POINTER_SHIFT(p, offset);
+ } else {
+ tagVal.cid = *(int16_t *)POINTER_SHIFT(p, offset);
+ }
+ printf("%s:%d loop[%d-%d] offset=%d\n", __func__, __LINE__, (int32_t)pTag->nTag, (int32_t)n, (int32_t)offset);
+ tGetTagVal(p + offset, &tagVal, isJson);
+ if (IS_VAR_DATA_TYPE(tagVal.type)) {
+ debugPrintTagVal(tagVal.type, tagVal.pData, tagVal.nData, __func__, __LINE__);
} else {
- ASSERT(pTagVal->nData == TYPE_BYTES[pTagVal->type]);
- tsize += pTagVal->nData;
+ debugPrintTagVal(tagVal.type, &tagVal.i64, tDataTypes[tagVal.type].bytes, __func__, __LINE__);
}
}
+ printf("\n");
+}
- (*ppTag) = (STag *)taosMemoryMalloc(tsize);
- if (*ppTag == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
+void debugCheckTags(STag *pTag) {
+ switch (pTag->flags) {
+ case 0x0:
+ case 0x20:
+ case 0x40:
+ case 0x60:
+ break;
+ default:
+ ASSERT(0);
}
- p = (uint8_t *)&((*ppTag)->idx[nTag]);
- n = 0;
+ ASSERT(pTag->nTag <= 128 && pTag->nTag >= 0);
+ ASSERT(pTag->ver <= 512 && pTag->ver >= 0); // temp condition for pTag->ver
+}
- (*ppTag)->len = tsize;
- (*ppTag)->nTag = nTag;
- for (int16_t iTag = 0; iTag < nTag; iTag++) {
- pTagVal = &pTagVals[iTag];
+static int32_t tPutTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
+ int32_t n = 0;
- (*ppTag)->idx[iTag].cid = pTagVal->cid;
- (*ppTag)->idx[iTag].offset = n;
+ // key
+ if (isJson) {
+ n += tPutCStr(p ? p + n : p, pTagVal->pKey);
+ } else {
+ n += tPutI16v(p ? p + n : p, pTagVal->cid);
+ }
- if (IS_VAR_DATA_TYPE(pTagVal->type)) {
- n += tPutBinary(p + n, pTagVal->pData, pTagVal->nData);
- } else {
- memcpy(p + n, pTagVal->pData, pTagVal->nData);
- n += pTagVal->nData;
- }
+ // type
+ n += tPutI8(p ? p + n : p, pTagVal->type);
+
+ // value
+ if (IS_VAR_DATA_TYPE(pTagVal->type)) {
+ n += tPutBinary(p ? p + n : p, pTagVal->pData, pTagVal->nData);
+ } else {
+ p = p ? p + n : p;
+ n += tDataTypes[pTagVal->type].bytes;
+ if (p) memcpy(p, &(pTagVal->i64), tDataTypes[pTagVal->type].bytes);
}
- qsort((*ppTag)->idx, (*ppTag)->nTag, sizeof(STagIdx), tTagIdxCmprFn);
- return 0;
+ return n;
}
+static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson) {
+ int32_t n = 0;
-void tTagFree(STag *pTag) {
- if (pTag) taosMemoryFree(pTag);
-}
+ // key
+ if (isJson) {
+ n += tGetCStr(p + n, &pTagVal->pKey);
+ } else {
+ n += tGetI16v(p + n, &pTagVal->cid);
+ }
-int32_t tTagSet(STag *pTag, SSchema *pSchema, int32_t nCols, int iCol, uint8_t *pData, uint32_t nData, STag **ppTag) {
- STagVal *pTagVals;
- int16_t nTags = 0;
- SSchema *pColumn;
- uint8_t *p;
- uint32_t n;
+ // type
+ n += tGetI8(p + n, &pTagVal->type);
- pTagVals = (STagVal *)taosMemoryMalloc(sizeof(*pTagVals) * nCols);
- if (pTagVals == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
+ // value
+ if (IS_VAR_DATA_TYPE(pTagVal->type)) {
+ n += tGetBinary(p + n, &pTagVal->pData, &pTagVal->nData);
+ } else {
+ memcpy(&(pTagVal->i64), p + n, tDataTypes[pTagVal->type].bytes);
+ n += tDataTypes[pTagVal->type].bytes;
}
- for (int32_t i = 0; i < nCols; i++) {
- pColumn = &pSchema[i];
+ return n;
+}
+int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) {
+ int32_t code = 0;
+ uint8_t *p = NULL;
+ int16_t n = 0;
+ int16_t nTag = taosArrayGetSize(pArray);
+ int32_t szTag = 0;
+ int8_t isLarge = 0;
+
+ // sort
+ if (isJson) {
+ qsort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn);
+ } else {
+ qsort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn);
+ }
+
+ // get size
+ for (int16_t iTag = 0; iTag < nTag; iTag++) {
+ szTag += tPutTagVal(NULL, (STagVal *)taosArrayGet(pArray, iTag), isJson);
+ }
+ if (szTag <= INT8_MAX) {
+ szTag = szTag + sizeof(STag) + sizeof(int8_t) * nTag;
+ } else {
+ szTag = szTag + sizeof(STag) + sizeof(int16_t) * nTag;
+ isLarge = 1;
+ }
+
+ ASSERT(szTag <= INT16_MAX);
+
+ // build tag
+ (*ppTag) = (STag *)taosMemoryCalloc(szTag, 1);
+ if ((*ppTag) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ (*ppTag)->flags = 0;
+ if (isJson) {
+ (*ppTag)->flags |= TD_TAG_JSON;
+ }
+ if (isLarge) {
+ (*ppTag)->flags |= TD_TAG_LARGE;
+ }
+ (*ppTag)->len = szTag;
+ (*ppTag)->nTag = nTag;
+ (*ppTag)->ver = version;
- if (i == iCol) {
- p = pData;
- n = nData;
+ if (isLarge) {
+ p = (uint8_t *)&((int16_t *)(*ppTag)->idx)[nTag];
+ } else {
+ p = (uint8_t *)&(*ppTag)->idx[nTag];
+ }
+ n = 0;
+ for (int16_t iTag = 0; iTag < nTag; iTag++) {
+ if (isLarge) {
+ ((int16_t *)(*ppTag)->idx)[iTag] = n;
} else {
- tTagGet(pTag, pColumn->colId, pColumn->type, &p, &n);
+ (*ppTag)->idx[iTag] = n;
}
+ n += tPutTagVal(p + n, (STagVal *)taosArrayGet(pArray, iTag), isJson);
+ }
+#ifdef TD_DEBUG_PRINT_TAG
+ debugPrintSTag(*ppTag, __func__, __LINE__);
+#endif
- if (p == NULL) continue;
+ debugCheckTags(*ppTag); // TODO: remove this line after debug
+ return code;
- ASSERT(IS_VAR_DATA_TYPE(pColumn->type) || n == pColumn->bytes);
+_err:
+ return code;
+}
- pTagVals[nTags].cid = pColumn->colId;
- pTagVals[nTags].type = pColumn->type;
- pTagVals[nTags].nData = n;
- pTagVals[nTags].pData = p;
+void tTagFree(STag *pTag) {
+ if (pTag) taosMemoryFree(pTag);
+}
- nTags++;
+char *tTagValToData(const STagVal *value, bool isJson) {
+ if (!value) return NULL;
+ char *data = NULL;
+ int8_t typeBytes = 0;
+ if (isJson) {
+ typeBytes = CHAR_BYTES;
}
-
- // create new tag
- if (tTagNew(pTagVals, nTags, ppTag) < 0) {
- taosMemoryFree(pTagVals);
- return -1;
+ if (IS_VAR_DATA_TYPE(value->type)) {
+ data = taosMemoryCalloc(1, typeBytes + VARSTR_HEADER_SIZE + value->nData);
+ if (data == NULL) return NULL;
+ if (isJson) *data = value->type;
+ varDataLen(data + typeBytes) = value->nData;
+ memcpy(varDataVal(data + typeBytes), value->pData, value->nData);
+ } else {
+ data = ((char *)&(value->i64)) - typeBytes; // json with type
}
- taosMemoryFree(pTagVals);
- return 0;
+ return data;
}
-void tTagGet(STag *pTag, int16_t cid, int8_t type, uint8_t **ppData, uint32_t *nData) {
- STagIdx *pTagIdx = bsearch(&((STagIdx){.cid = cid}), pTag->idx, pTag->nTag, sizeof(STagIdx), tTagIdxCmprFn);
- if (pTagIdx == NULL) {
- *ppData = NULL;
- *nData = 0;
+bool tTagGet(const STag *pTag, STagVal *pTagVal) {
+ int16_t lidx = 0;
+ int16_t ridx = pTag->nTag - 1;
+ int16_t midx;
+ uint8_t *p;
+ int8_t isJson = pTag->flags & TD_TAG_JSON;
+ int8_t isLarge = pTag->flags & TD_TAG_LARGE;
+ int16_t offset;
+ STagVal tv;
+ int c;
+
+ if (isLarge) {
+ p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
} else {
- uint8_t *p = (uint8_t *)&pTag->idx[pTag->nTag] + pTagIdx->offset;
- if (IS_VAR_DATA_TYPE(type)) {
- tGetBinary(p, ppData, nData);
+ p = (uint8_t *)&pTag->idx[pTag->nTag];
+ }
+
+ pTagVal->type = TSDB_DATA_TYPE_NULL;
+ pTagVal->pData = NULL;
+ pTagVal->nData = 0;
+ while (lidx <= ridx) {
+ midx = (lidx + ridx) / 2;
+ if (isLarge) {
+ offset = ((int16_t *)pTag->idx)[midx];
+ } else {
+ offset = pTag->idx[midx];
+ }
+
+ tGetTagVal(p + offset, &tv, isJson);
+ if (isJson) {
+ c = tTagValJsonCmprFn(pTagVal, &tv);
+ } else {
+ c = tTagValCmprFn(pTagVal, &tv);
+ }
+
+ if (c < 0) {
+ ridx = midx - 1;
+ } else if (c > 0) {
+ lidx = midx + 1;
} else {
- *ppData = p;
- *nData = TYPE_BYTES[type];
+ memcpy(pTagVal, &tv, sizeof(tv));
+ return true;
}
}
+ return false;
}
int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag) {
return tEncodeBinary(pEncoder, (const uint8_t *)pTag, pTag->len);
}
-int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) { return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL); }
+int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag) {
+ return tDecodeBinary(pDecoder, (uint8_t **)ppTag, NULL);
+}
+
+int32_t tTagToValArray(const STag *pTag, SArray **ppArray) {
+ int32_t code = 0;
+ uint8_t *p = NULL;
+ STagVal tv = {0};
+ int8_t isLarge = pTag->flags & TD_TAG_LARGE;
+ int16_t offset = 0;
+
+ if (isLarge) {
+ p = (uint8_t *)&((int16_t *)pTag->idx)[pTag->nTag];
+ } else {
+ p = (uint8_t *)&pTag->idx[pTag->nTag];
+ }
+
+ (*ppArray) = taosArrayInit(pTag->nTag + 1, sizeof(STagVal));
+ if (*ppArray == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ for (int16_t iTag = 0; iTag < pTag->nTag; iTag++) {
+ if (isLarge) {
+ offset = ((int16_t *)pTag->idx)[iTag];
+ } else {
+ offset = pTag->idx[iTag];
+ }
+ tGetTagVal(p + offset, &tv, pTag->flags & TD_TAG_JSON);
+ taosArrayPush(*ppArray, &tv);
+ }
+
+ return code;
+
+_err:
+ return code;
+}
#if 1 // ===================================================================================================================
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
@@ -974,162 +1580,4 @@ void tdResetDataCols(SDataCols *pCols) {
}
}
-SKVRow tdKVRowDup(SKVRow row) {
- SKVRow trow = taosMemoryMalloc(kvRowLen(row));
- if (trow == NULL) return NULL;
-
- kvRowCpy(trow, row);
- return trow;
-}
-
-static int compareColIdx(const void *a, const void *b) {
- const SColIdx *x = (const SColIdx *)a;
- const SColIdx *y = (const SColIdx *)b;
- if (x->colId > y->colId) {
- return 1;
- }
- if (x->colId < y->colId) {
- return -1;
- }
- return 0;
-}
-
-void tdSortKVRowByColIdx(SKVRow row) { qsort(kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), compareColIdx); }
-
-int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
- SColIdx *pColIdx = NULL;
- SKVRow row = *orow;
- SKVRow nrow = NULL;
- void *ptr = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_GE);
-
- if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) { // need to add a column value to the row
- int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
- int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
- int oRowCols = kvRowNCols(row);
-
- ASSERT(diff > 0);
- nrow = taosMemoryMalloc(nRowLen);
- if (nrow == NULL) return -1;
-
- kvRowSetLen(nrow, nRowLen);
- kvRowSetNCols(nrow, oRowCols + 1);
-
- memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
- memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
-
- pColIdx = kvRowColIdxAt(nrow, oRowCols);
- pColIdx->colId = colId;
- pColIdx->offset = kvRowValLen(row);
-
- memcpy(kvRowColVal(nrow, pColIdx), value, diff); // copy new value
-
- tdSortKVRowByColIdx(nrow);
-
- *orow = nrow;
- taosMemoryFree(row);
- } else {
- ASSERT(((SColIdx *)ptr)->colId == colId);
- if (IS_VAR_DATA_TYPE(type)) {
- void *pOldVal = kvRowColVal(row, (SColIdx *)ptr);
-
- if (varDataTLen(value) == varDataTLen(pOldVal)) { // just update the column value in place
- memcpy(pOldVal, value, varDataTLen(value));
- } else { // need to reallocate the memory
- int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
- ASSERT(nlen > 0);
- nrow = taosMemoryMalloc(nlen);
- if (nrow == NULL) return -1;
-
- kvRowSetLen(nrow, nlen);
- kvRowSetNCols(nrow, kvRowNCols(row));
-
- int zsize = sizeof(SColIdx) * kvRowNCols(row) + ((SColIdx *)ptr)->offset;
- memcpy(kvRowColIdx(nrow), kvRowColIdx(row), zsize);
- memcpy(kvRowColVal(nrow, ((SColIdx *)ptr)), value, varDataTLen(value));
- // Copy left value part
- int lsize = kvRowLen(row) - TD_KV_ROW_HEAD_SIZE - zsize - varDataTLen(pOldVal);
- if (lsize > 0) {
- memcpy(POINTER_SHIFT(nrow, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(value)),
- POINTER_SHIFT(row, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(pOldVal)), lsize);
- }
-
- for (int i = 0; i < kvRowNCols(nrow); i++) {
- pColIdx = kvRowColIdxAt(nrow, i);
-
- if (pColIdx->offset > ((SColIdx *)ptr)->offset) {
- pColIdx->offset = pColIdx->offset - varDataTLen(pOldVal) + varDataTLen(value);
- }
- }
-
- *orow = nrow;
- taosMemoryFree(row);
- }
- } else {
- memcpy(kvRowColVal(row, (SColIdx *)ptr), value, TYPE_BYTES[type]);
- }
- }
-
- return 0;
-}
-
-int tdEncodeKVRow(void **buf, SKVRow row) {
- // May change the encode purpose
- if (buf != NULL) {
- kvRowCpy(*buf, row);
- *buf = POINTER_SHIFT(*buf, kvRowLen(row));
- }
-
- return kvRowLen(row);
-}
-
-void *tdDecodeKVRow(void *buf, SKVRow *row) {
- *row = tdKVRowDup(buf);
- if (*row == NULL) return NULL;
- return POINTER_SHIFT(buf, kvRowLen(*row));
-}
-
-int tdInitKVRowBuilder(SKVRowBuilder *pBuilder) {
- pBuilder->tCols = 128;
- pBuilder->nCols = 0;
- pBuilder->pColIdx = (SColIdx *)taosMemoryMalloc(sizeof(SColIdx) * pBuilder->tCols);
- if (pBuilder->pColIdx == NULL) return -1;
- pBuilder->alloc = 1024;
- pBuilder->size = 0;
- pBuilder->buf = taosMemoryMalloc(pBuilder->alloc);
- if (pBuilder->buf == NULL) {
- taosMemoryFree(pBuilder->pColIdx);
- return -1;
- }
- return 0;
-}
-
-void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder) {
- taosMemoryFreeClear(pBuilder->pColIdx);
- taosMemoryFreeClear(pBuilder->buf);
-}
-
-void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) {
- pBuilder->nCols = 0;
- pBuilder->size = 0;
-}
-
-SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
- int tlen = sizeof(SColIdx) * pBuilder->nCols + pBuilder->size;
- // if (tlen == 0) return NULL; // nCols == 0 means no tags
-
- tlen += TD_KV_ROW_HEAD_SIZE;
-
- SKVRow row = taosMemoryMalloc(tlen);
- if (row == NULL) return NULL;
-
- kvRowSetNCols(row, pBuilder->nCols);
- kvRowSetLen(row, tlen);
-
- if (pBuilder->nCols > 0) {
- memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols);
- memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size);
- }
-
- return row;
-}
#endif
\ No newline at end of file
diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c
index 7615f7b070ca350a27cc7d6a05520386fcaa6759..0f3eec01c6b3df1051e51604256dbf853d247d01 100644
--- a/source/common/src/tmsg.c
+++ b/source/common/src/tmsg.c
@@ -28,7 +28,7 @@
#undef TD_MSG_SEG_CODE_
#include "tmsgdef.h"
-int32_t tInitSubmitMsgIter(SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
+int32_t tInitSubmitMsgIter(const SSubmitReq *pMsg, SSubmitMsgIter *pIter) {
if (pMsg == NULL) {
terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP;
return -1;
@@ -147,12 +147,24 @@ int32_t tEncodeSQueryNodeAddr(SEncoder *pEncoder, SQueryNodeAddr *pAddr) {
return 0;
}
+int32_t tEncodeSQueryNodeLoad(SEncoder *pEncoder, SQueryNodeLoad *pLoad) {
+ if (tEncodeSQueryNodeAddr(pEncoder, &pLoad->addr) < 0) return -1;
+ if (tEncodeU64(pEncoder, pLoad->load) < 0) return -1;
+ return 0;
+}
+
int32_t tDecodeSQueryNodeAddr(SDecoder *pDecoder, SQueryNodeAddr *pAddr) {
if (tDecodeI32(pDecoder, &pAddr->nodeId) < 0) return -1;
if (tDecodeSEpSet(pDecoder, &pAddr->epSet) < 0) return -1;
return 0;
}
+int32_t tDecodeSQueryNodeLoad(SDecoder *pDecoder, SQueryNodeLoad *pLoad) {
+ if (tDecodeSQueryNodeAddr(pDecoder, &pLoad->addr) < 0) return -1;
+ if (tDecodeU64(pDecoder, &pLoad->load) < 0) return -1;
+ return 0;
+}
+
int32_t taosEncodeSEpSet(void **buf, const SEpSet *pEp) {
int32_t tlen = 0;
tlen += taosEncodeFixedI8(buf, pEp->inUse);
@@ -304,6 +316,12 @@ static int32_t tSerializeSClientHbRsp(SEncoder *pEncoder, const SClientHbRsp *pR
if (tEncodeI32(pEncoder, pRsp->query->onlineDnodes) < 0) return -1;
if (tEncodeI8(pEncoder, pRsp->query->killConnection) < 0) return -1;
if (tEncodeSEpSet(pEncoder, &pRsp->query->epSet) < 0) return -1;
+ int32_t num = taosArrayGetSize(pRsp->query->pQnodeList);
+ if (tEncodeI32(pEncoder, num) < 0) return -1;
+ for (int32_t i = 0; i < num; ++i) {
+ SQueryNodeLoad *pLoad = taosArrayGet(pRsp->query->pQnodeList, i);
+ if (tEncodeSQueryNodeLoad(pEncoder, pLoad) < 0) return -1;
+ }
} else {
if (tEncodeI32(pEncoder, queryNum) < 0) return -1;
}
@@ -333,6 +351,15 @@ static int32_t tDeserializeSClientHbRsp(SDecoder *pDecoder, SClientHbRsp *pRsp)
if (tDecodeI32(pDecoder, &pRsp->query->onlineDnodes) < 0) return -1;
if (tDecodeI8(pDecoder, &pRsp->query->killConnection) < 0) return -1;
if (tDecodeSEpSet(pDecoder, &pRsp->query->epSet) < 0) return -1;
+ int32_t pQnodeNum = 0;
+ if (tDecodeI32(pDecoder, &pQnodeNum) < 0) return -1;
+ if (pQnodeNum > 0) {
+ pRsp->query->pQnodeList = taosArrayInit(pQnodeNum, sizeof(SQueryNodeLoad));
+ if (NULL == pRsp->query->pQnodeList) return -1;
+ SQueryNodeLoad load = {0};
+ if (tDecodeSQueryNodeLoad(pDecoder, &load) < 0) return -1;
+ taosArrayPush(pRsp->query->pQnodeList, &load);
+ }
}
int32_t kvNum = 0;
@@ -666,6 +693,7 @@ void tFreeSMAltertbReq(SMAlterStbReq *pReq) {
pReq->pFields = NULL;
}
+
int32_t tSerializeSEpSet(void *buf, int32_t bufLen, const SEpSet *pEpset) {
SEncoder encoder = {0};
tEncoderInit(&encoder, buf, bufLen);
@@ -898,6 +926,18 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
// mnode loads
if (tEncodeI32(&encoder, pReq->mload.syncState) < 0) return -1;
+ if (tEncodeI32(&encoder, pReq->qload.dnodeId) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfProcessedQuery) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfProcessedCQuery) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfProcessedFetch) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfProcessedDrop) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfProcessedHb) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.cacheDataSize) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfQueryInQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.numOfFetchInQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.timeInQueryQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pReq->qload.timeInFetchQueue) < 0) return -1;
+
tEndEncode(&encoder);
int32_t tlen = encoder.pos;
@@ -955,6 +995,18 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
if (tDecodeI32(&decoder, &pReq->mload.syncState) < 0) return -1;
+ if (tDecodeI32(&decoder, &pReq->qload.dnodeId) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfProcessedQuery) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfProcessedCQuery) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfProcessedFetch) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfProcessedDrop) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfProcessedHb) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.cacheDataSize) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfQueryInQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.numOfFetchInQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.timeInQueryQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pReq->qload.timeInFetchQueue) < 0) return -1;
+
tEndDecode(&decoder);
tDecoderClear(&decoder);
return 0;
@@ -1921,11 +1973,11 @@ int32_t tSerializeSQnodeListRsp(void *buf, int32_t bufLen, SQnodeListRsp *pRsp)
tEncoderInit(&encoder, buf, bufLen);
if (tStartEncode(&encoder) < 0) return -1;
- int32_t num = taosArrayGetSize(pRsp->addrsList);
+ int32_t num = taosArrayGetSize(pRsp->qnodeList);
if (tEncodeI32(&encoder, num) < 0) return -1;
for (int32_t i = 0; i < num; ++i) {
- SQueryNodeAddr *addr = taosArrayGet(pRsp->addrsList, i);
- if (tEncodeSQueryNodeAddr(&encoder, addr) < 0) return -1;
+ SQueryNodeLoad *pLoad = taosArrayGet(pRsp->qnodeList, i);
+ if (tEncodeSQueryNodeLoad(&encoder, pLoad) < 0) return -1;
}
tEndEncode(&encoder);
@@ -1941,15 +1993,15 @@ int32_t tDeserializeSQnodeListRsp(void *buf, int32_t bufLen, SQnodeListRsp *pRsp
if (tStartDecode(&decoder) < 0) return -1;
int32_t num = 0;
if (tDecodeI32(&decoder, &num) < 0) return -1;
- if (NULL == pRsp->addrsList) {
- pRsp->addrsList = taosArrayInit(num, sizeof(SQueryNodeAddr));
- if (NULL == pRsp->addrsList) return -1;
+ if (NULL == pRsp->qnodeList) {
+ pRsp->qnodeList = taosArrayInit(num, sizeof(SQueryNodeLoad));
+ if (NULL == pRsp->qnodeList) return -1;
}
for (int32_t i = 0; i < num; ++i) {
- SQueryNodeAddr addr = {0};
- if (tDecodeSQueryNodeAddr(&decoder, &addr) < 0) return -1;
- taosArrayPush(pRsp->addrsList, &addr);
+ SQueryNodeLoad load = {0};
+ if (tDecodeSQueryNodeLoad(&decoder, &load) < 0) return -1;
+ taosArrayPush(pRsp->qnodeList, &load);
}
tEndDecode(&decoder);
@@ -1957,7 +2009,7 @@ int32_t tDeserializeSQnodeListRsp(void *buf, int32_t bufLen, SQnodeListRsp *pRsp
return 0;
}
-void tFreeSQnodeListRsp(SQnodeListRsp *pRsp) { taosArrayDestroy(pRsp->addrsList); }
+void tFreeSQnodeListRsp(SQnodeListRsp *pRsp) { taosArrayDestroy(pRsp->qnodeList); }
int32_t tSerializeSCompactDbReq(void *buf, int32_t bufLen, SCompactDbReq *pReq) {
SEncoder encoder = {0};
@@ -2668,25 +2720,23 @@ int32_t tDeserializeSMDropCgroupReq(void *buf, int32_t bufLen, SMDropCgroupReq *
}
int32_t tSerializeSCMCreateTopicReq(void *buf, int32_t bufLen, const SCMCreateTopicReq *pReq) {
- int32_t sqlLen = 0;
- int32_t astLen = 0;
- if (pReq->sql != NULL) sqlLen = (int32_t)strlen(pReq->sql);
- if (pReq->ast != NULL) astLen = (int32_t)strlen(pReq->ast);
-
SEncoder encoder = {0};
tEncoderInit(&encoder, buf, bufLen);
if (tStartEncode(&encoder) < 0) return -1;
if (tEncodeCStr(&encoder, pReq->name) < 0) return -1;
if (tEncodeI8(&encoder, pReq->igExists) < 0) return -1;
- if (tEncodeI8(&encoder, pReq->withTbName) < 0) return -1;
- if (tEncodeI8(&encoder, pReq->withSchema) < 0) return -1;
- if (tEncodeI8(&encoder, pReq->withTag) < 0) return -1;
- if (tEncodeCStr(&encoder, pReq->subscribeDbName) < 0) return -1;
- if (tEncodeI32(&encoder, sqlLen) < 0) return -1;
- if (tEncodeI32(&encoder, astLen) < 0) return -1;
- if (sqlLen > 0 && tEncodeCStr(&encoder, pReq->sql) < 0) return -1;
- if (astLen > 0 && tEncodeCStr(&encoder, pReq->ast) < 0) return -1;
+ if (tEncodeI8(&encoder, pReq->subType) < 0) return -1;
+ if (tEncodeCStr(&encoder, pReq->subDbName) < 0) return -1;
+ if (TOPIC_SUB_TYPE__DB == pReq->subType) {
+ } else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
+ if (tEncodeCStr(&encoder, pReq->subStbName) < 0) return -1;
+ } else {
+ if (tEncodeI32(&encoder, strlen(pReq->ast)) < 0) return -1;
+ if (tEncodeCStr(&encoder, pReq->ast) < 0) return -1;
+ }
+ if (tEncodeI32(&encoder, strlen(pReq->sql)) < 0) return -1;
+ if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1;
tEndEncode(&encoder);
@@ -2705,26 +2755,26 @@ int32_t tDeserializeSCMCreateTopicReq(void *buf, int32_t bufLen, SCMCreateTopicR
if (tStartDecode(&decoder) < 0) return -1;
if (tDecodeCStrTo(&decoder, pReq->name) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->igExists) < 0) return -1;
- if (tDecodeI8(&decoder, &pReq->withTbName) < 0) return -1;
- if (tDecodeI8(&decoder, &pReq->withSchema) < 0) return -1;
- if (tDecodeI8(&decoder, &pReq->withTag) < 0) return -1;
- if (tDecodeCStrTo(&decoder, pReq->subscribeDbName) < 0) return -1;
+ if (tDecodeI8(&decoder, &pReq->subType) < 0) return -1;
+ if (tDecodeCStrTo(&decoder, pReq->subDbName) < 0) return -1;
+ if (TOPIC_SUB_TYPE__DB == pReq->subType) {
+ } else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) {
+ if (tDecodeCStrTo(&decoder, pReq->subStbName) < 0) return -1;
+ } else {
+ if (tDecodeI32(&decoder, &astLen) < 0) return -1;
+ if (astLen > 0) {
+ pReq->ast = taosMemoryCalloc(1, astLen + 1);
+ if (pReq->ast == NULL) return -1;
+ if (tDecodeCStrTo(&decoder, pReq->ast) < 0) return -1;
+ }
+ }
if (tDecodeI32(&decoder, &sqlLen) < 0) return -1;
- if (tDecodeI32(&decoder, &astLen) < 0) return -1;
-
if (sqlLen > 0) {
pReq->sql = taosMemoryCalloc(1, sqlLen + 1);
if (pReq->sql == NULL) return -1;
if (tDecodeCStrTo(&decoder, pReq->sql) < 0) return -1;
}
- if (astLen > 0) {
- pReq->ast = taosMemoryCalloc(1, astLen + 1);
- if (pReq->ast == NULL) return -1;
- if (tDecodeCStrTo(&decoder, pReq->ast) < 0) return -1;
- } else {
- }
-
tEndDecode(&decoder);
tDecoderClear(&decoder);
@@ -2733,7 +2783,9 @@ int32_t tDeserializeSCMCreateTopicReq(void *buf, int32_t bufLen, SCMCreateTopicR
void tFreeSCMCreateTopicReq(SCMCreateTopicReq *pReq) {
taosMemoryFreeClear(pReq->sql);
- taosMemoryFreeClear(pReq->ast);
+ if (TOPIC_SUB_TYPE__COLUMN == pReq->subType) {
+ taosMemoryFreeClear(pReq->ast);
+ }
}
int32_t tSerializeSCMCreateTopicRsp(void *buf, int32_t bufLen, const SCMCreateTopicRsp *pRsp) {
@@ -2882,7 +2934,6 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
if (tStartEncode(&encoder) < 0) return -1;
if (tEncodeI32(&encoder, pReq->vgId) < 0) return -1;
- if (tEncodeI32(&encoder, pReq->dnodeId) < 0) return -1;
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
if (tEncodeI64(&encoder, pReq->dbUid) < 0) return -1;
if (tEncodeI32(&encoder, pReq->vgVersion) < 0) return -1;
@@ -2905,6 +2956,7 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
if (tEncodeI8(&encoder, pReq->compression) < 0) return -1;
if (tEncodeI8(&encoder, pReq->strict) < 0) return -1;
if (tEncodeI8(&encoder, pReq->cacheLastRow) < 0) return -1;
+ if (tEncodeI8(&encoder, pReq->standby) < 0) return -1;
if (tEncodeI8(&encoder, pReq->replica) < 0) return -1;
if (tEncodeI8(&encoder, pReq->selfIndex) < 0) return -1;
for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) {
@@ -2921,6 +2973,11 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
}
if (tEncodeI8(&encoder, pReq->isTsma) < 0) return -1;
+ if (pReq->isTsma) {
+ uint32_t tsmaLen = (uint32_t)(htonl(((SMsgHead *)pReq->pTsma)->contLen));
+ if (tEncodeBinary(&encoder, (const uint8_t *)pReq->pTsma, tsmaLen) < 0) return -1;
+ }
+
tEndEncode(&encoder);
int32_t tlen = encoder.pos;
@@ -2934,7 +2991,6 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
if (tStartDecode(&decoder) < 0) return -1;
if (tDecodeI32(&decoder, &pReq->vgId) < 0) return -1;
- if (tDecodeI32(&decoder, &pReq->dnodeId) < 0) return -1;
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
if (tDecodeI64(&decoder, &pReq->dbUid) < 0) return -1;
if (tDecodeI32(&decoder, &pReq->vgVersion) < 0) return -1;
@@ -2957,6 +3013,7 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
if (tDecodeI8(&decoder, &pReq->compression) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->strict) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->cacheLastRow) < 0) return -1;
+ if (tDecodeI8(&decoder, &pReq->standby) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->replica) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->selfIndex) < 0) return -1;
for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) {
@@ -2984,6 +3041,9 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
}
if (tDecodeI8(&decoder, &pReq->isTsma) < 0) return -1;
+ if (pReq->isTsma) {
+ if (tDecodeBinaryAlloc(&decoder, &pReq->pTsma, NULL) < 0) return -1;
+ }
tEndDecode(&decoder);
tDecoderClear(&decoder);
@@ -2993,6 +3053,9 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
int32_t tFreeSCreateVnodeReq(SCreateVnodeReq *pReq) {
taosArrayDestroy(pReq->pRetensions);
pReq->pRetensions = NULL;
+ if (pReq->isTsma) {
+ taosMemoryFreeClear(pReq->pTsma);
+ }
return 0;
}
@@ -3071,8 +3134,8 @@ int32_t tSerializeSAlterVnodeReq(void *buf, int32_t bufLen, SAlterVnodeReq *pReq
if (tEncodeI8(&encoder, pReq->walLevel) < 0) return -1;
if (tEncodeI8(&encoder, pReq->strict) < 0) return -1;
if (tEncodeI8(&encoder, pReq->cacheLastRow) < 0) return -1;
- if (tEncodeI8(&encoder, pReq->replica) < 0) return -1;
if (tEncodeI8(&encoder, pReq->selfIndex) < 0) return -1;
+ if (tEncodeI8(&encoder, pReq->replica) < 0) return -1;
for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) {
SReplica *pReplica = &pReq->replicas[i];
if (tEncodeSReplica(&encoder, pReplica) < 0) return -1;
@@ -3102,8 +3165,8 @@ int32_t tDeserializeSAlterVnodeReq(void *buf, int32_t bufLen, SAlterVnodeReq *pR
if (tDecodeI8(&decoder, &pReq->walLevel) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->strict) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->cacheLastRow) < 0) return -1;
- if (tDecodeI8(&decoder, &pReq->replica) < 0) return -1;
if (tDecodeI8(&decoder, &pReq->selfIndex) < 0) return -1;
+ if (tDecodeI8(&decoder, &pReq->replica) < 0) return -1;
for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) {
SReplica *pReplica = &pReq->replicas[i];
if (tDecodeSReplica(&decoder, pReplica) < 0) return -1;
@@ -3591,6 +3654,7 @@ int32_t tEncodeTSma(SEncoder *pCoder, const STSma *pSma) {
if (tEncodeI8(pCoder, pSma->intervalUnit) < 0) return -1;
if (tEncodeI8(pCoder, pSma->slidingUnit) < 0) return -1;
if (tEncodeI8(pCoder, pSma->timezoneInt) < 0) return -1;
+ if (tEncodeI32(pCoder, pSma->dstVgId) < 0) return -1;
if (tEncodeCStr(pCoder, pSma->indexName) < 0) return -1;
if (tEncodeI32(pCoder, pSma->exprLen) < 0) return -1;
if (tEncodeI32(pCoder, pSma->tagsFilterLen) < 0) return -1;
@@ -3613,6 +3677,7 @@ int32_t tDecodeTSma(SDecoder *pCoder, STSma *pSma) {
if (tDecodeI8(pCoder, &pSma->version) < 0) return -1;
if (tDecodeI8(pCoder, &pSma->intervalUnit) < 0) return -1;
if (tDecodeI8(pCoder, &pSma->slidingUnit) < 0) return -1;
+ if (tDecodeI32(pCoder, &pSma->dstVgId) < 0) return -1;
if (tDecodeI8(pCoder, &pSma->timezoneInt) < 0) return -1;
if (tDecodeCStrTo(pCoder, pSma->indexName) < 0) return -1;
if (tDecodeI32(pCoder, &pSma->exprLen) < 0) return -1;
@@ -3846,7 +3911,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
if (pReq->type == TSDB_CHILD_TABLE) {
if (tEncodeI64(pCoder, pReq->ctb.suid) < 0) return -1;
- if (tEncodeBinary(pCoder, pReq->ctb.pTag, kvRowLen(pReq->ctb.pTag)) < 0) return -1;
+ if (tEncodeTag(pCoder, (const STag *)pReq->ctb.pTag) < 0) return -1;
} else if (pReq->type == TSDB_NORMAL_TABLE) {
if (tEncodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow) < 0) return -1;
} else {
@@ -3858,8 +3923,6 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
}
int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
- uint32_t len;
-
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeI32v(pCoder, &pReq->flags) < 0) return -1;
@@ -3871,7 +3934,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
if (pReq->type == TSDB_CHILD_TABLE) {
if (tDecodeI64(pCoder, &pReq->ctb.suid) < 0) return -1;
- if (tDecodeBinary(pCoder, &pReq->ctb.pTag, &len) < 0) return -1;
+ if (tDecodeTag(pCoder, (STag **)&pReq->ctb.pTag) < 0) return -1;
} else if (pReq->type == TSDB_NORMAL_TABLE) {
if (tDecodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow) < 0) return -1;
} else {
@@ -4285,13 +4348,96 @@ int32_t tDecodeSVAlterTbReq(SDecoder *pDecoder, SVAlterTbReq *pReq) {
int32_t tEncodeSVAlterTbRsp(SEncoder *pEncoder, const SVAlterTbRsp *pRsp) {
if (tStartEncode(pEncoder) < 0) return -1;
if (tEncodeI32(pEncoder, pRsp->code) < 0) return -1;
+ if (tEncodeI32(pEncoder, pRsp->pMeta ? 1 : 0) < 0) return -1;
+ if (pRsp->pMeta) {
+ if (tEncodeSTableMetaRsp(pEncoder, pRsp->pMeta) < 0) return -1;
+ }
tEndEncode(pEncoder);
return 0;
}
int32_t tDecodeSVAlterTbRsp(SDecoder *pDecoder, SVAlterTbRsp *pRsp) {
+ int32_t meta = 0;
if (tStartDecode(pDecoder) < 0) return -1;
if (tDecodeI32(pDecoder, &pRsp->code) < 0) return -1;
+ if (tDecodeI32(pDecoder, &meta) < 0) return -1;
+ if (meta) {
+ pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
+ if (NULL == pRsp->pMeta) return -1;
+ if (tDecodeSTableMetaRsp(pDecoder, pRsp->pMeta) < 0) return -1;
+ }
tEndDecode(pDecoder);
return 0;
}
+
+int32_t tDeserializeSVAlterTbRsp(void *buf, int32_t bufLen, SVAlterTbRsp *pRsp) {
+ int32_t meta = 0;
+ SDecoder decoder = {0};
+ tDecoderInit(&decoder, buf, bufLen);
+
+ if (tStartDecode(&decoder) < 0) return -1;
+ if (tDecodeI32(&decoder, &pRsp->code) < 0) return -1;
+ if (tDecodeI32(&decoder, &meta) < 0) return -1;
+ if (meta) {
+ pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
+ if (NULL == pRsp->pMeta) return -1;
+ if (tDecodeSTableMetaRsp(&decoder, pRsp->pMeta) < 0) return -1;
+ }
+ tEndDecode(&decoder);
+ tDecoderClear(&decoder);
+ return 0;
+}
+
+int32_t tEncodeSMAlterStbRsp(SEncoder *pEncoder, const SMAlterStbRsp *pRsp) {
+ if (tStartEncode(pEncoder) < 0) return -1;
+ if (tEncodeI32(pEncoder, pRsp->pMeta->pSchemas ? 1 : 0) < 0) return -1;
+ if (pRsp->pMeta->pSchemas) {
+ if (tEncodeSTableMetaRsp(pEncoder, pRsp->pMeta) < 0) return -1;
+ }
+ tEndEncode(pEncoder);
+ return 0;
+}
+
+int32_t tDecodeSMAlterStbRsp(SDecoder *pDecoder, SMAlterStbRsp *pRsp) {
+ int32_t meta = 0;
+ if (tStartDecode(pDecoder) < 0) return -1;
+ if (tDecodeI32(pDecoder, &meta) < 0) return -1;
+ if (meta) {
+ pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
+ if (NULL == pRsp->pMeta) return -1;
+ if (tDecodeSTableMetaRsp(pDecoder, pRsp->pMeta) < 0) return -1;
+ }
+ tEndDecode(pDecoder);
+ return 0;
+}
+
+int32_t tDeserializeSMAlterStbRsp(void *buf, int32_t bufLen, SMAlterStbRsp *pRsp) {
+ int32_t meta = 0;
+ SDecoder decoder = {0};
+ tDecoderInit(&decoder, buf, bufLen);
+
+ if (tStartDecode(&decoder) < 0) return -1;
+ if (tDecodeI32(&decoder, &meta) < 0) return -1;
+ if (meta) {
+ pRsp->pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
+ if (NULL == pRsp->pMeta) return -1;
+ if (tDecodeSTableMetaRsp(&decoder, pRsp->pMeta) < 0) return -1;
+ }
+ tEndDecode(&decoder);
+ tDecoderClear(&decoder);
+ return 0;
+}
+
+void tFreeSMAlterStbRsp(SMAlterStbRsp* pRsp) {
+ if (NULL == pRsp) {
+ return;
+ }
+
+ if (pRsp->pMeta) {
+ taosMemoryFree(pRsp->pMeta->pSchemas);
+ taosMemoryFree(pRsp->pMeta);
+ }
+}
+
+
+
diff --git a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
index ae8879326d6da92b6bd5ab3ea89584b347817fd4..ee811c0071cbd07c03edb7aaf117c3c4461adebb 100644
--- a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
+++ b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
@@ -35,6 +35,7 @@ typedef struct SDnodeMgmt {
SendMonitorReportFp sendMonitorReportFp;
GetVnodeLoadsFp getVnodeLoadsFp;
GetMnodeLoadsFp getMnodeLoadsFp;
+ GetQnodeLoadsFp getQnodeLoadsFp;
} SDnodeMgmt;
// dmHandle.c
@@ -58,4 +59,4 @@ void dmStopWorker(SDnodeMgmt *pMgmt);
}
#endif
-#endif /*_TD_DND_QNODE_INT_H_*/
\ No newline at end of file
+#endif /*_TD_DND_QNODE_INT_H_*/
diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
index 2533f268e5cd5355c1dba75fb384e977c386d1fa..fbd46db183d3024e40bb472decf80bf4c3936443 100644
--- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
+++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
@@ -79,6 +79,8 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
(*pMgmt->getMnodeLoadsFp)(&minfo);
req.mload = minfo.load;
+ (*pMgmt->getQnodeLoadsFp)(&req.qload);
+
int32_t contLen = tSerializeSStatusReq(NULL, 0, &req);
void *pHead = rpcMallocCont(contLen);
tSerializeSStatusReq(pHead, contLen, &req);
diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
index 59c926545e6f565a124a4846532e4f74efeecd5e..d2db1a4a62fd157b2df235133c85bb6e38ac680d 100644
--- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
+++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
@@ -48,6 +48,7 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
pMgmt->sendMonitorReportFp = pInput->sendMonitorReportFp;
pMgmt->getVnodeLoadsFp = pInput->getVnodeLoadsFp;
pMgmt->getMnodeLoadsFp = pInput->getMnodeLoadsFp;
+ pMgmt->getQnodeLoadsFp = pInput->getQnodeLoadsFp;
if (dmStartWorker(pMgmt) != 0) {
return -1;
diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c
index f6350ba27954349a89849f66a9d15be7ffb6266d..5c5316e3a3ba5f51a59e51b10bdc7663970dd71d 100644
--- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c
+++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c
@@ -197,6 +197,8 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_MND_SUBSCRIBE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_COMMIT_OFFSET, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_ASK_EP, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_DROP_CGROUP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_DROP_CGROUP_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_VG_CHANGE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_VG_DELETE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_STREAM, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
@@ -217,9 +219,9 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_HEARTBEAT, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER;
- if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
- if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
- if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_CONFIG_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_REPLICA_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_TIMEOUT, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_PING, mmPutNodeMsgToSyncQueue, 1) == NULL) goto _OVER;
diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c b/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c
index 65794b7b8136f0d6314880399ac08a195eecd22a..864f5b485afdea2c798cbc35a12466ecfa1b69b8 100644
--- a/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c
+++ b/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c
@@ -20,6 +20,14 @@ void qmGetMonitorInfo(SQnodeMgmt *pMgmt, SMonQmInfo *qmInfo) {
SQnodeLoad qload = {0};
qndGetLoad(pMgmt->pQnode, &qload);
+ qload.dnodeId = pMgmt->pData->dnodeId;
+
+}
+
+void qmGetQnodeLoads(SQnodeMgmt *pMgmt, SQnodeLoad *pInfo) {
+ qndGetLoad(pMgmt->pQnode, pInfo);
+
+ pInfo->dnodeId = pMgmt->pData->dnodeId;
}
int32_t qmProcessGetMonitorInfoReq(SQnodeMgmt *pMgmt, SRpcMsg *pMsg) {
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
index 8374db129ffacd5ba7776662cb0bc393ac77667e..018d7a607c146243019b085ab858e7c7a670eda6 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c
@@ -140,6 +140,7 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
pCfg->szCache = pCreate->pages;
pCfg->szBuf = (uint64_t)pCreate->buffer * 1024 * 1024;
pCfg->isWeak = true;
+ pCfg->isTsma = pCreate->isTsma;
pCfg->tsdbCfg.compression = pCreate->compression;
pCfg->tsdbCfg.precision = pCreate->precision;
pCfg->tsdbCfg.days = pCreate->daysPerFile;
@@ -149,20 +150,26 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
pCfg->tsdbCfg.minRows = pCreate->minRows;
pCfg->tsdbCfg.maxRows = pCreate->maxRows;
for (size_t i = 0; i < taosArrayGetSize(pCreate->pRetensions); ++i) {
- memcpy(&pCfg->tsdbCfg.retentions[i], taosArrayGet(pCreate->pRetensions, i), sizeof(SRetention));
+ SRetention *pRetention = &pCfg->tsdbCfg.retentions[i];
+ memcpy(pRetention, taosArrayGet(pCreate->pRetensions, i), sizeof(SRetention));
+ if (i == 0) {
+ if ((pRetention->freq > 0 && pRetention->keep > 0)) pCfg->isRsma = 1;
+ }
}
+
pCfg->walCfg.vgId = pCreate->vgId;
pCfg->hashBegin = pCreate->hashBegin;
pCfg->hashEnd = pCreate->hashEnd;
pCfg->hashMethod = pCreate->hashMethod;
+ pCfg->standby = pCfg->standby;
pCfg->syncCfg.myIndex = pCreate->selfIndex;
pCfg->syncCfg.replicaNum = pCreate->replica;
memset(&pCfg->syncCfg.nodeInfo, 0, sizeof(pCfg->syncCfg.nodeInfo));
for (int i = 0; i < pCreate->replica; ++i) {
- pCfg->syncCfg.nodeInfo[i].nodePort = pCreate->replicas[i].port;
- snprintf(pCfg->syncCfg.nodeInfo[i].nodeFqdn, sizeof(pCfg->syncCfg.nodeInfo[i].nodeFqdn), "%s",
- pCreate->replicas[i].fqdn);
+ SNodeInfo *pNode = &pCfg->syncCfg.nodeInfo[i];
+ pNode->nodePort = pCreate->replicas[i].port;
+ tstrncpy(pNode->nodeFqdn, pCreate->replicas[i].fqdn, sizeof(pNode->nodeFqdn));
}
}
@@ -175,6 +182,8 @@ static void vmGenerateWrapperCfg(SVnodeMgmt *pMgmt, SCreateVnodeReq *pCreate, SW
int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
SCreateVnodeReq createReq = {0};
+ SVnodeCfg vnodeCfg = {0};
+ SWrapperCfg wrapperCfg = {0};
int32_t code = -1;
char path[TSDB_FILENAME_LEN] = {0};
@@ -183,12 +192,9 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
return -1;
}
- dDebug("vgId:%d, create vnode req is received, tsma:%d", createReq.vgId, createReq.isTsma);
-
- SVnodeCfg vnodeCfg = {0};
+ dDebug("vgId:%d, create vnode req is received, tsma:%d standby:%d", createReq.vgId, createReq.isTsma,
+ createReq.standby);
vmGenerateVnodeCfg(&createReq, &vnodeCfg);
-
- SWrapperCfg wrapperCfg = {0};
vmGenerateWrapperCfg(pMgmt, &createReq, &wrapperCfg);
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, createReq.vgId);
@@ -209,7 +215,7 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb);
if (pImpl == NULL) {
- dError("vgId:%d, failed to create vnode since %s", createReq.vgId, terrstr());
+ dError("vgId:%d, failed to open vnode since %s", createReq.vgId, terrstr());
code = terrno;
goto _OVER;
}
@@ -217,9 +223,20 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
code = vmOpenVnode(pMgmt, &wrapperCfg, pImpl);
if (code != 0) {
dError("vgId:%d, failed to open vnode since %s", createReq.vgId, terrstr());
+ code = terrno;
goto _OVER;
}
+ if (createReq.isTsma) {
+ SMsgHead *smaMsg = createReq.pTsma;
+ uint32_t contLen = (uint32_t)(htonl(smaMsg->contLen) - sizeof(SMsgHead));
+ if (vnodeProcessCreateTSma(pImpl, POINTER_SHIFT(smaMsg, sizeof(SMsgHead)), contLen) < 0) {
+ dError("vgId:%d, failed to create tsma since %s", createReq.vgId, terrstr());
+ code = terrno;
+ goto _OVER;
+ };
+ }
+
code = vnodeStart(pImpl);
if (code != 0) {
dError("vgId:%d, failed to start sync since %s", createReq.vgId, terrstr());
@@ -227,7 +244,10 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
}
code = vmWriteVnodeListToFile(pMgmt);
- if (code != 0) goto _OVER;
+ if (code != 0) {
+ code = terrno;
+ goto _OVER;
+ }
_OVER:
if (code != 0) {
@@ -313,8 +333,9 @@ SArray *vmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_DISPATCH, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_RECOVER, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER;
- if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_VNODE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
- if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_VNODE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_REPLICA, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_CONFIG, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
+ if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE, vmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE, vmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
index 6183794bdd9c87da091a64c5333ad42f70dd824e..a945358d342f373f1ec4bda4659ea3008c9a2383 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
@@ -104,7 +104,7 @@ static void vmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
dTrace("msg:%p, get from vnode-write queue", pMsg);
if (taosArrayPush(pArray, &pMsg) == NULL) {
- dTrace("msg:%p, failed to process since %s", pMsg, terrstr());
+ dTrace("msg:%p, failed to push to array since %s", pMsg, terrstr());
vmSendRsp(pMsg, TSDB_CODE_OUT_OF_MEMORY);
}
}
diff --git a/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h b/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h
index 27f1140f2379f2db9a5856ff72ad0fbc0f42d9f2..adde0557965fb7651c66a8b4791d4a671db91201 100644
--- a/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h
+++ b/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h
@@ -168,6 +168,7 @@ int32_t dmProcessNodeMsg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg);
void dmSendMonitorReport();
void dmGetVnodeLoads(SMonVloadInfo *pInfo);
void dmGetMnodeLoads(SMonMloadInfo *pInfo);
+void dmGetQnodeLoads(SQnodeLoad *pInfo);
#ifdef __cplusplus
}
diff --git a/source/dnode/mgmt/node_mgmt/inc/dmNodes.h b/source/dnode/mgmt/node_mgmt/inc/dmNodes.h
index 3ac71de530d4dd9dad6ccd6b29b7789f56a85b1e..8c2d57808fc5d8e29c4bef5079f504c8a9e39802 100644
--- a/source/dnode/mgmt/node_mgmt/inc/dmNodes.h
+++ b/source/dnode/mgmt/node_mgmt/inc/dmNodes.h
@@ -37,6 +37,7 @@ void bmGetMonitorInfo(void *pMgmt, SMonBmInfo *pInfo);
void vmGetVnodeLoads(void *pMgmt, SMonVloadInfo *pInfo);
void mmGetMnodeLoads(void *pMgmt, SMonMloadInfo *pInfo);
+void qmGetQnodeLoads(void *pMgmt, SQnodeLoad *pInfo);
#ifdef __cplusplus
}
diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c
index 07d0c43360a5de639f5af2b64208d13c79192687..5f1bf30523c25cb8c2bad6755ecddc4769ea108d 100644
--- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c
+++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c
@@ -178,6 +178,7 @@ SMgmtInputOpt dmBuildMgmtInputOpt(SMgmtWrapper *pWrapper) {
.sendMonitorReportFp = dmSendMonitorReport,
.getVnodeLoadsFp = dmGetVnodeLoads,
.getMnodeLoadsFp = dmGetMnodeLoads,
+ .getQnodeLoadsFp = dmGetQnodeLoads,
};
opt.msgCb = dmGetMsgcb(pWrapper->pDnode);
diff --git a/source/dnode/mgmt/node_mgmt/src/dmMonitor.c b/source/dnode/mgmt/node_mgmt/src/dmMonitor.c
index 0b74d865fd5680311c483003a58da1785813a275..ecad390ef94a635fdeed8256004fce9978fde822 100644
--- a/source/dnode/mgmt/node_mgmt/src/dmMonitor.c
+++ b/source/dnode/mgmt/node_mgmt/src/dmMonitor.c
@@ -170,3 +170,17 @@ void dmGetMnodeLoads(SMonMloadInfo *pInfo) {
dmReleaseWrapper(pWrapper);
}
}
+
+void dmGetQnodeLoads(SQnodeLoad *pInfo) {
+ SDnode *pDnode = dmInstance();
+ SMgmtWrapper *pWrapper = &pDnode->wrappers[QNODE];
+ if (dmMarkWrapper(pWrapper) == 0) {
+ if (tsMultiProcess) {
+ dmSendLocalRecv(pDnode, TDMT_MON_QM_LOAD, tDeserializeSQnodeLoad, pInfo);
+ } else if (pWrapper->pMgmt != NULL) {
+ qmGetQnodeLoads(pWrapper->pMgmt, pInfo);
+ }
+ dmReleaseWrapper(pWrapper);
+ }
+}
+
diff --git a/source/dnode/mgmt/node_mgmt/src/dmTransport.c b/source/dnode/mgmt/node_mgmt/src/dmTransport.c
index 987fc5441653a09c27d889b03af30150622f96a3..e5893fd94740fa20fa244bd1957a02a50e39bf08 100644
--- a/source/dnode/mgmt/node_mgmt/src/dmTransport.c
+++ b/source/dnode/mgmt/node_mgmt/src/dmTransport.c
@@ -130,7 +130,7 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
_OVER:
if (code != 0) {
- dError("msg:%p, failed to process since %s", pMsg, terrstr());
+ dTrace("msg:%p, failed to process since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pRpc->msgType));
if (terrno != 0) code = terrno;
if (IsReq(pRpc)) {
diff --git a/source/dnode/mgmt/node_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h
index 0d921c2e8b8d810891d1718648f1aead826f9116..c142a6cfd892413f1a69e2e7ce1d41524b1dbb27 100644
--- a/source/dnode/mgmt/node_util/inc/dmUtil.h
+++ b/source/dnode/mgmt/node_util/inc/dmUtil.h
@@ -34,6 +34,7 @@
#include "dnode.h"
#include "mnode.h"
+#include "qnode.h"
#include "monitor.h"
#include "sync.h"
#include "wal.h"
@@ -92,6 +93,7 @@ typedef int32_t (*ProcessDropNodeFp)(EDndNodeType ntype, SRpcMsg *pMsg);
typedef void (*SendMonitorReportFp)();
typedef void (*GetVnodeLoadsFp)(SMonVloadInfo *pInfo);
typedef void (*GetMnodeLoadsFp)(SMonMloadInfo *pInfo);
+typedef void (*GetQnodeLoadsFp)(SQnodeLoad *pInfo);
typedef struct {
int32_t dnodeId;
@@ -118,6 +120,7 @@ typedef struct {
SendMonitorReportFp sendMonitorReportFp;
GetVnodeLoadsFp getVnodeLoadsFp;
GetMnodeLoadsFp getMnodeLoadsFp;
+ GetQnodeLoadsFp getQnodeLoadsFp;
} SMgmtInputOpt;
typedef struct {
@@ -180,4 +183,4 @@ void dmSetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet);
}
#endif
-#endif /*_TD_DM_INT_H_*/
\ No newline at end of file
+#endif /*_TD_DM_INT_H_*/
diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h
index 2164c98c83ec2a976695084692ecfb179d21ca0a..2f7c357aef93c2a7991947d29994443a5fe97023 100644
--- a/source/dnode/mnode/impl/inc/mndDef.h
+++ b/source/dnode/mnode/impl/inc/mndDef.h
@@ -54,85 +54,31 @@ typedef enum {
} EAuthOp;
typedef enum {
- TRN_STEP_LOG = 1,
- TRN_STEP_ACTION = 2,
-} ETrnStep;
+ TRN_CONFLICT_NOTHING = 0,
+ TRN_CONFLICT_GLOBAL = 1,
+ TRN_CONFLICT_DB = 2,
+ TRN_CONFLICT_DB_INSIDE = 3,
+} ETrnConflct;
typedef enum {
TRN_STAGE_PREPARE = 0,
- TRN_STAGE_REDO_LOG = 1,
- TRN_STAGE_REDO_ACTION = 2,
- TRN_STAGE_ROLLBACK = 3,
- TRN_STAGE_UNDO_ACTION = 4,
- TRN_STAGE_UNDO_LOG = 5,
- TRN_STAGE_COMMIT = 6,
- TRN_STAGE_COMMIT_LOG = 7,
- TRN_STAGE_FINISHED = 8
+ TRN_STAGE_REDO_ACTION = 1,
+ TRN_STAGE_ROLLBACK = 2,
+ TRN_STAGE_UNDO_ACTION = 3,
+ TRN_STAGE_COMMIT = 4,
+ TRN_STAGE_COMMIT_ACTION = 5,
+ TRN_STAGE_FINISHED = 6
} ETrnStage;
-typedef enum {
- TRN_TYPE_BASIC_SCOPE = 1000,
- TRN_TYPE_CREATE_ACCT = 1001,
- TRN_TYPE_CREATE_CLUSTER = 1002,
- TRN_TYPE_CREATE_USER = 1003,
- TRN_TYPE_ALTER_USER = 1004,
- TRN_TYPE_DROP_USER = 1005,
- TRN_TYPE_CREATE_FUNC = 1006,
- TRN_TYPE_DROP_FUNC = 1007,
-
- TRN_TYPE_CREATE_SNODE = 1010,
- TRN_TYPE_DROP_SNODE = 1011,
- TRN_TYPE_CREATE_QNODE = 1012,
- TRN_TYPE_DROP_QNODE = 10013,
- TRN_TYPE_CREATE_BNODE = 1014,
- TRN_TYPE_DROP_BNODE = 1015,
- TRN_TYPE_CREATE_MNODE = 1016,
- TRN_TYPE_DROP_MNODE = 1017,
-
- TRN_TYPE_CREATE_TOPIC = 1020,
- TRN_TYPE_DROP_TOPIC = 1021,
- TRN_TYPE_SUBSCRIBE = 1022,
- TRN_TYPE_REBALANCE = 1023,
- TRN_TYPE_COMMIT_OFFSET = 1024,
- TRN_TYPE_CREATE_STREAM = 1025,
- TRN_TYPE_DROP_STREAM = 1026,
- TRN_TYPE_ALTER_STREAM = 1027,
- TRN_TYPE_CONSUMER_LOST = 1028,
- TRN_TYPE_CONSUMER_RECOVER = 1029,
- TRN_TYPE_DROP_CGROUP = 1030,
- TRN_TYPE_BASIC_SCOPE_END,
-
- TRN_TYPE_GLOBAL_SCOPE = 2000,
- TRN_TYPE_CREATE_DNODE = 2001,
- TRN_TYPE_DROP_DNODE = 2002,
- TRN_TYPE_GLOBAL_SCOPE_END,
-
- TRN_TYPE_DB_SCOPE = 3000,
- TRN_TYPE_CREATE_DB = 3001,
- TRN_TYPE_ALTER_DB = 3002,
- TRN_TYPE_DROP_DB = 3003,
- TRN_TYPE_SPLIT_VGROUP = 3004,
- TRN_TYPE_MERGE_VGROUP = 3015,
- TRN_TYPE_DB_SCOPE_END,
-
- TRN_TYPE_STB_SCOPE = 4000,
- TRN_TYPE_CREATE_STB = 4001,
- TRN_TYPE_ALTER_STB = 4002,
- TRN_TYPE_DROP_STB = 4003,
- TRN_TYPE_CREATE_SMA = 4004,
- TRN_TYPE_DROP_SMA = 4005,
- TRN_TYPE_STB_SCOPE_END,
-} ETrnType;
-
typedef enum {
TRN_POLICY_ROLLBACK = 0,
TRN_POLICY_RETRY = 1,
} ETrnPolicy;
typedef enum {
- TRN_EXEC_PARALLEL = 0,
- TRN_EXEC_ONE_BY_ONE = 1,
-} ETrnExecType;
+ TRN_EXEC_PRARLLEL = 0,
+ TRN_EXEC_SERIAL = 1,
+} ETrnExec;
typedef enum {
DND_REASON_ONLINE = 0,
@@ -161,23 +107,24 @@ typedef struct {
int32_t id;
ETrnStage stage;
ETrnPolicy policy;
- ETrnType type;
- ETrnExecType parallel;
+ ETrnConflct conflict;
+ ETrnExec exec;
int32_t code;
int32_t failedTimes;
SRpcHandleInfo rpcInfo;
void* rpcRsp;
int32_t rpcRspLen;
- SArray* redoLogs;
- SArray* undoLogs;
- SArray* commitLogs;
+ int32_t redoActionPos;
SArray* redoActions;
SArray* undoActions;
+ SArray* commitActions;
int64_t createdTime;
int64_t lastExecTime;
- int64_t dbUid;
+ int32_t lastErrorAction;
+ int32_t lastErrorNo;
+ tmsg_t lastErrorMsgType;
+ SEpSet lastErrorEpset;
char dbname[TSDB_DB_FNAME_LEN];
- char lastError[TSDB_TRANS_ERROR_LEN];
int32_t startFunc;
int32_t stopFunc;
int32_t paramLen;
@@ -221,6 +168,7 @@ typedef struct {
int64_t createdTime;
int64_t updateTime;
SDnodeObj* pDnode;
+ SQnodeLoad load;
} SQnodeObj;
typedef struct {
@@ -345,6 +293,7 @@ typedef struct {
int8_t isTsma;
int8_t replica;
SVnodeGid vnodeGid[TSDB_MAX_REPLICA];
+ void* pTsma;
} SVgObj;
typedef struct {
@@ -461,19 +410,15 @@ typedef struct {
int64_t uid;
int64_t dbUid;
int32_t version;
- int8_t subType; // db or table
- int8_t withTbName;
- int8_t withSchema;
- int8_t withTag;
+ int8_t subType; // column, db or stable
SRWLatch lock;
- int32_t consumerCnt;
int32_t sqlLen;
int32_t astLen;
char* sql;
char* ast;
char* physicalPlan;
SSchemaWrapper schema;
- // int32_t refConsumerCnt;
+ int64_t stbUid;
} SMqTopicObj;
typedef struct {
@@ -532,9 +477,7 @@ typedef struct {
int64_t dbUid;
int32_t vgNum;
int8_t subType;
- int8_t withTbName;
- int8_t withSchema;
- int8_t withTag;
+ int64_t stbUid;
SHashObj* consumerHash; // consumerId -> SMqConsumerEp
SArray* unassignedVgs; // SArray
} SMqSubscribeObj;
@@ -586,7 +529,7 @@ typedef struct {
} SMqRebOutputObj;
typedef struct {
- char name[TSDB_TOPIC_FNAME_LEN];
+ char name[TSDB_STREAM_FNAME_LEN];
char sourceDb[TSDB_DB_FNAME_LEN];
char targetDb[TSDB_DB_FNAME_LEN];
char targetSTbName[TSDB_TABLE_FNAME_LEN];
diff --git a/source/dnode/mnode/impl/inc/mndQnode.h b/source/dnode/mnode/impl/inc/mndQnode.h
index 5d177b3f6db6e2f8c81be3c4461bdea0870ba322..3e38565a4fe67b93d8ba8b9d30160ce54b13dee5 100644
--- a/source/dnode/mnode/impl/inc/mndQnode.h
+++ b/source/dnode/mnode/impl/inc/mndQnode.h
@@ -22,9 +22,15 @@
extern "C" {
#endif
+#define QNODE_LOAD_VALUE(pQnode) (pQnode ? (pQnode->load.numOfQueryInQueue + pQnode->load.numOfFetchInQueue) : 0)
+
int32_t mndInitQnode(SMnode *pMnode);
void mndCleanupQnode(SMnode *pMnode);
+SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId);
+void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj);
+int32_t mndCreateQnodeList(SMnode *pMnode, SArray** pList, int32_t limit);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/dnode/mnode/impl/inc/mndScheduler.h b/source/dnode/mnode/impl/inc/mndScheduler.h
index 9f4e377dd17dffc94ab04366e2c1ba61e170b92f..05aea3f68c4023ceb68e16ad875f59c666f63171 100644
--- a/source/dnode/mnode/impl/inc/mndScheduler.h
+++ b/source/dnode/mnode/impl/inc/mndScheduler.h
@@ -30,7 +30,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream);
int32_t mndConvertRSmaTask(const char* ast, int64_t uid, int8_t triggerType, int64_t watermark, char** pStr,
- int32_t* pLen);
+ int32_t* pLen, double filesFactor);
#ifdef __cplusplus
}
diff --git a/source/dnode/mnode/impl/inc/mndTrans.h b/source/dnode/mnode/impl/inc/mndTrans.h
index ce302a88e3fb4735b99ce2037b2dcb378254a844..6d1f3710830563e24fe124a3a95582b316ef4e00 100644
--- a/source/dnode/mnode/impl/inc/mndTrans.h
+++ b/source/dnode/mnode/impl/inc/mndTrans.h
@@ -26,31 +26,24 @@ typedef enum {
TRANS_START_FUNC_TEST = 1,
TRANS_STOP_FUNC_TEST = 2,
TRANS_START_FUNC_MQ_REB = 3,
- TRANS_STOP_FUNC_TEST_MQ_REB = 4,
+ TRANS_STOP_FUNC_MQ_REB = 4,
} ETrnFunc;
typedef struct {
- SEpSet epSet;
- tmsg_t msgType;
- int8_t msgSent;
- int8_t msgReceived;
- int32_t errCode;
- int32_t acceptableCode;
- int32_t contLen;
- void *pCont;
-} STransAction;
-
-typedef struct {
+ int32_t id;
+ int32_t errCode;
+ int32_t acceptableCode;
+ int8_t stage;
+ int8_t actionType; // 0-msg, 1-raw
+ int8_t rawWritten;
+ int8_t msgSent;
+ int8_t msgReceived;
+ tmsg_t msgType;
+ SEpSet epSet;
+ int32_t contLen;
+ void *pCont;
SSdbRaw *pRaw;
-} STransLog;
-
-typedef struct {
- ETrnStep stepType;
- STransAction redoAction;
- STransAction undoAction;
- STransLog redoLog;
- STransLog undoLog;
-} STransStep;
+} STransAction;
typedef void (*TransCbFp)(SMnode *pMnode, void *param, int32_t paramLen);
@@ -59,7 +52,7 @@ void mndCleanupTrans(SMnode *pMnode);
STrans *mndAcquireTrans(SMnode *pMnode, int32_t transId);
void mndReleaseTrans(SMnode *pMnode, STrans *pTrans);
-STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnType type, const SRpcMsg *pReq);
+STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnConflct conflict, const SRpcMsg *pReq);
void mndTransDrop(STrans *pTrans);
int32_t mndTransAppendRedolog(STrans *pTrans, SSdbRaw *pRaw);
int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw);
@@ -68,8 +61,8 @@ int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction);
int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction);
void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen);
void mndTransSetCb(STrans *pTrans, ETrnFunc startFunc, ETrnFunc stopFunc, void *param, int32_t paramLen);
-void mndTransSetDbInfo(STrans *pTrans, SDbObj *pDb);
-void mndTransSetExecOneByOne(STrans *pTrans);
+void mndTransSetDbName(STrans *pTrans, const char *dbname);
+void mndTransSetSerial(STrans *pTrans);
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans);
void mndTransProcessRsp(SRpcMsg *pRsp);
diff --git a/source/dnode/mnode/impl/inc/mndVgroup.h b/source/dnode/mnode/impl/inc/mndVgroup.h
index c9099b6b050481b78030befbe93de59139df1b27..3f4f3f2053bd4fd633488eaf4a4fac71d642df51 100644
--- a/source/dnode/mnode/impl/inc/mndVgroup.h
+++ b/source/dnode/mnode/impl/inc/mndVgroup.h
@@ -36,7 +36,7 @@ SArray *mndBuildDnodesArray(SMnode *pMnode);
int32_t mndAddVnodeToVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray);
int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray, SVnodeGid *del1, SVnodeGid *del2);
-void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
+void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen, bool standby);
void *mndBuildDropVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
void *mndBuildAlterVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
diff --git a/source/dnode/mnode/impl/src/mndAcct.c b/source/dnode/mnode/impl/src/mndAcct.c
index a4fde4b70670952dbf14554aa0fce15f77cb49f5..0ce4a8c76e72ce2f2513819139b00a01c67f5231 100644
--- a/source/dnode/mnode/impl/src/mndAcct.c
+++ b/source/dnode/mnode/impl/src/mndAcct.c
@@ -78,11 +78,9 @@ static int32_t mndCreateDefaultAcct(SMnode *pMnode) {
if (pRaw == NULL) return -1;
sdbSetRawStatus(pRaw, SDB_STATUS_READY);
- mDebug("acct:%s, will be created while deploy sdb, raw:%p", acctObj.acct, pRaw);
-#if 0
- return sdbWrite(pMnode->pSdb, pRaw);
-#else
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_ACCT, NULL);
+ mDebug("acct:%s, will be created when deploying, raw:%p", acctObj.acct, pRaw);
+
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL);
if (pTrans == NULL) {
mError("acct:%s, failed to create since %s", acctObj.acct, terrstr());
return -1;
@@ -94,7 +92,6 @@ static int32_t mndCreateDefaultAcct(SMnode *pMnode) {
mndTransDrop(pTrans);
return -1;
}
- sdbSetRawStatus(pRaw, SDB_STATUS_READY);
if (mndTransPrepare(pMnode, pTrans) != 0) {
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
@@ -104,7 +101,6 @@ static int32_t mndCreateDefaultAcct(SMnode *pMnode) {
mndTransDrop(pTrans);
return 0;
-#endif
}
static SSdbRaw *mndAcctActionEncode(SAcctObj *pAcct) {
diff --git a/source/dnode/mnode/impl/src/mndBnode.c b/source/dnode/mnode/impl/src/mndBnode.c
index 3316a09462ff1d5ff7c940e623941c7abe72a76c..801f335a8056757c2cbe2d7f1ca6d65a4501003f 100644
--- a/source/dnode/mnode/impl/src/mndBnode.c
+++ b/source/dnode/mnode/impl/src/mndBnode.c
@@ -246,7 +246,7 @@ static int32_t mndCreateBnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
bnodeObj.createdTime = taosGetTimestampMs();
bnodeObj.updateTime = bnodeObj.createdTime;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_BNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create bnode:%d", pTrans->id, pCreate->dnodeId);
@@ -363,7 +363,7 @@ static int32_t mndSetDropBnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SBn
static int32_t mndDropBnode(SMnode *pMnode, SRpcMsg *pReq, SBnodeObj *pObj) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_DROP_BNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop bnode:%d", pTrans->id, pObj->id);
diff --git a/source/dnode/mnode/impl/src/mndCluster.c b/source/dnode/mnode/impl/src/mndCluster.c
index a421be5c062a709bdd1e74f583a95142da2aac82..bb3377d16ac815489ce0cfbec22307ebb02156d0 100644
--- a/source/dnode/mnode/impl/src/mndCluster.c
+++ b/source/dnode/mnode/impl/src/mndCluster.c
@@ -172,17 +172,15 @@ static int32_t mndCreateDefaultCluster(SMnode *pMnode) {
clusterObj.id = mndGenerateUid(clusterObj.name, TSDB_CLUSTER_ID_LEN);
clusterObj.id = (clusterObj.id >= 0 ? clusterObj.id : -clusterObj.id);
pMnode->clusterId = clusterObj.id;
- mDebug("cluster:%" PRId64 ", name is %s", clusterObj.id, clusterObj.name);
+ mInfo("cluster:%" PRId64 ", name is %s", clusterObj.id, clusterObj.name);
SSdbRaw *pRaw = mndClusterActionEncode(&clusterObj);
if (pRaw == NULL) return -1;
sdbSetRawStatus(pRaw, SDB_STATUS_READY);
- mDebug("cluster:%" PRId64 ", will be created while deploy sdb, raw:%p", clusterObj.id, pRaw);
-#if 0
- return sdbWrite(pMnode->pSdb, pRaw);
-#else
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_CLUSTER, NULL);
+ mDebug("cluster:%" PRId64 ", will be created when deploying, raw:%p", clusterObj.id, pRaw);
+
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL);
if (pTrans == NULL) {
mError("cluster:%" PRId64 ", failed to create since %s", clusterObj.id, terrstr());
return -1;
@@ -204,7 +202,6 @@ static int32_t mndCreateDefaultCluster(SMnode *pMnode) {
mndTransDrop(pTrans);
return 0;
-#endif
}
static int32_t mndRetrieveClusters(SRpcMsg *pMsg, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
diff --git a/source/dnode/mnode/impl/src/mndConsumer.c b/source/dnode/mnode/impl/src/mndConsumer.c
index c3eaeb73b2e21a7d26c7b260a7ebf43c87d707d1..1f8bf0699322ffdaad5c479b3c8fec3451645527 100644
--- a/source/dnode/mnode/impl/src/mndConsumer.c
+++ b/source/dnode/mnode/impl/src/mndConsumer.c
@@ -97,7 +97,7 @@ static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg) {
mndReleaseConsumer(pMnode, pConsumer);
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CONSUMER_LOST, pMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg);
if (pTrans == NULL) goto FAIL;
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
@@ -121,7 +121,7 @@ static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) {
mndReleaseConsumer(pMnode, pConsumer);
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CONSUMER_RECOVER, pMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg);
if (pTrans == NULL) goto FAIL;
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
@@ -306,6 +306,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
SMqTopicObj *pTopic = mndAcquireTopic(pMnode, topic);
ASSERT(pTopic);
taosRLockLatch(&pTopic->lock);
+ tstrncpy(topicEp.db, pTopic->db, TSDB_DB_FNAME_LEN);
topicEp.schema.nCols = pTopic->schema.nCols;
if (topicEp.schema.nCols) {
topicEp.schema.pSchema = taosMemoryCalloc(topicEp.schema.nCols, sizeof(SSchema));
@@ -403,7 +404,7 @@ static int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
int32_t newTopicNum = taosArrayGetSize(newSub);
// check topic existance
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_SUBSCRIBE, pMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg);
if (pTrans == NULL) goto SUBSCRIBE_OVER;
for (int32_t i = 0; i < newTopicNum; i++) {
diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c
index 99ac9c729c99f3874ce197b1692c46296a9bc4b5..c062a2c5523dd42ac5bcae27dc2863c058f8e374 100644
--- a/source/dnode/mnode/impl/src/mndDb.c
+++ b/source/dnode/mnode/impl/src/mndDb.c
@@ -261,7 +261,7 @@ void mndReleaseDb(SMnode *pMnode, SDbObj *pDb) {
sdbRelease(pSdb, pDb);
}
-static int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid) {
+static int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid, bool standby) {
STransAction action = {0};
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
@@ -270,7 +270,7 @@ static int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *p
mndReleaseDnode(pMnode, pDnode);
int32_t contLen = 0;
- void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
+ void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen, standby);
if (pReq == NULL) return -1;
action.pCont = pReq;
@@ -286,7 +286,7 @@ static int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *p
return 0;
}
-static int32_t mndAddAlterVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
+static int32_t mndAddAlterVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, tmsg_t msgType) {
STransAction action = {0};
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
@@ -296,7 +296,7 @@ static int32_t mndAddAlterVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pD
action.pCont = pReq;
action.contLen = contLen;
- action.msgType = TDMT_VND_ALTER_VNODE;
+ action.msgType = msgType;
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
taosMemoryFree(pReq);
@@ -388,7 +388,7 @@ static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) {
}
terrno = 0;
- return TSDB_CODE_SUCCESS;
+ return terrno;
}
static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
@@ -467,7 +467,7 @@ static int32_t mndSetCreateDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
for (int32_t vn = 0; vn < pVgroup->replica; ++vn) {
SVnodeGid *pVgid = pVgroup->vnodeGid + vn;
- if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pVgid) != 0) {
+ if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pVgid, false) != 0) {
return -1;
}
}
@@ -545,12 +545,12 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
}
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_DB, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create db:%s", pTrans->id, pCreate->db);
- mndTransSetDbInfo(pTrans, &dbObj);
+ mndTransSetDbName(pTrans, dbObj.name);
if (mndSetCreateDbRedoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
if (mndSetCreateDbUndoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
if (mndSetCreateDbCommitLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
@@ -688,29 +688,37 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) {
static int32_t mndSetAlterDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOld, SDbObj *pNew) {
SSdbRaw *pRedoRaw = mndDbActionEncode(pOld);
if (pRedoRaw == NULL) return -1;
- if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
- if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
+ if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
+ sdbFreeRaw(pRedoRaw);
+ return -1;
+ }
+ sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
return 0;
}
static int32_t mndSetAlterDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pOld, SDbObj *pNew) {
SSdbRaw *pCommitRaw = mndDbActionEncode(pNew);
if (pCommitRaw == NULL) return -1;
- if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1;
- if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1;
+ if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
+ sdbFreeRaw(pCommitRaw);
+ return -1;
+ }
+ sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY);
return 0;
}
static int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SArray *pArray) {
if (pVgroup->replica <= 0 || pVgroup->replica == pDb->cfg.replications) {
- if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, pVgroup) != 0) {
+ if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, pVgroup, TDMT_VND_ALTER_CONFIG) != 0) {
return -1;
}
} else {
SVgObj newVgroup = {0};
memcpy(&newVgroup, pVgroup, sizeof(SVgObj));
+ mndTransSetSerial(pTrans);
+
if (newVgroup.replica < pDb->cfg.replications) {
mInfo("db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId,
pVgroup->vnodeGid[0].dnodeId);
@@ -720,9 +728,9 @@ static int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj
return -1;
}
newVgroup.replica = pDb->cfg.replications;
- if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, &newVgroup) != 0) return -1;
- if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVgroup, &newVgroup.vnodeGid[1]) != 0) return -1;
- if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVgroup, &newVgroup.vnodeGid[2]) != 0) return -1;
+ if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVgroup, &newVgroup.vnodeGid[1], true) != 0) return -1;
+ if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, &newVgroup, &newVgroup.vnodeGid[2], true) != 0) return -1;
+ if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, &newVgroup, TDMT_VND_ALTER_REPLICA) != 0) return -1;
} else {
mInfo("db:%s, vgId:%d, will remove 2 vnodes", pVgroup->dbName, pVgroup->vgId);
@@ -733,15 +741,18 @@ static int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj
return -1;
}
newVgroup.replica = pDb->cfg.replications;
- if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, &newVgroup) != 0) return -1;
+ if (mndAddAlterVnodeAction(pMnode, pTrans, pDb, &newVgroup, TDMT_VND_ALTER_REPLICA) != 0) return -1;
if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVgroup, &del1, true) != 0) return -1;
if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVgroup, &del2, true) != 0) return -1;
}
SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup);
if (pVgRaw == NULL) return -1;
- if (mndTransAppendCommitlog(pTrans, pVgRaw) != 0) return -1;
- if (sdbSetRawStatus(pVgRaw, SDB_STATUS_READY) != 0) return -1;
+ if (mndTransAppendCommitlog(pTrans, pVgRaw) != 0) {
+ sdbFreeRaw(pVgRaw);
+ return -1;
+ }
+ sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
}
return 0;
@@ -774,18 +785,16 @@ static int32_t mndSetAlterDbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *
}
static int32_t mndAlterDb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pOld, SDbObj *pNew) {
- int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_ALTER_DB, pReq);
- if (pTrans == NULL) goto _OVER;
-
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq);
+ if (pTrans == NULL) return -1;
mDebug("trans:%d, used to alter db:%s", pTrans->id, pOld->name);
- mndTransSetDbInfo(pTrans, pOld);
+ int32_t code = -1;
+ mndTransSetDbName(pTrans, pOld->name);
if (mndSetAlterDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
if (mndSetAlterDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
if (mndSetAlterDbRedoActions(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
-
code = 0;
_OVER:
@@ -1036,11 +1045,11 @@ static int32_t mndBuildDropDbRsp(SDbObj *pDb, int32_t *pRspLen, void **ppRsp, bo
static int32_t mndDropDb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_DROP_DB, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop db:%s", pTrans->id, pDb->name);
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
@@ -1314,7 +1323,7 @@ int32_t mndValidateDbInfo(SMnode *pMnode, SDbVgVersion *pDbs, int32_t numOfDbs,
SDbObj *pDb = mndAcquireDb(pMnode, pDbVgVersion->dbFName);
if (pDb == NULL) {
- mDebug("db:%s, no exist", pDbVgVersion->dbFName);
+ mTrace("db:%s, no exist", pDbVgVersion->dbFName);
memcpy(usedbRsp.db, pDbVgVersion->dbFName, TSDB_DB_FNAME_LEN);
usedbRsp.uid = pDbVgVersion->dbId;
usedbRsp.vgVersion = -1;
diff --git a/source/dnode/mnode/impl/src/mndDef.c b/source/dnode/mnode/impl/src/mndDef.c
index 35ba25acd54abf39351e51cfea42152f41b57b9e..b6659e163223914682252b8986b95dcea133d732 100644
--- a/source/dnode/mnode/impl/src/mndDef.c
+++ b/source/dnode/mnode/impl/src/mndDef.c
@@ -395,10 +395,8 @@ SMqSubscribeObj *tCloneSubscribeObj(const SMqSubscribeObj *pSub) {
taosInitRWLatch(&pSubNew->lock);
pSubNew->dbUid = pSub->dbUid;
+ pSubNew->stbUid = pSub->stbUid;
pSubNew->subType = pSub->subType;
- pSubNew->withTbName = pSub->withTbName;
- pSubNew->withSchema = pSub->withSchema;
- pSubNew->withTag = pSub->withTag;
pSubNew->vgNum = pSub->vgNum;
pSubNew->consumerHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
@@ -431,9 +429,7 @@ int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
tlen += taosEncodeFixedI64(buf, pSub->dbUid);
tlen += taosEncodeFixedI32(buf, pSub->vgNum);
tlen += taosEncodeFixedI8(buf, pSub->subType);
- tlen += taosEncodeFixedI8(buf, pSub->withTbName);
- tlen += taosEncodeFixedI8(buf, pSub->withSchema);
- tlen += taosEncodeFixedI8(buf, pSub->withTag);
+ tlen += taosEncodeFixedI64(buf, pSub->stbUid);
void *pIter = NULL;
int32_t sz = taosHashGetSize(pSub->consumerHash);
@@ -458,9 +454,7 @@ void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub) {
buf = taosDecodeFixedI64(buf, &pSub->dbUid);
buf = taosDecodeFixedI32(buf, &pSub->vgNum);
buf = taosDecodeFixedI8(buf, &pSub->subType);
- buf = taosDecodeFixedI8(buf, &pSub->withTbName);
- buf = taosDecodeFixedI8(buf, &pSub->withSchema);
- buf = taosDecodeFixedI8(buf, &pSub->withTag);
+ buf = taosDecodeFixedI64(buf, &pSub->stbUid);
int32_t sz;
buf = taosDecodeFixedI32(buf, &sz);
diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c
index 22f858c60bdbfd56652570195b89cbf3f207651a..aeff018aa82da7216e21bb46270a6bbb8c3ead7a 100644
--- a/source/dnode/mnode/impl/src/mndDnode.c
+++ b/source/dnode/mnode/impl/src/mndDnode.c
@@ -17,6 +17,7 @@
#include "mndDnode.h"
#include "mndAuth.h"
#include "mndMnode.h"
+#include "mndQnode.h"
#include "mndShow.h"
#include "mndTrans.h"
#include "mndUser.h"
@@ -98,12 +99,9 @@ static int32_t mndCreateDefaultDnode(SMnode *pMnode) {
if (pRaw == NULL) return -1;
if (sdbSetRawStatus(pRaw, SDB_STATUS_READY) != 0) return -1;
- mDebug("dnode:%d, will be created while deploy sdb, raw:%p", dnodeObj.id, pRaw);
+ mDebug("dnode:%d, will be created when deploying, raw:%p", dnodeObj.id, pRaw);
-#if 0
- return sdbWrite(pMnode->pSdb, pRaw);
-#else
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_DNODE, NULL);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, NULL);
if (pTrans == NULL) {
mError("dnode:%s, failed to create since %s", dnodeObj.ep, terrstr());
return -1;
@@ -125,7 +123,6 @@ static int32_t mndCreateDefaultDnode(SMnode *pMnode) {
mndTransDrop(pTrans);
return 0;
-#endif
}
static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) {
@@ -259,7 +256,7 @@ int32_t mndGetDnodeSize(SMnode *pMnode) {
bool mndIsDnodeOnline(SMnode *pMnode, SDnodeObj *pDnode, int64_t curMs) {
int64_t interval = TABS(pDnode->lastAccessTime - curMs);
- if (interval > 30000 * tsStatusInterval) {
+ if (interval > 5000 * tsStatusInterval) {
if (pDnode->rebootTime > 0) {
pDnode->offlineReason = DND_REASON_STATUS_MSG_TIMEOUT;
}
@@ -388,9 +385,16 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
mndReleaseMnode(pMnode, pObj);
}
+ SQnodeObj *pQnode = mndAcquireQnode(pMnode, statusReq.qload.dnodeId);
+ if (pQnode != NULL) {
+ pQnode->load = statusReq.qload;
+ mndReleaseQnode(pMnode, pQnode);
+ }
+
+ int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
int64_t curMs = taosGetTimestampMs();
bool online = mndIsDnodeOnline(pMnode, pDnode, curMs);
- bool dnodeChanged = (statusReq.dnodeVer != sdbGetTableVer(pMnode->pSdb, SDB_DNODE));
+ bool dnodeChanged = (statusReq.dnodeVer != dnodeVer);
bool reboot = (pDnode->rebootTime != statusReq.rebootTime);
bool needCheck = !online || dnodeChanged || reboot;
@@ -433,7 +437,8 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
if (!online) {
mInfo("dnode:%d, from offline to online", pDnode->id);
} else {
- mDebug("dnode:%d, send dnode eps", pDnode->id);
+ mDebug("dnode:%d, send dnode epset, online:%d ver:% " PRId64 ":%" PRId64 " reboot:%d", pDnode->id, online,
+ statusReq.dnodeVer, dnodeVer, reboot);
}
pDnode->rebootTime = statusReq.rebootTime;
@@ -441,7 +446,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
pDnode->numOfSupportVnodes = statusReq.numOfSupportVnodes;
SStatusRsp statusRsp = {0};
- statusRsp.dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
+ statusRsp.dnodeVer = dnodeVer;
statusRsp.dnodeCfg.dnodeId = pDnode->id;
statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
statusRsp.pDnodeEps = taosArrayInit(mndGetDnodeSize(pMnode), sizeof(SDnodeEp));
@@ -479,7 +484,7 @@ static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pC
memcpy(dnodeObj.fqdn, pCreate->fqdn, TSDB_FQDN_LEN);
snprintf(dnodeObj.ep, TSDB_EP_LEN, "%s:%u", dnodeObj.fqdn, dnodeObj.port);
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_DNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq);
if (pTrans == NULL) {
mError("dnode:%s, failed to create since %s", dnodeObj.ep, terrstr());
return -1;
@@ -555,7 +560,7 @@ CREATE_DNODE_OVER:
}
static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode) {
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_DNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq);
if (pTrans == NULL) {
mError("dnode:%d, failed to drop since %s", pDnode->id, terrstr());
return -1;
@@ -608,7 +613,7 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId);
if (pMObj != NULL) {
- terrno = TSDB_CODE_MND_MNODE_DEPLOYED;
+ terrno = TSDB_CODE_MND_MNODE_NOT_EXIST;
goto DROP_DNODE_OVER;
}
diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c
index 9107dab693d4c9eb6adc6599d03126d5a59a5a69..bf4baebd8584bd8324f3e4e53836bbd8a2002fad 100644
--- a/source/dnode/mnode/impl/src/mndFunc.c
+++ b/source/dnode/mnode/impl/src/mndFunc.c
@@ -215,7 +215,7 @@ static int32_t mndCreateFunc(SMnode *pMnode, SRpcMsg *pReq, SCreateFuncReq *pCre
}
memcpy(func.pCode, pCreate->pCode, func.codeSize);
- pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_FUNC, pReq);
+ pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create func:%s", pTrans->id, pCreate->name);
@@ -245,7 +245,7 @@ _OVER:
static int32_t mndDropFunc(SMnode *pMnode, SRpcMsg *pReq, SFuncObj *pFunc) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_FUNC, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop user:%s", pTrans->id, pFunc->name);
diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c
index 0ac36c20ed3463a5bd9e794c83edab22b1675408..3a3fd7ebdb5ac8f56a64ea5b0169dfeda8cd3b97 100644
--- a/source/dnode/mnode/impl/src/mndMain.c
+++ b/source/dnode/mnode/impl/src/mndMain.c
@@ -369,7 +369,7 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) {
mError("failed to process sync msg:%p type:%s since %s", pMsg, TMSG_INFO(pMsg->msgType), terrstr());
return TAOS_SYNC_PROPOSE_OTHER_ERROR;
}
-
+
char logBuf[512] = {0};
char *syncNodeStr = sync2SimpleStr(pMgmt->sync);
snprintf(logBuf, sizeof(logBuf), "==vnodeProcessSyncReq== msgType:%d, syncNode: %s", pMsg->msgType, syncNodeStr);
@@ -686,4 +686,4 @@ void mndReleaseSyncRef(SMnode *pMnode) {
int32_t ref = atomic_sub_fetch_32(&pMnode->syncRef, 1);
mTrace("mnode sync is released, ref:%d", ref);
taosThreadRwlockUnlock(&pMnode->lock);
-}
\ No newline at end of file
+}
diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c
index 23634be77b3ca6f21f31019275353de12ab6c83b..7c94a33ffe10f93a6c809089f04bf704bcb6f676 100644
--- a/source/dnode/mnode/impl/src/mndMnode.c
+++ b/source/dnode/mnode/impl/src/mndMnode.c
@@ -18,9 +18,9 @@
#include "mndAuth.h"
#include "mndDnode.h"
#include "mndShow.h"
+#include "mndSync.h"
#include "mndTrans.h"
#include "mndUser.h"
-#include "mndSync.h"
#define MNODE_VER_NUMBER 1
#define MNODE_RESERVE_SIZE 64
@@ -90,12 +90,9 @@ static int32_t mndCreateDefaultMnode(SMnode *pMnode) {
if (pRaw == NULL) return -1;
sdbSetRawStatus(pRaw, SDB_STATUS_READY);
- mDebug("mnode:%d, will be created while deploy sdb, raw:%p", mnodeObj.id, pRaw);
+ mDebug("mnode:%d, will be created when deploying, raw:%p", mnodeObj.id, pRaw);
-#if 0
- return sdbWrite(pMnode->pSdb, pRaw);
-#else
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_DNODE, NULL);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, NULL);
if (pTrans == NULL) {
mError("mnode:%d, failed to create since %s", mnodeObj.id, terrstr());
return -1;
@@ -117,7 +114,6 @@ static int32_t mndCreateDefaultMnode(SMnode *pMnode) {
mndTransDrop(pTrans);
return 0;
-#endif
}
static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj) {
@@ -363,11 +359,11 @@ static int32_t mndCreateMnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
mnodeObj.createdTime = taosGetTimestampMs();
mnodeObj.updateTime = mnodeObj.createdTime;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_MNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId);
- mndTransSetExecOneByOne(pTrans);
+ mndTransSetSerial(pTrans);
if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER;
if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER;
if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) goto _OVER;
@@ -404,12 +400,22 @@ static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) {
goto _OVER;
}
+ if (sdbGetSize(pMnode->pSdb, SDB_MNODE) >= 3) {
+ terrno = TSDB_CODE_MND_TOO_MANY_MNODES;
+ goto _OVER;
+ }
+
pDnode = mndAcquireDnode(pMnode, createReq.dnodeId);
if (pDnode == NULL) {
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
goto _OVER;
}
+ if (!mndIsDnodeOnline(pMnode, pDnode, taosGetTimestampMs())) {
+ terrno = TSDB_CODE_NODE_OFFLINE;
+ goto _OVER;
+ }
+
pUser = mndAcquireUser(pMnode, pReq->conn.user);
if (pUser == NULL) {
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
@@ -535,11 +541,11 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode
static int32_t mndDropMnode(SMnode *pMnode, SRpcMsg *pReq, SMnodeObj *pObj) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_DROP_MNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id);
- mndTransSetExecOneByOne(pTrans);
+ mndTransSetSerial(pTrans);
if (mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj) != 0) goto _OVER;
if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) goto _OVER;
if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj) != 0) goto _OVER;
@@ -631,10 +637,12 @@ static int32_t mndRetrieveMnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB
int32_t numOfRows = 0;
int32_t cols = 0;
SMnodeObj *pObj = NULL;
+ ESdbStatus objStatus;
char *pWrite;
+ int64_t curMs = taosGetTimestampMs();
while (numOfRows < rows) {
- pShow->pIter = sdbFetch(pSdb, SDB_MNODE, pShow->pIter, (void **)&pObj);
+ pShow->pIter = sdbFetchAll(pSdb, SDB_MNODE, pShow->pIter, (void **)&pObj, &objStatus);
if (pShow->pIter == NULL) break;
cols = 0;
@@ -647,18 +655,26 @@ static int32_t mndRetrieveMnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, b1, false);
- const char *roles = NULL;
+ const char *roles = "OFFLINE";
if (pObj->id == pMnode->selfDnodeId) {
roles = syncStr(TAOS_SYNC_STATE_LEADER);
- } else {
+ }
+ if (pObj->pDnode && mndIsDnodeOnline(pMnode, pObj->pDnode, curMs)) {
roles = syncStr(pObj->state);
}
- char *b2 = taosMemoryCalloc(1, 12 + VARSTR_HEADER_SIZE);
+ char b2[12 + VARSTR_HEADER_SIZE] = {0};
STR_WITH_MAXSIZE_TO_VARSTR(b2, roles, pShow->pMeta->pSchemas[cols].bytes);
-
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)b2, false);
+ const char *status = "READY";
+ if (objStatus == SDB_STATUS_CREATING) status = "CREATING";
+ if (objStatus == SDB_STATUS_DROPPING) status = "DROPPING";
+ char b3[9 + VARSTR_HEADER_SIZE] = {0};
+ STR_WITH_MAXSIZE_TO_VARSTR(b3, status, pShow->pMeta->pSchemas[cols].bytes);
+ pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
+ colDataAppend(pColInfo, numOfRows, (const char *)b3, false);
+
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)&pObj->createdTime, false);
diff --git a/source/dnode/mnode/impl/src/mndOffset.c b/source/dnode/mnode/impl/src/mndOffset.c
index 6cbaca3c07818304417f05baed75fdeab70da5ca..00c8bb30d03d87545750b87d9eddab9efb8e821e 100644
--- a/source/dnode/mnode/impl/src/mndOffset.c
+++ b/source/dnode/mnode/impl/src/mndOffset.c
@@ -179,7 +179,7 @@ static int32_t mndProcessCommitOffsetReq(SRpcMsg *pMsg) {
tDecodeSMqCMCommitOffsetReq(&decoder, &commitOffsetReq);
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_COMMIT_OFFSET, pMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg);
for (int32_t i = 0; i < commitOffsetReq.num; i++) {
SMqOffset *pOffset = &commitOffsetReq.offsets[i];
diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c
index c9c52af0fe3ef377317530c26648c811d1112c95..bacdf2f3665fc144eec8320e68fc38fab330e34c 100644
--- a/source/dnode/mnode/impl/src/mndProfile.c
+++ b/source/dnode/mnode/impl/src/mndProfile.c
@@ -18,6 +18,7 @@
#include "mndDb.h"
#include "mndDnode.h"
#include "mndMnode.h"
+#include "mndQnode.h"
#include "mndShow.h"
#include "mndStb.h"
#include "mndUser.h"
@@ -382,6 +383,9 @@ static int32_t mndProcessQueryHeartBeat(SMnode *pMnode, SRpcMsg *pMsg, SClientHb
rspBasic->totalDnodes = mndGetDnodeSize(pMnode);
rspBasic->onlineDnodes = 1; // TODO
mndGetMnodeEpSet(pMnode, &rspBasic->epSet);
+
+ mndCreateQnodeList(pMnode, &rspBasic->pQnodeList, -1);
+
mndReleaseConn(pMnode, pConn);
hbRsp.query = rspBasic;
diff --git a/source/dnode/mnode/impl/src/mndQnode.c b/source/dnode/mnode/impl/src/mndQnode.c
index 3dc6200229b8a519fcf193393535500e98f4df20..27881865af11913b4a04c4fc84df115e98823fd1 100644
--- a/source/dnode/mnode/impl/src/mndQnode.c
+++ b/source/dnode/mnode/impl/src/mndQnode.c
@@ -60,7 +60,7 @@ int32_t mndInitQnode(SMnode *pMnode) {
void mndCleanupQnode(SMnode *pMnode) {}
-static SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId) {
+SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId) {
SQnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_QNODE, &qnodeId);
if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
terrno = TSDB_CODE_MND_QNODE_NOT_EXIST;
@@ -68,7 +68,7 @@ static SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId) {
return pObj;
}
-static void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj) {
+void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj) {
SSdb *pSdb = pMnode->pSdb;
sdbRelease(pSdb, pObj);
}
@@ -248,7 +248,7 @@ static int32_t mndCreateQnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
qnodeObj.createdTime = taosGetTimestampMs();
qnodeObj.updateTime = qnodeObj.createdTime;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_QNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create qnode:%d", pTrans->id, pCreate->dnodeId);
@@ -365,7 +365,7 @@ static int32_t mndSetDropQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQn
static int32_t mndDropQnode(SMnode *pMnode, SRpcMsg *pReq, SQnodeObj *pObj) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_DROP_QNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop qnode:%d", pTrans->id, pObj->id);
@@ -429,49 +429,62 @@ _OVER:
return code;
}
-static int32_t mndProcessQnodeListReq(SRpcMsg *pReq) {
- int32_t code = -1;
- int32_t numOfRows = 0;
- SMnode *pMnode = pReq->info.node;
- SSdb *pSdb = pMnode->pSdb;
+int32_t mndCreateQnodeList(SMnode *pMnode, SArray** pList, int32_t limit) {
+ SSdb *pSdb = pMnode->pSdb;
+ void *pIter = NULL;
SQnodeObj *pObj = NULL;
- SQnodeListReq qlistReq = {0};
- SQnodeListRsp qlistRsp = {0};
-
- if (tDeserializeSQnodeListReq(pReq->pCont, pReq->contLen, &qlistReq) != 0) {
- mError("failed to parse qnode list req");
- terrno = TSDB_CODE_INVALID_MSG;
- goto _OVER;
- }
+ int32_t numOfRows = 0;
- qlistRsp.addrsList = taosArrayInit(5, sizeof(SQueryNodeAddr));
- if (NULL == qlistRsp.addrsList) {
+ SArray* qnodeList = taosArrayInit(5, sizeof(SQueryNodeLoad));
+ if (NULL == qnodeList) {
mError("failed to alloc epSet while process qnode list req");
terrno = TSDB_CODE_OUT_OF_MEMORY;
- goto _OVER;
+ return terrno;
}
-
- void *pIter = NULL;
+
while (1) {
pIter = sdbFetch(pSdb, SDB_QNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
- SQueryNodeAddr nodeAddr = {0};
- nodeAddr.nodeId = QNODE_HANDLE;
- nodeAddr.epSet.numOfEps = 1;
- tstrncpy(nodeAddr.epSet.eps[0].fqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN);
- nodeAddr.epSet.eps[0].port = pObj->pDnode->port;
+ SQueryNodeLoad nodeLoad = {0};
+ nodeLoad.addr.nodeId = QNODE_HANDLE;
+ nodeLoad.addr.epSet.numOfEps = 1;
+ tstrncpy(nodeLoad.addr.epSet.eps[0].fqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN);
+ nodeLoad.addr.epSet.eps[0].port = pObj->pDnode->port;
+ nodeLoad.load = QNODE_LOAD_VALUE(pObj);
- (void)taosArrayPush(qlistRsp.addrsList, &nodeAddr);
+ (void)taosArrayPush(qnodeList, &nodeLoad);
numOfRows++;
sdbRelease(pSdb, pObj);
- if (qlistReq.rowNum > 0 && numOfRows >= qlistReq.rowNum) {
+ if (limit > 0 && numOfRows >= limit) {
break;
}
}
+ *pList = qnodeList;
+
+ return TSDB_CODE_SUCCESS;
+}
+
+
+static int32_t mndProcessQnodeListReq(SRpcMsg *pReq) {
+ int32_t code = -1;
+ SMnode *pMnode = pReq->info.node;
+ SQnodeListReq qlistReq = {0};
+ SQnodeListRsp qlistRsp = {0};
+
+ if (tDeserializeSQnodeListReq(pReq->pCont, pReq->contLen, &qlistReq) != 0) {
+ mError("failed to parse qnode list req");
+ terrno = TSDB_CODE_INVALID_MSG;
+ goto _OVER;
+ }
+
+ if (mndCreateQnodeList(pMnode, &qlistRsp.qnodeList, qlistReq.rowNum) != 0) {
+ goto _OVER;
+ }
+
int32_t rspLen = tSerializeSQnodeListRsp(NULL, 0, &qlistRsp);
void *pRsp = rpcMallocCont(rspLen);
if (pRsp == NULL) {
diff --git a/source/dnode/mnode/impl/src/mndScheduler.c b/source/dnode/mnode/impl/src/mndScheduler.c
index d1404b96fe09e51f2130cea5d0158a7435098f06..b390a7fe4a37bcb057fcc19837a58eb08d277799 100644
--- a/source/dnode/mnode/impl/src/mndScheduler.c
+++ b/source/dnode/mnode/impl/src/mndScheduler.c
@@ -36,7 +36,7 @@
extern bool tsStreamSchedV;
int32_t mndConvertRSmaTask(const char* ast, int64_t uid, int8_t triggerType, int64_t watermark, char** pStr,
- int32_t* pLen) {
+ int32_t* pLen, double filesFactor) {
SNode* pAst = NULL;
SQueryPlan* pPlan = NULL;
terrno = TSDB_CODE_SUCCESS;
@@ -58,6 +58,7 @@ int32_t mndConvertRSmaTask(const char* ast, int64_t uid, int8_t triggerType, int
.rSmaQuery = true,
.triggerType = triggerType,
.watermark = watermark,
+ .filesFactor = filesFactor,
};
if (qCreateQueryPlan(&cxt, &pPlan, NULL) < 0) {
terrno = TSDB_CODE_QRY_INVALID_INPUT;
@@ -506,7 +507,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
SQueryPlan* pPlan = NULL;
SSubplan* plan = NULL;
- if (pTopic->subType == TOPIC_SUB_TYPE__TABLE) {
+ if (pTopic->subType == TOPIC_SUB_TYPE__COLUMN) {
pPlan = qStringToQueryPlan(pTopic->physicalPlan);
if (pPlan == NULL) {
terrno = TSDB_CODE_QRY_INVALID_INPUT;
@@ -552,7 +553,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
mDebug("init subscription %s, assign vg: %d", pSub->key, pVgEp->vgId);
- if (pTopic->subType == TOPIC_SUB_TYPE__TABLE) {
+ if (pTopic->subType == TOPIC_SUB_TYPE__COLUMN) {
int32_t msgLen;
plan->execNode.epSet = pVgEp->epSet;
diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c
index 7b5d1b6c32eaf802eb0683a385acd85498b8a88d..6cb70d1f27895cd64f08fdb383f4072739e03f52 100644
--- a/source/dnode/mnode/impl/src/mndSma.c
+++ b/source/dnode/mnode/impl/src/mndSma.c
@@ -409,7 +409,8 @@ static int32_t mndSetCreateSmaRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
return 0;
}
-static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) {
+static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup,
+ SSmaObj *pSma) {
SVnodeGid *pVgid = pVgroup->vnodeGid + 0;
SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgid->dnodeId);
if (pDnode == NULL) return -1;
@@ -419,9 +420,14 @@ static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans,
mndReleaseDnode(pMnode, pDnode);
// todo add sma info here
+ int32_t smaContLen = 0;
+ void *pSmaReq = mndBuildVCreateSmaReq(pMnode, pVgroup, pSma, &smaContLen);
+ if (pSmaReq == NULL) return -1;
+ pVgroup->pTsma = pSmaReq;
int32_t contLen = 0;
- void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
+ void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen, false);
+ taosMemoryFreeClear(pSmaReq);
if (pReq == NULL) return -1;
action.pCont = pReq;
@@ -502,19 +508,19 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
streamObj.fixedSinkVgId = smaObj.dstVgId;
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_SMA, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create sma:%s", pTrans->id, pCreate->name);
- mndTransSetDbInfo(pTrans, pDb);
- mndTransSetExecOneByOne(pTrans);
+ mndTransSetDbName(pTrans, pDb->name);
+ mndTransSetSerial(pTrans);
if (mndSetCreateSmaRedoLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
if (mndSetCreateSmaVgroupRedoLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
if (mndSetCreateSmaCommitLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
if (mndSetCreateSmaVgroupCommitLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
if (mndSetCreateSmaRedoActions(pMnode, pTrans, pDb, &smaObj) != 0) goto _OVER;
- if (mndSetCreateSmaVgroupRedoActions(pMnode, pTrans, pDb, &streamObj.fixedSinkVg) != 0) goto _OVER;
+ if (mndSetCreateSmaVgroupRedoActions(pMnode, pTrans, pDb, &streamObj.fixedSinkVg, &smaObj) != 0) goto _OVER;
if (mndAddStreamToTrans(pMnode, &streamObj, pCreate->ast, STREAM_TRIGGER_AT_ONCE, 0, pTrans) != 0) goto _OVER;
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
@@ -747,11 +753,11 @@ static int32_t mndDropSma(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SSmaObj *p
pVgroup = mndAcquireVgroup(pMnode, pSma->dstVgId);
if (pVgroup == NULL) goto _OVER;
- pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_SMA, pReq);
+ pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop sma:%s", pTrans->id, pSma->name);
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
if (mndSetDropSmaRedoLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
if (mndSetDropSmaVgroupRedoLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
diff --git a/source/dnode/mnode/impl/src/mndSnode.c b/source/dnode/mnode/impl/src/mndSnode.c
index 87b61f59ecb088692941a9f57ebf89db2cefa054..c6acb4fef4a09ef78c561178f11428cb3004b4f3 100644
--- a/source/dnode/mnode/impl/src/mndSnode.c
+++ b/source/dnode/mnode/impl/src/mndSnode.c
@@ -253,7 +253,7 @@ static int32_t mndCreateSnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
snodeObj.createdTime = taosGetTimestampMs();
snodeObj.updateTime = snodeObj.createdTime;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_SNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create snode:%d", pTrans->id, pCreate->dnodeId);
@@ -372,7 +372,7 @@ static int32_t mndSetDropSnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SSn
static int32_t mndDropSnode(SMnode *pMnode, SRpcMsg *pReq, SSnodeObj *pObj) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_DROP_SNODE, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop snode:%d", pTrans->id, pObj->id);
diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c
index b33c09a0f9d0a4740a3b0b9ce9fb06dd5ea878ae..556837f397e0d9c09546d5fa9400654b44f39401 100644
--- a/source/dnode/mnode/impl/src/mndStb.c
+++ b/source/dnode/mnode/impl/src/mndStb.c
@@ -397,13 +397,13 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
req.pRSmaParam.xFilesFactor = pStb->xFilesFactor;
req.pRSmaParam.delay = pStb->delay;
if (pStb->ast1Len > 0) {
- if (mndConvertRSmaTask(pStb->pAst1, pStb->uid, 0, 0, &req.pRSmaParam.qmsg1, &req.pRSmaParam.qmsg1Len) !=
+ if (mndConvertRSmaTask(pStb->pAst1, pStb->uid, 0, 0, &req.pRSmaParam.qmsg1, &req.pRSmaParam.qmsg1Len, req.pRSmaParam.xFilesFactor) !=
TSDB_CODE_SUCCESS) {
return NULL;
}
}
if (pStb->ast2Len > 0) {
- if (mndConvertRSmaTask(pStb->pAst2, pStb->uid, 0, 0, &req.pRSmaParam.qmsg2, &req.pRSmaParam.qmsg2Len) !=
+ if (mndConvertRSmaTask(pStb->pAst2, pStb->uid, 0, 0, &req.pRSmaParam.qmsg2, &req.pRSmaParam.qmsg2Len, req.pRSmaParam.xFilesFactor) !=
TSDB_CODE_SUCCESS) {
return NULL;
}
@@ -735,7 +735,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_STB, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to create stb:%s", pTrans->id, pCreate->name);
@@ -754,7 +754,7 @@ _OVER:
}
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
@@ -1207,13 +1207,125 @@ static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj
return 0;
}
+
+static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
+ taosRLockLatch(&pStb->lock);
+
+ int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
+ pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
+ if (pRsp->pSchemas == NULL) {
+ taosRUnLockLatch(&pStb->lock);
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return -1;
+ }
+
+ strcpy(pRsp->dbFName, pStb->db);
+ strcpy(pRsp->tbName, tbName);
+ strcpy(pRsp->stbName, tbName);
+ pRsp->dbId = pDb->uid;
+ pRsp->numOfTags = pStb->numOfTags;
+ pRsp->numOfColumns = pStb->numOfColumns;
+ pRsp->precision = pDb->cfg.precision;
+ pRsp->tableType = TSDB_SUPER_TABLE;
+ pRsp->sversion = pStb->colVer;
+ pRsp->tversion = pStb->tagVer;
+ pRsp->suid = pStb->uid;
+ pRsp->tuid = pStb->uid;
+
+ for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
+ SSchema *pSchema = &pRsp->pSchemas[i];
+ SSchema *pSrcSchema = &pStb->pColumns[i];
+ memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
+ pSchema->type = pSrcSchema->type;
+ pSchema->colId = pSrcSchema->colId;
+ pSchema->bytes = pSrcSchema->bytes;
+ }
+
+ for (int32_t i = 0; i < pStb->numOfTags; ++i) {
+ SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
+ SSchema *pSrcSchema = &pStb->pTags[i];
+ memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
+ pSchema->type = pSrcSchema->type;
+ pSchema->colId = pSrcSchema->colId;
+ pSchema->bytes = pSrcSchema->bytes;
+ }
+
+ taosRUnLockLatch(&pStb->lock);
+ return 0;
+}
+
+static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
+ char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
+ snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
+
+ SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
+ if (pDb == NULL) {
+ terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
+ return -1;
+ }
+
+ SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
+ if (pStb == NULL) {
+ mndReleaseDb(pMnode, pDb);
+ terrno = TSDB_CODE_MND_INVALID_STB;
+ return -1;
+ }
+
+ int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
+ mndReleaseDb(pMnode, pDb);
+ mndReleaseStb(pMnode, pStb);
+ return code;
+}
+
+
+static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, const SMAlterStbReq *pAlter, SStbObj *pObj, void **pCont, int32_t *pLen) {
+ int ret;
+ SEncoder ec = {0};
+ uint32_t contLen = 0;
+ SMAlterStbRsp alterRsp = {0};
+ SName name = {0};
+ tNameFromString(&name, pAlter->name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
+
+ alterRsp.pMeta = taosMemoryCalloc(1, sizeof(STableMetaRsp));
+ if (NULL == alterRsp.pMeta) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return -1;
+ }
+
+ ret = mndBuildStbSchemaImp(pDb, pObj, name.tname, alterRsp.pMeta);
+ if (ret) {
+ tFreeSMAlterStbRsp(&alterRsp);
+ return ret;
+ }
+
+ tEncodeSize(tEncodeSMAlterStbRsp, &alterRsp, contLen, ret);
+ if (ret) {
+ tFreeSMAlterStbRsp(&alterRsp);
+ return ret;
+ }
+
+ void* cont = taosMemoryMalloc(contLen);
+ tEncoderInit(&ec, cont, contLen);
+ tEncodeSMAlterStbRsp(&ec, &alterRsp);
+ tEncoderClear(&ec);
+
+ tFreeSMAlterStbRsp(&alterRsp);
+
+ *pCont = cont;
+ *pLen = contLen;
+
+ return 0;
+}
+
static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *pAlter, SDbObj *pDb, SStbObj *pOld) {
+ bool needRsp = true;
SStbObj stbObj = {0};
taosRLockLatch(&pOld->lock);
memcpy(&stbObj, pOld, sizeof(SStbObj));
stbObj.pColumns = NULL;
stbObj.pTags = NULL;
stbObj.updateTime = taosGetTimestampMs();
+ stbObj.lock = 0;
taosRUnLockLatch(&pOld->lock);
int32_t code = -1;
@@ -1247,9 +1359,11 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p
code = mndAlterStbColumnBytes(pOld, &stbObj, pField0);
break;
case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
+ needRsp = false;
code = mndUpdateStbCommentAndTTL(pOld, &stbObj, pAlter->comment, pAlter->commentLen, pAlter->ttl);
break;
default:
+ needRsp = false;
terrno = TSDB_CODE_OPS_NOT_SUPPORT;
break;
}
@@ -1257,12 +1371,19 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p
if (code != 0) goto _OVER;
code = -1;
- pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_ALTER_STB, pReq);
+ pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to alter stb:%s", pTrans->id, pAlter->name);
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
+ if (needRsp) {
+ void* pCont = NULL;
+ int32_t contLen = 0;
+ if (mndBuildSMAlterStbRsp(pDb, pAlter, &stbObj, &pCont, &contLen)) goto _OVER;
+ mndTransSetRpcRsp(pTrans, pCont, contLen);
+ }
+
if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER;
@@ -1403,11 +1524,11 @@ static int32_t mndSetDropStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *
static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb) {
int32_t code = -1;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_STB, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
if (pTrans == NULL) goto _OVER;
mDebug("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
@@ -1483,75 +1604,6 @@ static int32_t mndProcessVDropStbRsp(SRpcMsg *pRsp) {
return 0;
}
-static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
- taosRLockLatch(&pStb->lock);
-
- int32_t totalCols = pStb->numOfColumns + pStb->numOfTags;
- pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema));
- if (pRsp->pSchemas == NULL) {
- taosRUnLockLatch(&pStb->lock);
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
-
- strcpy(pRsp->dbFName, pStb->db);
- strcpy(pRsp->tbName, tbName);
- strcpy(pRsp->stbName, tbName);
- pRsp->dbId = pDb->uid;
- pRsp->numOfTags = pStb->numOfTags;
- pRsp->numOfColumns = pStb->numOfColumns;
- pRsp->precision = pDb->cfg.precision;
- pRsp->tableType = TSDB_SUPER_TABLE;
- pRsp->sversion = pStb->colVer;
- pRsp->tversion = pStb->tagVer;
- pRsp->suid = pStb->uid;
- pRsp->tuid = pStb->uid;
-
- for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
- SSchema *pSchema = &pRsp->pSchemas[i];
- SSchema *pSrcSchema = &pStb->pColumns[i];
- memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
- pSchema->type = pSrcSchema->type;
- pSchema->colId = pSrcSchema->colId;
- pSchema->bytes = pSrcSchema->bytes;
- }
-
- for (int32_t i = 0; i < pStb->numOfTags; ++i) {
- SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns];
- SSchema *pSrcSchema = &pStb->pTags[i];
- memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN);
- pSchema->type = pSrcSchema->type;
- pSchema->colId = pSrcSchema->colId;
- pSchema->bytes = pSrcSchema->bytes;
- }
-
- taosRUnLockLatch(&pStb->lock);
- return 0;
-}
-
-static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp) {
- char tbFName[TSDB_TABLE_FNAME_LEN] = {0};
- snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName);
-
- SDbObj *pDb = mndAcquireDb(pMnode, dbFName);
- if (pDb == NULL) {
- terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
- return -1;
- }
-
- SStbObj *pStb = mndAcquireStb(pMnode, tbFName);
- if (pStb == NULL) {
- mndReleaseDb(pMnode, pDb);
- terrno = TSDB_CODE_MND_INVALID_STB;
- return -1;
- }
-
- int32_t code = mndBuildStbSchemaImp(pDb, pStb, tbName, pRsp);
- mndReleaseDb(pMnode, pDb);
- mndReleaseStb(pMnode, pStb);
- return code;
-}
-
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
int32_t code = -1;
@@ -1597,7 +1649,7 @@ static int32_t mndProcessTableMetaReq(SRpcMsg *pReq) {
pReq->info.rspLen = rspLen;
code = 0;
- mDebug("stb:%s.%s, meta is retrieved", infoReq.dbFName, infoReq.tbName);
+ mTrace("%s.%s, meta is retrieved", infoReq.dbFName, infoReq.tbName);
_OVER:
if (code != 0) {
diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c
index 13071b5c538a45f9339f4bc97fce9d9e3239a0f6..5ee5b06a578f7c31ab18f66f2de1cdef2aa85a04 100644
--- a/source/dnode/mnode/impl/src/mndStream.c
+++ b/source/dnode/mnode/impl/src/mndStream.c
@@ -402,7 +402,7 @@ static int32_t mndCreateStream(SMnode *pMnode, SRpcMsg *pReq, SCMCreateStreamReq
tstrncpy(streamObj.targetDb, pDb->name, TSDB_DB_FNAME_LEN);
}
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_STREAM, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("stream:%s, failed to create since %s", pCreate->name, terrstr());
return -1;
diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c
index f360f34e147148b44763ef44972cdf0e082da33b..41065a3fdd54d07cb75a65fba8e1da7bdd97d3a3 100644
--- a/source/dnode/mnode/impl/src/mndSubscribe.c
+++ b/source/dnode/mnode/impl/src/mndSubscribe.c
@@ -78,6 +78,7 @@ int32_t mndInitSubscribe(SMnode *pMnode) {
mndSetMsgHandle(pMnode, TDMT_MND_MQ_DO_REBALANCE, mndProcessRebalanceReq);
mndSetMsgHandle(pMnode, TDMT_MND_MQ_DO_REBALANCE, mndProcessRebalanceReq);
mndSetMsgHandle(pMnode, TDMT_MND_MQ_DROP_CGROUP, mndProcessDropCgroupReq);
+ mndSetMsgHandle(pMnode, TDMT_MND_MQ_DROP_CGROUP_RSP, mndProcessSubscribeInternalRsp);
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_SUBSCRIPTIONS, mndRetrieveSubscribe);
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_TOPICS, mndCancelGetNextSubscribe);
@@ -92,10 +93,8 @@ static SMqSubscribeObj *mndCreateSub(SMnode *pMnode, const SMqTopicObj *pTopic,
return NULL;
}
pSub->dbUid = pTopic->dbUid;
+ pSub->stbUid = pTopic->stbUid;
pSub->subType = pTopic->subType;
- pSub->withTbName = pTopic->withTbName;
- pSub->withSchema = pTopic->withSchema;
- pSub->withTag = pTopic->withTag;
ASSERT(pSub->unassignedVgs->size == 0);
ASSERT(taosHashGetSize(pSub->consumerHash) == 0);
@@ -120,9 +119,7 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
req.vgId = pRebVg->pVgEp->vgId;
req.qmsg = pRebVg->pVgEp->qmsg;
req.subType = pSub->subType;
- req.withTbName = pSub->withTbName;
- req.withSchema = pSub->withSchema;
- req.withTag = pSub->withTag;
+ req.suid = pSub->stbUid;
strncpy(req.subKey, pSub->key, TSDB_SUBSCRIBE_KEY_LEN);
int32_t tlen = sizeof(SMsgHead) + tEncodeSMqRebVgReq(NULL, &req);
@@ -393,8 +390,8 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
mInfo("rebalance calculation completed, rebalanced vg:");
for (int32_t i = 0; i < taosArrayGetSize(pOutput->rebVgs); i++) {
SMqRebOutputVg *pOutputRebVg = taosArrayGet(pOutput->rebVgs, i);
- mInfo("vg: %d moved from consumer %ld to consumer %ld", pOutputRebVg->pVgEp->vgId, pOutputRebVg->oldConsumerId,
- pOutputRebVg->newConsumerId);
+ mInfo("vgId:%d moved from consumer %" PRId64 " to consumer %" PRId64, pOutputRebVg->pVgEp->vgId,
+ pOutputRebVg->oldConsumerId, pOutputRebVg->newConsumerId);
}
// 9. clear
@@ -404,10 +401,9 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
}
static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOutputObj *pOutput) {
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_REBALANCE, pMsg);
- if (pTrans == NULL) {
- return -1;
- }
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg);
+ if (pTrans == NULL) return -1;
+
// make txn:
// 1. redo action: action to all vg
const SArray *rebVgs = pOutput->rebVgs;
@@ -501,7 +497,7 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
// 4. TODO commit log: modification log
// 5. set cb
- mndTransSetCb(pTrans, TRANS_START_FUNC_MQ_REB, TRANS_STOP_FUNC_TEST_MQ_REB, NULL, 0);
+ mndTransSetCb(pTrans, TRANS_START_FUNC_MQ_REB, TRANS_STOP_FUNC_MQ_REB, NULL, 0);
// 6. execution
if (mndTransPrepare(pMnode, pTrans) != 0) {
@@ -596,8 +592,8 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
}
static int32_t mndProcessDropCgroupReq(SRpcMsg *pReq) {
- SMnode *pMnode = pReq->info.node;
- /*SSdb *pSdb = pMnode->pSdb;*/
+ SMnode *pMnode = pReq->info.node;
+ SSdb *pSdb = pMnode->pSdb;
SMDropCgroupReq dropReq = {0};
if (tDeserializeSMDropCgroupReq(pReq->pCont, pReq->contLen, &dropReq) != 0) {
@@ -617,15 +613,17 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pReq) {
}
}
- if (taosHashGetSize(pSub->consumerHash) == 0) {
+ if (taosHashGetSize(pSub->consumerHash) != 0) {
terrno = TSDB_CODE_MND_CGROUP_USED;
mError("cgroup:%s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr());
+ mndReleaseSubscribe(pMnode, pSub);
return -1;
}
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_CGROUP, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("cgroup: %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr());
+ mndReleaseSubscribe(pMnode, pSub);
return -1;
}
@@ -633,14 +631,18 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pReq) {
if (mndDropOffsetBySubKey(pMnode, pTrans, pSub->key) < 0) {
ASSERT(0);
+ mndReleaseSubscribe(pMnode, pSub);
return -1;
}
if (mndSetDropSubCommitLogs(pMnode, pTrans, pSub) < 0) {
mError("cgroup %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr());
+ mndReleaseSubscribe(pMnode, pSub);
return -1;
}
+ mndTransPrepare(pMnode, pTrans);
+
mndReleaseSubscribe(pMnode, pSub);
return TSDB_CODE_ACTION_IN_PROGRESS;
diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c
index 8b602d796c47f29efa8dcfb059d2aff5b3b9de40..245f0938b906300af29bf3f6caf71c834877eaa1 100644
--- a/source/dnode/mnode/impl/src/mndSync.c
+++ b/source/dnode/mnode/impl/src/mndSync.c
@@ -65,7 +65,7 @@ int32_t mndSyncGetSnapshot(struct SSyncFSM *pFsm, SSnapshot *pSnapshot) {
void mndRestoreFinish(struct SSyncFSM *pFsm) {
SMnode *pMnode = pFsm->data;
if (!pMnode->deploy) {
- mInfo("mnode sync restore finished");
+ mInfo("mnode sync restore finished, and will handle outstanding transactions");
mndTransPullup(pMnode);
mndSetRestore(pMnode, true);
} else {
@@ -244,7 +244,7 @@ void mndSyncStart(SMnode *pMnode) {
} else {
syncStart(pMgmt->sync);
}
- mDebug("sync:%" PRId64 " is started, standby:%d", pMgmt->sync, pMgmt->standby);
+ mDebug("mnode sync started, id:%" PRId64 " standby:%d", pMgmt->sync, pMgmt->standby);
}
void mndSyncStop(SMnode *pMnode) {}
diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c
index 720233d625c0c20c169478e2a3a885dfa5a55f16..21b5e37e1ea5b1d5f534bae0efccd07d6f9115ae 100644
--- a/source/dnode/mnode/impl/src/mndTopic.c
+++ b/source/dnode/mnode/impl/src/mndTopic.c
@@ -96,11 +96,8 @@ SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic) {
SDB_SET_INT64(pRaw, dataPos, pTopic->dbUid, TOPIC_ENCODE_OVER);
SDB_SET_INT32(pRaw, dataPos, pTopic->version, TOPIC_ENCODE_OVER);
SDB_SET_INT8(pRaw, dataPos, pTopic->subType, TOPIC_ENCODE_OVER);
- SDB_SET_INT8(pRaw, dataPos, pTopic->withTbName, TOPIC_ENCODE_OVER);
- SDB_SET_INT8(pRaw, dataPos, pTopic->withSchema, TOPIC_ENCODE_OVER);
- SDB_SET_INT8(pRaw, dataPos, pTopic->withTag, TOPIC_ENCODE_OVER);
- SDB_SET_INT32(pRaw, dataPos, pTopic->consumerCnt, TOPIC_ENCODE_OVER);
+ SDB_SET_INT64(pRaw, dataPos, pTopic->stbUid, TOPIC_ENCODE_OVER);
SDB_SET_INT32(pRaw, dataPos, pTopic->sqlLen, TOPIC_ENCODE_OVER);
SDB_SET_BINARY(pRaw, dataPos, pTopic->sql, pTopic->sqlLen, TOPIC_ENCODE_OVER);
SDB_SET_INT32(pRaw, dataPos, pTopic->astLen, TOPIC_ENCODE_OVER);
@@ -122,8 +119,6 @@ SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic) {
SDB_SET_BINARY(pRaw, dataPos, swBuf, schemaLen, TOPIC_ENCODE_OVER);
}
- /*SDB_SET_INT32(pRaw, dataPos, pTopic->refConsumerCnt, TOPIC_ENCODE_OVER);*/
-
SDB_SET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_ENCODE_OVER);
SDB_SET_DATALEN(pRaw, dataPos, TOPIC_ENCODE_OVER);
@@ -168,12 +163,8 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) {
SDB_GET_INT64(pRaw, dataPos, &pTopic->dbUid, TOPIC_DECODE_OVER);
SDB_GET_INT32(pRaw, dataPos, &pTopic->version, TOPIC_DECODE_OVER);
SDB_GET_INT8(pRaw, dataPos, &pTopic->subType, TOPIC_DECODE_OVER);
- SDB_GET_INT8(pRaw, dataPos, &pTopic->withTbName, TOPIC_DECODE_OVER);
- SDB_GET_INT8(pRaw, dataPos, &pTopic->withSchema, TOPIC_DECODE_OVER);
- SDB_GET_INT8(pRaw, dataPos, &pTopic->withTag, TOPIC_DECODE_OVER);
-
- SDB_GET_INT32(pRaw, dataPos, &pTopic->consumerCnt, TOPIC_DECODE_OVER);
+ SDB_GET_INT64(pRaw, dataPos, &pTopic->stbUid, TOPIC_DECODE_OVER);
SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER);
pTopic->sql = taosMemoryCalloc(pTopic->sqlLen, sizeof(char));
if (pTopic->sql == NULL) {
@@ -222,8 +213,6 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) {
pTopic->schema.pSchema = NULL;
}
- /*SDB_GET_INT32(pRaw, dataPos, &pTopic->refConsumerCnt, TOPIC_DECODE_OVER);*/
-
SDB_GET_RESERVE(pRaw, dataPos, MND_TOPIC_RESERVE_SIZE, TOPIC_DECODE_OVER);
terrno = TSDB_CODE_SUCCESS;
@@ -254,8 +243,6 @@ static int32_t mndTopicActionUpdate(SSdb *pSdb, SMqTopicObj *pOldTopic, SMqTopic
atomic_exchange_64(&pOldTopic->updateTime, pNewTopic->updateTime);
atomic_exchange_32(&pOldTopic->version, pNewTopic->version);
- /*atomic_store_32(&pOldTopic->refConsumerCnt, pNewTopic->refConsumerCnt);*/
-
/*taosWLockLatch(&pOldTopic->lock);*/
// TODO handle update
@@ -278,18 +265,6 @@ void mndReleaseTopic(SMnode *pMnode, SMqTopicObj *pTopic) {
sdbRelease(pSdb, pTopic);
}
-#if 0
-static SDbObj *mndAcquireDbByTopic(SMnode *pMnode, char *topicName) {
- SName name = {0};
- tNameFromString(&name, topicName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
-
- char db[TSDB_TOPIC_FNAME_LEN] = {0};
- tNameGetFullDbName(&name, db);
-
- return mndAcquireDb(pMnode, db);
-}
-#endif
-
static SDDropTopicReq *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, SMqTopicObj *pTopic) {
int32_t contLen = sizeof(SDDropTopicReq);
@@ -308,11 +283,19 @@ static SDDropTopicReq *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, SMq
}
static int32_t mndCheckCreateTopicReq(SCMCreateTopicReq *pCreate) {
- if (pCreate->name[0] == 0 || pCreate->sql == NULL || pCreate->sql[0] == 0 || pCreate->subscribeDbName[0] == 0) {
- terrno = TSDB_CODE_MND_INVALID_TOPIC;
- return -1;
+ terrno = TSDB_CODE_MND_INVALID_TOPIC;
+
+ if (pCreate->sql == NULL) return -1;
+
+ if (pCreate->subType == TOPIC_SUB_TYPE__COLUMN) {
+ if (pCreate->ast == NULL || pCreate->ast[0] == 0) return -1;
+ } else if (pCreate->subType == TOPIC_SUB_TYPE__TABLE) {
+ if (pCreate->subStbName[0] == 0) return -1;
+ } else if (pCreate->subType == TOPIC_SUB_TYPE__DB) {
+ if (pCreate->subDbName[0] == 0) return -1;
}
+ terrno = TSDB_CODE_SUCCESS;
return 0;
}
@@ -328,14 +311,11 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
topicObj.version = 1;
topicObj.sql = strdup(pCreate->sql);
topicObj.sqlLen = strlen(pCreate->sql) + 1;
- /*topicObj.refConsumerCnt = 0;*/
+ topicObj.subType = pCreate->subType;
- if (pCreate->ast && pCreate->ast[0]) {
+ if (pCreate->subType == TOPIC_SUB_TYPE__COLUMN) {
topicObj.ast = strdup(pCreate->ast);
topicObj.astLen = strlen(pCreate->ast) + 1;
- topicObj.subType = TOPIC_SUB_TYPE__TABLE;
- topicObj.withTbName = pCreate->withTbName;
- topicObj.withSchema = pCreate->withSchema;
SNode *pAst = NULL;
if (nodesStringToNode(pCreate->ast, &pAst) != 0) {
@@ -368,16 +348,18 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
taosMemoryFree(topicObj.sql);
return -1;
}
- } else {
- topicObj.ast = NULL;
- topicObj.astLen = 0;
- topicObj.physicalPlan = NULL;
- topicObj.subType = TOPIC_SUB_TYPE__DB;
- topicObj.withTbName = 1;
- topicObj.withSchema = 1;
- }
-
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_TOPIC, pReq);
+ } else if (pCreate->subType == TOPIC_SUB_TYPE__TABLE) {
+ SStbObj *pStb = mndAcquireStb(pMnode, pCreate->subStbName);
+ topicObj.stbUid = pStb->uid;
+ }
+ /*} else if (pCreate->subType == TOPIC_SUB_TYPE__DB) {*/
+ /*topicObj.ast = NULL;*/
+ /*topicObj.astLen = 0;*/
+ /*topicObj.physicalPlan = NULL;*/
+ /*topicObj.withTbName = 1;*/
+ /*topicObj.withSchema = 1;*/
+
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("topic:%s, failed to create since %s", pCreate->name, terrstr());
taosMemoryFreeClear(topicObj.ast);
@@ -442,7 +424,7 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) {
goto CREATE_TOPIC_OVER;
}
- pDb = mndAcquireDb(pMnode, createTopicReq.subscribeDbName);
+ pDb = mndAcquireDb(pMnode, createTopicReq.subDbName);
if (pDb == NULL) {
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
goto CREATE_TOPIC_OVER;
@@ -545,7 +527,7 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
}
#endif
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_TOPIC, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("topic:%s, failed to drop since %s", pTopic->name, terrstr());
return -1;
diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c
index 9d392c64fb16199ae90568ed498bd4d49ec9c7a2..bbee59090d1600693478d38fec9ff47082bcc032 100644
--- a/source/dnode/mnode/impl/src/mndTrans.c
+++ b/source/dnode/mnode/impl/src/mndTrans.c
@@ -37,19 +37,18 @@ static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction);
static void mndTransDropLogs(SArray *pArray);
static void mndTransDropActions(SArray *pArray);
static void mndTransDropData(STrans *pTrans);
-static int32_t mndTransExecuteLogs(SMnode *pMnode, SArray *pArray);
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray);
static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans);
static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans);
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans);
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans);
-static int32_t mndTransExecuteCommitLogs(SMnode *pMnode, STrans *pTrans);
+static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans);
-static bool mndTransPerformCommitLogStage(SMnode *pMnode, STrans *pTrans);
+static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans);
static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans);
@@ -83,40 +82,30 @@ int32_t mndInitTrans(SMnode *pMnode) {
void mndCleanupTrans(SMnode *pMnode) {}
-static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
+static int32_t mndTransGetActionsSize(SArray *pArray) {
+ int32_t actionNum = taosArrayGetSize(pArray);
+ int32_t rawDataLen = 0;
- int32_t rawDataLen = sizeof(STrans) + TRANS_RESERVE_SIZE;
- int32_t redoLogNum = taosArrayGetSize(pTrans->redoLogs);
- int32_t undoLogNum = taosArrayGetSize(pTrans->undoLogs);
- int32_t commitLogNum = taosArrayGetSize(pTrans->commitLogs);
- int32_t redoActionNum = taosArrayGetSize(pTrans->redoActions);
- int32_t undoActionNum = taosArrayGetSize(pTrans->undoActions);
-
- for (int32_t i = 0; i < redoLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->redoLogs, i);
- rawDataLen += (sdbGetRawTotalSize(pTmp) + sizeof(int32_t));
- }
-
- for (int32_t i = 0; i < undoLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->undoLogs, i);
- rawDataLen += (sdbGetRawTotalSize(pTmp) + sizeof(int32_t));
+ for (int32_t i = 0; i < actionNum; ++i) {
+ STransAction *pAction = taosArrayGet(pArray, i);
+ if (pAction->actionType) {
+ rawDataLen += (sdbGetRawTotalSize(pAction->pRaw) + sizeof(int32_t));
+ } else {
+ rawDataLen += (sizeof(STransAction) + pAction->contLen);
+ }
+ rawDataLen += sizeof(pAction->actionType);
}
- for (int32_t i = 0; i < commitLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->commitLogs, i);
- rawDataLen += (sdbGetRawTotalSize(pTmp) + sizeof(int32_t));
- }
+ return rawDataLen;
+}
- for (int32_t i = 0; i < redoActionNum; ++i) {
- STransAction *pAction = taosArrayGet(pTrans->redoActions, i);
- rawDataLen += (sizeof(STransAction) + pAction->contLen);
- }
+static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
- for (int32_t i = 0; i < undoActionNum; ++i) {
- STransAction *pAction = taosArrayGet(pTrans->undoActions, i);
- rawDataLen += (sizeof(STransAction) + pAction->contLen);
- }
+ int32_t rawDataLen = sizeof(STrans) + TRANS_RESERVE_SIZE;
+ rawDataLen += mndTransGetActionsSize(pTrans->redoActions);
+ rawDataLen += mndTransGetActionsSize(pTrans->undoActions);
+ rawDataLen += mndTransGetActionsSize(pTrans->commitActions);
SSdbRaw *pRaw = sdbAllocRaw(SDB_TRANS, TRANS_VER_NUMBER, rawDataLen);
if (pRaw == NULL) {
@@ -126,67 +115,85 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
int32_t dataPos = 0;
SDB_SET_INT32(pRaw, dataPos, pTrans->id, _OVER)
-
- ETrnStage stage = pTrans->stage;
- if (stage == TRN_STAGE_REDO_LOG || stage == TRN_STAGE_REDO_ACTION) {
- stage = TRN_STAGE_PREPARE;
- } else if (stage == TRN_STAGE_UNDO_ACTION || stage == TRN_STAGE_UNDO_LOG) {
- stage = TRN_STAGE_ROLLBACK;
- } else if (stage == TRN_STAGE_COMMIT_LOG || stage == TRN_STAGE_FINISHED) {
- stage = TRN_STAGE_COMMIT;
- } else {
- }
-
- SDB_SET_INT16(pRaw, dataPos, stage, _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pTrans->stage, _OVER)
SDB_SET_INT16(pRaw, dataPos, pTrans->policy, _OVER)
- SDB_SET_INT16(pRaw, dataPos, pTrans->type, _OVER)
- SDB_SET_INT16(pRaw, dataPos, pTrans->parallel, _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pTrans->conflict, _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pTrans->exec, _OVER)
SDB_SET_INT64(pRaw, dataPos, pTrans->createdTime, _OVER)
- SDB_SET_INT64(pRaw, dataPos, pTrans->dbUid, _OVER)
SDB_SET_BINARY(pRaw, dataPos, pTrans->dbname, TSDB_DB_FNAME_LEN, _OVER)
- SDB_SET_INT32(pRaw, dataPos, redoLogNum, _OVER)
- SDB_SET_INT32(pRaw, dataPos, undoLogNum, _OVER)
- SDB_SET_INT32(pRaw, dataPos, commitLogNum, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pTrans->redoActionPos, _OVER)
+
+ int32_t redoActionNum = taosArrayGetSize(pTrans->redoActions);
+ int32_t undoActionNum = taosArrayGetSize(pTrans->undoActions);
+ int32_t commitActionNum = taosArrayGetSize(pTrans->commitActions);
SDB_SET_INT32(pRaw, dataPos, redoActionNum, _OVER)
SDB_SET_INT32(pRaw, dataPos, undoActionNum, _OVER)
-
- for (int32_t i = 0; i < redoLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->redoLogs, i);
- int32_t len = sdbGetRawTotalSize(pTmp);
- SDB_SET_INT32(pRaw, dataPos, len, _OVER)
- SDB_SET_BINARY(pRaw, dataPos, (void *)pTmp, len, _OVER)
- }
-
- for (int32_t i = 0; i < undoLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->undoLogs, i);
- int32_t len = sdbGetRawTotalSize(pTmp);
- SDB_SET_INT32(pRaw, dataPos, len, _OVER)
- SDB_SET_BINARY(pRaw, dataPos, (void *)pTmp, len, _OVER)
- }
-
- for (int32_t i = 0; i < commitLogNum; ++i) {
- SSdbRaw *pTmp = taosArrayGetP(pTrans->commitLogs, i);
- int32_t len = sdbGetRawTotalSize(pTmp);
- SDB_SET_INT32(pRaw, dataPos, len, _OVER)
- SDB_SET_BINARY(pRaw, dataPos, (void *)pTmp, len, _OVER)
- }
+ SDB_SET_INT32(pRaw, dataPos, commitActionNum, _OVER)
for (int32_t i = 0; i < redoActionNum; ++i) {
STransAction *pAction = taosArrayGet(pTrans->redoActions, i);
- SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
- SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
- SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
- SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
+ if (pAction->actionType) {
+ int32_t len = sdbGetRawTotalSize(pAction->pRaw);
+ SDB_SET_INT8(pRaw, dataPos, pAction->rawWritten, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, len, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
+ } else {
+ SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgSent, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgReceived, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
+ }
}
for (int32_t i = 0; i < undoActionNum; ++i) {
STransAction *pAction = taosArrayGet(pTrans->undoActions, i);
- SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
- SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
- SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
- SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pCont, pAction->contLen, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
+ if (pAction->actionType) {
+ int32_t len = sdbGetRawTotalSize(pAction->pRaw);
+ SDB_SET_INT8(pRaw, dataPos, pAction->rawWritten, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, len, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
+ } else {
+ SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgSent, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgReceived, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
+ }
+ }
+
+ for (int32_t i = 0; i < commitActionNum; ++i) {
+ STransAction *pAction = taosArrayGet(pTrans->commitActions, i);
+ SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
+ if (pAction->actionType) {
+ int32_t len = sdbGetRawTotalSize(pAction->pRaw);
+ SDB_SET_INT8(pRaw, dataPos, pAction->rawWritten, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, len, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
+ } else {
+ SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
+ SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgSent, _OVER)
+ SDB_SET_INT8(pRaw, dataPos, pAction->msgReceived, _OVER)
+ SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
+ SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
+ }
}
SDB_SET_INT32(pRaw, dataPos, pTrans->startFunc, _OVER)
@@ -220,11 +227,9 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
char *pData = NULL;
int32_t dataLen = 0;
int8_t sver = 0;
- int32_t redoLogNum = 0;
- int32_t undoLogNum = 0;
- int32_t commitLogNum = 0;
int32_t redoActionNum = 0;
int32_t undoActionNum = 0;
+ int32_t commitActionNum = 0;
int32_t dataPos = 0;
STransAction action = {0};
@@ -245,89 +250,116 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
int16_t stage = 0;
int16_t policy = 0;
- int16_t type = 0;
- int16_t parallel = 0;
+ int16_t conflict = 0;
+ int16_t exec = 0;
SDB_GET_INT16(pRaw, dataPos, &stage, _OVER)
SDB_GET_INT16(pRaw, dataPos, &policy, _OVER)
- SDB_GET_INT16(pRaw, dataPos, &type, _OVER)
- SDB_GET_INT16(pRaw, dataPos, ¶llel, _OVER)
+ SDB_GET_INT16(pRaw, dataPos, &conflict, _OVER)
+ SDB_GET_INT16(pRaw, dataPos, &exec, _OVER)
pTrans->stage = stage;
pTrans->policy = policy;
- pTrans->type = type;
- pTrans->parallel = parallel;
+ pTrans->conflict = conflict;
+ pTrans->exec = exec;
SDB_GET_INT64(pRaw, dataPos, &pTrans->createdTime, _OVER)
- SDB_GET_INT64(pRaw, dataPos, &pTrans->dbUid, _OVER)
SDB_GET_BINARY(pRaw, dataPos, pTrans->dbname, TSDB_DB_FNAME_LEN, _OVER)
- SDB_GET_INT32(pRaw, dataPos, &redoLogNum, _OVER)
- SDB_GET_INT32(pRaw, dataPos, &undoLogNum, _OVER)
- SDB_GET_INT32(pRaw, dataPos, &commitLogNum, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &pTrans->redoActionPos, _OVER)
SDB_GET_INT32(pRaw, dataPos, &redoActionNum, _OVER)
SDB_GET_INT32(pRaw, dataPos, &undoActionNum, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &commitActionNum, _OVER)
- pTrans->redoLogs = taosArrayInit(redoLogNum, sizeof(void *));
- pTrans->undoLogs = taosArrayInit(undoLogNum, sizeof(void *));
- pTrans->commitLogs = taosArrayInit(commitLogNum, sizeof(void *));
pTrans->redoActions = taosArrayInit(redoActionNum, sizeof(STransAction));
pTrans->undoActions = taosArrayInit(undoActionNum, sizeof(STransAction));
+ pTrans->commitActions = taosArrayInit(commitActionNum, sizeof(STransAction));
- if (pTrans->redoLogs == NULL) goto _OVER;
- if (pTrans->undoLogs == NULL) goto _OVER;
- if (pTrans->commitLogs == NULL) goto _OVER;
if (pTrans->redoActions == NULL) goto _OVER;
if (pTrans->undoActions == NULL) goto _OVER;
-
- for (int32_t i = 0; i < redoLogNum; ++i) {
- SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
- pData = taosMemoryMalloc(dataLen);
- if (pData == NULL) goto _OVER;
- mTrace("raw:%p, is created", pData);
- SDB_GET_BINARY(pRaw, dataPos, pData, dataLen, _OVER);
- if (taosArrayPush(pTrans->redoLogs, &pData) == NULL) goto _OVER;
- pData = NULL;
- }
-
- for (int32_t i = 0; i < undoLogNum; ++i) {
- SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
- pData = taosMemoryMalloc(dataLen);
- if (pData == NULL) goto _OVER;
- mTrace("raw:%p, is created", pData);
- SDB_GET_BINARY(pRaw, dataPos, pData, dataLen, _OVER);
- if (taosArrayPush(pTrans->undoLogs, &pData) == NULL) goto _OVER;
- pData = NULL;
- }
-
- for (int32_t i = 0; i < commitLogNum; ++i) {
- SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
- pData = taosMemoryMalloc(dataLen);
- if (pData == NULL) goto _OVER;
- mTrace("raw:%p, is created", pData);
- SDB_GET_BINARY(pRaw, dataPos, pData, dataLen, _OVER);
- if (taosArrayPush(pTrans->commitLogs, &pData) == NULL) goto _OVER;
- pData = NULL;
- }
+ if (pTrans->commitActions == NULL) goto _OVER;
for (int32_t i = 0; i < redoActionNum; ++i) {
- SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
- SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
- SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
- action.pCont = taosMemoryMalloc(action.contLen);
- if (action.pCont == NULL) goto _OVER;
- SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
- if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
- action.pCont = NULL;
+ SDB_GET_INT8(pRaw, dataPos, &action.actionType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.stage, _OVER)
+ if (action.actionType) {
+ SDB_GET_INT8(pRaw, dataPos, &action.rawWritten, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
+ action.pRaw = taosMemoryMalloc(dataLen);
+ if (action.pRaw == NULL) goto _OVER;
+ mTrace("raw:%p, is created", pData);
+ SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
+ if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
+ action.pRaw = NULL;
+ } else {
+ SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
+ SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgSent, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgReceived, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
+ action.pCont = taosMemoryMalloc(action.contLen);
+ if (action.pCont == NULL) goto _OVER;
+ SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
+ if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
+ action.pCont = NULL;
+ }
}
for (int32_t i = 0; i < undoActionNum; ++i) {
- SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
- SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
- SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
- action.pCont = taosMemoryMalloc(action.contLen);
- if (action.pCont == NULL) goto _OVER;
- SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
- if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
- action.pCont = NULL;
+ SDB_GET_INT8(pRaw, dataPos, &action.actionType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.stage, _OVER)
+ if (action.actionType) {
+ SDB_GET_INT8(pRaw, dataPos, &action.rawWritten, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
+ action.pRaw = taosMemoryMalloc(dataLen);
+ if (action.pRaw == NULL) goto _OVER;
+ mTrace("raw:%p, is created", pData);
+ SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
+ if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
+ action.pRaw = NULL;
+ } else {
+ SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
+ SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgSent, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgReceived, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
+ action.pCont = taosMemoryMalloc(action.contLen);
+ if (action.pCont == NULL) goto _OVER;
+ SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
+ if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
+ action.pCont = NULL;
+ }
+ }
+
+ for (int32_t i = 0; i < commitActionNum; ++i) {
+ SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.actionType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.stage, _OVER)
+ if (action.actionType) {
+ SDB_GET_INT8(pRaw, dataPos, &action.rawWritten, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
+ action.pRaw = taosMemoryMalloc(dataLen);
+ if (action.pRaw == NULL) goto _OVER;
+ mTrace("raw:%p, is created", action.pRaw);
+ SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
+ if (taosArrayPush(pTrans->commitActions, &action) == NULL) goto _OVER;
+ action.pRaw = NULL;
+ } else {
+ SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
+ SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgSent, _OVER)
+ SDB_GET_INT8(pRaw, dataPos, &action.msgReceived, _OVER)
+ SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
+ action.pCont = taosMemoryMalloc(action.contLen);
+ if (action.pCont == NULL) goto _OVER;
+ SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
+ if (taosArrayPush(pTrans->commitActions, &action) == NULL) goto _OVER;
+ action.pCont = NULL;
+ }
}
SDB_GET_INT32(pRaw, dataPos, &pTrans->startFunc, _OVER)
@@ -347,7 +379,6 @@ _OVER:
mError("trans:%d, failed to parse from raw:%p since %s", pTrans->id, pRaw, terrstr());
mndTransDropData(pTrans);
taosMemoryFreeClear(pRow);
- taosMemoryFreeClear(pData);
taosMemoryFreeClear(action.pCont);
return NULL;
}
@@ -360,20 +391,16 @@ static const char *mndTransStr(ETrnStage stage) {
switch (stage) {
case TRN_STAGE_PREPARE:
return "prepare";
- case TRN_STAGE_REDO_LOG:
- return "redoLog";
case TRN_STAGE_REDO_ACTION:
return "redoAction";
- case TRN_STAGE_COMMIT:
- return "commit";
- case TRN_STAGE_COMMIT_LOG:
- return "commitLog";
- case TRN_STAGE_UNDO_ACTION:
- return "undoAction";
- case TRN_STAGE_UNDO_LOG:
- return "undoLog";
case TRN_STAGE_ROLLBACK:
return "rollback";
+ case TRN_STAGE_UNDO_ACTION:
+ return "undoAction";
+ case TRN_STAGE_COMMIT:
+ return "commit";
+ case TRN_STAGE_COMMIT_ACTION:
+ return "commitAction";
case TRN_STAGE_FINISHED:
return "finished";
default:
@@ -381,81 +408,6 @@ static const char *mndTransStr(ETrnStage stage) {
}
}
-static const char *mndTransType(ETrnType type) {
- switch (type) {
- case TRN_TYPE_CREATE_USER:
- return "create-user";
- case TRN_TYPE_ALTER_USER:
- return "alter-user";
- case TRN_TYPE_DROP_USER:
- return "drop-user";
- case TRN_TYPE_CREATE_FUNC:
- return "create-func";
- case TRN_TYPE_DROP_FUNC:
- return "drop-func";
- case TRN_TYPE_CREATE_SNODE:
- return "create-snode";
- case TRN_TYPE_DROP_SNODE:
- return "drop-snode";
- case TRN_TYPE_CREATE_QNODE:
- return "create-qnode";
- case TRN_TYPE_DROP_QNODE:
- return "drop-qnode";
- case TRN_TYPE_CREATE_BNODE:
- return "create-bnode";
- case TRN_TYPE_DROP_BNODE:
- return "drop-bnode";
- case TRN_TYPE_CREATE_MNODE:
- return "create-mnode";
- case TRN_TYPE_DROP_MNODE:
- return "drop-mnode";
- case TRN_TYPE_CREATE_TOPIC:
- return "create-topic";
- case TRN_TYPE_DROP_TOPIC:
- return "drop-topic";
- case TRN_TYPE_SUBSCRIBE:
- return "subscribe";
- case TRN_TYPE_REBALANCE:
- return "rebalance";
- case TRN_TYPE_COMMIT_OFFSET:
- return "commit-offset";
- case TRN_TYPE_CREATE_STREAM:
- return "create-stream";
- case TRN_TYPE_DROP_STREAM:
- return "drop-stream";
- case TRN_TYPE_CONSUMER_LOST:
- return "consumer-lost";
- case TRN_TYPE_CONSUMER_RECOVER:
- return "consumer-recover";
- case TRN_TYPE_CREATE_DNODE:
- return "create-qnode";
- case TRN_TYPE_DROP_DNODE:
- return "drop-qnode";
- case TRN_TYPE_CREATE_DB:
- return "create-db";
- case TRN_TYPE_ALTER_DB:
- return "alter-db";
- case TRN_TYPE_DROP_DB:
- return "drop-db";
- case TRN_TYPE_SPLIT_VGROUP:
- return "split-vgroup";
- case TRN_TYPE_MERGE_VGROUP:
- return "merge-vgroup";
- case TRN_TYPE_CREATE_STB:
- return "create-stb";
- case TRN_TYPE_ALTER_STB:
- return "alter-stb";
- case TRN_TYPE_DROP_STB:
- return "drop-stb";
- case TRN_TYPE_CREATE_SMA:
- return "create-sma";
- case TRN_TYPE_DROP_SMA:
- return "drop-sma";
- default:
- return "invalid";
- }
-}
-
static void mndTransTestStartFunc(SMnode *pMnode, void *param, int32_t paramLen) {
mInfo("test trans start, param:%s, len:%d", (char *)param, paramLen);
}
@@ -472,7 +424,7 @@ static TransCbFp mndTransGetCbFp(ETrnFunc ftype) {
return mndTransTestStopFunc;
case TRANS_START_FUNC_MQ_REB:
return mndRebCntInc;
- case TRANS_STOP_FUNC_TEST_MQ_REB:
+ case TRANS_STOP_FUNC_MQ_REB:
return mndRebCntDec;
default:
return NULL;
@@ -493,11 +445,9 @@ static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans) {
}
static void mndTransDropData(STrans *pTrans) {
- mndTransDropLogs(pTrans->redoLogs);
- mndTransDropLogs(pTrans->undoLogs);
- mndTransDropLogs(pTrans->commitLogs);
mndTransDropActions(pTrans->redoActions);
mndTransDropActions(pTrans->undoActions);
+ mndTransDropActions(pTrans->commitActions);
if (pTrans->rpcRsp != NULL) {
taosMemoryFree(pTrans->rpcRsp);
pTrans->rpcRsp = NULL;
@@ -511,7 +461,7 @@ static void mndTransDropData(STrans *pTrans) {
}
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) {
- mDebug("trans:%d, perform delete action, row:%p stage:%s callfunc:%d", pTrans->id, pTrans, mndTransStr(pTrans->stage),
+ mTrace("trans:%d, perform delete action, row:%p stage:%s callfunc:%d", pTrans->id, pTrans, mndTransStr(pTrans->stage),
callFunc);
if (pTrans->stopFunc > 0 && callFunc) {
TransCbFp fp = mndTransGetCbFp(pTrans->stopFunc);
@@ -524,20 +474,35 @@ static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) {
return 0;
}
-static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
- if (pNew->stage == TRN_STAGE_COMMIT) {
- pNew->stage = TRN_STAGE_COMMIT_LOG;
- mTrace("trans:%d, stage from %s to %s", pNew->id, mndTransStr(TRN_STAGE_COMMIT), mndTransStr(TRN_STAGE_COMMIT_LOG));
- }
-
- if (pNew->stage == TRN_STAGE_ROLLBACK) {
- pNew->stage = TRN_STAGE_FINISHED;
- mTrace("trans:%d, stage from %s to %s", pNew->id, mndTransStr(TRN_STAGE_ROLLBACK), mndTransStr(TRN_STAGE_FINISHED));
+static void mndTransUpdateActions(SArray *pOldArray, SArray *pNewArray) {
+ for (int32_t i = 0; i < taosArrayGetSize(pOldArray); ++i) {
+ STransAction *pOldAction = taosArrayGet(pOldArray, i);
+ STransAction *pNewAction = taosArrayGet(pNewArray, i);
+ pOldAction->rawWritten = pNewAction->rawWritten;
+ pOldAction->msgSent = pNewAction->msgSent;
+ pOldAction->msgReceived = pNewAction->msgReceived;
+ pOldAction->errCode = pNewAction->errCode;
}
+}
+static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
mTrace("trans:%d, perform update action, old row:%p stage:%s, new row:%p stage:%s", pOld->id, pOld,
mndTransStr(pOld->stage), pNew, mndTransStr(pNew->stage));
+ mndTransUpdateActions(pOld->redoActions, pNew->redoActions);
+ mndTransUpdateActions(pOld->undoActions, pNew->undoActions);
+ mndTransUpdateActions(pOld->commitActions, pNew->commitActions);
pOld->stage = pNew->stage;
+ pOld->redoActionPos = pNew->redoActionPos;
+
+ if (pOld->stage == TRN_STAGE_COMMIT) {
+ pOld->stage = TRN_STAGE_COMMIT_ACTION;
+ mTrace("trans:%d, stage from commit to commitAction", pNew->id);
+ }
+
+ if (pOld->stage == TRN_STAGE_ROLLBACK) {
+ pOld->stage = TRN_STAGE_FINISHED;
+ mTrace("trans:%d, stage from rollback to finished", pNew->id);
+ }
return 0;
}
@@ -554,7 +519,7 @@ void mndReleaseTrans(SMnode *pMnode, STrans *pTrans) {
sdbRelease(pSdb, pTrans);
}
-STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnType type, const SRpcMsg *pReq) {
+STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnConflct conflict, const SRpcMsg *pReq) {
STrans *pTrans = taosMemoryCalloc(1, sizeof(STrans));
if (pTrans == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
@@ -565,41 +530,33 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnType type, const S
pTrans->id = sdbGetMaxId(pMnode->pSdb, SDB_TRANS);
pTrans->stage = TRN_STAGE_PREPARE;
pTrans->policy = policy;
- pTrans->type = type;
+ pTrans->conflict = conflict;
+ pTrans->exec = TRN_EXEC_PRARLLEL;
pTrans->createdTime = taosGetTimestampMs();
- if (pReq != NULL) pTrans->rpcInfo = pReq->info;
- pTrans->redoLogs = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(void *));
- pTrans->undoLogs = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(void *));
- pTrans->commitLogs = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(void *));
pTrans->redoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
pTrans->undoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
+ pTrans->commitActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
- if (pTrans->redoLogs == NULL || pTrans->undoLogs == NULL || pTrans->commitLogs == NULL ||
- pTrans->redoActions == NULL || pTrans->undoActions == NULL) {
+ if (pTrans->redoActions == NULL || pTrans->undoActions == NULL || pTrans->commitActions == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
mError("failed to create transaction since %s", terrstr());
return NULL;
}
- mDebug("trans:%d, local object is created, data:%p", pTrans->id, pTrans);
+ if (pReq != NULL) pTrans->rpcInfo = pReq->info;
+ mTrace("trans:%d, local object is created, data:%p", pTrans->id, pTrans);
return pTrans;
}
-static void mndTransDropLogs(SArray *pArray) {
- int32_t size = taosArrayGetSize(pArray);
- for (int32_t i = 0; i < size; ++i) {
- SSdbRaw *pRaw = taosArrayGetP(pArray, i);
- sdbFreeRaw(pRaw);
- }
-
- taosArrayDestroy(pArray);
-}
-
static void mndTransDropActions(SArray *pArray) {
int32_t size = taosArrayGetSize(pArray);
for (int32_t i = 0; i < size; ++i) {
STransAction *pAction = taosArrayGet(pArray, i);
- taosMemoryFreeClear(pAction->pCont);
+ if (pAction->actionType) {
+ taosMemoryFreeClear(pAction->pRaw);
+ } else {
+ taosMemoryFreeClear(pAction->pCont);
+ }
}
taosArrayDestroy(pArray);
@@ -608,18 +565,15 @@ static void mndTransDropActions(SArray *pArray) {
void mndTransDrop(STrans *pTrans) {
if (pTrans != NULL) {
mndTransDropData(pTrans);
- mDebug("trans:%d, local object is freed, data:%p", pTrans->id, pTrans);
+ mTrace("trans:%d, local object is freed, data:%p", pTrans->id, pTrans);
taosMemoryFreeClear(pTrans);
}
}
-static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw) {
- if (pArray == NULL || pRaw == NULL) {
- terrno = TSDB_CODE_INVALID_PARA;
- return -1;
- }
+static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction) {
+ pAction->id = taosArrayGetSize(pArray);
- void *ptr = taosArrayPush(pArray, &pRaw);
+ void *ptr = taosArrayPush(pArray, pAction);
if (ptr == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
@@ -628,27 +582,28 @@ static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw) {
return 0;
}
-int32_t mndTransAppendRedolog(STrans *pTrans, SSdbRaw *pRaw) { return mndTransAppendLog(pTrans->redoLogs, pRaw); }
-
-int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw) { return mndTransAppendLog(pTrans->undoLogs, pRaw); }
-
-int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw) { return mndTransAppendLog(pTrans->commitLogs, pRaw); }
+int32_t mndTransAppendRedolog(STrans *pTrans, SSdbRaw *pRaw) {
+ STransAction action = {.stage = TRN_STAGE_REDO_ACTION, .actionType = true, .pRaw = pRaw};
+ return mndTransAppendAction(pTrans->redoActions, &action);
+}
-static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction) {
- void *ptr = taosArrayPush(pArray, pAction);
- if (ptr == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
+int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw) {
+ STransAction action = {.stage = TRN_STAGE_UNDO_ACTION, .actionType = true, .pRaw = pRaw};
+ return mndTransAppendAction(pTrans->undoActions, &action);
+}
- return 0;
+int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw) {
+ STransAction action = {.stage = TRN_STAGE_COMMIT_ACTION, .actionType = true, .pRaw = pRaw};
+ return mndTransAppendAction(pTrans->commitActions, &action);
}
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction) {
+ pAction->stage = TRN_STAGE_REDO_ACTION;
return mndTransAppendAction(pTrans->redoActions, pAction);
}
int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction) {
+ pAction->stage = TRN_STAGE_UNDO_ACTION;
return mndTransAppendAction(pTrans->undoActions, pAction);
}
@@ -664,12 +619,9 @@ void mndTransSetCb(STrans *pTrans, ETrnFunc startFunc, ETrnFunc stopFunc, void *
pTrans->paramLen = paramLen;
}
-void mndTransSetDbInfo(STrans *pTrans, SDbObj *pDb) {
- pTrans->dbUid = pDb->uid;
- memcpy(pTrans->dbname, pDb->name, TSDB_DB_FNAME_LEN);
-}
+void mndTransSetDbName(STrans *pTrans, const char *dbname) { memcpy(pTrans->dbname, dbname, TSDB_DB_FNAME_LEN); }
-void mndTransSetExecOneByOne(STrans *pTrans) { pTrans->parallel = TRN_EXEC_ONE_BY_ONE; }
+void mndTransSetSerial(STrans *pTrans) { pTrans->exec = TRN_EXEC_SERIAL; }
static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
SSdbRaw *pRaw = mndTransActionEncode(pTrans);
@@ -679,7 +631,7 @@ static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
}
sdbSetRawStatus(pRaw, SDB_STATUS_READY);
- mDebug("trans:%d, sync to other nodes", pTrans->id);
+ mDebug("trans:%d, sync to other mnodes", pTrans->id);
int32_t code = mndSyncPropose(pMnode, pRaw, pTrans->id);
if (code != 0) {
mError("trans:%d, failed to sync since %s", pTrans->id, terrstr());
@@ -692,83 +644,50 @@ static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
return 0;
}
-static bool mndIsBasicTrans(STrans *pTrans) {
- return pTrans->type > TRN_TYPE_BASIC_SCOPE && pTrans->type < TRN_TYPE_BASIC_SCOPE_END;
-}
-
-static bool mndIsGlobalTrans(STrans *pTrans) {
- return pTrans->type > TRN_TYPE_GLOBAL_SCOPE && pTrans->type < TRN_TYPE_GLOBAL_SCOPE_END;
-}
-
-static bool mndIsDbTrans(STrans *pTrans) {
- return pTrans->type > TRN_TYPE_DB_SCOPE && pTrans->type < TRN_TYPE_DB_SCOPE_END;
-}
-
-static bool mndIsStbTrans(STrans *pTrans) {
- return pTrans->type > TRN_TYPE_STB_SCOPE && pTrans->type < TRN_TYPE_STB_SCOPE_END;
-}
-
-static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNewTrans) {
+static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
STrans *pTrans = NULL;
void *pIter = NULL;
bool conflict = false;
- if (mndIsBasicTrans(pNewTrans)) return conflict;
+ if (pNew->conflict == TRN_CONFLICT_NOTHING) return conflict;
while (1) {
pIter = sdbFetch(pMnode->pSdb, SDB_TRANS, pIter, (void **)&pTrans);
if (pIter == NULL) break;
- if (mndIsGlobalTrans(pNewTrans)) {
- if (mndIsDbTrans(pTrans) || mndIsStbTrans(pTrans)) {
- mError("trans:%d, can't execute since trans:%d in progress db:%s", pNewTrans->id, pTrans->id, pTrans->dbname);
- conflict = true;
- } else {
- }
- }
-
- else if (mndIsDbTrans(pNewTrans)) {
- if (mndIsGlobalTrans(pTrans)) {
- mError("trans:%d, can't execute since trans:%d in progress", pNewTrans->id, pTrans->id);
- conflict = true;
- } else if (mndIsDbTrans(pTrans) || mndIsStbTrans(pTrans)) {
- if (pNewTrans->dbUid == pTrans->dbUid) {
- mError("trans:%d, can't execute since trans:%d in progress db:%s", pNewTrans->id, pTrans->id, pTrans->dbname);
- conflict = true;
- }
- } else {
- }
+ if (pNew->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
+ if (pNew->conflict == TRN_CONFLICT_DB) {
+ if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
+ if (pTrans->conflict == TRN_CONFLICT_DB && strcmp(pNew->dbname, pTrans->dbname) == 0) conflict = true;
+ if (pTrans->conflict == TRN_CONFLICT_DB_INSIDE && strcmp(pNew->dbname, pTrans->dbname) == 0) conflict = true;
}
-
- else if (mndIsStbTrans(pNewTrans)) {
- if (mndIsGlobalTrans(pTrans)) {
- mError("trans:%d, can't execute since trans:%d in progress", pNewTrans->id, pTrans->id);
- conflict = true;
- } else if (mndIsDbTrans(pTrans)) {
- if (pNewTrans->dbUid == pTrans->dbUid) {
- mError("trans:%d, can't execute since trans:%d in progress db:%s", pNewTrans->id, pTrans->id, pTrans->dbname);
- conflict = true;
- }
- } else {
- }
+ if (pNew->conflict == TRN_CONFLICT_DB_INSIDE) {
+ if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
+ if (pTrans->conflict == TRN_CONFLICT_DB && strcmp(pNew->dbname, pTrans->dbname) == 0) conflict = true;
}
-
+ mError("trans:%d, can't execute since conflict with trans:%d, db:%s", pNew->id, pTrans->id, pTrans->dbname);
sdbRelease(pMnode->pSdb, pTrans);
}
- sdbCancelFetch(pMnode->pSdb, pIter);
- sdbRelease(pMnode->pSdb, pTrans);
return conflict;
}
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
+ if (pTrans->conflict == TRN_CONFLICT_DB || pTrans->conflict == TRN_CONFLICT_DB_INSIDE) {
+ if (strlen(pTrans->dbname) == 0) {
+ terrno = TSDB_CODE_MND_TRANS_CONFLICT;
+ mError("trans:%d, failed to prepare conflict db not set", pTrans->id);
+ return -1;
+ }
+ }
+
if (mndCheckTransConflict(pMnode, pTrans)) {
terrno = TSDB_CODE_MND_TRANS_CONFLICT;
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
return -1;
}
- if (taosArrayGetSize(pTrans->commitLogs) <= 0) {
+ if (taosArrayGetSize(pTrans->commitActions) <= 0) {
terrno = TSDB_CODE_MND_TRANS_CLOG_IS_NULL;
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
return -1;
@@ -799,8 +718,6 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
}
static int32_t mndTransCommit(SMnode *pMnode, STrans *pTrans) {
- if (taosArrayGetSize(pTrans->commitLogs) == 0 && taosArrayGetSize(pTrans->redoActions) == 0) return 0;
-
mDebug("trans:%d, commit transaction", pTrans->id);
if (mndTransSync(pMnode, pTrans) != 0) {
mError("trans:%d, failed to commit since %s", pTrans->id, terrstr());
@@ -829,32 +746,35 @@ static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans) {
}
if (pTrans->policy == TRN_POLICY_ROLLBACK) {
- if (pTrans->stage == TRN_STAGE_UNDO_LOG || pTrans->stage == TRN_STAGE_UNDO_ACTION ||
- pTrans->stage == TRN_STAGE_ROLLBACK) {
+ if (pTrans->stage == TRN_STAGE_UNDO_ACTION || pTrans->stage == TRN_STAGE_ROLLBACK) {
if (code == 0) code = TSDB_CODE_MND_TRANS_UNKNOW_ERROR;
sendRsp = true;
}
} else {
- if (pTrans->stage == TRN_STAGE_REDO_ACTION && pTrans->failedTimes > 6) {
+ if (pTrans->stage == TRN_STAGE_REDO_ACTION && pTrans->failedTimes > 3) {
if (code == 0) code = TSDB_CODE_MND_TRANS_UNKNOW_ERROR;
sendRsp = true;
}
}
if (sendRsp && pTrans->rpcInfo.handle != NULL) {
- void *rpcCont = rpcMallocCont(pTrans->rpcRspLen);
- if (rpcCont != NULL) {
- memcpy(rpcCont, pTrans->rpcRsp, pTrans->rpcRspLen);
+ mDebug("trans:%d, send rsp, code:0x%x stage:%s app:%p", pTrans->id, code, mndTransStr(pTrans->stage),
+ pTrans->rpcInfo.ahandle);
+ if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
+ code = TSDB_CODE_RPC_INDIRECT_NETWORK_UNAVAIL;
+ }
+ SRpcMsg rspMsg = {.code = code, .info = pTrans->rpcInfo};
+
+ if (pTrans->rpcRspLen != 0) {
+ void *rpcCont = rpcMallocCont(pTrans->rpcRspLen);
+ if (rpcCont != NULL) {
+ memcpy(rpcCont, pTrans->rpcRsp, pTrans->rpcRspLen);
+ rspMsg.pCont = rpcCont;
+ rspMsg.contLen = pTrans->rpcRspLen;
+ }
+ taosMemoryFree(pTrans->rpcRsp);
}
- taosMemoryFree(pTrans->rpcRsp);
- mDebug("trans:%d, send rsp, code:0x%x stage:%d app:%p", pTrans->id, code, pTrans->stage, pTrans->rpcInfo.ahandle);
- SRpcMsg rspMsg = {
- .code = code,
- .pCont = rpcCont,
- .contLen = pTrans->rpcRspLen,
- .info = pTrans->rpcInfo,
- };
tmsgSendRsp(&rspMsg);
pTrans->rpcInfo.handle = NULL;
pTrans->rpcRsp = NULL;
@@ -899,162 +819,150 @@ void mndTransProcessRsp(SRpcMsg *pRsp) {
if (pAction != NULL) {
pAction->msgReceived = 1;
pAction->errCode = pRsp->code;
- if (pAction->errCode != 0) {
- tstrncpy(pTrans->lastError, tstrerror(pAction->errCode), TSDB_TRANS_ERROR_LEN);
- }
}
- mDebug("trans:%d, action:%d response is received, code:0x%x, accept:0x%04x", transId, action, pRsp->code,
- pAction->acceptableCode);
+ mDebug("trans:%d, %s:%d response is received, code:0x%x, accept:0x%x", transId, mndTransStr(pAction->stage), action,
+ pRsp->code, pAction->acceptableCode);
mndTransExecute(pMnode, pTrans);
_OVER:
mndReleaseTrans(pMnode, pTrans);
}
-static int32_t mndTransExecuteLogs(SMnode *pMnode, SArray *pArray) {
- SSdb *pSdb = pMnode->pSdb;
- int32_t arraySize = taosArrayGetSize(pArray);
+static void mndTransResetActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
+ int32_t numOfActions = taosArrayGetSize(pArray);
- if (arraySize == 0) return 0;
+ for (int32_t action = 0; action < numOfActions; ++action) {
+ STransAction *pAction = taosArrayGet(pArray, action);
+ if (pAction->msgSent && pAction->msgReceived &&
+ (pAction->errCode == 0 || pAction->errCode == pAction->acceptableCode))
+ continue;
+ if (pAction->rawWritten && (pAction->errCode == 0 || pAction->errCode == pAction->acceptableCode)) continue;
- int32_t code = 0;
- for (int32_t i = 0; i < arraySize; ++i) {
- SSdbRaw *pRaw = taosArrayGetP(pArray, i);
- if (sdbWriteWithoutFree(pSdb, pRaw) != 0) {
- code = ((terrno != 0) ? terrno : -1);
- }
+ pAction->rawWritten = 0;
+ pAction->msgSent = 0;
+ pAction->msgReceived = 0;
+ pAction->errCode = 0;
+ mDebug("trans:%d, %s:%d execute status is reset", pTrans->id, mndTransStr(pAction->stage), action);
}
-
- terrno = code;
- return code;
}
-static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans) {
- int32_t code = mndTransExecuteLogs(pMnode, pTrans->redoLogs);
- if (code != 0) {
- mError("failed to execute redoLogs since %s", terrstr());
- }
- return code;
-}
+static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
+ if (pAction->rawWritten) return 0;
-static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans) {
- int32_t code = mndTransExecuteLogs(pMnode, pTrans->undoLogs);
- if (code != 0) {
- mError("failed to execute undoLogs since %s, return success", terrstr());
+ int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pAction->pRaw);
+ if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
+ pAction->rawWritten = true;
+ pAction->errCode = 0;
+ code = 0;
+ mDebug("trans:%d, %s:%d write to sdb", pTrans->id, mndTransStr(pAction->stage), pAction->id);
+ } else {
+ pAction->errCode = (terrno != 0) ? terrno : code;
+ mError("trans:%d, %s:%d failed to write sdb since %s", pTrans->id, mndTransStr(pAction->stage), pAction->id,
+ terrstr());
}
- return 0; // return success in any case
-}
-
-static int32_t mndTransExecuteCommitLogs(SMnode *pMnode, STrans *pTrans) {
- int32_t code = mndTransExecuteLogs(pMnode, pTrans->commitLogs);
- if (code != 0) {
- mError("failed to execute commitLogs since %s", terrstr());
- }
return code;
}
-static void mndTransResetActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
- int32_t numOfActions = taosArrayGetSize(pArray);
+static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
+ if (pAction->msgSent) return 0;
+ if (!pMnode->deploy && !mndIsMaster(pMnode)) return -1;
- for (int32_t action = 0; action < numOfActions; ++action) {
- STransAction *pAction = taosArrayGet(pArray, action);
- if (pAction == NULL) continue;
- if (pAction->msgSent && pAction->msgReceived && pAction->errCode == 0) continue;
+ int64_t signature = pTrans->id;
+ signature = (signature << 32);
+ signature += pAction->id;
- pAction->msgSent = 0;
+ SRpcMsg rpcMsg = {.msgType = pAction->msgType, .contLen = pAction->contLen, .info.ahandle = (void *)signature};
+ rpcMsg.pCont = rpcMallocCont(pAction->contLen);
+ if (rpcMsg.pCont == NULL) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ return -1;
+ }
+ memcpy(rpcMsg.pCont, pAction->pCont, pAction->contLen);
+
+ int32_t code = tmsgSendReq(&pAction->epSet, &rpcMsg);
+ if (code == 0) {
+ pAction->msgSent = 1;
pAction->msgReceived = 0;
pAction->errCode = 0;
- mDebug("trans:%d, action:%d execute status is reset", pTrans->id, action);
+ mDebug("trans:%d, %s:%d is sent to %s:%u", pTrans->id, mndTransStr(pAction->stage), pAction->id,
+ pAction->epSet.eps[pAction->epSet.inUse].fqdn, pAction->epSet.eps[pAction->epSet.inUse].port);
+ } else {
+ pAction->msgSent = 0;
+ pAction->msgReceived = 0;
+ pAction->errCode = (terrno != 0) ? terrno : code;
+ mError("trans:%d, %s:%d not send since %s", pTrans->id, mndTransStr(pAction->stage), pAction->id, terrstr());
+ }
+
+ return code;
+}
+
+static int32_t mndTransExecSingleAction(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
+ if (pAction->actionType) {
+ return mndTransWriteSingleLog(pMnode, pTrans, pAction);
+ } else {
+ return mndTransSendSingleMsg(pMnode, pTrans, pAction);
}
}
-static int32_t mndTransSendActionMsg(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
+static int32_t mndTransExecSingleActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
int32_t numOfActions = taosArrayGetSize(pArray);
+ int32_t code = 0;
for (int32_t action = 0; action < numOfActions; ++action) {
STransAction *pAction = taosArrayGet(pArray, action);
- if (pAction == NULL) continue;
-
- if (pAction->msgSent) {
- if (pAction->msgReceived) {
- continue;
- } else {
- if (pTrans->parallel == TRN_EXEC_ONE_BY_ONE) {
- break;
- } else {
- continue;
- }
- }
- }
-
- int64_t signature = pTrans->id;
- signature = (signature << 32);
- signature += action;
-
- SRpcMsg rpcMsg = {.msgType = pAction->msgType, .contLen = pAction->contLen, .info.ahandle = (void *)signature};
- rpcMsg.pCont = rpcMallocCont(pAction->contLen);
- if (rpcMsg.pCont == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
- memcpy(rpcMsg.pCont, pAction->pCont, pAction->contLen);
-
- if (tmsgSendReq(&pAction->epSet, &rpcMsg) == 0) {
- mDebug("trans:%d, action:%d is sent to %s:%u", pTrans->id, action, pAction->epSet.eps[pAction->epSet.inUse].fqdn,
- pAction->epSet.eps[pAction->epSet.inUse].port);
- pAction->msgSent = 1;
- pAction->msgReceived = 0;
- pAction->errCode = 0;
- if (pTrans->parallel == TRN_EXEC_ONE_BY_ONE) {
- break;
- }
- } else {
- pAction->msgSent = 0;
- pAction->msgReceived = 0;
- pAction->errCode = terrno;
- mError("trans:%d, action:%d not send since %s", pTrans->id, action, terrstr());
- return -1;
- }
+ code = mndTransExecSingleAction(pMnode, pTrans, pAction);
+ if (code != 0) break;
}
- return 0;
+ return code;
}
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
int32_t numOfActions = taosArrayGetSize(pArray);
if (numOfActions == 0) return 0;
- if (mndTransSendActionMsg(pMnode, pTrans, pArray) != 0) {
+ if (mndTransExecSingleActions(pMnode, pTrans, pArray) != 0) {
return -1;
}
- int32_t numOfReceived = 0;
- int32_t errCode = 0;
+ int32_t numOfExecuted = 0;
+ int32_t errCode = 0;
+ STransAction *pErrAction = NULL;
for (int32_t action = 0; action < numOfActions; ++action) {
STransAction *pAction = taosArrayGet(pArray, action);
- if (pAction == NULL) continue;
- if (pAction->msgSent && pAction->msgReceived) {
- numOfReceived++;
+ if (pAction->msgReceived || pAction->rawWritten) {
+ numOfExecuted++;
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
errCode = pAction->errCode;
+ pErrAction = pAction;
}
}
}
- if (numOfReceived == numOfActions) {
+ if (numOfExecuted == numOfActions) {
if (errCode == 0) {
+ pTrans->lastErrorAction = 0;
+ pTrans->lastErrorNo = 0;
+ pTrans->lastErrorMsgType = 0;
+ memset(&pTrans->lastErrorEpset, 0, sizeof(pTrans->lastErrorEpset));
mDebug("trans:%d, all %d actions execute successfully", pTrans->id, numOfActions);
return 0;
} else {
mError("trans:%d, all %d actions executed, code:0x%x", pTrans->id, numOfActions, errCode & 0XFFFF);
+ if (pErrAction != NULL) {
+ pTrans->lastErrorMsgType = pErrAction->msgType;
+ pTrans->lastErrorAction = pErrAction->id;
+ pTrans->lastErrorNo = pErrAction->errCode;
+ pTrans->lastErrorEpset = pErrAction->epSet;
+ }
mndTransResetActions(pMnode, pTrans, pArray);
terrno = errCode;
return errCode;
}
} else {
- mDebug("trans:%d, %d of %d actions executed", pTrans->id, numOfReceived, numOfActions);
+ mDebug("trans:%d, %d of %d actions executed", pTrans->id, numOfExecuted, numOfActions);
return TSDB_CODE_ACTION_IN_PROGRESS;
}
}
@@ -1075,35 +983,99 @@ static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans) {
return code;
}
-static bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
- bool continueExec = true;
- pTrans->stage = TRN_STAGE_REDO_LOG;
- mDebug("trans:%d, stage from prepare to redoLog", pTrans->id);
- return continueExec;
+static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans) {
+ int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->commitActions);
+ if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
+ mError("failed to execute commitActions since %s", terrstr());
+ }
+ return code;
}
-static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans) {
- bool continueExec = true;
- int32_t code = mndTransExecuteRedoLogs(pMnode, pTrans);
+static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans) {
+ int32_t code = 0;
+ int32_t numOfActions = taosArrayGetSize(pTrans->redoActions);
+ if (numOfActions == 0) return code;
+ if (pTrans->redoActionPos >= numOfActions) return code;
+
+ for (int32_t action = pTrans->redoActionPos; action < numOfActions; ++action) {
+ STransAction *pAction = taosArrayGet(pTrans->redoActions, pTrans->redoActionPos);
+
+ code = mndTransExecSingleAction(pMnode, pTrans, pAction);
+ if (code == 0) {
+ if (pAction->msgSent) {
+ if (pAction->msgReceived) {
+ if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
+ code = pAction->errCode;
+ pAction->msgSent = 0;
+ pAction->msgReceived = 0;
+ mDebug("trans:%d, %s:%d execute status is reset", pTrans->id, mndTransStr(pAction->stage), action);
+ }
+ } else {
+ code = TSDB_CODE_ACTION_IN_PROGRESS;
+ }
+ }
+ if (pAction->rawWritten) {
+ if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
+ code = pAction->errCode;
+ }
+ }
+ }
- if (code == 0) {
- pTrans->code = 0;
- pTrans->stage = TRN_STAGE_REDO_ACTION;
- mDebug("trans:%d, stage from redoLog to redoAction", pTrans->id);
- } else {
- pTrans->code = terrno;
- pTrans->stage = TRN_STAGE_UNDO_LOG;
- mError("trans:%d, stage from redoLog to undoLog since %s", pTrans->id, terrstr());
+ if (code == 0) {
+ pTrans->lastErrorAction = 0;
+ pTrans->lastErrorNo = 0;
+ pTrans->lastErrorMsgType = 0;
+ memset(&pTrans->lastErrorEpset, 0, sizeof(pTrans->lastErrorEpset));
+ } else {
+ pTrans->lastErrorMsgType = pAction->msgType;
+ pTrans->lastErrorAction = action;
+ pTrans->lastErrorNo = pAction->errCode;
+ pTrans->lastErrorEpset = pAction->epSet;
+ }
+
+ if (code == 0) {
+ pTrans->code = 0;
+ pTrans->redoActionPos++;
+ mDebug("trans:%d, %s:%d is executed and need sync to other mnodes", pTrans->id, mndTransStr(pAction->stage),
+ pAction->id);
+ code = mndTransSync(pMnode, pTrans);
+ if (code != 0) {
+ pTrans->code = terrno;
+ mError("trans:%d, %s:%d is executed and failed to sync to other mnodes since %s", pTrans->id,
+ mndTransStr(pAction->stage), pAction->id, terrstr());
+ break;
+ }
+ } else if (code == TSDB_CODE_ACTION_IN_PROGRESS) {
+ mDebug("trans:%d, %s:%d is in progress and wait it finish", pTrans->id, mndTransStr(pAction->stage), pAction->id);
+ break;
+ } else {
+ terrno = code;
+ pTrans->code = code;
+ mError("trans:%d, %s:%d failed to execute since %s", pTrans->id, mndTransStr(pAction->stage), pAction->id,
+ terrstr());
+ break;
+ }
}
+ return code;
+}
+
+static bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
+ bool continueExec = true;
+ pTrans->stage = TRN_STAGE_REDO_ACTION;
+ mDebug("trans:%d, stage from prepare to redoAction", pTrans->id);
return continueExec;
}
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans) {
- if (!pMnode->deploy && !mndIsMaster(pMnode)) return false;
-
bool continueExec = true;
- int32_t code = mndTransExecuteRedoActions(pMnode, pTrans);
+ int32_t code = 0;
+
+ if (pTrans->exec == TRN_EXEC_SERIAL) {
+ code = mndTransExecuteRedoActionsSerial(pMnode, pTrans);
+ } else {
+ code = mndTransExecuteRedoActions(pMnode, pTrans);
+ }
if (code == 0) {
pTrans->code = 0;
@@ -1135,8 +1107,8 @@ static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans) {
if (code == 0) {
pTrans->code = 0;
- pTrans->stage = TRN_STAGE_COMMIT_LOG;
- mDebug("trans:%d, stage from commit to commitLog", pTrans->id);
+ pTrans->stage = TRN_STAGE_COMMIT_ACTION;
+ mDebug("trans:%d, stage from commit to commitAction", pTrans->id);
continueExec = true;
} else {
pTrans->code = terrno;
@@ -1155,35 +1127,19 @@ static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans) {
return continueExec;
}
-static bool mndTransPerformCommitLogStage(SMnode *pMnode, STrans *pTrans) {
+static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans) {
bool continueExec = true;
- int32_t code = mndTransExecuteCommitLogs(pMnode, pTrans);
+ int32_t code = mndTransExecuteCommitActions(pMnode, pTrans);
if (code == 0) {
pTrans->code = 0;
pTrans->stage = TRN_STAGE_FINISHED;
- mDebug("trans:%d, stage from commitLog to finished", pTrans->id);
+ mDebug("trans:%d, stage from commitAction to finished", pTrans->id);
continueExec = true;
} else {
pTrans->code = terrno;
pTrans->failedTimes++;
- mError("trans:%d, stage keep on commitLog since %s, failedTimes:%d", pTrans->id, terrstr(), pTrans->failedTimes);
- continueExec = false;
- }
-
- return continueExec;
-}
-
-static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans) {
- bool continueExec = true;
- int32_t code = mndTransExecuteUndoLogs(pMnode, pTrans);
-
- if (code == 0) {
- pTrans->stage = TRN_STAGE_ROLLBACK;
- mDebug("trans:%d, stage from undoLog to rollback", pTrans->id);
- continueExec = true;
- } else {
- mError("trans:%d, stage keep on undoLog since %s", pTrans->id, terrstr());
+ mError("trans:%d, stage keep on commitAction since %s, failedTimes:%d", pTrans->id, terrstr(), pTrans->failedTimes);
continueExec = false;
}
@@ -1191,14 +1147,12 @@ static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans) {
}
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans) {
- if (!pMnode->deploy && !mndIsMaster(pMnode)) return false;
-
bool continueExec = true;
int32_t code = mndTransExecuteUndoActions(pMnode, pTrans);
if (code == 0) {
- pTrans->stage = TRN_STAGE_UNDO_LOG;
- mDebug("trans:%d, stage from undoAction to undoLog", pTrans->id);
+ pTrans->stage = TRN_STAGE_ROLLBACK;
+ mDebug("trans:%d, stage from undoAction to rollback", pTrans->id);
continueExec = true;
} else if (code == TSDB_CODE_ACTION_IN_PROGRESS) {
mDebug("trans:%d, stage keep on undoAction since %s", pTrans->id, tstrerror(code));
@@ -1243,8 +1197,7 @@ static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans) {
mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr());
}
- mDebug("trans:%d, finished, code:0x%x, failedTimes:%d", pTrans->id, pTrans->code, pTrans->failedTimes);
-
+ mDebug("trans:%d, execute finished, code:0x%x, failedTimes:%d", pTrans->id, pTrans->code, pTrans->failedTimes);
return continueExec;
}
@@ -1257,24 +1210,18 @@ static void mndTransExecute(SMnode *pMnode, STrans *pTrans) {
case TRN_STAGE_PREPARE:
continueExec = mndTransPerformPrepareStage(pMnode, pTrans);
break;
- case TRN_STAGE_REDO_LOG:
- continueExec = mndTransPerformRedoLogStage(pMnode, pTrans);
- break;
case TRN_STAGE_REDO_ACTION:
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
break;
- case TRN_STAGE_UNDO_LOG:
- continueExec = mndTransPerformUndoLogStage(pMnode, pTrans);
+ case TRN_STAGE_COMMIT:
+ continueExec = mndTransPerformCommitStage(pMnode, pTrans);
+ break;
+ case TRN_STAGE_COMMIT_ACTION:
+ continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
break;
case TRN_STAGE_UNDO_ACTION:
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
break;
- case TRN_STAGE_COMMIT_LOG:
- continueExec = mndTransPerformCommitLogStage(pMnode, pTrans);
- break;
- case TRN_STAGE_COMMIT:
- continueExec = mndTransPerformCommitStage(pMnode, pTrans);
- break;
case TRN_STAGE_ROLLBACK:
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
break;
@@ -1306,22 +1253,11 @@ int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans) {
return -1;
}
- int32_t size = taosArrayGetSize(pArray);
-
- for (int32_t i = 0; i < size; ++i) {
+ for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
STransAction *pAction = taosArrayGet(pArray, i);
- if (pAction == NULL) continue;
-
- if (pAction->msgReceived == 0) {
- mInfo("trans:%d, action:%d set processed for kill msg received", pTrans->id, i);
- pAction->msgSent = 1;
- pAction->msgReceived = 1;
- pAction->errCode = 0;
- }
-
if (pAction->errCode != 0) {
- mInfo("trans:%d, action:%d set processed for kill msg received, errCode from %s to success", pTrans->id, i,
- tstrerror(pAction->errCode));
+ mInfo("trans:%d, %s:%d set processed for kill msg received, errCode from %s to success", pTrans->id,
+ mndTransStr(pAction->stage), i, tstrerror(pAction->errCode));
pAction->msgSent = 1;
pAction->msgReceived = 1;
pAction->errCode = 0;
@@ -1357,9 +1293,7 @@ static int32_t mndProcessKillTransReq(SRpcMsg *pReq) {
pTrans = mndAcquireTrans(pMnode, killReq.transId);
if (pTrans == NULL) {
- terrno = TSDB_CODE_MND_TRANS_NOT_EXIST;
- mError("trans:%d, failed to kill since %s", killReq.transId, terrstr());
- return -1;
+ goto _OVER;
}
code = mndKillTrans(pMnode, pTrans);
@@ -1367,9 +1301,9 @@ static int32_t mndProcessKillTransReq(SRpcMsg *pReq) {
_OVER:
if (code != 0) {
mError("trans:%d, failed to kill since %s", killReq.transId, terrstr());
- return -1;
}
+ mndReleaseUser(pMnode, pUser);
mndReleaseTrans(pMnode, pTrans);
return code;
}
@@ -1435,11 +1369,6 @@ static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)dbname, false);
- char type[TSDB_TRANS_TYPE_LEN + VARSTR_HEADER_SIZE] = {0};
- STR_WITH_MAXSIZE_TO_VARSTR(type, mndTransType(pTrans->type), pShow->pMeta->pSchemas[cols].bytes);
- pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
- colDataAppend(pColInfo, numOfRows, (const char *)type, false);
-
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)&pTrans->failedTimes, false);
@@ -1447,7 +1376,20 @@ static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
colDataAppend(pColInfo, numOfRows, (const char *)&pTrans->lastExecTime, false);
char lastError[TSDB_TRANS_ERROR_LEN + VARSTR_HEADER_SIZE] = {0};
- STR_WITH_MAXSIZE_TO_VARSTR(lastError, pTrans->lastError, pShow->pMeta->pSchemas[cols].bytes);
+ char detail[TSDB_TRANS_ERROR_LEN] = {0};
+ if (pTrans->lastErrorNo != 0) {
+ int32_t len = snprintf(detail, sizeof(detail), "action:%d errno:0x%x(%s) ", pTrans->lastErrorAction,
+ pTrans->lastErrorNo & 0xFFFF, tstrerror(pTrans->lastErrorNo));
+ SEpSet epset = pTrans->lastErrorEpset;
+ if (epset.numOfEps > 0) {
+ len += snprintf(detail + len, sizeof(detail) - len, "msgType:%s numOfEps:%d inUse:%d ",
+ TMSG_INFO(pTrans->lastErrorMsgType), epset.numOfEps, epset.inUse);
+ }
+ for (int32_t i = 0; i < pTrans->lastErrorEpset.numOfEps; ++i) {
+ len += snprintf(detail + len, sizeof(detail) - len, "ep:%d-%s:%u ", i, epset.eps[i].fqdn, epset.eps[i].port);
+ }
+ }
+ STR_WITH_MAXSIZE_TO_VARSTR(lastError, detail, pShow->pMeta->pSchemas[cols].bytes);
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)lastError, false);
diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c
index cc6364c4571b7b56b096d282c4f8f29a7b624dca..345d756f4399a46b4d4abfa8db1ea74b2271b01e 100644
--- a/source/dnode/mnode/impl/src/mndUser.c
+++ b/source/dnode/mnode/impl/src/mndUser.c
@@ -77,12 +77,9 @@ static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char
if (pRaw == NULL) return -1;
sdbSetRawStatus(pRaw, SDB_STATUS_READY);
- mDebug("user:%s, will be created while deploy sdb, raw:%p", userObj.user, pRaw);
+ mDebug("user:%s, will be created when deploying, raw:%p", userObj.user, pRaw);
-#if 0
- return sdbWrite(pMnode->pSdb, pRaw);
-#else
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CREATE_USER, NULL);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, NULL);
if (pTrans == NULL) {
mError("user:%s, failed to create since %s", userObj.user, terrstr());
return -1;
@@ -104,7 +101,6 @@ static int32_t mndCreateDefaultUser(SMnode *pMnode, char *acct, char *user, char
mndTransDrop(pTrans);
return 0;
-#endif
}
static int32_t mndCreateDefaultUsers(SMnode *pMnode) {
@@ -291,7 +287,7 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate
userObj.updateTime = userObj.createdTime;
userObj.superUser = pCreate->superUser;
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_USER, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("user:%s, failed to create since %s", pCreate->user, terrstr());
return -1;
@@ -371,7 +367,7 @@ _OVER:
}
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SRpcMsg *pReq) {
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_ALTER_USER, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("user:%s, failed to alter since %s", pOld->user, terrstr());
return -1;
@@ -578,7 +574,7 @@ _OVER:
}
static int32_t mndDropUser(SMnode *pMnode, SRpcMsg *pReq, SUserObj *pUser) {
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_DROP_USER, pReq);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq);
if (pTrans == NULL) {
mError("user:%s, failed to drop since %s", pUser->user, terrstr());
return -1;
diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c
index e05b38a7c0345293eb53caeab2eb680f6d113651..9262aa167b20372dcabc4d8b78cf311911cf2162 100644
--- a/source/dnode/mnode/impl/src/mndVgroup.c
+++ b/source/dnode/mnode/impl/src/mndVgroup.c
@@ -51,9 +51,10 @@ int32_t mndInitVgroup(SMnode *pMnode) {
};
mndSetMsgHandle(pMnode, TDMT_DND_CREATE_VNODE_RSP, mndProcessCreateVnodeRsp);
- mndSetMsgHandle(pMnode, TDMT_VND_ALTER_VNODE_RSP, mndProcessAlterVnodeRsp);
+ mndSetMsgHandle(pMnode, TDMT_VND_ALTER_REPLICA_RSP, mndProcessAlterVnodeRsp);
+ mndSetMsgHandle(pMnode, TDMT_VND_ALTER_CONFIG_RSP, mndProcessAlterVnodeRsp);
mndSetMsgHandle(pMnode, TDMT_DND_DROP_VNODE_RSP, mndProcessDropVnodeRsp);
- mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_VNODE_RSP, mndProcessCompactVnodeRsp);
+ mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_RSP, mndProcessCompactVnodeRsp);
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndRetrieveVgroups);
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_VGROUP, mndCancelGetNextVgroup);
@@ -188,10 +189,10 @@ void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup) {
sdbRelease(pSdb, pVgroup);
}
-void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen) {
+void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen,
+ bool standby) {
SCreateVnodeReq createReq = {0};
createReq.vgId = pVgroup->vgId;
- createReq.dnodeId = pDnode->id;
memcpy(createReq.db, pDb->name, TSDB_DB_FNAME_LEN);
createReq.dbUid = pDb->uid;
createReq.vgVersion = pVgroup->version;
@@ -218,6 +219,9 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg
createReq.hashMethod = pDb->cfg.hashMethod;
createReq.numOfRetensions = pDb->cfg.numOfRetensions;
createReq.pRetensions = pDb->cfg.pRetensions;
+ createReq.standby = standby;
+ createReq.isTsma = pVgroup->isTsma;
+ createReq.pTsma = pVgroup->pTsma;
for (int32_t v = 0; v < pVgroup->replica; ++v) {
SReplica *pReplica = &createReq.replicas[v];
@@ -274,7 +278,6 @@ void *mndBuildAlterVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_
alterReq.strict = pDb->cfg.strict;
alterReq.cacheLastRow = pDb->cfg.cacheLastRow;
alterReq.replica = pVgroup->replica;
- alterReq.selfIndex = -1;
for (int32_t v = 0; v < pVgroup->replica; ++v) {
SReplica *pReplica = &alterReq.replicas[v];
@@ -290,13 +293,6 @@ void *mndBuildAlterVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_
mndReleaseDnode(pMnode, pVgidDnode);
}
-#if 0
- if (alterReq.selfIndex == -1) {
- terrno = TSDB_CODE_MND_APP_ERROR;
- return NULL;
- }
-#endif
-
int32_t contLen = tSerializeSAlterVnodeReq(NULL, 0, &alterReq);
if (contLen < 0) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
@@ -501,7 +497,7 @@ int32_t mndAllocVgroup(SMnode *pMnode, SDbObj *pDb, SVgObj **ppVgroups) {
*ppVgroups = pVgroups;
code = 0;
- mInfo("db:%s, %d vgroups is alloced, replica:%d", pDb->name, pDb->cfg.numOfVgroups, pDb->cfg.replications);
+ mInfo("db:%s, total %d vgroups is alloced, replica:%d", pDb->name, pDb->cfg.numOfVgroups, pDb->cfg.replications);
_OVER:
if (code != 0) taosMemoryFree(pVgroups);
@@ -536,10 +532,10 @@ int32_t mndAddVnodeToVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray) {
SVnodeGid *pVgid = &pVgroup->vnodeGid[maxPos];
pVgid->dnodeId = pDnode->id;
- pVgid->role = TAOS_SYNC_STATE_FOLLOWER;
+ pVgid->role = TAOS_SYNC_STATE_ERROR;
pDnode->numOfVnodes++;
- mInfo("db:%s, vgId:%d, vn:%d dnode:%d is added", pVgroup->dbName, pVgroup->vgId, maxPos, pVgid->dnodeId);
+ mInfo("db:%s, vgId:%d, vnode_index:%d dnode:%d is added", pVgroup->dbName, pVgroup->vgId, maxPos, pVgid->dnodeId);
maxPos++;
if (maxPos == 3) return 0;
}
@@ -549,14 +545,13 @@ int32_t mndAddVnodeToVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray) {
}
int32_t mndRemoveVnodeFromVgroup(SMnode *pMnode, SVgObj *pVgroup, SArray *pArray, SVnodeGid *del1, SVnodeGid *del2) {
- int32_t removedNum = 0;
-
taosArraySort(pArray, (__compar_fn_t)mndCompareDnodeVnodes);
for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
SDnodeObj *pDnode = taosArrayGet(pArray, i);
mDebug("dnode:%d, equivalent vnodes:%d", pDnode->id, pDnode->numOfVnodes);
}
+ int32_t removedNum = 0;
for (int32_t d = taosArrayGetSize(pArray) - 1; d >= 0; --d) {
SDnodeObj *pDnode = taosArrayGet(pArray, d);
@@ -662,6 +657,7 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p
int32_t numOfRows = 0;
SVgObj *pVgroup = NULL;
int32_t cols = 0;
+ int64_t curMs = taosGetTimestampMs();
SDbObj *pDb = NULL;
if (strlen(pShow->db) > 0) {
@@ -701,12 +697,15 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p
if (i < pVgroup->replica) {
colDataAppend(pColInfo, numOfRows, (const char *)&pVgroup->vnodeGid[i].dnodeId, false);
+ bool online = false;
+ SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
+ if (pDnode != NULL) {
+ online = mndIsDnodeOnline(pMnode, pDnode, curMs);
+ mndReleaseDnode(pMnode, pDnode);
+ }
+
char buf1[20] = {0};
- SDnodeObj *pDnodeObj = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId);
- ASSERT(pDnodeObj != NULL);
- bool isOffLine = !mndIsDnodeOnline(pMnode, pDnodeObj, taosGetTimestampMs());
- const char *role = isOffLine ? "OFFLINE" : syncStr(pVgroup->vnodeGid[i].role);
-
+ const char *role = online ? syncStr(pVgroup->vnodeGid[i].role) : "OFFLINE";
STR_WITH_MAXSIZE_TO_VARSTR(buf1, role, pShow->pMeta->pSchemas[cols].bytes);
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
diff --git a/source/dnode/mnode/impl/test/trans/trans2.cpp b/source/dnode/mnode/impl/test/trans/trans2.cpp
index cfcfc2490e022092386b64f859befe4b1b922c80..022c82c73d66ab39f9cf07aeb34642278018722d 100644
--- a/source/dnode/mnode/impl/test/trans/trans2.cpp
+++ b/source/dnode/mnode/impl/test/trans/trans2.cpp
@@ -11,6 +11,8 @@
#include
+#if 0
+
#include "mndTrans.h"
#include "mndUser.h"
#include "tcache.h"
@@ -103,7 +105,7 @@ class MndTestTrans2 : public ::testing::Test {
void SetUp() override {}
void TearDown() override {}
- int32_t CreateUserLog(const char *acct, const char *user, ETrnType type, SDbObj *pDb) {
+ int32_t CreateUserLog(const char *acct, const char *user, ETrnConflct conflict, SDbObj *pDb) {
SUserObj userObj = {0};
taosEncryptPass_c((uint8_t *)"taosdata", strlen("taosdata"), userObj.pass);
tstrncpy(userObj.user, user, TSDB_USER_LEN);
@@ -113,7 +115,7 @@ class MndTestTrans2 : public ::testing::Test {
userObj.superUser = 1;
SRpcMsg rpcMsg = {0};
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, type, &rpcMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, conflict, &rpcMsg);
SSdbRaw *pRedoRaw = mndUserActionEncode(&userObj);
mndTransAppendRedolog(pTrans, pRedoRaw);
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
@@ -126,7 +128,7 @@ class MndTestTrans2 : public ::testing::Test {
mndTransSetCb(pTrans, TRANS_START_FUNC_TEST, TRANS_STOP_FUNC_TEST, param, strlen(param) + 1);
if (pDb != NULL) {
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
}
int32_t code = mndTransPrepare(pMnode, pTrans);
@@ -135,7 +137,7 @@ class MndTestTrans2 : public ::testing::Test {
return code;
}
- int32_t CreateUserAction(const char *acct, const char *user, bool hasUndoAction, ETrnPolicy policy, ETrnType type,
+ int32_t CreateUserAction(const char *acct, const char *user, bool hasUndoAction, ETrnPolicy policy, ETrnConflct conflict,
SDbObj *pDb) {
SUserObj userObj = {0};
taosEncryptPass_c((uint8_t *)"taosdata", strlen("taosdata"), userObj.pass);
@@ -146,7 +148,7 @@ class MndTestTrans2 : public ::testing::Test {
userObj.superUser = 1;
SRpcMsg rpcMsg = {0};
- STrans *pTrans = mndTransCreate(pMnode, policy, type, &rpcMsg);
+ STrans *pTrans = mndTransCreate(pMnode, policy, conflict, &rpcMsg);
SSdbRaw *pRedoRaw = mndUserActionEncode(&userObj);
mndTransAppendRedolog(pTrans, pRedoRaw);
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
@@ -199,7 +201,7 @@ class MndTestTrans2 : public ::testing::Test {
}
if (pDb != NULL) {
- mndTransSetDbInfo(pTrans, pDb);
+ mndTransSetDbName(pTrans, pDb->name);
}
int32_t code = mndTransPrepare(pMnode, pTrans);
@@ -218,7 +220,7 @@ class MndTestTrans2 : public ::testing::Test {
userObj.superUser = 1;
SRpcMsg rpcMsg = {0};
- STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_CREATE_USER, &rpcMsg);
+ STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, &rpcMsg);
SSdbRaw *pRedoRaw = mndUserActionEncode(&userObj);
mndTransAppendRedolog(pTrans, pRedoRaw);
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
@@ -528,3 +530,5 @@ TEST_F(MndTestTrans2, 04_Conflict) {
mndReleaseUser(pMnode, pUser);
}
}
+
+#endif
\ No newline at end of file
diff --git a/source/dnode/mnode/impl/test/user/CMakeLists.txt b/source/dnode/mnode/impl/test/user/CMakeLists.txt
index b39ea0e73f728cacc648f6eb0723328e028c05f4..ed4d96461742a77fd4a2ba3d0b9cd070c2f00c43 100644
--- a/source/dnode/mnode/impl/test/user/CMakeLists.txt
+++ b/source/dnode/mnode/impl/test/user/CMakeLists.txt
@@ -5,7 +5,9 @@ target_link_libraries(
PUBLIC sut
)
-add_test(
- NAME userTest
- COMMAND userTest
-)
+if(NOT TD_WINDOWS)
+ add_test(
+ NAME userTest
+ COMMAND userTest
+ )
+endif(NOT TD_WINDOWS)
diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h
index c66b47a24b13f0c9efd55dc965743416737177ea..4a00befa1e8ec1b4ef4ff20a51a066ed08cf1883 100644
--- a/source/dnode/mnode/sdb/inc/sdb.h
+++ b/source/dnode/mnode/sdb/inc/sdb.h
@@ -168,6 +168,7 @@ typedef struct SSdb {
char *currDir;
char *tmpDir;
int64_t lastCommitVer;
+ int64_t lastCommitTerm;
int64_t curVer;
int64_t curTerm;
int64_t tableVer[SDB_MAX];
@@ -300,6 +301,7 @@ void sdbRelease(SSdb *pSdb, void *pObj);
* @return void* The next iterator of the table.
*/
void *sdbFetch(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj);
+void *sdbFetchAll(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj, ESdbStatus *status) ;
/**
* @brief Cancel a traversal
diff --git a/source/dnode/mnode/sdb/src/sdb.c b/source/dnode/mnode/sdb/src/sdb.c
index 485b729deb52ffcdf4c5b76c1999124a5157f5b2..0526ea5c2d65cee2b57d6312b92b90830bad0b8b 100644
--- a/source/dnode/mnode/sdb/src/sdb.c
+++ b/source/dnode/mnode/sdb/src/sdb.c
@@ -55,6 +55,7 @@ SSdb *sdbInit(SSdbOpt *pOption) {
pSdb->curVer = -1;
pSdb->curTerm = -1;
pSdb->lastCommitVer = -1;
+ pSdb->lastCommitTerm = -1;
pSdb->pMnode = pOption->pMnode;
taosThreadMutexInit(&pSdb->filelock, NULL);
mDebug("sdb init successfully");
diff --git a/source/dnode/mnode/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c
index 834e7a00c8c58638a9ac51ec498f87d66abe2b1e..83135491a993e5f8106ed05409255951342c0ac7 100644
--- a/source/dnode/mnode/sdb/src/sdbFile.c
+++ b/source/dnode/mnode/sdb/src/sdbFile.c
@@ -70,6 +70,7 @@ static void sdbResetData(SSdb *pSdb) {
pSdb->curVer = -1;
pSdb->curTerm = -1;
pSdb->lastCommitVer = -1;
+ pSdb->lastCommitTerm = -1;
mDebug("sdb reset successfully");
}
@@ -211,12 +212,12 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
char file[PATH_MAX] = {0};
snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
- mDebug("start to read file:%s", file);
+ mDebug("start to read sdb file:%s", file);
SSdbRaw *pRaw = taosMemoryMalloc(WAL_MAX_SIZE + 100);
if (pRaw == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
- mError("failed read file since %s", terrstr());
+ mError("failed read sdb file since %s", terrstr());
return -1;
}
@@ -224,12 +225,12 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
if (pFile == NULL) {
taosMemoryFree(pRaw);
terrno = TAOS_SYSTEM_ERROR(errno);
- mError("failed to read file:%s since %s", file, terrstr());
+ mError("failed to read sdb file:%s since %s", file, terrstr());
return 0;
}
if (sdbReadFileHead(pSdb, pFile) != 0) {
- mError("failed to read file:%s head since %s", file, terrstr());
+ mError("failed to read sdb file:%s head since %s", file, terrstr());
taosMemoryFree(pRaw);
taosCloseFile(&pFile);
return -1;
@@ -245,13 +246,13 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
if (ret < 0) {
code = TAOS_SYSTEM_ERROR(errno);
- mError("failed to read file:%s since %s", file, tstrerror(code));
+ mError("failed to read sdb file:%s since %s", file, tstrerror(code));
break;
}
if (ret != readLen) {
code = TSDB_CODE_FILE_CORRUPTED;
- mError("failed to read file:%s since %s", file, tstrerror(code));
+ mError("failed to read sdb file:%s since %s", file, tstrerror(code));
break;
}
@@ -259,34 +260,36 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
ret = taosReadFile(pFile, pRaw->pData, readLen);
if (ret < 0) {
code = TAOS_SYSTEM_ERROR(errno);
- mError("failed to read file:%s since %s", file, tstrerror(code));
+ mError("failed to read sdb file:%s since %s", file, tstrerror(code));
break;
}
if (ret != readLen) {
code = TSDB_CODE_FILE_CORRUPTED;
- mError("failed to read file:%s since %s", file, tstrerror(code));
+ mError("failed to read sdb file:%s since %s", file, tstrerror(code));
break;
}
int32_t totalLen = sizeof(SSdbRaw) + pRaw->dataLen + sizeof(int32_t);
if ((!taosCheckChecksumWhole((const uint8_t *)pRaw, totalLen)) != 0) {
code = TSDB_CODE_CHECKSUM_ERROR;
- mError("failed to read file:%s since %s", file, tstrerror(code));
+ mError("failed to read sdb file:%s since %s", file, tstrerror(code));
break;
}
code = sdbWriteWithoutFree(pSdb, pRaw);
if (code != 0) {
- mError("failed to read file:%s since %s", file, terrstr());
+ mError("failed to read sdb file:%s since %s", file, terrstr());
goto _OVER;
}
}
code = 0;
pSdb->lastCommitVer = pSdb->curVer;
+ pSdb->lastCommitTerm = pSdb->curTerm;
memcpy(pSdb->tableVer, tableVer, sizeof(tableVer));
- mDebug("read file:%s successfully, ver:%" PRId64, file, pSdb->lastCommitVer);
+ mDebug("read sdb file:%s successfully, ver:%" PRId64 " term:%" PRId64, file, pSdb->lastCommitVer,
+ pSdb->lastCommitTerm);
_OVER:
taosCloseFile(&pFile);
@@ -302,7 +305,7 @@ int32_t sdbReadFile(SSdb *pSdb) {
sdbResetData(pSdb);
int32_t code = sdbReadFileImp(pSdb);
if (code != 0) {
- mError("failed to read sdb since %s", terrstr());
+ mError("failed to read sdb file since %s", terrstr());
sdbResetData(pSdb);
}
@@ -318,18 +321,19 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
char curfile[PATH_MAX] = {0};
snprintf(curfile, sizeof(curfile), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
- mDebug("start to write file:%s, current ver:%" PRId64 " term:%" PRId64 ", commit ver:%" PRId64, curfile, pSdb->curVer,
- pSdb->curTerm, pSdb->lastCommitVer);
+ mDebug("start to write sdb file, current ver:%" PRId64 " term:%" PRId64 ", commit ver:%" PRId64 " term:%" PRId64
+ " file:%s",
+ pSdb->curVer, pSdb->curTerm, pSdb->lastCommitVer, pSdb->lastCommitTerm, curfile);
TdFilePtr pFile = taosOpenFile(tmpfile, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
if (pFile == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
- mError("failed to open file:%s for write since %s", tmpfile, terrstr());
+ mError("failed to open sdb file:%s for write since %s", tmpfile, terrstr());
return -1;
}
if (sdbWriteFileHead(pSdb, pFile) != 0) {
- mError("failed to write file:%s head since %s", tmpfile, terrstr());
+ mError("failed to write sdb file:%s head since %s", tmpfile, terrstr());
taosCloseFile(&pFile);
return -1;
}
@@ -338,7 +342,7 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
SdbEncodeFp encodeFp = pSdb->encodeFps[i];
if (encodeFp == NULL) continue;
- mTrace("write %s to file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
+ mTrace("write %s to sdb file, total %d rows", sdbTableName(i), sdbGetSize(pSdb, i));
SHashObj *hash = pSdb->hashObjs[i];
TdThreadRwlock *pLock = &pSdb->locks[i];
@@ -394,7 +398,7 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
code = taosFsyncFile(pFile);
if (code != 0) {
code = TAOS_SYSTEM_ERROR(errno);
- mError("failed to sync file:%s since %s", tmpfile, tstrerror(code));
+ mError("failed to sync sdb file:%s since %s", tmpfile, tstrerror(code));
}
}
@@ -404,15 +408,17 @@ static int32_t sdbWriteFileImp(SSdb *pSdb) {
code = taosRenameFile(tmpfile, curfile);
if (code != 0) {
code = TAOS_SYSTEM_ERROR(errno);
- mError("failed to write file:%s since %s", curfile, tstrerror(code));
+ mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
}
}
if (code != 0) {
- mError("failed to write file:%s since %s", curfile, tstrerror(code));
+ mError("failed to write sdb file:%s since %s", curfile, tstrerror(code));
} else {
pSdb->lastCommitVer = pSdb->curVer;
- mDebug("write file:%s successfully, ver:%" PRId64 " term:%" PRId64, curfile, pSdb->lastCommitVer, pSdb->curTerm);
+ pSdb->lastCommitTerm = pSdb->curTerm;
+ mDebug("write sdb file successfully, ver:%" PRId64 " term:%" PRId64 " file:%s", pSdb->lastCommitVer,
+ pSdb->lastCommitTerm, curfile);
}
terrno = code;
@@ -427,7 +433,7 @@ int32_t sdbWriteFile(SSdb *pSdb) {
taosThreadMutexLock(&pSdb->filelock);
int32_t code = sdbWriteFileImp(pSdb);
if (code != 0) {
- mError("failed to write sdb since %s", terrstr());
+ mError("failed to write sdb file since %s", terrstr());
}
taosThreadMutexUnlock(&pSdb->filelock);
return code;
@@ -493,7 +499,7 @@ int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter) {
if (taosCopyFile(datafile, pIter->name) < 0) {
taosThreadMutexUnlock(&pSdb->filelock);
terrno = TAOS_SYSTEM_ERROR(errno);
- mError("failed to copy file %s to %s since %s", datafile, pIter->name, terrstr());
+ mError("failed to copy sdb file %s to %s since %s", datafile, pIter->name, terrstr());
sdbCloseIter(pIter);
return -1;
}
@@ -502,7 +508,7 @@ int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter) {
pIter->file = taosOpenFile(pIter->name, TD_FILE_READ);
if (pIter->file == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
- mError("failed to open file:%s since %s", pIter->name, terrstr());
+ mError("failed to open sdb file:%s since %s", pIter->name, terrstr());
sdbCloseIter(pIter);
return -1;
}
diff --git a/source/dnode/mnode/sdb/src/sdbHash.c b/source/dnode/mnode/sdb/src/sdbHash.c
index abf35b71a91ea368b6d1bbc8e0927be59642ce6d..162da2bd0aaa3e2400f14cefa0596b5022e7afbe 100644
--- a/source/dnode/mnode/sdb/src/sdbHash.c
+++ b/source/dnode/mnode/sdb/src/sdbHash.c
@@ -368,6 +368,34 @@ void *sdbFetch(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj) {
return ppRow;
}
+void *sdbFetchAll(SSdb *pSdb, ESdbType type, void *pIter, void **ppObj, ESdbStatus *status) {
+ *ppObj = NULL;
+
+ SHashObj *hash = sdbGetHash(pSdb, type);
+ if (hash == NULL) return NULL;
+
+ TdThreadRwlock *pLock = &pSdb->locks[type];
+ taosThreadRwlockRdlock(pLock);
+
+ SSdbRow **ppRow = taosHashIterate(hash, pIter);
+ while (ppRow != NULL) {
+ SSdbRow *pRow = *ppRow;
+ if (pRow == NULL) {
+ ppRow = taosHashIterate(hash, ppRow);
+ continue;
+ }
+
+ atomic_add_fetch_32(&pRow->refCount, 1);
+ sdbPrintOper(pSdb, pRow, "fetch");
+ *ppObj = pRow->pObj;
+ *status = pRow->status;
+ break;
+ }
+ taosThreadRwlockUnlock(pLock);
+
+ return ppRow;
+}
+
void sdbCancelFetch(SSdb *pSdb, void *pIter) {
if (pIter == NULL) return;
SSdbRow *pRow = *(SSdbRow **)pIter;
diff --git a/source/dnode/qnode/src/qnode.c b/source/dnode/qnode/src/qnode.c
index 40aa572a56709a97e454cdc82cb7e97852356b27..438982ac6ae2ca13f2244acd978bdc58c723d6de 100644
--- a/source/dnode/qnode/src/qnode.c
+++ b/source/dnode/qnode/src/qnode.c
@@ -41,12 +41,24 @@ void qndClose(SQnode *pQnode) {
}
int32_t qndGetLoad(SQnode *pQnode, SQnodeLoad *pLoad) {
- SMsgCb* pCb = &pQnode->msgCb;
+ SReadHandle handle = {.pMsgCb = &pQnode->msgCb};
+ SQWorkerStat stat = {0};
+
+ int32_t code = qWorkerGetStat(&handle, pQnode->pQuery, &stat);
+ if (code) {
+ return code;
+ }
- pLoad->numOfQueryInQueue = pCb->qsizeFp(pCb->mgmt, pQnode->qndId, QUERY_QUEUE);
- pLoad->numOfFetchInQueue = pCb->qsizeFp(pCb->mgmt, pQnode->qndId, FETCH_QUEUE);
- pLoad->waitTimeInQueryQUeue = qWorkerGetWaitTimeInQueue(pQnode->pQuery, QUERY_QUEUE);
- pLoad->waitTimeInFetchQUeue = qWorkerGetWaitTimeInQueue(pQnode->pQuery, FETCH_QUEUE);
+ pLoad->numOfQueryInQueue = stat.numOfQueryInQueue;
+ pLoad->numOfFetchInQueue = stat.numOfFetchInQueue;
+ pLoad->timeInQueryQueue = stat.timeInQueryQueue;
+ pLoad->timeInFetchQueue = stat.timeInFetchQueue;
+ pLoad->cacheDataSize = stat.cacheDataSize;
+ pLoad->numOfProcessedQuery = stat.queryProcessed;
+ pLoad->numOfProcessedCQuery = stat.cqueryProcessed;
+ pLoad->numOfProcessedFetch = stat.fetchProcessed;
+ pLoad->numOfProcessedDrop = stat.dropProcessed;
+ pLoad->numOfProcessedHb = stat.hbProcessed;
return 0;
}
diff --git a/source/dnode/vnode/CMakeLists.txt b/source/dnode/vnode/CMakeLists.txt
index d988f97188b9330e1229368554b0f75a5713025b..890b8d08ab97b6f7db1bd0329466cb6f67db8910 100644
--- a/source/dnode/vnode/CMakeLists.txt
+++ b/source/dnode/vnode/CMakeLists.txt
@@ -35,7 +35,6 @@ target_sources(
"src/sma/smaTimeRange.c"
# tsdb
- # "src/tsdb/tsdbTDBImpl.c"
"src/tsdb/tsdbCommit.c"
"src/tsdb/tsdbCommit2.c"
"src/tsdb/tsdbFile.c"
@@ -45,16 +44,18 @@ target_sources(
"src/tsdb/tsdbMemTable2.c"
"src/tsdb/tsdbRead.c"
"src/tsdb/tsdbReadImpl.c"
- # "src/tsdb/tsdbSma.c"
"src/tsdb/tsdbWrite.c"
"src/tsdb/tsdbSnapshot.c"
# tq
"src/tq/tq.c"
- "src/tq/tqCommit.c"
+ "src/tq/tqExec.c"
+ "src/tq/tqMeta.c"
+ "src/tq/tqRead.c"
"src/tq/tqOffset.c"
"src/tq/tqPush.c"
- "src/tq/tqRead.c"
+ "src/tq/tqSink.c"
+ "src/tq/tqCommit.c"
)
target_include_directories(
vnode
diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h
index e4343e3bbf63a9dd847cc1bd2f79e2ef35721cd3..308f89736d2e1efd2263a8a6c130cc059574d243 100644
--- a/source/dnode/vnode/inc/vnode.h
+++ b/source/dnode/vnode/inc/vnode.h
@@ -68,6 +68,7 @@ void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId);
int32_t vnodeSnapshotReaderOpen(SVnode *pVnode, SVSnapshotReader **ppReader, int64_t sver, int64_t ever);
int32_t vnodeSnapshotReaderClose(SVSnapshotReader *pReader);
int32_t vnodeSnapshotRead(SVSnapshotReader *pReader, const void **ppData, uint32_t *nData);
+int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen);
// meta
typedef struct SMeta SMeta; // todo: remove
@@ -78,7 +79,19 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags);
void metaReaderClear(SMetaReader *pReader);
int32_t metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid);
int32_t metaReadNext(SMetaReader *pReader);
-const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t cid);
+const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t type, STagVal *tagVal);
+
+typedef struct SMetaFltParam {
+ tb_uid_t suid;
+ int16_t cid;
+ int16_t type;
+ char *val;
+ bool reverse;
+ int (*filterFunc)(void *a, void *b, int16_t type);
+
+} SMetaFltParam;
+
+int32_t metaFilteTableIds(SMeta *pMeta, SMetaFltParam *param, SArray *results);
#if 1 // refact APIs below (TODO)
typedef SVCreateTbReq STbCfg;
@@ -106,7 +119,8 @@ tsdbReaderT tsdbQueryCacheLast(SVnode *pVnode, SQueryTableDataCond *pCond, STab
int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT *pReader, STableBlockDistInfo *pTableBlockInfo);
bool isTsdbCacheLastRow(tsdbReaderT *pReader);
int32_t tsdbGetAllTableList(SMeta *pMeta, uint64_t uid, SArray *list);
-void * tsdbGetIdx(SMeta *pMeta);
+int32_t tsdbGetCtbIdList(SMeta *pMeta, int64_t suid, SArray *list);
+void *tsdbGetIdx(SMeta *pMeta);
int64_t tsdbGetNumOfRowsInMemTable(tsdbReaderT *pHandle);
bool tsdbNextDataBlock(tsdbReaderT pTsdbReadHandle);
@@ -159,12 +173,15 @@ struct SVnodeCfg {
uint64_t szBuf;
bool isHeap;
bool isWeak;
+ int8_t isTsma;
+ int8_t isRsma;
+ int8_t hashMethod;
+ int8_t standby;
STsdbCfg tsdbCfg;
SWalCfg walCfg;
SSyncCfg syncCfg;
uint32_t hashBegin;
uint32_t hashEnd;
- int8_t hashMethod;
};
typedef struct {
@@ -176,7 +193,7 @@ struct SMetaEntry {
int64_t version;
int8_t type;
tb_uid_t uid;
- char * name;
+ char *name;
union {
struct {
SSchemaWrapper schemaRow;
@@ -204,17 +221,17 @@ struct SMetaEntry {
struct SMetaReader {
int32_t flags;
- SMeta * pMeta;
+ SMeta *pMeta;
SDecoder coder;
SMetaEntry me;
- void * pBuf;
+ void *pBuf;
int32_t szBuf;
};
struct SMTbCursor {
- TBC * pDbc;
- void * pKey;
- void * pVal;
+ TBC *pDbc;
+ void *pKey;
+ void *pVal;
int32_t kLen;
int32_t vLen;
SMetaReader mr;
diff --git a/source/dnode/vnode/src/inc/meta.h b/source/dnode/vnode/src/inc/meta.h
index 3340bbb91ce0f8ed29b2ef48fc325472676b56e1..52e576ee5249de37a9b30c137bff98f123999081 100644
--- a/source/dnode/vnode/src/inc/meta.h
+++ b/source/dnode/vnode/src/inc/meta.h
@@ -16,8 +16,8 @@
#ifndef _TD_VNODE_META_H_
#define _TD_VNODE_META_H_
-#include "vnodeInt.h"
#include "index.h"
+#include "vnodeInt.h"
#ifdef __cplusplus
extern "C" {
@@ -45,8 +45,6 @@ int32_t metaULock(SMeta* pMeta);
int metaEncodeEntry(SEncoder* pCoder, const SMetaEntry* pME);
int metaDecodeEntry(SDecoder* pCoder, SMetaEntry* pME);
-// metaTable ==================
-
// metaQuery ==================
int metaGetTableEntryByVersion(SMetaReader* pReader, int64_t version, tb_uid_t uid);
@@ -118,6 +116,10 @@ typedef struct {
int64_t smaUid;
} SSmaIdxKey;
+// metaTable ==================
+int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void* pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
+ STagIdxKey** ppTagIdxKey, int32_t* nTagIdxKey);
+
#ifndef META_REFACT
// SMetaDB
int metaOpenDB(SMeta* pMeta);
diff --git a/source/dnode/vnode/src/inc/sma.h b/source/dnode/vnode/src/inc/sma.h
index 0601df61e71317aed596d6f200cb8314156430f5..03dd2ea66cb387edeed3a4949936db5affb9592b 100644
--- a/source/dnode/vnode/src/inc/sma.h
+++ b/source/dnode/vnode/src/inc/sma.h
@@ -219,7 +219,7 @@ static int32_t tdInitSmaEnv(SSma *pSma, int8_t smaType, const char *path, SDisk
void *tdFreeRSmaInfo(SRSmaInfo *pInfo);
int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg);
-int32_t tdUpdateExpiredWindowImpl(SSma *pSma, SSubmitReq *pMsg, int64_t version);
+int32_t tdUpdateExpiredWindowImpl(SSma *pSma, const SSubmitReq *pMsg, int64_t version);
// TODO: This is the basic params, and should wrap the params to a queryHandle.
int32_t tdGetTSmaDataImpl(SSma *pSma, char *pData, int64_t indexUid, TSKEY querySKey, int32_t nMaxResult);
@@ -227,4 +227,4 @@ int32_t tdGetTSmaDataImpl(SSma *pSma, char *pData, int64_t indexUid, TSKEY query
}
#endif
-#endif /*_TD_VNODE_SMA_H_*/
\ No newline at end of file
+#endif /*_TD_VNODE_SMA_H_*/
diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h
index 06ff6329e0b3ddc69cc50ec1becc9541e3939ca5..7cd82b0ac37446fa413715150210dbf951485006 100644
--- a/source/dnode/vnode/src/inc/tq.h
+++ b/source/dnode/vnode/src/inc/tq.h
@@ -44,56 +44,93 @@ extern "C" {
typedef struct STqOffsetCfg STqOffsetCfg;
typedef struct STqOffsetStore STqOffsetStore;
+// tqRead
+
struct STqReadHandle {
int64_t ver;
- SHashObj* tbIdHash;
const SSubmitReq* pMsg;
SSubmitBlk* pBlock;
SSubmitMsgIter msgIter;
SSubmitBlkIter blkIter;
- SMeta* pVnodeMeta;
- SArray* pColIdList; // SArray
- int32_t sver;
- int64_t cachedSchemaUid;
- SSchemaWrapper* pSchemaWrapper;
- STSchema* pSchema;
+
+ SMeta* pVnodeMeta;
+ SHashObj* tbIdHash;
+ SArray* pColIdList; // SArray
+
+ int32_t cachedSchemaVer;
+ int64_t cachedSchemaUid;
+ SSchemaWrapper* pSchemaWrapper;
+ STSchema* pSchema;
};
+// tqPush
+
typedef struct {
- int64_t consumerId;
- int32_t epoch;
- int32_t skipLogNum;
- int64_t reqOffset;
+ // msg info
+ int64_t consumerId;
+ int64_t reqOffset;
+ int64_t processedVer;
+ int32_t epoch;
+ int32_t skipLogNum;
+ // rpc info
+ int64_t reqId;
+ SRpcHandleInfo rpcInfo;
+ tmr_h timerId;
+ int8_t tmrStopped;
+ // exec
+ int8_t inputStatus;
+ int8_t execStatus;
+ SStreamQ inputQ;
SRWLatch lock;
- SRpcMsg* handle;
} STqPushHandle;
+// tqExec
+
typedef struct {
- char subKey[TSDB_SUBSCRIBE_KEY_LEN];
- int64_t consumerId;
- int32_t epoch;
- int8_t subType;
- int8_t withTbName;
- int8_t withSchema;
- int8_t withTag;
- char* qmsg;
- SHashObj* pDropTbUid;
- STqPushHandle pushHandle;
- // SRWLatch lock;
- SWalReadHandle* pWalReader;
- // task number should be the same with fetch thread
+ char* qmsg;
+ qTaskInfo_t task[5];
+} STqExecCol;
+
+typedef struct {
+ int64_t suid;
+} STqExecTb;
+
+typedef struct {
+ SHashObj* pFilterOutTbUid;
+} STqExecDb;
+
+typedef struct {
+ int8_t subType;
+
STqReadHandle* pExecReader[5];
- qTaskInfo_t task[5];
-} STqExec;
+ union {
+ STqExecCol execCol;
+ STqExecTb execTb;
+ STqExecDb execDb;
+ } exec;
+} STqExecHandle;
+
+typedef struct {
+ // info
+ char subKey[TSDB_SUBSCRIBE_KEY_LEN];
+ int64_t consumerId;
+ int32_t epoch;
+
+ // reader
+ SWalReadHandle* pWalReader;
-int32_t tEncodeSTqExec(SEncoder* pEncoder, const STqExec* pExec);
-int32_t tDecodeSTqExec(SDecoder* pDecoder, STqExec* pExec);
+ // push
+ STqPushHandle pushHandle;
+
+ // exec
+ STqExecHandle execHandle;
+} STqHandle;
struct STQ {
char* path;
- SHashObj* pushMgr; // consumerId -> STqExec*
- SHashObj* execs; // subKey -> STqExec
- SHashObj* pStreamTasks;
+ SHashObj* pushMgr; // consumerId -> STqHandle*
+ SHashObj* handles; // subKey -> STqHandle
+ SHashObj* pStreamTasks; // taksId -> SStreamTask
SVnode* pVnode;
SWal* pWal;
TDB* pMetaStore;
@@ -107,18 +144,29 @@ typedef struct {
static STqMgmt tqMgmt = {0};
-// init once
-int tqInit();
-void tqCleanUp();
+// tqRead
+int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead** pHeadWithCkSum);
-// tqOffset
-STqOffsetStore* STqOffsetOpen(STqOffsetCfg*);
-void STqOffsetClose(STqOffsetStore*);
+// tqExec
+int32_t tqDataExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataBlkRsp* pRsp, int32_t workerId);
+int32_t tqSendPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataBlkRsp* pRsp);
-int64_t tqOffsetFetch(STqOffsetStore* pStore, const char* subscribeKey);
-int32_t tqOffsetCommit(STqOffsetStore* pStore, const char* subscribeKey, int64_t offset);
-int32_t tqOffsetPersist(STqOffsetStore* pStore, const char* subscribeKey);
-int32_t tqOffsetPersistAll(STqOffsetStore* pStore);
+// tqMeta
+int32_t tqMetaOpen(STQ* pTq);
+int32_t tqMetaClose(STQ* pTq);
+int32_t tqMetaSaveHandle(STQ* pTq, const char* key, const STqHandle* pHandle);
+int32_t tqMetaDeleteHandle(STQ* pTq, const char* key);
+
+// tqSink
+void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data);
+
+// tqOffset
+STqOffsetStore* tqOffsetOpen(STqOffsetCfg*);
+void tqOffsetClose(STqOffsetStore*);
+int64_t tqOffsetFetch(STqOffsetStore* pStore, const char* subscribeKey);
+int32_t tqOffsetCommit(STqOffsetStore* pStore, const char* subscribeKey, int64_t offset);
+int32_t tqOffsetPersist(STqOffsetStore* pStore, const char* subscribeKey);
+int32_t tqOffsetPersistAll(STqOffsetStore* pStore);
#ifdef __cplusplus
}
diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h
index 2e4ff6a4abd8315afa06e9a881955947af9144c6..a62b4c4409ae0a4561c5150e4d6bd669698e666c 100644
--- a/source/dnode/vnode/src/inc/tsdb.h
+++ b/source/dnode/vnode/src/inc/tsdb.h
@@ -32,14 +32,27 @@ extern "C" {
#define tsdbTrace(...) do { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TSDB ", DEBUG_TRACE, tsdbDebugFlag, __VA_ARGS__); }} while(0)
// clang-format on
+typedef struct TSDBROW TSDBROW;
+typedef struct TSDBKEY TSDBKEY;
+typedef struct SDelOp SDelOp;
+
+static int tsdbKeyCmprFn(const void *p1, const void *p2);
+
+// tsdbMemTable2.c ==============================================================================================
+typedef struct SMemTable SMemTable;
+
+int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTable);
+void tsdbMemTableDestroy2(SMemTable *pMemTable);
+
// tsdbMemTable ================
+typedef struct STsdbRow STsdbRow;
typedef struct STbData STbData;
typedef struct STsdbMemTable STsdbMemTable;
typedef struct SMergeInfo SMergeInfo;
typedef struct STable STable;
int tsdbMemTableCreate(STsdb *pTsdb, STsdbMemTable **ppMemTable);
-void tsdbMemTableDestroy(STsdb *pTsdb, STsdbMemTable *pMemTable);
+void tsdbMemTableDestroy(STsdbMemTable *pMemTable);
int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead,
SDataCols *pCols, TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo);
@@ -845,6 +858,42 @@ static FORCE_INLINE int tsdbUnLockFS(STsdbFS *pFs) {
return 0;
}
+struct TSDBROW {
+ int64_t version;
+ STSRow2 tsRow;
+};
+
+struct TSDBKEY {
+ int64_t version;
+ TSKEY ts;
+};
+
+struct SDelOp {
+ int64_t version;
+ TSKEY sKey; // included
+ TSKEY eKey; // included
+ SDelOp *pNext;
+};
+
+static FORCE_INLINE int tsdbKeyCmprFn(const void *p1, const void *p2) {
+ TSDBKEY *pKey1 = (TSDBKEY *)p1;
+ TSDBKEY *pKey2 = (TSDBKEY *)p2;
+
+ if (pKey1->ts < pKey2->ts) {
+ return -1;
+ } else if (pKey1->ts > pKey2->ts) {
+ return 1;
+ }
+
+ if (pKey1->version < pKey2->version) {
+ return -1;
+ } else if (pKey1->version > pKey2->version) {
+ return 1;
+ }
+
+ return 0;
+}
+
#endif
#ifdef __cplusplus
diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h
index eb3382ac4cd46a602a214b09b5a8debeaf15087f..a5907cf9912aa9af0caff46e0aea85d690076cbb 100644
--- a/source/dnode/vnode/src/inc/vnd.h
+++ b/source/dnode/vnode/src/inc/vnd.h
@@ -81,9 +81,10 @@ int32_t vnodeSyncCommit(SVnode* pVnode);
int32_t vnodeAsyncCommit(SVnode* pVnode);
// vnodeSync.c
-int32_t vnodeSyncOpen(SVnode* pVnode, char* path);
-void vnodeSyncStart(SVnode* pVnode);
-void vnodeSyncClose(SVnode* pVnode);
+int32_t vnodeSyncOpen(SVnode* pVnode, char* path);
+void vnodeSyncStart(SVnode* pVnode);
+void vnodeSyncClose(SVnode* pVnode);
+void vnodeSyncAlter(SVnode* pVnode, SRpcMsg* pMsg);
#ifdef __cplusplus
}
diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h
index 0e67d9e426f1b708e927d986f7c9d797acc8759d..d3b5f29aac9e1ed96d8fe3569065ecaa8a1a1706 100644
--- a/source/dnode/vnode/src/inc/vnodeInt.h
+++ b/source/dnode/vnode/src/inc/vnodeInt.h
@@ -87,7 +87,7 @@ int metaAlterSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* p
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq);
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids);
-int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq);
+int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp *pMetaRsp);
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
@@ -125,6 +125,8 @@ int32_t tsdbSnapshotReaderClose(STsdbSnapshotReader* pReader);
int32_t tsdbSnapshotRead(STsdbSnapshotReader* pReader, void** ppData, uint32_t* nData);
// tq
+int tqInit();
+void tqCleanUp();
STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal);
void tqClose(STQ*);
int tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
@@ -145,11 +147,11 @@ int32_t tqProcessTaskRecoverRsp(STQ* pTq, SRpcMsg* pMsg);
int32_t smaOpen(SVnode* pVnode);
int32_t smaClose(SSma* pSma);
-int32_t tdUpdateExpireWindow(SSma* pSma, SSubmitReq* pMsg, int64_t version);
+int32_t tdUpdateExpireWindow(SSma* pSma, const SSubmitReq* pMsg, int64_t version);
int32_t tdProcessTSmaCreate(SSma* pSma, int64_t version, const char* msg);
int32_t tdProcessTSmaInsert(SSma* pSma, int64_t indexUid, const char* msg);
-int32_t tdProcessRSmaCreate(SSma* pSma, SMeta* pMeta, SVCreateStbReq* pReq, SMsgCb* pMsgCb);
+int32_t tdProcessRSmaCreate(SVnode* pVnode, SVCreateStbReq* pReq);
int32_t tdProcessRSmaSubmit(SSma* pSma, void* pMsg, int32_t inputType);
int32_t tdFetchTbUidList(SSma* pSma, STbUidStore** ppStore, tb_uid_t suid, tb_uid_t uid);
int32_t tdUpdateTbUidList(SSma* pSma, STbUidStore* pUidStore);
@@ -239,6 +241,8 @@ struct SVnode {
#define VND_RSMA1(vnd) ((vnd)->pSma->pRSmaTsdb1)
#define VND_RSMA2(vnd) ((vnd)->pSma->pRSmaTsdb2)
#define VND_RETENTIONS(vnd) (&(vnd)->config.tsdbCfg.retentions)
+#define VND_IS_RSMA(v) ((v)->config.isRsma == 1)
+#define VND_IS_TSMA(v) ((v)->config.isTsma == 1)
struct STbUidStore {
tb_uid_t suid;
@@ -271,11 +275,6 @@ struct SSma {
#define SMA_RSMA_TSDB1(s) ((s)->pRSmaTsdb1)
#define SMA_RSMA_TSDB2(s) ((s)->pRSmaTsdb2)
-static FORCE_INLINE bool vnodeIsRollup(SVnode* pVnode) {
- SRetention* pRetention = &(pVnode->config.tsdbCfg.retentions[0]);
- return (pRetention->freq > 0 && pRetention->keep > 0);
-}
-
// sma
void smaHandleRes(void* pVnode, int64_t smaId, const SArray* data);
diff --git a/source/dnode/vnode/src/meta/metaEntry.c b/source/dnode/vnode/src/meta/metaEntry.c
index be2ddfc32f83fcf0d6b5500fb21cdec632c27aa8..db99257ea707d68858887d34cdc29077e099eec3 100644
--- a/source/dnode/vnode/src/meta/metaEntry.c
+++ b/source/dnode/vnode/src/meta/metaEntry.c
@@ -30,7 +30,8 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
if (tEncodeI64(pCoder, pME->ctbEntry.ctime) < 0) return -1;
if (tEncodeI32(pCoder, pME->ctbEntry.ttlDays) < 0) return -1;
if (tEncodeI64(pCoder, pME->ctbEntry.suid) < 0) return -1;
- if (tEncodeBinary(pCoder, pME->ctbEntry.pTags, kvRowLen(pME->ctbEntry.pTags)) < 0) return -1;
+ debugCheckTags((STag*)pME->ctbEntry.pTags); // TODO: remove after debug
+ if (tEncodeTag(pCoder, (const STag *)pME->ctbEntry.pTags) < 0) return -1;
} else if (pME->type == TSDB_NORMAL_TABLE) {
if (tEncodeI64(pCoder, pME->ntbEntry.ctime) < 0) return -1;
if (tEncodeI32(pCoder, pME->ntbEntry.ttlDays) < 0) return -1;
@@ -47,7 +48,6 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
}
int metaDecodeEntry(SDecoder *pCoder, SMetaEntry *pME) {
- uint32_t len;
if (tStartDecode(pCoder) < 0) return -1;
if (tDecodeI64(pCoder, &pME->version) < 0) return -1;
@@ -62,7 +62,8 @@ int metaDecodeEntry(SDecoder *pCoder, SMetaEntry *pME) {
if (tDecodeI64(pCoder, &pME->ctbEntry.ctime) < 0) return -1;
if (tDecodeI32(pCoder, &pME->ctbEntry.ttlDays) < 0) return -1;
if (tDecodeI64(pCoder, &pME->ctbEntry.suid) < 0) return -1;
- if (tDecodeBinary(pCoder, &pME->ctbEntry.pTags, &len) < 0) return -1; // (TODO)
+ if (tDecodeTag(pCoder, (STag **)&pME->ctbEntry.pTags) < 0) return -1; // (TODO)
+ debugCheckTags((STag*)pME->ctbEntry.pTags); // TODO: remove after debug
} else if (pME->type == TSDB_NORMAL_TABLE) {
if (tDecodeI64(pCoder, &pME->ntbEntry.ctime) < 0) return -1;
if (tDecodeI32(pCoder, &pME->ntbEntry.ttlDays) < 0) return -1;
diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c
index 921c8a90a83dbd594cf6c2b0666b3bc87a9022f6..a57eb4e899a2fc18d8a8a1f8c7bcd0d80a528f07 100644
--- a/source/dnode/vnode/src/meta/metaQuery.c
+++ b/source/dnode/vnode/src/meta/metaQuery.c
@@ -31,7 +31,7 @@ void metaReaderClear(SMetaReader *pReader) {
}
int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) {
- SMeta *pMeta = pReader->pMeta;
+ SMeta * pMeta = pReader->pMeta;
STbDbKey tbDbKey = {.version = version, .uid = uid};
// query table.db
@@ -54,7 +54,7 @@ _err:
}
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
- SMeta *pMeta = pReader->pMeta;
+ SMeta * pMeta = pReader->pMeta;
int64_t version;
// query uid.idx
@@ -68,7 +68,7 @@ int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
}
int metaGetTableEntryByName(SMetaReader *pReader, const char *name) {
- SMeta *pMeta = pReader->pMeta;
+ SMeta * pMeta = pReader->pMeta;
tb_uid_t uid;
// query name.idx
@@ -82,7 +82,7 @@ int metaGetTableEntryByName(SMetaReader *pReader, const char *name) {
}
tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) {
- void *pData = NULL;
+ void * pData = NULL;
int nData = 0;
tb_uid_t uid = 0;
@@ -134,7 +134,7 @@ void metaCloseTbCursor(SMTbCursor *pTbCur) {
int metaTbCursorNext(SMTbCursor *pTbCur) {
int ret;
- void *pBuf;
+ void * pBuf;
STbCfg tbCfg;
for (;;) {
@@ -155,7 +155,7 @@ int metaTbCursorNext(SMTbCursor *pTbCur) {
}
SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, bool isinline) {
- void *pData = NULL;
+ void * pData = NULL;
int nData = 0;
int64_t version;
SSchemaWrapper schema = {0};
@@ -205,11 +205,11 @@ _err:
}
struct SMCtbCursor {
- SMeta *pMeta;
- TBC *pCur;
+ SMeta * pMeta;
+ TBC * pCur;
tb_uid_t suid;
- void *pKey;
- void *pVal;
+ void * pKey;
+ void * pVal;
int kLen;
int vLen;
};
@@ -281,10 +281,10 @@ tb_uid_t metaCtbCursorNext(SMCtbCursor *pCtbCur) {
STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
tb_uid_t quid;
SMetaReader mr = {0};
- STSchema *pTSchema = NULL;
+ STSchema * pTSchema = NULL;
SSchemaWrapper *pSW = NULL;
STSchemaBuilder sb = {0};
- SSchema *pSchema;
+ SSchema * pSchema;
metaReaderInit(&mr, pMeta, 0);
metaGetTableEntryByUid(&mr, uid);
@@ -321,11 +321,11 @@ int metaGetTbNum(SMeta *pMeta) {
}
typedef struct {
- SMeta *pMeta;
- TBC *pCur;
+ SMeta * pMeta;
+ TBC * pCur;
tb_uid_t uid;
- void *pKey;
- void *pVal;
+ void * pKey;
+ void * pVal;
int kLen;
int vLen;
} SMSmaCursor;
@@ -397,7 +397,7 @@ tb_uid_t metaSmaCursorNext(SMSmaCursor *pSmaCur) {
STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) {
STSmaWrapper *pSW = NULL;
- SArray *pSmaIds = NULL;
+ SArray * pSmaIds = NULL;
if (!(pSmaIds = metaGetSmaIdsByTable(pMeta, uid))) {
return NULL;
@@ -421,7 +421,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) {
metaReaderInit(&mr, pMeta, 0);
int64_t smaId;
int smaIdx = 0;
- STSma *pTSma = NULL;
+ STSma * pTSma = NULL;
for (int i = 0; i < pSW->number; ++i) {
smaId = *(tb_uid_t *)taosArrayGet(pSmaIds, i);
if (metaGetTableEntryByUid(&mr, smaId) < 0) {
@@ -469,7 +469,7 @@ _err:
}
STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) {
- STSma *pTSma = NULL;
+ STSma * pTSma = NULL;
SMetaReader mr = {0};
metaReaderInit(&mr, pMeta, 0);
if (metaGetTableEntryByUid(&mr, indexUid) < 0) {
@@ -491,7 +491,7 @@ STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) {
}
SArray *metaGetSmaIdsByTable(SMeta *pMeta, tb_uid_t uid) {
- SArray *pUids = NULL;
+ SArray * pUids = NULL;
SSmaIdxKey *pSmaIdxKey = NULL;
SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, uid);
@@ -529,7 +529,7 @@ SArray *metaGetSmaIdsByTable(SMeta *pMeta, tb_uid_t uid) {
}
SArray *metaGetSmaTbUids(SMeta *pMeta) {
- SArray *pUids = NULL;
+ SArray * pUids = NULL;
SSmaIdxKey *pSmaIdxKey = NULL;
tb_uid_t lastUid = 0;
@@ -573,7 +573,101 @@ SArray *metaGetSmaTbUids(SMeta *pMeta) {
#endif
-const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t cid) {
+const void *metaGetTableTagVal(SMetaEntry *pEntry, int16_t type, STagVal *val) {
ASSERT(pEntry->type == TSDB_CHILD_TABLE);
- return tdGetKVRowValOfCol((const SKVRow)pEntry->ctbEntry.pTags, cid);
+ STag *tag = (STag *)pEntry->ctbEntry.pTags;
+ if (type == TSDB_DATA_TYPE_JSON){
+ if(tag->nTag == 0){
+ return NULL;
+ }
+ return tag;
+ }
+ bool find = tTagGet(tag, val);
+
+ if(!find){
+ return NULL;
+ }
+ return val;
+}
+
+typedef struct {
+ SMeta * pMeta;
+ TBC * pCur;
+ tb_uid_t suid;
+ int16_t cid;
+ int16_t type;
+ void * pKey;
+ void * pVal;
+ int32_t kLen;
+ int32_t vLen;
+} SIdxCursor;
+
+int32_t metaFilteTableIds(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
+ SIdxCursor *pCursor = NULL;
+
+ char *tagData = param->val;
+
+ int32_t ret = 0, valid = 0;
+ pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
+ pCursor->pMeta = pMeta;
+ pCursor->suid = param->suid;
+ pCursor->cid = param->cid;
+ pCursor->type = param->type;
+
+ metaRLock(pMeta);
+ ret = tdbTbcOpen(pMeta->pTagIdx, &pCursor->pCur, NULL);
+ if (ret < 0) {
+ goto END;
+ }
+ STagIdxKey *pKey = NULL;
+ int32_t nKey = 0;
+
+ int32_t nTagData = 0;
+ if(IS_VAR_DATA_TYPE(param->type)){
+ nTagData = strlen(param->val);
+ }else{
+ nTagData = tDataTypes[param->type].bytes;
+ }
+ ret = metaCreateTagIdxKey(pCursor->suid, pCursor->cid, param->val, nTagData, pCursor->type,
+ param->reverse ? INT64_MAX : INT64_MIN, &pKey, &nKey);
+ if (ret != 0) {
+ goto END;
+ }
+ int cmp = 0;
+ if (tdbTbcMoveTo(pCursor->pCur, pKey, nKey, &cmp) < 0) {
+ goto END;
+ }
+ void * entryKey = NULL, *entryVal = NULL;
+ int32_t nEntryKey, nEntryVal;
+ while (1) {
+ valid = tdbTbcGet(pCursor->pCur, (const void **)&entryKey, &nEntryKey, (const void **)&entryVal, &nEntryVal);
+ if (valid < 0) {
+ break;
+ }
+ STagIdxKey *p = entryKey;
+ if (p != NULL) {
+ int32_t cmp = (*param->filterFunc)(p->data, pKey->data, pKey->type);
+ if (cmp == 0) {
+ // match
+ tb_uid_t tuid = *(tb_uid_t *)(p->data + tDataTypes[pCursor->type].bytes);
+ taosArrayPush(pUids, &tuid);
+ } else if (cmp == 1) {
+ // not match but should continue to iter
+ } else {
+ // not match and no more result
+ break;
+ }
+ }
+ valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
+ if (valid < 0) {
+ break;
+ }
+ }
+END:
+ if (pCursor->pMeta) metaULock(pCursor->pMeta);
+ if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
+
+ taosMemoryFree(pCursor);
+
+ return ret;
}
\ No newline at end of file
diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c
index f610f18126ef86a268801f73f5a951c97a380867..cb00f9f88711f56c36b6f79b0d06966c0d53aab0 100644
--- a/source/dnode/vnode/src/meta/metaTable.c
+++ b/source/dnode/vnode/src/meta/metaTable.c
@@ -25,15 +25,33 @@ static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME);
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry);
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type);
+static int metaUpdateMetaRsp(tb_uid_t uid, char* tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
+ pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
+ if (NULL == pMetaRsp->pSchemas) {
+ terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
+ return -1;
+ }
+
+ strcpy(pMetaRsp->tbName, tbName);
+ pMetaRsp->numOfColumns = pSchema->nCols;
+ pMetaRsp->tableType = TSDB_NORMAL_TABLE;
+ pMetaRsp->sversion = pSchema->version;
+ pMetaRsp->tuid = uid;
+
+ memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
+
+ return 0;
+}
+
int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
SMetaEntry me = {0};
int kLen = 0;
int vLen = 0;
const void *pKey = NULL;
const void *pVal = NULL;
- void * pBuf = NULL;
+ void *pBuf = NULL;
int32_t szBuf = 0;
- void * p = NULL;
+ void *p = NULL;
SMetaReader mr = {0};
// validate req
@@ -87,7 +105,7 @@ int metaDropSTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) {
}
// drop all child tables
- TBC * pCtbIdxc = NULL;
+ TBC *pCtbIdxc = NULL;
SArray *pArray = taosArrayInit(8, sizeof(tb_uid_t));
tdbTbcOpen(pMeta->pCtbIdx, &pCtbIdxc, &pMeta->txn);
@@ -142,8 +160,8 @@ _exit:
int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
SMetaEntry oStbEntry = {0};
SMetaEntry nStbEntry = {0};
- TBC * pUidIdxc = NULL;
- TBC * pTbDbc = NULL;
+ TBC *pUidIdxc = NULL;
+ TBC *pTbDbc = NULL;
const void *pData;
int nData;
int64_t oversion;
@@ -262,7 +280,7 @@ _err:
}
int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUids) {
- void * pData = NULL;
+ void *pData = NULL;
int nData = 0;
int rc = 0;
tb_uid_t uid;
@@ -288,7 +306,7 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUi
}
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
- void * pData = NULL;
+ void *pData = NULL;
int nData = 0;
int rc = 0;
int64_t version;
@@ -323,15 +341,15 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
return 0;
}
-static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
+static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq, STableMetaRsp *pMetaRsp) {
void * pVal = NULL;
int nVal = 0;
- const void * pData = NULL;
+ const void *pData = NULL;
int nData = 0;
int ret = 0;
tb_uid_t uid;
int64_t oversion;
- SSchema * pColumn = NULL;
+ SSchema *pColumn = NULL;
SMetaEntry entry = {0};
SSchemaWrapper *pSchema;
int c;
@@ -463,6 +481,8 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
metaULock(pMeta);
+ metaUpdateMetaRsp(uid, pAlterTbReq->tbName, pSchema, pMetaRsp);
+
if (pNewSchema) taosMemoryFree(pNewSchema);
tDecoderClear(&dc);
tdbTbcClose(pTbDbc);
@@ -479,7 +499,7 @@ _err:
static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTbReq) {
SMetaEntry ctbEntry = {0};
SMetaEntry stbEntry = {0};
- void * pVal = NULL;
+ void *pVal = NULL;
int nVal = 0;
int ret;
int c;
@@ -510,7 +530,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
oversion = *(int64_t *)pData;
// search table.db
- TBC * pTbDbc = NULL;
+ TBC *pTbDbc = NULL;
SDecoder dc1 = {0};
SDecoder dc2 = {0};
@@ -534,7 +554,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
metaDecodeEntry(&dc2, &stbEntry);
SSchemaWrapper *pTagSchema = &stbEntry.stbEntry.schemaTag;
- SSchema * pColumn = NULL;
+ SSchema *pColumn = NULL;
int32_t iCol = 0;
for (;;) {
pColumn = NULL;
@@ -563,29 +583,39 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
}
memcpy((void *)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
} else {
- SKVRowBuilder kvrb = {0};
- const SKVRow pOldTag = (const SKVRow)ctbEntry.ctbEntry.pTags;
- SKVRow pNewTag = NULL;
-
- tdInitKVRowBuilder(&kvrb);
+ const STag *pOldTag = (const STag *)ctbEntry.ctbEntry.pTags;
+ STag *pNewTag = NULL;
+ SArray *pTagArray = taosArrayInit(pTagSchema->nCols, sizeof(STagVal));
+ if (!pTagArray) {
+ terrno = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
for (int32_t i = 0; i < pTagSchema->nCols; i++) {
SSchema *pCol = &pTagSchema->pSchema[i];
if (iCol == i) {
- tdAddColToKVRow(&kvrb, pCol->colId, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
+ STagVal val = {0};
+ val.type = pCol->type;
+ val.cid = pCol->colId;
+ if (IS_VAR_DATA_TYPE(pCol->type)) {
+ val.pData = pAlterTbReq->pTagVal;
+ val.nData = pAlterTbReq->nTagVal;
+ } else {
+ memcpy(&val.i64, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal);
+ }
+ taosArrayPush(pTagArray, &val);
} else {
- void *p = tdGetKVRowValOfCol(pOldTag, pCol->colId);
- if (p) {
- if (IS_VAR_DATA_TYPE(pCol->type)) {
- tdAddColToKVRow(&kvrb, pCol->colId, p, varDataTLen(p));
- } else {
- tdAddColToKVRow(&kvrb, pCol->colId, p, pCol->bytes);
- }
+ STagVal val = {.cid = pCol->colId};
+ if (tTagGet(pOldTag, &val)) {
+ taosArrayPush(pTagArray, &val);
}
}
}
-
- ctbEntry.ctbEntry.pTags = tdGetKVRowFromBuilder(&kvrb);
- tdDestroyKVRowBuilder(&kvrb);
+ if ((terrno = tTagNew(pTagArray, pTagSchema->version, false, &pNewTag)) < 0) {
+ taosArrayDestroy(pTagArray);
+ goto _err;
+ }
+ ctbEntry.ctbEntry.pTags = (uint8_t *)pNewTag;
+ taosArrayDestroy(pTagArray);
}
// save to table.db
@@ -619,13 +649,13 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
return 0;
}
-int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
+int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pMetaRsp) {
switch (pReq->action) {
case TSDB_ALTER_TABLE_ADD_COLUMN:
case TSDB_ALTER_TABLE_DROP_COLUMN:
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
- return metaAlterTableColumn(pMeta, version, pReq);
+ return metaAlterTableColumn(pMeta, version, pReq, pMetaRsp);
case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:
return metaUpdateTableTagVal(pMeta, version, pReq);
case TSDB_ALTER_TABLE_UPDATE_OPTIONS:
@@ -639,8 +669,8 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq) {
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME) {
STbDbKey tbDbKey;
- void * pKey = NULL;
- void * pVal = NULL;
+ void *pKey = NULL;
+ void *pVal = NULL;
int kLen = 0;
int vLen = 0;
SEncoder coder = {0};
@@ -721,17 +751,17 @@ static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) {
return tdbTbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn);
}
-static int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int8_t type, tb_uid_t uid,
- STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
- int32_t nTagData = 0;
+int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int32_t nTagData, int8_t type, tb_uid_t uid,
+ STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) {
+ // int32_t nTagData = 0;
- if (pTagData) {
- if (IS_VAR_DATA_TYPE(type)) {
- nTagData = varDataTLen(pTagData);
- } else {
- nTagData = tDataTypes[type].bytes;
- }
- }
+ // if (pTagData) {
+ // if (IS_VAR_DATA_TYPE(type)) {
+ // nTagData = varDataTLen(pTagData);
+ // } else {
+ // nTagData = tDataTypes[type].bytes;
+ // }
+ // }
*nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t);
*ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey);
@@ -755,14 +785,15 @@ static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) {
}
static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
- void * pData = NULL;
+ void *pData = NULL;
int nData = 0;
STbDbKey tbDbKey = {0};
SMetaEntry stbEntry = {0};
- STagIdxKey * pTagIdxKey = NULL;
+ STagIdxKey *pTagIdxKey = NULL;
int32_t nTagIdxKey;
const SSchema *pTagColumn; // = &stbEntry.stbEntry.schema.pSchema[0];
- const void * pTagData = NULL; //
+ const void *pTagData = NULL; //
+ int32_t nTagData = 0;
SDecoder dc = {0};
// get super table
@@ -775,7 +806,21 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
metaDecodeEntry(&dc, &stbEntry);
pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0];
- pTagData = tdGetKVRowValOfCol((const SKVRow)pCtbEntry->ctbEntry.pTags, pTagColumn->colId);
+
+ STagVal tagVal = {.cid = pTagColumn->colId};
+ if (pTagColumn->type != TSDB_DATA_TYPE_JSON) {
+ tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal);
+ if (IS_VAR_DATA_TYPE(pTagColumn->type)) {
+ pTagData = tagVal.pData;
+ nTagData = (int32_t)tagVal.nData;
+ } else {
+ pTagData = &(tagVal.i64);
+ nTagData = tDataTypes[pTagColumn->type].bytes;
+ }
+ } else {
+ // pTagData = pCtbEntry->ctbEntry.pTags;
+ // nTagData = ((const STag *)pCtbEntry->ctbEntry.pTags)->len;
+ }
// update tag index
#ifdef USE_INVERTED_INDEX
@@ -790,8 +835,8 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
int ret = indexPut((SIndex *)pMeta->pTagIvtIdx, tmGroup, tuid);
indexMultiTermDestroy(tmGroup);
#else
- if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, pTagColumn->type, pCtbEntry->uid,
- &pTagIdxKey, &nTagIdxKey) < 0) {
+ if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
+ pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
return -1;
}
tdbTbInsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, &pMeta->txn);
@@ -804,7 +849,7 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
SEncoder coder = {0};
- void * pVal = NULL;
+ void *pVal = NULL;
int vLen = 0;
int rcode = 0;
SSkmDbKey skmDbKey = {0};
diff --git a/source/dnode/vnode/src/sma/sma.c b/source/dnode/vnode/src/sma/sma.c
index 0e7ce385a1c2aa225d21201af2fcc7f0ffd72d79..7a2b6a2757ad4153313586310b01148c4efb49b1 100644
--- a/source/dnode/vnode/src/sma/sma.c
+++ b/source/dnode/vnode/src/sma/sma.c
@@ -15,7 +15,6 @@
#include "sma.h"
-
// TODO: Who is responsible for resource allocate and release?
int32_t tdProcessTSmaInsert(SSma* pSma, int64_t indexUid, const char* msg) {
int32_t code = TSDB_CODE_SUCCESS;
@@ -37,7 +36,7 @@ int32_t tdProcessTSmaCreate(SSma* pSma, int64_t version, const char* msg) {
return code;
}
-int32_t tdUpdateExpireWindow(SSma* pSma, SSubmitReq* pMsg, int64_t version) {
+int32_t tdUpdateExpireWindow(SSma* pSma, const SSubmitReq* pMsg, int64_t version) {
int32_t code = TSDB_CODE_SUCCESS;
if ((code = tdUpdateExpiredWindowImpl(pSma, pMsg, version)) < 0) {
smaWarn("vgId:%d update expired sma window failed since %s", SMA_VID(pSma), tstrerror(terrno));
diff --git a/source/dnode/vnode/src/sma/smaOpen.c b/source/dnode/vnode/src/sma/smaOpen.c
index 2a74fe78cbc66a3873857347df010190554e1e76..dde6578054ac43965b9c2300dd2d118baea1d25e 100644
--- a/source/dnode/vnode/src/sma/smaOpen.c
+++ b/source/dnode/vnode/src/sma/smaOpen.c
@@ -104,7 +104,7 @@ int32_t smaOpen(SVnode *pVnode) {
taosThreadMutexInit(&pSma->mutex, NULL);
pSma->locked = false;
- if (vnodeIsRollup(pVnode)) {
+ if (VND_IS_RSMA(pVnode)) {
STsdbKeepCfg keepCfg = {0};
for (int i = 0; i < TSDB_RETENTION_MAX; ++i) {
if (i == TSDB_RETENTION_L0) {
diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c
index 0769da12bcb478ace23e01be4be0fd9b75da5249..42c215ee7c276ac6ed7d299390bef7e2083741ce 100644
--- a/source/dnode/vnode/src/sma/smaRollup.c
+++ b/source/dnode/vnode/src/sma/smaRollup.c
@@ -165,7 +165,10 @@ int32_t tdFetchTbUidList(SSma *pSma, STbUidStore **ppStore, tb_uid_t suid, tb_ui
* @param pReq
* @return int32_t
*/
-int32_t tdProcessRSmaCreate(SSma *pSma, SMeta *pMeta, SVCreateStbReq *pReq, SMsgCb *pMsgCb) {
+int32_t tdProcessRSmaCreate(SVnode *pVnode, SVCreateStbReq *pReq) {
+ SSma *pSma = pVnode->pSma;
+ SMeta *pMeta = pVnode->pMeta;
+ SMsgCb *pMsgCb = &pVnode->msgCb;
if (!pReq->rollup) {
smaTrace("vgId:%d return directly since no rollup for stable %s %" PRIi64, SMA_VID(pSma), pReq->name, pReq->suid);
return TSDB_CODE_SUCCESS;
@@ -210,6 +213,7 @@ int32_t tdProcessRSmaCreate(SSma *pSma, SMeta *pMeta, SVCreateStbReq *pReq, SMsg
.reader = pReadHandle,
.meta = pMeta,
.pMsgCb = pMsgCb,
+ .vnode = pVnode,
};
if (param->qmsg1) {
@@ -410,7 +414,7 @@ static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int3
}
taosMemoryFreeClear(pReq);
} else {
- smaWarn("vgId:%d no rsma % " PRIi8 " data generated since %s", SMA_VID(pSma), level, tstrerror(terrno));
+ smaDebug("vgId:%d no rsma % " PRIi8 " data generated since %s", SMA_VID(pSma), level, tstrerror(terrno));
}
taosArrayDestroy(pResult);
diff --git a/source/dnode/vnode/src/sma/smaTimeRange.c b/source/dnode/vnode/src/sma/smaTimeRange.c
index f771e73c8aa4210fd01b5c871877cbdaeb0fb2bc..f88afcaddf82eed173f00693ea9d905ea195bd91 100644
--- a/source/dnode/vnode/src/sma/smaTimeRange.c
+++ b/source/dnode/vnode/src/sma/smaTimeRange.c
@@ -932,7 +932,7 @@ static int32_t tdSetExpiredWindow(SSma *pSma, SHashObj *pItemsHash, int64_t inde
* @param msg SSubmitReq
* @return int32_t
*/
-int32_t tdUpdateExpiredWindowImpl(SSma *pSma, SSubmitReq *pMsg, int64_t version) {
+int32_t tdUpdateExpiredWindowImpl(SSma *pSma, const SSubmitReq *pMsg, int64_t version) {
// no time-range-sma, just return success
if (atomic_load_16(&SMA_TSMA_NUM(pSma)) <= 0) {
smaTrace("vgId:%d not update expire window since no tSma", SMA_VID(pSma));
diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c
index 96ce6e8eeeeaf17243d8e29baa733c369437c931..310b59b2e82c20bfbbb6dc5256f3393c67ae3ca3 100644
--- a/source/dnode/vnode/src/tq/tq.c
+++ b/source/dnode/vnode/src/tq/tq.c
@@ -14,7 +14,6 @@
*/
#include "tq.h"
-#include "tdbInt.h"
int32_t tqInit() {
int8_t old;
@@ -47,51 +46,6 @@ void tqCleanUp() {
}
}
-int tqExecKeyCompare(const void* pKey1, int32_t kLen1, const void* pKey2, int32_t kLen2) {
- return strcmp(pKey1, pKey2);
-}
-
-int32_t tqStoreExec(STQ* pTq, const char* key, const STqExec* pExec) {
- int32_t code;
- int32_t vlen;
- tEncodeSize(tEncodeSTqExec, pExec, vlen, code);
- ASSERT(code == 0);
-
- void* buf = taosMemoryCalloc(1, vlen);
- if (buf == NULL) {
- ASSERT(0);
- }
-
- SEncoder encoder;
- tEncoderInit(&encoder, buf, vlen);
-
- if (tEncodeSTqExec(&encoder, pExec) < 0) {
- ASSERT(0);
- }
-
- TXN txn;
-
- if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED) < 0) {
- ASSERT(0);
- }
-
- if (tdbBegin(pTq->pMetaStore, &txn) < 0) {
- ASSERT(0);
- }
-
- if (tdbTbUpsert(pTq->pExecStore, key, (int)strlen(key), buf, vlen, &txn) < 0) {
- ASSERT(0);
- }
-
- if (tdbCommit(pTq->pMetaStore, &txn) < 0) {
- ASSERT(0);
- }
-
- tEncoderClear(&encoder);
- taosMemoryFree(buf);
- return 0;
-}
-
STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal) {
STQ* pTq = taosMemoryMalloc(sizeof(STQ));
if (pTq == NULL) {
@@ -102,69 +56,13 @@ STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal) {
pTq->pVnode = pVnode;
pTq->pWal = pWal;
- pTq->execs = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
+ pTq->handles = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
pTq->pStreamTasks = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
pTq->pushMgr = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK);
- if (tdbOpen(path, 16 * 1024, 1, &pTq->pMetaStore) < 0) {
- ASSERT(0);
- }
-
- if (tdbTbOpen("exec", -1, -1, tqExecKeyCompare, pTq->pMetaStore, &pTq->pExecStore) < 0) {
- ASSERT(0);
- }
-
- TXN txn;
-
- if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, 0) < 0) {
- ASSERT(0);
- }
-
- /*if (tdbBegin(pTq->pMetaStore, &txn) < 0) {*/
- /*ASSERT(0);*/
- /*}*/
-
- TBC* pCur;
- if (tdbTbcOpen(pTq->pExecStore, &pCur, &txn) < 0) {
- ASSERT(0);
- }
-
- void* pKey;
- int kLen;
- void* pVal;
- int vLen;
-
- tdbTbcMoveToFirst(pCur);
- SDecoder decoder;
- while (tdbTbcNext(pCur, &pKey, &kLen, &pVal, &vLen) == 0) {
- STqExec exec;
- tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
- tDecodeSTqExec(&decoder, &exec);
- exec.pWalReader = walOpenReadHandle(pTq->pVnode->pWal);
- if (exec.subType == TOPIC_SUB_TYPE__TABLE) {
- for (int32_t i = 0; i < 5; i++) {
- exec.pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
-
- SReadHandle handle = {
- .reader = exec.pExecReader[i],
- .meta = pTq->pVnode->pMeta,
- .pMsgCb = &pTq->pVnode->msgCb,
- };
- exec.task[i] = qCreateStreamExecTaskInfo(exec.qmsg, &handle);
- ASSERT(exec.task[i]);
- }
- } else {
- for (int32_t i = 0; i < 5; i++) {
- exec.pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
- }
- exec.pDropTbUid = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
- }
- taosHashPut(pTq->execs, pKey, kLen, &exec, sizeof(STqExec));
- }
-
- if (tdbTxnClose(&txn) < 0) {
+ if (tqMetaOpen(pTq) < 0) {
ASSERT(0);
}
@@ -174,238 +72,50 @@ STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal) {
void tqClose(STQ* pTq) {
if (pTq) {
taosMemoryFreeClear(pTq->path);
- taosHashCleanup(pTq->execs);
+ taosHashCleanup(pTq->handles);
taosHashCleanup(pTq->pStreamTasks);
taosHashCleanup(pTq->pushMgr);
- tdbClose(pTq->pMetaStore);
+ tqMetaClose(pTq);
taosMemoryFree(pTq);
}
// TODO
}
-int32_t tEncodeSTqExec(SEncoder* pEncoder, const STqExec* pExec) {
- if (tStartEncode(pEncoder) < 0) return -1;
- if (tEncodeCStr(pEncoder, pExec->subKey) < 0) return -1;
- if (tEncodeI64(pEncoder, pExec->consumerId) < 0) return -1;
- if (tEncodeI32(pEncoder, pExec->epoch) < 0) return -1;
- if (tEncodeI8(pEncoder, pExec->subType) < 0) return -1;
- if (tEncodeI8(pEncoder, pExec->withTbName) < 0) return -1;
- if (tEncodeI8(pEncoder, pExec->withSchema) < 0) return -1;
- if (tEncodeI8(pEncoder, pExec->withTag) < 0) return -1;
- if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
- if (tEncodeCStr(pEncoder, pExec->qmsg) < 0) return -1;
- }
- tEndEncode(pEncoder);
- return pEncoder->pos;
-}
-
-int32_t tDecodeSTqExec(SDecoder* pDecoder, STqExec* pExec) {
- if (tStartDecode(pDecoder) < 0) return -1;
- if (tDecodeCStrTo(pDecoder, pExec->subKey) < 0) return -1;
- if (tDecodeI64(pDecoder, &pExec->consumerId) < 0) return -1;
- if (tDecodeI32(pDecoder, &pExec->epoch) < 0) return -1;
- if (tDecodeI8(pDecoder, &pExec->subType) < 0) return -1;
- if (tDecodeI8(pDecoder, &pExec->withTbName) < 0) return -1;
- if (tDecodeI8(pDecoder, &pExec->withSchema) < 0) return -1;
- if (tDecodeI8(pDecoder, &pExec->withTag) < 0) return -1;
- if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
- if (tDecodeCStrAlloc(pDecoder, &pExec->qmsg) < 0) return -1;
- }
- tEndDecode(pDecoder);
- return 0;
-}
-int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
- void* pIter = NULL;
- while (1) {
- pIter = taosHashIterate(pTq->execs, pIter);
- if (pIter == NULL) break;
- STqExec* pExec = (STqExec*)pIter;
- if (pExec->subType == TOPIC_SUB_TYPE__DB) {
- if (!isAdd) {
- int32_t sz = taosArrayGetSize(tbUidList);
- for (int32_t i = 0; i < sz; i++) {
- int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
- taosHashPut(pExec->pDropTbUid, &tbUid, sizeof(int64_t), NULL, 0);
- }
- }
- } else {
- for (int32_t i = 0; i < 5; i++) {
- int32_t code = qUpdateQualifiedTableId(pExec->task[i], tbUidList, isAdd);
- ASSERT(code == 0);
- }
- }
- }
- while (1) {
- pIter = taosHashIterate(pTq->pStreamTasks, pIter);
- if (pIter == NULL) break;
- SStreamTask* pTask = (SStreamTask*)pIter;
- if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) {
- int32_t code = qUpdateQualifiedTableId(pTask->exec.executor, tbUidList, isAdd);
- ASSERT(code == 0);
- }
- }
- return 0;
-}
-
-int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver, SRpcHandleInfo handleInfo) {
- if (msgType != TDMT_VND_SUBMIT) return 0;
- void* pIter = NULL;
- STqExec* pExec = NULL;
- SSubmitReq* pReq = (SSubmitReq*)msg;
- int32_t workerId = 4;
- int64_t fetchOffset = ver;
-
- while (1) {
- pIter = taosHashIterate(pTq->pushMgr, pIter);
- if (pIter == NULL) break;
- pExec = *(STqExec**)pIter;
-
- taosWLockLatch(&pExec->pushHandle.lock);
-
- SRpcMsg* pMsg = atomic_load_ptr(&pExec->pushHandle.handle);
- ASSERT(pMsg);
-
- SMqDataBlkRsp rsp = {0};
- rsp.reqOffset = pExec->pushHandle.reqOffset;
- rsp.blockData = taosArrayInit(0, sizeof(void*));
- rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
-
- if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
- qTaskInfo_t task = pExec->task[workerId];
- ASSERT(task);
- qSetStreamInput(task, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK, false);
- while (1) {
- SSDataBlock* pDataBlock = NULL;
- uint64_t ts = 0;
- if (qExecTask(task, &pDataBlock, &ts) < 0) {
- ASSERT(0);
- }
- if (pDataBlock == NULL) break;
-
- ASSERT(pDataBlock->info.rows != 0);
- ASSERT(pDataBlock->info.numOfCols != 0);
-
- int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pDataBlock);
- void* buf = taosMemoryCalloc(1, dataStrLen);
- SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf;
- pRetrieve->useconds = ts;
- pRetrieve->precision = TSDB_DEFAULT_PRECISION;
- pRetrieve->compressed = 0;
- pRetrieve->completed = 1;
- pRetrieve->numOfRows = htonl(pDataBlock->info.rows);
-
- // TODO enable compress
- int32_t actualLen = 0;
- blockCompressEncode(pDataBlock, pRetrieve->data, &actualLen, pDataBlock->info.numOfCols, false);
- actualLen += sizeof(SRetrieveTableRsp);
- ASSERT(actualLen <= dataStrLen);
- taosArrayPush(rsp.blockDataLen, &actualLen);
- taosArrayPush(rsp.blockData, &buf);
- rsp.blockNum++;
- }
- } else if (pExec->subType == TOPIC_SUB_TYPE__DB) {
- STqReadHandle* pReader = pExec->pExecReader[workerId];
- tqReadHandleSetMsg(pReader, pReq, 0);
- while (tqNextDataBlock(pReader)) {
- SSDataBlock block = {0};
- if (tqRetrieveDataBlock(&block.pDataBlock, pReader, &block.info.groupId, &block.info.uid, &block.info.rows,
- &block.info.numOfCols) < 0) {
- ASSERT(0);
- }
- int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(&block);
- void* buf = taosMemoryCalloc(1, dataStrLen);
- SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf;
- /*pRetrieve->useconds = 0;*/
- pRetrieve->precision = TSDB_DEFAULT_PRECISION;
- pRetrieve->compressed = 0;
- pRetrieve->completed = 1;
- pRetrieve->numOfRows = htonl(block.info.rows);
-
- // TODO enable compress
- int32_t actualLen = 0;
- blockCompressEncode(&block, pRetrieve->data, &actualLen, block.info.numOfCols, false);
- actualLen += sizeof(SRetrieveTableRsp);
- ASSERT(actualLen <= dataStrLen);
- taosArrayPush(rsp.blockDataLen, &actualLen);
- taosArrayPush(rsp.blockData, &buf);
- rsp.blockNum++;
- }
- } else {
- ASSERT(0);
- }
-
- if (rsp.blockNum == 0) {
- taosWUnLockLatch(&pExec->pushHandle.lock);
- continue;
- }
-
- ASSERT(taosArrayGetSize(rsp.blockData) == rsp.blockNum);
- ASSERT(taosArrayGetSize(rsp.blockDataLen) == rsp.blockNum);
-
- rsp.rspOffset = fetchOffset;
-
- int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, &rsp);
- void* buf = rpcMallocCont(tlen);
- if (buf == NULL) {
- pMsg->code = -1;
- return -1;
- }
-
- ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
- ((SMqRspHead*)buf)->epoch = pExec->pushHandle.epoch;
- ((SMqRspHead*)buf)->consumerId = pExec->pushHandle.consumerId;
-
- void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
- tEncodeSMqDataBlkRsp(&abuf, &rsp);
-
- SRpcMsg resp = {.info = handleInfo, .pCont = buf, .contLen = tlen, .code = 0};
- tmsgSendRsp(&resp);
-
- atomic_store_ptr(&pExec->pushHandle.handle, NULL);
- taosWUnLockLatch(&pExec->pushHandle.lock);
-
- tqDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
- TD_VID(pTq->pVnode), fetchOffset, pExec->pushHandle.consumerId, pExec->pushHandle.epoch, rsp.blockNum,
- rsp.reqOffset, rsp.rspOffset);
-
- // TODO destroy
- taosArrayDestroy(rsp.blockData);
- taosArrayDestroy(rsp.blockDataLen);
+int32_t tqSendPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataBlkRsp* pRsp) {
+ int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, pRsp);
+ void* buf = rpcMallocCont(tlen);
+ if (buf == NULL) {
+ return -1;
}
- return 0;
-}
-
-int tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
- if (msgType == TDMT_VND_SUBMIT) {
- if (taosHashGetSize(pTq->pStreamTasks) == 0) return 0;
+ ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
+ ((SMqRspHead*)buf)->epoch = pReq->epoch;
+ ((SMqRspHead*)buf)->consumerId = pReq->consumerId;
- if (tdUpdateExpireWindow(pTq->pVnode->pSma, msg, ver) != 0) {
- // TODO handle sma error
- }
- void* data = taosMemoryMalloc(msgLen);
- if (data == NULL) {
- return -1;
- }
- memcpy(data, msg, msgLen);
+ void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
+ tEncodeSMqDataBlkRsp(&abuf, pRsp);
- tqProcessStreamTrigger(pTq, data);
- }
+ SRpcMsg resp = {
+ .info = pMsg->info,
+ .pCont = buf,
+ .contLen = tlen,
+ .code = 0,
+ };
+ tmsgSendRsp(&resp);
- return 0;
-}
+ tqDebug("vg %d from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
+ TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->blockNum, pRsp->reqOffset, pRsp->rspOffset);
-int tqCommit(STQ* pTq) {
- // do nothing
return 0;
}
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
SMqPollReq* pReq = pMsg->pCont;
int64_t consumerId = pReq->consumerId;
- int64_t waitTime = pReq->waitTime;
+ int64_t timeout = pReq->timeout;
int32_t reqEpoch = pReq->epoch;
int64_t fetchOffset;
+ int32_t code = 0;
// get offset to fetch message
if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__EARLIEAST) {
@@ -419,12 +129,12 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
tqDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
TD_VID(pTq->pVnode), pReq->currentOffset, fetchOffset);
- STqExec* pExec = taosHashGet(pTq->execs, pReq->subKey, strlen(pReq->subKey));
- ASSERT(pExec);
+ STqHandle* pHandle = taosHashGet(pTq->handles, pReq->subKey, strlen(pReq->subKey));
+ ASSERT(pHandle);
- int32_t consumerEpoch = atomic_load_32(&pExec->epoch);
+ int32_t consumerEpoch = atomic_load_32(&pHandle->epoch);
while (consumerEpoch < reqEpoch) {
- consumerEpoch = atomic_val_compare_exchange_32(&pExec->epoch, consumerEpoch, reqEpoch);
+ consumerEpoch = atomic_val_compare_exchange_32(&pHandle->epoch, consumerEpoch, reqEpoch);
}
SWalHead* pHeadWithCkSum = taosMemoryMalloc(sizeof(SWalHead) + 2048);
@@ -432,259 +142,103 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
return -1;
}
- walSetReaderCapacity(pExec->pWalReader, 2048);
+ walSetReaderCapacity(pHandle->pWalReader, 2048);
SMqDataBlkRsp rsp = {0};
rsp.reqOffset = pReq->currentOffset;
- rsp.withSchema = pExec->withSchema;
rsp.blockData = taosArrayInit(0, sizeof(void*));
rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
- rsp.blockSchema = taosArrayInit(0, sizeof(void*));
- rsp.blockTbName = taosArrayInit(0, sizeof(void*));
- int8_t withTbName = pExec->withTbName;
- if (pReq->withTbName != -1) {
- withTbName = pReq->withTbName;
+ rsp.withTbName = pReq->withTbName;
+ if (rsp.withTbName) {
+ rsp.blockTbName = taosArrayInit(0, sizeof(void*));
+ }
+ if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ rsp.withSchema = false;
+ rsp.withTag = false;
+ } else {
+ rsp.withSchema = true;
+ rsp.withTag = false;
+ rsp.blockSchema = taosArrayInit(0, sizeof(void*));
}
- rsp.withTbName = withTbName;
while (1) {
- consumerEpoch = atomic_load_32(&pExec->epoch);
+ consumerEpoch = atomic_load_32(&pHandle->epoch);
if (consumerEpoch > reqEpoch) {
- tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
- consumerId, pReq->epoch, TD_VID(pTq->pVnode), fetchOffset, consumerEpoch, reqEpoch);
+ tqWarn("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d, discard req epoch %d",
+ consumerId, pReq->epoch, TD_VID(pTq->pVnode), fetchOffset, consumerEpoch, reqEpoch);
break;
}
- taosThreadMutexLock(&pExec->pWalReader->mutex);
-
- if (walFetchHead(pExec->pWalReader, fetchOffset, pHeadWithCkSum) < 0) {
- tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
- TD_VID(pTq->pVnode), fetchOffset);
- taosThreadMutexUnlock(&pExec->pWalReader->mutex);
+ if (tqFetchLog(pTq, pHandle, &fetchOffset, &pHeadWithCkSum) < 0) {
+ // TODO add push mgr
break;
}
- if (pHeadWithCkSum->head.msgType != TDMT_VND_SUBMIT) {
- ASSERT(walSkipFetchBody(pExec->pWalReader, pHeadWithCkSum) == 0);
- } else {
- ASSERT(walFetchBody(pExec->pWalReader, &pHeadWithCkSum) == 0);
- }
-
SWalReadHead* pHead = &pHeadWithCkSum->head;
- taosThreadMutexUnlock(&pExec->pWalReader->mutex);
-
-#if 0
- SWalReadHead* pHead;
- if (walReadWithHandle_s(pExec->pWalReader, fetchOffset, &pHead) < 0) {
- // TODO: no more log, set timer to wait blocking time
- // if data inserted during waiting, launch query and
- // response to user
- tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
- TD_VID(pTq->pVnode), fetchOffset);
-
-#if 0
- // add to pushMgr
- taosWLockLatch(&pExec->pushHandle.lock);
-
- pExec->pushHandle.consumerId = consumerId;
- pExec->pushHandle.epoch = reqEpoch;
- pExec->pushHandle.reqOffset = rsp.reqOffset;
- pExec->pushHandle.skipLogNum = rsp.skipLogNum;
- pExec->pushHandle.handle = pMsg;
-
- taosWUnLockLatch(&pExec->pushHandle.lock);
-
- // TODO add timer
-
- // TODO: the pointer will always be valid?
- taosHashPut(pTq->pushMgr, &consumerId, sizeof(int64_t), &pExec, sizeof(void*));
- taosArrayDestroy(rsp.blockData);
- taosArrayDestroy(rsp.blockDataLen);
- return 0;
-#endif
-
- break;
- }
-#endif
-
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
if (pHead->msgType == TDMT_VND_SUBMIT) {
SSubmitReq* pCont = (SSubmitReq*)&pHead->body;
- // table subscribe
- if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
- qTaskInfo_t task = pExec->task[workerId];
- ASSERT(task);
- qSetStreamInput(task, pCont, STREAM_DATA_TYPE_SUBMIT_BLOCK, false);
- while (1) {
- SSDataBlock* pDataBlock = NULL;
- uint64_t ts = 0;
- if (qExecTask(task, &pDataBlock, &ts) < 0) {
- ASSERT(0);
- }
- if (pDataBlock == NULL) break;
-
- ASSERT(pDataBlock->info.rows != 0);
- ASSERT(pDataBlock->info.numOfCols != 0);
-
- int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pDataBlock);
- void* buf = taosMemoryCalloc(1, dataStrLen);
- SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf;
- pRetrieve->useconds = ts;
- pRetrieve->precision = TSDB_DEFAULT_PRECISION;
- pRetrieve->compressed = 0;
- pRetrieve->completed = 1;
- pRetrieve->numOfRows = htonl(pDataBlock->info.rows);
-
- // TODO enable compress
- int32_t actualLen = 0;
- blockCompressEncode(pDataBlock, pRetrieve->data, &actualLen, pDataBlock->info.numOfCols, false);
- actualLen += sizeof(SRetrieveTableRsp);
- ASSERT(actualLen <= dataStrLen);
- taosArrayPush(rsp.blockDataLen, &actualLen);
- taosArrayPush(rsp.blockData, &buf);
-
- if (pExec->withSchema) {
- SSchemaWrapper* pSW = tCloneSSchemaWrapper(pExec->pExecReader[workerId]->pSchemaWrapper);
- taosArrayPush(rsp.blockSchema, &pSW);
- }
-
- if (withTbName) {
- SMetaReader mr = {0};
- metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
- int64_t uid = pExec->pExecReader[workerId]->msgIter.uid;
- if (metaGetTableEntryByUid(&mr, uid) < 0) {
- ASSERT(0);
- }
- char* tbName = strdup(mr.me.name);
- taosArrayPush(rsp.blockTbName, &tbName);
- metaReaderClear(&mr);
- }
-
- rsp.blockNum++;
- }
- // db subscribe
- } else if (pExec->subType == TOPIC_SUB_TYPE__DB) {
- rsp.withSchema = 1;
- STqReadHandle* pReader = pExec->pExecReader[workerId];
- tqReadHandleSetMsg(pReader, pCont, 0);
- while (tqNextDataBlockFilterOut(pReader, pExec->pDropTbUid)) {
- SSDataBlock block = {0};
- if (tqRetrieveDataBlock(&block.pDataBlock, pReader, &block.info.groupId, &block.info.uid, &block.info.rows,
- &block.info.numOfCols) < 0) {
- if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue;
- ASSERT(0);
- }
- int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(&block);
- void* buf = taosMemoryCalloc(1, dataStrLen);
- SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf;
- /*pRetrieve->useconds = 0;*/
- pRetrieve->precision = TSDB_DEFAULT_PRECISION;
- pRetrieve->compressed = 0;
- pRetrieve->completed = 1;
- pRetrieve->numOfRows = htonl(block.info.rows);
-
- // TODO enable compress
- int32_t actualLen = 0;
- blockCompressEncode(&block, pRetrieve->data, &actualLen, block.info.numOfCols, false);
- actualLen += sizeof(SRetrieveTableRsp);
- ASSERT(actualLen <= dataStrLen);
- taosArrayPush(rsp.blockDataLen, &actualLen);
- taosArrayPush(rsp.blockData, &buf);
- if (withTbName) {
- SMetaReader mr = {0};
- metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
- if (metaGetTableEntryByUid(&mr, block.info.uid) < 0) {
- ASSERT(0);
- }
- char* tbName = strdup(mr.me.name);
- taosArrayPush(rsp.blockTbName, &tbName);
- metaReaderClear(&mr);
- }
-
- SSchemaWrapper* pSW = tCloneSSchemaWrapper(pExec->pExecReader[workerId]->pSchemaWrapper);
- taosArrayPush(rsp.blockSchema, &pSW);
-
- rsp.blockNum++;
- }
- } else {
- ASSERT(0);
+
+ if (tqDataExec(pTq, &pHandle->execHandle, pCont, &rsp, workerId) < 0) {
+ /*ASSERT(0);*/
}
+ } else {
+ // TODO
+ ASSERT(0);
}
// TODO batch optimization:
// TODO continue scan until meeting batch requirement
- if (rsp.blockNum != 0) break;
- rsp.skipLogNum++;
- fetchOffset++;
+ if (rsp.blockNum > 0 /* threshold */) {
+ break;
+ } else {
+ fetchOffset++;
+ }
}
taosMemoryFree(pHeadWithCkSum);
+
ASSERT(taosArrayGetSize(rsp.blockData) == rsp.blockNum);
ASSERT(taosArrayGetSize(rsp.blockDataLen) == rsp.blockNum);
-
- if (rsp.blockNum != 0)
- rsp.rspOffset = fetchOffset;
- else
- rsp.rspOffset = fetchOffset - 1;
-
- int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, &rsp);
- void* buf = rpcMallocCont(tlen);
- if (buf == NULL) {
- pMsg->code = -1;
- return -1;
+ if (rsp.withSchema) {
+ ASSERT(taosArrayGetSize(rsp.blockSchema) == rsp.blockNum);
}
- ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
- ((SMqRspHead*)buf)->epoch = pReq->epoch;
- ((SMqRspHead*)buf)->consumerId = consumerId;
-
- void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
- tEncodeSMqDataBlkRsp(&abuf, &rsp);
-
- SRpcMsg resp = {.info = pMsg->info, .pCont = buf, .contLen = tlen, .code = 0};
- tmsgSendRsp(&resp);
+ rsp.rspOffset = fetchOffset;
- tqDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
- TD_VID(pTq->pVnode), fetchOffset, consumerId, pReq->epoch, rsp.blockNum, rsp.reqOffset, rsp.rspOffset);
+ if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) {
+ code = -1;
+ }
- // TODO destroy
+ // TODO wrap in destroy func
taosArrayDestroy(rsp.blockData);
taosArrayDestroy(rsp.blockDataLen);
- taosArrayDestroyP(rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
- taosArrayDestroyP(rsp.blockTbName, (FDelete)taosMemoryFree);
- return 0;
+ if (rsp.withSchema) {
+ taosArrayDestroyP(rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
+ }
+
+ if (rsp.withTbName) {
+ taosArrayDestroyP(rsp.blockTbName, (FDelete)taosMemoryFree);
+ }
+
+ return code;
}
int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen) {
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
- int32_t code = taosHashRemove(pTq->execs, pReq->subKey, strlen(pReq->subKey));
+ int32_t code = taosHashRemove(pTq->handles, pReq->subKey, strlen(pReq->subKey));
ASSERT(code == 0);
- TXN txn;
-
- if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED) < 0) {
- ASSERT(0);
- }
-
- if (tdbBegin(pTq->pMetaStore, &txn) < 0) {
- ASSERT(0);
- }
-
- if (tdbTbDelete(pTq->pExecStore, pReq->subKey, (int)strlen(pReq->subKey), &txn) < 0) {
- /*ASSERT(0);*/
- }
-
- if (tdbCommit(pTq->pMetaStore, &txn) < 0) {
+ if (tqMetaDeleteHandle(pTq, pReq->subKey) < 0) {
ASSERT(0);
}
-
return 0;
}
@@ -693,81 +247,67 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) {
SMqRebVgReq req = {0};
tDecodeSMqRebVgReq(msg, &req);
// todo lock
- STqExec* pExec = taosHashGet(pTq->execs, req.subKey, strlen(req.subKey));
- if (pExec == NULL) {
+ STqHandle* pHandle = taosHashGet(pTq->handles, req.subKey, strlen(req.subKey));
+ if (pHandle == NULL) {
ASSERT(req.oldConsumerId == -1);
ASSERT(req.newConsumerId != -1);
- STqExec exec = {0};
- pExec = &exec;
+ STqHandle tqHandle = {0};
+ pHandle = &tqHandle;
/*taosInitRWLatch(&pExec->lock);*/
- memcpy(pExec->subKey, req.subKey, TSDB_SUBSCRIBE_KEY_LEN);
- pExec->consumerId = req.newConsumerId;
- pExec->epoch = -1;
-
- pExec->subType = req.subType;
- pExec->withTbName = req.withTbName;
- pExec->withSchema = req.withSchema;
- pExec->withTag = req.withTag;
+ memcpy(pHandle->subKey, req.subKey, TSDB_SUBSCRIBE_KEY_LEN);
+ pHandle->consumerId = req.newConsumerId;
+ pHandle->epoch = -1;
- pExec->qmsg = req.qmsg;
- req.qmsg = NULL;
+ pHandle->execHandle.subType = req.subType;
- pExec->pWalReader = walOpenReadHandle(pTq->pVnode->pWal);
- if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
+ pHandle->pWalReader = walOpenReadHandle(pTq->pVnode->pWal);
+ for (int32_t i = 0; i < 5; i++) {
+ pHandle->execHandle.pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
+ }
+ if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ pHandle->execHandle.exec.execCol.qmsg = req.qmsg;
+ req.qmsg = NULL;
for (int32_t i = 0; i < 5; i++) {
- pExec->pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
-
SReadHandle handle = {
- .reader = pExec->pExecReader[i],
+ .reader = pHandle->execHandle.pExecReader[i],
.meta = pTq->pVnode->pMeta,
.pMsgCb = &pTq->pVnode->msgCb,
};
- pExec->task[i] = qCreateStreamExecTaskInfo(pExec->qmsg, &handle);
- ASSERT(pExec->task[i]);
+ pHandle->execHandle.exec.execCol.task[i] =
+ qCreateStreamExecTaskInfo(pHandle->execHandle.exec.execCol.qmsg, &handle);
+ ASSERT(pHandle->execHandle.exec.execCol.task[i]);
+ }
+ } else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__DB) {
+ pHandle->execHandle.exec.execDb.pFilterOutTbUid =
+ taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
+ } else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
+ pHandle->execHandle.exec.execTb.suid = req.suid;
+ SArray* tbUidList = taosArrayInit(0, sizeof(int64_t));
+ tsdbGetCtbIdList(pTq->pVnode->pMeta, req.suid, tbUidList);
+ tqDebug("vg %d, tq try get suid: %ld", pTq->pVnode->config.vgId, req.suid);
+ for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
+ int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
+ tqDebug("vg %d, idx %d, uid: %ld", pTq->pVnode->config.vgId, i, tbUid);
}
- } else {
for (int32_t i = 0; i < 5; i++) {
- pExec->pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
+ tqReadHandleSetTbUidList(pHandle->execHandle.pExecReader[i], tbUidList);
}
- pExec->pDropTbUid = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
- }
- taosHashPut(pTq->execs, req.subKey, strlen(req.subKey), pExec, sizeof(STqExec));
-
- if (tqStoreExec(pTq, req.subKey, pExec) < 0) {
- // TODO
+ taosArrayDestroy(tbUidList);
}
- return 0;
+ taosHashPut(pTq->handles, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
} else {
/*ASSERT(pExec->consumerId == req.oldConsumerId);*/
// TODO handle qmsg and exec modification
- atomic_store_32(&pExec->epoch, -1);
- atomic_store_64(&pExec->consumerId, req.newConsumerId);
- atomic_add_fetch_32(&pExec->epoch, 1);
-
- if (tqStoreExec(pTq, req.subKey, pExec) < 0) {
- // TODO
- }
- return 0;
+ atomic_store_32(&pHandle->epoch, -1);
+ atomic_store_64(&pHandle->consumerId, req.newConsumerId);
+ atomic_add_fetch_32(&pHandle->epoch, 1);
}
-}
-
-void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
- const SArray* pRes = (const SArray*)data;
- SVnode* pVnode = (SVnode*)vnode;
-
- ASSERT(pTask->tbSink.pTSchema);
- SSubmitReq* pReq = tdBlockToSubmit(pRes, pTask->tbSink.pTSchema, true, pTask->tbSink.stbUid,
- pTask->tbSink.stbFullName, pVnode->config.vgId);
- /*tPrintFixedSchemaSubmitReq(pReq, pTask->tbSink.pTSchema);*/
- // build write msg
- SRpcMsg msg = {
- .msgType = TDMT_VND_SUBMIT,
- .pCont = pReq,
- .contLen = ntohl(pReq->length),
- };
- ASSERT(tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) == 0);
+ if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) {
+ // TODO
+ }
+ return 0;
}
int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
@@ -860,9 +400,11 @@ int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) {
continue;
}
- streamDataSubmitRefInc(pSubmit);
- SStreamDataSubmit* pSubmitClone = taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM);
- memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit));
+ SStreamDataSubmit* pSubmitClone = streamSubmitRefClone(pSubmit);
+ if (pSubmitClone == NULL) {
+ atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED);
+ continue;
+ }
taosWriteQitem(pTask->inputQ, pSubmitClone);
int8_t execStatus = atomic_load_8(&pTask->status);
diff --git a/source/dnode/vnode/src/tq/tqCommit.c b/source/dnode/vnode/src/tq/tqCommit.c
index e31566f3faca14b0955b851f654247355f500630..7b116bff2e942bf1a461458ea443548e708756eb 100644
--- a/source/dnode/vnode/src/tq/tqCommit.c
+++ b/source/dnode/vnode/src/tq/tqCommit.c
@@ -14,3 +14,8 @@
*/
#include "tq.h"
+
+int tqCommit(STQ* pTq) {
+ // do nothing
+ return 0;
+}
diff --git a/source/dnode/vnode/src/tq/tqExec.c b/source/dnode/vnode/src/tq/tqExec.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8fec34b57f49ed732f3a2f3820ec50b367937fb
--- /dev/null
+++ b/source/dnode/vnode/src/tq/tqExec.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#include "tq.h"
+
+static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataBlkRsp* pRsp) {
+ int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock);
+ void* buf = taosMemoryCalloc(1, dataStrLen);
+ if (buf == NULL) return -1;
+
+ SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf;
+ pRetrieve->useconds = 0;
+ pRetrieve->precision = TSDB_DEFAULT_PRECISION;
+ pRetrieve->compressed = 0;
+ pRetrieve->completed = 1;
+ pRetrieve->numOfRows = htonl(pBlock->info.rows);
+
+ // TODO enable compress
+ int32_t actualLen = 0;
+ blockCompressEncode(pBlock, pRetrieve->data, &actualLen, pBlock->info.numOfCols, false);
+ actualLen += sizeof(SRetrieveTableRsp);
+ ASSERT(actualLen <= dataStrLen);
+ taosArrayPush(pRsp->blockDataLen, &actualLen);
+ taosArrayPush(pRsp->blockData, &buf);
+ return 0;
+}
+
+static int32_t tqAddBlockSchemaToRsp(const STqExecHandle* pExec, int32_t workerId, SMqDataBlkRsp* pRsp) {
+ SSchemaWrapper* pSW = tCloneSSchemaWrapper(pExec->pExecReader[workerId]->pSchemaWrapper);
+ taosArrayPush(pRsp->blockSchema, &pSW);
+ return 0;
+}
+
+static int32_t tqAddTbNameToRsp(const STQ* pTq, const STqExecHandle* pExec, SMqDataBlkRsp* pRsp, int32_t workerId) {
+ SMetaReader mr = {0};
+ metaReaderInit(&mr, pTq->pVnode->pMeta, 0);
+ int64_t uid = pExec->pExecReader[workerId]->msgIter.uid;
+ if (metaGetTableEntryByUid(&mr, uid) < 0) {
+ ASSERT(0);
+ return -1;
+ }
+ char* tbName = strdup(mr.me.name);
+ taosArrayPush(pRsp->blockTbName, &tbName);
+ metaReaderClear(&mr);
+ return 0;
+}
+
+int32_t tqDataExec(STQ* pTq, STqExecHandle* pExec, SSubmitReq* pReq, SMqDataBlkRsp* pRsp, int32_t workerId) {
+ if (pExec->subType == TOPIC_SUB_TYPE__COLUMN) {
+ qTaskInfo_t task = pExec->exec.execCol.task[workerId];
+ ASSERT(task);
+ qSetStreamInput(task, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK, false);
+ while (1) {
+ SSDataBlock* pDataBlock = NULL;
+ uint64_t ts = 0;
+ if (qExecTask(task, &pDataBlock, &ts) < 0) {
+ ASSERT(0);
+ }
+ if (pDataBlock == NULL) break;
+
+ ASSERT(pDataBlock->info.rows != 0);
+ ASSERT(pDataBlock->info.numOfCols != 0);
+
+ tqAddBlockDataToRsp(pDataBlock, pRsp);
+ if (pRsp->withTbName) {
+ tqAddTbNameToRsp(pTq, pExec, pRsp, workerId);
+ }
+ pRsp->blockNum++;
+ }
+ } else if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
+ pRsp->withSchema = 1;
+ STqReadHandle* pReader = pExec->pExecReader[workerId];
+ tqReadHandleSetMsg(pReader, pReq, 0);
+ while (tqNextDataBlock(pReader)) {
+ SSDataBlock block = {0};
+ if (tqRetrieveDataBlock(&block.pDataBlock, pReader, &block.info.groupId, &block.info.uid, &block.info.rows,
+ &block.info.numOfCols) < 0) {
+ if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue;
+ ASSERT(0);
+ }
+ tqAddBlockDataToRsp(&block, pRsp);
+ if (pRsp->withTbName) {
+ tqAddTbNameToRsp(pTq, pExec, pRsp, workerId);
+ }
+ tqAddBlockSchemaToRsp(pExec, workerId, pRsp);
+ pRsp->blockNum++;
+ }
+ } else if (pExec->subType == TOPIC_SUB_TYPE__DB) {
+ pRsp->withSchema = 1;
+ STqReadHandle* pReader = pExec->pExecReader[workerId];
+ tqReadHandleSetMsg(pReader, pReq, 0);
+ while (tqNextDataBlockFilterOut(pReader, pExec->exec.execDb.pFilterOutTbUid)) {
+ SSDataBlock block = {0};
+ if (tqRetrieveDataBlock(&block.pDataBlock, pReader, &block.info.groupId, &block.info.uid, &block.info.rows,
+ &block.info.numOfCols) < 0) {
+ if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue;
+ ASSERT(0);
+ }
+ tqAddBlockDataToRsp(&block, pRsp);
+ if (pRsp->withTbName) {
+ tqAddTbNameToRsp(pTq, pExec, pRsp, workerId);
+ }
+ tqAddBlockSchemaToRsp(pExec, workerId, pRsp);
+ pRsp->blockNum++;
+ }
+ }
+ if (pRsp->blockNum == 0) {
+ pRsp->skipLogNum++;
+ return -1;
+ }
+ return 0;
+}
diff --git a/source/dnode/vnode/src/tq/tqMeta.c b/source/dnode/vnode/src/tq/tqMeta.c
new file mode 100644
index 0000000000000000000000000000000000000000..9447c4007b87cd9dd256c555df1ac4eb431edaee
--- /dev/null
+++ b/source/dnode/vnode/src/tq/tqMeta.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#include "tdbInt.h"
+#include "tq.h"
+
+static int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle) {
+ if (tStartEncode(pEncoder) < 0) return -1;
+ if (tEncodeCStr(pEncoder, pHandle->subKey) < 0) return -1;
+ if (tEncodeI64(pEncoder, pHandle->consumerId) < 0) return -1;
+ if (tEncodeI32(pEncoder, pHandle->epoch) < 0) return -1;
+ if (tEncodeI8(pEncoder, pHandle->execHandle.subType) < 0) return -1;
+ if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ if (tEncodeCStr(pEncoder, pHandle->execHandle.exec.execCol.qmsg) < 0) return -1;
+ }
+ tEndEncode(pEncoder);
+ return pEncoder->pos;
+}
+
+static int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle) {
+ if (tStartDecode(pDecoder) < 0) return -1;
+ if (tDecodeCStrTo(pDecoder, pHandle->subKey) < 0) return -1;
+ if (tDecodeI64(pDecoder, &pHandle->consumerId) < 0) return -1;
+ if (tDecodeI32(pDecoder, &pHandle->epoch) < 0) return -1;
+ if (tDecodeI8(pDecoder, &pHandle->execHandle.subType) < 0) return -1;
+ if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ if (tDecodeCStrAlloc(pDecoder, &pHandle->execHandle.exec.execCol.qmsg) < 0) return -1;
+ }
+ tEndDecode(pDecoder);
+ return 0;
+}
+
+int tqExecKeyCompare(const void* pKey1, int32_t kLen1, const void* pKey2, int32_t kLen2) {
+ return strcmp(pKey1, pKey2);
+}
+
+int32_t tqMetaOpen(STQ* pTq) {
+ if (tdbOpen(pTq->path, 16 * 1024, 1, &pTq->pMetaStore) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbTbOpen("handles", -1, -1, tqExecKeyCompare, pTq->pMetaStore, &pTq->pExecStore) < 0) {
+ ASSERT(0);
+ }
+
+ TXN txn;
+
+ if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, 0) < 0) {
+ ASSERT(0);
+ }
+
+ TBC* pCur;
+ if (tdbTbcOpen(pTq->pExecStore, &pCur, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ void* pKey;
+ int kLen;
+ void* pVal;
+ int vLen;
+
+ tdbTbcMoveToFirst(pCur);
+ SDecoder decoder;
+
+ while (tdbTbcNext(pCur, &pKey, &kLen, &pVal, &vLen) == 0) {
+ STqHandle handle;
+ tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
+ tDecodeSTqHandle(&decoder, &handle);
+ handle.pWalReader = walOpenReadHandle(pTq->pVnode->pWal);
+ for (int32_t i = 0; i < 5; i++) {
+ handle.execHandle.pExecReader[i] = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
+ }
+ if (handle.execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ for (int32_t i = 0; i < 5; i++) {
+ SReadHandle reader = {
+ .reader = handle.execHandle.pExecReader[i],
+ .meta = pTq->pVnode->pMeta,
+ .pMsgCb = &pTq->pVnode->msgCb,
+ };
+ handle.execHandle.exec.execCol.task[i] =
+ qCreateStreamExecTaskInfo(handle.execHandle.exec.execCol.qmsg, &reader);
+ ASSERT(handle.execHandle.exec.execCol.task[i]);
+ }
+ } else {
+ handle.execHandle.exec.execDb.pFilterOutTbUid =
+ taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
+ }
+ taosHashPut(pTq->handles, pKey, kLen, &handle, sizeof(STqHandle));
+ }
+
+ if (tdbTxnClose(&txn) < 0) {
+ ASSERT(0);
+ }
+ return 0;
+}
+
+int32_t tqMetaClose(STQ* pTq) {
+ tdbClose(pTq->pMetaStore);
+ return 0;
+}
+
+int32_t tqMetaSaveHandle(STQ* pTq, const char* key, const STqHandle* pHandle) {
+ int32_t code;
+ int32_t vlen;
+ tEncodeSize(tEncodeSTqHandle, pHandle, vlen, code);
+ ASSERT(code == 0);
+
+ void* buf = taosMemoryCalloc(1, vlen);
+ if (buf == NULL) {
+ ASSERT(0);
+ }
+
+ SEncoder encoder;
+ tEncoderInit(&encoder, buf, vlen);
+
+ if (tEncodeSTqHandle(&encoder, pHandle) < 0) {
+ ASSERT(0);
+ }
+
+ TXN txn;
+
+ if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbBegin(pTq->pMetaStore, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbTbUpsert(pTq->pExecStore, key, (int)strlen(key), buf, vlen, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbCommit(pTq->pMetaStore, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ tEncoderClear(&encoder);
+ taosMemoryFree(buf);
+ return 0;
+}
+
+int32_t tqMetaDeleteHandle(STQ* pTq, const char* key) {
+ TXN txn;
+
+ if (tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbBegin(pTq->pMetaStore, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ if (tdbTbDelete(pTq->pExecStore, key, (int)strlen(key), &txn) < 0) {
+ /*ASSERT(0);*/
+ }
+
+ if (tdbCommit(pTq->pMetaStore, &txn) < 0) {
+ ASSERT(0);
+ }
+
+ return 0;
+}
diff --git a/source/dnode/vnode/src/tq/tqOffset.c b/source/dnode/vnode/src/tq/tqOffset.c
index 90f512611b1100bc79a6e85784ad87ebe10380c2..4d83a67579f89c24bde1c4724fdaacd1666bcfdd 100644
--- a/source/dnode/vnode/src/tq/tqOffset.c
+++ b/source/dnode/vnode/src/tq/tqOffset.c
@@ -30,7 +30,7 @@ struct STqOffsetStore {
SHashObj* pHash; // SHashObj
};
-STqOffsetStore* STqOffsetOpen(STqOffsetCfg* pCfg) {
+STqOffsetStore* tqOffsetOpen(STqOffsetCfg* pCfg) {
STqOffsetStore* pStore = taosMemoryMalloc(sizeof(STqOffsetStore));
if (pStore == NULL) {
return NULL;
diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c
index f2f48bbc8a69a022d0fc6b8a88c5a9a55d0b4ad6..26e9dfe2e2ceba9c854c51676d304428b1b86082 100644
--- a/source/dnode/vnode/src/tq/tqPush.c
+++ b/source/dnode/vnode/src/tq/tqPush.c
@@ -12,3 +12,246 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+
+#include "tq.h"
+
+void tqTmrRspFunc(void* param, void* tmrId) {
+ STqHandle* pHandle = (STqHandle*)param;
+ atomic_store_8(&pHandle->pushHandle.tmrStopped, 1);
+}
+
+int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) {
+ SMqDataBlkRsp rsp = {0};
+ // 1. guard and set status executing
+ int8_t execStatus =
+ atomic_val_compare_exchange_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE, TASK_STATUS__EXECUTING);
+ if (execStatus == TASK_STATUS__IDLE) {
+ SStreamDataSubmit* pSubmit = NULL;
+ // 2. check processedVer
+ // 2.1. if not missed, get msg from queue
+ // 2.2. if missed, scan wal
+ pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ);
+ while (pHandle->pushHandle.processedVer <= pSubmit->ver) {
+ // read from wal
+ }
+ while (pHandle->pushHandle.processedVer > pSubmit->ver + 1) {
+ streamQSetSuccess(&pHandle->pushHandle.inputQ);
+ streamDataSubmitRefDec(pSubmit);
+ pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ);
+ if (pSubmit == NULL) break;
+ }
+ // 3. exec, after each success, update processed ver
+ // first run
+ while (pSubmit != NULL) {
+ ASSERT(pSubmit->ver == pHandle->pushHandle.processedVer + 1);
+ if (tqDataExec(pTq, &pHandle->execHandle, pSubmit->data, &rsp, 0) < 0) {
+ /*ASSERT(0);*/
+ }
+ // update processed
+ atomic_store_64(&pHandle->pushHandle.processedVer, pSubmit->ver);
+ streamQSetSuccess(&pHandle->pushHandle.inputQ);
+ streamDataSubmitRefDec(pSubmit);
+ if (rsp.blockNum > 0) {
+ goto SEND_RSP;
+ } else {
+ pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ);
+ }
+ }
+ // set exec status closing
+ atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__CLOSING);
+ // second run
+ while (pSubmit != NULL) {
+ ASSERT(pSubmit->ver == pHandle->pushHandle.processedVer + 1);
+ if (tqDataExec(pTq, &pHandle->execHandle, pSubmit->data, &rsp, 0) < 0) {
+ /*ASSERT(0);*/
+ }
+ // update processed
+ atomic_store_64(&pHandle->pushHandle.processedVer, pSubmit->ver);
+ streamQSetSuccess(&pHandle->pushHandle.inputQ);
+ streamDataSubmitRefDec(pSubmit);
+ if (rsp.blockNum > 0) {
+ goto SEND_RSP;
+ } else {
+ pSubmit = streamQNextItem(&pHandle->pushHandle.inputQ);
+ }
+ }
+ // set exec status idle
+ atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE);
+ }
+SEND_RSP:
+ // 4. if get result
+ // 4.1 set exec input status blocked and exec status idle
+ atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE);
+ // 4.2 rpc send
+ rsp.rspOffset = pHandle->pushHandle.processedVer;
+ /*if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) {*/
+ /*return -1;*/
+ /*}*/
+ // 4.3 clear rpc info
+ memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
+ return 0;
+}
+
+int32_t tqOpenPushHandle(STQ* pTq, STqHandle* pHandle) {
+ memset(&pHandle->pushHandle, 0, sizeof(STqPushHandle));
+ pHandle->pushHandle.inputQ.queue = taosOpenQueue();
+ pHandle->pushHandle.inputQ.qall = taosAllocateQall();
+ if (pHandle->pushHandle.inputQ.queue == NULL || pHandle->pushHandle.inputQ.qall == NULL) {
+ if (pHandle->pushHandle.inputQ.queue) {
+ taosCloseQueue(pHandle->pushHandle.inputQ.queue);
+ }
+ if (pHandle->pushHandle.inputQ.qall) {
+ taosFreeQall(pHandle->pushHandle.inputQ.qall);
+ }
+ return -1;
+ }
+ return 0;
+}
+
+int32_t tqPreparePush(STQ* pTq, STqHandle* pHandle, int64_t reqId, const SRpcHandleInfo* pInfo, int64_t processedVer,
+ int64_t timeout) {
+ memcpy(&pHandle->pushHandle.rpcInfo, pInfo, sizeof(SRpcHandleInfo));
+ atomic_store_64(&pHandle->pushHandle.reqId, reqId);
+ atomic_store_64(&pHandle->pushHandle.processedVer, processedVer);
+ atomic_store_8(&pHandle->pushHandle.inputStatus, TASK_INPUT_STATUS__NORMAL);
+ atomic_store_8(&pHandle->pushHandle.tmrStopped, 0);
+ taosTmrReset(tqTmrRspFunc, (int32_t)timeout, pHandle, tqMgmt.timer, &pHandle->pushHandle.timerId);
+ return 0;
+}
+
+int32_t tqEnqueue(STqHandle* pHandle, SStreamDataSubmit* pSubmit) {
+ int8_t inputStatus = atomic_load_8(&pHandle->pushHandle.inputStatus);
+ if (inputStatus == TASK_INPUT_STATUS__NORMAL) {
+ SStreamDataSubmit* pSubmitClone = streamSubmitRefClone(pSubmit);
+ if (pSubmitClone == NULL) {
+ return -1;
+ }
+ taosWriteQitem(pHandle->pushHandle.inputQ.queue, pSubmitClone);
+ return 0;
+ }
+ return -1;
+}
+
+int32_t tqSendExecReq(STQ* pTq, STqHandle* pHandle) {
+ //
+ return 0;
+}
+
+int32_t tqEnqueueAll(STQ* pTq, SSubmitReq* pReq) {
+ void* pIter = NULL;
+ SStreamDataSubmit* pSubmit = streamDataSubmitNew(pReq);
+ if (pSubmit == NULL) {
+ return -1;
+ }
+
+ while (1) {
+ pIter = taosHashIterate(pTq->handles, pIter);
+ if (pIter == NULL) break;
+ STqHandle* pHandle = (STqHandle*)pIter;
+ if (tqEnqueue(pHandle, pSubmit) < 0) {
+ continue;
+ }
+ int8_t execStatus = atomic_load_8(&pHandle->pushHandle.execStatus);
+ if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) {
+ tqSendExecReq(pTq, pHandle);
+ }
+ }
+
+ streamDataSubmitRefDec(pSubmit);
+
+ return 0;
+}
+
+int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver, SRpcHandleInfo handleInfo) {
+ if (msgType != TDMT_VND_SUBMIT) return 0;
+ void* pIter = NULL;
+ STqHandle* pHandle = NULL;
+ SSubmitReq* pReq = (SSubmitReq*)msg;
+ int32_t workerId = 4;
+ int64_t fetchOffset = ver;
+
+ while (1) {
+ pIter = taosHashIterate(pTq->pushMgr, pIter);
+ if (pIter == NULL) break;
+ pHandle = *(STqHandle**)pIter;
+
+ taosWLockLatch(&pHandle->pushHandle.lock);
+
+ SMqDataBlkRsp rsp = {0};
+ rsp.reqOffset = pHandle->pushHandle.reqOffset;
+ rsp.blockData = taosArrayInit(0, sizeof(void*));
+ rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
+
+ if (msgType == TDMT_VND_SUBMIT) {
+ tqDataExec(pTq, &pHandle->execHandle, pReq, &rsp, workerId);
+ } else {
+ // TODO
+ ASSERT(0);
+ }
+
+ if (rsp.blockNum == 0) {
+ taosWUnLockLatch(&pHandle->pushHandle.lock);
+ continue;
+ }
+
+ ASSERT(taosArrayGetSize(rsp.blockData) == rsp.blockNum);
+ ASSERT(taosArrayGetSize(rsp.blockDataLen) == rsp.blockNum);
+
+ rsp.rspOffset = fetchOffset;
+
+ int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, &rsp);
+ void* buf = rpcMallocCont(tlen);
+ if (buf == NULL) {
+ // todo free
+ return -1;
+ }
+
+ ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
+ ((SMqRspHead*)buf)->epoch = pHandle->pushHandle.epoch;
+ ((SMqRspHead*)buf)->consumerId = pHandle->pushHandle.consumerId;
+
+ void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
+ tEncodeSMqDataBlkRsp(&abuf, &rsp);
+
+ SRpcMsg resp = {
+ .info = pHandle->pushHandle.rpcInfo,
+ .pCont = buf,
+ .contLen = tlen,
+ .code = 0,
+ };
+ tmsgSendRsp(&resp);
+
+ memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
+ taosWUnLockLatch(&pHandle->pushHandle.lock);
+
+ tqDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
+ TD_VID(pTq->pVnode), fetchOffset, pHandle->pushHandle.consumerId, pHandle->pushHandle.epoch, rsp.blockNum,
+ rsp.reqOffset, rsp.rspOffset);
+
+ // TODO destroy
+ taosArrayDestroy(rsp.blockData);
+ taosArrayDestroy(rsp.blockDataLen);
+ }
+
+ return 0;
+}
+
+int tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
+ if (msgType == TDMT_VND_SUBMIT) {
+ if (taosHashGetSize(pTq->pStreamTasks) == 0) return 0;
+
+ if (tdUpdateExpireWindow(pTq->pVnode->pSma, msg, ver) != 0) {
+ // TODO handle sma error
+ }
+ void* data = taosMemoryMalloc(msgLen);
+ if (data == NULL) {
+ return -1;
+ }
+ memcpy(data, msg, msgLen);
+
+ tqProcessStreamTrigger(pTq, data);
+ }
+
+ return 0;
+}
+
diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c
index 9f4c5fc81e05f7a39cd76612af0809f42f01700e..8909a00c72faf0e7ea9df06819c571af28921da8 100644
--- a/source/dnode/vnode/src/tq/tqRead.c
+++ b/source/dnode/vnode/src/tq/tqRead.c
@@ -15,6 +15,48 @@
#include "tq.h"
+int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead** ppHeadWithCkSum) {
+ int32_t code = 0;
+ taosThreadMutexLock(&pHandle->pWalReader->mutex);
+ int64_t offset = *fetchOffset;
+
+ while (1) {
+ if (walFetchHead(pHandle->pWalReader, offset, *ppHeadWithCkSum) < 0) {
+ tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", pHandle->consumerId,
+ pHandle->epoch, TD_VID(pTq->pVnode), offset);
+ *fetchOffset = offset - 1;
+ code = -1;
+ goto END;
+ }
+
+ if ((*ppHeadWithCkSum)->head.msgType == TDMT_VND_SUBMIT) {
+ code = walFetchBody(pHandle->pWalReader, ppHeadWithCkSum);
+
+ if (code < 0) {
+ ASSERT(0);
+ *fetchOffset = offset;
+ code = -1;
+ goto END;
+ }
+ *fetchOffset = offset;
+ code = 0;
+ goto END;
+ } else {
+ code = walSkipFetchBody(pHandle->pWalReader, *ppHeadWithCkSum);
+ if (code < 0) {
+ ASSERT(0);
+ *fetchOffset = offset;
+ code = -1;
+ goto END;
+ }
+ offset++;
+ }
+ }
+END:
+ taosThreadMutexUnlock(&pHandle->pWalReader->mutex);
+ return code;
+}
+
STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) {
STqReadHandle* pReadHandle = taosMemoryMalloc(sizeof(STqReadHandle));
if (pReadHandle == NULL) {
@@ -24,7 +66,7 @@ STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) {
pReadHandle->pMsg = NULL;
pReadHandle->ver = -1;
pReadHandle->pColIdList = NULL;
- pReadHandle->sver = -1;
+ pReadHandle->cachedSchemaVer = -1;
pReadHandle->cachedSchemaUid = -1;
pReadHandle->pSchema = NULL;
pReadHandle->pSchemaWrapper = NULL;
@@ -88,11 +130,11 @@ int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* p
// TODO set to real sversion
/*int32_t sversion = 1;*/
int32_t sversion = htonl(pHandle->pBlock->sversion);
- if (pHandle->sver != sversion || pHandle->cachedSchemaUid != pHandle->msgIter.suid) {
+ if (pHandle->cachedSchemaVer != sversion || pHandle->cachedSchemaUid != pHandle->msgIter.suid) {
pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion);
if (pHandle->pSchema == NULL) {
tqWarn("cannot found tsschema for table: uid: %ld (suid: %ld), version %d, possibly dropped table",
- pHandle->msgIter.uid, pHandle->msgIter.suid, pHandle->sver);
+ pHandle->msgIter.uid, pHandle->msgIter.suid, pHandle->cachedSchemaVer);
/*ASSERT(0);*/
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
return -1;
@@ -102,12 +144,12 @@ int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* p
pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true);
if (pHandle->pSchemaWrapper == NULL) {
tqWarn("cannot found schema wrapper for table: suid: %ld, version %d, possibly dropped table",
- pHandle->msgIter.suid, pHandle->sver);
+ pHandle->msgIter.suid, pHandle->cachedSchemaVer);
/*ASSERT(0);*/
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
return -1;
}
- pHandle->sver = sversion;
+ pHandle->cachedSchemaVer = sversion;
pHandle->cachedSchemaUid = pHandle->msgIter.suid;
}
@@ -256,3 +298,38 @@ int tqReadHandleRemoveTbUidList(STqReadHandle* pHandle, const SArray* tbUidList)
return 0;
}
+
+int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
+ void* pIter = NULL;
+ while (1) {
+ pIter = taosHashIterate(pTq->handles, pIter);
+ if (pIter == NULL) break;
+ STqHandle* pExec = (STqHandle*)pIter;
+ if (pExec->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
+ for (int32_t i = 0; i < 5; i++) {
+ int32_t code = qUpdateQualifiedTableId(pExec->execHandle.exec.execCol.task[i], tbUidList, isAdd);
+ ASSERT(code == 0);
+ }
+ } else if (pExec->execHandle.subType == TOPIC_SUB_TYPE__DB) {
+ if (!isAdd) {
+ int32_t sz = taosArrayGetSize(tbUidList);
+ for (int32_t i = 0; i < sz; i++) {
+ int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
+ taosHashPut(pExec->execHandle.exec.execDb.pFilterOutTbUid, &tbUid, sizeof(int64_t), NULL, 0);
+ }
+ }
+ } else {
+ // tq update id
+ }
+ }
+ while (1) {
+ pIter = taosHashIterate(pTq->pStreamTasks, pIter);
+ if (pIter == NULL) break;
+ SStreamTask* pTask = (SStreamTask*)pIter;
+ if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) {
+ int32_t code = qUpdateQualifiedTableId(pTask->exec.executor, tbUidList, isAdd);
+ ASSERT(code == 0);
+ }
+ }
+ return 0;
+}
diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c
new file mode 100644
index 0000000000000000000000000000000000000000..5c0bf971fb8702ffbb73ed92feb8c97d1f4032d1
--- /dev/null
+++ b/source/dnode/vnode/src/tq/tqSink.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#include "tq.h"
+
+void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
+ const SArray* pRes = (const SArray*)data;
+ SVnode* pVnode = (SVnode*)vnode;
+
+ ASSERT(pTask->tbSink.pTSchema);
+ SSubmitReq* pReq = tdBlockToSubmit(pRes, pTask->tbSink.pTSchema, true, pTask->tbSink.stbUid,
+ pTask->tbSink.stbFullName, pVnode->config.vgId);
+ /*tPrintFixedSchemaSubmitReq(pReq, pTask->tbSink.pTSchema);*/
+ // build write msg
+ SRpcMsg msg = {
+ .msgType = TDMT_VND_SUBMIT,
+ .pCont = pReq,
+ .contLen = ntohl(pReq->length),
+ };
+
+ ASSERT(tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) == 0);
+}
diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c
index 88d8ee9f9250f0139c19f3f9e2b0f8a553dc0520..0a85cb46383f7183efeea2dd44a869933a27587c 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCommit.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c
@@ -238,7 +238,7 @@ static void tsdbStartCommit(STsdb *pRepo) {
static void tsdbEndCommit(STsdb *pTsdb, int eno) {
tsdbEndFSTxn(pTsdb);
- tsdbMemTableDestroy(pTsdb, pTsdb->imem);
+ tsdbMemTableDestroy(pTsdb->imem);
pTsdb->imem = NULL;
tsdbInfo("vgId:%d commit over, %s", REPO_ID(pTsdb), (eno == TSDB_CODE_SUCCESS) ? "succeed" : "failed");
}
diff --git a/source/dnode/vnode/src/tsdb/tsdbDelete.c b/source/dnode/vnode/src/tsdb/tsdbDelete.c
new file mode 100644
index 0000000000000000000000000000000000000000..6dea4a4e57392be988126c579648f39a8270b9bf
--- /dev/null
+++ b/source/dnode/vnode/src/tsdb/tsdbDelete.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
\ No newline at end of file
diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable.c b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
index 9b9a431b5008c806adfbbf3172f61830129c3bdb..350e7235413cbca9f0dd0bdb1df0a938b389a5f8 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMemTable.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMemTable.c
@@ -60,7 +60,7 @@ int tsdbMemTableCreate(STsdb *pTsdb, STsdbMemTable **ppMemTable) {
return 0;
}
-void tsdbMemTableDestroy(STsdb *pTsdb, STsdbMemTable *pMemTable) {
+void tsdbMemTableDestroy(STsdbMemTable *pMemTable) {
if (pMemTable) {
taosHashCleanup(pMemTable->pHashIdx);
SSkipListIterator *pIter = tSkipListCreateIter(pMemTable->pSlIdx);
@@ -142,69 +142,6 @@ int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, SSkipListIterator *pIter
} else {
fKey = tdGetKey(filterKeys[filterIter]);
}
-#if 0
- } else if (fKey > rowKey) {
- if (isRowDel) {
- pMergeInfo->rowsDeleteFailed++;
- } else {
- if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break;
- if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
-
- pMergeInfo->rowsInserted++;
- pMergeInfo->nOperations++;
- pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
- pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
- tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row);
- }
-
- tSkipListIterNext(pIter);
- row = tsdbNextIterRow(pIter);
- if (row == NULL || TD_ROW_KEY(row) > maxKey) {
- rowKey = INT64_MAX;
- isRowDel = false;
- } else {
- rowKey = TD_ROW_KEY(row);
- isRowDel = TD_ROW_IS_DELETED(row);
- }
- } else {
- if (isRowDel) {
- ASSERT(!keepDup);
- if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
- pMergeInfo->rowsDeleteSucceed++;
- pMergeInfo->nOperations++;
- tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row);
- } else {
- if (keepDup) {
- if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
- pMergeInfo->rowsUpdated++;
- pMergeInfo->nOperations++;
- pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
- pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
- tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row);
- } else {
- pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
- pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
- }
- }
-
- tSkipListIterNext(pIter);
- row = tsdbNextIterRow(pIter);
- if (row == NULL || TD_ROW_KEY(row) > maxKey) {
- rowKey = INT64_MAX;
- isRowDel = false;
- } else {
- rowKey = TD_ROW_KEY(row);
- isRowDel = TD_ROW_IS_DELETED(row);
- }
-
- filterIter++;
- if (filterIter >= nFilterKeys) {
- fKey = INT64_MAX;
- } else {
- fKey = tdGetKey(filterKeys[filterIter]);
- }
- }
-#endif
#if 1
} else if (fKey > rowKey) {
if (isRowDel) {
@@ -321,7 +258,7 @@ int tsdbInsertTableData(STsdb *pTsdb, SSubmitMsgIter *pMsgIter, SSubmitBlk *pBlo
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
return -1;
}
- if(pRsp->tblFName) strcat(pRsp->tblFName, mr.me.name);
+ if (pRsp->tblFName) strcat(pRsp->tblFName, mr.me.name);
if (mr.me.type == TSDB_NORMAL_TABLE) {
sverNew = mr.me.ntbEntry.schemaRow.version;
diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c
index 025b2ab580163cf3e9b9031b24f1b07881d3ec61..94c88a14ffb31a6f80e4bd3ed9d6ab3207d2eb65 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c
@@ -15,52 +15,308 @@
#include "tsdb.h"
-typedef struct SMemTable SMemTable;
-typedef struct SMemData SMemData;
-typedef struct SMemSkipList SMemSkipList;
-typedef struct SMemSkipListNode SMemSkipListNode;
-typedef struct SMemSkipListCurosr SMemSkipListCurosr;
-
-#define SL_MAX_LEVEL 5
-
-struct SMemTable {
- STsdb *pTsdb;
- TSKEY minKey;
- TSKEY maxKey;
- int64_t minVer;
- int64_t maxVer;
- int64_t nRows;
- int32_t nHash;
- int32_t nBucket;
- SMemData **pBuckets;
- SMemSkipListCurosr *pSlc;
-};
+typedef struct SMemData SMemData;
+typedef struct SMemSkipList SMemSkipList;
+typedef struct SMemSkipListNode SMemSkipListNode;
struct SMemSkipListNode {
int8_t level;
- SMemSkipListNode *forwards[1]; // Windows does not allow 0
+ SMemSkipListNode *forwards[0];
};
struct SMemSkipList {
- uint32_t seed;
- int8_t maxLevel;
- int8_t level;
- int32_t size;
- SMemSkipListNode pHead[1]; // Windows does not allow 0
+ uint32_t seed;
+ int32_t size;
+ int8_t maxLevel;
+ int8_t level;
+ SMemSkipListNode *pHead;
+ SMemSkipListNode *pTail;
};
struct SMemData {
- SMemData *pHashNext;
tb_uid_t suid;
tb_uid_t uid;
- TSKEY minKey;
- TSKEY maxKey;
- int64_t minVer;
- int64_t maxVer;
- int64_t nRows;
+ TSDBKEY minKey;
+ TSDBKEY maxKey;
+ SDelOp *delOpHead;
+ SDelOp *delOpTail;
SMemSkipList sl;
};
+struct SMemTable {
+ STsdb *pTsdb;
+ int32_t nRef;
+ TSDBKEY minKey;
+ TSDBKEY maxKey;
+ int64_t nRows;
+ SArray *pArray; // SArray
+};
+
+#define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2)
+#define SL_NODE_HALF_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l))
+#define SL_NODE_FORWARD(n, l) ((n)->forwards[l])
+#define SL_NODE_BACKWARD(n, l) ((n)->forwards[(n)->level + (l)])
+#define SL_NODE_DATA(n) (&SL_NODE_BACKWARD(n, (n)->level))
+
+#define SL_HEAD_FORWARD(sl, l) SL_NODE_FORWARD((sl)->pHead, l)
+#define SL_TAIL_BACKWARD(sl, l) SL_NODE_FORWARD((sl)->pTail, l)
+
+static int32_t tsdbGetOrCreateMemData(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, SMemData **ppMemData);
+static int memDataPCmprFn(const void *p1, const void *p2);
+static int32_t tPutTSDBRow(uint8_t *p, TSDBROW *pRow);
+static int32_t tGetTSDBRow(uint8_t *p, TSDBROW *pRow);
+static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl);
+
+// SMemTable ==============================================
+int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTable) {
+ int32_t code = 0;
+ SMemTable *pMemTable = NULL;
+
+ pMemTable = (SMemTable *)taosMemoryCalloc(1, sizeof(*pMemTable));
+ if (pMemTable == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ pMemTable->pTsdb = pTsdb;
+ pMemTable->nRef = 1;
+ pMemTable->minKey = (TSDBKEY){.version = INT64_MAX, .ts = TSKEY_MAX};
+ pMemTable->maxKey = (TSDBKEY){.version = -1, .ts = TSKEY_MIN};
+ pMemTable->nRows = 0;
+ pMemTable->pArray = taosArrayInit(512, sizeof(SMemData *));
+ if (pMemTable->pArray == NULL) {
+ taosMemoryFree(pMemTable);
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+ *ppMemTable = pMemTable;
+ return code;
+
+_err:
+ *ppMemTable = NULL;
+ return code;
+}
+
+void tsdbMemTableDestroy2(SMemTable *pMemTable) {
+ taosArrayDestroyEx(pMemTable->pArray, NULL /*TODO*/);
+ taosMemoryFree(pMemTable);
+}
+
+int32_t tsdbInsertTableData2(STsdb *pTsdb, int64_t version, SVSubmitBlk *pSubmitBlk) {
+ int32_t code = 0;
+ SMemTable *pMemTable = (SMemTable *)pTsdb->mem; // TODO
+ SMemData *pMemData;
+ TSDBROW row = {.version = version};
+
+ ASSERT(pMemTable);
+
+ {
+ // check if table exists (todo)
+ }
+
+ code = tsdbGetOrCreateMemData(pMemTable, pSubmitBlk->suid, pSubmitBlk->uid, &pMemData);
+ if (code) {
+ tsdbError("vgId:%d failed to create/get table data since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
+ goto _err;
+ }
+
+ // do insert
+ int32_t nt;
+ uint8_t *pt;
+ int32_t n = 0;
+ uint8_t *p = pSubmitBlk->pData;
+ SVBufPool *pPool = pTsdb->pVnode->inUse;
+ int8_t level;
+ SMemSkipListNode *pNode;
+ while (n < pSubmitBlk->nData) {
+ nt = tGetTSRow(p + n, &row.tsRow);
+ n += nt;
+
+ ASSERT(n <= pSubmitBlk->nData);
+
+ // build the node
+ level = tsdbMemSkipListRandLevel(&pMemData->sl);
+ pNode = (SMemSkipListNode *)vnodeBufPoolMalloc(pPool, SL_NODE_SIZE(level) + nt + sizeof(version));
+ if (pNode == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ pNode->level = level;
+ tPutTSDBRow((uint8_t *)SL_NODE_DATA(pNode), &row);
+
+ // put the node (todo)
+
+ // set info
+ if (tsdbKeyCmprFn(&row, &pMemData->minKey) < 0) pMemData->minKey = *(TSDBKEY *)&row;
+ if (tsdbKeyCmprFn(&row, &pMemData->maxKey) > 0) pMemData->maxKey = *(TSDBKEY *)&row;
+ }
+
+ if (tsdbKeyCmprFn(&pMemTable->minKey, &pMemData->minKey) < 0) pMemTable->minKey = pMemData->minKey;
+ if (tsdbKeyCmprFn(&pMemTable->maxKey, &pMemData->maxKey) > 0) pMemTable->maxKey = pMemData->maxKey;
+
+ return code;
+
+_err:
+ return code;
+}
+
+int32_t tsdbDeleteTableData2(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey) {
+ int32_t code = 0;
+ SMemTable *pMemTable = (SMemTable *)pTsdb->mem; // TODO
+ SMemData *pMemData;
+ SVBufPool *pPool = pTsdb->pVnode->inUse;
+
+ ASSERT(pMemTable);
+
+ {
+ // check if table exists (todo)
+ }
+
+ code = tsdbGetOrCreateMemData(pMemTable, suid, uid, &pMemData);
+ if (code) {
+ goto _err;
+ }
+
+ // do delete
+ SDelOp *pDelOp = (SDelOp *)vnodeBufPoolMalloc(pPool, sizeof(*pDelOp));
+ if (pDelOp == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ pDelOp->version = version;
+ pDelOp->sKey = sKey;
+ pDelOp->eKey = eKey;
+ pDelOp->pNext = NULL;
+ if (pMemData->delOpHead == NULL) {
+ ASSERT(pMemData->delOpTail == NULL);
+ pMemData->delOpHead = pMemData->delOpTail = pDelOp;
+ } else {
+ pMemData->delOpTail->pNext = pDelOp;
+ pMemData->delOpTail = pDelOp;
+ }
+
+ {
+ // update the state of pMemTable, pMemData, last and lastrow (todo)
+ }
+
+ tsdbDebug("vgId:%d delete data from table suid:%" PRId64 " uid:%" PRId64 " sKey:%" PRId64 " eKey:%" PRId64
+ " since %s",
+ TD_VID(pTsdb->pVnode), suid, uid, sKey, eKey, tstrerror(code));
+ return code;
+
+_err:
+ tsdbError("vgId:%d failed to delete data from table suid:%" PRId64 " uid:%" PRId64 " sKey:%" PRId64 " eKey:%" PRId64
+ " since %s",
+ TD_VID(pTsdb->pVnode), suid, uid, sKey, eKey, tstrerror(code));
+ return code;
+}
+
+static int32_t tsdbGetOrCreateMemData(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, SMemData **ppMemData) {
+ int32_t code = 0;
+ int32_t idx = 0;
+ SMemData *pMemDataT = &(SMemData){.suid = suid, .uid = uid};
+ SMemData *pMemData = NULL;
+ SVBufPool *pPool = pMemTable->pTsdb->pVnode->inUse;
+ int8_t maxLevel = pMemTable->pTsdb->pVnode->config.tsdbCfg.slLevel;
+
+ // get
+ idx = taosArraySearchIdx(pMemTable->pArray, &pMemDataT, memDataPCmprFn, TD_GE);
+ if (idx >= 0) {
+ pMemData = (SMemData *)taosArrayGet(pMemTable->pArray, idx);
+ if (memDataPCmprFn(&pMemDataT, &pMemData) == 0) goto _exit;
+ }
+
+ // create
+ pMemData = vnodeBufPoolMalloc(pPool, sizeof(*pMemData) + SL_NODE_HALF_SIZE(maxLevel) * 2);
+ if (pMemData == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+ pMemData->suid = suid;
+ pMemData->uid = uid;
+ pMemData->minKey = (TSDBKEY){.version = INT64_MAX, .ts = TSKEY_MAX};
+ pMemData->maxKey = (TSDBKEY){.version = -1, .ts = TSKEY_MIN};
+ pMemData->delOpHead = pMemData->delOpTail = NULL;
+ pMemData->sl.seed = taosRand();
+ pMemData->sl.size = 0;
+ pMemData->sl.maxLevel = maxLevel;
+ pMemData->sl.level = 0;
+ pMemData->sl.pHead = (SMemSkipListNode *)&pMemData[1];
+ pMemData->sl.pTail = (SMemSkipListNode *)POINTER_SHIFT(pMemData->sl.pHead, SL_NODE_HALF_SIZE(maxLevel));
+
+ for (int8_t iLevel = 0; iLevel < pMemData->sl.maxLevel; iLevel++) {
+ SL_HEAD_FORWARD(&pMemData->sl, iLevel) = pMemData->sl.pTail;
+ SL_TAIL_BACKWARD(&pMemData->sl, iLevel) = pMemData->sl.pHead;
+ }
+
+ if (idx < 0) idx = 0;
+ if (taosArrayInsert(pMemTable->pArray, idx, &pMemData) == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto _err;
+ }
+
+_exit:
+ *ppMemData = pMemData;
+ return code;
+
+_err:
+ *ppMemData = NULL;
+ return code;
+}
+
+static int memDataPCmprFn(const void *p1, const void *p2) {
+ SMemData *pMemData1 = *(SMemData **)p1;
+ SMemData *pMemData2 = *(SMemData **)p2;
+
+ if (pMemData1->suid < pMemData2->suid) {
+ return -1;
+ } else if (pMemData1->suid > pMemData2->suid) {
+ return 1;
+ }
+
+ if (pMemData1->uid < pMemData2->uid) {
+ return -1;
+ } else if (pMemData1->uid > pMemData2->uid) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int32_t tPutTSDBRow(uint8_t *p, TSDBROW *pRow) {
+ int32_t n = 0;
+
+ n += tPutI64(p ? p + n : p, pRow->version);
+ n += tPutTSRow(p ? p + n : p, &pRow->tsRow);
+
+ return n;
+}
+
+static int32_t tGetTSDBRow(uint8_t *p, TSDBROW *pRow) {
+ int32_t n = 0;
+
+ n += tGetI64(p + n, &pRow->version);
+ n += tGetTSRow(p + n, &pRow->tsRow);
+
+ return n;
+}
+
+static FORCE_INLINE int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) {
+ int8_t level = 1;
+ int8_t tlevel = TMIN(pSl->maxLevel, pSl->level + 1);
+ const uint32_t factor = 4;
+
+ while ((taosRandR(&pSl->seed) % factor) == 0 && level < tlevel) {
+ level++;
+ }
+
+ return level;
+}
+
+#if 0 //====================================================================================
+
+#define SL_MAX_LEVEL 5
+
struct SMemSkipListCurosr {
SMemSkipList *pSl;
SMemSkipListNode *pNodes[SL_MAX_LEVEL];
@@ -74,12 +330,6 @@ typedef struct {
#define HASH_BUCKET(SUID, UID, NBUCKET) (TABS((SUID) + (UID)) % (NBUCKET))
-#define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2)
-#define SL_NODE_HALF_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l))
-#define SL_NODE_FORWARD(n, l) ((n)->forwards[l])
-#define SL_NODE_BACKWARD(n, l) ((n)->forwards[(n)->level + (l)])
-#define SL_NODE_DATA(n) (&SL_NODE_BACKWARD(n, (n)->level))
-
#define SL_HEAD_NODE(sl) ((sl)->pHead)
#define SL_TAIL_NODE(sl) ((SMemSkipListNode *)&SL_NODE_FORWARD(SL_HEAD_NODE(sl), (sl)->maxLevel))
#define SL_HEAD_NODE_FORWARD(n, l) SL_NODE_FORWARD(n, l)
@@ -99,50 +349,7 @@ static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc);
static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc);
static SMemSkipListNode *tsdbMemSkipListNodeCreate(SVBufPool *pPool, SMemSkipList *pSl, const STsdbRow *pTRow);
-// SMemTable
-int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) {
- SMemTable *pMemTb = NULL;
-
- pMemTb = taosMemoryCalloc(1, sizeof(*pMemTb));
- if (pMemTb == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
-
- pMemTb->pTsdb = pTsdb;
- pMemTb->minKey = TSKEY_MAX;
- pMemTb->maxKey = TSKEY_MIN;
- pMemTb->minVer = -1;
- pMemTb->maxVer = -1;
- pMemTb->nRows = 0;
- pMemTb->nHash = 0;
- pMemTb->nBucket = 1024;
- pMemTb->pBuckets = taosMemoryCalloc(pMemTb->nBucket, sizeof(*pMemTb->pBuckets));
- if (pMemTb->pBuckets == NULL) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- taosMemoryFree(pMemTb);
- return -1;
- }
- if (tsdbMemSkipListCursorCreate(pTsdb->pVnode->config.tsdbCfg.slLevel, &pMemTb->pSlc) < 0) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- taosMemoryFree(pMemTb->pBuckets);
- taosMemoryFree(pMemTb);
- }
-
- *ppMemTb = pMemTb;
- return 0;
-}
-
-int32_t tsdbMemTableDestroy2(STsdb *pTsdb, SMemTable *pMemTb) {
- if (pMemTb) {
- // loop to destroy the contents (todo)
- tsdbMemSkipListCursorDestroy(pMemTb->pSlc);
- taosMemoryFree(pMemTb->pBuckets);
- taosMemoryFree(pMemTb);
- }
- return 0;
-}
-
+// SMemTable ========================
int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *pSubmitBlk) {
SMemData *pMemData;
STsdb *pTsdb = pMemTb->pTsdb;
@@ -253,18 +460,6 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p
return 0;
}
-static FORCE_INLINE int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) {
- int8_t level = 1;
- int8_t tlevel = TMIN(pSl->maxLevel, pSl->level + 1);
- const uint32_t factor = 4;
-
- while ((taosRandR(&pSl->seed) % factor) == 0 && level < tlevel) {
- level++;
- }
-
- return level;
-}
-
static FORCE_INLINE int32_t tsdbEncodeRow(SEncoder *pEncoder, const STsdbRow *pRow) {
if (tEncodeI64(pEncoder, pRow->version) < 0) return -1;
if (tEncodeBinary(pEncoder, (const uint8_t *)pRow->pRow, pRow->szRow) < 0) return -1;
@@ -377,4 +572,5 @@ static SMemSkipListNode *tsdbMemSkipListNodeCreate(SVBufPool *pPool, SMemSkipLis
}
return pNode;
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c
index 62125b6dc7a5dadcbe534c4dab64b07e9964c3f2..61daa0c9b345837a3406ea7d2947faf61d72fe06 100644
--- a/source/dnode/vnode/src/tsdb/tsdbRead.c
+++ b/source/dnode/vnode/src/tsdb/tsdbRead.c
@@ -13,8 +13,8 @@
* along with this program. If not, see .
*/
-#include "vnode.h"
#include "tsdb.h"
+#include "vnode.h"
#define EXTRA_BYTES 2
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
@@ -327,13 +327,13 @@ static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableData
if (updateTs) {
tsdbDebug("%p update the query time window, old:%" PRId64 " - %" PRId64 ", new:%" PRId64 " - %" PRId64 ", %s",
- pTsdbReadHandle, pCond->twindows[tWinIdx].skey, pCond->twindows[tWinIdx].ekey, pTsdbReadHandle->window.skey,
- pTsdbReadHandle->window.ekey, pTsdbReadHandle->idStr);
+ pTsdbReadHandle, pCond->twindows[tWinIdx].skey, pCond->twindows[tWinIdx].ekey,
+ pTsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey, pTsdbReadHandle->idStr);
}
}
static STsdb* getTsdbByRetentions(SVnode* pVnode, STsdbReadHandle* pReadHandle, TSKEY winSKey, SRetention* retentions) {
- if (vnodeIsRollup(pVnode)) {
+ if (VND_IS_RSMA(pVnode)) {
int level = 0;
int64_t now = taosGetTimestamp(pVnode->config.tsdbCfg.precision);
@@ -586,7 +586,8 @@ void tsdbResetReadHandle(tsdbReaderT queryHandle, SQueryTableDataCond* pCond, in
resetCheckInfo(pTsdbReadHandle);
}
-void tsdbResetQueryHandleForNewTable(tsdbReaderT queryHandle, SQueryTableDataCond* pCond, STableListInfo* tableList, int32_t tWinIdx) {
+void tsdbResetQueryHandleForNewTable(tsdbReaderT queryHandle, SQueryTableDataCond* pCond, STableListInfo* tableList,
+ int32_t tWinIdx) {
STsdbReadHandle* pTsdbReadHandle = queryHandle;
pTsdbReadHandle->order = pCond->order;
@@ -2845,6 +2846,22 @@ int32_t tsdbGetAllTableList(SMeta* pMeta, uint64_t uid, SArray* list) {
return TSDB_CODE_SUCCESS;
}
+int32_t tsdbGetCtbIdList(SMeta* pMeta, int64_t suid, SArray* list) {
+ SMCtbCursor* pCur = metaOpenCtbCursor(pMeta, suid);
+
+ while (1) {
+ tb_uid_t id = metaCtbCursorNext(pCur);
+ if (id == 0) {
+ break;
+ }
+
+ taosArrayPush(list, &id);
+ }
+
+ metaCloseCtbCursor(pCur);
+ return TSDB_CODE_SUCCESS;
+}
+
static void destroyHelper(void* param) {
if (param == NULL) {
return;
diff --git a/source/dnode/vnode/src/tsdb/tsdbSma.c b/source/dnode/vnode/src/tsdb/tsdbSma.c
deleted file mode 100644
index 45b17a0180e4dabd411b01757c35e40910d62579..0000000000000000000000000000000000000000
--- a/source/dnode/vnode/src/tsdb/tsdbSma.c
+++ /dev/null
@@ -1,2203 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#include "tsdbSma.h"
-#include "tsdb.h"
-
-static const char *TSDB_SMA_DNAME[] = {
- "", // TSDB_SMA_TYPE_BLOCK
- "tsma", // TSDB_SMA_TYPE_TIME_RANGE
- "rsma", // TSDB_SMA_TYPE_ROLLUP
-};
-
-#undef _TEST_SMA_PRINT_DEBUG_LOG_
-#define SMA_STORAGE_TSDB_DAYS 30
-#define SMA_STORAGE_TSDB_TIMES 10
-#define SMA_STORAGE_SPLIT_HOURS 24
-#define SMA_KEY_LEN 16 // TSKEY+groupId 8+8
-#define SMA_DROP_EXPIRED_TIME 10 // default is 10 seconds
-
-#define SMA_STATE_HASH_SLOT 4
-#define SMA_STATE_ITEM_HASH_SLOT 32
-
-#define SMA_TEST_INDEX_NAME "smaTestIndexName" // TODO: just for test
-#define SMA_TEST_INDEX_UID 2000000001 // TODO: just for test
-
-typedef struct SRSmaInfo SRSmaInfo;
-typedef enum {
- SMA_STORAGE_LEVEL_TSDB = 0, // use days of self-defined e.g. vnode${N}/tsdb/tsma/sma_index_uid/v2f200.tsma
- SMA_STORAGE_LEVEL_DFILESET = 1 // use days of TS data e.g. vnode${N}/tsdb/tsma/sma_index_uid/v2f1906.tsma
-} ESmaStorageLevel;
-
-typedef struct SPoolMem {
- int64_t size;
- struct SPoolMem *prev;
- struct SPoolMem *next;
-} SPoolMem;
-
-struct SSmaEnv {
- TdThreadRwlock lock;
- int8_t type;
- TXN txn;
- SPoolMem *pPool;
- SDiskID did;
- TDB *dbEnv; // TODO: If it's better to put it in smaIndex level?
- char *path; // relative path
- SSmaStat *pStat;
-};
-
-#define SMA_ENV_LOCK(env) ((env)->lock)
-#define SMA_ENV_TYPE(env) ((env)->type)
-#define SMA_ENV_DID(env) ((env)->did)
-#define SMA_ENV_ENV(env) ((env)->dbEnv)
-#define SMA_ENV_PATH(env) ((env)->path)
-#define SMA_ENV_STAT(env) ((env)->pStat)
-#define SMA_ENV_STAT_ITEMS(env) ((env)->pStat->smaStatItems)
-
-typedef struct {
- STsdb *pTsdb;
- SDBFile dFile;
- const SArray *pDataBlocks; // sma data
- int32_t interval; // interval with the precision of DB
-} STSmaWriteH;
-
-typedef struct {
- int32_t iter;
- int32_t fid;
-} SmaFsIter;
-
-typedef struct {
- STsdb *pTsdb;
- SDBFile dFile;
- int32_t interval; // interval with the precision of DB
- int32_t blockSize; // size of SMA block item
- int8_t storageLevel;
- int8_t days;
- SmaFsIter smaFsIter;
-} STSmaReadH;
-
-typedef struct {
- /**
- * @brief The field 'state' is here to demonstrate if one smaIndex is ready to provide service.
- * - TSDB_SMA_STAT_OK: 1) The sma calculation of history data is finished; 2) Or recevied information from
- * Streaming Module or TSDB local persistence.
- * - TSDB_SMA_STAT_EXPIRED: 1) If sma calculation of history TS data is not finished; 2) Or if the TSDB is open,
- * without information about its previous state.
- * - TSDB_SMA_STAT_DROPPED: 1)sma dropped
- * N.B. only applicable to tsma
- */
- int8_t state; // ETsdbSmaStat
- SHashObj *expiredWindows; // key: skey of time window, value: N/A
- STSma *pSma; // cache schema
-} SSmaStatItem;
-
-#define RSMA_TASK_INFO_HASH_SLOT 8
-struct SRSmaInfo {
- void *taskInfo[TSDB_RETENTION_L2]; // qTaskInfo_t
-};
-
-struct SSmaStat {
- union {
- SHashObj *smaStatItems; // key: indexUid, value: SSmaStatItem for tsma
- SHashObj *rsmaInfoHash; // key: stbUid, value: SRSmaInfo;
- };
- T_REF_DECLARE()
-};
-#define SMA_STAT_ITEMS(s) ((s)->smaStatItems)
-#define SMA_STAT_INFO_HASH(s) ((s)->rsmaInfoHash)
-
-static FORCE_INLINE void tsdbFreeTaskHandle(qTaskInfo_t *taskHandle) {
- // Note: free/kill may in RC
- qTaskInfo_t otaskHandle = atomic_load_ptr(taskHandle);
- if (otaskHandle && atomic_val_compare_exchange_ptr(taskHandle, otaskHandle, NULL)) {
- qDestroyTask(otaskHandle);
- }
-}
-
-static FORCE_INLINE void *tsdbFreeRSmaInfo(SRSmaInfo *pInfo) {
- for (int32_t i = 0; i < TSDB_RETENTION_MAX; ++i) {
- if (pInfo->taskInfo[i]) {
- tsdbFreeTaskHandle(pInfo->taskInfo[i]);
- }
- }
- return NULL;
-}
-
-// declaration of static functions
-
-// expired window
-static int32_t tsdbUpdateExpiredWindowImpl(STsdb *pTsdb, SSubmitReq *pMsg, int64_t version);
-static int32_t tsdbSetExpiredWindow(STsdb *pTsdb, SHashObj *pItemsHash, int64_t indexUid, int64_t winSKey,
- int64_t version);
-static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat, int8_t smaType);
-static void *tsdbFreeSmaStatItem(SSmaStatItem *pSmaStatItem);
-static int32_t tsdbDestroySmaState(SSmaStat *pSmaStat, int8_t smaType);
-static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, int8_t smaType, const char *path, SDiskID did);
-static int32_t tsdbInitSmaEnv(STsdb *pTsdb, int8_t smaType, const char *path, SDiskID did, SSmaEnv **pEnv);
-static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, SSmaStat *pStat, int64_t indexUid, TSKEY skey);
-static int32_t tsdbRefSmaStat(STsdb *pTsdb, SSmaStat *pStat);
-static int32_t tsdbUnRefSmaStat(STsdb *pTsdb, SSmaStat *pStat);
-
-// read data
-// TODO: This is the basic params, and should wrap the params to a queryHandle.
-static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, char *pData, int64_t indexUid, TSKEY querySKey, int32_t nMaxResult);
-
-// insert data
-static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, const SArray *pDataBlocks, int64_t interval,
- int8_t intervalUnit);
-static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH);
-static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit);
-static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit);
-static int32_t tsdbSetRSmaDataFile(STSmaWriteH *pSmaH, int32_t fid);
-static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, int32_t keyLen, void *pData, int32_t dataLen,
- TXN *txn);
-static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit, int8_t precision, bool adjusted);
-static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel);
-static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, int64_t indexUid, int32_t fid);
-static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, int64_t indexUid, TSKEY skey);
-static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey);
-static void tsdbGetSmaDir(int32_t vgId, ETsdbSmaType smaType, char dirName[]);
-static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, int64_t indexUid, const char *msg);
-static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, const char *msg);
-
-static FORCE_INLINE int32_t tsdbUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
-static FORCE_INLINE int32_t tsdbUpdateTbUidListImpl(STsdb *pTsdb, tb_uid_t *suid, SArray *tbUids);
-static FORCE_INLINE int32_t tsdbExecuteRSmaImpl(STsdb *pTsdb, const void *pMsg, int32_t inputType,
- qTaskInfo_t *taskInfo, STSchema *pTSchema, tb_uid_t suid, tb_uid_t uid,
- int8_t level);
-// mgmt interface
-static int32_t tsdbDropTSmaDataImpl(STsdb *pTsdb, int64_t indexUid);
-
-// Pool Memory
-static SPoolMem *openPool();
-static void clearPool(SPoolMem *pPool);
-static void closePool(SPoolMem *pPool);
-static void *poolMalloc(void *arg, size_t size);
-static void poolFree(void *arg, void *ptr);
-
-static int tsdbSmaBeginCommit(SSmaEnv *pEnv);
-static int tsdbSmaEndCommit(SSmaEnv *pEnv);
-
-// implementation
-static FORCE_INLINE int16_t tsdbTSmaAdd(STsdb *pTsdb, int16_t n) {
- return atomic_add_fetch_16(&REPO_TSMA_NUM(pTsdb), n);
-}
-static FORCE_INLINE int16_t tsdbTSmaSub(STsdb *pTsdb, int16_t n) {
- return atomic_sub_fetch_16(&REPO_TSMA_NUM(pTsdb), n);
-}
-
-static FORCE_INLINE int32_t tsdbRLockSma(SSmaEnv *pEnv) {
- int code = taosThreadRwlockRdlock(&(pEnv->lock));
- if (code != 0) {
- terrno = TAOS_SYSTEM_ERROR(code);
- return -1;
- }
- return 0;
-}
-
-static FORCE_INLINE int32_t tsdbWLockSma(SSmaEnv *pEnv) {
- int code = taosThreadRwlockWrlock(&(pEnv->lock));
- if (code != 0) {
- terrno = TAOS_SYSTEM_ERROR(code);
- return -1;
- }
- return 0;
-}
-
-static FORCE_INLINE int32_t tsdbUnLockSma(SSmaEnv *pEnv) {
- int code = taosThreadRwlockUnlock(&(pEnv->lock));
- if (code != 0) {
- terrno = TAOS_SYSTEM_ERROR(code);
- return -1;
- }
- return 0;
-}
-
-static SPoolMem *openPool() {
- SPoolMem *pPool = (SPoolMem *)taosMemoryMalloc(sizeof(*pPool));
-
- pPool->prev = pPool->next = pPool;
- pPool->size = 0;
-
- return pPool;
-}
-
-static void clearPool(SPoolMem *pPool) {
- if (!pPool) return;
-
- SPoolMem *pMem;
-
- do {
- pMem = pPool->next;
-
- if (pMem == pPool) break;
-
- pMem->next->prev = pMem->prev;
- pMem->prev->next = pMem->next;
- pPool->size -= pMem->size;
-
- taosMemoryFree(pMem);
- } while (1);
-
- assert(pPool->size == 0);
-}
-
-static void closePool(SPoolMem *pPool) {
- if (pPool) {
- clearPool(pPool);
- taosMemoryFree(pPool);
- }
-}
-
-static void *poolMalloc(void *arg, size_t size) {
- void *ptr = NULL;
- SPoolMem *pPool = (SPoolMem *)arg;
- SPoolMem *pMem;
-
- pMem = (SPoolMem *)taosMemoryMalloc(sizeof(*pMem) + size);
- if (!pMem) {
- assert(0);
- }
-
- pMem->size = sizeof(*pMem) + size;
- pMem->next = pPool->next;
- pMem->prev = pPool;
-
- pPool->next->prev = pMem;
- pPool->next = pMem;
- pPool->size += pMem->size;
-
- ptr = (void *)(&pMem[1]);
- return ptr;
-}
-
-static void poolFree(void *arg, void *ptr) {
- SPoolMem *pPool = (SPoolMem *)arg;
- SPoolMem *pMem;
-
- pMem = &(((SPoolMem *)ptr)[-1]);
-
- pMem->next->prev = pMem->prev;
- pMem->prev->next = pMem->next;
- pPool->size -= pMem->size;
-
- taosMemoryFree(pMem);
-}
-
-int32_t tsdbInitSma(STsdb *pTsdb) {
- // tSma
- int32_t numOfTSma = taosArrayGetSize(metaGetSmaTbUids(REPO_META(pTsdb), false));
- if (numOfTSma > 0) {
- atomic_store_16(&REPO_TSMA_NUM(pTsdb), (int16_t)numOfTSma);
- }
- // TODO: rSma
- return TSDB_CODE_SUCCESS;
-}
-
-static FORCE_INLINE int8_t tsdbSmaStat(SSmaStatItem *pStatItem) {
- if (pStatItem) {
- return atomic_load_8(&pStatItem->state);
- }
- return TSDB_SMA_STAT_UNKNOWN;
-}
-
-static FORCE_INLINE bool tsdbSmaStatIsOK(SSmaStatItem *pStatItem, int8_t *state) {
- if (!pStatItem) {
- return false;
- }
-
- if (state) {
- *state = atomic_load_8(&pStatItem->state);
- return *state == TSDB_SMA_STAT_OK;
- }
- return atomic_load_8(&pStatItem->state) == TSDB_SMA_STAT_OK;
-}
-
-static FORCE_INLINE bool tsdbSmaStatIsExpired(SSmaStatItem *pStatItem) {
- return pStatItem ? (atomic_load_8(&pStatItem->state) & TSDB_SMA_STAT_EXPIRED) : true;
-}
-
-static FORCE_INLINE bool tsdbSmaStatIsDropped(SSmaStatItem *pStatItem) {
- return pStatItem ? (atomic_load_8(&pStatItem->state) & TSDB_SMA_STAT_DROPPED) : true;
-}
-
-static FORCE_INLINE void tsdbSmaStatSetOK(SSmaStatItem *pStatItem) {
- if (pStatItem) {
- atomic_store_8(&pStatItem->state, TSDB_SMA_STAT_OK);
- }
-}
-
-static FORCE_INLINE void tsdbSmaStatSetExpired(SSmaStatItem *pStatItem) {
- if (pStatItem) {
- atomic_or_fetch_8(&pStatItem->state, TSDB_SMA_STAT_EXPIRED);
- }
-}
-
-static FORCE_INLINE void tsdbSmaStatSetDropped(SSmaStatItem *pStatItem) {
- if (pStatItem) {
- atomic_or_fetch_8(&pStatItem->state, TSDB_SMA_STAT_DROPPED);
- }
-}
-
-static void tsdbGetSmaDir(int32_t vgId, ETsdbSmaType smaType, char dirName[]) {
- snprintf(dirName, TSDB_FILENAME_LEN, "vnode%svnode%d%s%s", TD_DIRSEP, vgId, TD_DIRSEP, TSDB_SMA_DNAME[smaType]);
-}
-
-static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, int8_t smaType, const char *path, SDiskID did) {
- SSmaEnv *pEnv = NULL;
-
- pEnv = (SSmaEnv *)taosMemoryCalloc(1, sizeof(SSmaEnv));
- if (!pEnv) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return NULL;
- }
-
- SMA_ENV_TYPE(pEnv) = smaType;
-
- int code = taosThreadRwlockInit(&(pEnv->lock), NULL);
- if (code) {
- terrno = TAOS_SYSTEM_ERROR(code);
- taosMemoryFree(pEnv);
- return NULL;
- }
-
- ASSERT(path && (strlen(path) > 0));
- SMA_ENV_PATH(pEnv) = strdup(path);
- if (!SMA_ENV_PATH(pEnv)) {
- tsdbFreeSmaEnv(pEnv);
- return NULL;
- }
-
- SMA_ENV_DID(pEnv) = did;
-
- if (tsdbInitSmaStat(&SMA_ENV_STAT(pEnv), smaType) != TSDB_CODE_SUCCESS) {
- tsdbFreeSmaEnv(pEnv);
- return NULL;
- }
-
- char aname[TSDB_FILENAME_LEN] = {0};
- tfsAbsoluteName(REPO_TFS(pTsdb), did, path, aname);
- if (tsdbOpenDBEnv(&pEnv->dbEnv, aname) != TSDB_CODE_SUCCESS) {
- tsdbFreeSmaEnv(pEnv);
- return NULL;
- }
-
- if (!(pEnv->pPool = openPool())) {
- tsdbFreeSmaEnv(pEnv);
- return NULL;
- }
-
- return pEnv;
-}
-
-static int32_t tsdbInitSmaEnv(STsdb *pTsdb, int8_t smaType, const char *path, SDiskID did, SSmaEnv **pEnv) {
- if (!pEnv) {
- terrno = TSDB_CODE_INVALID_PTR;
- return TSDB_CODE_FAILED;
- }
-
- if (!(*pEnv)) {
- if (!(*pEnv = tsdbNewSmaEnv(pTsdb, smaType, path, did))) {
- return TSDB_CODE_FAILED;
- }
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Release resources allocated for its member fields, not including itself.
- *
- * @param pSmaEnv
- * @return int32_t
- */
-void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv) {
- if (pSmaEnv) {
- tsdbDestroySmaState(pSmaEnv->pStat, SMA_ENV_TYPE(pSmaEnv));
- taosMemoryFreeClear(pSmaEnv->pStat);
- taosMemoryFreeClear(pSmaEnv->path);
- taosThreadRwlockDestroy(&(pSmaEnv->lock));
- tsdbCloseDBEnv(pSmaEnv->dbEnv);
- closePool(pSmaEnv->pPool);
- }
-}
-
-void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv) {
- tsdbDestroySmaEnv(pSmaEnv);
- taosMemoryFreeClear(pSmaEnv);
- return NULL;
-}
-
-static int32_t tsdbRefSmaStat(STsdb *pTsdb, SSmaStat *pStat) {
- if (!pStat) return 0;
-
- int ref = T_REF_INC(pStat);
- tsdbDebug("vgId:%d ref sma stat:%p, val:%d", REPO_ID(pTsdb), pStat, ref);
- return 0;
-}
-
-static int32_t tsdbUnRefSmaStat(STsdb *pTsdb, SSmaStat *pStat) {
- if (!pStat) return 0;
-
- int ref = T_REF_DEC(pStat);
- tsdbDebug("vgId:%d unref sma stat:%p, val:%d", REPO_ID(pTsdb), pStat, ref);
- return 0;
-}
-
-static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat, int8_t smaType) {
- ASSERT(pSmaStat != NULL);
-
- if (*pSmaStat) { // no lock
- return TSDB_CODE_SUCCESS;
- }
-
- /**
- * 1. Lazy mode utilized when init SSmaStat to update expired window(or hungry mode when tsdbNew).
- * 2. Currently, there is mutex lock when init SSmaEnv, thus no need add lock on SSmaStat, and please add lock if
- * tsdbInitSmaStat invoked in other multithread environment later.
- */
- if (!(*pSmaStat)) {
- *pSmaStat = (SSmaStat *)taosMemoryCalloc(1, sizeof(SSmaStat));
- if (!(*pSmaStat)) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
-
- if (smaType == TSDB_SMA_TYPE_ROLLUP) {
- SMA_STAT_INFO_HASH(*pSmaStat) = taosHashInit(
- RSMA_TASK_INFO_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK);
-
- if (!SMA_STAT_INFO_HASH(*pSmaStat)) {
- taosMemoryFreeClear(*pSmaStat);
- return TSDB_CODE_FAILED;
- }
- } else if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
- SMA_STAT_ITEMS(*pSmaStat) =
- taosHashInit(SMA_STATE_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
-
- if (!SMA_STAT_ITEMS(*pSmaStat)) {
- taosMemoryFreeClear(*pSmaStat);
- return TSDB_CODE_FAILED;
- }
- } else {
- ASSERT(0);
- }
- }
- return TSDB_CODE_SUCCESS;
-}
-
-static SSmaStatItem *tsdbNewSmaStatItem(int8_t state) {
- SSmaStatItem *pItem = NULL;
-
- pItem = (SSmaStatItem *)taosMemoryCalloc(1, sizeof(SSmaStatItem));
- if (pItem) {
- pItem->state = state;
- pItem->expiredWindows = taosHashInit(SMA_STATE_ITEM_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP),
- true, HASH_ENTRY_LOCK);
- if (!pItem->expiredWindows) {
- taosMemoryFreeClear(pItem);
- }
- }
- return pItem;
-}
-
-static void *tsdbFreeSmaStatItem(SSmaStatItem *pSmaStatItem) {
- if (pSmaStatItem) {
- tdDestroyTSma(pSmaStatItem->pSma);
- taosMemoryFreeClear(pSmaStatItem->pSma);
- taosHashCleanup(pSmaStatItem->expiredWindows);
- taosMemoryFreeClear(pSmaStatItem);
- }
- return NULL;
-}
-
-/**
- * @brief Release resources allocated for its member fields, not including itself.
- *
- * @param pSmaStat
- * @return int32_t
- */
-int32_t tsdbDestroySmaState(SSmaStat *pSmaStat, int8_t smaType) {
- if (pSmaStat) {
- // TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready.
- if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
- void *item = taosHashIterate(SMA_STAT_ITEMS(pSmaStat), NULL);
- while (item) {
- SSmaStatItem *pItem = *(SSmaStatItem **)item;
- tsdbFreeSmaStatItem(pItem);
- item = taosHashIterate(SMA_STAT_ITEMS(pSmaStat), item);
- }
- taosHashCleanup(SMA_STAT_ITEMS(pSmaStat));
- } else if (smaType == TSDB_SMA_TYPE_ROLLUP) {
- void *infoHash = taosHashIterate(SMA_STAT_INFO_HASH(pSmaStat), NULL);
- while (infoHash) {
- SRSmaInfo *pInfoHash = *(SRSmaInfo **)infoHash;
- tsdbFreeRSmaInfo(pInfoHash);
- infoHash = taosHashIterate(SMA_STAT_INFO_HASH(pSmaStat), infoHash);
- }
- taosHashCleanup(SMA_STAT_INFO_HASH(pSmaStat));
- } else {
- ASSERT(0);
- }
- }
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbCheckAndInitSmaEnv(STsdb *pTsdb, int8_t smaType) {
- SSmaEnv *pEnv = NULL;
-
- // return if already init
- switch (smaType) {
- case TSDB_SMA_TYPE_TIME_RANGE:
- if ((pEnv = (SSmaEnv *)atomic_load_ptr(&REPO_TSMA_ENV(pTsdb)))) {
- return TSDB_CODE_SUCCESS;
- }
- break;
- case TSDB_SMA_TYPE_ROLLUP:
- if ((pEnv = (SSmaEnv *)atomic_load_ptr(&REPO_RSMA_ENV(pTsdb)))) {
- return TSDB_CODE_SUCCESS;
- }
- break;
- default:
- terrno = TSDB_CODE_INVALID_PARA;
- return TSDB_CODE_FAILED;
- }
-
- // init sma env
- tsdbLockRepo(pTsdb);
- pEnv = (smaType == TSDB_SMA_TYPE_TIME_RANGE) ? atomic_load_ptr(&REPO_TSMA_ENV(pTsdb))
- : atomic_load_ptr(&REPO_RSMA_ENV(pTsdb));
- if (!pEnv) {
- char rname[TSDB_FILENAME_LEN] = {0};
-
- SDiskID did = {0};
- tfsAllocDisk(REPO_TFS(pTsdb), TFS_PRIMARY_LEVEL, &did);
- if (did.level < 0 || did.id < 0) {
- tsdbUnlockRepo(pTsdb);
- return TSDB_CODE_FAILED;
- }
- tsdbGetSmaDir(REPO_ID(pTsdb), smaType, rname);
-
- if (tfsMkdirRecurAt(REPO_TFS(pTsdb), rname, did) != TSDB_CODE_SUCCESS) {
- tsdbUnlockRepo(pTsdb);
- return TSDB_CODE_FAILED;
- }
-
- if (tsdbInitSmaEnv(pTsdb, smaType, rname, did, &pEnv) != TSDB_CODE_SUCCESS) {
- tsdbUnlockRepo(pTsdb);
- return TSDB_CODE_FAILED;
- }
-
- (smaType == TSDB_SMA_TYPE_TIME_RANGE) ? atomic_store_ptr(&REPO_TSMA_ENV(pTsdb), pEnv)
- : atomic_store_ptr(&REPO_RSMA_ENV(pTsdb), pEnv);
- }
- tsdbUnlockRepo(pTsdb);
-
- return TSDB_CODE_SUCCESS;
-};
-
-static int32_t tsdbSetExpiredWindow(STsdb *pTsdb, SHashObj *pItemsHash, int64_t indexUid, int64_t winSKey,
- int64_t version) {
- SSmaStatItem *pItem = taosHashGet(pItemsHash, &indexUid, sizeof(indexUid));
- if (!pItem) {
- // TODO: use TSDB_SMA_STAT_EXPIRED and update by stream computing later
- pItem = tsdbNewSmaStatItem(TSDB_SMA_STAT_OK); // TODO use the real state
- if (!pItem) {
- // Response to stream computing: OOM
- // For query, if the indexUid not found, the TSDB should tell query module to query raw TS data.
- return TSDB_CODE_FAILED;
- }
-
- // cache smaMeta
- STSma *pSma = metaGetSmaInfoByIndex(REPO_META(pTsdb), indexUid, true);
- if (!pSma) {
- terrno = TSDB_CODE_TDB_NO_SMA_INDEX_IN_META;
- taosHashCleanup(pItem->expiredWindows);
- taosMemoryFree(pItem);
- tsdbWarn("vgId:%d update expired window failed for smaIndex %" PRIi64 " since %s", REPO_ID(pTsdb), indexUid,
- tstrerror(terrno));
- return TSDB_CODE_FAILED;
- }
- pItem->pSma = pSma;
-
- if (taosHashPut(pItemsHash, &indexUid, sizeof(indexUid), &pItem, sizeof(pItem)) != 0) {
- // If error occurs during put smaStatItem, free the resources of pItem
- taosHashCleanup(pItem->expiredWindows);
- taosMemoryFree(pItem);
- return TSDB_CODE_FAILED;
- }
- } else if (!(pItem = *(SSmaStatItem **)pItem)) {
- terrno = TSDB_CODE_INVALID_PTR;
- return TSDB_CODE_FAILED;
- }
-
- if (taosHashPut(pItem->expiredWindows, &winSKey, sizeof(TSKEY), &version, sizeof(version)) != 0) {
- // If error occurs during taosHashPut expired windows, remove the smaIndex from pTsdb->pSmaStat, thus TSDB would
- // tell query module to query raw TS data.
- // N.B.
- // 1) It is assumed to be extemely little probability event of fail to taosHashPut.
- // 2) This would solve the inconsistency to some extent, but not completely, unless we record all expired
- // windows failed to put into hash table.
- taosHashCleanup(pItem->expiredWindows);
- taosMemoryFreeClear(pItem->pSma);
- taosHashRemove(pItemsHash, &indexUid, sizeof(indexUid));
- tsdbWarn("vgId:%d smaIndex %" PRIi64 ", put skey %" PRIi64 " to expire window fail", REPO_ID(pTsdb), indexUid,
- winSKey);
- return TSDB_CODE_FAILED;
- }
-
- tsdbDebug("vgId:%d smaIndex %" PRIi64 ", put skey %" PRIi64 " to expire window succeed", REPO_ID(pTsdb), indexUid,
- winSKey);
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Update expired window according to msg from stream computing module.
- *
- * @param pTsdb
- * @param msg SSubmitReq
- * @return int32_t
- */
-int32_t tsdbUpdateExpiredWindowImpl(STsdb *pTsdb, SSubmitReq *pMsg, int64_t version) {
- // no time-range-sma, just return success
- if (atomic_load_16(&REPO_TSMA_NUM(pTsdb)) <= 0) {
- tsdbTrace("vgId:%d not update expire window since no tSma", REPO_ID(pTsdb));
- return TSDB_CODE_SUCCESS;
- }
-
- if (!REPO_META(pTsdb)) {
- terrno = TSDB_CODE_INVALID_PTR;
- return TSDB_CODE_FAILED;
- }
-
- if (tsdbCheckAndInitSmaEnv(pTsdb, TSDB_SMA_TYPE_TIME_RANGE) != TSDB_CODE_SUCCESS) {
- terrno = TSDB_CODE_TDB_INIT_FAILED;
- return TSDB_CODE_FAILED;
- }
-
- // Firstly, assume that tSma can only be created on super table/normal table.
- // getActiveTimeWindow
-
- SSmaEnv *pEnv = REPO_TSMA_ENV(pTsdb);
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SHashObj *pItemsHash = SMA_ENV_STAT_ITEMS(pEnv);
-
- TASSERT(pEnv && pStat && pItemsHash);
-
- // basic procedure
- // TODO: optimization
- tsdbRefSmaStat(pTsdb, pStat);
-
- SSubmitMsgIter msgIter = {0};
- SSubmitBlk *pBlock = NULL;
- SInterval interval = {0};
- TSKEY lastWinSKey = INT64_MIN;
-
- if (tInitSubmitMsgIter(pMsg, &msgIter) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_FAILED;
- }
-
- while (true) {
- tGetSubmitMsgNext(&msgIter, &pBlock);
- if (!pBlock) break;
-
- STSmaWrapper *pSW = NULL;
- STSma *pTSma = NULL;
-
- SSubmitBlkIter blkIter = {0};
- if (tInitSubmitBlkIter(&msgIter, pBlock, &blkIter) != TSDB_CODE_SUCCESS) {
- pSW = tdFreeTSmaWrapper(pSW);
- break;
- }
-
- while (true) {
- STSRow *row = tGetSubmitBlkNext(&blkIter);
- if (!row) {
- tdFreeTSmaWrapper(pSW);
- break;
- }
- if (!pSW || (pTSma->tableUid != pBlock->suid)) {
- if (pSW) {
- pSW = tdFreeTSmaWrapper(pSW);
- }
- if (!(pSW = metaGetSmaInfoByTable(REPO_META(pTsdb), pBlock->suid))) {
- break;
- }
- if ((pSW->number) <= 0 || !pSW->tSma) {
- pSW = tdFreeTSmaWrapper(pSW);
- break;
- }
-
- pTSma = pSW->tSma;
-
- interval.interval = pTSma->interval;
- interval.intervalUnit = pTSma->intervalUnit;
- interval.offset = pTSma->offset;
- interval.precision = REPO_CFG(pTsdb)->precision;
- interval.sliding = pTSma->sliding;
- interval.slidingUnit = pTSma->slidingUnit;
- }
-
- TSKEY winSKey = taosTimeTruncate(TD_ROW_KEY(row), &interval, interval.precision);
-
- if (lastWinSKey != winSKey) {
- lastWinSKey = winSKey;
- tsdbSetExpiredWindow(pTsdb, pItemsHash, pTSma->indexUid, winSKey, version);
- } else {
- tsdbDebug("vgId:%d smaIndex %" PRIi64 ", put skey %" PRIi64 " to expire window ignore as duplicated",
- REPO_ID(pTsdb), pTSma->indexUid, winSKey);
- }
- }
- }
-
- tsdbUnRefSmaStat(pTsdb, pStat);
-
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief When sma data received from stream computing, make the relative expired window valid.
- *
- * @param pTsdb
- * @param pStat
- * @param indexUid
- * @param skey
- * @return int32_t
- */
-static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, SSmaStat *pStat, int64_t indexUid, TSKEY skey) {
- SSmaStatItem *pItem = NULL;
-
- tsdbRefSmaStat(pTsdb, pStat);
-
- if (pStat && SMA_STAT_ITEMS(pStat)) {
- pItem = taosHashGet(SMA_STAT_ITEMS(pStat), &indexUid, sizeof(indexUid));
- }
- if ((pItem) && ((pItem = *(SSmaStatItem **)pItem))) {
- // pItem resides in hash buffer all the time unless drop sma index
- // TODO: multithread protect
- if (taosHashRemove(pItem->expiredWindows, &skey, sizeof(TSKEY)) != 0) {
- // error handling
- tsdbUnRefSmaStat(pTsdb, pStat);
- tsdbWarn("vgId:%d remove skey %" PRIi64 " from expired window for sma index %" PRIi64 " fail", REPO_ID(pTsdb),
- skey, indexUid);
- return TSDB_CODE_FAILED;
- }
- tsdbDebug("vgId:%d remove skey %" PRIi64 " from expired window for sma index %" PRIi64 " succeed", REPO_ID(pTsdb),
- skey, indexUid);
- // TODO: use a standalone interface to received state upate notification from stream computing module.
- /**
- * @brief state
- * - When SMA env init in TSDB, its status is TSDB_SMA_STAT_OK.
- * - In startup phase of stream computing module, it should notify the SMA env in TSDB to expired if needed(e.g.
- * when batch data caculation not finised)
- * - When TSDB_SMA_STAT_OK, the stream computing module should also notify that to the SMA env in TSDB.
- */
- pItem->state = TSDB_SMA_STAT_OK;
- } else {
- // error handling
- tsdbUnRefSmaStat(pTsdb, pStat);
- tsdbWarn("vgId:%d expired window %" PRIi64 " not exists for sma index %" PRIi64, REPO_ID(pTsdb), skey, indexUid);
- return TSDB_CODE_FAILED;
- }
-
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Judge the tSma storage level
- *
- * @param interval
- * @param intervalUnit
- * @return int32_t
- */
-static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit) {
- // TODO: configurable for SMA_STORAGE_SPLIT_HOURS?
- switch (intervalUnit) {
- case TIME_UNIT_HOUR:
- if (interval < SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- case TIME_UNIT_MINUTE:
- if (interval < 60 * SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- case TIME_UNIT_SECOND:
- if (interval < 3600 * SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- case TIME_UNIT_MILLISECOND:
- if (interval < 3600 * 1e3 * SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- case TIME_UNIT_MICROSECOND:
- if (interval < 3600 * 1e6 * SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- case TIME_UNIT_NANOSECOND:
- if (interval < 3600 * 1e9 * SMA_STORAGE_SPLIT_HOURS) {
- return SMA_STORAGE_LEVEL_DFILESET;
- }
- break;
- default:
- break;
- }
- return SMA_STORAGE_LEVEL_TSDB;
-}
-
-/**
- * @brief Insert TSma data blocks to DB File build by B+Tree
- *
- * @param pSmaH
- * @param smaKey tableUid-colId-skeyOfWindow(8-2-8)
- * @param keyLen
- * @param pData
- * @param dataLen
- * @return int32_t
- */
-static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, int32_t keyLen, void *pData, int32_t dataLen,
- TXN *txn) {
- SDBFile *pDBFile = &pSmaH->dFile;
-
- // TODO: insert tsma data blocks into B+Tree(TTB)
- if (tsdbSaveSmaToDB(pDBFile, smaKey, keyLen, pData, dataLen, txn) != 0) {
- tsdbWarn("vgId:%d insert tsma data blocks into %s: smaKey %" PRIx64 "-%" PRIx64 ", dataLen %" PRIu32 " fail",
- REPO_ID(pSmaH->pTsdb), pDBFile->path, *(int64_t *)smaKey, *(int64_t *)POINTER_SHIFT(smaKey, 8), dataLen);
- return TSDB_CODE_FAILED;
- }
- tsdbDebug("vgId:%d insert tsma data blocks into %s: smaKey %" PRIx64 "-%" PRIx64 ", dataLen %" PRIu32 " succeed",
- REPO_ID(pSmaH->pTsdb), pDBFile->path, *(int64_t *)smaKey, *(int64_t *)POINTER_SHIFT(smaKey, 8), dataLen);
-
-#ifdef _TEST_SMA_PRINT_DEBUG_LOG_
- uint32_t valueSize = 0;
- void *data = tsdbGetSmaDataByKey(pDBFile, smaKey, keyLen, &valueSize);
- ASSERT(data != NULL);
- for (uint32_t v = 0; v < valueSize; v += 8) {
- tsdbWarn("vgId:%d insert sma data val[%d] %" PRIi64, REPO_ID(pSmaH->pTsdb), v, *(int64_t *)POINTER_SHIFT(data, v));
- }
-#endif
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Approximate value for week/month/year.
- *
- * @param interval
- * @param intervalUnit
- * @param precision
- * @param adjusted Interval already adjusted according to DB precision
- * @return int64_t
- */
-static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit, int8_t precision, bool adjusted) {
- if (adjusted) {
- return interval;
- }
-
- switch (intervalUnit) {
- case TIME_UNIT_YEAR: // approximate value
- interval *= 365 * 86400 * 1e3;
- break;
- case TIME_UNIT_MONTH: // approximate value
- interval *= 30 * 86400 * 1e3;
- break;
- case TIME_UNIT_WEEK: // approximate value
- interval *= 7 * 86400 * 1e3;
- break;
- case TIME_UNIT_DAY: // the interval for tSma calculation must <= day
- interval *= 86400 * 1e3;
- break;
- case TIME_UNIT_HOUR:
- interval *= 3600 * 1e3;
- break;
- case TIME_UNIT_MINUTE:
- interval *= 60 * 1e3;
- break;
- case TIME_UNIT_SECOND:
- interval *= 1e3;
- break;
- default:
- break;
- }
-
- switch (precision) {
- case TSDB_TIME_PRECISION_MILLI:
- if (TIME_UNIT_MICROSECOND == intervalUnit) { // us
- return interval / 1e3;
- } else if (TIME_UNIT_NANOSECOND == intervalUnit) { // nano second
- return interval / 1e6;
- } else { // ms
- return interval;
- }
- break;
- case TSDB_TIME_PRECISION_MICRO:
- if (TIME_UNIT_MICROSECOND == intervalUnit) { // us
- return interval;
- } else if (TIME_UNIT_NANOSECOND == intervalUnit) { // ns
- return interval / 1e3;
- } else { // ms
- return interval * 1e3;
- }
- break;
- case TSDB_TIME_PRECISION_NANO:
- if (TIME_UNIT_MICROSECOND == intervalUnit) { // us
- return interval * 1e3;
- } else if (TIME_UNIT_NANOSECOND == intervalUnit) { // ns
- return interval;
- } else { // ms
- return interval * 1e6;
- }
- break;
- default: // ms
- if (TIME_UNIT_MICROSECOND == intervalUnit) { // us
- return interval / 1e3;
- } else if (TIME_UNIT_NANOSECOND == intervalUnit) { // ns
- return interval / 1e6;
- } else { // ms
- return interval;
- }
- break;
- }
- return interval;
-}
-
-static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, const SArray *pDataBlocks, int64_t interval,
- int8_t intervalUnit) {
- pSmaH->pTsdb = pTsdb;
- pSmaH->interval = tsdbGetIntervalByPrecision(interval, intervalUnit, REPO_CFG(pTsdb)->precision, true);
- pSmaH->pDataBlocks = pDataBlocks;
- pSmaH->dFile.fid = TSDB_IVLD_FID;
- return TSDB_CODE_SUCCESS;
-}
-
-static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH) {
- if (pSmaH) {
- tsdbCloseDBF(&pSmaH->dFile);
- }
-}
-
-static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, int64_t indexUid, int32_t fid) {
- STsdb *pTsdb = pSmaH->pTsdb;
- ASSERT(!pSmaH->dFile.path && !pSmaH->dFile.pDB);
-
- pSmaH->dFile.fid = fid;
- char tSmaFile[TSDB_FILENAME_LEN] = {0};
- snprintf(tSmaFile, TSDB_FILENAME_LEN, "%" PRIi64 "%sv%df%d.tsma", indexUid, TD_DIRSEP, REPO_ID(pTsdb), fid);
- pSmaH->dFile.path = strdup(tSmaFile);
-
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief
- *
- * @param pTsdb
- * @param interval Interval calculated by DB's precision
- * @param storageLevel
- * @return int32_t
- */
-static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel) {
- STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pTsdb);
- int32_t daysPerFile = pCfg->days;
-
- if (storageLevel == SMA_STORAGE_LEVEL_TSDB) {
- int32_t days = SMA_STORAGE_TSDB_TIMES * (interval / tsTickPerMin[pCfg->precision]);
- daysPerFile = days > SMA_STORAGE_TSDB_DAYS ? days : SMA_STORAGE_TSDB_DAYS;
- }
-
- return daysPerFile;
-}
-
-static int tsdbSmaBeginCommit(SSmaEnv *pEnv) {
- TXN *pTxn = &pEnv->txn;
- // start a new txn
- tdbTxnOpen(pTxn, 0, poolMalloc, poolFree, pEnv->pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
- if (tdbBegin(pEnv->dbEnv, pTxn) != 0) {
- tsdbWarn("tsdbSma tdb begin commit fail");
- return -1;
- }
- return 0;
-}
-
-static int tsdbSmaEndCommit(SSmaEnv *pEnv) {
- TXN *pTxn = &pEnv->txn;
-
- // Commit current txn
- if (tdbCommit(pEnv->dbEnv, pTxn) != 0) {
- tsdbWarn("tsdbSma tdb end commit fail");
- return -1;
- }
- tdbTxnClose(pTxn);
- clearPool(pEnv->pPool);
- return 0;
-}
-
-/**
- * @brief Insert/Update Time-range-wise SMA data.
- * - If interval < SMA_STORAGE_SPLIT_HOURS(e.g. 24), save the SMA data as a part of DFileSet to e.g.
- * v3f1900.tsma.${sma_index_name}. The days is the same with that for TS data files.
- * - If interval >= SMA_STORAGE_SPLIT_HOURS, save the SMA data to e.g. vnode3/tsma/v3f632.tsma.${sma_index_name}. The
- * days is 30 times of the interval, and the minimum days is SMA_STORAGE_TSDB_DAYS(30d).
- * - The destination file of one data block for some interval is determined by its start TS key.
- *
- * @param pTsdb
- * @param msg
- * @return int32_t
- */
-static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, int64_t indexUid, const char *msg) {
- STsdbCfg *pCfg = REPO_CFG(pTsdb);
- const SArray *pDataBlocks = (const SArray *)msg;
-
- // TODO: destroy SSDataBlocks(msg)
-
- // For super table aggregation, the sma data is stored in vgroup calculated from the hash value of stable name. Thus
- // the sma data would arrive ahead of the update-expired-window msg.
- if (tsdbCheckAndInitSmaEnv(pTsdb, TSDB_SMA_TYPE_TIME_RANGE) != TSDB_CODE_SUCCESS) {
- terrno = TSDB_CODE_TDB_INIT_FAILED;
- return TSDB_CODE_FAILED;
- }
-
- if (!pDataBlocks) {
- terrno = TSDB_CODE_INVALID_PTR;
- tsdbWarn("vgId:%d insert tSma data failed since pDataBlocks is NULL", REPO_ID(pTsdb));
- return terrno;
- }
-
- if (taosArrayGetSize(pDataBlocks) <= 0) {
- terrno = TSDB_CODE_INVALID_PARA;
- tsdbWarn("vgId:%d insert tSma data failed since pDataBlocks is empty", REPO_ID(pTsdb));
- return TSDB_CODE_FAILED;
- }
-
- SSmaEnv *pEnv = REPO_TSMA_ENV(pTsdb);
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SSmaStatItem *pItem = NULL;
-
- tsdbRefSmaStat(pTsdb, pStat);
-
- if (pStat && SMA_STAT_ITEMS(pStat)) {
- pItem = taosHashGet(SMA_STAT_ITEMS(pStat), &indexUid, sizeof(indexUid));
- }
-
- if (!pItem || !(pItem = *(SSmaStatItem **)pItem) || tsdbSmaStatIsDropped(pItem)) {
- terrno = TSDB_CODE_TDB_INVALID_SMA_STAT;
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_FAILED;
- }
-
- STSma *pSma = pItem->pSma;
- STSmaWriteH tSmaH = {0};
-
- if (tsdbInitTSmaWriteH(&tSmaH, pTsdb, pDataBlocks, pSma->interval, pSma->intervalUnit) != 0) {
- return TSDB_CODE_FAILED;
- }
-
- char rPath[TSDB_FILENAME_LEN] = {0};
- char aPath[TSDB_FILENAME_LEN] = {0};
- snprintf(rPath, TSDB_FILENAME_LEN, "%s%s%" PRIi64, SMA_ENV_PATH(pEnv), TD_DIRSEP, indexUid);
- tfsAbsoluteName(REPO_TFS(pTsdb), SMA_ENV_DID(pEnv), rPath, aPath);
- if (!taosCheckExistFile(aPath)) {
- if (tfsMkdirRecurAt(REPO_TFS(pTsdb), rPath, SMA_ENV_DID(pEnv)) != TSDB_CODE_SUCCESS) {
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_FAILED;
- }
- }
-
- // Step 1: Judge the storage level and days
- int32_t storageLevel = tsdbGetSmaStorageLevel(pSma->interval, pSma->intervalUnit);
- int32_t daysPerFile = tsdbGetTSmaDays(pTsdb, tSmaH.interval, storageLevel);
-
- char smaKey[SMA_KEY_LEN] = {0}; // key: skey + groupId
- char dataBuf[512] = {0}; // val: aggr data // TODO: handle 512 buffer?
- void *pDataBuf = NULL;
- int32_t sz = taosArrayGetSize(pDataBlocks);
- for (int32_t i = 0; i < sz; ++i) {
- SSDataBlock *pDataBlock = taosArrayGet(pDataBlocks, i);
- int32_t colNum = pDataBlock->info.numOfCols;
- int32_t rows = pDataBlock->info.rows;
- int32_t rowSize = pDataBlock->info.rowSize;
- int64_t groupId = pDataBlock->info.groupId;
- for (int32_t j = 0; j < rows; ++j) {
- printf("|");
- TSKEY skey = TSKEY_INITIAL_VAL; // the start key of TS window by interval
- void *pSmaKey = &smaKey;
- bool isStartKey = false;
-
- int32_t tlen = 0; // reset the len
- pDataBuf = &dataBuf; // reset the buf
- for (int32_t k = 0; k < colNum; ++k) {
- SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
- void *var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes);
- switch (pColInfoData->info.type) {
- case TSDB_DATA_TYPE_TIMESTAMP:
- if (!isStartKey) {
- isStartKey = true;
- skey = *(TSKEY *)var;
- printf("= skey %" PRIi64 " groupId = %" PRIi64 "|", skey, groupId);
- tsdbEncodeTSmaKey(groupId, skey, &pSmaKey);
- } else {
- printf(" %" PRIi64 " |", *(int64_t *)var);
- tlen += taosEncodeFixedI64(&pDataBuf, *(int64_t *)var);
- break;
- }
- break;
- case TSDB_DATA_TYPE_BOOL:
- case TSDB_DATA_TYPE_UTINYINT:
- printf(" %15d |", *(uint8_t *)var);
- tlen += taosEncodeFixedU8(&pDataBuf, *(uint8_t *)var);
- break;
- case TSDB_DATA_TYPE_TINYINT:
- printf(" %15d |", *(int8_t *)var);
- tlen += taosEncodeFixedI8(&pDataBuf, *(int8_t *)var);
- break;
- case TSDB_DATA_TYPE_SMALLINT:
- printf(" %15d |", *(int16_t *)var);
- tlen += taosEncodeFixedI16(&pDataBuf, *(int16_t *)var);
- break;
- case TSDB_DATA_TYPE_USMALLINT:
- printf(" %15d |", *(uint16_t *)var);
- tlen += taosEncodeFixedU16(&pDataBuf, *(uint16_t *)var);
- break;
- case TSDB_DATA_TYPE_INT:
- printf(" %15d |", *(int32_t *)var);
- tlen += taosEncodeFixedI32(&pDataBuf, *(int32_t *)var);
- break;
- case TSDB_DATA_TYPE_FLOAT:
- printf(" %15f |", *(float *)var);
- tlen += taosEncodeBinary(&pDataBuf, var, sizeof(float));
- break;
- case TSDB_DATA_TYPE_UINT:
- printf(" %15u |", *(uint32_t *)var);
- tlen += taosEncodeFixedU32(&pDataBuf, *(uint32_t *)var);
- break;
- case TSDB_DATA_TYPE_BIGINT:
- printf(" %15ld |", *(int64_t *)var);
- tlen += taosEncodeFixedI64(&pDataBuf, *(int64_t *)var);
- break;
- case TSDB_DATA_TYPE_DOUBLE:
- printf(" %15lf |", *(double *)var);
- tlen += taosEncodeBinary(&pDataBuf, var, sizeof(double));
- case TSDB_DATA_TYPE_UBIGINT:
- printf(" %15lu |", *(uint64_t *)var);
- tlen += taosEncodeFixedU64(&pDataBuf, *(uint64_t *)var);
- break;
- case TSDB_DATA_TYPE_NCHAR: {
- char tmpChar[100] = {0};
- strncpy(tmpChar, varDataVal(var), varDataLen(var));
- printf(" %s |", tmpChar);
- tlen += taosEncodeBinary(&pDataBuf, varDataVal(var), varDataLen(var));
- break;
- }
- case TSDB_DATA_TYPE_VARCHAR: { // TSDB_DATA_TYPE_BINARY
- char tmpChar[100] = {0};
- strncpy(tmpChar, varDataVal(var), varDataLen(var));
- printf(" %s |", tmpChar);
- tlen += taosEncodeBinary(&pDataBuf, varDataVal(var), varDataLen(var));
- break;
- }
- case TSDB_DATA_TYPE_VARBINARY:
- // TODO: add binary/varbinary
- TASSERT(0);
- default:
- printf("the column type %" PRIi16 " is undefined\n", pColInfoData->info.type);
- TASSERT(0);
- break;
- }
- }
- // if ((tlen > 0) && (skey != TSKEY_INITIAL_VAL)) {
- if (tlen > 0) {
- int32_t fid = (int32_t)(TSDB_KEY_FID(skey, daysPerFile, pCfg->precision));
-
- // Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index
- // file
- // - Set and open the DFile or the B+Tree file
- // TODO: tsdbStartTSmaCommit();
- if (fid != tSmaH.dFile.fid) {
- if (tSmaH.dFile.fid != TSDB_IVLD_FID) {
- tsdbSmaEndCommit(pEnv);
- tsdbCloseDBF(&tSmaH.dFile);
- }
- tsdbSetTSmaDataFile(&tSmaH, indexUid, fid);
- if (tsdbOpenDBF(pEnv->dbEnv, &tSmaH.dFile) != 0) {
- tsdbWarn("vgId:%d open DB file %s failed since %s", REPO_ID(pTsdb),
- tSmaH.dFile.path ? tSmaH.dFile.path : "path is NULL", tstrerror(terrno));
- tsdbDestroyTSmaWriteH(&tSmaH);
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_FAILED;
- }
- tsdbSmaBeginCommit(pEnv);
- }
-
- if (tsdbInsertTSmaBlocks(&tSmaH, &smaKey, SMA_KEY_LEN, dataBuf, tlen, &pEnv->txn) != 0) {
- tsdbWarn("vgId:%d insert tsma data blocks fail for index %" PRIi64 ", skey %" PRIi64 ", groupId %" PRIi64
- " since %s",
- REPO_ID(pTsdb), indexUid, skey, groupId, tstrerror(terrno));
- tsdbSmaEndCommit(pEnv);
- tsdbDestroyTSmaWriteH(&tSmaH);
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_FAILED;
- }
- tsdbDebug("vgId:%d insert tsma data blocks success for index %" PRIi64 ", skey %" PRIi64 ", groupId %" PRIi64,
- REPO_ID(pTsdb), indexUid, skey, groupId);
- // TODO:tsdbEndTSmaCommit();
-
- // Step 3: reset the SSmaStat
- tsdbResetExpiredWindow(pTsdb, pStat, indexUid, skey);
- } else {
- tsdbWarn("vgId:%d invalid data skey:%" PRIi64 ", tlen %" PRIi32 " during insert tSma data for %" PRIi64,
- REPO_ID(pTsdb), skey, tlen, indexUid);
- }
-
- printf("\n");
- }
- }
- tsdbSmaEndCommit(pEnv); // TODO: not commit for every insert
- tsdbDestroyTSmaWriteH(&tSmaH);
- tsdbUnRefSmaStat(pTsdb, pStat);
-
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Drop tSma data and local cache
- * - insert/query reference
- * @param pTsdb
- * @param msg
- * @return int32_t
- */
-static int32_t tsdbDropTSmaDataImpl(STsdb *pTsdb, int64_t indexUid) {
- SSmaEnv *pEnv = atomic_load_ptr(&REPO_TSMA_ENV(pTsdb));
-
- // clear local cache
- if (pEnv) {
- tsdbDebug("vgId:%d drop tSma local cache for %" PRIi64, REPO_ID(pTsdb), indexUid);
-
- SSmaStatItem *pItem = taosHashGet(SMA_ENV_STAT_ITEMS(pEnv), &indexUid, sizeof(indexUid));
- if ((pItem) || ((pItem = *(SSmaStatItem **)pItem))) {
- if (tsdbSmaStatIsDropped(pItem)) {
- tsdbDebug("vgId:%d tSma stat is already dropped for %" PRIi64, REPO_ID(pTsdb), indexUid);
- return TSDB_CODE_TDB_INVALID_ACTION; // TODO: duplicate drop msg would be intercepted by mnode
- }
-
- tsdbWLockSma(pEnv);
- if (tsdbSmaStatIsDropped(pItem)) {
- tsdbUnLockSma(pEnv);
- tsdbDebug("vgId:%d tSma stat is already dropped for %" PRIi64, REPO_ID(pTsdb), indexUid);
- return TSDB_CODE_TDB_INVALID_ACTION; // TODO: duplicate drop msg would be intercepted by mnode
- }
- tsdbSmaStatSetDropped(pItem);
- tsdbUnLockSma(pEnv);
-
- int32_t nSleep = 0;
- int32_t refVal = INT32_MAX;
- while (true) {
- if ((refVal = T_REF_VAL_GET(SMA_ENV_STAT(pEnv))) <= 0) {
- tsdbDebug("vgId:%d drop index %" PRIi64 " since refVal=%d", REPO_ID(pTsdb), indexUid, refVal);
- break;
- }
- tsdbDebug("vgId:%d wait 1s to drop index %" PRIi64 " since refVal=%d", REPO_ID(pTsdb), indexUid, refVal);
- taosSsleep(1);
- if (++nSleep > SMA_DROP_EXPIRED_TIME) {
- tsdbDebug("vgId:%d drop index %" PRIi64 " after wait %d (refVal=%d)", REPO_ID(pTsdb), indexUid, nSleep,
- refVal);
- break;
- };
- }
-
- tsdbFreeSmaStatItem(pItem);
- tsdbDebug("vgId:%d getTSmaDataImpl failed since no index %" PRIi64 " in local cache", REPO_ID(pTsdb), indexUid);
- }
- }
- // clear sma data files
- // TODO:
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbSetRSmaDataFile(STSmaWriteH *pSmaH, int32_t fid) {
- STsdb *pTsdb = pSmaH->pTsdb;
-
- char tSmaFile[TSDB_FILENAME_LEN] = {0};
- snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.rsma", REPO_ID(pTsdb), fid);
- pSmaH->dFile.path = strdup(tSmaFile);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, const char *msg) {
- STsdbCfg *pCfg = REPO_CFG(pTsdb);
- const SArray *pDataBlocks = (const SArray *)msg;
- SSmaEnv *pEnv = atomic_load_ptr(&REPO_RSMA_ENV(pTsdb));
- int64_t indexUid = SMA_TEST_INDEX_UID;
-
- if (!pEnv) {
- terrno = TSDB_CODE_INVALID_PTR;
- tsdbWarn("vgId:%d insert rSma data failed since pTSmaEnv is NULL", REPO_ID(pTsdb));
- return terrno;
- }
-
- if (!pDataBlocks) {
- terrno = TSDB_CODE_INVALID_PTR;
- tsdbWarn("vgId:%d insert rSma data failed since pDataBlocks is NULL", REPO_ID(pTsdb));
- return terrno;
- }
-
- if (taosArrayGetSize(pDataBlocks) <= 0) {
- terrno = TSDB_CODE_INVALID_PARA;
- tsdbWarn("vgId:%d insert rSma data failed since pDataBlocks is empty", REPO_ID(pTsdb));
- return TSDB_CODE_FAILED;
- }
-
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SSmaStatItem *pItem = NULL;
-
- tsdbRefSmaStat(pTsdb, pStat);
-
- if (pStat && SMA_STAT_ITEMS(pStat)) {
- pItem = taosHashGet(SMA_STAT_ITEMS(pStat), &indexUid, sizeof(indexUid));
- }
-
- if (!pItem || !(pItem = *(SSmaStatItem **)pItem) || tsdbSmaStatIsDropped(pItem)) {
- terrno = TSDB_CODE_TDB_INVALID_SMA_STAT;
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_FAILED;
- }
-
- STSma *pSma = pItem->pSma;
-
- STSmaWriteH tSmaH = {0};
-
- if (tsdbInitTSmaWriteH(&tSmaH, pTsdb, pDataBlocks, pSma->interval, pSma->intervalUnit) != 0) {
- return TSDB_CODE_FAILED;
- }
-
- char rPath[TSDB_FILENAME_LEN] = {0};
- char aPath[TSDB_FILENAME_LEN] = {0};
- snprintf(rPath, TSDB_FILENAME_LEN, "%s%s%" PRIi64, SMA_ENV_PATH(pEnv), TD_DIRSEP, indexUid);
- tfsAbsoluteName(REPO_TFS(pTsdb), SMA_ENV_DID(pEnv), rPath, aPath);
- if (!taosCheckExistFile(aPath)) {
- if (tfsMkdirRecurAt(REPO_TFS(pTsdb), rPath, SMA_ENV_DID(pEnv)) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_FAILED;
- }
- }
-
- // Step 1: Judge the storage level and days
- int32_t storageLevel = tsdbGetSmaStorageLevel(pSma->interval, pSma->intervalUnit);
- int32_t daysPerFile = tsdbGetTSmaDays(pTsdb, tSmaH.interval, storageLevel);
-#if 0
- int32_t fid = (int32_t)(TSDB_KEY_FID(pData->skey, daysPerFile, pCfg->precision));
-
- // Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index file
- // - Set and open the DFile or the B+Tree file
- // TODO: tsdbStartTSmaCommit();
- tsdbSetTSmaDataFile(&tSmaH, pData, indexUid, fid);
- if (tsdbOpenDBF(pTsdb->pTSmaEnv->dbEnv, &tSmaH.dFile) != 0) {
- tsdbWarn("vgId:%d open DB file %s failed since %s", REPO_ID(pTsdb),
- tSmaH.dFile.path ? tSmaH.dFile.path : "path is NULL", tstrerror(terrno));
- tsdbDestroyTSmaWriteH(&tSmaH);
- return TSDB_CODE_FAILED;
- }
-
- if (tsdbInsertTSmaDataSection(&tSmaH, pData) != 0) {
- tsdbWarn("vgId:%d insert tSma data section failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- tsdbDestroyTSmaWriteH(&tSmaH);
- return TSDB_CODE_FAILED;
- }
- // TODO:tsdbEndTSmaCommit();
-
- // Step 3: reset the SSmaStat
- tsdbResetExpiredWindow(pTsdb, SMA_ENV_STAT(pTsdb->pTSmaEnv), pData->indexUid, pData->skey);
-#endif
-
- tsdbDestroyTSmaWriteH(&tSmaH);
- tsdbUnRefSmaStat(pTsdb, pStat);
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief
- *
- * @param pSmaH
- * @param pTsdb
- * @param interval
- * @param intervalUnit
- * @return int32_t
- */
-static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit) {
- pSmaH->pTsdb = pTsdb;
- pSmaH->interval = tsdbGetIntervalByPrecision(interval, intervalUnit, REPO_CFG(pTsdb)->precision, true);
- pSmaH->storageLevel = tsdbGetSmaStorageLevel(interval, intervalUnit);
- pSmaH->days = tsdbGetTSmaDays(pTsdb, pSmaH->interval, pSmaH->storageLevel);
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Init of tSma FS
- *
- * @param pReadH
- * @param indexUid
- * @param skey
- * @return int32_t
- */
-static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, int64_t indexUid, TSKEY skey) {
- STsdb *pTsdb = pSmaH->pTsdb;
-
- int32_t fid = (int32_t)(TSDB_KEY_FID(skey, pSmaH->days, REPO_CFG(pTsdb)->precision));
- char tSmaFile[TSDB_FILENAME_LEN] = {0};
- snprintf(tSmaFile, TSDB_FILENAME_LEN, "%" PRIi64 "%sv%df%d.tsma", indexUid, TD_DIRSEP, REPO_ID(pTsdb), fid);
- pSmaH->dFile.path = strdup(tSmaFile);
- pSmaH->smaFsIter.iter = 0;
- pSmaH->smaFsIter.fid = fid;
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Set and open tSma file if it has key locates in queryWin.
- *
- * @param pReadH
- * @param param
- * @param queryWin
- * @return true
- * @return false
- */
-static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey) {
- SArray *smaFs = pReadH->pTsdb->fs->cstatus->sf;
- int32_t nSmaFs = taosArrayGetSize(smaFs);
-
- tsdbCloseDBF(&pReadH->dFile);
-
-#if 0
- while (pReadH->smaFsIter.iter < nSmaFs) {
- void *pSmaFile = taosArrayGet(smaFs, pReadH->smaFsIter.iter);
- if (pSmaFile) { // match(indexName, queryWindow)
- // TODO: select the file by index_name ...
- pReadH->dFile = pSmaFile;
- ++pReadH->smaFsIter.iter;
- break;
- }
- ++pReadH->smaFsIter.iter;
- }
-
- if (pReadH->pDFile) {
- tsdbDebug("vg%d: smaFile %s matched", REPO_ID(pReadH->pTsdb), "[pSmaFile dir]");
- return true;
- }
-#endif
-
- return false;
-}
-
-/**
- * @brief
- *
- * @param pTsdb Return the data between queryWin and fill the pData.
- * @param pData
- * @param indexUid
- * @param pQuerySKey
- * @param nMaxResult The query invoker should control the nMaxResult need to return to avoid OOM.
- * @return int32_t
- */
-static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, char *pData, int64_t indexUid, TSKEY querySKey, int32_t nMaxResult) {
- SSmaEnv *pEnv = atomic_load_ptr(&REPO_TSMA_ENV(pTsdb));
- SSmaStat *pStat = NULL;
-
- if (!pEnv) {
- terrno = TSDB_CODE_INVALID_PTR;
- tsdbWarn("vgId:%d getTSmaDataImpl failed since pTSmaEnv is NULL", REPO_ID(pTsdb));
- return TSDB_CODE_FAILED;
- }
-
- pStat = SMA_ENV_STAT(pEnv);
-
- tsdbRefSmaStat(pTsdb, pStat);
- SSmaStatItem *pItem = taosHashGet(SMA_ENV_STAT_ITEMS(pEnv), &indexUid, sizeof(indexUid));
- if (!pItem || !(pItem = *(SSmaStatItem **)pItem)) {
- // Normally pItem should not be NULL, mark all windows as expired and notify query module to fetch raw TS data if
- // it's NULL.
- tsdbUnRefSmaStat(pTsdb, pStat);
- terrno = TSDB_CODE_TDB_INVALID_ACTION;
- tsdbDebug("vgId:%d getTSmaDataImpl failed since no index %" PRIi64, REPO_ID(pTsdb), indexUid);
- return TSDB_CODE_FAILED;
- }
-
-#if 0
- int32_t nQueryWin = taosArrayGetSize(pQuerySKey);
- for (int32_t n = 0; n < nQueryWin; ++n) {
- TSKEY skey = taosArrayGet(pQuerySKey, n);
- if (taosHashGet(pItem->expiredWindows, &skey, sizeof(TSKEY))) {
- // TODO: mark this window as expired.
- }
- }
-#endif
-
-#if 1
- int8_t smaStat = 0;
- if (!tsdbSmaStatIsOK(pItem, &smaStat)) { // TODO: multiple check for large scale sma query
- tsdbUnRefSmaStat(pTsdb, pStat);
- terrno = TSDB_CODE_TDB_INVALID_SMA_STAT;
- tsdbWarn("vgId:%d getTSmaDataImpl failed from index %" PRIi64 " since %s %" PRIi8, REPO_ID(pTsdb), indexUid,
- tstrerror(terrno), smaStat);
- return TSDB_CODE_FAILED;
- }
-
- if (taosHashGet(pItem->expiredWindows, &querySKey, sizeof(TSKEY))) {
- // TODO: mark this window as expired.
- tsdbDebug("vgId:%d skey %" PRIi64 " of window exists in expired window for index %" PRIi64, REPO_ID(pTsdb),
- querySKey, indexUid);
- } else {
- tsdbDebug("vgId:%d skey %" PRIi64 " of window not in expired window for index %" PRIi64, REPO_ID(pTsdb), querySKey,
- indexUid);
- }
-
- STSma *pTSma = pItem->pSma;
-#endif
-
- STSmaReadH tReadH = {0};
- tsdbInitTSmaReadH(&tReadH, pTsdb, pTSma->interval, pTSma->intervalUnit);
- tsdbCloseDBF(&tReadH.dFile);
-
- tsdbUnRefSmaStat(pTsdb, pStat);
-
- tsdbInitTSmaFile(&tReadH, indexUid, querySKey);
- if (tsdbOpenDBF(pEnv->dbEnv, &tReadH.dFile) != 0) {
- tsdbWarn("vgId:%d open DBF %s failed since %s", REPO_ID(pTsdb), tReadH.dFile.path, tstrerror(terrno));
- return TSDB_CODE_FAILED;
- }
-
- char smaKey[SMA_KEY_LEN] = {0};
- void *pSmaKey = &smaKey;
- int64_t queryGroupId = 1;
- tsdbEncodeTSmaKey(queryGroupId, querySKey, (void **)&pSmaKey);
-
- tsdbDebug("vgId:%d get sma data from %s: smaKey %" PRIx64 "-%" PRIx64 ", keyLen %d", REPO_ID(pTsdb),
- tReadH.dFile.path, *(int64_t *)smaKey, *(int64_t *)POINTER_SHIFT(smaKey, 8), SMA_KEY_LEN);
-
- void *result = NULL;
- int32_t valueSize = 0;
- if (!(result = tsdbGetSmaDataByKey(&tReadH.dFile, smaKey, SMA_KEY_LEN, &valueSize))) {
- tsdbWarn("vgId:%d get sma data failed from smaIndex %" PRIi64 ", smaKey %" PRIx64 "-%" PRIx64 " since %s",
- REPO_ID(pTsdb), indexUid, *(int64_t *)smaKey, *(int64_t *)POINTER_SHIFT(smaKey, 8), tstrerror(terrno));
- tsdbCloseDBF(&tReadH.dFile);
- return TSDB_CODE_FAILED;
- }
-
-#ifdef _TEST_SMA_PRINT_DEBUG_LOG_
- for (uint32_t v = 0; v < valueSize; v += 8) {
- tsdbWarn("vgId:%d get sma data v[%d]=%" PRIi64, REPO_ID(pTsdb), v, *(int64_t *)POINTER_SHIFT(result, v));
- }
-#endif
- taosMemoryFreeClear(result); // TODO: fill the result to output
-
-#if 0
- int32_t nResult = 0;
- int64_t lastKey = 0;
-
- while (true) {
- if (nResult >= nMaxResult) {
- break;
- }
-
- // set and open the file according to the STSma param
- if (tsdbSetAndOpenTSmaFile(&tReadH, queryWin)) {
- char bTree[100] = "\0";
- while (strncmp(bTree, "has more nodes", 100) == 0) {
- if (nResult >= nMaxResult) {
- break;
- }
- // tsdbGetDataFromBTree(bTree, queryWin, lastKey)
- // fill the pData
- ++nResult;
- }
- }
- }
-#endif
- // read data from file and fill the result
- tsdbCloseDBF(&tReadH.dFile);
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t tsdbCreateTSma(STsdb *pTsdb, char *pMsg) {
- SSmaCfg vCreateSmaReq = {0};
- if (!tDeserializeSVCreateTSmaReq(pMsg, &vCreateSmaReq)) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- tsdbWarn("vgId:%d tsma create msg received but deserialize failed since %s", REPO_ID(pTsdb), terrstr(terrno));
- return -1;
- }
-
- tsdbDebug("vgId:%d tsma create msg %s:%" PRIi64 " for table %" PRIi64 " received", REPO_ID(pTsdb),
- vCreateSmaReq.tSma.indexName, vCreateSmaReq.tSma.indexUid, vCreateSmaReq.tSma.tableUid);
-
- // record current timezone of server side
- vCreateSmaReq.tSma.timezoneInt = tsTimezone;
-
- if (metaCreateTSma(REPO_META(pTsdb), &vCreateSmaReq) < 0) {
- // TODO: handle error
- tsdbWarn("vgId:%d tsma %s:%" PRIi64 " create failed for table %" PRIi64 " since %s", REPO_ID(pTsdb),
- vCreateSmaReq.tSma.indexName, vCreateSmaReq.tSma.indexUid, vCreateSmaReq.tSma.tableUid, terrstr(terrno));
- tdDestroyTSma(&vCreateSmaReq.tSma);
- return -1;
- }
-
- tsdbTSmaAdd(pTsdb, 1);
-
- tdDestroyTSma(&vCreateSmaReq.tSma);
- // TODO: return directly or go on follow steps?
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t tsdbDropTSma(STsdb *pTsdb, char *pMsg) {
- SVDropTSmaReq vDropSmaReq = {0};
- if (!tDeserializeSVDropTSmaReq(pMsg, &vDropSmaReq)) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return -1;
- }
-
- // TODO: send msg to stream computing to drop tSma
- // if ((send msg to stream computing) < 0) {
- // tdDestroyTSma(&vCreateSmaReq);
- // return -1;
- // }
- //
-
- if (metaDropTSma(REPO_META(pTsdb), vDropSmaReq.indexUid) < 0) {
- // TODO: handle error
- return -1;
- }
-
- if (tsdbDropTSmaData(pTsdb, vDropSmaReq.indexUid) < 0) {
- // TODO: handle error
- return -1;
- }
-
- tsdbTSmaSub(pTsdb, 1);
-
- // TODO: return directly or go on follow steps?
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Check and init qTaskInfo_t, only applicable to stable with SRSmaParam.
- *
- * @param pTsdb
- * @param pMeta
- * @param pReq
- * @return int32_t
- */
-int32_t tsdbRegisterRSma(STsdb *pTsdb, SMeta *pMeta, SVCreateStbReq *pReq, SMsgCb *pMsgCb) {
- if (!pReq->rollup) {
- tsdbDebug("vgId:%d return directly since no rollup for stable %s %" PRIi64, REPO_ID(pTsdb), pReq->name, pReq->suid);
- return TSDB_CODE_SUCCESS;
- }
-
- SRSmaParam *param = &pReq->pRSmaParam;
-
- if ((param->qmsg1Len == 0) && (param->qmsg2Len == 0)) {
- tsdbWarn("vgId:%d no qmsg1/qmsg2 for rollup stable %s %" PRIi64, REPO_ID(pTsdb), pReq->name, pReq->suid);
- return TSDB_CODE_SUCCESS;
- }
-
- if (tsdbCheckAndInitSmaEnv(pTsdb, TSDB_SMA_TYPE_ROLLUP) != TSDB_CODE_SUCCESS) {
- terrno = TSDB_CODE_TDB_INIT_FAILED;
- return TSDB_CODE_FAILED;
- }
-
- SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SRSmaInfo *pRSmaInfo = NULL;
-
- pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), &pReq->suid, sizeof(tb_uid_t));
- if (pRSmaInfo) {
- tsdbWarn("vgId:%d rsma info already exists for stb: %s, %" PRIi64, REPO_ID(pTsdb), pReq->name, pReq->suid);
- return TSDB_CODE_SUCCESS;
- }
-
- pRSmaInfo = (SRSmaInfo *)taosMemoryCalloc(1, sizeof(SRSmaInfo));
- if (!pRSmaInfo) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
-
- STqReadHandle *pReadHandle = tqInitSubmitMsgScanner(pMeta);
- if (!pReadHandle) {
- taosMemoryFree(pRSmaInfo);
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
-
- SReadHandle handle = {
- .reader = pReadHandle,
- .meta = pMeta,
- .pMsgCb = pMsgCb,
- };
-
- if (param->qmsg1) {
- pRSmaInfo->taskInfo[0] = qCreateStreamExecTaskInfo(param->qmsg1, &handle);
- if (!pRSmaInfo->taskInfo[0]) {
- taosMemoryFree(pRSmaInfo);
- taosMemoryFree(pReadHandle);
- return TSDB_CODE_FAILED;
- }
- }
-
- if (param->qmsg2) {
- pRSmaInfo->taskInfo[1] = qCreateStreamExecTaskInfo(param->qmsg2, &handle);
- if (!pRSmaInfo->taskInfo[1]) {
- taosMemoryFree(pRSmaInfo);
- taosMemoryFree(pReadHandle);
- return TSDB_CODE_FAILED;
- }
- }
-
- if (taosHashPut(SMA_STAT_INFO_HASH(pStat), &pReq->suid, sizeof(tb_uid_t), &pRSmaInfo, sizeof(pRSmaInfo)) !=
- TSDB_CODE_SUCCESS) {
- return TSDB_CODE_FAILED;
- } else {
- tsdbDebug("vgId:%d register rsma info succeed for suid:%" PRIi64, REPO_ID(pTsdb), pReq->suid);
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief store suid/[uids], prefer to use array and then hash
- *
- * @param pStore
- * @param suid
- * @param uid
- * @return int32_t
- */
-static int32_t tsdbUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid) {
- // prefer to store suid/uids in array
- if ((suid == pStore->suid) || (pStore->suid == 0)) {
- if (pStore->suid == 0) {
- pStore->suid = suid;
- }
- if (uid) {
- if (!pStore->tbUids) {
- if (!(pStore->tbUids = taosArrayInit(1, sizeof(tb_uid_t)))) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- }
- if (!taosArrayPush(pStore->tbUids, uid)) {
- return TSDB_CODE_FAILED;
- }
- }
- } else {
- // store other suid/uids in hash when multiple stable/table included in 1 batch of request
- if (!pStore->uidHash) {
- pStore->uidHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
- if (!pStore->uidHash) {
- return TSDB_CODE_FAILED;
- }
- }
- if (uid) {
- SArray *uidArray = taosHashGet(pStore->uidHash, &suid, sizeof(tb_uid_t));
- if (uidArray && ((uidArray = *(SArray **)uidArray))) {
- taosArrayPush(uidArray, uid);
- } else {
- SArray *pUidArray = taosArrayInit(1, sizeof(tb_uid_t));
- if (!pUidArray) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- if (!taosArrayPush(pUidArray, uid)) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), &pUidArray, sizeof(pUidArray)) != 0) {
- return TSDB_CODE_FAILED;
- }
- }
- } else {
- if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), NULL, 0) != 0) {
- return TSDB_CODE_FAILED;
- }
- }
- }
- return TSDB_CODE_SUCCESS;
-}
-
-void tsdbUidStoreDestory(STbUidStore *pStore) {
- if (pStore) {
- if (pStore->uidHash) {
- if (pStore->tbUids) {
- // When pStore->tbUids not NULL, the pStore->uidHash has k/v; otherwise pStore->uidHash only has keys.
- void *pIter = taosHashIterate(pStore->uidHash, NULL);
- while (pIter) {
- SArray *arr = *(SArray **)pIter;
- taosArrayDestroy(arr);
- pIter = taosHashIterate(pStore->uidHash, pIter);
- }
- }
- taosHashCleanup(pStore->uidHash);
- }
- taosArrayDestroy(pStore->tbUids);
- }
-}
-
-void *tsdbUidStoreFree(STbUidStore *pStore) {
- if (pStore) {
- tsdbUidStoreDestory(pStore);
- taosMemoryFree(pStore);
- }
- return NULL;
-}
-
-/**
- * @brief fetch suid/uids when create child tables of rollup SMA
- *
- * @param pTsdb
- * @param ppStore
- * @param suid
- * @param uid
- * @return int32_t
- */
-int32_t tsdbFetchTbUidList(STsdb *pTsdb, STbUidStore **ppStore, tb_uid_t suid, tb_uid_t uid) {
- SSmaEnv *pEnv = REPO_RSMA_ENV((STsdb *)pTsdb);
-
- // only applicable to rollup SMA ctables
- if (!pEnv) {
- return TSDB_CODE_SUCCESS;
- }
-
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SHashObj *infoHash = NULL;
- if (!pStat || !(infoHash = SMA_STAT_INFO_HASH(pStat))) {
- terrno = TSDB_CODE_TDB_INVALID_SMA_STAT;
- return TSDB_CODE_FAILED;
- }
-
- // info cached when create rsma stable and return directly for non-rsma ctables
- if (!taosHashGet(infoHash, &suid, sizeof(tb_uid_t))) {
- return TSDB_CODE_SUCCESS;
- }
-
- ASSERT(ppStore != NULL);
-
- if (!(*ppStore)) {
- if (tsdbUidStoreInit(ppStore) != 0) {
- return TSDB_CODE_FAILED;
- }
- }
-
- if (tsdbUidStorePut(*ppStore, suid, &uid) != 0) {
- *ppStore = tsdbUidStoreFree(*ppStore);
- return TSDB_CODE_FAILED;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-static FORCE_INLINE int32_t tsdbUpdateTbUidListImpl(STsdb *pTsdb, tb_uid_t *suid, SArray *tbUids) {
- SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SRSmaInfo *pRSmaInfo = NULL;
-
- if (!suid || !tbUids) {
- terrno = TSDB_CODE_INVALID_PTR;
- tsdbError("vgId:%d failed to get rsma info for uid:%" PRIi64 " since %s", REPO_ID(pTsdb), *suid, terrstr(terrno));
- return TSDB_CODE_FAILED;
- }
-
- pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), suid, sizeof(tb_uid_t));
- if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
- tsdbError("vgId:%d failed to get rsma info for uid:%" PRIi64, REPO_ID(pTsdb), *suid);
- terrno = TSDB_CODE_TDB_INVALID_SMA_STAT;
- return TSDB_CODE_FAILED;
- }
-
- if (pRSmaInfo->taskInfo[0] && (qUpdateQualifiedTableId(pRSmaInfo->taskInfo[0], tbUids, true) != 0)) {
- tsdbError("vgId:%d update tbUidList failed for uid:%" PRIi64 " since %s", REPO_ID(pTsdb), *suid, terrstr(terrno));
- return TSDB_CODE_FAILED;
- } else {
- tsdbDebug("vgId:%d update tbUidList succeed for qTaskInfo:%p with suid:%" PRIi64 ", uid:%" PRIi64, REPO_ID(pTsdb),
- pRSmaInfo->taskInfo[0], *suid, *(int64_t *)taosArrayGet(tbUids, 0));
- }
-
- if (pRSmaInfo->taskInfo[1] && (qUpdateQualifiedTableId(pRSmaInfo->taskInfo[1], tbUids, true) != 0)) {
- tsdbError("vgId:%d update tbUidList failed for uid:%" PRIi64 " since %s", REPO_ID(pTsdb), *suid, terrstr(terrno));
- return TSDB_CODE_FAILED;
- } else {
- tsdbDebug("vgId:%d update tbUidList succeed for qTaskInfo:%p with suid:%" PRIi64 ", uid:%" PRIi64, REPO_ID(pTsdb),
- pRSmaInfo->taskInfo[1], *suid, *(int64_t *)taosArrayGet(tbUids, 0));
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t tsdbUpdateTbUidList(STsdb *pTsdb, STbUidStore *pStore) {
- if (!pStore || (taosArrayGetSize(pStore->tbUids) == 0)) {
- return TSDB_CODE_SUCCESS;
- }
-
- if (tsdbUpdateTbUidListImpl(pTsdb, &pStore->suid, pStore->tbUids) != TSDB_CODE_SUCCESS) {
- return TSDB_CODE_FAILED;
- }
-
- void *pIter = taosHashIterate(pStore->uidHash, NULL);
- while (pIter) {
- tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
- SArray *pTbUids = *(SArray **)pIter;
-
- if (tsdbUpdateTbUidListImpl(pTsdb, pTbSuid, pTbUids) != TSDB_CODE_SUCCESS) {
- taosHashCancelIterate(pStore->uidHash, pIter);
- return TSDB_CODE_FAILED;
- }
-
- pIter = taosHashIterate(pStore->uidHash, pIter);
- }
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbProcessSubmitReq(STsdb *pTsdb, int64_t version, void *pReq) {
- if (!pReq) {
- terrno = TSDB_CODE_INVALID_PTR;
- return TSDB_CODE_FAILED;
- }
-
- SSubmitReq *pSubmitReq = (SSubmitReq *)pReq;
-
- if (tsdbInsertData(pTsdb, version, pSubmitReq, NULL) < 0) {
- return TSDB_CODE_FAILED;
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbFetchSubmitReqSuids(SSubmitReq *pMsg, STbUidStore *pStore) {
- ASSERT(pMsg != NULL);
- SSubmitMsgIter msgIter = {0};
- SSubmitBlk *pBlock = NULL;
- SSubmitBlkIter blkIter = {0};
- STSRow *row = NULL;
-
- terrno = TSDB_CODE_SUCCESS;
-
- if (tInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1;
- while (true) {
- if (tGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1;
-
- if (!pBlock) break;
- tsdbUidStorePut(pStore, msgIter.suid, NULL);
- pStore->uid = msgIter.uid; // TODO: remove, just for debugging
- }
-
- if (terrno != TSDB_CODE_SUCCESS) return -1;
- return 0;
-}
-
-static FORCE_INLINE int32_t tsdbExecuteRSmaImpl(STsdb *pTsdb, const void *pMsg, int32_t inputType,
- qTaskInfo_t *taskInfo, STSchema *pTSchema, tb_uid_t suid, tb_uid_t uid,
- int8_t level) {
- SArray *pResult = NULL;
-
- if (!taskInfo) {
- tsdbDebug("vgId:%d no qTaskInfo to execute rsma %" PRIi8 " task for suid:%" PRIu64, REPO_ID(pTsdb), level, suid);
- return TSDB_CODE_SUCCESS;
- }
-
- tsdbDebug("vgId:%d execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64, REPO_ID(pTsdb), level, taskInfo,
- suid);
-
- qSetStreamInput(taskInfo, pMsg, inputType, false);
- while (1) {
- SSDataBlock *output = NULL;
- uint64_t ts;
- if (qExecTask(taskInfo, &output, &ts) < 0) {
- ASSERT(false);
- }
- if (!output) {
- break;
- }
- if (!pResult) {
- pResult = taosArrayInit(0, sizeof(SSDataBlock));
- if (!pResult) {
- terrno = TSDB_CODE_OUT_OF_MEMORY;
- return TSDB_CODE_FAILED;
- }
- }
-
- taosArrayPush(pResult, output);
- }
-
- if (taosArrayGetSize(pResult) > 0) {
- blockDebugShowData(pResult);
- STsdb *sinkTsdb = (level == TSDB_RETENTION_L1 ? pTsdb->pVnode->pRSma1 : pTsdb->pVnode->pRSma2);
- SSubmitReq *pReq = NULL;
- if (buildSubmitReqFromDataBlock(&pReq, pResult, pTSchema, TD_VID(pTsdb->pVnode), suid) != 0) {
- taosArrayDestroy(pResult);
- return TSDB_CODE_FAILED;
- }
- if (tsdbProcessSubmitReq(sinkTsdb, INT64_MAX, pReq) != 0) {
- taosArrayDestroy(pResult);
- taosMemoryFreeClear(pReq);
- return TSDB_CODE_FAILED;
- }
- taosMemoryFreeClear(pReq);
- } else {
- tsdbWarn("vgId:%d no rsma % " PRIi8 " data generated since %s", REPO_ID(pTsdb), level, tstrerror(terrno));
- }
-
- taosArrayDestroy(pResult);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t tsdbExecuteRSma(STsdb *pTsdb, const void *pMsg, int32_t inputType, tb_uid_t suid, tb_uid_t uid) {
- SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
- if (!pEnv) {
- // only applicable when rsma env exists
- return TSDB_CODE_SUCCESS;
- }
-
- ASSERT(uid != 0); // TODO: remove later
-
- SSmaStat *pStat = SMA_ENV_STAT(pEnv);
- SRSmaInfo *pRSmaInfo = NULL;
-
- pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
-
- if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
- tsdbDebug("vgId:%d no rsma info for suid:%" PRIu64, REPO_ID(pTsdb), suid);
- return TSDB_CODE_SUCCESS;
- }
- if (!pRSmaInfo->taskInfo[0]) {
- tsdbDebug("vgId:%d no rsma qTaskInfo for suid:%" PRIu64, REPO_ID(pTsdb), suid);
- return TSDB_CODE_SUCCESS;
- }
-
- if (inputType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
- // TODO: use the proper schema instead of 1, and cache STSchema in cache
- STSchema *pTSchema = metaGetTbTSchema(pTsdb->pVnode->pMeta, suid, 1);
- if (!pTSchema) {
- terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION;
- return TSDB_CODE_FAILED;
- }
- tsdbExecuteRSmaImpl(pTsdb, pMsg, inputType, pRSmaInfo->taskInfo[0], pTSchema, suid, uid, TSDB_RETENTION_L1);
- tsdbExecuteRSmaImpl(pTsdb, pMsg, inputType, pRSmaInfo->taskInfo[1], pTSchema, suid, uid, TSDB_RETENTION_L2);
- taosMemoryFree(pTSchema);
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
-int32_t tsdbTriggerRSma(STsdb *pTsdb, void *pMsg, int32_t inputType) {
- SSmaEnv *pEnv = REPO_RSMA_ENV(pTsdb);
- if (!pEnv) {
- // only applicable when rsma env exists
- return TSDB_CODE_SUCCESS;
- }
-
- if (inputType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
- STbUidStore uidStore = {0};
- tsdbFetchSubmitReqSuids(pMsg, &uidStore);
-
- if (uidStore.suid != 0) {
- tsdbExecuteRSma(pTsdb, pMsg, inputType, uidStore.suid, uidStore.uid);
-
- void *pIter = taosHashIterate(uidStore.uidHash, NULL);
- while (pIter) {
- tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL);
- tsdbExecuteRSma(pTsdb, pMsg, inputType, *pTbSuid, 0);
- pIter = taosHashIterate(uidStore.uidHash, pIter);
- }
-
- tsdbUidStoreDestory(&uidStore);
- }
- }
- return TSDB_CODE_SUCCESS;
-}
-
-#if 0
-/**
- * @brief Get the start TS key of the last data block of one interval/sliding.
- *
- * @param pTsdb
- * @param param
- * @param result
- * @return int32_t
- * 1) Return 0 and fill the result if the check procedure is normal;
- * 2) Return -1 if error occurs during the check procedure.
- */
-int32_t tsdbGetTSmaStatus(STsdb *pTsdb, void *smaIndex, void *result) {
- const char *procedure = "";
- if (strncmp(procedure, "get the start TS key of the last data block", 100) != 0) {
- return -1;
- }
- // fill the result
- return TSDB_CODE_SUCCESS;
-}
-
-/**
- * @brief Remove the tSma data files related to param between pWin.
- *
- * @param pTsdb
- * @param param
- * @param pWin
- * @return int32_t
- */
-int32_t tsdbRemoveTSmaData(STsdb *pTsdb, void *smaIndex, STimeWindow *pWin) {
- // for ("tSmaFiles of param-interval-sliding between pWin") {
- // // remove the tSmaFile
- // }
- return TSDB_CODE_SUCCESS;
-}
-#endif
-
-// TODO: Who is responsible for resource allocate and release?
-int32_t tsdbInsertTSmaData(STsdb *pTsdb, int64_t indexUid, const char *msg) {
- int32_t code = TSDB_CODE_SUCCESS;
- if ((code = tsdbInsertTSmaDataImpl(pTsdb, indexUid, msg)) < 0) {
- tsdbWarn("vgId:%d insert tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- }
- // TODO: destroy SSDataBlocks(msg)
- return code;
-}
-
-int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, SSubmitReq *pMsg, int64_t version) {
- int32_t code = TSDB_CODE_SUCCESS;
- if ((code = tsdbUpdateExpiredWindowImpl(pTsdb, pMsg, version)) < 0) {
- tsdbWarn("vgId:%d update expired sma window failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- }
- return code;
-}
-
-int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg) {
- int32_t code = TSDB_CODE_SUCCESS;
- if ((code = tsdbInsertRSmaDataImpl(pTsdb, msg)) < 0) {
- tsdbWarn("vgId:%d insert rSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- }
- return code;
-}
-
-int32_t tsdbGetTSmaData(STsdb *pTsdb, char *pData, int64_t indexUid, TSKEY querySKey, int32_t nMaxResult) {
- int32_t code = TSDB_CODE_SUCCESS;
- if ((code = tsdbGetTSmaDataImpl(pTsdb, pData, indexUid, querySKey, nMaxResult)) < 0) {
- tsdbWarn("vgId:%d get tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- }
- return code;
-}
-
-int32_t tsdbDropTSmaData(STsdb *pTsdb, int64_t indexUid) {
- int32_t code = TSDB_CODE_SUCCESS;
- if ((code = tsdbDropTSmaDataImpl(pTsdb, indexUid)) < 0) {
- tsdbWarn("vgId:%d drop tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
- }
- return code;
-}
\ No newline at end of file
diff --git a/source/dnode/vnode/src/tsdb/tsdbTDBImpl.c b/source/dnode/vnode/src/tsdb/tsdbTDBImpl.c
deleted file mode 100644
index a553f32bee0ad4d0df24ca844ad2616e5c4157ae..0000000000000000000000000000000000000000
--- a/source/dnode/vnode/src/tsdb/tsdbTDBImpl.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define ALLOW_FORBID_FUNC
-
-#include "tsdb.h"
-
-int32_t tsdbOpenDBEnv(TDB **ppEnv, const char *path) {
- int ret = 0;
-
- if (path == NULL) return -1;
-
- ret = tdbOpen(path, 4096, 256, ppEnv); // use as param
-
- if (ret != 0) {
- tsdbError("Failed to create tsdb db env, ret = %d", ret);
- return -1;
- }
-
- return 0;
-}
-
-int32_t tsdbCloseDBEnv(TDB *pEnv) { return tdbClose(pEnv); }
-
-static inline int tsdbSmaKeyCmpr(const void *arg1, int len1, const void *arg2, int len2) {
- const SSmaKey *pKey1 = (const SSmaKey *)arg1;
- const SSmaKey *pKey2 = (const SSmaKey *)arg2;
-
- ASSERT(len1 == len2 && len1 == sizeof(SSmaKey));
-
- if (pKey1->skey < pKey2->skey) {
- return -1;
- } else if (pKey1->skey > pKey2->skey) {
- return 1;
- }
- if (pKey1->groupId < pKey2->groupId) {
- return -1;
- } else if (pKey1->groupId > pKey2->groupId) {
- return 1;
- }
-
- return 0;
-}
-
-static int32_t tsdbOpenDBDb(TTB **ppDB, TDB *pEnv, const char *pFName) {
- int ret;
- tdb_cmpr_fn_t compFunc;
-
- // Create a database
- compFunc = tsdbSmaKeyCmpr;
- ret = tdbTbOpen(pFName, -1, -1, compFunc, pEnv, ppDB);
-
- return 0;
-}
-
-static int32_t tsdbCloseDBDb(TTB *pDB) { return tdbTbClose(pDB); }
-
-int32_t tsdbOpenDBF(TDB *pEnv, SDBFile *pDBF) {
- // TEnv is shared by a group of SDBFile
- if (!pEnv || !pDBF) {
- terrno = TSDB_CODE_INVALID_PTR;
- return -1;
- }
-
- // Open DBF
- if (tsdbOpenDBDb(&(pDBF->pDB), pEnv, pDBF->path) < 0) {
- terrno = TSDB_CODE_TDB_INIT_FAILED;
- tsdbCloseDBDb(pDBF->pDB);
- return -1;
- }
-
- return 0;
-}
-
-int32_t tsdbCloseDBF(SDBFile *pDBF) {
- int32_t ret = 0;
- if (pDBF->pDB) {
- ret = tsdbCloseDBDb(pDBF->pDB);
- pDBF->pDB = NULL;
- }
- taosMemoryFreeClear(pDBF->path);
- return ret;
-}
-
-int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *pKey, int32_t keyLen, void *pVal, int32_t valLen, TXN *txn) {
- int32_t ret;
-
- ret = tdbTbInsert(pDBF->pDB, pKey, keyLen, pVal, valLen, txn);
- if (ret < 0) {
- tsdbError("Failed to create insert sma data into db, ret = %d", ret);
- return -1;
- }
-
- return 0;
-}
-
-void *tsdbGetSmaDataByKey(SDBFile *pDBF, const void *pKey, int32_t keyLen, int32_t *valLen) {
- void *pVal = NULL;
- int ret;
-
- ret = tdbTbGet(pDBF->pDB, pKey, keyLen, &pVal, valLen);
-
- if (ret < 0) {
- tsdbError("Failed to get sma data from db, ret = %d", ret);
- return NULL;
- }
-
- ASSERT(*valLen >= 0);
-
- // TODO: lock?
- // TODO: Would the key/value be destoryed during return the data?
- // TODO: How about the key is updated while value length is changed? The original value buffer would be freed
- // automatically?
-
- return pVal;
-}
\ No newline at end of file
diff --git a/source/dnode/vnode/src/vnd/vnodeCfg.c b/source/dnode/vnode/src/vnd/vnodeCfg.c
index a66ecc493d7cbef19370349568398d084dc5bc27..e8fa2ed3c140312d3f64d42fbf5449178c67a772 100644
--- a/source/dnode/vnode/src/vnd/vnodeCfg.c
+++ b/source/dnode/vnode/src/vnd/vnodeCfg.c
@@ -56,6 +56,8 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
if (tjsonAddIntegerToObject(pJson, "szBuf", pCfg->szBuf) < 0) return -1;
if (tjsonAddIntegerToObject(pJson, "isHeap", pCfg->isHeap) < 0) return -1;
if (tjsonAddIntegerToObject(pJson, "isWeak", pCfg->isWeak) < 0) return -1;
+ if (tjsonAddIntegerToObject(pJson, "isTsma", pCfg->isTsma) < 0) return -1;
+ if (tjsonAddIntegerToObject(pJson, "isRsma", pCfg->isRsma) < 0) return -1;
if (tjsonAddIntegerToObject(pJson, "precision", pCfg->tsdbCfg.precision) < 0) return -1;
if (tjsonAddIntegerToObject(pJson, "update", pCfg->tsdbCfg.update) < 0) return -1;
if (tjsonAddIntegerToObject(pJson, "compression", pCfg->tsdbCfg.compression) < 0) return -1;
@@ -130,6 +132,10 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
if(code < 0) return -1;
tjsonGetNumberValue(pJson, "isWeak", pCfg->isWeak, code);
if(code < 0) return -1;
+ tjsonGetNumberValue(pJson, "isTsma", pCfg->isTsma, code);
+ if(code < 0) return -1;
+ tjsonGetNumberValue(pJson, "isRsma", pCfg->isRsma, code);
+ if(code < 0) return -1;
tjsonGetNumberValue(pJson, "precision", pCfg->tsdbCfg.precision, code);
if(code < 0) return -1;
tjsonGetNumberValue(pJson, "update", pCfg->tsdbCfg.update, code);
diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c
index b4fbd01c633c87ae8d14c707a9bfba2cbb0511a0..a0db3cfe2da57c9a9b8ebc7e743ff69554763dd6 100644
--- a/source/dnode/vnode/src/vnd/vnodeCommit.c
+++ b/source/dnode/vnode/src/vnd/vnodeCommit.c
@@ -230,7 +230,7 @@ int vnodeCommit(SVnode *pVnode) {
return -1;
}
- if(vnodeIsRollup(pVnode)) {
+ if (VND_IS_RSMA(pVnode)) {
if (tsdbCommit(VND_RSMA0(pVnode)) < 0) {
ASSERT(0);
return -1;
@@ -250,7 +250,6 @@ int vnodeCommit(SVnode *pVnode) {
}
}
-
if (tqCommit(pVnode->pTq) < 0) {
ASSERT(0);
return -1;
diff --git a/source/dnode/vnode/src/vnd/vnodeModule.c b/source/dnode/vnode/src/vnd/vnodeModule.c
index efae74b55a95525c105c7a8c3de3e887a0f3b2d2..d0aede145eb8640e1e9031160d5ab7573d4a74e8 100644
--- a/source/dnode/vnode/src/vnd/vnodeModule.c
+++ b/source/dnode/vnode/src/vnd/vnodeModule.c
@@ -69,6 +69,9 @@ int vnodeInit(int nthreads) {
if (walInit() < 0) {
return -1;
}
+ if (tqInit() < 0) {
+ return -1;
+ }
return 0;
}
@@ -94,6 +97,9 @@ void vnodeCleanup() {
taosMemoryFreeClear(vnodeGlobal.threads);
taosThreadCondDestroy(&(vnodeGlobal.hasTask));
taosThreadMutexDestroy(&(vnodeGlobal.mutex));
+
+ walCleanUp();
+ tqCleanUp();
}
int vnodeScheduleTask(int (*execute)(void*), void* arg) {
@@ -155,4 +161,4 @@ static void* loop(void* arg) {
}
return NULL;
-}
\ No newline at end of file
+}
diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c
index a90bb7afcb6847ba0cb803d7a7e58720159bf10f..7a26c16e4ba0d4137e44262569a457d87b1a5adf 100644
--- a/source/dnode/vnode/src/vnd/vnodeOpen.c
+++ b/source/dnode/vnode/src/vnd/vnodeOpen.c
@@ -97,7 +97,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
}
// open tsdb
- if (!vnodeIsRollup(pVnode) && tsdbOpen(pVnode, &VND_TSDB(pVnode), VNODE_TSDB_DIR, TSDB_TYPE_TSDB) < 0) {
+ if (!VND_IS_RSMA(pVnode) && tsdbOpen(pVnode, &VND_TSDB(pVnode), VNODE_TSDB_DIR, NULL) < 0) {
vError("vgId:%d failed to open vnode tsdb since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err;
}
@@ -189,4 +189,4 @@ void vnodeStop(SVnode *pVnode) {}
int64_t vnodeGetSyncHandle(SVnode *pVnode) { return pVnode->sync; }
-void vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnapshot) { pSnapshot->lastApplyIndex = pVnode->state.committed; }
\ No newline at end of file
+void vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnapshot) { pSnapshot->lastApplyIndex = pVnode->state.committed; }
diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c
index 74b6982008da95f55448b699e5896b86fefeb1b1..ab879c5dbbbff95a663747d8c1ce09f987f5dc8f 100644
--- a/source/dnode/vnode/src/vnd/vnodeSvr.c
+++ b/source/dnode/vnode/src/vnd/vnodeSvr.c
@@ -22,7 +22,7 @@ static int vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pReq,
static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessDropTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
static int vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
-static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp);
+static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
int32_t vnodePreprocessReq(SVnode *pVnode, SRpcMsg *pMsg) {
SDecoder dc = {0};
@@ -88,6 +88,9 @@ int32_t vnodePreprocessReq(SVnode *pVnode, SRpcMsg *pMsg) {
}
} break;
+ case TDMT_VND_ALTER_REPLICA: {
+ vnodeSyncAlter(pVnode, pMsg);
+ } break;
default:
break;
}
@@ -154,7 +157,7 @@ int vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRpcMsg
pMsg->contLen - sizeof(SMsgHead)) < 0) {
}
} break;
- case TDMT_VND_ALTER_VNODE:
+ case TDMT_VND_ALTER_CONFIG:
break;
default:
ASSERT(0);
@@ -248,6 +251,13 @@ void smaHandleRes(void *pVnode, int64_t smaId, const SArray *data) {
tdProcessTSmaInsert(((SVnode *)pVnode)->pSma, smaId, (const char *)data);
}
+void vnodeUpdateMetaRsp(SVnode *pVnode, STableMetaRsp *pMetaRsp) {
+ strcpy(pMetaRsp->dbFName, pVnode->config.dbname);
+ pMetaRsp->dbId = pVnode->config.dbId;
+ pMetaRsp->vgId = TD_VID(pVnode);
+ pMetaRsp->precision = pVnode->config.tsdbCfg.precision;
+}
+
int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
int32_t ret = TAOS_SYNC_PROPOSE_OTHER_ERROR;
@@ -360,7 +370,7 @@ static int vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *pReq,
goto _err;
}
- tdProcessRSmaCreate(pVnode->pSma, pVnode->pMeta, &req, &pVnode->msgCb);
+ tdProcessRSmaCreate(pVnode, &req);
tDecoderClear(&coder);
return 0;
@@ -517,12 +527,13 @@ _exit:
}
static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
- SVAlterTbReq vAlterTbReq = {0};
- SVAlterTbRsp vAlterTbRsp = {0};
- SDecoder dc = {0};
- int rcode = 0;
- int ret;
- SEncoder ec = {0};
+ SVAlterTbReq vAlterTbReq = {0};
+ SVAlterTbRsp vAlterTbRsp = {0};
+ SDecoder dc = {0};
+ int rcode = 0;
+ int ret;
+ SEncoder ec = {0};
+ STableMetaRsp vMetaRsp = {0};
pRsp->msgType = TDMT_VND_ALTER_TABLE_RSP;
pRsp->pCont = NULL;
@@ -540,7 +551,7 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, i
}
// process
- if (metaAlterTable(pVnode->pMeta, version, &vAlterTbReq) < 0) {
+ if (metaAlterTable(pVnode->pMeta, version, &vAlterTbReq, &vMetaRsp) < 0) {
vAlterTbRsp.code = TSDB_CODE_INVALID_MSG;
tDecoderClear(&dc);
rcode = -1;
@@ -548,6 +559,11 @@ static int vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pReq, i
}
tDecoderClear(&dc);
+ if (NULL != vMetaRsp.pSchemas) {
+ vnodeUpdateMetaRsp(pVnode, &vMetaRsp);
+ vAlterTbRsp.pMeta = &vMetaRsp;
+ }
+
_exit:
tEncodeSize(tEncodeSVAlterTbRsp, &vAlterTbRsp, pRsp->contLen, ret);
pRsp->pCont = rpcMallocCont(pRsp->contLen);
@@ -776,28 +792,30 @@ _exit:
// TODO: the partial success scenario and the error case
// TODO: refactor
- if ((terrno == TSDB_CODE_SUCCESS || terrno == TSDB_CODE_TDB_TABLE_ALREADY_EXIST) &&
- (pRsp->code == TSDB_CODE_SUCCESS)) {
+ if ((terrno == TSDB_CODE_SUCCESS) && (pRsp->code == TSDB_CODE_SUCCESS)) {
tdProcessRSmaSubmit(pVnode->pSma, pReq, STREAM_DATA_TYPE_SUBMIT_BLOCK);
}
return 0;
}
-static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp) {
+static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
SVCreateTSmaReq req = {0};
SDecoder coder;
- pRsp->msgType = TDMT_VND_CREATE_SMA_RSP;
- pRsp->code = TSDB_CODE_SUCCESS;
- pRsp->pCont = NULL;
- pRsp->contLen = 0;
+ if (pRsp) {
+ pRsp->msgType = TDMT_VND_CREATE_SMA_RSP;
+ pRsp->code = TSDB_CODE_SUCCESS;
+ pRsp->pCont = NULL;
+ pRsp->contLen = 0;
+ }
// decode and process req
tDecoderInit(&coder, pReq, len);
if (tDecodeSVCreateTSmaReq(&coder, &req) < 0) {
- pRsp->code = terrno;
+ terrno = TSDB_CODE_MSG_DECODE_ERROR;
+ if (pRsp) pRsp->code = terrno;
goto _err;
}
@@ -805,18 +823,30 @@ static int vnodeProcessCreateTSmaReq(SVnode *pVnode, int64_t version, void *pReq
req.timezoneInt = tsTimezone;
if (tdProcessTSmaCreate(pVnode->pSma, version, (const char *)&req) < 0) {
- pRsp->code = terrno;
+ if (pRsp) pRsp->code = terrno;
goto _err;
}
tDecoderClear(&coder);
- vDebug("vgId:%d success to create tsma %s:%" PRIi64 " for table %" PRIi64, TD_VID(pVnode), req.indexName,
- req.indexUid, req.tableUid);
+ vDebug("vgId:%d success to create tsma %s:%" PRIi64 " version %" PRIi64 " for table %" PRIi64, TD_VID(pVnode),
+ req.indexName, req.indexUid, version, req.tableUid);
return 0;
_err:
tDecoderClear(&coder);
- vError("vgId:%d failed to create tsma %s:%" PRIi64 " for table %" PRIi64 " since %s", TD_VID(pVnode), req.indexName,
- req.indexUid, req.tableUid, terrstr(terrno));
+ vError("vgId:%d failed to create tsma %s:%" PRIi64 " version %" PRIi64 "for table %" PRIi64 " since %s",
+ TD_VID(pVnode), req.indexName, req.indexUid, version, req.tableUid, terrstr(terrno));
return -1;
}
+
+/**
+ * @brief specific for smaDstVnode
+ *
+ * @param pVnode
+ * @param pCont
+ * @param contLen
+ * @return int32_t
+ */
+int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen) {
+ return vnodeProcessCreateTSmaReq(pVnode, 1, pCont, contLen, NULL);
+}
diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c
index d1468778531d08cb8f2744c7e953b452a28df810..8792fbbb0c60d52a06b7af28ca040a1a0f22eb9b 100644
--- a/source/dnode/vnode/src/vnd/vnodeSync.c
+++ b/source/dnode/vnode/src/vnd/vnodeSync.c
@@ -27,6 +27,7 @@ static int32_t vnodeSyncGetSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot);
int32_t vnodeSyncOpen(SVnode *pVnode, char *path) {
SSyncInfo syncInfo = {
.vgId = pVnode->config.vgId,
+ .isStandBy = pVnode->config.standby,
.syncCfg = pVnode->config.syncCfg,
.pWal = pVnode->pWal,
.msgcb = NULL,
@@ -49,28 +50,72 @@ int32_t vnodeSyncOpen(SVnode *pVnode, char *path) {
return 0;
}
+void vnodeSyncAlter(SVnode *pVnode, SRpcMsg *pMsg) {
+ SAlterVnodeReq req = {0};
+ if (tDeserializeSAlterVnodeReq((char *)pMsg->pCont + sizeof(SMsgHead), pMsg->contLen - sizeof(SMsgHead), &req) != 0) {
+ terrno = TSDB_CODE_INVALID_MSG;
+ vError("vgId:%d, failed to alter replica since %s", TD_VID(pVnode), terrstr());
+ SRpcMsg rsp = {.info = pMsg->info, .code = terrno};
+ tmsgSendRsp(&rsp);
+ }
+
+ vInfo("vgId:%d, start to alter vnode replica to %d", TD_VID(pVnode), req.replica);
+ SSyncCfg cfg = {.replicaNum = req.replica, .myIndex = req.selfIndex};
+ for (int32_t r = 0; r < req.replica; ++r) {
+ SNodeInfo *pNode = &cfg.nodeInfo[r];
+ tstrncpy(pNode->nodeFqdn, req.replicas[r].fqdn, sizeof(pNode->nodeFqdn));
+ pNode->nodePort = req.replicas[r].port;
+ vInfo("vgId:%d, replica:%d %s:%u", TD_VID(pVnode), r, pNode->nodeFqdn, pNode->nodePort);
+ }
+
+ if (syncReconfig(pVnode->sync, &cfg) != 0) {
+ vError("vgId:%d, failed to propose sync reconfig since %s", TD_VID(pVnode), terrstr());
+ SRpcMsg rsp = {.info = pMsg->info, .code = terrno};
+ tmsgSendRsp(&rsp);
+ }
+}
+
void vnodeSyncStart(SVnode *pVnode) {
syncSetMsgCb(pVnode->sync, &pVnode->msgCb);
- syncStart(pVnode->sync);
+ if (pVnode->config.standby) {
+ syncStartStandBy(pVnode->sync);
+ } else {
+ syncStart(pVnode->sync);
+ }
}
void vnodeSyncClose(SVnode *pVnode) { syncStop(pVnode->sync); }
-int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
+int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
if (code != 0) {
rpcFreeCont(pMsg->pCont);
+ pMsg->pCont = NULL;
}
return code;
}
-int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) { return tmsgSendReq(pEpSet, pMsg); }
+int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
+ int32_t code = tmsgSendReq(pEpSet, pMsg);
+ if (code != 0) {
+ rpcFreeCont(pMsg->pCont);
+ pMsg->pCont = NULL;
+ }
+ return code;
+}
int32_t vnodeSyncGetSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) {
vnodeGetSnapshot(pFsm->data, pSnapshot);
return 0;
}
+void vnodeSyncReconfig(struct SSyncFSM *pFsm, SSyncCfg newCfg, SReConfigCbMeta cbMeta) {
+ SVnode *pVnode = pFsm->data;
+ vInfo("vgId:%d, sync reconfig is confirmed", TD_VID(pVnode));
+
+ // todo rpc response here
+}
+
void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
SyncIndex beginIndex = SYNC_INDEX_INVALID;
if (pFsm->FpGetSnapshot != NULL) {
@@ -87,20 +132,12 @@ void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta)
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state), beginIndex);
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
- SVnode *pVnode = (SVnode *)(pFsm->data);
+ SVnode *pVnode = pFsm->data;
SyncApplyMsg *pSyncApplyMsg = syncApplyMsgBuild2(pMsg, pVnode->config.vgId, &cbMeta);
SRpcMsg applyMsg;
syncApplyMsg2RpcMsg(pSyncApplyMsg, &applyMsg);
syncApplyMsgDestroy(pSyncApplyMsg);
- /*
- SRpcMsg applyMsg;
- applyMsg = *pMsg;
- applyMsg.pCont = rpcMallocCont(applyMsg.contLen);
- assert(applyMsg.contLen == pMsg->contLen);
- memcpy(applyMsg.pCont, pMsg->pCont, applyMsg.contLen);
- */
-
// recover handle for response
SRpcMsg saveRpcMsg;
int32_t ret = syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &saveRpcMsg);
@@ -142,14 +179,13 @@ void vnodeSyncRollBackMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta
SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
- memset(pFsm, 0, sizeof(*pFsm));
pFsm->data = pVnode;
pFsm->FpCommitCb = vnodeSyncCommitMsg;
pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
pFsm->FpGetSnapshot = vnodeSyncGetSnapshot;
pFsm->FpRestoreFinishCb = NULL;
- pFsm->FpReConfigCb = NULL;
+ pFsm->FpReConfigCb = vnodeSyncReconfig;
return pFsm;
}
\ No newline at end of file
diff --git a/source/dnode/vnode/test/tsdbSmaTest.cpp b/source/dnode/vnode/test/tsdbSmaTest.cpp
index ab617cb18660bc6663b500d7ef9da60a5c2d9fa5..4d2741f751066b62ebb463b4ff8d2930f057a318 100644
--- a/source/dnode/vnode/test/tsdbSmaTest.cpp
+++ b/source/dnode/vnode/test/tsdbSmaTest.cpp
@@ -368,7 +368,7 @@ TEST(testCase, tSma_Data_Insert_Query_Test) {
SDiskCfg pDisks = {0};
pDisks.level = 0;
pDisks.primary = 1;
- strncpy(pDisks.dir, "/var/lib/taos", TSDB_FILENAME_LEN);
+ strncpy(pDisks.dir, TD_DATA_DIR_PATH, TSDB_FILENAME_LEN);
int32_t numOfDisks = 1;
pTsdb->pTfs = tfsOpen(&pDisks, numOfDisks);
EXPECT_NE(pTsdb->pTfs, nullptr);
diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h
index 230949ab7fbf696b050d3e10d7e76c858612e52b..239d719fa80eb3b4fbf9b075e165dc50051b3e52 100644
--- a/source/libs/catalog/inc/catalogInt.h
+++ b/source/libs/catalog/inc/catalogInt.h
@@ -302,7 +302,7 @@ typedef struct SCtgUpdateEpsetMsg {
typedef struct SCtgCacheOperation {
int32_t opId;
void *data;
- bool syncReq;
+ bool syncOp;
uint64_t seqId;
} SCtgCacheOperation;
@@ -342,16 +342,16 @@ typedef struct SCtgOperation {
ctgOpFunc func;
} SCtgOperation;
-#define CTG_QUEUE_ADD() atomic_add_fetch_64(&gCtgMgmt.queue.qRemainNum, 1)
-#define CTG_QUEUE_SUB() atomic_sub_fetch_64(&gCtgMgmt.queue.qRemainNum, 1)
+#define CTG_QUEUE_INC() atomic_add_fetch_64(&gCtgMgmt.queue.qRemainNum, 1)
+#define CTG_QUEUE_DEC() atomic_sub_fetch_64(&gCtgMgmt.queue.qRemainNum, 1)
-#define CTG_STAT_ADD(_item, _n) atomic_add_fetch_64(&(_item), _n)
-#define CTG_STAT_SUB(_item, _n) atomic_sub_fetch_64(&(_item), _n)
+#define CTG_STAT_INC(_item, _n) atomic_add_fetch_64(&(_item), _n)
+#define CTG_STAT_DEC(_item, _n) atomic_sub_fetch_64(&(_item), _n)
#define CTG_STAT_GET(_item) atomic_load_64(&(_item))
-#define CTG_RUNTIME_STAT_ADD(item, n) (CTG_STAT_ADD(gCtgMgmt.stat.runtime.item, n))
-#define CTG_CACHE_STAT_ADD(item, n) (CTG_STAT_ADD(gCtgMgmt.stat.cache.item, n))
-#define CTG_CACHE_STAT_SUB(item, n) (CTG_STAT_SUB(gCtgMgmt.stat.cache.item, n))
+#define CTG_RT_STAT_INC(item, n) (CTG_STAT_INC(gCtgMgmt.stat.runtime.item, n))
+#define CTG_CACHE_STAT_INC(item, n) (CTG_STAT_INC(gCtgMgmt.stat.cache.item, n))
+#define CTG_CACHE_STAT_DEC(item, n) (CTG_STAT_DEC(gCtgMgmt.stat.cache.item, n))
#define CTG_IS_META_NULL(type) ((type) == META_TYPE_NULL_TABLE)
#define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE)
diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c
index 6519440dad3c7711057f3fd1e203b328ed263a52..7e0efe22dbfa2dd61a5c662c1103a1b98f579da8 100644
--- a/source/libs/catalog/src/catalog.c
+++ b/source/libs/catalog/src/catalog.c
@@ -314,6 +314,36 @@ _return:
CTG_RET(code);
}
+int32_t ctgUpdateTbMeta(SCatalog* pCtg, STableMetaRsp *rspMsg, bool syncOp) {
+ STableMetaOutput *output = taosMemoryCalloc(1, sizeof(STableMetaOutput));
+ if (NULL == output) {
+ ctgError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
+ CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
+ }
+
+ int32_t code = 0;
+
+ strcpy(output->dbFName, rspMsg->dbFName);
+ strcpy(output->tbName, rspMsg->tbName);
+
+ output->dbId = rspMsg->dbId;
+
+ SET_META_TYPE_TABLE(output->metaType);
+
+ CTG_ERR_JRET(queryCreateTableMetaFromMsg(rspMsg, rspMsg->tableType == TSDB_SUPER_TABLE, &output->tbMeta));
+
+ CTG_ERR_JRET(ctgUpdateTbMetaEnqueue(pCtg, output, syncOp));
+
+ return TSDB_CODE_SUCCESS;
+
+_return:
+
+ taosMemoryFreeClear(output->tbMeta);
+ taosMemoryFreeClear(output);
+
+ CTG_RET(code);
+}
+
int32_t ctgChkAuth(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, const char* user, const char* dbFName, AUTH_TYPE type, bool *pass) {
bool inCache = false;
@@ -558,7 +588,7 @@ int32_t catalogGetHandle(uint64_t clusterId, SCatalog** catalogHandle) {
*catalogHandle = clusterCtg;
- CTG_CACHE_STAT_ADD(clusterNum, 1);
+ CTG_CACHE_STAT_INC(clusterNum, 1);
return TSDB_CODE_SUCCESS;
@@ -579,7 +609,7 @@ void catalogFreeHandle(SCatalog* pCtg) {
return;
}
- CTG_CACHE_STAT_SUB(clusterNum, 1);
+ CTG_CACHE_STAT_DEC(clusterNum, 1);
uint64_t clusterId = pCtg->clusterId;
@@ -779,38 +809,17 @@ int32_t catalogGetSTableMeta(SCatalog* pCtg, void * pTrans, const SEpSet* pMgmtE
CTG_API_LEAVE(ctgGetTbMeta(CTG_PARAMS_LIST(), &ctx, pTableMeta));
}
-int32_t catalogUpdateSTableMeta(SCatalog* pCtg, STableMetaRsp *rspMsg) {
+int32_t catalogUpdateTableMeta(SCatalog* pCtg, STableMetaRsp *pMsg) {
CTG_API_ENTER();
- if (NULL == pCtg || NULL == rspMsg) {
+ if (NULL == pCtg || NULL == pMsg) {
CTG_API_LEAVE(TSDB_CODE_CTG_INVALID_INPUT);
}
- STableMetaOutput *output = taosMemoryCalloc(1, sizeof(STableMetaOutput));
- if (NULL == output) {
- ctgError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
- CTG_API_LEAVE(TSDB_CODE_CTG_MEM_ERROR);
- }
-
int32_t code = 0;
-
- strcpy(output->dbFName, rspMsg->dbFName);
- strcpy(output->tbName, rspMsg->tbName);
-
- output->dbId = rspMsg->dbId;
-
- SET_META_TYPE_TABLE(output->metaType);
-
- CTG_ERR_JRET(queryCreateTableMetaFromMsg(rspMsg, true, &output->tbMeta));
-
- CTG_ERR_JRET(ctgUpdateTbMetaEnqueue(pCtg, output, false));
-
- CTG_API_LEAVE(code);
+ CTG_ERR_JRET(ctgUpdateTbMeta(pCtg, pMsg, true));
_return:
-
- taosMemoryFreeClear(output->tbMeta);
- taosMemoryFreeClear(output);
CTG_API_LEAVE(code);
}
@@ -990,7 +999,7 @@ int32_t catalogGetAllMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps,
}
if (pReq->qNodeRequired) {
- pRsp->pQnodeList = taosArrayInit(10, sizeof(SQueryNodeAddr));
+ pRsp->pQnodeList = taosArrayInit(10, sizeof(SQueryNodeLoad));
CTG_ERR_JRET(ctgGetQnodeListFromMnode(CTG_PARAMS_LIST(), pRsp->pQnodeList, NULL));
}
diff --git a/source/libs/catalog/src/ctgCache.c b/source/libs/catalog/src/ctgCache.c
index d1e2056becc86c1ad8f36f4d8ea3bfffe9acb97a..0f1344c3432b2540c2daa33de33c2f8c570658f0 100644
--- a/source/libs/catalog/src/ctgCache.c
+++ b/source/libs/catalog/src/ctgCache.c
@@ -178,7 +178,7 @@ int32_t ctgAcquireVgInfoFromCache(SCatalog* pCtg, const char *dbFName, SCtgDBCac
*pCache = dbCache;
- CTG_CACHE_STAT_ADD(vgHitNum, 1);
+ CTG_CACHE_STAT_INC(vgHitNum, 1);
ctgDebug("Got db vgInfo from cache, dbFName:%s", dbFName);
@@ -192,7 +192,7 @@ _return:
*pCache = NULL;
- CTG_CACHE_STAT_ADD(vgMissNum, 1);
+ CTG_CACHE_STAT_INC(vgMissNum, 1);
return TSDB_CODE_SUCCESS;
}
@@ -279,7 +279,7 @@ int32_t ctgReadTbMetaFromCache(SCatalog* pCtg, SCtgTbMetaCtx* ctx, STableMeta**
ctgReleaseDBCache(pCtg, dbCache);
ctgDebug("Got meta from cache, type:%d, dbFName:%s, tbName:%s", tbMeta->tableType, dbFName, ctx->pName->tname);
- CTG_CACHE_STAT_ADD(tblHitNum, 1);
+ CTG_CACHE_STAT_INC(tblHitNum, 1);
return TSDB_CODE_SUCCESS;
}
@@ -312,7 +312,7 @@ int32_t ctgReadTbMetaFromCache(SCatalog* pCtg, SCtgTbMetaCtx* ctx, STableMeta**
ctgReleaseDBCache(pCtg, dbCache);
- CTG_CACHE_STAT_ADD(tblHitNum, 1);
+ CTG_CACHE_STAT_INC(tblHitNum, 1);
ctgDebug("Got tbmeta from cache, dbFName:%s, tbName:%s", dbFName, ctx->pName->tname);
@@ -323,7 +323,7 @@ _return:
ctgReleaseDBCache(pCtg, dbCache);
taosMemoryFreeClear(*pTableMeta);
- CTG_CACHE_STAT_ADD(tblMissNum, 1);
+ CTG_CACHE_STAT_INC(tblMissNum, 1);
CTG_RET(code);
}
@@ -462,7 +462,7 @@ int32_t ctgChkAuthFromCache(SCatalog* pCtg, const char* user, const char* dbFNam
*inCache = true;
ctgDebug("Got user from cache, user:%s", user);
- CTG_CACHE_STAT_ADD(userHitNum, 1);
+ CTG_CACHE_STAT_INC(userHitNum, 1);
if (pUser->superUser) {
*pass = true;
@@ -491,7 +491,7 @@ int32_t ctgChkAuthFromCache(SCatalog* pCtg, const char* user, const char* dbFNam
_return:
*inCache = false;
- CTG_CACHE_STAT_ADD(userMissNum, 1);
+ CTG_CACHE_STAT_INC(userMissNum, 1);
return TSDB_CODE_SUCCESS;
}
@@ -521,7 +521,7 @@ void ctgDequeue(SCtgCacheOperation **op) {
SCtgQNode *node = gCtgMgmt.queue.head->next;
gCtgMgmt.queue.head = gCtgMgmt.queue.head->next;
- CTG_QUEUE_SUB();
+ CTG_QUEUE_DEC();
taosMemoryFreeClear(orig);
@@ -545,14 +545,14 @@ int32_t ctgEnqueue(SCatalog* pCtg, SCtgCacheOperation *operation) {
gCtgMgmt.queue.tail = node;
CTG_UNLOCK(CTG_WRITE, &gCtgMgmt.queue.qlock);
- CTG_QUEUE_ADD();
- CTG_RUNTIME_STAT_ADD(qNum, 1);
+ CTG_QUEUE_INC();
+ CTG_RT_STAT_INC(qNum, 1);
tsem_post(&gCtgMgmt.queue.reqSem);
ctgDebug("action [%s] added into queue", gCtgCacheOperation[operation->opId].name);
- if (operation->syncReq) {
+ if (operation->syncOp) {
ctgWaitOpDone(operation);
}
@@ -591,9 +591,9 @@ _return:
}
-int32_t ctgDropStbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid, bool syncReq) {
+int32_t ctgDropStbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid, bool syncOp) {
int32_t code = 0;
- SCtgCacheOperation action= {.opId = CTG_OP_DROP_STB_META, .syncReq = syncReq};
+ SCtgCacheOperation action= {.opId = CTG_OP_DROP_STB_META, .syncOp = syncOp};
SCtgRemoveStbMsg *msg = taosMemoryMalloc(sizeof(SCtgRemoveStbMsg));
if (NULL == msg) {
ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveStbMsg));
@@ -620,9 +620,9 @@ _return:
-int32_t ctgDropTbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName, bool syncReq) {
+int32_t ctgDropTbMetaEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName, bool syncOp) {
int32_t code = 0;
- SCtgCacheOperation action= {.opId = CTG_OP_DROP_TB_META, .syncReq = syncReq};
+ SCtgCacheOperation action= {.opId = CTG_OP_DROP_TB_META, .syncOp = syncOp};
SCtgRemoveTblMsg *msg = taosMemoryMalloc(sizeof(SCtgRemoveTblMsg));
if (NULL == msg) {
ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveTblMsg));
@@ -646,9 +646,9 @@ _return:
CTG_RET(code);
}
-int32_t ctgUpdateVgroupEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, SDBVgInfo* dbInfo, bool syncReq) {
+int32_t ctgUpdateVgroupEnqueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, SDBVgInfo* dbInfo, bool syncOp) {
int32_t code = 0;
- SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_VGROUP, .syncReq = syncReq};
+ SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_VGROUP, .syncOp = syncOp};
SCtgUpdateVgMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateVgMsg));
if (NULL == msg) {
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateVgMsg));
@@ -679,9 +679,9 @@ _return:
CTG_RET(code);
}
-int32_t ctgUpdateTbMetaEnqueue(SCatalog* pCtg, STableMetaOutput *output, bool syncReq) {
+int32_t ctgUpdateTbMetaEnqueue(SCatalog* pCtg, STableMetaOutput *output, bool syncOp) {
int32_t code = 0;
- SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_TB_META, .syncReq = syncReq};
+ SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_TB_META, .syncOp = syncOp};
SCtgUpdateTblMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateTblMsg));
if (NULL == msg) {
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateTblMsg));
@@ -738,9 +738,9 @@ _return:
-int32_t ctgUpdateUserEnqueue(SCatalog* pCtg, SGetUserAuthRsp *pAuth, bool syncReq) {
+int32_t ctgUpdateUserEnqueue(SCatalog* pCtg, SGetUserAuthRsp *pAuth, bool syncOp) {
int32_t code = 0;
- SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_USER, .syncReq = syncReq};
+ SCtgCacheOperation action= {.opId = CTG_OP_UPDATE_USER, .syncOp = syncOp};
SCtgUpdateUserMsg *msg = taosMemoryMalloc(sizeof(SCtgUpdateUserMsg));
if (NULL == msg) {
ctgError("malloc %d failed", (int32_t)sizeof(SCtgUpdateUserMsg));
@@ -988,7 +988,7 @@ int32_t ctgAddNewDBCache(SCatalog *pCtg, const char *dbFName, uint64_t dbId) {
CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR);
}
- CTG_CACHE_STAT_ADD(dbNum, 1);
+ CTG_CACHE_STAT_INC(dbNum, 1);
SDbVgVersion vgVersion = {.dbId = newDBCache.dbId, .vgVersion = -1};
strncpy(vgVersion.dbFName, dbFName, sizeof(vgVersion.dbFName));
@@ -1048,7 +1048,7 @@ int32_t ctgRemoveDBFromCache(SCatalog* pCtg, SCtgDBCache *dbCache, const char* d
CTG_ERR_RET(TSDB_CODE_CTG_DB_DROPPED);
}
- CTG_CACHE_STAT_SUB(dbNum, 1);
+ CTG_CACHE_STAT_DEC(dbNum, 1);
ctgInfo("db removed from cache, dbFName:%s, dbId:%"PRIx64, dbFName, dbId);
@@ -1187,7 +1187,7 @@ int32_t ctgWriteTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFNam
if (taosHashRemove(tbCache->stbCache, &orig->suid, sizeof(orig->suid))) {
ctgError("stb not exist in stbCache, dbFName:%s, stb:%s, suid:%"PRIx64, dbFName, tbName, orig->suid);
} else {
- CTG_CACHE_STAT_SUB(stblNum, 1);
+ CTG_CACHE_STAT_DEC(stblNum, 1);
}
CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock);
@@ -1214,7 +1214,7 @@ int32_t ctgWriteTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFNam
}
if (NULL == orig) {
- CTG_CACHE_STAT_ADD(tblNum, 1);
+ CTG_CACHE_STAT_INC(tblNum, 1);
}
ctgDebug("tbmeta updated to cache, dbFName:%s, tbName:%s, tbType:%d", dbFName, tbName, meta->tableType);
@@ -1233,7 +1233,7 @@ int32_t ctgWriteTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFNam
CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR);
}
- CTG_CACHE_STAT_ADD(stblNum, 1);
+ CTG_CACHE_STAT_INC(stblNum, 1);
CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock);
@@ -1371,14 +1371,14 @@ int32_t ctgOpDropStbMeta(SCtgCacheOperation *operation) {
if (taosHashRemove(dbCache->tbCache.stbCache, &msg->suid, sizeof(msg->suid))) {
ctgDebug("stb not exist in stbCache, may be removed, dbFName:%s, stb:%s, suid:%"PRIx64, msg->dbFName, msg->stbName, msg->suid);
} else {
- CTG_CACHE_STAT_SUB(stblNum, 1);
+ CTG_CACHE_STAT_DEC(stblNum, 1);
}
CTG_LOCK(CTG_READ, &dbCache->tbCache.metaLock);
if (taosHashRemove(dbCache->tbCache.metaCache, msg->stbName, strlen(msg->stbName))) {
ctgError("stb not exist in cache, dbFName:%s, stb:%s, suid:%"PRIx64, msg->dbFName, msg->stbName, msg->suid);
} else {
- CTG_CACHE_STAT_SUB(tblNum, 1);
+ CTG_CACHE_STAT_DEC(tblNum, 1);
}
CTG_UNLOCK(CTG_READ, &dbCache->tbCache.metaLock);
@@ -1419,7 +1419,7 @@ int32_t ctgOpDropTbMeta(SCtgCacheOperation *operation) {
ctgError("stb not exist in cache, dbFName:%s, tbName:%s", msg->dbFName, msg->tbName);
CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR);
} else {
- CTG_CACHE_STAT_SUB(tblNum, 1);
+ CTG_CACHE_STAT_DEC(tblNum, 1);
}
CTG_UNLOCK(CTG_READ, &dbCache->tbCache.metaLock);
@@ -1574,11 +1574,11 @@ void* ctgUpdateThreadFunc(void* param) {
gCtgMgmt.queue.seqDone = operation->seqId;
- if (operation->syncReq) {
+ if (operation->syncOp) {
tsem_post(&gCtgMgmt.queue.rspSem);
}
- CTG_RUNTIME_STAT_ADD(qDoneNum, 1);
+ CTG_RT_STAT_INC(qDoneNum, 1);
ctgdShowClusterCache(pCtg);
}
diff --git a/source/libs/catalog/src/ctgRemote.c b/source/libs/catalog/src/ctgRemote.c
index 4def1fff4f3c2185de569a706f59ace1c215d488..b16a082f75ff54946bdb20ef8c25989e8f597ec0 100644
--- a/source/libs/catalog/src/ctgRemote.c
+++ b/source/libs/catalog/src/ctgRemote.c
@@ -275,7 +275,7 @@ int32_t ctgGetQnodeListFromMnode(CTG_PARAMS, SArray *out, SCtgTask* pTask) {
}
if (pTask) {
- void* pOut = taosArrayInit(4, sizeof(struct SQueryNodeAddr));
+ void* pOut = taosArrayInit(4, sizeof(SQueryNodeLoad));
if (NULL == pOut) {
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
}
diff --git a/source/libs/catalog/src/ctgUtil.c b/source/libs/catalog/src/ctgUtil.c
index 4fbf1463d8f0191a26c99399f26e66d32b319ca5..4625203dd8d20a6a96af8ea8b748533d4b0a1534 100644
--- a/source/libs/catalog/src/ctgUtil.c
+++ b/source/libs/catalog/src/ctgUtil.c
@@ -85,7 +85,7 @@ void ctgFreeTbMetaCache(SCtgTbMetaCache *cache) {
int32_t stblNum = taosHashGetSize(cache->stbCache);
taosHashCleanup(cache->stbCache);
cache->stbCache = NULL;
- CTG_CACHE_STAT_SUB(stblNum, stblNum);
+ CTG_CACHE_STAT_DEC(stblNum, stblNum);
}
CTG_UNLOCK(CTG_WRITE, &cache->stbLock);
@@ -94,7 +94,7 @@ void ctgFreeTbMetaCache(SCtgTbMetaCache *cache) {
int32_t tblNum = taosHashGetSize(cache->metaCache);
taosHashCleanup(cache->metaCache);
cache->metaCache = NULL;
- CTG_CACHE_STAT_SUB(tblNum, tblNum);
+ CTG_CACHE_STAT_DEC(tblNum, tblNum);
}
CTG_UNLOCK(CTG_WRITE, &cache->metaLock);
}
@@ -145,7 +145,7 @@ void ctgFreeHandle(SCatalog* pCtg) {
taosHashCleanup(pCtg->dbCache);
- CTG_CACHE_STAT_SUB(dbNum, dbNum);
+ CTG_CACHE_STAT_DEC(dbNum, dbNum);
}
if (pCtg->userCache) {
@@ -162,7 +162,7 @@ void ctgFreeHandle(SCatalog* pCtg) {
taosHashCleanup(pCtg->userCache);
- CTG_CACHE_STAT_SUB(userNum, userNum);
+ CTG_CACHE_STAT_DEC(userNum, userNum);
}
taosMemoryFree(pCtg);
diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp
index 81d206a0f3fee7f33f24b9740c973ab8d89b10d1..e4ae2c004f412e356feba406fca07f1c83863abe 100644
--- a/source/libs/catalog/test/catalogTests.cpp
+++ b/source/libs/catalog/test/catalogTests.cpp
@@ -137,7 +137,7 @@ void ctgTestInitLogFile() {
tsAsyncLog = 0;
qDebugFlag = 159;
- strcpy(tsLogDir, "/var/log/taos");
+ strcpy(tsLogDir, TD_LOG_DIR_PATH);
ctgdEnableDebug("api");
ctgdEnableDebug("meta");
@@ -1380,7 +1380,7 @@ TEST(tableMeta, updateStbMeta) {
STableMetaRsp rsp = {0};
ctgTestBuildSTableMetaRsp(&rsp);
- code = catalogUpdateSTableMeta(pCtg, &rsp);
+ code = catalogUpdateTableMeta(pCtg, &rsp);
ASSERT_EQ(code, 0);
taosMemoryFreeClear(rsp.pSchemas);
diff --git a/source/libs/executor/inc/dataSinkInt.h b/source/libs/executor/inc/dataSinkInt.h
index 85356a862ce282ac53aaad4ee72f0a77b19f115c..8f49440105c813b512835717e861d3da1b2065df 100644
--- a/source/libs/executor/inc/dataSinkInt.h
+++ b/source/libs/executor/inc/dataSinkInt.h
@@ -37,6 +37,7 @@ typedef void (*FEndPut)(struct SDataSinkHandle* pHandle, uint64_t useconds);
typedef void (*FGetDataLength)(struct SDataSinkHandle* pHandle, int32_t* pLen, bool* pQueryEnd);
typedef int32_t (*FGetDataBlock)(struct SDataSinkHandle* pHandle, SOutputData* pOutput);
typedef int32_t (*FDestroyDataSinker)(struct SDataSinkHandle* pHandle);
+typedef int32_t (*FGetCacheSize)(struct SDataSinkHandle* pHandle, uint64_t* size);
typedef struct SDataSinkHandle {
FPutDataBlock fPut;
@@ -44,6 +45,7 @@ typedef struct SDataSinkHandle {
FGetDataLength fGetLen;
FGetDataBlock fGetData;
FDestroyDataSinker fDestroy;
+ FGetCacheSize fGetCacheSize;
} SDataSinkHandle;
int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSinkNode* pDataSink, DataSinkHandle* pHandle);
diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h
index 0b3e75f08169c433390378401556d603a78ae82f..e7a3390cf3114b07be4439b23f346e11ded0f78f 100644
--- a/source/libs/executor/inc/executorimpl.h
+++ b/source/libs/executor/inc/executorimpl.h
@@ -440,6 +440,7 @@ typedef struct STimeWindowSupp {
int64_t waterMark;
TSKEY maxTs;
SColumnInfoData timeWindowData; // query time window info for scalar function execution.
+ SHashObj *winMap;
} STimeWindowAggSupp;
typedef struct SIntervalAggOperatorInfo {
@@ -759,7 +760,7 @@ SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo*
SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHandle,
SArray* pTableIdList, STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo,
- STimeWindowAggSupp* pTwSup, int16_t tsColId);
+ STimeWindowAggSupp* pTwSup);
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols,
@@ -838,6 +839,8 @@ SResultWindowInfo* getSessionTimeWindow(SArray* pWinInfos, TSKEY ts, int64_t gap
int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pTs, int32_t rows,
int32_t start, int64_t gap, SHashObj* pStDeleted);
bool functionNeedToExecute(SqlFunctionCtx* pCtx);
+int64_t getSmaWaterMark(int64_t interval, double filesFactor);
+bool isSmaStream(int8_t triggerType);
int32_t compareTimeWindow(const void* p1, const void* p2, const void* param);
#ifdef __cplusplus
diff --git a/source/libs/executor/src/dataDispatcher.c b/source/libs/executor/src/dataDispatcher.c
index fa9e27a5f810268f057a53d10b4d946dbd6825ea..080cf5c2ad44f31f11f0fce0e2350fe121c2c1fb 100644
--- a/source/libs/executor/src/dataDispatcher.c
+++ b/source/libs/executor/src/dataDispatcher.c
@@ -22,6 +22,8 @@
#include "tglobal.h"
#include "tqueue.h"
+extern SDataSinkStat gDataSinkStat;
+
typedef struct SDataDispatchBuf {
int32_t useSize;
int32_t allocSize;
@@ -45,6 +47,7 @@ typedef struct SDataDispatchHandle {
int32_t status;
bool queryEnd;
uint64_t useconds;
+ uint64_t cachedSize;
TdThreadMutex mutex;
} SDataDispatchHandle;
@@ -71,7 +74,7 @@ static bool needCompress(const SSDataBlock* pData, int32_t numOfCols) {
// +----------------+--------------+----------+--------------------------------------+-------------+-----------+-------------+-----------+
// The length of bitmap is decided by number of rows of this data block, and the length of each column data is
// recorded in the first segment, next to the struct header
-static void toDataCacheEntry(const SDataDispatchHandle* pHandle, const SInputData* pInput, SDataDispatchBuf* pBuf) {
+static void toDataCacheEntry(SDataDispatchHandle* pHandle, const SInputData* pInput, SDataDispatchBuf* pBuf) {
int32_t numOfCols = LIST_LENGTH(pHandle->pSchema->pSlots);
SDataCacheEntry* pEntry = (SDataCacheEntry*)pBuf->pData;
@@ -84,6 +87,9 @@ static void toDataCacheEntry(const SDataDispatchHandle* pHandle, const SInputDat
blockCompressEncode(pInput->pData, pEntry->data, &pEntry->dataLen, numOfCols, pEntry->compressed);
pBuf->useSize += pEntry->dataLen;
+
+ atomic_add_fetch_64(&pHandle->cachedSize, pEntry->dataLen);
+ atomic_add_fetch_64(&gDataSinkStat.cachedSize, pEntry->dataLen);
}
static bool allocBuf(SDataDispatchHandle* pDispatcher, const SInputData* pInput, SDataDispatchBuf* pBuf) {
@@ -156,6 +162,7 @@ static void getDataLength(SDataSinkHandle* pHandle, int32_t* pLen, bool* pQueryE
taosFreeQitem(pBuf);
*pLen = ((SDataCacheEntry*)(pDispatcher->nextOutput.pData))->dataLen;
*pQueryEnd = pDispatcher->queryEnd;
+ qDebug("got data len %d, row num %d in sink", *pLen, ((SDataCacheEntry*)(pDispatcher->nextOutput.pData))->numOfRows);
}
static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
@@ -173,6 +180,10 @@ static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
pOutput->numOfRows = pEntry->numOfRows;
pOutput->numOfCols = pEntry->numOfCols;
pOutput->compressed = pEntry->compressed;
+
+ atomic_sub_fetch_64(&pDispatcher->cachedSize, pEntry->dataLen);
+ atomic_sub_fetch_64(&gDataSinkStat.cachedSize, pEntry->dataLen);
+
taosMemoryFreeClear(pDispatcher->nextOutput.pData); // todo persistent
pOutput->bufStatus = updateStatus(pDispatcher);
taosThreadMutexLock(&pDispatcher->mutex);
@@ -180,11 +191,14 @@ static int32_t getDataBlock(SDataSinkHandle* pHandle, SOutputData* pOutput) {
pOutput->useconds = pDispatcher->useconds;
pOutput->precision = pDispatcher->pSchema->precision;
taosThreadMutexUnlock(&pDispatcher->mutex);
+
+
return TSDB_CODE_SUCCESS;
}
static int32_t destroyDataSinker(SDataSinkHandle* pHandle) {
SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle;
+ atomic_sub_fetch_64(&gDataSinkStat.cachedSize, pDispatcher->cachedSize);
taosMemoryFreeClear(pDispatcher->nextOutput.pData);
while (!taosQueueEmpty(pDispatcher->pDataBlocks)) {
SDataDispatchBuf* pBuf = NULL;
@@ -197,6 +211,13 @@ static int32_t destroyDataSinker(SDataSinkHandle* pHandle) {
return TSDB_CODE_SUCCESS;
}
+int32_t getCacheSize(struct SDataSinkHandle* pHandle, uint64_t* size) {
+ SDataDispatchHandle* pDispatcher = (SDataDispatchHandle*)pHandle;
+
+ *size = atomic_load_64(&pDispatcher->cachedSize);
+ return TSDB_CODE_SUCCESS;
+}
+
int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSinkNode* pDataSink, DataSinkHandle* pHandle) {
SDataDispatchHandle* dispatcher = taosMemoryCalloc(1, sizeof(SDataDispatchHandle));
if (NULL == dispatcher) {
@@ -208,6 +229,7 @@ int32_t createDataDispatcher(SDataSinkManager* pManager, const SDataSinkNode* pD
dispatcher->sink.fGetLen = getDataLength;
dispatcher->sink.fGetData = getDataBlock;
dispatcher->sink.fDestroy = destroyDataSinker;
+ dispatcher->sink.fGetCacheSize = getCacheSize;
dispatcher->pManager = pManager;
dispatcher->pSchema = pDataSink->pInputDataBlockDesc;
dispatcher->status = DS_BUF_EMPTY;
diff --git a/source/libs/executor/src/dataSinkMgt.c b/source/libs/executor/src/dataSinkMgt.c
index 64206fc10aac0ab9835d65333322657a0ccaecbf..9016ca274a3567d8cbc45d522d5e1cb93b176e68 100644
--- a/source/libs/executor/src/dataSinkMgt.c
+++ b/source/libs/executor/src/dataSinkMgt.c
@@ -19,6 +19,7 @@
#include "planner.h"
static SDataSinkManager gDataSinkManager = {0};
+SDataSinkStat gDataSinkStat = {0};
int32_t dsDataSinkMgtInit(SDataSinkMgtCfg *cfg) {
gDataSinkManager.cfg = *cfg;
@@ -26,6 +27,13 @@ int32_t dsDataSinkMgtInit(SDataSinkMgtCfg *cfg) {
return 0; // to avoid compiler eror
}
+int32_t dsDataSinkGetCacheSize(SDataSinkStat *pStat) {
+ pStat->cachedSize = atomic_load_64(&gDataSinkStat.cachedSize);
+
+ return 0;
+}
+
+
int32_t dsCreateDataSinker(const SDataSinkNode *pDataSink, DataSinkHandle* pHandle) {
if (QUERY_NODE_PHYSICAL_PLAN_DISPATCH == nodeType(pDataSink)) {
return createDataDispatcher(&gDataSinkManager, pDataSink, pHandle);
@@ -53,6 +61,12 @@ int32_t dsGetDataBlock(DataSinkHandle handle, SOutputData* pOutput) {
return pHandleImpl->fGetData(pHandleImpl, pOutput);
}
+int32_t dsGetCacheSize(DataSinkHandle handle, uint64_t *pSize) {
+ SDataSinkHandle* pHandleImpl = (SDataSinkHandle*)handle;
+ return pHandleImpl->fGetCacheSize(pHandleImpl, pSize);
+}
+
+
void dsScheduleProcess(void* ahandle, void* pItem) {
// todo
}
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c
index a40d6ea2e7b855e373af4b9789630895285a33ef..3c46f46e198bd1fae7ebd6173df64b8dec0e6737 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorimpl.c
@@ -4418,8 +4418,9 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
qDebug("%s pDataReader is not NULL", GET_TASKID(pTaskInfo));
}
SArray* tableIdList = extractTableIdList(pTableListInfo);
- SOperatorInfo* pOperator = createStreamScanOperatorInfo(pDataReader, pHandle, tableIdList, pTableScanNode,
- pTaskInfo, &twSup, pTableScanNode->tsColId);
+
+ SOperatorInfo* pOperator = createStreamScanOperatorInfo(pDataReader, pHandle,
+ tableIdList, pTableScanNode, pTaskInfo, &twSup);
taosArrayDestroy(tableIdList);
return pOperator;
@@ -4520,7 +4521,19 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
.calTrigger = pIntervalPhyNode->window.triggerType,
- .maxTs = INT64_MIN};
+ .maxTs = INT64_MIN,
+ .winMap = NULL,};
+ if (isSmaStream(pIntervalPhyNode->window.triggerType)) {
+ if (FLT_LESS(pIntervalPhyNode->window.filesFactor, 1.000000)) {
+ as.calTrigger = STREAM_TRIGGER_AT_ONCE_SMA;
+ } else {
+ _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
+ as.winMap = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
+ as.waterMark = getSmaWaterMark(interval.interval,
+ pIntervalPhyNode->window.filesFactor);
+ as.calTrigger = STREAM_TRIGGER_WINDOW_CLOSE_SMA;
+ }
+ }
int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, &as, pTaskInfo);
@@ -4819,7 +4832,7 @@ int32_t getTableList(void* metaHandle, int32_t tableType, uint64_t tableUid, STa
if (tableType == TSDB_SUPER_TABLE) {
if (pTagCond) {
- SIndexMetaArg metaArg = {.metaHandle = tsdbGetIdx(metaHandle), .suid = tableUid};
+ SIndexMetaArg metaArg = {.metaEx = metaHandle, .metaHandle = tsdbGetIdx(metaHandle), .suid = tableUid};
SArray* res = taosArrayInit(8, sizeof(uint64_t));
code = doFilterTag(pTagCond, &metaArg, res);
@@ -5189,3 +5202,18 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, const char* pKey) {
}
return createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, pKey, TD_TMP_DIR_PATH);
}
+
+int64_t getSmaWaterMark(int64_t interval, double filesFactor) {
+ int64_t waterMark = 0;
+ ASSERT(FLT_GREATEREQUAL(filesFactor,0.000000));
+ waterMark = -1 * filesFactor;
+ return waterMark;
+}
+
+bool isSmaStream(int8_t triggerType) {
+ if (triggerType == STREAM_TRIGGER_AT_ONCE ||
+ triggerType == STREAM_TRIGGER_WINDOW_CLOSE) {
+ return false;
+ }
+ return true;
+}
diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c
index 48b6e8b7200c84fb7681b23824417325b53c6347..348d85943e9ce306347a5530617131b6e00cf89a 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -303,7 +303,9 @@ void addTagPseudoColumnData(SReadHandle *pHandle, SExprInfo* pPseudoExpr, int32_
int32_t dstSlotId = pExpr->base.resSchema.slotId;
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotId);
+
colInfoDataEnsureCapacity(pColInfoData, 0, pBlock->info.rows);
+ colInfoDataCleanup(pColInfoData, pBlock->info.rows);
int32_t functionId = pExpr->pExpr->_function.functionId;
@@ -311,29 +313,23 @@ void addTagPseudoColumnData(SReadHandle *pHandle, SExprInfo* pPseudoExpr, int32_
if (fmIsScanPseudoColumnFunc(functionId)) {
setTbNameColData(pHandle->meta, pBlock, pColInfoData, functionId);
} else { // these are tags
- const char* p = NULL;
- if (pColInfoData->info.type == TSDB_DATA_TYPE_JSON) {
- const uint8_t* tmp = mr.me.ctbEntry.pTags;
-
- char* data = taosMemoryCalloc(kvRowLen(tmp) + 1, 1);
- if (data == NULL) {
- metaReaderClear(&mr);
- qError("doTagScan calloc error:%d", kvRowLen(tmp) + 1);
- return;
- }
-
- *data = TSDB_DATA_TYPE_JSON;
- memcpy(data + 1, tmp, kvRowLen(tmp));
- p = data;
- } else {
- p = metaGetTableTagVal(&mr.me, pExpr->base.pParam[0].pCol->colId);
+ STagVal tagVal = {0};
+ tagVal.cid = pExpr->base.pParam[0].pCol->colId;
+ const char *p = metaGetTableTagVal(&mr.me, pColInfoData->info.type, &tagVal);
+
+ char *data = NULL;
+ if(pColInfoData->info.type != TSDB_DATA_TYPE_JSON && p != NULL){
+ data = tTagValToData((const STagVal *)p, false);
+ }else {
+ data = (char*)p;
}
for (int32_t i = 0; i < pBlock->info.rows; ++i) {
- colDataAppend(pColInfoData, i, p, (p == NULL));
+ colDataAppend(pColInfoData, i, data, (data == NULL));
}
- if (pColInfoData->info.type == TSDB_DATA_TYPE_JSON) {
- taosMemoryFree((void*)p);
+ if (data && (pColInfoData->info.type != TSDB_DATA_TYPE_JSON) && p != NULL &&
+ IS_VAR_DATA_TYPE(((const STagVal*)p)->type)) {
+ taosMemoryFree(data);
}
}
}
@@ -875,7 +871,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
if (rows == 0) {
pOperator->status = OP_EXEC_DONE;
} else if (pInfo->pUpdateInfo) {
- SSDataBlock* upRes = getUpdateDataBlock(pInfo, true); // TODO(liuyao) get invertible from plan
+ SSDataBlock* upRes = getUpdateDataBlock(pInfo, true);
if (upRes) {
pInfo->pUpdateRes = upRes;
if (upRes->info.type == STREAM_REPROCESS) {
@@ -894,7 +890,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHandle,
SArray* pTableIdList, STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo,
- STimeWindowAggSupp* pTwSup, int16_t tsColId) {
+ STimeWindowAggSupp* pTwSup) {
SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) {
@@ -939,8 +935,12 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
goto _error;
}
- pInfo->primaryTsIndex = tsColId;
- if (pSTInfo->interval.interval > 0) {
+ if (isSmaStream(pTableScanNode->triggerType)) {
+ pTwSup->waterMark = getSmaWaterMark(pSTInfo->interval.interval,
+ pTableScanNode->filesFactor);
+ }
+ pInfo->primaryTsIndex = 0; // pTableScanNode->tsColId;
+ if (pSTInfo->interval.interval > 0 && pDataReader) {
pInfo->pUpdateInfo = updateInfoInitP(&pSTInfo->interval, pTwSup->waterMark);
} else {
pInfo->pUpdateInfo = NULL;
@@ -1583,22 +1583,21 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
STR_TO_VARSTR(str, mr.me.name);
colDataAppend(pDst, count, str, false);
} else { // it is a tag value
- if (pDst->info.type == TSDB_DATA_TYPE_JSON) {
- const uint8_t* tmp = mr.me.ctbEntry.pTags;
- // TODO opt perf by realloc memory
- char* data = taosMemoryCalloc(kvRowLen(tmp) + 1, 1);
- if (data == NULL) {
- qError("%s failed to malloc memory, size:%d", GET_TASKID(pTaskInfo), kvRowLen(tmp) + 1);
- longjmp(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
- }
+ STagVal val = {0};
+ val.cid = pExprInfo[j].base.pParam[0].pCol->colId;
+ const char* p = metaGetTableTagVal(&mr.me, pDst->info.type, &val);
+
+ char *data = NULL;
+ if(pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL){
+ data = tTagValToData((const STagVal *)p, false);
+ }else {
+ data = (char*)p;
+ }
+ colDataAppend(pDst, count, data, (data == NULL));
- *data = TSDB_DATA_TYPE_JSON;
- memcpy(data + 1, tmp, kvRowLen(tmp));
- colDataAppend(pDst, count, data, false);
+ if(pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL
+ && IS_VAR_DATA_TYPE(((const STagVal *)p)->type) && data != NULL){
taosMemoryFree(data);
- } else {
- const char* p = metaGetTableTagVal(&mr.me, pExprInfo[j].base.pParam[0].pCol->colId);
- colDataAppend(pDst, count, p, (p == NULL));
}
}
}
@@ -1628,8 +1627,8 @@ static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) {
}
SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, SExprInfo* pExpr, int32_t numOfOutput,
- SSDataBlock* pResBlock, SArray* pColMatchInfo,
- STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo) {
+ SSDataBlock* pResBlock, SArray* pColMatchInfo, STableListInfo* pTableListInfo,
+ SExecTaskInfo* pTaskInfo) {
STagScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STagScanInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
if (pInfo == NULL || pOperator == NULL) {
diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c
index 97ee124a6dd26e8f9a8c077f3be9185ac4d8af78..41037e9f163ff476e6ba583d316357ade84e773a 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -789,9 +789,14 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM &&
- (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE || pInfo->twAggSup.calTrigger == 0)) {
- saveResult(pResult, tableGroupId, pUpdated);
+ if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
+ pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE_SMA) {
+ saveResult(pResult, tableGroupId, pUpdated);
+ }
+ if (pInfo->twAggSup.winMap) {
+ taosHashRemove(pInfo->twAggSup.winMap, &win.skey, sizeof(TSKEY));
+ }
}
TSKEY ekey = ascScan? win.ekey:win.skey;
@@ -836,9 +841,15 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM &&
- (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE || pInfo->twAggSup.calTrigger == 0)) {
- saveResult(pResult, tableGroupId, pUpdated);
+
+ if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE ||
+ pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE_SMA) {
+ saveResult(pResult, tableGroupId, pUpdated);
+ }
+ if (pInfo->twAggSup.winMap) {
+ taosHashRemove(pInfo->twAggSup.winMap, &win.skey, sizeof(TSKEY));
+ }
}
ekey = ascScan? nextWin.ekey:nextWin.skey;
@@ -1218,15 +1229,23 @@ static int32_t closeIntervalWindow(SHashObj *pHashMap, STimeWindowAggSupp *pSup,
void* key = taosHashGetKey(pIte, &keyLen);
uint64_t groupId = *(uint64_t*) key;
ASSERT(keyLen == GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY)));
- TSKEY ts = *(uint64_t*) ((char*)key + sizeof(uint64_t));
+ TSKEY ts = *(int64_t*) ((char*)key + sizeof(uint64_t));
SResultRowInfo dumyInfo;
dumyInfo.cur.pageId = -1;
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, ts, pInterval,
pInterval->precision, NULL);
if (win.ekey < pSup->maxTs - pSup->waterMark) {
+ if (pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE_SMA) {
+ if (taosHashGet(pSup->winMap, &win.skey, sizeof(TSKEY))) {
+ continue;
+ }
+ }
char keyBuf[GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))];
SET_RES_WINDOW_KEY(keyBuf, &ts, sizeof(TSKEY), groupId);
- taosHashRemove(pHashMap, keyBuf, keyLen);
+ if (pSup->calTrigger != STREAM_TRIGGER_AT_ONCE_SMA &&
+ pSup->calTrigger != STREAM_TRIGGER_WINDOW_CLOSE_SMA) {
+ taosHashRemove(pHashMap, keyBuf, keyLen);
+ }
SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
if (pos == NULL) {
return TSDB_CODE_OUT_OF_MEMORY;
@@ -1238,6 +1257,7 @@ static int32_t closeIntervalWindow(SHashObj *pHashMap, STimeWindowAggSupp *pSup,
taosMemoryFree(pos);
return TSDB_CODE_OUT_OF_MEMORY;
}
+ taosHashPut(pSup->winMap, &win.skey, sizeof(TSKEY), NULL, 0);
}
}
return TSDB_CODE_SUCCESS;
@@ -1291,9 +1311,12 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, MAIN_SCAN, pUpdated);
}
- closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, pClosed);
- finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pClosed, pInfo->binfo.rowCellInfoOffset);
- if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER__WINDOW_CLOSE) {
+ closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup,
+ &pInfo->interval, pClosed);
+ finalizeUpdatedResult(pOperator->numOfExprs, pInfo->aggSup.pResultBuf, pClosed,
+ pInfo->binfo.rowCellInfoOffset);
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE ||
+ pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE_SMA) {
taosArrayAddAll(pUpdated, pClosed);
}
@@ -2509,7 +2532,7 @@ int32_t closeSessionWindow(SArray *pWins, STimeWindowAggSupp *pTwSup, SArray *pC
return TSDB_CODE_OUT_OF_MEMORY;
}
pSeWin->isClosed = true;
- if (calTrigger == STREAM_TRIGGER__WINDOW_CLOSE) {
+ if (calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
pSeWin->isOutput = true;
}
}
@@ -2583,7 +2606,7 @@ static SSDataBlock* doStreamSessionWindowAgg(SOperatorInfo* pOperator) {
SArray* pUpdated = taosArrayInit(16, POINTER_BYTES);
copyUpdateResult(pStUpdated, pUpdated, pBInfo->pRes->info.groupId);
taosHashCleanup(pStUpdated);
- if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER__WINDOW_CLOSE) {
+ if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
taosArrayAddAll(pUpdated, pClosed);
}
diff --git a/source/libs/function/inc/builtins.h b/source/libs/function/inc/builtins.h
index 3bd0f35bf5f8b29cd585ec841363b091b02211c5..bc91875006b0c45162f52505084c9971b17e5429 100644
--- a/source/libs/function/inc/builtins.h
+++ b/source/libs/function/inc/builtins.h
@@ -26,22 +26,24 @@ typedef int32_t (*FTranslateFunc)(SFunctionNode* pFunc, char* pErrBuf, int32_t l
typedef EFuncDataRequired (*FFuncDataRequired)(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
typedef struct SBuiltinFuncDefinition {
- char name[FUNCTION_NAME_MAX_LENGTH];
- EFunctionType type;
- uint64_t classification;
- FTranslateFunc translateFunc;
- FFuncDataRequired dataRequiredFunc;
- FExecGetEnv getEnvFunc;
- FExecInit initFunc;
- FExecProcess processFunc;
+ const char* name;
+ EFunctionType type;
+ uint64_t classification;
+ FTranslateFunc translateFunc;
+ FFuncDataRequired dataRequiredFunc;
+ FExecGetEnv getEnvFunc;
+ FExecInit initFunc;
+ FExecProcess processFunc;
FScalarExecProcess sprocessFunc;
- FExecFinalize finalizeFunc;
- FExecProcess invertFunc;
- FExecCombine combineFunc;
+ FExecFinalize finalizeFunc;
+ FExecProcess invertFunc;
+ FExecCombine combineFunc;
+ const char* pPartialFunc;
+ const char* pMergeFunc;
} SBuiltinFuncDefinition;
extern const SBuiltinFuncDefinition funcMgtBuiltins[];
-extern const int funcMgtBuiltinsNum;
+extern const int funcMgtBuiltinsNum;
#ifdef __cplusplus
}
diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c
index 402368fc4bf3239b0971f251c3356b0b9caefc74..d68d774a6b31f62a01a7f027642211956690636d 100644
--- a/source/libs/function/src/builtins.c
+++ b/source/libs/function/src/builtins.c
@@ -102,6 +102,28 @@ static int32_t translateInOutStr(SFunctionNode* pFunc, char* pErrBuf, int32_t le
return TSDB_CODE_SUCCESS;
}
+static int32_t translateLogarithm(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
+ int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
+ if (1 != numOfParams && 2 != numOfParams) {
+ return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
+ }
+
+ uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
+ if (!IS_NUMERIC_TYPE(para1Type)) {
+ return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
+ }
+
+ if (2 == numOfParams) {
+ uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
+ if (!IS_NUMERIC_TYPE(para2Type)) {
+ return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
+ }
+ }
+
+ pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE};
+ return TSDB_CODE_SUCCESS;
+}
+
static int32_t translateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
@@ -155,14 +177,14 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param0
+ // param0
SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0);
if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
"The first parameter of PERCENTILE function can only be column");
}
- //param1
+ // param1
SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1);
if (pValue->datum.i < 0 || pValue->datum.i > 100) {
@@ -177,12 +199,12 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
- //set result type
+ // set result type
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE};
return TSDB_CODE_SUCCESS;
}
-static bool validAperventileAlgo(const SValueNode* pVal) {
+static bool validateApercentileAlgo(const SValueNode* pVal) {
if (TSDB_DATA_TYPE_BINARY != pVal->node.resType.type) {
return false;
}
@@ -196,14 +218,14 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param0
+ // param0
SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0);
if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
"The first parameter of APERCENTILE function can only be column");
}
- //param1
+ // param1
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
if (nodeType(pParamNode1) != QUERY_NODE_VALUE) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
@@ -222,7 +244,7 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param2
+ // param2
if (3 == numOfParams) {
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
if (!IS_VAR_DATA_TYPE(para3Type)) {
@@ -230,7 +252,7 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
}
SNode* pParamNode2 = nodesListGetNode(pFunc->pParameterList, 2);
- if (QUERY_NODE_VALUE != nodeType(pParamNode2) || !validAperventileAlgo((SValueNode*)pParamNode2)) {
+ if (QUERY_NODE_VALUE != nodeType(pParamNode2) || !validateApercentileAlgo((SValueNode*)pParamNode2)) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
"Third parameter algorithm of apercentile must be 'default' or 't-digest'");
}
@@ -262,14 +284,14 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param0
+ // param0
SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0);
if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
"The first parameter of TOP/BOTTOM function can only be column");
}
- //param1
+ // param1
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
if (nodeType(pParamNode1) != QUERY_NODE_VALUE) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
@@ -286,7 +308,7 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
pValue->notReserved = true;
- //set result type
+ // set result type
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
return TSDB_CODE_SUCCESS;
@@ -437,6 +459,18 @@ static int32_t translateHLL(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
return TSDB_CODE_SUCCESS;
}
+static bool validateStateOper(const SValueNode* pVal) {
+ if (TSDB_DATA_TYPE_BINARY != pVal->node.resType.type) {
+ return false;
+ }
+ return (0 == strcasecmp(varDataVal(pVal->datum.p), "GT") ||
+ 0 == strcasecmp(varDataVal(pVal->datum.p), "GE") ||
+ 0 == strcasecmp(varDataVal(pVal->datum.p), "LT") ||
+ 0 == strcasecmp(varDataVal(pVal->datum.p), "LE") ||
+ 0 == strcasecmp(varDataVal(pVal->datum.p), "EQ") ||
+ 0 == strcasecmp(varDataVal(pVal->datum.p), "NE"));
+}
+
static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
if (3 != numOfParams) {
@@ -463,6 +497,12 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
SValueNode* pValue = (SValueNode*)pParamNode;
+ if (i == 1 && !validateStateOper(pValue)) {
+ return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
+ "Second parameter of STATECOUNT function"
+ "must be one of the following: 'GE', 'GT', 'LE', 'LT', 'EQ', 'NE'");
+ }
+
pValue->notReserved = true;
}
@@ -503,6 +543,16 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
SValueNode* pValue = (SValueNode*)pParamNode;
+ if (i == 1 && !validateStateOper(pValue)) {
+ return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
+ "Second parameter of STATEDURATION function"
+ "must be one of the following: 'GE', 'GT', 'LE', 'LT', 'EQ', 'NE'");
+ } else if (i == 3 && pValue->datum.i == 0) {
+ return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
+ "STATEDURATION function time unit parameter should be greater than db precision");
+ }
+
+
pValue->notReserved = true;
}
@@ -658,8 +708,8 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (pValue->datum.i < ((i > 1) ? 0 : 1) || pValue->datum.i > 100) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
- "TAIL function second parameter should be in range [1, 100], "
- "third parameter should be in range [0, 100]");
+ "TAIL function second parameter should be in range [1, 100], "
+ "third parameter should be in range [0, 100]");
}
pValue->notReserved = true;
@@ -720,7 +770,7 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param0
+ // param0
SNode* pParamNode0 = nodesListGetNode(pFunc->pParameterList, 0);
if (nodeType(pParamNode0) != QUERY_NODE_COLUMN) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
@@ -728,12 +778,11 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
}
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
- if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) &&
- TSDB_DATA_TYPE_BOOL != colType) {
+ if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
- //param1
+ // param1
if (numOfParams == 2) {
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
if (!IS_INTEGER_TYPE(paraType)) {
@@ -788,11 +837,20 @@ static int32_t translateConcatImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
int32_t resultBytes = 0;
int32_t sepBytes = 0;
+ //concat_ws separator should be constant string
+ if (hasSep) {
+ SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
+ if (nodeType(pPara) != QUERY_NODE_VALUE) {
+ return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
+ "The first parameter of CONCAT_WS function can only be constant string");
+ }
+ }
+
/* For concat/concat_ws function, if params have NCHAR type, promote the final result to NCHAR */
for (int32_t i = 0; i < numOfParams; ++i) {
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
- if (!IS_VAR_DATA_TYPE(paraType)) {
+ if (!IS_VAR_DATA_TYPE(paraType) && TSDB_DATA_TYPE_NULL != paraType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
if (TSDB_DATA_TYPE_NCHAR == paraType) {
@@ -851,7 +909,7 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
if (3 == numOfParams) {
SExprNode* p2 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 2);
- uint8_t para2Type = p2->resType.type;
+ uint8_t para2Type = p2->resType.type;
if (!IS_INTEGER_TYPE(para2Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
@@ -892,16 +950,108 @@ static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
return TSDB_CODE_SUCCESS;
}
+/* Following are valid ISO-8601 timezone format:
+ * 1 z/Z
+ * 2 ±hh:mm
+ * 3 ±hhmm
+ * 4 ±hh
+ *
+ */
+
+static bool validateTimezoneFormat(const SValueNode* pVal) {
+ if (TSDB_DATA_TYPE_BINARY != pVal->node.resType.type) {
+ return false;
+ }
+
+ char *tz = varDataVal(pVal->datum.p);
+ int32_t len = varDataLen(pVal->datum.p);
+
+ if (len == 0) {
+ return false;
+ } else if (len == 1 && (tz[0] == 'z' || tz[0] == 'Z')) {
+ return true;
+ } else if ((tz[0] == '+' || tz[0] == '-')) {
+ switch (len) {
+ case 3:
+ case 5: {
+ for (int32_t i = 1; i < len; ++i) {
+ if (!isdigit(tz[i])) {
+ return false;
+ }
+ }
+ break;
+ }
+ case 6: {
+ for (int32_t i = 1; i < len; ++i) {
+ if (i == 3) {
+ if (tz[i] != ':') {
+ return false;
+ }
+ continue;
+ }
+ if (!isdigit(tz[i])) {
+ return false;
+ }
+ }
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+void static addTimezoneParam(SNodeList* pList) {
+ char buf[6] = {0};
+ time_t t = taosTime(NULL);
+ struct tm *tmInfo = taosLocalTime(&t, NULL);
+ strftime(buf, sizeof(buf), "%z", tmInfo);
+ int32_t len = (int32_t)strlen(buf);
+
+ SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
+ pVal->literal = strndup(buf, len);
+ pVal->isDuration =false;
+ pVal->translate = true;
+ pVal->node.resType.type = TSDB_DATA_TYPE_BINARY;
+ pVal->node.resType.bytes = len + VARSTR_HEADER_SIZE;
+ pVal->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
+ pVal->datum.p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE +1);
+ varDataSetLen(pVal->datum.p, len);
+ strncpy(varDataVal(pVal->datum.p), pVal->literal, len);
+
+ nodesListAppend(pList, pVal);
+}
+
static int32_t translateToIso8601(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
- if (1 != LIST_LENGTH(pFunc->pParameterList)) {
+ int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
+ if (1 != numOfParams && 2 != numOfParams) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
+ //param0
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
if (!IS_INTEGER_TYPE(paraType) && TSDB_DATA_TYPE_TIMESTAMP != paraType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
+ //param1
+ if (numOfParams == 2) {
+ SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1);
+
+ if (!validateTimezoneFormat(pValue)) {
+ return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
+ "Invalid timzone format");
+ }
+ } else { //add default client timezone
+ addTimezoneParam(pFunc->pParameterList);
+ }
+
+ //set result type
pFunc->node.resType = (SDataType){.bytes = 64, .type = TSDB_DATA_TYPE_BINARY};
return TSDB_CODE_SUCCESS;
}
@@ -992,6 +1142,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.finalizeFunc = functionFinalize,
.invertFunc = countInvertFunction,
.combineFunc = combineFunction,
+ // .pPartialFunc = "count",
+ // .pMergeFunc = "sum"
},
{
.name = "sum",
@@ -1283,7 +1435,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.name = "log",
.type = FUNCTION_TYPE_LOG,
.classification = FUNC_MGT_SCALAR_FUNC,
- .translateFunc = translateIn2NumOutDou,
+ .translateFunc = translateLogarithm,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = logFunction,
diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c
index 6f7ace45b3cf87f88f9dab79924d0e6aa2128205..be18150234c5b1d7dc4064dfb561900290e3722b 100644
--- a/source/libs/function/src/builtinsimpl.c
+++ b/source/libs/function/src/builtinsimpl.c
@@ -1655,8 +1655,8 @@ bool leastSQRFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInf
pInfo->startVal = IS_FLOAT_TYPE(pCtx->param[1].param.nType) ? pCtx->param[1].param.d :
(double)pCtx->param[1].param.i;
- pInfo->stepVal = IS_FLOAT_TYPE(pCtx->param[1].param.nType) ? pCtx->param[2].param.d :
- (double)pCtx->param[1].param.i;
+ pInfo->stepVal = IS_FLOAT_TYPE(pCtx->param[2].param.nType) ? pCtx->param[2].param.d :
+ (double)pCtx->param[2].param.i;
return true;
}
@@ -1763,6 +1763,11 @@ int32_t leastSQRFunction(SqlFunctionCtx* pCtx) {
}
break;
}
+ case TSDB_DATA_TYPE_NULL: {
+ GET_RES_INFO(pCtx)->isNullRes = 1;
+ numOfElem = 1;
+ break;
+ }
default:
break;
@@ -1806,7 +1811,7 @@ int32_t leastSQRFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
size_t len = snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{slop:%.6lf, intercept:%.6lf}", param[0][2], param[1][2]);
varDataSetLen(buf, len);
- colDataAppend(pCol, currentRow, buf, false);
+ colDataAppend(pCol, currentRow, buf, pResInfo->isNullRes);
return pResInfo->numOfRes;
}
diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c
index c2b325bc928be50ac908c103bb6a14a907156b39..611ae8d81fdc681c28936456b5b46c0a7e09d4c0 100644
--- a/source/libs/function/src/functionMgt.c
+++ b/source/libs/function/src/functionMgt.c
@@ -199,3 +199,81 @@ bool fmIsInvertible(int32_t funcId) {
}
return res;
}
+
+static SFunctionNode* createFunction(const char* pName, SNodeList* pParameterList) {
+ SFunctionNode* pFunc = nodesMakeNode(QUERY_NODE_FUNCTION);
+ if (NULL == pFunc) {
+ return NULL;
+ }
+ strcpy(pFunc->functionName, pName);
+ pFunc->pParameterList = pParameterList;
+ char msg[64] = {0};
+ if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pFunc, msg, sizeof(msg))) {
+ nodesDestroyNode(pFunc);
+ return NULL;
+ }
+ return pFunc;
+}
+
+static SColumnNode* createColumnByFunc(const SFunctionNode* pFunc) {
+ SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
+ if (NULL == pCol) {
+ return NULL;
+ }
+ strcpy(pCol->colName, pFunc->node.aliasName);
+ pCol->node.resType = pFunc->node.resType;
+ return pCol;
+}
+
+bool fmIsDistExecFunc(int32_t funcId) {
+ if (!fmIsVectorFunc(funcId)) {
+ return true;
+ }
+ return (NULL != funcMgtBuiltins[funcId].pPartialFunc && NULL != funcMgtBuiltins[funcId].pMergeFunc);
+}
+
+static int32_t createPartialFunction(const SFunctionNode* pSrcFunc, SFunctionNode** pPartialFunc) {
+ SNodeList* pParameterList = nodesCloneList(pSrcFunc->pParameterList);
+ if (NULL == pParameterList) {
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ *pPartialFunc = createFunction(funcMgtBuiltins[pSrcFunc->funcId].pPartialFunc, pParameterList);
+ if (NULL == *pPartialFunc) {
+ nodesDestroyList(pParameterList);
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ snprintf((*pPartialFunc)->node.aliasName, sizeof((*pPartialFunc)->node.aliasName), "%s.%p",
+ (*pPartialFunc)->functionName, pSrcFunc);
+ return TSDB_CODE_SUCCESS;
+}
+
+static int32_t createMergeFunction(const SFunctionNode* pSrcFunc, const SFunctionNode* pPartialFunc,
+ SFunctionNode** pMergeFunc) {
+ SNodeList* pParameterList = NULL;
+ nodesListMakeStrictAppend(&pParameterList, createColumnByFunc(pPartialFunc));
+ *pMergeFunc = createFunction(funcMgtBuiltins[pSrcFunc->funcId].pMergeFunc, pParameterList);
+ if (NULL == *pMergeFunc) {
+ nodesDestroyList(pParameterList);
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ strcpy((*pMergeFunc)->node.aliasName, pSrcFunc->node.aliasName);
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc) {
+ if (!fmIsDistExecFunc(pFunc->funcId)) {
+ return TSDB_CODE_FAILED;
+ }
+
+ int32_t code = createPartialFunction(pFunc, pPartialFunc);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = createMergeFunction(pFunc, *pPartialFunc, pMergeFunc);
+ }
+
+ if (TSDB_CODE_SUCCESS != code) {
+ nodesDestroyNode(*pPartialFunc);
+ nodesDestroyNode(*pMergeFunc);
+ }
+
+ return code;
+}
diff --git a/source/libs/index/CMakeLists.txt b/source/libs/index/CMakeLists.txt
index e55b004972d841a2049dc0474dbf3343b1cc300a..75eac2430f70c7a4cfc215eee5515a392d1bcd40 100644
--- a/source/libs/index/CMakeLists.txt
+++ b/source/libs/index/CMakeLists.txt
@@ -12,6 +12,7 @@ target_link_libraries(
PUBLIC os
PUBLIC util
PUBLIC common
+ PUBLIC vnode
PUBLIC nodes
PUBLIC scalar
PUBLIC function
diff --git a/source/libs/index/inc/indexCache.h b/source/libs/index/inc/indexCache.h
index 1046a04db34062367fb84bef2c6b292da6b147d5..6e68163d74677ad0b7c9df944b73d2ebe602d93a 100644
--- a/source/libs/index/inc/indexCache.h
+++ b/source/libs/index/inc/indexCache.h
@@ -36,6 +36,7 @@ typedef struct MemTable {
typedef struct IndexCache {
T_REF_DECLARE()
MemTable *mem, *imm;
+ int32_t merging;
SIndex* index;
char* colName;
int64_t version;
diff --git a/source/libs/index/inc/indexComm.h b/source/libs/index/inc/indexComm.h
index 3066fd1c2c57481cc80a6b19a7dc2de1a9b4d6cc..c338300b57d1c5d2d570130f596303503ee30187 100644
--- a/source/libs/index/inc/indexComm.h
+++ b/source/libs/index/inc/indexComm.h
@@ -33,8 +33,9 @@ typedef enum { MATCH, CONTINUE, BREAK } TExeCond;
typedef TExeCond (*_cache_range_compare)(void* a, void* b, int8_t type);
-TExeCond tCompare(__compar_fn_t func, int8_t cmpType, void* a, void* b, int8_t dType);
-TExeCond tDoCompare(__compar_fn_t func, int8_t cmpType, void* a, void* b);
+__compar_fn_t indexGetCompar(int8_t type);
+TExeCond tCompare(__compar_fn_t func, int8_t cmpType, void* a, void* b, int8_t dType);
+TExeCond tDoCompare(__compar_fn_t func, int8_t cmpType, void* a, void* b);
_cache_range_compare indexGetCompare(RangeType ty);
diff --git a/source/libs/index/inc/indexInt.h b/source/libs/index/inc/indexInt.h
index 81d43daf133ab0613b3cc56ec68d82e87bc0326c..24a4e99970692b202ab36fd1d1a83a45a09bcaa4 100644
--- a/source/libs/index/inc/indexInt.h
+++ b/source/libs/index/inc/indexInt.h
@@ -131,8 +131,7 @@ typedef struct TFileCacheKey {
char* colName;
int32_t nColName;
} ICacheKey;
-
-int indexFlushCacheToTFile(SIndex* sIdx, void*);
+int indexFlushCacheToTFile(SIndex* sIdx, void*, bool quit);
int64_t indexAddRef(void* p);
int32_t indexRemoveRef(int64_t ref);
diff --git a/source/libs/index/src/index.c b/source/libs/index/src/index.c
index 8584d95bf26bc2a586e0e5842ab8c4e5b5572bbd..ba3aea969f6c8a5214a3999a7d4ca2c68ec503ac 100644
--- a/source/libs/index/src/index.c
+++ b/source/libs/index/src/index.c
@@ -80,7 +80,7 @@ static TdThreadOnce isInit = PTHREAD_ONCE_INIT;
static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* term, SArray** result);
static void indexInterResultsDestroy(SArray* results);
-static int indexMergeFinalResults(SArray* interResults, EIndexOperatorType oType, SArray* finalResult);
+static int indexMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out);
static int indexGenTFile(SIndex* index, IndexCache* cache, SArray* batch);
@@ -150,6 +150,7 @@ void indexClose(SIndex* sIdx) {
indexCacheForceToMerge((void*)(*pCache));
indexInfo("%s wait to merge", (*pCache)->colName);
indexWait((void*)(sIdx));
+ indexInfo("%s finish to wait", (*pCache)->colName);
iter = taosHashIterate(sIdx->colObj, iter);
indexCacheUnRef(*pCache);
}
@@ -386,21 +387,21 @@ static void indexInterResultsDestroy(SArray* results) {
taosArrayDestroy(results);
}
-static int indexMergeFinalResults(SArray* interResults, EIndexOperatorType oType, SArray* fResults) {
+static int indexMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out) {
// refactor, merge interResults into fResults by oType
- for (int i = 0; i < taosArrayGetSize(interResults); i--) {
- SArray* t = taosArrayGetP(interResults, i);
+ for (int i = 0; i < taosArrayGetSize(in); i--) {
+ SArray* t = taosArrayGetP(in, i);
taosArraySort(t, uidCompare);
taosArrayRemoveDuplicate(t, uidCompare, NULL);
}
if (oType == MUST) {
- iIntersection(interResults, fResults);
+ iIntersection(in, out);
} else if (oType == SHOULD) {
- iUnion(interResults, fResults);
+ iUnion(in, out);
} else if (oType == NOT) {
// just one column index, enhance later
- taosArrayAddAll(fResults, interResults);
+ // taosArrayAddAll(fResults, interResults);
// not use currently
}
return 0;
@@ -454,7 +455,7 @@ static void indexDestroyFinalResult(SArray* result) {
taosArrayDestroy(result);
}
-int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
+int indexFlushCacheToTFile(SIndex* sIdx, void* cache, bool quit) {
if (sIdx == NULL) {
return -1;
}
@@ -462,7 +463,10 @@ int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
int64_t st = taosGetTimestampUs();
- IndexCache* pCache = (IndexCache*)cache;
+ IndexCache* pCache = (IndexCache*)cache;
+
+ while (quit && atomic_load_32(&pCache->merging) == 1) {
+ }
TFileReader* pReader = tfileGetReaderByCol(sIdx->tindex, pCache->suid, pCache->colName);
if (pReader == NULL) {
indexWarn("empty tfile reader found");
@@ -473,9 +477,9 @@ int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
indexError("%p immtable is empty, ignore merge opera", pCache);
indexCacheDestroyImm(pCache);
tfileReaderUnRef(pReader);
- if (sIdx->quit) {
+ atomic_store_32(&pCache->merging, 0);
+ if (quit) {
indexPost(sIdx);
- // indexCacheBroadcast(pCache);
}
indexReleaseRef(sIdx->refId);
return 0;
@@ -536,7 +540,8 @@ int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
} else {
indexInfo("success to merge , time cost: %" PRId64 "ms", cost / 1000);
}
- if (sIdx->quit) {
+ atomic_store_32(&pCache->merging, 0);
+ if (quit) {
indexPost(sIdx);
}
indexReleaseRef(sIdx->refId);
@@ -605,6 +610,7 @@ static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
taosThreadMutexLock(&tf->mtx);
tfileCachePut(tf->cache, &key, reader);
taosThreadMutexUnlock(&tf->mtx);
+
return ret;
END:
if (tw != NULL) {
diff --git a/source/libs/index/src/indexCache.c b/source/libs/index/src/indexCache.c
index 3b33006452989fbe8f69155f30041d6345b1d1e0..4e7be245ef7fb0a4c383a0abf0b242ebbb46522c 100644
--- a/source/libs/index/src/indexCache.c
+++ b/source/libs/index/src/indexCache.c
@@ -494,16 +494,19 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
// TODO: wake up by condition variable
indexCacheWait(cache);
} else {
- bool notifyQuit = cache->occupiedMem >= MEM_SIGNAL_QUIT ? true : false;
+ bool quit = cache->occupiedMem >= MEM_SIGNAL_QUIT ? true : false;
indexCacheRef(cache);
cache->imm = cache->mem;
cache->mem = indexInternalCacheCreate(cache->type);
cache->mem->pCache = cache;
cache->occupiedMem = 0;
+ if (quit == false) {
+ atomic_store_32(&cache->merging, 1);
+ }
// sched to merge
// unref cache in bgwork
- indexCacheSchedToMerge(cache, notifyQuit);
+ indexCacheSchedToMerge(cache, quit);
}
}
}
@@ -725,9 +728,9 @@ static void doMergeWork(SSchedMsg* msg) {
IndexCache* pCache = msg->ahandle;
SIndex* sidx = (SIndex*)pCache->index;
- sidx->quit = msg->thandle ? true : false;
+ int quit = msg->thandle ? true : false;
taosMemoryFree(msg->thandle);
- indexFlushCacheToTFile(sidx, pCache);
+ indexFlushCacheToTFile(sidx, pCache, quit);
}
static bool indexCacheIteratorNext(Iterate* itera) {
SSkipListIterator* iter = itera->iter;
diff --git a/source/libs/index/src/indexComm.c b/source/libs/index/src/indexComm.c
index 78c7babb681e44629281f0ffd6ea6ba835495b5b..5310e1c3451dee18bd3a31922b2ce14f752ebc1d 100644
--- a/source/libs/index/src/indexComm.c
+++ b/source/libs/index/src/indexComm.c
@@ -75,7 +75,7 @@ char* indexInt2str(int64_t val, char* dst, int radix) {
;
return dst - 1;
}
-static __compar_fn_t indexGetCompar(int8_t type) {
+__compar_fn_t indexGetCompar(int8_t type) {
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
return (__compar_fn_t)strcmp;
}
@@ -182,6 +182,9 @@ TExeCond tDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
case QUERY_GREATER_EQUAL: {
if (ret >= 0) return MATCH;
}
+ case QUERY_TERM: {
+ if (ret == 0) return MATCH;
+ }
}
return CONTINUE;
}
diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c
index b882caa168a3b89dcd037ee34eefa2f8b82bd904..766746dd2a695076d3ab524076bfa143ceba1c54 100644
--- a/source/libs/index/src/indexFilter.c
+++ b/source/libs/index/src/indexFilter.c
@@ -14,11 +14,13 @@
*/
#include "index.h"
+#include "indexComm.h"
#include "indexInt.h"
#include "nodes.h"
#include "querynodes.h"
#include "scalar.h"
#include "tdatablock.h"
+#include "vnode.h"
// clang-format off
#define SIF_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0)
@@ -259,10 +261,52 @@ static int32_t sifExecFunction(SFunctionNode *node, SIFCtx *ctx, SIFParam *outpu
indexError("index-filter not support buildin function");
return TSDB_CODE_QRY_INVALID_INPUT;
}
+
+typedef int (*Filter)(void *a, void *b, int16_t dtype);
+
+int sifGreaterThan(void *a, void *b, int16_t dtype) {
+ __compar_fn_t func = indexGetCompar(dtype);
+ return tDoCompare(func, QUERY_GREATER_THAN, a, b);
+}
+int sifGreaterEqual(void *a, void *b, int16_t dtype) {
+ __compar_fn_t func = indexGetCompar(dtype);
+ return tDoCompare(func, QUERY_GREATER_EQUAL, a, b);
+}
+int sifLessEqual(void *a, void *b, int16_t dtype) {
+ __compar_fn_t func = indexGetCompar(dtype);
+ return tDoCompare(func, QUERY_LESS_EQUAL, a, b);
+}
+int sifLessThan(void *a, void *b, int16_t dtype) {
+ __compar_fn_t func = indexGetCompar(dtype);
+ return (int)tDoCompare(func, QUERY_LESS_THAN, a, b);
+}
+int sifEqual(void *a, void *b, int16_t dtype) {
+ __compar_fn_t func = indexGetCompar(dtype);
+ return (int)tDoCompare(func, QUERY_TERM, a, b);
+}
+static Filter sifGetFilterFunc(EIndexQueryType type, bool *reverse) {
+ if (type == QUERY_LESS_EQUAL || type == QUERY_LESS_THAN) {
+ *reverse = true;
+ } else {
+ *reverse = false;
+ }
+ if (type == QUERY_LESS_EQUAL)
+ return sifLessEqual;
+ else if (type == QUERY_LESS_THAN)
+ return sifLessThan;
+ else if (type == QUERY_GREATER_EQUAL)
+ return sifGreaterEqual;
+ else if (type == QUERY_GREATER_THAN)
+ return sifGreaterThan;
+ else if (type == QUERY_TERM) {
+ return sifEqual;
+ }
+ return NULL;
+}
static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFParam *output) {
-#ifdef USE_INVERTED_INDEX
SIndexMetaArg *arg = &output->arg;
- SIndexTerm * tm = indexTermCreate(arg->suid, DEFAULT, left->colValType, left->colName, strlen(left->colName),
+#ifdef USE_INVERTED_INDEX
+ SIndexTerm *tm = indexTermCreate(arg->suid, DEFAULT, left->colValType, left->colName, strlen(left->colName),
right->condValue, strlen(right->condValue));
if (tm == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
@@ -278,8 +322,22 @@ static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFP
indexMultiTermQueryDestroy(mtm);
return ret;
#else
- return 0;
+ EIndexQueryType qtype = 0;
+ SIF_ERR_RET(sifGetFuncFromSql(operType, &qtype));
+ bool reverse;
+ Filter filterFunc = sifGetFilterFunc(qtype, &reverse);
+
+ SMetaFltParam param = {.suid = arg->suid,
+ .cid = left->colId,
+ .type = left->colValType,
+ .val = right->condValue,
+ .reverse = reverse,
+ .filterFunc = filterFunc};
+
+ int ret = metaFilteTableIds(arg->metaEx, ¶m, output->result);
+ return ret;
#endif
+ return 0;
}
static int32_t sifLessThanFunc(SIFParam *left, SIFParam *right, SIFParam *output) {
diff --git a/source/libs/index/src/indexJson.c b/source/libs/index/src/indexJson.c
index de88ff3c8ae287eda194fd4c9d7bff7080edd15c..a2f0563d470f30cf989f71bf068c16e38b236ce4 100644
--- a/source/libs/index/src/indexJson.c
+++ b/source/libs/index/src/indexJson.c
@@ -24,8 +24,8 @@ int tIndexJsonPut(SIndexJson *index, SIndexJsonMultiTerm *terms, uint64_t uid) {
SIndexJsonTerm *p = taosArrayGetP(terms, i);
INDEX_TYPE_ADD_EXTERN_TYPE(p->colType, TSDB_DATA_TYPE_JSON);
}
- return indexPut(index, terms, uid);
// handle put
+ return indexPut(index, terms, uid);
}
int tIndexJsonSearch(SIndexJson *index, SIndexJsonMultiTermQuery *tq, SArray *result) {
@@ -34,11 +34,11 @@ int tIndexJsonSearch(SIndexJson *index, SIndexJsonMultiTermQuery *tq, SArray *re
SIndexJsonTerm *p = taosArrayGetP(terms, i);
INDEX_TYPE_ADD_EXTERN_TYPE(p->colType, TSDB_DATA_TYPE_JSON);
}
- return indexSearch(index, tq, result);
// handle search
+ return indexSearch(index, tq, result);
}
void tIndexJsonClose(SIndexJson *index) {
- return indexClose(index);
// handle close
+ return indexClose(index);
}
diff --git a/source/libs/index/test/jsonUT.cc b/source/libs/index/test/jsonUT.cc
index cd5a5d9b0f192883f67e9dfecdbcb3854669fdf3..48ce8839c459bb2c523d710f1804346f2bede33a 100644
--- a/source/libs/index/test/jsonUT.cc
+++ b/source/libs/index/test/jsonUT.cc
@@ -51,6 +51,7 @@ class JsonEnv : public ::testing::Test {
tIndexJsonClose(index);
indexOptsDestroy(opts);
printf("destory\n");
+ taosMsleep(1000);
}
SIndexJsonOpts* opts;
SIndexJson* index;
diff --git a/source/libs/monitor/src/monMsg.c b/source/libs/monitor/src/monMsg.c
index e106cbd428b48f7751785b019e21f8c5e547969c..944a7b54750c9e8850d0fe124f36561c54a6630e 100644
--- a/source/libs/monitor/src/monMsg.c
+++ b/source/libs/monitor/src/monMsg.c
@@ -556,4 +556,50 @@ int32_t tDeserializeSMonMloadInfo(void *buf, int32_t bufLen, SMonMloadInfo *pInf
tDecoderClear(&decoder);
return 0;
-}
\ No newline at end of file
+}
+
+
+int32_t tSerializeSQnodeLoad(void *buf, int32_t bufLen, SQnodeLoad *pInfo) {
+ SEncoder encoder = {0};
+ tEncoderInit(&encoder, buf, bufLen);
+
+ if (tStartEncode(&encoder) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfProcessedQuery) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfProcessedCQuery) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfProcessedFetch) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfProcessedDrop) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfProcessedHb) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->cacheDataSize) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfQueryInQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->numOfFetchInQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->timeInQueryQueue) < 0) return -1;
+ if (tEncodeI64(&encoder, pInfo->timeInFetchQueue) < 0) return -1;
+ tEndEncode(&encoder);
+
+ int32_t tlen = encoder.pos;
+ tEncoderClear(&encoder);
+ return tlen;
+}
+
+int32_t tDeserializeSQnodeLoad(void *buf, int32_t bufLen, SQnodeLoad *pInfo) {
+ SDecoder decoder = {0};
+ tDecoderInit(&decoder, buf, bufLen);
+
+ if (tStartDecode(&decoder) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfProcessedQuery) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfProcessedCQuery) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfProcessedFetch) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfProcessedDrop) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfProcessedHb) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->cacheDataSize) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfQueryInQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->numOfFetchInQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->timeInQueryQueue) < 0) return -1;
+ if (tDecodeI64(&decoder, &pInfo->timeInFetchQueue) < 0) return -1;
+ tEndDecode(&decoder);
+
+ tDecoderClear(&decoder);
+ return 0;
+}
+
+
diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c
index 68d3741b482105d02d4751847f01f3fbdc32986f..94661388cb90e8ac41a7cca5e24871db8b8d7d98 100644
--- a/source/libs/nodes/src/nodesCloneFuncs.c
+++ b/source/libs/nodes/src/nodesCloneFuncs.c
@@ -142,14 +142,16 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
break;
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
- case TSDB_DATA_TYPE_VARBINARY:
- pDst->datum.p = taosMemoryMalloc(pSrc->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
+ case TSDB_DATA_TYPE_VARBINARY:{
+ int32_t len = varDataTLen(pSrc->datum.p) + 1;
+ pDst->datum.p = taosMemoryCalloc(1, len);
if (NULL == pDst->datum.p) {
nodesDestroyNode(pDst);
return NULL;
}
- memcpy(pDst->datum.p, pSrc->datum.p, pSrc->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
+ memcpy(pDst->datum.p, pSrc->datum.p, len);
break;
+ }
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
@@ -305,6 +307,7 @@ static SNode* logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
CLONE_NODE_FIELD(pConditions);
CLONE_NODE_LIST_FIELD(pChildren);
COPY_SCALAR_FIELD(optimizedFlag);
+ COPY_SCALAR_FIELD(precision);
return (SNode*)pDst;
}
@@ -328,6 +331,10 @@ static SNode* logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
COPY_SCALAR_FIELD(intervalUnit);
COPY_SCALAR_FIELD(slidingUnit);
CLONE_NODE_FIELD(pTagCond);
+ COPY_SCALAR_FIELD(triggerType);
+ COPY_SCALAR_FIELD(watermark);
+ COPY_SCALAR_FIELD(tsColId);
+ COPY_SCALAR_FIELD(filesFactor);
return (SNode*)pDst;
}
@@ -366,7 +373,14 @@ static SNode* logicVnodeModifCopy(const SVnodeModifLogicNode* pSrc, SVnodeModifL
static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
COPY_SCALAR_FIELD(srcGroupId);
- COPY_SCALAR_FIELD(precision);
+ return (SNode*)pDst;
+}
+
+static SNode* logicMergeCopy(const SMergeLogicNode* pSrc, SMergeLogicNode* pDst) {
+ COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
+ CLONE_NODE_LIST_FIELD(pMergeKeys);
+ COPY_SCALAR_FIELD(numOfChannels);
+ COPY_SCALAR_FIELD(srcGroupId);
return (SNode*)pDst;
}
@@ -384,6 +398,7 @@ static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pD
CLONE_NODE_FIELD(pStateExpr);
COPY_SCALAR_FIELD(triggerType);
COPY_SCALAR_FIELD(watermark);
+ COPY_SCALAR_FIELD(filesFactor);
return (SNode*)pDst;
}
@@ -529,6 +544,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
+ case QUERY_NODE_LOGIC_PLAN_MERGE:
+ return logicMergeCopy((const SMergeLogicNode*)pNode, (SMergeLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_WINDOW:
return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_FILL:
diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c
index 78710569cbe6718c6fa899448a1cab11edebaab3..4bce6381cde1cda187d11f5691bdb35b4e3dfca6 100644
--- a/source/libs/nodes/src/nodesCodeFuncs.c
+++ b/source/libs/nodes/src/nodesCodeFuncs.c
@@ -190,6 +190,8 @@ const char* nodesNodeName(ENodeType type) {
return "LogicVnodeModif";
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
return "LogicExchange";
+ case QUERY_NODE_LOGIC_PLAN_MERGE:
+ return "LogicMerge";
case QUERY_NODE_LOGIC_PLAN_WINDOW:
return "LogicWindow";
case QUERY_NODE_LOGIC_PLAN_FILL:
@@ -220,6 +222,8 @@ const char* nodesNodeName(ENodeType type) {
return "PhysiAgg";
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
return "PhysiExchange";
+ case QUERY_NODE_PHYSICAL_PLAN_MERGE:
+ return "PhysiMerge";
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return "PhysiSort";
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
@@ -596,7 +600,6 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
}
static const char* jkExchangeLogicPlanSrcGroupId = "SrcGroupId";
-static const char* jkExchangeLogicPlanSrcPrecision = "Precision";
static int32_t logicExchangeNodeToJson(const void* pObj, SJson* pJson) {
const SExchangeLogicNode* pNode = (const SExchangeLogicNode*)pObj;
@@ -605,9 +608,6 @@ static int32_t logicExchangeNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkExchangeLogicPlanSrcGroupId, pNode->srcGroupId);
}
- if (TSDB_CODE_SUCCESS == code) {
- code = tjsonAddIntegerToObject(pJson, jkExchangeLogicPlanSrcPrecision, pNode->precision);
- }
return code;
}
@@ -619,8 +619,144 @@ static int32_t jsonToLogicExchangeNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkExchangeLogicPlanSrcGroupId, &pNode->srcGroupId);
}
+
+ return code;
+}
+
+static const char* jkMergeLogicPlanMergeKeys = "MergeKeys";
+static const char* jkMergeLogicPlanNumOfChannels = "NumOfChannels";
+static const char* jkMergeLogicPlanSrcGroupId = "SrcGroupId";
+
+static int32_t logicMergeNodeToJson(const void* pObj, SJson* pJson) {
+ const SMergeLogicNode* pNode = (const SMergeLogicNode*)pObj;
+
+ int32_t code = logicPlanNodeToJson(pObj, pJson);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = nodeListToJson(pJson, jkMergeLogicPlanMergeKeys, pNode->pMergeKeys);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkMergeLogicPlanNumOfChannels, pNode->numOfChannels);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkMergeLogicPlanSrcGroupId, pNode->srcGroupId);
+ }
+
+ return code;
+}
+
+static int32_t jsonToLogicMergeNode(const SJson* pJson, void* pObj) {
+ SMergeLogicNode* pNode = (SMergeLogicNode*)pObj;
+
+ int32_t code = jsonToLogicPlanNode(pJson, pObj);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = jsonToNodeList(pJson, jkMergeLogicPlanMergeKeys, &pNode->pMergeKeys);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetIntValue(pJson, jkMergeLogicPlanNumOfChannels, &pNode->numOfChannels);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetIntValue(pJson, jkMergeLogicPlanSrcGroupId, &pNode->srcGroupId);
+ }
+
+ return code;
+}
+
+static const char* jkWindowLogicPlanWinType = "WinType";
+static const char* jkWindowLogicPlanFuncs = "Funcs";
+static const char* jkWindowLogicPlanInterval = "Interval";
+static const char* jkWindowLogicPlanOffset = "Offset";
+static const char* jkWindowLogicPlanSliding = "Sliding";
+static const char* jkWindowLogicPlanIntervalUnit = "IntervalUnit";
+static const char* jkWindowLogicPlanSlidingUnit = "SlidingUnit";
+static const char* jkWindowLogicPlanSessionGap = "SessionGap";
+static const char* jkWindowLogicPlanTspk = "Tspk";
+static const char* jkWindowLogicPlanStateExpr = "StateExpr";
+static const char* jkWindowLogicPlanTriggerType = "TriggerType";
+static const char* jkWindowLogicPlanWatermark = "Watermark";
+
+static int32_t logicWindowNodeToJson(const void* pObj, SJson* pJson) {
+ const SWindowLogicNode* pNode = (const SWindowLogicNode*)pObj;
+
+ int32_t code = logicPlanNodeToJson(pObj, pJson);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanWinType, pNode->winType);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = nodeListToJson(pJson, jkWindowLogicPlanFuncs, pNode->pFuncs);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanInterval, pNode->interval);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanOffset, pNode->offset);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanSliding, pNode->sliding);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanIntervalUnit, pNode->intervalUnit);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanSlidingUnit, pNode->slidingUnit);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanSessionGap, pNode->sessionGap);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddObject(pJson, jkWindowLogicPlanTspk, nodeToJson, pNode->pTspk);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddObject(pJson, jkWindowLogicPlanStateExpr, nodeToJson, pNode->pStateExpr);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanTriggerType, pNode->triggerType);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkWindowLogicPlanWatermark, pNode->watermark);
+ }
+
+ return code;
+}
+
+static int32_t jsonToLogicWindowNode(const SJson* pJson, void* pObj) {
+ SWindowLogicNode* pNode = (SWindowLogicNode*)pObj;
+
+ int32_t code = jsonToLogicPlanNode(pJson, pObj);
+ if (TSDB_CODE_SUCCESS == code) {
+ tjsonGetNumberValue(pJson, jkWindowLogicPlanWinType, pNode->winType, code);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = jsonToNodeList(pJson, jkWindowLogicPlanFuncs, &pNode->pFuncs);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetBigIntValue(pJson, jkWindowLogicPlanInterval, &pNode->interval);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetBigIntValue(pJson, jkWindowLogicPlanOffset, &pNode->offset);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetBigIntValue(pJson, jkWindowLogicPlanSliding, &pNode->sliding);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetTinyIntValue(pJson, jkWindowLogicPlanIntervalUnit, &pNode->intervalUnit);
+ }
if (TSDB_CODE_SUCCESS == code) {
- code = tjsonGetUTinyIntValue(pJson, jkExchangeLogicPlanSrcPrecision, &pNode->precision);
+ code = tjsonGetTinyIntValue(pJson, jkWindowLogicPlanSlidingUnit, &pNode->slidingUnit);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetBigIntValue(pJson, jkWindowLogicPlanSessionGap, &pNode->sessionGap);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = jsonToNodeObject(pJson, jkWindowLogicPlanTspk, &pNode->pTspk);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = jsonToNodeObject(pJson, jkWindowLogicPlanStateExpr, &pNode->pStateExpr);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetTinyIntValue(pJson, jkWindowLogicPlanTriggerType, &pNode->triggerType);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetBigIntValue(pJson, jkWindowLogicPlanWatermark, &pNode->watermark);
}
return code;
@@ -1133,6 +1269,7 @@ static const char* jkTableScanPhysiPlanSlidingUnit = "slidingUnit";
static const char* jkTableScanPhysiPlanTriggerType = "triggerType";
static const char* jkTableScanPhysiPlanWatermark = "watermark";
static const char* jkTableScanPhysiPlanTsColId = "tsColId";
+static const char* jkTableScanPhysiPlanFilesFactor = "FilesFactor";
static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
const STableScanPhysiNode* pNode = (const STableScanPhysiNode*)pObj;
@@ -1183,6 +1320,9 @@ static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanTsColId, pNode->tsColId);
}
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddDoubleToObject(pJson, jkTableScanPhysiPlanFilesFactor, pNode->filesFactor);
+ }
return code;
}
@@ -1242,7 +1382,9 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
tjsonGetNumberValue(pJson, jkTableScanPhysiPlanTsColId, pNode->tsColId, code);
}
-
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetDoubleValue(pJson, jkTableScanPhysiPlanFilesFactor, &pNode->filesFactor);
+ }
return code;
}
@@ -1453,6 +1595,44 @@ static int32_t jsonToPhysiExchangeNode(const SJson* pJson, void* pObj) {
return code;
}
+static const char* jkMergePhysiPlanMergeKeys = "MergeKeys";
+static const char* jkMergePhysiPlanNumOfChannels = "NumOfChannels";
+static const char* jkMergePhysiPlanSrcGroupId = "SrcGroupId";
+
+static int32_t physiMergeNodeToJson(const void* pObj, SJson* pJson) {
+ const SMergePhysiNode* pNode = (const SMergePhysiNode*)pObj;
+
+ int32_t code = physicPlanNodeToJson(pObj, pJson);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = nodeListToJson(pJson, jkMergePhysiPlanMergeKeys, pNode->pMergeKeys);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkMergePhysiPlanNumOfChannels, pNode->numOfChannels);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddIntegerToObject(pJson, jkMergePhysiPlanSrcGroupId, pNode->srcGroupId);
+ }
+
+ return code;
+}
+
+static int32_t jsonToPhysiMergeNode(const SJson* pJson, void* pObj) {
+ SMergePhysiNode* pNode = (SMergePhysiNode*)pObj;
+
+ int32_t code = jsonToPhysicPlanNode(pJson, pObj);
+ if (TSDB_CODE_SUCCESS == code) {
+ code = jsonToNodeList(pJson, jkMergePhysiPlanMergeKeys, &pNode->pMergeKeys);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetIntValue(pJson, jkMergePhysiPlanNumOfChannels, &pNode->numOfChannels);
+ }
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetIntValue(pJson, jkMergePhysiPlanSrcGroupId, &pNode->srcGroupId);
+ }
+
+ return code;
+}
+
static const char* jkSortPhysiPlanExprs = "Exprs";
static const char* jkSortPhysiPlanSortKeys = "SortKeys";
static const char* jkSortPhysiPlanTargets = "Targets";
@@ -1496,6 +1676,7 @@ static const char* jkWindowPhysiPlanFuncs = "Funcs";
static const char* jkWindowPhysiPlanTsPk = "TsPk";
static const char* jkWindowPhysiPlanTriggerType = "TriggerType";
static const char* jkWindowPhysiPlanWatermark = "Watermark";
+static const char* jkWindowPhysiPlanFilesFactor = "FilesFactor";
static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
const SWinodwPhysiNode* pNode = (const SWinodwPhysiNode*)pObj;
@@ -1516,6 +1697,9 @@ static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanWatermark, pNode->watermark);
}
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonAddDoubleToObject(pJson, jkWindowPhysiPlanFilesFactor, pNode->filesFactor);
+ }
return code;
}
@@ -1541,6 +1725,9 @@ static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) {
tjsonGetNumberValue(pJson, jkWindowPhysiPlanWatermark, pNode->watermark, code);
;
}
+ if (TSDB_CODE_SUCCESS == code) {
+ code = tjsonGetDoubleValue(pJson, jkWindowPhysiPlanFilesFactor, &pNode->filesFactor);
+ }
return code;
}
@@ -3276,7 +3463,7 @@ static int32_t createTopicStmtToJson(const void* pObj, SJson* pJson) {
int32_t code = tjsonAddStringToObject(pJson, jkCreateTopicStmtTopicName, pNode->topicName);
if (TSDB_CODE_SUCCESS == code) {
- code = tjsonAddStringToObject(pJson, jkCreateTopicStmtSubscribeDbName, pNode->subscribeDbName);
+ code = tjsonAddStringToObject(pJson, jkCreateTopicStmtSubscribeDbName, pNode->subDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkCreateTopicStmtIgnoreExists, pNode->ignoreExists);
@@ -3293,7 +3480,7 @@ static int32_t jsonToCreateTopicStmt(const SJson* pJson, void* pObj) {
int32_t code = tjsonGetStringValue(pJson, jkCreateTopicStmtTopicName, pNode->topicName);
if (TSDB_CODE_SUCCESS == code) {
- code = tjsonGetStringValue(pJson, jkCreateTopicStmtSubscribeDbName, pNode->subscribeDbName);
+ code = tjsonGetStringValue(pJson, jkCreateTopicStmtSubscribeDbName, pNode->subDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkCreateTopicStmtIgnoreExists, &pNode->ignoreExists);
@@ -3388,6 +3575,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
break;
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
return logicExchangeNodeToJson(pObj, pJson);
+ case QUERY_NODE_LOGIC_PLAN_MERGE:
+ return logicMergeNodeToJson(pObj, pJson);
+ case QUERY_NODE_LOGIC_PLAN_WINDOW:
+ return logicWindowNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_FILL:
return logicFillNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_SORT:
@@ -3414,6 +3605,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return physiAggNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
return physiExchangeNodeToJson(pObj, pJson);
+ case QUERY_NODE_PHYSICAL_PLAN_MERGE:
+ return physiMergeNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return physiSortNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
@@ -3499,6 +3692,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicProjectNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
return jsonToLogicExchangeNode(pJson, pObj);
+ case QUERY_NODE_LOGIC_PLAN_MERGE:
+ return jsonToLogicMergeNode(pJson, pObj);
+ case QUERY_NODE_LOGIC_PLAN_WINDOW:
+ return jsonToLogicWindowNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_FILL:
return jsonToLogicFillNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_SORT:
@@ -3525,6 +3722,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToPhysiAggNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
return jsonToPhysiExchangeNode(pJson, pObj);
+ case QUERY_NODE_PHYSICAL_PLAN_MERGE:
+ return jsonToPhysiMergeNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return jsonToPhysiSortNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c
index e28844f2e16f07c57232b073f0052411d60a2d0f..51111ad864568649f5757e9b20f5f14190271c1a 100644
--- a/source/libs/nodes/src/nodesUtilFuncs.c
+++ b/source/libs/nodes/src/nodesUtilFuncs.c
@@ -86,8 +86,6 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SExplainOptions));
case QUERY_NODE_STREAM_OPTIONS:
return makeNode(type, sizeof(SStreamOptions));
- case QUERY_NODE_TOPIC_OPTIONS:
- return makeNode(type, sizeof(STopicOptions));
case QUERY_NODE_LEFT_VALUE:
return makeNode(type, sizeof(SLeftValueNode));
case QUERY_NODE_SET_OPERATOR:
@@ -222,6 +220,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SVnodeModifLogicNode));
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
return makeNode(type, sizeof(SExchangeLogicNode));
+ case QUERY_NODE_LOGIC_PLAN_MERGE:
+ return makeNode(type, sizeof(SMergeLogicNode));
case QUERY_NODE_LOGIC_PLAN_WINDOW:
return makeNode(type, sizeof(SWindowLogicNode));
case QUERY_NODE_LOGIC_PLAN_FILL:
@@ -252,6 +252,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SAggPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:
return makeNode(type, sizeof(SExchangePhysiNode));
+ case QUERY_NODE_PHYSICAL_PLAN_MERGE:
+ return makeNode(type, sizeof(SMergePhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_SORT:
return makeNode(type, sizeof(SSortPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h
index a1c304118bfcdc5078bf0a19b73a8bde17e3c0cf..7dd0ef2616bf3fda27192fa7099906348753c163 100644
--- a/source/libs/parser/inc/parAst.h
+++ b/source/libs/parser/inc/parAst.h
@@ -59,7 +59,6 @@ typedef enum EDatabaseOptionType {
typedef enum ETableOptionType {
TABLE_OPTION_COMMENT = 1,
- TABLE_OPTION_DELAY,
TABLE_OPTION_FILE_FACTOR,
TABLE_OPTION_ROLLUP,
TABLE_OPTION_TTL,
@@ -168,7 +167,7 @@ SNode* createCreateComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, co
SNode* createDropComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pDnodeId);
SNode* createTopicOptions(SAstCreateContext* pCxt);
SNode* createCreateTopicStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pTopicName, SNode* pQuery,
- const SToken* pSubscribeDbName, SNode* pOptions);
+ const SToken* pSubDbName, SNode* pRealTable);
SNode* createDropTopicStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pTopicName);
SNode* createDropCGroupStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pCGroupId,
const SToken* pTopicName);
diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h
index 2468f7d75bd16acb21c2bb45dd74ae46c1b669d7..0351023f5bc8fdbae4476e810e66f7d8bfc4e71f 100644
--- a/source/libs/parser/inc/parUtil.h
+++ b/source/libs/parser/inc/parUtil.h
@@ -58,7 +58,7 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
int32_t getNumOfTags(const STableMeta* pTableMeta);
STableComInfo getTableInfo(const STableMeta* pTableMeta);
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
-int32_t parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBuf* errMsg, int16_t startColId);
+int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag **ppTag, SMsgBuf* pMsgBuf);
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y
index 1fb60f83a5a822e627f8cbdf54b3a1e42c4daa5d..6c090a07901c1d96a567961b8a2ec3daabaaedf8 100644
--- a/source/libs/parser/inc/sql.y
+++ b/source/libs/parser/inc/sql.y
@@ -15,11 +15,15 @@
#include
#include
+#define ALLOW_FORBID_FUNC
+
#include "functionMgt.h"
#include "nodes.h"
#include "parToken.h"
#include "ttokendef.h"
#include "parAst.h"
+
+#define YYSTACKDEPTH 0
}
%syntax_error {
@@ -313,7 +317,6 @@ tags_def(A) ::= TAGS NK_LP column_def_list(B) NK_RP.
table_options(A) ::= . { A = createDefaultTableOptions(pCxt); }
table_options(A) ::= table_options(B) COMMENT NK_STRING(C). { A = setTableOption(pCxt, B, TABLE_OPTION_COMMENT, &C); }
-table_options(A) ::= table_options(B) DELAY NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_DELAY, &C); }
table_options(A) ::= table_options(B) FILE_FACTOR NK_FLOAT(C). { A = setTableOption(pCxt, B, TABLE_OPTION_FILE_FACTOR, &C); }
table_options(A) ::= table_options(B) ROLLUP NK_LP func_name_list(C) NK_RP. { A = setTableOption(pCxt, B, TABLE_OPTION_ROLLUP, C); }
table_options(A) ::= table_options(B) TTL NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_TTL, &C); }
@@ -403,17 +406,12 @@ func_list(A) ::= func_list(B) NK_COMMA func(C).
func(A) ::= function_name(B) NK_LP expression_list(C) NK_RP. { A = createFunctionNode(pCxt, &B, C); }
/************************************************ create/drop topic ***************************************************/
-cmd ::= CREATE TOPIC not_exists_opt(A)
- topic_name(B) topic_options(D) AS query_expression(C). { pCxt->pRootNode = createCreateTopicStmt(pCxt, A, &B, C, NULL, D); }
-cmd ::= CREATE TOPIC not_exists_opt(A)
- topic_name(B) topic_options(D) AS db_name(C). { pCxt->pRootNode = createCreateTopicStmt(pCxt, A, &B, NULL, &C, D); }
+cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) AS query_expression(C). { pCxt->pRootNode = createCreateTopicStmt(pCxt, A, &B, C, NULL, NULL); }
+cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) AS DATABASE db_name(C). { pCxt->pRootNode = createCreateTopicStmt(pCxt, A, &B, NULL, &C, NULL); }
+cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B)
+ AS STABLE full_table_name(C). { pCxt->pRootNode = createCreateTopicStmt(pCxt, A, &B, NULL, NULL, C); }
cmd ::= DROP TOPIC exists_opt(A) topic_name(B). { pCxt->pRootNode = createDropTopicStmt(pCxt, A, &B); }
-cmd ::= DROP CGROUP exists_opt(A) cgroup_name(B) ON topic_name(C). { pCxt->pRootNode = createDropCGroupStmt(pCxt, A, &B, &C); }
-
-topic_options(A) ::= . { A = createTopicOptions(pCxt); }
-topic_options(A) ::= topic_options(B) WITH TABLE. { ((STopicOptions*)B)->withTable = true; A = B; }
-topic_options(A) ::= topic_options(B) WITH SCHEMA. { ((STopicOptions*)B)->withSchema = true; A = B; }
-topic_options(A) ::= topic_options(B) WITH TAG. { ((STopicOptions*)B)->withTag = true; A = B; }
+cmd ::= DROP CONSUMER GROUP exists_opt(A) cgroup_name(B) ON topic_name(C). { pCxt->pRootNode = createDropCGroupStmt(pCxt, A, &B, &C); }
/************************************************ desc/describe *******************************************************/
cmd ::= DESC full_table_name(A). { pCxt->pRootNode = createDescribeStmt(pCxt, A); }
diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c
index 836a0cb520684e264cecb3cd6425ae3c7688de68..72a88548d2270d6d4776e2614bf05fc8c2b7ebf6 100644
--- a/source/libs/parser/src/parAstCreater.c
+++ b/source/libs/parser/src/parAstCreater.c
@@ -857,7 +857,6 @@ SNode* createDefaultTableOptions(SAstCreateContext* pCxt) {
CHECK_PARSER_STATUS(pCxt);
STableOptions* pOptions = nodesMakeNode(QUERY_NODE_TABLE_OPTIONS);
CHECK_OUT_OF_MEM(pOptions);
- pOptions->delay = TSDB_DEFAULT_ROLLUP_DELAY;
pOptions->filesFactor = TSDB_DEFAULT_ROLLUP_FILE_FACTOR;
pOptions->ttl = TSDB_DEFAULT_TABLE_TTL;
return (SNode*)pOptions;
@@ -867,7 +866,6 @@ SNode* createAlterTableOptions(SAstCreateContext* pCxt) {
CHECK_PARSER_STATUS(pCxt);
STableOptions* pOptions = nodesMakeNode(QUERY_NODE_TABLE_OPTIONS);
CHECK_OUT_OF_MEM(pOptions);
- pOptions->delay = -1;
pOptions->filesFactor = -1;
pOptions->ttl = -1;
return (SNode*)pOptions;
@@ -882,11 +880,8 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType
sizeof(((STableOptions*)pOptions)->comment));
}
break;
- case TABLE_OPTION_DELAY:
- ((STableOptions*)pOptions)->delay = taosStr2Int32(((SToken*)pVal)->z, NULL, 10);
- break;
case TABLE_OPTION_FILE_FACTOR:
- ((STableOptions*)pOptions)->filesFactor = taosStr2Float(((SToken*)pVal)->z, NULL);
+ ((STableOptions*)pOptions)->filesFactor = taosStr2Double(((SToken*)pVal)->z, NULL);
break;
case TABLE_OPTION_ROLLUP:
((STableOptions*)pOptions)->pRollupFuncs = pVal;
@@ -1266,28 +1261,22 @@ SNode* createDropComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, cons
return (SNode*)pStmt;
}
-SNode* createTopicOptions(SAstCreateContext* pCxt) {
- CHECK_PARSER_STATUS(pCxt);
- STopicOptions* pOptions = nodesMakeNode(QUERY_NODE_TOPIC_OPTIONS);
- CHECK_OUT_OF_MEM(pOptions);
- pOptions->withTable = false;
- pOptions->withSchema = false;
- pOptions->withTag = false;
- return (SNode*)pOptions;
-}
-
SNode* createCreateTopicStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pTopicName, SNode* pQuery,
- const SToken* pSubscribeDbName, SNode* pOptions) {
+ const SToken* pSubDbName, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SCreateTopicStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_TOPIC_STMT);
CHECK_OUT_OF_MEM(pStmt);
strncpy(pStmt->topicName, pTopicName->z, pTopicName->n);
pStmt->ignoreExists = ignoreExists;
- pStmt->pQuery = pQuery;
- if (NULL != pSubscribeDbName) {
- strncpy(pStmt->subscribeDbName, pSubscribeDbName->z, pSubscribeDbName->n);
+ if (NULL != pRealTable) {
+ strcpy(pStmt->subDbName, ((SRealTableNode*)pRealTable)->table.dbName);
+ strcpy(pStmt->subSTbName, ((SRealTableNode*)pRealTable)->table.tableName);
+ nodesDestroyNode(pRealTable);
+ } else if (NULL != pSubDbName) {
+ strncpy(pStmt->subDbName, pSubDbName->z, pSubDbName->n);
+ } else {
+ pStmt->pQuery = pQuery;
}
- pStmt->pOptions = (STopicOptions*)pOptions;
return (SNode*)pStmt;
}
diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c
index 047c2d15045f667d41319b6d7c14c475cd6273a1..593a597a823b831bd766ffaa02195153fcb49c2b 100644
--- a/source/libs/parser/src/parInsert.c
+++ b/source/libs/parser/src/parInsert.c
@@ -54,13 +54,13 @@ typedef struct SInsertParseContext {
SMsgBuf msg; // input
STableMeta* pTableMeta; // each table
SParsedDataColInfo tags; // each table
- SKVRowBuilder tagsBuilder; // each table
SVCreateTbReq createTblReq; // each table
SHashObj* pVgroupsHashObj; // global
SHashObj* pTableBlockHashObj; // global
SHashObj* pSubTableHashObj; // global
SArray* pVgDataBlocks; // global
SHashObj* pTableNameHashObj; // global
+ SHashObj* pDbFNameHashObj; // global
int32_t totalNum;
SVnodeModifOpStmt* pOutput;
SStmtCallback* pStmtCb;
@@ -73,9 +73,10 @@ static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
typedef struct SKvParam {
- SKVRowBuilder* builder;
- SSchema* schema;
- char buf[TSDB_MAX_TAGS_LEN];
+ int16_t pos;
+ SArray* pTagVals;
+ SSchema* schema;
+ char buf[TSDB_MAX_TAGS_LEN];
} SKvParam;
typedef struct SMemParam {
@@ -446,7 +447,7 @@ static int parseTime(char** end, SToken* pToken, int16_t timePrec, int64_t* time
return TSDB_CODE_SUCCESS;
}
-static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
+static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
if ((pToken->type != TK_NOW && pToken->type != TK_TODAY && pToken->type != TK_NK_INTEGER &&
pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT &&
@@ -492,7 +493,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
uint64_t uv;
char* endptr = NULL;
- int32_t code = checkAndTrimValue(pToken, pSchema->type, tmpTokenBuf, pMsgBuf);
+ int32_t code = checkAndTrimValue(pToken, tmpTokenBuf, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@@ -641,14 +642,12 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
case TSDB_DATA_TYPE_NCHAR: {
return func(pMsgBuf, pToken->z, pToken->n, param);
}
-
case TSDB_DATA_TYPE_JSON: {
if (pToken->n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
return buildSyntaxErrMsg(pMsgBuf, "json string too long than 4095", pToken->z);
}
return func(pMsgBuf, pToken->z, pToken->n, param);
}
-
case TSDB_DATA_TYPE_TIMESTAMP: {
int64_t tmpVal;
if (parseTime(end, pToken, timePrec, &tmpVal, pMsgBuf) != TSDB_CODE_SUCCESS) {
@@ -773,99 +772,282 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo*
return TSDB_CODE_SUCCESS;
}
-static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param) {
- SKvParam* pa = (SKvParam*)param;
+static void buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, STag* pTag, int64_t suid) {
+ pTbReq->type = TD_CHILD_TABLE;
+ pTbReq->name = strdup(tname);
+ pTbReq->ctb.suid = suid;
+ pTbReq->ctb.pTag = (uint8_t*)pTag;
- int8_t type = pa->schema->type;
- int16_t colId = pa->schema->colId;
+ return;
+}
- if (TSDB_DATA_TYPE_JSON == type) {
- return parseJsontoTagData(value, pa->builder, pMsgBuf, colId);
- }
+static int32_t parseTagToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, STagVal* val,
+ SMsgBuf* pMsgBuf) {
+ int64_t iv;
+ uint64_t uv;
+ char* endptr = NULL;
+
+ if (isNullStr(pToken)) {
+ if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
+ return buildSyntaxErrMsg(pMsgBuf, "primary timestamp should not be null", pToken->z);
+ }
- if (value == NULL) { // it is a null data
- // tdAppendColValToRow(rb, pa->schema->colId, pa->schema->type, TD_VTYPE_NULL, value, false, pa->toffset,
- // pa->colIdx);
return TSDB_CODE_SUCCESS;
}
- if (TSDB_DATA_TYPE_BINARY == type) {
- STR_WITH_SIZE_TO_VARSTR(pa->buf, value, len);
- tdAddColToKVRow(pa->builder, colId, pa->buf, varDataTLen(pa->buf));
- } else if (TSDB_DATA_TYPE_NCHAR == type) {
- // if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
- int32_t output = 0;
- if (!taosMbsToUcs4(value, len, (TdUcs4*)varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
- if (errno == E2BIG) {
- return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pa->schema->name);
+ val->cid = pSchema->colId;
+ val->type = pSchema->type;
+
+ switch (pSchema->type) {
+ case TSDB_DATA_TYPE_BOOL: {
+ if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
+ if (strncmp(pToken->z, "true", pToken->n) == 0) {
+ *(int8_t*)(&val->i64) = TRUE_VALUE;
+ } else if (strncmp(pToken->z, "false", pToken->n) == 0) {
+ *(int8_t*)(&val->i64) = FALSE_VALUE;
+ } else {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
+ }
+ } else if (pToken->type == TK_NK_INTEGER) {
+ *(int8_t*)(&val->i64) = ((taosStr2Int64(pToken->z, NULL, 10) == 0) ? FALSE_VALUE : TRUE_VALUE);
+ } else if (pToken->type == TK_NK_FLOAT) {
+ *(int8_t*)(&val->i64) = ((taosStr2Double(pToken->z, NULL) == 0) ? FALSE_VALUE : TRUE_VALUE);
+ } else {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
}
+ break;
+ }
- char buf[512] = {0};
- snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(errno));
- return buildSyntaxErrMsg(pMsgBuf, buf, value);
+ case TSDB_DATA_TYPE_TINYINT: {
+ if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z);
+ } else if (!IS_VALID_TINYINT(iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z);
+ }
+
+ *(int8_t*)(&val->i64) = iv;
+ break;
}
- varDataSetLen(pa->buf, output);
- tdAddColToKVRow(pa->builder, colId, pa->buf, varDataTLen(pa->buf));
- } else {
- tdAddColToKVRow(pa->builder, colId, value, TYPE_BYTES[type]);
- }
+ case TSDB_DATA_TYPE_UTINYINT: {
+ if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z);
+ } else if (!IS_VALID_UTINYINT(uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z);
+ }
+ *(uint8_t*)(&val->i64) = uv;
+ break;
+ }
- return TSDB_CODE_SUCCESS;
-}
+ case TSDB_DATA_TYPE_SMALLINT: {
+ if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z);
+ } else if (!IS_VALID_SMALLINT(iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z);
+ }
+ *(int16_t*)(&val->i64) = iv;
+ break;
+ }
-static int32_t buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, SKVRow row, int64_t suid) {
- pTbReq->type = TD_CHILD_TABLE;
- pTbReq->name = strdup(tname);
- pTbReq->ctb.suid = suid;
- pTbReq->ctb.pTag = row;
+ case TSDB_DATA_TYPE_USMALLINT: {
+ if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z);
+ } else if (!IS_VALID_USMALLINT(uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z);
+ }
+ *(uint16_t*)(&val->i64) = uv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_INT: {
+ if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z);
+ } else if (!IS_VALID_INT(iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z);
+ }
+ *(int32_t*)(&val->i64) = iv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_UINT: {
+ if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z);
+ } else if (!IS_VALID_UINT(uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z);
+ }
+ *(uint32_t*)(&val->i64) = uv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_BIGINT: {
+ if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z);
+ } else if (!IS_VALID_BIGINT(iv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "bigint data overflow", pToken->z);
+ }
+
+ val->i64 = iv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_UBIGINT: {
+ if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z);
+ } else if (!IS_VALID_UBIGINT(uv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "unsigned bigint data overflow", pToken->z);
+ }
+ *(uint64_t*)(&val->i64) = uv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_FLOAT: {
+ double dv;
+ if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
+ return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
+ }
+ if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) ||
+ isnan(dv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
+ }
+ *(float*)(&val->i64) = dv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_DOUBLE: {
+ double dv;
+ if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
+ return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
+ }
+ if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
+ return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
+ }
+
+ *(double*)(&val->i64) = dv;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_BINARY: {
+ // Too long values will raise the invalid sql error message
+ if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
+ return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
+ }
+ val->pData = pToken->z;
+ val->nData = pToken->n;
+ break;
+ }
+
+ case TSDB_DATA_TYPE_NCHAR: {
+ int32_t output = 0;
+ void* p = taosMemoryCalloc(1, pToken->n * TSDB_NCHAR_SIZE);
+ if (p == NULL) {
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)(p), pToken->n * TSDB_NCHAR_SIZE, &output)) {
+ if (errno == E2BIG) {
+ taosMemoryFree(p);
+ return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
+ }
+ char buf[512] = {0};
+ snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(errno));
+ taosMemoryFree(p);
+ return buildSyntaxErrMsg(pMsgBuf, buf, pToken->z);
+ }
+ val->pData = p;
+ val->nData = output;
+ break;
+ }
+ case TSDB_DATA_TYPE_TIMESTAMP: {
+ if (parseTime(end, pToken, timePrec, &iv, pMsgBuf) != TSDB_CODE_SUCCESS) {
+ return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp", pToken->z);
+ }
+
+ val->i64 = iv;
+ break;
+ }
+ }
return TSDB_CODE_SUCCESS;
}
// pSql -> tag1_value, ...)
static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint8_t precision, const char* tName) {
- if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) {
- return TSDB_CODE_TSC_OUT_OF_MEMORY;
- }
-
- SKvParam param = {.builder = &pCxt->tagsBuilder};
- SToken sToken;
- bool isParseBindParam = false;
- char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character: \\, \', \"
+ int32_t code = TSDB_CODE_SUCCESS;
+ SArray* pTagVals = taosArrayInit(pCxt->tags.numOfBound, sizeof(STagVal));
+ SToken sToken;
+ bool isParseBindParam = false;
+ bool isJson = false;
+ STag* pTag = NULL;
for (int i = 0; i < pCxt->tags.numOfBound; ++i) {
NEXT_TOKEN_WITH_PREV(pCxt->pSql, sToken);
if (sToken.type == TK_NK_QUESTION) {
isParseBindParam = true;
if (NULL == pCxt->pStmtCb) {
- return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", sToken.z);
+ code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", sToken.z);
+ goto end;
}
continue;
}
if (isParseBindParam) {
- return buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and tag values");
+ code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and tag values");
+ goto end;
}
SSchema* pTagSchema = &pSchema[pCxt->tags.boundColumns[i]];
- param.schema = pTagSchema;
- CHECK_CODE(
- parseValueToken(&pCxt->pSql, &sToken, pTagSchema, precision, tmpTokenBuf, KvRowAppend, ¶m, &pCxt->msg));
+ char* tmpTokenBuf = taosMemoryCalloc(1, sToken.n); // this can be optimize with parse column
+ code = checkAndTrimValue(&sToken, tmpTokenBuf, &pCxt->msg);
+ if (code != TSDB_CODE_SUCCESS) {
+ taosMemoryFree(tmpTokenBuf);
+ goto end;
+ }
+ if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
+ if (sToken.n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
+ code = buildSyntaxErrMsg(&pCxt->msg, "json string too long than 4095", sToken.z);
+ taosMemoryFree(tmpTokenBuf);
+ goto end;
+ }
+ code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg);
+ taosMemoryFree(tmpTokenBuf);
+ if (code != TSDB_CODE_SUCCESS) {
+ goto end;
+ }
+ isJson = true;
+ } else {
+ STagVal val = {0};
+ code = parseTagToken(&pCxt->pSql, &sToken, pTagSchema, precision, &val, &pCxt->msg);
+ if (TSDB_CODE_SUCCESS != code) {
+ taosMemoryFree(tmpTokenBuf);
+ goto end;
+ }
+ if (pTagSchema->type != TSDB_DATA_TYPE_BINARY) {
+ taosMemoryFree(tmpTokenBuf);
+ }
+ taosArrayPush(pTagVals, &val);
+ }
}
if (isParseBindParam) {
- return TSDB_CODE_SUCCESS;
+ code = TSDB_CODE_SUCCESS;
+ goto end;
}
- SKVRow row = tdGetKVRowFromBuilder(&pCxt->tagsBuilder);
- if (NULL == row) {
- return buildInvalidOperationMsg(&pCxt->msg, "out of memory");
+ if (!isJson && (code = tTagNew(pTagVals, 1, false, &pTag)) != TSDB_CODE_SUCCESS) {
+ goto end;
}
- tdSortKVRowByColIdx(row);
- return buildCreateTbReq(&pCxt->createTblReq, tName, row, pCxt->pTableMeta->suid);
+ buildCreateTbReq(&pCxt->createTblReq, tName, pTag, pCxt->pTableMeta->suid);
+
+end:
+ for (int i = 0; i < taosArrayGetSize(pTagVals); ++i) {
+ STagVal* p = (STagVal*)taosArrayGet(pTagVals, i);
+ if (IS_VAR_DATA_TYPE(p->type)) {
+ taosMemoryFree(p->pData);
+ }
+ }
+ taosArrayDestroy(pTagVals);
+ return code;
}
static int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) {
@@ -972,6 +1154,10 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks,
continue;
}
+ if (TK_NK_RP == sToken.type) {
+ return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
+ }
+
if (isParseBindParam) {
return buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and values");
}
@@ -1082,7 +1268,6 @@ void destroyCreateSubTbReq(SVCreateTbReq* pReq) {
static void destroyInsertParseContextForTable(SInsertParseContext* pCxt) {
taosMemoryFreeClear(pCxt->pTableMeta);
destroyBoundColumnInfo(&pCxt->tags);
- tdDestroyKVRowBuilder(&pCxt->tagsBuilder);
destroyCreateSubTbReq(&pCxt->createTblReq);
}
@@ -1091,6 +1276,7 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) {
taosHashCleanup(pCxt->pVgroupsHashObj);
taosHashCleanup(pCxt->pSubTableHashObj);
taosHashCleanup(pCxt->pTableNameHashObj);
+ taosHashCleanup(pCxt->pDbFNameHashObj);
destroyBlockHashmap(pCxt->pTableBlockHashObj);
destroyBlockArrayList(pCxt->pVgDataBlocks);
@@ -1151,6 +1337,9 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
tNameExtractFullName(&name, tbFName);
CHECK_CODE(taosHashPut(pCxt->pTableNameHashObj, tbFName, strlen(tbFName), &name, sizeof(SName)));
+ char dbFName[TSDB_DB_FNAME_LEN];
+ tNameGetFullDbName(&name, dbFName);
+ CHECK_CODE(taosHashPut(pCxt->pDbFNameHashObj, dbFName, strlen(dbFName), dbFName, sizeof(dbFName)));
// USING clause
if (TK_USING == sToken.type) {
@@ -1158,8 +1347,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
NEXT_TOKEN(pCxt->pSql, sToken);
autoCreateTbl = true;
} else {
- char dbFName[TSDB_DB_FNAME_LEN];
- tNameGetFullDbName(&name, dbFName);
CHECK_CODE(getTableMeta(pCxt, &name, dbFName));
}
@@ -1238,6 +1425,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
.pTableMeta = NULL,
.pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
.pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
+ .pDbFNameHashObj = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK),
.totalNum = 0,
.pOutput = (SVnodeModifOpStmt*)nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT),
.pStmtCb = pContext->pStmtCb};
@@ -1252,7 +1440,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
}
if (NULL == context.pVgroupsHashObj || NULL == context.pTableBlockHashObj || NULL == context.pSubTableHashObj ||
- NULL == context.pTableNameHashObj || NULL == context.pOutput) {
+ NULL == context.pTableNameHashObj || NULL == context.pDbFNameHashObj || NULL == context.pOutput) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
@@ -1278,6 +1466,13 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
}
}
+ if (NULL == (*pQuery)->pDbList) {
+ (*pQuery)->pDbList = taosArrayInit(taosHashGetSize(context.pDbFNameHashObj), TSDB_DB_FNAME_LEN);
+ if (NULL == (*pQuery)->pDbList) {
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ }
+
context.pOutput->payloadType = PAYLOAD_TYPE_KV;
int32_t code = skipInsertInto(&context.pSql, &context.msg);
@@ -1290,6 +1485,12 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) {
taosArrayPush((*pQuery)->pTableList, pTable);
pTable = taosHashIterate(context.pTableNameHashObj, pTable);
}
+
+ char* pDb = taosHashIterate(context.pDbFNameHashObj, NULL);
+ while (NULL != pDb) {
+ taosArrayPush((*pQuery)->pDbList, pDb);
+ pDb = taosHashIterate(context.pDbFNameHashObj, pDb);
+ }
}
destroyInsertParseContext(&context);
return code;
@@ -1516,46 +1717,93 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tN
return TSDB_CODE_QRY_APP_ERROR;
}
- SKVRowBuilder tagBuilder;
- if (tdInitKVRowBuilder(&tagBuilder) < 0) {
- return TSDB_CODE_TSC_OUT_OF_MEMORY;
+ SArray* pTagArray = taosArrayInit(tags->numOfBound, sizeof(STagVal));
+ if (!pTagArray) {
+ return buildInvalidOperationMsg(&pBuf, "out of memory");
}
+ int32_t code = TSDB_CODE_SUCCESS;
SSchema* pSchema = pDataBlock->pTableMeta->schema;
- SKvParam param = {.builder = &tagBuilder};
+
+ bool isJson = false;
+ STag* pTag = NULL;
for (int c = 0; c < tags->numOfBound; ++c) {
if (bind[c].is_null && bind[c].is_null[0]) {
- KvRowAppend(&pBuf, NULL, 0, ¶m);
continue;
}
SSchema* pTagSchema = &pSchema[tags->boundColumns[c]];
- param.schema = pTagSchema;
-
- int32_t colLen = pTagSchema->bytes;
+ int32_t colLen = pTagSchema->bytes;
if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
colLen = bind[c].length[0];
}
+ if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
+ if (colLen > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
+ code = buildSyntaxErrMsg(&pBuf, "json string too long than 4095", bind[c].buffer);
+ goto end;
+ }
- CHECK_CODE(KvRowAppend(&pBuf, (char*)bind[c].buffer, colLen, ¶m));
+ isJson = true;
+ char* tmp = taosMemoryCalloc(1, colLen + 1);
+ memcpy(tmp, bind[c].buffer, colLen);
+ code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf);
+ taosMemoryFree(tmp);
+ if (code != TSDB_CODE_SUCCESS) {
+ goto end;
+ }
+ } else {
+ STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
+ if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) {
+ val.pData = (uint8_t*)bind[c].buffer;
+ val.nData = colLen;
+ } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
+ int32_t output = 0;
+ void* p = taosMemoryCalloc(1, colLen * TSDB_NCHAR_SIZE);
+ if (p == NULL) {
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto end;
+ }
+ if (!taosMbsToUcs4(bind[c].buffer, colLen, (TdUcs4*)(p), colLen * TSDB_NCHAR_SIZE, &output)) {
+ if (errno == E2BIG) {
+ taosMemoryFree(p);
+ code = generateSyntaxErrMsg(&pBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pTagSchema->name);
+ goto end;
+ }
+ char buf[512] = {0};
+ snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(errno));
+ taosMemoryFree(p);
+ code = buildSyntaxErrMsg(&pBuf, buf, bind[c].buffer);
+ goto end;
+ }
+ val.pData = p;
+ val.nData = output;
+ } else {
+ memcpy(&val.i64, bind[c].buffer, colLen);
+ }
+ taosArrayPush(pTagArray, &val);
+ }
}
- SKVRow row = tdGetKVRowFromBuilder(&tagBuilder);
- if (NULL == row) {
- tdDestroyKVRowBuilder(&tagBuilder);
- return buildInvalidOperationMsg(&pBuf, "out of memory");
+ if (!isJson && (code = tTagNew(pTagArray, 1, false, &pTag)) != TSDB_CODE_SUCCESS) {
+ goto end;
}
- tdSortKVRowByColIdx(row);
SVCreateTbReq tbReq = {0};
- CHECK_CODE(buildCreateTbReq(&tbReq, tName, row, suid));
- CHECK_CODE(buildCreateTbMsg(pDataBlock, &tbReq));
-
+ buildCreateTbReq(&tbReq, tName, pTag, suid);
+ code = buildCreateTbMsg(pDataBlock, &tbReq);
destroyCreateSubTbReq(&tbReq);
- tdDestroyKVRowBuilder(&tagBuilder);
- return TSDB_CODE_SUCCESS;
+end:
+ for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
+ STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
+ if (p->type == TSDB_DATA_TYPE_NCHAR) {
+ taosMemoryFree(p->pData);
+ }
+ }
+ taosArrayDestroy(pTagArray);
+
+ return code;
}
int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen) {
@@ -1724,18 +1972,24 @@ int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBu
return TSDB_CODE_SUCCESS;
}
-int32_t buildBoundFields(SParsedDataColInfo* boundInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD** fields) {
+int32_t buildBoundFields(SParsedDataColInfo* boundInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_E** fields,
+ uint8_t timePrec) {
if (fields) {
*fields = taosMemoryCalloc(boundInfo->numOfBound, sizeof(TAOS_FIELD));
if (NULL == *fields) {
return TSDB_CODE_OUT_OF_MEMORY;
}
+ SSchema* schema = &pSchema[boundInfo->boundColumns[0]];
+ if (TSDB_DATA_TYPE_TIMESTAMP == schema->type) {
+ (*fields)[0].precision = timePrec;
+ }
+
for (int32_t i = 0; i < boundInfo->numOfBound; ++i) {
- SSchema* pTagSchema = &pSchema[boundInfo->boundColumns[i]];
- strcpy((*fields)[i].name, pTagSchema->name);
- (*fields)[i].type = pTagSchema->type;
- (*fields)[i].bytes = pTagSchema->bytes;
+ schema = &pSchema[boundInfo->boundColumns[i]];
+ strcpy((*fields)[i].name, schema->name);
+ (*fields)[i].type = schema->type;
+ (*fields)[i].bytes = schema->bytes;
}
}
@@ -1744,7 +1998,7 @@ int32_t buildBoundFields(SParsedDataColInfo* boundInfo, SSchema* pSchema, int32_
return TSDB_CODE_SUCCESS;
}
-int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD** fields) {
+int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields) {
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags;
if (NULL == tags) {
@@ -1759,12 +2013,12 @@ int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TA
return TSDB_CODE_SUCCESS;
}
- CHECK_CODE(buildBoundFields(tags, pSchema, fieldNum, fields));
+ CHECK_CODE(buildBoundFields(tags, pSchema, fieldNum, fields, 0));
return TSDB_CODE_SUCCESS;
}
-int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields) {
+int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_E** fields) {
STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock;
SSchema* pSchema = getTableColumnSchema(pDataBlock->pTableMeta);
if (pDataBlock->boundColumnInfo.numOfBound <= 0) {
@@ -1776,7 +2030,8 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields
return TSDB_CODE_SUCCESS;
}
- CHECK_CODE(buildBoundFields(&pDataBlock->boundColumnInfo, pSchema, fieldNum, fields));
+ CHECK_CODE(buildBoundFields(&pDataBlock->boundColumnInfo, pSchema, fieldNum, fields,
+ pDataBlock->pTableMeta->tableInfo.precision));
return TSDB_CODE_SUCCESS;
}
@@ -1785,7 +2040,6 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields
typedef struct SmlExecTableHandle {
SParsedDataColInfo tags; // each table
- SKVRowBuilder tagsBuilder; // each table
SVCreateTbReq createTblReq; // each table
} SmlExecTableHandle;
@@ -1797,7 +2051,6 @@ typedef struct SmlExecHandle {
static void smlDestroyTableHandle(void* pHandle) {
SmlExecTableHandle* handle = (SmlExecTableHandle*)pHandle;
- tdDestroyKVRowBuilder(&handle->tagsBuilder);
destroyBoundColumnInfo(&handle->tags);
destroyCreateSubTbReq(&handle->createTblReq);
}
@@ -1873,30 +2126,68 @@ static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SS
return TSDB_CODE_SUCCESS;
}
-static int32_t smlBuildTagRow(SArray* cols, SKVRowBuilder* tagsBuilder, SParsedDataColInfo* tags, SSchema* pSchema,
- SKVRow* row, SMsgBuf* msg) {
- if (tdInitKVRowBuilder(tagsBuilder) < 0) {
+/**
+ * @brief No json tag for schemaless
+ *
+ * @param cols
+ * @param tags
+ * @param pSchema
+ * @param ppTag
+ * @param msg
+ * @return int32_t
+ */
+static int32_t smlBuildTagRow(SArray* cols, SParsedDataColInfo* tags, SSchema* pSchema, STag** ppTag, SMsgBuf* msg) {
+ SArray* pTagArray = taosArrayInit(tags->numOfBound, sizeof(STagVal));
+ if (!pTagArray) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SKvParam param = {.builder = tagsBuilder};
+ int32_t code = TSDB_CODE_SUCCESS;
for (int i = 0; i < tags->numOfBound; ++i) {
SSchema* pTagSchema = &pSchema[tags->boundColumns[i]];
- param.schema = pTagSchema;
- SSmlKv* kv = taosArrayGetP(cols, i);
- if (IS_VAR_DATA_TYPE(kv->type)) {
- KvRowAppend(msg, kv->value, kv->length, ¶m);
+ SSmlKv* kv = taosArrayGetP(cols, i);
+
+ STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
+ if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) {
+ val.pData = (uint8_t*)kv->value;
+ val.nData = kv->length;
+ } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
+ int32_t output = 0;
+ void *p = taosMemoryCalloc(1, kv->length * TSDB_NCHAR_SIZE);
+ if(p == NULL){
+ code = TSDB_CODE_OUT_OF_MEMORY;
+ goto end;
+ }
+ if (!taosMbsToUcs4(kv->value, kv->length, (TdUcs4*)(p), kv->length * TSDB_NCHAR_SIZE, &output)) {
+ if (errno == E2BIG) {
+ taosMemoryFree(p);
+ code = generateSyntaxErrMsg(msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pTagSchema->name);
+ goto end;
+ }
+ char buf[512] = {0};
+ snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(errno));
+ taosMemoryFree(p);
+ code = buildSyntaxErrMsg(msg, buf, kv->value);
+ goto end;
+ }
+ val.pData = p;
+ val.nData = output;
} else {
- KvRowAppend(msg, &(kv->value), kv->length, ¶m);
+ memcpy(&val.i64, &(kv->value), kv->length);
}
+ taosArrayPush(pTagArray, &val);
}
- *row = tdGetKVRowFromBuilder(tagsBuilder);
- if (*row == NULL) {
- return TSDB_CODE_OUT_OF_MEMORY;
+ code = tTagNew(pTagArray, 1, false, ppTag);
+end:
+ for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
+ STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
+ if (p->type == TSDB_DATA_TYPE_NCHAR) {
+ taosMemoryFree(p->pData);
+ }
}
- tdSortKVRowByColIdx(*row);
- return TSDB_CODE_SUCCESS;
+ taosArrayDestroy(pTagArray);
+ return code;
}
int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols, bool format, STableMeta* pTableMeta,
@@ -1912,14 +2203,13 @@ int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols
buildInvalidOperationMsg(&pBuf, "bound tags error");
return ret;
}
- SKVRow row = NULL;
- ret = smlBuildTagRow(tags, &smlHandle->tableExecHandle.tagsBuilder, &smlHandle->tableExecHandle.tags, pTagsSchema,
- &row, &pBuf);
+ STag* pTag = NULL;
+ ret = smlBuildTagRow(tags, &smlHandle->tableExecHandle.tags, pTagsSchema, &pTag, &pBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
- buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, row, pTableMeta->suid);
+ buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, pTag, pTableMeta->suid);
STableDataBlocks* pDataBlock = NULL;
ret = getDataBlockFromList(smlHandle->pBlockHash, &pTableMeta->uid, sizeof(pTableMeta->uid),
diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c
index 540de2d639be9e69e798316e04bb4a46ff9dd58e..e9539073583c6d21a100efa5b33516eb9db18393 100644
--- a/source/libs/parser/src/parTokenizer.c
+++ b/source/libs/parser/src/parTokenizer.c
@@ -53,7 +53,6 @@ static SKeyword keywordTable[] = {
{"CACHE", TK_CACHE},
{"CACHELAST", TK_CACHELAST},
{"CAST", TK_CAST},
- {"CGROUP", TK_CGROUP},
{"CLUSTER", TK_CLUSTER},
{"COLUMN", TK_COLUMN},
{"COMMENT", TK_COMMENT},
@@ -62,13 +61,13 @@ static SKeyword keywordTable[] = {
{"CONNS", TK_CONNS},
{"CONNECTION", TK_CONNECTION},
{"CONNECTIONS", TK_CONNECTIONS},
+ {"CONSUMER", TK_CONSUMER},
{"COUNT", TK_COUNT},
{"CREATE", TK_CREATE},
{"DATABASE", TK_DATABASE},
{"DATABASES", TK_DATABASES},
{"DAYS", TK_DAYS},
{"DBS", TK_DBS},
- {"DELAY", TK_DELAY},
{"DESC", TK_DESC},
{"DESCRIBE", TK_DESCRIBE},
{"DISTINCT", TK_DISTINCT},
@@ -156,7 +155,6 @@ static SKeyword keywordTable[] = {
{"RETENTIONS", TK_RETENTIONS},
{"REVOKE", TK_REVOKE},
{"ROLLUP", TK_ROLLUP},
- {"SCHEMA", TK_SCHEMA},
{"SCHEMALESS", TK_SCHEMALESS},
{"SCORES", TK_SCORES},
{"SELECT", TK_SELECT},
@@ -214,7 +212,6 @@ static SKeyword keywordTable[] = {
{"WATERMARK", TK_WATERMARK},
{"WHERE", TK_WHERE},
{"WINDOW_CLOSE", TK_WINDOW_CLOSE},
- {"WITH", TK_WITH},
{"WRITE", TK_WRITE},
{"_C0", TK_ROWTS},
{"_QENDTS", TK_QENDTS},
diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c
index c6a7f95d5e141bf685d706fa4eed60e91d5d0cab..c4e63ee8807b837e4875660f400a63bf8b835ad8 100644
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -465,20 +465,22 @@ static bool isPrimaryKey(STempTableNode* pTable, SNode* pExpr) {
return isPrimaryKeyImpl(pTable, pExpr);
}
-static bool findAndSetColumn(SColumnNode** pColRef, const STableNode* pTable) {
+static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, const STableNode* pTable,
+ bool* pFound) {
SColumnNode* pCol = *pColRef;
- bool found = false;
+ *pFound = false;
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
if (isInternalPrimaryKey(pCol)) {
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, false, pCol);
- return true;
+ *pFound = true;
+ return TSDB_CODE_SUCCESS;
}
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
for (int32_t i = 0; i < nums; ++i) {
if (0 == strcmp(pCol->colName, pMeta->schema[i].name)) {
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i >= pMeta->tableInfo.numOfColumns), pCol);
- found = true;
+ *pFound = true;
break;
}
}
@@ -489,13 +491,15 @@ static bool findAndSetColumn(SColumnNode** pColRef, const STableNode* pTable) {
SExprNode* pExpr = (SExprNode*)pNode;
if (0 == strcmp(pCol->colName, pExpr->aliasName) ||
(isPrimaryKey((STempTableNode*)pTable, pNode) && isInternalPrimaryKey(pCol))) {
+ if (*pFound) {
+ return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, pCol->colName);
+ }
setColumnInfoByExpr(pTable, pExpr, pColRef);
- found = true;
- break;
+ *pFound = true;
}
}
}
- return found;
+ return TSDB_CODE_SUCCESS;
}
static EDealRes translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode** pCol) {
@@ -506,7 +510,12 @@ static EDealRes translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode**
STableNode* pTable = taosArrayGetP(pTables, i);
if (belongTable(pCxt->pParseCxt->db, (*pCol), pTable)) {
foundTable = true;
- if (findAndSetColumn(pCol, pTable)) {
+ bool foundCol = false;
+ pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
+ if (TSDB_CODE_SUCCESS != pCxt->errCode) {
+ return DEAL_RES_ERROR;
+ }
+ if (foundCol) {
break;
}
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
@@ -525,14 +534,19 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
bool isInternalPk = isInternalPrimaryKey(*pCol);
for (size_t i = 0; i < nums; ++i) {
STableNode* pTable = taosArrayGetP(pTables, i);
- if (findAndSetColumn(pCol, pTable)) {
+ bool foundCol = false;
+ pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
+ if (TSDB_CODE_SUCCESS != pCxt->errCode) {
+ return DEAL_RES_ERROR;
+ }
+ if (foundCol) {
if (found) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_AMBIGUOUS_COLUMN, (*pCol)->colName);
}
found = true;
- if (isInternalPk) {
- break;
- }
+ }
+ if (isInternalPk) {
+ break;
}
}
if (!found) {
@@ -698,7 +712,6 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
if (NULL == pVal->datum.p) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
- ;
}
int32_t len = 0;
@@ -816,7 +829,8 @@ static EDealRes translateComparisonOperator(STranslateContext* pCxt, SOperatorNo
if (!IS_VAR_DATA_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pLeft))->aliasName);
}
- if (QUERY_NODE_VALUE != nodeType(pOp->pRight) || !IS_STR_DATA_TYPE(((SExprNode*)(pOp->pRight))->resType.type)) {
+ if (QUERY_NODE_VALUE != nodeType(pOp->pRight) ||
+ ((!IS_STR_DATA_TYPE(((SExprNode*)(pOp->pRight))->resType.type)) && (((SExprNode*)(pOp->pRight))->resType.type != TSDB_DATA_TYPE_NULL))) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
}
}
@@ -1939,7 +1953,9 @@ static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* p
}
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
strcpy(pCol->colName, PK_TS_COL_INTERNAL_NAME);
- if (!findAndSetColumn(&pCol, pTable)) {
+ bool found = false;
+ int32_t code = findAndSetColumn(pCxt, &pCol, pTable, &found);
+ if (TSDB_CODE_SUCCESS != code || !found) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_FUNC);
}
*pPrimaryKey = (SNode*)pCol;
@@ -2617,10 +2633,7 @@ static int32_t checkTableSchema(STranslateContext* pCxt, SCreateTableStmt* pStmt
}
static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
- int32_t code = checkRangeOption(pCxt, "delay", pStmt->pOptions->delay, TSDB_MIN_ROLLUP_DELAY, TSDB_MAX_ROLLUP_DELAY);
- if (TSDB_CODE_SUCCESS == code) {
- code = checTableFactorOption(pCxt, pStmt->pOptions->filesFactor);
- }
+ int32_t code = checTableFactorOption(pCxt, pStmt->pOptions->filesFactor);
if (TSDB_CODE_SUCCESS == code) {
code = checkTableRollupOption(pCxt, pStmt->pOptions->pRollupFuncs);
}
@@ -2861,7 +2874,6 @@ static int32_t buildRollupAst(STranslateContext* pCxt, SCreateTableStmt* pStmt,
static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStmt, SMCreateStbReq* pReq) {
pReq->igExists = pStmt->ignoreExists;
pReq->xFilesFactor = pStmt->pOptions->filesFactor;
- pReq->delay = pStmt->pOptions->delay;
pReq->ttl = pStmt->pOptions->ttl;
columnDefNodeToField(pStmt->pCols, &pReq->pColumns);
columnDefNodeToField(pStmt->pTags, &pReq->pTags);
@@ -3287,9 +3299,6 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->topicName, strlen(pStmt->topicName));
tNameGetFullDbName(&name, pReq->name);
pReq->igExists = pStmt->ignoreExists;
- pReq->withTbName = pStmt->pOptions->withTable;
- pReq->withSchema = pStmt->pOptions->withSchema;
- pReq->withTag = pStmt->pOptions->withTag;
pReq->sql = strdup(pCxt->pParseCxt->pSql);
if (NULL == pReq->sql) {
@@ -3298,19 +3307,26 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS
int32_t code = TSDB_CODE_SUCCESS;
- const char* dbName;
- if (NULL != pStmt->pQuery) {
- dbName = ((SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable))->table.dbName;
+ if ('\0' != pStmt->subSTbName[0]) {
+ pReq->subType = TOPIC_SUB_TYPE__TABLE;
+ toName(pCxt->pParseCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name);
+ tNameGetFullDbName(&name, pReq->subDbName);
+ tNameExtractFullName(&name, pReq->subStbName);
+ } else if ('\0' != pStmt->subDbName[0]) {
+ pReq->subType = TOPIC_SUB_TYPE__DB;
+ tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->subDbName, strlen(pStmt->subDbName));
+ tNameGetFullDbName(&name, pReq->subDbName);
+ } else {
+ pReq->subType = TOPIC_SUB_TYPE__COLUMN;
+ char* dbName = ((SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable))->table.dbName;
+ tNameSetDbName(&name, pCxt->pParseCxt->acctId, dbName, strlen(dbName));
+ tNameGetFullDbName(&name, pReq->subDbName);
pCxt->pParseCxt->topicQuery = true;
code = translateQuery(pCxt, pStmt->pQuery);
if (TSDB_CODE_SUCCESS == code) {
code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
}
- } else {
- dbName = pStmt->subscribeDbName;
}
- tNameSetDbName(&name, pCxt->pParseCxt->acctId, dbName, strlen(dbName));
- tNameGetFullDbName(&name, pReq->subscribeDbName);
return code;
}
@@ -3365,7 +3381,7 @@ static int32_t translateDropCGroup(STranslateContext* pCxt, SDropCGroupStmt* pSt
dropReq.igNotExists = pStmt->ignoreNotExists;
strcpy(dropReq.cgroup, pStmt->cgroup);
- return buildCmdMsg(pCxt, TDMT_MND_DROP_CGROUP, (FSerializeFunc)tSerializeSMDropCgroupReq, &dropReq);
+ return buildCmdMsg(pCxt, TDMT_MND_MQ_DROP_CGROUP, (FSerializeFunc)tSerializeSMDropCgroupReq, &dropReq);
}
static int32_t translateAlterLocal(STranslateContext* pCxt, SAlterLocalStmt* pStmt) {
@@ -4145,8 +4161,8 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) {
return code;
}
-static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt, SKVRow row,
- uint64_t suid, SVgroupInfo* pVgInfo) {
+static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt,
+ const STag* pTag, uint64_t suid, SVgroupInfo* pVgInfo) {
char dbFName[TSDB_DB_FNAME_LEN] = {0};
SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId};
strcpy(name.dbname, pStmt->dbName);
@@ -4156,7 +4172,7 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S
req.type = TD_CHILD_TABLE;
req.name = strdup(pStmt->tableName);
req.ctb.suid = suid;
- req.ctb.pTag = row;
+ req.ctb.pTag = (uint8_t*)pTag;
if (pStmt->ignoreExists) {
req.flags |= TD_CREATE_IF_NOT_EXISTS;
}
@@ -4176,24 +4192,6 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S
}
}
-static int32_t addValToKVRow(STranslateContext* pCxt, SValueNode* pVal, const SSchema* pSchema,
- SKVRowBuilder* pBuilder) {
- if (pSchema->type == TSDB_DATA_TYPE_JSON) {
- if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
- return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal);
- }
-
- return parseJsontoTagData(pVal->literal, pBuilder, &pCxt->msgBuf, pSchema->colId);
- }
-
- if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
- tdAddColToKVRow(pBuilder, pSchema->colId, nodesGetValueFromNode(pVal),
- IS_VAR_DATA_TYPE(pSchema->type) ? varDataTLen(pVal->datum.p) : TYPE_BYTES[pSchema->type]);
- }
-
- return TSDB_CODE_SUCCESS;
-}
-
static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* pFunc, SValueNode** pVal) {
int32_t code = getFuncInfo(pCxt, pFunc);
if (TSDB_CODE_SUCCESS == code) {
@@ -4221,15 +4219,22 @@ static int32_t translateTagVal(STranslateContext* pCxt, uint8_t precision, SSche
}
static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta,
- SKVRowBuilder* pBuilder) {
+ STag** ppTag) {
int32_t numOfTags = getNumOfTags(pSuperTableMeta);
if (LIST_LENGTH(pStmt->pValsOfTags) != LIST_LENGTH(pStmt->pSpecificTags) ||
numOfTags < LIST_LENGTH(pStmt->pValsOfTags)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
}
+ SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
+ if (!pTagArray) {
+ return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_TSC_OUT_OF_MEMORY);
+ }
+ int32_t code = TSDB_CODE_SUCCESS;
+ int16_t nTags = 0, nBufPos = 0;
SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta);
- SNode * pTag, *pNode;
+ SNode * pTag = NULL, *pNode = NULL;
+ bool isJson = false;
FORBOTH(pTag, pStmt->pSpecificTags, pNode, pStmt->pValsOfTags) {
SColumnNode* pCol = (SColumnNode*)pTag;
SSchema* pSchema = NULL;
@@ -4240,56 +4245,125 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla
}
}
if (NULL == pSchema) {
- return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, pCol->colName);
+ code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, pCol->colName);
+ goto end;
}
SValueNode* pVal = NULL;
- int32_t code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal);
- if (TSDB_CODE_SUCCESS == code) {
- if (NULL == pVal) {
- pVal = (SValueNode*)pNode;
- } else {
- REPLACE_LIST2_NODE(pVal);
- }
+ code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal);
+ if (TSDB_CODE_SUCCESS != code) {
+ goto end;
}
- if (TSDB_CODE_SUCCESS == code) {
- code = addValToKVRow(pCxt, pVal, pSchema, pBuilder);
+
+ if (NULL == pVal) {
+ pVal = (SValueNode*)pNode;
+ } else {
+ REPLACE_LIST2_NODE(pVal);
}
- if (TSDB_CODE_SUCCESS != code) {
- return code;
+ if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
+ if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
+ code = buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal);
+ goto end;
+ }
+
+ isJson = true;
+ code = parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf);
+ if(code != TSDB_CODE_SUCCESS){
+ goto end;
+ }
+ }else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
+ void* nodeVal = nodesGetValueFromNode(pVal);
+ STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
+ if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
+ val.pData = varDataVal(nodeVal);
+ val.nData = varDataLen(nodeVal);
+ } else {
+ memcpy(&val.i64, nodeVal, pTagSchema->bytes);
+ }
+ taosArrayPush(pTagArray, &val);
}
}
+ if(!isJson) code = tTagNew(pTagArray, 1, false, ppTag);
+
+end:
+ if(isJson){
+ for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
+ STagVal *p = (STagVal *)taosArrayGet(pTagArray, i);
+ if(IS_VAR_DATA_TYPE(p->type)){
+ taosMemoryFree(p->pData);
+ }
+ }
+ }
+ taosArrayDestroy(pTagArray);
return TSDB_CODE_SUCCESS;
}
static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta,
- SKVRowBuilder* pBuilder) {
+ STag** ppTag) {
if (getNumOfTags(pSuperTableMeta) != LIST_LENGTH(pStmt->pValsOfTags)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
}
- SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta);
+ SSchema* pTagSchemas = getTableTagSchema(pSuperTableMeta);
SNode* pNode;
+ int32_t code = TSDB_CODE_SUCCESS;
int32_t index = 0;
+ SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
+ if (!pTagArray) {
+ return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_TSC_OUT_OF_MEMORY);
+ }
+
+ bool isJson = false;
FOREACH(pNode, pStmt->pValsOfTags) {
SValueNode* pVal = NULL;
- int32_t code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema + index, pNode, &pVal);
- if (TSDB_CODE_SUCCESS == code) {
- if (NULL == pVal) {
- pVal = (SValueNode*)pNode;
+ SSchema* pTagSchema = pTagSchemas + index;
+ code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal);
+ if (TSDB_CODE_SUCCESS != code) {
+ goto end;
+ }
+ if (NULL == pVal) {
+ pVal = (SValueNode*)pNode;
+ } else {
+ REPLACE_NODE(pVal);
+ }
+ if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
+ if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
+ code = buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal);
+ goto end;
+ }
+
+ isJson = true;
+ code = parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf);
+ if(code != TSDB_CODE_SUCCESS){
+ goto end;
+ }
+ }else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
+ char* tmpVal = nodesGetValueFromNode(pVal);
+ STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
+ if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
+ val.pData = varDataVal(tmpVal);
+ val.nData = varDataLen(tmpVal);
} else {
- REPLACE_NODE(pVal);
+ memcpy(&val.i64, tmpVal, pTagSchema->bytes);
}
+ taosArrayPush(pTagArray, &val);
}
- if (TSDB_CODE_SUCCESS == code) {
- code = addValToKVRow(pCxt, pVal, pTagSchema + index++, pBuilder);
- }
- if (TSDB_CODE_SUCCESS != code) {
- return code;
+ ++index;
+ }
+ if(!isJson) code = tTagNew(pTagArray, 1, false, ppTag);
+
+end:
+ if(isJson){
+ for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
+ STagVal *p = (STagVal *)taosArrayGet(pTagArray, i);
+ if(IS_VAR_DATA_TYPE(p->type)){
+ taosMemoryFree(p->pData);
+ }
}
}
- return TSDB_CODE_SUCCESS;
+ taosArrayDestroy(pTagArray);
+ return code;
}
static int32_t checkCreateSubTable(STranslateContext* pCxt, SCreateSubTableClause* pStmt) {
@@ -4306,26 +4380,13 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla
code = getTableMeta(pCxt, pStmt->useDbName, pStmt->useTableName, &pSuperTableMeta);
}
- SKVRowBuilder kvRowBuilder = {0};
- if (TSDB_CODE_SUCCESS == code) {
- code = tdInitKVRowBuilder(&kvRowBuilder);
- }
+ STag* pTag = NULL;
if (TSDB_CODE_SUCCESS == code) {
if (NULL != pStmt->pSpecificTags) {
- code = buildKVRowForBindTags(pCxt, pStmt, pSuperTableMeta, &kvRowBuilder);
+ code = buildKVRowForBindTags(pCxt, pStmt, pSuperTableMeta, &pTag);
} else {
- code = buildKVRowForAllTags(pCxt, pStmt, pSuperTableMeta, &kvRowBuilder);
- }
- }
-
- SKVRow row = NULL;
- if (TSDB_CODE_SUCCESS == code) {
- row = tdGetKVRowFromBuilder(&kvRowBuilder);
- if (NULL == row) {
- code = TSDB_CODE_OUT_OF_MEMORY;
- } else {
- tdSortKVRowByColIdx(row);
+ code = buildKVRowForAllTags(pCxt, pStmt, pSuperTableMeta, &pTag);
}
}
@@ -4334,11 +4395,10 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla
code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info);
}
if (TSDB_CODE_SUCCESS == code) {
- addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, row, pSuperTableMeta->uid, &info);
+ addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid, &info);
}
taosMemoryFreeClear(pSuperTableMeta);
- tdDestroyKVRowBuilder(&kvRowBuilder);
return code;
}
@@ -4560,37 +4620,41 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS
pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type);
if (pStmt->pVal->node.resType.type == TSDB_DATA_TYPE_JSON) {
- SKVRowBuilder kvRowBuilder = {0};
- int32_t code = tdInitKVRowBuilder(&kvRowBuilder);
-
- if (TSDB_CODE_SUCCESS != code) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
if (pStmt->pVal->literal &&
strlen(pStmt->pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pStmt->pVal->literal);
}
-
- code = parseJsontoTagData(pStmt->pVal->literal, &kvRowBuilder, &pCxt->msgBuf, pSchema->colId);
- if (TSDB_CODE_SUCCESS != code) {
- return code;
+ SArray *pTagVals = taosArrayInit(1, sizeof(STagVal));
+ int32_t code = TSDB_CODE_SUCCESS;
+ STag* pTag = NULL;
+ do{
+ code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf);
+ if (TSDB_CODE_SUCCESS != code) {
+ break;
+ }
+ }while(0);
+ for (int i = 0; i < taosArrayGetSize(pTagVals); ++i) {
+ STagVal *p = (STagVal *)taosArrayGet(pTagVals, i);
+ if(IS_VAR_DATA_TYPE(p->type)){
+ taosMemoryFree(p->pData);
+ }
}
-
- SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
- if (NULL == row) {
- tdDestroyKVRowBuilder(&kvRowBuilder);
- return TSDB_CODE_OUT_OF_MEMORY;
+ taosArrayDestroy(pTagVals);
+ if (code != TSDB_CODE_SUCCESS){
+ return code;
}
- pReq->nTagVal = kvRowLen(row);
- pReq->pTagVal = row;
- pStmt->pVal->datum.p = row; // for free
- tdDestroyKVRowBuilder(&kvRowBuilder);
+ pReq->nTagVal = pTag->len;
+ pReq->pTagVal = (uint8_t *)pTag;
+ pStmt->pVal->datum.p = (char*)pTag; // for free
} else {
pReq->nTagVal = pStmt->pVal->node.resType.bytes;
- if (TSDB_DATA_TYPE_NCHAR == pStmt->pVal->node.resType.type) {
- pReq->nTagVal = pReq->nTagVal * TSDB_NCHAR_SIZE;
- }
pReq->pTagVal = nodesGetValueFromNode(pStmt->pVal);
+
+ // data and length are seperated for new tag format STagVal
+ if (IS_VAR_DATA_TYPE(pStmt->pVal->node.resType.type)) {
+ pReq->nTagVal = varDataLen(pReq->pTagVal);
+ pReq->pTagVal = varDataVal(pReq->pTagVal);
+ }
}
return TSDB_CODE_SUCCESS;
@@ -4872,6 +4936,47 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
return code;
}
+static int32_t toMsgType(ENodeType type) {
+ switch (type) {
+ case QUERY_NODE_CREATE_TABLE_STMT:
+ return TDMT_VND_CREATE_TABLE;
+ case QUERY_NODE_ALTER_TABLE_STMT:
+ return TDMT_VND_ALTER_TABLE;
+ case QUERY_NODE_DROP_TABLE_STMT:
+ return TDMT_VND_DROP_TABLE;
+ default:
+ break;
+ }
+ return TDMT_VND_CREATE_TABLE;
+}
+
+static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery) {
+ if (NULL != pCxt->pDbs) {
+ pQuery->pDbList = taosArrayInit(taosHashGetSize(pCxt->pDbs), TSDB_DB_FNAME_LEN);
+ if (NULL == pQuery->pDbList) {
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ SFullDatabaseName* pDb = taosHashIterate(pCxt->pDbs, NULL);
+ while (NULL != pDb) {
+ taosArrayPush(pQuery->pDbList, pDb->fullDbName);
+ pDb = taosHashIterate(pCxt->pDbs, pDb);
+ }
+ }
+
+ if (NULL != pCxt->pTables) {
+ pQuery->pTableList = taosArrayInit(taosHashGetSize(pCxt->pTables), sizeof(SName));
+ if (NULL == pQuery->pTableList) {
+ return TSDB_CODE_OUT_OF_MEMORY;
+ }
+ SName* pTable = taosHashIterate(pCxt->pTables, NULL);
+ while (NULL != pTable) {
+ taosArrayPush(pQuery->pTableList, pTable);
+ pTable = taosHashIterate(pCxt->pTables, pTable);
+ }
+ }
+ return TSDB_CODE_SUCCESS;
+}
+
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
switch (nodeType(pQuery->pRoot)) {
case QUERY_NODE_SELECT_STMT:
@@ -4883,7 +4988,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
break;
case QUERY_NODE_VNODE_MODIF_STMT:
pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
- pQuery->msgType = TDMT_VND_CREATE_TABLE;
+ pQuery->msgType = toMsgType(((SVnodeModifOpStmt*)pQuery->pRoot)->sqlNodeType);
break;
case QUERY_NODE_DESCRIBE_STMT:
pQuery->execMode = QUERY_EXEC_MODE_LOCAL;
@@ -4911,30 +5016,6 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
}
}
- if (NULL != pCxt->pDbs) {
- pQuery->pDbList = taosArrayInit(taosHashGetSize(pCxt->pDbs), TSDB_DB_FNAME_LEN);
- if (NULL == pQuery->pDbList) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
- SFullDatabaseName* pDb = taosHashIterate(pCxt->pDbs, NULL);
- while (NULL != pDb) {
- taosArrayPush(pQuery->pDbList, pDb->fullDbName);
- pDb = taosHashIterate(pCxt->pDbs, pDb);
- }
- }
-
- if (NULL != pCxt->pTables) {
- pQuery->pTableList = taosArrayInit(taosHashGetSize(pCxt->pTables), sizeof(SName));
- if (NULL == pQuery->pTableList) {
- return TSDB_CODE_OUT_OF_MEMORY;
- }
- SName* pTable = taosHashIterate(pCxt->pTables, NULL);
- while (NULL != pTable) {
- taosArrayPush(pQuery->pTableList, pTable);
- pTable = taosHashIterate(pCxt->pTables, pTable);
- }
- }
-
return TSDB_CODE_SUCCESS;
}
@@ -4954,6 +5035,7 @@ int32_t translate(SParseContext* pParseCxt, SQuery* pQuery) {
if (TSDB_CODE_SUCCESS == code) {
code = setQuery(&cxt, pQuery);
}
+ setRefreshMate(&cxt, pQuery);
destroyTranslateContext(&cxt);
return code;
}
diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c
index 9882440bbb632e2d989da9f8a5f2be880bb37eab..0a1915d6c2fc5c1c776f6e991a2e39ee6d8a9aa3 100644
--- a/source/libs/parser/src/parUtil.c
+++ b/source/libs/parser/src/parUtil.c
@@ -322,33 +322,35 @@ static bool isValidateTag(char* input) {
return true;
}
-int32_t parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBuf* pMsgBuf, int16_t startColId) {
+int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag **ppTag, SMsgBuf* pMsgBuf) {
+ int32_t retCode = TSDB_CODE_SUCCESS;
+ cJSON* root = NULL;
+ SHashObj* keyHash = NULL;
+ int32_t size = 0;
// set json NULL data
- uint8_t jsonNULL = TSDB_DATA_TYPE_NULL;
- int32_t jsonIndex = startColId + 1;
if (!json || strtrim((char*)json) == 0 || strcasecmp(json, TSDB_DATA_NULL_STR_L) == 0) {
- tdAddColToKVRow(kvRowBuilder, jsonIndex, &jsonNULL, CHAR_BYTES);
- return TSDB_CODE_SUCCESS;
+ retCode = TSDB_CODE_SUCCESS;
+ goto end;
}
// set json real data
- cJSON* root = cJSON_Parse(json);
+ root = cJSON_Parse(json);
if (root == NULL) {
- return buildSyntaxErrMsg(pMsgBuf, "json parse error", json);
+ retCode = buildSyntaxErrMsg(pMsgBuf, "json parse error", json);
+ goto end;
}
- int32_t size = cJSON_GetArraySize(root);
+ size = cJSON_GetArraySize(root);
if (!cJSON_IsObject(root)) {
- return buildSyntaxErrMsg(pMsgBuf, "json error invalide value", json);
+ retCode = buildSyntaxErrMsg(pMsgBuf, "json error invalide value", json);
+ goto end;
}
- int32_t retCode = 0;
- char* tagKV = NULL;
- SHashObj* keyHash = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, false);
+ keyHash = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, false);
for (int32_t i = 0; i < size; i++) {
cJSON* item = cJSON_GetArrayItem(root, i);
if (!item) {
- qError("json inner error:%d", i);
+ uError("json inner error:%d", i);
retCode = buildSyntaxErrMsg(pMsgBuf, "json inner error", json);
goto end;
}
@@ -360,85 +362,60 @@ int32_t parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBu
}
size_t keyLen = strlen(jsonKey);
if (keyLen > TSDB_MAX_JSON_KEY_LEN) {
- qError("json key too long error");
+ uError("json key too long error");
retCode = buildSyntaxErrMsg(pMsgBuf, "json key too long, more than 256", jsonKey);
goto end;
}
if (keyLen == 0 || taosHashGet(keyHash, jsonKey, keyLen) != NULL) {
continue;
}
- // key: keyLen + VARSTR_HEADER_SIZE, value type: CHAR_BYTES, value reserved: DOUBLE_BYTES
- tagKV = taosMemoryCalloc(keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES + DOUBLE_BYTES, 1);
- if (!tagKV) {
- retCode = TSDB_CODE_TSC_OUT_OF_MEMORY;
- goto end;
- }
- strncpy(varDataVal(tagKV), jsonKey, keyLen);
- varDataSetLen(tagKV, keyLen);
- if (taosHashGetSize(keyHash) == 0) {
- uint8_t jsonNotNULL = TSDB_DATA_TYPE_JSON;
- tdAddColToKVRow(kvRowBuilder, jsonIndex++, &jsonNotNULL, CHAR_BYTES); // add json type
- }
- taosHashPut(keyHash, jsonKey, keyLen, &keyLen,
- CHAR_BYTES); // add key to hash to remove dumplicate, value is useless
+ STagVal val = {0};
+ val.pKey = jsonKey;
+ taosHashPut(keyHash, jsonKey, keyLen, &keyLen, CHAR_BYTES); // add key to hash to remove dumplicate, value is useless
if (item->type == cJSON_String) { // add json value format: type|data
char* jsonValue = item->valuestring;
int32_t valLen = (int32_t)strlen(jsonValue);
- int32_t totalLen = keyLen + VARSTR_HEADER_SIZE + valLen * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE + CHAR_BYTES;
- char* tmp = taosMemoryRealloc(tagKV, totalLen);
+ char* tmp = taosMemoryCalloc(1, valLen * TSDB_NCHAR_SIZE);
if (!tmp) {
retCode = TSDB_CODE_TSC_OUT_OF_MEMORY;
goto end;
}
- tagKV = tmp;
- char* valueType = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE);
- char* valueData = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES);
- *valueType = TSDB_DATA_TYPE_NCHAR;
- if (valLen > 0 && !taosMbsToUcs4(jsonValue, valLen, (TdUcs4*)varDataVal(valueData),
+ val.type = TSDB_DATA_TYPE_NCHAR;
+ if (valLen > 0 && !taosMbsToUcs4(jsonValue, valLen, (TdUcs4*)tmp,
(int32_t)(valLen * TSDB_NCHAR_SIZE), &valLen)) {
- qError("charset:%s to %s. val:%s, errno:%s, convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, jsonValue,
+ uError("charset:%s to %s. val:%s, errno:%s, convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, jsonValue,
strerror(errno));
retCode = buildSyntaxErrMsg(pMsgBuf, "charset convert json error", jsonValue);
goto end;
}
-
- varDataSetLen(valueData, valLen);
- tdAddColToKVRow(kvRowBuilder, jsonIndex++, tagKV, totalLen);
+ val.nData = valLen;
+ val.pData = tmp;
} else if (item->type == cJSON_Number) {
if (!isfinite(item->valuedouble)) {
- qError("json value is invalidate");
+ uError("json value is invalidate");
retCode = buildSyntaxErrMsg(pMsgBuf, "json value number is illegal", json);
goto end;
}
- char* valueType = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE);
- char* valueData = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES);
- *valueType = TSDB_DATA_TYPE_DOUBLE;
- *((double*)valueData) = item->valuedouble;
- tdAddColToKVRow(kvRowBuilder, jsonIndex++, tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES + DOUBLE_BYTES);
+ val.type = TSDB_DATA_TYPE_DOUBLE;
+ *((double*)&(val.i64)) = item->valuedouble;
} else if (item->type == cJSON_True || item->type == cJSON_False) {
- char* valueType = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE);
- char* valueData = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES);
- *valueType = TSDB_DATA_TYPE_BOOL;
- *valueData = (char)(item->valueint);
- tdAddColToKVRow(kvRowBuilder, jsonIndex++, tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES + CHAR_BYTES);
+ val.type = TSDB_DATA_TYPE_BOOL;
+ *((char*)&(val.i64)) = (char)(item->valueint);
} else if (item->type == cJSON_NULL) {
- char* valueType = POINTER_SHIFT(tagKV, keyLen + VARSTR_HEADER_SIZE);
- *valueType = TSDB_DATA_TYPE_NULL;
- tdAddColToKVRow(kvRowBuilder, jsonIndex++, tagKV, keyLen + VARSTR_HEADER_SIZE + CHAR_BYTES);
+ val.type = TSDB_DATA_TYPE_NULL;
} else {
retCode = buildSyntaxErrMsg(pMsgBuf, "invalidate json value", json);
goto end;
}
- }
-
- if (taosHashGetSize(keyHash) == 0) { // set json NULL true
- tdAddColToKVRow(kvRowBuilder, jsonIndex, &jsonNULL, CHAR_BYTES);
+ taosArrayPush(pTagVals, &val);
}
end:
- taosMemoryFree(tagKV);
taosHashCleanup(keyHash);
+ if(retCode == TSDB_CODE_SUCCESS){
+ tTagNew(pTagVals, 1, true, ppTag);
+ }
cJSON_Delete(root);
return retCode;
}
diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c
index bb70458f983832533fe8fa18ab58b58ca38558a6..c2e1eba4727281a54b778d64afc25ea159a11880 100644
--- a/source/libs/parser/src/parser.c
+++ b/source/libs/parser/src/parser.c
@@ -76,28 +76,8 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
int32_t inputSize = (NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes);
pVal->node.resType.type = pParam->buffer_type;
pVal->node.resType.bytes = inputSize;
+
switch (pParam->buffer_type) {
- case TSDB_DATA_TYPE_BOOL:
- pVal->datum.b = *((bool*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_TINYINT:
- pVal->datum.i = *((int8_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_SMALLINT:
- pVal->datum.i = *((int16_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_INT:
- pVal->datum.i = *((int32_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_BIGINT:
- pVal->datum.i = *((int64_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_FLOAT:
- pVal->datum.d = *((float*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_DOUBLE:
- pVal->datum.d = *((double*)pParam->buffer);
- break;
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
@@ -124,28 +104,13 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
pVal->node.resType.bytes = output + VARSTR_HEADER_SIZE;
break;
}
- case TSDB_DATA_TYPE_TIMESTAMP:
- pVal->datum.i = *((int64_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_UTINYINT:
- pVal->datum.u = *((uint8_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_USMALLINT:
- pVal->datum.u = *((uint16_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_UINT:
- pVal->datum.u = *((uint32_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_UBIGINT:
- pVal->datum.u = *((uint64_t*)pParam->buffer);
- break;
- case TSDB_DATA_TYPE_JSON:
- case TSDB_DATA_TYPE_DECIMAL:
- case TSDB_DATA_TYPE_BLOB:
- case TSDB_DATA_TYPE_MEDIUMBLOB:
- // todo
- default:
+ default: {
+ int32_t code = nodesSetValueNodeValue(pVal, pParam->buffer);
+ if (code) {
+ return code;
+ }
break;
+ }
}
pVal->translate = true;
return TSDB_CODE_SUCCESS;
diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c
index 262abac54bbd1c1ea9847c05507bb13fdedb0462..ff4fe4032e9be6ab95696bf41d6e1f398983e7b1 100644
--- a/source/libs/parser/src/sql.c
+++ b/source/libs/parser/src/sql.c
@@ -32,11 +32,15 @@
#include
#include
+#define ALLOW_FORBID_FUNC
+
#include "functionMgt.h"
#include "nodes.h"
#include "parToken.h"
#include "ttokendef.h"
#include "parAst.h"
+
+#define YYSTACKDEPTH 0
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders". This section is blank unless
@@ -100,25 +104,25 @@
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
-#define YYNOCODE 361
+#define YYNOCODE 357
#define YYACTIONTYPE unsigned short int
#define ParseTOKENTYPE SToken
typedef union {
int yyinit;
ParseTOKENTYPE yy0;
- EFillMode yy18;
- SAlterOption yy25;
- SToken yy53;
- EOperatorType yy136;
- int32_t yy158;
- ENullOrder yy185;
- SNodeList* yy236;
- EJoinType yy342;
- EOrder yy430;
- int64_t yy435;
- SDataType yy450;
- bool yy603;
- SNode* yy636;
+ SAlterOption yy53;
+ ENullOrder yy109;
+ SToken yy113;
+ EJoinType yy120;
+ int64_t yy123;
+ bool yy131;
+ EOrder yy428;
+ SDataType yy490;
+ EFillMode yy522;
+ int32_t yy550;
+ EOperatorType yy632;
+ SNodeList* yy670;
+ SNode* yy686;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -134,17 +138,18 @@ typedef union {
#define ParseCTX_FETCH
#define ParseCTX_STORE
#define YYFALLBACK 1
-#define YYNSTATE 611
-#define YYNRULE 455
-#define YYNTOKEN 240
-#define YY_MAX_SHIFT 610
-#define YY_MIN_SHIFTREDUCE 901
-#define YY_MAX_SHIFTREDUCE 1355
-#define YY_ERROR_ACTION 1356
-#define YY_ACCEPT_ACTION 1357
-#define YY_NO_ACTION 1358
-#define YY_MIN_REDUCE 1359
-#define YY_MAX_REDUCE 1813
+#define YYNSTATE 612
+#define YYNRULE 451
+#define YYNRULE_WITH_ACTION 451
+#define YYNTOKEN 237
+#define YY_MAX_SHIFT 611
+#define YY_MIN_SHIFTREDUCE 898
+#define YY_MAX_SHIFTREDUCE 1348
+#define YY_ERROR_ACTION 1349
+#define YY_ACCEPT_ACTION 1350
+#define YY_NO_ACTION 1351
+#define YY_MIN_REDUCE 1352
+#define YY_MAX_REDUCE 1802
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -211,604 +216,622 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2153)
+#define YY_ACTTAB_COUNT (2125)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 386, 1647, 387, 1391, 295, 394, 524, 387, 1391, 28,
- /* 10 */ 226, 931, 35, 33, 130, 1676, 1371, 1660, 104, 1791,
- /* 20 */ 304, 1644, 1169, 477, 523, 424, 36, 34, 32, 31,
- /* 30 */ 30, 385, 1790, 62, 389, 1490, 1788, 1640, 1646, 36,
- /* 40 */ 34, 32, 31, 30, 1535, 1676, 108, 1167, 527, 935,
- /* 50 */ 936, 294, 1000, 508, 524, 1485, 1533, 154, 14, 476,
- /* 60 */ 35, 33, 1296, 507, 1175, 24, 350, 1630, 304, 1002,
- /* 70 */ 1169, 1418, 277, 488, 523, 36, 34, 32, 31, 30,
- /* 80 */ 56, 1, 60, 1490, 1689, 59, 524, 80, 1661, 510,
- /* 90 */ 1663, 1664, 506, 1359, 527, 1167, 1207, 1729, 104, 603,
- /* 100 */ 602, 276, 1725, 607, 1258, 429, 14, 36, 34, 32,
- /* 110 */ 31, 30, 1175, 1791, 1168, 1490, 140, 103, 102, 101,
- /* 120 */ 100, 99, 98, 97, 96, 95, 147, 376, 1529, 2,
- /* 130 */ 1788, 583, 582, 581, 319, 39, 580, 579, 578, 114,
- /* 140 */ 573, 572, 571, 570, 569, 568, 567, 566, 121, 562,
- /* 150 */ 511, 607, 1568, 307, 1259, 55, 1580, 55, 1170, 156,
- /* 160 */ 94, 1791, 1168, 93, 92, 91, 90, 89, 88, 87,
- /* 170 */ 86, 85, 158, 157, 146, 352, 1264, 1352, 1788, 393,
- /* 180 */ 1173, 1174, 389, 1220, 1221, 1223, 1224, 1225, 1226, 1227,
- /* 190 */ 503, 525, 1235, 1236, 1237, 1238, 1239, 1240, 1468, 36,
- /* 200 */ 34, 32, 31, 30, 64, 292, 1170, 131, 191, 274,
- /* 210 */ 148, 1447, 27, 302, 1253, 1254, 1255, 1256, 1257, 1261,
- /* 220 */ 1262, 1263, 1421, 36, 34, 32, 31, 30, 1173, 1174,
- /* 230 */ 484, 1220, 1221, 1223, 1224, 1225, 1226, 1227, 503, 525,
- /* 240 */ 1235, 1236, 1237, 1238, 1239, 1240, 35, 33, 1467, 948,
- /* 250 */ 70, 947, 438, 437, 304, 403, 1169, 436, 1351, 112,
- /* 260 */ 109, 433, 308, 1791, 432, 431, 430, 35, 33, 1310,
- /* 270 */ 128, 1483, 1660, 403, 523, 304, 1789, 1169, 949, 1492,
- /* 280 */ 1788, 1167, 438, 437, 148, 1193, 148, 436, 62, 972,
- /* 290 */ 109, 433, 14, 1207, 432, 431, 430, 110, 1175, 1360,
- /* 300 */ 1676, 1303, 1167, 1382, 1660, 524, 973, 1193, 508, 524,
- /* 310 */ 1486, 486, 142, 1736, 1737, 2, 1741, 351, 507, 1175,
- /* 320 */ 94, 361, 1630, 93, 92, 91, 90, 89, 88, 87,
- /* 330 */ 86, 85, 1676, 1381, 1490, 38, 8, 607, 1490, 1689,
- /* 340 */ 487, 559, 82, 1661, 510, 1663, 1664, 506, 1168, 527,
- /* 350 */ 507, 1191, 1729, 1630, 1630, 1535, 1728, 1725, 607, 128,
- /* 360 */ 558, 557, 309, 556, 555, 554, 1380, 1533, 1493, 1168,
- /* 370 */ 565, 1689, 1462, 1535, 81, 1661, 510, 1663, 1664, 506,
- /* 380 */ 315, 527, 524, 1630, 1729, 1533, 1743, 26, 297, 1725,
- /* 390 */ 141, 478, 1170, 54, 362, 435, 434, 36, 34, 32,
- /* 400 */ 31, 30, 218, 36, 34, 32, 31, 30, 466, 1756,
- /* 410 */ 1740, 1490, 55, 1170, 1173, 1174, 1630, 1220, 1221, 1223,
- /* 420 */ 1224, 1225, 1226, 1227, 503, 525, 1235, 1236, 1237, 1238,
- /* 430 */ 1239, 1240, 460, 577, 575, 1173, 1174, 1379, 1220, 1221,
- /* 440 */ 1223, 1224, 1225, 1226, 1227, 503, 525, 1235, 1236, 1237,
- /* 450 */ 1238, 1239, 1240, 35, 33, 1241, 1378, 443, 1195, 610,
- /* 460 */ 316, 304, 1377, 1169, 148, 148, 249, 1571, 1573, 1520,
- /* 470 */ 1246, 1222, 451, 243, 35, 33, 1193, 1481, 1376, 1660,
- /* 480 */ 1647, 461, 304, 312, 1169, 105, 190, 1630, 1167, 524,
- /* 490 */ 473, 599, 595, 591, 587, 242, 391, 1644, 446, 1357,
- /* 500 */ 1644, 402, 1191, 440, 561, 1175, 1630, 1676, 189, 1167,
- /* 510 */ 337, 484, 1630, 1640, 1646, 508, 1640, 1646, 1490, 484,
- /* 520 */ 78, 1791, 9, 237, 527, 507, 1175, 527, 1630, 1630,
- /* 530 */ 339, 335, 564, 51, 145, 488, 50, 127, 1788, 511,
- /* 540 */ 112, 148, 576, 9, 607, 1581, 1689, 1194, 112, 80,
- /* 550 */ 1661, 510, 1663, 1664, 506, 1168, 527, 520, 320, 1729,
- /* 560 */ 1375, 479, 474, 276, 1725, 607, 36, 34, 32, 31,
- /* 570 */ 30, 1648, 1130, 314, 1479, 1791, 1168, 428, 110, 553,
- /* 580 */ 1132, 128, 465, 340, 217, 198, 110, 1465, 145, 55,
- /* 590 */ 1492, 1644, 1788, 143, 1736, 1737, 77, 1741, 1791, 1170,
- /* 600 */ 427, 144, 1736, 1737, 1146, 1741, 193, 1640, 1646, 113,
- /* 610 */ 1630, 145, 277, 1572, 1573, 1788, 490, 1482, 527, 1295,
- /* 620 */ 1170, 1173, 1174, 1374, 1220, 1221, 1223, 1224, 1225, 1226,
- /* 630 */ 1227, 503, 525, 1235, 1236, 1237, 1238, 1239, 1240, 286,
- /* 640 */ 1222, 1131, 1173, 1174, 1258, 1220, 1221, 1223, 1224, 1225,
- /* 650 */ 1226, 1227, 503, 525, 1235, 1236, 1237, 1238, 1239, 1240,
- /* 660 */ 35, 33, 273, 559, 1191, 345, 1320, 344, 304, 524,
- /* 670 */ 1169, 369, 524, 1630, 381, 32, 31, 30, 1748, 1291,
- /* 680 */ 559, 1487, 558, 557, 1610, 556, 555, 554, 287, 7,
- /* 690 */ 285, 284, 382, 426, 1259, 1167, 947, 428, 1490, 558,
- /* 700 */ 557, 1490, 556, 555, 554, 470, 1318, 1319, 1321, 1322,
- /* 710 */ 1535, 317, 1175, 11, 10, 1373, 1264, 1743, 148, 128,
- /* 720 */ 427, 422, 1534, 935, 936, 1743, 1154, 1155, 1492, 2,
- /* 730 */ 1038, 550, 549, 548, 1042, 547, 1044, 1045, 546, 1047,
- /* 740 */ 543, 1739, 1053, 540, 1055, 1056, 537, 534, 346, 1738,
- /* 750 */ 1370, 607, 27, 302, 1253, 1254, 1255, 1256, 1257, 1261,
- /* 760 */ 1262, 1263, 1168, 380, 1466, 1630, 375, 374, 373, 372,
- /* 770 */ 371, 368, 367, 366, 365, 364, 360, 359, 358, 357,
- /* 780 */ 356, 355, 354, 353, 524, 524, 129, 524, 1791, 1196,
- /* 790 */ 492, 255, 1192, 1193, 1272, 1260, 521, 522, 1475, 239,
- /* 800 */ 1630, 145, 1369, 253, 53, 1788, 1170, 52, 1368, 1367,
- /* 810 */ 1366, 452, 1365, 1490, 1490, 1364, 1490, 1265, 524, 1363,
- /* 820 */ 1660, 561, 1362, 47, 159, 275, 1294, 1477, 1173, 1174,
- /* 830 */ 318, 1220, 1221, 1223, 1224, 1225, 1226, 1227, 503, 525,
- /* 840 */ 1235, 1236, 1237, 1238, 1239, 1240, 495, 1490, 1676, 55,
- /* 850 */ 1473, 1791, 1630, 25, 1619, 194, 487, 1408, 1630, 1630,
- /* 860 */ 1630, 1291, 1630, 1403, 145, 1630, 507, 1401, 1788, 1630,
- /* 870 */ 1630, 182, 1630, 184, 180, 186, 183, 188, 185, 439,
- /* 880 */ 187, 1660, 500, 450, 502, 441, 79, 1689, 76, 444,
- /* 890 */ 81, 1661, 510, 1663, 1664, 506, 448, 527, 72, 327,
- /* 900 */ 1729, 11, 10, 552, 297, 1725, 141, 1372, 459, 1676,
- /* 910 */ 1354, 1355, 1650, 1448, 1660, 202, 1178, 508, 58, 57,
- /* 920 */ 349, 118, 46, 153, 471, 1757, 1177, 507, 343, 205,
- /* 930 */ 221, 1630, 37, 37, 37, 453, 212, 1677, 1392, 228,
- /* 940 */ 272, 421, 1676, 333, 1530, 329, 325, 150, 1689, 1652,
- /* 950 */ 508, 81, 1661, 510, 1663, 1664, 506, 1222, 527, 1759,
- /* 960 */ 507, 1729, 462, 1317, 1630, 297, 1725, 1804, 1191, 116,
- /* 970 */ 207, 117, 485, 1266, 1228, 1124, 1763, 493, 148, 1660,
- /* 980 */ 230, 1689, 220, 1181, 81, 1661, 510, 1663, 1664, 506,
- /* 990 */ 223, 527, 118, 1180, 1729, 1660, 46, 532, 297, 1725,
- /* 1000 */ 1804, 322, 117, 225, 1250, 3, 118, 1676, 326, 1786,
- /* 1010 */ 516, 282, 236, 1000, 283, 508, 119, 117, 244, 155,
- /* 1020 */ 1138, 363, 370, 1676, 1570, 507, 378, 1660, 377, 1630,
- /* 1030 */ 379, 508, 383, 1031, 1197, 496, 384, 248, 1059, 392,
- /* 1040 */ 1200, 507, 395, 1063, 162, 1630, 1689, 1070, 396, 82,
- /* 1050 */ 1661, 510, 1663, 1664, 506, 1676, 527, 1068, 120, 1729,
- /* 1060 */ 1199, 164, 1689, 508, 1726, 81, 1661, 510, 1663, 1664,
- /* 1070 */ 506, 1201, 527, 507, 397, 1729, 398, 1630, 1660, 297,
- /* 1080 */ 1725, 1804, 167, 488, 399, 169, 1198, 400, 401, 172,
- /* 1090 */ 1747, 61, 404, 1660, 1689, 175, 423, 262, 1661, 510,
- /* 1100 */ 1663, 1664, 506, 425, 527, 84, 1676, 1175, 1480, 179,
- /* 1110 */ 1476, 291, 181, 1614, 508, 122, 123, 1478, 1474, 124,
- /* 1120 */ 125, 1676, 245, 1791, 507, 192, 455, 195, 1630, 508,
- /* 1130 */ 246, 197, 454, 464, 488, 463, 147, 200, 1196, 507,
- /* 1140 */ 1788, 458, 472, 1630, 1660, 1689, 1770, 203, 262, 1661,
- /* 1150 */ 510, 1663, 1664, 506, 514, 527, 6, 1750, 469, 1769,
- /* 1160 */ 1689, 211, 481, 82, 1661, 510, 1663, 1664, 506, 206,
- /* 1170 */ 527, 1760, 1676, 1729, 1791, 296, 475, 499, 1725, 1195,
- /* 1180 */ 505, 468, 5, 1291, 111, 40, 497, 145, 1744, 1807,
- /* 1190 */ 507, 1788, 298, 18, 1630, 512, 1660, 513, 494, 306,
- /* 1200 */ 311, 310, 1579, 135, 1578, 1660, 214, 517, 518, 519,
- /* 1210 */ 1183, 1689, 213, 1787, 270, 1661, 510, 1663, 1664, 506,
- /* 1220 */ 504, 527, 501, 1701, 1676, 219, 232, 71, 491, 1710,
- /* 1230 */ 234, 247, 508, 1676, 69, 1176, 250, 1491, 241, 222,
- /* 1240 */ 606, 508, 507, 1463, 498, 48, 1630, 530, 224, 256,
- /* 1250 */ 134, 507, 1175, 1660, 263, 1630, 257, 293, 467, 252,
- /* 1260 */ 254, 1624, 1623, 1689, 321, 1620, 132, 1661, 510, 1663,
- /* 1270 */ 1664, 506, 1689, 527, 323, 271, 1661, 510, 1663, 1664,
- /* 1280 */ 506, 1676, 527, 324, 1163, 1660, 1164, 151, 1618, 508,
- /* 1290 */ 328, 528, 330, 331, 1617, 332, 334, 1616, 336, 507,
- /* 1300 */ 1615, 338, 1179, 1630, 1600, 152, 341, 1141, 342, 1140,
- /* 1310 */ 489, 1805, 1594, 1676, 1593, 347, 348, 1660, 1592, 1591,
- /* 1320 */ 1689, 508, 1107, 266, 1661, 510, 1663, 1664, 506, 1563,
- /* 1330 */ 527, 507, 1562, 1561, 1560, 1630, 1559, 1558, 1557, 1556,
- /* 1340 */ 1555, 1554, 1553, 1552, 1551, 1676, 1184, 1550, 1549, 1548,
- /* 1350 */ 1547, 1546, 1689, 508, 1545, 132, 1661, 510, 1663, 1664,
- /* 1360 */ 506, 480, 527, 507, 115, 1660, 1544, 1630, 1187, 1543,
- /* 1370 */ 301, 1542, 1541, 1540, 1109, 1539, 1538, 1537, 1660, 525,
- /* 1380 */ 1235, 1236, 1536, 1420, 1689, 1388, 160, 271, 1661, 510,
- /* 1390 */ 1663, 1664, 506, 1676, 527, 938, 106, 138, 937, 388,
- /* 1400 */ 1806, 505, 1387, 161, 390, 107, 1676, 1608, 1602, 1586,
- /* 1410 */ 1585, 507, 1576, 1469, 508, 1630, 166, 171, 1660, 1419,
- /* 1420 */ 966, 1417, 1415, 407, 507, 405, 1413, 411, 1630, 415,
- /* 1430 */ 1411, 303, 1689, 419, 406, 270, 1661, 510, 1663, 1664,
- /* 1440 */ 506, 409, 527, 410, 1702, 1689, 1676, 413, 271, 1661,
- /* 1450 */ 510, 1663, 1664, 506, 508, 527, 414, 1400, 177, 1399,
- /* 1460 */ 418, 417, 1386, 1471, 507, 1074, 1660, 1470, 1630, 1073,
- /* 1470 */ 139, 305, 574, 576, 999, 1169, 420, 416, 412, 408,
- /* 1480 */ 176, 45, 998, 178, 997, 1689, 996, 993, 271, 1661,
- /* 1490 */ 510, 1663, 1664, 506, 1676, 527, 992, 991, 1409, 288,
- /* 1500 */ 1167, 1404, 508, 289, 442, 63, 1402, 290, 174, 1385,
- /* 1510 */ 447, 445, 507, 1384, 449, 83, 1630, 1175, 1607, 1148,
- /* 1520 */ 49, 1601, 456, 1660, 1584, 126, 1583, 1575, 199, 65,
- /* 1530 */ 196, 4, 133, 1689, 201, 37, 258, 1661, 510, 1663,
- /* 1540 */ 1664, 506, 204, 527, 15, 457, 43, 1316, 1309, 208,
- /* 1550 */ 22, 1676, 209, 23, 210, 66, 607, 1288, 1650, 508,
- /* 1560 */ 1287, 216, 1345, 42, 136, 41, 173, 1168, 165, 507,
- /* 1570 */ 170, 1660, 168, 1630, 17, 1340, 1339, 16, 13, 1334,
- /* 1580 */ 10, 299, 1344, 1343, 300, 1251, 19, 137, 149, 1230,
- /* 1590 */ 1689, 163, 1215, 265, 1661, 510, 1663, 1664, 506, 1676,
- /* 1600 */ 527, 1660, 509, 1574, 29, 515, 12, 508, 1649, 233,
- /* 1610 */ 72, 1170, 1229, 20, 235, 1185, 531, 507, 238, 21,
- /* 1620 */ 229, 1630, 227, 529, 1314, 964, 313, 231, 67, 1676,
- /* 1630 */ 68, 1660, 1692, 1173, 1174, 1232, 526, 508, 1689, 44,
- /* 1640 */ 533, 267, 1661, 510, 1663, 1664, 506, 507, 527, 1060,
- /* 1650 */ 1057, 1630, 535, 538, 536, 541, 544, 1054, 539, 1676,
- /* 1660 */ 1037, 1052, 1048, 542, 1069, 1046, 545, 508, 1689, 551,
- /* 1670 */ 1051, 259, 1661, 510, 1663, 1664, 506, 507, 527, 1660,
- /* 1680 */ 73, 1630, 74, 75, 1066, 1065, 1050, 560, 1660, 1049,
- /* 1690 */ 988, 1006, 563, 240, 986, 985, 984, 983, 1689, 981,
- /* 1700 */ 1067, 268, 1661, 510, 1663, 1664, 506, 1676, 527, 982,
- /* 1710 */ 1003, 980, 979, 1001, 976, 508, 1676, 975, 974, 971,
- /* 1720 */ 970, 969, 1416, 584, 508, 507, 585, 586, 1414, 1630,
- /* 1730 */ 588, 589, 590, 1412, 507, 592, 1660, 593, 1630, 594,
- /* 1740 */ 1410, 596, 597, 598, 1398, 600, 1689, 601, 1397, 260,
- /* 1750 */ 1661, 510, 1663, 1664, 506, 1689, 527, 1383, 269, 1661,
- /* 1760 */ 510, 1663, 1664, 506, 1676, 527, 609, 604, 605, 1358,
- /* 1770 */ 1358, 1171, 508, 251, 608, 1358, 1358, 1358, 1358, 1358,
- /* 1780 */ 1358, 1358, 507, 1358, 1660, 1358, 1630, 1358, 1358, 1358,
- /* 1790 */ 1358, 1358, 1358, 1358, 1358, 1660, 1358, 1358, 1358, 1358,
- /* 1800 */ 1358, 1358, 1358, 1689, 1358, 1358, 261, 1661, 510, 1663,
- /* 1810 */ 1664, 506, 1676, 527, 1660, 1358, 1358, 1358, 1358, 1358,
- /* 1820 */ 508, 1358, 1358, 1676, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 1830 */ 507, 508, 1358, 1358, 1630, 1358, 1358, 1358, 1358, 1358,
- /* 1840 */ 1358, 507, 1676, 1358, 1358, 1630, 1358, 1358, 1358, 1358,
- /* 1850 */ 508, 1689, 1358, 1358, 1672, 1661, 510, 1663, 1664, 506,
- /* 1860 */ 507, 527, 1689, 1358, 1630, 1671, 1661, 510, 1663, 1664,
- /* 1870 */ 506, 1358, 527, 1660, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 1880 */ 1358, 1689, 1660, 1358, 1670, 1661, 510, 1663, 1664, 506,
- /* 1890 */ 1358, 527, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 1900 */ 1358, 1676, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 508,
- /* 1910 */ 1676, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 508, 507,
- /* 1920 */ 1358, 1358, 1358, 1630, 1358, 1358, 1358, 1358, 507, 1358,
- /* 1930 */ 1358, 1358, 1630, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 1940 */ 1689, 1358, 1660, 280, 1661, 510, 1663, 1664, 506, 1689,
- /* 1950 */ 527, 1660, 279, 1661, 510, 1663, 1664, 506, 1358, 527,
- /* 1960 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 1970 */ 1676, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 508, 1676,
- /* 1980 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 508, 507, 1358,
- /* 1990 */ 1358, 1358, 1630, 1358, 1358, 1358, 1358, 507, 1358, 1660,
- /* 2000 */ 1358, 1630, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1689,
- /* 2010 */ 484, 1358, 281, 1661, 510, 1663, 1664, 506, 1689, 527,
- /* 2020 */ 1358, 278, 1661, 510, 1663, 1664, 506, 1676, 527, 1358,
- /* 2030 */ 1358, 1358, 1358, 1358, 1358, 508, 1358, 1358, 1358, 112,
- /* 2040 */ 1358, 1358, 1358, 1358, 1358, 507, 484, 1358, 1358, 1630,
- /* 2050 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 488,
- /* 2060 */ 1358, 1358, 1358, 1358, 1358, 1358, 1689, 1358, 1358, 264,
- /* 2070 */ 1661, 510, 1663, 1664, 506, 112, 527, 110, 1358, 1358,
- /* 2080 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 2090 */ 1358, 1358, 215, 1736, 483, 488, 482, 1358, 1358, 1791,
- /* 2100 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
- /* 2110 */ 1358, 1358, 147, 110, 1358, 1358, 1788, 1358, 1358, 1358,
- /* 2120 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 215, 1736,
- /* 2130 */ 483, 1358, 482, 1358, 1358, 1791, 1358, 1358, 1358, 1358,
- /* 2140 */ 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 145, 1358,
- /* 2150 */ 1358, 1358, 1788,
+ /* 0 */ 132, 1780, 345, 1636, 1440, 1636, 294, 385, 311, 386,
+ /* 10 */ 1384, 78, 35, 33, 1779, 1472, 24, 1649, 1777, 131,
+ /* 20 */ 303, 1364, 1162, 1633, 114, 1633, 36, 34, 32, 31,
+ /* 30 */ 30, 1780, 1475, 36, 34, 32, 31, 30, 1629, 1635,
+ /* 40 */ 1629, 1635, 1780, 525, 147, 1665, 928, 1160, 1777, 529,
+ /* 50 */ 525, 529, 1350, 489, 393, 146, 386, 1384, 14, 1777,
+ /* 60 */ 35, 33, 1289, 509, 1168, 56, 384, 1619, 303, 388,
+ /* 70 */ 1162, 36, 34, 32, 31, 30, 36, 34, 32, 31,
+ /* 80 */ 30, 1, 77, 1678, 932, 933, 82, 1650, 512, 1652,
+ /* 90 */ 1653, 508, 73, 529, 1375, 1160, 1718, 1414, 1780, 1296,
+ /* 100 */ 296, 1714, 142, 608, 39, 1186, 14, 1353, 35, 33,
+ /* 110 */ 319, 1778, 1168, 1161, 220, 1777, 303, 277, 1162, 462,
+ /* 120 */ 468, 1745, 36, 34, 32, 31, 30, 71, 95, 2,
+ /* 130 */ 1374, 94, 93, 92, 91, 90, 89, 88, 87, 86,
+ /* 140 */ 525, 1200, 55, 1160, 1619, 315, 1303, 307, 1476, 1251,
+ /* 150 */ 1780, 608, 1563, 1565, 14, 129, 1163, 438, 437, 1780,
+ /* 160 */ 1168, 1161, 436, 146, 1485, 110, 433, 1777, 277, 432,
+ /* 170 */ 431, 430, 146, 945, 497, 944, 1777, 2, 1166, 1167,
+ /* 180 */ 1619, 1213, 1214, 1216, 1217, 1218, 1219, 1220, 505, 527,
+ /* 190 */ 1228, 1229, 1230, 1231, 1232, 1233, 286, 1239, 1252, 608,
+ /* 200 */ 1251, 38, 946, 1186, 1163, 55, 62, 95, 149, 1161,
+ /* 210 */ 94, 93, 92, 91, 90, 89, 88, 87, 86, 1257,
+ /* 220 */ 1732, 36, 34, 32, 31, 30, 1166, 1167, 1479, 1213,
+ /* 230 */ 1214, 1216, 1217, 1218, 1219, 1220, 505, 527, 1228, 1229,
+ /* 240 */ 1230, 1231, 1232, 1233, 1729, 287, 1373, 285, 284, 1252,
+ /* 250 */ 426, 403, 1163, 1372, 428, 27, 301, 1246, 1247, 1248,
+ /* 260 */ 1249, 1250, 1254, 1255, 1256, 513, 1188, 1215, 306, 149,
+ /* 270 */ 1257, 1572, 28, 228, 1166, 1167, 427, 1213, 1214, 1216,
+ /* 280 */ 1217, 1218, 1219, 1220, 505, 527, 1228, 1229, 1230, 1231,
+ /* 290 */ 1232, 1233, 35, 33, 1352, 1313, 1619, 64, 292, 1461,
+ /* 300 */ 303, 192, 1162, 1619, 526, 351, 27, 301, 1246, 1247,
+ /* 310 */ 1248, 1249, 1250, 1254, 1255, 1256, 349, 1189, 104, 103,
+ /* 320 */ 102, 101, 100, 99, 98, 97, 96, 1160, 149, 452,
+ /* 330 */ 560, 1649, 149, 1483, 472, 1311, 1312, 1314, 1315, 275,
+ /* 340 */ 35, 33, 1234, 1162, 1168, 486, 313, 1665, 303, 559,
+ /* 350 */ 1162, 558, 557, 556, 129, 479, 403, 1345, 526, 1665,
+ /* 360 */ 498, 8, 1371, 1485, 1560, 1215, 526, 489, 1160, 1780,
+ /* 370 */ 350, 157, 1527, 392, 113, 1160, 388, 509, 360, 293,
+ /* 380 */ 1186, 1619, 146, 608, 1525, 1168, 1777, 1483, 35, 33,
+ /* 390 */ 478, 219, 1168, 1161, 1370, 1483, 303, 1678, 1162, 1459,
+ /* 400 */ 82, 1650, 512, 1652, 1653, 508, 55, 529, 26, 9,
+ /* 410 */ 1718, 111, 1619, 1288, 296, 1714, 142, 141, 36, 34,
+ /* 420 */ 32, 31, 30, 1160, 608, 488, 143, 1725, 1726, 1521,
+ /* 430 */ 1730, 608, 62, 1369, 1161, 1746, 1163, 1344, 438, 437,
+ /* 440 */ 1168, 1161, 204, 436, 1619, 109, 110, 433, 11, 10,
+ /* 450 */ 432, 431, 430, 480, 1478, 1368, 562, 9, 1166, 1167,
+ /* 460 */ 475, 1213, 1214, 1216, 1217, 1218, 1219, 1220, 505, 527,
+ /* 470 */ 1228, 1229, 1230, 1231, 1232, 1233, 1187, 1163, 316, 608,
+ /* 480 */ 344, 336, 343, 1619, 1163, 1460, 129, 997, 149, 1161,
+ /* 490 */ 36, 34, 32, 31, 30, 1485, 1527, 604, 603, 1166,
+ /* 500 */ 1167, 338, 334, 308, 999, 1619, 1166, 1167, 1525, 1213,
+ /* 510 */ 1214, 1216, 1217, 1218, 1219, 1220, 505, 527, 1228, 1229,
+ /* 520 */ 1230, 1231, 1232, 1233, 36, 34, 32, 31, 30, 1265,
+ /* 530 */ 481, 476, 1163, 149, 7, 1035, 552, 551, 550, 1039,
+ /* 540 */ 549, 1041, 1042, 548, 1044, 545, 1367, 1050, 542, 1052,
+ /* 550 */ 1053, 539, 536, 1366, 1166, 1167, 1649, 1213, 1214, 1216,
+ /* 560 */ 1217, 1218, 1219, 1220, 505, 527, 1228, 1229, 1230, 1231,
+ /* 570 */ 1232, 1233, 35, 33, 274, 375, 1184, 1411, 560, 526,
+ /* 580 */ 303, 526, 1162, 368, 1665, 1732, 380, 250, 155, 390,
+ /* 590 */ 1513, 105, 507, 361, 1200, 1184, 1619, 559, 424, 558,
+ /* 600 */ 557, 556, 509, 1619, 381, 1527, 1619, 1160, 1483, 1728,
+ /* 610 */ 1483, 1363, 314, 60, 1253, 513, 59, 1525, 1287, 159,
+ /* 620 */ 158, 1573, 1678, 128, 1168, 270, 1650, 512, 1652, 1653,
+ /* 630 */ 508, 506, 529, 503, 1690, 1258, 486, 584, 583, 582,
+ /* 640 */ 318, 2, 581, 580, 579, 115, 574, 573, 572, 571,
+ /* 650 */ 570, 569, 568, 567, 122, 563, 1362, 32, 31, 30,
+ /* 660 */ 1186, 1619, 1361, 608, 1360, 113, 435, 434, 562, 578,
+ /* 670 */ 576, 25, 1359, 1161, 379, 1458, 1358, 374, 373, 372,
+ /* 680 */ 371, 370, 367, 366, 365, 364, 363, 359, 358, 357,
+ /* 690 */ 356, 355, 354, 353, 352, 486, 1564, 1565, 526, 932,
+ /* 700 */ 933, 1732, 111, 1527, 1284, 198, 1619, 54, 1357, 1356,
+ /* 710 */ 402, 526, 1619, 1355, 1619, 1526, 1163, 144, 1725, 1726,
+ /* 720 */ 1185, 1730, 1619, 105, 113, 1727, 1619, 1483, 129, 1649,
+ /* 730 */ 429, 55, 566, 65, 1455, 1365, 1474, 1486, 1166, 1167,
+ /* 740 */ 1483, 1213, 1214, 1216, 1217, 1218, 1219, 1220, 505, 527,
+ /* 750 */ 1228, 1229, 1230, 1231, 1232, 1233, 1633, 1665, 1619, 1619,
+ /* 760 */ 1649, 111, 1608, 1619, 428, 510, 969, 944, 560, 1737,
+ /* 770 */ 1284, 1629, 1635, 1147, 1148, 509, 145, 1725, 1726, 1619,
+ /* 780 */ 1730, 555, 529, 970, 490, 526, 427, 559, 1665, 558,
+ /* 790 */ 557, 556, 422, 502, 577, 1678, 510, 1480, 81, 1650,
+ /* 800 */ 512, 1652, 1653, 508, 494, 529, 509, 326, 1718, 1468,
+ /* 810 */ 1619, 526, 276, 1714, 1483, 490, 183, 185, 1637, 181,
+ /* 820 */ 184, 1649, 1215, 1599, 1780, 187, 1678, 1470, 186, 81,
+ /* 830 */ 1650, 512, 1652, 1653, 508, 339, 529, 148, 1633, 1718,
+ /* 840 */ 1483, 1777, 1639, 276, 1714, 130, 310, 309, 526, 1665,
+ /* 850 */ 256, 565, 450, 1629, 1635, 1780, 1176, 510, 149, 1466,
+ /* 860 */ 460, 195, 254, 53, 529, 448, 52, 509, 146, 504,
+ /* 870 */ 526, 1619, 1777, 443, 526, 189, 119, 1483, 188, 1641,
+ /* 880 */ 46, 1169, 523, 160, 1649, 207, 524, 1678, 451, 526,
+ /* 890 */ 82, 1650, 512, 1652, 1653, 508, 1171, 529, 1168, 1483,
+ /* 900 */ 1718, 241, 191, 1483, 296, 1714, 1793, 1401, 55, 1396,
+ /* 910 */ 1394, 526, 1665, 1243, 446, 1752, 554, 464, 1483, 440,
+ /* 920 */ 510, 1310, 1441, 317, 190, 37, 209, 492, 1170, 439,
+ /* 930 */ 509, 441, 444, 37, 1619, 1347, 1348, 530, 46, 223,
+ /* 940 */ 1483, 37, 11, 10, 80, 230, 117, 1172, 459, 51,
+ /* 950 */ 1678, 473, 50, 82, 1650, 512, 1652, 1653, 508, 453,
+ /* 960 */ 529, 214, 1174, 1718, 1666, 421, 1259, 296, 1714, 1793,
+ /* 970 */ 1649, 1385, 118, 119, 1221, 58, 57, 348, 1775, 249,
+ /* 980 */ 154, 1522, 1120, 222, 1748, 342, 232, 518, 495, 534,
+ /* 990 */ 1177, 118, 119, 487, 1173, 225, 1184, 273, 1665, 3,
+ /* 1000 */ 332, 1649, 328, 324, 151, 321, 510, 227, 325, 120,
+ /* 1010 */ 282, 997, 1180, 238, 1028, 1131, 509, 246, 118, 283,
+ /* 1020 */ 1619, 362, 1562, 527, 1228, 1229, 156, 369, 377, 1665,
+ /* 1030 */ 1056, 376, 1060, 1066, 378, 149, 1678, 510, 382, 82,
+ /* 1040 */ 1650, 512, 1652, 1653, 508, 1190, 529, 509, 383, 1718,
+ /* 1050 */ 1064, 1619, 391, 296, 1714, 1793, 490, 1193, 486, 121,
+ /* 1060 */ 394, 163, 1649, 395, 1736, 165, 1192, 1678, 1194, 397,
+ /* 1070 */ 261, 1650, 512, 1652, 1653, 508, 396, 529, 168, 399,
+ /* 1080 */ 170, 400, 1191, 401, 173, 61, 425, 113, 404, 176,
+ /* 1090 */ 1665, 1473, 423, 180, 1168, 291, 1780, 1469, 510, 85,
+ /* 1100 */ 247, 454, 1603, 455, 182, 193, 490, 458, 509, 148,
+ /* 1110 */ 123, 124, 1619, 1777, 1471, 1467, 125, 490, 196, 126,
+ /* 1120 */ 461, 199, 202, 1189, 111, 1649, 1759, 466, 1678, 474,
+ /* 1130 */ 516, 261, 1650, 512, 1652, 1653, 508, 1758, 529, 217,
+ /* 1140 */ 1725, 485, 465, 484, 6, 483, 1780, 471, 463, 205,
+ /* 1150 */ 208, 470, 295, 1665, 477, 213, 1649, 1780, 1739, 148,
+ /* 1160 */ 1284, 510, 5, 1777, 1749, 1188, 112, 1733, 40, 136,
+ /* 1170 */ 146, 509, 499, 496, 1777, 1619, 215, 18, 1571, 1570,
+ /* 1180 */ 1796, 514, 519, 297, 1665, 515, 305, 520, 234, 216,
+ /* 1190 */ 521, 1678, 510, 236, 83, 1650, 512, 1652, 1653, 508,
+ /* 1200 */ 1699, 529, 509, 248, 1718, 70, 1619, 72, 1717, 1714,
+ /* 1210 */ 1649, 1484, 251, 607, 532, 1456, 1776, 221, 47, 1649,
+ /* 1220 */ 135, 493, 1678, 243, 224, 83, 1650, 512, 1652, 1653,
+ /* 1230 */ 508, 500, 529, 226, 262, 1718, 272, 263, 1665, 501,
+ /* 1240 */ 1714, 253, 255, 1613, 1612, 320, 510, 1665, 1609, 322,
+ /* 1250 */ 323, 1156, 1157, 152, 327, 510, 509, 1607, 329, 330,
+ /* 1260 */ 1619, 331, 1606, 333, 1605, 509, 335, 1604, 337, 1619,
+ /* 1270 */ 1589, 153, 340, 341, 1134, 1133, 1678, 346, 347, 133,
+ /* 1280 */ 1650, 512, 1652, 1653, 508, 1678, 529, 1583, 83, 1650,
+ /* 1290 */ 512, 1652, 1653, 508, 1582, 529, 611, 1649, 1718, 1103,
+ /* 1300 */ 1555, 1554, 1553, 1715, 1581, 1580, 1552, 1551, 1649, 1550,
+ /* 1310 */ 245, 1549, 1548, 1547, 1546, 1545, 1544, 1543, 1542, 1541,
+ /* 1320 */ 1540, 1539, 106, 491, 1794, 1665, 1538, 1537, 600, 596,
+ /* 1330 */ 592, 588, 244, 510, 1536, 116, 1665, 1535, 1534, 1533,
+ /* 1340 */ 1532, 1531, 1530, 509, 510, 1105, 1529, 1619, 161, 935,
+ /* 1350 */ 469, 1528, 1413, 1381, 509, 1380, 1597, 79, 1619, 107,
+ /* 1360 */ 239, 934, 108, 1678, 1591, 139, 271, 1650, 512, 1652,
+ /* 1370 */ 1653, 508, 387, 529, 1678, 389, 1649, 266, 1650, 512,
+ /* 1380 */ 1652, 1653, 508, 162, 529, 1579, 167, 169, 1578, 1568,
+ /* 1390 */ 1462, 172, 963, 522, 1412, 1410, 407, 405, 1408, 411,
+ /* 1400 */ 1406, 1404, 406, 415, 1665, 409, 410, 413, 414, 419,
+ /* 1410 */ 418, 1393, 510, 1392, 417, 482, 1070, 179, 467, 1379,
+ /* 1420 */ 1464, 200, 509, 1463, 1069, 1649, 1619, 996, 995, 994,
+ /* 1430 */ 993, 990, 575, 45, 577, 1402, 1649, 288, 1397, 1139,
+ /* 1440 */ 289, 194, 1678, 989, 988, 133, 1650, 512, 1652, 1653,
+ /* 1450 */ 508, 442, 529, 1665, 1395, 290, 445, 1378, 447, 1377,
+ /* 1460 */ 1596, 510, 449, 84, 1665, 201, 456, 1577, 1141, 1590,
+ /* 1470 */ 1576, 509, 507, 1575, 1567, 1619, 212, 49, 300, 41,
+ /* 1480 */ 66, 457, 509, 4, 15, 134, 1619, 1649, 37, 48,
+ /* 1490 */ 1795, 1678, 206, 43, 271, 1650, 512, 1652, 1653, 508,
+ /* 1500 */ 1639, 529, 1678, 211, 1309, 270, 1650, 512, 1652, 1653,
+ /* 1510 */ 508, 210, 529, 197, 1691, 1665, 203, 10, 22, 23,
+ /* 1520 */ 42, 1302, 67, 510, 178, 218, 1649, 1281, 1280, 127,
+ /* 1530 */ 137, 1338, 1327, 509, 17, 1333, 140, 1619, 19, 1649,
+ /* 1540 */ 302, 1332, 420, 416, 412, 408, 177, 298, 1337, 1336,
+ /* 1550 */ 299, 1244, 29, 1678, 1665, 138, 271, 1650, 512, 1652,
+ /* 1560 */ 1653, 508, 510, 529, 1223, 1222, 12, 1665, 20, 1208,
+ /* 1570 */ 150, 63, 509, 21, 175, 510, 1619, 229, 1307, 304,
+ /* 1580 */ 231, 1566, 16, 235, 1178, 509, 13, 511, 1649, 1619,
+ /* 1590 */ 233, 517, 1678, 68, 69, 271, 1650, 512, 1652, 1653,
+ /* 1600 */ 508, 237, 529, 1638, 240, 1678, 1225, 73, 257, 1650,
+ /* 1610 */ 512, 1652, 1653, 508, 1681, 529, 1665, 1649, 528, 44,
+ /* 1620 */ 531, 1057, 533, 312, 510, 535, 537, 1054, 1049, 538,
+ /* 1630 */ 540, 174, 1051, 166, 509, 171, 541, 398, 1619, 543,
+ /* 1640 */ 1045, 546, 544, 1034, 547, 1665, 1043, 1048, 1047, 553,
+ /* 1650 */ 74, 75, 1065, 510, 1678, 164, 1649, 265, 1650, 512,
+ /* 1660 */ 1652, 1653, 508, 509, 529, 76, 1063, 1619, 1062, 961,
+ /* 1670 */ 1046, 561, 985, 1003, 564, 242, 983, 982, 981, 980,
+ /* 1680 */ 979, 978, 977, 1678, 1665, 976, 267, 1650, 512, 1652,
+ /* 1690 */ 1653, 508, 510, 529, 998, 973, 972, 971, 968, 967,
+ /* 1700 */ 966, 1000, 509, 1409, 585, 1649, 1619, 586, 587, 1407,
+ /* 1710 */ 589, 590, 591, 1405, 593, 594, 1649, 595, 1403, 597,
+ /* 1720 */ 599, 598, 1678, 1391, 601, 258, 1650, 512, 1652, 1653,
+ /* 1730 */ 508, 1390, 529, 1665, 602, 1376, 605, 606, 1351, 1351,
+ /* 1740 */ 609, 510, 1164, 252, 1665, 610, 1351, 1351, 1351, 1351,
+ /* 1750 */ 1351, 509, 510, 1351, 1351, 1619, 1351, 1351, 1351, 1351,
+ /* 1760 */ 1351, 1351, 509, 1351, 1351, 1649, 1619, 1351, 1351, 1351,
+ /* 1770 */ 1351, 1678, 1351, 1351, 268, 1650, 512, 1652, 1653, 508,
+ /* 1780 */ 1649, 529, 1678, 1351, 1351, 259, 1650, 512, 1652, 1653,
+ /* 1790 */ 508, 1351, 529, 1665, 1351, 1351, 1351, 1649, 1351, 1351,
+ /* 1800 */ 1351, 510, 1351, 1351, 1351, 1351, 1351, 1351, 1665, 1351,
+ /* 1810 */ 1351, 509, 1649, 1351, 1351, 1619, 510, 1351, 1351, 1351,
+ /* 1820 */ 1351, 1351, 1351, 1351, 1351, 1665, 509, 1351, 1351, 1649,
+ /* 1830 */ 1619, 1678, 1351, 510, 269, 1650, 512, 1652, 1653, 508,
+ /* 1840 */ 1665, 529, 1351, 509, 1351, 1351, 1678, 1619, 510, 260,
+ /* 1850 */ 1650, 512, 1652, 1653, 508, 1351, 529, 1665, 509, 1351,
+ /* 1860 */ 1351, 1351, 1619, 1678, 1351, 510, 1661, 1650, 512, 1652,
+ /* 1870 */ 1653, 508, 1351, 529, 1351, 509, 1649, 1351, 1678, 1619,
+ /* 1880 */ 1351, 1660, 1650, 512, 1652, 1653, 508, 1351, 529, 1351,
+ /* 1890 */ 1351, 1351, 1351, 1351, 1351, 1678, 1351, 1351, 1659, 1650,
+ /* 1900 */ 512, 1652, 1653, 508, 1665, 529, 1351, 1351, 1649, 1351,
+ /* 1910 */ 1351, 1351, 510, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
+ /* 1920 */ 1351, 1351, 509, 1351, 1351, 1649, 1619, 1351, 1351, 1351,
+ /* 1930 */ 1351, 1351, 1351, 1351, 1351, 1351, 1665, 1351, 1351, 1351,
+ /* 1940 */ 1351, 1351, 1678, 1351, 510, 280, 1650, 512, 1652, 1653,
+ /* 1950 */ 508, 1351, 529, 1665, 509, 1351, 1351, 1649, 1619, 1351,
+ /* 1960 */ 1351, 510, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
+ /* 1970 */ 1351, 509, 1351, 1351, 1678, 1619, 1351, 279, 1650, 512,
+ /* 1980 */ 1652, 1653, 508, 1351, 529, 1665, 1351, 1351, 1351, 1351,
+ /* 1990 */ 1351, 1678, 1351, 510, 281, 1650, 512, 1652, 1653, 508,
+ /* 2000 */ 1351, 529, 1351, 509, 1351, 1351, 1649, 1619, 1351, 1351,
+ /* 2010 */ 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 486,
+ /* 2020 */ 1351, 1351, 1351, 1678, 1351, 1351, 278, 1650, 512, 1652,
+ /* 2030 */ 1653, 508, 1351, 529, 1665, 1351, 1351, 1351, 1351, 1351,
+ /* 2040 */ 1351, 1351, 510, 1351, 1351, 1351, 1351, 1351, 113, 1351,
+ /* 2050 */ 1351, 1351, 509, 1351, 1351, 1351, 1619, 1351, 1351, 1351,
+ /* 2060 */ 1351, 1351, 1351, 1351, 1351, 1351, 1351, 490, 1351, 1351,
+ /* 2070 */ 1351, 1351, 1678, 1351, 1351, 264, 1650, 512, 1652, 1653,
+ /* 2080 */ 508, 1351, 529, 1351, 1351, 111, 1351, 1351, 1351, 1351,
+ /* 2090 */ 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
+ /* 2100 */ 217, 1725, 485, 1351, 484, 1351, 1351, 1780, 1351, 1351,
+ /* 2110 */ 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1351,
+ /* 2120 */ 146, 1351, 1351, 1351, 1777,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 246, 273, 248, 249, 276, 246, 250, 248, 249, 324,
- /* 10 */ 325, 4, 12, 13, 242, 271, 244, 243, 262, 339,
- /* 20 */ 20, 293, 22, 279, 20, 269, 12, 13, 14, 15,
- /* 30 */ 16, 247, 352, 255, 250, 279, 356, 309, 310, 12,
- /* 40 */ 13, 14, 15, 16, 271, 271, 268, 47, 320, 42,
- /* 50 */ 43, 278, 47, 279, 250, 277, 283, 55, 58, 315,
- /* 60 */ 12, 13, 14, 289, 64, 2, 262, 293, 20, 64,
- /* 70 */ 22, 0, 58, 299, 20, 12, 13, 14, 15, 16,
- /* 80 */ 4, 81, 80, 279, 310, 83, 250, 313, 314, 315,
- /* 90 */ 316, 317, 318, 0, 320, 47, 82, 323, 262, 251,
- /* 100 */ 252, 327, 328, 103, 90, 269, 58, 12, 13, 14,
- /* 110 */ 15, 16, 64, 339, 114, 279, 270, 24, 25, 26,
- /* 120 */ 27, 28, 29, 30, 31, 32, 352, 75, 282, 81,
- /* 130 */ 356, 60, 61, 62, 63, 81, 65, 66, 67, 68,
- /* 140 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 150 */ 289, 103, 279, 292, 140, 81, 295, 81, 158, 286,
- /* 160 */ 21, 339, 114, 24, 25, 26, 27, 28, 29, 30,
- /* 170 */ 31, 32, 120, 121, 352, 250, 162, 150, 356, 247,
- /* 180 */ 180, 181, 250, 183, 184, 185, 186, 187, 188, 189,
- /* 190 */ 190, 191, 192, 193, 194, 195, 196, 197, 0, 12,
- /* 200 */ 13, 14, 15, 16, 167, 168, 158, 256, 171, 284,
- /* 210 */ 210, 260, 198, 199, 200, 201, 202, 203, 204, 205,
- /* 220 */ 206, 207, 0, 12, 13, 14, 15, 16, 180, 181,
- /* 230 */ 250, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- /* 240 */ 192, 193, 194, 195, 196, 197, 12, 13, 0, 20,
- /* 250 */ 253, 22, 60, 61, 20, 57, 22, 65, 231, 279,
- /* 260 */ 68, 69, 263, 339, 72, 73, 74, 12, 13, 82,
- /* 270 */ 271, 274, 243, 57, 20, 20, 352, 22, 49, 280,
- /* 280 */ 356, 47, 60, 61, 210, 20, 210, 65, 255, 47,
- /* 290 */ 68, 69, 58, 82, 72, 73, 74, 317, 64, 0,
- /* 300 */ 271, 14, 47, 243, 243, 250, 64, 20, 279, 250,
- /* 310 */ 277, 331, 332, 333, 334, 81, 336, 262, 289, 64,
- /* 320 */ 21, 262, 293, 24, 25, 26, 27, 28, 29, 30,
- /* 330 */ 31, 32, 271, 243, 279, 81, 81, 103, 279, 310,
- /* 340 */ 279, 93, 313, 314, 315, 316, 317, 318, 114, 320,
- /* 350 */ 289, 20, 323, 293, 293, 271, 327, 328, 103, 271,
- /* 360 */ 112, 113, 278, 115, 116, 117, 243, 283, 280, 114,
- /* 370 */ 259, 310, 261, 271, 313, 314, 315, 316, 317, 318,
- /* 380 */ 278, 320, 250, 293, 323, 283, 311, 2, 327, 328,
- /* 390 */ 329, 20, 158, 3, 262, 257, 258, 12, 13, 14,
- /* 400 */ 15, 16, 341, 12, 13, 14, 15, 16, 347, 348,
- /* 410 */ 335, 279, 81, 158, 180, 181, 293, 183, 184, 185,
- /* 420 */ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
- /* 430 */ 196, 197, 250, 257, 258, 180, 181, 243, 183, 184,
- /* 440 */ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
- /* 450 */ 195, 196, 197, 12, 13, 14, 243, 4, 20, 19,
- /* 460 */ 281, 20, 243, 22, 210, 210, 264, 288, 289, 267,
- /* 470 */ 14, 184, 19, 33, 12, 13, 20, 273, 243, 243,
- /* 480 */ 273, 299, 20, 276, 22, 45, 33, 293, 47, 250,
- /* 490 */ 144, 51, 52, 53, 54, 55, 14, 293, 45, 240,
- /* 500 */ 293, 262, 20, 50, 57, 64, 293, 271, 55, 47,
- /* 510 */ 153, 250, 293, 309, 310, 279, 309, 310, 279, 250,
- /* 520 */ 80, 339, 81, 83, 320, 289, 64, 320, 293, 293,
- /* 530 */ 173, 174, 64, 80, 352, 299, 83, 146, 356, 289,
- /* 540 */ 279, 210, 41, 81, 103, 295, 310, 20, 279, 313,
- /* 550 */ 314, 315, 316, 317, 318, 114, 320, 117, 299, 323,
- /* 560 */ 243, 215, 216, 327, 328, 103, 12, 13, 14, 15,
- /* 570 */ 16, 273, 80, 263, 272, 339, 114, 93, 317, 92,
- /* 580 */ 88, 271, 142, 82, 146, 145, 317, 0, 352, 81,
- /* 590 */ 280, 293, 356, 332, 333, 334, 253, 336, 339, 158,
- /* 600 */ 116, 332, 333, 334, 164, 336, 166, 309, 310, 266,
- /* 610 */ 293, 352, 58, 288, 289, 356, 226, 274, 320, 4,
- /* 620 */ 158, 180, 181, 243, 183, 184, 185, 186, 187, 188,
- /* 630 */ 189, 190, 191, 192, 193, 194, 195, 196, 197, 35,
- /* 640 */ 184, 149, 180, 181, 90, 183, 184, 185, 186, 187,
- /* 650 */ 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
- /* 660 */ 12, 13, 18, 93, 20, 157, 180, 159, 20, 250,
- /* 670 */ 22, 27, 250, 293, 30, 14, 15, 16, 208, 209,
- /* 680 */ 93, 262, 112, 113, 262, 115, 116, 117, 84, 37,
- /* 690 */ 86, 87, 48, 89, 140, 47, 22, 93, 279, 112,
- /* 700 */ 113, 279, 115, 116, 117, 219, 220, 221, 222, 223,
- /* 710 */ 271, 263, 64, 1, 2, 243, 162, 311, 210, 271,
- /* 720 */ 116, 47, 283, 42, 43, 311, 169, 170, 280, 81,
- /* 730 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
- /* 740 */ 104, 335, 106, 107, 108, 109, 110, 111, 299, 335,
- /* 750 */ 243, 103, 198, 199, 200, 201, 202, 203, 204, 205,
- /* 760 */ 206, 207, 114, 119, 0, 293, 122, 123, 124, 125,
- /* 770 */ 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
- /* 780 */ 136, 137, 138, 139, 250, 250, 18, 250, 339, 20,
- /* 790 */ 41, 23, 20, 20, 82, 140, 262, 262, 272, 262,
- /* 800 */ 293, 352, 243, 35, 36, 356, 158, 39, 243, 243,
- /* 810 */ 243, 299, 243, 279, 279, 243, 279, 162, 250, 243,
- /* 820 */ 243, 57, 243, 146, 56, 148, 211, 272, 180, 181,
- /* 830 */ 262, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- /* 840 */ 192, 193, 194, 195, 196, 197, 41, 279, 271, 81,
- /* 850 */ 272, 339, 293, 198, 0, 272, 279, 0, 293, 293,
- /* 860 */ 293, 209, 293, 0, 352, 293, 289, 0, 356, 293,
- /* 870 */ 293, 85, 293, 85, 88, 85, 88, 85, 88, 22,
- /* 880 */ 88, 243, 58, 21, 272, 22, 118, 310, 81, 22,
- /* 890 */ 313, 314, 315, 316, 317, 318, 34, 320, 91, 45,
- /* 900 */ 323, 1, 2, 272, 327, 328, 329, 244, 303, 271,
- /* 910 */ 195, 196, 44, 260, 243, 146, 47, 279, 150, 151,
- /* 920 */ 152, 41, 41, 155, 350, 348, 47, 289, 160, 41,
- /* 930 */ 359, 293, 41, 41, 41, 307, 344, 271, 249, 41,
- /* 940 */ 172, 251, 271, 175, 282, 177, 178, 179, 310, 81,
- /* 950 */ 279, 313, 314, 315, 316, 317, 318, 184, 320, 312,
- /* 960 */ 289, 323, 82, 82, 293, 327, 328, 329, 20, 41,
- /* 970 */ 82, 41, 337, 82, 82, 82, 338, 228, 210, 243,
- /* 980 */ 82, 310, 353, 114, 313, 314, 315, 316, 317, 318,
- /* 990 */ 353, 320, 41, 114, 323, 243, 41, 41, 327, 328,
- /* 1000 */ 329, 250, 41, 353, 180, 340, 41, 271, 45, 338,
- /* 1010 */ 82, 308, 82, 47, 257, 279, 41, 41, 301, 40,
- /* 1020 */ 156, 250, 287, 271, 250, 289, 140, 243, 285, 293,
- /* 1030 */ 285, 279, 250, 82, 20, 230, 245, 82, 82, 245,
- /* 1040 */ 20, 289, 305, 82, 255, 293, 310, 82, 289, 313,
- /* 1050 */ 314, 315, 316, 317, 318, 271, 320, 82, 82, 323,
- /* 1060 */ 20, 255, 310, 279, 328, 313, 314, 315, 316, 317,
- /* 1070 */ 318, 20, 320, 289, 297, 323, 300, 293, 243, 327,
- /* 1080 */ 328, 329, 255, 299, 297, 255, 20, 279, 290, 255,
- /* 1090 */ 338, 255, 250, 243, 310, 255, 245, 313, 314, 315,
- /* 1100 */ 316, 317, 318, 271, 320, 250, 271, 64, 271, 271,
- /* 1110 */ 271, 245, 271, 293, 279, 271, 271, 271, 271, 271,
- /* 1120 */ 271, 271, 305, 339, 289, 253, 304, 253, 293, 279,
- /* 1130 */ 297, 253, 165, 290, 299, 279, 352, 253, 20, 289,
- /* 1140 */ 356, 289, 218, 293, 243, 310, 349, 294, 313, 314,
- /* 1150 */ 315, 316, 317, 318, 217, 320, 225, 346, 293, 349,
- /* 1160 */ 310, 345, 224, 313, 314, 315, 316, 317, 318, 294,
- /* 1170 */ 320, 312, 271, 323, 339, 293, 293, 327, 328, 20,
- /* 1180 */ 279, 213, 212, 209, 279, 40, 229, 352, 311, 360,
- /* 1190 */ 289, 356, 232, 81, 293, 293, 243, 293, 227, 293,
- /* 1200 */ 12, 13, 294, 343, 294, 243, 330, 143, 291, 290,
- /* 1210 */ 22, 310, 342, 355, 313, 314, 315, 316, 317, 318,
- /* 1220 */ 319, 320, 321, 322, 271, 354, 279, 81, 355, 326,
- /* 1230 */ 253, 267, 279, 271, 253, 47, 250, 279, 253, 354,
- /* 1240 */ 245, 279, 289, 261, 355, 302, 293, 275, 354, 265,
- /* 1250 */ 306, 289, 64, 243, 265, 293, 265, 298, 296, 254,
- /* 1260 */ 241, 0, 0, 310, 72, 0, 313, 314, 315, 316,
- /* 1270 */ 317, 318, 310, 320, 47, 313, 314, 315, 316, 317,
- /* 1280 */ 318, 271, 320, 176, 47, 243, 47, 47, 0, 279,
- /* 1290 */ 176, 103, 47, 47, 0, 176, 47, 0, 47, 289,
- /* 1300 */ 0, 47, 114, 293, 0, 81, 162, 114, 161, 158,
- /* 1310 */ 357, 358, 0, 271, 0, 154, 153, 243, 0, 0,
- /* 1320 */ 310, 279, 44, 313, 314, 315, 316, 317, 318, 0,
- /* 1330 */ 320, 289, 0, 0, 0, 293, 0, 0, 0, 0,
- /* 1340 */ 0, 0, 0, 0, 0, 271, 158, 0, 0, 0,
- /* 1350 */ 0, 0, 310, 279, 0, 313, 314, 315, 316, 317,
- /* 1360 */ 318, 351, 320, 289, 40, 243, 0, 293, 180, 0,
- /* 1370 */ 296, 0, 0, 0, 22, 0, 0, 0, 243, 191,
- /* 1380 */ 192, 193, 0, 0, 310, 0, 40, 313, 314, 315,
- /* 1390 */ 316, 317, 318, 271, 320, 14, 37, 41, 14, 44,
- /* 1400 */ 358, 279, 0, 38, 44, 37, 271, 0, 0, 0,
- /* 1410 */ 0, 289, 0, 0, 279, 293, 37, 37, 243, 0,
- /* 1420 */ 59, 0, 0, 37, 289, 47, 0, 37, 293, 37,
- /* 1430 */ 0, 296, 310, 37, 45, 313, 314, 315, 316, 317,
- /* 1440 */ 318, 47, 320, 45, 322, 310, 271, 47, 313, 314,
- /* 1450 */ 315, 316, 317, 318, 279, 320, 45, 0, 33, 0,
- /* 1460 */ 45, 47, 0, 0, 289, 47, 243, 0, 293, 22,
- /* 1470 */ 45, 296, 41, 41, 47, 22, 51, 52, 53, 54,
- /* 1480 */ 55, 90, 47, 88, 47, 310, 47, 47, 313, 314,
- /* 1490 */ 315, 316, 317, 318, 271, 320, 47, 47, 0, 22,
- /* 1500 */ 47, 0, 279, 22, 48, 80, 0, 22, 83, 0,
- /* 1510 */ 22, 47, 289, 0, 22, 20, 293, 64, 0, 47,
- /* 1520 */ 146, 0, 22, 243, 0, 163, 0, 0, 37, 81,
- /* 1530 */ 143, 41, 81, 310, 141, 41, 313, 314, 315, 316,
- /* 1540 */ 317, 318, 82, 320, 214, 146, 41, 82, 82, 81,
- /* 1550 */ 81, 271, 41, 41, 44, 81, 103, 82, 44, 279,
- /* 1560 */ 82, 44, 82, 41, 44, 208, 141, 114, 143, 289,
- /* 1570 */ 145, 243, 147, 293, 41, 47, 47, 214, 214, 82,
- /* 1580 */ 2, 47, 47, 47, 47, 180, 41, 44, 44, 82,
- /* 1590 */ 310, 166, 22, 313, 314, 315, 316, 317, 318, 271,
- /* 1600 */ 320, 243, 182, 0, 81, 144, 81, 279, 44, 37,
- /* 1610 */ 91, 158, 82, 81, 141, 22, 47, 289, 44, 81,
- /* 1620 */ 81, 293, 82, 92, 82, 59, 47, 81, 81, 271,
- /* 1630 */ 81, 243, 81, 180, 181, 82, 81, 279, 310, 81,
- /* 1640 */ 81, 313, 314, 315, 316, 317, 318, 289, 320, 82,
- /* 1650 */ 82, 293, 47, 47, 81, 47, 47, 82, 81, 271,
- /* 1660 */ 22, 105, 82, 81, 47, 82, 81, 279, 310, 93,
- /* 1670 */ 105, 313, 314, 315, 316, 317, 318, 289, 320, 243,
- /* 1680 */ 81, 293, 81, 81, 47, 22, 105, 58, 243, 105,
- /* 1690 */ 47, 64, 79, 41, 47, 47, 47, 47, 310, 22,
- /* 1700 */ 114, 313, 314, 315, 316, 317, 318, 271, 320, 47,
- /* 1710 */ 64, 47, 47, 47, 47, 279, 271, 47, 47, 47,
- /* 1720 */ 47, 47, 0, 47, 279, 289, 45, 37, 0, 293,
- /* 1730 */ 47, 45, 37, 0, 289, 47, 243, 45, 293, 37,
- /* 1740 */ 0, 47, 45, 37, 0, 47, 310, 46, 0, 313,
- /* 1750 */ 314, 315, 316, 317, 318, 310, 320, 0, 313, 314,
- /* 1760 */ 315, 316, 317, 318, 271, 320, 20, 22, 21, 361,
- /* 1770 */ 361, 22, 279, 22, 21, 361, 361, 361, 361, 361,
- /* 1780 */ 361, 361, 289, 361, 243, 361, 293, 361, 361, 361,
- /* 1790 */ 361, 361, 361, 361, 361, 243, 361, 361, 361, 361,
- /* 1800 */ 361, 361, 361, 310, 361, 361, 313, 314, 315, 316,
- /* 1810 */ 317, 318, 271, 320, 243, 361, 361, 361, 361, 361,
- /* 1820 */ 279, 361, 361, 271, 361, 361, 361, 361, 361, 361,
- /* 1830 */ 289, 279, 361, 361, 293, 361, 361, 361, 361, 361,
- /* 1840 */ 361, 289, 271, 361, 361, 293, 361, 361, 361, 361,
- /* 1850 */ 279, 310, 361, 361, 313, 314, 315, 316, 317, 318,
- /* 1860 */ 289, 320, 310, 361, 293, 313, 314, 315, 316, 317,
- /* 1870 */ 318, 361, 320, 243, 361, 361, 361, 361, 361, 361,
- /* 1880 */ 361, 310, 243, 361, 313, 314, 315, 316, 317, 318,
- /* 1890 */ 361, 320, 361, 361, 361, 361, 361, 361, 361, 361,
- /* 1900 */ 361, 271, 361, 361, 361, 361, 361, 361, 361, 279,
- /* 1910 */ 271, 361, 361, 361, 361, 361, 361, 361, 279, 289,
- /* 1920 */ 361, 361, 361, 293, 361, 361, 361, 361, 289, 361,
- /* 1930 */ 361, 361, 293, 361, 361, 361, 361, 361, 361, 361,
- /* 1940 */ 310, 361, 243, 313, 314, 315, 316, 317, 318, 310,
- /* 1950 */ 320, 243, 313, 314, 315, 316, 317, 318, 361, 320,
- /* 1960 */ 361, 361, 361, 361, 361, 361, 361, 361, 361, 361,
- /* 1970 */ 271, 361, 361, 361, 361, 361, 361, 361, 279, 271,
- /* 1980 */ 361, 361, 361, 361, 361, 361, 361, 279, 289, 361,
- /* 1990 */ 361, 361, 293, 361, 361, 361, 361, 289, 361, 243,
- /* 2000 */ 361, 293, 361, 361, 361, 361, 361, 361, 361, 310,
- /* 2010 */ 250, 361, 313, 314, 315, 316, 317, 318, 310, 320,
- /* 2020 */ 361, 313, 314, 315, 316, 317, 318, 271, 320, 361,
- /* 2030 */ 361, 361, 361, 361, 361, 279, 361, 361, 361, 279,
- /* 2040 */ 361, 361, 361, 361, 361, 289, 250, 361, 361, 293,
- /* 2050 */ 361, 361, 361, 361, 361, 361, 361, 361, 361, 299,
- /* 2060 */ 361, 361, 361, 361, 361, 361, 310, 361, 361, 313,
- /* 2070 */ 314, 315, 316, 317, 318, 279, 320, 317, 361, 361,
- /* 2080 */ 361, 361, 361, 361, 361, 361, 361, 361, 361, 361,
- /* 2090 */ 361, 361, 332, 333, 334, 299, 336, 361, 361, 339,
- /* 2100 */ 361, 361, 361, 361, 361, 361, 361, 361, 361, 361,
- /* 2110 */ 361, 361, 352, 317, 361, 361, 356, 361, 361, 361,
- /* 2120 */ 361, 361, 361, 361, 361, 361, 361, 361, 332, 333,
- /* 2130 */ 334, 361, 336, 361, 361, 339, 361, 361, 361, 361,
- /* 2140 */ 361, 361, 361, 361, 361, 361, 361, 361, 352, 361,
- /* 2150 */ 361, 361, 356,
+ /* 0 */ 253, 335, 295, 270, 257, 270, 273, 243, 273, 245,
+ /* 10 */ 246, 250, 12, 13, 348, 269, 2, 240, 352, 239,
+ /* 20 */ 20, 241, 22, 290, 263, 290, 12, 13, 14, 15,
+ /* 30 */ 16, 335, 271, 12, 13, 14, 15, 16, 305, 306,
+ /* 40 */ 305, 306, 335, 20, 348, 268, 4, 47, 352, 316,
+ /* 50 */ 20, 316, 237, 276, 243, 348, 245, 246, 58, 352,
+ /* 60 */ 12, 13, 14, 286, 64, 4, 244, 290, 20, 247,
+ /* 70 */ 22, 12, 13, 14, 15, 16, 12, 13, 14, 15,
+ /* 80 */ 16, 81, 81, 306, 42, 43, 309, 310, 311, 312,
+ /* 90 */ 313, 314, 91, 316, 240, 47, 319, 0, 335, 14,
+ /* 100 */ 323, 324, 325, 103, 81, 20, 58, 0, 12, 13,
+ /* 110 */ 295, 348, 64, 113, 337, 352, 20, 58, 22, 295,
+ /* 120 */ 343, 344, 12, 13, 14, 15, 16, 250, 21, 81,
+ /* 130 */ 240, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ /* 140 */ 20, 82, 81, 47, 290, 278, 82, 260, 271, 90,
+ /* 150 */ 335, 103, 285, 286, 58, 268, 156, 60, 61, 335,
+ /* 160 */ 64, 113, 65, 348, 277, 68, 69, 352, 58, 72,
+ /* 170 */ 73, 74, 348, 20, 41, 22, 352, 81, 178, 179,
+ /* 180 */ 290, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ /* 190 */ 190, 191, 192, 193, 194, 195, 35, 14, 139, 103,
+ /* 200 */ 90, 81, 49, 20, 156, 81, 252, 21, 208, 113,
+ /* 210 */ 24, 25, 26, 27, 28, 29, 30, 31, 32, 160,
+ /* 220 */ 307, 12, 13, 14, 15, 16, 178, 179, 274, 181,
+ /* 230 */ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ /* 240 */ 192, 193, 194, 195, 331, 84, 240, 86, 87, 139,
+ /* 250 */ 89, 57, 156, 240, 93, 196, 197, 198, 199, 200,
+ /* 260 */ 201, 202, 203, 204, 205, 286, 20, 182, 289, 208,
+ /* 270 */ 160, 292, 320, 321, 178, 179, 115, 181, 182, 183,
+ /* 280 */ 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
+ /* 290 */ 194, 195, 12, 13, 0, 178, 290, 165, 166, 0,
+ /* 300 */ 20, 169, 22, 290, 247, 247, 196, 197, 198, 199,
+ /* 310 */ 200, 201, 202, 203, 204, 205, 259, 20, 24, 25,
+ /* 320 */ 26, 27, 28, 29, 30, 31, 32, 47, 208, 295,
+ /* 330 */ 93, 240, 208, 276, 217, 218, 219, 220, 221, 281,
+ /* 340 */ 12, 13, 14, 22, 64, 247, 260, 268, 20, 112,
+ /* 350 */ 22, 114, 115, 116, 268, 276, 57, 148, 247, 268,
+ /* 360 */ 227, 81, 240, 277, 276, 182, 247, 276, 47, 335,
+ /* 370 */ 259, 283, 268, 244, 276, 47, 247, 286, 259, 275,
+ /* 380 */ 20, 290, 348, 103, 280, 64, 352, 276, 12, 13,
+ /* 390 */ 311, 145, 64, 113, 240, 276, 20, 306, 22, 0,
+ /* 400 */ 309, 310, 311, 312, 313, 314, 81, 316, 2, 81,
+ /* 410 */ 319, 313, 290, 4, 323, 324, 325, 267, 12, 13,
+ /* 420 */ 14, 15, 16, 47, 103, 327, 328, 329, 330, 279,
+ /* 430 */ 332, 103, 252, 240, 113, 344, 156, 228, 60, 61,
+ /* 440 */ 64, 113, 145, 65, 290, 265, 68, 69, 1, 2,
+ /* 450 */ 72, 73, 74, 20, 274, 240, 57, 81, 178, 179,
+ /* 460 */ 143, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ /* 470 */ 190, 191, 192, 193, 194, 195, 20, 156, 260, 103,
+ /* 480 */ 155, 151, 157, 290, 156, 0, 268, 47, 208, 113,
+ /* 490 */ 12, 13, 14, 15, 16, 277, 268, 248, 249, 178,
+ /* 500 */ 179, 171, 172, 275, 64, 290, 178, 179, 280, 181,
+ /* 510 */ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ /* 520 */ 192, 193, 194, 195, 12, 13, 14, 15, 16, 82,
+ /* 530 */ 213, 214, 156, 208, 37, 94, 95, 96, 97, 98,
+ /* 540 */ 99, 100, 101, 102, 103, 104, 240, 106, 107, 108,
+ /* 550 */ 109, 110, 111, 240, 178, 179, 240, 181, 182, 183,
+ /* 560 */ 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
+ /* 570 */ 194, 195, 12, 13, 18, 75, 20, 0, 93, 247,
+ /* 580 */ 20, 247, 22, 27, 268, 307, 30, 261, 55, 14,
+ /* 590 */ 264, 259, 276, 259, 82, 20, 290, 112, 266, 114,
+ /* 600 */ 115, 116, 286, 290, 48, 268, 290, 47, 276, 331,
+ /* 610 */ 276, 240, 275, 80, 139, 286, 83, 280, 209, 119,
+ /* 620 */ 120, 292, 306, 145, 64, 309, 310, 311, 312, 313,
+ /* 630 */ 314, 315, 316, 317, 318, 160, 247, 60, 61, 62,
+ /* 640 */ 63, 81, 65, 66, 67, 68, 69, 70, 71, 72,
+ /* 650 */ 73, 74, 75, 76, 77, 78, 240, 14, 15, 16,
+ /* 660 */ 20, 290, 240, 103, 240, 276, 254, 255, 57, 254,
+ /* 670 */ 255, 196, 240, 113, 118, 0, 240, 121, 122, 123,
+ /* 680 */ 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+ /* 690 */ 134, 135, 136, 137, 138, 247, 285, 286, 247, 42,
+ /* 700 */ 43, 307, 313, 268, 207, 55, 290, 3, 240, 240,
+ /* 710 */ 259, 247, 290, 240, 290, 280, 156, 328, 329, 330,
+ /* 720 */ 20, 332, 290, 259, 276, 331, 290, 276, 268, 240,
+ /* 730 */ 266, 81, 256, 83, 258, 241, 270, 277, 178, 179,
+ /* 740 */ 276, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ /* 750 */ 190, 191, 192, 193, 194, 195, 290, 268, 290, 290,
+ /* 760 */ 240, 313, 0, 290, 93, 276, 47, 22, 93, 206,
+ /* 770 */ 207, 305, 306, 167, 168, 286, 328, 329, 330, 290,
+ /* 780 */ 332, 92, 316, 64, 295, 247, 115, 112, 268, 114,
+ /* 790 */ 115, 116, 47, 58, 41, 306, 276, 259, 309, 310,
+ /* 800 */ 311, 312, 313, 314, 41, 316, 286, 45, 319, 269,
+ /* 810 */ 290, 247, 323, 324, 276, 295, 85, 85, 270, 88,
+ /* 820 */ 88, 240, 182, 259, 335, 85, 306, 269, 88, 309,
+ /* 830 */ 310, 311, 312, 313, 314, 82, 316, 348, 290, 319,
+ /* 840 */ 276, 352, 44, 323, 324, 18, 12, 13, 247, 268,
+ /* 850 */ 23, 64, 21, 305, 306, 335, 22, 276, 208, 269,
+ /* 860 */ 259, 269, 35, 36, 316, 34, 39, 286, 348, 269,
+ /* 870 */ 247, 290, 352, 4, 247, 85, 41, 276, 88, 81,
+ /* 880 */ 41, 47, 259, 56, 240, 41, 259, 306, 19, 247,
+ /* 890 */ 309, 310, 311, 312, 313, 314, 47, 316, 64, 276,
+ /* 900 */ 319, 259, 33, 276, 323, 324, 325, 0, 81, 0,
+ /* 910 */ 0, 247, 268, 178, 45, 334, 269, 82, 276, 50,
+ /* 920 */ 276, 82, 257, 259, 55, 41, 82, 223, 47, 22,
+ /* 930 */ 286, 22, 22, 41, 290, 193, 194, 103, 41, 355,
+ /* 940 */ 276, 41, 1, 2, 117, 41, 41, 113, 299, 80,
+ /* 950 */ 306, 346, 83, 309, 310, 311, 312, 313, 314, 303,
+ /* 960 */ 316, 340, 113, 319, 268, 248, 82, 323, 324, 325,
+ /* 970 */ 240, 246, 41, 41, 82, 148, 149, 150, 334, 82,
+ /* 980 */ 153, 279, 82, 349, 308, 158, 82, 82, 225, 41,
+ /* 990 */ 156, 41, 41, 333, 113, 349, 20, 170, 268, 336,
+ /* 1000 */ 173, 240, 175, 176, 177, 247, 276, 349, 45, 41,
+ /* 1010 */ 304, 47, 178, 82, 82, 154, 286, 297, 41, 254,
+ /* 1020 */ 290, 247, 247, 189, 190, 191, 40, 284, 139, 268,
+ /* 1030 */ 82, 282, 82, 82, 282, 208, 306, 276, 247, 309,
+ /* 1040 */ 310, 311, 312, 313, 314, 20, 316, 286, 242, 319,
+ /* 1050 */ 82, 290, 242, 323, 324, 325, 295, 20, 247, 82,
+ /* 1060 */ 301, 252, 240, 286, 334, 252, 20, 306, 20, 296,
+ /* 1070 */ 309, 310, 311, 312, 313, 314, 294, 316, 252, 294,
+ /* 1080 */ 252, 276, 20, 287, 252, 252, 268, 276, 247, 252,
+ /* 1090 */ 268, 268, 242, 268, 64, 242, 335, 268, 276, 247,
+ /* 1100 */ 301, 163, 290, 300, 268, 250, 295, 286, 286, 348,
+ /* 1110 */ 268, 268, 290, 352, 268, 268, 268, 295, 250, 268,
+ /* 1120 */ 247, 250, 250, 20, 313, 240, 345, 287, 306, 216,
+ /* 1130 */ 215, 309, 310, 311, 312, 313, 314, 345, 316, 328,
+ /* 1140 */ 329, 330, 276, 332, 222, 147, 335, 290, 294, 291,
+ /* 1150 */ 291, 211, 290, 268, 290, 341, 240, 335, 342, 348,
+ /* 1160 */ 207, 276, 210, 352, 308, 20, 276, 307, 40, 339,
+ /* 1170 */ 348, 286, 226, 224, 352, 290, 338, 81, 291, 291,
+ /* 1180 */ 356, 290, 142, 229, 268, 290, 290, 288, 276, 326,
+ /* 1190 */ 287, 306, 276, 250, 309, 310, 311, 312, 313, 314,
+ /* 1200 */ 322, 316, 286, 264, 319, 250, 290, 81, 323, 324,
+ /* 1210 */ 240, 276, 247, 242, 272, 258, 351, 350, 298, 240,
+ /* 1220 */ 302, 351, 306, 250, 350, 309, 310, 311, 312, 313,
+ /* 1230 */ 314, 351, 316, 350, 262, 319, 262, 262, 268, 323,
+ /* 1240 */ 324, 251, 238, 0, 0, 72, 276, 268, 0, 47,
+ /* 1250 */ 174, 47, 47, 47, 174, 276, 286, 0, 47, 47,
+ /* 1260 */ 290, 174, 0, 47, 0, 286, 47, 0, 47, 290,
+ /* 1270 */ 0, 81, 160, 159, 113, 156, 306, 152, 151, 309,
+ /* 1280 */ 310, 311, 312, 313, 314, 306, 316, 0, 309, 310,
+ /* 1290 */ 311, 312, 313, 314, 0, 316, 19, 240, 319, 44,
+ /* 1300 */ 0, 0, 0, 324, 0, 0, 0, 0, 240, 0,
+ /* 1310 */ 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 1320 */ 0, 0, 45, 353, 354, 268, 0, 0, 51, 52,
+ /* 1330 */ 53, 54, 55, 276, 0, 40, 268, 0, 0, 0,
+ /* 1340 */ 0, 0, 0, 286, 276, 22, 0, 290, 40, 14,
+ /* 1350 */ 293, 0, 0, 0, 286, 0, 0, 80, 290, 37,
+ /* 1360 */ 83, 14, 37, 306, 0, 41, 309, 310, 311, 312,
+ /* 1370 */ 313, 314, 44, 316, 306, 44, 240, 309, 310, 311,
+ /* 1380 */ 312, 313, 314, 38, 316, 0, 37, 147, 0, 0,
+ /* 1390 */ 0, 37, 59, 116, 0, 0, 37, 47, 0, 37,
+ /* 1400 */ 0, 0, 45, 37, 268, 47, 45, 47, 45, 37,
+ /* 1410 */ 45, 0, 276, 0, 47, 347, 47, 88, 141, 0,
+ /* 1420 */ 0, 144, 286, 0, 22, 240, 290, 47, 47, 47,
+ /* 1430 */ 47, 47, 41, 90, 41, 0, 240, 22, 0, 162,
+ /* 1440 */ 22, 164, 306, 47, 47, 309, 310, 311, 312, 313,
+ /* 1450 */ 314, 48, 316, 268, 0, 22, 47, 0, 22, 0,
+ /* 1460 */ 0, 276, 22, 20, 268, 37, 22, 0, 47, 0,
+ /* 1470 */ 0, 286, 276, 0, 0, 290, 44, 145, 293, 206,
+ /* 1480 */ 81, 145, 286, 41, 212, 81, 290, 240, 41, 145,
+ /* 1490 */ 354, 306, 82, 41, 309, 310, 311, 312, 313, 314,
+ /* 1500 */ 44, 316, 306, 41, 82, 309, 310, 311, 312, 313,
+ /* 1510 */ 314, 81, 316, 142, 318, 268, 140, 2, 81, 41,
+ /* 1520 */ 41, 82, 81, 276, 33, 44, 240, 82, 82, 161,
+ /* 1530 */ 44, 82, 82, 286, 41, 47, 45, 290, 41, 240,
+ /* 1540 */ 293, 47, 51, 52, 53, 54, 55, 47, 47, 47,
+ /* 1550 */ 47, 178, 81, 306, 268, 44, 309, 310, 311, 312,
+ /* 1560 */ 313, 314, 276, 316, 82, 82, 81, 268, 81, 22,
+ /* 1570 */ 44, 80, 286, 81, 83, 276, 290, 82, 82, 293,
+ /* 1580 */ 81, 0, 212, 37, 22, 286, 212, 180, 240, 290,
+ /* 1590 */ 81, 143, 306, 81, 81, 309, 310, 311, 312, 313,
+ /* 1600 */ 314, 140, 316, 44, 44, 306, 82, 91, 309, 310,
+ /* 1610 */ 311, 312, 313, 314, 81, 316, 268, 240, 81, 81,
+ /* 1620 */ 92, 82, 47, 47, 276, 81, 47, 82, 105, 81,
+ /* 1630 */ 47, 140, 82, 142, 286, 144, 81, 146, 290, 47,
+ /* 1640 */ 82, 47, 81, 22, 81, 268, 82, 105, 105, 93,
+ /* 1650 */ 81, 81, 47, 276, 306, 164, 240, 309, 310, 311,
+ /* 1660 */ 312, 313, 314, 286, 316, 81, 113, 290, 22, 59,
+ /* 1670 */ 105, 58, 47, 64, 79, 41, 47, 47, 47, 47,
+ /* 1680 */ 47, 22, 47, 306, 268, 47, 309, 310, 311, 312,
+ /* 1690 */ 313, 314, 276, 316, 47, 47, 47, 47, 47, 47,
+ /* 1700 */ 47, 64, 286, 0, 47, 240, 290, 45, 37, 0,
+ /* 1710 */ 47, 45, 37, 0, 47, 45, 240, 37, 0, 47,
+ /* 1720 */ 37, 45, 306, 0, 47, 309, 310, 311, 312, 313,
+ /* 1730 */ 314, 0, 316, 268, 46, 0, 22, 21, 357, 357,
+ /* 1740 */ 21, 276, 22, 22, 268, 20, 357, 357, 357, 357,
+ /* 1750 */ 357, 286, 276, 357, 357, 290, 357, 357, 357, 357,
+ /* 1760 */ 357, 357, 286, 357, 357, 240, 290, 357, 357, 357,
+ /* 1770 */ 357, 306, 357, 357, 309, 310, 311, 312, 313, 314,
+ /* 1780 */ 240, 316, 306, 357, 357, 309, 310, 311, 312, 313,
+ /* 1790 */ 314, 357, 316, 268, 357, 357, 357, 240, 357, 357,
+ /* 1800 */ 357, 276, 357, 357, 357, 357, 357, 357, 268, 357,
+ /* 1810 */ 357, 286, 240, 357, 357, 290, 276, 357, 357, 357,
+ /* 1820 */ 357, 357, 357, 357, 357, 268, 286, 357, 357, 240,
+ /* 1830 */ 290, 306, 357, 276, 309, 310, 311, 312, 313, 314,
+ /* 1840 */ 268, 316, 357, 286, 357, 357, 306, 290, 276, 309,
+ /* 1850 */ 310, 311, 312, 313, 314, 357, 316, 268, 286, 357,
+ /* 1860 */ 357, 357, 290, 306, 357, 276, 309, 310, 311, 312,
+ /* 1870 */ 313, 314, 357, 316, 357, 286, 240, 357, 306, 290,
+ /* 1880 */ 357, 309, 310, 311, 312, 313, 314, 357, 316, 357,
+ /* 1890 */ 357, 357, 357, 357, 357, 306, 357, 357, 309, 310,
+ /* 1900 */ 311, 312, 313, 314, 268, 316, 357, 357, 240, 357,
+ /* 1910 */ 357, 357, 276, 357, 357, 357, 357, 357, 357, 357,
+ /* 1920 */ 357, 357, 286, 357, 357, 240, 290, 357, 357, 357,
+ /* 1930 */ 357, 357, 357, 357, 357, 357, 268, 357, 357, 357,
+ /* 1940 */ 357, 357, 306, 357, 276, 309, 310, 311, 312, 313,
+ /* 1950 */ 314, 357, 316, 268, 286, 357, 357, 240, 290, 357,
+ /* 1960 */ 357, 276, 357, 357, 357, 357, 357, 357, 357, 357,
+ /* 1970 */ 357, 286, 357, 357, 306, 290, 357, 309, 310, 311,
+ /* 1980 */ 312, 313, 314, 357, 316, 268, 357, 357, 357, 357,
+ /* 1990 */ 357, 306, 357, 276, 309, 310, 311, 312, 313, 314,
+ /* 2000 */ 357, 316, 357, 286, 357, 357, 240, 290, 357, 357,
+ /* 2010 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 247,
+ /* 2020 */ 357, 357, 357, 306, 357, 357, 309, 310, 311, 312,
+ /* 2030 */ 313, 314, 357, 316, 268, 357, 357, 357, 357, 357,
+ /* 2040 */ 357, 357, 276, 357, 357, 357, 357, 357, 276, 357,
+ /* 2050 */ 357, 357, 286, 357, 357, 357, 290, 357, 357, 357,
+ /* 2060 */ 357, 357, 357, 357, 357, 357, 357, 295, 357, 357,
+ /* 2070 */ 357, 357, 306, 357, 357, 309, 310, 311, 312, 313,
+ /* 2080 */ 314, 357, 316, 357, 357, 313, 357, 357, 357, 357,
+ /* 2090 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
+ /* 2100 */ 328, 329, 330, 357, 332, 357, 357, 335, 357, 357,
+ /* 2110 */ 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
+ /* 2120 */ 348, 357, 357, 357, 352, 237, 237, 237, 237, 237,
+ /* 2130 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2140 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2150 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2160 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2170 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2180 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2190 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2200 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2210 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2220 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2230 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2240 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2250 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2260 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2270 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2280 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2290 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2300 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2310 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2320 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2330 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2340 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2350 */ 237, 237, 237, 237, 237, 237, 237, 237, 237, 237,
+ /* 2360 */ 237, 237,
};
-#define YY_SHIFT_COUNT (610)
+#define YY_SHIFT_COUNT (611)
#define YY_SHIFT_MIN (0)
-#define YY_SHIFT_MAX (1757)
+#define YY_SHIFT_MAX (1735)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 768, 0, 0, 48, 234, 234, 234, 234, 255, 255,
- /* 10 */ 234, 234, 441, 462, 648, 462, 462, 462, 462, 462,
- /* 20 */ 462, 462, 462, 462, 462, 462, 462, 462, 462, 462,
- /* 30 */ 462, 462, 462, 462, 462, 462, 462, 462, 254, 254,
- /* 40 */ 54, 54, 54, 1188, 1188, 1188, 1188, 331, 508, 74,
- /* 50 */ 4, 4, 7, 7, 76, 74, 74, 4, 4, 4,
- /* 60 */ 4, 4, 4, 216, 4, 265, 371, 527, 265, 4,
- /* 70 */ 4, 265, 4, 265, 265, 527, 265, 4, 447, 644,
- /* 80 */ 14, 554, 554, 139, 192, 1453, 1453, 1453, 1453, 1453,
- /* 90 */ 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1453,
- /* 100 */ 1453, 1453, 1453, 1453, 604, 229, 482, 482, 198, 5,
- /* 110 */ 438, 438, 438, 764, 5, 772, 527, 265, 265, 527,
- /* 120 */ 487, 468, 636, 636, 636, 636, 636, 636, 636, 440,
- /* 130 */ 299, 222, 27, 486, 37, 346, 287, 456, 681, 674,
- /* 140 */ 484, 769, 470, 652, 470, 390, 390, 390, 615, 773,
- /* 150 */ 948, 963, 966, 864, 948, 948, 979, 886, 886, 948,
- /* 160 */ 1014, 1014, 1020, 216, 527, 216, 1040, 1051, 216, 1040,
- /* 170 */ 216, 772, 1066, 216, 216, 948, 216, 1014, 265, 265,
- /* 180 */ 265, 265, 265, 265, 265, 265, 265, 265, 265, 948,
- /* 190 */ 1014, 1043, 1020, 447, 967, 527, 447, 1040, 447, 772,
- /* 200 */ 1066, 447, 1118, 924, 937, 1043, 924, 937, 1043, 1043,
- /* 210 */ 265, 931, 938, 968, 970, 974, 772, 1159, 1145, 957,
- /* 220 */ 971, 960, 957, 971, 957, 971, 1112, 937, 1043, 1043,
- /* 230 */ 937, 1043, 1064, 772, 1066, 447, 487, 447, 772, 1146,
- /* 240 */ 468, 948, 447, 1014, 2153, 2153, 2153, 2153, 2153, 2153,
- /* 250 */ 2153, 2153, 71, 1425, 93, 453, 248, 587, 187, 63,
- /* 260 */ 385, 391, 211, 570, 95, 95, 95, 95, 95, 95,
- /* 270 */ 95, 95, 357, 2, 52, 492, 712, 655, 661, 661,
- /* 280 */ 661, 661, 854, 501, 786, 788, 790, 792, 857, 863,
- /* 290 */ 867, 862, 557, 677, 880, 881, 888, 900, 715, 749,
- /* 300 */ 805, 891, 824, 892, 868, 893, 898, 928, 930, 951,
- /* 310 */ 869, 879, 955, 956, 961, 965, 975, 976, 807, 242,
- /* 320 */ 1261, 1262, 1192, 1265, 1227, 1107, 1237, 1239, 1240, 1114,
- /* 330 */ 1288, 1245, 1246, 1119, 1294, 1249, 1297, 1251, 1300, 1254,
- /* 340 */ 1304, 1224, 1144, 1147, 1193, 1151, 1312, 1314, 1161, 1163,
- /* 350 */ 1318, 1319, 1278, 1329, 1332, 1333, 1334, 1336, 1337, 1338,
- /* 360 */ 1339, 1340, 1341, 1342, 1343, 1344, 1347, 1348, 1349, 1350,
- /* 370 */ 1351, 1324, 1354, 1366, 1369, 1371, 1372, 1373, 1352, 1375,
- /* 380 */ 1376, 1377, 1382, 1383, 1385, 1346, 1359, 1356, 1381, 1355,
- /* 390 */ 1384, 1360, 1402, 1365, 1368, 1407, 1408, 1409, 1379, 1410,
- /* 400 */ 1412, 1380, 1413, 1361, 1419, 1421, 1378, 1389, 1386, 1422,
- /* 410 */ 1394, 1398, 1390, 1426, 1400, 1411, 1392, 1430, 1414, 1415,
- /* 420 */ 1396, 1457, 1459, 1462, 1463, 1391, 1395, 1418, 1447, 1467,
- /* 430 */ 1427, 1435, 1437, 1439, 1431, 1432, 1440, 1449, 1450, 1498,
- /* 440 */ 1477, 1501, 1481, 1456, 1506, 1485, 1464, 1509, 1488, 1513,
- /* 450 */ 1492, 1495, 1518, 1374, 1472, 1521, 1362, 1500, 1399, 1387,
- /* 460 */ 1524, 1526, 1527, 1448, 1491, 1393, 1490, 1494, 1330, 1460,
- /* 470 */ 1505, 1465, 1451, 1468, 1469, 1466, 1511, 1510, 1514, 1474,
- /* 480 */ 1512, 1363, 1475, 1478, 1517, 1357, 1522, 1520, 1480, 1533,
- /* 490 */ 1364, 1497, 1528, 1529, 1534, 1535, 1536, 1537, 1497, 1578,
- /* 500 */ 1405, 1545, 1507, 1523, 1530, 1543, 1525, 1532, 1544, 1570,
- /* 510 */ 1420, 1538, 1540, 1542, 1539, 1546, 1461, 1547, 1603, 1572,
- /* 520 */ 1473, 1549, 1519, 1564, 1574, 1551, 1553, 1555, 1593, 1558,
- /* 530 */ 1531, 1567, 1569, 1579, 1559, 1568, 1605, 1573, 1575, 1606,
- /* 540 */ 1577, 1580, 1608, 1582, 1583, 1609, 1585, 1556, 1565, 1581,
- /* 550 */ 1584, 1638, 1576, 1599, 1601, 1617, 1602, 1586, 1637, 1663,
- /* 560 */ 1566, 1629, 1643, 1627, 1613, 1652, 1647, 1648, 1649, 1650,
- /* 570 */ 1662, 1677, 1664, 1665, 1646, 1431, 1666, 1432, 1667, 1670,
- /* 580 */ 1671, 1672, 1673, 1674, 1722, 1676, 1681, 1690, 1728, 1683,
- /* 590 */ 1686, 1695, 1733, 1688, 1692, 1702, 1740, 1694, 1697, 1706,
- /* 600 */ 1744, 1698, 1701, 1748, 1757, 1745, 1747, 1749, 1751, 1753,
- /* 610 */ 1746,
+ /* 0 */ 827, 0, 0, 48, 96, 96, 96, 96, 280, 280,
+ /* 10 */ 96, 96, 328, 376, 560, 376, 376, 376, 376, 376,
+ /* 20 */ 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,
+ /* 30 */ 376, 376, 376, 376, 376, 376, 376, 376, 120, 120,
+ /* 40 */ 23, 23, 23, 834, 834, 834, 834, 325, 650, 124,
+ /* 50 */ 30, 30, 42, 42, 61, 124, 124, 30, 30, 30,
+ /* 60 */ 30, 30, 30, 194, 30, 30, 360, 433, 456, 360,
+ /* 70 */ 30, 30, 360, 30, 360, 360, 456, 360, 30, 611,
+ /* 80 */ 556, 59, 110, 110, 186, 378, 321, 321, 321, 321,
+ /* 90 */ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321,
+ /* 100 */ 321, 321, 321, 321, 321, 161, 153, 575, 575, 299,
+ /* 110 */ 440, 246, 246, 246, 399, 440, 700, 456, 360, 360,
+ /* 120 */ 456, 689, 787, 441, 441, 441, 441, 441, 441, 441,
+ /* 130 */ 1277, 107, 97, 209, 117, 132, 317, 85, 183, 657,
+ /* 140 */ 745, 671, 297, 563, 497, 563, 704, 704, 704, 409,
+ /* 150 */ 640, 976, 963, 964, 861, 976, 976, 986, 889, 889,
+ /* 160 */ 976, 1025, 1025, 1037, 194, 456, 194, 1046, 1048, 194,
+ /* 170 */ 1046, 194, 700, 1062, 194, 194, 976, 194, 1025, 360,
+ /* 180 */ 360, 360, 360, 360, 360, 360, 360, 360, 360, 360,
+ /* 190 */ 976, 1025, 1030, 1037, 611, 938, 456, 611, 976, 1046,
+ /* 200 */ 611, 700, 1062, 611, 1103, 913, 915, 1030, 913, 915,
+ /* 210 */ 1030, 1030, 360, 922, 998, 940, 952, 953, 700, 1145,
+ /* 220 */ 1128, 946, 949, 954, 946, 949, 946, 949, 1096, 915,
+ /* 230 */ 1030, 1030, 915, 1030, 1040, 700, 1062, 611, 689, 611,
+ /* 240 */ 700, 1126, 787, 976, 611, 1025, 2125, 2125, 2125, 2125,
+ /* 250 */ 2125, 2125, 2125, 577, 1491, 294, 869, 64, 14, 406,
+ /* 260 */ 478, 512, 485, 675, 21, 21, 21, 21, 21, 21,
+ /* 270 */ 21, 21, 237, 330, 533, 500, 447, 475, 643, 643,
+ /* 280 */ 643, 643, 762, 753, 731, 732, 740, 790, 907, 909,
+ /* 290 */ 910, 831, 606, 835, 839, 844, 941, 742, 763, 133,
+ /* 300 */ 884, 735, 892, 798, 900, 904, 905, 931, 932, 849,
+ /* 310 */ 881, 897, 948, 950, 951, 968, 977, 1, 719, 1243,
+ /* 320 */ 1244, 1173, 1248, 1202, 1076, 1204, 1205, 1206, 1080, 1257,
+ /* 330 */ 1211, 1212, 1087, 1262, 1216, 1264, 1219, 1267, 1221, 1270,
+ /* 340 */ 1190, 1112, 1114, 1161, 1119, 1287, 1294, 1125, 1127, 1304,
+ /* 350 */ 1305, 1255, 1300, 1301, 1302, 1306, 1307, 1309, 1311, 1312,
+ /* 360 */ 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1326,
+ /* 370 */ 1295, 1327, 1334, 1337, 1338, 1339, 1340, 1323, 1341, 1342,
+ /* 380 */ 1346, 1351, 1352, 1353, 1308, 1322, 1324, 1335, 1328, 1347,
+ /* 390 */ 1331, 1355, 1345, 1325, 1356, 1364, 1385, 1349, 1240, 1388,
+ /* 400 */ 1389, 1354, 1390, 1333, 1394, 1395, 1350, 1357, 1359, 1398,
+ /* 410 */ 1358, 1361, 1362, 1400, 1360, 1363, 1366, 1401, 1367, 1365,
+ /* 420 */ 1372, 1411, 1413, 1419, 1420, 1343, 1329, 1369, 1402, 1423,
+ /* 430 */ 1380, 1381, 1382, 1383, 1391, 1393, 1384, 1396, 1397, 1435,
+ /* 440 */ 1415, 1438, 1418, 1403, 1454, 1433, 1409, 1457, 1436, 1459,
+ /* 450 */ 1440, 1443, 1460, 1332, 1421, 1469, 1368, 1444, 1336, 1371,
+ /* 460 */ 1467, 1470, 1473, 1344, 1474, 1399, 1428, 1376, 1442, 1447,
+ /* 470 */ 1272, 1410, 1452, 1422, 1404, 1430, 1437, 1439, 1462, 1432,
+ /* 480 */ 1456, 1441, 1478, 1370, 1445, 1446, 1481, 1273, 1479, 1486,
+ /* 490 */ 1449, 1493, 1374, 1450, 1488, 1494, 1500, 1501, 1502, 1503,
+ /* 500 */ 1450, 1515, 1373, 1497, 1482, 1471, 1483, 1511, 1485, 1487,
+ /* 510 */ 1526, 1547, 1407, 1492, 1495, 1496, 1499, 1509, 1448, 1512,
+ /* 520 */ 1581, 1546, 1461, 1513, 1516, 1559, 1560, 1533, 1524, 1537,
+ /* 530 */ 1562, 1538, 1528, 1539, 1575, 1576, 1544, 1545, 1579, 1548,
+ /* 540 */ 1550, 1583, 1555, 1558, 1592, 1561, 1564, 1594, 1563, 1523,
+ /* 550 */ 1542, 1543, 1565, 1621, 1556, 1569, 1570, 1605, 1584, 1553,
+ /* 560 */ 1646, 1610, 1613, 1625, 1609, 1595, 1634, 1629, 1630, 1631,
+ /* 570 */ 1632, 1633, 1659, 1635, 1638, 1637, 1391, 1647, 1393, 1648,
+ /* 580 */ 1649, 1650, 1651, 1652, 1653, 1703, 1657, 1662, 1671, 1709,
+ /* 590 */ 1663, 1666, 1675, 1713, 1667, 1670, 1680, 1718, 1672, 1676,
+ /* 600 */ 1683, 1723, 1677, 1688, 1731, 1735, 1714, 1716, 1720, 1721,
+ /* 610 */ 1719, 1725,
};
-#define YY_REDUCE_COUNT (251)
-#define YY_REDUCE_MIN (-320)
-#define YY_REDUCE_MAX (1796)
+#define YY_REDUCE_COUNT (252)
+#define YY_REDUCE_MIN (-334)
+#define YY_REDUCE_MAX (1772)
static const short yy_reduce_ofst[] = {
- /* 0 */ 259, -226, 236, 61, 577, 638, 671, 752, 784, 835,
- /* 10 */ 29, 850, 901, 953, 736, 962, 1010, 1042, 1074, 1122,
- /* 20 */ 1135, 1175, 1223, 1280, 1328, 1358, 1388, 1436, 1445, 1493,
- /* 30 */ 1541, 1552, 1571, 1630, 1639, 1699, 1708, 1756, 1760, 1796,
- /* 40 */ -20, 261, 269, -272, 207, 204, 298, 182, 449, 512,
- /* 50 */ -244, -164, -246, -241, -320, -178, -76, -196, 55, 59,
- /* 60 */ 132, 239, 419, -222, 422, -227, -256, -139, -1, 534,
- /* 70 */ 535, 84, 537, 310, 102, 179, 448, 568, 343, -75,
- /* 80 */ -315, -315, -315, -228, -49, 60, 90, 123, 194, 213,
- /* 90 */ 219, 235, 317, 380, 472, 507, 559, 565, 566, 567,
- /* 100 */ 569, 572, 576, 579, -154, -152, -216, -68, 33, 138,
- /* 110 */ 75, 406, 414, -3, 176, -127, 250, 88, 439, 325,
- /* 120 */ 202, 111, 302, 526, 555, 578, 583, 612, 631, 605,
- /* 130 */ 663, 653, 571, 574, 628, 592, 666, 666, 689, 690,
- /* 140 */ 662, 647, 635, 635, 635, 629, 637, 650, 665, 666,
- /* 150 */ 751, 703, 757, 717, 771, 774, 735, 743, 745, 782,
- /* 160 */ 791, 794, 737, 789, 759, 806, 777, 776, 827, 787,
- /* 170 */ 830, 808, 798, 834, 836, 842, 840, 851, 832, 837,
- /* 180 */ 838, 839, 841, 844, 845, 846, 847, 848, 849, 855,
- /* 190 */ 866, 820, 817, 872, 822, 852, 874, 833, 878, 856,
- /* 200 */ 843, 884, 859, 797, 853, 865, 810, 875, 882, 883,
- /* 210 */ 666, 811, 816, 860, 870, 635, 905, 877, 876, 858,
- /* 220 */ 871, 829, 873, 885, 889, 894, 903, 908, 902, 904,
- /* 230 */ 910, 906, 917, 947, 919, 977, 964, 981, 958, 972,
- /* 240 */ 982, 986, 985, 995, 943, 944, 959, 984, 989, 991,
- /* 250 */ 1005, 1019,
+ /* 0 */ -185, 489, 520, -223, 91, 581, 644, 730, 761, 822,
+ /* 10 */ 885, 916, 316, 970, 979, 1057, 1068, 1136, 1185, 1196,
+ /* 20 */ 1247, 1286, 1299, 1348, 1377, 1416, 1465, 1476, 1525, 1540,
+ /* 30 */ 1557, 1572, 1589, 1636, 1668, 1685, 1717, 1766, 811, 1772,
+ /* 40 */ 98, 389, 448, -267, -265, 466, 548, -293, -176, 34,
+ /* 50 */ 332, 464, -236, -189, -334, -304, -237, 57, 111, 119,
+ /* 60 */ 334, 451, 538, 180, 564, 601, 104, 79, -21, -113,
+ /* 70 */ 623, 627, 228, 642, 86, 337, -133, 218, 664, -239,
+ /* 80 */ 58, -48, -48, -48, -220, -253, -146, -110, 6, 13,
+ /* 90 */ 122, 154, 193, 215, 306, 313, 371, 416, 422, 424,
+ /* 100 */ 432, 436, 468, 469, 473, 150, 249, -178, 129, -46,
+ /* 110 */ 412, -87, 278, 394, -123, 415, 88, 329, 460, 435,
+ /* 120 */ 411, 326, 476, -254, 540, 558, 590, 592, 600, 647,
+ /* 130 */ 649, 494, 665, 584, 605, 656, 621, 696, 696, 725,
+ /* 140 */ 717, 702, 676, 660, 660, 660, 634, 646, 658, 663,
+ /* 150 */ 696, 758, 706, 765, 720, 774, 775, 743, 749, 752,
+ /* 160 */ 791, 806, 810, 759, 809, 777, 813, 782, 773, 826,
+ /* 170 */ 785, 828, 805, 796, 832, 833, 841, 837, 850, 818,
+ /* 180 */ 823, 825, 829, 836, 842, 843, 846, 847, 848, 851,
+ /* 190 */ 852, 853, 812, 799, 855, 803, 821, 868, 873, 854,
+ /* 200 */ 871, 866, 840, 872, 856, 781, 858, 857, 792, 859,
+ /* 210 */ 862, 864, 696, 816, 814, 830, 838, 660, 890, 860,
+ /* 220 */ 863, 865, 867, 824, 870, 874, 880, 883, 878, 887,
+ /* 230 */ 891, 895, 888, 896, 899, 912, 903, 943, 939, 955,
+ /* 240 */ 935, 942, 957, 965, 973, 971, 920, 918, 972, 974,
+ /* 250 */ 975, 990, 1004,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 10 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 20 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 30 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 40 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 50 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 60 */ 1356, 1356, 1356, 1425, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 70 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1423, 1564,
- /* 80 */ 1356, 1731, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 90 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 100 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1425, 1356,
- /* 110 */ 1742, 1742, 1742, 1423, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 120 */ 1519, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1603,
- /* 130 */ 1356, 1356, 1808, 1356, 1609, 1766, 1356, 1356, 1356, 1356,
- /* 140 */ 1472, 1758, 1734, 1748, 1735, 1793, 1793, 1793, 1751, 1356,
- /* 150 */ 1356, 1356, 1356, 1595, 1356, 1356, 1569, 1566, 1566, 1356,
- /* 160 */ 1356, 1356, 1356, 1425, 1356, 1425, 1356, 1356, 1425, 1356,
- /* 170 */ 1425, 1356, 1356, 1425, 1425, 1356, 1425, 1356, 1356, 1356,
- /* 180 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 190 */ 1356, 1356, 1356, 1423, 1605, 1356, 1423, 1356, 1423, 1356,
- /* 200 */ 1356, 1423, 1356, 1773, 1771, 1356, 1773, 1771, 1356, 1356,
- /* 210 */ 1356, 1785, 1781, 1764, 1762, 1748, 1356, 1356, 1356, 1799,
- /* 220 */ 1795, 1811, 1799, 1795, 1799, 1795, 1356, 1771, 1356, 1356,
- /* 230 */ 1771, 1356, 1577, 1356, 1356, 1423, 1356, 1423, 1356, 1488,
- /* 240 */ 1356, 1356, 1423, 1356, 1597, 1611, 1587, 1522, 1522, 1522,
- /* 250 */ 1426, 1361, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 260 */ 1356, 1356, 1356, 1484, 1675, 1784, 1783, 1707, 1706, 1705,
- /* 270 */ 1703, 1674, 1356, 1356, 1356, 1356, 1356, 1356, 1668, 1669,
- /* 280 */ 1667, 1666, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 290 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1732, 1356, 1796,
- /* 300 */ 1800, 1356, 1356, 1356, 1651, 1356, 1356, 1356, 1356, 1356,
- /* 310 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 320 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 330 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 340 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 350 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 360 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 370 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 380 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1390, 1356, 1356,
- /* 390 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 400 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 410 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 420 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 430 */ 1356, 1356, 1356, 1356, 1453, 1452, 1356, 1356, 1356, 1356,
- /* 440 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 450 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 460 */ 1356, 1356, 1356, 1356, 1356, 1356, 1755, 1765, 1356, 1356,
- /* 470 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1651, 1356,
- /* 480 */ 1782, 1356, 1741, 1737, 1356, 1356, 1733, 1356, 1356, 1794,
- /* 490 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1727,
- /* 500 */ 1356, 1700, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 510 */ 1662, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 520 */ 1356, 1356, 1356, 1650, 1356, 1691, 1356, 1356, 1356, 1356,
- /* 530 */ 1356, 1356, 1356, 1356, 1516, 1356, 1356, 1356, 1356, 1356,
- /* 540 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1501, 1499, 1498,
- /* 550 */ 1497, 1356, 1494, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 560 */ 1356, 1356, 1356, 1356, 1356, 1445, 1356, 1356, 1356, 1356,
- /* 570 */ 1356, 1356, 1356, 1356, 1356, 1436, 1356, 1435, 1356, 1356,
- /* 580 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 590 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 600 */ 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
- /* 610 */ 1356,
+ /* 0 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 10 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 20 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 30 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 40 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 50 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 60 */ 1349, 1349, 1349, 1418, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 70 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1416,
+ /* 80 */ 1556, 1349, 1720, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 90 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 100 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1418,
+ /* 110 */ 1349, 1731, 1731, 1731, 1416, 1349, 1349, 1349, 1349, 1349,
+ /* 120 */ 1349, 1512, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 130 */ 1592, 1349, 1349, 1797, 1349, 1598, 1755, 1349, 1349, 1349,
+ /* 140 */ 1349, 1465, 1747, 1723, 1737, 1724, 1782, 1782, 1782, 1740,
+ /* 150 */ 1349, 1349, 1349, 1349, 1584, 1349, 1349, 1561, 1558, 1558,
+ /* 160 */ 1349, 1349, 1349, 1349, 1418, 1349, 1418, 1349, 1349, 1418,
+ /* 170 */ 1349, 1418, 1349, 1349, 1418, 1418, 1349, 1418, 1349, 1349,
+ /* 180 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 190 */ 1349, 1349, 1349, 1349, 1416, 1594, 1349, 1416, 1349, 1349,
+ /* 200 */ 1416, 1349, 1349, 1416, 1349, 1762, 1760, 1349, 1762, 1760,
+ /* 210 */ 1349, 1349, 1349, 1774, 1770, 1753, 1751, 1737, 1349, 1349,
+ /* 220 */ 1349, 1788, 1784, 1800, 1788, 1784, 1788, 1784, 1349, 1760,
+ /* 230 */ 1349, 1349, 1760, 1349, 1569, 1349, 1349, 1416, 1349, 1416,
+ /* 240 */ 1349, 1481, 1349, 1349, 1416, 1349, 1586, 1600, 1515, 1515,
+ /* 250 */ 1515, 1419, 1354, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 260 */ 1349, 1349, 1349, 1349, 1664, 1773, 1772, 1696, 1695, 1694,
+ /* 270 */ 1692, 1663, 1477, 1349, 1349, 1349, 1349, 1349, 1657, 1658,
+ /* 280 */ 1656, 1655, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 290 */ 1349, 1349, 1349, 1349, 1349, 1349, 1721, 1349, 1785, 1789,
+ /* 300 */ 1349, 1349, 1349, 1640, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 310 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 320 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 330 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 340 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 350 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 360 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 370 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 380 */ 1349, 1349, 1349, 1349, 1349, 1349, 1383, 1349, 1349, 1349,
+ /* 390 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 400 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 410 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 420 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 430 */ 1349, 1349, 1349, 1349, 1446, 1445, 1349, 1349, 1349, 1349,
+ /* 440 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 450 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 460 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1744, 1754,
+ /* 470 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 480 */ 1640, 1349, 1771, 1349, 1730, 1726, 1349, 1349, 1722, 1349,
+ /* 490 */ 1349, 1783, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 500 */ 1349, 1716, 1349, 1689, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 510 */ 1349, 1349, 1651, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 520 */ 1349, 1349, 1349, 1349, 1349, 1639, 1349, 1680, 1349, 1349,
+ /* 530 */ 1349, 1349, 1349, 1349, 1349, 1349, 1509, 1349, 1349, 1349,
+ /* 540 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1494,
+ /* 550 */ 1492, 1491, 1490, 1349, 1487, 1349, 1349, 1349, 1349, 1349,
+ /* 560 */ 1349, 1349, 1349, 1349, 1349, 1349, 1438, 1349, 1349, 1349,
+ /* 570 */ 1349, 1349, 1349, 1349, 1349, 1349, 1429, 1349, 1428, 1349,
+ /* 580 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 590 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 600 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
+ /* 610 */ 1349, 1349,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -940,7 +963,6 @@ static const YYCODETYPE yyFallback[] = {
0, /* BLOB => nothing */
0, /* VARBINARY => nothing */
0, /* DECIMAL => nothing */
- 0, /* DELAY => nothing */
0, /* FILE_FACTOR => nothing */
0, /* NK_FLOAT => nothing */
0, /* ROLLUP => nothing */
@@ -975,9 +997,8 @@ static const YYCODETYPE yyFallback[] = {
0, /* INTERVAL => nothing */
0, /* TOPIC => nothing */
0, /* AS => nothing */
- 0, /* CGROUP => nothing */
- 0, /* WITH => nothing */
- 0, /* SCHEMA => nothing */
+ 0, /* CONSUMER => nothing */
+ 0, /* GROUP => nothing */
0, /* DESC => nothing */
0, /* DESCRIBE => nothing */
0, /* RESET => nothing */
@@ -1052,7 +1073,6 @@ static const YYCODETYPE yyFallback[] = {
0, /* PREV => nothing */
0, /* LINEAR => nothing */
0, /* NEXT => nothing */
- 0, /* GROUP => nothing */
0, /* HAVING => nothing */
0, /* ORDER => nothing */
0, /* SLIMIT => nothing */
@@ -1062,12 +1082,12 @@ static const YYCODETYPE yyFallback[] = {
0, /* ASC => nothing */
0, /* NULLS => nothing */
0, /* ID => nothing */
- 233, /* NK_BITNOT => ID */
- 233, /* INSERT => ID */
- 233, /* VALUES => ID */
- 233, /* IMPORT => ID */
- 233, /* NK_SEMI => ID */
- 233, /* FILE => ID */
+ 230, /* NK_BITNOT => ID */
+ 230, /* INSERT => ID */
+ 230, /* VALUES => ID */
+ 230, /* IMPORT => ID */
+ 230, /* NK_SEMI => ID */
+ 230, /* FILE => ID */
};
#endif /* YYFALLBACK */
@@ -1267,255 +1287,251 @@ static const char *const yyTokenName[] = {
/* 109 */ "BLOB",
/* 110 */ "VARBINARY",
/* 111 */ "DECIMAL",
- /* 112 */ "DELAY",
- /* 113 */ "FILE_FACTOR",
- /* 114 */ "NK_FLOAT",
- /* 115 */ "ROLLUP",
- /* 116 */ "TTL",
- /* 117 */ "SMA",
- /* 118 */ "SHOW",
- /* 119 */ "DATABASES",
- /* 120 */ "TABLES",
- /* 121 */ "STABLES",
- /* 122 */ "MNODES",
- /* 123 */ "MODULES",
- /* 124 */ "QNODES",
- /* 125 */ "FUNCTIONS",
- /* 126 */ "INDEXES",
- /* 127 */ "ACCOUNTS",
- /* 128 */ "APPS",
- /* 129 */ "CONNECTIONS",
- /* 130 */ "LICENCE",
- /* 131 */ "GRANTS",
- /* 132 */ "QUERIES",
- /* 133 */ "SCORES",
- /* 134 */ "TOPICS",
- /* 135 */ "VARIABLES",
- /* 136 */ "BNODES",
- /* 137 */ "SNODES",
- /* 138 */ "CLUSTER",
- /* 139 */ "TRANSACTIONS",
- /* 140 */ "LIKE",
- /* 141 */ "INDEX",
- /* 142 */ "FULLTEXT",
- /* 143 */ "FUNCTION",
- /* 144 */ "INTERVAL",
- /* 145 */ "TOPIC",
- /* 146 */ "AS",
- /* 147 */ "CGROUP",
- /* 148 */ "WITH",
- /* 149 */ "SCHEMA",
- /* 150 */ "DESC",
- /* 151 */ "DESCRIBE",
- /* 152 */ "RESET",
- /* 153 */ "QUERY",
- /* 154 */ "CACHE",
- /* 155 */ "EXPLAIN",
- /* 156 */ "ANALYZE",
- /* 157 */ "VERBOSE",
- /* 158 */ "NK_BOOL",
- /* 159 */ "RATIO",
- /* 160 */ "COMPACT",
- /* 161 */ "VNODES",
- /* 162 */ "IN",
- /* 163 */ "OUTPUTTYPE",
- /* 164 */ "AGGREGATE",
- /* 165 */ "BUFSIZE",
- /* 166 */ "STREAM",
- /* 167 */ "INTO",
- /* 168 */ "TRIGGER",
- /* 169 */ "AT_ONCE",
- /* 170 */ "WINDOW_CLOSE",
- /* 171 */ "WATERMARK",
- /* 172 */ "KILL",
- /* 173 */ "CONNECTION",
- /* 174 */ "TRANSACTION",
- /* 175 */ "MERGE",
- /* 176 */ "VGROUP",
- /* 177 */ "REDISTRIBUTE",
- /* 178 */ "SPLIT",
- /* 179 */ "SYNCDB",
- /* 180 */ "NULL",
- /* 181 */ "NK_QUESTION",
- /* 182 */ "NK_ARROW",
- /* 183 */ "ROWTS",
- /* 184 */ "TBNAME",
- /* 185 */ "QSTARTTS",
- /* 186 */ "QENDTS",
- /* 187 */ "WSTARTTS",
- /* 188 */ "WENDTS",
- /* 189 */ "WDURATION",
- /* 190 */ "CAST",
- /* 191 */ "NOW",
- /* 192 */ "TODAY",
- /* 193 */ "TIMEZONE",
- /* 194 */ "COUNT",
- /* 195 */ "FIRST",
- /* 196 */ "LAST",
- /* 197 */ "LAST_ROW",
- /* 198 */ "BETWEEN",
- /* 199 */ "IS",
- /* 200 */ "NK_LT",
- /* 201 */ "NK_GT",
- /* 202 */ "NK_LE",
- /* 203 */ "NK_GE",
- /* 204 */ "NK_NE",
- /* 205 */ "MATCH",
- /* 206 */ "NMATCH",
- /* 207 */ "CONTAINS",
- /* 208 */ "JOIN",
- /* 209 */ "INNER",
- /* 210 */ "SELECT",
- /* 211 */ "DISTINCT",
- /* 212 */ "WHERE",
- /* 213 */ "PARTITION",
- /* 214 */ "BY",
- /* 215 */ "SESSION",
- /* 216 */ "STATE_WINDOW",
- /* 217 */ "SLIDING",
- /* 218 */ "FILL",
- /* 219 */ "VALUE",
- /* 220 */ "NONE",
- /* 221 */ "PREV",
- /* 222 */ "LINEAR",
- /* 223 */ "NEXT",
- /* 224 */ "GROUP",
- /* 225 */ "HAVING",
- /* 226 */ "ORDER",
- /* 227 */ "SLIMIT",
- /* 228 */ "SOFFSET",
- /* 229 */ "LIMIT",
- /* 230 */ "OFFSET",
- /* 231 */ "ASC",
- /* 232 */ "NULLS",
- /* 233 */ "ID",
- /* 234 */ "NK_BITNOT",
- /* 235 */ "INSERT",
- /* 236 */ "VALUES",
- /* 237 */ "IMPORT",
- /* 238 */ "NK_SEMI",
- /* 239 */ "FILE",
- /* 240 */ "cmd",
- /* 241 */ "account_options",
- /* 242 */ "alter_account_options",
- /* 243 */ "literal",
- /* 244 */ "alter_account_option",
- /* 245 */ "user_name",
- /* 246 */ "privileges",
- /* 247 */ "priv_level",
- /* 248 */ "priv_type_list",
- /* 249 */ "priv_type",
- /* 250 */ "db_name",
- /* 251 */ "dnode_endpoint",
- /* 252 */ "dnode_host_name",
- /* 253 */ "not_exists_opt",
- /* 254 */ "db_options",
- /* 255 */ "exists_opt",
- /* 256 */ "alter_db_options",
- /* 257 */ "integer_list",
- /* 258 */ "variable_list",
- /* 259 */ "retention_list",
- /* 260 */ "alter_db_option",
- /* 261 */ "retention",
- /* 262 */ "full_table_name",
- /* 263 */ "column_def_list",
- /* 264 */ "tags_def_opt",
- /* 265 */ "table_options",
- /* 266 */ "multi_create_clause",
- /* 267 */ "tags_def",
- /* 268 */ "multi_drop_clause",
- /* 269 */ "alter_table_clause",
- /* 270 */ "alter_table_options",
- /* 271 */ "column_name",
- /* 272 */ "type_name",
- /* 273 */ "signed_literal",
- /* 274 */ "create_subtable_clause",
- /* 275 */ "specific_tags_opt",
- /* 276 */ "literal_list",
- /* 277 */ "drop_table_clause",
- /* 278 */ "col_name_list",
- /* 279 */ "table_name",
- /* 280 */ "column_def",
- /* 281 */ "func_name_list",
- /* 282 */ "alter_table_option",
- /* 283 */ "col_name",
- /* 284 */ "db_name_cond_opt",
- /* 285 */ "like_pattern_opt",
- /* 286 */ "table_name_cond",
- /* 287 */ "from_db_opt",
- /* 288 */ "func_name",
- /* 289 */ "function_name",
- /* 290 */ "index_name",
- /* 291 */ "index_options",
- /* 292 */ "func_list",
- /* 293 */ "duration_literal",
- /* 294 */ "sliding_opt",
- /* 295 */ "func",
- /* 296 */ "expression_list",
- /* 297 */ "topic_name",
- /* 298 */ "topic_options",
- /* 299 */ "query_expression",
- /* 300 */ "cgroup_name",
- /* 301 */ "analyze_opt",
- /* 302 */ "explain_options",
- /* 303 */ "agg_func_opt",
- /* 304 */ "bufsize_opt",
- /* 305 */ "stream_name",
- /* 306 */ "stream_options",
- /* 307 */ "into_opt",
- /* 308 */ "dnode_list",
- /* 309 */ "signed",
- /* 310 */ "literal_func",
- /* 311 */ "table_alias",
- /* 312 */ "column_alias",
- /* 313 */ "expression",
- /* 314 */ "pseudo_column",
- /* 315 */ "column_reference",
- /* 316 */ "function_expression",
- /* 317 */ "subquery",
- /* 318 */ "star_func",
- /* 319 */ "star_func_para_list",
- /* 320 */ "noarg_func",
- /* 321 */ "other_para_list",
- /* 322 */ "star_func_para",
- /* 323 */ "predicate",
- /* 324 */ "compare_op",
- /* 325 */ "in_op",
- /* 326 */ "in_predicate_value",
- /* 327 */ "boolean_value_expression",
- /* 328 */ "boolean_primary",
- /* 329 */ "common_expression",
- /* 330 */ "from_clause",
- /* 331 */ "table_reference_list",
- /* 332 */ "table_reference",
- /* 333 */ "table_primary",
- /* 334 */ "joined_table",
- /* 335 */ "alias_opt",
- /* 336 */ "parenthesized_joined_table",
- /* 337 */ "join_type",
- /* 338 */ "search_condition",
- /* 339 */ "query_specification",
- /* 340 */ "set_quantifier_opt",
- /* 341 */ "select_list",
- /* 342 */ "where_clause_opt",
- /* 343 */ "partition_by_clause_opt",
- /* 344 */ "twindow_clause_opt",
- /* 345 */ "group_by_clause_opt",
- /* 346 */ "having_clause_opt",
- /* 347 */ "select_sublist",
- /* 348 */ "select_item",
- /* 349 */ "fill_opt",
- /* 350 */ "fill_mode",
- /* 351 */ "group_by_list",
- /* 352 */ "query_expression_body",
- /* 353 */ "order_by_clause_opt",
- /* 354 */ "slimit_clause_opt",
- /* 355 */ "limit_clause_opt",
- /* 356 */ "query_primary",
- /* 357 */ "sort_specification_list",
- /* 358 */ "sort_specification",
- /* 359 */ "ordering_specification_opt",
- /* 360 */ "null_ordering_opt",
+ /* 112 */ "FILE_FACTOR",
+ /* 113 */ "NK_FLOAT",
+ /* 114 */ "ROLLUP",
+ /* 115 */ "TTL",
+ /* 116 */ "SMA",
+ /* 117 */ "SHOW",
+ /* 118 */ "DATABASES",
+ /* 119 */ "TABLES",
+ /* 120 */ "STABLES",
+ /* 121 */ "MNODES",
+ /* 122 */ "MODULES",
+ /* 123 */ "QNODES",
+ /* 124 */ "FUNCTIONS",
+ /* 125 */ "INDEXES",
+ /* 126 */ "ACCOUNTS",
+ /* 127 */ "APPS",
+ /* 128 */ "CONNECTIONS",
+ /* 129 */ "LICENCE",
+ /* 130 */ "GRANTS",
+ /* 131 */ "QUERIES",
+ /* 132 */ "SCORES",
+ /* 133 */ "TOPICS",
+ /* 134 */ "VARIABLES",
+ /* 135 */ "BNODES",
+ /* 136 */ "SNODES",
+ /* 137 */ "CLUSTER",
+ /* 138 */ "TRANSACTIONS",
+ /* 139 */ "LIKE",
+ /* 140 */ "INDEX",
+ /* 141 */ "FULLTEXT",
+ /* 142 */ "FUNCTION",
+ /* 143 */ "INTERVAL",
+ /* 144 */ "TOPIC",
+ /* 145 */ "AS",
+ /* 146 */ "CONSUMER",
+ /* 147 */ "GROUP",
+ /* 148 */ "DESC",
+ /* 149 */ "DESCRIBE",
+ /* 150 */ "RESET",
+ /* 151 */ "QUERY",
+ /* 152 */ "CACHE",
+ /* 153 */ "EXPLAIN",
+ /* 154 */ "ANALYZE",
+ /* 155 */ "VERBOSE",
+ /* 156 */ "NK_BOOL",
+ /* 157 */ "RATIO",
+ /* 158 */ "COMPACT",
+ /* 159 */ "VNODES",
+ /* 160 */ "IN",
+ /* 161 */ "OUTPUTTYPE",
+ /* 162 */ "AGGREGATE",
+ /* 163 */ "BUFSIZE",
+ /* 164 */ "STREAM",
+ /* 165 */ "INTO",
+ /* 166 */ "TRIGGER",
+ /* 167 */ "AT_ONCE",
+ /* 168 */ "WINDOW_CLOSE",
+ /* 169 */ "WATERMARK",
+ /* 170 */ "KILL",
+ /* 171 */ "CONNECTION",
+ /* 172 */ "TRANSACTION",
+ /* 173 */ "MERGE",
+ /* 174 */ "VGROUP",
+ /* 175 */ "REDISTRIBUTE",
+ /* 176 */ "SPLIT",
+ /* 177 */ "SYNCDB",
+ /* 178 */ "NULL",
+ /* 179 */ "NK_QUESTION",
+ /* 180 */ "NK_ARROW",
+ /* 181 */ "ROWTS",
+ /* 182 */ "TBNAME",
+ /* 183 */ "QSTARTTS",
+ /* 184 */ "QENDTS",
+ /* 185 */ "WSTARTTS",
+ /* 186 */ "WENDTS",
+ /* 187 */ "WDURATION",
+ /* 188 */ "CAST",
+ /* 189 */ "NOW",
+ /* 190 */ "TODAY",
+ /* 191 */ "TIMEZONE",
+ /* 192 */ "COUNT",
+ /* 193 */ "FIRST",
+ /* 194 */ "LAST",
+ /* 195 */ "LAST_ROW",
+ /* 196 */ "BETWEEN",
+ /* 197 */ "IS",
+ /* 198 */ "NK_LT",
+ /* 199 */ "NK_GT",
+ /* 200 */ "NK_LE",
+ /* 201 */ "NK_GE",
+ /* 202 */ "NK_NE",
+ /* 203 */ "MATCH",
+ /* 204 */ "NMATCH",
+ /* 205 */ "CONTAINS",
+ /* 206 */ "JOIN",
+ /* 207 */ "INNER",
+ /* 208 */ "SELECT",
+ /* 209 */ "DISTINCT",
+ /* 210 */ "WHERE",
+ /* 211 */ "PARTITION",
+ /* 212 */ "BY",
+ /* 213 */ "SESSION",
+ /* 214 */ "STATE_WINDOW",
+ /* 215 */ "SLIDING",
+ /* 216 */ "FILL",
+ /* 217 */ "VALUE",
+ /* 218 */ "NONE",
+ /* 219 */ "PREV",
+ /* 220 */ "LINEAR",
+ /* 221 */ "NEXT",
+ /* 222 */ "HAVING",
+ /* 223 */ "ORDER",
+ /* 224 */ "SLIMIT",
+ /* 225 */ "SOFFSET",
+ /* 226 */ "LIMIT",
+ /* 227 */ "OFFSET",
+ /* 228 */ "ASC",
+ /* 229 */ "NULLS",
+ /* 230 */ "ID",
+ /* 231 */ "NK_BITNOT",
+ /* 232 */ "INSERT",
+ /* 233 */ "VALUES",
+ /* 234 */ "IMPORT",
+ /* 235 */ "NK_SEMI",
+ /* 236 */ "FILE",
+ /* 237 */ "cmd",
+ /* 238 */ "account_options",
+ /* 239 */ "alter_account_options",
+ /* 240 */ "literal",
+ /* 241 */ "alter_account_option",
+ /* 242 */ "user_name",
+ /* 243 */ "privileges",
+ /* 244 */ "priv_level",
+ /* 245 */ "priv_type_list",
+ /* 246 */ "priv_type",
+ /* 247 */ "db_name",
+ /* 248 */ "dnode_endpoint",
+ /* 249 */ "dnode_host_name",
+ /* 250 */ "not_exists_opt",
+ /* 251 */ "db_options",
+ /* 252 */ "exists_opt",
+ /* 253 */ "alter_db_options",
+ /* 254 */ "integer_list",
+ /* 255 */ "variable_list",
+ /* 256 */ "retention_list",
+ /* 257 */ "alter_db_option",
+ /* 258 */ "retention",
+ /* 259 */ "full_table_name",
+ /* 260 */ "column_def_list",
+ /* 261 */ "tags_def_opt",
+ /* 262 */ "table_options",
+ /* 263 */ "multi_create_clause",
+ /* 264 */ "tags_def",
+ /* 265 */ "multi_drop_clause",
+ /* 266 */ "alter_table_clause",
+ /* 267 */ "alter_table_options",
+ /* 268 */ "column_name",
+ /* 269 */ "type_name",
+ /* 270 */ "signed_literal",
+ /* 271 */ "create_subtable_clause",
+ /* 272 */ "specific_tags_opt",
+ /* 273 */ "literal_list",
+ /* 274 */ "drop_table_clause",
+ /* 275 */ "col_name_list",
+ /* 276 */ "table_name",
+ /* 277 */ "column_def",
+ /* 278 */ "func_name_list",
+ /* 279 */ "alter_table_option",
+ /* 280 */ "col_name",
+ /* 281 */ "db_name_cond_opt",
+ /* 282 */ "like_pattern_opt",
+ /* 283 */ "table_name_cond",
+ /* 284 */ "from_db_opt",
+ /* 285 */ "func_name",
+ /* 286 */ "function_name",
+ /* 287 */ "index_name",
+ /* 288 */ "index_options",
+ /* 289 */ "func_list",
+ /* 290 */ "duration_literal",
+ /* 291 */ "sliding_opt",
+ /* 292 */ "func",
+ /* 293 */ "expression_list",
+ /* 294 */ "topic_name",
+ /* 295 */ "query_expression",
+ /* 296 */ "cgroup_name",
+ /* 297 */ "analyze_opt",
+ /* 298 */ "explain_options",
+ /* 299 */ "agg_func_opt",
+ /* 300 */ "bufsize_opt",
+ /* 301 */ "stream_name",
+ /* 302 */ "stream_options",
+ /* 303 */ "into_opt",
+ /* 304 */ "dnode_list",
+ /* 305 */ "signed",
+ /* 306 */ "literal_func",
+ /* 307 */ "table_alias",
+ /* 308 */ "column_alias",
+ /* 309 */ "expression",
+ /* 310 */ "pseudo_column",
+ /* 311 */ "column_reference",
+ /* 312 */ "function_expression",
+ /* 313 */ "subquery",
+ /* 314 */ "star_func",
+ /* 315 */ "star_func_para_list",
+ /* 316 */ "noarg_func",
+ /* 317 */ "other_para_list",
+ /* 318 */ "star_func_para",
+ /* 319 */ "predicate",
+ /* 320 */ "compare_op",
+ /* 321 */ "in_op",
+ /* 322 */ "in_predicate_value",
+ /* 323 */ "boolean_value_expression",
+ /* 324 */ "boolean_primary",
+ /* 325 */ "common_expression",
+ /* 326 */ "from_clause",
+ /* 327 */ "table_reference_list",
+ /* 328 */ "table_reference",
+ /* 329 */ "table_primary",
+ /* 330 */ "joined_table",
+ /* 331 */ "alias_opt",
+ /* 332 */ "parenthesized_joined_table",
+ /* 333 */ "join_type",
+ /* 334 */ "search_condition",
+ /* 335 */ "query_specification",
+ /* 336 */ "set_quantifier_opt",
+ /* 337 */ "select_list",
+ /* 338 */ "where_clause_opt",
+ /* 339 */ "partition_by_clause_opt",
+ /* 340 */ "twindow_clause_opt",
+ /* 341 */ "group_by_clause_opt",
+ /* 342 */ "having_clause_opt",
+ /* 343 */ "select_sublist",
+ /* 344 */ "select_item",
+ /* 345 */ "fill_opt",
+ /* 346 */ "fill_mode",
+ /* 347 */ "group_by_list",
+ /* 348 */ "query_expression_body",
+ /* 349 */ "order_by_clause_opt",
+ /* 350 */ "slimit_clause_opt",
+ /* 351 */ "limit_clause_opt",
+ /* 352 */ "query_primary",
+ /* 353 */ "sort_specification_list",
+ /* 354 */ "sort_specification",
+ /* 355 */ "ordering_specification_opt",
+ /* 356 */ "null_ordering_opt",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -1688,296 +1704,292 @@ static const char *const yyRuleName[] = {
/* 162 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP",
/* 163 */ "table_options ::=",
/* 164 */ "table_options ::= table_options COMMENT NK_STRING",
- /* 165 */ "table_options ::= table_options DELAY NK_INTEGER",
- /* 166 */ "table_options ::= table_options FILE_FACTOR NK_FLOAT",
- /* 167 */ "table_options ::= table_options ROLLUP NK_LP func_name_list NK_RP",
- /* 168 */ "table_options ::= table_options TTL NK_INTEGER",
- /* 169 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP",
- /* 170 */ "alter_table_options ::= alter_table_option",
- /* 171 */ "alter_table_options ::= alter_table_options alter_table_option",
- /* 172 */ "alter_table_option ::= COMMENT NK_STRING",
- /* 173 */ "alter_table_option ::= TTL NK_INTEGER",
- /* 174 */ "col_name_list ::= col_name",
- /* 175 */ "col_name_list ::= col_name_list NK_COMMA col_name",
- /* 176 */ "col_name ::= column_name",
- /* 177 */ "cmd ::= SHOW DNODES",
- /* 178 */ "cmd ::= SHOW USERS",
- /* 179 */ "cmd ::= SHOW DATABASES",
- /* 180 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt",
- /* 181 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt",
- /* 182 */ "cmd ::= SHOW db_name_cond_opt VGROUPS",
- /* 183 */ "cmd ::= SHOW MNODES",
- /* 184 */ "cmd ::= SHOW MODULES",
- /* 185 */ "cmd ::= SHOW QNODES",
- /* 186 */ "cmd ::= SHOW FUNCTIONS",
- /* 187 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt",
- /* 188 */ "cmd ::= SHOW STREAMS",
- /* 189 */ "cmd ::= SHOW ACCOUNTS",
- /* 190 */ "cmd ::= SHOW APPS",
- /* 191 */ "cmd ::= SHOW CONNECTIONS",
- /* 192 */ "cmd ::= SHOW LICENCE",
- /* 193 */ "cmd ::= SHOW GRANTS",
- /* 194 */ "cmd ::= SHOW CREATE DATABASE db_name",
- /* 195 */ "cmd ::= SHOW CREATE TABLE full_table_name",
- /* 196 */ "cmd ::= SHOW CREATE STABLE full_table_name",
- /* 197 */ "cmd ::= SHOW QUERIES",
- /* 198 */ "cmd ::= SHOW SCORES",
- /* 199 */ "cmd ::= SHOW TOPICS",
- /* 200 */ "cmd ::= SHOW VARIABLES",
- /* 201 */ "cmd ::= SHOW BNODES",
- /* 202 */ "cmd ::= SHOW SNODES",
- /* 203 */ "cmd ::= SHOW CLUSTER",
- /* 204 */ "cmd ::= SHOW TRANSACTIONS",
- /* 205 */ "db_name_cond_opt ::=",
- /* 206 */ "db_name_cond_opt ::= db_name NK_DOT",
- /* 207 */ "like_pattern_opt ::=",
- /* 208 */ "like_pattern_opt ::= LIKE NK_STRING",
- /* 209 */ "table_name_cond ::= table_name",
- /* 210 */ "from_db_opt ::=",
- /* 211 */ "from_db_opt ::= FROM db_name",
- /* 212 */ "func_name_list ::= func_name",
- /* 213 */ "func_name_list ::= func_name_list NK_COMMA func_name",
- /* 214 */ "func_name ::= function_name",
- /* 215 */ "cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options",
- /* 216 */ "cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP",
- /* 217 */ "cmd ::= DROP INDEX exists_opt index_name ON table_name",
- /* 218 */ "index_options ::=",
- /* 219 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt",
- /* 220 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt",
- /* 221 */ "func_list ::= func",
- /* 222 */ "func_list ::= func_list NK_COMMA func",
- /* 223 */ "func ::= function_name NK_LP expression_list NK_RP",
- /* 224 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name topic_options AS query_expression",
- /* 225 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name topic_options AS db_name",
+ /* 165 */ "table_options ::= table_options FILE_FACTOR NK_FLOAT",
+ /* 166 */ "table_options ::= table_options ROLLUP NK_LP func_name_list NK_RP",
+ /* 167 */ "table_options ::= table_options TTL NK_INTEGER",
+ /* 168 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP",
+ /* 169 */ "alter_table_options ::= alter_table_option",
+ /* 170 */ "alter_table_options ::= alter_table_options alter_table_option",
+ /* 171 */ "alter_table_option ::= COMMENT NK_STRING",
+ /* 172 */ "alter_table_option ::= TTL NK_INTEGER",
+ /* 173 */ "col_name_list ::= col_name",
+ /* 174 */ "col_name_list ::= col_name_list NK_COMMA col_name",
+ /* 175 */ "col_name ::= column_name",
+ /* 176 */ "cmd ::= SHOW DNODES",
+ /* 177 */ "cmd ::= SHOW USERS",
+ /* 178 */ "cmd ::= SHOW DATABASES",
+ /* 179 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt",
+ /* 180 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt",
+ /* 181 */ "cmd ::= SHOW db_name_cond_opt VGROUPS",
+ /* 182 */ "cmd ::= SHOW MNODES",
+ /* 183 */ "cmd ::= SHOW MODULES",
+ /* 184 */ "cmd ::= SHOW QNODES",
+ /* 185 */ "cmd ::= SHOW FUNCTIONS",
+ /* 186 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt",
+ /* 187 */ "cmd ::= SHOW STREAMS",
+ /* 188 */ "cmd ::= SHOW ACCOUNTS",
+ /* 189 */ "cmd ::= SHOW APPS",
+ /* 190 */ "cmd ::= SHOW CONNECTIONS",
+ /* 191 */ "cmd ::= SHOW LICENCE",
+ /* 192 */ "cmd ::= SHOW GRANTS",
+ /* 193 */ "cmd ::= SHOW CREATE DATABASE db_name",
+ /* 194 */ "cmd ::= SHOW CREATE TABLE full_table_name",
+ /* 195 */ "cmd ::= SHOW CREATE STABLE full_table_name",
+ /* 196 */ "cmd ::= SHOW QUERIES",
+ /* 197 */ "cmd ::= SHOW SCORES",
+ /* 198 */ "cmd ::= SHOW TOPICS",
+ /* 199 */ "cmd ::= SHOW VARIABLES",
+ /* 200 */ "cmd ::= SHOW BNODES",
+ /* 201 */ "cmd ::= SHOW SNODES",
+ /* 202 */ "cmd ::= SHOW CLUSTER",
+ /* 203 */ "cmd ::= SHOW TRANSACTIONS",
+ /* 204 */ "db_name_cond_opt ::=",
+ /* 205 */ "db_name_cond_opt ::= db_name NK_DOT",
+ /* 206 */ "like_pattern_opt ::=",
+ /* 207 */ "like_pattern_opt ::= LIKE NK_STRING",
+ /* 208 */ "table_name_cond ::= table_name",
+ /* 209 */ "from_db_opt ::=",
+ /* 210 */ "from_db_opt ::= FROM db_name",
+ /* 211 */ "func_name_list ::= func_name",
+ /* 212 */ "func_name_list ::= func_name_list NK_COMMA func_name",
+ /* 213 */ "func_name ::= function_name",
+ /* 214 */ "cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options",
+ /* 215 */ "cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP",
+ /* 216 */ "cmd ::= DROP INDEX exists_opt index_name ON table_name",
+ /* 217 */ "index_options ::=",
+ /* 218 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt",
+ /* 219 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt",
+ /* 220 */ "func_list ::= func",
+ /* 221 */ "func_list ::= func_list NK_COMMA func",
+ /* 222 */ "func ::= function_name NK_LP expression_list NK_RP",
+ /* 223 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression",
+ /* 224 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name",
+ /* 225 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name",
/* 226 */ "cmd ::= DROP TOPIC exists_opt topic_name",
- /* 227 */ "cmd ::= DROP CGROUP exists_opt cgroup_name ON topic_name",
- /* 228 */ "topic_options ::=",
- /* 229 */ "topic_options ::= topic_options WITH TABLE",
- /* 230 */ "topic_options ::= topic_options WITH SCHEMA",
- /* 231 */ "topic_options ::= topic_options WITH TAG",
- /* 232 */ "cmd ::= DESC full_table_name",
- /* 233 */ "cmd ::= DESCRIBE full_table_name",
- /* 234 */ "cmd ::= RESET QUERY CACHE",
- /* 235 */ "cmd ::= EXPLAIN analyze_opt explain_options query_expression",
- /* 236 */ "analyze_opt ::=",
- /* 237 */ "analyze_opt ::= ANALYZE",
- /* 238 */ "explain_options ::=",
- /* 239 */ "explain_options ::= explain_options VERBOSE NK_BOOL",
- /* 240 */ "explain_options ::= explain_options RATIO NK_FLOAT",
- /* 241 */ "cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP",
- /* 242 */ "cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt",
- /* 243 */ "cmd ::= DROP FUNCTION exists_opt function_name",
- /* 244 */ "agg_func_opt ::=",
- /* 245 */ "agg_func_opt ::= AGGREGATE",
- /* 246 */ "bufsize_opt ::=",
- /* 247 */ "bufsize_opt ::= BUFSIZE NK_INTEGER",
- /* 248 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression",
- /* 249 */ "cmd ::= DROP STREAM exists_opt stream_name",
- /* 250 */ "into_opt ::=",
- /* 251 */ "into_opt ::= INTO full_table_name",
- /* 252 */ "stream_options ::=",
- /* 253 */ "stream_options ::= stream_options TRIGGER AT_ONCE",
- /* 254 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE",
- /* 255 */ "stream_options ::= stream_options WATERMARK duration_literal",
- /* 256 */ "cmd ::= KILL CONNECTION NK_INTEGER",
- /* 257 */ "cmd ::= KILL QUERY NK_INTEGER",
- /* 258 */ "cmd ::= KILL TRANSACTION NK_INTEGER",
- /* 259 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER",
- /* 260 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list",
- /* 261 */ "cmd ::= SPLIT VGROUP NK_INTEGER",
- /* 262 */ "dnode_list ::= DNODE NK_INTEGER",
- /* 263 */ "dnode_list ::= dnode_list DNODE NK_INTEGER",
- /* 264 */ "cmd ::= SYNCDB db_name REPLICA",
- /* 265 */ "cmd ::= query_expression",
- /* 266 */ "literal ::= NK_INTEGER",
- /* 267 */ "literal ::= NK_FLOAT",
- /* 268 */ "literal ::= NK_STRING",
- /* 269 */ "literal ::= NK_BOOL",
- /* 270 */ "literal ::= TIMESTAMP NK_STRING",
- /* 271 */ "literal ::= duration_literal",
- /* 272 */ "literal ::= NULL",
- /* 273 */ "literal ::= NK_QUESTION",
- /* 274 */ "duration_literal ::= NK_VARIABLE",
- /* 275 */ "signed ::= NK_INTEGER",
- /* 276 */ "signed ::= NK_PLUS NK_INTEGER",
- /* 277 */ "signed ::= NK_MINUS NK_INTEGER",
- /* 278 */ "signed ::= NK_FLOAT",
- /* 279 */ "signed ::= NK_PLUS NK_FLOAT",
- /* 280 */ "signed ::= NK_MINUS NK_FLOAT",
- /* 281 */ "signed_literal ::= signed",
- /* 282 */ "signed_literal ::= NK_STRING",
- /* 283 */ "signed_literal ::= NK_BOOL",
- /* 284 */ "signed_literal ::= TIMESTAMP NK_STRING",
- /* 285 */ "signed_literal ::= duration_literal",
- /* 286 */ "signed_literal ::= NULL",
- /* 287 */ "signed_literal ::= literal_func",
- /* 288 */ "literal_list ::= signed_literal",
- /* 289 */ "literal_list ::= literal_list NK_COMMA signed_literal",
- /* 290 */ "db_name ::= NK_ID",
- /* 291 */ "table_name ::= NK_ID",
- /* 292 */ "column_name ::= NK_ID",
- /* 293 */ "function_name ::= NK_ID",
- /* 294 */ "table_alias ::= NK_ID",
- /* 295 */ "column_alias ::= NK_ID",
- /* 296 */ "user_name ::= NK_ID",
- /* 297 */ "index_name ::= NK_ID",
- /* 298 */ "topic_name ::= NK_ID",
- /* 299 */ "stream_name ::= NK_ID",
- /* 300 */ "cgroup_name ::= NK_ID",
- /* 301 */ "expression ::= literal",
- /* 302 */ "expression ::= pseudo_column",
- /* 303 */ "expression ::= column_reference",
- /* 304 */ "expression ::= function_expression",
- /* 305 */ "expression ::= subquery",
- /* 306 */ "expression ::= NK_LP expression NK_RP",
- /* 307 */ "expression ::= NK_PLUS expression",
- /* 308 */ "expression ::= NK_MINUS expression",
- /* 309 */ "expression ::= expression NK_PLUS expression",
- /* 310 */ "expression ::= expression NK_MINUS expression",
- /* 311 */ "expression ::= expression NK_STAR expression",
- /* 312 */ "expression ::= expression NK_SLASH expression",
- /* 313 */ "expression ::= expression NK_REM expression",
- /* 314 */ "expression ::= column_reference NK_ARROW NK_STRING",
- /* 315 */ "expression_list ::= expression",
- /* 316 */ "expression_list ::= expression_list NK_COMMA expression",
- /* 317 */ "column_reference ::= column_name",
- /* 318 */ "column_reference ::= table_name NK_DOT column_name",
- /* 319 */ "pseudo_column ::= ROWTS",
- /* 320 */ "pseudo_column ::= TBNAME",
- /* 321 */ "pseudo_column ::= table_name NK_DOT TBNAME",
- /* 322 */ "pseudo_column ::= QSTARTTS",
- /* 323 */ "pseudo_column ::= QENDTS",
- /* 324 */ "pseudo_column ::= WSTARTTS",
- /* 325 */ "pseudo_column ::= WENDTS",
- /* 326 */ "pseudo_column ::= WDURATION",
- /* 327 */ "function_expression ::= function_name NK_LP expression_list NK_RP",
- /* 328 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP",
- /* 329 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP",
- /* 330 */ "function_expression ::= literal_func",
- /* 331 */ "literal_func ::= noarg_func NK_LP NK_RP",
- /* 332 */ "literal_func ::= NOW",
- /* 333 */ "noarg_func ::= NOW",
- /* 334 */ "noarg_func ::= TODAY",
- /* 335 */ "noarg_func ::= TIMEZONE",
- /* 336 */ "star_func ::= COUNT",
- /* 337 */ "star_func ::= FIRST",
- /* 338 */ "star_func ::= LAST",
- /* 339 */ "star_func ::= LAST_ROW",
- /* 340 */ "star_func_para_list ::= NK_STAR",
- /* 341 */ "star_func_para_list ::= other_para_list",
- /* 342 */ "other_para_list ::= star_func_para",
- /* 343 */ "other_para_list ::= other_para_list NK_COMMA star_func_para",
- /* 344 */ "star_func_para ::= expression",
- /* 345 */ "star_func_para ::= table_name NK_DOT NK_STAR",
- /* 346 */ "predicate ::= expression compare_op expression",
- /* 347 */ "predicate ::= expression BETWEEN expression AND expression",
- /* 348 */ "predicate ::= expression NOT BETWEEN expression AND expression",
- /* 349 */ "predicate ::= expression IS NULL",
- /* 350 */ "predicate ::= expression IS NOT NULL",
- /* 351 */ "predicate ::= expression in_op in_predicate_value",
- /* 352 */ "compare_op ::= NK_LT",
- /* 353 */ "compare_op ::= NK_GT",
- /* 354 */ "compare_op ::= NK_LE",
- /* 355 */ "compare_op ::= NK_GE",
- /* 356 */ "compare_op ::= NK_NE",
- /* 357 */ "compare_op ::= NK_EQ",
- /* 358 */ "compare_op ::= LIKE",
- /* 359 */ "compare_op ::= NOT LIKE",
- /* 360 */ "compare_op ::= MATCH",
- /* 361 */ "compare_op ::= NMATCH",
- /* 362 */ "compare_op ::= CONTAINS",
- /* 363 */ "in_op ::= IN",
- /* 364 */ "in_op ::= NOT IN",
- /* 365 */ "in_predicate_value ::= NK_LP expression_list NK_RP",
- /* 366 */ "boolean_value_expression ::= boolean_primary",
- /* 367 */ "boolean_value_expression ::= NOT boolean_primary",
- /* 368 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression",
- /* 369 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression",
- /* 370 */ "boolean_primary ::= predicate",
- /* 371 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP",
- /* 372 */ "common_expression ::= expression",
- /* 373 */ "common_expression ::= boolean_value_expression",
- /* 374 */ "from_clause ::= FROM table_reference_list",
- /* 375 */ "table_reference_list ::= table_reference",
- /* 376 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference",
- /* 377 */ "table_reference ::= table_primary",
- /* 378 */ "table_reference ::= joined_table",
- /* 379 */ "table_primary ::= table_name alias_opt",
- /* 380 */ "table_primary ::= db_name NK_DOT table_name alias_opt",
- /* 381 */ "table_primary ::= subquery alias_opt",
- /* 382 */ "table_primary ::= parenthesized_joined_table",
- /* 383 */ "alias_opt ::=",
- /* 384 */ "alias_opt ::= table_alias",
- /* 385 */ "alias_opt ::= AS table_alias",
- /* 386 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP",
- /* 387 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP",
- /* 388 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition",
- /* 389 */ "join_type ::=",
- /* 390 */ "join_type ::= INNER",
- /* 391 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt",
- /* 392 */ "set_quantifier_opt ::=",
- /* 393 */ "set_quantifier_opt ::= DISTINCT",
- /* 394 */ "set_quantifier_opt ::= ALL",
- /* 395 */ "select_list ::= NK_STAR",
- /* 396 */ "select_list ::= select_sublist",
- /* 397 */ "select_sublist ::= select_item",
- /* 398 */ "select_sublist ::= select_sublist NK_COMMA select_item",
- /* 399 */ "select_item ::= common_expression",
- /* 400 */ "select_item ::= common_expression column_alias",
- /* 401 */ "select_item ::= common_expression AS column_alias",
- /* 402 */ "select_item ::= table_name NK_DOT NK_STAR",
- /* 403 */ "where_clause_opt ::=",
- /* 404 */ "where_clause_opt ::= WHERE search_condition",
- /* 405 */ "partition_by_clause_opt ::=",
- /* 406 */ "partition_by_clause_opt ::= PARTITION BY expression_list",
- /* 407 */ "twindow_clause_opt ::=",
- /* 408 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP",
- /* 409 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP",
- /* 410 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt",
- /* 411 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt",
- /* 412 */ "sliding_opt ::=",
- /* 413 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP",
- /* 414 */ "fill_opt ::=",
- /* 415 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP",
- /* 416 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP",
- /* 417 */ "fill_mode ::= NONE",
- /* 418 */ "fill_mode ::= PREV",
- /* 419 */ "fill_mode ::= NULL",
- /* 420 */ "fill_mode ::= LINEAR",
- /* 421 */ "fill_mode ::= NEXT",
- /* 422 */ "group_by_clause_opt ::=",
- /* 423 */ "group_by_clause_opt ::= GROUP BY group_by_list",
- /* 424 */ "group_by_list ::= expression",
- /* 425 */ "group_by_list ::= group_by_list NK_COMMA expression",
- /* 426 */ "having_clause_opt ::=",
- /* 427 */ "having_clause_opt ::= HAVING search_condition",
- /* 428 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt",
- /* 429 */ "query_expression_body ::= query_primary",
- /* 430 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body",
- /* 431 */ "query_expression_body ::= query_expression_body UNION query_expression_body",
- /* 432 */ "query_primary ::= query_specification",
- /* 433 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP",
- /* 434 */ "order_by_clause_opt ::=",
- /* 435 */ "order_by_clause_opt ::= ORDER BY sort_specification_list",
- /* 436 */ "slimit_clause_opt ::=",
- /* 437 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER",
- /* 438 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER",
- /* 439 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER",
- /* 440 */ "limit_clause_opt ::=",
- /* 441 */ "limit_clause_opt ::= LIMIT NK_INTEGER",
- /* 442 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER",
- /* 443 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER",
- /* 444 */ "subquery ::= NK_LP query_expression NK_RP",
- /* 445 */ "search_condition ::= common_expression",
- /* 446 */ "sort_specification_list ::= sort_specification",
- /* 447 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification",
- /* 448 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt",
- /* 449 */ "ordering_specification_opt ::=",
- /* 450 */ "ordering_specification_opt ::= ASC",
- /* 451 */ "ordering_specification_opt ::= DESC",
- /* 452 */ "null_ordering_opt ::=",
- /* 453 */ "null_ordering_opt ::= NULLS FIRST",
- /* 454 */ "null_ordering_opt ::= NULLS LAST",
+ /* 227 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name",
+ /* 228 */ "cmd ::= DESC full_table_name",
+ /* 229 */ "cmd ::= DESCRIBE full_table_name",
+ /* 230 */ "cmd ::= RESET QUERY CACHE",
+ /* 231 */ "cmd ::= EXPLAIN analyze_opt explain_options query_expression",
+ /* 232 */ "analyze_opt ::=",
+ /* 233 */ "analyze_opt ::= ANALYZE",
+ /* 234 */ "explain_options ::=",
+ /* 235 */ "explain_options ::= explain_options VERBOSE NK_BOOL",
+ /* 236 */ "explain_options ::= explain_options RATIO NK_FLOAT",
+ /* 237 */ "cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP",
+ /* 238 */ "cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt",
+ /* 239 */ "cmd ::= DROP FUNCTION exists_opt function_name",
+ /* 240 */ "agg_func_opt ::=",
+ /* 241 */ "agg_func_opt ::= AGGREGATE",
+ /* 242 */ "bufsize_opt ::=",
+ /* 243 */ "bufsize_opt ::= BUFSIZE NK_INTEGER",
+ /* 244 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression",
+ /* 245 */ "cmd ::= DROP STREAM exists_opt stream_name",
+ /* 246 */ "into_opt ::=",
+ /* 247 */ "into_opt ::= INTO full_table_name",
+ /* 248 */ "stream_options ::=",
+ /* 249 */ "stream_options ::= stream_options TRIGGER AT_ONCE",
+ /* 250 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE",
+ /* 251 */ "stream_options ::= stream_options WATERMARK duration_literal",
+ /* 252 */ "cmd ::= KILL CONNECTION NK_INTEGER",
+ /* 253 */ "cmd ::= KILL QUERY NK_INTEGER",
+ /* 254 */ "cmd ::= KILL TRANSACTION NK_INTEGER",
+ /* 255 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER",
+ /* 256 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list",
+ /* 257 */ "cmd ::= SPLIT VGROUP NK_INTEGER",
+ /* 258 */ "dnode_list ::= DNODE NK_INTEGER",
+ /* 259 */ "dnode_list ::= dnode_list DNODE NK_INTEGER",
+ /* 260 */ "cmd ::= SYNCDB db_name REPLICA",
+ /* 261 */ "cmd ::= query_expression",
+ /* 262 */ "literal ::= NK_INTEGER",
+ /* 263 */ "literal ::= NK_FLOAT",
+ /* 264 */ "literal ::= NK_STRING",
+ /* 265 */ "literal ::= NK_BOOL",
+ /* 266 */ "literal ::= TIMESTAMP NK_STRING",
+ /* 267 */ "literal ::= duration_literal",
+ /* 268 */ "literal ::= NULL",
+ /* 269 */ "literal ::= NK_QUESTION",
+ /* 270 */ "duration_literal ::= NK_VARIABLE",
+ /* 271 */ "signed ::= NK_INTEGER",
+ /* 272 */ "signed ::= NK_PLUS NK_INTEGER",
+ /* 273 */ "signed ::= NK_MINUS NK_INTEGER",
+ /* 274 */ "signed ::= NK_FLOAT",
+ /* 275 */ "signed ::= NK_PLUS NK_FLOAT",
+ /* 276 */ "signed ::= NK_MINUS NK_FLOAT",
+ /* 277 */ "signed_literal ::= signed",
+ /* 278 */ "signed_literal ::= NK_STRING",
+ /* 279 */ "signed_literal ::= NK_BOOL",
+ /* 280 */ "signed_literal ::= TIMESTAMP NK_STRING",
+ /* 281 */ "signed_literal ::= duration_literal",
+ /* 282 */ "signed_literal ::= NULL",
+ /* 283 */ "signed_literal ::= literal_func",
+ /* 284 */ "literal_list ::= signed_literal",
+ /* 285 */ "literal_list ::= literal_list NK_COMMA signed_literal",
+ /* 286 */ "db_name ::= NK_ID",
+ /* 287 */ "table_name ::= NK_ID",
+ /* 288 */ "column_name ::= NK_ID",
+ /* 289 */ "function_name ::= NK_ID",
+ /* 290 */ "table_alias ::= NK_ID",
+ /* 291 */ "column_alias ::= NK_ID",
+ /* 292 */ "user_name ::= NK_ID",
+ /* 293 */ "index_name ::= NK_ID",
+ /* 294 */ "topic_name ::= NK_ID",
+ /* 295 */ "stream_name ::= NK_ID",
+ /* 296 */ "cgroup_name ::= NK_ID",
+ /* 297 */ "expression ::= literal",
+ /* 298 */ "expression ::= pseudo_column",
+ /* 299 */ "expression ::= column_reference",
+ /* 300 */ "expression ::= function_expression",
+ /* 301 */ "expression ::= subquery",
+ /* 302 */ "expression ::= NK_LP expression NK_RP",
+ /* 303 */ "expression ::= NK_PLUS expression",
+ /* 304 */ "expression ::= NK_MINUS expression",
+ /* 305 */ "expression ::= expression NK_PLUS expression",
+ /* 306 */ "expression ::= expression NK_MINUS expression",
+ /* 307 */ "expression ::= expression NK_STAR expression",
+ /* 308 */ "expression ::= expression NK_SLASH expression",
+ /* 309 */ "expression ::= expression NK_REM expression",
+ /* 310 */ "expression ::= column_reference NK_ARROW NK_STRING",
+ /* 311 */ "expression_list ::= expression",
+ /* 312 */ "expression_list ::= expression_list NK_COMMA expression",
+ /* 313 */ "column_reference ::= column_name",
+ /* 314 */ "column_reference ::= table_name NK_DOT column_name",
+ /* 315 */ "pseudo_column ::= ROWTS",
+ /* 316 */ "pseudo_column ::= TBNAME",
+ /* 317 */ "pseudo_column ::= table_name NK_DOT TBNAME",
+ /* 318 */ "pseudo_column ::= QSTARTTS",
+ /* 319 */ "pseudo_column ::= QENDTS",
+ /* 320 */ "pseudo_column ::= WSTARTTS",
+ /* 321 */ "pseudo_column ::= WENDTS",
+ /* 322 */ "pseudo_column ::= WDURATION",
+ /* 323 */ "function_expression ::= function_name NK_LP expression_list NK_RP",
+ /* 324 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP",
+ /* 325 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP",
+ /* 326 */ "function_expression ::= literal_func",
+ /* 327 */ "literal_func ::= noarg_func NK_LP NK_RP",
+ /* 328 */ "literal_func ::= NOW",
+ /* 329 */ "noarg_func ::= NOW",
+ /* 330 */ "noarg_func ::= TODAY",
+ /* 331 */ "noarg_func ::= TIMEZONE",
+ /* 332 */ "star_func ::= COUNT",
+ /* 333 */ "star_func ::= FIRST",
+ /* 334 */ "star_func ::= LAST",
+ /* 335 */ "star_func ::= LAST_ROW",
+ /* 336 */ "star_func_para_list ::= NK_STAR",
+ /* 337 */ "star_func_para_list ::= other_para_list",
+ /* 338 */ "other_para_list ::= star_func_para",
+ /* 339 */ "other_para_list ::= other_para_list NK_COMMA star_func_para",
+ /* 340 */ "star_func_para ::= expression",
+ /* 341 */ "star_func_para ::= table_name NK_DOT NK_STAR",
+ /* 342 */ "predicate ::= expression compare_op expression",
+ /* 343 */ "predicate ::= expression BETWEEN expression AND expression",
+ /* 344 */ "predicate ::= expression NOT BETWEEN expression AND expression",
+ /* 345 */ "predicate ::= expression IS NULL",
+ /* 346 */ "predicate ::= expression IS NOT NULL",
+ /* 347 */ "predicate ::= expression in_op in_predicate_value",
+ /* 348 */ "compare_op ::= NK_LT",
+ /* 349 */ "compare_op ::= NK_GT",
+ /* 350 */ "compare_op ::= NK_LE",
+ /* 351 */ "compare_op ::= NK_GE",
+ /* 352 */ "compare_op ::= NK_NE",
+ /* 353 */ "compare_op ::= NK_EQ",
+ /* 354 */ "compare_op ::= LIKE",
+ /* 355 */ "compare_op ::= NOT LIKE",
+ /* 356 */ "compare_op ::= MATCH",
+ /* 357 */ "compare_op ::= NMATCH",
+ /* 358 */ "compare_op ::= CONTAINS",
+ /* 359 */ "in_op ::= IN",
+ /* 360 */ "in_op ::= NOT IN",
+ /* 361 */ "in_predicate_value ::= NK_LP expression_list NK_RP",
+ /* 362 */ "boolean_value_expression ::= boolean_primary",
+ /* 363 */ "boolean_value_expression ::= NOT boolean_primary",
+ /* 364 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression",
+ /* 365 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression",
+ /* 366 */ "boolean_primary ::= predicate",
+ /* 367 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP",
+ /* 368 */ "common_expression ::= expression",
+ /* 369 */ "common_expression ::= boolean_value_expression",
+ /* 370 */ "from_clause ::= FROM table_reference_list",
+ /* 371 */ "table_reference_list ::= table_reference",
+ /* 372 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference",
+ /* 373 */ "table_reference ::= table_primary",
+ /* 374 */ "table_reference ::= joined_table",
+ /* 375 */ "table_primary ::= table_name alias_opt",
+ /* 376 */ "table_primary ::= db_name NK_DOT table_name alias_opt",
+ /* 377 */ "table_primary ::= subquery alias_opt",
+ /* 378 */ "table_primary ::= parenthesized_joined_table",
+ /* 379 */ "alias_opt ::=",
+ /* 380 */ "alias_opt ::= table_alias",
+ /* 381 */ "alias_opt ::= AS table_alias",
+ /* 382 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP",
+ /* 383 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP",
+ /* 384 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition",
+ /* 385 */ "join_type ::=",
+ /* 386 */ "join_type ::= INNER",
+ /* 387 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt",
+ /* 388 */ "set_quantifier_opt ::=",
+ /* 389 */ "set_quantifier_opt ::= DISTINCT",
+ /* 390 */ "set_quantifier_opt ::= ALL",
+ /* 391 */ "select_list ::= NK_STAR",
+ /* 392 */ "select_list ::= select_sublist",
+ /* 393 */ "select_sublist ::= select_item",
+ /* 394 */ "select_sublist ::= select_sublist NK_COMMA select_item",
+ /* 395 */ "select_item ::= common_expression",
+ /* 396 */ "select_item ::= common_expression column_alias",
+ /* 397 */ "select_item ::= common_expression AS column_alias",
+ /* 398 */ "select_item ::= table_name NK_DOT NK_STAR",
+ /* 399 */ "where_clause_opt ::=",
+ /* 400 */ "where_clause_opt ::= WHERE search_condition",
+ /* 401 */ "partition_by_clause_opt ::=",
+ /* 402 */ "partition_by_clause_opt ::= PARTITION BY expression_list",
+ /* 403 */ "twindow_clause_opt ::=",
+ /* 404 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP",
+ /* 405 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP",
+ /* 406 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt",
+ /* 407 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt",
+ /* 408 */ "sliding_opt ::=",
+ /* 409 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP",
+ /* 410 */ "fill_opt ::=",
+ /* 411 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP",
+ /* 412 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP",
+ /* 413 */ "fill_mode ::= NONE",
+ /* 414 */ "fill_mode ::= PREV",
+ /* 415 */ "fill_mode ::= NULL",
+ /* 416 */ "fill_mode ::= LINEAR",
+ /* 417 */ "fill_mode ::= NEXT",
+ /* 418 */ "group_by_clause_opt ::=",
+ /* 419 */ "group_by_clause_opt ::= GROUP BY group_by_list",
+ /* 420 */ "group_by_list ::= expression",
+ /* 421 */ "group_by_list ::= group_by_list NK_COMMA expression",
+ /* 422 */ "having_clause_opt ::=",
+ /* 423 */ "having_clause_opt ::= HAVING search_condition",
+ /* 424 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt",
+ /* 425 */ "query_expression_body ::= query_primary",
+ /* 426 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body",
+ /* 427 */ "query_expression_body ::= query_expression_body UNION query_expression_body",
+ /* 428 */ "query_primary ::= query_specification",
+ /* 429 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP",
+ /* 430 */ "order_by_clause_opt ::=",
+ /* 431 */ "order_by_clause_opt ::= ORDER BY sort_specification_list",
+ /* 432 */ "slimit_clause_opt ::=",
+ /* 433 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER",
+ /* 434 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER",
+ /* 435 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER",
+ /* 436 */ "limit_clause_opt ::=",
+ /* 437 */ "limit_clause_opt ::= LIMIT NK_INTEGER",
+ /* 438 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER",
+ /* 439 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER",
+ /* 440 */ "subquery ::= NK_LP query_expression NK_RP",
+ /* 441 */ "search_condition ::= common_expression",
+ /* 442 */ "sort_specification_list ::= sort_specification",
+ /* 443 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification",
+ /* 444 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt",
+ /* 445 */ "ordering_specification_opt ::=",
+ /* 446 */ "ordering_specification_opt ::= ASC",
+ /* 447 */ "ordering_specification_opt ::= DESC",
+ /* 448 */ "null_ordering_opt ::=",
+ /* 449 */ "null_ordering_opt ::= NULLS FIRST",
+ /* 450 */ "null_ordering_opt ::= NULLS LAST",
};
#endif /* NDEBUG */
@@ -2104,175 +2116,174 @@ static void yy_destructor(
*/
/********* Begin destructor definitions ***************************************/
/* Default NON-TERMINAL Destructor */
- case 240: /* cmd */
- case 243: /* literal */
- case 254: /* db_options */
- case 256: /* alter_db_options */
- case 261: /* retention */
- case 262: /* full_table_name */
- case 265: /* table_options */
- case 269: /* alter_table_clause */
- case 270: /* alter_table_options */
- case 273: /* signed_literal */
- case 274: /* create_subtable_clause */
- case 277: /* drop_table_clause */
- case 280: /* column_def */
- case 283: /* col_name */
- case 284: /* db_name_cond_opt */
- case 285: /* like_pattern_opt */
- case 286: /* table_name_cond */
- case 287: /* from_db_opt */
- case 288: /* func_name */
- case 291: /* index_options */
- case 293: /* duration_literal */
- case 294: /* sliding_opt */
- case 295: /* func */
- case 298: /* topic_options */
- case 299: /* query_expression */
- case 302: /* explain_options */
- case 306: /* stream_options */
- case 307: /* into_opt */
- case 309: /* signed */
- case 310: /* literal_func */
- case 313: /* expression */
- case 314: /* pseudo_column */
- case 315: /* column_reference */
- case 316: /* function_expression */
- case 317: /* subquery */
- case 322: /* star_func_para */
- case 323: /* predicate */
- case 326: /* in_predicate_value */
- case 327: /* boolean_value_expression */
- case 328: /* boolean_primary */
- case 329: /* common_expression */
- case 330: /* from_clause */
- case 331: /* table_reference_list */
- case 332: /* table_reference */
- case 333: /* table_primary */
- case 334: /* joined_table */
- case 336: /* parenthesized_joined_table */
- case 338: /* search_condition */
- case 339: /* query_specification */
- case 342: /* where_clause_opt */
- case 344: /* twindow_clause_opt */
- case 346: /* having_clause_opt */
- case 348: /* select_item */
- case 349: /* fill_opt */
- case 352: /* query_expression_body */
- case 354: /* slimit_clause_opt */
- case 355: /* limit_clause_opt */
- case 356: /* query_primary */
- case 358: /* sort_specification */
+ case 237: /* cmd */
+ case 240: /* literal */
+ case 251: /* db_options */
+ case 253: /* alter_db_options */
+ case 258: /* retention */
+ case 259: /* full_table_name */
+ case 262: /* table_options */
+ case 266: /* alter_table_clause */
+ case 267: /* alter_table_options */
+ case 270: /* signed_literal */
+ case 271: /* create_subtable_clause */
+ case 274: /* drop_table_clause */
+ case 277: /* column_def */
+ case 280: /* col_name */
+ case 281: /* db_name_cond_opt */
+ case 282: /* like_pattern_opt */
+ case 283: /* table_name_cond */
+ case 284: /* from_db_opt */
+ case 285: /* func_name */
+ case 288: /* index_options */
+ case 290: /* duration_literal */
+ case 291: /* sliding_opt */
+ case 292: /* func */
+ case 295: /* query_expression */
+ case 298: /* explain_options */
+ case 302: /* stream_options */
+ case 303: /* into_opt */
+ case 305: /* signed */
+ case 306: /* literal_func */
+ case 309: /* expression */
+ case 310: /* pseudo_column */
+ case 311: /* column_reference */
+ case 312: /* function_expression */
+ case 313: /* subquery */
+ case 318: /* star_func_para */
+ case 319: /* predicate */
+ case 322: /* in_predicate_value */
+ case 323: /* boolean_value_expression */
+ case 324: /* boolean_primary */
+ case 325: /* common_expression */
+ case 326: /* from_clause */
+ case 327: /* table_reference_list */
+ case 328: /* table_reference */
+ case 329: /* table_primary */
+ case 330: /* joined_table */
+ case 332: /* parenthesized_joined_table */
+ case 334: /* search_condition */
+ case 335: /* query_specification */
+ case 338: /* where_clause_opt */
+ case 340: /* twindow_clause_opt */
+ case 342: /* having_clause_opt */
+ case 344: /* select_item */
+ case 345: /* fill_opt */
+ case 348: /* query_expression_body */
+ case 350: /* slimit_clause_opt */
+ case 351: /* limit_clause_opt */
+ case 352: /* query_primary */
+ case 354: /* sort_specification */
{
- nodesDestroyNode((yypminor->yy636));
+ nodesDestroyNode((yypminor->yy686));
}
break;
- case 241: /* account_options */
- case 242: /* alter_account_options */
- case 244: /* alter_account_option */
- case 304: /* bufsize_opt */
+ case 238: /* account_options */
+ case 239: /* alter_account_options */
+ case 241: /* alter_account_option */
+ case 300: /* bufsize_opt */
{
}
break;
- case 245: /* user_name */
- case 247: /* priv_level */
- case 250: /* db_name */
- case 251: /* dnode_endpoint */
- case 252: /* dnode_host_name */
- case 271: /* column_name */
- case 279: /* table_name */
- case 289: /* function_name */
- case 290: /* index_name */
- case 297: /* topic_name */
- case 300: /* cgroup_name */
- case 305: /* stream_name */
- case 311: /* table_alias */
- case 312: /* column_alias */
- case 318: /* star_func */
- case 320: /* noarg_func */
- case 335: /* alias_opt */
+ case 242: /* user_name */
+ case 244: /* priv_level */
+ case 247: /* db_name */
+ case 248: /* dnode_endpoint */
+ case 249: /* dnode_host_name */
+ case 268: /* column_name */
+ case 276: /* table_name */
+ case 286: /* function_name */
+ case 287: /* index_name */
+ case 294: /* topic_name */
+ case 296: /* cgroup_name */
+ case 301: /* stream_name */
+ case 307: /* table_alias */
+ case 308: /* column_alias */
+ case 314: /* star_func */
+ case 316: /* noarg_func */
+ case 331: /* alias_opt */
{
}
break;
- case 246: /* privileges */
- case 248: /* priv_type_list */
- case 249: /* priv_type */
+ case 243: /* privileges */
+ case 245: /* priv_type_list */
+ case 246: /* priv_type */
{
}
break;
- case 253: /* not_exists_opt */
- case 255: /* exists_opt */
- case 301: /* analyze_opt */
- case 303: /* agg_func_opt */
- case 340: /* set_quantifier_opt */
+ case 250: /* not_exists_opt */
+ case 252: /* exists_opt */
+ case 297: /* analyze_opt */
+ case 299: /* agg_func_opt */
+ case 336: /* set_quantifier_opt */
{
}
break;
- case 257: /* integer_list */
- case 258: /* variable_list */
- case 259: /* retention_list */
- case 263: /* column_def_list */
- case 264: /* tags_def_opt */
- case 266: /* multi_create_clause */
- case 267: /* tags_def */
- case 268: /* multi_drop_clause */
- case 275: /* specific_tags_opt */
- case 276: /* literal_list */
- case 278: /* col_name_list */
- case 281: /* func_name_list */
- case 292: /* func_list */
- case 296: /* expression_list */
- case 308: /* dnode_list */
- case 319: /* star_func_para_list */
- case 321: /* other_para_list */
- case 341: /* select_list */
- case 343: /* partition_by_clause_opt */
- case 345: /* group_by_clause_opt */
- case 347: /* select_sublist */
- case 351: /* group_by_list */
- case 353: /* order_by_clause_opt */
- case 357: /* sort_specification_list */
+ case 254: /* integer_list */
+ case 255: /* variable_list */
+ case 256: /* retention_list */
+ case 260: /* column_def_list */
+ case 261: /* tags_def_opt */
+ case 263: /* multi_create_clause */
+ case 264: /* tags_def */
+ case 265: /* multi_drop_clause */
+ case 272: /* specific_tags_opt */
+ case 273: /* literal_list */
+ case 275: /* col_name_list */
+ case 278: /* func_name_list */
+ case 289: /* func_list */
+ case 293: /* expression_list */
+ case 304: /* dnode_list */
+ case 315: /* star_func_para_list */
+ case 317: /* other_para_list */
+ case 337: /* select_list */
+ case 339: /* partition_by_clause_opt */
+ case 341: /* group_by_clause_opt */
+ case 343: /* select_sublist */
+ case 347: /* group_by_list */
+ case 349: /* order_by_clause_opt */
+ case 353: /* sort_specification_list */
{
- nodesDestroyList((yypminor->yy236));
+ nodesDestroyList((yypminor->yy670));
}
break;
- case 260: /* alter_db_option */
- case 282: /* alter_table_option */
+ case 257: /* alter_db_option */
+ case 279: /* alter_table_option */
{
}
break;
- case 272: /* type_name */
+ case 269: /* type_name */
{
}
break;
- case 324: /* compare_op */
- case 325: /* in_op */
+ case 320: /* compare_op */
+ case 321: /* in_op */
{
}
break;
- case 337: /* join_type */
+ case 333: /* join_type */
{
}
break;
- case 350: /* fill_mode */
+ case 346: /* fill_mode */
{
}
break;
- case 359: /* ordering_specification_opt */
+ case 355: /* ordering_specification_opt */
{
}
break;
- case 360: /* null_ordering_opt */
+ case 356: /* null_ordering_opt */
{
}
@@ -2400,15 +2411,18 @@ static YYACTIONTYPE yy_find_shift_action(
do{
i = yy_shift_ofst[stateno];
assert( i>=0 );
- /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
+ assert( i<=YY_ACTTAB_COUNT );
+ assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD );
assert( iLookAhead!=YYNOCODE );
assert( iLookAhead < YYNTOKEN );
i += iLookAhead;
- if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
+ assert( i<(int)YY_NLOOKAHEAD );
+ if( yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
- if( iLookAhead %s\n",
@@ -2423,16 +2437,8 @@ static YYACTIONTYPE yy_find_shift_action(
#ifdef YYWILDCARD
{
int j = i - iLookAhead + YYWILDCARD;
- if(
-#if YY_SHIFT_MIN+YYWILDCARD<0
- j>=0 &&
-#endif
-#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
- j0
- ){
+ assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) );
+ if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
@@ -2446,6 +2452,7 @@ static YYACTIONTYPE yy_find_shift_action(
#endif /* YYWILDCARD */
return yy_default[stateno];
}else{
+ assert( i>=0 && iyytos;
#ifndef NDEBUG
if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- yysize = yyRuleInfo[yyruleno].nrhs;
+ yysize = yyRuleInfoNRhs[yyruleno];
if( yysize ){
- fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+ fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
yyTracePrompt,
- yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
+ yyruleno, yyRuleName[yyruleno],
+ yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){
yypParser->yyhwm++;
@@ -3114,11 +3572,11 @@ static YYACTIONTYPE yy_reduce(
YYMINORTYPE yylhsminor;
case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */
{ pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
- yy_destructor(yypParser,241,&yymsp[0].minor);
+ yy_destructor(yypParser,238,&yymsp[0].minor);
break;
case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */
{ pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
- yy_destructor(yypParser,242,&yymsp[0].minor);
+ yy_destructor(yypParser,239,&yymsp[0].minor);
break;
case 2: /* account_options ::= */
{ }
@@ -3132,20 +3590,20 @@ static YYACTIONTYPE yy_reduce(
case 9: /* account_options ::= account_options USERS literal */ yytestcase(yyruleno==9);
case 10: /* account_options ::= account_options CONNS literal */ yytestcase(yyruleno==10);
case 11: /* account_options ::= account_options STATE literal */ yytestcase(yyruleno==11);
-{ yy_destructor(yypParser,241,&yymsp[-2].minor);
+{ yy_destructor(yypParser,238,&yymsp[-2].minor);
{ }
- yy_destructor(yypParser,243,&yymsp[0].minor);
+ yy_destructor(yypParser,240,&yymsp[0].minor);
}
break;
case 12: /* alter_account_options ::= alter_account_option */
-{ yy_destructor(yypParser,244,&yymsp[0].minor);
+{ yy_destructor(yypParser,241,&yymsp[0].minor);
{ }
}
break;
case 13: /* alter_account_options ::= alter_account_options alter_account_option */
-{ yy_destructor(yypParser,242,&yymsp[-1].minor);
+{ yy_destructor(yypParser,239,&yymsp[-1].minor);
{ }
- yy_destructor(yypParser,244,&yymsp[0].minor);
+ yy_destructor(yypParser,241,&yymsp[0].minor);
}
break;
case 14: /* alter_account_option ::= PASS literal */
@@ -3159,63 +3617,63 @@ static YYACTIONTYPE yy_reduce(
case 22: /* alter_account_option ::= CONNS literal */ yytestcase(yyruleno==22);
case 23: /* alter_account_option ::= STATE literal */ yytestcase(yyruleno==23);
{ }
- yy_destructor(yypParser,243,&yymsp[0].minor);
+ yy_destructor(yypParser,240,&yymsp[0].minor);
break;
case 24: /* cmd ::= CREATE USER user_name PASS NK_STRING */
-{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy0); }
+{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy0); }
break;
case 25: /* cmd ::= ALTER USER user_name PASS NK_STRING */
-{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy53, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); }
+{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy113, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); }
break;
case 26: /* cmd ::= ALTER USER user_name PRIVILEGE NK_STRING */
-{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy53, TSDB_ALTER_USER_PRIVILEGES, &yymsp[0].minor.yy0); }
+{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy113, TSDB_ALTER_USER_PRIVILEGES, &yymsp[0].minor.yy0); }
break;
case 27: /* cmd ::= DROP USER user_name */
-{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy113); }
break;
case 28: /* cmd ::= GRANT privileges ON priv_level TO user_name */
-{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-4].minor.yy435, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-4].minor.yy123, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113); }
break;
case 29: /* cmd ::= REVOKE privileges ON priv_level FROM user_name */
-{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-4].minor.yy435, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-4].minor.yy123, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113); }
break;
case 30: /* privileges ::= ALL */
-{ yymsp[0].minor.yy435 = PRIVILEGE_TYPE_ALL; }
+{ yymsp[0].minor.yy123 = PRIVILEGE_TYPE_ALL; }
break;
case 31: /* privileges ::= priv_type_list */
case 32: /* priv_type_list ::= priv_type */ yytestcase(yyruleno==32);
-{ yylhsminor.yy435 = yymsp[0].minor.yy435; }
- yymsp[0].minor.yy435 = yylhsminor.yy435;
+{ yylhsminor.yy123 = yymsp[0].minor.yy123; }
+ yymsp[0].minor.yy123 = yylhsminor.yy123;
break;
case 33: /* priv_type_list ::= priv_type_list NK_COMMA priv_type */
-{ yylhsminor.yy435 = yymsp[-2].minor.yy435 | yymsp[0].minor.yy435; }
- yymsp[-2].minor.yy435 = yylhsminor.yy435;
+{ yylhsminor.yy123 = yymsp[-2].minor.yy123 | yymsp[0].minor.yy123; }
+ yymsp[-2].minor.yy123 = yylhsminor.yy123;
break;
case 34: /* priv_type ::= READ */
-{ yymsp[0].minor.yy435 = PRIVILEGE_TYPE_READ; }
+{ yymsp[0].minor.yy123 = PRIVILEGE_TYPE_READ; }
break;
case 35: /* priv_type ::= WRITE */
-{ yymsp[0].minor.yy435 = PRIVILEGE_TYPE_WRITE; }
+{ yymsp[0].minor.yy123 = PRIVILEGE_TYPE_WRITE; }
break;
case 36: /* priv_level ::= NK_STAR NK_DOT NK_STAR */
-{ yylhsminor.yy53 = yymsp[-2].minor.yy0; }
- yymsp[-2].minor.yy53 = yylhsminor.yy53;
+{ yylhsminor.yy113 = yymsp[-2].minor.yy0; }
+ yymsp[-2].minor.yy113 = yylhsminor.yy113;
break;
case 37: /* priv_level ::= db_name NK_DOT NK_STAR */
-{ yylhsminor.yy53 = yymsp[-2].minor.yy53; }
- yymsp[-2].minor.yy53 = yylhsminor.yy53;
+{ yylhsminor.yy113 = yymsp[-2].minor.yy113; }
+ yymsp[-2].minor.yy113 = yylhsminor.yy113;
break;
case 38: /* cmd ::= CREATE DNODE dnode_endpoint */
-{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy53, NULL); }
+{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy113, NULL); }
break;
case 39: /* cmd ::= CREATE DNODE dnode_host_name PORT NK_INTEGER */
-{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy0); }
+{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy0); }
break;
case 40: /* cmd ::= DROP DNODE NK_INTEGER */
{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy0); }
break;
case 41: /* cmd ::= DROP DNODE dnode_endpoint */
-{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy113); }
break;
case 42: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING */
{ pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, NULL); }
@@ -3232,26 +3690,26 @@ static YYACTIONTYPE yy_reduce(
case 46: /* dnode_endpoint ::= NK_STRING */
case 47: /* dnode_host_name ::= NK_ID */ yytestcase(yyruleno==47);
case 48: /* dnode_host_name ::= NK_IPTOKEN */ yytestcase(yyruleno==48);
- case 290: /* db_name ::= NK_ID */ yytestcase(yyruleno==290);
- case 291: /* table_name ::= NK_ID */ yytestcase(yyruleno==291);
- case 292: /* column_name ::= NK_ID */ yytestcase(yyruleno==292);
- case 293: /* function_name ::= NK_ID */ yytestcase(yyruleno==293);
- case 294: /* table_alias ::= NK_ID */ yytestcase(yyruleno==294);
- case 295: /* column_alias ::= NK_ID */ yytestcase(yyruleno==295);
- case 296: /* user_name ::= NK_ID */ yytestcase(yyruleno==296);
- case 297: /* index_name ::= NK_ID */ yytestcase(yyruleno==297);
- case 298: /* topic_name ::= NK_ID */ yytestcase(yyruleno==298);
- case 299: /* stream_name ::= NK_ID */ yytestcase(yyruleno==299);
- case 300: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==300);
- case 333: /* noarg_func ::= NOW */ yytestcase(yyruleno==333);
- case 334: /* noarg_func ::= TODAY */ yytestcase(yyruleno==334);
- case 335: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==335);
- case 336: /* star_func ::= COUNT */ yytestcase(yyruleno==336);
- case 337: /* star_func ::= FIRST */ yytestcase(yyruleno==337);
- case 338: /* star_func ::= LAST */ yytestcase(yyruleno==338);
- case 339: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==339);
-{ yylhsminor.yy53 = yymsp[0].minor.yy0; }
- yymsp[0].minor.yy53 = yylhsminor.yy53;
+ case 286: /* db_name ::= NK_ID */ yytestcase(yyruleno==286);
+ case 287: /* table_name ::= NK_ID */ yytestcase(yyruleno==287);
+ case 288: /* column_name ::= NK_ID */ yytestcase(yyruleno==288);
+ case 289: /* function_name ::= NK_ID */ yytestcase(yyruleno==289);
+ case 290: /* table_alias ::= NK_ID */ yytestcase(yyruleno==290);
+ case 291: /* column_alias ::= NK_ID */ yytestcase(yyruleno==291);
+ case 292: /* user_name ::= NK_ID */ yytestcase(yyruleno==292);
+ case 293: /* index_name ::= NK_ID */ yytestcase(yyruleno==293);
+ case 294: /* topic_name ::= NK_ID */ yytestcase(yyruleno==294);
+ case 295: /* stream_name ::= NK_ID */ yytestcase(yyruleno==295);
+ case 296: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==296);
+ case 329: /* noarg_func ::= NOW */ yytestcase(yyruleno==329);
+ case 330: /* noarg_func ::= TODAY */ yytestcase(yyruleno==330);
+ case 331: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==331);
+ case 332: /* star_func ::= COUNT */ yytestcase(yyruleno==332);
+ case 333: /* star_func ::= FIRST */ yytestcase(yyruleno==333);
+ case 334: /* star_func ::= LAST */ yytestcase(yyruleno==334);
+ case 335: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==335);
+{ yylhsminor.yy113 = yymsp[0].minor.yy0; }
+ yymsp[0].minor.yy113 = yylhsminor.yy113;
break;
case 49: /* cmd ::= ALTER LOCAL NK_STRING */
{ pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[0].minor.yy0, NULL); }
@@ -3284,1169 +3742,1153 @@ static YYACTIONTYPE yy_reduce(
{ pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_MNODE_STMT, &yymsp[0].minor.yy0); }
break;
case 59: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */
-{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy603, &yymsp[-1].minor.yy53, yymsp[0].minor.yy636); }
+{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy113, yymsp[0].minor.yy686); }
break;
case 60: /* cmd ::= DROP DATABASE exists_opt db_name */
-{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy603, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy131, &yymsp[0].minor.yy113); }
break;
case 61: /* cmd ::= USE db_name */
-{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy53); }
+{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy113); }
break;
case 62: /* cmd ::= ALTER DATABASE db_name alter_db_options */
-{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy53, yymsp[0].minor.yy636); }
+{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy113, yymsp[0].minor.yy686); }
break;
case 63: /* not_exists_opt ::= IF NOT EXISTS */
-{ yymsp[-2].minor.yy603 = true; }
+{ yymsp[-2].minor.yy131 = true; }
break;
case 64: /* not_exists_opt ::= */
case 66: /* exists_opt ::= */ yytestcase(yyruleno==66);
- case 236: /* analyze_opt ::= */ yytestcase(yyruleno==236);
- case 244: /* agg_func_opt ::= */ yytestcase(yyruleno==244);
- case 392: /* set_quantifier_opt ::= */ yytestcase(yyruleno==392);
-{ yymsp[1].minor.yy603 = false; }
+ case 232: /* analyze_opt ::= */ yytestcase(yyruleno==232);
+ case 240: /* agg_func_opt ::= */ yytestcase(yyruleno==240);
+ case 388: /* set_quantifier_opt ::= */ yytestcase(yyruleno==388);
+{ yymsp[1].minor.yy131 = false; }
break;
case 65: /* exists_opt ::= IF EXISTS */
-{ yymsp[-1].minor.yy603 = true; }
+{ yymsp[-1].minor.yy131 = true; }
break;
case 67: /* db_options ::= */
-{ yymsp[1].minor.yy636 = createDefaultDatabaseOptions(pCxt); }
+{ yymsp[1].minor.yy686 = createDefaultDatabaseOptions(pCxt); }
break;
case 68: /* db_options ::= db_options BUFFER NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 69: /* db_options ::= db_options CACHELAST NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 70: /* db_options ::= db_options COMP NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_COMP, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_COMP, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 71: /* db_options ::= db_options DAYS NK_INTEGER */
case 72: /* db_options ::= db_options DAYS NK_VARIABLE */ yytestcase(yyruleno==72);
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_DAYS, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_DAYS, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 73: /* db_options ::= db_options FSYNC NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 74: /* db_options ::= db_options MAXROWS NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 75: /* db_options ::= db_options MINROWS NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 76: /* db_options ::= db_options KEEP integer_list */
case 77: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==77);
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_KEEP, yymsp[0].minor.yy236); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_KEEP, yymsp[0].minor.yy670); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 78: /* db_options ::= db_options PAGES NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_PAGES, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_PAGES, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 79: /* db_options ::= db_options PAGESIZE NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 80: /* db_options ::= db_options PRECISION NK_STRING */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 81: /* db_options ::= db_options REPLICA NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 82: /* db_options ::= db_options STRICT NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_STRICT, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_STRICT, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 83: /* db_options ::= db_options WAL NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_WAL, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_WAL, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 84: /* db_options ::= db_options VGROUPS NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 85: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 86: /* db_options ::= db_options RETENTIONS retention_list */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_RETENTIONS, yymsp[0].minor.yy236); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_RETENTIONS, yymsp[0].minor.yy670); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 87: /* db_options ::= db_options SCHEMALESS NK_INTEGER */
-{ yylhsminor.yy636 = setDatabaseOption(pCxt, yymsp[-2].minor.yy636, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setDatabaseOption(pCxt, yymsp[-2].minor.yy686, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 88: /* alter_db_options ::= alter_db_option */
-{ yylhsminor.yy636 = createAlterDatabaseOptions(pCxt); yylhsminor.yy636 = setAlterDatabaseOption(pCxt, yylhsminor.yy636, &yymsp[0].minor.yy25); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterDatabaseOptions(pCxt); yylhsminor.yy686 = setAlterDatabaseOption(pCxt, yylhsminor.yy686, &yymsp[0].minor.yy53); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
case 89: /* alter_db_options ::= alter_db_options alter_db_option */
-{ yylhsminor.yy636 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy636, &yymsp[0].minor.yy25); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy686, &yymsp[0].minor.yy53); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
case 90: /* alter_db_option ::= BUFFER NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 91: /* alter_db_option ::= CACHELAST NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_CACHELAST; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_CACHELAST; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 92: /* alter_db_option ::= FSYNC NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 93: /* alter_db_option ::= KEEP integer_list */
case 94: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==94);
-{ yymsp[-1].minor.yy25.type = DB_OPTION_KEEP; yymsp[-1].minor.yy25.pList = yymsp[0].minor.yy236; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_KEEP; yymsp[-1].minor.yy53.pList = yymsp[0].minor.yy670; }
break;
case 95: /* alter_db_option ::= PAGES NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_PAGES; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_PAGES; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 96: /* alter_db_option ::= REPLICA NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 97: /* alter_db_option ::= STRICT NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_STRICT; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_STRICT; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 98: /* alter_db_option ::= WAL NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = DB_OPTION_WAL; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+{ yymsp[-1].minor.yy53.type = DB_OPTION_WAL; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
case 99: /* integer_list ::= NK_INTEGER */
-{ yylhsminor.yy236 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
+{ yylhsminor.yy670 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
break;
case 100: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */
- case 263: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==263);
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-2].minor.yy236, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
- yymsp[-2].minor.yy236 = yylhsminor.yy236;
+ case 259: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==259);
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-2].minor.yy670, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
+ yymsp[-2].minor.yy670 = yylhsminor.yy670;
break;
case 101: /* variable_list ::= NK_VARIABLE */
-{ yylhsminor.yy236 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
+{ yylhsminor.yy670 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
break;
case 102: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-2].minor.yy236, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
- yymsp[-2].minor.yy236 = yylhsminor.yy236;
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-2].minor.yy670, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
+ yymsp[-2].minor.yy670 = yylhsminor.yy670;
break;
case 103: /* retention_list ::= retention */
case 123: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==123);
case 126: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==126);
case 133: /* column_def_list ::= column_def */ yytestcase(yyruleno==133);
- case 174: /* col_name_list ::= col_name */ yytestcase(yyruleno==174);
- case 212: /* func_name_list ::= func_name */ yytestcase(yyruleno==212);
- case 221: /* func_list ::= func */ yytestcase(yyruleno==221);
- case 288: /* literal_list ::= signed_literal */ yytestcase(yyruleno==288);
- case 342: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==342);
- case 397: /* select_sublist ::= select_item */ yytestcase(yyruleno==397);
- case 446: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==446);
-{ yylhsminor.yy236 = createNodeList(pCxt, yymsp[0].minor.yy636); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
+ case 173: /* col_name_list ::= col_name */ yytestcase(yyruleno==173);
+ case 211: /* func_name_list ::= func_name */ yytestcase(yyruleno==211);
+ case 220: /* func_list ::= func */ yytestcase(yyruleno==220);
+ case 284: /* literal_list ::= signed_literal */ yytestcase(yyruleno==284);
+ case 338: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==338);
+ case 393: /* select_sublist ::= select_item */ yytestcase(yyruleno==393);
+ case 442: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==442);
+{ yylhsminor.yy670 = createNodeList(pCxt, yymsp[0].minor.yy686); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
break;
case 104: /* retention_list ::= retention_list NK_COMMA retention */
case 134: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==134);
- case 175: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==175);
- case 213: /* func_name_list ::= func_name_list NK_COMMA func_name */ yytestcase(yyruleno==213);
- case 222: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==222);
- case 289: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==289);
- case 343: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==343);
- case 398: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==398);
- case 447: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==447);
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-2].minor.yy236, yymsp[0].minor.yy636); }
- yymsp[-2].minor.yy236 = yylhsminor.yy236;
+ case 174: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==174);
+ case 212: /* func_name_list ::= func_name_list NK_COMMA func_name */ yytestcase(yyruleno==212);
+ case 221: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==221);
+ case 285: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==285);
+ case 339: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==339);
+ case 394: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==394);
+ case 443: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==443);
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-2].minor.yy670, yymsp[0].minor.yy686); }
+ yymsp[-2].minor.yy670 = yylhsminor.yy670;
break;
case 105: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */
-{ yylhsminor.yy636 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 106: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */
case 108: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==108);
-{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy603, yymsp[-5].minor.yy636, yymsp[-3].minor.yy236, yymsp[-1].minor.yy236, yymsp[0].minor.yy636); }
+{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy131, yymsp[-5].minor.yy686, yymsp[-3].minor.yy670, yymsp[-1].minor.yy670, yymsp[0].minor.yy686); }
break;
case 107: /* cmd ::= CREATE TABLE multi_create_clause */
-{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy236); }
+{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy670); }
break;
case 109: /* cmd ::= DROP TABLE multi_drop_clause */
-{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy236); }
+{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy670); }
break;
case 110: /* cmd ::= DROP STABLE exists_opt full_table_name */
-{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy603, yymsp[0].minor.yy636); }
+{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy131, yymsp[0].minor.yy686); }
break;
case 111: /* cmd ::= ALTER TABLE alter_table_clause */
case 112: /* cmd ::= ALTER STABLE alter_table_clause */ yytestcase(yyruleno==112);
- case 265: /* cmd ::= query_expression */ yytestcase(yyruleno==265);
-{ pCxt->pRootNode = yymsp[0].minor.yy636; }
+ case 261: /* cmd ::= query_expression */ yytestcase(yyruleno==261);
+{ pCxt->pRootNode = yymsp[0].minor.yy686; }
break;
case 113: /* alter_table_clause ::= full_table_name alter_table_options */
-{ yylhsminor.yy636 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy636, yymsp[0].minor.yy636); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy686, yymsp[0].minor.yy686); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
case 114: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */
-{ yylhsminor.yy636 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy53, yymsp[0].minor.yy450); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy113, yymsp[0].minor.yy490); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 115: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */
-{ yylhsminor.yy636 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy636, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy53); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy686, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy113); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
case 116: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */
-{ yylhsminor.yy636 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy53, yymsp[0].minor.yy450); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy113, yymsp[0].minor.yy490); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 117: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */
-{ yylhsminor.yy636 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy53, &yymsp[0].minor.yy53); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy113, &yymsp[0].minor.yy113); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 118: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */
-{ yylhsminor.yy636 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy53, yymsp[0].minor.yy450); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy113, yymsp[0].minor.yy490); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 119: /* alter_table_clause ::= full_table_name DROP TAG column_name */
-{ yylhsminor.yy636 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy636, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy53); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy686, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy113); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
case 120: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */
-{ yylhsminor.yy636 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy53, yymsp[0].minor.yy450); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy113, yymsp[0].minor.yy490); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 121: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */
-{ yylhsminor.yy636 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy636, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy53, &yymsp[0].minor.yy53); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy686, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy113, &yymsp[0].minor.yy113); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
case 122: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */
-{ yylhsminor.yy636 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy636, &yymsp[-2].minor.yy53, yymsp[0].minor.yy636); }
- yymsp[-5].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy686, &yymsp[-2].minor.yy113, yymsp[0].minor.yy686); }
+ yymsp[-5].minor.yy686 = yylhsminor.yy686;
break;
case 124: /* multi_create_clause ::= multi_create_clause create_subtable_clause */
case 127: /* multi_drop_clause ::= multi_drop_clause drop_table_clause */ yytestcase(yyruleno==127);
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-1].minor.yy236, yymsp[0].minor.yy636); }
- yymsp[-1].minor.yy236 = yylhsminor.yy236;
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-1].minor.yy670, yymsp[0].minor.yy686); }
+ yymsp[-1].minor.yy670 = yylhsminor.yy670;
break;
case 125: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_tags_opt TAGS NK_LP literal_list NK_RP table_options */
-{ yylhsminor.yy636 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy603, yymsp[-8].minor.yy636, yymsp[-6].minor.yy636, yymsp[-5].minor.yy236, yymsp[-2].minor.yy236, yymsp[0].minor.yy636); }
- yymsp[-9].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy131, yymsp[-8].minor.yy686, yymsp[-6].minor.yy686, yymsp[-5].minor.yy670, yymsp[-2].minor.yy670, yymsp[0].minor.yy686); }
+ yymsp[-9].minor.yy686 = yylhsminor.yy686;
break;
case 128: /* drop_table_clause ::= exists_opt full_table_name */
-{ yylhsminor.yy636 = createDropTableClause(pCxt, yymsp[-1].minor.yy603, yymsp[0].minor.yy636); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createDropTableClause(pCxt, yymsp[-1].minor.yy131, yymsp[0].minor.yy686); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
case 129: /* specific_tags_opt ::= */
case 160: /* tags_def_opt ::= */ yytestcase(yyruleno==160);
- case 405: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==405);
- case 422: /* group_by_clause_opt ::= */ yytestcase(yyruleno==422);
- case 434: /* order_by_clause_opt ::= */ yytestcase(yyruleno==434);
-{ yymsp[1].minor.yy236 = NULL; }
+ case 401: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==401);
+ case 418: /* group_by_clause_opt ::= */ yytestcase(yyruleno==418);
+ case 430: /* order_by_clause_opt ::= */ yytestcase(yyruleno==430);
+{ yymsp[1].minor.yy670 = NULL; }
break;
case 130: /* specific_tags_opt ::= NK_LP col_name_list NK_RP */
-{ yymsp[-2].minor.yy236 = yymsp[-1].minor.yy236; }
+{ yymsp[-2].minor.yy670 = yymsp[-1].minor.yy670; }
break;
case 131: /* full_table_name ::= table_name */
-{ yylhsminor.yy636 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy53, NULL); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy113, NULL); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
case 132: /* full_table_name ::= db_name NK_DOT table_name */
-{ yylhsminor.yy636 = createRealTableNode(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53, NULL); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createRealTableNode(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113, NULL); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
case 135: /* column_def ::= column_name type_name */
-{ yylhsminor.yy636 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy53, yymsp[0].minor.yy450, NULL); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy113, yymsp[0].minor.yy490, NULL); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
case 136: /* column_def ::= column_name type_name COMMENT NK_STRING */
-{ yylhsminor.yy636 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy53, yymsp[-2].minor.yy450, &yymsp[0].minor.yy0); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy113, yymsp[-2].minor.yy490, &yymsp[0].minor.yy0); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
case 137: /* type_name ::= BOOL */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_BOOL); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_BOOL); }
break;
case 138: /* type_name ::= TINYINT */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_TINYINT); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_TINYINT); }
break;
case 139: /* type_name ::= SMALLINT */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_SMALLINT); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_SMALLINT); }
break;
case 140: /* type_name ::= INT */
case 141: /* type_name ::= INTEGER */ yytestcase(yyruleno==141);
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_INT); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_INT); }
break;
case 142: /* type_name ::= BIGINT */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_BIGINT); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_BIGINT); }
break;
case 143: /* type_name ::= FLOAT */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_FLOAT); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_FLOAT); }
break;
case 144: /* type_name ::= DOUBLE */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_DOUBLE); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_DOUBLE); }
break;
case 145: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */
-{ yymsp[-3].minor.yy450 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); }
+{ yymsp[-3].minor.yy490 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); }
break;
case 146: /* type_name ::= TIMESTAMP */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); }
break;
case 147: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */
-{ yymsp[-3].minor.yy450 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); }
+{ yymsp[-3].minor.yy490 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); }
break;
case 148: /* type_name ::= TINYINT UNSIGNED */
-{ yymsp[-1].minor.yy450 = createDataType(TSDB_DATA_TYPE_UTINYINT); }
+{ yymsp[-1].minor.yy490 = createDataType(TSDB_DATA_TYPE_UTINYINT); }
break;
case 149: /* type_name ::= SMALLINT UNSIGNED */
-{ yymsp[-1].minor.yy450 = createDataType(TSDB_DATA_TYPE_USMALLINT); }
+{ yymsp[-1].minor.yy490 = createDataType(TSDB_DATA_TYPE_USMALLINT); }
break;
case 150: /* type_name ::= INT UNSIGNED */
-{ yymsp[-1].minor.yy450 = createDataType(TSDB_DATA_TYPE_UINT); }
+{ yymsp[-1].minor.yy490 = createDataType(TSDB_DATA_TYPE_UINT); }
break;
case 151: /* type_name ::= BIGINT UNSIGNED */
-{ yymsp[-1].minor.yy450 = createDataType(TSDB_DATA_TYPE_UBIGINT); }
+{ yymsp[-1].minor.yy490 = createDataType(TSDB_DATA_TYPE_UBIGINT); }
break;
case 152: /* type_name ::= JSON */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_JSON); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_JSON); }
break;
case 153: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */
-{ yymsp[-3].minor.yy450 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); }
+{ yymsp[-3].minor.yy490 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); }
break;
case 154: /* type_name ::= MEDIUMBLOB */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); }
break;
case 155: /* type_name ::= BLOB */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_BLOB); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_BLOB); }
break;
case 156: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */
-{ yymsp[-3].minor.yy450 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); }
+{ yymsp[-3].minor.yy490 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); }
break;
case 157: /* type_name ::= DECIMAL */
-{ yymsp[0].minor.yy450 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
+{ yymsp[0].minor.yy490 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
break;
case 158: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */
-{ yymsp[-3].minor.yy450 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
+{ yymsp[-3].minor.yy490 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
break;
case 159: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */
-{ yymsp[-5].minor.yy450 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
+{ yymsp[-5].minor.yy490 = createDataType(TSDB_DATA_TYPE_DECIMAL); }
break;
case 161: /* tags_def_opt ::= tags_def */
- case 341: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==341);
- case 396: /* select_list ::= select_sublist */ yytestcase(yyruleno==396);
-{ yylhsminor.yy236 = yymsp[0].minor.yy236; }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
+ case 337: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==337);
+ case 392: /* select_list ::= select_sublist */ yytestcase(yyruleno==392);
+{ yylhsminor.yy670 = yymsp[0].minor.yy670; }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
break;
case 162: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */
-{ yymsp[-3].minor.yy236 = yymsp[-1].minor.yy236; }
+{ yymsp[-3].minor.yy670 = yymsp[-1].minor.yy670; }
break;
case 163: /* table_options ::= */
-{ yymsp[1].minor.yy636 = createDefaultTableOptions(pCxt); }
+{ yymsp[1].minor.yy686 = createDefaultTableOptions(pCxt); }
break;
case 164: /* table_options ::= table_options COMMENT NK_STRING */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-2].minor.yy636, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 165: /* table_options ::= table_options DELAY NK_INTEGER */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-2].minor.yy636, TABLE_OPTION_DELAY, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-2].minor.yy686, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 166: /* table_options ::= table_options FILE_FACTOR NK_FLOAT */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-2].minor.yy636, TABLE_OPTION_FILE_FACTOR, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 165: /* table_options ::= table_options FILE_FACTOR NK_FLOAT */
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-2].minor.yy686, TABLE_OPTION_FILE_FACTOR, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 167: /* table_options ::= table_options ROLLUP NK_LP func_name_list NK_RP */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-4].minor.yy636, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy236); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+ case 166: /* table_options ::= table_options ROLLUP NK_LP func_name_list NK_RP */
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-4].minor.yy686, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy670); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
- case 168: /* table_options ::= table_options TTL NK_INTEGER */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-2].minor.yy636, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 167: /* table_options ::= table_options TTL NK_INTEGER */
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-2].minor.yy686, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 169: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-4].minor.yy636, TABLE_OPTION_SMA, yymsp[-1].minor.yy236); }
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+ case 168: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-4].minor.yy686, TABLE_OPTION_SMA, yymsp[-1].minor.yy670); }
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
- case 170: /* alter_table_options ::= alter_table_option */
-{ yylhsminor.yy636 = createAlterTableOptions(pCxt); yylhsminor.yy636 = setTableOption(pCxt, yylhsminor.yy636, yymsp[0].minor.yy25.type, &yymsp[0].minor.yy25.val); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 169: /* alter_table_options ::= alter_table_option */
+{ yylhsminor.yy686 = createAlterTableOptions(pCxt); yylhsminor.yy686 = setTableOption(pCxt, yylhsminor.yy686, yymsp[0].minor.yy53.type, &yymsp[0].minor.yy53.val); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 171: /* alter_table_options ::= alter_table_options alter_table_option */
-{ yylhsminor.yy636 = setTableOption(pCxt, yymsp[-1].minor.yy636, yymsp[0].minor.yy25.type, &yymsp[0].minor.yy25.val); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ case 170: /* alter_table_options ::= alter_table_options alter_table_option */
+{ yylhsminor.yy686 = setTableOption(pCxt, yymsp[-1].minor.yy686, yymsp[0].minor.yy53.type, &yymsp[0].minor.yy53.val); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 172: /* alter_table_option ::= COMMENT NK_STRING */
-{ yymsp[-1].minor.yy25.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+ case 171: /* alter_table_option ::= COMMENT NK_STRING */
+{ yymsp[-1].minor.yy53.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
- case 173: /* alter_table_option ::= TTL NK_INTEGER */
-{ yymsp[-1].minor.yy25.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy25.val = yymsp[0].minor.yy0; }
+ case 172: /* alter_table_option ::= TTL NK_INTEGER */
+{ yymsp[-1].minor.yy53.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy53.val = yymsp[0].minor.yy0; }
break;
- case 176: /* col_name ::= column_name */
-{ yylhsminor.yy636 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy53); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 175: /* col_name ::= column_name */
+{ yylhsminor.yy686 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy113); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 177: /* cmd ::= SHOW DNODES */
+ case 176: /* cmd ::= SHOW DNODES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT, NULL, NULL); }
break;
- case 178: /* cmd ::= SHOW USERS */
+ case 177: /* cmd ::= SHOW USERS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USERS_STMT, NULL, NULL); }
break;
- case 179: /* cmd ::= SHOW DATABASES */
+ case 178: /* cmd ::= SHOW DATABASES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT, NULL, NULL); }
break;
- case 180: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */
-{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy636, yymsp[0].minor.yy636); }
+ case 179: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */
+{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 181: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */
-{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy636, yymsp[0].minor.yy636); }
+ case 180: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */
+{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 182: /* cmd ::= SHOW db_name_cond_opt VGROUPS */
-{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy636, NULL); }
+ case 181: /* cmd ::= SHOW db_name_cond_opt VGROUPS */
+{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy686, NULL); }
break;
- case 183: /* cmd ::= SHOW MNODES */
+ case 182: /* cmd ::= SHOW MNODES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT, NULL, NULL); }
break;
- case 184: /* cmd ::= SHOW MODULES */
+ case 183: /* cmd ::= SHOW MODULES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT, NULL, NULL); }
break;
- case 185: /* cmd ::= SHOW QNODES */
+ case 184: /* cmd ::= SHOW QNODES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT, NULL, NULL); }
break;
- case 186: /* cmd ::= SHOW FUNCTIONS */
+ case 185: /* cmd ::= SHOW FUNCTIONS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT, NULL, NULL); }
break;
- case 187: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */
-{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[-1].minor.yy636, yymsp[0].minor.yy636); }
+ case 186: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */
+{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[-1].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 188: /* cmd ::= SHOW STREAMS */
+ case 187: /* cmd ::= SHOW STREAMS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT, NULL, NULL); }
break;
- case 189: /* cmd ::= SHOW ACCOUNTS */
+ case 188: /* cmd ::= SHOW ACCOUNTS */
{ pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); }
break;
- case 190: /* cmd ::= SHOW APPS */
+ case 189: /* cmd ::= SHOW APPS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT, NULL, NULL); }
break;
- case 191: /* cmd ::= SHOW CONNECTIONS */
+ case 190: /* cmd ::= SHOW CONNECTIONS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT, NULL, NULL); }
break;
- case 192: /* cmd ::= SHOW LICENCE */
- case 193: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==193);
+ case 191: /* cmd ::= SHOW LICENCE */
+ case 192: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==192);
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCE_STMT, NULL, NULL); }
break;
- case 194: /* cmd ::= SHOW CREATE DATABASE db_name */
-{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy53); }
+ case 193: /* cmd ::= SHOW CREATE DATABASE db_name */
+{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy113); }
break;
- case 195: /* cmd ::= SHOW CREATE TABLE full_table_name */
-{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy636); }
+ case 194: /* cmd ::= SHOW CREATE TABLE full_table_name */
+{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy686); }
break;
- case 196: /* cmd ::= SHOW CREATE STABLE full_table_name */
-{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy636); }
+ case 195: /* cmd ::= SHOW CREATE STABLE full_table_name */
+{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy686); }
break;
- case 197: /* cmd ::= SHOW QUERIES */
+ case 196: /* cmd ::= SHOW QUERIES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT, NULL, NULL); }
break;
- case 198: /* cmd ::= SHOW SCORES */
+ case 197: /* cmd ::= SHOW SCORES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SCORES_STMT, NULL, NULL); }
break;
- case 199: /* cmd ::= SHOW TOPICS */
+ case 198: /* cmd ::= SHOW TOPICS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT, NULL, NULL); }
break;
- case 200: /* cmd ::= SHOW VARIABLES */
+ case 199: /* cmd ::= SHOW VARIABLES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLE_STMT, NULL, NULL); }
break;
- case 201: /* cmd ::= SHOW BNODES */
+ case 200: /* cmd ::= SHOW BNODES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT, NULL, NULL); }
break;
- case 202: /* cmd ::= SHOW SNODES */
+ case 201: /* cmd ::= SHOW SNODES */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT, NULL, NULL); }
break;
- case 203: /* cmd ::= SHOW CLUSTER */
+ case 202: /* cmd ::= SHOW CLUSTER */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT, NULL, NULL); }
break;
- case 204: /* cmd ::= SHOW TRANSACTIONS */
+ case 203: /* cmd ::= SHOW TRANSACTIONS */
{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT, NULL, NULL); }
break;
- case 205: /* db_name_cond_opt ::= */
- case 210: /* from_db_opt ::= */ yytestcase(yyruleno==210);
-{ yymsp[1].minor.yy636 = createDefaultDatabaseCondValue(pCxt); }
- break;
- case 206: /* db_name_cond_opt ::= db_name NK_DOT */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy53); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
- break;
- case 207: /* like_pattern_opt ::= */
- case 218: /* index_options ::= */ yytestcase(yyruleno==218);
- case 250: /* into_opt ::= */ yytestcase(yyruleno==250);
- case 403: /* where_clause_opt ::= */ yytestcase(yyruleno==403);
- case 407: /* twindow_clause_opt ::= */ yytestcase(yyruleno==407);
- case 412: /* sliding_opt ::= */ yytestcase(yyruleno==412);
- case 414: /* fill_opt ::= */ yytestcase(yyruleno==414);
- case 426: /* having_clause_opt ::= */ yytestcase(yyruleno==426);
- case 436: /* slimit_clause_opt ::= */ yytestcase(yyruleno==436);
- case 440: /* limit_clause_opt ::= */ yytestcase(yyruleno==440);
-{ yymsp[1].minor.yy636 = NULL; }
- break;
- case 208: /* like_pattern_opt ::= LIKE NK_STRING */
-{ yymsp[-1].minor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); }
+ case 204: /* db_name_cond_opt ::= */
+ case 209: /* from_db_opt ::= */ yytestcase(yyruleno==209);
+{ yymsp[1].minor.yy686 = createDefaultDatabaseCondValue(pCxt); }
break;
- case 209: /* table_name_cond ::= table_name */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy53); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 205: /* db_name_cond_opt ::= db_name NK_DOT */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy113); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 211: /* from_db_opt ::= FROM db_name */
-{ yymsp[-1].minor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy53); }
+ case 206: /* like_pattern_opt ::= */
+ case 217: /* index_options ::= */ yytestcase(yyruleno==217);
+ case 246: /* into_opt ::= */ yytestcase(yyruleno==246);
+ case 399: /* where_clause_opt ::= */ yytestcase(yyruleno==399);
+ case 403: /* twindow_clause_opt ::= */ yytestcase(yyruleno==403);
+ case 408: /* sliding_opt ::= */ yytestcase(yyruleno==408);
+ case 410: /* fill_opt ::= */ yytestcase(yyruleno==410);
+ case 422: /* having_clause_opt ::= */ yytestcase(yyruleno==422);
+ case 432: /* slimit_clause_opt ::= */ yytestcase(yyruleno==432);
+ case 436: /* limit_clause_opt ::= */ yytestcase(yyruleno==436);
+{ yymsp[1].minor.yy686 = NULL; }
break;
- case 214: /* func_name ::= function_name */
-{ yylhsminor.yy636 = createFunctionNode(pCxt, &yymsp[0].minor.yy53, NULL); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 207: /* like_pattern_opt ::= LIKE NK_STRING */
+{ yymsp[-1].minor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); }
break;
- case 215: /* cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */
-{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy603, &yymsp[-3].minor.yy53, &yymsp[-1].minor.yy53, NULL, yymsp[0].minor.yy636); }
+ case 208: /* table_name_cond ::= table_name */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy113); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 216: /* cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */
-{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, yymsp[-6].minor.yy603, &yymsp[-5].minor.yy53, &yymsp[-3].minor.yy53, yymsp[-1].minor.yy236, NULL); }
+ case 210: /* from_db_opt ::= FROM db_name */
+{ yymsp[-1].minor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy113); }
break;
- case 217: /* cmd ::= DROP INDEX exists_opt index_name ON table_name */
-{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-3].minor.yy603, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53); }
+ case 213: /* func_name ::= function_name */
+{ yylhsminor.yy686 = createFunctionNode(pCxt, &yymsp[0].minor.yy113, NULL); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 219: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */
-{ yymsp[-8].minor.yy636 = createIndexOption(pCxt, yymsp[-6].minor.yy236, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), NULL, yymsp[0].minor.yy636); }
+ case 214: /* cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */
+{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy131, &yymsp[-3].minor.yy113, &yymsp[-1].minor.yy113, NULL, yymsp[0].minor.yy686); }
break;
- case 220: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */
-{ yymsp[-10].minor.yy636 = createIndexOption(pCxt, yymsp[-8].minor.yy236, releaseRawExprNode(pCxt, yymsp[-4].minor.yy636), releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), yymsp[0].minor.yy636); }
+ case 215: /* cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */
+{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, yymsp[-6].minor.yy131, &yymsp[-5].minor.yy113, &yymsp[-3].minor.yy113, yymsp[-1].minor.yy670, NULL); }
break;
- case 223: /* func ::= function_name NK_LP expression_list NK_RP */
-{ yylhsminor.yy636 = createFunctionNode(pCxt, &yymsp[-3].minor.yy53, yymsp[-1].minor.yy236); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+ case 216: /* cmd ::= DROP INDEX exists_opt index_name ON table_name */
+{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-3].minor.yy131, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113); }
break;
- case 224: /* cmd ::= CREATE TOPIC not_exists_opt topic_name topic_options AS query_expression */
-{ pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy603, &yymsp[-3].minor.yy53, yymsp[0].minor.yy636, NULL, yymsp[-2].minor.yy636); }
+ case 218: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */
+{ yymsp[-8].minor.yy686 = createIndexOption(pCxt, yymsp[-6].minor.yy670, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), NULL, yymsp[0].minor.yy686); }
break;
- case 225: /* cmd ::= CREATE TOPIC not_exists_opt topic_name topic_options AS db_name */
-{ pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy603, &yymsp[-3].minor.yy53, NULL, &yymsp[0].minor.yy53, yymsp[-2].minor.yy636); }
+ case 219: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */
+{ yymsp[-10].minor.yy686 = createIndexOption(pCxt, yymsp[-8].minor.yy670, releaseRawExprNode(pCxt, yymsp[-4].minor.yy686), releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), yymsp[0].minor.yy686); }
break;
- case 226: /* cmd ::= DROP TOPIC exists_opt topic_name */
-{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy603, &yymsp[0].minor.yy53); }
+ case 222: /* func ::= function_name NK_LP expression_list NK_RP */
+{ yylhsminor.yy686 = createFunctionNode(pCxt, &yymsp[-3].minor.yy113, yymsp[-1].minor.yy670); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
- case 227: /* cmd ::= DROP CGROUP exists_opt cgroup_name ON topic_name */
-{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy603, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53); }
+ case 223: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */
+{ pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-3].minor.yy131, &yymsp[-2].minor.yy113, yymsp[0].minor.yy686, NULL, NULL); }
break;
- case 228: /* topic_options ::= */
-{ yymsp[1].minor.yy636 = createTopicOptions(pCxt); }
+ case 224: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */
+{ pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy131, &yymsp[-3].minor.yy113, NULL, &yymsp[0].minor.yy113, NULL); }
break;
- case 229: /* topic_options ::= topic_options WITH TABLE */
-{ ((STopicOptions*)yymsp[-2].minor.yy636)->withTable = true; yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 225: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */
+{ pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy131, &yymsp[-3].minor.yy113, NULL, NULL, yymsp[0].minor.yy686); }
break;
- case 230: /* topic_options ::= topic_options WITH SCHEMA */
-{ ((STopicOptions*)yymsp[-2].minor.yy636)->withSchema = true; yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 226: /* cmd ::= DROP TOPIC exists_opt topic_name */
+{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy131, &yymsp[0].minor.yy113); }
break;
- case 231: /* topic_options ::= topic_options WITH TAG */
-{ ((STopicOptions*)yymsp[-2].minor.yy636)->withTag = true; yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 227: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */
+{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy131, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113); }
break;
- case 232: /* cmd ::= DESC full_table_name */
- case 233: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==233);
-{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy636); }
+ case 228: /* cmd ::= DESC full_table_name */
+ case 229: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==229);
+{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy686); }
break;
- case 234: /* cmd ::= RESET QUERY CACHE */
+ case 230: /* cmd ::= RESET QUERY CACHE */
{ pCxt->pRootNode = createResetQueryCacheStmt(pCxt); }
break;
- case 235: /* cmd ::= EXPLAIN analyze_opt explain_options query_expression */
-{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy603, yymsp[-1].minor.yy636, yymsp[0].minor.yy636); }
+ case 231: /* cmd ::= EXPLAIN analyze_opt explain_options query_expression */
+{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy131, yymsp[-1].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 237: /* analyze_opt ::= ANALYZE */
- case 245: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==245);
- case 393: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==393);
-{ yymsp[0].minor.yy603 = true; }
+ case 233: /* analyze_opt ::= ANALYZE */
+ case 241: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==241);
+ case 389: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==389);
+{ yymsp[0].minor.yy131 = true; }
break;
- case 238: /* explain_options ::= */
-{ yymsp[1].minor.yy636 = createDefaultExplainOptions(pCxt); }
+ case 234: /* explain_options ::= */
+{ yymsp[1].minor.yy686 = createDefaultExplainOptions(pCxt); }
break;
- case 239: /* explain_options ::= explain_options VERBOSE NK_BOOL */
-{ yylhsminor.yy636 = setExplainVerbose(pCxt, yymsp[-2].minor.yy636, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 235: /* explain_options ::= explain_options VERBOSE NK_BOOL */
+{ yylhsminor.yy686 = setExplainVerbose(pCxt, yymsp[-2].minor.yy686, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 240: /* explain_options ::= explain_options RATIO NK_FLOAT */
-{ yylhsminor.yy636 = setExplainRatio(pCxt, yymsp[-2].minor.yy636, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 236: /* explain_options ::= explain_options RATIO NK_FLOAT */
+{ yylhsminor.yy686 = setExplainRatio(pCxt, yymsp[-2].minor.yy686, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 241: /* cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */
-{ pCxt->pRootNode = createCompactStmt(pCxt, yymsp[-1].minor.yy236); }
+ case 237: /* cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */
+{ pCxt->pRootNode = createCompactStmt(pCxt, yymsp[-1].minor.yy670); }
break;
- case 242: /* cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */
-{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-6].minor.yy603, yymsp[-8].minor.yy603, &yymsp[-5].minor.yy53, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy450, yymsp[0].minor.yy158); }
+ case 238: /* cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */
+{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-6].minor.yy131, yymsp[-8].minor.yy131, &yymsp[-5].minor.yy113, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy490, yymsp[0].minor.yy550); }
break;
- case 243: /* cmd ::= DROP FUNCTION exists_opt function_name */
-{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy603, &yymsp[0].minor.yy53); }
+ case 239: /* cmd ::= DROP FUNCTION exists_opt function_name */
+{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy131, &yymsp[0].minor.yy113); }
break;
- case 246: /* bufsize_opt ::= */
-{ yymsp[1].minor.yy158 = 0; }
+ case 242: /* bufsize_opt ::= */
+{ yymsp[1].minor.yy550 = 0; }
break;
- case 247: /* bufsize_opt ::= BUFSIZE NK_INTEGER */
-{ yymsp[-1].minor.yy158 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); }
+ case 243: /* bufsize_opt ::= BUFSIZE NK_INTEGER */
+{ yymsp[-1].minor.yy550 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); }
break;
- case 248: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */
-{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-5].minor.yy603, &yymsp[-4].minor.yy53, yymsp[-2].minor.yy636, yymsp[-3].minor.yy636, yymsp[0].minor.yy636); }
+ case 244: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */
+{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy113, yymsp[-2].minor.yy686, yymsp[-3].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 249: /* cmd ::= DROP STREAM exists_opt stream_name */
-{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy603, &yymsp[0].minor.yy53); }
+ case 245: /* cmd ::= DROP STREAM exists_opt stream_name */
+{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy131, &yymsp[0].minor.yy113); }
break;
- case 251: /* into_opt ::= INTO full_table_name */
- case 374: /* from_clause ::= FROM table_reference_list */ yytestcase(yyruleno==374);
- case 404: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==404);
- case 427: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==427);
-{ yymsp[-1].minor.yy636 = yymsp[0].minor.yy636; }
+ case 247: /* into_opt ::= INTO full_table_name */
+ case 370: /* from_clause ::= FROM table_reference_list */ yytestcase(yyruleno==370);
+ case 400: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==400);
+ case 423: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==423);
+{ yymsp[-1].minor.yy686 = yymsp[0].minor.yy686; }
break;
- case 252: /* stream_options ::= */
-{ yymsp[1].minor.yy636 = createStreamOptions(pCxt); }
+ case 248: /* stream_options ::= */
+{ yymsp[1].minor.yy686 = createStreamOptions(pCxt); }
break;
- case 253: /* stream_options ::= stream_options TRIGGER AT_ONCE */
-{ ((SStreamOptions*)yymsp[-2].minor.yy636)->triggerType = STREAM_TRIGGER_AT_ONCE; yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 249: /* stream_options ::= stream_options TRIGGER AT_ONCE */
+{ ((SStreamOptions*)yymsp[-2].minor.yy686)->triggerType = STREAM_TRIGGER_AT_ONCE; yylhsminor.yy686 = yymsp[-2].minor.yy686; }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 254: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */
-{ ((SStreamOptions*)yymsp[-2].minor.yy636)->triggerType = STREAM_TRIGGER_WINDOW_CLOSE; yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 250: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */
+{ ((SStreamOptions*)yymsp[-2].minor.yy686)->triggerType = STREAM_TRIGGER_WINDOW_CLOSE; yylhsminor.yy686 = yymsp[-2].minor.yy686; }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 255: /* stream_options ::= stream_options WATERMARK duration_literal */
-{ ((SStreamOptions*)yymsp[-2].minor.yy636)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy636); yylhsminor.yy636 = yymsp[-2].minor.yy636; }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 251: /* stream_options ::= stream_options WATERMARK duration_literal */
+{ ((SStreamOptions*)yymsp[-2].minor.yy686)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy686); yylhsminor.yy686 = yymsp[-2].minor.yy686; }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 256: /* cmd ::= KILL CONNECTION NK_INTEGER */
+ case 252: /* cmd ::= KILL CONNECTION NK_INTEGER */
{ pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); }
break;
- case 257: /* cmd ::= KILL QUERY NK_INTEGER */
+ case 253: /* cmd ::= KILL QUERY NK_INTEGER */
{ pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_QUERY_STMT, &yymsp[0].minor.yy0); }
break;
- case 258: /* cmd ::= KILL TRANSACTION NK_INTEGER */
+ case 254: /* cmd ::= KILL TRANSACTION NK_INTEGER */
{ pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); }
break;
- case 259: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */
+ case 255: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */
{ pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); }
break;
- case 260: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */
-{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy236); }
+ case 256: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */
+{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy670); }
break;
- case 261: /* cmd ::= SPLIT VGROUP NK_INTEGER */
+ case 257: /* cmd ::= SPLIT VGROUP NK_INTEGER */
{ pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); }
break;
- case 262: /* dnode_list ::= DNODE NK_INTEGER */
-{ yymsp[-1].minor.yy236 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
- break;
- case 264: /* cmd ::= SYNCDB db_name REPLICA */
-{ pCxt->pRootNode = createSyncdbStmt(pCxt, &yymsp[-1].minor.yy53); }
- break;
- case 266: /* literal ::= NK_INTEGER */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 267: /* literal ::= NK_FLOAT */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 268: /* literal ::= NK_STRING */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 269: /* literal ::= NK_BOOL */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 270: /* literal ::= TIMESTAMP NK_STRING */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
- break;
- case 271: /* literal ::= duration_literal */
- case 281: /* signed_literal ::= signed */ yytestcase(yyruleno==281);
- case 301: /* expression ::= literal */ yytestcase(yyruleno==301);
- case 302: /* expression ::= pseudo_column */ yytestcase(yyruleno==302);
- case 303: /* expression ::= column_reference */ yytestcase(yyruleno==303);
- case 304: /* expression ::= function_expression */ yytestcase(yyruleno==304);
- case 305: /* expression ::= subquery */ yytestcase(yyruleno==305);
- case 330: /* function_expression ::= literal_func */ yytestcase(yyruleno==330);
- case 366: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==366);
- case 370: /* boolean_primary ::= predicate */ yytestcase(yyruleno==370);
- case 372: /* common_expression ::= expression */ yytestcase(yyruleno==372);
- case 373: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==373);
- case 375: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==375);
- case 377: /* table_reference ::= table_primary */ yytestcase(yyruleno==377);
- case 378: /* table_reference ::= joined_table */ yytestcase(yyruleno==378);
- case 382: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==382);
- case 429: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==429);
- case 432: /* query_primary ::= query_specification */ yytestcase(yyruleno==432);
-{ yylhsminor.yy636 = yymsp[0].minor.yy636; }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 272: /* literal ::= NULL */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 273: /* literal ::= NK_QUESTION */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 274: /* duration_literal ::= NK_VARIABLE */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 275: /* signed ::= NK_INTEGER */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 276: /* signed ::= NK_PLUS NK_INTEGER */
-{ yymsp[-1].minor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); }
- break;
- case 277: /* signed ::= NK_MINUS NK_INTEGER */
+ case 258: /* dnode_list ::= DNODE NK_INTEGER */
+{ yymsp[-1].minor.yy670 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
+ break;
+ case 260: /* cmd ::= SYNCDB db_name REPLICA */
+{ pCxt->pRootNode = createSyncdbStmt(pCxt, &yymsp[-1].minor.yy113); }
+ break;
+ case 262: /* literal ::= NK_INTEGER */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 263: /* literal ::= NK_FLOAT */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 264: /* literal ::= NK_STRING */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 265: /* literal ::= NK_BOOL */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 266: /* literal ::= TIMESTAMP NK_STRING */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 267: /* literal ::= duration_literal */
+ case 277: /* signed_literal ::= signed */ yytestcase(yyruleno==277);
+ case 297: /* expression ::= literal */ yytestcase(yyruleno==297);
+ case 298: /* expression ::= pseudo_column */ yytestcase(yyruleno==298);
+ case 299: /* expression ::= column_reference */ yytestcase(yyruleno==299);
+ case 300: /* expression ::= function_expression */ yytestcase(yyruleno==300);
+ case 301: /* expression ::= subquery */ yytestcase(yyruleno==301);
+ case 326: /* function_expression ::= literal_func */ yytestcase(yyruleno==326);
+ case 362: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==362);
+ case 366: /* boolean_primary ::= predicate */ yytestcase(yyruleno==366);
+ case 368: /* common_expression ::= expression */ yytestcase(yyruleno==368);
+ case 369: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==369);
+ case 371: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==371);
+ case 373: /* table_reference ::= table_primary */ yytestcase(yyruleno==373);
+ case 374: /* table_reference ::= joined_table */ yytestcase(yyruleno==374);
+ case 378: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==378);
+ case 425: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==425);
+ case 428: /* query_primary ::= query_specification */ yytestcase(yyruleno==428);
+{ yylhsminor.yy686 = yymsp[0].minor.yy686; }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 268: /* literal ::= NULL */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 269: /* literal ::= NK_QUESTION */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 270: /* duration_literal ::= NK_VARIABLE */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 271: /* signed ::= NK_INTEGER */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 272: /* signed ::= NK_PLUS NK_INTEGER */
+{ yymsp[-1].minor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); }
+ break;
+ case 273: /* signed ::= NK_MINUS NK_INTEGER */
{
SToken t = yymsp[-1].minor.yy0;
t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z;
- yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t);
+ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t);
}
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 278: /* signed ::= NK_FLOAT */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 274: /* signed ::= NK_FLOAT */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 279: /* signed ::= NK_PLUS NK_FLOAT */
-{ yymsp[-1].minor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); }
+ case 275: /* signed ::= NK_PLUS NK_FLOAT */
+{ yymsp[-1].minor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); }
break;
- case 280: /* signed ::= NK_MINUS NK_FLOAT */
+ case 276: /* signed ::= NK_MINUS NK_FLOAT */
{
SToken t = yymsp[-1].minor.yy0;
t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z;
- yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t);
+ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t);
}
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 282: /* signed_literal ::= NK_STRING */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 278: /* signed_literal ::= NK_STRING */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 283: /* signed_literal ::= NK_BOOL */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 279: /* signed_literal ::= NK_BOOL */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 284: /* signed_literal ::= TIMESTAMP NK_STRING */
-{ yymsp[-1].minor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); }
+ case 280: /* signed_literal ::= TIMESTAMP NK_STRING */
+{ yymsp[-1].minor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); }
break;
- case 285: /* signed_literal ::= duration_literal */
- case 287: /* signed_literal ::= literal_func */ yytestcase(yyruleno==287);
- case 344: /* star_func_para ::= expression */ yytestcase(yyruleno==344);
- case 399: /* select_item ::= common_expression */ yytestcase(yyruleno==399);
- case 445: /* search_condition ::= common_expression */ yytestcase(yyruleno==445);
-{ yylhsminor.yy636 = releaseRawExprNode(pCxt, yymsp[0].minor.yy636); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 281: /* signed_literal ::= duration_literal */
+ case 283: /* signed_literal ::= literal_func */ yytestcase(yyruleno==283);
+ case 340: /* star_func_para ::= expression */ yytestcase(yyruleno==340);
+ case 395: /* select_item ::= common_expression */ yytestcase(yyruleno==395);
+ case 441: /* search_condition ::= common_expression */ yytestcase(yyruleno==441);
+{ yylhsminor.yy686 = releaseRawExprNode(pCxt, yymsp[0].minor.yy686); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 286: /* signed_literal ::= NULL */
-{ yylhsminor.yy636 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
+ case 282: /* signed_literal ::= NULL */
+{ yylhsminor.yy686 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
break;
- case 306: /* expression ::= NK_LP expression NK_RP */
- case 371: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==371);
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy636)); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 302: /* expression ::= NK_LP expression NK_RP */
+ case 367: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==367);
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy686)); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 307: /* expression ::= NK_PLUS expression */
+ case 303: /* expression ::= NK_PLUS expression */
{
- SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy636));
+ SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy686));
}
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 308: /* expression ::= NK_MINUS expression */
+ case 304: /* expression ::= NK_MINUS expression */
{
- SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy636), NULL));
+ SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy686), NULL));
}
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 309: /* expression ::= expression NK_PLUS expression */
+ case 305: /* expression ::= expression NK_PLUS expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 310: /* expression ::= expression NK_MINUS expression */
+ case 306: /* expression ::= expression NK_MINUS expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 311: /* expression ::= expression NK_STAR expression */
+ case 307: /* expression ::= expression NK_STAR expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 312: /* expression ::= expression NK_SLASH expression */
+ case 308: /* expression ::= expression NK_SLASH expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 313: /* expression ::= expression NK_REM expression */
+ case 309: /* expression ::= expression NK_REM expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 314: /* expression ::= column_reference NK_ARROW NK_STRING */
+ case 310: /* expression ::= column_reference NK_ARROW NK_STRING */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 315: /* expression_list ::= expression */
-{ yylhsminor.yy236 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy636)); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
- break;
- case 316: /* expression_list ::= expression_list NK_COMMA expression */
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-2].minor.yy236, releaseRawExprNode(pCxt, yymsp[0].minor.yy636)); }
- yymsp[-2].minor.yy236 = yylhsminor.yy236;
- break;
- case 317: /* column_reference ::= column_name */
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy53, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy53)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 318: /* column_reference ::= table_name NK_DOT column_name */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53, createColumnNode(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy53)); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 319: /* pseudo_column ::= ROWTS */
- case 320: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==320);
- case 322: /* pseudo_column ::= QSTARTTS */ yytestcase(yyruleno==322);
- case 323: /* pseudo_column ::= QENDTS */ yytestcase(yyruleno==323);
- case 324: /* pseudo_column ::= WSTARTTS */ yytestcase(yyruleno==324);
- case 325: /* pseudo_column ::= WENDTS */ yytestcase(yyruleno==325);
- case 326: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==326);
- case 332: /* literal_func ::= NOW */ yytestcase(yyruleno==332);
-{ yylhsminor.yy636 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); }
- yymsp[0].minor.yy636 = yylhsminor.yy636;
- break;
- case 321: /* pseudo_column ::= table_name NK_DOT TBNAME */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy53)))); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 327: /* function_expression ::= function_name NK_LP expression_list NK_RP */
- case 328: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==328);
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy53, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy53, yymsp[-1].minor.yy236)); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
- break;
- case 329: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy636), yymsp[-1].minor.yy450)); }
- yymsp[-5].minor.yy636 = yylhsminor.yy636;
- break;
- case 331: /* literal_func ::= noarg_func NK_LP NK_RP */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy53, NULL)); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 340: /* star_func_para_list ::= NK_STAR */
-{ yylhsminor.yy236 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
- break;
- case 345: /* star_func_para ::= table_name NK_DOT NK_STAR */
- case 402: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==402);
-{ yylhsminor.yy636 = createColumnNode(pCxt, &yymsp[-2].minor.yy53, &yymsp[0].minor.yy0); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
- break;
- case 346: /* predicate ::= expression compare_op expression */
- case 351: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==351);
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 311: /* expression_list ::= expression */
+{ yylhsminor.yy670 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy686)); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
+ break;
+ case 312: /* expression_list ::= expression_list NK_COMMA expression */
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-2].minor.yy670, releaseRawExprNode(pCxt, yymsp[0].minor.yy686)); }
+ yymsp[-2].minor.yy670 = yylhsminor.yy670;
+ break;
+ case 313: /* column_reference ::= column_name */
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy113, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy113)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 314: /* column_reference ::= table_name NK_DOT column_name */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113, createColumnNode(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy113)); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 315: /* pseudo_column ::= ROWTS */
+ case 316: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==316);
+ case 318: /* pseudo_column ::= QSTARTTS */ yytestcase(yyruleno==318);
+ case 319: /* pseudo_column ::= QENDTS */ yytestcase(yyruleno==319);
+ case 320: /* pseudo_column ::= WSTARTTS */ yytestcase(yyruleno==320);
+ case 321: /* pseudo_column ::= WENDTS */ yytestcase(yyruleno==321);
+ case 322: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==322);
+ case 328: /* literal_func ::= NOW */ yytestcase(yyruleno==328);
+{ yylhsminor.yy686 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); }
+ yymsp[0].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 317: /* pseudo_column ::= table_name NK_DOT TBNAME */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy113)))); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 323: /* function_expression ::= function_name NK_LP expression_list NK_RP */
+ case 324: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==324);
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy113, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy113, yymsp[-1].minor.yy670)); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 325: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy686), yymsp[-1].minor.yy490)); }
+ yymsp[-5].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 327: /* literal_func ::= noarg_func NK_LP NK_RP */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy113, NULL)); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 336: /* star_func_para_list ::= NK_STAR */
+{ yylhsminor.yy670 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
+ break;
+ case 341: /* star_func_para ::= table_name NK_DOT NK_STAR */
+ case 398: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==398);
+{ yylhsminor.yy686 = createColumnNode(pCxt, &yymsp[-2].minor.yy113, &yymsp[0].minor.yy0); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
+ break;
+ case 342: /* predicate ::= expression compare_op expression */
+ case 347: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==347);
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy136, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy632, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 347: /* predicate ::= expression BETWEEN expression AND expression */
+ case 343: /* predicate ::= expression BETWEEN expression AND expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy636), releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy686), releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-4].minor.yy636 = yylhsminor.yy636;
+ yymsp[-4].minor.yy686 = yylhsminor.yy686;
break;
- case 348: /* predicate ::= expression NOT BETWEEN expression AND expression */
+ case 344: /* predicate ::= expression NOT BETWEEN expression AND expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy636), releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy686), releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-5].minor.yy636 = yylhsminor.yy636;
+ yymsp[-5].minor.yy686 = yylhsminor.yy686;
break;
- case 349: /* predicate ::= expression IS NULL */
+ case 345: /* predicate ::= expression IS NULL */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), NULL));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), NULL));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 350: /* predicate ::= expression IS NOT NULL */
+ case 346: /* predicate ::= expression IS NOT NULL */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy636), NULL));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy686), NULL));
}
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
- case 352: /* compare_op ::= NK_LT */
-{ yymsp[0].minor.yy136 = OP_TYPE_LOWER_THAN; }
+ case 348: /* compare_op ::= NK_LT */
+{ yymsp[0].minor.yy632 = OP_TYPE_LOWER_THAN; }
break;
- case 353: /* compare_op ::= NK_GT */
-{ yymsp[0].minor.yy136 = OP_TYPE_GREATER_THAN; }
+ case 349: /* compare_op ::= NK_GT */
+{ yymsp[0].minor.yy632 = OP_TYPE_GREATER_THAN; }
break;
- case 354: /* compare_op ::= NK_LE */
-{ yymsp[0].minor.yy136 = OP_TYPE_LOWER_EQUAL; }
+ case 350: /* compare_op ::= NK_LE */
+{ yymsp[0].minor.yy632 = OP_TYPE_LOWER_EQUAL; }
break;
- case 355: /* compare_op ::= NK_GE */
-{ yymsp[0].minor.yy136 = OP_TYPE_GREATER_EQUAL; }
+ case 351: /* compare_op ::= NK_GE */
+{ yymsp[0].minor.yy632 = OP_TYPE_GREATER_EQUAL; }
break;
- case 356: /* compare_op ::= NK_NE */
-{ yymsp[0].minor.yy136 = OP_TYPE_NOT_EQUAL; }
+ case 352: /* compare_op ::= NK_NE */
+{ yymsp[0].minor.yy632 = OP_TYPE_NOT_EQUAL; }
break;
- case 357: /* compare_op ::= NK_EQ */
-{ yymsp[0].minor.yy136 = OP_TYPE_EQUAL; }
+ case 353: /* compare_op ::= NK_EQ */
+{ yymsp[0].minor.yy632 = OP_TYPE_EQUAL; }
break;
- case 358: /* compare_op ::= LIKE */
-{ yymsp[0].minor.yy136 = OP_TYPE_LIKE; }
+ case 354: /* compare_op ::= LIKE */
+{ yymsp[0].minor.yy632 = OP_TYPE_LIKE; }
break;
- case 359: /* compare_op ::= NOT LIKE */
-{ yymsp[-1].minor.yy136 = OP_TYPE_NOT_LIKE; }
+ case 355: /* compare_op ::= NOT LIKE */
+{ yymsp[-1].minor.yy632 = OP_TYPE_NOT_LIKE; }
break;
- case 360: /* compare_op ::= MATCH */
-{ yymsp[0].minor.yy136 = OP_TYPE_MATCH; }
+ case 356: /* compare_op ::= MATCH */
+{ yymsp[0].minor.yy632 = OP_TYPE_MATCH; }
break;
- case 361: /* compare_op ::= NMATCH */
-{ yymsp[0].minor.yy136 = OP_TYPE_NMATCH; }
+ case 357: /* compare_op ::= NMATCH */
+{ yymsp[0].minor.yy632 = OP_TYPE_NMATCH; }
break;
- case 362: /* compare_op ::= CONTAINS */
-{ yymsp[0].minor.yy136 = OP_TYPE_JSON_CONTAINS; }
+ case 358: /* compare_op ::= CONTAINS */
+{ yymsp[0].minor.yy632 = OP_TYPE_JSON_CONTAINS; }
break;
- case 363: /* in_op ::= IN */
-{ yymsp[0].minor.yy136 = OP_TYPE_IN; }
+ case 359: /* in_op ::= IN */
+{ yymsp[0].minor.yy632 = OP_TYPE_IN; }
break;
- case 364: /* in_op ::= NOT IN */
-{ yymsp[-1].minor.yy136 = OP_TYPE_NOT_IN; }
+ case 360: /* in_op ::= NOT IN */
+{ yymsp[-1].minor.yy632 = OP_TYPE_NOT_IN; }
break;
- case 365: /* in_predicate_value ::= NK_LP expression_list NK_RP */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy236)); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 361: /* in_predicate_value ::= NK_LP expression_list NK_RP */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy670)); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 367: /* boolean_value_expression ::= NOT boolean_primary */
+ case 363: /* boolean_value_expression ::= NOT boolean_primary */
{
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy636), NULL));
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy686), NULL));
}
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 368: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */
+ case 364: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 369: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */
+ case 365: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */
{
- SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy636);
- SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy636);
- yylhsminor.yy636 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), releaseRawExprNode(pCxt, yymsp[0].minor.yy636)));
+ SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy686);
+ SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy686);
+ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), releaseRawExprNode(pCxt, yymsp[0].minor.yy686)));
}
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 376: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */
-{ yylhsminor.yy636 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy636, yymsp[0].minor.yy636, NULL); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 372: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */
+{ yylhsminor.yy686 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy686, yymsp[0].minor.yy686, NULL); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 379: /* table_primary ::= table_name alias_opt */
-{ yylhsminor.yy636 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy53, &yymsp[0].minor.yy53); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ case 375: /* table_primary ::= table_name alias_opt */
+{ yylhsminor.yy686 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy113, &yymsp[0].minor.yy113); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 380: /* table_primary ::= db_name NK_DOT table_name alias_opt */
-{ yylhsminor.yy636 = createRealTableNode(pCxt, &yymsp[-3].minor.yy53, &yymsp[-1].minor.yy53, &yymsp[0].minor.yy53); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+ case 376: /* table_primary ::= db_name NK_DOT table_name alias_opt */
+{ yylhsminor.yy686 = createRealTableNode(pCxt, &yymsp[-3].minor.yy113, &yymsp[-1].minor.yy113, &yymsp[0].minor.yy113); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
- case 381: /* table_primary ::= subquery alias_opt */
-{ yylhsminor.yy636 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy636), &yymsp[0].minor.yy53); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ case 377: /* table_primary ::= subquery alias_opt */
+{ yylhsminor.yy686 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy686), &yymsp[0].minor.yy113); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 383: /* alias_opt ::= */
-{ yymsp[1].minor.yy53 = nil_token; }
+ case 379: /* alias_opt ::= */
+{ yymsp[1].minor.yy113 = nil_token; }
break;
- case 384: /* alias_opt ::= table_alias */
-{ yylhsminor.yy53 = yymsp[0].minor.yy53; }
- yymsp[0].minor.yy53 = yylhsminor.yy53;
+ case 380: /* alias_opt ::= table_alias */
+{ yylhsminor.yy113 = yymsp[0].minor.yy113; }
+ yymsp[0].minor.yy113 = yylhsminor.yy113;
break;
- case 385: /* alias_opt ::= AS table_alias */
-{ yymsp[-1].minor.yy53 = yymsp[0].minor.yy53; }
+ case 381: /* alias_opt ::= AS table_alias */
+{ yymsp[-1].minor.yy113 = yymsp[0].minor.yy113; }
break;
- case 386: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */
- case 387: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==387);
-{ yymsp[-2].minor.yy636 = yymsp[-1].minor.yy636; }
+ case 382: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */
+ case 383: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==383);
+{ yymsp[-2].minor.yy686 = yymsp[-1].minor.yy686; }
break;
- case 388: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */
-{ yylhsminor.yy636 = createJoinTableNode(pCxt, yymsp[-4].minor.yy342, yymsp[-5].minor.yy636, yymsp[-2].minor.yy636, yymsp[0].minor.yy636); }
- yymsp[-5].minor.yy636 = yylhsminor.yy636;
+ case 384: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */
+{ yylhsminor.yy686 = createJoinTableNode(pCxt, yymsp[-4].minor.yy120, yymsp[-5].minor.yy686, yymsp[-2].minor.yy686, yymsp[0].minor.yy686); }
+ yymsp[-5].minor.yy686 = yylhsminor.yy686;
break;
- case 389: /* join_type ::= */
-{ yymsp[1].minor.yy342 = JOIN_TYPE_INNER; }
+ case 385: /* join_type ::= */
+{ yymsp[1].minor.yy120 = JOIN_TYPE_INNER; }
break;
- case 390: /* join_type ::= INNER */
-{ yymsp[0].minor.yy342 = JOIN_TYPE_INNER; }
+ case 386: /* join_type ::= INNER */
+{ yymsp[0].minor.yy120 = JOIN_TYPE_INNER; }
break;
- case 391: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */
+ case 387: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt twindow_clause_opt group_by_clause_opt having_clause_opt */
{
- yymsp[-8].minor.yy636 = createSelectStmt(pCxt, yymsp[-7].minor.yy603, yymsp[-6].minor.yy236, yymsp[-5].minor.yy636);
- yymsp[-8].minor.yy636 = addWhereClause(pCxt, yymsp[-8].minor.yy636, yymsp[-4].minor.yy636);
- yymsp[-8].minor.yy636 = addPartitionByClause(pCxt, yymsp[-8].minor.yy636, yymsp[-3].minor.yy236);
- yymsp[-8].minor.yy636 = addWindowClauseClause(pCxt, yymsp[-8].minor.yy636, yymsp[-2].minor.yy636);
- yymsp[-8].minor.yy636 = addGroupByClause(pCxt, yymsp[-8].minor.yy636, yymsp[-1].minor.yy236);
- yymsp[-8].minor.yy636 = addHavingClause(pCxt, yymsp[-8].minor.yy636, yymsp[0].minor.yy636);
+ yymsp[-8].minor.yy686 = createSelectStmt(pCxt, yymsp[-7].minor.yy131, yymsp[-6].minor.yy670, yymsp[-5].minor.yy686);
+ yymsp[-8].minor.yy686 = addWhereClause(pCxt, yymsp[-8].minor.yy686, yymsp[-4].minor.yy686);
+ yymsp[-8].minor.yy686 = addPartitionByClause(pCxt, yymsp[-8].minor.yy686, yymsp[-3].minor.yy670);
+ yymsp[-8].minor.yy686 = addWindowClauseClause(pCxt, yymsp[-8].minor.yy686, yymsp[-2].minor.yy686);
+ yymsp[-8].minor.yy686 = addGroupByClause(pCxt, yymsp[-8].minor.yy686, yymsp[-1].minor.yy670);
+ yymsp[-8].minor.yy686 = addHavingClause(pCxt, yymsp[-8].minor.yy686, yymsp[0].minor.yy686);
}
break;
- case 394: /* set_quantifier_opt ::= ALL */
-{ yymsp[0].minor.yy603 = false; }
+ case 390: /* set_quantifier_opt ::= ALL */
+{ yymsp[0].minor.yy131 = false; }
break;
- case 395: /* select_list ::= NK_STAR */
-{ yymsp[0].minor.yy236 = NULL; }
+ case 391: /* select_list ::= NK_STAR */
+{ yymsp[0].minor.yy670 = NULL; }
break;
- case 400: /* select_item ::= common_expression column_alias */
-{ yylhsminor.yy636 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy636), &yymsp[0].minor.yy53); }
- yymsp[-1].minor.yy636 = yylhsminor.yy636;
+ case 396: /* select_item ::= common_expression column_alias */
+{ yylhsminor.yy686 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy686), &yymsp[0].minor.yy113); }
+ yymsp[-1].minor.yy686 = yylhsminor.yy686;
break;
- case 401: /* select_item ::= common_expression AS column_alias */
-{ yylhsminor.yy636 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), &yymsp[0].minor.yy53); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 397: /* select_item ::= common_expression AS column_alias */
+{ yylhsminor.yy686 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), &yymsp[0].minor.yy113); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 406: /* partition_by_clause_opt ::= PARTITION BY expression_list */
- case 423: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==423);
- case 435: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==435);
-{ yymsp[-2].minor.yy236 = yymsp[0].minor.yy236; }
+ case 402: /* partition_by_clause_opt ::= PARTITION BY expression_list */
+ case 419: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==419);
+ case 431: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==431);
+{ yymsp[-2].minor.yy670 = yymsp[0].minor.yy670; }
break;
- case 408: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */
-{ yymsp[-5].minor.yy636 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy636), releaseRawExprNode(pCxt, yymsp[-1].minor.yy636)); }
+ case 404: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */
+{ yymsp[-5].minor.yy686 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy686), releaseRawExprNode(pCxt, yymsp[-1].minor.yy686)); }
break;
- case 409: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */
-{ yymsp[-3].minor.yy636 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy636)); }
+ case 405: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */
+{ yymsp[-3].minor.yy686 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy686)); }
break;
- case 410: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */
-{ yymsp[-5].minor.yy636 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy636), NULL, yymsp[-1].minor.yy636, yymsp[0].minor.yy636); }
+ case 406: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */
+{ yymsp[-5].minor.yy686 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy686), NULL, yymsp[-1].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 411: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */
-{ yymsp[-7].minor.yy636 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy636), releaseRawExprNode(pCxt, yymsp[-3].minor.yy636), yymsp[-1].minor.yy636, yymsp[0].minor.yy636); }
+ case 407: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */
+{ yymsp[-7].minor.yy686 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy686), releaseRawExprNode(pCxt, yymsp[-3].minor.yy686), yymsp[-1].minor.yy686, yymsp[0].minor.yy686); }
break;
- case 413: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */
-{ yymsp[-3].minor.yy636 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy636); }
+ case 409: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */
+{ yymsp[-3].minor.yy686 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy686); }
break;
- case 415: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */
-{ yymsp[-3].minor.yy636 = createFillNode(pCxt, yymsp[-1].minor.yy18, NULL); }
+ case 411: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */
+{ yymsp[-3].minor.yy686 = createFillNode(pCxt, yymsp[-1].minor.yy522, NULL); }
break;
- case 416: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */
-{ yymsp[-5].minor.yy636 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy236)); }
+ case 412: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */
+{ yymsp[-5].minor.yy686 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy670)); }
break;
- case 417: /* fill_mode ::= NONE */
-{ yymsp[0].minor.yy18 = FILL_MODE_NONE; }
+ case 413: /* fill_mode ::= NONE */
+{ yymsp[0].minor.yy522 = FILL_MODE_NONE; }
break;
- case 418: /* fill_mode ::= PREV */
-{ yymsp[0].minor.yy18 = FILL_MODE_PREV; }
+ case 414: /* fill_mode ::= PREV */
+{ yymsp[0].minor.yy522 = FILL_MODE_PREV; }
break;
- case 419: /* fill_mode ::= NULL */
-{ yymsp[0].minor.yy18 = FILL_MODE_NULL; }
+ case 415: /* fill_mode ::= NULL */
+{ yymsp[0].minor.yy522 = FILL_MODE_NULL; }
break;
- case 420: /* fill_mode ::= LINEAR */
-{ yymsp[0].minor.yy18 = FILL_MODE_LINEAR; }
+ case 416: /* fill_mode ::= LINEAR */
+{ yymsp[0].minor.yy522 = FILL_MODE_LINEAR; }
break;
- case 421: /* fill_mode ::= NEXT */
-{ yymsp[0].minor.yy18 = FILL_MODE_NEXT; }
+ case 417: /* fill_mode ::= NEXT */
+{ yymsp[0].minor.yy522 = FILL_MODE_NEXT; }
break;
- case 424: /* group_by_list ::= expression */
-{ yylhsminor.yy236 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy636))); }
- yymsp[0].minor.yy236 = yylhsminor.yy236;
+ case 420: /* group_by_list ::= expression */
+{ yylhsminor.yy670 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy686))); }
+ yymsp[0].minor.yy670 = yylhsminor.yy670;
break;
- case 425: /* group_by_list ::= group_by_list NK_COMMA expression */
-{ yylhsminor.yy236 = addNodeToList(pCxt, yymsp[-2].minor.yy236, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy636))); }
- yymsp[-2].minor.yy236 = yylhsminor.yy236;
+ case 421: /* group_by_list ::= group_by_list NK_COMMA expression */
+{ yylhsminor.yy670 = addNodeToList(pCxt, yymsp[-2].minor.yy670, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy686))); }
+ yymsp[-2].minor.yy670 = yylhsminor.yy670;
break;
- case 428: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */
+ case 424: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */
{
- yylhsminor.yy636 = addOrderByClause(pCxt, yymsp[-3].minor.yy636, yymsp[-2].minor.yy236);
- yylhsminor.yy636 = addSlimitClause(pCxt, yylhsminor.yy636, yymsp[-1].minor.yy636);
- yylhsminor.yy636 = addLimitClause(pCxt, yylhsminor.yy636, yymsp[0].minor.yy636);
+ yylhsminor.yy686 = addOrderByClause(pCxt, yymsp[-3].minor.yy686, yymsp[-2].minor.yy670);
+ yylhsminor.yy686 = addSlimitClause(pCxt, yylhsminor.yy686, yymsp[-1].minor.yy686);
+ yylhsminor.yy686 = addLimitClause(pCxt, yylhsminor.yy686, yymsp[0].minor.yy686);
}
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
- case 430: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */
-{ yylhsminor.yy636 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy636, yymsp[0].minor.yy636); }
- yymsp[-3].minor.yy636 = yylhsminor.yy636;
+ case 426: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */
+{ yylhsminor.yy686 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy686, yymsp[0].minor.yy686); }
+ yymsp[-3].minor.yy686 = yylhsminor.yy686;
break;
- case 431: /* query_expression_body ::= query_expression_body UNION query_expression_body */
-{ yylhsminor.yy636 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy636, yymsp[0].minor.yy636); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 427: /* query_expression_body ::= query_expression_body UNION query_expression_body */
+{ yylhsminor.yy686 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy686, yymsp[0].minor.yy686); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 433: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */
-{ yymsp[-5].minor.yy636 = yymsp[-4].minor.yy636; }
- yy_destructor(yypParser,353,&yymsp[-3].minor);
- yy_destructor(yypParser,354,&yymsp[-2].minor);
- yy_destructor(yypParser,355,&yymsp[-1].minor);
+ case 429: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */
+{ yymsp[-5].minor.yy686 = yymsp[-4].minor.yy686; }
+ yy_destructor(yypParser,349,&yymsp[-3].minor);
+ yy_destructor(yypParser,350,&yymsp[-2].minor);
+ yy_destructor(yypParser,351,&yymsp[-1].minor);
break;
- case 437: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */
- case 441: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==441);
-{ yymsp[-1].minor.yy636 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); }
+ case 433: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */
+ case 437: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==437);
+{ yymsp[-1].minor.yy686 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); }
break;
- case 438: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */
- case 442: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==442);
-{ yymsp[-3].minor.yy636 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); }
+ case 434: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */
+ case 438: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==438);
+{ yymsp[-3].minor.yy686 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); }
break;
- case 439: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */
- case 443: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==443);
-{ yymsp[-3].minor.yy636 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); }
+ case 435: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */
+ case 439: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==439);
+{ yymsp[-3].minor.yy686 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); }
break;
- case 444: /* subquery ::= NK_LP query_expression NK_RP */
-{ yylhsminor.yy636 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy636); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 440: /* subquery ::= NK_LP query_expression NK_RP */
+{ yylhsminor.yy686 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy686); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 448: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */
-{ yylhsminor.yy636 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy636), yymsp[-1].minor.yy430, yymsp[0].minor.yy185); }
- yymsp[-2].minor.yy636 = yylhsminor.yy636;
+ case 444: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */
+{ yylhsminor.yy686 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy686), yymsp[-1].minor.yy428, yymsp[0].minor.yy109); }
+ yymsp[-2].minor.yy686 = yylhsminor.yy686;
break;
- case 449: /* ordering_specification_opt ::= */
-{ yymsp[1].minor.yy430 = ORDER_ASC; }
+ case 445: /* ordering_specification_opt ::= */
+{ yymsp[1].minor.yy428 = ORDER_ASC; }
break;
- case 450: /* ordering_specification_opt ::= ASC */
-{ yymsp[0].minor.yy430 = ORDER_ASC; }
+ case 446: /* ordering_specification_opt ::= ASC */
+{ yymsp[0].minor.yy428 = ORDER_ASC; }
break;
- case 451: /* ordering_specification_opt ::= DESC */
-{ yymsp[0].minor.yy430 = ORDER_DESC; }
+ case 447: /* ordering_specification_opt ::= DESC */
+{ yymsp[0].minor.yy428 = ORDER_DESC; }
break;
- case 452: /* null_ordering_opt ::= */
-{ yymsp[1].minor.yy185 = NULL_ORDER_DEFAULT; }
+ case 448: /* null_ordering_opt ::= */
+{ yymsp[1].minor.yy109 = NULL_ORDER_DEFAULT; }
break;
- case 453: /* null_ordering_opt ::= NULLS FIRST */
-{ yymsp[-1].minor.yy185 = NULL_ORDER_FIRST; }
+ case 449: /* null_ordering_opt ::= NULLS FIRST */
+{ yymsp[-1].minor.yy109 = NULL_ORDER_FIRST; }
break;
- case 454: /* null_ordering_opt ::= NULLS LAST */
-{ yymsp[-1].minor.yy185 = NULL_ORDER_LAST; }
+ case 450: /* null_ordering_opt ::= NULLS LAST */
+{ yymsp[-1].minor.yy109 = NULL_ORDER_LAST; }
break;
default:
break;
/********** End reduce actions ************************************************/
};
- assert( yyrulenocatalogGetDBVgInfo(dbFName, pVgList);
}
int32_t __catalogGetDBCfg(SCatalog* pCtg, void* pRpc, const SEpSet* pMgmtEps, const char* dbFName, SDbCfgInfo* pDbCfg) {
diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp
index 566c4d8b04c0127e04ef9ce0fb0b5eabae7d25da..4834d2d37711d537d09d0e1b12e2bd8dc9697827 100644
--- a/source/libs/parser/test/mockCatalogService.cpp
+++ b/source/libs/parser/test/mockCatalogService.cpp
@@ -18,6 +18,7 @@
#include
#include
#include