diff --git a/cmake/cmake.version b/cmake/cmake.version index fcb31adc39..2d86335b3c 100644 --- a/cmake/cmake.version +++ b/cmake/cmake.version @@ -2,7 +2,7 @@ IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "3.0.1.2") + SET(TD_VER_NUMBER "3.0.1.3") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in index 448c2b99c0..5d2fcf27b2 100644 --- a/cmake/taostools_CMakeLists.txt.in +++ b/cmake/taostools_CMakeLists.txt.in @@ -2,7 +2,7 @@ # taos-tools ExternalProject_Add(taos-tools GIT_REPOSITORY https://github.com/taosdata/taos-tools.git - GIT_TAG f03c09a + GIT_TAG 70f5a1c SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools" BINARY_DIR "" #BUILD_IN_SOURCE TRUE diff --git a/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx index 11db3daeb0..c91dbba5d2 100644 --- a/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx +++ b/docs/en/07-develop/03-insert-data/02-influxdb-line.mdx @@ -37,7 +37,8 @@ meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0 - All the data in `tag_set` will be converted to nchar type automatically . - Each data in `field_set` must be self-descriptive for its data type. For example 1.2f32 means a value 1.2 of float type. Without the "f" type suffix, it will be treated as type double. - Multiple kinds of precision can be used for the `timestamp` field. Time precision can be from nanosecond (ns) to hour (h). - +- You can configure smlChildTableName in taos.cfg to specify table names, for example, `smlChildTableName=tname`. You can insert `st,tname=cpul,t1=4 c1=3 1626006833639000000` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored. +- It is assumed that the order of field_set in a supertable is consistent, meaning that the first record contains all fields and subsequent records store fields in the same order. If the order is not consistent, set smlDataFormat in taos.cfg to false. Otherwise, data will be written out of order and a database error will occur.(smlDataFormat in taos.cfg default to false after version of 3.0.1.3) ::: For more details please refer to [InfluxDB Line Protocol](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) and [TDengine Schemaless](/reference/schemaless/#Schemaless-Line-Protocol) @@ -64,3 +65,7 @@ For more details please refer to [InfluxDB Line Protocol](https://docs.influxdat + +## Query Examples +If you want query the data of `location=California.LosAngeles,groupid=2`,here is the query sql: +select * from `meters.voltage` where location="California.LosAngeles" and groupid=2 diff --git a/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx index db9bfd7364..d88a6335cb 100644 --- a/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx +++ b/docs/en/07-develop/03-insert-data/03-opentsdb-telnet.mdx @@ -31,7 +31,7 @@ For example: ```txt meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3 ``` - +- The defult child table name is generated by rules.You can configure smlChildTableName in taos.cfg to specify chile table names, for example, `smlChildTableName=tname`. You can insert `meters.current 1648432611250 11.3 tname=cpu1 location=California.LosAngeles groupid=3` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored. Please refer to [OpenTSDB Telnet API](http://opentsdb.net/docs/build/html/api_telnet/put.html) for more details. ## Examples @@ -79,3 +79,6 @@ taos> select tbname, * from `meters.current`; t_7e7b26dd860280242c6492a16... | 2022-03-28 09:56:51.250 | 12.600000000 | 2 | California.SanFrancisco | Query OK, 4 row(s) in set (0.005399s) ``` +## Query Examples +If you want query the data of `location=California.LosAngeles groupid=3`,here is the query sql: +select * from `meters.voltage` where location="California.LosAngeles" and groupid=3 diff --git a/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx index 23703f4087..e2e6d6fc9f 100644 --- a/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx +++ b/docs/en/07-develop/03-insert-data/04-opentsdb-json.mdx @@ -48,7 +48,7 @@ Please refer to [OpenTSDB HTTP API](http://opentsdb.net/docs/build/html/api_http - In JSON protocol, strings will be converted to nchar type and numeric values will be converted to double type. - Only data in array format is accepted and so an array must be used even if there is only one row. - +- The defult child table name is generated by rules.You can configure smlChildTableName in taos.cfg to specify chile table names, for example, `smlChildTableName=tname`. You can insert `"tags": { "host": "web02","dc": "lga","tname":"cpu1"}` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored. ::: ## Examples @@ -94,3 +94,6 @@ taos> select * from `meters.current`; 2022-03-28 09:56:51.250 | 12.600000000 | 2.000000000 | California.SanFrancisco | Query OK, 2 row(s) in set (0.004076s) ``` +## Query Examples +If you want query the data of "tags": {"location": "California.LosAngeles", "groupid": 1},here is the query sql: +select * from `meters.voltage` where location="California.LosAngeles" and groupid=1 diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index 14dedfb216..243ede5fcb 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -867,6 +867,7 @@ INTERP(expr) - 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. - Interpolation is performed based on `FILL` parameter. - `INTERP` can only be used to interpolate in single timeline. So it must be used with `partition by tbname` when it's used on a STable. +- Pseudo column `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.1.4). ### LAST diff --git a/docs/en/12-taos-sql/22-meta.md b/docs/en/12-taos-sql/22-meta.md index 9bda5a0a10..0a59777946 100644 --- a/docs/en/12-taos-sql/22-meta.md +++ b/docs/en/12-taos-sql/22-meta.md @@ -11,7 +11,15 @@ TDengine includes a built-in database named `INFORMATION_SCHEMA` to provide acce 4. Future versions of TDengine can add new columns to INFORMATION_SCHEMA tables without affecting existing business systems. 5. It is easier for users coming from other database management systems. For example, Oracle users can query data dictionary tables. -Note: SHOW statements are still supported for the convenience of existing users. +:::info + +- SHOW statements are still supported for the convenience of existing users. +- Some columns in the system table may be keywords, and you need to use the escape character '\`' when querying, for example, to query the VGROUPS in the database `test`: +```sql + select `vgroups` from ins_databases where name = 'test'; +``` + +::: This document introduces the tables of INFORMATION_SCHEMA and their structure. @@ -102,7 +110,11 @@ Provides information about user-created databases. Similar to SHOW DATABASES. | 24 | wal_retention_period | INT | WAL retention period | | 25 | wal_retention_size | INT | Maximum WAL size | | 26 | wal_roll_period | INT | WAL rotation period | -| 27 | wal_segment_size | WAL file size | +| 27 | wal_segment_size | BIGINT | WAL file size | +| 28 | stt_trigger | SMALLINT | The threshold for number of files to trigger file merging | +| 29 | table_prefix | SMALLINT | The prefix length in the table name that is ignored when distributing table to vnode based on table name | +| 30 | table_suffix | SMALLINT | The suffix length in the table name that is ignored when distributing table to vnode based on table name | +| 31 | tsdb_pagesize | INT | The page size for internal storage engine, its unit is KB | ## INS_FUNCTIONS diff --git a/docs/en/14-reference/12-config/index.md b/docs/en/14-reference/12-config/index.md index 5ab6f59454..726a1ccd69 100644 --- a/docs/en/14-reference/12-config/index.md +++ b/docs/en/14-reference/12-config/index.md @@ -177,12 +177,21 @@ The parameters described in this document by the effect that they have on the sy ### maxNumOfDistinctRes | Attribute | Description | -| -------- | -------------------------------- | --- | +| -------- | -------------------------------- | | Applicable | Server Only | | Meaning | The maximum number of distinct rows returned | | Value Range | [100,000 - 100,000,000] | | Default Value | 100,000 | +### keepColumnName + +| Attribute | Description | +| -------- | -------------------------------- | +| Applicable | Client only | +| Meaning | When the Last, First, LastRow function is queried, whether the returned column name contains the function name. | +| Value Range | 0 means including the function name, 1 means not including the function name. | +| Default Value | 0 | + ## Locale Parameters ### timezone diff --git a/docs/en/14-reference/13-schemaless/13-schemaless.md b/docs/en/14-reference/13-schemaless/13-schemaless.md index 4f50c38cbb..5b7924ce56 100644 --- a/docs/en/14-reference/13-schemaless/13-schemaless.md +++ b/docs/en/14-reference/13-schemaless/13-schemaless.md @@ -47,9 +47,8 @@ In the schemaless writing data line protocol, each data item in the field_set ne - `t`, `T`, `true`, `True`, `TRUE`, `f`, `F`, `false`, and `False` will be handled directly as BOOL types. -For example, the following data rows indicate that the t1 label is "3" (NCHAR), the t2 label is "4" (NCHAR), and the t3 label -is "t3" to the super table named `st` labeled "t3" (NCHAR), write c1 column as 3 (BIGINT), c2 column as false (BOOL), c3 column -is "passit" (BINARY), c4 column is 4 (DOUBLE), and the primary key timestamp is 1626006833639000000 in one row. +For example, the following data rows write c1 column as 3 (BIGINT), c2 column as false (BOOL), c3 column +as "passit" (BINARY), c4 column as 4 (DOUBLE), and the primary key timestamp as 1626006833639000000 to child table with the t1 label as "3" (NCHAR), the t2 label as "4" (NCHAR), and the t3 label as "t3" (NCHAR) and the super table named `st`. ```json st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000 @@ -69,7 +68,7 @@ Schemaless writes process row data according to the following principles. Note that tag_key1, tag_key2 are not the original order of the tags entered by the user but the result of using the tag names in ascending order of the strings. Therefore, tag_key1 is not the first tag entered in the line protocol. The string's MD5 hash value "md5_val" is calculated after the ranking is completed. The calculation result is then combined with the string to generate the table name: "t_md5_val". "t_" is a fixed prefix that every table generated by this mapping relationship has. -You can configure smlChildTableName to specify table names, for example, `smlChildTableName=tname`. You can insert `st,tname=cpul,t1=4 c1=3 1626006833639000000` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored. +You can configure smlChildTableName in taos.cfg to specify table names, for example, `smlChildTableName=tname`. You can insert `st,tname=cpul,t1=4 c1=3 1626006833639000000` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored. 2. If the super table obtained by parsing the line protocol does not exist, this super table is created. 3. If the subtable obtained by the parse line protocol does not exist, Schemaless creates the sub-table according to the subtable name determined in steps 1 or 2. @@ -78,7 +77,7 @@ You can configure smlChildTableName to specify table names, for example, `smlChi NULL. 6. For BINARY or NCHAR columns, if the length of the value provided in a data row exceeds the column type limit, the maximum length of characters allowed to be stored in the column is automatically increased (only incremented and not decremented) to ensure complete preservation of the data. 7. Errors encountered throughout the processing will interrupt the writing process and return an error code. -8. It is assumed that the order of field_set in a supertable is consistent, meaning that the first record contains all fields and subsequent records store fields in the same order. If the order is not consistent, set smlDataFormat to false. Otherwise, data will be written out of order and a database error will occur. +8. It is assumed that the order of field_set in a supertable is consistent, meaning that the first record contains all fields and subsequent records store fields in the same order. If the order is not consistent, set smlDataFormat in taos.cfg to false. Otherwise, data will be written out of order and a database error will occur.(smlDataFormat in taos.cfg default to false after version of 3.0.1.3) :::tip All processing logic of schemaless will still follow TDengine's underlying restrictions on data structures, such as the total length of each row of data cannot exceed diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index 414986d107..a65a2fff63 100644 --- a/docs/en/28-releases/01-tdengine.md +++ b/docs/en/28-releases/01-tdengine.md @@ -6,6 +6,10 @@ description: TDengine release history, Release Notes and download links. import Release from "/components/ReleaseV3"; +## 3.0.1.3 + + + ## 3.0.1.2 diff --git a/docs/en/28-releases/02-tools.md b/docs/en/28-releases/02-tools.md index 086d3adea2..a83723bff7 100644 --- a/docs/en/28-releases/02-tools.md +++ b/docs/en/28-releases/02-tools.md @@ -6,6 +6,10 @@ description: taosTools release history, Release Notes, download links. import Release from "/components/ReleaseV3"; +## 2.2.3 + + + ## 2.2.2 diff --git a/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx b/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx index f88284ad67..a107ffb1b6 100644 --- a/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx +++ b/docs/zh/07-develop/03-insert-data/02-influxdb-line.mdx @@ -37,7 +37,9 @@ meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0 - tag_set 中的所有的数据自动转化为 nchar 数据类型; - field_set 中的每个数据项都需要对自身的数据类型进行描述, 比如 1.2f32 代表 float 类型的数值 1.2, 如果不带类型后缀会被当作 double 处理; - timestamp 支持多种时间精度。写入数据的时候需要用参数指定时间精度,支持从小时到纳秒的 6 种时间精度。 - +- 为了提高写入的效率,默认假设同一个超级表中 field_set 的顺序是一样的(第一条数据包含所有的 field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数 smlDataFormat 为 false,否则,数据写入按照相同顺序写入,库中数据会异常。(3.0.1.3之后的版本 smlDataFormat 默认为 false) [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) +- 默认生产的子表名是根据规则生成的唯一ID值。为了让用户可以指定生成的表名,可以通过在taos.cfg里配置 smlChildTableName 参数来指定。 +举例如下:配置 smlChildTableName=tname 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) ::: 要了解更多可参考:[InfluxDB Line 协议官方文档](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) 和 [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) @@ -64,3 +66,7 @@ meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0 + +## 查询示例 +比如查询 location=California.LosAngeles,groupid=2 子表的数据可以通过如下sql: +select * from meters where location=California.LosAngeles and groupid=2 diff --git a/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx b/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx index 4f63e17635..58bca7f843 100644 --- a/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx +++ b/docs/zh/07-develop/03-insert-data/03-opentsdb-telnet.mdx @@ -32,6 +32,8 @@ OpenTSDB 行协议同样采用一行字符串来表示一行数据。OpenTSDB meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3 ``` +- 默认生产的子表名是根据规则生成的唯一ID值。为了让用户可以指定生成的表名,可以通过在taos.cfg里配置 smlChildTableName 参数来指定。 +举例如下:配置 smlChildTableName=tname 插入数据为 meters.current 1648432611250 11.3 tname=cpu1 location=California.LosAngeles groupid=3 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 参考[OpenTSDB Telnet API 文档](http://opentsdb.net/docs/build/html/api_telnet/put.html)。 ## 示例代码 @@ -79,3 +81,6 @@ taos> select tbname, * from `meters.current`; t_7e7b26dd860280242c6492a16... | 2022-03-28 09:56:51.250 | 12.600000000 | 2 | California.SanFrancisco | Query OK, 4 row(s) in set (0.005399s) ``` +## 查询示例: +想要查询 location=California.LosAngeles groupid=3 的数据,可以通过如下sql: +select * from `meters.voltage` where location="California.LosAngeles" and groupid=3 diff --git a/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx b/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx index b0257b9cb7..aa3e5980cf 100644 --- a/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx +++ b/docs/zh/07-develop/03-insert-data/04-opentsdb-json.mdx @@ -48,7 +48,8 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据 - 对于 JSON 格式协议,TDengine 并不会自动把所有标签转成 nchar 类型, 字符串将将转为 nchar 类型, 数值将同样转换为 double 类型。 - TDengine 只接收 JSON **数组格式**的字符串,即使一行数据也需要转换成数组形式。 - +- 默认生产的子表名是根据规则生成的唯一ID值。为了让用户可以指定生成的表名,可以通过在taos.cfg里配置 smlChildTableName 参数来指定。 +举例如下:配置 smlChildTableName=tname 插入数据为 "tags": { "host": "web02","dc": "lga","tname":"cpu1"} 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 ::: ## 示例代码 @@ -94,3 +95,7 @@ taos> select * from `meters.current`; 2022-03-28 09:56:51.250 | 12.600000000 | 2.000000000 | California.SanFrancisco | Query OK, 2 row(s) in set (0.004076s) ``` + +## 查询示例 +想要查询"tags": {"location": "California.LosAngeles", "groupid": 1} 的数据,可以通过如下sql: +select * from `meters.voltage` where location="California.LosAngeles" and groupid=1 diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md index 2a4d82045f..4c33b5232a 100644 --- a/docs/zh/12-taos-sql/10-function.md +++ b/docs/zh/12-taos-sql/10-function.md @@ -868,6 +868,7 @@ INTERP(expr) - INTERP 根据 EVERY 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(EVERY 值)进行插值。如果没有指定 EVERY,则默认窗口大小为无穷大,即从 timestamp1 开始只有一个窗口。 - INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。 - INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 partition by tbname 一起使用。 +- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.1.4版本以后支持)。 ### LAST diff --git a/docs/zh/12-taos-sql/22-meta.md b/docs/zh/12-taos-sql/22-meta.md index c1ffc4a757..c192d0e5e8 100644 --- a/docs/zh/12-taos-sql/22-meta.md +++ b/docs/zh/12-taos-sql/22-meta.md @@ -12,7 +12,15 @@ TDengine 内置了一个名为 `INFORMATION_SCHEMA` 的数据库,提供对数 4. TDengine 在后续演进中可以灵活的添加已有 INFORMATION_SCHEMA 中表的列,而不用担心对既有业务系统造成影响 5. 与其他数据库系统更具互操作性。例如,Oracle 数据库用户熟悉查询 Oracle 数据字典中的表 -Note: 由于 SHOW 语句已经被开发者熟悉和广泛使用,所以它们仍然被保留。 +:::info + +- 由于 SHOW 语句已经被开发者熟悉和广泛使用,所以它们仍然被保留。 +- 系统表中的一些列可能是关键字,在查询时需要使用转义符'\`',例如查询数据库 test 有几个 VGROUP: +```sql + select `vgroups` from ins_databases where name = 'test'; +``` + +::: 本章将详细介绍 `INFORMATION_SCHEMA` 这个内置元数据库中的表和表结构。 @@ -103,7 +111,11 @@ Note: 由于 SHOW 语句已经被开发者熟悉和广泛使用,所以它们 | 24 | wal_retention_period | INT | WAL 的保存时长 | | 25 | wal_retention_size | INT | WAL 的保存上限 | | 26 | wal_roll_period | INT | wal 文件切换时长 | -| 27 | wal_segment_size | wal 单个文件大小 | +| 27 | wal_segment_size | BIGINT | wal 单个文件大小 | +| 28 | stt_trigger | SMALLINT | 触发文件合并的落盘文件的个数 | +| 29 | table_prefix | SMALLINT | 内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的前缀的长度 | +| 30 | table_suffix | SMALLINT | 内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的后缀的长度 | +| 31 | tsdb_pagesize | INT | 时序数据存储引擎中的页大小 | ## INS_FUNCTIONS diff --git a/docs/zh/14-reference/12-config/index.md b/docs/zh/14-reference/12-config/index.md index 179a3c6df0..6f26878cdd 100644 --- a/docs/zh/14-reference/12-config/index.md +++ b/docs/zh/14-reference/12-config/index.md @@ -177,12 +177,21 @@ taos --dump-config ### maxNumOfDistinctRes | 属性 | 说明 | -| -------- | -------------------------------- | --- | +| -------- | -------------------------------- | | 适用范围 | 仅服务端适用 | | 含义 | 允许返回的 distinct 结果最大行数 | | 取值范围 | 默认值为 10 万,最大值 1 亿 | | 缺省值 | 10 万 | +### keepColumnName + +| 属性 | 说明 | +| -------- | -------------------------------- | +| 适用范围 | 仅客户端适用 | +| 含义 | Last、First、LastRow 函数查询时,返回的列名是否包含函数名。 | +| 取值范围 | 0 表示包含函数名,1 表示不包含函数名。 | +| 缺省值 | 0 | + ## 区域相关 ### timezone diff --git a/docs/zh/14-reference/13-schemaless/13-schemaless.md b/docs/zh/14-reference/13-schemaless/13-schemaless.md index a33abafaf8..07d5b0692b 100644 --- a/docs/zh/14-reference/13-schemaless/13-schemaless.md +++ b/docs/zh/14-reference/13-schemaless/13-schemaless.md @@ -67,9 +67,12 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000 "measurement,tag_key1=tag_value1,tag_key2=tag_value2" ``` +:::tip 需要注意的是,这里的 tag_key1, tag_key2 并不是用户输入的标签的原始顺序,而是使用了标签名称按照字符串升序排列后的结果。所以,tag_key1 并不是在行协议中输入的第一个标签。 排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t_” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。 -为了让用户可以指定生成的表名,可以通过配置 smlChildTableName 来指定(比如 配置 smlChildTableName=tname 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一次自动建表时指定的 tag_set,其他的会忽略)。 +:::tip +为了让用户可以指定生成的表名,可以通过在taos.cfg里配置 smlChildTableName 参数来指定。 +举例如下:配置 smlChildTableName=tname 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 2. 如果解析行协议获得的超级表不存在,则会创建这个超级表(不建议手动创建超级表,不然插入数据可能异常)。 3. 如果解析行协议获得子表不存在,则 Schemaless 会按照步骤 1 或 2 确定的子表名来创建子表。 diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index b05cf7a942..597e98238b 100644 --- a/docs/zh/28-releases/01-tdengine.md +++ b/docs/zh/28-releases/01-tdengine.md @@ -6,6 +6,10 @@ description: TDengine 发布历史、Release Notes 及下载链接 import Release from "/components/ReleaseV3"; +## 3.0.1.3 + + + ## 3.0.1.2 diff --git a/docs/zh/28-releases/02-tools.md b/docs/zh/28-releases/02-tools.md index f793981d06..8604885d3c 100644 --- a/docs/zh/28-releases/02-tools.md +++ b/docs/zh/28-releases/02-tools.md @@ -6,6 +6,10 @@ description: taosTools 的发布历史、Release Notes 和下载链接 import Release from "/components/ReleaseV3"; +## 2.2.3 + + + ## 2.2.2 diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 49db88d703..7aec00c7c1 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -55,11 +55,10 @@ extern int32_t tMsgDict[]; #define TMSG_SEG_CODE(TYPE) (((TYPE)&0xff00) >> 8) #define TMSG_SEG_SEQ(TYPE) ((TYPE)&0xff) -#define TMSG_INFO(TYPE) \ - ((TYPE) >= 0 && ((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || \ - (TYPE) < TDMT_SCH_MAX_MSG || (TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || \ - (TYPE) < TDMT_SYNC_MAX_MSG)) \ - ? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \ +#define TMSG_INFO(TYPE) \ + ((TYPE) < TDMT_DND_MAX_MSG || (TYPE) < TDMT_MND_MAX_MSG || (TYPE) < TDMT_VND_MAX_MSG || (TYPE) < TDMT_SCH_MAX_MSG || \ + (TYPE) < TDMT_STREAM_MAX_MSG || (TYPE) < TDMT_MON_MAX_MSG || (TYPE) < TDMT_SYNC_MAX_MSG) \ + ? tMsgInfo[tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)] \ : 0 #define TMSG_INDEX(TYPE) (tMsgDict[TMSG_SEG_CODE(TYPE)] + TMSG_SEG_SEQ(TYPE)) diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 32249e3d8b..560832cd74 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -239,6 +239,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_FILL, + QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL, QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION, QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index e6e34648f9..25ff18a8fc 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -464,6 +464,8 @@ typedef struct SFillPhysiNode { EOrder inputTsOrder; } SFillPhysiNode; +typedef SFillPhysiNode SStreamFillPhysiNode; + typedef struct SMultiTableIntervalPhysiNode { SIntervalPhysiNode interval; SNodeList* pPartitionKeys; diff --git a/include/libs/stream/streamState.h b/include/libs/stream/streamState.h index 849d83a58b..0adcf976f0 100644 --- a/include/libs/stream/streamState.h +++ b/include/libs/stream/streamState.h @@ -31,6 +31,7 @@ typedef struct { TDB* db; TTB* pStateDb; TTB* pFuncStateDb; + TTB* pFillStateDb; // todo refactor TXN txn; } SStreamState; @@ -51,15 +52,22 @@ int32_t streamStateFuncDel(SStreamState* pState, const STupleKey* key); int32_t streamStatePut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen); int32_t streamStateGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); int32_t streamStateDel(SStreamState* pState, const SWinKey* key); + +int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen); +int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); +int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key); + int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen); int32_t streamStateReleaseBuf(SStreamState* pState, const SWinKey* key, void* pVal); void streamFreeVal(void* val); SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key); -SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key); -SStreamStateCur* streamStateSeekKeyPrev(SStreamState* pState, const SWinKey* key); +SStreamStateCur* streamStateGetAndCheckCur(SStreamState* pState, SWinKey* key); +SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey* key); +SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey* key); void streamStateFreeCur(SStreamStateCur* pCur); +int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen); int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen); int32_t streamStateSeekFirst(SStreamState* pState, SStreamStateCur* pCur); diff --git a/packaging/cfg/nginxd.service b/packaging/cfg/nginxd.service deleted file mode 100644 index 50bbc1a21d..0000000000 --- a/packaging/cfg/nginxd.service +++ /dev/null @@ -1,22 +0,0 @@ -[Unit] -Description=Nginx For TDengine Service -After=network-online.target -Wants=network-online.target - -[Service] -Type=forking -PIDFile=/usr/local/nginxd/logs/nginx.pid -ExecStart=/usr/local/nginxd/sbin/nginx -ExecStop=/usr/local/nginxd/sbin/nginx -s stop -TimeoutStopSec=1000000s -LimitNOFILE=infinity -LimitNPROC=infinity -LimitCORE=infinity -TimeoutStartSec=0 -StandardOutput=null -Restart=always -StartLimitBurst=3 -StartLimitInterval=60s - -[Install] -WantedBy=multi-user.target diff --git a/packaging/check_package.sh b/packaging/check_package.sh index e728c6455a..5c3a2f9267 100644 --- a/packaging/check_package.sh +++ b/packaging/check_package.sh @@ -38,8 +38,6 @@ temp_version="" fin_result="" service_config_dir="/etc/systemd/system" -nginx_port=6060 -nginx_dir="/usr/local/nginxd" # Color setting RED='\033[0;31m' @@ -132,10 +130,7 @@ function check_main_path() { check_file ${install_main_dir} $i done if [ "$verMode" == "cluster" ]; then - nginx_main_dir=("admin" "conf" "html" "sbin" "logs") - for i in "${nginx_main_dir[@]}";do - check_file ${nginx_dir} $i - done + check_file ${install_main_dir} "share/admin" fi echo -e "Check main path:\033[32mOK\033[0m!" } @@ -150,9 +145,6 @@ function check_bin_path() { for i in "${lbin_dir[@]}";do check_link ${bin_link_dir}/$i done - if [ "$verMode" == "cluster" ]; then - check_file ${nginx_dir}/sbin nginx - fi echo -e "Check bin path:\033[32mOK\033[0m!" } diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index 5088e9bdac..9694a89a8f 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -50,8 +50,7 @@ install_main_dir=${installDir} bin_dir="${installDir}/bin" service_config_dir="/etc/systemd/system" -nginx_port=6060 -nginx_dir="/usr/local/nginxd" +web_port=6041 # Color setting RED='\033[0;31m' @@ -182,7 +181,7 @@ function install_main_path() { ${csudo}mkdir -p ${install_main_dir}/include # ${csudo}mkdir -p ${install_main_dir}/init.d if [ "$verMode" == "cluster" ]; then - ${csudo}mkdir -p ${nginx_dir} + ${csudo}mkdir -p ${install_main_dir}/share fi if [[ -e ${script_dir}/email ]]; then @@ -218,12 +217,6 @@ function install_bin() { [ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : [ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - - if [ "$verMode" == "cluster" ]; then - ${csudo}cp -r ${script_dir}/nginxd/* ${nginx_dir} && ${csudo}chmod 0555 ${nginx_dir}/* - ${csudo}mkdir -p ${nginx_dir}/logs - ${csudo}chmod 777 ${nginx_dir}/sbin/nginx - fi } function install_lib() { @@ -574,6 +567,13 @@ function install_examples() { fi } +function install_web() { + if [ -d "${script_dir}/share" ]; then + ${csudo}cp -rf ${script_dir}/share/* ${install_main_dir}/share + fi +} + + function clean_service_on_sysvinit() { if pidof ${serverName} &>/dev/null; then ${csudo}service ${serverName} stop || : @@ -654,16 +654,6 @@ function clean_service_on_systemd() { fi ${csudo}systemctl disable tarbitratord &>/dev/null || echo &>/dev/null ${csudo}rm -f ${tarbitratord_service_config} - - if [ "$verMode" == "cluster" ]; then - nginx_service_config="${service_config_dir}/nginxd.service" - if systemctl is-active --quiet nginxd; then - echo "Nginx for ${productName} is running, stopping it..." - ${csudo}systemctl stop nginxd &>/dev/null || echo &>/dev/null - fi - ${csudo}systemctl disable nginxd &>/dev/null || echo &>/dev/null - ${csudo}rm -f ${nginx_service_config} - fi } function install_service_on_systemd() { @@ -677,19 +667,6 @@ function install_service_on_systemd() { ${csudo}systemctl enable ${serverName} ${csudo}systemctl daemon-reload - - if [ "$verMode" == "cluster" ]; then - [ -f ${script_dir}/cfg/nginxd.service ] && - ${csudo}cp ${script_dir}/cfg/nginxd.service \ - ${service_config_dir}/ || : - ${csudo}systemctl daemon-reload - - if ! ${csudo}systemctl enable nginxd &>/dev/null; then - ${csudo}systemctl daemon-reexec - ${csudo}systemctl enable nginxd - fi - ${csudo}systemctl start nginxd - fi } function install_adapter_service() { @@ -793,19 +770,6 @@ function updateProduct() { sleep 1 fi - if [ "$verMode" == "cluster" ]; then - if pidof nginx &>/dev/null; then - if ((${service_mod} == 0)); then - ${csudo}systemctl stop nginxd || : - elif ((${service_mod} == 1)); then - ${csudo}service nginxd stop || : - else - kill_process nginx - fi - sleep 1 - fi - fi - install_main_path install_log @@ -817,6 +781,7 @@ function updateProduct() { fi install_examples + install_web if [ -z $1 ]; then install_bin install_service @@ -825,18 +790,6 @@ function updateProduct() { install_adapter_config openresty_work=false - if [ "$verMode" == "cluster" ]; then - # Check if openresty is installed - # Check if nginx is installed successfully - if type curl &>/dev/null; then - if curl -sSf http://127.0.0.1:${nginx_port} &>/dev/null; then - echo -e "\033[44;32;1mNginx for ${productName} is updated successfully!${NC}" - openresty_work=true - else - echo -e "\033[44;31;5mNginx for ${productName} does not work! Please try again!\033[0m" - fi - fi - fi echo echo -e "${GREEN_DARK}To configure ${productName} ${NC}: edit ${cfg_install_dir}/${configFile}" @@ -857,7 +810,7 @@ function updateProduct() { fi if [ ${openresty_work} = 'true' ]; then - echo -e "${GREEN_DARK}To access ${productName} ${NC}: use ${GREEN_UNDERLINE}${clientName} -h $serverFqdn${NC} in shell OR from ${GREEN_UNDERLINE}http://127.0.0.1:${nginx_port}${NC}" + echo -e "${GREEN_DARK}To access ${productName} ${NC}: use ${GREEN_UNDERLINE}${clientName} -h $serverFqdn${NC} in shell OR from ${GREEN_UNDERLINE}http://127.0.0.1:${web_port}${NC}" else echo -e "${GREEN_DARK}To access ${productName} ${NC}: use ${GREEN_UNDERLINE}${clientName} -h $serverFqdn${NC} in shell${NC}" fi @@ -906,6 +859,7 @@ function installProduct() { install_connector fi install_examples + install_web if [ -z $1 ]; then # install service and client # For installing new @@ -915,17 +869,6 @@ function installProduct() { install_adapter_config openresty_work=false - if [ "$verMode" == "cluster" ]; then - # Check if nginx is installed successfully - if type curl &>/dev/null; then - if curl -sSf http://127.0.0.1:${nginx_port} &>/dev/null; then - echo -e "\033[44;32;1mNginx for ${productName} is installed successfully!${NC}" - openresty_work=true - else - echo -e "\033[44;31;5mNginx for ${productName} does not work! Please try again!\033[0m" - fi - fi - fi install_config diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index d1e7a222cc..58b4385001 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -151,6 +151,7 @@ function install_main_path() { ${csudo}mkdir -p ${install_main_dir}/driver ${csudo}mkdir -p ${install_main_dir}/examples ${csudo}mkdir -p ${install_main_dir}/include + ${csudo}mkdir -p ${install_main_dir}/share # ${csudo}mkdir -p ${install_main_dir}/init.d else ${csudo}rm -rf ${install_main_dir} || ${csudo}rm -rf ${install_main_2_dir} || : @@ -161,6 +162,7 @@ function install_main_path() { ${csudo}mkdir -p ${install_main_dir}/driver || ${csudo}mkdir -p ${install_main_2_dir}/driver ${csudo}mkdir -p ${install_main_dir}/examples || ${csudo}mkdir -p ${install_main_2_dir}/examples ${csudo}mkdir -p ${install_main_dir}/include || ${csudo}mkdir -p ${install_main_2_dir}/include + ${csudo}mkdir -p ${install_main_dir}/share || ${csudo}mkdir -p ${install_main_2_dir}/share fi } @@ -469,6 +471,16 @@ function install_examples() { fi } +function install_web() { + if [ -d "${binary_dir}/build/share" ]; then + if [ "$osType" != "Darwin" ]; then + ${csudo}cp -rf ${binary_dir}/build/share/* ${install_main_dir}/share || : + else + ${csudo}cp -rf ${binary_dir}/build/share/* ${install_main_dir}/share || ${csudo}cp -rf ${binary_dir}/build/share/* ${install_main_2_dir}/share || : + fi + fi +} + function clean_service_on_sysvinit() { if pidof ${serverName} &>/dev/null; then ${csudo}service ${serverName} stop || : @@ -596,6 +608,7 @@ function update_TDengine() { install_lib # install_connector install_examples + install_web install_bin install_service diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index 2305b96b36..fb0ef4f9a3 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -107,7 +107,7 @@ else fi install_files="${script_dir}/install.sh" -nginx_dir="${top_dir}/../enterprise/src/plugins/web" +web_dir="${top_dir}/../enterprise/src/plugins/web" init_file_deb=${script_dir}/../deb/taosd init_file_rpm=${script_dir}/../rpm/taosd @@ -132,10 +132,6 @@ if [ -f "${cfg_dir}/${serverName}.service" ]; then cp ${cfg_dir}/${serverName}.service ${install_dir}/cfg || : fi -if [ -f "${top_dir}/packaging/cfg/nginxd.service" ]; then - cp ${top_dir}/packaging/cfg/nginxd.service ${install_dir}/cfg || : -fi - mkdir -p ${install_dir}/bin && cp ${bin_files} ${install_dir}/bin && chmod a+x ${install_dir}/bin/* || : mkdir -p ${install_dir}/init.d && cp ${init_file_deb} ${install_dir}/init.d/${serverName}.deb mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/${serverName}.rpm @@ -222,16 +218,6 @@ if [ "$verMode" == "cluster" ]; then sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >>remove_temp.sh mv remove_temp.sh ${install_dir}/bin/remove.sh - mkdir -p ${install_dir}/nginxd && cp -r ${nginx_dir}/* ${install_dir}/nginxd - cp ${nginx_dir}/png/taos.png ${install_dir}/nginxd/admin/images/taos.png - rm -rf ${install_dir}/nginxd/png - - if [ "$cpuType" == "aarch64" ]; then - cp -f ${install_dir}/nginxd/sbin/arm/64bit/nginx ${install_dir}/nginxd/sbin/ - elif [ "$cpuType" == "aarch32" ]; then - cp -f ${install_dir}/nginxd/sbin/arm/32bit/nginx ${install_dir}/nginxd/sbin/ - fi - rm -rf ${install_dir}/nginxd/sbin/arm fi cd ${install_dir} @@ -288,6 +274,13 @@ if [[ $dbName == "taos" ]]; then cp -r ${examples_dir}/C# ${install_dir}/examples mkdir -p ${install_dir}/examples/taosbenchmark-json && cp ${examples_dir}/../tools/taos-tools/example/* ${install_dir}/examples/taosbenchmark-json fi + + # Add web files + if [ -d "${web_dir}/admin" ]; then + mkdir -p ${install_dir}/share/ + cp ${web_dir}/admin ${install_dir}/share/ -r + cp ${web_dir}/png/taos.png ${install_dir}/share/admin/images/taos.png + fi fi # Copy driver diff --git a/packaging/tools/remove.sh b/packaging/tools/remove.sh index bf4ff564f5..a648750904 100755 --- a/packaging/tools/remove.sh +++ b/packaging/tools/remove.sh @@ -27,13 +27,11 @@ local_bin_link_dir="/usr/local/bin" lib_link_dir="/usr/lib" lib64_link_dir="/usr/lib64" inc_link_dir="/usr/include" -install_nginxd_dir="/usr/local/nginxd" service_config_dir="/etc/systemd/system" taos_service_name=${serverName} taosadapter_service_name="taosadapter" tarbitrator_service_name="tarbitratord" -nginx_service_name="nginxd" csudo="" if command -v sudo >/dev/null; then csudo="sudo " @@ -153,18 +151,6 @@ function clean_service_on_systemd() { fi ${csudo}systemctl disable ${tarbitrator_service_name} &>/dev/null || echo &>/dev/null ${csudo}rm -f ${tarbitratord_service_config} - - if [ "$verMode" == "cluster" ]; then - nginx_service_config="${service_config_dir}/${nginx_service_name}.service" - if [ -d ${install_nginxd_dir} ]; then - if systemctl is-active --quiet ${nginx_service_name}; then - echo "Nginx for ${productName} is running, stopping it..." - ${csudo}systemctl stop ${nginx_service_name} &>/dev/null || echo &>/dev/null - fi - ${csudo}systemctl disable ${nginx_service_name} &>/dev/null || echo &>/dev/null - ${csudo}rm -f ${nginx_service_config} - fi - fi } function clean_service_on_sysvinit() { @@ -239,7 +225,6 @@ clean_config ${csudo}rm -rf ${data_link_dir} || : ${csudo}rm -rf ${install_main_dir} -${csudo}rm -rf ${install_nginxd_dir} if [[ -e /etc/os-release ]]; then osinfo=$(awk -F= '/^NAME/{print $2}' /etc/os-release) else diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 6a4ef3d821..5792f498ef 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -19,6 +19,7 @@ #include "functionMgt.h" #include "os.h" #include "query.h" +#include "qworker.h" #include "scheduler.h" #include "tcache.h" #include "tglobal.h" @@ -27,7 +28,6 @@ #include "trpc.h" #include "tsched.h" #include "ttime.h" -#include "qworker.h" #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 @@ -70,11 +70,10 @@ static void deregisterRequest(SRequestObj *pRequest) { int32_t currentInst = atomic_sub_fetch_64((int64_t *)&pActivity->currentRequests, 1); int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1); - int64_t nowUs = taosGetTimestampUs(); - int64_t duration = nowUs - pRequest->metric.start; - tscDebug("0x%" PRIx64 " free Request from connObj: 0x%" PRIx64 ", reqId:0x%" PRIx64 " elapsed:%" PRIu64 - " ms, current:%d, app current:%d", - pRequest->self, pTscObj->id, pRequest->requestId, duration / 1000, num, currentInst); + int64_t duration = taosGetTimestampUs() - pRequest->metric.start; + tscDebug("0x%" PRIx64 " free Request from connObj: 0x%" PRIx64 ", reqId:0x%" PRIx64 " elapsed:%.2f ms, " + "current:%d, app current:%d", + pRequest->self, pTscObj->id, pRequest->requestId, duration / 1000.0, num, currentInst); if (QUERY_NODE_VNODE_MODIF_STMT == pRequest->stmtType) { tscPerf("insert duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 @@ -85,11 +84,12 @@ static void deregisterRequest(SRequestObj *pRequest) { atomic_add_fetch_64((int64_t *)&pActivity->insertElapsedTime, duration); } else if (QUERY_NODE_SELECT_STMT == pRequest->stmtType) { tscPerf("select duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 - "us, planner:%" PRId64 "us, exec:%" PRId64 "us", + "us, planner:%" PRId64 "us, exec:%" PRId64 "us, reqId:0x%"PRIx64, duration, pRequest->metric.syntaxEnd - pRequest->metric.syntaxStart, pRequest->metric.ctgEnd - pRequest->metric.ctgStart, pRequest->metric.semanticEnd - pRequest->metric.ctgEnd, pRequest->metric.planEnd - pRequest->metric.semanticEnd, - pRequest->metric.resultReady - pRequest->metric.planEnd); + pRequest->metric.resultReady - pRequest->metric.planEnd, pRequest->requestId); + atomic_add_fetch_64((int64_t *)&pActivity->queryElapsedTime, duration); } diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 13b47052bf..8c3b637b7b 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -483,8 +483,8 @@ void setResPrecision(SReqResultInfo* pResInfo, int32_t precision) { int32_t buildVnodePolicyNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SArray* pDbVgList) { SArray* nodeList = taosArrayInit(4, sizeof(SQueryNodeLoad)); - char *policy = (tsQueryPolicy == QUERY_POLICY_VNODE) ? "vnode" : "client"; - + char* policy = (tsQueryPolicy == QUERY_POLICY_VNODE) ? "vnode" : "client"; + int32_t dbNum = taosArrayGetSize(pDbVgList); for (int32_t i = 0; i < dbNum; ++i) { SArray* pVg = taosArrayGetP(pDbVgList, i); @@ -815,7 +815,7 @@ int32_t handleCreateTbExecRes(void* res, SCatalog* pCatalog) { int32_t handleQueryExecRsp(SRequestObj* pRequest) { if (NULL == pRequest->body.resInfo.execRes.res) { - return TSDB_CODE_SUCCESS; + return pRequest->code; } SCatalog* pCatalog = NULL; @@ -868,10 +868,12 @@ int32_t handleQueryExecRsp(SRequestObj* pRequest) { return code; } +//todo refacto the error code mgmt void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*)param; - pRequest->code = code; + STscObj* pTscObj = pRequest->pTscObj; + pRequest->code = code; pRequest->metric.resultReady = taosGetTimestampUs(); if (pResult) { @@ -879,33 +881,32 @@ void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) { memcpy(&pRequest->body.resInfo.execRes, pResult, sizeof(*pResult)); } - if (TDMT_VND_SUBMIT == pRequest->type || TDMT_VND_DELETE == pRequest->type || - TDMT_VND_CREATE_TABLE == pRequest->type) { + int32_t type = pRequest->type; + if (TDMT_VND_SUBMIT == type || TDMT_VND_DELETE == type || TDMT_VND_CREATE_TABLE == type) { if (pResult) { pRequest->body.resInfo.numOfRows = pResult->numOfRows; - if (TDMT_VND_SUBMIT == pRequest->type) { - STscObj* pTscObj = pRequest->pTscObj; + + // record the insert rows + if (TDMT_VND_SUBMIT == type) { SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary; atomic_add_fetch_64((int64_t*)&pActivity->numOfInsertRows, pResult->numOfRows); } } schedulerFreeJob(&pRequest->body.queryJob, 0); - - pRequest->metric.execEnd = taosGetTimestampUs(); } taosMemoryFree(pResult); + tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code), + pRequest->requestId); - tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, - tstrerror(code), pRequest->requestId); - - STscObj* pTscObj = pRequest->pTscObj; if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code) && pRequest->sqlstr != NULL) { - tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64, - pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId); + tscDebug("0x%" PRIx64 " client retry to handle the error, code:%s, tryCount:%d, reqId:0x%" PRIx64, + pRequest->self, tstrerror(code), pRequest->retry, pRequest->requestId); pRequest->prevCode = code; schedulerFreeJob(&pRequest->body.queryJob, 0); + qDestroyQuery(pRequest->pQuery); + pRequest->pQuery = NULL; doAsyncQuery(pRequest, true); return; } @@ -915,7 +916,11 @@ void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) { removeMeta(pTscObj, pRequest->targetTableList); } - handleQueryExecRsp(pRequest); + pRequest->metric.execEnd = taosGetTimestampUs(); + int32_t code1 = handleQueryExecRsp(pRequest); + if (pRequest->code == TSDB_CODE_SUCCESS && pRequest->code != code1) { + pRequest->code = code1; + } // return to client pRequest->body.queryFp(pRequest->body.param, pRequest, code); diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index fecd76ac58..194392162f 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -20,13 +20,13 @@ #include "functionMgt.h" #include "os.h" #include "query.h" +#include "qworker.h" #include "scheduler.h" #include "tglobal.h" #include "tmsg.h" #include "tref.h" #include "trpc.h" #include "version.h" -#include "qworker.h" #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 @@ -700,6 +700,7 @@ void retrieveMetaCallback(SMetaData *pResultMeta, void *param, int32_t code) { SQuery *pQuery = pRequest->pQuery; pRequest->metric.ctgEnd = taosGetTimestampUs(); + qDebug("0x%" PRIx64 " start to semantic analysis, reqId:0x%" PRIx64, pRequest->self, pRequest->requestId); if (code == TSDB_CODE_SUCCESS) { code = qAnalyseSqlSemantic(pWrapper->pCtx, &pWrapper->catalogReq, pResultMeta, pQuery); @@ -723,13 +724,16 @@ void retrieveMetaCallback(SMetaData *pResultMeta, void *param, int32_t code) { destorySqlParseWrapper(pWrapper); - tscDebug("0x%" PRIx64 " analysis semantics completed, start async query, reqId:0x%" PRIx64, pRequest->self, - pRequest->requestId); + double el = (pRequest->metric.semanticEnd - pRequest->metric.ctgEnd)/1000.0; + tscDebug("0x%" PRIx64 " analysis semantics completed, start async query, elapsed time:%.2f ms, reqId:0x%" PRIx64, + pRequest->self, el, pRequest->requestId); + launchAsyncQuery(pRequest, pQuery, pResultMeta); } else { destorySqlParseWrapper(pWrapper); qDestroyQuery(pRequest->pQuery); pRequest->pQuery = NULL; + if (NEED_CLIENT_HANDLE_ERROR(code)) { tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 973203097b..c0203dadb8 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -85,8 +85,7 @@ uint16_t tsTelemPort = 80; char tsSmlTagName[TSDB_COL_NAME_LEN] = "_tag_null"; char tsSmlChildTableName[TSDB_TABLE_NAME_LEN] = ""; // user defined child table name can be specified in tag value. // If set to empty system will generate table name using MD5 hash. -bool tsSmlDataFormat = - true; // true means that the name and order of cols in each line are the same(only for influx protocol) +bool tsSmlDataFormat = false; // true means that the name and order of cols in each line are the same(only for influx protocol) // query int32_t tsQueryPolicy = 1; @@ -206,7 +205,9 @@ static int32_t taosLoadCfg(SConfig *pCfg, const char **envCmd, const char *input tstrncpy(cfgFile, cfgDir, sizeof(cfgDir)); } - if (apolloUrl == NULL || apolloUrl[0] == '\0') cfgGetApollUrl(envCmd, envFile, apolloUrl); + if (apolloUrl != NULL && apolloUrl[0] == '\0') { + cfgGetApollUrl(envCmd, envFile, apolloUrl); + } if (cfgLoad(pCfg, CFG_STYPE_APOLLO_URL, apolloUrl) != 0) { uError("failed to load from apollo url:%s since %s", apolloUrl, terrstr()); @@ -1132,11 +1133,20 @@ int32_t taosCreateLog(const char *logname, int32_t logFileNum, const char *cfgDi if (tsc) { tsLogEmbedded = 0; - if (taosAddClientLogCfg(pCfg) != 0) return -1; + if (taosAddClientLogCfg(pCfg) != 0) { + cfgCleanup(pCfg); + return -1; + } } else { tsLogEmbedded = 1; - if (taosAddClientLogCfg(pCfg) != 0) return -1; - if (taosAddServerLogCfg(pCfg) != 0) return -1; + if (taosAddClientLogCfg(pCfg) != 0) { + cfgCleanup(pCfg); + return -1; + } + if (taosAddServerLogCfg(pCfg) != 0) { + cfgCleanup(pCfg); + return -1; + } } if (taosLoadCfg(pCfg, envCmd, cfgDir, envFile, apolloUrl) != 0) { diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c index 1c7edbe6be..66386b0ee0 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c @@ -87,6 +87,7 @@ int32_t qmPutRpcMsgToQueue(SQnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) { return 0; default: terrno = TSDB_CODE_INVALID_PARA; + taosFreeQitem(pMsg); return -1; } } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c index cbcb541200..82fc286a94 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c @@ -135,12 +135,14 @@ _OVER: if (content != NULL) taosMemoryFree(content); if (root != NULL) cJSON_Delete(root); if (pFile != NULL) taosCloseFile(&pFile); + if (*ppCfgs == NULL && pCfgs != NULL) taosMemoryFree(pCfgs); terrno = code; return code; } int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) { + int32_t ret = 0; char file[PATH_MAX] = {0}; char realfile[PATH_MAX] = {0}; snprintf(file, sizeof(file), "%s%svnodes.json.bak", pMgmt->path, TD_DIRSEP); @@ -161,13 +163,16 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) { char *content = taosMemoryCalloc(1, maxLen + 1); if (content == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; + ret = -1; + goto _OVER; } len += snprintf(content + len, maxLen - len, "{\n"); len += snprintf(content + len, maxLen - len, " \"vnodes\": [\n"); for (int32_t i = 0; i < numOfVnodes; ++i) { SVnodeObj *pVnode = pVnodes[i]; + if (pVnode == NULL) continue; + len += snprintf(content + len, maxLen - len, " {\n"); len += snprintf(content + len, maxLen - len, " \"vgId\": %d,\n", pVnode->vgId); len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pVnode->dropped); @@ -180,12 +185,13 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) { } len += snprintf(content + len, maxLen - len, " ]\n"); len += snprintf(content + len, maxLen - len, "}\n"); + terrno = 0; +_OVER: taosWriteFile(pFile, content, len); taosFsyncFile(pFile); taosCloseFile(&pFile); taosMemoryFree(content); - terrno = 0; for (int32_t i = 0; i < numOfVnodes; ++i) { SVnodeObj *pVnode = pVnodes[i]; @@ -196,6 +202,8 @@ int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) { taosMemoryFree(pVnodes); } + if (ret != 0) return -1; + dDebug("successed to write %s, numOfVnodes:%d", realfile, numOfVnodes); return taosRenameFile(file, realfile); } \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index e3ad1b9389..4047bc2340 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -175,7 +175,7 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) { pCfg->hashSuffix = pCreate->hashSuffix; pCfg->tsdbPageSize = pCreate->tsdbPageSize * 1024; - pCfg->standby = pCfg->standby; + pCfg->standby = 0; pCfg->syncCfg.myIndex = pCreate->selfIndex; pCfg->syncCfg.replicaNum = pCreate->replica; memset(&pCfg->syncCfg.nodeInfo, 0, sizeof(pCfg->syncCfg.nodeInfo)); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index f0c43d8b36..19ed2cbc88 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -58,11 +58,14 @@ int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) { if (pVnode->path == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; + taosMemoryFree(pVnode); return -1; } if (vmAllocQueue(pMgmt, pVnode) != 0) { terrno = TSDB_CODE_OUT_OF_MEMORY; + taosMemoryFree(pVnode->path); + taosMemoryFree(pVnode); return -1; } @@ -221,6 +224,7 @@ static void vmCloseVnodes(SVnodeMgmt *pMgmt) { SVnodeObj **ppVnodes = vmGetVnodeListFromHash(pMgmt, &numOfVnodes); for (int32_t i = 0; i < numOfVnodes; ++i) { + if (ppVnodes == NULL || ppVnodes[i] == NULL) continue; vmCloseVnode(pMgmt, ppVnodes[i]); } @@ -380,7 +384,9 @@ static int32_t vmStartVnodes(SVnodeMgmt *pMgmt) { for (int32_t v = 0; v < numOfVnodes; ++v) { int32_t t = v % threadNum; SVnodeThread *pThread = &threads[t]; - pThread->ppVnodes[pThread->vnodeNum++] = ppVnodes[v]; + if (pThread->ppVnodes != NULL) { + pThread->ppVnodes[pThread->vnodeNum++] = ppVnodes[v]; + } } pMgmt->state.openVnodes = 0; @@ -411,8 +417,8 @@ static int32_t vmStartVnodes(SVnodeMgmt *pMgmt) { taosMemoryFree(threads); for (int32_t i = 0; i < numOfVnodes; ++i) { - SVnodeObj *pVnode = ppVnodes[i]; - vmReleaseVnode(pMgmt, pVnode); + if (ppVnodes == NULL || ppVnodes[i] == NULL) continue; + vmReleaseVnode(pMgmt, ppVnodes[i]); } if (ppVnodes != NULL) { diff --git a/source/dnode/mnode/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c index ff0c4b26ef..b5cfa7b0f6 100644 --- a/source/dnode/mnode/sdb/src/sdbFile.c +++ b/source/dnode/mnode/sdb/src/sdbFile.c @@ -514,7 +514,7 @@ static void sdbCloseIter(SSdbIter *pIter) { } if (pIter->name != NULL) { - taosRemoveFile(pIter->name); + (void)taosRemoveFile(pIter->name); taosMemoryFree(pIter->name); pIter->name = NULL; } @@ -606,6 +606,7 @@ int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) { if (pIter->file == NULL) { terrno = TAOS_SYSTEM_ERROR(errno); mError("failed to open %s since %s", pIter->name, terrstr()); + sdbCloseIter(pIter); return -1; } @@ -636,9 +637,9 @@ int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, i return -1; } - sdbCloseIter(pIter); if (sdbReadFile(pSdb) != 0) { mError("sdbiter:%p, failed to read from %s since %s", pIter, datafile, terrstr()); + sdbCloseIter(pIter); return -1; } @@ -656,6 +657,7 @@ int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply, int64_t index, i } mInfo("sdbiter:%p, success applyed to sdb", pIter); + sdbCloseIter(pIter); return 0; } diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index 5083db78bf..75b2f74096 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -662,7 +662,8 @@ typedef struct { } SSkmInfo; int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid, - STimeWindow *pTimeWindow, SVersionRange *pVerRange, void *pBlockLoadInfo, bool destroyLoadInfo, const char *idStr); + STimeWindow *pTimeWindow, SVersionRange *pVerRange, SSttBlockLoadInfo *pBlockLoadInfo, + bool destroyLoadInfo, const char *idStr); void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter); bool tMergeTreeNext(SMergeTree *pMTree); TSDBROW tMergeTreeGetRow(SMergeTree *pMTree); diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 520701a9bd..3a921349e6 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -456,10 +456,10 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) { code = tsdbDataFReaderOpen(&state->pDataFReader, state->pTsdb, pFileSet); if (code) goto _err; - struct SSttBlockLoadInfo* pLoadInfo = tCreateLastBlockLoadInfo(state->pTSchema, NULL, 0); + SSttBlockLoadInfo* pLoadInfo = tCreateLastBlockLoadInfo(state->pTSchema, NULL, 0); tMergeTreeOpen(&state->mergeTree, 1, state->pDataFReader, state->suid, state->uid, &(STimeWindow){.skey = TSKEY_MIN, .ekey = TSKEY_MAX}, - &(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, pLoadInfo, true, NULL); + &(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, pLoadInfo,true, NULL); bool hasVal = tMergeTreeNext(&state->mergeTree); if (!hasVal) { state->state = SFSLASTNEXTROW_FILESET; diff --git a/source/dnode/vnode/src/tsdb/tsdbMergeTree.c b/source/dnode/vnode/src/tsdb/tsdbMergeTree.c index d5a17d0fc3..ec53fc61b3 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMergeTree.c +++ b/source/dnode/vnode/src/tsdb/tsdbMergeTree.c @@ -474,7 +474,8 @@ static FORCE_INLINE int32_t tLDataIterCmprFn(const void *p1, const void *p2) { } int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid, - STimeWindow *pTimeWindow, SVersionRange *pVerRange, void* pBlockLoadInfo, bool destroyLoadInfo, const char* idStr) { + STimeWindow *pTimeWindow, SVersionRange *pVerRange, SSttBlockLoadInfo *pBlockLoadInfo, + bool destroyLoadInfo, const char *idStr) { pMTree->backward = backward; pMTree->pIter = NULL; pMTree->pIterList = taosArrayInit(4, POINTER_BYTES); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 734694b9d1..1f38cd9b42 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -34,6 +34,7 @@ extern "C" { #include "scalar.h" #include "taosdef.h" #include "tarray.h" +#include "tfill.h" #include "thash.h" #include "tlockfree.h" #include "tmsg.h" @@ -799,6 +800,22 @@ typedef struct SStreamPartitionOperatorInfo { SSDataBlock* pDelRes; } SStreamPartitionOperatorInfo; +typedef struct SStreamFillOperatorInfo { + SStreamFillSupporter* pFillSup; + SSDataBlock* pRes; + SSDataBlock* pSrcBlock; + int32_t srcRowIndex; + SSDataBlock* pPrevSrcBlock; + SSDataBlock* pSrcDelBlock; + int32_t srcDelRowIndex; + SSDataBlock* pDelRes; + SNode* pCondition; + SArray* pColMatchColInfo; + int32_t primaryTsCol; + int32_t primarySrcSlotId; + SStreamFillInfo* pFillInfo; +} SStreamFillOperatorInfo; + typedef struct STimeSliceOperatorInfo { SSDataBlock* pRes; STimeWindow win; @@ -1007,6 +1024,8 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, + SExecTaskInfo* pTaskInfo); int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx, int32_t numOfOutput, SArray* pPseudoList); @@ -1095,6 +1114,7 @@ int32_t setOutputBuf(STimeWindow* win, SResultRow** pResult, int64_t tableGroupI SExecTaskInfo* pTaskInfo); int32_t releaseOutputBuf(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult); int32_t saveOutputBuf(SExecTaskInfo* pTaskInfo, SWinKey* pKey, SResultRow* pResult, int32_t resSize); +void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order); #ifdef __cplusplus } diff --git a/source/libs/executor/inc/tfill.h b/source/libs/executor/inc/tfill.h index 63abfc019d..ed019be767 100644 --- a/source/libs/executor/inc/tfill.h +++ b/source/libs/executor/inc/tfill.h @@ -23,12 +23,13 @@ extern "C" { #include "os.h" #include "taosdef.h" #include "tcommon.h" +#include "tsimplehash.h" struct SSDataBlock; typedef struct SFillColInfo { - SExprInfo *pExpr; - bool notFillCol; // denote if this column needs fill operation + SExprInfo* pExpr; + bool notFillCol; // denote if this column needs fill operation SVariant fillVal; } SFillColInfo; @@ -51,46 +52,96 @@ typedef struct { } SRowVal; typedef struct SFillInfo { - TSKEY start; // start timestamp - TSKEY end; // endKey for fill - TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure. - int32_t tsSlotId; // primary time stamp slot id - int32_t srcTsSlotId; // timestamp column id in the source data block. - int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC] - int32_t type; // fill type - int32_t numOfRows; // number of rows in the input data block - int32_t index; // active row index - int32_t numOfTotal; // number of filled rows in one round - int32_t numOfCurrent; // number of filled rows in current results - int32_t numOfCols; // number of columns, including the tags columns - SInterval interval; - SRowVal prev; - SRowVal next; - SSDataBlock *pSrcBlock; - int32_t alloc; // data buffer size in rows + TSKEY start; // start timestamp + TSKEY end; // endKey for fill + TSKEY currentKey; // current active timestamp, the value may be changed during the fill procedure. + int32_t tsSlotId; // primary time stamp slot id + int32_t srcTsSlotId; // timestamp column id in the source data block. + int32_t order; // order [TSDB_ORDER_ASC|TSDB_ORDER_DESC] + int32_t type; // fill type + int32_t numOfRows; // number of rows in the input data block + int32_t index; // active row index + int32_t numOfTotal; // number of filled rows in one round + int32_t numOfCurrent; // number of filled rows in current results + int32_t numOfCols; // number of columns, including the tags columns + SInterval interval; + SRowVal prev; + SRowVal next; + SSDataBlock* pSrcBlock; + int32_t alloc; // data buffer size in rows - SFillColInfo* pFillCol; // column info for fill operations - SFillTagColInfo* pTags; // tags value for filling gap - const char* id; + SFillColInfo* pFillCol; // column info for fill operations + SFillTagColInfo* pTags; // tags value for filling gap + const char* id; } SFillInfo; +typedef struct SResultCellData { + bool isNull; + int8_t type; + int32_t bytes; + char pData[]; +} SResultCellData; + +typedef struct SResultRowData { + TSKEY key; + SResultCellData* pRowVal; +} SResultRowData; + +typedef struct SStreamFillLinearInfo { + TSKEY nextEnd; + SArray* pDeltaVal; // double. value for Fill(linear). + SArray* pNextDeltaVal; // double. value for Fill(linear). + int64_t winIndex; + bool hasNext; +} SStreamFillLinearInfo; + +typedef struct SStreamFillInfo { + TSKEY start; // startKey for fill + TSKEY end; // endKey for fill + TSKEY current; // current Key for fill + TSKEY preRowKey; + TSKEY nextRowKey; + SResultRowData* pResRow; + SStreamFillLinearInfo* pLinearInfo; + bool needFill; + int32_t type; // fill type + int32_t pos; + SArray* delRanges; + int32_t delIndex; +} SStreamFillInfo; + +typedef struct SStreamFillSupporter { + int32_t type; // fill type + SInterval interval; + SResultRowData prev; + SResultRowData cur; + SResultRowData next; + SResultRowData nextNext; + SFillColInfo* pAllColInfo; // fill exprs and not fill exprs + int32_t numOfAllCols; // number of all exprs, including the tags columns + int32_t numOfFillCols; + int32_t numOfNotFillCols; + int32_t rowSize; + SSHashObj* pResMap; + bool hasDelete; +} SStreamFillSupporter; + int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows); - -void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey); -void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp); -void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput); -struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr, int32_t numOfNotFillCols, const struct SNodeListNode* val); -bool taosFillHasMoreResults(struct SFillInfo* pFillInfo); +void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey); +void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp); +void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput); +struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprInfo* pNotFillExpr, + int32_t numOfNotFillCols, const struct SNodeListNode* val); +bool taosFillHasMoreResults(struct SFillInfo* pFillInfo); SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t numOfNotFillCols, int32_t capacity, SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol, int32_t slotId, int32_t order, const char* id); -void* taosDestroyFillInfo(struct SFillInfo *pFillInfo); +void* taosDestroyFillInfo(struct SFillInfo* pFillInfo); int64_t taosFillResultDataBlock(struct SFillInfo* pFillInfo, SSDataBlock* p, int32_t capacity); -int64_t getFillInfoStart(struct SFillInfo *pFillInfo); - +int64_t getFillInfoStart(struct SFillInfo* pFillInfo); #ifdef __cplusplus } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 7314bd0368..50fb100544 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3754,6 +3754,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) { pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, pTaskInfo); + } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL == type) { + pOptr = createStreamFillOperatorInfo(ops[0], (SStreamFillPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) { pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 6d3a9232a8..f7a42c5905 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1027,11 +1027,7 @@ static uint64_t getGroupIdByCol(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0); } -static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) { - if (pInfo->partitionSup.needCalc) { - return getGroupIdByCol(pInfo, uid, ts, maxVersion); - } - +static uint64_t getGroupIdByUid(SStreamScanInfo* pInfo, uint64_t uid) { SHashObj* map = pInfo->pTableScanOp->pTaskInfo->tableqinfoList.map; uint64_t* groupId = taosHashGet(map, &uid, sizeof(int64_t)); if (groupId) { @@ -1040,6 +1036,14 @@ static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, return 0; } +static uint64_t getGroupIdByData(SStreamScanInfo* pInfo, uint64_t uid, TSKEY ts, int64_t maxVersion) { + if (pInfo->partitionSup.needCalc) { + return getGroupIdByCol(pInfo, uid, ts, maxVersion); + } + + return getGroupIdByUid(pInfo, uid); +} + static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_t* pRowIndex) { if ((*pRowIndex) == pBlock->info.rows) { return false; @@ -1086,26 +1090,32 @@ static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_ return true; } -static STimeWindow getSlidingWindow(TSKEY* startTsCol, TSKEY* endTsCol, SInterval* pInterval, +static STimeWindow getSlidingWindow(TSKEY* startTsCol, TSKEY* endTsCol, uint64_t* gpIdCol, SInterval* pInterval, SDataBlockInfo* pDataBlockInfo, int32_t* pRowIndex, bool hasGroup) { SResultRowInfo dumyInfo; dumyInfo.cur.pageId = -1; STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTsCol[*pRowIndex], pInterval, TSDB_ORDER_ASC); STimeWindow endWin = win; STimeWindow preWin = win; + uint64_t groupId = gpIdCol[*pRowIndex]; while (1) { if (hasGroup) { (*pRowIndex) += 1; } else { - (*pRowIndex) += getNumOfRowsInTimeWindow(pDataBlockInfo, startTsCol, *pRowIndex, endWin.ekey, binarySearchForKey, - NULL, TSDB_ORDER_ASC); + while ((groupId == gpIdCol[(*pRowIndex)] && startTsCol[*pRowIndex] < endWin.ekey)) { + (*pRowIndex) += 1; + if ((*pRowIndex) == pDataBlockInfo->rows) { + break; + } + } } + do { preWin = endWin; getNextTimeWindow(pInterval, &endWin, TSDB_ORDER_ASC); } while (endTsCol[(*pRowIndex) - 1] >= endWin.skey); endWin = preWin; - if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows) { + if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows || groupId != gpIdCol[*pRowIndex]) { win.ekey = endWin.ekey; return win; } @@ -1240,11 +1250,13 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS int64_t version = pSrcBlock->info.version - 1; for (int32_t i = 0; i < rows;) { uint64_t srcUid = srcUidData[i]; - uint64_t groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version); - uint64_t srcGpId = srcGp[i]; - TSKEY calStartTs = srcStartTsCol[i]; + uint64_t groupId = srcGp[i]; + if (groupId == 0) { + groupId = getGroupIdByData(pInfo, srcUid, srcStartTsCol[i], version); + } + TSKEY calStartTs = srcStartTsCol[i]; colDataAppend(pCalStartTsCol, pDestBlock->info.rows, (const char*)(&calStartTs), false); - STimeWindow win = getSlidingWindow(srcStartTsCol, srcEndTsCol, &pInfo->interval, &pSrcBlock->info, &i, + STimeWindow win = getSlidingWindow(srcStartTsCol, srcEndTsCol, srcGp, &pInfo->interval, &pSrcBlock->info, &i, pInfo->partitionSup.needCalc); TSKEY calEndTs = srcStartTsCol[i - 1]; colDataAppend(pCalEndTsCol, pDestBlock->info.rows, (const char*)(&calEndTs), false); @@ -1253,15 +1265,6 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS colDataAppend(pEndTsCol, pDestBlock->info.rows, (const char*)(&win.ekey), false); colDataAppend(pGpCol, pDestBlock->info.rows, (const char*)(&groupId), false); pDestBlock->info.rows++; - if (pInfo->partitionSup.needCalc && srcGpId != 0 && groupId != srcGpId) { - colDataAppend(pCalStartTsCol, pDestBlock->info.rows, (const char*)(&calStartTs), false); - colDataAppend(pCalEndTsCol, pDestBlock->info.rows, (const char*)(&calEndTs), false); - colDataAppend(pDeUidCol, pDestBlock->info.rows, (const char*)(&srcUid), false); - colDataAppend(pStartTsCol, pDestBlock->info.rows, (const char*)(&win.skey), false); - colDataAppend(pEndTsCol, pDestBlock->info.rows, (const char*)(&win.ekey), false); - colDataAppend(pGpCol, pDestBlock->info.rows, (const char*)(&srcGpId), false); - pDestBlock->info.rows++; - } } return TSDB_CODE_SUCCESS; } @@ -1336,7 +1339,7 @@ void appendOneRow(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock* pBlock, bool out) { if (out) { blockDataCleanup(pInfo->pUpdateDataRes); - blockDataEnsureCapacity(pInfo->pUpdateDataRes, pBlock->info.rows); + blockDataEnsureCapacity(pInfo->pUpdateDataRes, pBlock->info.rows * 2); } SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex); ASSERT(pColDataInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP); @@ -1357,10 +1360,12 @@ static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock isDeletedStreamWindow(&win, pBlock->info.groupId, pInfo->pTableScanOp, &pInfo->twAggSup); if ((update || closedWin) && out) { qDebug("stream update check not pass, update %d, closedWin %d", update, closedWin); - uint64_t gpId = closedWin && pInfo->partitionSup.needCalc - ? calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pBlock, rowId) - : 0; + uint64_t gpId = 0; appendOneRow(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId); + if (closedWin && pInfo->partitionSup.needCalc) { + gpId = calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pBlock, rowId); + appendOneRow(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid, &gpId); + } } } if (out && pInfo->pUpdateDataRes->info.rows > 0) { @@ -1537,6 +1542,30 @@ static int32_t filterDelBlockByUid(SSDataBlock* pDst, const SSDataBlock* pSrc, S return 0; } +// for partition by tag +static void setBlockGroupIdByUid(SStreamScanInfo* pInfo, SSDataBlock* pBlock) { + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startTsCol = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* gpCol = (uint64_t*)pGpCol->pData; + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + uint64_t* uidCol = (uint64_t*)pUidCol->pData; + int32_t rows = pBlock->info.rows; + if (!pInfo->partitionSup.needCalc) { + for (int32_t i = 0; i < rows; i++) { + uint64_t groupId = getGroupIdByUid(pInfo, uidCol[i]); + colDataAppend(pGpCol, i, (const char*)&groupId, false); + } + } else { + // SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, uidCol[i], startTsCol, ts, maxVersion); + // if (!pPreRes || pPreRes->info.rows == 0) { + // return 0; + // } + // ASSERT(pPreRes->info.rows == 1); + // return calGroupIdByData(&pInfo->partitionSup, pInfo->pPartScalarSup, pPreRes, 0); + } +} + static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { // NOTE: this operator does never check if current status is done or not SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; @@ -1633,7 +1662,8 @@ FETCH_NEXT_BLOCK: } else { pDelBlock = pBlock; } - printDataBlock(pBlock, "stream scan delete recv filtered"); + setBlockGroupIdByUid(pInfo, pDelBlock); + printDataBlock(pDelBlock, "stream scan delete recv filtered"); if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) { generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT; diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c index f23552c5a7..ea0d26f4de 100644 --- a/source/libs/executor/src/tfill.c +++ b/source/libs/executor/src/tfill.c @@ -19,6 +19,7 @@ #include "tmsg.h" #include "ttypes.h" +#include "executorimpl.h" #include "tcommon.h" #include "thash.h" #include "ttime.h" @@ -35,18 +36,30 @@ #define GET_DEST_SLOT_ID(_p) ((_p)->pExpr->base.resSchema.slotId) +#define FILL_POS_INVALID 0 +#define FILL_POS_START 1 +#define FILL_POS_MID 2 +#define FILL_POS_END 3 + +typedef struct STimeRange { + TSKEY skey; + TSKEY ekey; + uint64_t groupId; +} STimeRange; + static void doSetVal(SColumnInfoData* pDstColInfoData, int32_t rowIndex, const SGroupKeys* pKey); -static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex); +static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, + int32_t rowIndex); static void setNullRow(SSDataBlock* pBlock, SFillInfo* pFillInfo, int32_t rowIndex) { - for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - int32_t dstSlotId = GET_DEST_SLOT_ID(pCol); + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + int32_t dstSlotId = GET_DEST_SLOT_ID(pCol); SColumnInfoData* pDstColInfo = taosArrayGet(pBlock->pDataBlock, dstSlotId); if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfo, rowIndex); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfo, rowIndex, pKey); } @@ -76,8 +89,9 @@ static void doSetUserSpecifiedValue(SColumnInfoData* pDst, SVariant* pVar, int32 } } -//fill windows pseudo column, _wstart, _wend, _wduration and return true, otherwise return false -static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex) { +// fill windows pseudo column, _wstart, _wend, _wduration and return true, otherwise return false +static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, + int32_t rowIndex) { if (!pCol->notFillCol) { return false; } @@ -89,15 +103,15 @@ static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, S colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->currentKey, false); return true; } else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_END) { - //TODO: include endpoint + // TODO: include endpoint SInterval* pInterval = &pFillInfo->interval; - int32_t step = (pFillInfo->order == TSDB_ORDER_ASC) ? 1 : -1; - int64_t windowEnd = + int32_t step = (pFillInfo->order == TSDB_ORDER_ASC) ? 1 : -1; + int64_t windowEnd = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision); colDataAppend(pDstColInfoData, rowIndex, (const char*)&windowEnd, false); return true; } else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_DURATION) { - //TODO: include endpoint + // TODO: include endpoint colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->interval.sliding, false); return true; } @@ -115,13 +129,13 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* // set the other values if (pFillInfo->type == TSDB_FILL_PREV) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo)? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); + bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); if (!filled) { SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfoData, index, pKey); @@ -131,9 +145,9 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->next.pRowVal : pFillInfo->prev.pRowVal; // todo refactor: start from 0 not 1 for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { - SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); + bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index); if (!filled) { SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfoData, index, pKey); @@ -154,7 +168,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstCol, index); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstCol, index, pKey); } @@ -190,13 +204,13 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - int32_t slotId = GET_DEST_SLOT_ID(pCol); + int32_t slotId = GET_DEST_SLOT_ID(pCol); SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, slotId); if (pCol->notFillCol) { bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDst, index); if (!filled) { - SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; + SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal; SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDst, index, pKey); } @@ -261,8 +275,8 @@ static void copyCurrentRowIntoBuf(SFillInfo* pFillInfo, int32_t rowIndex, SArray } else if (type == QUERY_NODE_OPERATOR) { SColumnInfoData* pSrcCol = taosArrayGet(pFillInfo->pSrcBlock->pDataBlock, i); - bool isNull = colDataIsNull_s(pSrcCol, rowIndex); - char* p = colDataGetData(pSrcCol, rowIndex); + bool isNull = colDataIsNull_s(pSrcCol, rowIndex); + char* p = colDataGetData(pSrcCol, rowIndex); saveColData(pRow, i, p, isNull); } else { ASSERT(0); @@ -425,9 +439,9 @@ struct SFillInfo* taosCreateFillInfo(TSKEY skey, int32_t numOfFillCols, int32_t pFillInfo->order = order; pFillInfo->srcTsSlotId = primaryTsSlotId; - for(int32_t i = 0; i < numOfNotFillCols; ++i) { + for (int32_t i = 0; i < numOfNotFillCols; ++i) { SFillColInfo* p = &pCol[i + numOfFillCols]; - int32_t srcSlotId = GET_DEST_SLOT_ID(p); + int32_t srcSlotId = GET_DEST_SLOT_ID(p); if (srcSlotId == primaryTsSlotId) { pFillInfo->tsSlotId = i + numOfFillCols; break; @@ -499,9 +513,9 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) { } taosArrayDestroy(pFillInfo->next.pRowVal); -// for (int32_t i = 0; i < pFillInfo->numOfTags; ++i) { -// taosMemoryFreeClear(pFillInfo->pTags[i].tagVal); -// } + // for (int32_t i = 0; i < pFillInfo->numOfTags; ++i) { + // taosMemoryFreeClear(pFillInfo->pTags[i].tagVal); + // } taosMemoryFreeClear(pFillInfo->pTags); taosMemoryFreeClear(pFillInfo->pFillCol); @@ -640,7 +654,7 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprIn } } - for(int32_t i = 0; i < numOfNotFillExpr; ++i) { + for (int32_t i = 0; i < numOfNotFillExpr; ++i) { SExprInfo* pExprInfo = &pNotFillExpr[i]; pFillCol[i + numOfFillExpr].pExpr = pExprInfo; pFillCol[i + numOfFillExpr].notFillCol = true; @@ -648,3 +662,1050 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfFillExpr, SExprIn return pFillCol; } + +TSKEY getNextWindowTs(TSKEY ts, SInterval* pInterval) { + STimeWindow win = {.skey = ts, .ekey = ts}; + getNextIntervalWindow(pInterval, &win, TSDB_ORDER_ASC); + return win.skey; +} + +TSKEY getPrevWindowTs(TSKEY ts, SInterval* pInterval) { + STimeWindow win = {.skey = ts, .ekey = ts}; + getNextIntervalWindow(pInterval, &win, TSDB_ORDER_DESC); + return win.skey; +} + +void setRowCell(SColumnInfoData* pCol, int32_t rowId, const SResultCellData* pCell) { + colDataAppend(pCol, rowId, pCell->pData, pCell->isNull); +} + +SResultCellData* getResultCell(SResultRowData* pRaw, int32_t index) { + if (!pRaw || !pRaw->pRowVal) { + return NULL; + } + char* pData = (char*)pRaw->pRowVal; + SResultCellData* pCell = pRaw->pRowVal; + for (int32_t i = 0; i < index; i++) { + pData += (pCell->bytes + sizeof(SResultCellData)); + pCell = (SResultCellData*)pData; + } + return pCell; +} + +void* destroyFillColumnInfo(SFillColInfo* pFillCol, int32_t start, int32_t end) { + for (int32_t i = start; i < end; i++) { + destroyExprInfo(pFillCol[i].pExpr, 1); + taosMemoryFreeClear(pFillCol[i].pExpr); + taosVariantDestroy(&pFillCol[i].fillVal); + } + taosMemoryFree(pFillCol); + return NULL; +} + +void* destroyStreamFillSupporter(SStreamFillSupporter* pFillSup) { + pFillSup->pAllColInfo = destroyFillColumnInfo(pFillSup->pAllColInfo, pFillSup->numOfFillCols, pFillSup->numOfAllCols); + tSimpleHashCleanup(pFillSup->pResMap); + pFillSup->pResMap = NULL; + taosMemoryFree(pFillSup); + return NULL; +} + +void* destroyStreamFillLinearInfo(SStreamFillLinearInfo* pFillLinear) { + taosArrayDestroy(pFillLinear->pDeltaVal); + taosArrayDestroy(pFillLinear->pNextDeltaVal); + taosMemoryFree(pFillLinear); + return NULL; +} +void* destroyStreamFillInfo(SStreamFillInfo* pFillInfo) { + if (pFillInfo->type == TSDB_FILL_SET_VALUE || pFillInfo->type == TSDB_FILL_NULL) { + taosMemoryFreeClear(pFillInfo->pResRow->pRowVal); + taosMemoryFreeClear(pFillInfo->pResRow); + } + pFillInfo->pLinearInfo = destroyStreamFillLinearInfo(pFillInfo->pLinearInfo); + taosMemoryFree(pFillInfo); + return NULL; +} + +void destroyStreamFillOperatorInfo(void* param) { + SStreamFillOperatorInfo* pInfo = (SStreamFillOperatorInfo*)param; + pInfo->pFillInfo = destroyStreamFillInfo(pInfo->pFillInfo); + pInfo->pFillSup = destroyStreamFillSupporter(pInfo->pFillSup); + pInfo->pRes = blockDataDestroy(pInfo->pRes); + pInfo->pSrcBlock = blockDataDestroy(pInfo->pSrcBlock); + pInfo->pColMatchColInfo = taosArrayDestroy(pInfo->pColMatchColInfo); + taosMemoryFree(pInfo); +} + +static void resetFillWindow(SResultRowData* pRowData) { + pRowData->key = INT64_MIN; + pRowData->pRowVal = NULL; +} + +void resetPrevAndNextWindow(SStreamFillSupporter* pFillSup, SStreamState* pState) { + resetFillWindow(&pFillSup->prev); + resetFillWindow(&pFillSup->cur); + resetFillWindow(&pFillSup->next); + resetFillWindow(&pFillSup->nextNext); +} + +void getCurWindowFromDiscBuf(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, SStreamFillSupporter* pFillSup) { + SStreamState* pState = pOperator->pTaskInfo->streamInfo.pState; + resetPrevAndNextWindow(pFillSup, pState); + + SWinKey key = {.ts = ts, .groupId = groupId}; + void* curVal = NULL; + int32_t curVLen = 0; + int32_t code = streamStateFillGet(pState, &key, (void**)&curVal, &curVLen); + ASSERT(code == TSDB_CODE_SUCCESS); + pFillSup->cur.key = key.ts; + pFillSup->cur.pRowVal = curVal; +} + +void getWindowFromDiscBuf(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, SStreamFillSupporter* pFillSup) { + SStreamState* pState = pOperator->pTaskInfo->streamInfo.pState; + resetPrevAndNextWindow(pFillSup, pState); + + SWinKey key = {.ts = ts, .groupId = groupId}; + void* curVal = NULL; + int32_t curVLen = 0; + int32_t code = streamStateFillGet(pState, &key, (void**)&curVal, &curVLen); + ASSERT(code == TSDB_CODE_SUCCESS); + pFillSup->cur.key = key.ts; + pFillSup->cur.pRowVal = curVal; + + SStreamStateCur* pCur = streamStateFillSeekKeyPrev(pState, &key); + SWinKey preKey = {.groupId = groupId}; + void* preVal = NULL; + int32_t preVLen = 0; + if (pCur) { + code = streamStateGetGroupKVByCur(pCur, &preKey, (const void**)&preVal, &preVLen); + } + + if (pCur && code == TSDB_CODE_SUCCESS) { + pFillSup->prev.key = preKey.ts; + pFillSup->prev.pRowVal = preVal; + + code = streamStateCurNext(pState, pCur); + ASSERT(code == TSDB_CODE_SUCCESS); + + code = streamStateCurNext(pState, pCur); + if (code != TSDB_CODE_SUCCESS) { + pCur = NULL; + } + } else { + pCur = streamStateFillSeekKeyNext(pState, &key); + } + + if (pCur) { + SWinKey nextKey = {.groupId = groupId}; + void* nextVal = NULL; + int32_t nextVLen = 0; + code = streamStateGetGroupKVByCur(pCur, &nextKey, (const void**)&nextVal, &nextVLen); + if (code == TSDB_CODE_SUCCESS) { + pFillSup->next.key = nextKey.ts; + pFillSup->next.pRowVal = nextVal; + if (pFillSup->type == TSDB_FILL_PREV || pFillSup->type == TSDB_FILL_NEXT) { + code = streamStateCurNext(pState, pCur); + if (code == TSDB_CODE_SUCCESS) { + SWinKey nextNextKey = {.groupId = groupId}; + void* nextNextVal = NULL; + int32_t nextNextVLen = 0; + code = streamStateGetGroupKVByCur(pCur, &nextNextKey, (const void**)&nextNextVal, &nextNextVLen); + if (code == TSDB_CODE_SUCCESS) { + pFillSup->nextNext.key = nextNextKey.ts; + pFillSup->nextNext.pRowVal = nextNextVal; + } + } + } + } + } +} + +static bool hasPrevWindow(SStreamFillSupporter* pFillSup) { return pFillSup->prev.key != INT64_MIN; } +static bool hasNextWindow(SStreamFillSupporter* pFillSup) { return pFillSup->next.key != INT64_MIN; } +static bool hasNextNextWindow(SStreamFillSupporter* pFillSup) { + return pFillSup->nextNext.key != INT64_MIN; + return false; +} + +static void transBlockToResultRow(const SSDataBlock* pBlock, int32_t rowId, TSKEY ts, SResultRowData* pRowVal) { + int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); + SResultCellData* pCell = getResultCell(pRowVal, i); + if (!colDataIsNull_s(pColData, rowId)) { + pCell->isNull = false; + pCell->type = pColData->info.type; + pCell->bytes = pColData->info.bytes; + char* val = colDataGetData(pColData, rowId); + if (IS_VAR_DATA_TYPE(pCell->type)) { + memcpy(pCell->pData, val, varDataTLen(val)); + } else { + memcpy(pCell->pData, val, pCell->bytes); + } + } else { + pCell->isNull = true; + } + } + pRowVal->key = ts; +} + +static void calcDeltaData(SSDataBlock* pBlock, int32_t rowId, SResultRowData* pRowVal, SArray* pDelta, + SFillColInfo* pFillCol, int32_t numOfCol, int32_t winCount, int32_t order) { + for (int32_t i = 0; i < numOfCol; i++) { + if (!pFillCol[i].notFillCol) { + int32_t slotId = GET_DEST_SLOT_ID(pFillCol + i); + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + char* var = colDataGetData(pCol, rowId); + double start = 0; + GET_TYPED_DATA(start, double, pCol->info.type, var); + SResultCellData* pCell = getResultCell(pRowVal, slotId); + double end = 0; + GET_TYPED_DATA(end, double, pCell->type, pCell->pData); + double delta = 0; + if (order == TSDB_ORDER_ASC) { + delta = (end - start) / winCount; + } else { + delta = (start - end) / winCount; + } + taosArraySet(pDelta, slotId, &delta); + } + } +} + +static void calcRowDeltaData(SResultRowData* pStartRow, SResultRowData* pEndRow, SArray* pDelta, SFillColInfo* pFillCol, + int32_t numOfCol, int32_t winCount) { + for (int32_t i = 0; i < numOfCol; i++) { + if (!pFillCol[i].notFillCol) { + int32_t slotId = GET_DEST_SLOT_ID(pFillCol + i); + SResultCellData* pSCell = getResultCell(pStartRow, slotId); + double start = 0.0; + GET_TYPED_DATA(start, double, pSCell->type, pSCell->pData); + SResultCellData* pECell = getResultCell(pEndRow, slotId); + double end = 0.0; + GET_TYPED_DATA(end, double, pECell->type, pECell->pData); + double delta = (end - start) / winCount; + taosArraySet(pDelta, slotId, &delta); + } + } +} + +static void setFillInfoStart(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + ts = taosTimeAdd(ts, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); + pFillInfo->start = ts; +} + +static void setFillInfoEnd(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + ts = taosTimeAdd(ts, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision); + pFillInfo->end = ts; +} + +static void setFillKeyInfo(TSKEY start, TSKEY end, SInterval* pInterval, SStreamFillInfo* pFillInfo) { + setFillInfoStart(start, pInterval, pFillInfo); + pFillInfo->current = pFillInfo->start; + setFillInfoEnd(end, pInterval, pFillInfo); +} + +void setDeleteFillValueInfo(TSKEY start, TSKEY end, SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo) { + if (!hasPrevWindow(pFillSup) || !hasNextWindow(pFillSup)) { + pFillInfo->needFill = false; + return; + } + + pFillInfo->needFill = true; + pFillInfo->start = start; + pFillInfo->current = pFillInfo->start; + pFillInfo->end = end; + pFillInfo->pos = FILL_POS_INVALID; + switch (pFillInfo->type) { + case TSDB_FILL_NULL: + case TSDB_FILL_SET_VALUE: + break; + case TSDB_FILL_PREV: + pFillInfo->pResRow = &pFillSup->prev; + break; + case TSDB_FILL_NEXT: + pFillInfo->pResRow = &pFillSup->next; + break; + case TSDB_FILL_LINEAR: { + setFillKeyInfo(pFillSup->prev.key, pFillSup->next.key, &pFillSup->interval, pFillInfo); + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(pFillSup->prev.key, pFillSup->next.key, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->next, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + pFillInfo->pLinearInfo->winIndex = 0; + } break; + default: + ASSERT(0); + break; + } +} + +void setFillValueInfo(SSDataBlock* pBlock, TSKEY ts, int32_t rowId, SStreamFillSupporter* pFillSup, + SStreamFillInfo* pFillInfo) { + pFillInfo->preRowKey = pFillSup->cur.key; + if (!hasPrevWindow(pFillSup) && !hasNextWindow(pFillSup)) { + pFillInfo->needFill = false; + pFillInfo->pos = FILL_POS_START; + return; + } + TSKEY prevWKey = INT64_MIN; + TSKEY nextWKey = INT64_MIN; + if (hasPrevWindow(pFillSup)) { + prevWKey = pFillSup->prev.key; + } + if (hasNextWindow(pFillSup)) { + nextWKey = pFillSup->next.key; + } + + pFillInfo->needFill = true; + pFillInfo->pos = FILL_POS_INVALID; + switch (pFillInfo->type) { + case TSDB_FILL_NULL: + case TSDB_FILL_SET_VALUE: { + if (pFillSup->prev.key == pFillInfo->preRowKey) { + resetFillWindow(&pFillSup->prev); + } + if (hasPrevWindow(pFillSup) && hasNextWindow(pFillSup)) { + if (pFillSup->next.key == pFillInfo->nextRowKey) { + pFillInfo->preRowKey = INT64_MIN; + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + } else { + pFillInfo->needFill = false; + pFillInfo->pos = FILL_POS_START; + } + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + } else { + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + } + } break; + case TSDB_FILL_PREV: { + if (hasNextWindow(pFillSup) && ((pFillSup->next.key != pFillInfo->nextRowKey) || + (pFillSup->next.key == pFillInfo->nextRowKey && hasNextNextWindow(pFillSup)) || + (pFillSup->next.key == pFillInfo->nextRowKey && !hasPrevWindow(pFillSup)))) { + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + pFillSup->prev.key = pFillSup->cur.key; + pFillSup->prev.pRowVal = pFillSup->cur.pRowVal; + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillInfo->preRowKey = INT64_MIN; + } + pFillInfo->pResRow = &pFillSup->prev; + } break; + case TSDB_FILL_NEXT: { + if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillSup->next.key = pFillSup->cur.key; + pFillSup->next.pRowVal = pFillSup->cur.pRowVal; + pFillInfo->preRowKey = INT64_MIN; + } else { + ASSERT(hasNextWindow(pFillSup)); + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + } + pFillInfo->pResRow = &pFillSup->next; + } break; + case TSDB_FILL_LINEAR: { + pFillInfo->pLinearInfo->winIndex = 0; + if (hasPrevWindow(pFillSup) && hasNextWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_MID; + pFillInfo->pLinearInfo->nextEnd = nextWKey; + int32_t numOfWins = taosTimeCountInterval(prevWKey, ts, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->cur, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + + numOfWins = taosTimeCountInterval(ts, nextWKey, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->cur, &pFillSup->next, pFillInfo->pLinearInfo->pNextDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pLinearInfo->hasNext = true; + } else if (hasPrevWindow(pFillSup)) { + setFillKeyInfo(prevWKey, ts, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_END; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(prevWKey, ts, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->prev, &pFillSup->cur, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->prev; + pFillInfo->pLinearInfo->hasNext = false; + } else { + ASSERT(hasNextWindow(pFillSup)); + setFillKeyInfo(ts, nextWKey, &pFillSup->interval, pFillInfo); + pFillInfo->pos = FILL_POS_START; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + int32_t numOfWins = taosTimeCountInterval(ts, nextWKey, pFillSup->interval.sliding, + pFillSup->interval.slidingUnit, pFillSup->interval.precision); + calcRowDeltaData(&pFillSup->cur, &pFillSup->next, pFillInfo->pLinearInfo->pDeltaVal, pFillSup->pAllColInfo, + pFillSup->numOfAllCols, numOfWins); + pFillInfo->pResRow = &pFillSup->cur; + pFillInfo->pLinearInfo->hasNext = false; + } + } break; + default: + ASSERT(0); + break; + } + ASSERT(pFillInfo->pos != FILL_POS_INVALID); +} + +static bool checkResult(SStreamFillSupporter* pFillSup, TSKEY ts, uint64_t groupId) { + SWinKey key = {.groupId = groupId, .ts = ts}; + if (tSimpleHashGet(pFillSup->pResMap, &key, sizeof(SWinKey)) != NULL) { + return false; + } + tSimpleHashPut(pFillSup->pResMap, &key, sizeof(SWinKey), NULL, 0); + return true; +} + +static void buildFillResult(SResultRowData* pResRow, SStreamFillSupporter* pFillSup, TSKEY ts, SSDataBlock* pBlock) { + uint64_t groupId = pBlock->info.groupId; + if (pFillSup->hasDelete && !checkResult(pFillSup, ts, groupId)) { + return; + } + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, slotId); + SFillInfo tmpInfo = { + .currentKey = ts, + .order = TSDB_ORDER_ASC, + .interval = pFillSup->interval, + }; + bool filled = fillIfWindowPseudoColumn(&tmpInfo, pFillCol, pColData, pBlock->info.rows); + if (!filled) { + SResultCellData* pCell = getResultCell(pResRow, slotId); + setRowCell(pColData, pBlock->info.rows, pCell); + } + } + pBlock->info.rows++; +} + +static bool hasRemainCalc(SStreamFillInfo* pFillInfo) { + if (pFillInfo->current != INT64_MIN && pFillInfo->current <= pFillInfo->end) { + return true; + } + return false; +} + +static void doStreamFillNormal(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock) { + while (hasRemainCalc(pFillInfo) && pBlock->info.rows < pBlock->info.capacity) { + buildFillResult(pFillInfo->pResRow, pFillSup, pFillInfo->current, pBlock); + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + } +} + +static void doStreamFillLinear(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock) { + while (hasRemainCalc(pFillInfo) && pBlock->info.rows < pBlock->info.capacity) { + uint64_t groupId = pBlock->info.groupId; + SWinKey key = {.groupId = groupId, .ts = pFillInfo->current}; + if (pFillSup->hasDelete && !checkResult(pFillSup, pFillInfo->current, groupId)) { + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + pFillInfo->pLinearInfo->winIndex++; + continue; + } + pFillInfo->pLinearInfo->winIndex++; + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pFillSup->pAllColInfo + i; + SFillInfo tmp = { + .currentKey = pFillInfo->current, + .order = TSDB_ORDER_ASC, + .interval = pFillSup->interval, + }; + + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, slotId); + int16_t type = pColData->info.type; + SResultCellData* pCell = getResultCell(pFillInfo->pResRow, slotId); + int32_t index = pBlock->info.rows; + if (pFillCol->notFillCol) { + bool filled = fillIfWindowPseudoColumn(&tmp, pFillCol, pColData, index); + if (!filled) { + setRowCell(pColData, index, pCell); + } + } else { + if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || pCell->isNull) { + colDataAppendNULL(pColData, index); + continue; + } + double* pDelta = taosArrayGet(pFillInfo->pLinearInfo->pDeltaVal, slotId); + double vCell = 0; + GET_TYPED_DATA(vCell, double, pCell->type, pCell->pData); + vCell += (*pDelta) * pFillInfo->pLinearInfo->winIndex; + int64_t result = 0; + SET_TYPED_DATA(&result, pCell->type, vCell); + colDataAppend(pColData, index, (const char*)&result, false); + } + } + pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit, + pFillSup->interval.precision); + pBlock->info.rows++; + } +} + +static void keepResultInDiscBuf(SOperatorInfo* pOperator, uint64_t groupId, SResultRowData* pRow, int32_t len) { + SWinKey key = {.groupId = groupId, .ts = pRow->key}; + int32_t code = streamStateFillPut(pOperator->pTaskInfo->streamInfo.pState, &key, pRow->pRowVal, len); + ASSERT(code == TSDB_CODE_SUCCESS); +} + +static void doStreamFillRange(SStreamFillInfo* pFillInfo, SStreamFillSupporter* pFillSup, SSDataBlock* pRes) { + if (pFillInfo->needFill == false) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + return; + } + + if (pFillInfo->pos == FILL_POS_START) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } + if (pFillInfo->type != TSDB_FILL_LINEAR) { + doStreamFillNormal(pFillSup, pFillInfo, pRes); + } else { + doStreamFillLinear(pFillSup, pFillInfo, pRes); + + if (pFillInfo->pos == FILL_POS_MID) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } + + if (pFillInfo->current > pFillInfo->end && pFillInfo->pLinearInfo->hasNext) { + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->winIndex = 0; + taosArrayClear(pFillInfo->pLinearInfo->pDeltaVal); + taosArrayAddAll(pFillInfo->pLinearInfo->pDeltaVal, pFillInfo->pLinearInfo->pNextDeltaVal); + pFillInfo->pResRow = &pFillSup->cur; + setFillKeyInfo(pFillSup->cur.key, pFillInfo->pLinearInfo->nextEnd, &pFillSup->interval, pFillInfo); + doStreamFillLinear(pFillSup, pFillInfo, pRes); + } + } + if (pFillInfo->pos == FILL_POS_END) { + buildFillResult(&pFillSup->cur, pFillSup, pFillSup->cur.key, pRes); + } +} + +void keepBlockRowInDiscBuf(SOperatorInfo* pOperator, SStreamFillInfo* pFillInfo, SSDataBlock* pBlock, TSKEY* tsCol, + int32_t rowId, uint64_t groupId, int32_t rowSize) { + TSKEY ts = tsCol[rowId]; + pFillInfo->nextRowKey = ts; + SResultRowData tmpNextRow = {.key = ts}; + tmpNextRow.pRowVal = taosMemoryCalloc(1, rowSize); + transBlockToResultRow(pBlock, rowId, ts, &tmpNextRow); + keepResultInDiscBuf(pOperator, groupId, &tmpNextRow, rowSize); + taosMemoryFreeClear(tmpNextRow.pRowVal); +} + +static void doFillResults(SOperatorInfo* pOperator, SStreamFillSupporter* pFillSup, SStreamFillInfo* pFillInfo, + SSDataBlock* pBlock, TSKEY* tsCol, int32_t rowId, SSDataBlock* pRes) { + uint64_t groupId = pBlock->info.groupId; + getWindowFromDiscBuf(pOperator, tsCol[rowId], groupId, pFillSup); + if (pFillSup->prev.key == pFillInfo->preRowKey) { + resetFillWindow(&pFillSup->prev); + } + setFillValueInfo(pBlock, tsCol[rowId], rowId, pFillSup, pFillInfo); + doStreamFillRange(pFillInfo, pFillSup, pRes); +} + +static void doStreamFillImpl(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStreamFillSupporter* pFillSup = pInfo->pFillSup; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + SSDataBlock* pBlock = pInfo->pSrcBlock; + uint64_t groupId = pBlock->info.groupId; + SSDataBlock* pRes = pInfo->pRes; + pRes->info.groupId = groupId; + if (hasRemainCalc(pFillInfo)) { + doStreamFillRange(pFillInfo, pFillSup, pRes); + } + + SColumnInfoData* pTsCol = taosArrayGet(pInfo->pSrcBlock->pDataBlock, pInfo->primaryTsCol); + TSKEY* tsCol = (TSKEY*)pTsCol->pData; + + if (pInfo->srcRowIndex == 0) { + keepBlockRowInDiscBuf(pOperator, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex, groupId, pFillSup->rowSize); + SSDataBlock* preBlock = pInfo->pPrevSrcBlock; + if (preBlock->info.rows > 0) { + int preRowId = preBlock->info.rows - 1; + SColumnInfoData* pPreTsCol = taosArrayGet(preBlock->pDataBlock, pInfo->primaryTsCol); + doFillResults(pOperator, pFillSup, pFillInfo, preBlock, (TSKEY*)pPreTsCol->pData, preRowId, pRes); + } + pInfo->srcRowIndex++; + } + + while (pInfo->srcRowIndex < pBlock->info.rows) { + TSKEY ts = tsCol[pInfo->srcRowIndex]; + keepBlockRowInDiscBuf(pOperator, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex, groupId, pFillSup->rowSize); + doFillResults(pOperator, pFillSup, pFillInfo, pBlock, tsCol, pInfo->srcRowIndex - 1, pRes); + if (pInfo->pRes->info.rows == pInfo->pRes->info.capacity) { + blockDataUpdateTsWindow(pRes, pInfo->primaryTsCol); + return; + } + pInfo->srcRowIndex++; + } + blockDataUpdateTsWindow(pRes, pInfo->primaryTsCol); + blockDataCleanup(pInfo->pPrevSrcBlock); + copyDataBlock(pInfo->pPrevSrcBlock, pInfo->pSrcBlock); + blockDataCleanup(pInfo->pSrcBlock); +} + +static void buildDeleteRange(TSKEY start, TSKEY end, uint64_t groupId, SSDataBlock* delRes) { + SSDataBlock* pBlock = delRes; + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + SColumnInfoData* pCalStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + SColumnInfoData* pCalEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + colDataAppend(pStartCol, pBlock->info.rows, (const char*)&start, false); + colDataAppend(pEndCol, pBlock->info.rows, (const char*)&end, false); + colDataAppendNULL(pUidCol, pBlock->info.rows); + colDataAppend(pGroupCol, pBlock->info.rows, (const char*)&groupId, false); + colDataAppendNULL(pCalStartCol, pBlock->info.rows); + colDataAppendNULL(pCalEndCol, pBlock->info.rows); + pBlock->info.rows++; +} + +static void buildDeleteResult(SStreamFillSupporter* pFillSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SSDataBlock* delRes) { + if (hasPrevWindow(pFillSup)) { + TSKEY start = getNextWindowTs(pFillSup->prev.key, &pFillSup->interval); + buildDeleteRange(start, endTs, groupId, delRes); + } else if (hasNextWindow(pFillSup)) { + TSKEY end = getPrevWindowTs(pFillSup->next.key, &pFillSup->interval); + buildDeleteRange(startTs, end, groupId, delRes); + } else { + buildDeleteRange(startTs, endTs, groupId, delRes); + } +} + +static void doDeleteFillResultImpl(SOperatorInfo* pOperator, TSKEY startTs, TSKEY endTs, uint64_t groupId) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + getWindowFromDiscBuf(pOperator, startTs, groupId, pInfo->pFillSup); + setDeleteFillValueInfo(startTs, endTs, pInfo->pFillSup, pInfo->pFillInfo); + SWinKey key = {.ts = startTs, .groupId = groupId}; + if (!pInfo->pFillInfo->needFill) { + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &key); + buildDeleteResult(pInfo->pFillSup, startTs, endTs, groupId, pInfo->pDelRes); + } else { + STimeRange tw = { + .skey = startTs, + .ekey = endTs, + .groupId = groupId, + }; + taosArrayPush(pInfo->pFillInfo->delRanges, &tw); + while (key.ts <= endTs) { + key.ts = taosTimeAdd(key.ts, pInfo->pFillSup->interval.sliding, pInfo->pFillSup->interval.slidingUnit, + pInfo->pFillSup->interval.precision); + tSimpleHashPut(pInfo->pFillSup->pResMap, &key, sizeof(SWinKey), NULL, 0); + } + } +} + +static void doDeleteFillFinalize(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + int32_t size = taosArrayGetSize(pFillInfo->delRanges); + tSimpleHashClear(pInfo->pFillSup->pResMap); + for (; pFillInfo->delIndex < size; pFillInfo->delIndex++) { + STimeRange* range = taosArrayGet(pFillInfo->delRanges, pFillInfo->delIndex); + if (pInfo->pRes->info.groupId != 0 && pInfo->pRes->info.groupId != range->groupId) { + return; + } + getWindowFromDiscBuf(pOperator, range->skey, range->groupId, pInfo->pFillSup); + setDeleteFillValueInfo(range->skey, range->ekey, pInfo->pFillSup, pInfo->pFillInfo); + if (pInfo->pFillInfo->needFill) { + doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); + pInfo->pRes->info.groupId = range->groupId; + } + SWinKey key = {.ts = range->skey, .groupId = range->groupId}; + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &key); + } +} + +static void doDeleteFillResult(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SStreamFillSupporter* pFillSup = pInfo->pFillSup; + SStreamFillInfo* pFillInfo = pInfo->pFillInfo; + SSDataBlock* pBlock = pInfo->pSrcDelBlock; + SSDataBlock* pRes = pInfo->pRes; + SSDataBlock* pDelRes = pInfo->pDelRes; + + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* tsStarts = (TSKEY*)pStartCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* groupIds = (uint64_t*)pGroupCol->pData; + while (pInfo->srcDelRowIndex < pBlock->info.rows) { + TSKEY ts = tsStarts[pInfo->srcDelRowIndex]; + TSKEY endTs = ts; + uint64_t groupId = groupIds[pInfo->srcDelRowIndex]; + SWinKey key = {.ts = ts, .groupId = groupId}; + SStreamStateCur* pCur = streamStateGetAndCheckCur(pOperator->pTaskInfo->streamInfo.pState, &key); + if (!pCur) { + pInfo->srcDelRowIndex++; + continue; + } + + SWinKey nextKey = {.groupId = groupId, .ts = ts}; + while (pInfo->srcDelRowIndex < pBlock->info.rows) { + void* nextVal = NULL; + int32_t nextLen = 0; + TSKEY delTs = tsStarts[pInfo->srcDelRowIndex]; + uint64_t delGroupId = groupIds[pInfo->srcDelRowIndex]; + int32_t code = TSDB_CODE_SUCCESS; + if (groupId != delGroupId) { + break; + } + if (delTs > nextKey.ts) { + break; + } + endTs = delTs; + SWinKey delKey = {.groupId = delGroupId, .ts = delTs}; + if (delTs == nextKey.ts) { + code = streamStateCurNext(pOperator->pTaskInfo->streamInfo.pState, pCur); + if (code == TSDB_CODE_SUCCESS) { + code = streamStateGetGroupKVByCur(pCur, &nextKey, (const void**)&nextVal, &nextLen); + } + if (delTs != ts) { + streamStateFillDel(pOperator->pTaskInfo->streamInfo.pState, &delKey); + } + if (code != TSDB_CODE_SUCCESS) { + break; + } + } + pInfo->srcDelRowIndex++; + } + doDeleteFillResultImpl(pOperator, ts, endTs, groupId); + } + pFillInfo->current = pFillInfo->end + 1; +} + +static void resetStreamFillInfo(SStreamFillOperatorInfo* pInfo) { + blockDataCleanup(pInfo->pPrevSrcBlock); + tSimpleHashClear(pInfo->pFillSup->pResMap); + pInfo->pFillSup->hasDelete = false; + taosArrayClear(pInfo->pFillInfo->delRanges); + pInfo->pFillInfo->delIndex = 0; +} + +static void doApplyStreamScalarCalculation(SOperatorInfo* pOperator, SSDataBlock* pSrcBlock, SSDataBlock* pDstBlock) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExprSupp* pSup = &pOperator->exprSupp; + + blockDataCleanup(pDstBlock); + blockDataEnsureCapacity(pDstBlock, pSrcBlock->info.rows); + setInputDataBlock(pOperator, pSup->pCtx, pSrcBlock, TSDB_ORDER_ASC, MAIN_SCAN, false); + projectApplyFunctions(pSup->pExprInfo, pDstBlock, pSrcBlock, pSup->pCtx, pSup->numOfExprs, NULL); + pDstBlock->info.groupId = pSrcBlock->info.groupId; + + SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, pInfo->primaryTsCol); + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, pInfo->primarySrcSlotId); + colDataAssign(pDst, pSrc, pDstBlock->info.rows, &pDstBlock->info); + + int32_t numOfNotFill = pInfo->pFillSup->numOfAllCols - pInfo->pFillSup->numOfFillCols; + for (int32_t i = 0; i < numOfNotFill; ++i) { + SFillColInfo* pCol = &pInfo->pFillSup->pAllColInfo[i + pInfo->pFillSup->numOfFillCols]; + ASSERT(pCol->notFillCol); + + SExprInfo* pExpr = pCol->pExpr; + int32_t srcSlotId = pExpr->base.pParam[0].pCol->slotId; + int32_t dstSlotId = pExpr->base.resSchema.slotId; + + SColumnInfoData* pDst1 = taosArrayGet(pDstBlock->pDataBlock, dstSlotId); + SColumnInfoData* pSrc1 = taosArrayGet(pSrcBlock->pDataBlock, srcSlotId); + colDataAssign(pDst1, pSrc1, pDstBlock->info.rows, &pDstBlock->info); + } + blockDataUpdateTsWindow(pDstBlock, pInfo->primaryTsCol); +} + +static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { + SStreamFillOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + blockDataCleanup(pInfo->pRes); + if (pOperator->status == OP_RES_TO_RETURN) { + if (hasRemainCalc(pInfo->pFillInfo)) { + doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); + if (pInfo->pRes->info.rows > 0) { + return pInfo->pRes; + } + } + doDeleteFillFinalize(pOperator); + if (pInfo->pRes->info.rows > 0) { + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; + } + doSetOperatorCompleted(pOperator); + resetStreamFillInfo(pInfo); + return NULL; + } + + SSDataBlock* fillResult = NULL; + SOperatorInfo* downstream = pOperator->pDownstream[0]; + while (1) { + if (pInfo->srcRowIndex >= pInfo->pSrcBlock->info.rows) { + // If there are delete datablocks, we receive them first. + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + pOperator->status = OP_RES_TO_RETURN; + SSDataBlock* preBlock = pInfo->pPrevSrcBlock; + if (preBlock->info.rows > 0) { + int preRowId = preBlock->info.rows - 1; + SColumnInfoData* pPreTsCol = taosArrayGet(preBlock->pDataBlock, pInfo->primaryTsCol); + doFillResults(pOperator, pInfo->pFillSup, pInfo->pFillInfo, preBlock, (TSKEY*)pPreTsCol->pData, preRowId, + pInfo->pRes); + } + pInfo->pFillInfo->preRowKey = INT64_MIN; + if (pInfo->pRes->info.rows > 0) { + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; + } + break; + } + printDataBlock(pBlock, "stream fill recv"); + + switch (pBlock->info.type) { + case STREAM_RETRIEVE: + return pBlock; + case STREAM_DELETE_RESULT: { + pInfo->pSrcDelBlock = pBlock; + pInfo->srcDelRowIndex = 0; + blockDataCleanup(pInfo->pDelRes); + pInfo->pFillSup->hasDelete = true; + doDeleteFillResult(pOperator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, "stream fill delete"); + return pInfo->pDelRes; + } + continue; + } break; + case STREAM_NORMAL: + case STREAM_INVALID: { + doApplyStreamScalarCalculation(pOperator, pBlock, pInfo->pSrcBlock); + pInfo->srcRowIndex = 0; + } break; + default: + ASSERT(0); + break; + } + } + + doStreamFillImpl(pOperator); + doFilter(pInfo->pCondition, pInfo->pRes, pInfo->pColMatchColInfo); + pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; + if (pInfo->pRes->info.rows > 0) { + break; + } + } + if (pOperator->status == OP_RES_TO_RETURN) { + doDeleteFillFinalize(pOperator); + } + + if (pInfo->pRes->info.rows == 0) { + doSetOperatorCompleted(pOperator); + resetStreamFillInfo(pInfo); + return NULL; + } + + pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; + printDataBlock(pInfo->pRes, "stream fill"); + return pInfo->pRes; +} + +static int32_t initResultBuf(SStreamFillSupporter* pFillSup) { + pFillSup->rowSize = sizeof(SResultCellData) * pFillSup->numOfAllCols; + for (int i = 0; i < pFillSup->numOfAllCols; i++) { + SFillColInfo* pCol = &pFillSup->pAllColInfo[i]; + SResSchema* pSchema = &pCol->pExpr->base.resSchema; + pFillSup->rowSize += pSchema->bytes; + } + pFillSup->next.key = INT64_MIN; + pFillSup->nextNext.key = INT64_MIN; + pFillSup->prev.key = INT64_MIN; + pFillSup->next.pRowVal = NULL; + pFillSup->nextNext.pRowVal = NULL; + pFillSup->prev.pRowVal = NULL; + return TSDB_CODE_SUCCESS; +} + +static SStreamFillSupporter* initStreamFillSup(SStreamFillPhysiNode* pPhyFillNode, SInterval* pInterval, + SExprInfo* pFillExprInfo, int32_t numOfFillCols) { + SStreamFillSupporter* pFillSup = taosMemoryCalloc(1, sizeof(SStreamFillSupporter)); + if (!pFillSup) { + return NULL; + } + pFillSup->numOfFillCols = numOfFillCols; + int32_t numOfNotFillCols = 0; + SExprInfo* pNotFillExprInfo = createExprInfo(pPhyFillNode->pNotFillExprs, NULL, &numOfNotFillCols); + pFillSup->pAllColInfo = createFillColInfo(pFillExprInfo, pFillSup->numOfFillCols, pNotFillExprInfo, numOfNotFillCols, + (const SNodeListNode*)(pPhyFillNode->pValues)); + pFillSup->type = convertFillType(pPhyFillNode->mode); + pFillSup->numOfAllCols = pFillSup->numOfFillCols + numOfNotFillCols; + pFillSup->interval = *pInterval; + + int32_t code = initResultBuf(pFillSup); + if (code != TSDB_CODE_SUCCESS) { + destroyStreamFillSupporter(pFillSup); + return NULL; + } + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pFillSup->pResMap = tSimpleHashInit(16, hashFn); + pFillSup->hasDelete = false; + return pFillSup; +} + +SStreamFillInfo* initStreamFillInfo(SStreamFillSupporter* pFillSup, SSDataBlock* pRes) { + SStreamFillInfo* pFillInfo = taosMemoryCalloc(1, sizeof(SStreamFillInfo)); + pFillInfo->start = INT64_MIN; + pFillInfo->current = INT64_MIN; + pFillInfo->end = INT64_MIN; + pFillInfo->preRowKey = INT64_MIN; + pFillInfo->needFill = false; + pFillInfo->pLinearInfo = taosMemoryCalloc(1, sizeof(SStreamFillLinearInfo)); + pFillInfo->pLinearInfo->hasNext = false; + pFillInfo->pLinearInfo->nextEnd = INT64_MIN; + pFillInfo->pLinearInfo->pDeltaVal = NULL; + pFillInfo->pLinearInfo->pNextDeltaVal = NULL; + if (pFillSup->type == TSDB_FILL_LINEAR) { + pFillInfo->pLinearInfo->pDeltaVal = taosArrayInit(pFillSup->numOfAllCols, sizeof(double)); + pFillInfo->pLinearInfo->pNextDeltaVal = taosArrayInit(pFillSup->numOfAllCols, sizeof(double)); + for (int32_t i = 0; i < pFillSup->numOfAllCols; i++) { + double value = 0.0; + taosArrayPush(pFillInfo->pLinearInfo->pDeltaVal, &value); + taosArrayPush(pFillInfo->pLinearInfo->pNextDeltaVal, &value); + } + } + pFillInfo->pLinearInfo->winIndex = 0; + + pFillInfo->pResRow = NULL; + if (pFillSup->type == TSDB_FILL_SET_VALUE || pFillSup->type == TSDB_FILL_NULL) { + pFillInfo->pResRow = taosMemoryCalloc(1, sizeof(SResultRowData)); + pFillInfo->pResRow->key = INT64_MIN; + pFillInfo->pResRow->pRowVal = taosMemoryCalloc(1, pFillSup->rowSize); + for (int32_t i = 0; i < pFillSup->numOfAllCols; ++i) { + SColumnInfoData* pColData = taosArrayGet(pRes->pDataBlock, i); + SResultCellData* pCell = getResultCell(pFillInfo->pResRow, i); + pCell->bytes = pColData->info.bytes; + pCell->type = pColData->info.type; + } + } + + pFillInfo->type = pFillSup->type; + pFillInfo->delRanges = taosArrayInit(16, sizeof(STimeRange)); + pFillInfo->delIndex = 0; + return pFillInfo; +} + +SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, + SExecTaskInfo* pTaskInfo) { + SStreamFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamFillOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + SInterval* pInterval = QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL == downstream->operatorType + ? &((SStreamFinalIntervalOperatorInfo*)downstream->info)->interval + : &((SStreamIntervalOperatorInfo*)downstream->info)->interval; + int32_t numOfFillCols = 0; + SExprInfo* pFillExprInfo = createExprInfo(pPhyFillNode->pFillExprs, NULL, &numOfFillCols); + pInfo->pFillSup = initStreamFillSup(pPhyFillNode, pInterval, pFillExprInfo, numOfFillCols); + if (!pInfo->pFillSup) { + goto _error; + } + + SResultInfo* pResultInfo = &pOperator->resultInfo; + initResultSizeInfo(&pOperator->resultInfo, 4096); + pInfo->pRes = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + pInfo->pSrcBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + pInfo->pPrevSrcBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc); + blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + blockDataEnsureCapacity(pInfo->pSrcBlock, pOperator->resultInfo.capacity); + blockDataEnsureCapacity(pInfo->pPrevSrcBlock, pOperator->resultInfo.capacity); + + pInfo->pFillInfo = initStreamFillInfo(pInfo->pFillSup, pInfo->pRes); + if (!pInfo->pFillInfo) { + goto _error; + } + + if (pInfo->pFillInfo->type == TSDB_FILL_SET_VALUE) { + for (int32_t i = 0; i < pInfo->pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pInfo->pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SResultCellData* pCell = getResultCell(pInfo->pFillInfo->pResRow, slotId); + SVariant* pVar = &(pFillCol->fillVal); + if (pCell->type == TSDB_DATA_TYPE_FLOAT) { + float v = 0; + GET_TYPED_DATA(v, float, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else if (pCell->type == TSDB_DATA_TYPE_DOUBLE) { + double v = 0; + GET_TYPED_DATA(v, double, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else if (IS_SIGNED_NUMERIC_TYPE(pCell->type)) { + int64_t v = 0; + GET_TYPED_DATA(v, int64_t, pVar->nType, &pVar->i); + SET_TYPED_DATA(pCell->pData, pCell->type, v); + } else { + pCell->isNull = true; + } + } + } else if (pInfo->pFillInfo->type == TSDB_FILL_NULL) { + for (int32_t i = 0; i < pInfo->pFillSup->numOfAllCols; ++i) { + SFillColInfo* pFillCol = pInfo->pFillSup->pAllColInfo + i; + int32_t slotId = GET_DEST_SLOT_ID(pFillCol); + SResultCellData* pCell = getResultCell(pInfo->pFillInfo->pResRow, slotId); + pCell->isNull = true; + } + } + + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + blockDataEnsureCapacity(pInfo->pDelRes, pOperator->resultInfo.capacity); + + pInfo->primaryTsCol = ((STargetNode*)pPhyFillNode->pWStartTs)->slotId; + pInfo->primarySrcSlotId = ((SColumnNode*)((STargetNode*)pPhyFillNode->pWStartTs)->pExpr)->slotId; + + int32_t numOfOutputCols = 0; + SArray* pColMatchColInfo = extractColMatchInfo(pPhyFillNode->pFillExprs, pPhyFillNode->node.pOutputDataBlockDesc, + &numOfOutputCols, COL_MATCH_FROM_SLOT_ID); + pInfo->pCondition = pPhyFillNode->node.pConditions; + pInfo->pColMatchColInfo = pColMatchColInfo; + initExprSupp(&pOperator->exprSupp, pFillExprInfo, numOfFillCols); + pInfo->srcRowIndex = 0; + + pOperator->name = "FillOperator"; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL; + pOperator->info = pInfo; + pOperator->pTaskInfo = pTaskInfo; + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStreamFill, NULL, NULL, destroyStreamFillOperatorInfo, + NULL, NULL, NULL); + + int32_t code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + return pOperator; + +_error: + destroyStreamFillOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + return NULL; +} diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index d292cda9d2..e441353f82 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -271,6 +271,10 @@ static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t o tw->ekey -= 1; } +void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) { + getNextTimeWindow(pInterval, pInterval->precision, order, tw); +} + void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) { SqlFunctionCtx* pCtx = pSup->pCtx; @@ -2095,12 +2099,17 @@ static void genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp bool hasInterp = true; for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) { SExprInfo* pExprInfo = &pExprSup->pExprInfo[j]; - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - // SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); + int32_t dstSlot = pExprInfo->base.resSchema.slotId; SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); + if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { + colDataAppend(pDst, rows, (char*)&pSliceInfo->current, false); + continue; + } + + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + // SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); switch (pSliceInfo->fillType) { case TSDB_FILL_NULL: { colDataAppendNULL(pDst, rows); @@ -2346,19 +2355,24 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (ts == pSliceInfo->current) { for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); + int32_t dstSlot = pExprInfo->base.resSchema.slotId; SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); - if (colDataIsNull_s(pSrc, i)) { - colDataAppendNULL(pDst, pResBlock->info.rows); - continue; - } + if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { + colDataAppend(pDst, pResBlock->info.rows, (char *)&pSliceInfo->current, false); + } else { + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); - char* v = colDataGetData(pSrc, i); - colDataAppend(pDst, pResBlock->info.rows, v, false); + if (colDataIsNull_s(pSrc, i)) { + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; + } + + char* v = colDataGetData(pSrc, i); + colDataAppend(pDst, pResBlock->info.rows, v, false); + } } pResBlock->info.rows += 1; @@ -2478,14 +2492,24 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (ts == pSliceInfo->current && pSliceInfo->current <= pSliceInfo->win.ekey) { for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; - SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); + int32_t dstSlot = pExprInfo->base.resSchema.slotId; SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); - char* v = colDataGetData(pSrc, i); - colDataAppend(pDst, pResBlock->info.rows, v, false); + if (IS_TIMESTAMP_TYPE(pExprInfo->base.resSchema.type)) { + colDataAppend(pDst, pResBlock->info.rows, (char *)&pSliceInfo->current, false); + } else { + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); + + if (colDataIsNull_s(pSrc, i)) { + colDataAppendNULL(pDst, pResBlock->info.rows); + continue; + } + + char* v = colDataGetData(pSrc, i); + colDataAppend(pDst, pResBlock->info.rows, v, false); + } } pResBlock->info.rows += 1; @@ -3146,20 +3170,21 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { } doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - if (pInfo->binfo.pRes->info.rows == 0) { - pOperator->status = OP_EXEC_DONE; - if (!IS_FINAL_OP(pInfo)) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamIntervalOperator(pInfo); - qDebug("===stream===clear semi operator"); - } else { - freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); - } - return NULL; + if (pInfo->binfo.pRes->info.rows != 0) { + printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + return pInfo->binfo.pRes; } - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->binfo.pRes; + + doSetOperatorCompleted(pOperator); + if (!IS_FINAL_OP(pInfo)) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamIntervalOperator(pInfo); + qDebug("===stream===clear semi operator"); + } else { + freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); + } + return NULL; } else { if (!IS_FINAL_OP(pInfo)) { doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); @@ -3316,7 +3341,13 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { return pInfo->pPullDataRes; } - // we should send result first. + doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + return pInfo->pDelRes; + } + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pInfo->binfo.pRes->info.rows != 0) { printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); @@ -3330,13 +3361,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { // process the rest of the data return pInfo->pUpdateRes; } - - doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pDelRes; - } return NULL; } @@ -5744,19 +5768,18 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval"); + printDataBlock(pInfo->pDelRes, "single interval delete"); return pInfo->pDelRes; } doBuildResult(pOperator, pInfo->binfo.pRes, &pInfo->groupResInfo); - // doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainResults(&pInfo->groupResInfo)) { - pOperator->status = OP_EXEC_DONE; - qDebug("===stream===single interval is done"); - freeAllPages(pInfo->pRecycledPages, pInfo->aggSup.pResultBuf); + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval"); + return pInfo->binfo.pRes; } - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes; + + doSetOperatorCompleted(pOperator); + return NULL; } SOperatorInfo* downstream = pOperator->pDownstream[0]; @@ -5823,24 +5846,24 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { } taosArraySort(pUpdated, resultrowComparAsc); - // new disc buf - // finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, - // pSup->rowEntryInfoOffset); initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); removeDeleteResults(pUpdatedMap, pInfo->pDelWins); taosHashCleanup(pUpdatedMap); + doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval"); + printDataBlock(pInfo->pDelRes, "single interval delete"); return pInfo->pDelRes; } - // doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); - // new disc buf doBuildResult(pOperator, pInfo->binfo.pRes, &pInfo->groupResInfo); - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes->info.rows == 0 ? NULL : pInfo->binfo.pRes; + if (pInfo->binfo.pRes->info.rows > 0) { + printDataBlock(pInfo->binfo.pRes, "single interval"); + return pInfo->binfo.pRes; + } + + return NULL; } void destroyStreamIntervalOperatorInfo(void* param) { diff --git a/source/libs/index/src/indexCache.c b/source/libs/index/src/indexCache.c index 7e867db755..39bba4e269 100644 --- a/source/libs/index/src/indexCache.c +++ b/source/libs/index/src/indexCache.c @@ -302,6 +302,7 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR char* p = taosMemoryCalloc(1, strlen(c->colVal) + 1); memcpy(p, c->colVal, strlen(c->colVal)); cond = cmpFn(p + skip, term->colVal, dType); + taosMemoryFree(p); } } if (cond == MATCH) { diff --git a/source/libs/index/src/indexFstFile.c b/source/libs/index/src/indexFstFile.c index 2a33ddd477..7021fdfae3 100644 --- a/source/libs/index/src/indexFstFile.c +++ b/source/libs/index/src/indexFstFile.c @@ -69,6 +69,8 @@ static int idxFileCtxDoReadFrom(IFileCtx* ctx, uint8_t* buf, int len, int32_t of int32_t blkOffset = offset % kBlockSize; int32_t blkLeft = kBlockSize - blkOffset; + if (offset >= ctx->file.size) return 0; + do { char key[128] = {0}; idxGenLRUKey(key, ctx->file.buf, blkId); @@ -80,24 +82,34 @@ static int idxFileCtxDoReadFrom(IFileCtx* ctx, uint8_t* buf, int len, int32_t of memcpy(buf + total, blk->buf + blkOffset, nread); taosLRUCacheRelease(ctx->lru, h, false); } else { - int32_t cacheMemSize = sizeof(SDataBlock) + kBlockSize; + int32_t left = ctx->file.size - offset; + if (left < kBlockSize) { + nread = TMIN(left, len); + int32_t bytes = taosPReadFile(ctx->file.pFile, buf + total, nread, offset); + assert(bytes == nread); - SDataBlock* blk = taosMemoryCalloc(1, cacheMemSize); - blk->blockId = blkId; - blk->nread = taosPReadFile(ctx->file.pFile, blk->buf, kBlockSize, blkId * kBlockSize); - assert(blk->nread <= kBlockSize); + total += bytes; + return total; + } else { + int32_t cacheMemSize = sizeof(SDataBlock) + kBlockSize; - if (blk->nread < kBlockSize && blk->nread < len) { - break; - } + SDataBlock* blk = taosMemoryCalloc(1, cacheMemSize); + blk->blockId = blkId; + blk->nread = taosPReadFile(ctx->file.pFile, blk->buf, kBlockSize, blkId * kBlockSize); + assert(blk->nread <= kBlockSize); - nread = TMIN(blkLeft, len); - memcpy(buf + total, blk->buf + blkOffset, nread); + if (blk->nread < kBlockSize && blk->nread < len) { + break; + } - LRUStatus s = taosLRUCacheInsert(ctx->lru, key, strlen(key), blk, cacheMemSize, deleteDataBlockFromLRU, NULL, - TAOS_LRU_PRIORITY_LOW); - if (s != TAOS_LRU_STATUS_OK) { - return -1; + nread = TMIN(blkLeft, len); + memcpy(buf + total, blk->buf + blkOffset, nread); + + LRUStatus s = taosLRUCacheInsert(ctx->lru, key, strlen(key), blk, cacheMemSize, deleteDataBlockFromLRU, NULL, + TAOS_LRU_PRIORITY_LOW); + if (s != TAOS_LRU_STATUS_OK) { + return -1; + } } } total += nread; @@ -146,9 +158,7 @@ IFileCtx* idxFileCtxCreate(WriterType type, const char* path, bool readOnly, int } else { ctx->file.pFile = taosOpenFile(path, TD_FILE_READ); - int64_t size = 0; taosFStatFile(ctx->file.pFile, &ctx->file.size, NULL); - ctx->file.size = (int)size; #ifdef USE_MMAP ctx->file.ptr = (char*)tfMmapReadOnly(ctx->file.pFile, ctx->file.size); #endif diff --git a/source/libs/index/test/jsonUT.cc b/source/libs/index/test/jsonUT.cc index 1911514d97..8ae3fd4135 100644 --- a/source/libs/index/test/jsonUT.cc +++ b/source/libs/index/test/jsonUT.cc @@ -172,9 +172,9 @@ TEST_F(JsonEnv, testWriteMillonData) { { std::string colName("voltagefdadfa"); std::string colVal("abxxxxxxxxxxxx"); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10000; i++) { colVal[i % colVal.size()] = '0' + i % 128; - for (size_t i = 0; i < 100; i++) { + for (size_t i = 0; i < 10; i++) { SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 78afadb75c..e401a3da7f 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -254,6 +254,7 @@ const char* nodesNodeName(ENodeType type) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return "PhysiStreamSemiInterval"; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return "PhysiFill"; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: return "PhysiSessionWindow"; @@ -4635,6 +4636,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return physiIntervalNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return physiFillNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: @@ -4788,6 +4790,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return jsonToPhysiIntervalNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return jsonToPhysiFillNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 989a4f5925..8d1d332ac7 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -3633,6 +3633,7 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { code = physiIntervalNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: code = physiFillNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: @@ -3770,6 +3771,7 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) { code = msgToPhysiIntervalNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: code = msgToPhysiFillNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 71e53bd9be..f8dda501e9 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -511,6 +511,7 @@ SNode* nodesMakeNode(ENodeType type) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: return makeNode(type, sizeof(SStreamSemiIntervalPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: return makeNode(type, sizeof(SFillPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: return makeNode(type, sizeof(SSessionWinodwPhysiNode)); @@ -1156,7 +1157,8 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode); break; - case QUERY_NODE_PHYSICAL_PLAN_FILL: { + case QUERY_NODE_PHYSICAL_PLAN_FILL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: { SFillPhysiNode* pPhyNode = (SFillPhysiNode*)pNode; destroyPhysiNode((SPhysiNode*)pPhyNode); nodesDestroyList(pPhyNode->pFillExprs); diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 421da8f110..810b82b9fc 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1409,7 +1409,9 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SFillLogicNode* pFillNode, SPhysiNode** pPhyNode) { - SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pFillNode, QUERY_NODE_PHYSICAL_PLAN_FILL); + SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode( + pCxt, (SLogicNode*)pFillNode, + pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL : QUERY_NODE_PHYSICAL_PLAN_FILL); if (NULL == pFill) { return TSDB_CODE_OUT_OF_MEMORY; } diff --git a/source/libs/scheduler/src/schJob.c b/source/libs/scheduler/src/schJob.c index 5e47c0a0ed..69495c8b7a 100644 --- a/source/libs/scheduler/src/schJob.c +++ b/source/libs/scheduler/src/schJob.c @@ -47,8 +47,7 @@ void schUpdateJobErrCode(SSchJob *pJob, int32_t errCode) { return; _return: - - SCH_JOB_DLOG("job errCode updated to %x - %s", errCode, tstrerror(errCode)); + SCH_JOB_DLOG("job errCode updated to %s", tstrerror(errCode)); } bool schJobDone(SSchJob *pJob) { @@ -491,7 +490,7 @@ int32_t schProcessOnJobFailure(SSchJob *pJob, int32_t errCode) { int32_t code = atomic_load_32(&pJob->errCode); if (code) { - SCH_JOB_DLOG("job failed with error: %s", tstrerror(code)); + SCH_JOB_DLOG("job failed with error %s", tstrerror(code)); } schPostJobRes(pJob, 0); diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index fde8bca77b..7f3e155a70 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -40,6 +40,11 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) { goto _err; } + // todo refactor + if (tdbTbOpen("func.state.db", sizeof(SWinKey), -1, SWinKeyCmpr, pState->db, &pState->pFillStateDb) < 0) { + goto _err; + } + if (tdbTbOpen("func.state.db", sizeof(STupleKey), -1, STupleKeyCmpr, pState->db, &pState->pFuncStateDb) < 0) { goto _err; } @@ -55,6 +60,7 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) { _err: tdbTbClose(pState->pStateDb); tdbTbClose(pState->pFuncStateDb); + tdbTbClose(pState->pFillStateDb); tdbClose(pState->db); taosMemoryFree(pState); return NULL; @@ -64,6 +70,7 @@ void streamStateClose(SStreamState* pState) { tdbCommit(pState->db, &pState->txn); tdbTbClose(pState->pStateDb); tdbTbClose(pState->pFuncStateDb); + tdbTbClose(pState->pFillStateDb); tdbClose(pState->db); taosMemoryFree(pState); @@ -126,14 +133,30 @@ int32_t streamStateFuncDel(SStreamState* pState, const STupleKey* key) { int32_t streamStatePut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen) { return tdbTbUpsert(pState->pStateDb, key, sizeof(SWinKey), value, vLen, &pState->txn); } + +// todo refactor +int32_t streamStateFillPut(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen) { + return tdbTbUpsert(pState->pFillStateDb, key, sizeof(SWinKey), value, vLen, &pState->txn); +} + int32_t streamStateGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { return tdbTbGet(pState->pStateDb, key, sizeof(SWinKey), pVal, pVLen); } +// todo refactor +int32_t streamStateFillGet(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { + return tdbTbGet(pState->pFillStateDb, key, sizeof(SWinKey), pVal, pVLen); +} + int32_t streamStateDel(SStreamState* pState, const SWinKey* key) { return tdbTbDelete(pState->pStateDb, key, sizeof(SWinKey), &pState->txn); } +// todo refactor +int32_t streamStateFillDel(SStreamState* pState, const SWinKey* key) { + return tdbTbDelete(pState->pFillStateDb, key, sizeof(SWinKey), &pState->txn); +} + int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen) { // todo refactor int32_t size = *pVLen; @@ -165,6 +188,31 @@ SStreamStateCur* streamStateGetCur(SStreamState* pState, const SWinKey* key) { return pCur; } +SStreamStateCur* streamStateFillGetCur(SStreamState* pState, const SWinKey* key) { + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + if (pCur == NULL) return NULL; + tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL); + + int32_t c; + tdbTbcMoveTo(pCur->pCur, key, sizeof(SWinKey), &c); + if (c != 0) { + taosMemoryFree(pCur); + return NULL; + } + return pCur; +} + +SStreamStateCur* streamStateGetAndCheckCur(SStreamState* pState, SWinKey* key) { + SStreamStateCur* pCur = streamStateFillGetCur(pState, key); + if (pCur) { + int32_t code = streamStateGetGroupKVByCur(pCur, key, NULL, 0); + if (code == 0) { + return pCur; + } + } + return NULL; +} + int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen) { const SWinKey* pKTmp = NULL; int32_t kLen; @@ -175,6 +223,17 @@ int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** return 0; } +int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen) { + uint64_t groupId = pKey->groupId; + int32_t code = streamStateGetKVByCur(pCur, pKey, pVal, pVLen); + if (code == 0) { + if (pKey->groupId == groupId) { + return 0; + } + } + return -1; +} + int32_t streamStateSeekFirst(SStreamState* pState, SStreamStateCur* pCur) { // return tdbTbcMoveToFirst(pCur->pCur); @@ -185,12 +244,12 @@ int32_t streamStateSeekLast(SStreamState* pState, SStreamStateCur* pCur) { return tdbTbcMoveToLast(pCur->pCur); } -SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key) { +SStreamStateCur* streamStateFillSeekKeyNext(SStreamState* pState, const SWinKey* key) { SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - if (tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL) < 0) { + if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) { taosMemoryFree(pCur); return NULL; } @@ -211,12 +270,12 @@ SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key return pCur; } -SStreamStateCur* streamStateSeekKeyPrev(SStreamState* pState, const SWinKey* key) { +SStreamStateCur* streamStateFillSeekKeyPrev(SStreamState* pState, const SWinKey* key) { SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - if (tdbTbcOpen(pState->pStateDb, &pCur->pCur, NULL) < 0) { + if (tdbTbcOpen(pState->pFillStateDb, &pCur->pCur, NULL) < 0) { taosMemoryFree(pCur); return NULL; } diff --git a/source/util/src/tqueue.c b/source/util/src/tqueue.c index eb70002680..eb62e12a19 100644 --- a/source/util/src/tqueue.c +++ b/source/util/src/tqueue.c @@ -151,15 +151,15 @@ int64_t taosQueueMemorySize(STaosQueue *queue) { void *taosAllocateQitem(int32_t size, EQItype itype) { STaosQnode *pNode = taosMemoryCalloc(1, sizeof(STaosQnode) + size); - pNode->size = size; - pNode->itype = itype; - pNode->timestamp = taosGetTimestampUs(); - if (pNode == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } + pNode->size = size; + pNode->itype = itype; + pNode->timestamp = taosGetTimestampUs(); + if (itype == RPC_QITEM) { int64_t alloced = atomic_add_fetch_64(&tsRpcQueueMemoryUsed, size); if (alloced > tsRpcQueueMemoryAllowed) { diff --git a/source/util/src/tuuid.c b/source/util/src/tuuid.c index 7460ccbc82..d192b1229d 100644 --- a/source/util/src/tuuid.c +++ b/source/util/src/tuuid.c @@ -20,8 +20,8 @@ static int32_t tUUIDSerialNo = 0; int32_t tGenIdPI32(void) { if (tUUIDHashId == 0) { - char uid[64]; - int32_t code = taosGetSystemUUID(uid, tListLen(uid)); + char uid[65] = {0}; + int32_t code = taosGetSystemUUID(uid, sizeof(uid)); if (code != TSDB_CODE_SUCCESS) { terrno = TAOS_SYSTEM_ERROR(errno); } else { diff --git a/source/util/src/tworker.c b/source/util/src/tworker.c index 1f0731812c..d9ded20070 100644 --- a/source/util/src/tworker.c +++ b/source/util/src/tworker.c @@ -46,7 +46,7 @@ int32_t tQWorkerInit(SQWorkerPool *pool) { void tQWorkerCleanup(SQWorkerPool *pool) { for (int32_t i = 0; i < pool->max; ++i) { SQWorker *worker = pool->workers + i; - if (worker == NULL) continue; + // if (worker == NULL) continue; if (taosCheckPthreadValid(worker->thread)) { taosQsetThreadResume(pool->qset); } @@ -54,7 +54,7 @@ void tQWorkerCleanup(SQWorkerPool *pool) { for (int32_t i = 0; i < pool->max; ++i) { SQWorker *worker = pool->workers + i; - if (worker == NULL) continue; + // if (worker == NULL) continue; if (taosCheckPthreadValid(worker->thread)) { taosThreadJoin(worker->thread, NULL); taosThreadClear(&worker->thread); @@ -138,8 +138,8 @@ STaosQueue *tQWorkerAllocQueue(SQWorkerPool *pool, void *ahandle, FItem fp) { } void tQWorkerFreeQueue(SQWorkerPool *pool, STaosQueue *queue) { - taosCloseQueue(queue); uDebug("worker:%s, queue:%p is freed", pool->name, queue); + taosCloseQueue(queue); } int32_t tWWorkerInit(SWWorkerPool *pool) { @@ -283,8 +283,8 @@ STaosQueue *tWWorkerAllocQueue(SWWorkerPool *pool, void *ahandle, FItems fp) { } void tWWorkerFreeQueue(SWWorkerPool *pool, STaosQueue *queue) { - taosCloseQueue(queue); uDebug("worker:%s, queue:%p is freed", pool->name, queue); + taosCloseQueue(queue); } int32_t tSingleWorkerInit(SSingleWorker *pWorker, const SSingleWorkerCfg *pCfg) { diff --git a/tests/script/tsim/stream/deleteInterval.sim b/tests/script/tsim/stream/deleteInterval.sim index 00d10afad9..7532b2d5de 100644 --- a/tests/script/tsim/stream/deleteInterval.sim +++ b/tests/script/tsim/stream/deleteInterval.sim @@ -413,13 +413,8 @@ if $data12 != 3 then goto loop14 endi -return 1 -sql drop stream if exists streams3; -sql drop database if exists test3; -sql drop database if exists test; sql create database test3 vgroups 4; -sql create database test vgroups 1; sql use test3; sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); sql create table t1 using st tags(1,1,1); @@ -435,7 +430,7 @@ sql delete from t1; loop15: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -453,7 +448,7 @@ sql delete from t1 where ts > 100; loop16: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -471,7 +466,7 @@ sql delete from st; loop17: sleep 200 -sql select * from test.streamt2 order by c1, c2, c3; +sql select * from test.streamt3 order by c1, c2, c3; $loop_count = $loop_count + 1 if $loop_count == 10 then diff --git a/tests/script/tsim/stream/fillIntervalDelete0.sim b/tests/script/tsim/stream/fillIntervalDelete0.sim new file mode 100644 index 0000000000..77d09d5ae8 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalDelete0.sim @@ -0,0 +1,375 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791213000,1,1,1,1.0,'aaa'); +sleep 200 + +$loop_count = 0 + +loop0: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows=$rows + goto loop0 +endi + +sql delete from t1; + +$loop_count = 0 + +loop1: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 0 then + print =====rows1=$rows + goto loop1 +endi + +sql select * from streamt2 order by ts; + +if $rows != 0 then + print =====rows2=$rows + goto loop1 +endi + +sql select * from streamt3 order by ts; + +if $rows != 0 then + print =====rows3=$rows + goto loop1 +endi + +sql select * from streamt4 order by ts; + +if $rows != 0 then + print =====rows4=$rows + goto loop1 +endi + +sql select * from streamt5 order by ts; + +if $rows != 0 then + print =====rows5=$rows + goto loop1 +endi + +sql insert into t1 values(1648791210000,4,4,4,4.0,'ddd'); +sql insert into t1 values(1648791215000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791217000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791219000,5,5,5,5.0,'eee'); + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 10 then + print =====rows=$rows + goto loop2 +endi + +#temp +system sh/stop_dnodes.sh +return 1 + +sql delete from t1 where ts >= 1648791214000; + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows1=$rows + goto loop3 +endi + +sql select * from streamt2 order by ts; + +if $rows != 1 then + print =====rows2=$rows + goto loop3 +endi + +sql select * from streamt3 order by ts; + +if $rows != 1 then + print =====rows3=$rows + goto loop3 +endi + +sql select * from streamt4 order by ts; + +if $rows != 1 then + print =====rows4=$rows + goto loop3 +endi + +sql select * from streamt5 order by ts; + +if $rows != 1 then + print =====rows5=$rows + goto loop3 +endi + +if $data01 != 4 then + print =====data01=$data01 + return -1 +endi + + + +sql insert into t1 values(1648791213000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791219000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop4: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 4 then + print =====rows=$rows + goto loop4 +endi + + +sql delete from t1 where ts <= 1648791216000; + +$loop_count = 0 + +loop5: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 1 then + print =====rows1=$rows + goto loop5 +endi + +sql select * from streamt2 order by ts; + +if $rows != 1 then + print =====rows2=$rows + goto loop5 +endi + +sql select * from streamt3 order by ts; + +if $rows != 1 then + print =====rows3=$rows + goto loop5 +endi + +sql select * from streamt4 order by ts; + +if $rows != 1 then + print =====rows4=$rows + goto loop5 +endi + +sql select * from streamt5 order by ts; + +if $rows != 1 then + print =====rows5=$rows + goto loop5 +endi + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi + + + + +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; +sql drop database if exists test6; +sql create database test6 vgroups 1; +sql use test6; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(1,1,1); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams9 trigger at_once into streamt9 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams10 trigger at_once into streamt10 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,1,1,1,1.0,'aaa'); + +sql insert into t2 values(1648791215000,1,1,1,1.0,'aaa'); + +sleep 200 + +$loop_count = 0 + +loop7: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 8 then + print =====rows=$rows + goto loop7 +endi + +sql delete from t1; + +$loop_count = 0 + +loop8: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 0 then + print =====rows6=$rows + goto loop8 +endi + +sql select * from streamt7 order by ts; + +if $rows != 0 then + print =====rows7=$rows + goto loop8 +endi + +sql select * from streamt8 order by ts; + +if $rows != 0 then + print =====rows8=$rows + goto loop8 +endi + +sql select * from streamt9 order by ts; + +if $rows != 0 then + print =====rows9=$rows + goto loop8 +endi + +sql select * from streamt10 order by ts; + +if $rows != 0 then + print =====rows10=$rows + goto loop8 +endi + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalDelete1.sim b/tests/script/tsim/stream/fillIntervalDelete1.sim new file mode 100644 index 0000000000..8e6972975e --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalDelete1.sim @@ -0,0 +1,379 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a), sum(b), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,0,0,0,0.0,'aaa'); +sql insert into t1 values(1648791213000,1,1,1,1.0,'bbb'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'ccc'); +sql insert into t1 values(1648791217000,6,6,6,6.0,'ddd'); + +$loop_count = 0 + +loop0: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print =====rows=$rows + goto loop0 +endi + + +sql delete from t1 where ts = 1648791213000; + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print ====streamt1=rows1=$rows + goto loop2 +endi +if $data31 != NULL then + print ====streamt1=data31=$data31 + goto loop2 +endi + +sql select * from streamt2 order by ts; + +if $rows != 8 then + print ====streamt2=rows2=$rows + goto loop2 +endi +if $data31 != 100 then + print ====streamt2=data31=$data31 + goto loop2 +endi + +sql select * from streamt3 order by ts; + +if $rows != 8 then + print ====streamt3=rows3=$rows + goto loop2 +endi +if $data31 != 5 then + print ====streamt3=data31=$data31 + goto loop2 +endi + +sql select * from streamt4 order by ts; + +if $rows != 8 then + print ====streamt4=rows4=$rows + goto loop2 +endi +if $data31 != 0 then + print ====streamt4=data31=$data31 + goto loop2 +endi + +sql select * from streamt5 order by ts; + +if $rows != 8 then + print ====streamt5=rows5=$rows + goto loop2 +endi +if $data31 != 3 then + print ====streamt5=data31=$data31 + goto loop2 +endi + + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791213000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $data21 != 5 then + print ====133=rows=$rows + goto loop3 +endi +if $data31 != 6 then + print ====137=rows=$rows + goto loop3 +endi + + +sql delete from t1 where ts >= 1648791211000 and ts <= 1648791214000; + +$loop_count = 0 + +loop4: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by ts; + +if $rows != 8 then + print ====streamt1=rows1=$rows + goto loop4 +endi +if $data31 != NULL then + print ====streamt1=data31=$data31 + goto loop4 +endi + +sql select * from streamt2 order by ts; + +if $rows != 8 then + print ====streamt2=rows2=$rows + goto loop4 +endi +if $data31 != 100 then + print ====streamt2=data31=$data31 + goto loop4 +endi + +sql select * from streamt3 order by ts; + +if $rows != 8 then + print ====streamt3=rows3=$rows + goto loop4 +endi +if $data31 != 5 then + print ====streamt3=data31=$data31 + goto loop4 +endi + +sql select * from streamt4 order by ts; + +if $rows != 8 then + print ====streamt4=rows4=$rows + goto loop4 +endi +if $data31 != 0 then + print ====streamt4=data31=$data31 + goto loop4 +endi + +sql select * from streamt5 order by ts; + +if $rows != 8 then + print ====streamt5=rows5=$rows + goto loop4 +endi +if $data31 != 3 then + print ====streamt5=data31=$data31 + goto loop4 +endi + + + +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; +sql drop database if exists test6; +sql create database test6 vgroups 1; +sql use test6; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(1,1,1); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(NULL); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value,100,200,300); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql create stream streams9 trigger at_once into streamt9 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams10 trigger at_once into streamt10 as select _wstart as ts, max(a), sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791215000,6,8,8,8.0,'bbb'); +sql insert into t1 values(1648791220000,11,10,10,10.0,'ccc'); +sql insert into t1 values(1648791221000,6,6,6,6.0,'fff'); + +sql insert into t2 values(1648791212000,4,4,4,4.0,'ddd'); +sql insert into t2 values(1648791214000,5,5,5,5.0,'eee'); +sql insert into t2 values(1648791216000,2,2,2,2.0,'bbb'); +sql insert into t2 values(1648791222000,6,6,6,6.0,'fff'); + +$loop_count = 0 + +loop5: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 13 then + print ====streamt6=rows1=$rows + goto loop5 +endi +if $data21 != 4 then + print ====streamt6=data21=$data21 + goto loop5 +endi + +sql delete from t2; +print delete from t2; + +$loop_count = 0 + +loop6: + +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt6 order by ts; + +if $rows != 12 then + print ====streamt6=rows2=$rows + goto loop6 +endi +if $data31 != NULL then + print ====streamt6=data31=$data31 + goto loop6 +endi + + +sql select * from streamt7 order by ts; + +if $rows != 12 then + print ====streamt7=rows2=$rows + goto loop6 +endi +if $data31 != 100 then + print ====streamt7=data31=$data31 + goto loop6 +endi + +sql select * from streamt8 order by ts; + +if $rows != 12 then + print ====streamt8=rows3=$rows + goto loop6 +endi +if $data31 != 6 then + print ====streamt8=data31=$data31 + goto loop6 +endi + +sql select * from streamt9 order by ts; + +if $rows != 12 then + print ====streamt9=rows4=$rows + goto loop6 +endi +if $data31 != 1 then + print ====streamt9=data31=$data31 + goto loop6 +endi + +sql select * from streamt10 order by ts; + +if $rows != 12 then + print ====streamt10=rows5=$rows + goto loop6 +endi +if $data21 != 3 then + print ====streamt10=data21=$data21 + return -1 +endi +if $data31 != 4 then + print ====streamt10=data31=$data31 + return -1 +endi +if $data71 != 8 then + print ====streamt10=data71=$data71 + return -1 +endi +if $data91 != 10 then + print ====streamt10=data91=$data91 + return -1 +endi + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalLinear.sim b/tests/script/tsim/stream/fillIntervalLinear.sim new file mode 100644 index 0000000000..46ff785fd3 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalLinear.sim @@ -0,0 +1,695 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a)+sum(c), avg(b), first(s), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791216000,5,5,5,5.0,'bbb'); +sql insert into t1 values(1648791210000,1,1,1,1.0,'ccc') (1648791219000,2,2,2,2.0,'ddd') (1648791222000,3,3,3,3.0,'eee'); + + +$loop_count = 0 + +loop1: +sleep 200 +sql use test1; +sql select * from streamt1 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 13 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 2.000000000 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi +if $data04 != 1 then + print =====data04=$data04 + return -1 +endi + + +if $data11 != 4.000000000 then + print =====data11=$data11 + return -1 +endi +if $data12 != 2.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 6.000000000 then + print =====data21=$data21 + return -1 +endi +if $data22 != 3.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != NULL then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 8.000000000 then + print =====data31=$data31 + return -1 +endi +if $data32 != 4.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != aaa then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 8.666666667 then + print =====data41=$data41 + return -1 +endi +if $data42 != 4.333333333 then + print =====data42=$data42 + return -1 +endi +if $data43 != NULL then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 9.333333333 then + print =====data01=$data01 + return -1 +endi +if $data52 != 4.666666667 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 10.000000000 then + print =====data61=$data61 + return -1 +endi +if $data62 != 5.000000000 then + print =====data62=$data62 + return -1 +endi + + +if $data71 != 8.000000000 then + print =====data71=$data71 + return -1 +endi +if $data72 != 4.000000000 then + print =====data72=$data72 + return -1 +endi + + +if $data81 != 6.000000000 then + print =====data81=$data81 + return -1 +endi +if $data82 != 3.000000000 then + print =====data82=$data82 + return -1 +endi + + +if $data91 != 4.000000000 then + print =====data91=$data91 + return -1 +endi +if $data92 != 2.000000000 then + print =====data92=$data92 + return -1 +endi + +if $data[10][1] != 4.666666667 then + print =====data[10][1]=$data[10][1] + return -1 +endi +if $data[10][2] != 2.333333333 then + print =====data[10][2]=$data[10][2] + return -1 +endi + + +if $data[11][1] != 5.333333333 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 2.666666667 then + print =====data[11][2]=$data[11][2] + return -1 +endi + + +if $data[12][1] != 6.000000000 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 3.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi + + + +sql drop stream if exists streams2; +sql drop database if exists test2; +sql create database test2 vgroups 1; +sql use test2; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a)+sum(c), avg(b), first(s), count(*) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791210000,1,1,1,1.0,'ccc') (1648791219000,2,2,2,2.0,'ddd') (1648791222000,3,3,3,3.0,'eee'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791216000,5,5,5,5.0,'bbb'); + + +$loop_count = 0 + +loop2: + +sleep 200 + +sql select * from streamt2 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 13 then + print =====rows=$rows + goto loop2 +endi + +if $data01 != 2.000000000 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi +if $data04 != 1 then + print =====data04=$data04 + return -1 +endi + + +if $data11 != 4.000000000 then + print =====data11=$data11 + return -1 +endi +if $data12 != 2.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 6.000000000 then + print =====data21=$data21 + return -1 +endi +if $data22 != 3.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != NULL then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 8.000000000 then + print =====data31=$data31 + return -1 +endi +if $data32 != 4.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != aaa then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 8.666666667 then + print =====data41=$data41 + return -1 +endi +if $data42 != 4.333333333 then + print =====data42=$data42 + return -1 +endi +if $data43 != NULL then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 9.333333333 then + print =====data01=$data01 + return -1 +endi +if $data52 != 4.666666667 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 10.000000000 then + print =====data61=$data61 + return -1 +endi +if $data62 != 5.000000000 then + print =====data62=$data62 + return -1 +endi + + +if $data71 != 8.000000000 then + print =====data71=$data71 + return -1 +endi +if $data72 != 4.000000000 then + print =====data72=$data72 + return -1 +endi + + +if $data81 != 6.000000000 then + print =====data81=$data81 + return -1 +endi +if $data82 != 3.000000000 then + print =====data82=$data82 + return -1 +endi + + +if $data91 != 4.000000000 then + print =====data91=$data91 + return -1 +endi +if $data92 != 2.000000000 then + print =====data92=$data92 + return -1 +endi + +if $data[10][1] != 4.666666667 then + print =====data[10][1]=$data[10][1] + return -1 +endi +if $data[10][2] != 2.333333333 then + print =====data[10][2]=$data[10][2] + return -1 +endi + + +if $data[11][1] != 5.333333333 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 2.666666667 then + print =====data[11][2]=$data[11][2] + return -1 +endi + + +if $data[12][1] != 6.000000000 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 3.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi + + + +sql drop stream if exists streams3; +sql drop database if exists test3; +sql create database test3 vgroups 1; +sql use test3; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a), b+c, s, b+1, 1 from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(linear); +sql insert into t1 values(1648791215000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791211000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'ddd'); + + +$loop_count = 0 + +loop3: +sleep 300 +sql select * from streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 7 then + print =====rows=$rows + goto loop3 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 6.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi + +if $data11 != 3 then + print =====data11=$data11 + return -1 +endi +if $data12 != 7.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 8.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ddd then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 2 then + print =====data31=$data31 + return -1 +endi +if $data32 != 5.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != NULL then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 2.000000000 then + print =====data42=$data42 + return -1 +endi +if $data43 != aaa then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 1 then + print =====data51=$data51 + return -1 +endi +if $data52 != 3.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != NULL then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 4.000000000 then + print =====data62=$data62 + return -1 +endi +if $data63 != bbb then + print =====data63=$data63 + return -1 +endi + + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791207000,6,6,6,6.0,'fff') (1648791209000,7,7,7,7.0,'ggg') (1648791219000,8,8,8,8.0,'hhh') (1648791221000,9,9,9,9.0,'iii'); + + + +$loop_count = 0 + +loop4: + +sleep 200 + +sql select * from test3.streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 15 then + print =====rows=$rows + goto loop4 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 12.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != fff then + print =====data03=$data03 + return -1 +endi + +if $data11 != 6 then + print =====data11=$data11 + return -1 +endi +if $data12 != 13.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != NULL then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data22 != 14.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ggg then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 5 then + print =====data31=$data31 + return -1 +endi +if $data32 != 10.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != NULL then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data52 != 10.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != eee then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 5 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 10.000000000 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != NULL then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 16.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi +if $data[12][3] != hhh then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 8 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][2] != 17.000000000 then + print =====data[13][2]=$data[13][2] + return -1 +endi +if $data[13][3] != NULL then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][2] != 18.000000000 then + print =====data[14][2]=$data[14][2] + return -1 +endi +if $data[14][3] != iii then + print =====data[14][3]=$data[14][3] + return -1 +endi + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalPartitionBy.sim b/tests/script/tsim/stream/fillIntervalPartitionBy.sim new file mode 100644 index 0000000000..384aa2c8e4 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalPartitionBy.sim @@ -0,0 +1,171 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create stable st(ts timestamp, a int, b int , c int, d double, s varchar(20)) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(NULL); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(value,100,200,300); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(next); +sql create stream streams4 trigger at_once into streamt4 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(prev); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, max(a) c1, sum(b), count(*) from st where ts >= 1648791210000 and ts < 1648791261000 partition by ta interval(1s) fill(linear); + +sql insert into t1 values(1648791210000,0,0,0,0.0,'aaa'); +sql insert into t1 values(1648791213000,1,1,1,1.0,'bbb'); +sql insert into t1 values(1648791215000,5,5,5,5.0,'ccc'); +sql insert into t1 values(1648791216000,6,6,6,6.0,'ddd'); +sql insert into t2 values(1648791210000,7,0,0,0.0,'aaa'); +sql insert into t2 values(1648791213000,8,1,1,1.0,'bbb'); +sql insert into t2 values(1648791215000,9,5,5,5.0,'ccc'); +sql insert into t2 values(1648791216000,10,6,6,6.0,'ddd'); + +$loop_count = 0 + +loop2: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +sql select * from streamt1 order by group_id, ts; + +if $rows != 14 then + print ====streamt1=rows1=$rows + goto loop2 +endi + +sql select * from streamt2 order by group_id, ts; + +if $rows != 14 then + print ====streamt2=rows2=$rows + goto loop2 +endi + +sql select * from streamt3 order by group_id, ts; + +if $rows != 14 then + print ====streamt3=rows3=$rows + goto loop2 +endi + +sql select * from streamt4 order by group_id, ts; + +if $rows != 14 then + print ====streamt4=rows4=$rows + goto loop2 +endi + +sql select * from streamt5 order by group_id, ts; + +if $rows != 14 then + print ====streamt5=rows5=$rows + goto loop2 +endi + +sql delete from t1 where ts = 1648791216000; +print ======delete from t1 where ts = 1648791216000; + +$loop_count = 0 + +loop3: +sleep 200 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt1 order by group_id, ts; + +if $rows != 13 then + print ====streamt1=rows1=$rows + goto loop3 +endi + +sql select * from streamt2 order by group_id, ts; + +if $rows != 13 then + print ====streamt2=rows2=$rows + goto loop3 +endi + +sql select * from streamt3 order by group_id, ts; + +if $rows != 13 then + print ====streamt3=rows3=$rows + goto loop3 +endi + +sql select * from streamt4 order by group_id, ts; + +if $rows != 13 then + print ====streamt4=rows4=$rows + goto loop3 +endi + +sql select * from streamt5 order by group_id, ts; + +if $rows != 13 then + print ====streamt5=rows5=$rows + goto loop3 +endi + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop stream if exists streams9; +sql drop stream if exists streams10; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalPrevNext.sim b/tests/script/tsim/stream/fillIntervalPrevNext.sim new file mode 100644 index 0000000000..5eab5fdac1 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalPrevNext.sim @@ -0,0 +1,1036 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop database if exists test1; +sql create database test1 vgroups 1; +sql use test1; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams1 trigger at_once into streamt1 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, count(*) c1, max(a)+min(c), avg(b) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); + + +$loop_count = 0 + +loop1: +sleep 200 +sql use test1; +sql select * from streamt1 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi + + +if $data11 != 1 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 2.000000000 then + print =====data12=$data12 + goto loop1 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi + + +if $data31 != 1 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 8.000000000 then + print =====data32=$data32 + goto loop1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop1 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi + + +if $data51 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data52 != 10.000000000 then + print =====data52=$data52 + goto loop1 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop1 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop1 +endi + +if $data72 != 4.000000000 then + print =====data72=$data72 + goto loop1 +endi + + +if $data81 != 1 then + print =====data81=$data81 + goto loop1 +endi + +if $data82 != 4.000000000 then + print =====data82=$data82 + goto loop1 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop1 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop1 +endi + +sql use test1; +sql select * from streamt2 order by ts; + +print next----------------------151 + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi +if $data03 != 1.000000000 then + print =====data03=$data03 + goto loop1 +endi + +if $data12 != 8.000000000 then + print =====data12=$data12 + goto loop1 +endi +if $data13 != 4.000000000 then + print =====data13=$data13 + goto loop1 +endi + + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi +if $data23 != 4.000000000 then + print =====data23=$data23 + goto loop1 +endi + + +if $data32 != 10.000000000 then + print =====data32=$data32 + goto loop1 +endi +if $data33 != 5.000000000 then + print =====data33=$data33 + goto loop1 +endi + + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi +if $data43 != 5.000000000 then + print =====data43=$data43 + goto loop1 +endi + + +if $data52 != 4.000000000 then + print =====data52=$data52 + goto loop1 +endi +if $data53 != 2.000000000 then + print =====data53=$data53 + goto loop1 +endi + + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi +if $data63 != 2.000000000 then + print =====data63=$data63 + goto loop1 +endi + + +if $data72 != 6.000000000 then + print =====data72=$data72 + return -1 +endi +if $data73 != 3.000000000 then + print =====data73=$data73 + return -1 +endi + + +if $data82 != 6.000000000 then + print =====data82=$data82 + return -1 +endi +if $data83 != 3.000000000 then + print =====data83=$data83 + return -1 +endi + + +if $data92 != 6.000000000 then + print =====data92=$data92 + return -1 +endi +if $data93 != 3.000000000 then + print =====data93=$data93 + return -1 +endi + + + +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop database if exists test5; +sql create database test5 vgroups 1; +sql use test5; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams5 trigger at_once into streamt5 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams6 trigger at_once into streamt6 as select _wstart as ts, count(*) c1, max(a)+min(c), avg(b) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); + +$loop_count = 0 + +loop5: +sleep 200 +sql select * from streamt5 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop5 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop5 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop5 +endi + + +if $data11 != 1 then + print =====data11=$data11 + goto loop5 +endi + +if $data12 != 2.000000000 then + print =====data12=$data12 + goto loop5 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop5 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop5 +endi + + +if $data31 != 1 then + print =====data31=$data31 + goto loop5 +endi + +if $data32 != 8.000000000 then + print =====data32=$data32 + goto loop5 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop5 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop5 +endi + + +if $data51 != 1 then + print =====data01=$data01 + goto loop5 +endi + +if $data52 != 10.000000000 then + print =====data52=$data52 + goto loop5 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop5 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop5 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop5 +endi + +if $data72 != 4.000000000 then + print =====data72=$data72 + goto loop5 +endi + + +if $data81 != 1 then + print =====data81=$data81 + goto loop5 +endi + +if $data82 != 4.000000000 then + print =====data82=$data82 + goto loop5 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop5 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop5 +endi + + +$loop_count = 0 + +loop6: + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sleep 200 + +sql select * from streamt6 order by ts; + +if $rows != 10 then + print =====rows=$rows + goto loop6 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop6 +endi +if $data03 != 1.000000000 then + print =====data03=$data03 + goto loop6 +endi + +if $data12 != 8.000000000 then + print =====data12=$data12 + goto loop6 +endi +if $data13 != 4.000000000 then + print =====data13=$data13 + goto loop6 +endi + + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop6 +endi +if $data23 != 4.000000000 then + print =====data23=$data23 + goto loop6 +endi + + +if $data32 != 10.000000000 then + print =====data32=$data32 + goto loop6 +endi +if $data33 != 5.000000000 then + print =====data33=$data33 + goto loop6 +endi + + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop6 +endi +if $data43 != 5.000000000 then + print =====data43=$data43 + goto loop6 +endi + + +if $data52 != 4.000000000 then + print =====data52=$data52 + goto loop6 +endi +if $data53 != 2.000000000 then + print =====data53=$data53 + goto loop6 +endi + + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop6 +endi +if $data63 != 2.000000000 then + print =====data63=$data63 + goto loop6 +endi + + +if $data72 != 6.000000000 then + print =====data72=$data72 + return -1 +endi +if $data73 != 3.000000000 then + print =====data73=$data73 + return -1 +endi + + +if $data82 != 6.000000000 then + print =====data82=$data82 + return -1 +endi +if $data83 != 3.000000000 then + print =====data83=$data83 + return -1 +endi + + +if $data92 != 6.000000000 then + print =====data92=$data92 + return -1 +endi +if $data93 != 3.000000000 then + print =====data93=$data93 + return -1 +endi + + + +sql drop stream if exists streams7; +sql drop stream if exists streams8; +sql drop database if exists test7; +sql create database test7 vgroups 1; +sql use test7; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams7 trigger at_once into streamt7 as select _wstart as ts, max(a), b+c, s from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(prev); +sql create stream streams8 trigger at_once into streamt8 as select _wstart as ts, max(a), 1, b+1 from t1 where ts >= 1648791150000 and ts < 1648791261000 interval(1s) fill(next); +sql insert into t1 values(1648791215000,1,1,1,1.0,'aaa'); +sql insert into t1 values(1648791217000,2,2,2,2.0,'bbb'); +sql insert into t1 values(1648791211000,3,3,3,3.0,'ccc'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'ddd'); + + +$loop_count = 0 + +loop7: +sleep 300 +sql select * from streamt7 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 7 then + print =====rows=$rows + goto loop7 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 6.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != ccc then + print =====data03=$data03 + return -1 +endi + +if $data11 != 3 then + print =====data11=$data11 + return -1 +endi +if $data12 != 6.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != ccc then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 8.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ddd then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 4 then + print =====data31=$data31 + return -1 +endi +if $data32 != 8.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != ddd then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 2.000000000 then + print =====data42=$data42 + return -1 +endi +if $data43 != aaa then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 1 then + print =====data51=$data51 + return -1 +endi +if $data52 != 2.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != aaa then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 4.000000000 then + print =====data62=$data62 + return -1 +endi +if $data63 != bbb then + print =====data63=$data63 + return -1 +endi + +#-------------- + +sleep 200 +sql select * from streamt8 order by ts; + + +if $rows != 7 then + print =====rows=$rows + return -1 +endi + + +if $data01 != 3 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1 then + print =====data02=$data02 + return -1 +endi +if $data03 != 4.000000000 then + print =====data03=$data03 + return -1 +endi + +if $data11 != 4 then + print =====data11=$data11 + return -1 +endi +if $data12 != 1 then + print =====data12=$data12 + return -1 +endi +if $data13 != 5.000000000 then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 4 then + print =====data21=$data21 + return -1 +endi +if $data22 != 1 then + print =====data22=$data22 + return -1 +endi +if $data23 != 5.000000000 then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 1 then + print =====data31=$data31 + return -1 +endi +if $data32 != 1 then + print =====data32=$data32 + return -1 +endi +if $data33 != 2.000000000 then + print =====data33=$data33 + return -1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + return -1 +endi +if $data42 != 1 then + print =====data42=$data42 + return -1 +endi +if $data43 != 2.000000000 then + print =====data43=$data43 + return -1 +endi + + +if $data51 != 2 then + print =====data51=$data51 + return -1 +endi +if $data52 != 1 then + print =====data52=$data52 + return -1 +endi +if $data53 != 3.000000000 then + print =====data53=$data53 + return -1 +endi + + +if $data61 != 2 then + print =====data61=$data61 + return -1 +endi +if $data62 != 1 then + print =====data62=$data62 + return -1 +endi +if $data63 != 3.000000000 then + print =====data63=$data63 + return -1 +endi + +sql insert into t1 values(1648791212000,5,5,5,5.0,'eee'); +sql insert into t1 values(1648791207000,6,6,6,6.0,'fff') (1648791209000,7,7,7,7.0,'ggg') (1648791219000,8,8,8,8.0,'hhh') (1648791221000,9,9,9,9.0,'iii'); + + + +$loop_count = 0 + +loop8: +sleep 200 +sql select * from streamt7 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +if $rows != 15 then + print =====rows=$rows + goto loop8 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 12.000000000 then + print =====data02=$data02 + return -1 +endi +if $data03 != fff then + print =====data03=$data03 + return -1 +endi + +if $data11 != 6 then + print =====data11=$data11 + return -1 +endi +if $data12 != 12.000000000 then + print =====data12=$data12 + return -1 +endi +if $data13 != fff then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data22 != 14.000000000 then + print =====data22=$data22 + return -1 +endi +if $data23 != ggg then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 7 then + print =====data31=$data31 + return -1 +endi +if $data32 != 14.000000000 then + print =====data32=$data32 + return -1 +endi +if $data33 != ggg then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data52 != 10.000000000 then + print =====data52=$data52 + return -1 +endi +if $data53 != eee then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 2 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 4.000000000 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != bbb then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][2] != 16.000000000 then + print =====data[12][2]=$data[12][2] + return -1 +endi +if $data[12][3] != hhh then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 8 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][2] != 16.000000000 then + print =====data[13][2]=$data[13][2] + return -1 +endi +if $data[13][3] != hhh then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][2] != 18.000000000 then + print =====data[14][2]=$data[14][2] + return -1 +endi +if $data[14][3] != iii then + print =====data[14][3]=$data[14][3] + return -1 +endi + +print fill next-----------------890 +sql use test7; +sql select * from streamt8 order by ts; + +if $rows != 15 then + print =====rows=$rows + goto loop8 +endi + + +if $data01 != 6 then + print =====data01=$data01 + return -1 +endi +if $data02 != 1 then + print =====data02=$data02 + return -1 +endi +if $data03 != 7.000000000 then + print =====data03=$data03 + return -1 +endi + +if $data11 != 7 then + print =====data11=$data11 + return -1 +endi +if $data13 != 8.000000000 then + print =====data13=$data13 + return -1 +endi + + +if $data21 != 7 then + print =====data21=$data21 + return -1 +endi +if $data23 != 8.000000000 then + print =====data23=$data23 + return -1 +endi + + +if $data31 != 3 then + print =====data31=$data31 + return -1 +endi +if $data33 != 4.000000000 then + print =====data33=$data33 + return -1 +endi + +if $data51 != 5 then + print =====data51=$data51 + return -1 +endi +if $data53 != 6.000000000 then + print =====data53=$data53 + return -1 +endi + + +if $data[11][1] != 8 then + print =====data[11][1]=$data[11][1] + return -1 +endi +if $data[11][2] != 1 then + print =====data[11][2]=$data[11][2] + return -1 +endi +if $data[11][3] != 9.000000000 then + print =====data[11][3]=$data[11][3] + return -1 +endi + +if $data[12][1] != 8 then + print =====data[12][1]=$data[12][1] + return -1 +endi +if $data[12][3] != 9.000000000 then + print =====data[12][3]=$data[12][3] + return -1 +endi + +if $data[13][1] != 9 then + print =====data[13][1]=$data[13][1] + return -1 +endi +if $data[13][3] != 10.000000000 then + print =====data[13][3]=$data[13][3] + return -1 +endi + +if $data[14][1] != 9 then + print =====data[14][1]=$data[14][1] + return -1 +endi +if $data[14][3] != 10.000000000 then + print =====data[14][3]=$data[14][3] + return -1 +endi + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test1; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/fillIntervalValue.sim b/tests/script/tsim/stream/fillIntervalValue.sim new file mode 100644 index 0000000000..113eae9270 --- /dev/null +++ b/tests/script/tsim/stream/fillIntervalValue.sim @@ -0,0 +1,488 @@ +$loop_all = 0 +looptest: + +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +sql drop database if exists test; +sql create database test vgroups 1; +sql use test; + +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20));; +sql create stream streams1 trigger at_once into streamt as select _wstart ts, count(*) c1 from t1 where ts > 1648791210000 and ts < 1648791413000 interval(10s) fill(value, 100); +sql insert into t1 values(1648791213000,1,2,3,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791233000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791223000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791283000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791253000,1,2,3,1.0,'aaa'); + +$loop_count = 0 + +loop0: +sleep 200 +sql select * from streamt order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 8 then + print =====rows=$rows + goto loop0 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +if $data11 != 1 then + print =====data11=$data11 + goto loop0 +endi + +if $data21 != 1 then + print =====data21=$data21 + goto loop0 +endi + +if $data31 != 100 then + print =====data31=$data31 + goto loop0 +endi + +if $data41 != 1 then + print =====data41=$data41 + goto loop0 +endi + +if $data51 != 100 then + print =====data01=$data01 + goto loop0 +endi + +if $data61 != 100 then + print =====data61=$data61 + goto loop0 +endi + +if $data71 != 1 then + print =====data71=$data71 + goto loop0 +endi + +sql drop stream if exists streams2; +sql drop database if exists test2; +sql create database test2 vgroups 1; +sql use test2; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams2 trigger at_once into streamt2 as select _wstart as ts, count(*) c1, max(b)+sum(a) from t1 where ts >= 1648791210000 and ts < 1648791261000 interval(1s) fill(value, 100,200); +sql insert into t1 values(1648791211000,1,1,1,1.0,'aaa') (1648791217000,2,2,2,2.0,'aaa') (1648791220000,3,3,3,3.0,'aaa'); +sql insert into t1 values(1648791213000,4,4,4,4.0,'aaa') (1648791215000,5,5,5,5.0,'aaa'); + +$loop_count = 0 + +loop1: +sleep 200 +sql select * from streamt2 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 10 then + print =====rows=$rows + goto loop1 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop1 +endi + + +if $data11 != 100 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 200.000000000 then + print =====data12=$data12 + goto loop1 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 8.000000000 then + print =====data22=$data22 + goto loop1 +endi + + +if $data31 != 100 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 200.000000000 then + print =====data32=$data32 + goto loop1 +endi + + +if $data41 != 1 then + print =====data41=$data41 + goto loop1 +endi + +if $data42 != 10.000000000 then + print =====data42=$data42 + goto loop1 +endi + + +if $data51 != 100 then + print =====data01=$data01 + goto loop1 +endi + +if $data52 != 200.000000000 then + print =====data52=$data52 + goto loop1 +endi + + +if $data61 != 1 then + print =====data61=$data61 + goto loop1 +endi + +if $data62 != 4.000000000 then + print =====data62=$data62 + goto loop1 +endi + + +if $data71 != 100 then + print =====data71=$data71 + goto loop1 +endi + +if $data72 != 200.000000000 then + print =====data72=$data72 + goto loop1 +endi + + +if $data81 != 100 then + print =====data81=$data81 + goto loop1 +endi + +if $data82 != 200.000000000 then + print =====data82=$data82 + goto loop1 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop1 +endi + +if $data92 != 6.000000000 then + print =====data92=$data92 + goto loop1 +endi + +sql drop stream if exists streams3; +sql drop database if exists test3; +sql create database test3 vgroups 1; +sql use test3; +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20)); +sql create stream streams3 trigger at_once into streamt3 as select _wstart as ts, max(b), a+b, c from t1 where ts >= 1648791200000 and ts < 1648791261000 interval(10s) sliding(3s) fill(value, 100,200,300); + +sql insert into t1 values(1648791220000,1,1,1,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791260000,1,1,1,1.0,'aaa'); +sleep 100 +sql insert into t1 values(1648791200000,1,1,1,1.0,'aaa'); + +$loop_count = 0 + +loop3: +sleep 200 +sql select * from streamt3 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 23 then + print =====rows=$rows + goto loop3 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop3 +endi + +if $data02 != 2.000000000 then + print =====data02=$data02 + goto loop3 +endi + +if $data03 != 1 then + print =====data03=$data03 + goto loop3 +endi + + +if $data21 != 1 then + print =====data21=$data21 + goto loop3 +endi + +if $data22 != 2.000000000 then + print =====data22=$data22 + goto loop3 +endi + +if $data23 != 1 then + print =====data23=$data23 + goto loop3 +endi + + +if $data31 != 100 then + print =====data31=$data31 + goto loop3 +endi + +if $data32 != 200.000000000 then + print =====data32=$data32 + goto loop3 +endi + +if $data33 != 300 then + print =====data33=$data33 + goto loop3 +endi + +if $data61 != 100 then + print =====data61=$data61 + goto loop3 +endi + +if $data62 != 200.000000000 then + print =====data62=$data62 + goto loop3 +endi + +if $data63 != 300 then + print =====data63=$data63 + goto loop3 +endi + + +if $data71 != 1 then + print =====data71=$data71 + goto loop3 +endi + +if $data72 != 2.000000000 then + print =====data72=$data72 + goto loop3 +endi + +if $data73 != 1 then + print =====data73=$data73 + goto loop3 +endi + + +if $data91 != 1 then + print =====data91=$data91 + goto loop3 +endi + +if $data92 != 2.000000000 then + print =====data92=$data92 + goto loop3 +endi + +if $data93 != 1 then + print =====data93=$data93 + goto loop3 +endi + + +if $data[10][1] != 100 then + print =====data[10][1]=$data[10][1] + goto loop3 +endi + +if $data[10][2] != 200.000000000 then + print =====data[10][2]=$data[10][2] + goto loop3 +endi + +if $data[10][3] != 300 then + print =====data[10][3]=$data[10][3] + goto loop3 +endi + +if $data[19][1] != 100 then + print =====data[19][1]=$data[19][1] + goto loop3 +endi + +if $data[19][2] != 200.000000000 then + print =====data[19][2]=$data[19][2] + goto loop3 +endi + +if $data[19][3] != 300 then + print =====data[19][3]=$data[19][3] + goto loop3 +endi + + +if $data[20][1] != 1 then + print =====data[20][1]=$data[20][1] + goto loop3 +endi + +if $data[20][2] != 2.000000000 then + print =====data[20][2]=$data[20][2] + goto loop3 +endi + +if $data[20][3] != 1 then + print =====data[20][3]=$data[20][3] + goto loop3 +endi + + +if $data[22][1] != 1 then + print =====data[22][1]=$data[22][1] + goto loop3 +endi + +if $data[22][2] != 2.000000000 then + print =====data[22][2]=$data[22][2] + goto loop3 +endi + +if $data[22][3] != 1 then + print =====data[22][3]=$data[22][3] + goto loop3 +endi + + +sql drop stream if exists streams4; +sql drop database if exists test4; +sql create database test4 vgroups 1; +sql use test4; + +sql create table t1(ts timestamp, a int, b int , c int, d double, s varchar(20));; +sql create stream streams4 trigger at_once into streamt4 as select _wstart ts, count(*) c1 from t1 where ts > 1648791210000 and ts < 1648791413000 interval(10s) fill(NULL); +sql insert into t1 values(1648791213000,1,2,3,1.0,'aaa'); +sql insert into t1 values(1648791233000,1,2,3,1.0,'aaa'); + +$loop_count = 0 + +loop4: +sleep 200 +sql select * from streamt4 order by ts; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 3 then + print =====rows=$rows + goto loop4 +endi + +if $data11 != NULL then + print =====data11=$data11 + goto loop4 +endi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sql drop stream if exists streams0; +sql drop stream if exists streams1; +sql drop stream if exists streams2; +sql drop stream if exists streams3; +sql drop stream if exists streams4; +sql drop stream if exists streams5; +sql drop stream if exists streams6; +sql drop stream if exists streams7; +sql drop stream if exists streams8; + +sql use test; +sql select * from t1; +print $data00 + +$loop_all = $loop_all + 1 +print ============loop_all=$loop_all + +system sh/stop_dnodes.sh + +#goto looptest \ No newline at end of file diff --git a/tests/script/tsim/stream/partitionby.sim b/tests/script/tsim/stream/partitionby.sim index e5e02c3873..bc2c07b951 100644 --- a/tests/script/tsim/stream/partitionby.sim +++ b/tests/script/tsim/stream/partitionby.sim @@ -5,13 +5,14 @@ sleep 50 sql connect sql create database test vgroups 4; +sql create database test0 vgroups 1; sql use test; sql create stable st(ts timestamp, a int, b int , c int, d double) tags(ta int,tb int,tc int); sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); +sql create stream stream_t1 trigger at_once into test0.streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); sql insert into ts1 values(1648791213001,1,12,3,1.0); sql insert into ts2 values(1648791213001,1,12,3,1.0); @@ -22,7 +23,7 @@ $loop_count = 0 loop0: sleep 300 -sql select * from streamtST1; +sql select * from test0.streamtST1; $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -34,6 +35,29 @@ print =====rows=$rows goto loop0 endi +sql insert into ts1 values(1648791223001,1,12,3,1.0); +sql insert into ts2 values(1648791223001,1,12,3,1.0); + +sql insert into ts3 values(1648791223001,1,12,3,1.0); +sql insert into ts4 values(1648791223001,1,12,3,1.0); +sleep 300 +sql delete from st where ts = 1648791223001; + +loop00: +sleep 300 +sql select * from test0.streamtST1; + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +if $rows != 4 then + print =====rows=$rows + goto loop00 +endi + + print =====loop0 sql create database test1 vgroups 1; diff --git a/tests/script/tsim/stream/partitionbyColumnInterval.sim b/tests/script/tsim/stream/partitionbyColumnInterval.sim index 24fdb9c994..fd1d796fdb 100644 --- a/tests/script/tsim/stream/partitionbyColumnInterval.sim +++ b/tests/script/tsim/stream/partitionbyColumnInterval.sim @@ -562,6 +562,53 @@ if $data21 != 1 then goto loop14 endi +sql drop stream if exists streams5; +sql drop database if exists test5; +sql create database test5 vgroups 4; +sql use test5; +sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(2,2,2); +sql create table t4 using st tags(2,2,2); +sql create stream streams5 trigger at_once into test.streamt5 as select _wstart c1, count(*) c2, max(a) c3 from st partition by a interval(10s); + +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t2 values(1648791213000,2,2,3,1.0); +sql insert into t3 values(1648791213000,3,2,3,1.0); +sql insert into t4 values(1648791213000,4,2,3,1.0); + +sql insert into t1 values(1648791223000,1,2,3,1.0); +sql insert into t2 values(1648791223000,2,2,3,1.0); +sql insert into t3 values(1648791223000,3,2,3,1.0); +sql insert into t4 values(1648791223000,4,2,3,1.0); + +sleep 300 + +sql delete from st where ts = 1648791223000; + +sql select * from test.streamt5; + +$loop_count = 0 + +loop15: +sleep 50 +sql select * from test.streamt5 order by c1, c2, c3; + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +if $rows != 4 then + print =====rows=$rows + print =====rows=$rows + print =====rows=$rows +# goto loop15 +endi + + + $loop_all = $loop_all + 1 print ============loop_all=$loop_all diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index 7bf0191ec1..bee20710b5 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -356,8 +356,261 @@ class TDTestCase: tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:16', '2020-02-01 00:00:19') every(1s) fill(linear)") tdSql.checkRows(0) + tdLog.printNoPrefix("==========step8:test _irowts with interp") - tdLog.printNoPrefix("==========step8:test intra block interpolation") + # fill null + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:08', '2020-02-01 00:00:12') every(500a) fill(null)") + tdSql.checkRows(9) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:08.500') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:09.500') + tdSql.checkData(4, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.500') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.500') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(null)") + tdSql.checkRows(13) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:04.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:06.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(6, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + tdSql.checkData(9, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(10, 0, '2020-02-01 00:00:14.000') + tdSql.checkData(11, 0, '2020-02-01 00:00:15.000') + tdSql.checkData(12, 0, '2020-02-01 00:00:16.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-01 00:00:15') every(2s) fill(null)") + tdSql.checkRows(6) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:15.000') + + # fill value + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:08', '2020-02-01 00:00:12') every(500a) fill(value, 1)") + tdSql.checkRows(9) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:08.500') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:09.500') + tdSql.checkData(4, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.500') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.500') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(value, 1)") + tdSql.checkRows(13) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:04.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:06.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(6, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + tdSql.checkData(9, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(10, 0, '2020-02-01 00:00:14.000') + tdSql.checkData(11, 0, '2020-02-01 00:00:15.000') + tdSql.checkData(12, 0, '2020-02-01 00:00:16.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-01 00:00:15') every(2s) fill(value, 1)") + tdSql.checkRows(6) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:15.000') + + # fill prev + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:08', '2020-02-01 00:00:12') every(500a) fill(prev)") + tdSql.checkRows(9) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:08.500') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:09.500') + tdSql.checkData(4, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.500') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.500') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(prev)") + tdSql.checkRows(12) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:06.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:12.000') + tdSql.checkData(8, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(9, 0, '2020-02-01 00:00:14.000') + tdSql.checkData(10, 0, '2020-02-01 00:00:15.000') + tdSql.checkData(11, 0, '2020-02-01 00:00:16.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-01 00:00:15') every(2s) fill(prev)") + tdSql.checkRows(6) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:15.000') + + # fill next + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:08', '2020-02-01 00:00:12') every(500a) fill(next)") + tdSql.checkRows(9) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:08.500') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:09.500') + tdSql.checkData(4, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.500') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.500') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(next)") + tdSql.checkRows(12) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:04.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:06.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(6, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + tdSql.checkData(9, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(10, 0, '2020-02-01 00:00:14.000') + tdSql.checkData(11, 0, '2020-02-01 00:00:15.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-01 00:00:15') every(2s) fill(next)") + tdSql.checkRows(6) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:15.000') + + # fill linear + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:08', '2020-02-01 00:00:12') every(500a) fill(linear)") + tdSql.checkRows(9) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:08.500') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:09.500') + tdSql.checkData(4, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.500') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:11.500') + tdSql.checkData(8, 0, '2020-02-01 00:00:12.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:06.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:08.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:10.000') + tdSql.checkData(6, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 0, '2020-02-01 00:00:12.000') + tdSql.checkData(8, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(9, 0, '2020-02-01 00:00:14.000') + tdSql.checkData(10, 0, '2020-02-01 00:00:15.000') + + tdSql.query(f"select _irowts,interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-01 00:00:15') every(2s) fill(linear)") + tdSql.checkRows(6) + tdSql.checkCols(2) + + tdSql.checkData(0, 0, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 0, '2020-02-01 00:00:07.000') + tdSql.checkData(2, 0, '2020-02-01 00:00:09.000') + tdSql.checkData(3, 0, '2020-02-01 00:00:11.000') + tdSql.checkData(4, 0, '2020-02-01 00:00:13.000') + tdSql.checkData(5, 0, '2020-02-01 00:00:15.000') + + # multiple _irowts + tdSql.query(f"select interp(c0),_irowts from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkCols(2) + + tdSql.checkData(0, 1, '2020-02-01 00:00:05.000') + tdSql.checkData(1, 1, '2020-02-01 00:00:06.000') + tdSql.checkData(2, 1, '2020-02-01 00:00:07.000') + tdSql.checkData(3, 1, '2020-02-01 00:00:08.000') + tdSql.checkData(4, 1, '2020-02-01 00:00:09.000') + tdSql.checkData(5, 1, '2020-02-01 00:00:10.000') + tdSql.checkData(6, 1, '2020-02-01 00:00:11.000') + tdSql.checkData(7, 1, '2020-02-01 00:00:12.000') + tdSql.checkData(8, 1, '2020-02-01 00:00:13.000') + tdSql.checkData(9, 1, '2020-02-01 00:00:14.000') + tdSql.checkData(10, 1, '2020-02-01 00:00:15.000') + + tdSql.query(f"select _irowts, interp(c0), interp(c0), _irowts from {dbname}.{tbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(linear)") + tdSql.checkRows(11) + tdSql.checkCols(4) + + cols = (0, 3) + for i in cols: + tdSql.checkData(0, i, '2020-02-01 00:00:05.000') + tdSql.checkData(1, i, '2020-02-01 00:00:06.000') + tdSql.checkData(2, i, '2020-02-01 00:00:07.000') + tdSql.checkData(3, i, '2020-02-01 00:00:08.000') + tdSql.checkData(4, i, '2020-02-01 00:00:09.000') + tdSql.checkData(5, i, '2020-02-01 00:00:10.000') + tdSql.checkData(6, i, '2020-02-01 00:00:11.000') + tdSql.checkData(7, i, '2020-02-01 00:00:12.000') + tdSql.checkData(8, i, '2020-02-01 00:00:13.000') + tdSql.checkData(9, i, '2020-02-01 00:00:14.000') + tdSql.checkData(10, i, '2020-02-01 00:00:15.000') + + + tdLog.printNoPrefix("==========step9:test intra block interpolation") tdSql.execute(f"drop database {dbname}"); tdSql.prepare() @@ -551,7 +804,7 @@ class TDTestCase: tdSql.checkData(0, 0, 15) tdSql.checkData(1, 0, 15) - tdLog.printNoPrefix("==========step9:test multi-interp cases") + tdLog.printNoPrefix("==========step10:test multi-interp cases") tdSql.query(f"select interp(c0),interp(c1),interp(c2),interp(c3) from {dbname}.{tbname} range('2020-02-09 00:00:05', '2020-02-13 00:00:05') every(1d) fill(null)") tdSql.checkRows(5) tdSql.checkCols(4) @@ -601,7 +854,7 @@ class TDTestCase: for i in range (tdSql.queryCols): tdSql.checkData(0, i, 13) - tdLog.printNoPrefix("==========step10:test error cases") + tdLog.printNoPrefix("==========step11:test error cases") tdSql.error(f"select interp(c0) from {dbname}.{tbname}") tdSql.error(f"select interp(c0) from {dbname}.{tbname} range('2020-02-10 00:00:05', '2020-02-15 00:00:05')") diff --git a/tests/system-test/7-tmq/subscribeDb3.py b/tests/system-test/7-tmq/subscribeDb3.py index e8e475456c..0ff609ab6b 100644 --- a/tests/system-test/7-tmq/subscribeDb3.py +++ b/tests/system-test/7-tmq/subscribeDb3.py @@ -295,7 +295,7 @@ class TDTestCase: ifManualCommit = 1 keyList = 'group.id:cgrp1,\ enable.auto.commit:true,\ - auto.commit.interval.ms:1000,\ + auto.commit.interval.ms:200,\ auto.offset.reset:earliest' self.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) diff --git a/tools/shell/src/shellArguments.c b/tools/shell/src/shellArguments.c index 93f8b8a23b..eedb6d7295 100644 --- a/tools/shell/src/shellArguments.c +++ b/tools/shell/src/shellArguments.c @@ -358,7 +358,7 @@ static int32_t shellCheckArgs() { return -1; } - if (pArgs->password != NULL && (strlen(pArgs->password) <= 0)) { + if (/*pArgs->password != NULL && */ (strlen(pArgs->password) <= 0)) { printf("Invalid password\r\n"); return -1; } diff --git a/utils/tsim/src/simExe.c b/utils/tsim/src/simExe.c index 16732ff9a1..5bb53287db 100644 --- a/utils/tsim/src/simExe.c +++ b/utils/tsim/src/simExe.c @@ -224,10 +224,24 @@ char *simGetVariable(SScript *script, char *varName, int32_t varLen) { } int32_t simExecuteExpression(SScript *script, char *exp) { - char *op1, *op2, *var1, *var2, *var3, *rest; - int32_t op1Len, op2Len, var1Len, var2Len, var3Len, val0, val1; - char t0[1024], t1[1024], t2[1024], t3[2048]; - int32_t result; + char *op1 = NULL; + char *op2 = NULL; + char *var1 = NULL; + char *var2 = NULL; + char *var3 = NULL; + char *rest = NULL; + int32_t op1Len = 0; + int32_t op2Len = 0; + int32_t var1Len = 0; + int32_t var2Len = 0; + int32_t var3Len = 0; + int32_t val0 = 0; + int32_t val1 = 0; + char t0[1024] = {0}; + char t1[1024] = {0}; + char t2[1024] = {0}; + char t3[2048] = {0}; + int32_t result = 0; rest = paGetToken(exp, &var1, &var1Len); rest = paGetToken(rest, &op1, &op1Len); @@ -241,9 +255,9 @@ int32_t simExecuteExpression(SScript *script, char *exp) { t0[var1Len] = 0; } - if (var2[0] == '$') - strcpy(t1, simGetVariable(script, var2 + 1, var2Len - 1)); - else { + if (var2[0] == '$') { + tstrncpy(t1, simGetVariable(script, var2 + 1, var2Len - 1), 1024); + } else { memcpy(t1, var2, var2Len); t1[var2Len] = 0; } @@ -258,14 +272,21 @@ int32_t simExecuteExpression(SScript *script, char *exp) { t2[var3Len] = 0; } + int64_t t1l = atoll(t1); + int64_t t2l = atoll(t2); + if (op2[0] == '+') { - sprintf(t3, "%lld", atoll(t1) + atoll(t2)); + sprintf(t3, "%" PRId64, t1l + t2l); } else if (op2[0] == '-') { - sprintf(t3, "%lld", atoll(t1) - atoll(t2)); + sprintf(t3, "%" PRId64, t1l - t2l); } else if (op2[0] == '*') { - sprintf(t3, "%lld", atoll(t1) * atoll(t2)); + sprintf(t3, "%" PRId64, t1l * t2l); } else if (op2[0] == '/') { - sprintf(t3, "%lld", atoll(t1) / atoll(t2)); + if (t2l == 0) { + sprintf(t3, "%" PRId64, INT64_MAX); + } else { + sprintf(t3, "%" PRId64, t1l / t2l); + } } else if (op2[0] == '.') { sprintf(t3, "%s%s", t1, t2); } @@ -636,7 +657,7 @@ bool simCreateTaosdConnect(SScript *script, char *rest) { } bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) { - char timeStr[30] = {0}; + char timeStr[80] = {0}; time_t tt; struct tm tp; SCmdLine *line = &script->lines[script->linePos]; @@ -943,7 +964,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) { return true; } - TAOS_RES *pSql = pSql = taos_query(script->taos, rest); + TAOS_RES *pSql = taos_query(script->taos, rest); int32_t ret = taos_errno(pSql); taos_free_result(pSql); @@ -961,7 +982,7 @@ bool simExecuteSqlErrorCmd(SScript *script, char *rest) { } bool simExecuteLineInsertCmd(SScript *script, char *rest) { - char buf[TSDB_MAX_BINARY_LEN]; + char buf[TSDB_MAX_BINARY_LEN] = {0}; simVisuallizeOption(script, rest, buf); rest = buf; @@ -973,10 +994,7 @@ bool simExecuteLineInsertCmd(SScript *script, char *rest) { char *lines[] = {rest}; #if 0 int32_t ret = taos_insert_lines(script->taos, lines, 1); -#else - int32_t ret = 0; -#endif - if (ret == TSDB_CODE_SUCCESS) { + if (ret == TSDB_CODE_SUCCESS) { simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest); script->linePos++; return true; @@ -985,6 +1003,11 @@ bool simExecuteLineInsertCmd(SScript *script, char *rest) { tstrerror(ret)); return false; } +#else + simDebug("script:%s, taos:%p, %s executed. success.", script->fileName, script->taos, rest); + script->linePos++; + return true; +#endif } bool simExecuteLineInsertErrorCmd(SScript *script, char *rest) { diff --git a/utils/tsim/src/simMain.c b/utils/tsim/src/simMain.c index 713e46df58..e58a22cf68 100644 --- a/utils/tsim/src/simMain.c +++ b/utils/tsim/src/simMain.c @@ -33,7 +33,7 @@ int32_t main(int32_t argc, char *argv[]) { if (strcmp(argv[i], "-c") == 0 && i < argc - 1) { tstrncpy(configDir, argv[++i], 128); } else if (strcmp(argv[i], "-f") == 0 && i < argc - 1) { - strcpy(scriptFile, argv[++i]); + tstrncpy(scriptFile, argv[++i], MAX_FILE_NAME_LEN); } else if (strcmp(argv[i], "-m") == 0) { useMultiProcess = true; } else if (strcmp(argv[i], "-v") == 0) { diff --git a/utils/tsim/src/simParse.c b/utils/tsim/src/simParse.c index b9f7610be8..14be10bc8a 100644 --- a/utils/tsim/src/simParse.c +++ b/utils/tsim/src/simParse.c @@ -175,14 +175,17 @@ SScript *simBuildScriptObj(char *fileName) { SScript *simParseScript(char *fileName) { TdFilePtr pFile; int32_t tokenLen, lineNum = 0; - char buffer[10*1024], name[128], *token, *rest; - SCommand *pCmd; - SScript *script; + char buffer[10 * 1024] = {0}; + char name[PATH_MAX] = {9}; + char *token = NULL; + char *rest = NULL; + SCommand *pCmd = NULL; + SScript *script = NULL; if ((fileName[0] == '.') || (fileName[0] == '/')) { - strcpy(name, fileName); + tstrncpy(name, fileName, PATH_MAX); } else { - sprintf(name, "%s" TD_DIRSEP "%s", simScriptDir, fileName); + snprintf(name, PATH_MAX, "%s" TD_DIRSEP "%s", simScriptDir, fileName); taosRealPath(name, NULL, sizeof(name)); }