Merge branch 'main' into merge/mainto3.0

This commit is contained in:
Shengliang Guan 2025-01-09 13:38:37 +08:00
commit c62e189496
103 changed files with 3567 additions and 902 deletions

View File

@ -42,7 +42,7 @@ jobs:
cmake .. -DBUILD_TOOLS=true \
-DBUILD_KEEPER=true \
-DBUILD_HTTP=false \
-DBUILD_TEST=false \
-DBUILD_TEST=true \
-DBUILD_DEPENDENCY_TESTS=false
make -j 4
sudo make install

View File

@ -368,8 +368,8 @@ def pre_test_build_win() {
'''
bat '''
cd %WIN_COMMUNITY_ROOT%/tests/ci
pip3 install taospy==2.7.16
pip3 install taos-ws-py==0.3.5
pip3 install taospy==2.7.21
pip3 install taos-ws-py==0.3.8
xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
'''
return 1

View File

@ -13,9 +13,9 @@ Through the Python connector of TDengine, Superset can support TDengine data sou
Prepare the following environment:
- TDengine is installed and running normally (both Enterprise and Community versions are available)
- taosAdapter is running normally, refer to [taosAdapter](../../../reference/components/taosAdapter)
- taosAdapter is running normally, refer to [taosAdapter](../../../tdengine-reference/components/taosadapter/)
- Apache Superset version 2.1.0 or above is already installed, refre to [Apache Superset](https://superset.apache.org/)
## Install TDengine Python Connector
The Python connector of TDengine comes with a connection driver that supports Superset in versions 2.1.18 and later, which will be automatically installed in the Superset directory and provide data source services.

View File

@ -43,7 +43,7 @@ After modifying configuration file parameters, you need to restart the *taosd* s
|resolveFQDNRetryTime | Cancelled after 3.x |Not supported |Number of retries when FQDN resolution fails|
|timeToGetAvailableConn | Cancelled after 3.3.4.x |Maximum waiting time to get an available connection, range 10-50000000, in milliseconds, default value 500000|
|maxShellConns | Cancelled after 3.x |Supported, effective after restart|Maximum number of connections allowed|
|maxRetryWaitTime | |Supported, effective after restart|Maximum timeout for reconnection, default value is 10s|
|maxRetryWaitTime | |Supported, effective after restart|Maximum timeout for reconnection,calculated from the time of retry,range is 0-86400000,in milliseconds, default value 10000|
|shareConnLimit |Added in 3.3.4.0 |Supported, effective after restart|Number of requests a connection can share, range 1-512, default value 10|
|readTimeout |Added in 3.3.4.0 |Supported, effective after restart|Minimum timeout for a single request, range 64-604800, in seconds, default value 900|

View File

@ -268,7 +268,22 @@ An exporter used by Prometheus that exposes hardware and operating system metric
### Getting the VGroup ID of a table
You can access the HTTP interface `http://<fqdn>:6041/rest/vgid?db=<db>&table=<table>` to get the VGroup ID of a table.
You can send a POST request to the HTTP interface `http://<fqdn>:<port>/rest/sql/<db>/vgid` to get the VGroup ID of a table.
The body should be a JSON array of multiple table names.
Example: Get the VGroup ID for the database power and tables d_bind_1 and d_bind_2.
```shell
curl --location 'http://127.0.0.1:6041/rest/sql/power/vgid' \
--user 'root:taosdata' \
--data '["d_bind_1","d_bind_2"]'
```
response:
```json
{"code":0,"vgIDs":[153,152]}
```
## Memory Usage Optimization Methods

View File

@ -491,15 +491,15 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
:::
## UNION ALL Clause
## UNION Clause
```text title=Syntax
SELECT ...
UNION ALL SELECT ...
[UNION ALL SELECT ...]
UNION [ALL] SELECT ...
[UNION [ALL] SELECT ...]
```
TDengine supports the UNION ALL operator. This means that if multiple SELECT clauses return result sets with the exact same structure (column names, column types, number of columns, order), these result sets can be combined together using UNION ALL. Currently, only the UNION ALL mode is supported, which means that duplicates are not removed during the merging process. In the same SQL statement, a maximum of 100 UNION ALLs are supported.
TDengine supports the UNION [ALL] operator. This means that if multiple SELECT clauses return result sets with the exact same structure (column names, column types, number of columns, order), these result sets can be combined together using UNION [ALL].
## SQL Examples

View File

@ -45,7 +45,7 @@ ALTER ALL DNODES dnode_option
For configuration parameters that support dynamic modification, you can use the ALTER DNODE or ALTER ALL DNODES syntax to modify the values of configuration parameters in a dnode. Starting from version 3.3.4.0, the modified configuration parameters will be automatically persisted and will remain effective even after the database service is restarted.
To check whether a configuration parameter supports dynamic modification, please refer to the following page: [taosd Reference](../01-components/01-taosd.md)
To check whether a configuration parameter supports dynamic modification, please refer to the following page: [taosd Reference](/tdengine-reference/components/taosd/)
The value is the parameter's value and needs to be in character format. For example, to change the log output level of dnode 1 to debug:
@ -130,7 +130,7 @@ ALTER LOCAL local_option
You can use the above syntax to modify the client's configuration parameters, and there is no need to restart the client. The changes take effect immediately.
To check whether a configuration parameter supports dynamic modification, please refer to the following page:[taosc Reference](../01-components/02-taosc.md)
To check whether a configuration parameter supports dynamic modification, please refer to the following page:[taosc Reference](/tdengine-reference/components/taosc/)
## View Client Configuration

View File

@ -60,7 +60,7 @@ CREATE [OR REPLACE] AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 64;
```
About how to develop custom functions, please refer to [UDF Usage Instructions](../../../developer-guide/user-defined-functions/).
About how to develop custom functions, please refer to [UDF Usage Instructions](/developer-guide/user-defined-functions/).
## Manage UDF

View File

@ -4,7 +4,11 @@ title: Time-Range Small Materialized Aggregates (TSMAs)
slug: /tdengine-reference/sql-manual/manage-tsmas
---
To improve the performance of aggregate function queries with large data volumes, window pre-aggregation (TSMA Time-Range Small Materialized Aggregates) objects are created. By using fixed time windows to pre-calculate specified aggregate functions and storing the results, query performance is enhanced by querying these pre-calculated results.
In scenarios with large amounts of data, it is often necessary to query summary results for a certain period. As historical data increases or the time range expands, query time will also increase accordingly. By using materialized aggregation, the calculation results can be stored in advance, allowing subsequent queries to directly read the aggregated results without scanning the original data, such as the SMA (Small Materialized Aggregates) information within the current block.
The SMA information within a block has a small granularity. If the query time range is in days, months, or even years, the number of blocks will be large. Therefore, TSMA (Time-Range Small Materialized Aggregates) supports users to specify a time window for materialized aggregation. By pre-calculating the data within a fixed time window and storing the calculation results, queries can be performed on the pre-calculated results to improve query performance.
![TSMA Introduction](./assets/TSMA_intro.png)
## Creating TSMA

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -509,8 +509,8 @@ For the OpenTSDB text protocol, the parsing of timestamps follows its official p
- **Interface Description**: Used for polling to consume data. Each consumer can only call this interface in a single thread.
- tmq: [Input] Points to a valid ws_tmq_t structure pointer, which represents a TMQ consumer object.
- timeout: [Input] Polling timeout in milliseconds, a negative number indicates a default timeout of 1 second.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a WS_RES structure, which contains the received message. `NULL`: Failure, indicates no data. WS_RES results are consistent with taos_query results, and information in WS_RES can be obtained through various query interfaces, such as schema, etc.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a WS_RES structure, which contains the received message. `NULL`: indicates no data, the error code can be obtained through ws_errno (NULL), please refer to the reference manual for specific error message. WS_RES results are consistent with taos_query results, and information in WS_RES can be obtained through various query interfaces, such as schema, etc.
- `int32_t ws_tmq_consumer_close(ws_tmq_t *tmq)`
- **Interface Description**: Used to close the ws_tmq_t structure. Must be used in conjunction with ws_tmq_consumer_new.
- tmq: [Input] Points to a valid ws_tmq_t structure pointer, which represents a TMQ consumer object.
@ -1195,8 +1195,8 @@ In addition to using SQL or parameter binding APIs to insert data, you can also
- **Interface Description**: Used to poll for consuming data, each consumer can only call this interface in a single thread.
- tmq: [Input] Points to a valid tmq_t structure pointer, representing a TMQ consumer object.
- timeout: [Input] Polling timeout in milliseconds, a negative number indicates a default timeout of 1 second.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a TAOS_RES structure containing the received messages. `NULL`: Failure, indicates no data. TAOS_RES results are consistent with taos_query results, and information in TAOS_RES can be obtained through various query interfaces, such as schema, etc.
- **Return Value**: Non-`NULL`: Success, returns a pointer to a TAOS_RES structure containing the received messages. `NULL`: indicates no data, the error code can be obtained through taos_errno (NULL), please refer to the reference manual for specific error message. TAOS_RES results are consistent with taos_query results, and information in TAOS_RES can be obtained through various query interfaces, such as schema, etc.
- `int32_t tmq_consumer_close(tmq_t *tmq)`
- **Interface Description**: Used to close a tmq_t structure. Must be used in conjunction with tmq_consumer_new.
- tmq: [Input] Points to a valid tmq_t structure pointer, which represents a TMQ consumer object.

View File

@ -23,13 +23,14 @@ import RequestId from "../../assets/resources/_request_id.mdx";
## Version History
| Connector Version | Major Changes | TDengine Version |
|------------------|-------------------------------------------------|-------------------|
| 3.1.4 | Improved WebSocket query and insert performance. | 3.3.2.0 and higher |
| 3.1.3 | Supported WebSocket auto-reconnect. | - |
| 3.1.2 | Fixed schemaless resource release. | - |
| 3.1.1 | Supported varbinary and geometry types. | - |
| 3.1.0 | WebSocket uses a native C# implementation. | 3.2.1.0 and higher |
| Connector Version | Major Changes | TDengine Version |
|-------------------|------------------------------------------------------------|--------------------|
| 3.1.5 | Fix WebSocket encoding error for Chinese character length. | - |
| 3.1.4 | Improved WebSocket query and insert performance. | 3.3.2.0 and higher |
| 3.1.3 | Supported WebSocket auto-reconnect. | - |
| 3.1.2 | Fixed schemaless resource release. | - |
| 3.1.1 | Supported varbinary and geometry types. | - |
| 3.1.0 | WebSocket uses a native C# implementation. | 3.2.1.0 and higher |
## Exceptions and Error Codes

View File

@ -252,7 +252,7 @@ Description:
- code: (`int`) 0 represents success.
- column_meta: (`[][3]any`) Column information, each column is described by three values: column name (string), column type (string), and type length (int).
- rows: (`int`) Number of data return rows.
- data: (`[][]any`) Specific data content (time format only supports RFC3339, result set for timezone 0).
- data: (`[][]any`) Specific data content (time format only supports RFC3339, result set for timezone 0, when specifying tz, the corresponding time zone is returned).
Column types use the following strings:
@ -434,7 +434,6 @@ curl http://<fqnd>:<port>/rest/login/<username>/<password>
Here, `fqdn` is the FQDN or IP address of the TDengine database, `port` is the port number of the TDengine service, `username` is the database username, and `password` is the database password. The return is in JSON format, with the fields meaning as follows:
- status: Flag of the request result.
- code: Return code.
- desc: Authorization code.

View File

@ -534,4 +534,5 @@ This document details the server error codes that may be encountered when using
| 0x80004000 | Invalid message | The subscribed data is illegal, generally does not occur | Check the client-side error logs for details |
| 0x80004001 | Consumer mismatch | The vnode requested for subscription and the reassigned vnode are inconsistent, usually occurs when new consumers join the same consumer group | Internal error, not exposed to users |
| 0x80004002 | Consumer closed | The consumer no longer exists | Check if it has already been closed |
| 0x80004017 | Invalid status, please subscribe topic first | tmq status invalidate | Without calling subscribe, directly poll data |
| 0x80004100 | Stream task not exist | The stream computing task does not exist | Check the server-side error logs |

View File

@ -2,7 +2,7 @@
title: TDengine 3.3.4.8 Release Notes
sidebar_label: 3.3.4.8
description: Version 3.3.4.8 Notes
slug: /release-history/release-notes/3.3.4.8
slug: /release-history/release-notes/3-3-4-8
---
## New Features

View File

@ -2,7 +2,7 @@
title: TDengine 3.3.5.0 Release Notes
sidebar_label: 3.3.5.0
description: Version 3.3.5.0 Notes
slug: /release-history/release-notes/3.3.5.0
slug: /release-history/release-notes/3-3-5-0
---
## Features

View File

@ -3,9 +3,10 @@ title: Release Notes
slug: /release-history/release-notes
---
[3.3.5.0](./3-3-5-0/)
[3.3.4.8](./3-3-4-8/)
[3.3.5.0](./3.3.5.0)
[3.3.4.3](./3-3-4-3/)
[3.3.3.0](./3-3-3-0/)

View File

@ -63,7 +63,7 @@ toc_max_heading_level: 4
1. 数据库Database数据库提供时序数据的高效存储和读取能力。在工业、物联网场景由设备所产生的时序数据量是十分惊人的。从存储数据的角度来说数据库需要把这些数据持久化到硬盘上并最大程度地压缩从而降低存储成本。从读取数据的角度来说数据库需要保证实时查询以及历史数据的查询效率。比较传统的存储方案是使用 MySql、Oracle 等关系型数据库,也有 Hadoop 体系的 HBase专用的时序数据库则有 InfluxDB、OpenTSDB、Prometheus 等。
2. 数据订阅Data Subscription很多时序数据应用都需要在第一时间订阅到业务所需的实时数据从而及时了解被监测对象的最新状态,用 AI 或其他工具做实时的数据分析。同时,由于数据的隐私以及安全,你只能允许应用订阅他有权限访问的数据。因此,一个时序数据处理平台一定需要具备数据订阅的能力,帮助应用实时获取最新数据。
2. 数据订阅Data Subscription很多时序数据应用都需要在第一时间订阅到业务所需的实时数据从而及时了解被监测对象的最新状态用 AI 或其他工具做实时的数据分析。同时,由于数据的隐私以及安全,你只能允许应用订阅他有权限访问的数据。因此,一个时序数据处理平台一定需要具备数据订阅的能力,帮助应用实时获取最新数据。
3. ETLExtract Transform Load在实际的物联网、工业场景中时序数据的采集需要特定的 ETL 工具进行数据的提取、清洗和转换操作,才能把数据写入数据库中,以保证数据的质量。因为不同数据采集系统往往使用不同的标准,比如采集的温度的物理单位不一致,有的用摄氏度,有的用华氏度;系统之间所在的时区不一致,要进行转换;时间分辨率也可能不统一,因此这些从不同系统汇聚来的数据需要进行转换才能写入数据库。
@ -135,4 +135,4 @@ toc_max_heading_level: 4
18. 需要支持私有化部署。因为很多企业出于安全以及各种因素的考虑,希望采用私有化部署。而传统的企业往往没有很强的 IT 运维团队,因此在安装、部署、运维等方面需要做到简单、快捷,可维护性强。
总之,时序大数据平台应具备高效、可扩展、实时、可靠、灵活、开放、简单、易维护等特点。近年来,众多企业纷纷将时序数据从传统大数据平台或关系型数据库迁移到专用时序大数据平台,以保障海量时序数据得到快速和有效处理,支撑相关业务的持续增长。
总之,时序大数据平台应具备高效、可扩展、实时、可靠、灵活、开放、简单、易维护等特点。近年来,众多企业纷纷将时序数据从传统大数据平台或关系型数据库迁移到专用时序大数据平台,以保障海量时序数据得到快速和有效处理,支撑相关业务的持续增长。

View File

@ -158,6 +158,14 @@ let v3 = data["voltage"].split(",");
过滤功能可以设置过滤条件,满足条件的数据行 才会被写入目标表。过滤条件表达式的结果必须是 boolean 类型。在编写过滤条件前,必须确定 解析字段的类型,根据解析字段的类型,可以使用判断函数、比较操作符(`>`、`>=`、`<=`、`<`、`==`、`!=`)来判断。
对时间戳过滤,可以采用以下函数。其中 ts 为符合 rfc3339 日期时间格式化字符串的字段t1 和 t2 为相对当前时间的秒数,时间范围为 now + t1 ~ now + t2.
```
between_time_range(ts, t1, t2)
// 如果时间范围为最近7点内的才能入库则过滤条件为
between_time_range(ts, -604800, 0)
```
#### 字段类型及转换
只有明确解析出的每个字段的类型,才能使用正确的语法做数据过滤。

View File

@ -19,7 +19,7 @@ DBeaver 是一款流行的跨平台数据库管理工具,方便开发者、数
![DBeaver 连接 TDengine](./dbeaver/dbeaver-connect-tdengine-zh.webp)
2. 配置 TDengine 连接,填入主机地址、端口号、用户名和密码。如果 TDengine 部署在本机,可以只填用户名和密码,默认用户名为 root默认密码为 taosdata。点击“测试连接”可以对连接是否可用进行测试。如果本机没有安装 TDengine Java
2. 配置 TDengine 连接,填入主机地址、端口号6041、用户名和密码。如果 TDengine 部署在本机,可以只填用户名和密码,默认用户名为 root默认密码为 taosdata。点击“测试连接”可以对连接是否可用进行测试。如果本机没有安装 TDengine Java
连接器DBeaver 会提示下载安装。
![配置 TDengine 连接](./dbeaver/dbeaver-config-tdengine-zh.webp)

View File

@ -41,7 +41,7 @@ taosd 命令行参数如下
|resolveFQDNRetryTime | 3.x 之后取消 |不支持动态修改 |FQDN 解析失败时的重试次数|
|timeToGetAvailableConn | 3.3.4.x之后取消 |支持动态修改 重启生效 |获得可用连接的最长等待时间,取值范围 10-50000000单位为毫秒默认值 500000|
|maxShellConns | 3.x 后取消 |支持动态修改 重启生效 |允许创建的最大链接数|
|maxRetryWaitTime | |支持动态修改 重启生效 |重连最大超时时间, 默认值是 10s|
|maxRetryWaitTime | |支持动态修改 重启生效 |重连最大超时时间, 从重试时候开始计算, 取值范围0-86400000, 单位为毫秒, 默认值10000|
|shareConnLimit |3.3.4.0 新增 |支持动态修改 重启生效 |一个链接可以共享的请求的数目,取值范围 1-512默认值 10|
|readTimeout |3.3.4.0 新增 |支持动态修改 重启生效 |单个请求最小超时时间,取值范围 64-604800单位为秒默认值 900|

View File

@ -262,7 +262,21 @@ Prometheus 使用的由 \*NIX 内核暴露的硬件和操作系统指标的输
### 获取 table 的 VGroup ID
可以访问 http 接口 `http://<fqdn>:6041/rest/vgid?db=<db>&table=<table>` 获取 table 的 VGroup ID。
可以 POST 请求 http 接口 `http://<fqdn>:<port>/rest/sql/<db>/vgid` 获取 table 的 VGroup IDbody 是多个表名 JSON 数组。
样例:获取数据库为 power表名为 d_bind_1 和 d_bind_2 的 VGroup ID
```shell
curl --location 'http://127.0.0.1:6041/rest/sql/power/vgid' \
--user 'root:taosdata' \
--data '["d_bind_1","d_bind_2"]'
```
响应:
```json
{"code":0,"vgIDs":[153,152]}
```
## 内存使用优化方法

View File

@ -225,3 +225,5 @@ sc.exe stop taos-explorer # Windows
登录时,请使用数据库用户名和密码登录。首次使用,默认的用户名为 `root`,密码为 `taosdata`。登录成功后即可进入`数据浏览器`页面,您可以使用查看数据库、 创建数据库、创建超级表/子表等管理功能。
其他功能页面,如`数据写入-数据源`等页面,为企业版特有功能,您可以点击查看和简单体验,并不能实际使用。
如果由于网络原因无法完成注册环节,则需要在有外网的环境注册完毕,然后把注册好的 /etc/taos/explorer-register.cfg 替换到内网环境。

View File

@ -218,7 +218,7 @@ ALTER TABLE tb_name COMMENT 'string_value'
DROP TABLE [IF EXISTS] [db_name.]tb_name [, [IF EXISTS] [db_name.]tb_name] ...
```
**注意**:删除表并不会立即释放该表所占用的磁盘空间,而是把该表的数据标记为已删除,在查询时这些数据将不会再出现,但释放磁盘空间会延迟到系统自动或用户手动进行数据重整时。
**注意**:删除表并不会立即释放该表所占用的磁盘空间,而是把该表的数据标记为已删除,在查询时这些数据将不会再出现,但释放磁盘空间会延迟到系统自动(建库参数 keep 生效)或用户手动进行数据重整时(企业版功能 compact
## 查看表的信息

View File

@ -491,15 +491,15 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
:::
## UNION ALL 子句
## UNION 子句
```txt title=语法
SELECT ...
UNION ALL SELECT ...
[UNION ALL SELECT ...]
UNION [ALL] SELECT ...
[UNION [ALL] SELECT ...]
```
TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION ALL 把这些结果集合并到一起。目前只支持 UNION ALL 模式,也即在结果集的合并过程中是不去重的。在同一个 sql 语句中UNION ALL 最多支持 100 个。
TDengine 支持 UNION [ALL] 操作符。也就是说,如果多个 SELECT 子句返回结果集的结构完全相同(列名、列类型、列数、顺序),那么可以通过 UNION [ALL] 把这些结果集合并到一起。
## SQL 示例

View File

@ -231,6 +231,7 @@ description: TDengine 保留关键字的详细列表
| LEADER | |
| LEADING | |
| LEFT | |
| LEVEL | 3.3.0.0 到 3.3.2.11 的所有版本 |
| LICENCES | |
| LIKE | |
| LIMIT | |

View File

@ -4,7 +4,10 @@ title: 窗口预聚集
description: 窗口预聚集使用说明
---
为了提高大数据量的聚合函数查询性能,通过创建窗口预聚集 (TSMA Time-Range Small Materialized Aggregates) 对象, 使用固定时间窗口对指定的聚集函数进行预计算,并将计算结果存储下来,查询时通过查询预计算结果以提高查询性能。
在大数据量场景下, 经常需要查询某段时间内的汇总结果, 当历史数据变多或者时间范围变大时, 查询时间也会相应增加. 通过预聚集的方式可以将计算结果提前存储下来, 后续查询可以直接读取聚集结果, 而不需要扫描原始数据, 如当前Block内的SMA (Small Materialized Aggregates)信息.
Block内的SMA信息粒度较小, 若查询时间范围是日,月甚至年时, Block的数量将会很多, 因此TSMA (Time-Range Small Materialized Aggregates)支持用户指定时间窗口进行预聚集. 通过对固定时间窗口内的数据进行预计算, 并将计算结果存储下来, 查询时通过查询预计算结果以提高查询性能。
![TSMA Introduction](./pic/TSMA_intro.png)
## 创建TSMA

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -509,7 +509,7 @@ TDengine 推荐数据库应用的每个线程都建立一个独立的连接,
- **接口说明**:用于轮询消费数据,每一个消费者,只能单线程调用该接口。
- tmq[入参] 指向一个有效的 ws_tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
- timeout[入参] 轮询的超时时间单位为毫秒负数表示默认超时1秒。
- **返回值**:非 `NULL`:成功,返回一个指向 WS_RES 结构体的指针,该结构体包含了接收到的消息。`NULL`失败,表示没有数据。WS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 WS_RES 里的信息,比如 schema 等。
- **返回值**:非 `NULL`:成功,返回一个指向 WS_RES 结构体的指针,该结构体包含了接收到的消息。`NULL`:表示没有数据, 可通过 ws_errno(NULL) 获取错误码,具体错误码参见参考手册。WS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 WS_RES 里的信息,比如 schema 等。
- `int32_t ws_tmq_consumer_close(ws_tmq_t *tmq)`
- **接口说明**:用于关闭 ws_tmq_t 结构体。需与 ws_tmq_consumer_new 配合使用。
@ -1189,7 +1189,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
- `int32_t tmq_consumer_close(tmq_t *tmq)`
- **接口说明**:用于关闭 tmq_t 结构体。需与 tmq_consumer_new 配合使用。
- tmq[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。
- **返回值**`0`:成功。非 `0`:失败,可调用函数 `char *tmq_err2str(int32_t code)` 获取更详细的错误信息
- **返回值**非 `NULL`:成功,返回一个指向 TAOS_RES 结构体的指针,该结构体包含了接收到的消息。。`NULL`表示没有数据可通过taos_errno(NULL) 获取错误码具体错误码参见参考手册。TAOS_RES 结果和 taos_query 返回结果一致,可通过查询的各种接口获取 TAOS_RES 里的信息,比如 schema 等
- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)`
- **接口说明**:返回当前 consumer 分配的 vgroup 的信息,每个 vgroup 的信息包括 vgIdwal 的最大最小 offset以及当前消费到的 offset。

View File

@ -24,6 +24,7 @@ import RequestId from "./_request_id.mdx";
| Connector 版本 | 主要变化 | TDengine 版本 |
|:-------------|:---------------------------|:--------------|
| 3.1.5 | 修复 websocket 协议编码中文时长度错误 | - |
| 3.1.4 | 提升 websocket 查询和写入性能 | 3.3.2.0 及更高版本 |
| 3.1.3 | 支持 WebSocket 自动重连 | - |
| 3.1.2 | 修复 schemaless 资源释放 | - |

View File

@ -253,7 +253,7 @@ C 接口网络不可用相关错误码:
- code`int`0 代表成功。
- column_meta`[][3]any` 列信息每个列会用三个值来说明分别为列名string、列类型string、类型长度int
- rows`int`)数据返回行数。
- data`[][]any`)具体数据内容(时间格式仅支持 RFC3339结果集为 0 时区)。
- data`[][]any`)具体数据内容(时间格式仅支持 RFC3339结果集为 0 时区,指定 tz 时返回对应时区)。
列类型使用如下字符串:
@ -435,7 +435,6 @@ curl http://<fqnd>:<port>/rest/login/<username>/<password>
其中,`fqdn` 是 TDengine 数据库的 FQDN 或 IP 地址,`port` 是 TDengine 服务的端口号,`username` 为数据库用户名,`password` 为数据库密码,返回值为 JSON 格式,各字段含义如下:
- status请求结果的标志位。
- code返回值代码。
- desc授权码。

View File

@ -554,5 +554,6 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x80004000 | Invalid message | 订阅到的数据非法,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80004001 | Consumer mismatch | 订阅请求的vnode和重新分配的vnode不一致一般存在于有新消费者加入相同消费者组里时 | 内部错误,不暴露给用户 |
| 0x80004002 | Consumer closed | 消费者已经不存在了 | 查看是否已经close掉了 |
| 0x80004017 | Invalid status, please subscribe topic first | 数据订阅状态不对 | 没有调用 subscribe直接poll数据 |
| 0x80004100 | Stream task not exist | 流计算任务不存在 | 具体查看server端的错误日志 |

View File

@ -18,9 +18,9 @@ taosc 的执行过程可以简要总结为:解析 SQL 为 AST生成逻辑
### mnode
在 TDengine 集群中超级表的信息和元数据库的基础信息都得到妥善管理。mnode 为元数据服务器,负责响应 taosc 的元数据查询请求。当 taosc 需要获取 vgroup 等元数据信息时,它会向 mnode 发送请求。mnode 在收到请求后,会迅速返回所需的信息,确保 taosc 能够顺利执行其操作。
在 TDengine 集群中超级表的信息和元数据库的基础信息都得到妥善管理。mnode 为元数据服务器,负责响应 taosc 的元数据查询请求。当 taosc 需要获取 vgroup 等元数据信息时,它会向 mnode 发送请求。mnode 在收到请求后,会迅速返回所需的信息,确保 taosc 能够顺利执行其操作。
此外mnode 还负责接收 taosc 发送的心跳信息。这些心跳信息有助于维持 aosc 与 mnode 之间的连接状态,确保两者之间的通信畅通无阻。
此外mnode 还负责接收 taosc 发送的心跳信息。这些心跳信息有助于维持 taosc 与 mnode 之间的连接状态,确保两者之间的通信畅通无阻。
### vnode

View File

@ -123,6 +123,10 @@ enum {
TMQ_MSG_TYPE__POLL_BATCH_META_RSP,
};
static char* tmqMsgTypeStr[] = {
"data", "meta", "ask ep", "meta data", "wal info", "batch meta"
};
enum {
STREAM_INPUT__DATA_SUBMIT = 1,
STREAM_INPUT__DATA_BLOCK,

View File

@ -57,9 +57,9 @@ const static uint8_t BIT2_MAP[4] = {0b11111100, 0b11110011, 0b11001111, 0b001111
#define ONE ((uint8_t)1)
#define THREE ((uint8_t)3)
#define DIV_8(i) ((i) >> 3)
#define MOD_8(i) ((i) & 7)
#define MOD_8(i) ((i)&7)
#define DIV_4(i) ((i) >> 2)
#define MOD_4(i) ((i) & 3)
#define MOD_4(i) ((i)&3)
#define MOD_4_TIME_2(i) (MOD_4(i) << 1)
#define BIT1_SIZE(n) (DIV_8((n)-1) + 1)
#define BIT2_SIZE(n) (DIV_4((n)-1) + 1)
@ -201,8 +201,10 @@ int32_t tColDataSortMerge(SArray **arr);
int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap,
char *data);
// for encode/decode
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData);
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData);
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData);
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow);
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow);
// STRUCT ================================
struct STColumn {

View File

@ -261,6 +261,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_UPDATE_DNODE_INFO, "update-dnode-info", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_AUDIT, "audit", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG, "init-config", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG_SDB, "config-sdb", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_RESET_STREAM, "reset-stream", NULL, NULL)
TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG)

View File

@ -374,7 +374,7 @@ void* getTaskPoolWorkerCb();
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR || \
(_code) == TSDB_CODE_VND_STOPPED || (_code) == TSDB_CODE_APP_IS_STARTING || (_code) == TSDB_CODE_APP_IS_STOPPING)
#define SYNC_SELF_LEADER_REDIRECT_ERROR(_code) \
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR)
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR || (_code) == TSDB_CODE_SYN_TIMEOUT)
#define SYNC_OTHER_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_MNODE_NOT_FOUND)
#define NO_RET_REDIRECT_ERROR(_code) \

View File

@ -176,7 +176,9 @@ typedef struct SSyncFSM {
void (*FpRollBackCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
void (*FpRestoreFinishCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
void (*FpAfterRestoredCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
void (*FpReConfigCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SReConfigCbMeta* pMeta);
void (*FpLeaderTransferCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
bool (*FpApplyQueueEmptyCb)(const struct SSyncFSM* pFsm);
int32_t (*FpApplyQueueItems)(const struct SSyncFSM* pFsm);

View File

@ -47,6 +47,7 @@ const char* terrstr();
char* taosGetErrMsgReturn();
char* taosGetErrMsg();
void taosClearErrMsg();
int32_t* taosGetErrno();
int32_t* taosGetErrln();
int32_t taosGetErrSize();
@ -1014,6 +1015,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT TAOS_DEF_ERROR_CODE(0, 0x4014)
#define TSDB_CODE_TMQ_NO_TABLE_QUALIFIED TAOS_DEF_ERROR_CODE(0, 0x4015)
#define TSDB_CODE_TMQ_NO_NEED_REBALANCE TAOS_DEF_ERROR_CODE(0, 0x4016)
#define TSDB_CODE_TMQ_INVALID_STATUS TAOS_DEF_ERROR_CODE(0, 0x4017)
// stream
#define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100)

View File

@ -562,6 +562,7 @@ typedef enum ELogicConditionType {
#define TSDB_QUERY_CLEAR_TYPE(x, _type) ((x) &= (~_type))
#define TSDB_QUERY_RESET_TYPE(x) ((x) = TSDB_QUERY_TYPE_NON_TYPE)
#define TSDB_ORDER_NONE 0
#define TSDB_ORDER_ASC 1
#define TSDB_ORDER_DESC 2
@ -668,6 +669,14 @@ typedef enum {
ANAL_ALGO_TYPE_END,
} EAnalAlgoType;
typedef enum {
TSDB_VERSION_UNKNOWN = 0,
TSDB_VERSION_OSS,
TSDB_VERSION_ENTERPRISE,
TSDB_VERSION_CLOUD,
TSDB_VERSION_END,
} EVersionType;
#define MIN_RESERVE_MEM_SIZE 1024 // MB
#ifdef __cplusplus

View File

@ -118,6 +118,7 @@ static int32_t tDecodeI64v(SDecoder* pCoder, int64_t* val);
static int32_t tDecodeFloat(SDecoder* pCoder, float* val);
static int32_t tDecodeDouble(SDecoder* pCoder, double* val);
static int32_t tDecodeBool(SDecoder* pCoder, bool* val);
static int32_t tDecodeBinaryWithSize(SDecoder* pCoder, uint32_t size, uint8_t** val);
static int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len);
static int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len);
static int32_t tDecodeCStr(SDecoder* pCoder, char** val);
@ -404,6 +405,19 @@ static int32_t tDecodeBool(SDecoder* pCoder, bool* val) {
return 0;
}
static FORCE_INLINE int32_t tDecodeBinaryWithSize(SDecoder* pCoder, uint32_t size, uint8_t** val) {
if (pCoder->pos + size > pCoder->size) {
TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
}
if (val) {
*val = pCoder->data + pCoder->pos;
}
pCoder->pos += size;
return 0;
}
static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint32_t* len) {
uint32_t length = 0;
@ -412,21 +426,12 @@ static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint3
*len = length;
}
if (pCoder->pos + length > pCoder->size) {
TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
}
if (val) {
*val = pCoder->data + pCoder->pos;
}
pCoder->pos += length;
return 0;
TAOS_RETURN(tDecodeBinaryWithSize(pCoder, length, val));
}
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
TAOS_CHECK_RETURN(tDecodeBinary(pCoder, (uint8_t**)val, len));
if (*len > 0) { // notice!!! *len maybe 0
if (*len > 0) { // notice!!! *len maybe 0
(*len) -= 1;
}
return 0;
@ -497,7 +502,7 @@ static FORCE_INLINE int32_t tDecodeBinaryAlloc32(SDecoder* pCoder, void** val, u
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
TAOS_CHECK_RETURN(tDecodeBinaryAlloc(pCoder, (void**)val, len));
if (*len > 0){
if (*len > 0) {
(*len) -= 1;
}
return 0;

View File

@ -15,7 +15,7 @@ TimeoutStartSec=0
StandardOutput=null
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
StartLimitInterval=900s
[Install]
WantedBy=multi-user.target

View File

@ -553,7 +553,7 @@ function install_service_on_systemd() {
${csudo}bash -c "echo 'StandardOutput=null' >> ${taosd_service_config}"
${csudo}bash -c "echo 'Restart=always' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitBurst=3' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitInterval=60s' >> ${taosd_service_config}"
${csudo}bash -c "echo 'StartLimitInterval=900s' >> ${taosd_service_config}"
${csudo}bash -c "echo >> ${taosd_service_config}"
${csudo}bash -c "echo '[Install]' >> ${taosd_service_config}"
${csudo}bash -c "echo 'WantedBy=multi-user.target' >> ${taosd_service_config}"

View File

@ -2572,6 +2572,7 @@ int32_t tmq_write_raw(TAOS* taos, tmq_raw_data raw) {
SET_ERROR_MSG("taos:%p or data:%p is NULL or raw_len <= 0", taos, raw.raw);
return TSDB_CODE_INVALID_PARA;
}
taosClearErrMsg(); // clear global error message
return writeRawImpl(taos, raw.raw, raw.raw_len, raw.raw_type);
}

View File

@ -64,6 +64,7 @@ enum {
enum {
TMQ_CONSUMER_STATUS__INIT = 0,
TMQ_CONSUMER_STATUS__READY,
TMQ_CONSUMER_STATUS__LOST,
TMQ_CONSUMER_STATUS__CLOSED,
};
@ -768,7 +769,7 @@ static int32_t innerCommit(tmq_t* tmq, char* pTopicName, STqOffsetVal* offsetVal
}
tqDebugC("consumer:0x%" PRIx64 " topic:%s on vgId:%d send commit msg success, send offset:%s committed:%s",
tmq->consumerId, pTopicName, pVg->vgId, offsetBuf, commitBuf);
tmq->consumerId, pTopicName, pVg->vgId, offsetBuf, commitBuf);
tOffsetCopy(&pVg->offsetInfo.committedOffset, offsetVal);
return code;
}
@ -823,7 +824,7 @@ static void asyncCommitFromResult(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_c
code = asyncCommitOffset(tmq, pTopicName, vgId, &offsetVal, pCommitFp, userParam);
end:
end:
if (code != TSDB_CODE_SUCCESS && pCommitFp != NULL) {
if (code == TSDB_CODE_TMQ_SAME_COMMITTED_VALUE) code = TSDB_CODE_SUCCESS;
pCommitFp(tmq, code, userParam);
@ -863,7 +864,7 @@ static int32_t innerCommitAll(tmq_t* tmq, SMqCommitCbParamSet* pParamSet){
}
tqDebugC("consumer:0x%" PRIx64 " total commit:%d for %d topics", tmq->consumerId, pParamSet->waitingRspNum - DEFAULT_COMMIT_CNT,
numOfTopics);
END:
END:
taosRUnLockLatch(&tmq->lock);
return code;
}
@ -988,7 +989,7 @@ int32_t tmqHbCb(void* param, SDataBuf* pMsg, int32_t code) {
tDestroySMqHbRsp(&rsp);
END:
END:
taosMemoryFree(pMsg->pData);
taosMemoryFree(pMsg->pEpSet);
return code;
@ -1088,7 +1089,7 @@ void tmqSendHbReq(void* param, void* tmrId) {
}
(void)atomic_val_compare_exchange_8(&tmq->pollFlag, 1, 0);
END:
END:
tDestroySMqHbReq(&req);
if (tmrId != NULL) {
bool ret = taosTmrReset(tmqSendHbReq, tmq->heartBeatIntervalMs, param, tmqMgmt.timer, &tmq->hbLiveTimer);
@ -1209,9 +1210,9 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
}
static void buildNewTopicList(tmq_t* tmq, SArray* newTopics, const SMqAskEpRsp* pRsp){
if (tmq == NULL || newTopics == NULL || pRsp == NULL) {
return;
}
if (tmq == NULL || newTopics == NULL || pRsp == NULL) {
return;
}
SHashObj* pVgOffsetHashMap = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
if (pVgOffsetHashMap == NULL) {
tqErrorC("consumer:0x%" PRIx64 " taos hash init null, code:%d", tmq->consumerId, terrno);
@ -1266,9 +1267,9 @@ static void buildNewTopicList(tmq_t* tmq, SArray* newTopics, const SMqAskEpRsp*
}
static void doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp) {
if (tmq == NULL || pRsp == NULL) {
return;
}
if (tmq == NULL || pRsp == NULL) {
return;
}
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
// vnode transform (epoch == tmq->epoch && topicNumGet != 0)
// ask ep rsp (epoch == tmq->epoch && topicNumGet == 0)
@ -1318,6 +1319,9 @@ static int32_t askEpCb(void* param, SDataBuf* pMsg, int32_t code) {
if (code != TSDB_CODE_SUCCESS) {
if (code != TSDB_CODE_MND_CONSUMER_NOT_READY){
tqErrorC("consumer:0x%" PRIx64 ", get topic endpoint error, code:%s", tmq->consumerId, tstrerror(code));
if (code == TSDB_CODE_MND_CONSUMER_NOT_EXIST){
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__LOST);
}
}
goto END;
}
@ -1388,49 +1392,32 @@ static int32_t askEp(tmq_t* pTmq, void* param, bool sync, bool updateEpSet) {
if (pTmq == NULL) {
return TSDB_CODE_INVALID_PARA;
}
int32_t code = 0;
int32_t lino = 0;
SMqAskEpReq req = {0};
req.consumerId = pTmq->consumerId;
req.epoch = updateEpSet ? -1 : pTmq->epoch;
tstrncpy(req.cgroup, pTmq->groupId, TSDB_CGROUP_LEN);
int code = 0;
SMqAskEpCbParam* pParam = NULL;
void* pReq = NULL;
int32_t tlen = tSerializeSMqAskEpReq(NULL, 0, &req);
if (tlen < 0) {
tqErrorC("consumer:0x%" PRIx64 ", tSerializeSMqAskEpReq failed", pTmq->consumerId);
return TSDB_CODE_INVALID_PARA;
}
TSDB_CHECK_CONDITION(tlen >= 0, code, lino, END, TSDB_CODE_INVALID_PARA);
pReq = taosMemoryCalloc(1, tlen);
if (pReq == NULL) {
tqErrorC("consumer:0x%" PRIx64 ", failed to malloc askEpReq msg, size:%d", pTmq->consumerId, tlen);
return terrno;
}
TSDB_CHECK_NULL(pReq, code, lino, END, terrno);
if (tSerializeSMqAskEpReq(pReq, tlen, &req) < 0) {
tqErrorC("consumer:0x%" PRIx64 ", tSerializeSMqAskEpReq %d failed", pTmq->consumerId, tlen);
taosMemoryFree(pReq);
return TSDB_CODE_INVALID_PARA;
}
code = tSerializeSMqAskEpReq(pReq, tlen, &req);
TSDB_CHECK_CONDITION(code >= 0, code, lino, END, TSDB_CODE_INVALID_PARA);
pParam = taosMemoryCalloc(1, sizeof(SMqAskEpCbParam));
if (pParam == NULL) {
tqErrorC("consumer:0x%" PRIx64 ", failed to malloc subscribe param", pTmq->consumerId);
taosMemoryFree(pReq);
return terrno;
}
TSDB_CHECK_NULL(pParam, code, lino, END, terrno);
pParam->refId = pTmq->refId;
pParam->sync = sync;
pParam->pParam = param;
SMsgSendInfo* sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
if (sendInfo == NULL) {
taosMemoryFree(pReq);
taosMemoryFree(pParam);
return terrno;
}
TSDB_CHECK_NULL(sendInfo, code, lino, END, terrno);
sendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = tlen, .handle = NULL};
sendInfo->requestId = generateRequestId();
@ -1440,28 +1427,36 @@ static int32_t askEp(tmq_t* pTmq, void* param, bool sync, bool updateEpSet) {
sendInfo->fp = askEpCb;
sendInfo->msgType = TDMT_MND_TMQ_ASK_EP;
pReq = NULL;
pParam = NULL;
SEpSet epSet = getEpSet_s(&pTmq->pTscObj->pAppInfo->mgmtEp);
tqDebugC("consumer:0x%" PRIx64 " ask ep from mnode,QID:0x%" PRIx64, pTmq->consumerId, sendInfo->requestId);
return asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, NULL, sendInfo);
code = asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, NULL, sendInfo);
END:
if (code != 0) {
tqErrorC("%s failed at %d, msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFree(pReq);
taosMemoryFree(pParam);
return code;
}
void tmqHandleAllDelayedTask(tmq_t* pTmq) {
if (pTmq == NULL) {
return;
}
static int32_t tmqHandleAllDelayedTask(tmq_t* pTmq) {
STaosQall* qall = NULL;
int32_t code = 0;
code = taosAllocateQall(&qall);
if (code) {
tqErrorC("consumer:0x%" PRIx64 ", failed to allocate qall, code:%s", pTmq->consumerId, tstrerror(code));
return;
return code;
}
int32_t numOfItems = taosReadAllQitems(pTmq->delayedTask, qall);
if (numOfItems == 0) {
taosFreeQall(qall);
return;
return 0;
}
tqDebugC("consumer:0x%" PRIx64 " handle delayed %d tasks before poll data", pTmq->consumerId, numOfItems);
@ -1472,7 +1467,6 @@ void tmqHandleAllDelayedTask(tmq_t* pTmq) {
code = askEp(pTmq, NULL, false, false);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", pTmq->consumerId, tstrerror(code));
continue;
}
tqDebugC("consumer:0x%" PRIx64 " retrieve ep from mnode in 1s", pTmq->consumerId);
bool ret = taosTmrReset(tmqAssignAskEpTask, DEFAULT_ASKEP_INTERVAL, (void*)(pTmq->refId), tmqMgmt.timer,
@ -1494,6 +1488,7 @@ void tmqHandleAllDelayedTask(tmq_t* pTmq) {
}
taosFreeQall(qall);
return 0;
}
void tmqClearUnhandleMsg(tmq_t* tmq) {
@ -1562,7 +1557,7 @@ int32_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
}
void tmqFreeImpl(void* handle) {
if (handle == NULL) return;
if (handle == NULL) return;
tmq_t* tmq = (tmq_t*)handle;
int64_t id = tmq->consumerId;
@ -1759,13 +1754,13 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
STqOffsetVal offset = {.type = pTmq->resetOffsetCfg};
tFormatOffset(buf, tListLen(buf), &offset);
tqInfoC("consumer:0x%" PRIx64 " is setup, refId:%" PRId64
", groupId:%s, snapshot:%d, autoCommit:%d, commitInterval:%dms, offset:%s",
", groupId:%s, snapshot:%d, autoCommit:%d, commitInterval:%dms, offset:%s",
pTmq->consumerId, pTmq->refId, pTmq->groupId, pTmq->useSnapshot, pTmq->autoCommit, pTmq->autoCommitInterval,
buf);
return pTmq;
_failed:
_failed:
tmqFreeImpl(pTmq);
return NULL;
}
@ -1942,7 +1937,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
}
}
END:
END:
taosArrayDestroyP(req.topicNames, NULL);
return code;
}
@ -2032,7 +2027,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
if (msgEpoch != clientEpoch) {
tqErrorC("consumer:0x%" PRIx64
" msg discard from vgId:%d since epoch not equal, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64,
" msg discard from vgId:%d since epoch not equal, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64,
tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId);
code = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
goto END;
@ -2057,7 +2052,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
pRspWrapper->pollRsp.pEpset = pMsg->pEpSet;
pMsg->pEpSet = NULL;
END:
END:
if (pRspWrapper) {
pRspWrapper->code = code;
pRspWrapper->pollRsp.vgId = vgId;
@ -2082,7 +2077,7 @@ END:
tqErrorC("failed to release ref:%"PRId64 ", code:%d", refId, ret);
}
EXIT:
EXIT:
taosMemoryFreeClear(pMsg->pData);
taosMemoryFreeClear(pMsg->pEpSet);
return code;
@ -2095,7 +2090,7 @@ void tmqBuildConsumeReqImpl(SMqPollReq* pReq, tmq_t* tmq, int64_t timeout, SMqCl
(void)snprintf(pReq->subKey, TSDB_SUBSCRIBE_KEY_LEN, "%s%s%s", tmq->groupId, TMQ_SEPARATOR, pTopic->topicName);
pReq->withTbName = tmq->withTbName;
pReq->consumerId = tmq->consumerId;
pReq->timeout = timeout;
pReq->timeout = timeout < 0 ? INT32_MAX : timeout;
pReq->epoch = tmq->epoch;
pReq->reqOffset = pVg->offsetInfo.endOffset;
pReq->head.vgId = pVg->vgId;
@ -2199,39 +2194,24 @@ static void tmqBuildRspFromWrapperInner(SMqPollRspWrapper* pWrapper, SMqClientVg
}
static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* pVg, int64_t timeout) {
if (pTmq == NULL || pTopic == NULL || pVg == NULL) {
return TSDB_CODE_INVALID_MSG;
}
SMqPollReq req = {0};
char* msg = NULL;
SMqPollCbParam* pParam = NULL;
SMsgSendInfo* sendInfo = NULL;
int code = 0;
int lino = 0;
tmqBuildConsumeReqImpl(&req, pTmq, timeout, pTopic, pVg);
int32_t msgSize = tSerializeSMqPollReq(NULL, 0, &req);
if (msgSize < 0) {
code = TSDB_CODE_INVALID_MSG;
return code;
}
TSDB_CHECK_CONDITION(msgSize >= 0, code, lino, END, TSDB_CODE_INVALID_MSG);
msg = taosMemoryCalloc(1, msgSize);
if (NULL == msg) {
return terrno;
}
TSDB_CHECK_NULL(msg, code, lino, END, terrno);
if (tSerializeSMqPollReq(msg, msgSize, &req) < 0) {
code = TSDB_CODE_INVALID_MSG;
taosMemoryFreeClear(msg);
return code;
}
TSDB_CHECK_CONDITION(tSerializeSMqPollReq(msg, msgSize, &req) >= 0, code, lino, END, TSDB_CODE_INVALID_MSG);
pParam = taosMemoryMalloc(sizeof(SMqPollCbParam));
if (pParam == NULL) {
code = terrno;
taosMemoryFreeClear(msg);
return code;
}
TSDB_CHECK_NULL(pParam, code, lino, END, terrno);
pParam->refId = pTmq->refId;
tstrncpy(pParam->topicName, pTopic->topicName, TSDB_TOPIC_FNAME_LEN);
@ -2239,11 +2219,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
pParam->requestId = req.reqId;
sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
if (sendInfo == NULL) {
taosMemoryFreeClear(pParam);
taosMemoryFreeClear(msg);
return terrno;
}
TSDB_CHECK_NULL(sendInfo, code, lino, END, terrno);
sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL};
sendInfo->requestId = req.reqId;
@ -2253,30 +2229,41 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
sendInfo->fp = tmqPollCb;
sendInfo->msgType = TDMT_VND_TMQ_CONSUME;
msg = NULL;
pParam = NULL;
char offsetFormatBuf[TSDB_OFFSET_LEN] = {0};
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.endOffset);
code = asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &pVg->epSet, NULL, sendInfo);
tqDebugC("consumer:0x%" PRIx64 " send poll to %s vgId:%d, code:%d, epoch %d, req:%s,QID:0x%" PRIx64, pTmq->consumerId,
pTopic->topicName, pVg->vgId, code, pTmq->epoch, offsetFormatBuf, req.reqId);
if (code != 0) {
return code;
}
TSDB_CHECK_CODE(code, lino, END);
pVg->pollCnt++;
pVg->seekUpdated = false; // reset this flag.
pTmq->pollCnt++;
return 0;
END:
if (code != 0){
tqErrorC("%s failed at %d msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFreeClear(pParam);
taosMemoryFreeClear(msg);
return code;
}
// broadcast the poll request to all related vnodes
static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) {
return TSDB_CODE_INVALID_MSG;
}
int32_t code = 0;
taosWLockLatch(&tmq->lock);
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__LOST){
code = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
goto end;
}
int32_t numOfTopics = taosArrayGetSize(tmq->clientTopics);
tqDebugC("consumer:0x%" PRIx64 " start to poll data, numOfTopics:%d", tmq->consumerId, numOfTopics);
@ -2325,7 +2312,7 @@ static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
}
}
end:
end:
taosWUnLockLatch(&tmq->lock);
tqDebugC("consumer:0x%" PRIx64 " end to poll data, code:%d", tmq->consumerId, code);
return code;
@ -2361,9 +2348,6 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){
SMqBatchMetaRsp batchMetaRsp;
} MEMSIZE;
if (pollRspWrapper == NULL) {
return NULL;
}
SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj));
if (pRspObj == NULL) {
tqErrorC("buildRsp:failed to allocate memory");
@ -2377,22 +2361,22 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){
return pRspObj;
}
static void processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if (tmq == NULL || pRspWrapper == NULL) {
return;
}
static int32_t processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
int32_t code = 0;
SMqPollRspWrapper* pollRspWrapper = &pRspWrapper->pollRsp;
if (pRspWrapper->code == TSDB_CODE_VND_INVALID_VGROUP_ID) { // for vnode transform
int32_t code = askEp(tmq, NULL, false, true);
code = askEp(tmq, NULL, false, true);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", tmq->consumerId, tstrerror(code));
}
} else if (pRspWrapper->code == TSDB_CODE_TMQ_CONSUMER_MISMATCH) {
int32_t code = askEp(tmq, NULL, false, false);
code = askEp(tmq, NULL, false, false);
if (code != 0) {
tqErrorC("consumer:0x%" PRIx64 " failed to ask ep, code:%s", tmq->consumerId, tstrerror(code));
}
} else if (pRspWrapper->code == TSDB_CODE_TMQ_NO_TABLE_QUALIFIED){
code = 0;
}
tqInfoC("consumer:0x%" PRIx64 " msg from vgId:%d discarded, since %s", tmq->consumerId, pollRspWrapper->vgId,
tstrerror(pRspWrapper->code));
@ -2404,17 +2388,18 @@ static void processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
}
taosWUnLockLatch(&tmq->lock);
return code;
}
static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if (tmq == NULL || pRspWrapper == NULL) {
return NULL;
}
int32_t code = 0;
SMqRspObj* pRspObj = NULL;
if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__EP_RSP) {
tqDebugC("consumer:0x%" PRIx64 " ep msg received", tmq->consumerId);
SMqAskEpRsp* rspMsg = &pRspWrapper->epRsp;
doUpdateLocalEp(tmq, pRspWrapper->epoch, rspMsg);
terrno = code;
return pRspObj;
}
@ -2425,6 +2410,7 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
if(pVg == NULL) {
tqErrorC("consumer:0x%" PRIx64 " get vg or topic error, topic:%s vgId:%d", tmq->consumerId,
pollRspWrapper->topicName, pollRspWrapper->vgId);
code = TSDB_CODE_TMQ_INVALID_VGID;
goto END;
}
pollRspWrapper->topicHandle = getTopicInfo(tmq, pollRspWrapper->topicName);
@ -2483,88 +2469,92 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){
}
END:
terrno = code;
taosWUnLockLatch(&tmq->lock);
return pRspObj;
}
static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) {
return NULL;
}
static void* tmqHandleAllRsp(tmq_t* tmq) {
tqDebugC("consumer:0x%" PRIx64 " start to handle the rsp, total:%d", tmq->consumerId, taosQallItemSize(tmq->qall));
int32_t code = 0;
void* returnVal = NULL;
while (1) {
SMqRspWrapper* pRspWrapper = NULL;
if (taosGetQitem(tmq->qall, (void**)&pRspWrapper) == 0) {
if (taosReadAllQitems(tmq->mqueue, tmq->qall) == 0){
return NULL;
code = taosReadAllQitems(tmq->mqueue, tmq->qall);
if (code == 0){
goto END;
}
if (taosGetQitem(tmq->qall, (void**)&pRspWrapper) == 0) {
return NULL;
code = taosGetQitem(tmq->qall, (void**)&pRspWrapper);
if (code == 0) {
goto END;
}
}
tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%d", tmq->consumerId, pRspWrapper->tmqRspType);
tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%s", tmq->consumerId, tmqMsgTypeStr[pRspWrapper->tmqRspType]);
if (pRspWrapper->code != 0) {
processMqRspError(tmq, pRspWrapper);
code = processMqRspError(tmq, pRspWrapper);
}else{
returnVal = processMqRsp(tmq, pRspWrapper);
code = terrno;
}
tmqFreeRspWrapper(pRspWrapper);
taosFreeQitem(pRspWrapper);
if(returnVal != NULL){
if(returnVal != NULL || code != 0){
break;
}
}
END:
terrno = code;
return returnVal;
}
TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
if (tmq == NULL) return NULL;
int32_t lino = 0;
int32_t code = 0;
TSDB_CHECK_NULL(tmq, code, lino, END, TSDB_CODE_INVALID_PARA);
void* rspObj = NULL;
int64_t startTime = taosGetTimestampMs();
tqDebugC("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
timeout);
// in no topic status, delayed task also need to be processed
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
tqInfoC("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId);
taosMsleep(500); // sleep for a while
return NULL;
}
tqDebugC("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime, timeout);
TSDB_CHECK_CONDITION(atomic_load_8(&tmq->status) != TMQ_CONSUMER_STATUS__INIT, code, lino, END, TSDB_CODE_TMQ_INVALID_STATUS);
(void)atomic_val_compare_exchange_8(&tmq->pollFlag, 0, 1);
while (1) {
tmqHandleAllDelayedTask(tmq);
code = tmqHandleAllDelayedTask(tmq);
TSDB_CHECK_CODE(code, lino, END);
if (tmqPollImpl(tmq, timeout) < 0) {
tqErrorC("consumer:0x%" PRIx64 " return due to poll error", tmq->consumerId);
}
code = tmqPollImpl(tmq, timeout);
TSDB_CHECK_CODE(code, lino, END);
rspObj = tmqHandleAllRsp(tmq, timeout);
rspObj = tmqHandleAllRsp(tmq);
if (rspObj) {
tqDebugC("consumer:0x%" PRIx64 " return rsp %p", tmq->consumerId, rspObj);
return (TAOS_RES*)rspObj;
}
code = terrno;
TSDB_CHECK_CODE(code, lino, END);
if (timeout >= 0) {
int64_t currentTime = taosGetTimestampMs();
int64_t elapsedTime = currentTime - startTime;
if (elapsedTime > timeout || elapsedTime < 0) {
tqDebugC("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
tmq->consumerId, tmq->epoch, startTime, currentTime);
return NULL;
}
TSDB_CHECK_CONDITION(elapsedTime <= timeout && elapsedTime >= 0, code, lino, END, 0);
(void)tsem2_timewait(&tmq->rspSem, (timeout - elapsedTime));
} else {
(void)tsem2_timewait(&tmq->rspSem, 1000);
}
}
END:
terrno = code;
if (tmq != NULL) {
tqErrorC("consumer:0x%" PRIx64 " poll error at line:%d, msg:%s", tmq->consumerId, lino, tstrerror(terrno));
}
return NULL;
}
static void displayConsumeStatistics(tmq_t* pTmq) {
@ -2572,7 +2562,7 @@ static void displayConsumeStatistics(tmq_t* pTmq) {
taosRLockLatch(&pTmq->lock);
int32_t numOfTopics = taosArrayGetSize(pTmq->clientTopics);
tqInfoC("consumer:0x%" PRIx64 " closing poll:%" PRId64 " rows:%" PRId64 " topics:%d, final epoch:%d",
pTmq->consumerId, pTmq->pollCnt, pTmq->totalRows, numOfTopics, pTmq->epoch);
pTmq->consumerId, pTmq->pollCnt, pTmq->totalRows, numOfTopics, pTmq->epoch);
tqInfoC("consumer:0x%" PRIx64 " rows dist begin: ", pTmq->consumerId);
for (int32_t i = 0; i < numOfTopics; ++i) {
@ -2597,14 +2587,14 @@ int32_t tmq_unsubscribe(tmq_t* tmq) {
tqInfoC("consumer:0x%" PRIx64 " start to unsubscribe consumer, status:%d", tmq->consumerId, status);
displayConsumeStatistics(tmq);
if (status != TMQ_CONSUMER_STATUS__READY) {
if (status != TMQ_CONSUMER_STATUS__READY && status != TMQ_CONSUMER_STATUS__LOST) {
tqInfoC("consumer:0x%" PRIx64 " status:%d, already closed or not in ready state, no need unsubscribe", tmq->consumerId, status);
goto END;
}
if (tmq->autoCommit) {
code = tmq_commit_sync(tmq, NULL);
if (code != 0) {
goto END;
goto END;
}
}
tmqSendHbReq((void*)(tmq->refId), NULL);
@ -2620,7 +2610,7 @@ int32_t tmq_unsubscribe(tmq_t* tmq) {
goto END;
}
END:
END:
return code;
}
@ -2942,7 +2932,7 @@ void tmq_commit_offset_async(tmq_t* tmq, const char* pTopicName, int32_t vgId, i
tqInfoC("consumer:0x%" PRIx64 " async send commit to vgId:%d, offset:%" PRId64 " code:%s", tmq->consumerId, vgId,
offset, tstrerror(code));
end:
end:
if (code != 0 && cb != NULL) {
if (code == TSDB_CODE_TMQ_SAME_COMMITTED_VALUE) code = TSDB_CODE_SUCCESS;
cb(tmq, code, param);
@ -2951,9 +2941,9 @@ end:
int32_t tmqGetNextResInfo(TAOS_RES* res, bool convertUcs4, SReqResultInfo** pResInfo) {
if (res == NULL || pResInfo == NULL) {
return TSDB_CODE_INVALID_PARA;
}
if (res == NULL || pResInfo == NULL) {
return TSDB_CODE_INVALID_PARA;
}
SMqRspObj* pRspObj = (SMqRspObj*)res;
SMqDataRsp* data = &pRspObj->dataRsp;
@ -3014,9 +3004,9 @@ static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
SMqRspHead* pHead = pMsg->pData;
tmq_topic_assignment assignment = {.begin = pHead->walsver,
.end = pHead->walever + 1,
.currentOffset = rsp.rspOffset.version,
.vgId = pParam->vgId};
.end = pHead->walever + 1,
.currentOffset = rsp.rspOffset.version,
.vgId = pParam->vgId};
(void)taosThreadMutexLock(&pCommon->mutex);
if (taosArrayPush(pCommon->pList, &assignment) == NULL) {
@ -3027,7 +3017,7 @@ static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
(void)taosThreadMutexUnlock(&pCommon->mutex);
}
END:
END:
pCommon->code = code;
if (total == pParam->totalReq) {
if (tsem2_post(&pCommon->rsp) != 0) {
@ -3084,7 +3074,7 @@ static int32_t tmCommittedCb(void* param, SDataBuf* pMsg, int32_t code) {
tDecoderClear(&decoder);
}
end:
end:
if (pMsg) {
taosMemoryFree(pMsg->pData);
taosMemoryFree(pMsg->pEpSet);
@ -3290,7 +3280,7 @@ int64_t tmq_committed(tmq_t* tmq, const char* pTopicName, int32_t vgId) {
committed = getCommittedFromServer(tmq, tname, vgId, &epSet);
end:
end:
tqInfoC("consumer:0x%" PRIx64 " tmq_committed vgId:%d committed:%" PRId64, tmq->consumerId, vgId, committed);
return committed;
}
@ -3493,7 +3483,7 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
}
}
end:
end:
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(*assignment);
*assignment = NULL;
@ -3647,4 +3637,4 @@ TAOS* tmq_get_connect(tmq_t* tmq) {
return (TAOS*)(&(tmq->pTscObj->id));
}
return NULL;
}
}

View File

@ -105,12 +105,14 @@ TARGET_INCLUDE_DIRECTORIES(
TARGET_INCLUDE_DIRECTORIES(
stmt2Test
PUBLIC "${TD_SOURCE_DIR}/include/client/"
PUBLIC "${TD_SOURCE_DIR}/include/libs/geometry"
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
)
TARGET_INCLUDE_DIRECTORIES(
stmtTest
PUBLIC "${TD_SOURCE_DIR}/include/client/"
PUBLIC "${TD_SOURCE_DIR}/include/libs/geometry"
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
)

View File

@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include <string.h>
#include "clientInt.h"
#include "geosWrapper.h"
#include "osSemaphore.h"
#include "taoserror.h"
#include "tglobal.h"
@ -33,17 +34,17 @@
#include "taos.h"
namespace {
void checkRows(TAOS* pConn, const char* sql, int32_t expectedRows) {
TAOS_RES* pRes = taos_query(pConn, sql);
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
TAOS_ROW pRow = NULL;
int rows = 0;
while ((pRow = taos_fetch_row(pRes)) != NULL) {
rows++;
void checkError(TAOS_STMT2* stmt, int code) {
if (code != TSDB_CODE_SUCCESS) {
STscStmt2* pStmt = (STscStmt2*)stmt;
if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr) {
printf("stmt api error\n stats : %d\n errstr : %s\n", pStmt->sql.status, taos_stmt_errstr(stmt));
} else {
printf("stmt api error\n sql : %s\n stats : %d\n errstr : %s\n", pStmt->sql.sqlStr, pStmt->sql.status,
taos_stmt_errstr(stmt));
}
ASSERT_EQ(code, TSDB_CODE_SUCCESS);
}
// ASSERT_EQ(rows, expectedRows);
taos_free_result(pRes);
}
void stmtAsyncQueryCb(void* param, TAOS_RES* pRes, int code) {
@ -56,12 +57,12 @@ void getFieldsSuccess(TAOS* taos, const char* sql, TAOS_FIELD_ALL* expectedField
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int fieldNum = 0;
TAOS_FIELD_ALL* pFields = NULL;
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
ASSERT_EQ(code, 0);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedFieldNum);
for (int i = 0; i < fieldNum; i++) {
@ -81,7 +82,7 @@ void getFieldsError(TAOS* taos, const char* sql, int errorCode) {
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int fieldNum = 0;
TAOS_FIELD_ALL* pFields = NULL;
@ -96,12 +97,12 @@ void getQueryFields(TAOS* taos, const char* sql, int expectedFieldNum) {
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int fieldNum = 0;
TAOS_FIELD_ALL* pFields = NULL;
code = taos_stmt2_get_fields(stmt, &fieldNum, NULL);
ASSERT_EQ(code, 0);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedFieldNum);
taos_stmt2_free_fields(stmt, NULL);
taos_stmt2_close(stmt);
@ -109,21 +110,27 @@ void getQueryFields(TAOS* taos, const char* sql, int expectedFieldNum) {
void do_query(TAOS* taos, const char* sql) {
TAOS_RES* result = taos_query(taos, sql);
ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
// printf("sql: %s\n", sql);
int code = taos_errno(result);
if (code != TSDB_CODE_SUCCESS) {
printf("query failen sql : %s\n errstr : %s\n", sql, taos_errstr(result));
ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
}
taos_free_result(result);
}
void do_stmt(TAOS* taos, TAOS_STMT2_OPTION* option, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS,
bool hastags, bool createTable) {
printf("%s\n", sql);
printf("test sql : %s\n", sql);
do_query(taos, "drop database if exists testdb1");
do_query(taos, "create database IF NOT EXISTS testdb1");
do_query(taos, "create table testdb1.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
do_query(taos, "create stable testdb1.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
TAOS_STMT2* stmt = taos_stmt2_init(taos, option);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int total_affected = 0;
// tbname
char** tbs = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*));
@ -182,11 +189,13 @@ void do_stmt(TAOS* taos, TAOS_STMT2_OPTION* option, const char* sql, int CTB_NUM
// bind
TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, tags, paramv};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
// exec
code = taos_stmt2_exec(stmt, NULL);
ASSERT_EQ(code, 0);
int affected;
code = taos_stmt2_exec(stmt, &affected);
total_affected += affected;
checkError(stmt, code);
for (int i = 0; i < CTB_NUMS; i++) {
if (hastags) {
@ -206,7 +215,7 @@ void do_stmt(TAOS* taos, TAOS_STMT2_OPTION* option, const char* sql, int CTB_NUM
}
}
checkRows(taos, "select * from testdb1.stb", CYC_NUMS * ROW_NUMS * CTB_NUMS);
ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS);
for (int i = 0; i < CTB_NUMS; i++) {
taosMemoryFree(tbs[i]);
}
@ -229,12 +238,12 @@ TEST(stmt2Case, insert_stb_get_fields_Test) {
do_query(taos, "drop database if exists testdb2");
do_query(taos, "create database IF NOT EXISTS testdb2 PRECISION 'ns'");
do_query(taos,
"create table testdb2.stb (ts timestamp, b binary(10)) tags(t1 "
"create stable testdb2.stb (ts timestamp, b binary(10)) tags(t1 "
"int, t2 binary(10))");
do_query(
taos,
"create table if not exists testdb2.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 "
"tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
"create stable if not exists testdb2.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, "
"v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
"binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 "
"smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint "
"unsigned, tv10 float, tv11 double, tv12 binary(20), tv13 varbinary(20), tv14 geometry(100), tv15 nchar(20));");
@ -440,12 +449,12 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
do_query(taos, "drop database if exists testdb3");
do_query(taos, "create database IF NOT EXISTS testdb3 PRECISION 'ns'");
do_query(taos,
"create table testdb3.stb (ts timestamp, b binary(10)) tags(t1 "
"create stable testdb3.stb (ts timestamp, b binary(10)) tags(t1 "
"int, t2 binary(10))");
do_query(
taos,
"create table if not exists testdb3.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 "
"tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
"create stable if not exists testdb3.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, "
"v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
"binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 "
"smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint "
"unsigned, tv10 float, tv11 double, tv12 binary(20), tv13 varbinary(20), tv14 geometry(100), tv15 nchar(20));");
@ -641,11 +650,10 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) {
do_query(taos, "drop database if exists testdb4");
do_query(taos, "create database IF NOT EXISTS testdb4 PRECISION 'ms'");
do_query(taos, "CREATE TABLE testdb4.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);");
do_query(
taos,
"create table if not exists testdb4.all_ntb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 "
"tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
"binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20));");
do_query(taos,
"create table if not exists testdb4.all_ntb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 "
"bigint, v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 "
"double, v12 binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20));");
printf("support case \n");
@ -817,12 +825,17 @@ TEST(stmt2Case, stmt2_stb_insert) {
// normal
TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
{ do_stmt(taos, &option, "insert into `testdb1`.`stb` (tbname,ts,b,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, true); }
{ do_stmt(taos, &option, "insert into `testdb1`.? using `testdb1`.`stb` tags(?,?) values(?,?)", 3, 3, 3, true, true); }
{
do_stmt(taos, &option, "insert into `testdb1`.? using `testdb1`.`stb` tags(?,?) values(?,?)", 3, 3, 3, true, true);
}
// async
option = {0, true, true, stmtAsyncQueryCb, NULL};
{ do_stmt(taos, &option, "insert into testdb1.stb (ts,b,tbname,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, true); }
{ do_stmt(taos, &option, "insert into testdb1.? using testdb1.stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true, true); }
{
do_stmt(taos, &option, "insert into testdb1.? using testdb1.stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true,
true);
}
// { do_stmt(taos, &option, "insert into db.? values(?,?)", 3, 3, 3, false, true); }
// interlace = 0 & use db]
@ -848,7 +861,7 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
do_query(taos, "drop database if exists example_all_type_stmt1");
do_query(taos, "create database IF NOT EXISTS example_all_type_stmt1");
do_query(taos,
"create table example_all_type_stmt1.stb1 (ts timestamp, int_col int,long_col bigint,double_col "
"create stable example_all_type_stmt1.stb1 (ts timestamp, int_col int,long_col bigint,double_col "
"double,bool_col bool,binary_col binary(20),nchar_col nchar(20),varbinary_col varbinary(20),geometry_col "
"geometry(200)) tags(int_tag int,long_tag bigint,double_tag double,bool_tag bool,binary_tag "
"binary(20),nchar_tag nchar(20),varbinary_tag varbinary(20),geometry_tag geometry(200));");
@ -861,7 +874,8 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
ASSERT_NE(stmt, nullptr);
const char* sql = "INSERT INTO example_all_type_stmt1.stb1 (ts,int_tag,tbname) VALUES (?,?,?)";
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int total_affect_rows = 0;
int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
int tag_i = 0;
@ -881,16 +895,16 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
char* tbname[2] = {"tb1", "tb2"};
TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int affected_rows;
taos_stmt2_exec(stmt, &affected_rows);
ASSERT_EQ(code, 0);
total_affect_rows += affected_rows;
checkError(stmt, code);
}
checkRows(taos, "select * from example_all_type_stmt1.tb1", 6);
checkRows(taos, "select * from example_all_type_stmt1.tb2", 6);
checkRows(taos, "select * from example_all_type_stmt1.stb1", 12);
ASSERT_EQ(total_affect_rows, 12);
taos_stmt2_close(stmt);
}
@ -901,7 +915,7 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
const char* sql =
"INSERT INTO example_all_type_stmt1.stb1 (binary_tag,int_col,tbname,ts,int_tag) VALUES (?,?,?,?,?)";
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int tag_i = 0;
int tag_l = sizeof(int);
@ -910,6 +924,7 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
int coli[2] = {1, 2};
int ilen[2] = {sizeof(int), sizeof(int)};
int total_affect_rows = 0;
for (int i = 0; i < 3; i++) {
ts[0] += 1000;
ts[1] += 1000;
@ -928,16 +943,14 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
char* tbname[2] = {"tb3", "tb4"};
TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int affected_rows;
taos_stmt2_exec(stmt, &affected_rows);
ASSERT_EQ(code, 0);
total_affect_rows += affected_rows;
checkError(stmt, code);
}
checkRows(taos, "select * from example_all_type_stmt1.tb3", 6);
checkRows(taos, "select * from example_all_type_stmt1.tb4", 6);
checkRows(taos, "select * from example_all_type_stmt1.stb1", 24);
ASSERT_EQ(total_affect_rows, 12);
taos_stmt2_close(stmt);
}
@ -951,7 +964,7 @@ TEST(stmt2Case, stmt2_insert_db) {
do_query(taos, "drop database if exists example_all_type_stmt1");
do_query(taos, "create database IF NOT EXISTS example_all_type_stmt1");
do_query(taos,
"create table `example_all_type_stmt1`.`stb1` (ts timestamp, int_col int,long_col bigint,double_col "
"create stable `example_all_type_stmt1`.`stb1` (ts timestamp, int_col int,long_col bigint,double_col "
"double,bool_col bool,binary_col binary(20),nchar_col nchar(20),varbinary_col varbinary(20),geometry_col "
"geometry(200)) tags(int_tag int,long_tag bigint,double_tag double,bool_tag bool,binary_tag "
"binary(20),nchar_tag nchar(20),varbinary_tag varbinary(20),geometry_tag geometry(200));");
@ -962,12 +975,13 @@ TEST(stmt2Case, stmt2_insert_db) {
ASSERT_NE(stmt, nullptr);
const char* sql = "INSERT INTO `example_all_type_stmt1`.`stb1` (ts,int_tag,tbname) VALUES (?,?,?)";
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
int tag_i = 0;
int tag_l = sizeof(int);
int64_t ts[2] = {1591060628000, 1591060628100};
int total_affect_rows = 0;
for (int i = 0; i < 3; i++) {
ts[0] += 1000;
ts[1] += 1000;
@ -982,16 +996,15 @@ TEST(stmt2Case, stmt2_insert_db) {
char* tbname[2] = {"tb1", "tb2"};
TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int affected_rows;
taos_stmt2_exec(stmt, &affected_rows);
ASSERT_EQ(code, 0);
total_affect_rows += affected_rows;
checkError(stmt, code);
}
checkRows(taos, "select * from example_all_type_stmt1.tb1", 6);
checkRows(taos, "select * from example_all_type_stmt1.tb2", 6);
checkRows(taos, "select * from example_all_type_stmt1.stb1", 12);
ASSERT_EQ(total_affect_rows, 12);
taos_stmt2_close(stmt);
taos_close(taos);
}
@ -1001,7 +1014,7 @@ TEST(stmt2Case, stmt2_query) {
ASSERT_NE(taos, nullptr);
do_query(taos, "drop database if exists testdb7");
do_query(taos, "create database IF NOT EXISTS testdb7");
do_query(taos, "create table testdb7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
do_query(taos, "create stable testdb7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
do_query(taos,
"insert into testdb7.tb1 using testdb7.stb tags(1,'abc') values(1591060628000, "
"'abc'),(1591060628001,'def'),(1591060628002, 'hij')");
@ -1017,7 +1030,7 @@ TEST(stmt2Case, stmt2_query) {
const char* sql = "select * from testdb7.stb where ts = ? and tbname = ?";
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int t64_len[1] = {sizeof(int64_t)};
int b_len[1] = {3};
@ -1027,10 +1040,10 @@ TEST(stmt2Case, stmt2_query) {
TAOS_STMT2_BIND* paramv = &params[0];
TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
taos_stmt2_exec(stmt, NULL);
ASSERT_EQ(code, 0);
checkError(stmt, code);
TAOS_RES* pRes = taos_stmt2_result(stmt);
ASSERT_NE(pRes, nullptr);
@ -1058,9 +1071,11 @@ TEST(stmt2Case, stmt2_ntb_insert) {
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
int total_affected_rows = 0;
const char* sql = "insert into testdb8.ntb values(?,?)";
int code = taos_stmt2_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
for (int i = 0; i < 3; i++) {
int64_t ts[3] = {1591060628000 + i * 3, 1591060628001 + i * 3, 1591060628002 + i * 3};
int t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
@ -1076,12 +1091,14 @@ TEST(stmt2Case, stmt2_ntb_insert) {
code = taos_stmt2_bind_param(stmt, &bindv1, 0);
code = taos_stmt2_bind_param(stmt, &bindv2, 1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
code = taos_stmt2_exec(stmt, NULL);
ASSERT_EQ(code, 0);
int affected_rows;
code = taos_stmt2_exec(stmt, &affected_rows);
total_affected_rows += affected_rows;
checkError(stmt, code);
}
checkRows(taos, "select * from testdb8.ntb", 9);
ASSERT_EQ(total_affected_rows, 9);
taos_stmt2_close(stmt);
taos_close(taos);
@ -1194,7 +1211,7 @@ TEST(stmt2Case, stmt2_nchar) {
params[5].num = 10;
int code = taos_stmt2_prepare(stmt, "insert into ? (ts, blob2, blob, blob3, blob4, blob5) values(?,?,?,?,?,?)", 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int64_t ts = 1591060628000;
for (int i = 0; i < 10; ++i) {
@ -1219,13 +1236,15 @@ TEST(stmt2Case, stmt2_nchar) {
TAOS_STMT2_BIND* bind_cols[1] = {&params[0]};
TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &bind_cols[0]};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
code = taos_stmt2_exec(stmt, NULL);
ASSERT_EQ(code, 0);
int affected_rows;
code = taos_stmt2_exec(stmt, &affected_rows);
checkError(stmt, code);
ASSERT_EQ(affected_rows, 10);
taos_stmt2_close(stmt);
taos_close(taos);
taosMemoryFree(blob_len);
taosMemoryFree(blob_len2);
taosMemoryFree(blob_len5);
@ -1239,16 +1258,16 @@ TEST(stmt2Case, all_type) {
do_query(taos, "drop database if exists testdb11");
do_query(taos, "create database IF NOT EXISTS testdb11");
do_query(taos,
"create stable testdb11.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint, c7 "
"tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 binary(8), t6 "
"smallint, t7 "
"tinyint, t8 bool, t9 nchar(8))");
do_query(
taos,
"create stable testdb11.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint, c7 "
"tinyint, c8 bool, c9 nchar(8), c10 geometry(256))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 "
"binary(8), t6 smallint, t7 tinyint, t8 bool, t9 nchar(8), t10 geometry(256))");
TAOS_STMT2_OPTION option = {0};
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
int code = 0;
uintptr_t c10len = 0;
struct {
int64_t c1;
@ -1340,22 +1359,102 @@ TEST(stmt2Case, all_type) {
params[9].is_null = NULL;
params[9].num = 1;
char* stmt_sql = "insert into testdb11.? using stb tags(?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt2_prepare(stmt, stmt_sql, 0);
ASSERT_EQ(code, 0);
unsigned char* outputGeom1;
size_t size1;
initCtxMakePoint();
code = doMakePoint(1.000, 2.000, &outputGeom1, &size1);
checkError(stmt, code);
params[10].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[10].buffer = outputGeom1;
params[10].length = (int32_t*)&size1;
params[10].is_null = NULL;
params[10].num = 1;
char* tbname = "tb1";
char* stmt_sql = "insert into testdb11.? using stb tags(?,?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt2_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
char* tbname[1] = {"tb1"};
TAOS_STMT2_BIND* tags = &params[0];
TAOS_STMT2_BIND* cols = &params[0];
TAOS_STMT2_BINDV bindv = {1, &tbname, &tags, &cols};
TAOS_STMT2_BINDV bindv = {1, &tbname[0], &tags, &cols};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
ASSERT_EQ(code, 0);
checkError(stmt, code);
code = taos_stmt2_exec(stmt, NULL);
ASSERT_EQ(code, 0);
int affected_rows;
code = taos_stmt2_exec(stmt, &affected_rows);
checkError(stmt, code);
ASSERT_EQ(affected_rows, 1);
geosFreeBuffer(outputGeom1);
taos_stmt2_close(stmt);
taos_close(taos);
}
TEST(stmt2Case, geometry) {
TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
do_query(taos, "DROP DATABASE IF EXISTS testdb15");
do_query(taos, "CREATE DATABASE IF NOT EXISTS testdb15");
do_query(taos, "CREATE TABLE testdb15.tb1(ts timestamp,c1 geometry(256))");
TAOS_STMT2_OPTION option = {0};
TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
ASSERT_NE(stmt, nullptr);
unsigned char wkb1[] = { // 1
0x01, // 字节顺序:小端字节序
0x01, 0x00, 0x00, 0x00, // 几何类型Point (1)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, // p1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, // p2
// 2
0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
0x3f,
// 3
0x01,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40};
// unsigned char* wkb_all[3]{&wkb1[0], &wkb2[0], &wkb3[0]};
int32_t wkb_len[3] = {21, 61, 41};
int64_t ts[3] = {1591060628000, 1591060628001, 1591060628002};
int32_t t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
TAOS_STMT2_BIND params[2];
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer = &ts[0];
params[0].length = &t64_len[0];
params[0].is_null = NULL;
params[0].num = 3;
params[1].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[1].buffer = &wkb1[0];
params[1].length = &wkb_len[0];
params[1].is_null = NULL;
params[1].num = 3;
char* stmt_sql = "insert into testdb15.tb1 (ts,c1)values(?,?)";
int code = taos_stmt2_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
TAOS_STMT2_BIND* cols = &params[0];
TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &cols};
code = taos_stmt2_bind_param(stmt, &bindv, -1);
checkError(stmt, code);
int affected_rows;
code = taos_stmt2_exec(stmt, &affected_rows);
checkError(stmt, code);
ASSERT_EQ(affected_rows, 3);
taos_stmt2_close(stmt);
taos_close(taos);
}
#pragma GCC diagnostic pop

View File

@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include <string.h>
#include "clientInt.h"
#include "geosWrapper.h"
#include "osSemaphore.h"
#include "taoserror.h"
#include "tglobal.h"
@ -33,23 +34,29 @@
#include "taos.h"
namespace {
void checkError(TAOS_STMT *stmt, int code) {
if (code != TSDB_CODE_SUCCESS) {
STscStmt *pStmt = (STscStmt *)stmt;
if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr) {
printf("stmt api error\n stats : %d\n errstr : %s\n", pStmt->sql.status, taos_stmt_errstr(stmt));
} else {
printf("stmt api error\n sql : %s\n stats : %d\n errstr : %s\n", pStmt->sql.sqlStr, pStmt->sql.status,
taos_stmt_errstr(stmt));
}
ASSERT_EQ(code, TSDB_CODE_SUCCESS);
}
}
void do_query(TAOS *taos, const char *sql) {
TAOS_RES *result = taos_query(taos, sql);
// printf("sql: %s\n", sql);
ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
taos_free_result(result);
}
void checkRows(TAOS *pConn, const char *sql, int32_t expectedRows) {
TAOS_RES *pRes = taos_query(pConn, sql);
ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS);
TAOS_ROW pRow = NULL;
int rows = 0;
while ((pRow = taos_fetch_row(pRes)) != NULL) {
rows++;
int code = taos_errno(result);
if (code != TSDB_CODE_SUCCESS) {
printf("query failen sql : %s\n errstr : %s\n", sql, taos_errstr(result));
ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
}
ASSERT_EQ(rows, expectedRows);
taos_free_result(pRes);
taos_free_result(result);
}
typedef struct {
@ -62,13 +69,12 @@ typedef struct {
void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS,
bool isCreateTable) {
// create database and table
do_query(taos, "DROP DATABASE IF EXISTS stmttest_db_1");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmttest_db_1");
do_query(
taos,
"CREATE STABLE IF NOT EXISTS stmttest_db_1.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
do_query(taos, "USE stmttest_db_1");
do_query(taos, "DROP DATABASE IF EXISTS testdb2");
do_query(taos, "CREATE DATABASE IF NOT EXISTS testdb2");
do_query(taos,
"CREATE STABLE IF NOT EXISTS testdb2.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
do_query(taos, "USE testdb2");
// init
TAOS_STMT *stmt;
@ -79,7 +85,7 @@ void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_
}
ASSERT_NE(stmt, nullptr);
int code = taos_stmt_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
int total_affected = 0;
for (int k = 0; k < CYC_NUMS; k++) {
@ -118,23 +124,23 @@ void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_
if (!isCreateTable) {
if (k % 2 == 0) {
code = taos_stmt_set_tbname_tags(stmt, table_name, tags);
ASSERT_EQ(code, 0);
checkError(stmt, code);
} else {
if (i % 2 == 0) {
code = taos_stmt_set_tbname(stmt, table_name);
ASSERT_EQ(code, 0);
checkError(stmt, code);
} else {
code = taos_stmt_set_sub_tbname(stmt, table_name);
ASSERT_EQ(code, 0);
checkError(stmt, code);
}
code = taos_stmt_set_tags(stmt, tags);
ASSERT_EQ(code, 0);
checkError(stmt, code);
}
} else {
code = taos_stmt_set_tbname(stmt, table_name);
ASSERT_EQ(code, 0);
checkError(stmt, code);
}
// insert rows
@ -177,14 +183,14 @@ void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_
params[3].buffer = &phase;
// bind param
code = taos_stmt_bind_param(stmt, params);
ASSERT_EQ(code, 0);
checkError(stmt, code);
}
// add batch
code = taos_stmt_add_batch(stmt);
ASSERT_EQ(code, 0);
checkError(stmt, code);
// execute batch
code = taos_stmt_execute(stmt);
ASSERT_EQ(code, 0);
checkError(stmt, code);
// get affected rows
int affected = taos_stmt_affected_rows_once(stmt);
total_affected += affected;
@ -194,7 +200,6 @@ void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_
}
}
ASSERT_EQ(total_affected, CTB_NUMS * ROW_NUMS * CYC_NUMS);
checkRows(taos, "select * from meters", CTB_NUMS * ROW_NUMS * CYC_NUMS);
taos_stmt_close(stmt);
}
@ -202,29 +207,28 @@ void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_
void getFields(TAOS *taos, const char *sql, int expectedALLFieldNum, TAOS_FIELD_E *expectedTagFields,
int expectedTagFieldNum, TAOS_FIELD_E *expectedColFields, int expectedColFieldNum) {
// create database and table
do_query(taos, "DROP DATABASE IF EXISTS stmttest_db_2");
do_query(taos, "CREATE DATABASE IF NOT EXISTS stmttest_db_2");
do_query(taos, "USE stmttest_db_2");
do_query(
taos,
"CREATE STABLE IF NOT EXISTS stmttest_db_2.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
do_query(taos, "DROP DATABASE IF EXISTS testdb3");
do_query(taos, "CREATE DATABASE IF NOT EXISTS testdb3");
do_query(taos, "USE testdb3");
do_query(taos,
"CREATE STABLE IF NOT EXISTS testdb3.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
int code = taos_stmt_prepare(stmt, sql, 0);
ASSERT_EQ(code, 0);
checkError(stmt, code);
code = taos_stmt_set_tbname(stmt, "ctb_1");
ASSERT_EQ(code, 0);
checkError(stmt, code);
int fieldNum = 0;
TAOS_FIELD_E *pFields = NULL;
code = stmtGetParamNum(stmt, &fieldNum);
ASSERT_EQ(code, 0);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedColFieldNum);
code = taos_stmt_get_tag_fields(stmt, &fieldNum, &pFields);
ASSERT_EQ(code, 0);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedTagFieldNum);
for (int i = 0; i < fieldNum; i++) {
ASSERT_STREQ(pFields[i].name, expectedTagFields[i].name);
@ -238,7 +242,7 @@ void getFields(TAOS *taos, const char *sql, int expectedALLFieldNum, TAOS_FIELD_
int type;
int bytes;
code = taos_stmt_get_col_fields(stmt, &fieldNum, &pFields);
ASSERT_EQ(code, 0);
checkError(stmt, code);
ASSERT_EQ(fieldNum, expectedColFieldNum);
for (int i = 0; i < fieldNum; i++) {
taos_stmt_get_param(stmt, i, &type, &bytes);
@ -267,7 +271,7 @@ TEST(stmtCase, stb_insert) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
// interlace = 0
{ insertData(taos, nullptr, "INSERT INTO stmttest_db_1.? USING meters TAGS(?,?) VALUES (?,?,?,?)", 1, 1, 1, false); }
{ insertData(taos, nullptr, "INSERT INTO testdb2.? USING meters TAGS(?,?) VALUES (?,?,?,?)", 1, 1, 1, false); }
{ insertData(taos, nullptr, "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)", 3, 3, 3, false); }
@ -302,14 +306,13 @@ TEST(stmtCase, all_type) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
do_query(taos, "drop database if exists stmt_db");
do_query(taos, "create database IF NOT EXISTS stmt_db");
do_query(taos,
"create stable stmt_db.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint,
c7 " "tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 binary(8), t6 "
"smallint, t7 "
"tinyint, t8 bool, t9 nchar(8))");
do_query(taos, "DROP DATABASE IF EXISTS testdb1");
do_query(taos, "CREATE DATABASE IF NOT EXISTS testdb1");
do_query(
taos,
"CREATE STABLE testdb1.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint, c7 "
"tinyint, c8 bool, c9 nchar(8), c10 geometry(100))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 "
"binary(8), t6 smallint, t7 tinyint, t8 bool, t9 nchar(8), t10 geometry(100))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
@ -326,7 +329,24 @@ c7 " "tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 fl
int8_t c8;
int8_t c9;
char c10[32];
} v = {0};
} v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"};
struct {
int32_t c1;
int32_t c2;
int32_t c3;
int32_t c4;
int32_t c5;
int32_t c6;
int32_t c7;
int32_t c8;
int32_t c9;
int32_t c10;
} v_len = {sizeof(int64_t), sizeof(int32_t),
sizeof(int64_t), sizeof(float),
sizeof(double), 8,
sizeof(int16_t), sizeof(int8_t),
sizeof(int8_t), 8};
TAOS_MULTI_BIND params[11];
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(v.c1);
@ -398,38 +418,111 @@ c7 " "tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 fl
params[9].is_null = NULL;
params[9].num = 1;
char *stmt_sql = "insert into stmt_db.? using stb tags(?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?)";
int code = taos_stmt_prepare(stmt, stmt_sql, 0);
ASSERT_EQ(code, 0);
unsigned char *outputGeom1;
size_t size1;
initCtxMakePoint();
int code = doMakePoint(1.000, 2.000, &outputGeom1, &size1);
checkError(stmt, code);
params[10].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[10].buffer = outputGeom1;
params[10].length = (int32_t *)&size1;
params[10].is_null = NULL;
params[10].num = 1;
char *stmt_sql = "insert into testdb1.? using stb tags(?,?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?,?)";
code = taos_stmt_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
code = taos_stmt_set_tbname(stmt, "ntb");
ASSERT_EQ(code, 0);
checkError(stmt, code);
code = taos_stmt_set_tags(stmt, params);
ASSERT_EQ(code, 0);
checkError(stmt, code);
v.c1 = (int64_t)1591060628000;
v.c2 = (int32_t)2147483647;
v.c3 = (int64_t)2147483648;
v.c4 = (float)0.1;
v.c5 = (double)0.000000001;
for (int j = 0; j < sizeof(v.c6); j++) {
v.c6[j] = (char)('a');
}
v.c7 = 32767;
v.c8 = 127;
v.c9 = 1;
strcpy(v.c10, "一二三四五六七八");
c10len = strlen(v.c10);
taos_stmt_bind_param(stmt, params);
taos_stmt_add_batch(stmt);
code = taos_stmt_bind_param(stmt, params);
checkError(stmt, code);
code = taos_stmt_add_batch(stmt);
checkError(stmt, code);
code = taos_stmt_execute(stmt);
ASSERT_EQ(code, 0);
checkError(stmt, code);
taos_stmt_close(stmt);
taos_close(taos);
}
*/
TEST(stmtCase, geometry) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
do_query(taos, "DROP DATABASE IF EXISTS testdb5");
do_query(taos, "CREATE DATABASE IF NOT EXISTS testdb5");
do_query(taos, "CREATE TABLE testdb5.tb1(ts timestamp,c1 geometry(256))");
TAOS_STMT *stmt = taos_stmt_init(taos);
ASSERT_NE(stmt, nullptr);
unsigned char wkb1[3][61] = {
{
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
},
//
{0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f},
{0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}};
int64_t ts[3] = {1591060628000, 1591060628001, 1591060628002};
int32_t *t64_len = (int32_t *)taosMemoryMalloc(sizeof(int32_t) * 3);
int32_t *wkb_len = (int32_t *)taosMemoryMalloc(sizeof(int32_t) * 3);
for (int i = 0; i < 3; i++) {
t64_len[i] = sizeof(int64_t);
}
wkb_len[0] = 21;
wkb_len[1] = 61;
wkb_len[2] = 41;
TAOS_MULTI_BIND params[2];
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(int64_t);
params[0].buffer = &ts[0];
params[0].length = t64_len;
params[0].is_null = NULL;
params[0].num = 3;
params[1].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
params[1].buffer_length = 61;
params[1].buffer = wkb1;
params[1].length = wkb_len;
params[1].is_null = NULL;
params[1].num = 3;
char *stmt_sql = "insert into testdb5.tb1 (ts,c1)values(?,?)";
int code = taos_stmt_prepare(stmt, stmt_sql, 0);
checkError(stmt, code);
// code = taos_stmt_set_tbname(stmt, "tb1");
// checkError(stmt, code);
code = taos_stmt_bind_param_batch(stmt, params);
checkError(stmt, code);
code = taos_stmt_add_batch(stmt);
checkError(stmt, code);
code = taos_stmt_execute(stmt);
checkError(stmt, code);
taosMemoryFree(t64_len);
taosMemoryFree(wkb_len);
taos_stmt_close(stmt);
taos_close(taos);
}
#pragma GCC diagnostic pop

View File

@ -14,8 +14,8 @@
*/
#define _DEFAULT_SOURCE
#include "tglobal.h"
#include "tmsg.h"
#include "tglobal.h"
#undef TD_MSG_NUMBER_
#undef TD_MSG_DICT_
@ -11639,16 +11639,14 @@ static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubm
TAOS_CHECK_EXIT(tEncodeU64v(pCoder, nColData));
for (uint64_t i = 0; i < nColData; i++) {
pCoder->pos +=
tPutColData(SUBMIT_REQUEST_VERSION, pCoder->data ? pCoder->data + pCoder->pos : NULL, &aColData[i]);
TAOS_CHECK_EXIT(tEncodeColData(SUBMIT_REQUEST_VERSION, pCoder, &aColData[i]));
}
} else {
TAOS_CHECK_EXIT(tEncodeU64v(pCoder, TARRAY_SIZE(pSubmitTbData->aRowP)));
SRow **rows = (SRow **)TARRAY_DATA(pSubmitTbData->aRowP);
for (int32_t iRow = 0; iRow < TARRAY_SIZE(pSubmitTbData->aRowP); ++iRow) {
if (pCoder->data) memcpy(pCoder->data + pCoder->pos, rows[iRow], rows[iRow]->len);
pCoder->pos += rows[iRow]->len;
TAOS_CHECK_EXIT(tEncodeRow(pCoder, rows[iRow]));
}
}
TAOS_CHECK_EXIT(tEncodeI64(pCoder, pSubmitTbData->ctimeMs));
@ -11695,7 +11693,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa
}
for (int32_t i = 0; i < nColData; ++i) {
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, taosArrayReserve(pSubmitTbData->aCol, 1));
TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1)));
}
} else {
uint64_t nRow;
@ -11712,8 +11710,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa
TAOS_CHECK_EXIT(terrno);
}
*ppRow = (SRow *)(pCoder->data + pCoder->pos);
pCoder->pos += (*ppRow)->len;
TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow));
}
}

View File

@ -2673,7 +2673,7 @@ static void (*tColDataGetValueImpl[])(SColData *pColData, int32_t iVal, SColVal
};
int32_t tColDataGetValue(SColData *pColData, int32_t iVal, SColVal *pColVal) {
if (iVal < 0 || iVal >= pColData->nVal ||
(pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl)/POINTER_BYTES)){
(pColData->flag <= 0 || pColData->flag >= sizeof(tColDataGetValueImpl) / POINTER_BYTES)) {
return TSDB_CODE_INVALID_PARA;
}
tColDataGetValueImpl[pColData->flag](pColData, iVal, pColVal);
@ -3689,25 +3689,25 @@ _exit:
return 0;
}
static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
int32_t n = 0;
static int32_t tEncodeColDataVersion0(SEncoder *pEncoder, SColData *pColData) {
int32_t code = 0;
n += tPutI16v(pBuf ? pBuf + n : NULL, pColData->cid);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->type);
n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nVal);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->flag);
if ((code = tEncodeI16v(pEncoder, pColData->cid))) return code;
if ((code = tEncodeI8(pEncoder, pColData->type))) return code;
if ((code = tEncodeI32v(pEncoder, pColData->nVal))) return code;
if ((code = tEncodeI8(pEncoder, pColData->flag))) return code;
// bitmap
switch (pColData->flag) {
case (HAS_NULL | HAS_NONE):
case (HAS_VALUE | HAS_NONE):
case (HAS_VALUE | HAS_NULL):
if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
n += BIT1_SIZE(pColData->nVal);
code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT1_SIZE(pColData->nVal));
if (code) return code;
break;
case (HAS_VALUE | HAS_NULL | HAS_NONE):
if (pBuf) (void)memcpy(pBuf + n, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
n += BIT2_SIZE(pColData->nVal);
code = tEncodeFixed(pEncoder, pColData->pBitMap, BIT2_SIZE(pColData->nVal));
if (code) return code;
break;
default:
break;
@ -3716,40 +3716,46 @@ static int32_t tPutColDataVersion0(uint8_t *pBuf, SColData *pColData) {
// value
if (pColData->flag & HAS_VALUE) {
if (IS_VAR_DATA_TYPE(pColData->type)) {
if (pBuf) (void)memcpy(pBuf + n, pColData->aOffset, pColData->nVal << 2);
n += (pColData->nVal << 2);
code = tEncodeFixed(pEncoder, pColData->aOffset, pColData->nVal << 2);
if (code) return code;
n += tPutI32v(pBuf ? pBuf + n : NULL, pColData->nData);
if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
n += pColData->nData;
code = tEncodeI32v(pEncoder, pColData->nData);
if (code) return code;
code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
if (code) return code;
} else {
if (pBuf) (void)memcpy(pBuf + n, pColData->pData, pColData->nData);
n += pColData->nData;
code = tEncodeFixed(pEncoder, pColData->pData, pColData->nData);
if (code) return code;
}
}
return n;
return code;
}
static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
int32_t n = 0;
static int32_t tDecodeColDataVersion0(SDecoder *pDecoder, SColData *pColData) {
int32_t code = 0;
n += tGetI16v(pBuf + n, &pColData->cid);
n += tGetI8(pBuf + n, &pColData->type);
n += tGetI32v(pBuf + n, &pColData->nVal);
n += tGetI8(pBuf + n, &pColData->flag);
if ((code = tDecodeI16v(pDecoder, &pColData->cid))) return code;
if ((code = tDecodeI8(pDecoder, &pColData->type))) return code;
if ((code = tDecodeI32v(pDecoder, &pColData->nVal))) return code;
if ((code = tDecodeI8(pDecoder, &pColData->flag))) return code;
if (pColData->type <= 0 || pColData->type >= TSDB_DATA_TYPE_MAX || pColData->flag <= 0 || pColData->flag >= 8) {
return TSDB_CODE_INVALID_PARA;
}
// bitmap
switch (pColData->flag) {
case (HAS_NULL | HAS_NONE):
case (HAS_VALUE | HAS_NONE):
case (HAS_VALUE | HAS_NULL):
pColData->pBitMap = pBuf + n;
n += BIT1_SIZE(pColData->nVal);
code = tDecodeBinaryWithSize(pDecoder, BIT1_SIZE(pColData->nVal), &pColData->pBitMap);
if (code) return code;
break;
case (HAS_VALUE | HAS_NULL | HAS_NONE):
pColData->pBitMap = pBuf + n;
n += BIT2_SIZE(pColData->nVal);
code = tDecodeBinaryWithSize(pDecoder, BIT2_SIZE(pColData->nVal), &pColData->pBitMap);
if (code) return code;
break;
default:
break;
@ -3758,55 +3764,74 @@ static int32_t tGetColDataVersion0(uint8_t *pBuf, SColData *pColData) {
// value
if (pColData->flag & HAS_VALUE) {
if (IS_VAR_DATA_TYPE(pColData->type)) {
pColData->aOffset = (int32_t *)(pBuf + n);
n += (pColData->nVal << 2);
code = tDecodeBinaryWithSize(pDecoder, pColData->nVal << 2, (uint8_t **)&pColData->aOffset);
if (code) return code;
n += tGetI32v(pBuf + n, &pColData->nData);
pColData->pData = pBuf + n;
n += pColData->nData;
code = tDecodeI32v(pDecoder, &pColData->nData);
if (code) return code;
code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
if (code) return code;
} else {
pColData->pData = pBuf + n;
pColData->nData = TYPE_BYTES[pColData->type] * pColData->nVal;
n += pColData->nData;
code = tDecodeBinaryWithSize(pDecoder, pColData->nData, &pColData->pData);
if (code) return code;
}
}
pColData->cflag = 0;
return n;
return code;
}
static int32_t tPutColDataVersion1(uint8_t *pBuf, SColData *pColData) {
int32_t n = tPutColDataVersion0(pBuf, pColData);
n += tPutI8(pBuf ? pBuf + n : NULL, pColData->cflag);
return n;
static int32_t tEncodeColDataVersion1(SEncoder *pEncoder, SColData *pColData) {
int32_t code = tEncodeColDataVersion0(pEncoder, pColData);
if (code) return code;
return tEncodeI8(pEncoder, pColData->cflag);
}
static int32_t tGetColDataVersion1(uint8_t *pBuf, SColData *pColData) {
int32_t n = tGetColDataVersion0(pBuf, pColData);
n += tGetI8(pBuf ? pBuf + n : NULL, &pColData->cflag);
return n;
static int32_t tDecodeColDataVersion1(SDecoder *pDecoder, SColData *pColData) {
int32_t code = tDecodeColDataVersion0(pDecoder, pColData);
if (code) return code;
code = tDecodeI8(pDecoder, &pColData->cflag);
return code;
}
int32_t tPutColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
int32_t tEncodeColData(uint8_t version, SEncoder *pEncoder, SColData *pColData) {
if (version == 0) {
return tPutColDataVersion0(pBuf, pColData);
return tEncodeColDataVersion0(pEncoder, pColData);
} else if (version == 1) {
return tPutColDataVersion1(pBuf, pColData);
return tEncodeColDataVersion1(pEncoder, pColData);
} else {
return TSDB_CODE_INVALID_PARA;
}
}
int32_t tGetColData(uint8_t version, uint8_t *pBuf, SColData *pColData) {
int32_t tDecodeColData(uint8_t version, SDecoder *pDecoder, SColData *pColData) {
if (version == 0) {
return tGetColDataVersion0(pBuf, pColData);
return tDecodeColDataVersion0(pDecoder, pColData);
} else if (version == 1) {
return tGetColDataVersion1(pBuf, pColData);
return tDecodeColDataVersion1(pDecoder, pColData);
} else {
return TSDB_CODE_INVALID_PARA;
}
}
int32_t tEncodeRow(SEncoder *pEncoder, SRow *pRow) { return tEncodeFixed(pEncoder, pRow, pRow->len); }
int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
if (ppRow == NULL) {
return TSDB_CODE_INVALID_PARA;
}
if (pDecoder->pos + sizeof(SRow) > pDecoder->size) {
return TSDB_CODE_OUT_OF_RANGE;
}
SRow *pRow = (SRow *)(pDecoder->data + pDecoder->pos);
return tDecodeBinaryWithSize(pDecoder, pRow->len, (uint8_t **)ppRow);
}
#define CALC_SUM_MAX_MIN(SUM, MAX, MIN, VAL) \
do { \
(SUM) += (VAL); \

View File

@ -2757,6 +2757,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
{"tsmaDataDeleteMark", &tsmaDataDeleteMark},
{"numOfRpcSessions", &tsNumOfRpcSessions},
{"bypassFlag", &tsBypassFlag},
{"safetyCheckLevel", &tsSafetyCheckLevel},
{"streamCoverage", &tsStreamCoverage}};
if ((code = taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true)) != TSDB_CODE_SUCCESS) {

View File

@ -114,6 +114,8 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_SDB_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
@ -130,6 +132,7 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_USER_AUTH, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_SDB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_MNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_MNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;

View File

@ -17,6 +17,7 @@
#include "audit.h"
#include "mndConfig.h"
#include "mndDnode.h"
#include "mndMnode.h"
#include "mndPrivilege.h"
#include "mndSync.h"
#include "mndTrans.h"
@ -33,8 +34,10 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq);
static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp);
static int32_t mndProcessConfigReq(SRpcMsg *pReq);
static int32_t mndInitWriteCfg(SMnode *pMnode);
static int32_t mndTryRebuildCfg(SMnode *pMnode);
static int32_t mndSendRebuildReq(SMnode *pMnode);
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp);
static int32_t initConfigArrayFromSdb(SMnode *pMnode, SArray *array);
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq);
static void cfgArrayCleanUp(SArray *array);
static void cfgObjArrayCleanUp(SArray *array);
@ -59,6 +62,8 @@ int32_t mndInitConfig(SMnode *pMnode) {
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_DNODE, mndProcessConfigDnodeReq);
mndSetMsgHandle(pMnode, TDMT_DND_CONFIG_DNODE_RSP, mndProcessConfigDnodeRsp);
mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB, mndTryRebuildConfigSdb);
mndSetMsgHandle(pMnode, TDMT_MND_CONFIG_SDB_RSP, mndTryRebuildConfigSdbRsp);
return sdbSetTable(pMnode->pSdb, table);
}
@ -214,7 +219,7 @@ static int32_t mndCfgActionUpdate(SSdb *pSdb, SConfigObj *pOld, SConfigObj *pNew
static int32_t mndCfgActionDeploy(SMnode *pMnode) { return mndInitWriteCfg(pMnode); }
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndTryRebuildCfg(pMnode); }
static int32_t mndCfgActionAfterRestored(SMnode *pMnode) { return mndSendRebuildReq(pMnode); }
static int32_t mndProcessConfigReq(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
@ -340,7 +345,30 @@ _OVER:
return code;
}
int32_t mndTryRebuildCfg(SMnode *pMnode) {
int32_t mndSendRebuildReq(SMnode *pMnode) {
int32_t code = 0;
SRpcMsg rpcMsg = {.pCont = NULL,
.contLen = 0,
.msgType = TDMT_MND_CONFIG_SDB,
.info.ahandle = 0,
.info.notFreeAhandle = 1,
.info.refId = 0,
.info.noResp = 0,
.info.handle = 0};
SEpSet epSet = {0};
mndGetMnodeEpSet(pMnode, &epSet);
code = tmsgSendReq(&epSet, &rpcMsg);
if (code != 0) {
mError("failed to send rebuild config req, since %s", tstrerror(code));
}
return code;
}
static int32_t mndTryRebuildConfigSdb(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
if (!mndIsLeader(pMnode)) {
return TSDB_CODE_SUCCESS;
}
@ -518,6 +546,8 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
SMCfgDnodeReq cfgReq = {0};
SConfigObj *vObj = sdbAcquire(pMnode->pSdb, SDB_CFG, "tsmmConfigVersion");
if (vObj == NULL) {
code = TSDB_CODE_SDB_OBJ_NOT_THERE;
mInfo("failed to acquire mnd config version, since %s", tstrerror(code));
goto _err_out;
}
@ -609,6 +639,11 @@ static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
return 0;
}
static int32_t mndTryRebuildConfigSdbRsp(SRpcMsg *pRsp) {
mInfo("rebuild config sdb rsp");
return 0;
}
// get int32_t value from 'SMCfgDnodeReq'
static int32_t mndMCfgGetValInt32(SMCfgDnodeReq *pMCfgReq, int32_t optLen, int32_t *pOutValue) {
int32_t code = 0;
@ -770,7 +805,6 @@ static void cfgObjArrayCleanUp(SArray *array) {
for (int32_t i = 0; i < sz; ++i) {
SConfigObj *obj = taosArrayGet(array, i);
tFreeSConfigObj(obj);
taosMemoryFree(obj);
}
taosArrayDestroy(array);
}

View File

@ -263,7 +263,7 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
MND_TMQ_RETURN_CHECK(mndAcquireConsumer(pMnode, consumerId, &pConsumer));
MND_TMQ_RETURN_CHECK(checkPrivilege(pMnode, pConsumer, &rsp, pMsg->info.conn.user));
atomic_store_32(&pConsumer->hbStatus, 0);
mDebug("consumer:0x%" PRIx64 " receive hb pollFlag:%d %d", consumerId, req.pollFlag, pConsumer->pollStatus);
mDebug("consumer:0x%" PRIx64 " receive hb pollFlag:%d pollStatus:%d", consumerId, req.pollFlag, pConsumer->pollStatus);
if (req.pollFlag == 1){
atomic_store_32(&pConsumer->pollStatus, 0);
}

View File

@ -1170,8 +1170,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
}
}
SArray *pInvalidList = taosArrayInit(4, sizeof(STaskId));
for (int32_t i = 0; i < taosArrayGetSize(execInfo.pTaskList); ++i) {
STaskId *p = taosArrayGet(execInfo.pTaskList, i);
if (p == NULL) {
@ -1183,23 +1181,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
continue;
}
if (pEntry->status == TASK_STATUS__STOP) {
for (int32_t j = 0; j < taosArrayGetSize(pInvalidList); ++j) {
STaskId *pId = taosArrayGet(pInvalidList, j);
if (pId == NULL) {
continue;
}
if (pEntry->id.streamId == pId->streamId) {
void *px = taosArrayPush(pInvalidList, &pEntry->id);
if (px == NULL) {
mError("failed to put stream into invalid list, code:%s", tstrerror(TSDB_CODE_OUT_OF_MEMORY));
}
break;
}
}
}
if (pEntry->status != TASK_STATUS__READY) {
mDebug("s-task:0x%" PRIx64 "-0x%x (nodeId:%d) status:%s, checkpoint not issued", pEntry->id.streamId,
(int32_t)pEntry->id.taskId, pEntry->nodeId, streamTaskGetStatusStr(pEntry->status));
@ -1217,9 +1198,6 @@ static int32_t mndCheckTaskAndNodeStatus(SMnode *pMnode) {
}
}
removeTasksInBuf(pInvalidList, &execInfo);
taosArrayDestroy(pInvalidList);
streamMutexUnlock(&execInfo.lock);
return ready ? 0 : -1;
}
@ -1260,6 +1238,30 @@ static int32_t streamWaitComparFn(const void *p1, const void *p2) {
return pInt1->duration > pInt2->duration ? -1 : 1;
}
// all tasks of this stream should be ready, otherwise do nothing
static bool isStreamReadyHelp(int64_t now, SStreamObj* pStream) {
bool ready = false;
streamMutexLock(&execInfo.lock);
int64_t lastReadyTs = getStreamTaskLastReadyState(execInfo.pTaskList, pStream->uid);
if ((lastReadyTs == -1) || ((lastReadyTs != -1) && ((now - lastReadyTs) < tsStreamCheckpointInterval * 1000))) {
if (lastReadyTs != -1) {
mInfo("not start checkpoint, stream:0x%"PRIx64" last ready ts:%"PRId64" ready duration:%"PRId64" less than threshold",
pStream->uid, lastReadyTs, now - lastReadyTs);
} else {
mInfo("not start checkpoint, stream:0x%"PRIx64" not ready now", pStream->uid);
}
ready = false;
} else {
ready = true;
}
streamMutexUnlock(&execInfo.lock);
return ready;
}
static int32_t mndProcessStreamCheckpoint(SRpcMsg *pReq) {
SMnode *pMnode = pReq->info.node;
SSdb *pSdb = pMnode->pSdb;
@ -1286,20 +1288,17 @@ static int32_t mndProcessStreamCheckpoint(SRpcMsg *pReq) {
continue;
}
streamMutexLock(&execInfo.lock);
int64_t startTs = getStreamTaskLastReadyState(execInfo.pTaskList, pStream->uid);
if (startTs != -1 && (now - startTs) < tsStreamCheckpointInterval * 1000) {
streamMutexUnlock(&execInfo.lock);
bool ready = isStreamReadyHelp(now, pStream);
if (!ready) {
sdbRelease(pSdb, pStream);
continue;
}
streamMutexUnlock(&execInfo.lock);
SCheckpointInterval in = {.streamId = pStream->uid, .duration = duration};
void *p = taosArrayPush(pList, &in);
if (p) {
int32_t currentSize = taosArrayGetSize(pList);
mDebug("stream:%s (uid:0x%" PRIx64 ") total %d stream(s) beyond chpt interval threshold: %ds(%" PRId64
mDebug("stream:%s (uid:0x%" PRIx64 ") total %d stream(s) beyond chkpt interval threshold: %ds(%" PRId64
"s), concurrently launch threshold:%d",
pStream->name, pStream->uid, currentSize, tsStreamCheckpointInterval, duration / 1000,
tsMaxConcurrentCheckpoint);

View File

@ -309,9 +309,6 @@ void mndRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
} else {
mInfo("vgId:1, sync restore finished, repeat call");
}
if (sdbAfterRestored(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
}
} else {
mInfo("vgId:1, sync restore finished");
}
@ -329,6 +326,17 @@ void mndRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
}
}
void mndAfterRestored(const SSyncFSM *pFsm, const SyncIndex commitIdx) {
SMnode *pMnode = pFsm->data;
if (!pMnode->deploy) {
if (sdbAfterRestored(pMnode->pSdb) != 0) {
mError("failed to prepare sdb while start mnode");
}
mInfo("vgId:1, sync restore finished and restore sdb success");
}
}
int32_t mndSnapshotStartRead(const SSyncFSM *pFsm, void *pParam, void **ppReader) {
mInfo("start to read snapshot from sdb");
SMnode *pMnode = pFsm->data;
@ -443,6 +451,7 @@ SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
pFsm->FpPreCommitCb = NULL;
pFsm->FpRollBackCb = NULL;
pFsm->FpRestoreFinishCb = mndRestoreFinish;
pFsm->FpAfterRestoredCb = mndAfterRestored;
pFsm->FpLeaderTransferCb = NULL;
pFsm->FpApplyQueueEmptyCb = mndApplyQueueEmpty;
pFsm->FpApplyQueueItems = mndApplyQueueItems;

View File

@ -61,6 +61,7 @@ static FORCE_INLINE tb_uid_t metaGenerateUid(SMeta* pMeta) { return tGenIdPI64()
// metaTable ==================
int32_t metaHandleEntry2(SMeta* pMeta, const SMetaEntry* pEntry);
void metaHandleSyncEntry(SMeta* pMeta, const SMetaEntry* pEntry);
// metaCache ==================
int32_t metaCacheOpen(SMeta* pMeta);

View File

@ -112,13 +112,12 @@ int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle);
void tqDestroyTqHandle(void* data);
// tqRead
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* offset);
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* offset, int64_t timeout);
int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset, const SMqPollReq* pRequest);
int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t reqId);
// tqExec
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded);
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp,
int32_t type, int32_t vgId);
void tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId);
@ -178,6 +177,7 @@ int32_t tqExtractDropCtbDataBlock(const void* data, int32_t len, int64_t ver, vo
#define TQ_SUBSCRIBE_NAME "subscribe"
#define TQ_OFFSET_NAME "offset-ver0"
#define TQ_POLL_MAX_TIME 1000
#ifdef __cplusplus
}

View File

@ -1915,3 +1915,12 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
}
TAOS_RETURN(code);
}
void metaHandleSyncEntry(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
}
return;
}

View File

@ -197,8 +197,7 @@ int32_t metaSnapWrite(SMetaSnapWriter* pWriter, uint8_t* pData, uint32_t nData)
code = metaDecodeEntry(pDecoder, &metaEntry);
TSDB_CHECK_CODE(code, lino, _exit);
code = metaHandleEntry2(pMeta, &metaEntry);
TSDB_CHECK_CODE(code, lino, _exit);
metaHandleSyncEntry(pMeta, &metaEntry);
_exit:
if (code) {

View File

@ -15,16 +15,13 @@
#include "tq.h"
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision) {
int32_t code = TDB_CODE_SUCCESS;
int32_t lino = 0;
void* buf = NULL;
TSDB_CHECK_NULL(pBlock, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision) {
int32_t code = 0;
int32_t lino = 0;
size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
int32_t dataStrLen = sizeof(SRetrieveTableRspForTmq) + dataEncodeBufSize;
buf = taosMemoryCalloc(1, dataStrLen);
void* buf = taosMemoryCalloc(1, dataStrLen);
TSDB_CHECK_NULL(buf, code, lino, END, terrno);
SRetrieveTableRspForTmq* pRetrieve = (SRetrieveTableRspForTmq*)buf;
@ -35,16 +32,17 @@ int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t
int32_t actualLen = blockEncode(pBlock, pRetrieve->data, dataEncodeBufSize, numOfCols);
TSDB_CHECK_CONDITION(actualLen >= 0, code, lino, END, terrno);
actualLen += sizeof(SRetrieveTableRspForTmq);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &actualLen), code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno);
tqDebug("add block data to block array, blockDataLen:%d, blockData:%p", actualLen, buf);
buf = NULL;
END:
if (code != TSDB_CODE_SUCCESS) {
taosMemoryFree(buf);
tqError("%s failed at %d, failed to add block data to response:%s", __FUNCTION__, lino, tstrerror(code));
if (code != 0){
tqError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
taosMemoryFree(buf);
return code;
}
@ -173,7 +171,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
TSDB_CHECK_CODE(code, lino, END);
qStreamSetSourceExcluded(task, pRequest->sourceExcluded);
uint64_t st = taosGetTimestampMs();
int64_t st = taosGetTimestampMs();
while (1) {
SSDataBlock* pDataBlock = NULL;
code = getDataBlock(task, pHandle, vgId, &pDataBlock);
@ -192,7 +190,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal*
pRsp->blockNum++;
totalRows += pDataBlock->info.rows;
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
break;
}
}
@ -207,22 +205,18 @@ END:
return code;
}
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* pOffset) {
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBatchMetaRsp* pBatchMetaRsp, STqOffsetVal* pOffset, int64_t timeout) {
int32_t code = 0;
int32_t lino = 0;
char* tbName = NULL;
SSchemaWrapper* pSW = NULL;
TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pTq, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pHandle, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pOffset, code, lino, END, TSDB_CODE_INVALID_PARA);
TSDB_CHECK_NULL(pBatchMetaRsp, code, lino, END, TSDB_CODE_INVALID_PARA);
const STqExecHandle* pExec = &pHandle->execHandle;
qTaskInfo_t task = pExec->task;
code = qStreamPrepareScan(task, pOffset, pHandle->execHandle.subType);
TSDB_CHECK_CODE(code, lino, END);
int32_t rowCnt = 0;
int64_t st = taosGetTimestampMs();
while (1) {
SSDataBlock* pDataBlock = NULL;
uint64_t ts = 0;
@ -236,20 +230,23 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBat
tbName = taosStrdup(qExtractTbnameFromTask(task));
TSDB_CHECK_NULL(tbName, code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockTbName, &tbName), code, lino, END, terrno);
tqDebug("vgId:%d, add tbname:%s to rsp msg", pTq->pVnode->config.vgId, tbName);
tbName = NULL;
}
if (pRsp->withSchema) {
pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task));
SSchemaWrapper* pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task));
TSDB_CHECK_NULL(pSW, code, lino, END, terrno);
TSDB_CHECK_NULL(taosArrayPush(pRsp->blockSchema, &pSW), code, lino, END, terrno);
pSW = NULL;
}
code = tqAddBlockDataToRsp(pDataBlock, pRsp, taosArrayGetSize(pDataBlock->pDataBlock), pTq->pVnode->config.tsdbCfg.precision);
code = tqAddBlockDataToRsp(pDataBlock, pRsp, taosArrayGetSize(pDataBlock->pDataBlock),
pTq->pVnode->config.tsdbCfg.precision);
TSDB_CHECK_CODE(code, lino, END);
pRsp->blockNum++;
rowCnt += pDataBlock->info.rows;
if (rowCnt <= tmqRowSize) {
if (rowCnt <= tmqRowSize && (taosGetTimestampMs() - st <= TMIN(TQ_POLL_MAX_TIME, timeout))) {
continue;
}
}
@ -283,11 +280,10 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBat
break;
}
}
tqDebug("%s:%d success", __FUNCTION__, lino);
END:
if (code != 0){
tqDebug("%s:%d failed, code:%s", __FUNCTION__, lino, tstrerror(code) );
tqError("%s failed at %d, vgId:%d, task exec error since %s", __FUNCTION__ , lino, pTq->pVnode->config.vgId, tstrerror(code));
}
taosMemoryFree(pSW);
taosMemoryFree(tbName);
@ -422,4 +418,4 @@ END:
tqError("%s failed at %d, failed to scan log:%s", __FUNCTION__, lino, tstrerror(code));
}
return code;
}
}

View File

@ -101,7 +101,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
char formatBuf[TSDB_OFFSET_LEN] = {0};
tFormatOffset(formatBuf, TSDB_OFFSET_LEN, pOffsetVal);
tqDebug("tmq poll: consumer:0x%" PRIx64
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue.QID:0x%" PRIx64,
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue.QID:0x%" PRIx64,
consumerId, pHandle->subKey, vgId, formatBuf, pRequest->reqId);
return 0;
} else {
@ -138,7 +138,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
return code;
} else if (pRequest->reqOffset.type == TMQ_OFFSET__RESET_NONE) {
tqError("tmq poll: subkey:%s, no offset committed for consumer:0x%" PRIx64
" in vg %d, subkey %s, reset none failed",
" in vg %d, subkey %s, reset none failed",
pHandle->subKey, consumerId, vgId, pRequest->subKey);
return TSDB_CODE_TQ_NO_COMMITTED_OFFSET;
}
@ -231,7 +231,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_ERR_GO_TO_END(tqInitTaosxRsp(&taosxRsp, *offset));
if (offset->type != TMQ_OFFSET__LOG) {
TQ_ERR_GO_TO_END(tqScanTaosx(pTq, pHandle, &taosxRsp, &btMetaRsp, offset));
TQ_ERR_GO_TO_END(tqScanTaosx(pTq, pHandle, &taosxRsp, &btMetaRsp, offset, pRequest->timeout));
if (taosArrayGetSize(btMetaRsp.batchMetaReq) > 0) {
code = tqSendBatchMetaPollRsp(pHandle, pMsg, pRequest, &btMetaRsp, vgId);
@ -274,7 +274,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
}
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
}
@ -287,7 +287,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
if (totalRows > 0) {
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
}
@ -349,7 +349,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_NULL_GO_TO_END (taosArrayPush(btMetaRsp.batchMetaReq, &tBuf));
TQ_NULL_GO_TO_END (taosArrayPush(btMetaRsp.batchMetaLen, &tLen));
totalMetaRows++;
if ((taosArrayGetSize(btMetaRsp.batchMetaReq) >= tmqRowSize) || (taosGetTimestampMs() - st > 1000)) {
if ((taosArrayGetSize(btMetaRsp.batchMetaReq) >= tmqRowSize) || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
tqOffsetResetToLog(&btMetaRsp.rspOffset, fetchVer);
code = tqSendBatchMetaPollRsp(pHandle, pMsg, pRequest, &btMetaRsp, vgId);
goto END;
@ -372,10 +372,10 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
TQ_ERR_GO_TO_END(tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows, pRequest->sourceExcluded));
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > 1000)) {
if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) {
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1);
code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp,
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId);
goto END;
} else {
fetchVer++;
@ -386,7 +386,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
END:
if (code != 0){
tqError("tmq poll: tqTaosxScanLog error. consumerId:0x%" PRIx64 ", in vgId:%d, subkey %s", pRequest->consumerId, vgId,
pRequest->subKey);
pRequest->subKey);
}
tDeleteMqBatchMetaRsp(&btMetaRsp);
tDeleteSTaosxRsp(&taosxRsp);
@ -794,4 +794,4 @@ _exit:
taosMemoryFree(pBlock);
}
return code;
}
}

View File

@ -318,7 +318,12 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int
}
SColData colData = {0};
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, &colData);
code = tDecodeColData(version, pCoder, &colData);
if (code) {
code = TSDB_CODE_INVALID_MSG;
goto _exit;
}
if (colData.flag != HAS_VALUE) {
code = TSDB_CODE_INVALID_MSG;
goto _exit;
@ -332,7 +337,11 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int
}
for (uint64_t i = 1; i < nColData; i++) {
pCoder->pos += tGetColData(version, pCoder->data + pCoder->pos, &colData);
code = tDecodeColData(version, pCoder, &colData);
if (code) {
code = TSDB_CODE_INVALID_MSG;
goto _exit;
}
}
} else {
uint64_t nRow;
@ -816,7 +825,7 @@ _exit:
_err:
vError("vgId:%d, process %s request failed since %s, ver:%" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
tstrerror(code), ver);
tstrerror(terrno), ver);
return code;
}

View File

@ -697,6 +697,7 @@ static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
pFsm->FpGetSnapshot = NULL;
pFsm->FpGetSnapshotInfo = vnodeSyncGetSnapshotInfo;
pFsm->FpRestoreFinishCb = vnodeRestoreFinish;
pFsm->FpAfterRestoredCb = NULL;
pFsm->FpLeaderTransferCb = NULL;
pFsm->FpApplyQueueEmptyCb = vnodeApplyQueueEmpty;
pFsm->FpApplyQueueItems = vnodeApplyQueueItems;

View File

@ -1582,7 +1582,6 @@ static int32_t doSessionWindowAggNext(SOperatorInfo* pOperator, SSDataBlock** pp
SOptrBasicInfo* pBInfo = &pInfo->binfo;
SExprSupp* pSup = &pOperator->exprSupp;
pInfo->cleanGroupResInfo = false;
if (pOperator->status == OP_RES_TO_RETURN) {
while (1) {
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
@ -1609,6 +1608,7 @@ static int32_t doSessionWindowAggNext(SOperatorInfo* pOperator, SSDataBlock** pp
SOperatorInfo* downstream = pOperator->pDownstream[0];
pInfo->cleanGroupResInfo = false;
while (1) {
SSDataBlock* pBlock = getNextBlockFromDownstream(pOperator, 0);
if (pBlock == NULL) {

View File

@ -325,11 +325,6 @@ int32_t checkWKB(const unsigned char *wkb, size_t size) {
return TSDB_CODE_FUNC_FUNTION_PARA_VALUE;
}
if (!GEOSisValid_r(geosCtx->handle, geom)) {
code = TSDB_CODE_FUNC_FUNTION_PARA_VALUE;
goto _exit;
}
_exit:
if (geom) {
GEOSGeom_destroy_r(geosCtx->handle, geom);

View File

@ -102,6 +102,9 @@ static int32_t exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
COPY_OBJECT_FIELD(resType, sizeof(SDataType));
COPY_CHAR_ARRAY_FIELD(aliasName);
COPY_CHAR_ARRAY_FIELD(userAlias);
COPY_SCALAR_FIELD(asAlias);
COPY_SCALAR_FIELD(asParam);
COPY_SCALAR_FIELD(asPosition);
COPY_SCALAR_FIELD(projIdx);
return TSDB_CODE_SUCCESS;
}

View File

@ -1392,7 +1392,7 @@ static int32_t setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SCo
tstrncpy(pCol->node.aliasName, pExpr->aliasName, TSDB_COL_NAME_LEN);
}
if ('\0' == pCol->node.userAlias[0]) {
tstrncpy(pCol->node.userAlias, pExpr->aliasName, TSDB_COL_NAME_LEN);
tstrncpy(pCol->node.userAlias, pExpr->userAlias, TSDB_COL_NAME_LEN);
}
pCol->node.resType = pExpr->resType;
return TSDB_CODE_SUCCESS;
@ -7578,6 +7578,11 @@ static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelet
}
static int32_t translateDelete(STranslateContext* pCxt, SDeleteStmt* pDelete) {
const char* dbName = ((STableNode*)pDelete->pFromTable)->dbName;
if (IS_SYS_DBNAME(dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot delete from system database: `%s`", dbName);
}
pCxt->pCurrStmt = (SNode*)pDelete;
int32_t code = translateFrom(pCxt, &pDelete->pFromTable);
if (TSDB_CODE_SUCCESS == code) {
@ -8433,6 +8438,10 @@ static int32_t checkCreateDatabase(STranslateContext* pCxt, SCreateDatabaseStmt*
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME,
"The database name cannot contain '.'");
}
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot create system database: `%s`", pStmt->dbName);
}
return checkDatabaseOptions(pCxt, pStmt->dbName, pStmt->pOptions);
}
@ -8622,6 +8631,10 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS
}
static int32_t translateDropDatabase(STranslateContext* pCxt, SDropDatabaseStmt* pStmt) {
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION, "Cannot drop system database: `%s`",
pStmt->dbName);
}
SDropDbReq dropReq = {0};
SName name = {0};
int32_t code = tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
@ -8669,6 +8682,10 @@ static int32_t buildAlterDbReq(STranslateContext* pCxt, SAlterDatabaseStmt* pStm
}
static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStmt* pStmt) {
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION, "Cannot alter system database: `%s`",
pStmt->dbName);
}
if (pStmt->pOptions->walLevel == 0) {
TAOS_CHECK_RETURN(translateGetDbCfg(pCxt, pStmt->dbName, &pStmt->pOptions->pDbCfg));
if (pStmt->pOptions->pDbCfg->replications > 1) {
@ -9146,6 +9163,12 @@ static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt
"The table name cannot contain '.'");
}
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot create table of system database: `%s`.`%s`", pStmt->dbName,
pStmt->tableName);
}
SDbCfgInfo dbCfg = {0};
int32_t code = getDBCfg(pCxt, pStmt->dbName, &dbCfg);
if (TSDB_CODE_SUCCESS == code && !createStable && NULL != dbCfg.pRetensions) {
@ -9892,6 +9915,11 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable
}
static int32_t checkAlterSuperTable(STranslateContext* pCxt, SAlterTableStmt* pStmt) {
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot alter table of system database: `%s`.`%s`", pStmt->dbName, pStmt->tableName);
}
if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType ||
TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL == pStmt->alterType) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE,
@ -11538,6 +11566,10 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm
}
}
if (NULL != pSelect->pHaving) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported Having");
}
return TSDB_CODE_SUCCESS;
}
@ -15587,11 +15619,6 @@ static int32_t rewriteDropTableWithOpt(STranslateContext* pCxt, SQuery* pQuery)
char pTableName[TSDB_TABLE_NAME_LEN] = {0};
FOREACH(pNode, pStmt->pTables) {
SDropTableClause* pClause = (SDropTableClause*)pNode;
if (IS_SYS_DBNAME(pClause->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot drop table of system database: `%s`.`%s`", pClause->dbName,
pClause->tableName);
}
for (int32_t i = 0; i < TSDB_TABLE_NAME_LEN; i++) {
if (pClause->tableName[i] == '\0') {
break;
@ -15622,6 +15649,15 @@ static int32_t rewriteDropTable(STranslateContext* pCxt, SQuery* pQuery) {
SNode* pNode;
SArray* pTsmas = NULL;
FOREACH(pNode, pStmt->pTables) {
SDropTableClause* pClause = (SDropTableClause*)pNode;
if (IS_SYS_DBNAME(pClause->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot drop table of system database: `%s`.`%s`", pClause->dbName,
pClause->tableName);
}
}
TAOS_CHECK_RETURN(rewriteDropTableWithOpt(pCxt, pQuery));
SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
@ -15711,11 +15747,6 @@ static int32_t rewriteDropSuperTablewithOpt(STranslateContext* pCxt, SQuery* pQu
if (!pStmt->withOpt) return code;
pCxt->withOpt = true;
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot drop table of system database: `%s`.`%s`", pStmt->dbName, pStmt->tableName);
}
for (int32_t i = 0; i < TSDB_TABLE_NAME_LEN; i++) {
if (pStmt->tableName[i] == '\0') {
break;
@ -15745,6 +15776,11 @@ static int32_t rewriteDropSuperTablewithOpt(STranslateContext* pCxt, SQuery* pQu
}
static int32_t rewriteDropSuperTable(STranslateContext* pCxt, SQuery* pQuery) {
SDropSuperTableStmt* pStmt = (SDropSuperTableStmt*)pQuery->pRoot;
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot drop table of system database: `%s`.`%s`", pStmt->dbName, pStmt->tableName);
}
TAOS_CHECK_RETURN(rewriteDropSuperTablewithOpt(pCxt, pQuery));
TAOS_RETURN(0);
}
@ -16298,6 +16334,11 @@ static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* p
static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) {
SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot;
if (IS_SYS_DBNAME(pStmt->dbName)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION,
"Cannot alter table of system database: `%s`.`%s`", pStmt->dbName, pStmt->tableName);
}
if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
}

View File

@ -196,14 +196,23 @@ TEST_F(ParserInitialATest, alterDatabase) {
setAlterDbFsync(200);
setAlterDbWal(1);
setAlterDbCacheModel(TSDB_CACHE_MODEL_LAST_ROW);
#ifndef _STORAGE
setAlterDbSttTrigger(-1);
#else
setAlterDbSttTrigger(16);
#endif
setAlterDbBuffer(16);
setAlterDbPages(128);
setAlterDbReplica(3);
setAlterDbWalRetentionPeriod(10);
setAlterDbWalRetentionSize(20);
#ifndef _STORAGE
run("ALTER DATABASE test BUFFER 16 CACHEMODEL 'last_row' CACHESIZE 32 WAL_FSYNC_PERIOD 200 KEEP 10 PAGES 128 "
"REPLICA 3 WAL_LEVEL 1 WAL_RETENTION_PERIOD 10 WAL_RETENTION_SIZE 20");
#else
run("ALTER DATABASE test BUFFER 16 CACHEMODEL 'last_row' CACHESIZE 32 WAL_FSYNC_PERIOD 200 KEEP 10 PAGES 128 "
"REPLICA 3 WAL_LEVEL 1 STT_TRIGGER 16 WAL_RETENTION_PERIOD 10 WAL_RETENTION_SIZE 20");
#endif
clearAlterDbReq();
initAlterDb("test");
@ -286,6 +295,7 @@ TEST_F(ParserInitialATest, alterDatabase) {
run("ALTER DATABASE test REPLICA 3");
clearAlterDbReq();
#ifdef _STORAGE
initAlterDb("test");
setAlterDbSttTrigger(1);
run("ALTER DATABASE test STT_TRIGGER 1");
@ -294,6 +304,7 @@ TEST_F(ParserInitialATest, alterDatabase) {
setAlterDbSttTrigger(16);
run("ALTER DATABASE test STT_TRIGGER 16");
clearAlterDbReq();
#endif
initAlterDb("test");
setAlterDbMinRows(10);
@ -335,9 +346,9 @@ TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
run("ALTER DATABASE test KEEP 1000000000s", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test KEEP 1w", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test PAGES 63", TSDB_CODE_PAR_INVALID_DB_OPTION);
//run("ALTER DATABASE test WAL_LEVEL 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
// run("ALTER DATABASE test WAL_LEVEL 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test WAL_LEVEL 3", TSDB_CODE_PAR_INVALID_DB_OPTION);
//run("ALTER DATABASE test REPLICA 2", TSDB_CODE_PAR_INVALID_DB_OPTION);
// run("ALTER DATABASE test REPLICA 2", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test STT_TRIGGER 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test STT_TRIGGER 17", TSDB_CODE_PAR_INVALID_DB_OPTION);
// Regardless of the specific sentence

View File

@ -249,7 +249,7 @@ TEST_F(ParserInitialCTest, createDatabase) {
for (int32_t i = 0; i < expect.numOfRetensions; ++i) {
SRetention* pReten = (SRetention*)taosArrayGet(req.pRetensions, i);
SRetention* pExpectReten = (SRetention*)taosArrayGet(expect.pRetensions, i);
if(i == 0) {
if (i == 0) {
ASSERT_EQ(pReten->freq, 0);
} else {
ASSERT_EQ(pReten->freq, pExpectReten->freq);
@ -292,10 +292,44 @@ TEST_F(ParserInitialCTest, createDatabase) {
setDbWalRetentionSize(-1);
setDbWalRollPeriod(10);
setDbWalSegmentSize(20);
#ifndef _STORAGE
setDbSstTrigger(1);
#else
setDbSstTrigger(16);
#endif
setDbHashPrefix(3);
setDbHashSuffix(4);
setDbTsdbPageSize(32);
#ifndef _STORAGE
run("CREATE DATABASE IF NOT EXISTS wxy_db "
"BUFFER 64 "
"CACHEMODEL 'last_value' "
"CACHESIZE 20 "
"COMP 1 "
"DURATION 100 "
"WAL_FSYNC_PERIOD 100 "
"MAXROWS 1000 "
"MINROWS 100 "
"KEEP 1440 "
"PAGES 96 "
"PAGESIZE 8 "
"PRECISION 'ns' "
"REPLICA 3 "
"RETENTIONS -:7d,1m:21d,15m:500d "
// "STRICT 'on' "
"WAL_LEVEL 2 "
"VGROUPS 100 "
"SINGLE_STABLE 1 "
"SCHEMALESS 1 "
"WAL_RETENTION_PERIOD -1 "
"WAL_RETENTION_SIZE -1 "
"WAL_ROLL_PERIOD 10 "
"WAL_SEGMENT_SIZE 20 "
"STT_TRIGGER 1 "
"TABLE_PREFIX 3 "
"TABLE_SUFFIX 4 "
"TSDB_PAGESIZE 32");
#else
run("CREATE DATABASE IF NOT EXISTS wxy_db "
"BUFFER 64 "
"CACHEMODEL 'last_value' "
@ -324,6 +358,8 @@ TEST_F(ParserInitialCTest, createDatabase) {
"TABLE_PREFIX 3 "
"TABLE_SUFFIX 4 "
"TSDB_PAGESIZE 32");
#endif
clearCreateDbReq();
setCreateDbReq("wxy_db", 1);
@ -583,8 +619,6 @@ TEST_F(ParserInitialCTest, createView) {
clearCreateStreamReq();
}
/*
* CREATE MNODE ON DNODE dnode_id
*/
@ -679,7 +713,7 @@ TEST_F(ParserInitialCTest, createSmaIndex) {
ASSERT_EQ(QUERY_NODE_SELECT_STMT, nodeType(pQuery->pPrevRoot));
SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pQuery->pRoot;
SCmdMsgInfo* pCmdMsg = (SCmdMsgInfo*)taosMemoryMalloc(sizeof(SCmdMsgInfo));
SCmdMsgInfo* pCmdMsg = (SCmdMsgInfo*)taosMemoryMalloc(sizeof(SCmdMsgInfo));
if (NULL == pCmdMsg) FAIL();
pCmdMsg->msgType = TDMT_MND_CREATE_SMA;
pCmdMsg->msgLen = tSerializeSMCreateSmaReq(NULL, 0, pStmt->pReq);
@ -1068,7 +1102,8 @@ TEST_F(ParserInitialCTest, createStreamSemanticCheck) {
run("CREATE STREAM s2 INTO st1 AS SELECT ts, to_json('{c1:1}') FROM st1 PARTITION BY TBNAME",
TSDB_CODE_PAR_INVALID_STREAM_QUERY);
run("CREATE STREAM s3 INTO st3 TAGS(tname VARCHAR(10), id INT) SUBTABLE(CONCAT('new-', tbname)) "
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 INTERVAL(10S)", TSDB_CODE_PAR_INVALID_STREAM_QUERY);
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 INTERVAL(10S)",
TSDB_CODE_PAR_INVALID_STREAM_QUERY);
}
/*
@ -1296,10 +1331,10 @@ TEST_F(ParserInitialCTest, createTopic) {
run("CREATE TOPIC IF NOT EXISTS tp1 AS STABLE st1 WHERE tag1 > 0");
clearCreateTopicReq();
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 with meta as stable st1 where tag1 > 0", nullptr, "test", "st1", 1);
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 with meta as stable st1 where tag1 > 0", nullptr, "test",
"st1", 1);
run("CREATE TOPIC IF NOT EXISTS tp1 WITH META AS STABLE st1 WHERE tag1 > 0");
clearCreateTopicReq();
}
/*

View File

@ -70,6 +70,7 @@ bool isPartTagAgg(SAggLogicNode* pAgg);
bool isPartTableWinodw(SWindowLogicNode* pWindow);
bool keysHasCol(SNodeList* pKeys);
bool keysHasTbname(SNodeList* pKeys);
bool projectCouldMergeUnsortDataBlock(SProjectLogicNode* pProject);
SFunctionNode* createGroupKeyAggFunc(SColumnNode* pGroupCol);
int32_t getTimeRangeFromNode(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict);
int32_t tagScanSetExecutionMode(SScanLogicNode* pScan);

View File

@ -412,7 +412,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
int32_t code = makeScanLogicNode(pCxt, pRealTable, pSelect->hasRepeatScanFuncs, (SLogicNode**)&pScan);
pScan->node.groupAction = GROUP_ACTION_NONE;
pScan->node.resultDataOrder = DATA_ORDER_LEVEL_IN_BLOCK;
pScan->node.resultDataOrder = (pRealTable->pMeta->tableType == TSDB_SUPER_TABLE) ? DATA_ORDER_LEVEL_IN_BLOCK : DATA_ORDER_LEVEL_GLOBAL;
if (pCxt->pPlanCxt->streamQuery) {
pScan->triggerType = pCxt->pPlanCxt->triggerType;
pScan->watermark = pCxt->pPlanCxt->watermark;

View File

@ -223,6 +223,13 @@ static void optSetParentOrder(SLogicNode* pNode, EOrder order, SLogicNode* pNode
// Use window output ts order instead.
order = pNode->outputTsOrder;
break;
case QUERY_NODE_LOGIC_PLAN_PROJECT:
if (projectCouldMergeUnsortDataBlock((SProjectLogicNode*)pNode)) {
pNode->outputTsOrder = TSDB_ORDER_NONE;
return;
}
pNode->outputTsOrder = order;
break;
default:
pNode->outputTsOrder = order;
break;

View File

@ -2053,6 +2053,23 @@ static bool projectCanMergeDataBlock(SProjectLogicNode* pProject) {
return DATA_ORDER_LEVEL_GLOBAL == pChild->resultDataOrder ? true : false;
}
bool projectCouldMergeUnsortDataBlock(SProjectLogicNode* pProject) {
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProject->node.pChildren, 0);
if (DATA_ORDER_LEVEL_GLOBAL == pChild->resultDataOrder) {
return false;
}
if (GROUP_ACTION_KEEP == pProject->node.groupAction) {
return false;
}
if (DATA_ORDER_LEVEL_NONE == pProject->node.resultDataOrder) {
return true;
}
if (1 != LIST_LENGTH(pProject->node.pChildren)) {
return true;
}
return false;
}
static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SProjectLogicNode* pProjectLogicNode, SPhysiNode** pPhyNode) {
SProjectPhysiNode* pProject =

View File

@ -15,10 +15,10 @@
#define _DEFAULT_SOURCE
#include "syncPipeline.h"
#include "syncCommit.h"
#include "syncIndexMgr.h"
#include "syncInt.h"
#include "syncPipeline.h"
#include "syncRaftCfg.h"
#include "syncRaftEntry.h"
#include "syncRaftStore.h"
@ -787,6 +787,7 @@ int32_t syncLogBufferCommit(SSyncLogBuffer* pBuf, SSyncNode* pNode, int64_t comm
bool inBuf = false;
SSyncRaftEntry* pNextEntry = NULL;
bool nextInBuf = false;
bool restoreFinishAtThisCommit = false;
if (commitIndex <= pBuf->commitIndex) {
sDebug("vgId:%d, stale commit index. current:%" PRId64 ", notified:%" PRId64 "", vgId, pBuf->commitIndex,
@ -907,6 +908,7 @@ _out:
currentTerm <= pEntry->term) {
pNode->pFsm->FpRestoreFinishCb(pNode->pFsm, pBuf->commitIndex);
pNode->restoreFinish = true;
restoreFinishAtThisCommit = true;
sInfo("vgId:%d, restore finished. term:%" PRId64 ", log buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")",
pNode->vgId, currentTerm, pBuf->startIndex, pBuf->commitIndex, pBuf->matchIndex, pBuf->endIndex);
}
@ -920,6 +922,12 @@ _out:
pNextEntry = NULL;
}
(void)taosThreadMutexUnlock(&pBuf->mutex);
if (restoreFinishAtThisCommit && pNode->pFsm->FpAfterRestoredCb != NULL) {
pNode->pFsm->FpAfterRestoredCb(pNode->pFsm, pBuf->commitIndex);
sInfo("vgId:%d, after restore finished callback executed)", pNode->vgId);
}
TAOS_CHECK_RETURN(syncLogBufferValidate(pBuf));
TAOS_RETURN(code);
}

View File

@ -28,8 +28,7 @@ int32_t syncRespMgrCreate(void *data, int64_t ttl, SSyncRespMgr **ppObj) {
TAOS_RETURN(terrno);
}
pObj->pRespHash =
taosHashInit(sizeof(uint64_t), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
pObj->pRespHash = taosHashInit(8192, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), true, HASH_NO_LOCK);
if (pObj->pRespHash == NULL) {
taosMemoryFree(pObj);
TAOS_RETURN(terrno);

View File

@ -287,12 +287,12 @@ TEST(TcsTest, InterfaceNonBlobTest) {
uint8_t *pBlock = NULL;
code = tcsGetObjectBlock(object_name, 0, size, check, &pBlock);
GTEST_ASSERT_EQ(code, 0);
for (int i = 0; i < size / 2; ++i) {
GTEST_ASSERT_EQ(pBlock[i * 2], 0);
GTEST_ASSERT_EQ(pBlock[i * 2 + 1], 1);
if (pBlock) {
for (int i = 0; i < size / 2; ++i) {
GTEST_ASSERT_EQ(pBlock[i * 2], 0);
GTEST_ASSERT_EQ(pBlock[i * 2 + 1], 1);
}
}
taosMemoryFree(pBlock);
code = tcsGetObjectToFile(object_name, path_download);

View File

@ -294,7 +294,10 @@ void *taosMemCalloc(int64_t num, int64_t size) {
#ifdef USE_TD_MEMORY
int32_t memorySize = num * size;
char *tmp = calloc(memorySize + sizeof(TdMemoryInfo), 1);
if (tmp == NULL) return NULL;
if (tmp == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)tmp;
pTdMemoryInfo->memorySize = memorySize;
@ -328,6 +331,7 @@ void *taosMemRealloc(void *ptr, int64_t size) {
TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
if (tpTdMemoryInfo->symbol != TD_MEMORY_SYMBOL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
@ -335,7 +339,10 @@ void *taosMemRealloc(void *ptr, int64_t size) {
memcpy(&tdMemoryInfo, pTdMemoryInfo, sizeof(TdMemoryInfo));
void *tmp = realloc(pTdMemoryInfo, size + sizeof(TdMemoryInfo));
if (tmp == NULL) return NULL;
if (tmp == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
memcpy(tmp, &tdMemoryInfo, sizeof(TdMemoryInfo));
((TdMemoryInfoPtr)tmp)->memorySize = size;

View File

@ -29,6 +29,7 @@ static threadlocal char tsErrMsgReturn[ERR_MSG_LEN] = {0};
int32_t* taosGetErrno() { return &tsErrno; }
int32_t* taosGetErrln() { return &tsErrln; }
char* taosGetErrMsg() { return tsErrMsgDetail; }
void taosClearErrMsg() { tsErrMsgDetail[0] = '\0'; }
char* taosGetErrMsgReturn() { return tsErrMsgReturn; }
#ifdef TAOS_ERROR_C
@ -857,6 +858,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_REPLAY_NEED_ONE_VGROUP, "Replay need only on
TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT, "Replay is disabled if subscribe db or stable")
TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_TABLE_QUALIFIED, "No table qualified for query")
TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_NEED_REBALANCE, "No need rebalance")
TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_STATUS, "Invalid status, please subscribe topic first")
// stream
TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist")

View File

@ -22,7 +22,9 @@ from frame.autogen import *
class TDTestCase(TBase):
clientCfgDict = { "keepColumnName": 1 }
updatecfgDict = { "clientCfg": clientCfgDict }
def ts_30189(self):
tdLog.info("create database ts_30189")
tdSql.execute(f"create database ts_30189")
@ -144,6 +146,40 @@ class TDTestCase(TBase):
tdSql.checkRows(1)
tdSql.checkData(0, 0, 2)
def ts_5878(self):
# prepare data
tdLog.info("create database ts_5878")
tdSql.execute("create database ts_5878")
tdSql.execute("use ts_5878")
sqls = [
"CREATE STABLE meters (ts timestamp, c1 int) TAGS (gid int)",
"CREATE TABLE d0 USING meters (gid) TAGS (0)",
"CREATE TABLE d1 USING meters (gid) TAGS (1)",
"CREATE TABLE d2 USING meters (gid) TAGS (2)",
"INSERT INTO d0 VALUES ('2025-01-01 00:00:00', 0)",
"INSERT INTO d1 VALUES ('2025-01-01 00:01:00', 1)",
"INSERT INTO d2 VALUES ('2025-01-01 00:02:00', 2)"
]
tdSql.executes(sqls)
# check column name in query result
sql1 = "SELECT * FROM (SELECT LAST_ROW(ts) FROM d1)"
cols = ["ts"]
rows = [["2025-01-01 00:01:00"]]
colNames = tdSql.getColNameList(sql1)
tdSql.checkColNameList(colNames, cols)
tdSql.checkDataMem(sql1, rows)
sql2 = "SELECT * FROM (SELECT LAST(ts) FROM meters PARTITION BY tbname) ORDER BY 1"
cols = ["ts"]
rows = [
["2025-01-01 00:00:00"],
["2025-01-01 00:01:00"],
["2025-01-01 00:02:00"],
]
colNames = tdSql.getColNameList(sql2)
tdSql.checkColNameList(colNames, cols)
tdSql.checkDataMem(sql2, rows)
# run
def run(self):
tdLog.debug(f"start to excute {__file__}")
@ -154,6 +190,9 @@ class TDTestCase(TBase):
# TS-5443
self.ts_5443()
# TS-5878
self.ts_5878()
tdLog.success(f"{__file__} successfully executed")

View File

@ -130,7 +130,7 @@ pip3 install kafka-python
python3 kafka_example_consumer.py
# 21
pip3 install taos-ws-py==0.3.5
pip3 install taos-ws-py==0.3.8
python3 conn_websocket_pandas.py
# 22

View File

@ -334,6 +334,7 @@
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/td-33225.py
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_ts4563.py
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_td32526.py
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_td32471.py
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_replay.py
,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmqSeekAndCommit.py
,,n,system-test,python3 ./test.py -f 7-tmq/tmq_offset.py
@ -494,6 +495,7 @@
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/test_td29793.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/insert_timestamp.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/test_td29157.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/ddl_in_sysdb.py
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show.py
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show_tag_index.py
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/information_schema.py
@ -736,7 +738,6 @@
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/tb_100w_data_order.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_childtable.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_normaltable.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_systable.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/keep_expired.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/stmt_error.py
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/drop.py

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,7 @@ md5sum /home/TDinternal/debug/build/lib/libtaos.so
#get python connector and update: taospy 2.7.16 taos-ws-py 0.3.5
pip3 install taospy==2.7.21
pip3 install taos-ws-py==0.3.5
pip3 install taos-ws-py==0.3.8
$TIMEOUT_CMD $cmd
RET=$?
echo "cmd exit code: $RET"

View File

@ -1,6 +1,6 @@
import json
import subprocess
import threading
import psutil
import time
import taos
@ -21,31 +21,86 @@ class MonitorSystemLoad:
def get_proc_status(self):
process = psutil.Process(self.pid)
with open('/tmp/pref.txt', 'w+') as f:
while True:
cpu_percent = process.cpu_percent(interval=1)
memory_info = process.memory_info()
memory_percent = process.memory_percent()
io_counters = process.io_counters()
sys_load = psutil.getloadavg()
s = "load: %.2f, CPU:%s, Mem:%.2fMiB, %.2f%%, Read: %.2fMiB, %d, Write: %.2fMib, %d" % (
sys_load[0], cpu_percent, memory_info.rss / 1048576.0,
memory_percent, io_counters.read_bytes / 1048576.0, io_counters.read_count,
io_counters.write_bytes / 1048576.0, io_counters.write_count)
print(s)
f.write(s + '\n')
f.flush()
time.sleep(1)
self.count -= 1
if self.count <= 0:
break
def do_monitor():
print("start monitor threads")
loader = MonitorSystemLoad('taosd', 80000)
loader.get_proc_status()
def get_table_list(cursor):
cursor.execute('use stream_test')
sql = "select table_name from information_schema.ins_tables where db_name = 'stream_test' and stable_name='stb' order by table_name"
cursor.execute(sql)
res = cursor.fetchall()
return res
def do_multi_insert(index, total, host, user, passwd, conf, tz):
conn = taos.connect(
host=host, user=user, password=passwd, config=conf, timezone=tz
)
cursor = conn.cursor()
cursor.execute('use stream_test')
start_ts = 1609430400000
step = 5
cursor.execute("create stable if not exists stb_result(wstart timestamp, minx float, maxx float, countx bigint) tags(gid bigint unsigned)")
list = get_table_list(cursor)
list = list[index*total: (index+1)*total]
print("there are %d tables" % len(list))
for index, n in enumerate(list):
cursor.execute(f"create table if not exists {n[0]}_1 using stb_result tags(1)")
count = 1
while True:
cpu_percent = process.cpu_percent(interval=1)
sql = (f"select cast({start_ts + step * 1000 * (count - 1)} as timestamp), min(c1), max(c2), count(c3) from stream_test.{n[0]} "
f"where ts >= {start_ts + step * 1000 * (count - 1)} and ts < {start_ts + step * 1000 * count}")
cursor.execute(sql)
memory_info = process.memory_info()
memory_percent = process.memory_percent()
io_counters = process.io_counters()
sys_load = psutil.getloadavg()
print("load: %s, CPU:%s, Mem:%.2f MiB(%.2f%%), Read: %.2fMiB(%d), Write: %.2fMib (%d)" % (
sys_load, cpu_percent, memory_info.rss / 1048576.0,
memory_percent, io_counters.read_bytes / 1048576.0, io_counters.read_count,
io_counters.write_bytes / 1048576.0, io_counters.write_count))
time.sleep(1)
self.count -= 1
if self.count <= 0:
res = cursor.fetchall()
if res[0][3] == 0:
break
insert = f"insert into {n[0]}_1 values ({start_ts + step * 1000 * (count - 1)}, {res[0][1]}, {res[0][2]}, {res[0][3]})"
cursor.execute(insert)
count += 1
conn.close()
class StreamStarter:
def __init__(self) -> None:
self.sql = None
self.host='127.0.0.1'
self.host='ubuntu'
self.user = 'root'
self.passwd = 'taosdata'
self.conf = '/etc/taos/taos.cfg'
@ -55,18 +110,18 @@ class StreamStarter:
json_data = {
"filetype": "insert",
"cfgdir": "/etc/taos/cfg",
"host": "127.0.0.1",
"host": "ubuntu",
"port": 6030,
"rest_port": 6041,
"user": "root",
"password": "taosdata",
"thread_count": 20,
"create_table_thread_count": 40,
"thread_count": 5,
"create_table_thread_count": 5,
"result_file": "/tmp/taosBenchmark_result.log",
"confirm_parameter_prompt": "no",
"insert_interval": 0,
"num_of_records_per_req": 10000,
"max_sql_len": 1024000,
"insert_interval": 1000,
"num_of_records_per_req": 1000,
"max_sql_len": 102400,
"databases": [
{
"dbinfo": {
@ -96,7 +151,7 @@ class StreamStarter:
"insert_mode": "taosc",
"interlace_rows": 400,
"tcp_transfer": "no",
"insert_rows": 10000,
"insert_rows": 1000,
"partial_col_num": 0,
"childtable_limit": 0,
"childtable_offset": 0,
@ -281,6 +336,78 @@ class StreamStarter:
loader = MonitorSystemLoad('taosd', 80)
loader.get_proc_status()
def do_query_then_insert(self):
self.prepare_data()
try:
subprocess.Popen('taosBenchmark --f /tmp/stream.json', stdout=subprocess.PIPE, shell=True, text=True)
except subprocess.CalledProcessError as e:
print(f"Error running Bash command: {e}")
time.sleep(50)
conn = taos.connect(
host=self.host, user=self.user, password=self.passwd, config=self.conf, timezone=self.tz
)
cursor = conn.cursor()
cursor.execute('use stream_test')
start_ts = 1609430400000
step = 5
cursor.execute("create stable if not exists stb_result(wstart timestamp, minx float, maxx float, countx bigint) tags(gid bigint unsigned)")
try:
t = threading.Thread(target=do_monitor)
t.start()
except Exception as e:
print("Error: unable to start thread, %s" % e)
print("start to query")
list = get_table_list(cursor)
print("there are %d tables" % len(list))
for index, n in enumerate(list):
cursor.execute(f"create table if not exists {n[0]}_1 using stb_result tags(1)")
count = 1
while True:
sql = (f"select cast({start_ts + step * 1000 * (count - 1)} as timestamp), min(c1), max(c2), count(c3) from stream_test.{n[0]} "
f"where ts >= {start_ts + step * 1000 * (count - 1)} and ts < {start_ts + step * 1000 * count}")
cursor.execute(sql)
res = cursor.fetchall()
if res[0][3] == 0:
break
insert = f"insert into {n[0]}_1 values ({start_ts + step * 1000 * (count - 1)}, {res[0][1]}, {res[0][2]}, {res[0][3]})"
cursor.execute(insert)
count += 1
conn.close()
def multi_insert(self):
self.prepare_data()
try:
subprocess.Popen('taosBenchmark --f /tmp/stream.json', stdout=subprocess.PIPE, shell=True, text=True)
except subprocess.CalledProcessError as e:
print(f"Error running Bash command: {e}")
time.sleep(10)
for n in range(5):
try:
print(f"start query_insert thread {n}")
t = threading.Thread(target=do_multi_insert, args=(n, 100, self.host, self.user, self.passwd, self.conf, self.tz))
t.start()
except Exception as e:
print("Error: unable to start thread, %s" % e)
loader = MonitorSystemLoad('taosd', 80)
loader.get_proc_status()
if __name__ == "__main__":
StreamStarter().do_start()
# StreamStarter().do_start()
# StreamStarter().do_query_then_insert()
StreamStarter().multi_insert()

240
tests/run_all_ci_cases.sh Normal file → Executable file
View File

@ -13,16 +13,33 @@ function print_color() {
echo -e "${color}${message}${NC}"
}
# 初始化参数
TDENGINE_DIR="/root/TDinternal/community"
function printHelp() {
echo "Usage: $(basename $0) [options]"
echo
echo "Options:"
echo " -d [Project dir] Project directory (default: outermost project directory)"
echo " Options: "
echo " e.g., -d /root/TDengine or -d /root/TDinternal"
echo " -b [Build test branch] Build test branch (default: null)"
echo " Options: "
echo " e.g., -b main (pull main branch, build and install)"
echo " -s [Save cases log] Save cases log(default: notsave)"
echo " Options:"
echo " e.g., -c notsave : do not save the log "
echo " -c save : default save ci case log in Project dir/tests/ci_bak"
exit 0
}
# Initialization parameter
PROJECT_DIR=""
BRANCH=""
SAVE_LOG="notsave"
# 解析命令行参数
while getopts "hd:b:t:s:" arg; do
# Parse command line parameters
while getopts "hb:d:s:" arg; do
case $arg in
d)
TDENGINE_DIR=$OPTARG
PROJECT_DIR=$OPTARG
;;
b)
BRANCH=$OPTARG
@ -31,11 +48,7 @@ while getopts "hd:b:t:s:" arg; do
SAVE_LOG=$OPTARG
;;
h)
echo "Usage: $(basename $0) -d [TDengine_dir] -b [branch] -s [save ci case log]"
echo " -d [TDengine_dir] [default /root/TDinternal/community] "
echo " -b [branch] [default local branch] "
echo " -s [save/notsave] [default save ci case log in TDengine_dir/tests/ci_bak] "
exit 0
printHelp
;;
?)
echo "Usage: ./$(basename $0) -h"
@ -44,76 +57,144 @@ while getopts "hd:b:t:s:" arg; do
esac
done
# 检查是否提供了命令名称
if [ -z "$TDENGINE_DIR" ]; then
echo "Error: TDengine dir is required."
echo "Usage: $(basename $0) -d [TDengine_dir] -b [branch] -s [save ci case log] "
echo " -d [TDengine_dir] [default /root/TDinternal/community] "
echo " -b [branch] [default local branch] "
echo " -s [save/notsave] [default save ci case log in TDengine_dir/tests/ci_bak] "
exit 1
fi
function get_DIR() {
today=`date +"%Y%m%d"`
if [ -z "$PROJECT_DIR" ]; then
CODE_DIR=$(dirname $0)
cd $CODE_DIR
CODE_DIR=$(pwd)
if [[ "$CODE_DIR" == *"/community/"* ]]; then
PROJECT_DIR=$(realpath ../..)
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
BACKUP_DIR="$TDENGINE_DIR/tests/ci_bak"
mkdir -p "$BACKUP_DIR"
else
PROJECT_DIR=$(realpath ..)
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
BACKUP_DIR="$TDENGINE_DIR/tests/ci_bak"
mkdir -p "$BACKUP_DIR"
cp $TDENGINE_DIR/tests/parallel_test/cases.task $TDENGINE_DIR/tests/parallel_test/cases_tdengine.task
fi
elif [[ "$PROJECT_DIR" == *"/TDinternal" ]]; then
TDENGINE_DIR="$PROJECT_DIR/community"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
BACKUP_DIR="$TDENGINE_DIR/tests/ci_bak"
mkdir -p "$BACKUP_DIR"
cp $TDENGINE_DIR/tests/parallel_test/cases.task $TDENGINE_DIR/tests/parallel_test/cases_tdengine.task
elif [[ "$PROJECT_DIR" == *"/TDengine" ]]; then
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
BACKUP_DIR="$TDENGINE_DIR/tests/ci_bak"
mkdir -p "$BACKUP_DIR"
fi
}
get_DIR
echo "PROJECT_DIR = $PROJECT_DIR"
echo "TDENGINE_DIR = $TDENGINE_DIR"
today=`date +"%Y%m%d"`
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
BACKUP_DIR="$TDENGINE_DIR/tests/ci_bak"
mkdir -p "$BACKUP_DIR"
#cd $BACKUP_DIR && rm -rf *
echo "BUILD_DIR = $BUILD_DIR"
echo "BACKUP_DIR = $BACKUP_DIR"
function buildTDengine() {
print_color "$GREEN" "TDengine build start"
# pull parent code
cd "$TDENGINE_DIR/../"
print_color "$GREEN" "git pull parent code..."
git remote prune origin > /dev/null
git remote update > /dev/null
if [[ "$PROJECT_DIR" == *"/TDinternal" ]]; then
TDENGINE_DIR="$PROJECT_DIR/community"
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "git pull tdengine code..."
git remote prune origin > /dev/null
git remote update > /dev/null
REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch`
LOCAL_COMMIT=`git rev-parse --short @`
print_color "$GREEN" " LOCAL: $LOCAL_COMMIT"
print_color "$GREEN" "REMOTE: $REMOTE_COMMIT"
# pull tdinternal code
cd "$TDENGINE_DIR/../"
print_color "$GREEN" "Git pull TDinternal code..."
git remote prune origin > /dev/null
git remote update > /dev/null
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "Git pull TDengine code..."
git remote prune origin > /dev/null
git remote update > /dev/null
REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch`
LOCAL_COMMIT=`git rev-parse --short @`
print_color "$GREEN" " LOCAL: $LOCAL_COMMIT"
print_color "$GREEN" "REMOTE: $REMOTE_COMMIT"
if [ "$LOCAL_COMMIT" == "$REMOTE_COMMIT" ]; then
print_color "$GREEN" "Repo up-to-date"
else
print_color "$GREEN" "Repo need to pull"
fi
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
[ -d $TDENGINE_DIR/../debug ] || mkdir $TDENGINE_DIR/../debug
cd $TDENGINE_DIR/../debug
print_color "$GREEN" "Rebuild.."
LOCAL_COMMIT=`git rev-parse --short @`
rm -rf *
makecmd="cmake -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=false -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../ "
print_color "$GREEN" "$makecmd"
$makecmd
make -j 8 install
if [ "$LOCAL_COMMIT" == "$REMOTE_COMMIT" ]; then
print_color "$GREEN" "repo up-to-date"
else
print_color "$GREEN" "repo need to pull"
TDENGINE_DIR="$PROJECT_DIR"
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "Git pull TDengine code..."
git remote prune origin > /dev/null
git remote update > /dev/null
REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch`
LOCAL_COMMIT=`git rev-parse --short @`
print_color "$GREEN" " LOCAL: $LOCAL_COMMIT"
print_color "$GREEN" "REMOTE: $REMOTE_COMMIT"
if [ "$LOCAL_COMMIT" == "$REMOTE_COMMIT" ]; then
print_color "$GREEN" "Repo up-to-date"
else
print_color "$GREEN" "Repo need to pull"
fi
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
[ -d $TDENGINE_DIR/debug ] || mkdir $TDENGINE_DIR/debug
cd $TDENGINE_DIR/debug
print_color "$GREEN" "Rebuild.."
LOCAL_COMMIT=`git rev-parse --short @`
rm -rf *
makecmd="cmake -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=0 -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../ "
print_color "$GREEN" "$makecmd"
$makecmd
make -j 8 install
fi
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
[ -d $TDENGINE_DIR/debug ] || mkdir $TDENGINE_DIR/debug
cd $TDENGINE_DIR/debug
print_color "$GREEN" "rebuild.."
LOCAL_COMMIT=`git rev-parse --short @`
rm -rf *
makecmd="cmake -DBUILD_TEST=false -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=0 -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../../"
print_color "$GREEN" "$makecmd"
$makecmd
make -j 8 install
print_color "$GREEN" "TDengine build end"
}
# 检查并获取分支名称
if [ -n "$BRANCH" ]; then
# Check and get the branch name
if [ -n "$BRANCH" ] ; then
branch="$BRANCH"
print_color "$GREEN" "Testing branch: $branch "
print_color "$GREEN" "Build is required for this test"
@ -135,18 +216,11 @@ function runCasesOneByOne () {
date +%F\ %T | tee -a $TDENGINE_ALLCI_REPORT && timeout 20m $cmd > $TDENGINE_DIR/tests/$case_file.log 2>&1 && \
echo -e "${GREEN}$case success${NC}" | tee -a $TDENGINE_ALLCI_REPORT || \
echo -e "${RED}$case failed${NC}" | tee -a $TDENGINE_ALLCI_REPORT
# # 记录日志和备份
# mkdir -p "$BACKUP_DIR/$case_file"
# tar --exclude='*.sock*' -czf "$BACKUP_DIR/$case_file/sim.tar.gz" -C "$TDENGINE_DIR/.." sim
# mv "$TDENGINE_DIR/tests/$case_file.log" "$BACKUP_DIR/$case_file"
if [ "$SAVE_LOG" == "save" ]; then
mkdir -p "$BACKUP_DIR/$case_file"
tar --exclude='*.sock*' -czf "$BACKUP_DIR/$case_file/sim.tar.gz" -C "$TDENGINE_DIR/.." sim
mv "$TDENGINE_DIR/tests/$case_file.log" "$BACKUP_DIR/$case_file"
else
echo "This case not save log!"
fi
end_time=`date +%s`
@ -168,8 +242,6 @@ function runCasesOneByOne () {
mkdir -p "$BACKUP_DIR/$case_file"
tar --exclude='*.sock*' -czf "$BACKUP_DIR/$case_file/sim.tar.gz" -C "$TDENGINE_DIR/.." sim
mv "$TDENGINE_DIR/tests/$case_file.log" "$BACKUP_DIR/$case_file"
else
echo "This case not save log!"
fi
end_time=`date +%s`
@ -180,10 +252,12 @@ function runCasesOneByOne () {
}
function runUnitTest() {
print_color "$GREEN" "=== Run unit test case ==="
print_color "$GREEN" " $TDENGINE_DIR/../debug"
cd $TDENGINE_DIR/../debug
ctest -j12
get_DIR
print_color "$GREEN" "cd $BUILD_DIR"
cd $BUILD_DIR
pgrep taosd || taosd >> /dev/null 2>&1 &
sleep 10
ctest -E "cunit_test" -j8
print_color "$GREEN" "3.0 unit test done"
}
@ -191,7 +265,7 @@ function runSimCases() {
print_color "$GREEN" "=== Run sim cases ==="
cd $TDENGINE_DIR/tests/script
runCasesOneByOne $TDENGINE_DIR/tests/parallel_test/cases.task sim
runCasesOneByOne $TDENGINE_DIR/tests/parallel_test/cases_tdengine.task sim
totalSuccess=`grep 'sim success' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalSuccess" -gt "0" ]; then
@ -208,19 +282,19 @@ function runPythonCases() {
print_color "$GREEN" "=== Run python cases ==="
cd $TDENGINE_DIR/tests/parallel_test
sed -i '/compatibility.py/d' cases.task
sed -i '/compatibility.py/d' cases_tdengine.task
# army
cd $TDENGINE_DIR/tests/army
runCasesOneByOne ../parallel_test/cases.task army
runCasesOneByOne ../parallel_test/cases_tdengine.task army
# system-test
cd $TDENGINE_DIR/tests/system-test
runCasesOneByOne ../parallel_test/cases.task system-test
runCasesOneByOne ../parallel_test/cases_tdengine.task system-test
# develop-test
cd $TDENGINE_DIR/tests/develop-test
runCasesOneByOne ../parallel_test/cases.task develop-test
runCasesOneByOne ../parallel_test/cases_tdengine.task develop-test
totalSuccess=`grep 'py success' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalSuccess" -gt "0" ]; then
@ -280,7 +354,7 @@ function stopTaosadapter {
}
WORK_DIR=/root/
WORK_DIR=$TDENGINE_DIR
date >> $WORK_DIR/date.log
print_color "$GREEN" "Run all ci test cases" | tee -a $WORK_DIR/date.log

View File

@ -13,23 +13,53 @@ function print_color() {
echo -e "${color}${message}${NC}"
}
# Initialization parameter
TDENGINE_DIR="/root/TDinternal/community"
function printHelp() {
echo "Usage: $(basename $0) [options]"
echo
echo "Options:"
echo " -d [Project dir] Project directory (default: outermost project directory)"
echo " e.g., -d /root/TDinternal/community"
echo " -b [Build specify branch] Build specify branch (default: main)"
echo " Options: "
echo " e.g., -b main (pull main branch, build and install)[Branches need to be specified for the first run]"
echo " -i [Build develop branch] Build develop branch (default: null)"
echo " Options: "
echo " yes/YES (pull , build and install)"
echo " only_install/ONLY_INSTALL (only install)"
echo " -f [Capture gcda dir] Capture gcda directory (default: <project dir>/debug)"
echo " -c [Test case] Test single case or all cases (default: null)"
echo " Options:"
echo " -c all : run all python, sim cases in longtimeruning_cases.task and unit cases"
echo " -c task : run all python and sim cases in longtimeruning_cases.task "
echo " -c cmd : run the specified test command"
echo " e.g., -c './test.sh -f tsim/stream/streamFwcIntervalFill.sim'"
echo " -u [Unit test case] Unit test case (default: null)"
echo " e.g., -u './schedulerTest'"
echo " -l [Lcov bin dir] Lcov bin dir (default: /usr/local/bin)"
echo " e.g., -l '/root/TDinternal/community/tests/lcov-1.16/bin'"
exit 0
}
PROJECT_DIR=""
CAPTURE_GCDA_DIR=""
TEST_CASE="task"
UNIT_TEST_CASE=""
BRANCH=""
TDENGINE_GCDA_DIR="/root/TDinternal/community/debug/"
BRANCH_BUILD=""
LCOV_DIR="/usr/local/bin"
# Parse command line parameters
while getopts "hd:b:f:c:u:i:l:" arg; do
case $arg in
d)
TDENGINE_DIR=$OPTARG
PROJECT_DIR=$OPTARG
;;
b)
BRANCH=$OPTARG
;;
f)
TDENGINE_GCDA_DIR=$OPTARG
CAPTURE_GCDA_DIR=$OPTARG
;;
c)
TEST_CASE=$OPTARG
@ -44,15 +74,7 @@ while getopts "hd:b:f:c:u:i:l:" arg; do
LCOV_DIR=$OPTARG
;;
h)
echo "Usage: $(basename $0) -d [TDengine dir] -b [Test branch] -i [Build test branch] -f [TDengine gcda dir] -c [Test single case/all cases] -u [Unit test case] -l [Lcov dir]"
echo " -d [TDengine dir] [default /root/TDinternal/community; eg: /home/TDinternal/community] "
echo " -b [Test branch] [default local branch; eg:cover/3.0] "
echo " -i [Build test branch] [default no:not build, but still install ;yes:will build and install ] "
echo " -f [TDengine gcda dir] [default /root/TDinternal/community/debug; eg:/root/TDinternal/community/debug/community/source/dnode/vnode/CMakeFiles/vnode.dir/src/tq/] "
echo " -c [Test single case/all cases] [default null; -c all : include parallel_test/longtimeruning_cases.task and all unit cases; -c task : include parallel_test/longtimeruning_cases.task; single case: eg: -c './test.sh -f tsim/stream/streamFwcIntervalFill.sim' ] "
echo " -u [Unit test case] [default null; eg: './schedulerTest' ] "
echo " -l [Lcov bin dir] [default /usr/local/bin; eg: '/root/TDinternal/community/tests/lcov-1.14/bin' ] "
exit 0
printHelp
;;
?)
echo "Usage: ./$(basename $0) -h"
@ -61,65 +83,141 @@ while getopts "hd:b:f:c:u:i:l:" arg; do
esac
done
# Check if the command name is provided
if [ -z "$TDENGINE_DIR" ]; then
echo "Error: TDengine dir is required."
echo "Usage: $(basename $0) -d [TDengine dir] -b [Test branch] -i [Build test branch] -f [TDengine gcda dir] -c [Test single case/all cases] -u [Unit test case] -l [Lcov dir] "
echo " -d [TDengine dir] [default /root/TDinternal/community; eg: /home/TDinternal/community] "
echo " -b [Test branch] [default local branch; eg:cover/3.0] "
echo " -i [Build test branch] [default no:not build, but still install ;yes:will build and install ] "
echo " -f [TDengine gcda dir] [default /root/TDinternal/community/debug; eg:/root/TDinternal/community/debug/community/source/dnode/vnode/CMakeFiles/vnode.dir/src/tq/] "
echo " -c [Test casingle case/all casesse] [default null; -c all : include parallel_test/longtimeruning_cases.task and all unit cases; -c task : include parallel_test/longtimeruning_cases.task; single case: eg: -c './test.sh -f tsim/stream/streamFwcIntervalFill.sim' ] "
echo " -u [Unit test case] [default null; eg: './schedulerTest' ] "
echo " -l [Lcov bin dir] [default /usr/local/bin; eg: '/root/TDinternal/community/tests/lcov-1.14/bin' ] "
exit 1
fi
echo "TDENGINE_DIR = $TDENGINE_DIR"
today=`date +"%Y%m%d"`
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
function pullTDengine() {
print_color "$GREEN" "TDengine pull start"
# pull parent code
cd "$TDENGINE_DIR/../"
print_color "$GREEN" "git pull parent code..."
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "git pull tdengine code..."
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
print_color "$GREEN" "TDengine pull end"
# Find the project/tdengine/build/capture directory
function get_DIR() {
today=`date +"%Y%m%d"`
if [ -z "$PROJECT_DIR" ]; then
CODE_DIR=$(dirname $0)
cd $CODE_DIR
CODE_DIR=$(pwd)
if [[ "$CODE_DIR" == *"/community/"* ]]; then
PROJECT_DIR=$(realpath ../..)
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
CAPTURE_GCDA_DIR="$BUILD_DIR"
else
PROJECT_DIR=$(realpath ..)
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
CAPTURE_GCDA_DIR="$BUILD_DIR"
fi
elif [[ "$PROJECT_DIR" == *"/TDinternal" ]]; then
TDENGINE_DIR="$PROJECT_DIR/community"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
CAPTURE_GCDA_DIR="$BUILD_DIR"
elif [[ "$PROJECT_DIR" == *"/TDengine" ]]; then
TDENGINE_DIR="$PROJECT_DIR"
BUILD_DIR="$PROJECT_DIR/debug"
TDENGINE_ALLCI_REPORT="$TDENGINE_DIR/tests/all-ci-report-$today.log"
CAPTURE_GCDA_DIR="$BUILD_DIR"
fi
}
# Show all parameters
get_DIR
echo "PROJECT_DIR = $PROJECT_DIR"
echo "TDENGINE_DIR = $TDENGINE_DIR"
echo "BUILD_DIR = $BUILD_DIR"
echo "CAPTURE_GCDA_DIR = $CAPTURE_GCDA_DIR"
echo "TEST_CASE = $TEST_CASE"
echo "UNIT_TEST_CASE = $UNIT_TEST_CASE"
echo "BRANCH_BUILD = $BRANCH_BUILD"
echo "LCOV_DIR = $LCOV_DIR"
function buildTDengine() {
print_color "$GREEN" "TDengine build start"
if [[ "$PROJECT_DIR" == *"/TDinternal" ]]; then
TDENGINE_DIR="$PROJECT_DIR/community"
[ -d $TDENGINE_DIR/debug ] || mkdir $TDENGINE_DIR/debug
cd $TDENGINE_DIR/debug
# pull tdinternal code
cd "$TDENGINE_DIR/../"
print_color "$GREEN" "Git pull TDinternal code..."
git remote prune origin > /dev/null
git remote update > /dev/null
print_color "$GREEN" "rebuild.."
rm -rf *
makecmd="cmake -DCOVER=true -DBUILD_TEST=false -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=0 -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../../"
print_color "$GREEN" "$makecmd"
$makecmd
make -j 8 install
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "Git pull TDengine code..."
git remote prune origin > /dev/null
git remote update > /dev/null
REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch`
LOCAL_COMMIT=`git rev-parse --short @`
print_color "$GREEN" " LOCAL: $LOCAL_COMMIT"
print_color "$GREEN" "REMOTE: $REMOTE_COMMIT"
if [ "$LOCAL_COMMIT" == "$REMOTE_COMMIT" ]; then
print_color "$GREEN" "Repo up-to-date"
else
print_color "$GREEN" "Repo need to pull"
fi
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
[ -d $TDENGINE_DIR/../debug ] || mkdir $TDENGINE_DIR/../debug
cd $TDENGINE_DIR/../debug
print_color "$GREEN" "Rebuild.."
LOCAL_COMMIT=`git rev-parse --short @`
rm -rf *
makecmd="cmake -DCOVER=true -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=false -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../ "
print_color "$GREEN" "$makecmd"
$makecmd
make -j $(nproc) install
else
TDENGINE_DIR="$PROJECT_DIR"
# pull tdengine code
cd $TDENGINE_DIR
print_color "$GREEN" "Git pull TDengine code..."
git remote prune origin > /dev/null
git remote update > /dev/null
REMOTE_COMMIT=`git rev-parse --short remotes/origin/$branch`
LOCAL_COMMIT=`git rev-parse --short @`
print_color "$GREEN" " LOCAL: $LOCAL_COMMIT"
print_color "$GREEN" "REMOTE: $REMOTE_COMMIT"
if [ "$LOCAL_COMMIT" == "$REMOTE_COMMIT" ]; then
print_color "$GREEN" "Repo up-to-date"
else
print_color "$GREEN" "Repo need to pull"
fi
git reset --hard
git checkout -- .
git checkout $branch
git checkout -- .
git clean -f
git pull
[ -d $TDENGINE_DIR/debug ] || mkdir $TDENGINE_DIR/debug
cd $TDENGINE_DIR/debug
print_color "$GREEN" "Rebuild.."
LOCAL_COMMIT=`git rev-parse --short @`
rm -rf *
makecmd="cmake -DCOVER=true -DBUILD_HTTP=false -DBUILD_DEPENDENCY_TESTS=0 -DBUILD_TOOLS=true -DBUILD_GEOS=true -DBUILD_TEST=true -DBUILD_CONTRIB=false ../ "
print_color "$GREEN" "$makecmd"
$makecmd
make -j $(nproc) install
fi
print_color "$GREEN" "TDengine build end"
}
# Check and get the branch name and build branch
@ -127,28 +225,39 @@ if [ -n "$BRANCH" ] && [ -z "$BRANCH_BUILD" ] ; then
branch="$BRANCH"
print_color "$GREEN" "Testing branch: $branch "
print_color "$GREEN" "Build is required for this test!"
pullTDengine
buildTDengine
elif [ -n "$BRANCH_BUILD" ] && [ "$BRANCH_BUILD" == "yes" ] ; then
branch="$BRANCH"
elif [ -n "$BRANCH_BUILD" ] && [ "$BRANCH_BUILD" = "YES" -o "$BRANCH_BUILD" = "yes" ] ; then
CURRENT_DIR=$(pwd)
echo "CURRENT_DIR: $CURRENT_DIR"
if [ -d .git ]; then
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "CURRENT_BRANCH: $CURRENT_BRANCH"
else
echo "The current directory is not a Git repository"
fi
branch="$CURRENT_BRANCH"
print_color "$GREEN" "Testing branch: $branch "
print_color "$GREEN" "Build is required for this test!"
pullTDengine
buildTDengine
elif [ -n "$BRANCH_BUILD" ] && [ "$BRANCH_BUILD" == "no" ] ; then
branch="$BRANCH"
elif [ -n "$BRANCH_BUILD" ] && [ "$BRANCH_BUILD" = "ONLY_INSTALL" -o "$BRANCH_BUILD" = "only_install" ] ; then
CURRENT_DIR=$(pwd)
echo "CURRENT_DIR: $CURRENT_DIR"
if [ -d .git ]; then
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "CURRENT_BRANCH: $CURRENT_BRANCH"
else
echo "The current directory is not a Git repository"
fi
branch="$CURRENT_BRANCH"
print_color "$GREEN" "Testing branch: $branch "
print_color "$GREEN" "not build,only install!"
cd "$TDENGINE_DIR/../"
git pull
cd "$TDENGINE_DIR/"
git pull
cd $TDENGINE_DIR/debug
make -j 8 install
else
make -j $(nproc) install
elif [ -z "$BRANCH" ] && [ -z "$BRANCH_BUILD" ] ; then
print_color "$GREEN" "Build is not required for this test!"
fi
function runCasesOneByOne () {
while read -r line; do
if [[ "$line" != "#"* ]]; then
@ -184,9 +293,12 @@ function runCasesOneByOne () {
function runUnitTest() {
print_color "$GREEN" "=== Run unit test case ==="
print_color "$GREEN" " $TDENGINE_DIR/debug"
cd $TDENGINE_DIR/debug
ctest -j12
get_DIR
print_color "$GREEN" "cd $BUILD_DIR"
cd $BUILD_DIR
pgrep taosd || taosd >> /dev/null 2>&1 &
sleep 10
ctest -E "cunit_test" -j $(nproc)
print_color "$GREEN" "3.0 unit test done"
}
@ -267,10 +379,27 @@ function runTest() {
if [ -n "$TEST_CASE" ] && [ "$TEST_CASE" != "all" ] && [ "$TEST_CASE" != "task" ]; then
TEST_CASE="$TEST_CASE"
print_color "$GREEN" "Test case: $TEST_CASE "
cd $TDENGINE_DIR/tests/script/ && $TEST_CASE
cd $TDENGINE_DIR/tests/army/ && $TEST_CASE
cd $TDENGINE_DIR/tests/system-test/ && $TEST_CASE
cd $TDENGINE_DIR/tests/develop-test/ && $TEST_CASE
PYTHON_SIM=$(echo $TEST_CASE | awk '{print $1}' | xargs basename)
echo "PYTHON_SIM: $PYTHON_SIM"
if [[ "$PYTHON_SIM" == "python3" ]]; then
CASE_FILENAME=$(echo $TEST_CASE | awk -F' ' '{print $4}' | xargs basename)
echo "CASE_FILENAME: $CASE_FILENAME"
CASE_DIR=$(find $TDENGINE_DIR/tests -name $CASE_FILENAME)
echo "CASE_DIR: $CASE_DIR"
if [[ "$CASE_DIR" == *"/army/"* ]]; then
cd $TDENGINE_DIR/tests/army/ && $TEST_CASE
elif [[ "$CASE_DIR" == *"/system-test/"* ]]; then
cd $TDENGINE_DIR/tests/system-test/ && $TEST_CASE
elif [[ "$CASE_DIR" == *"/develop-test/"* ]]; then
cd $TDENGINE_DIR/tests/develop-test/ && $TEST_CASE
fi
else
CASE_FILENAME=$(echo $TEST_CASE | awk -F' ' '{print $3}' | xargs basename)
echo "CASE_FILENAME: $CASE_FILENAME"
CASE_DIR=$(find $TDENGINE_DIR/tests -name $CASE_FILENAME)
echo "CASE_DIR: $CASE_DIR"
cd $TDENGINE_DIR/tests/script/ && $TEST_CASE
fi
elif [ "$TEST_CASE" == "all" ]; then
print_color "$GREEN" "Test case is : parallel_test/longtimeruning_cases.task and all unit cases"
runTest_all
@ -280,12 +409,11 @@ function runTest() {
runPythonCases
elif [ -n "$UNIT_TEST_CASE" ]; then
UNIT_TEST_CASE="$UNIT_TEST_CASE"
cd $TDENGINE_DIR/debug/build/bin/ && $UNIT_TEST_CASE
cd $BUILD_DIR/build/bin/ && $UNIT_TEST_CASE
else
print_color "$GREEN" "Test case is null"
fi
stopTaosd
cd $TDENGINE_DIR/tests/script
find . -name '*.sql' | xargs rm -f
@ -298,13 +426,6 @@ function lcovFunc {
echo "collect data by lcov"
cd $TDENGINE_DIR
if [ -n "$TDENGINE_GCDA_DIR" ]; then
TDENGINE_GCDA_DIR="$TDENGINE_GCDA_DIR"
print_color "$GREEN" "Test gcda file dir: $TDENGINE_GCDA_DIR "
else
print_color "$GREEN" "Test gcda file dir is default: /root/TDinternal/community/debug"
fi
if [ -n "$LCOV_DIR" ]; then
LCOV_DIR="$LCOV_DIR"
print_color "$GREEN" "Lcov bin dir: $LCOV_DIR "
@ -313,7 +434,7 @@ function lcovFunc {
fi
# collect data
$LCOV_DIR/lcov -d "$TDENGINE_GCDA_DIR" -capture --rc lcov_branch_coverage=1 --rc genhtml_branch_coverage=1 --no-external -b $TDENGINE_DIR -o coverage.info
$LCOV_DIR/lcov -d "$CAPTURE_GCDA_DIR" -capture --rc lcov_branch_coverage=1 --rc genhtml_branch_coverage=1 --no-external -b $TDENGINE_DIR -o coverage.info
# remove exclude paths
$LCOV_DIR/lcov --remove coverage.info \
@ -360,10 +481,9 @@ function stopTaosadapter {
}
WORK_DIR=/root
date >> $WORK_DIR/date.log
print_color "$GREEN" "Run local coverage test cases" | tee -a $WORK_DIR/date.log
date >> $TDENGINE_DIR/date.log
print_color "$GREEN" "Run local coverage test cases" | tee -a $TDENGINE_DIR/date.log
stopTaosd
@ -372,13 +492,13 @@ runTest
lcovFunc
date >> $WORK_DIR/date.log
print_color "$GREEN" "End of local coverage test cases" | tee -a $WORK_DIR/date.log
date >> $TDENGINE_DIR/date.log
print_color "$GREEN" "End of local coverage test cases" | tee -a $TDENGINE_DIR/date.log
# Define coverage information files and output directories
COVERAGE_INFO="$TDENGINE_DIR/coverage.info"
OUTPUT_DIR="$WORK_DIR/coverage_report"
OUTPUT_DIR="$TDENGINE_DIR/coverage_report"
# Check whether the coverage information file exists
if [ ! -f "$COVERAGE_INFO" ]; then
@ -398,8 +518,8 @@ $LCOV_DIR/genhtml "$COVERAGE_INFO" --branch-coverage --function-coverage --outp
# Check whether the report was generated successfully
if [ $? -eq 0 ]; then
echo "HTML coverage report generated successfully in $OUTPUT_DIR"
echo "For more details : "
echo "http://192.168.1.61:7000/"
echo "For more details : use 'python3 -m http.server port' in $OUTPUT_DIR"
echo "eg: http://IP:PORT/"
else
echo "Error generating HTML coverage report"
exit 1

View File

@ -7,13 +7,21 @@ unset LD_PRELOAD
UNAME_BIN=`which uname`
OS_TYPE=`$UNAME_BIN`
psby() {
if [ "$OS_TYPE" != "Darwin" ]; then
ps -C $1
else
ps a -c
fi
}
PID=`ps -ef|grep /usr/bin/taosd | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ]; then
echo systemctl stop taosd
systemctl stop taosd
fi
PID=`ps -ef|grep -w taosd | grep -v grep | grep -v taosanode | awk '{print $2}'`
PID=`psby taosd | grep -w "[t]aosd" | awk '{print $1}' | head -n 1`
while [ -n "$PID" ]; do
echo kill -9 $PID
#pkill -9 taosd
@ -24,10 +32,10 @@ while [ -n "$PID" ]; do
else
lsof -nti:6030 | xargs kill -9
fi
PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
PID=`psby taosd | grep -w "[t]aosd" | awk '{print $1}' | head -n 1`
done
PID=`ps -ef|grep -w taos | grep -v grep | grep -v taosanode|awk '{print $2}'`
PID=`psby taos | grep -w "[t]aos" | awk '{print $1}' | head -n 1`
while [ -n "$PID" ]; do
echo kill -9 $PID
#pkill -9 taos
@ -38,10 +46,10 @@ while [ -n "$PID" ]; do
else
lsof -nti:6030 | xargs kill -9
fi
PID=`ps -ef|grep -w taos | grep -v grep |grep -v taosanode| awk '{print $2}'`
PID=`psby taos | grep -w "[t]aos" | awk '{print $1}' | head -n 1`
done
PID=`ps -ef|grep -w tmq_sim | grep -v grep | grep -v taosanode|awk '{print $2}'`
PID=`psby tmq_sim | grep -w "[t]mq_sim" | awk '{print $1}' | head -n 1`
while [ -n "$PID" ]; do
echo kill -9 $PID
#pkill -9 tmq_sim
@ -52,5 +60,5 @@ while [ -n "$PID" ]; do
else
lsof -nti:6030 | xargs kill -9
fi
PID=`ps -ef|grep -w tmq_sim | grep -v grep | grep -v taosanode| awk '{print $2}'`
done
PID=`psby tmq_sim | grep -w "[t]mq_sim" | awk '{print $1}' | head -n 1`
done

View File

@ -43,9 +43,9 @@ CODE_DIR=`pwd`
IN_TDINTERNAL="community"
if [[ "$CODE_DIR" == *"$IN_TDINTERNAL"* ]]; then
cd ../../..
pushd ../../..
else
cd ../../
pushd ../../
fi
TOP_DIR=`pwd`
@ -119,6 +119,8 @@ ulimit -c unlimited
#sudo sysctl -w kernel.core_pattern=$TOP_DIR/core.%p.%e
popd
if [ -n "$FILE_NAME" ]; then
echo "------------------------------------------------------------------------"
if [ $VALGRIND -eq 1 ]; then

View File

@ -146,4 +146,11 @@ sql_error create stream streams2 trigger max_delay 4s ignore update 0 ignore exp
sql create stream streams3 trigger max_delay 5000a ignore update 0 ignore expired 0 into streamtST3 as select _wstart, count(*) from st interval(5s);
sql create stream streams4 trigger max_delay 5s ignore update 0 ignore expired 0 into streamtST4 as select _wstart, count(*) from st interval(5s);
sql_error create stream streams5 trigger at_once ignore update 0 ignore expired 0 into streamtST5 as select _wstart, count(*) from st interval(5s) having count(*) > 2;
sql_error create stream streams6 trigger at_once ignore update 0 ignore expired 0 into streamtST6 as select _wstart, count(*) from st session(ts, 5s) having count(*) > 2;
sql_error create stream streams7 trigger at_once ignore update 0 ignore expired 1 into streamtST7 as select _wstart, count(*) from st count_window(10) having count(*) > 2;
sql_error create stream streams8 trigger at_once ignore update 0 ignore expired 0 into streamtST8 as select _wstart, count(*) from st state_window(a) having count(*) > 2;
sql_error create stream streams9 trigger at_once ignore update 0 ignore expired 0 into streamtST9 as select _wstart, count(*) from st event_window start with a = 0 end with b = 9 having count(*) > 2;
system sh/exec.sh -n dnode1 -s stop -x SIGINT

View File

@ -236,3 +236,28 @@ sql drop view view6;
sql drop view view7;
sql drop view view8;
sql use testb;
sql create view viewx1 as select ts, t from (select last(ts) as ts, last(f) as f, t from st3 partition by t order by ts desc);
sql create view viewx2 as select ts, t from (select last(dt) as ts, last(f) as f, t from st3 partition by t order by ts desc);
sql create view viewx3 as select ts1, t from (select last(ts) as ts1, last(f) as f, t from st3 partition by t order by ts1 desc);
sql create view viewx4 as select f, t from (select last(ts) as f, last(g) as g, t from st3 partition by t order by f desc);
sql select * from viewx1;
if $rows != 4 then
return -1
endi
sql select * from viewx2;
if $rows != 4 then
return -1
endi
sql select * from viewx3;
if $rows != 4 then
return -1
endi
sql select * from viewx4;
if $rows != 4 then
return -1
endi
sql drop view viewx1;
sql drop view viewx2;
sql drop view viewx3;
sql drop view viewx4;

View File

@ -40,6 +40,12 @@ sql insert into ctb22 using st2 tags(2) values('2023-10-16 09:10:12', 110222, 11
sql insert into ctb23 using st2 tags(3) values('2023-10-16 09:10:13', 110223, 1102230);
sql insert into ctb24 using st2 tags(4) values('2023-10-16 09:10:14', 110224, 1102240);
sql create table st3(dt timestamp, ts timestamp, f int, g int) tags (t int);
sql insert into ctb31 using st3 tags(1) values('2023-10-16 09:10:11', 0, 110221, 1102210);
sql insert into ctb32 using st3 tags(2) values('2023-10-16 09:10:12', 1, 110222, 1102220);
sql insert into ctb33 using st3 tags(3) values('2023-10-16 09:10:13', 2, 110223, 1102230);
sql insert into ctb34 using st3 tags(4) values('2023-10-16 09:10:14', 3, 110224, 1102240);
run tsim/view/privilege_basic_view.sim
run tsim/view/privilege_nested_view.sim
run tsim/view/create_drop_view.sim
@ -63,4 +69,14 @@ run tsim/view/stream_view.sim
run tsim/view/show_desc_view.sim
run tsim/view/same_name_tb_view.sim
sql alter local 'keepColumnName' '1'
run tsim/view/privilege_basic_view.sim
run tsim/view/privilege_nested_view.sim
run tsim/view/create_drop_view.sim
run tsim/view/query_view.sim
run tsim/view/insert_view.sim
run tsim/view/stream_view.sim
run tsim/view/show_desc_view.sim
run tsim/view/same_name_tb_view.sim
system sh/exec.sh -n dnode1 -s stop -x SIGINT

View File

@ -0,0 +1,95 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import random
import string
from numpy import logspace
from util import constant
from util.log import *
from util.cases import *
from util.sql import *
from util.common import *
from util.sqlset import TDSetSql
sysdb_tables = {
"information_schema": ["ins_dnodes", "ins_mnodes", "ins_modules", "ins_qnodes", "ins_snodes", "ins_cluster", "ins_databases", "ins_functions", "ins_indexes", "ins_stables", "ins_tables", "ins_tags", "ins_columns", "ins_users", "ins_grants", "ins_vgroups", "ins_configs", "ins_dnode_variables", "ins_topics", "ins_subscriptions", "ins_streams", "ins_streams_tasks", "ins_vnodes", "ins_user_privileges", "undefined"],
"performance_schema": ["perf_connections", "perf_queries", "perf_consumers", "perf_trans", "perf_apps", "undefined"]
}
class TDTestCase:
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor())
def ddl_sysdb(self):
for db, _ in sysdb_tables.items():
tdSql.error(f'create database {db}', expectErrInfo="Cannot create system database", fullMatched=False)
tdSql.error(f'create database {db} vgroups 10', expectErrInfo="Cannot create system database", fullMatched=False)
tdSql.error(f'alter database {db} wal_level 0', expectErrInfo="Cannot alter system database", fullMatched=False)
tdSql.error(f'alter database {db} cachemodel \'none\'', expectErrInfo="Cannot alter system database", fullMatched=False)
tdSql.error(f'drop database {db}', expectErrInfo="Cannot drop system database", fullMatched=False)
tdSql.error(f'drop database {db}', expectErrInfo="Cannot drop system database", fullMatched=False)
def ddl_systb(self):
tdSql.execute('drop database if exists d0')
tdSql.execute('create database if not exists d0')
tdSql.execute('create stable d0.stb0 (ts timestamp, c0 int) tags(t0 int)')
for db, tbs in sysdb_tables.items():
tdSql.execute(f'use {db}')
for tb in tbs:
tdSql.error(f'create table {tb} (ts timestamp, c0 int)', expectErrInfo="Cannot create table of system database", fullMatched=False)
tdSql.error(f'create table d0.ctb0 using db.stb0 tags(0) {tb} using {tb} tags(1)', expectErrInfo="Corresponding super table not in this db", fullMatched=False)
tdSql.error(f'create table {db}.{tb} (ts timestamp, c0 int)', expectErrInfo="Cannot create table of system database", fullMatched=False)
tdSql.error(f'create table d0.ctb0 using db.stb0 tags(0) {db}.{tb} using {db}.{tb} tags(1)', expectErrInfo="Corresponding super table not in this db", fullMatched=False)
tdSql.error(f'create stable {tb} (ts timestamp, c0 int) tags(t0 int)', expectErrInfo="Cannot create table of system database", fullMatched=False)
tdSql.error(f'create stable {db}.{tb} (ts timestamp, c0 int) tags(t0 int)', expectErrInfo="Cannot create table of system database", fullMatched=False)
tdSql.error(f'alter table {tb} add column c1 int', expectErrInfo="Cannot alter table of system database", fullMatched=False)
tdSql.error(f'alter table {db}.{tb} add column c1 int', expectErrInfo="Cannot alter table of system database", fullMatched=False)
tdSql.error(f'alter stable {tb} add column c1 int', expectErrInfo="Cannot alter table of system database", fullMatched=False)
tdSql.error(f'alter stable {db}.{tb} add column c1 int', expectErrInfo="Cannot alter table of system database", fullMatched=False)
tdSql.error(f'insert into {tb} values (now,1)', expectErrInfo="System table not allowed", fullMatched=False)
tdSql.error(f'insert into {db}.{tb} values (now,1)', expectErrInfo="System table not allowed", fullMatched=False)
tdSql.error(f'insert into {tb} values (now,1) using stb tags(0) values(now,1)', expectErrInfo="System table not allowed", fullMatched=False)
tdSql.error(f'insert into {db}.{tb} values (now,1) using stb tags(0) values(now,1)', expectErrInfo="System table not allowed", fullMatched=False)
tdSql.error(f'delete from {tb}', expectErrInfo="Cannot delete from system database", fullMatched=False)
tdSql.error(f'delete from {db}.{tb}', expectErrInfo="Cannot delete from system database", fullMatched=False)
tdSql.error(f'delete from {tb} where ts >= 0', expectErrInfo="Cannot delete from system database", fullMatched=False)
tdSql.error(f'delete from {db}.{tb} where ts >= 0', expectErrInfo="Cannot delete from system database", fullMatched=False)
tdSql.error(f'drop table {tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop table {db}.{tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop stable {tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop stable {db}.{tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop table with {tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop table with {db}.{tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop stable with {tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.error(f'drop stable with {db}.{tb}', expectErrInfo="Cannot drop table of system database", fullMatched=False)
tdSql.execute('drop database if exists d0')
def ddl_in_sysdb(self):
self.ddl_sysdb()
self.ddl_systb()
def run(self):
self.ddl_in_sysdb()
tdDnodes.stoptaosd(1)
tdDnodes.starttaosd(1)
self.ddl_in_sysdb()
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -1,111 +0,0 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import random
import string
from numpy import logspace
from util import constant
from util.log import *
from util.cases import *
from util.sql import *
from util.common import *
from util.sqlset import TDSetSql
info_schema_db = "information_schema"
perf_schema_db = "performance_schema"
info_schema_tables = [
"ins_dnodes",
"ins_mnodes",
"ins_modules",
"ins_qnodes",
"ins_snodes",
"ins_cluster",
"ins_databases",
"ins_functions",
"ins_indexes",
"ins_stables",
"ins_tables",
"ins_tags",
"ins_columns",
"ins_users",
"ins_grants",
"ins_vgroups",
"ins_configs",
"ins_dnode_variables",
"ins_topics",
"ins_subscriptions",
"ins_streams",
"ins_streams_tasks",
"ins_vnodes",
"ins_user_privileges"
]
perf_schema_tables = [
"perf_connections",
"perf_queries",
"perf_consumers",
"perf_trans",
"perf_apps"
]
class TDTestCase:
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor())
def delete_systb(self):
tdSql.execute(f'use {info_schema_db}')
for i in info_schema_tables:
tdSql.error(f'delete from {i}')
tdSql.error(f'delete from {info_schema_db}.{i}')
tdSql.error(f'delete from {i} where ts >= 0')
tdSql.error(f'delete from {info_schema_db}.{i} where ts >= 0')
tdSql.execute(f'use {perf_schema_db}')
for i in perf_schema_tables:
tdSql.error(f'delete from {i}')
tdSql.error(f'delete from {perf_schema_db}.{i}')
tdSql.error(f'delete from {i} where ts >= 0')
tdSql.error(f'delete from {perf_schema_db}.{i} where ts >= 0')
def drop_systb(self):
tdSql.execute(f'use {info_schema_db}')
for i in info_schema_tables:
tdSql.error(f'drop table {i}')
tdSql.error(f'drop {info_schema_db}.{i}')
tdSql.error(f'drop database {info_schema_db}')
tdSql.execute(f'use {perf_schema_db}')
for i in perf_schema_tables:
tdSql.error(f'drop table {i}')
tdSql.error(f'drop table {perf_schema_db}.{i}')
tdSql.error(f'drop database {perf_schema_db}')
def delete_from_systb(self):
self.delete_systb()
self.drop_systb()
def run(self):
self.delete_from_systb()
tdDnodes.stoptaosd(1)
tdDnodes.starttaosd(1)
self.delete_from_systb()
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -353,6 +353,13 @@ class TDTestCase:
tdSql.checkData(0, 2, -999)
tdSql.checkData(0, 3, None)
tdSql.checkData(0, 4,-9.99000)
tdSql.query(f"select last_row(c1), c2, c3 , c4, c5 from (select * from {dbname}.ct1)")
tdSql.checkData(0, 0, 9)
tdSql.checkData(0, 1, -99999)
tdSql.checkData(0, 2, -999)
tdSql.checkData(0, 3, None)
tdSql.checkData(0, 4,-9.99000)
# bug need fix
tdSql.query(f"select last_row(c1), c2, c3 , c4, c5 from {dbname}.stb1 where tbname='ct1'")
@ -477,6 +484,11 @@ class TDTestCase:
tdSql.checkData(0,1,33333)
tdSql.checkData(0,2,333)
tdSql.checkData(0,3,3)
tdSql.query(f"select last_row(abs(floor(t1)) ,t2 ,ceil(abs(t3)) , abs(ceil(t4)) ) from (select * from {dbname}.stb1)")
tdSql.checkData(0,0,3)
tdSql.checkData(0,1,33333)
tdSql.checkData(0,2,333)
tdSql.checkData(0,3,3)
# filter by tag
tdSql.query(f"select tbname ,last_row(c1) from {dbname}.stb1 where t1 =0 ")
@ -912,6 +924,70 @@ class TDTestCase:
tdSql.checkData(0 , 1 , None)
tdSql.checkData(0 , 2 , None)
def lastrow_in_subquery(self, dbname="db"):
tdSql.execute(f'create database if not exists {dbname};')
tdSql.execute(f'use {dbname}')
tdSql.execute(f'drop table if exists {dbname}.meters')
tdSql.execute(f'create table {dbname}.meters (ts timestamp, c0 int, c1 float, c2 nchar(30), c3 bool) tags (t1 nchar(30))')
tdSql.execute(f'create table {dbname}.d0 using {dbname}.meters tags("st1")')
tdSql.execute(f'create table {dbname}.d1 using {dbname}.meters tags("st2")')
tdSql.execute(f'insert into {dbname}.d0 values(1734574929000, 1, 1, "c2", true)')
tdSql.execute(f'insert into {dbname}.d0 values(1734574929001, 2, 2, "bbbbbbbbb1", false)')
tdSql.execute(f'insert into {dbname}.d0 values(1734574929002, 2, 2, "bbbbbbbbb1", false)')
tdSql.execute(f'insert into {dbname}.d0 values(1734574929003, 3, 3, "a2", true)')
tdSql.execute(f'insert into {dbname}.d0 values(1734574929004, 4, 4, "bbbbbbbbb2", false)')
tdSql.execute(f'insert into {dbname}.d1 values(1734574929000, 1, 1, "c2", true)')
tdSql.execute(f'use {dbname}')
tdSql.execute(f'Create table {dbname}.normal_table (ts timestamp, c0 int, c1 float, c2 nchar(30), c3 bool)')
tdSql.execute(f'insert into {dbname}.normal_table (select * from {dbname}.d0)')
tdSql.query(f'select count(1), last(ts), last_row(c0) from (select * from {dbname}.meters)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select count(1), last(ts), last_row(c0) from (select * from {dbname}.meters order by ts desc)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select count(1), last(ts), last_row(c0) from (select * from {dbname}.meters order by ts asc)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select count(1), last(ts), last_row(c0) from (select * from {dbname}.meters order by c0 asc)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select count(1), last_row(ts), last_row(c0) from (select * from {dbname}.meters)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 6)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select tbname, last_row(ts), last_row(c0) from (select *, tbname from {dbname}.meters) group by tbname order by tbname')
tdSql.checkRows(2)
tdSql.checkData(0, 0, 'd0')
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.checkData(1, 0, 'd1')
tdSql.checkData(1, 1, 1734574929000)
tdSql.checkData(1, 2, 1)
tdSql.query(f'select count(1), last_row(ts), last_row(c0) from (select * from {dbname}.d0)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 5)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
tdSql.query(f'select count(1), last_row(ts), last_row(c0) from (select * from {dbname}.normal_table)')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 5)
tdSql.checkData(0, 1, 1734574929004)
tdSql.checkData(0, 2, 4)
def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring
# tdSql.prepare()
@ -944,6 +1020,8 @@ class TDTestCase:
self.basic_query()
self.lastRowDelayTest("DELAYTEST")
self.lastrow_in_subquery("db1")
def stop(self):

View File

@ -0,0 +1,54 @@
import taos
import sys
import time
import socket
import os
import threading
from util.log import *
from util.sql import *
from util.cases import *
from util.dnodes import *
from util.common import *
from taos.tmq import *
sys.path.append("./7-tmq")
from tmqCommon import *
class TDTestCase:
updatecfgDict = {'debugFlag': 135, 'asynclog': 0}
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor())
#tdSql.init(conn.cursor(), logSql) # output sql.txt file
def run(self):
tdSql.execute(f'create database if not exists db_32471')
tdSql.execute(f'use db_32471')
tdSql.execute(f'CREATE STABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)')
tdSql.execute("INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-05 14:38:05.000',10.30000,219,0.31000)")
buildPath = tdCom.getBuildPath()
cmdStr = '%s/build/bin/tmq_td32471'%(buildPath)
# tdLog.info(cmdStr)
# os.system(cmdStr)
#
# tdSql.execute("drop topic db_32471_topic")
tdSql.execute(f'alter stable meters add column item_tags nchar(500)')
tdSql.execute(f'alter stable meters add column new_col nchar(100)')
tdSql.execute("create topic db_32471_topic as select * from db_32471.meters")
tdSql.execute("INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-06 14:38:05.000',10.30000,219,0.31000, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '1')")
tdLog.info(cmdStr)
if os.system(cmdStr) != 0:
tdLog.exit(cmdStr)
return
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())

View File

@ -562,7 +562,7 @@ python3 ./test.py -f 1-insert/update_data.py
python3 ./test.py -f 1-insert/tb_100w_data_order.py
python3 ./test.py -f 1-insert/delete_childtable.py
python3 ./test.py -f 1-insert/delete_normaltable.py
python3 ./test.py -f 1-insert/delete_systable.py
python3 ./test.py -f 1-insert/ddl_in_sysdb.py
python3 ./test.py -f 1-insert/keep_expired.py
python3 ./test.py -f 1-insert/stmt_error.py
python3 ./test.py -f 1-insert/drop.py

View File

@ -43,7 +43,7 @@ void shellAutoExit();
void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb);
// introduction
void printfIntroduction(bool community);
void printfIntroduction(EVersionType type);
// show enterprise AD at start or end
void showAD(bool end);

View File

@ -453,7 +453,7 @@ SMatch* lastMatch = NULL; // save last match result
int cntDel = 0; // delete byte count after next press tab
// show auto tab introduction
void printfIntroduction(bool community) {
void printfIntroduction(EVersionType type) {
printf(" ********************************* Tab Completion *************************************\n");
char secondLine[160] = "\0";
sprintf(secondLine, " * The %s CLI supports tab completion for a variety of items, ", shell.info.cusName);
@ -473,11 +473,11 @@ void printfIntroduction(bool community) {
printf(" * [ Ctrl + L ] ...... clear the entire screen *\n");
printf(" * [ Ctrl + K ] ...... clear the screen after the cursor *\n");
printf(" * [ Ctrl + U ] ...... clear the screen before the cursor *\n");
if(community) {
printf(" * ------------------------------------------------------------------------------------ *\n");
printf(" * You are using TDengine OSS. To experience advanced features, like backup/restore, *\n");
printf(" * privilege control and more, or receive 7x24 technical support, try TDengine *\n");
printf(" * Enterprise or TDengine Cloud. Learn more at https://tdengine.com *\n");
if (type == TSDB_VERSION_OSS) {
printf(" * ------------------------------------------------------------------------------------ *\n");
printf(" * You are using TDengine OSS. To experience advanced features, like backup/restore, *\n");
printf(" * privilege control and more, or receive 7x24 technical support, try TDengine *\n");
printf(" * Enterprise or TDengine Cloud. Learn more at https://tdengine.com *\n");
}
printf(" ****************************************************************************************\n\n");
}

View File

@ -58,7 +58,7 @@ static void shellWriteHistory();
static void shellPrintError(TAOS_RES *tres, int64_t st);
static bool shellIsCommentLine(char *line);
static void shellSourceFile(const char *file);
static bool shellGetGrantInfo(char* buf);
static int32_t shellGetGrantInfo(char* buf);
static void shellCleanup(void *arg);
static void *shellCancelHandler(void *arg);
@ -1163,9 +1163,9 @@ void shellSourceFile(const char *file) {
taosCloseFile(&pFile);
}
bool shellGetGrantInfo(char *buf) {
bool community = true;
char sinfo[256] = {0};
int32_t shellGetGrantInfo(char *buf) {
int32_t verType = TSDB_VERSION_UNKNOWN;
char sinfo[256] = {0};
tstrncpy(sinfo, taos_get_server_info(shell.conn), sizeof(sinfo));
strtok(sinfo, "\r\n");
@ -1180,7 +1180,7 @@ bool shellGetGrantInfo(char *buf) {
fprintf(stderr, "Failed to check Server Edition, Reason:0x%04x:%s\r\n\r\n", code, taos_errstr(tres));
}
taos_free_result(tres);
return community;
return verType;
}
int32_t num_fields = taos_field_count(tres);
@ -1208,12 +1208,12 @@ bool shellGetGrantInfo(char *buf) {
memcpy(expired, row[2], fields[2].bytes);
if (strcmp(serverVersion, "community") == 0) {
community = true;
verType = TSDB_VERSION_OSS;
} else if (strcmp(expiretime, "unlimited") == 0) {
community = false;
verType = TSDB_VERSION_ENTERPRISE;
sprintf(buf, "Server is %s, %s and will never expire.\r\n", serverVersion, sinfo);
} else {
community = false;
verType = TSDB_VERSION_ENTERPRISE;
sprintf(buf, "Server is %s, %s and will expire at %s.\r\n", serverVersion, sinfo, expiretime);
}
@ -1221,7 +1221,7 @@ bool shellGetGrantInfo(char *buf) {
}
fprintf(stdout, "\r\n");
return community;
return verType;
}
#ifdef WINDOWS
@ -1381,22 +1381,21 @@ int32_t shellExecute() {
#ifdef WEBSOCKET
if (!shell.args.restful && !shell.args.cloud) {
#endif
char *buf = taosMemoryMalloc(512);
bool community = shellGetGrantInfo(buf);
char buf[512] = {0};
int32_t verType = shellGetGrantInfo(buf);
#ifndef WINDOWS
printfIntroduction(community);
printfIntroduction(verType);
#else
#ifndef WEBSOCKET
if (community) {
if (verType == TSDB_VERSION_OSS) {
showAD(false);
}
#endif
#endif
// printf version
if (!community) {
if (verType == TSDB_VERSION_ENTERPRISE || verType == TSDB_VERSION_CLOUD) {
printf("%s\n", buf);
}
taosMemoryFree(buf);
#ifdef WEBSOCKET
}
@ -1412,7 +1411,7 @@ int32_t shellExecute() {
}
#ifndef WEBSOCKET
// commnuity
if (community) {
if (verType == TSDB_VERSION_OSS) {
showAD(true);
}
#endif

Some files were not shown because too many files have changed in this diff Show More