diff --git a/Jenkinsfile2 b/Jenkinsfile2
index 249a8d1c9d..6fa3483099 100644
--- a/Jenkinsfile2
+++ b/Jenkinsfile2
@@ -78,7 +78,7 @@ def check_docs(){
file_only_tdgpt_change_except = sh (
script: '''
cd ${WKC}
- git --no-pager diff --name-only FETCH_HEAD `git merge-base FETCH_HEAD ${CHANGE_TARGET}`|grep -v "^docs/en/"|grep -v "^docs/zh/"|grep -v ".md$" | grep -v "forecastoperator.c\\|anomalywindowoperator.c" |grep -v "tsim/analytics" |grep -v "tdgpt_cases.task" || :
+ git --no-pager diff --name-only FETCH_HEAD `git merge-base FETCH_HEAD ${CHANGE_TARGET}`|grep -v "^docs/en/"|grep -v "^docs/zh/"|grep -v ".md$" | grep -v "forecastoperator.c\\|anomalywindowoperator.c\\|tanalytics.h\\|tanalytics.c" |grep -v "tsim/analytics" |grep -v "tdgpt_cases.task" || :
''',
returnStdout: true
).trim()
diff --git a/README.md b/README.md
index 030be7bc3b..f827c38975 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,6 @@
-[](https://cloud.drone.io/taosdata/TDengine)
-[](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
[](https://coveralls.io/github/taosdata/TDengine?branch=3.0)
[](https://bestpractices.coreinfrastructure.org/projects/4201)
diff --git a/cmake/taosadapter_CMakeLists.txt.in b/cmake/taosadapter_CMakeLists.txt.in
index ef6ed4af1d..13826a1a74 100644
--- a/cmake/taosadapter_CMakeLists.txt.in
+++ b/cmake/taosadapter_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taosadapter
ExternalProject_Add(taosadapter
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
- GIT_TAG 3.0
+ GIT_TAG main
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/cmake/taostools_CMakeLists.txt.in b/cmake/taostools_CMakeLists.txt.in
index 9a6a5329ae..9bbda8309f 100644
--- a/cmake/taostools_CMakeLists.txt.in
+++ b/cmake/taostools_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taos-tools
ExternalProject_Add(taos-tools
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
- GIT_TAG 3.0
+ GIT_TAG main
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/cmake/taosws_CMakeLists.txt.in b/cmake/taosws_CMakeLists.txt.in
index 17446d184d..b013d45911 100644
--- a/cmake/taosws_CMakeLists.txt.in
+++ b/cmake/taosws_CMakeLists.txt.in
@@ -2,7 +2,7 @@
# taosws-rs
ExternalProject_Add(taosws-rs
GIT_REPOSITORY https://github.com/taosdata/taos-connector-rust.git
- GIT_TAG 3.0
+ GIT_TAG main
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosws-rs"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE
diff --git a/docs/en/10-third-party/03-visual/01-grafana.md b/docs/en/10-third-party/03-visual/01-grafana.md
index ec857f7795..8a503b4195 100644
--- a/docs/en/10-third-party/03-visual/01-grafana.md
+++ b/docs/en/10-third-party/03-visual/01-grafana.md
@@ -22,15 +22,11 @@ import imgStep11 from '../../assets/grafana-11.png';
This document describes how to integrate the TDengine data source with the open-source data visualization system [Grafana](https://www.grafana.com/) to achieve data visualization and build a monitoring and alert system. With the TDengine plugin, you can easily display data from TDengine tables on Grafana dashboards without the need for complex development work.
-## Grafana Version Requirements
-
-TDengine currently supports Grafana version 7.5 and above. It is recommended to use the latest version. Please download and install the corresponding version of Grafana according to your system environment.
-
## Prerequisites
To add the TDengine data source to Grafana normally, the following preparations are needed.
-- Grafana service has been deployed and is running normally.
+- Grafana service has been deployed and is running normally. TDengine currently supports Grafana version 7.5 and above. It is recommended to use the latest version.
**Note**: Ensure that the account starting Grafana has write permissions to its installation directory, otherwise you may not be able to install plugins later.
- TDengine cluster has been deployed and is running normally.
- taosAdapter has been installed and is running normally. For details, please refer to the [taosAdapter user manual](../../../tdengine-reference/components/taosadapter/)
diff --git a/docs/en/10-third-party/05-bi/09-seeq.md b/docs/en/10-third-party/05-bi/09-seeq.md
index c8f7462a19..7fb7569461 100644
--- a/docs/en/10-third-party/05-bi/09-seeq.md
+++ b/docs/en/10-third-party/05-bi/09-seeq.md
@@ -13,13 +13,11 @@ Seeq is advanced analytics software for the manufacturing and Industrial Interne
Through the TDengine Java connector, Seeq can easily support querying time-series data provided by TDengine and offer data presentation, analysis, prediction, and other functions.
-## Seeq Installation Method
+## Prerequisites
-Download the relevant software from [Seeq's official website](https://www.seeq.com/customer-download), such as Seeq Server and Seeq Data Lab, etc. Seeq Data Lab needs to be installed on a different server from Seeq Server and interconnected through configuration. For detailed installation and configuration instructions, refer to the [Seeq Knowledge Base](https://support.seeq.com/kb/latest/cloud/).
+- Seeq has been installed. Download the relevant software from [Seeq's official website](https://www.seeq.com/customer-download), such as Seeq Server and Seeq Data Lab, etc. Seeq Data Lab needs to be installed on a different server from Seeq Server and interconnected through configuration. For detailed installation and configuration instructions, refer to the [Seeq Knowledge Base](https://support.seeq.com/kb/latest/cloud/).
-### TDengine Local Instance Installation Method
-
-Please refer to the [official documentation](../../../get-started).
+- TDengine local instance has been installed. Please refer to the [official documentation](../../../get-started). If using TDengine Cloud, please go to https://cloud.taosdata.com apply for an account and log in to see how to access TDengine Cloud.
## Configuring Seeq to Access TDengine
diff --git a/docs/en/10-third-party/05-bi/11-superset.md b/docs/en/10-third-party/05-bi/11-superset.md
index aa56648b99..be3e3aa08d 100644
--- a/docs/en/10-third-party/05-bi/11-superset.md
+++ b/docs/en/10-third-party/05-bi/11-superset.md
@@ -9,14 +9,13 @@ Apache Superset provides an intuitive user interface that makes creating, sharin
Through the Python connector of TDengine, Superset can support TDengine data sources and provide functions such as data presentation and analysis
-## Install Apache Superset
-
-Ensure that Apache Superset v2.1.0 or above is installed. If not, please visit [official website](https://superset.apache.org/) to install
-
-## Install TDengine
-
-Both TDengine Enterprise Edition and Community Edition are supported, with version requirements of 3.0 or higher
+## Prerequisites
+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)
+- 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.
diff --git a/docs/en/14-reference/01-components/05-taosx-agent.md b/docs/en/14-reference/01-components/05-taosx-agent.md
index 3e8b4f4d63..d7d86a64cb 100644
--- a/docs/en/14-reference/01-components/05-taosx-agent.md
+++ b/docs/en/14-reference/01-components/05-taosx-agent.md
@@ -14,6 +14,7 @@ The default configuration file for `Agent` is located at `/etc/taos/agent.toml`,
- `token`: Required, the Token generated when creating `Agent` in `Explorer`.
- `instanceId`: The instance ID of the current taosx-agent service. If multiple taosx-agent instances are started on the same machine, it is necessary to ensure that the instance IDs of each instance are unique.
- `compression`: Optional, can be configured as `true` or `false`, default is `false`. If set to `true`, it enables data compression in communication between `Agent` and `taosX`.
+- `in_memory_cache_capacity`: Optional, signifies the maximum number of message batches that can be cached in memory and can be configured as a positive integer greater than zero. The default value is set at 64.
- `log_level`: Optional, log level, default is `info`. Like `taosX`, it supports five levels: `error`, `warn`, `info`, `debug`, `trace`. Deprecated, please use `log.level` instead.
- `log_keep_days`: Optional, the number of days to keep logs, default is `30` days. Deprecated, please use `log.keepDays` instead.
- `log.path`: The directory where log files are stored.
@@ -45,6 +46,10 @@ As shown below:
#
#compression = true
+# In-memory cache capacity
+#
+#in_memory_cache_capacity = 64
+
# log configuration
[log]
# All log files are stored in this directory
diff --git a/docs/en/14-reference/02-tools/09-taosdump.md b/docs/en/14-reference/02-tools/09-taosdump.md
index d336f66c02..75747f2f57 100644
--- a/docs/en/14-reference/02-tools/09-taosdump.md
+++ b/docs/en/14-reference/02-tools/09-taosdump.md
@@ -4,22 +4,17 @@ sidebar_label: taosdump
slug: /tdengine-reference/tools/taosdump
---
-taosdump is a tool application that supports backing up data from a running TDengine cluster and restoring the backed-up data to the same or another running TDengine cluster.
-
-taosdump can back up data using databases, supertables, or basic tables as logical data units, and can also back up data records within a specified time period from databases, supertables, and basic tables. You can specify the directory path for data backup; if not specified, taosdump defaults to backing up data to the current directory.
-
-If the specified location already has data files, taosdump will prompt the user and exit immediately to avoid data being overwritten. This means the same path can only be used for one backup.
-If you see related prompts, please operate carefully.
-
-taosdump is a logical backup tool, it should not be used to back up any raw data, environment settings, hardware information, server configuration, or cluster topology. taosdump uses [Apache AVRO](https://avro.apache.org/) as the data file format to store backup data.
+`taosdump` is a TDengine data backup/recovery tool provided for open source users, and the backed up data files adopt the standard [Apache AVRO](https://avro.apache.org/)
+ Format, convenient for exchanging data with the external ecosystem.
+ Taosdump provides multiple data backup and recovery options to meet different data needs, and all supported options can be viewed through --help.
## Installation
-There are two ways to install taosdump:
+Taosdump provides two installation methods:
-- Install the official taosTools package, please find taosTools on the [release history page](../../../release-history/taostools/) and download it for installation.
+- Taosdump is the default installation component in the TDengine installation package, which can be used after installing TDengine. For how to install TDengine, please refer to [TDengine Installation](../../../get-started/)
-- Compile taos-tools separately and install, please refer to the [taos-tools](https://github.com/taosdata/taos-tools) repository for details.
+- Compile and install taos tools separately, refer to [taos tools](https://github.com/taosdata/taos-tools) .
## Common Use Cases
@@ -30,6 +25,9 @@ There are two ways to install taosdump:
3. Backup certain supertables or basic tables in a specified database: use the `dbname stbname1 stbname2 tbname1 tbname2 ...` parameter, note that this input sequence starts with the database name, supports only one database, and the second and subsequent parameters are the names of the supertables or basic tables in that database, separated by spaces;
4. Backup the system log database: TDengine clusters usually include a system database named `log`, which contains data for TDengine's own operation, taosdump does not back up the log database by default. If there is a specific need to back up the log database, you can use the `-a` or `--allow-sys` command line parameter.
5. "Tolerant" mode backup: Versions after taosdump 1.4.1 provide the `-n` and `-L` parameters, used for backing up data without using escape characters and in "tolerant" mode, which can reduce backup data time and space occupied when table names, column names, and label names do not use escape characters. If unsure whether to use `-n` and `-L`, use the default parameters for "strict" mode backup. For an explanation of escape characters, please refer to the [official documentation](../../sql-manual/escape-characters/).
+6. If a backup file already exists in the directory specified by the `-o` parameter, to prevent data from being overwritten, taosdump will report an error and exit. Please replace it with another empty directory or clear the original data before backing up.
+7. Currently, taosdump does not support data breakpoint backup function. Once the data backup is interrupted, it needs to be started from scratch.
+ If the backup takes a long time, it is recommended to use the (-S -E options) method to specify the start/end time for segmented backup.
:::tip
@@ -42,7 +40,8 @@ There are two ways to install taosdump:
### taosdump Restore Data
-Restore data files from a specified path: use the `-i` parameter along with the data file path. As mentioned earlier, the same directory should not be used to back up different data sets, nor should the same path be used to back up the same data set multiple times, otherwise, the backup data will cause overwriting or multiple backups.
+- Restore data files from a specified path: use the `-i` parameter along with the data file path. As mentioned earlier, the same directory should not be used to back up different data sets, nor should the same path be used to back up the same data set multiple times, otherwise, the backup data will cause overwriting or multiple backups.
+- taosdump supports data recovery to a new database name with the parameter `-W`, please refer to the command line parameter description for details.
:::tip
taosdump internally uses the TDengine stmt binding API to write restored data, currently using 16384 as a batch for writing. If there are many columns in the backup data, it may cause a "WAL size exceeds limit" error, in which case you can try adjusting the `-B` parameter to a smaller value.
@@ -105,6 +104,13 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
the table name.(Version 2.5.3)
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
8.
+ -W, --rename=RENAME-LIST Rename database name with new name during
+ importing data. RENAME-LIST:
+ "db1=newDB1|db2=newDB2" means rename db1 to newDB1
+ and rename db2 to newDB2 (Version 2.5.4)
+ -k, --retry-count=VALUE Set the number of retry attempts for connection or
+ query failures
+ -z, --retry-sleep-ms=VALUE retry interval sleep time, unit ms
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
-R, --restful Use RESTful interface to connect TDengine
-t, --timeout=SECONDS The timeout seconds for websocket to interact.
@@ -112,10 +118,6 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
-?, --help Give this help list
--usage Give a short usage message
-V, --version Print program version
- -W, --rename=RENAME-LIST Rename database name with new name during
- importing data. RENAME-LIST:
- "db1=newDB1|db2=newDB2" means rename db1 to newDB1
- and rename db2 to newDB2 (Version 2.5.4)
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
diff --git a/docs/en/14-reference/02-tools/10-taosbenchmark.md b/docs/en/14-reference/02-tools/10-taosbenchmark.md
index 09227f210b..d1a18b5d1c 100644
--- a/docs/en/14-reference/02-tools/10-taosbenchmark.md
+++ b/docs/en/14-reference/02-tools/10-taosbenchmark.md
@@ -4,35 +4,38 @@ sidebar_label: taosBenchmark
slug: /tdengine-reference/tools/taosbenchmark
---
-taosBenchmark (formerly known as taosdemo) is a tool for testing the performance of the TDengine product. taosBenchmark can test the performance of TDengine's insert, query, and subscription functions. It can simulate massive data generated by a large number of devices and flexibly control the number of databases, supertables, types and number of tag columns, types and number of data columns, number of subtables, data volume per subtable, data insertion interval, number of working threads in taosBenchmark, whether and how to insert out-of-order data, etc. To accommodate the usage habits of past users, the installation package provides taosdemo as a soft link to taosBenchmark.
+TaosBenchmark is a performance benchmarking tool for TDengine products, providing insertion, query, and subscription performance testing for TDengine products, and outputting performance indicators.
## Installation
-There are two ways to install taosBenchmark:
+taosBenchmark provides two installation methods:
-- taosBenchmark is automatically installed with the official TDengine installation package, for details please refer to [TDengine Installation](../../../get-started/).
+- taosBenchmark is the default installation component in the TDengine installation package, which can be used after installing TDengine. For how to install TDengine, please refer to [TDengine Installation](../../../get started/)
-- Compile and install taos-tools separately, for details please refer to the [taos-tools](https://github.com/taosdata/taos-tools) repository.
+- Compile and install taos tools separately, refer to [taos tools](https://github.com/taosdata/taos-tools) .
## Operation
### Configuration and Operation Methods
-taosBenchmark needs to be executed in the operating system's terminal, and this tool supports two configuration methods: Command Line Arguments and JSON Configuration File. These two methods are mutually exclusive; when using a configuration file, only one command line argument `-f ` can be used to specify the configuration file. When using command line arguments to run taosBenchmark and control its behavior, the `-f` parameter cannot be used; instead, other parameters must be used for configuration. In addition, taosBenchmark also offers a special mode of operation, which is running without any parameters.
-
-taosBenchmark supports comprehensive performance testing for TDengine, and the TDengine features it supports are divided into three categories: writing, querying, and subscribing. These three functions are mutually exclusive, and each run of taosBenchmark can only select one of them. It is important to note that the type of function to be tested is not configurable when using the command line configuration method; the command line configuration method can only test writing performance. To test TDengine's query and subscription performance, you must use the configuration file method and specify the type of function to be tested through the `filetype` parameter in the configuration file.
+taosBbenchmark supports three operating modes:
+- No parameter mode
+- Command line mode
+- JSON configuration file mode
+The command-line approach is a subset of the functionality of JSON configuration files, which immediately uses the command line and then the configuration file, with the parameters specified by the command line taking precedence.
**Ensure that the TDengine cluster is running correctly before running taosBenchmark.**
### Running Without Command Line Arguments
-Execute the following command to quickly experience taosBenchmark performing a write performance test on TDengine based on the default configuration.
+Execute the following command to quickly experience taosBenchmark performing a write performance test on TDengine based on the default configuration.
```shell
taosBenchmark
```
-When running without parameters, taosBenchmark by default connects to the TDengine cluster specified under `/etc/taos`, and creates a database named `test` in TDengine, under which a supertable named `meters` is created, and 10,000 tables are created under the supertable, each table having 10,000 records inserted. Note that if a `test` database already exists, this command will delete the existing database and create a new `test` database.
+When running without parameters, taosBenchmark defaults to connecting to the TDengine cluster specified in `/etc/taos/taos.cfg `.
+After successful connection, a smart meter example database test, super meters, and 10000 sub meters will be created, with 10000 records per sub meter. If the test database already exists, it will be deleted before creating a new one.
### Running Using Command Line Configuration Parameters
@@ -46,9 +49,7 @@ The above command `taosBenchmark` will create a database named `test`, establish
### Running Using a Configuration File
-The taosBenchmark installation package includes examples of configuration files, located in `/examples/taosbenchmark-json`
-
-Use the following command line to run taosBenchmark and control its behavior through a configuration file.
+Running in configuration file mode provides all functions, so parameters can be configured to run in the configuration file.
```shell
taosBenchmark -f
@@ -214,6 +215,61 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
- **-?/--help**:
Displays help information and exits. Cannot be used with other parameters.
+
+## Output performance indicators
+
+#### Write indicators
+
+After writing is completed, a summary performance metric will be output in the last two lines in the following format:
+``` bash
+SUCC: Spent 8.527298 (real 8.117379) seconds to insert rows: 10000000 with 8 thread(s) into test 1172704.41 (real 1231924.74) records/second
+SUCC: insert delay, min: 19.6780ms, avg: 64.9390ms, p90: 94.6900ms, p95: 105.1870ms, p99: 130.6660ms, max: 157.0830ms
+```
+First line write speed statistics:
+- Spent: Total write time, in seconds, counting from the start of writing the first data to the end of the last data. This indicates that a total of 8.527298 seconds were spent
+- Real: Total write time (calling the engine), excluding the time spent preparing data for the testing framework. Purely counting the time spent on engine calls, The time spent is 8.117379 seconds. If 8.527298-8.117379=0.409919 seconds, it is the time spent preparing data for the testing framework
+- Rows: Write the total number of rows, which is 10 million pieces of data
+- Threads: The number of threads being written, which is 8 threads writing simultaneously
+- Records/second write speed = `total write time` / `total number of rows written`, real in parentheses is the same as before, indicating pure engine write speed
+
+Second line single write delay statistics:
+- min: Write minimum delay
+- avg: Write normal delay
+- p90: Write delay p90 percentile delay number
+- p95: Write delay p95 percentile delay number
+- p99: Write delay p99 percentile delay number
+- max: maximum write delay
+Through this series of indicators, the distribution of write request latency can be observed
+
+#### Query indicators
+The query performance test mainly outputs the QPS indicator of query request speed, and the output format is as follows:
+
+``` bash
+complete query with 3 threads and 10000 query delay avg: 0.002686s min: 0.001182s max: 0.012189s p90: 0.002977s p95: 0.003493s p99: 0.004645s SQL command: select ...
+INFO: Total specified queries: 30000
+INFO: Spend 26.9530 second completed total queries: 30000, the QPS of all threads: 1113.049
+```
+
+- The first line represents the percentile distribution of query execution and query request delay for each of the three threads executing 10000 queries. The SQL command is the test query statement
+- The second line indicates that a total of 10000 * 3 = 30000 queries have been completed
+- The third line indicates that the total query time is 26.9653 seconds, and the query rate per second (QPS) is 1113.049 times/second
+
+#### Subscription metrics
+
+The subscription performance test mainly outputs consumer consumption speed indicators, with the following output format:
+``` bash
+INFO: consumer id 0 has poll total msgs: 376, period rate: 37.592 msgs/s, total rows: 3760000, period rate: 375924.815 rows/s
+INFO: consumer id 1 has poll total msgs: 362, period rate: 36.131 msgs/s, total rows: 3620000, period rate: 361313.504 rows/s
+INFO: consumer id 2 has poll total msgs: 364, period rate: 36.378 msgs/s, total rows: 3640000, period rate: 363781.731 rows/s
+INFO: consumerId: 0, consume msgs: 1000, consume rows: 10000000
+INFO: consumerId: 1, consume msgs: 1000, consume rows: 10000000
+INFO: consumerId: 2, consume msgs: 1000, consume rows: 10000000
+INFO: Consumed total msgs: 3000, total rows: 30000000
+```
+- Lines 1 to 3 real-time output of the current consumption speed of each consumer, msgs/s represents the number of consumption messages, each message contains multiple rows of data, and rows/s represents the consumption speed calculated by rows
+- Lines 4 to 6 show the overall statistics of each consumer after the test is completed, including the total number of messages consumed and the total number of lines
+- The overall statistics of all consumers in line 7, `msgs` represents how many messages were consumed in total, `rows` represents how many rows of data were consumed in total
+
## Configuration File Parameters Detailed Explanation
### General Configuration Parameters
@@ -331,21 +387,6 @@ Parameters related to supertable creation are configured in the `super_tables` s
- **repeat_ts_max** : Numeric type, when composite primary key is enabled, specifies the maximum number of records with the same timestamp to be generated
- **sqls** : Array of strings type, specifies the array of sql to be executed after the supertable is successfully created, the table name specified in sql must be prefixed with the database name, otherwise an unspecified database error will occur
-#### tsma Configuration Parameters
-
-Specify the configuration parameters for tsma in `super_tables` under `tsmas`, with the following specific parameters:
-
-- **name**: Specifies the name of the tsma, mandatory.
-
-- **function**: Specifies the function of the tsma, mandatory.
-
-- **interval**: Specifies the time interval for the tsma, mandatory.
-
-- **sliding**: Specifies the window time shift for the tsma, mandatory.
-
-- **custom**: Specifies custom configuration appended at the end of the tsma creation statement, optional.
-
-- **start_when_inserted**: Specifies when to create the tsma after how many rows are inserted, optional, default is 0.
#### Tag and Data Column Configuration Parameters
@@ -423,6 +464,11 @@ For other common parameters, see Common Configuration Parameters.
Configuration parameters for querying specified tables (can specify supertables, subtables, or regular tables) are set in `specified_table_query`.
+- **mixed_query** "yes": `Mixed Query` "no": `Normal Query`, default is "no"
+`Mixed Query`: All SQL statements in `sqls` are grouped by the number of threads, with each thread executing one group. Each SQL statement in a thread needs to perform `query_times` queries.
+`Normal Query `: Each SQL in `sqls` starts `threads` and exits after executing `query_times` times. The next SQL can only be executed after all previous SQL threads have finished executing and exited.
+Regardless of whether it is a `Normal Query` or `Mixed Query`, the total number of query executions is the same. The total number of queries = `sqls` * `threads` * `query_times`. The difference is that `Normal Query` starts `threads` for each SQL query, while ` Mixed Query` only starts `threads` once to complete all SQL queries. The number of thread startups for the two is different.
+
- **query_interval** : Query interval, in seconds, default is 0.
- **threads** : Number of threads executing the SQL query, default is 1.
@@ -433,7 +479,8 @@ Configuration parameters for querying specified tables (can specify supertables,
#### Configuration Parameters for Querying Supertables
-Configuration parameters for querying supertables are set in `super_table_query`.
+Configuration parameters for querying supertables are set in `super_table_query`.
+The thread mode of the super table query is the same as the `Normal Query` mode of the specified query statement described above, except that `sqls` is filled all sub tables.
- **stblname** : The name of the supertable to query, required.
diff --git a/docs/en/14-reference/09-error-code.md b/docs/en/14-reference/09-error-code.md
index 1d3ea3f9a1..2bbd8f9305 100644
--- a/docs/en/14-reference/09-error-code.md
+++ b/docs/en/14-reference/09-error-code.md
@@ -386,7 +386,7 @@ This document details the server error codes that may be encountered when using
| 0x8000260D | Tags number not matched | Mismatched number of tag columns | Check and correct the SQL statement |
| 0x8000260E | Invalid tag name | Invalid or non-existent tag name | Check and correct the SQL statement |
| 0x80002610 | Value is too long | Value length exceeds limit | Check and correct the SQL statement or API parameters |
-| 0x80002611 | Password can not be empty | Password is empty | Use a valid password |
+| 0x80002611 | Password too short or empty | Password is empty or less than 8 chars | Use a valid password |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | Illegal port number | Check and correct the port number |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | Incorrect address format | Check and correct the address information |
| 0x80002614 | This statement is no longer supported | Feature has been deprecated | Refer to the feature documentation |
diff --git a/docs/zh/06-advanced/05-data-in/07-mqtt.md b/docs/zh/06-advanced/05-data-in/07-mqtt.mdx
similarity index 98%
rename from docs/zh/06-advanced/05-data-in/07-mqtt.md
rename to docs/zh/06-advanced/05-data-in/07-mqtt.mdx
index a0e121f632..3ffab4dfbf 100644
--- a/docs/zh/06-advanced/05-data-in/07-mqtt.md
+++ b/docs/zh/06-advanced/05-data-in/07-mqtt.mdx
@@ -166,6 +166,12 @@ json 数据支持 JSONObject 或者 JSONArray,使用 json 解析器可以解

-### 8. 创建完成
+### 8. 异常处理策略
+
+import Contributing from './_03-exception-handling-strategy.mdx'
+
+
+
+### 9. 创建完成
点击 **提交** 按钮,完成创建 MQTT 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/08-kafka.md b/docs/zh/06-advanced/05-data-in/08-kafka.mdx
similarity index 97%
rename from docs/zh/06-advanced/05-data-in/08-kafka.md
rename to docs/zh/06-advanced/05-data-in/08-kafka.mdx
index b605f84c7a..71070b271c 100644
--- a/docs/zh/06-advanced/05-data-in/08-kafka.md
+++ b/docs/zh/06-advanced/05-data-in/08-kafka.mdx
@@ -196,12 +196,16 @@ json 数据支持 JSONObject 或者 JSONArray,使用 json 解析器可以解
### 8. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-
+
-
+### 9. 异常处理策略
-### 9. 创建完成
+import Contributing from './_03-exception-handling-strategy.mdx'
+
+
+
+### 10. 创建完成
点击 **提交** 按钮,完成创建 Kafka 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/09-influxdb.md b/docs/zh/06-advanced/05-data-in/09-influxdb.mdx
similarity index 94%
rename from docs/zh/06-advanced/05-data-in/09-influxdb.md
rename to docs/zh/06-advanced/05-data-in/09-influxdb.mdx
index d0b781667d..b88bcdf3c6 100644
--- a/docs/zh/06-advanced/05-data-in/09-influxdb.md
+++ b/docs/zh/06-advanced/05-data-in/09-influxdb.mdx
@@ -75,9 +75,9 @@ InfluxDB 是一种流行的开源时间序列数据库,它针对处理大量
### 6. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
-
-
+import AdvancedOptions from './_02-advanced_options.mdx'
+
+
### 7. 创建完成
diff --git a/docs/zh/06-advanced/05-data-in/10-opentsdb.md b/docs/zh/06-advanced/05-data-in/10-opentsdb.mdx
similarity index 92%
rename from docs/zh/06-advanced/05-data-in/10-opentsdb.md
rename to docs/zh/06-advanced/05-data-in/10-opentsdb.mdx
index 3737f2a415..eeb4e37988 100644
--- a/docs/zh/06-advanced/05-data-in/10-opentsdb.md
+++ b/docs/zh/06-advanced/05-data-in/10-opentsdb.mdx
@@ -58,9 +58,9 @@ OpenTSDB 是一个架构在 HBase 系统之上的实时监控信息收集和展
### 5. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
-
-
+import AdvancedOptions from './_02-advanced_options.mdx'
+
+
### 6. 创建完成
diff --git a/docs/zh/06-advanced/05-data-in/11-csv.md b/docs/zh/06-advanced/05-data-in/11-csv.mdx
similarity index 95%
rename from docs/zh/06-advanced/05-data-in/11-csv.md
rename to docs/zh/06-advanced/05-data-in/11-csv.mdx
index 4924ed2fbd..5737fc8b79 100644
--- a/docs/zh/06-advanced/05-data-in/11-csv.md
+++ b/docs/zh/06-advanced/05-data-in/11-csv.mdx
@@ -107,13 +107,25 @@ sidebar_label: "CSV"

-### 5. 创建完成
+### 5. 配置高级选项
+
+import AdvancedOptions from './_02-advanced_options.mdx'
+
+
+
+### 6. 异常处理策略
+
+import Contributing from './_03-exception-handling-strategy.mdx'
+
+
+
+### 7. 创建完成
点击 **提交** 按钮,完成创建 CSV 到 TDengine 的数据同步任务,回到数据写入任务列表页面,可查看任务执行情况,也可以进行任务的“启动/停止”操作与“查看/编辑/删除/复制”操作。

-### 6. 查看运行指标
+### 8. 查看运行指标
点击 **查看** 按钮,查看任务的运行指标,同时也可以查看任务中所有文件的处理情况。
diff --git a/docs/zh/06-advanced/05-data-in/12-aveva-historian.md b/docs/zh/06-advanced/05-data-in/12-aveva-historian.mdx
similarity index 97%
rename from docs/zh/06-advanced/05-data-in/12-aveva-historian.md
rename to docs/zh/06-advanced/05-data-in/12-aveva-historian.mdx
index ee04194dea..e8ab4c839e 100644
--- a/docs/zh/06-advanced/05-data-in/12-aveva-historian.md
+++ b/docs/zh/06-advanced/05-data-in/12-aveva-historian.mdx
@@ -134,6 +134,12 @@ split 提取器,seperator 填写分割符 `,`, number 填写 2。

-### 7. 创建完成
+### 7. 异常处理策略
+
+import Contributing from './_03-exception-handling-strategy.mdx'
+
+
+
+### 8. 创建完成
点击 **提交** 按钮,完成创建任务。提交任务后,回到**数据写入**页面可以查看任务状态。
diff --git a/docs/zh/06-advanced/05-data-in/13-mysql.md b/docs/zh/06-advanced/05-data-in/13-mysql.mdx
similarity index 93%
rename from docs/zh/06-advanced/05-data-in/13-mysql.md
rename to docs/zh/06-advanced/05-data-in/13-mysql.mdx
index 4cc84fbfa2..f1894190cb 100644
--- a/docs/zh/06-advanced/05-data-in/13-mysql.md
+++ b/docs/zh/06-advanced/05-data-in/13-mysql.mdx
@@ -98,14 +98,16 @@ MySQL 是最流行的关系型数据库之一。很多系统都曾经或正在
### 8. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
-**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+### 9. 异常处理策略
-
+import Contributing from './_03-exception-handling-strategy.mdx'
-### 9. 创建完成
+
+
+### 10. 创建完成
点击 **提交** 按钮,完成创建 MySQL 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/14-postgres.md b/docs/zh/06-advanced/05-data-in/14-postgres.mdx
similarity index 93%
rename from docs/zh/06-advanced/05-data-in/14-postgres.md
rename to docs/zh/06-advanced/05-data-in/14-postgres.mdx
index af8297bfff..7651db68f2 100644
--- a/docs/zh/06-advanced/05-data-in/14-postgres.md
+++ b/docs/zh/06-advanced/05-data-in/14-postgres.mdx
@@ -99,14 +99,16 @@ TDengine 可以高效地从 PostgreSQL 读取数据并将其写入 TDengine,
### 8. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
-**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+### 9. 异常处理策略
-
+import Contributing from './_03-exception-handling-strategy.mdx'
-### 9. 创建完成
+
+
+### 10. 创建完成
点击 **提交** 按钮,完成创建 PostgreSQL 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/15-oracle.md b/docs/zh/06-advanced/05-data-in/15-oracle.mdx
similarity index 93%
rename from docs/zh/06-advanced/05-data-in/15-oracle.md
rename to docs/zh/06-advanced/05-data-in/15-oracle.mdx
index 39bbab32d3..484365415e 100644
--- a/docs/zh/06-advanced/05-data-in/15-oracle.md
+++ b/docs/zh/06-advanced/05-data-in/15-oracle.mdx
@@ -91,14 +91,16 @@ TDengine 可以高效地从 Oracle 读取数据并将其写入 TDengine,以实
### 7. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
-**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+### 8. 异常处理策略
-
+import Contributing from './_03-exception-handling-strategy.mdx'
-### 8. 创建完成
+
+
+### 9. 创建完成
点击 **提交** 按钮,完成创建 Oracle 到 TDengine 的数据同步任务,回到**数据源列表****页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/16-mssql.md b/docs/zh/06-advanced/05-data-in/16-mssql.mdx
similarity index 94%
rename from docs/zh/06-advanced/05-data-in/16-mssql.md
rename to docs/zh/06-advanced/05-data-in/16-mssql.mdx
index 81e9e98013..1e6b9928be 100644
--- a/docs/zh/06-advanced/05-data-in/16-mssql.md
+++ b/docs/zh/06-advanced/05-data-in/16-mssql.mdx
@@ -105,14 +105,16 @@ Microsoft SQL Server 是最流行的关系型数据库之一。很多系统都
### 8. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
-**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+### 9. 异常处理策略
-
+import Contributing from './_03-exception-handling-strategy.mdx'
-### 9. 创建完成
+
+
+### 10. 创建完成
点击 **提交** 按钮,完成创建 Microsoft SQL Server 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/17-mongodb.md b/docs/zh/06-advanced/05-data-in/17-mongodb.mdx
similarity index 94%
rename from docs/zh/06-advanced/05-data-in/17-mongodb.md
rename to docs/zh/06-advanced/05-data-in/17-mongodb.mdx
index 5311bc43c6..e92f37a6f0 100644
--- a/docs/zh/06-advanced/05-data-in/17-mongodb.md
+++ b/docs/zh/06-advanced/05-data-in/17-mongodb.mdx
@@ -122,14 +122,16 @@ MongoDB 是一个介于关系型数据库与非关系型数据库之间的产品
### 8. 配置高级选项
-**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+import AdvancedOptions from './_02-advanced_options.mdx'
-**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
-**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+### 9. 异常处理策略
-
+import Contributing from './_03-exception-handling-strategy.mdx'
-### 9. 创建完成
+
+
+### 10. 创建完成
点击 **提交** 按钮,完成创建 MongoDB 到 TDengine 的数据同步任务,回到**数据源列表**页面可查看任务执行情况。
diff --git a/docs/zh/06-advanced/05-data-in/_02-advanced_options.mdx b/docs/zh/06-advanced/05-data-in/_02-advanced_options.mdx
new file mode 100644
index 0000000000..f37de063c0
--- /dev/null
+++ b/docs/zh/06-advanced/05-data-in/_02-advanced_options.mdx
@@ -0,0 +1,7 @@
+**高级选项** 区域是默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+
+**最大读取并发数** 数据源连接数或读取线程数限制,当默认参数不满足需要或需要调整资源使用量时修改此参数。
+
+**批次大小** 单次发送的最大消息数或行数。默认是 10000。
+
+
\ No newline at end of file
diff --git a/docs/zh/06-advanced/05-data-in/_03-exception-handling-strategy.mdx b/docs/zh/06-advanced/05-data-in/_03-exception-handling-strategy.mdx
new file mode 100644
index 0000000000..470c304ff3
--- /dev/null
+++ b/docs/zh/06-advanced/05-data-in/_03-exception-handling-strategy.mdx
@@ -0,0 +1,23 @@
+异常处理策略区域是对数据异常时的处理策略进行配置,默认折叠的,点击右侧 `>` 可以展开,如下图所示:
+
+
+
+各异常项说明及相应可选处理策略如下:
+
+> 通用处理策略说明:
+> 归档:将异常数据写入归档文件(默认路径为 `${data_dir}/tasks/_id/.datetime`),不写入目标库
+> 丢弃:将异常数据忽略,不写入目标库
+> 报错:任务报错
+
+- **主键时间戳溢出** 检查数据中第一列时间戳是否在正确的时间范围内(now - keep1, now + 100y),可选处理策略:归档、丢弃、报错
+- **主键时间戳空** 检查数据中第一列时间戳是否为空,可选处理策略:归档、丢弃、报错、使用当前时间
+ > 使用当前时间:使用当前时间填充到空的时间戳字段中
+- **表名长度溢出** 检查子表表名的长度是否超出限制(最大 192 字符),可选处理策略:归档、丢弃、报错、截断、截断且归档
+ > 截断:截取原始表名的前 192 个字符作为新的表名
+ > 截断且归档:截取原始表名的前 192 个字符作为新的表名,并且将此行记录写入归档文件
+- **表名非法字符** 检查子表表名中是否包含特殊字符(符号 `.` 等),可选处理策略:归档、丢弃、报错、非法字符替换为指定字符串
+ > 非法字符替换为指定字符串:将原始表名中的特殊字符替换为后方输入框中的指定字符串,例如 `a.b` 替换为 `a_b`
+- **表名模板变量空值** 检查子表表名模板中的变量是否为空,可选处理策略:丢弃、留空、变量替换为指定字符串
+ > 留空:变量位置不做任何特殊处理,例如 `a_{x}` 转换为 `a_`
+ > 变量替换为指定字符串:变量位置使用后方输入框中的指定字符串,例如 `a_{x}` 转换为 `a_b`
+- **列名长度溢出** 检查列名的长度是否超出限制(最大 64 字符),可选处理策略:归档、丢弃、报错
\ No newline at end of file
diff --git a/docs/zh/06-advanced/05-data-in/kafka-15.png b/docs/zh/06-advanced/05-data-in/kafka-15.png
deleted file mode 100644
index 96d593dad9..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/kafka-15.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/kafka-16.png b/docs/zh/06-advanced/05-data-in/kafka-16.png
deleted file mode 100644
index 395453c410..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/kafka-16.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/InfluxDB-09zh-AdvancedOptionsExpandButton.png b/docs/zh/06-advanced/05-data-in/pic/InfluxDB-09zh-AdvancedOptionsExpandButton.png
deleted file mode 100644
index f12692c506..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/InfluxDB-09zh-AdvancedOptionsExpandButton.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/InfluxDB-10zh-AdvancedOptionsExpand.png b/docs/zh/06-advanced/05-data-in/pic/InfluxDB-10zh-AdvancedOptionsExpand.png
deleted file mode 100644
index dbb188852c..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/InfluxDB-10zh-AdvancedOptionsExpand.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-07zh-AdvancedOptionsExpandButton.png b/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-07zh-AdvancedOptionsExpandButton.png
deleted file mode 100644
index 65d6344e56..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-07zh-AdvancedOptionsExpandButton.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-08zh-AdvancedOptionsExpand.png b/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-08zh-AdvancedOptionsExpand.png
deleted file mode 100644
index ea5dc538e5..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/OpenTSDB-08zh-AdvancedOptionsExpand.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/advanced_options.png b/docs/zh/06-advanced/05-data-in/pic/advanced_options.png
new file mode 100644
index 0000000000..8ef9b8d35a
Binary files /dev/null and b/docs/zh/06-advanced/05-data-in/pic/advanced_options.png differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/exception-handling-strategy.png b/docs/zh/06-advanced/05-data-in/pic/exception-handling-strategy.png
new file mode 100644
index 0000000000..1e1d55d85c
Binary files /dev/null and b/docs/zh/06-advanced/05-data-in/pic/exception-handling-strategy.png differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/mongodb-07.png b/docs/zh/06-advanced/05-data-in/pic/mongodb-07.png
deleted file mode 100644
index 2305ec3d2e..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/mongodb-07.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/mssql-07.png b/docs/zh/06-advanced/05-data-in/pic/mssql-07.png
deleted file mode 100644
index 6c1668481c..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/mssql-07.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/mysql-07.png b/docs/zh/06-advanced/05-data-in/pic/mysql-07.png
deleted file mode 100644
index 6c1668481c..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/mysql-07.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/oracle-06.png b/docs/zh/06-advanced/05-data-in/pic/oracle-06.png
deleted file mode 100644
index 0de5443f08..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/oracle-06.png and /dev/null differ
diff --git a/docs/zh/06-advanced/05-data-in/pic/postgres-07.png b/docs/zh/06-advanced/05-data-in/pic/postgres-07.png
deleted file mode 100644
index 6c1668481c..0000000000
Binary files a/docs/zh/06-advanced/05-data-in/pic/postgres-07.png and /dev/null differ
diff --git a/docs/zh/08-operation/09-backup.md b/docs/zh/08-operation/09-backup.md
index 1eda0a646b..075cc244f4 100644
--- a/docs/zh/08-operation/09-backup.md
+++ b/docs/zh/08-operation/09-backup.md
@@ -6,45 +6,154 @@ toc_max_heading_level: 4
为了防止数据丢失、误删操作,TDengine 提供全面的数据备份、恢复、容错、异地数据实时同步等功能,以保证数据存储的安全。本节简要说明备份和恢复功能。
-## 基于 taosdump 进行数据备份恢复
+# 1. 基于 taosdump 进行数据备份恢复
-taosdump 是一个开源工具,用于支持从运行中的 TDengine 集群备份数据并将备份的数据恢复到相同或另一个正在运行的 TDengine 集群中。taosdump 可以将数据库作为逻辑数据单元进行备份,也可以对数据库中指定时间段内的数据记录进行备份。在使用taosdump 时,可以指定数据备份的目录路径。如果不指定目录路径,taosdump 将默认将数据备份到当前目录。
+taosdump 是一个开源工具,用于支持从运行中的 TDengine 集群备份数据并将备份的数据恢复到相同或另一个正在运行的 TDengine
+集群中。taosdump 可以将数据库作为逻辑数据单元进行备份,也可以对数据库中指定时间段内的数据记录进行备份。在使用taosdump
+时,可以指定数据备份的目录路径。如果不指定目录路径,taosdump 将默认将数据备份到当前目录。
以下为 taosdump 执行数据备份的使用示例。
+
```shell
taosdump -h localhost -P 6030 -D dbname -o /file/path
```
-执行上述命令后,taosdump 会连接 localhost:6030 所在的 TDengine 集群,查询数据库 dbname 中的所有数据,并将数据备份到 /f ile/path 下。
+执行上述命令后,taosdump 会连接 localhost:6030 所在的 TDengine 集群,查询数据库 dbname 中的所有数据,并将数据备份到 /f
+ile/path 下。
-在使用 taosdump 时,如果指定的存储路径已经包含数据文件,taosdump 会提示用户并立即退出,以避免数据被覆盖。这意味着同一存储路径只能用于一次备份。如果你看到相关提示,请谨慎操作,以免误操作导致数据丢失。
+在使用 taosdump 时,如果指定的存储路径已经包含数据文件,taosdump
+会提示用户并立即退出,以避免数据被覆盖。这意味着同一存储路径只能用于一次备份。如果你看到相关提示,请谨慎操作,以免误操作导致数据丢失。
+
+要将本地指定文件路径中的数据文件恢复到正在运行的 TDengine 集群中,可以通过指定命令行参数和数据文件所在路径来执行 taosdump
+命令。以下为 taosdump 执行数据恢复的示例代码。
-要将本地指定文件路径中的数据文件恢复到正在运行的 TDengine 集群中,可以通过指定命令行参数和数据文件所在路径来执行 taosdump 命令。以下为 taosdump 执行数据恢复的示例代码。
```shell
taosdump -i /file/path -h localhost -P 6030
```
执行上述命令后,taosdump 会连接 localhost:6030 所在的 TDengine 集群,并将 /file/path 下的数据文件恢复到 TDengine 集群中。
-## 基于 TDengine Enterprise 进行数据备份恢复
+# 2. 基于 TDengine Enterprise 进行数据备份恢复
-TDengine Enterprise 提供了一个高效的增量备份功能,具体流程如下。
+## 2.1. 概念
-第 1 步,通过浏览器访问 taosExplorer 服务,访问地址通常为 TDengine 集群所在 IP 地址的端口 6060,如 http://localhost:6060。
+基于 TDengine 的数据订阅功能,TDengine Enterprise 实现了数据的增量备份和恢复。用户可以通过 taosExplorer 对 TDengine
+集群进行备份和恢复。
-第 2 步,在 taosExplorer 服务页面中的“系统管理 - 备份”页面新增一个数据备份任务,在任务配置信息中填写需要备份的数据库名称和备份存储文件路径,完成创建任务
-后即可启动数据备份。 在数据备份配置页面中可以配置三个参数:
- - 备份周期:必填项,配置每次执行数据备份的时间间隔,可通过下拉框选择每天、每 7 天、每 30 天执行一次数据备份,配置后,会在对应的备份周期的0:00时启动一次数据备份任务;
- - 数据库:必填项,配置需要备份的数据库名(数据库的 wal_retention_period 参数需大于0);
- - 目录:必填项,配置将数据备份到 taosX 所在运行环境中指定的路径下,如 /root/data_backup;
+TDengine Enterprise 的备份和恢复功能包括以下几个概念:
-第 3 步,在数据备份任务完成后,在相同页面的已创建任务列表中找到创建的数据备份任务,直接执行一键恢复,就能够将数据恢复到 TDengine 中。
+1. 备份对象:用户可以对一个数据库,或者一个超级表进行备份。
+2. 备份计划:用户可以为某个备份对象创建一个备份计划。备份计划从指定的时间点开始,周期性的执行一次备份任务,并生成一组备份文件。
+3. 备份点:每执行一次备份任务,生成一组备份文件,它们对应一个时间点,称为**备份点**。第一个备份点称为**初始备份点**。
+4. 备份文件:多个备份点,组成备份计划的备份文件。
+5. 恢复任务:用户可以选择备份计划的某个备份点,创建一个恢复任务。恢复任务会从初始备份点开始,逐个应用备份点,恢复到指定的备份点。
-与 taosdump 相比,如果对相同的数据在指定存储路径下进行多次备份操作,由于TDengine Enterprise 不仅备份效率高,而且实行的是增量处理,因此每次备份任务都会很快完成。而由于 taosdump 永远是全量备份,因此 TDengine Enterprise 在数据量较大的场景下可以显著减小系统开销,而且更加方便。
+
-**常见错误排查**
+以上面的图为例:
-1. 如果任务启动失败并报以下错误:
+1. 用户创建了一个备份计划,从 2024-08-27 00:00:00 开始,每隔 1 天执行一次备份任务。
+2. 在 2024-08-27 00:00:00 执行了第一次备份任务,生成了一个备份点。
+3. 之后,每隔 1 天执行一次备份任务,生成了多个备份点,组成了备份文件。
+4. 用户可以选择某个备份点,创建一个恢复任务,恢复到指定的备份点。
+5. 恢复任务会从初始备份点开始,逐个应用备份点,恢复到指定的备份点。
+
+## 2.2. 备份计划
+
+### 2.1.1. 创建
+
+1. 通过浏览器访问 taosExplorer 服务,访问地址通常为 TDengine 集群所在 IP 地址的端口 6060,如 http://localhost:6060。
+2. 在 taosExplorer 服务页面中,进入“系统管理 - 备份”页面,点击“创建备份计划”按钮。
+
+
+
+3. 在弹出的“创建备份计划”表单中,填写备份计划的相关信息。
+
+
+
+需要填写的信息包括:
+
+* 数据库:需要备份的数据库名称。一个备份计划只能备份一个数据库/超级表。
+* 超级表:需要备份的超级表名称。如果不填写,则备份整个数据库。
+* 下次执行时间:首次执行备份任务的日期时间。
+* 备份周期:备份点之间的时间间隔。注意:备份周期必须大于数据库的 WAL_RETENTION_PERIOD 参数值。
+* 错误重试次数:对于可通过重试解决的错误,系统会按照此次数进行重试。
+* 错误重试间隔:每次重试之间的时间间隔。
+* 目录:存储备份文件的目录。
+* 备份文件大小:备份文件的大小限制。当备份文件大小达到此限制时,会自动创建新的备份文件。
+* 文件压缩等级:备份文件的压缩等级。支持:最快速度、最佳压缩比、兼具速度和压缩比。
+
+创建成功后,备份计划会开始按照配置的参数运行。
+
+### 2.1.2. 查看
+
+在“备份计划”下的列表中,可以查看已创建的备份计划。
+
+
+
+点击“操作”中的“查看”按钮,可以查看备份计划的详细信息。
+
+
+
+### 2.1.3. 修改
+
+点击“操作”中的“修改”按钮,可以修改备份计划的配置。
+
+
+
+修改备份计划的配置后,当前运行的备份任务会先停止,然后按照新的配置重新运行。
+
+### 2.1.4. 复制
+
+点击“操作”中的“复制”按钮,可以复制备份计划。
+
+
+
+除了数据库和超级表被置为空外,其他配置项和被复制的计划相同。用户点击“确认”后,创建一个新的备份计划。
+
+### 2.1.5. 删除
+
+在操作中点击关闭按钮,可以停止当前备份计划。点击“操作”中的“删除”按钮,可以删除备份计划。
+
+
+
+删除备份计划时,可以选择,是否删除关联的备份文件。
+
+## 2.2. 备份文件
+
+### 2.2.1. 查看
+
+在备份计划列表中,选择要一个备份计划。在“备份文件”列中,点击“查看”按钮。可以查看和备份计划的所有备份点。
+
+
+
+在备份文件列表中,可以查看备份文件的详细信息。
+
+
+
+## 2.3. 恢复任务
+
+### 2.3.1. 创建
+
+在备份文件列表中,点击“操作”中的“恢复”按钮,可以创建一个恢复任务。
+
+
+
+在弹出的对话框中,选择使用哪个备份点开始恢复,默认为最早的备份点。点击“确定”后,创建恢复任务,并跳转至“恢复任务”列表。
+
+### 2.3.2. 查看
+
+在“恢复任务”列表中,可以查看已创建的恢复任务。
+
+
+
+恢复任务可以终止。点击“操作”中的开关,可以终止当前恢复任务。
+
+# 3. 常见错误排查
+
+## 3.1. 端口访问异常
+
+如果任务启动失败并报以下错误:
```text
Error: tmq to td task exec error
@@ -52,9 +161,12 @@ Error: tmq to td task exec error
Caused by:
[0x000B] Unable to establish connection
```
+
产生原因是与数据源的端口链接异常,需检查数据源 FQDN 是否联通及端口 6030 是否可正常访问。
-2. 如果使用 WebSocket 连接,任务启动失败并报以下错误:
+## 3.2. 连接异常
+
+如果使用 WebSocket 连接,任务启动失败并报以下错误:
```text
Error: tmq to td task exec error
@@ -73,7 +185,9 @@ Caused by:
- "HTTP error: *": 可能连接到错误的 taosAdapter 端口或 LSB/Nginx/Proxy 配置错误。
- "WebSocket protocol error: Handshake not finished": WebSocket 连接错误,通常是因为配置的端口不正确。
-3. 如果任务启动失败并报以下错误:
+## 3.3. 任务启动失败
+
+如果任务启动失败并报以下错误:
```text
Error: tmq to td task exec error
@@ -88,5 +202,6 @@ Caused by:
修改数据 WAL 配置:
```sql
-alter database test wal_retention_period 3600;
+alter
+database test wal_retention_period 3600;
```
\ No newline at end of file
diff --git a/docs/zh/08-operation/18-ha/01-replica3.md b/docs/zh/08-operation/18-ha/01-replica3.md
new file mode 100644
index 0000000000..fee19a0afe
--- /dev/null
+++ b/docs/zh/08-operation/18-ha/01-replica3.md
@@ -0,0 +1,66 @@
+---
+title: 三副本方案
+sidebar_label: 三副本方案
+toc_max_heading_level: 4
+---
+
+TDengine 的三副本方案采用 RAFT 算法来实现数据的一致性,包括元数据和时序数据。一个虚拟节点组(VGroup)构成了一个 RAFT 组;VGroup 中的虚拟节点(Vnode),便是该 RAFT 组的成员节点,也称之为副本。
+
+1. 每个 Vnode 都有自己的角色,可以是 Leader(领导者)、Follower(跟随者)、Candidate(候选人)。
+2. 每个 Vnode 都维护了一份连续的日志,用于记录数据写入、变更、或删除等操作的所有指令。日志是由一系列有序的日志条目组成,每条日志都有唯一的编号,用于标识日志协商或执行的进度。
+3. Leader 角色的 Vnode 提供读写服务,在故障节点不超过半数的情况下保证集群的高可用性。此外,即使发生了节点重启及 Leader 重新选举等事件后,RAFT 协议也能够始终保证新产生的 Leader 可以提供已经写入成功的全部完整数据的读写服务。
+4. 每一次对数据库的变更请求(比如数据写入),都对应一条日志。在持续写入数据的过程中,会按照协议机制在每个成员节点上产生完全相同的日志记录,并且以相同的顺序执行数据变更操作,以 WAL 文件的形式存储在数据文件目录中。
+5. 只有当过半数的节点把该条日志追加到 WAL 文件,并且收到确认消息之后,这条日志才会被 Leader 认为是安全的;此时该日志进入 committed 状态,完成数据的插入,随后该日志被标记为 applied 的状态。
+
+多副本工作原理参见 [数据写入与复制流程](../../26-tdinternal/01-arch.md#数据写入与复制流程)
+
+## 集群配置
+
+三副本要求集群至少配置三个服务器节点,基本部署与配置步骤如下:
+1. 确定服务器节点数量、主机名或域名,配置好所有节点的域名解析:DNS 或 /etc/hosts
+2. 各节点分别安装 TDengine 服务端安装包,按需编辑好各节点 taos.cfg
+3. 启动各节点 taosd 服务,其他服务可按需启动(taosadapter/taosx/taoskeeper/taos-explorer)
+
+## 运维命令
+
+### 创建集群
+
+创建三节点的集群
+
+```sql
+CREATE dnode port ;
+CREATE dnode port ;
+```
+
+创建三副本的 Mnode,保证 Mnode 高可用
+
+```sql
+CREATE mnode on dnode ;
+CREATE mnode on dnode ;
+```
+
+### 数据库创建
+
+创建三副本的数据库
+
+```sql
+create database replica 3 vgroups xx buffer xx ...
+```
+
+### 修改数据库副本数
+
+创建了单副本数据库后,如果希望改为三副本时,可通过 alter 命令来实现,反之亦然
+
+```sql
+alter database replica 3|1
+```
+
+## 常见问题
+
+### 1. 创建三副本数据库或修改为三副本时,报错:DB error: Out of dnodes
+- 服务器节点数不足:原因是服务器节点数少于三个。
+- 解决方案:增加服务器节点数量,满足最低要求。
+
+### 2. 创建三副本数据库或 split vgroup 时,报错:DB error: Vnodes exhausted
+- 服务器可用 Vnodes 不足:原因是某些服务器节点可用 Vnodes 数少于建库或 split vgroup 的需求数。
+- 解决方案:调整服务器 CPU 数量、SupportVnodes 配置参数,满足建库要求。
\ No newline at end of file
diff --git a/docs/zh/08-operation/18-ha/02-replica2.md b/docs/zh/08-operation/18-ha/02-replica2.md
new file mode 100644
index 0000000000..7f3eb2fe5c
--- /dev/null
+++ b/docs/zh/08-operation/18-ha/02-replica2.md
@@ -0,0 +1,84 @@
+---
+title: 双副本方案
+sidebar_label: 双副本方案
+toc_max_heading_level: 4
+---
+
+部分用户期望在保证一定可靠性、可用性条件下,尽可能压缩部署成本。为此,TDengine 提出基于 Arbitrator 的双副本方案,可提供集群中**只有单个服务故障且不出现连续故障**的容错能力。双副本方案是 TDengine Enterprise 特有功能,在 3.3.0.0 版本中第一次发布,建议使用最新版本。
+
+双副本选主由高可用的 Mnode 提供仲裁服务,不由 Raft 组内决定。
+1. Arbitrator:仲裁服务,不存储数据,VGroup 因某一 Vnode 故障而无法提供服务时,Arbitrator 可根据数据同步情况指定 VGroup 内另一 Vnode 成为 Assigned Leader
+2. AssignedLeader:被强制设置为 Leader 的 Vnode,无论其他副本 Vnode 是否存活,均可一直响应用户请求
+
+
+
+## 集群配置
+
+双副本要求集群至少配置三个节点,基本部署与配置步骤如下:
+1. 确定服务器节点数量、主机名或域名,配置好所有节点的域名解析:DNS 或 /etc/hosts
+2. 各节点分别安装 TDengine **企业版**服务端安装包,按需编辑好各节点 taos.cfg
+3. 可选择其中一个节点仅提供仲裁服务(部署 Mnode),将 SupportVnodes 参数设置为 0,表示不存储时序数据;该占用资源较少,仅需 1~2 核,且可与其他应用共用
+4. 启动各节点 taosd 服务,其他服务可按需启动(taosadapter/taosx/taoskeeper/taos-explorer)
+
+## 约束条件
+1. 最小配置的服务器节点数为 2+1 个,其中两个数据节点,一个仲裁节点
+2. 双副本为数据库建库参数,不同数据库可按需选择副本数
+3. 支持 TDengine 集群的完整特性,包括:读缓存、数据订阅、流计算等
+4. 支持 TDengine 所有语言连接器以及连接方式
+5. 支持单副本与双副本之间切换(前提是节点数量满足需求、各节点可用 Vnode 数量/内存/存储空间足够)
+6. 不支持双副本与三副本之间的切换
+7. 不支持双副本切换为双活,除非另外部署一套实例与当前实例组成双活方案
+
+## 运维命令
+
+### 创建集群
+
+创建三节点的集群
+
+```sql
+CREATE dnode port ;
+CREATE dnode port ;
+```
+
+创建三副本的 Mnode,保证 Mnode 高可用,确保仲裁服务的高可用
+
+```sql
+CREATE mnode on dnode ;
+CREATE mnode on dnode ;
+```
+
+### 数据库创建
+
+按需创建双副本数据库
+
+```sql
+create database replica 2 vgroups xx buffer xx ...
+```
+
+### 修改数据库副本数
+
+创建了单副本数据库后,希望改为双副本时,可通过 alter 命令来实现,反之亦然
+
+```sql
+alter database replica 2|1
+```
+
+## 异常情况
+
+| 异常场景 | 集群状态 |
+| ------- | ------ |
+| 没有 Vnode 发生故障: Arbitrator 故障(Mnode 宕机节点超过一个,导致 Mnode 无法选主)| **持续提供服务** |
+| 仅一个 Vnode 故障:VGroup 已经达成同步后,某一个 Vnode 才发生故障的 | **持续提供服务** |
+| 仅一个 Vnode 故障:离线 Vnode 启动后,VGroup 未达成同步前,另一个 Vnode 服务故障的 | **无法提供服务** |
+| 两个 Vnode 都发生故障 | **无法提供服务** |
+
+
+## 常见问题
+
+### 1. 创建双副本数据库或修改为双副本时,报错:DB error: Out of dnodes
+- 服务器节点数不足:原因是,数据服务器节点数少于两个。
+- 解决方案:增加服务器节点数量,满足最低要求。
+
+### 2. 创建双副本数据库或 split vgroup 时,报错:DB error: Vnodes exhausted
+- 服务器可用 Vnodes 不足:原因是某些服务器节点可用 Vnodes 数少于建库或 split vgroup 的需求数。
+- 解决方案:调整服务器 CPU 数量、SupportVnodes 数量,满足建库要求。
diff --git a/docs/zh/08-operation/18-dual.md b/docs/zh/08-operation/18-ha/03-dual.md
similarity index 70%
rename from docs/zh/08-operation/18-dual.md
rename to docs/zh/08-operation/18-ha/03-dual.md
index caddb7ab3b..20565bd562 100644
--- a/docs/zh/08-operation/18-dual.md
+++ b/docs/zh/08-operation/18-ha/03-dual.md
@@ -1,31 +1,29 @@
---
-title: TDengine 双活系统
-sidebar_label: 双活系统
+title: 双活方案
+sidebar_label: 双活方案
toc_max_heading_level: 4
---
-本节介绍 TDengine 双活系统的配置和使用。
+部分用户因为部署环境的特殊性只能部署两台服务器,同时希望实现一定的服务高可用和数据高可靠。本文主要描述基于数据复制和客户端 Failover 两项关键技术的 TDengine 双活系统的产品行为,包括双活系统的架构、配置、运维等。TDengine 双活既可以用于前面所述资源受限的环境,也可用于在两套 TDengine 集群(不限资源)之间的灾备场景。双活是 TDengine Enterprise 特有功能,在 3.3.0.0 版本中第一次发布,建议使用最新版本。
-1. 部分用户因为部署环境的特殊性只能部署两台服务器,同时希望实现一定的服务高可用和数据高可靠。本文主要描述基于数据复制和客户端 Failover 两项关键技术的 TDengine 双活系统的产品行为,包括双活系统的架构、配置、运维等。TDengine 双活既可以用于前面所述资源受限的环境,也可用于在两套 TDengine 集群(不限资源)之间的灾备场景。双活是 TDengine Enterprise 特有功能,在 3.3.0.0 版本中第一次发布,建议使用最新版本。
+双活系统的定义是:业务系统中有且仅有两台服务器,其上分别部署一套服务,在业务层看来这两台机器和两套服务是一个完整的系统,对其中的细节业务层不需要感知。双活中的两个节点通常被称为 Master-Slave,意为”主从“或”主备“,本文档中可能会出现混用的情况。
-2. 双活系统的定义是:业务系统中有且仅有两台服务器,其上分别部署一套服务,在业务层看来这两台机器和两套服务是一个完整的系统,对其中的细节业务层不需要感知。双活中的两个节点通常被称为 Master-Slave,意为”主从“或”主备“,本文档中可能会出现混用的情况。
+TDengine 双活系统的部署架构图如下, 其中涉及到三个关键点:
-3. TDengine 双活系统的部署架构图如下, 其中涉及到三个关键点:
1. 由 Client Driver 实现对双系统的 Failover,即主节点宕机时的主从切换
2. 由 taosX 从(当前的)主节点到从节点实现数据复制
3. 由数据订阅的写接口在写入复制过来的数据时在 WAL 中加入特殊标记,由数据订阅的读接口在读取数据时自动过滤掉带有该特殊标记的数据,避免重复复制形成 infinite loop
注:下图中仅以一个单机版 TDengine 作为示例,但在实际部署中图中的一个 Host 也可以被任意节点数量的 TDengine 集群代替。
-
+
-## 配置
-### 集群配置
+## 集群配置
双活对 TDengine 集群本身的配置没有任何要求,但对要在双活系统之间同步的数据库的 WAL 保留时长有一定要求,WAL 保留时长越大双活系统的容错率越高;如果备节点宕机时长超过主节点上的 WAL 保留时长,必定会导致备节点上有数据缺失;如果备节点宕机时长虽未超过主节点上的 WAL 保留时长,也有一定概率丢失数据,取决于接近的程度以及数据同步的速度。
-### 客户端配置
+## 客户端配置
目前只有 Java 连接器在 WebSocket 连接模式下支持双活,其配置示例如下
@@ -42,19 +40,19 @@ connection = DriverManager.getConnection(url, properties);
其中的配置属性及含义如下表
-| 属性名 | 含义 |
-| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
-| PROPERTY_KEY_SLAVE_CLUSTER_HOST | 第二节点的主机名或者 ip,默认空 |
-| PROPERTY_KEY_SLAVE_CLUSTER_PORT | 第二节点的端口号,默认空 |
+| 属性名 | 含义 |
+| ---------------------------------- | --- |
+| PROPERTY_KEY_SLAVE_CLUSTER_HOST | 第二节点的主机名或者 ip,默认空 |
+| PROPERTY_KEY_SLAVE_CLUSTER_PORT | 第二节点的端口号,默认空 |
| PROPERTY_KEY_ENABLE_AUTO_RECONNECT | 是否启用自动重连。仅在使用 WebSocket 连接时生效。true: 启用,false: 不启用。默认为 false。双活场景下请设置为 true |
-| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 重连的时间间隔,单位毫秒:默认 2000 毫秒,也就是 2 秒;最小值为 0, 表示立即重试;最大值不做限制 |
-| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 每节点最多重试次数:默认值为 3;最小值为 0,表示不进行重试;最大值不做限制 |
+| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 重连的时间间隔,单位毫秒:默认 2000 毫秒,也就是 2 秒;最小值为 0, 表示立即重试;最大值不做限制 |
+| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 每节点最多重试次数:默认值为 3;最小值为 0,表示不进行重试;最大值不做限制 |
-### 约束条件
+## 约束条件
-1. 应用程序不能使用订阅接口,如果配置了双活参数会导致创建消费者失败。
-2. 不建议应用程序使用参数绑定的写入和查询方式,如果使用应用需要自己解决连接切换后的相关对象失效问题。
-3. 在双活场景下,不建议用户应用程序显示调用 use database,应该在连接参数中指定 database。
+1. 应用程序不能使用订阅接口,如果配置了双活参数会导致创建消费者失败
+2. 不建议应用程序使用参数绑定的写入和查询方式,如果使用应用需要自己解决连接切换后的相关对象失效问题
+3. 在双活场景下,不建议用户应用程序显示调用 use database,应该在连接参数中指定 database
4. 双活的两端集群必须同构(即数据库的命名和所有配置参数以及用户名密码和权限设置等完全相同)
5. 只支持 WebSocket 连接模式
@@ -73,7 +71,7 @@ taosx replica start
1. 方法一
```shell
- - taosx replica start -f source_endpoint -t sink_endpoint [database...]
+taosx replica start -f source_endpoint -t sink_endpoint [database...]
```
在本机器所在的 taosx 服务中建立从 source_endpoint 到 sink_endpoint 的同步任务。运行该命令成功后,将打印 replica ID 到控制台(后续记为 id)。
@@ -82,6 +80,7 @@ taosx replica start
```shell
taosx replica start -f td1:6030 -t td2:6030
```
+
该示例命令会自动创建除 information_schema、performance_schema、log、audit 库之外的同步任务。可以使用 `http://td2:6041` 指定该 endpoint 使用 websocket 接口(默认是原生接口)。也可以指定数据库同步:taosx replica start -f td1:6030 -t td2:6030 db1 仅创建指定的数据库同步任务。
2. 方法二
@@ -93,9 +92,9 @@ taosx replica start -i id [database...]
使用上面已经创建的 Replica ID (id) 以在该同步任务中增加其它数据库。
注意:
-- 多次使用该命令,不会创建重复任务,仅将所指定的数据库增加到相应任务中。
-- replica id 在一个 taosX 实例内是全局唯一的,与 source/sink 的组合无关
-- 为便于记忆,replica id 为一个随机常用单词,系统自动将 source/sink 组合对应到一个词库中取得一个唯一可用单词。
+1. 多次使用该命令,不会创建重复任务,仅将所指定的数据库增加到相应任务中。
+2. replica id 在一个 taosX 实例内是全局唯一的,与 source/sink 的组合无关
+3. 为便于记忆,replica id 为一个随机常用单词,系统自动将 source/sink 组合对应到一个词库中取得一个唯一可用单词。
### 查看任务状态
@@ -120,8 +119,8 @@ taosx replica stop id [db...]
```
该命令作用如下:
-- 停止指定 Replica ID 下所有或指定数据库的双副本同步任务。
-- 使用 `taosx replica stop id1 db1` 表示停止 id1 replica 下 db1的同步任务。
+1. 停止指定 Replica ID 下所有或指定数据库的双副本同步任务。
+2. 使用 `taosx replica stop id1 db1` 表示停止 id1 replica 下 db1的同步任务。
### 重启双活任务
@@ -130,8 +129,8 @@ taosx replica restart id [db...]
```
该命令作用如下:
-- 重启指定 Replica ID 下所有或指定数据库的双副本同步任务。
-- 使用 `taosx replica start id1 db1` 仅重启指定数据库 db1的同步任务。
+1. 重启指定 Replica ID 下所有或指定数据库的双副本同步任务。
+2. 使用 `taosx replica start id1 db1` 仅重启指定数据库 db1的同步任务。
### 查看同步进度
diff --git a/docs/zh/08-operation/18-ha/index.md b/docs/zh/08-operation/18-ha/index.md
new file mode 100644
index 0000000000..d482646ddd
--- /dev/null
+++ b/docs/zh/08-operation/18-ha/index.md
@@ -0,0 +1,25 @@
+---
+sidebar_label: 高可用
+title: 高可用
+---
+
+TDengine 作为分布式时序数据库,支持高可用特性。默认高可用方案为基于 RAFT 协议的标准三副本方案;为适应不同用户场景的需要,提供基于 RAFT 协议改造的双副本方案;为满足传统双机主备架构的需求,提供基于 WAL 数据同步的双活方案。
+
+- 标准三副本方案:时序数据的副本数目为 3,确保了最高的可用性,成本也最高。
+- 双副本结合 Arbitrator 方案:时序数据的副本数目为 2,但节点数目至少为 3,以确保高可用性和良好的数据一致性,可显著降低成本。与三副本方案相比,此方案在显著降低成本的同时,依然保持了较高的可用性。
+- 双活方案:可仅部署两个节点,高可用性较好,数据一致性较弱(最终一致性)。
+
+以下为三种方案的特点:
+
+| # | **三副本** | **双副本** | **双活** |
+|:--|:----------|:----------|:--------|
+| **集群数目** | 部署一个集群 | 部署一个集群 | 部署两个不同集群 |
+| **最小节点数** | 三个数据节点 | 两个数据节点,一个仲裁节点 | 两个数据节点 |
+| **选主原理** | Raft 协议 | 管理节点仲裁选主 | 无需选主 |
+| **同步原理** | Raft 协议 | Raft 协议 | 通过 taosX 进行数据同步 |
+| **同步延迟** | 无延迟 | 无延迟 | 依赖于 taosX 的同步速度,秒级延迟 |
+| **数据安全性** | 无数据丢失 | 无数据丢失 | 依赖于 WAL 的保存时长 |
+| **数据一致性** | RAFT 一致性 | RAFT 一致性 | 最终一致性 |
+| **高可用性** | 任一节点宕机不影响服务 | 任一节点宕机不影响服务,但不能处理连续宕机场景 | 一个实例存活即可提供服务 |
+
+
diff --git a/docs/zh/08-operation/Active-Standby.png b/docs/zh/08-operation/Active-Standby.png
deleted file mode 100644
index f0caab5c55..0000000000
Binary files a/docs/zh/08-operation/Active-Standby.png and /dev/null differ
diff --git a/docs/zh/08-operation/pic/backup-00-concept.png b/docs/zh/08-operation/pic/backup-00-concept.png
new file mode 100644
index 0000000000..5123b4d540
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-00-concept.png differ
diff --git a/docs/zh/08-operation/pic/backup-01-create.png b/docs/zh/08-operation/pic/backup-01-create.png
new file mode 100644
index 0000000000..a424c276e5
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-01-create.png differ
diff --git a/docs/zh/08-operation/pic/backup-02-form.png b/docs/zh/08-operation/pic/backup-02-form.png
new file mode 100644
index 0000000000..3ccd81c831
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-02-form.png differ
diff --git a/docs/zh/08-operation/pic/backup-03-list.png b/docs/zh/08-operation/pic/backup-03-list.png
new file mode 100644
index 0000000000..505d6a8040
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-03-list.png differ
diff --git a/docs/zh/08-operation/pic/backup-04-view.png b/docs/zh/08-operation/pic/backup-04-view.png
new file mode 100644
index 0000000000..7bfa699906
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-04-view.png differ
diff --git a/docs/zh/08-operation/pic/backup-05-edit.png b/docs/zh/08-operation/pic/backup-05-edit.png
new file mode 100644
index 0000000000..5ff1204ad5
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-05-edit.png differ
diff --git a/docs/zh/08-operation/pic/backup-06-copy.png b/docs/zh/08-operation/pic/backup-06-copy.png
new file mode 100644
index 0000000000..2ec1ea68d0
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-06-copy.png differ
diff --git a/docs/zh/08-operation/pic/backup-07-del.png b/docs/zh/08-operation/pic/backup-07-del.png
new file mode 100644
index 0000000000..e1cf4748bf
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-07-del.png differ
diff --git a/docs/zh/08-operation/pic/backup-08-files.png b/docs/zh/08-operation/pic/backup-08-files.png
new file mode 100644
index 0000000000..07f2184d4f
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-08-files.png differ
diff --git a/docs/zh/08-operation/pic/backup-09-filelist.png b/docs/zh/08-operation/pic/backup-09-filelist.png
new file mode 100644
index 0000000000..b963091f36
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-09-filelist.png differ
diff --git a/docs/zh/08-operation/pic/backup-10-restore-create.png b/docs/zh/08-operation/pic/backup-10-restore-create.png
new file mode 100644
index 0000000000..e0e22160d0
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-10-restore-create.png differ
diff --git a/docs/zh/08-operation/pic/backup-11-restore-list.png b/docs/zh/08-operation/pic/backup-11-restore-list.png
new file mode 100644
index 0000000000..ca1f1b45d5
Binary files /dev/null and b/docs/zh/08-operation/pic/backup-11-restore-list.png differ
diff --git a/docs/zh/08-operation/pic/replica2.png b/docs/zh/08-operation/pic/replica2.png
new file mode 100644
index 0000000000..985f7b35c4
Binary files /dev/null and b/docs/zh/08-operation/pic/replica2.png differ
diff --git a/docs/zh/10-third-party/03-visual/01-grafana.mdx b/docs/zh/10-third-party/03-visual/01-grafana.mdx
index d7406352c9..043cfcaa5c 100644
--- a/docs/zh/10-third-party/03-visual/01-grafana.mdx
+++ b/docs/zh/10-third-party/03-visual/01-grafana.mdx
@@ -10,15 +10,11 @@ import TabItem from "@theme/TabItem";
## 概述
本文档介绍如何将 TDengine 数据源与开源数据可视化系统 [Grafana](https://www.grafana.com/) 集成,以实现数据的可视化和监测报警系统的搭建。通过 TDengine 插件,您可以轻松地将 TDengine 数据表的数据展示在 Grafana 仪表盘上,且无需进行复杂的开发工作。
-## Grafana 版本要求
-当前 TDengine 支持 Grafana 7.5 及以上版本,建议使用最新版本。请根据您的系统环境下载并安装对应版本的 Grafana。
-
-
## 前置条件
要让 Grafana 能正常添加 TDengine 数据源,需要以下几方面的准备工作。
-- Grafana 服务已经部署并正常运行。
+- Grafana 服务已经部署并正常运行。当前 TDengine 支持 Grafana 7.5 及以上版本,建议使用最新版本。
**注意**:要确保启动 Grafana 的账号有其安装目录的写权限,否则可能后面无法安装插件。
- TDengine 集群已经部署并正常运行。
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](../../../reference/components/taosadapter)
diff --git a/docs/zh/10-third-party/05-bi/05-yhbi.md b/docs/zh/10-third-party/05-bi/05-yhbi.md
index b60b0495f0..70dda71051 100644
--- a/docs/zh/10-third-party/05-bi/05-yhbi.md
+++ b/docs/zh/10-third-party/05-bi/05-yhbi.md
@@ -10,13 +10,10 @@ toc_max_heading_level: 4
一旦数据源配置完成,永洪BI便能直接从TDengine中读取数据,并利用其强大的数据处理和分析功能,为用户提供丰富的数据展示、分析和预测能力。这意味着用户无须编写复杂的代码或进行烦琐的数据转换工作,即可轻松获取所需的业务洞察。
-## 安装永洪 BI
+## 前置条件
-确保永洪 BI 已经安装并运行(如果未安装,请到永洪科技官方下载页面下载)。
-
-## 安装JDBC驱动
-
-从 maven.org 下载 TDengine JDBC 连接器文件 “taos-jdbcdriver-3.2.7-dist.jar”,并安装在永洪 BI 的机器上。
+- 确保永洪 BI 已经安装并运行(如果未安装,请到永洪科技官方下载页面下载)。
+- 安装JDBC驱动。从 maven.org 下载 TDengine JDBC 连接器文件 “taos-jdbcdriver-3.4.0-dist.jar”,并安装在永洪 BI 的机器上。
## 配置JDBC数据源
diff --git a/docs/zh/10-third-party/05-bi/09-seeq.md b/docs/zh/10-third-party/05-bi/09-seeq.md
index 7e61cdcb11..e01deb7e84 100644
--- a/docs/zh/10-third-party/05-bi/09-seeq.md
+++ b/docs/zh/10-third-party/05-bi/09-seeq.md
@@ -8,16 +8,11 @@ Seeq 是制造业和工业互联网(IIOT)高级分析软件。Seeq 支持在
通过 TDengine Java connector, Seeq 可以轻松支持查询 TDengine 提供的时序数据,并提供数据展现、分析、预测等功能。
-## Seeq 安装方法
+## 前置条件
-从 [Seeq 官网](https://www.seeq.com/customer-download)下载相关软件,例如 Seeq Server 和 Seeq Data Lab 等。Seeq Data Lab 需要安装在和 Seeq Server 不同的服务器上,并通过配置和 Seeq Server 互联。详细安装配置指令参见[Seeq 知识库]( https://support.seeq.com/kb/latest/cloud/)。
+- Seeq 已经安装。从 [Seeq 官网](https://www.seeq.com/customer-download)下载相关软件,例如 Seeq Server 和 Seeq Data Lab 等。Seeq Data Lab 需要安装在和 Seeq Server 不同的服务器上,并通过配置和 Seeq Server 互联。详细安装配置指令参见[Seeq 知识库]( https://support.seeq.com/kb/latest/cloud/)。
-### TDengine 本地实例安装方法
-
-请参考[官网文档](../../../get-started)。
-
-### TDengine Cloud 访问方法
-如果使用 Seeq 连接 TDengine Cloud,请在 https://cloud.taosdata.com 申请帐号并登录查看如何访问 TDengine Cloud。
+- TDengine 本地实例已安装。 请参考[官网文档](../../../get-started)。 若使用 TDengine Cloud,请在 https://cloud.taosdata.com 申请帐号并登录查看如何访问 TDengine Cloud。
## 配置 Seeq 访问 TDengine
diff --git a/docs/zh/10-third-party/05-bi/11-superset.md b/docs/zh/10-third-party/05-bi/11-superset.md
index 5e6252ced0..337fc53825 100644
--- a/docs/zh/10-third-party/05-bi/11-superset.md
+++ b/docs/zh/10-third-party/05-bi/11-superset.md
@@ -4,26 +4,27 @@ title: 与 Superset 集成
---
Apache Superset 是一个现代的企业级商业智能(BI)Web 应用程序,主要用于数据探索和可视化。它由 Apache 软件基金会支持,是一个开源项目,它拥有活跃的社区和丰富的生态系统。Apache Superset 提供了直观的用户界面,使得创建、分享和可视化数据变得简单,同时支持多种数据源和丰富的可视化选项。
-通过 TDengine 的 Python 连接器, Superset 可支持 TDengine 数据源并提供数据展现、分析等功能
+通过 TDengine 的 Python 连接器, Apache Superset 可支持 TDengine 数据源并提供数据展现、分析等功能
-## 安装 Apache Superset
-确保已安装 Apache Superset v2.1.0 及以上版本, 如未安装,请到其 [官网](https://superset.apache.org/) 安装
+## 前置条件
-## 安装 TDengine
+准备以下环境:
+- TDengine 集群已部署并正常运行(企业及社区版均可)
+- taosAdapter 能够正常运行。详细参考 [taosAdapter 使用手册](../../../reference/components/taosadapter)
+- Apache Superset v2.1.0 或以上版本已安装。安装 Apache Superset 请参考 [官方文档](https://superset.apache.org/)
-TDengine 企业版及社区版均可支持,版本要求在 3.0 及以上
## 安装 TDengine Python 连接器
-TDengine Python 连接器从 `v2.1.18` 开始自带 Superset 连接驱动,安装程序会把连接驱动安装到 Superset 相应目录下并向 Superset 提供数据源服务
-Superset 与 TDengine 之间使用 WebSocket 协议连接,所以需另安装支持 WebSocket 连接协议的组件 `taos-ws-py` , 全部安装脚本如下:
+TDengine Python 连接器从 `v2.1.18` 起带 Superset 连接驱动,会安装至 Superset 相应目录下并向 Superset 提供数据源服务
+Superset 与 TDengine 之间使用 WebSocket 协议连接,需安装支持此协议的 `taos-ws-py` 组件, 全部安装脚本如下:
```bash
pip3 install taospy
pip3 install taos-ws-py
```
-## Superset 中配置 TDengine 连接
+## 配置 TDengine 数据源
**第 1 步**,进入新建数据库连接页面 "Superset" → "Setting" → "Database Connections" → "+DATABASE"
**第 2 步**,选择 TDengine 数据库连接。"SUPPORTED DATABASES" 下拉列表中选择 "TDengine" 项。
diff --git a/docs/zh/14-reference/01-components/05-taosx-agent.md b/docs/zh/14-reference/01-components/05-taosx-agent.md
index bf2e6f7e78..1f1276e834 100644
--- a/docs/zh/14-reference/01-components/05-taosx-agent.md
+++ b/docs/zh/14-reference/01-components/05-taosx-agent.md
@@ -12,7 +12,8 @@ sidebar_label: taosX-Agent
- `endpoint`: 必填,`taosX` 的 GRPC 服务地址。
- `token`: 必填,在 `Explorer` 上创建 `Agent` 时,产生的 Token。
- `instanceId`:当前 taosx-agent 服务的实例 ID,如果同一台机器上启动了多个 taosx-agent 实例,必须保证各个实例的实例 ID 互不相同。
-- `compression`: 非必填,可配置为 `ture` 或 `false`, 默认为 `false`。配置为`true`, 则开启 `Agent` 和 `taosX` 通信数据压缩。
+- `compression`: 非必填,可配置为 `true` 或 `false`, 默认为 `false`。配置为`true`, 则开启 `Agent` 和 `taosX` 通信数据压缩。
+- `in_memory_cache_capacity`: 非必填,表示可在内存中缓存的最大消息批次数,可配置为大于 0 的整数。默认为 `64`。
- `log_level`: 非必填,日志级别,默认为 `info`, 同 `taosX` 一样,支持 `error`,`warn`,`info`,`debug`,`trace` 五级。已弃用,请使用 `log.level` 代替。
- `log_keep_days`:非必填,日志保存天数,默认为 `30` 天。已弃用,请使用 `log.keepDays` 代替。
- `log.path`:日志文件存放的目录。
@@ -44,6 +45,10 @@ sidebar_label: taosX-Agent
#
#compression = true
+# In-memory cache capacity
+#
+#in_memory_cache_capacity = 64
+
# log configuration
[log]
# All log files are stored in this directory
diff --git a/docs/zh/14-reference/02-tools/09-taosdump.md b/docs/zh/14-reference/02-tools/09-taosdump.md
index 7afe8721ee..6a4df44f25 100644
--- a/docs/zh/14-reference/02-tools/09-taosdump.md
+++ b/docs/zh/14-reference/02-tools/09-taosdump.md
@@ -4,26 +4,17 @@ sidebar_label: taosdump
toc_max_heading_level: 4
---
-taosdump 是一个支持从运行中的 TDengine 集群备份数据并将备份的数据恢复到相同或另一个运行中的 TDengine 集群中的工具应用程序。
+taosdump 是为开源用户提供的 TDengine 数据备份/恢复工具,备份数据文件采用标准 [ Apache AVRO ](https://avro.apache.org/) 格式,方便与外界生态交换数据。taosdump 提供多种数据备份及恢复选项来满足不同需求,可通过 --help 查看支持的全部选项。
-taosdump 可以用数据库、超级表或普通表作为逻辑数据单元进行备份,也可以对数据库、超级
-表和普通表中指定时间段内的数据记录进行备份。使用时可以指定数据备份的目录路径,如果
-不指定位置,taosdump 默认会将数据备份到当前目录。
-
-如果指定的位置已经有数据文件,taosdump 会提示用户并立即退出,避免数据被覆盖。这意味着同一路径只能被用于一次备份。
-如果看到相关提示,请小心操作。
-
-taosdump 是一个逻辑备份工具,它不应被用于备份任何原始数据、环境设置、
-硬件信息、服务端配置或集群的拓扑结构。taosdump 使用
-[ Apache AVRO ](https://avro.apache.org/)作为数据文件格式来存储备份数据。
## 安装
-taosdump 有两种安装方式:
+taosdump 提供两种安装方式:
-- 安装 taosTools 官方安装包, 请从[发布历史页面](https://docs.taosdata.com/releases/tools/)页面找到 taosTools 并下载安装。
+- taosdump 是 TDengine 安装包中默认安装组件,安装 TDengine 后即可使用,可参考[TDengine 安装](../../../get-started/)
+
+- 单独编译 taos-tools 并安装, 参考 [taos-tools](https://github.com/taosdata/taos-tools) 仓库。
-- 单独编译 taos-tools 并安装, 详情请参考 [taos-tools](https://github.com/taosdata/taos-tools) 仓库。
## 常用使用场景
@@ -31,9 +22,11 @@ taosdump 有两种安装方式:
1. 备份所有数据库:指定 `-A` 或 `--all-databases` 参数;
2. 备份多个指定数据库:使用 `-D db1,db2,...` 参数;
-3. 备份指定数据库中的某些超级表或普通表:使用 `dbname stbname1 stbname2 tbname1 tbname2 ...` 参数,注意这种输入序列第一个参数为数据库名称,且只支持一个数据库,第二个和之后的参数为该数据库中的超级表或普通表名称,中间以空格分隔;
+3. 备份指定数据库中某些超级表或普通表:使用 `dbname stbname1 stbname2 tbname1 tbname2 ...` 参数,注意这种输入序列第一个参数为数据库名称,且只支持一个数据库,第二个和之后的参数为该数据库中的超级表或普通表名称,中间以空格分隔;
4. 备份系统 log 库:TDengine 集群通常会包含一个系统数据库,名为 `log`,这个数据库内的数据为 TDengine 自我运行的数据,taosdump 默认不会对 log 库进行备份。如果有特定需求对 log 库进行备份,可以使用 `-a` 或 `--allow-sys` 命令行参数。
5. “宽容”模式备份:taosdump 1.4.1 之后的版本提供 `-n` 参数和 `-L` 参数,用于备份数据时不使用转义字符和“宽容”模式,可以在表名、列名、标签名没使用转义字符的情况下减少备份数据时间和备份数据占用空间。如果不确定符合使用 `-n` 和 `-L` 条件时请使用默认参数进行“严格”模式进行备份。转义字符的说明请参考[官方文档](../../taos-sql/escape)。
+6. `-o` 参数指定的目录下如果已存在备份文件,为防止数据被覆盖,taosdump 会报错并退出,请更换其它空目录或清空原来数据后再备份。
+7. 目前 taosdump 不支持数据断点继备功能,一旦数据备份中断,需要从头开始。如果备份需要很长时间,建议使用(-S -E 选项)指定开始/结束时间进行分段备份的方法,
:::tip
- taosdump 1.4.1 之后的版本提供 `-I` 参数,用于解析 avro 文件 schema 和数据,如果指定 `-s` 参数将只解析 schema。
@@ -45,7 +38,9 @@ taosdump 有两种安装方式:
### taosdump 恢复数据
-恢复指定路径下的数据文件:使用 `-i` 参数加上数据文件所在路径。如前面提及,不应该使用同一个目录备份不同数据集合,也不应该在同一路径多次备份同一数据集,否则备份数据会造成覆盖或多次备份。
+- 恢复指定路径下的数据文件:使用 `-i` 参数加上数据文件所在路径。如前面提及,不应该使用同一个目录备份不同数据集合,也不应该在同一路径多次备份同一数据集,否则备份数据会造成覆盖或多次备份。
+- taosdump 支持数据恢复至新数据库名下,参数是 -W, 详细见命令行参数说明。
+
:::tip
taosdump 内部使用 TDengine stmt binding API 进行恢复数据的写入,为提高数据恢复性能,目前使用 16384 为一次写入批次。如果备份数据中有比较多列数据,可能会导致产生 "WAL size exceeds limit" 错误,此时可以通过使用 `-B` 参数调整为一个更小的值进行尝试。
@@ -108,6 +103,13 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
the table name.(Version 2.5.3)
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
8.
+ -W, --rename=RENAME-LIST Rename database name with new name during
+ importing data. RENAME-LIST:
+ "db1=newDB1|db2=newDB2" means rename db1 to newDB1
+ and rename db2 to newDB2 (Version 2.5.4)
+ -k, --retry-count=VALUE Set the number of retry attempts for connection or
+ query failures
+ -z, --retry-sleep-ms=VALUE retry interval sleep time, unit ms
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
-R, --restful Use RESTful interface to connect TDengine
-t, --timeout=SECONDS The timeout seconds for websocket to interact.
@@ -115,10 +117,6 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
-?, --help Give this help list
--usage Give a short usage message
-V, --version Print program version
- -W, --rename=RENAME-LIST Rename database name with new name during
- importing data. RENAME-LIST:
- "db1=newDB1|db2=newDB2" means rename db1 to newDB1
- and rename db2 to newDB2 (Version 2.5.4)
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
diff --git a/docs/zh/14-reference/02-tools/10-taosbenchmark.md b/docs/zh/14-reference/02-tools/10-taosbenchmark.md
index d655290577..44dab0ad5f 100644
--- a/docs/zh/14-reference/02-tools/10-taosbenchmark.md
+++ b/docs/zh/14-reference/02-tools/10-taosbenchmark.md
@@ -4,59 +4,59 @@ sidebar_label: taosBenchmark
toc_max_heading_level: 4
---
-taosBenchmark (曾用名 taosdemo ) 是一个用于测试 TDengine 产品性能的工具。taosBenchmark 可以测试 TDengine 的插入、查询和订阅等功能的性能,它可以模拟由大量设备产生的大量数据,还可以灵活地控制数据库、超级表、标签列的数量和类型、数据列的数量和类型、子表的数量、每张子表的数据量、插入数据的时间间隔、taosBenchmark 的工作线程数量、是否以及如何插入乱序数据等。为了兼容过往用户的使用习惯,安装包提供 了 taosdemo 作为 taosBenchmark 的软链接。
+taosBenchmark 是 TDengine 产品性能基准测试工具,提供对 TDengine 产品写入、查询及订阅性能测试,输出性能指标。
## 安装
-taosBenchmark 有两种安装方式:
+taosBenchmark 提供两种安装方式:
-- 安装 TDengine 官方安装包的同时会自动安装 taosBenchmark, 详情请参考[ TDengine 安装](../../../get-started/)。
+- taosBenchmark 是 TDengine 安装包中默认安装组件,安装 TDengine 后即可使用,参考 [TDengine 安装](../../../get-started/)
-- 单独编译 taos-tools 并安装, 详情请参考 [taos-tools](https://github.com/taosdata/taos-tools) 仓库。
+- 单独编译 taos-tools 并安装, 参考 [taos-tools](https://github.com/taosdata/taos-tools) 仓库。
## 运行
-### 配置和运行方式
+### 运行方式
-taosBenchmark 需要在操作系统的终端执行,该工具支持两种配置方式:[命令行参数](#命令行参数详解) 和 [JSON 配置文件](#配置文件参数详解)。这两种方式是互斥的,在使用配置文件时只能使用一个命令行参数 `-f ` 指定配置文件。在使用命令行参数运行 taosBenchmark 并控制其行为时则不能使用 `-f` 参数而要用其它参数来进行配置。除此之外,taosBenchmark 还提供了一种特殊的运行方式,即无参数运行。
+taosBenchmark 支持三种运行模式:
+- 无参数模式
+- 命令行模式
+- JSON 配置文件模式
+`命令行方式` 为 `JSON 配置文件方式` 功能子集,两者都使用时,命令行方式优先。
-taosBenchmark 支持对 TDengine 做完备的性能测试,其所支持的 TDengine 功能分为三大类:写入、查询和订阅。这三种功能之间是互斥的,每次运行 taosBenchmark 只能选择其中之一。值得注意的是,所要测试的功能类型在使用命令行配置方式时是不可配置的,命令行配置方式只能测试写入性能。若要测试 TDengine 的查询和订阅性能,必须使用配置文件的方式,通过配置文件中的参数 `filetype` 指定所要测试的功能类型。
**在运行 taosBenchmark 之前要确保 TDengine 集群已经在正确运行。**
### 无命令行参数运行
-执行下列命令即可快速体验 taosBenchmark 对 TDengine 进行基于默认配置的写入性能测试。
-
```bash
taosBenchmark
```
-在无参数运行时,taosBenchmark 默认连接 `/etc/taos` 下指定的 TDengine 集群,并在 TDengine 中创建一个名为 test 的数据库,test 数据库下创建名为 meters 的一张超级表,超级表下创建 10000 张表,每张表中写入 10000 条记录。注意,如果已有 test 数据库,这个命令会先删除该数据库后建立一个全新的 test 数据库。
+在无参数运行时,taosBenchmark 默认连接 `/etc/taos/taos.cfg` 中指定的 TDengine 集群。
+连接成功后,会默认创建智能电表示例数据库 test,创建超级表 meters, 创建子表 1 万,每子写入数据 1 万条,若 test 库已存在,默认会先删再建。
-### 使用命令行配置参数运行
-
-在使用命令行参数运行 taosBenchmark 并控制其行为时,`-f ` 参数不能使用。所有配置参数都必须通过命令行指定。以下是使用命令行方式测试 taosBenchmark 写入性能的一个示例。
+### 使用命令行参数运行
+命令行支持的参数为写入功能中使用较为频繁的参数,查询与订阅功能不支持命令行方式
+示例:
```bash
-taosBenchmark -I stmt -n 200 -t 100
+taosBenchmark -d db -t 100 -n 1000 -T 4 -I stmt -y
```
-上面的命令 `taosBenchmark` 将创建一个名为`test`的数据库,在其中建立一张超级表`meters`,在该超级表中建立 100 张子表并使用参数绑定的方式为每张子表插入 200 条记录。
+此命令表示使用 `taosBenchmark` 将创建一个名为 `db` 的数据库,并建立默认超级表 `meters`,子表 100 ,使用参数绑定(stmt)方式为每张子表写入 1000 条记录。
### 使用配置文件运行
-taosBenchmark 安装包中提供了配置文件的示例,位于 `/examples/taosbenchmark-json` 下
-
-使用如下命令行即可运行 taosBenchmark 并通过配置文件控制其行为。
+配置文件方式运行提供了全部功能,所有命令行参数都可以在配置文件中配置运行
```bash
taosBenchmark -f
```
-**下面是几个配置文件的示例:**
+**下面为支持的写入、查询、订阅三大功能的配置文件示例:**
-#### 插入场景 JSON 配置文件示例
+#### 写入场景 JSON 配置文件示例
insert.json
@@ -89,130 +89,102 @@ taosBenchmark -f
+查看更多 json 配置文件示例可 [点击这里](https://github.com/taosdata/taos-tools/tree/main/example)
+
## 命令行参数详解
+| 命令行参数 | 功能说明 |
+| ---------------------------- | ----------------------------------------------- |
+| -f/--file \ | 要使用的 JSON 配置文件,由该文件指定所有参数,本参数与命令行其他参数不能同时使用。没有默认值 |
+| -c/--config-dir \ | TDengine 集群配置文件所在的目录,默认路径是 /etc/taos |
+| -h/--host \ | 指定要连接的 TDengine 服务端的 FQDN,默认值为 localhost |
+| -P/--port \ | 要连接的 TDengine 服务器的端口号,默认值为 6030 |
+| -I/--interface \ | 插入模式,可选项有 taosc, rest, stmt, sml, sml-rest, 分别对应普通写入、restful 接口写入、参数绑定接口写入、schemaless 接口写入、restful schemaless 接口写入 (由 taosAdapter 提供)。默认值为 taosc |
+| -u/--user \ | 用于连接 TDengine 服务端的用户名,默认为 root |
+| -U/--supplement-insert | 写入数据而不提前建数据库和表,默认关闭 |
+| -p/--password \ | 用于连接 TDengine 服务端的密码,默认值为 taosdata |
+| -o/--output \ | 结果输出文件的路径,默认值为 ./output.txt |
+| -T/--thread \ | 插入数据的线程数量,默认为 8 |
+| -B/--interlace-rows \ |启用交错插入模式并同时指定向每个子表每次插入的数据行数。交错插入模式是指依次向每张子表插入由本参数所指定的行数并重复这个过程,直到所有子表的数据都插入完成。默认值为 0, 即向一张子表完成数据插入后才会向下一张子表进行数据插入 |
+| -i/--insert-interval \ | 指定交错插入模式的插入间隔,单位为 ms,默认值为 0。 只有当 `-B/--interlace-rows` 大于 0 时才起作用 |意味着数据插入线程在为每个子表插入隔行扫描记录后,会等待该值指定的时间间隔后再进行下一轮写入 |
+| -r/--rec-per-req \ | 每次向 TDengine 请求写入的数据行数,默认值为 30000 |
+| -t/--tables \ | 指定子表的数量,默认为 10000 |
+| -S/--timestampstep \ | 每个子表中插入数据的时间戳步长,单位是 ms,默认值是 1 |
+| -n/--records \ | 每个子表插入的记录数,默认值为 10000 |
+| -d/--database \ | 所使用的数据库的名称,默认值为 test |
+| -b/--data-type \ | 指定超级表普通列数据类型, 多个使用逗号分隔,默认值: "FLOAT,INT,FLOAT" 如:`taosBenchmark -b "FLOAT,BINARY(8),NCHAR(16)"`|
+| -A/--tag-type \ | 指定超级表标签列数据类型,多个使用逗号分隔,默认值: "INT,BINARY(24)" 如:`taosBenchmark -A "INT,BINARY(8),NCHAR(8)"`|
+| -l/--columns \ | 超级表的数据列的总数量。如果同时设置了该参数和 `-b/--data-type`,则最后的结果列数为两者取大。如果本参数指定的数量大于 `-b/--data-type` 指定的列数,则未指定的列类型默认为 INT, 例如: `-l 5 -b float,double`, 那么最后的列为 `FLOAT,DOUBLE,INT,INT,INT`。如果 columns 指定的数量小于或等于 `-b/--data-type` 指定的列数,则结果为 `-b/--data-type` 指定的列和类型,例如: `-l 3 -b float,double,float,bigint`,那么最后的列为 `FLOAT,DOUBLE,FLOAT,BIGINT` |
+| -L/--partial-col-num \ | 指定某些列写入数据,其他列数据为 NULL。默认所有列都写入数据 |
+| -w/--binwidth \ | nchar 和 binary 类型的默认长度,默认值为 64 |
+| -m/--table-prefix \ | 子表名称的前缀,默认值为 "d" |
+| -E/--escape-character | 开关参数,指定在超级表和子表名称中是否使用转义字符。默认值为不使用 |
+| -C/--chinese | 开关参数,指定 nchar 和 binary 是否使用 Unicode 中文字符。默认值为不使用 |
+| -N/--normal-table | 开关参数,指定只创建普通表,不创建超级表。默认值为 false。仅当插入模式为 taosc, stmt, rest 模式下可以使用 |
+| -M/--random | 开关参数,插入数据为生成的随机值。默认值为 false。若配置此参数,则随机生成要插入的数据。对于数值类型的 标签列/数据列,其值为该类型取值范围内的随机值。对于 NCHAR 和 BINARY 类型的 标签列/数据列,其值为指定长度范围内的随机字符串 |
+| -x/--aggr-func | 开关参数,指示插入后查询聚合函数。默认值为 false |
+| -y/--answer-yes | 开关参数,要求用户在提示后确认才能继续 |默认值为 false 。
+| -O/--disorder \ | 指定乱序数据的百分比概率,其值域为 [0,50]。默认为 0,即没有乱序数据 |
+| -R/--disorder-range \ | 指定乱序数据的时间戳回退范围。所生成的乱序时间戳为非乱序情况下应该使用的时间戳减去这个范围内的一个随机值。仅在 `-O/--disorder` 指定的乱序数据百分比大于 0 时有效|
+| -F/--prepare_rand \ | 生成的随机数据中唯一值的数量。若为 1 则表示所有数据都相同。默认值为 10000 |
+| -a/--replica \ | 创建数据库时指定其副本数,默认值为 1 |
+| -k/--keep-trying \ | 失败后进行重试的次数,默认不重试。需使用 v3.0.9 以上版本|
+| -z/--trying-interval \ | 失败重试间隔时间,单位为毫秒,仅在 -k 指定重试后有效。需使用 v3.0.9 以上版本 |
+| -v/--vgroups \ | 创建数据库时指定 vgroups 数,仅对 TDengine v3.0+ 有效|
+| -V/--version | 显示版本信息并退出。不能与其它参数混用|
+| -?/--help | 显示帮助信息并退出。不能与其它参数混用|
-- **-f/--file \** :
- 要使用的 JSON 配置文件,由该文件指定所有参数,本参数与命令行其他参数不能同时使用。没有默认值。
-- **-c/--config-dir \** :
- TDengine 集群配置文件所在的目录,默认路径是 /etc/taos 。
+## 输出性能指标
-- **-h/--host \** :
- 指定要连接的 TDengine 服务端的 FQDN,默认值为 localhost 。
-
-- **-P/--port \** :
- 要连接的 TDengine 服务器的端口号,默认值为 6030 。
-
-- **-I/--interface \** :
- 插入模式,可选项有 taosc, rest, stmt, sml, sml-rest, 分别对应普通写入、restful 接口写入、参数绑定接口写入、schemaless 接口写入、restful schemaless 接口写入 (由 taosAdapter 提供)。默认值为 taosc。
-
-- **-u/--user \** :
- 用于连接 TDengine 服务端的用户名,默认为 root 。
-
-- **-U/--supplement-insert ** :
- 写入数据而不提前建数据库和表,默认关闭。
-
-- **-p/--password \** :
- 用于连接 TDengine 服务端的密码,默认值为 taosdata。
-
-- **-o/--output \** :
- 结果输出文件的路径,默认值为 ./output.txt。
-
-- **-T/--thread \** :
- 插入数据的线程数量,默认为 8 。
-
-- **-B/--interlace-rows \** :
- 启用交错插入模式并同时指定向每个子表每次插入的数据行数。交错插入模式是指依次向每张子表插入由本参数所指定的行数并重复这个过程,直到所有子表的数据都插入完成。默认值为 0, 即向一张子表完成数据插入后才会向下一张子表进行数据插入。
-
-- **-i/--insert-interval \** :
- 指定交错插入模式的插入间隔,单位为 ms,默认值为 0。 只有当 `-B/--interlace-rows` 大于 0 时才起作用。意味着数据插入线程在为每个子表插入隔行扫描记录后,会等待该值指定的时间间隔后再进行下一轮写入。
-
-- **-r/--rec-per-req \** :
- 每次向 TDengine 请求写入的数据行数,默认值为 30000 。
-
-- **-t/--tables \** :
- 指定子表的数量,默认为 10000 。
-
-- **-S/--timestampstep \** :
- 每个子表中插入数据的时间戳步长,单位是 ms,默认值是 1。
-
-- **-n/--records \** :
- 每个子表插入的记录数,默认值为 10000 。
-
-- **-d/--database \** :
- 所使用的数据库的名称,默认值为 test 。
-
-- **-b/--data-type \** :
- 超级表的数据列的类型。如果不使用则默认为有三个数据列,其类型分别为 FLOAT, INT, FLOAT 。
-
-- **-l/--columns \** :
- 超级表的数据列的总数量。如果同时设置了该参数和 `-b/--data-type`,则最后的结果列数为两者取大。如果本参数指定的数量大于 `-b/--data-type` 指定的列数,则未指定的列类型默认为 INT, 例如: `-l 5 -b float,double`, 那么最后的列为 `FLOAT,DOUBLE,INT,INT,INT`。如果 columns 指定的数量小于或等于 `-b/--data-type` 指定的列数,则结果为 `-b/--data-type` 指定的列和类型,例如: `-l 3 -b float,double,float,bigint`,那么最后的列为 `FLOAT,DOUBLE,FLOAT,BIGINT` 。
-
-- **-L/--partial-col-num \ **:
- 指定某些列写入数据,其他列数据为 NULL。默认所有列都写入数据。
-
-- **-A/--tag-type \** :
- 超级表的标签列类型。nchar 和 binary 类型可以同时设置长度,例如:
+#### 写入指标
+写入结束后会在最后两行输出总体性能指标,格式如下:
+``` bash
+SUCC: Spent 8.527298 (real 8.117379) seconds to insert rows: 10000000 with 8 thread(s) into test 1172704.41 (real 1231924.74) records/second
+SUCC: insert delay, min: 19.6780ms, avg: 64.9390ms, p90: 94.6900ms, p95: 105.1870ms, p99: 130.6660ms, max: 157.0830ms
```
-taosBenchmark -A INT,DOUBLE,NCHAR,BINARY(16)
+第一行写入速度统计:
+ - Spent: 写入总耗时,单位秒,从开始写入第一个数据开始计时到最后一条数据结束,这里表示共花了 8.527298 秒
+ - real : 写入总耗时(调用引擎),此耗时已抛去测试框架准备数据时间,纯统计在引擎调用上花费的时间,示例为 8.117379 秒,8.527298 - 8.117379 = 0.409919 秒则为测试框架准备数据消耗时间
+ - rows : 写入总行数,为 1000 万条数据
+ - threads: 写入线程数,这里是 8 个线程同时写入
+ - records/second 写入速度 = `写入总耗时`/ `写入总行数` , 括号中 `real` 同前,表示纯引擎写入速度
+第二行单个写入延时统计:
+ - min : 写入最小延时
+ - avg : 写入平时延时
+ - p90 : 写入延时 p90 百分位上的延时数
+ - p95 : 写入延时 p95 百分位上的延时数
+ - p99 : 写入延时 p99 百分位上的延时数
+ - max : 写入最大延时
+通过此系列指标,可观察到写入请求延时分布情况
+
+#### 查询指标
+
+查询性能测试主要输出查询请求速度 QPS 指标, 输出格式如下:
+``` bash
+complete query with 3 threads and 10000 query delay avg: 0.002686s min: 0.001182s max: 0.012189s p90: 0.002977s p95: 0.003493s p99: 0.004645s SQL command: select ...
+INFO: Total specified queries: 30000
+INFO: Spend 26.9530 second completed total queries: 30000, the QPS of all threads: 1113.049
```
+- 第一行表示 3 个线程每个线程执行 10000 次查询及查询请求延时百分位分布情况,`SQL command` 为测试的查询语句
+- 第二行表示总共完成了 10000 * 3 = 30000 次查询总数
+- 第三行表示查询总耗时为 26.9653 秒,每秒查询率(QPS)为:1113.049 次/秒
-如果没有设置标签类型,默认是两个标签,其类型分别为 INT 和 BINARY(16)。
-注意:在有的 shell 比如 bash 命令里面 “()” 需要转义,则上述指令应为:
+#### 订阅指标
+订阅性能测试主要输出消费者消费速度指标,输出格式如下:
+``` bash
+INFO: consumer id 0 has poll total msgs: 376, period rate: 37.592 msgs/s, total rows: 3760000, period rate: 375924.815 rows/s
+INFO: consumer id 1 has poll total msgs: 362, period rate: 36.131 msgs/s, total rows: 3620000, period rate: 361313.504 rows/s
+INFO: consumer id 2 has poll total msgs: 364, period rate: 36.378 msgs/s, total rows: 3640000, period rate: 363781.731 rows/s
+INFO: consumerId: 0, consume msgs: 1000, consume rows: 10000000
+INFO: consumerId: 1, consume msgs: 1000, consume rows: 10000000
+INFO: consumerId: 2, consume msgs: 1000, consume rows: 10000000
+INFO: Consumed total msgs: 3000, total rows: 30000000
```
-taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
-```
-
-- **-w/--binwidth \**:
- nchar 和 binary 类型的默认长度,默认值为 64。
-
-- **-m/--table-prefix \** :
- 子表名称的前缀,默认值为 "d"。
-
-- **-E/--escape-character** :
- 开关参数,指定在超级表和子表名称中是否使用转义字符。默认值为不使用。
-
-- **-C/--chinese** :
- 开关参数,指定 nchar 和 binary 是否使用 Unicode 中文字符。默认值为不使用。
-
-- **-N/--normal-table** :
- 开关参数,指定只创建普通表,不创建超级表。默认值为 false。仅当插入模式为 taosc, stmt, rest 模式下可以使用。
-
-- **-M/--random** :
- 开关参数,插入数据为生成的随机值。默认值为 false。若配置此参数,则随机生成要插入的数据。对于数值类型的 标签列/数据列,其值为该类型取值范围内的随机值。对于 NCHAR 和 BINARY 类型的 标签列/数据列,其值为指定长度范围内的随机字符串。
-
-- **-x/--aggr-func** :
- 开关参数,指示插入后查询聚合函数。默认值为 false。
-
-- **-y/--answer-yes** :
- 开关参数,要求用户在提示后确认才能继续。默认值为 false 。
-
-- **-O/--disorder \** :
- 指定乱序数据的百分比概率,其值域为 [0,50]。默认为 0,即没有乱序数据。
-
-- **-R/--disorder-range \** :
- 指定乱序数据的时间戳回退范围。所生成的乱序时间戳为非乱序情况下应该使用的时间戳减去这个范围内的一个随机值。仅在 `-O/--disorder` 指定的乱序数据百分比大于 0 时有效。
-
-- **-F/--prepare_rand \** :
- 生成的随机数据中唯一值的数量。若为 1 则表示所有数据都相同。默认值为 10000 。
-
-- **-a/--replica \** :
- 创建数据库时指定其副本数,默认值为 1 。
-
-- ** -k/--keep-trying \** : 失败后进行重试的次数,默认不重试。需使用 v3.0.9 以上版本。
-
-- ** -z/--trying-interval \** : 失败重试间隔时间,单位为毫秒,仅在 -k 指定重试后有效。需使用 v3.0.9 以上版本。
-
-- **-v/--vgroups \** :
- 创建数据库时指定 vgroups 数,仅对 TDengine v3.0+ 有效。
-
-- **-V/--version** :
- 显示版本信息并退出。不能与其它参数混用。
-
-- **-?/--help** :
- 显示帮助信息并退出。不能与其它参数混用。
+- 1 ~ 3 行实时输出每个消费者当前的消费速度,`msgs/s` 表示消费消息个数,每个消息中包含多行数据,`rows/s` 表示按行数统计的消费速度
+- 4 ~ 6 行是测试完成后每个消费者总体统计,统计共消费了多少条消息,共计多少行
+- 第 7 行所有消费者总体统计,`msgs` 表示共消费了多少条消息, `rows` 表示共消费了多少行数据
## 配置文件参数详解
@@ -220,7 +192,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
本节所列参数适用于所有功能模式。
-- **filetype** : 要测试的功能,可选值为 `insert`, `query` 和 `subscribe`。分别对应插入、查询和订阅功能。每个配置文件中只能指定其中之一。
+- **filetype** : 功能分类,可选值为 `insert`, `query` 和 `subscribe`。分别对应插入、查询和订阅功能。每个配置文件中只能指定其中之一。
- **cfgdir** : TDengine 客户端配置文件所在的目录,默认路径是 /etc/taos 。
- **host** : 指定要连接的 TDengine 服务端的 FQDN,默认值为 localhost。
@@ -252,7 +224,7 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
- **name** : 数据库名。
-- **drop** : 插入前是否删除数据库,可选项为 "yes" 或者 "no", 为 "no" 时不创建。默认删除。
+- **drop** : 数据库已存在时是否删除重建,可选项为 "yes" 或 "no", 默认为 “yes”
#### 流式计算相关配置参数
@@ -331,21 +303,6 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
- **repeat_ts_max** : 数值类型,复合主键开启情况下指定生成相同时间戳记录的最大个数
- **sqls** : 字符串数组类型,指定超级表创建成功后要执行的 sql 数组,sql 中指定表名前面要带数据库名,否则会报未指定数据库错误
-#### tsma配置参数
-
-指定tsma的配置参数在 `super_tables` 中的 `tsmas` 中,具体参数如下。
-
-- **name** : 指定 tsma 的名字,必选项。
-
-- **function** : 指定 tsma 的函数,必选项。
-
-- **interval** : 指定 tsma 的时间间隔,必选项。
-
-- **sliding** : 指定 tsma 的窗口时间位移,必选项。
-
-- **custom** : 指定 tsma 的创建语句结尾追加的自定义配置,可选项。
-
-- **start_when_inserted** : 指定当插入多少行时创建 tsma,可选项,默认为 0。
#### 标签列与数据列配置参数
@@ -415,7 +372,8 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
查询场景下 `filetype` 必须设置为 `query`。
`query_times` 指定运行查询的次数,数值类型
-查询场景可以通过设置 `kill_slow_query_threshold` 和 `kill_slow_query_interval` 参数来控制杀掉慢查询语句的执行,threshold 控制如果 exec_usec 超过指定时间的查询将被 taosBenchmark 杀掉,单位为秒;interval 控制休眠时间,避免持续查询慢查询消耗 CPU ,单位为秒。
+查询场景可以通过设置 `kill_slow_query_threshold` 和 `kill_slow_query_interval` 参数来控制杀掉慢查询语句的执行,threshold 控制如果 exec_usec 超过指定时间的查询将被 taosBenchmark 杀掉,单位为秒;
+interval 控制休眠时间,避免持续查询慢查询消耗 CPU ,单位为秒。
其它通用参数详见[通用配置参数](#通用配置参数)。
@@ -423,6 +381,11 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
查询指定表(可以指定超级表、子表或普通表)的配置参数在 `specified_table_query` 中设置。
+- **mixed_query** : 查询模式,取值 “yes” 为`混合查询`, "no" 为`正常查询` , 默认值为 “no”
+ `混合查询`:`sqls` 中所有 sql 按 `threads` 线程数分组,每个线程执行一组, 线程中每个 sql 都需执行 `query_times` 次查询
+ `正常查询`:`sqls` 中每个 sql 启动 `threads` 个线程,每个线程执行完 `query_times` 次后退出,下个 sql 需等待上个 sql 线程全部执行完退出后方可执行
+ 不管 `正常查询` 还是 `混合查询` ,执行查询总次数是相同的 ,查询总次数 = `sqls` 个数 * `threads` * `query_times`, 区别是 `正常查询` 每个 sql 都会启动 `threads` 个线程,而 `混合查询` 只启动一次 `threads` 个线程执行完所有 SQL, 两者启动线程次数不一样。
+
- **query_interval** : 查询时间间隔,单位是秒,默认值为 0。
- **threads** : 执行查询 SQL 的线程数,默认值为 1。
@@ -433,7 +396,8 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
#### 查询超级表的配置参数
-查询超级表的配置参数在 `super_table_query` 中设置。
+查询超级表的配置参数在 `super_table_query` 中设置。
+超级表查询的线程模式与上面介绍的指定查询语句查询的 `正常查询` 模式相同,不同之处是本 `sqls` 使用所有子表填充。
- **stblname** : 指定要查询的超级表的名称,必填。
diff --git a/docs/zh/14-reference/09-error-code.md b/docs/zh/14-reference/09-error-code.md
index 2bebe2406b..51453cef4c 100644
--- a/docs/zh/14-reference/09-error-code.md
+++ b/docs/zh/14-reference/09-error-code.md
@@ -403,7 +403,7 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x8000260D | Tags number not matched | tag列个数不匹配 | 检查并修正SQL语句 |
| 0x8000260E | Invalid tag name | 无效或不存在的tag名 | 检查并修正SQL语句 |
| 0x80002610 | Value is too long | 值长度超出限制 | 检查并修正SQL语句或API参数 |
-| 0x80002611 | Password can not be empty | 密码为空 | 使用合法的密码 |
+| 0x80002611 | Password too short or empty | 密码为空或少于 8 个字符 | 使用合法的密码 |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | 端口号非法 | 检查并修正端口号 |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | 地址格式错误 | 检查并修正地址信息 |
| 0x80002614 | This statement is no longer supported | 功能已经废弃 | 参考功能文档说明 |
diff --git a/docs/zh/26-tdinternal/aggquery.png b/docs/zh/26-tdinternal/aggquery.png
index 8e2094eb8c..50123b939c 100644
Binary files a/docs/zh/26-tdinternal/aggquery.png and b/docs/zh/26-tdinternal/aggquery.png differ
diff --git a/docs/zh/26-tdinternal/cache.png b/docs/zh/26-tdinternal/cache.png
index a5ff851a78..acc4569ae5 100644
Binary files a/docs/zh/26-tdinternal/cache.png and b/docs/zh/26-tdinternal/cache.png differ
diff --git a/docs/zh/26-tdinternal/compression.png b/docs/zh/26-tdinternal/compression.png
index 80f027ffd2..173990a838 100644
Binary files a/docs/zh/26-tdinternal/compression.png and b/docs/zh/26-tdinternal/compression.png differ
diff --git a/docs/zh/26-tdinternal/streamarch.png b/docs/zh/26-tdinternal/streamarch.png
index 92a2b61d39..5f1b017dad 100644
Binary files a/docs/zh/26-tdinternal/streamarch.png and b/docs/zh/26-tdinternal/streamarch.png differ
diff --git a/docs/zh/26-tdinternal/streamtask.png b/docs/zh/26-tdinternal/streamtask.png
index fc132c5c76..fa09f55592 100644
Binary files a/docs/zh/26-tdinternal/streamtask.png and b/docs/zh/26-tdinternal/streamtask.png differ
diff --git a/docs/zh/26-tdinternal/taskarch.png b/docs/zh/26-tdinternal/taskarch.png
index d9fae4908d..37b2369fbb 100644
Binary files a/docs/zh/26-tdinternal/taskarch.png and b/docs/zh/26-tdinternal/taskarch.png differ
diff --git a/include/common/tanalytics.h b/include/common/tanalytics.h
index d0af84ecfb..6ebdb38fa6 100644
--- a/include/common/tanalytics.h
+++ b/include/common/tanalytics.h
@@ -28,8 +28,8 @@ extern "C" {
#define ANAL_FORECAST_DEFAULT_ROWS 10
#define ANAL_FORECAST_DEFAULT_CONF 95
#define ANAL_FORECAST_DEFAULT_WNCHECK 1
-#define ANAL_FORECAST_MAX_ROWS 10000
-#define ANAL_ANOMALY_WINDOW_MAX_ROWS 10000
+#define ANAL_FORECAST_MAX_ROWS 40000
+#define ANAL_ANOMALY_WINDOW_MAX_ROWS 40000
typedef struct {
EAnalAlgoType type;
diff --git a/include/common/tglobal.h b/include/common/tglobal.h
index e6333d2ddc..584c4b5775 100644
--- a/include/common/tglobal.h
+++ b/include/common/tglobal.h
@@ -114,6 +114,7 @@ extern int32_t tsRetentionSpeedLimitMB;
extern const char *tsAlterCompactTaskKeywords;
extern int32_t tsNumOfCompactThreads;
+extern int32_t tsNumOfRetentionThreads;
// sync raft
extern int32_t tsElectInterval;
@@ -291,6 +292,7 @@ extern bool tsFilterScalarMode;
extern int32_t tsMaxStreamBackendCache;
extern int32_t tsPQSortMemThreshold;
extern int32_t tsResolveFQDNRetryTime;
+extern bool tsStreamCoverage;
extern bool tsExperimental;
// #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
@@ -323,6 +325,8 @@ void printConfigNotMatch(SArray *array);
int32_t compareSConfigItemArrays(SArray *mArray, const SArray *dArray, SArray *diffArray);
bool isConifgItemLazyMode(SConfigItem *item);
+int32_t taosUpdateTfsItemDisable(SConfig *pCfg, const char *value, void *pTfs);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/libs/function/function.h b/include/libs/function/function.h
index 0ca1962b4e..126ed2c9b0 100644
--- a/include/libs/function/function.h
+++ b/include/libs/function/function.h
@@ -288,6 +288,7 @@ struct SScalarParam {
bool colAlloced;
SColumnInfoData *columnData;
SHashObj *pHashFilter;
+ SHashObj *pHashFilterOthers;
int32_t hashValueType;
void *param; // other parameter, such as meta handle from vnode, to extract table name/tag value
int32_t numOfRows;
diff --git a/include/libs/function/tudf.h b/include/libs/function/tudf.h
index 52cb847b6f..2c7e6216f5 100644
--- a/include/libs/function/tudf.h
+++ b/include/libs/function/tudf.h
@@ -109,8 +109,9 @@ int32_t doCallUdfAggProcess(UdfcFuncHandle handle, SSDataBlock *block, SUdfInter
int32_t doCallUdfAggFinalize(UdfcFuncHandle handle, SUdfInterBuf *interBuf, SUdfInterBuf *resultData);
// input: interbuf1, interbuf2
// output: resultBuf
-int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
- SUdfInterBuf *resultBuf);
+// udf todo: aggmerge
+// int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
+// SUdfInterBuf *resultBuf);
// input: block
// output: resultData
int32_t doCallUdfScalarFunc(UdfcFuncHandle handle, SScalarParam *input, int32_t numOfCols, SScalarParam *output);
diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h
index fd936dd087..67fd954ad7 100644
--- a/include/libs/scalar/scalar.h
+++ b/include/libs/scalar/scalar.h
@@ -40,7 +40,7 @@ pDst need to freed in caller
int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst);
int32_t scalarGetOperatorParamNum(EOperatorType type);
-int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type);
+int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type, int8_t processType);
int32_t vectorGetConvertType(int32_t type1, int32_t type2);
int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut, int32_t *overflow, int32_t startIndex, int32_t numOfRows);
diff --git a/include/libs/tfs/tfs.h b/include/libs/tfs/tfs.h
index 446c1d6fd7..a6a3c63a50 100644
--- a/include/libs/tfs/tfs.h
+++ b/include/libs/tfs/tfs.h
@@ -319,6 +319,15 @@ bool tfsDiskSpaceAvailable(STfs *pTfs, int32_t level);
*/
bool tfsDiskSpaceSufficient(STfs *pTfs, int32_t level, int32_t disk);
+/**
+ * @brief Update disk size of tfs.
+ *
+ * @param pTfs The fs object.
+ * @param dir The directory.
+ * @param disable The disable flag.
+ */
+int32_t tfsUpdateDiskDisable(STfs *pTfs, const char *dir, int8_t disable);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/util/taoserror.h b/include/util/taoserror.h
index 64ef0b3829..e317fdd65a 100644
--- a/include/util/taoserror.h
+++ b/include/util/taoserror.h
@@ -801,7 +801,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_PAR_TAGS_NOT_MATCHED TAOS_DEF_ERROR_CODE(0, 0x260D)
#define TSDB_CODE_PAR_INVALID_TAG_NAME TAOS_DEF_ERROR_CODE(0, 0x260E)
#define TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG TAOS_DEF_ERROR_CODE(0, 0x2610)
-#define TSDB_CODE_PAR_PASSWD_EMPTY TAOS_DEF_ERROR_CODE(0, 0x2611)
+#define TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY TAOS_DEF_ERROR_CODE(0, 0x2611)
#define TSDB_CODE_PAR_INVALID_PORT TAOS_DEF_ERROR_CODE(0, 0x2612)
#define TSDB_CODE_PAR_INVALID_ENDPOINT TAOS_DEF_ERROR_CODE(0, 0x2613)
#define TSDB_CODE_PAR_EXPRIE_STATEMENT TAOS_DEF_ERROR_CODE(0, 0x2614)
diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh
index 906a227ad5..9d28b63a15 100755
--- a/packaging/deb/makedeb.sh
+++ b/packaging/deb/makedeb.sh
@@ -44,27 +44,27 @@ mkdir -p ${pkg_dir}${install_home_path}/include
#mkdir -p ${pkg_dir}${install_home_path}/init.d
mkdir -p ${pkg_dir}${install_home_path}/script
-# download taoskeeper and build
-if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
- arch=amd64
-elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
- arch=386
-elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
- arch=arm
-elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
- arch=arm64
-else
- arch=$cpuType
-fi
+# # download taoskeeper and build
+# if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
+# arch=amd64
+# elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
+# arch=386
+# elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
+# arch=arm
+# elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
+# arch=arm64
+# else
+# arch=$cpuType
+# fi
-echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper -t ver-${tdengine_ver}"
-echo "$top_dir=${top_dir}"
-taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper -t ver-${tdengine_ver}`
-echo "taoskeeper_binary: ${taoskeeper_binary}"
+# echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper -t ver-${tdengine_ver}"
+# echo "$top_dir=${top_dir}"
+# taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper -t ver-${tdengine_ver}`
+# echo "taoskeeper_binary: ${taoskeeper_binary}"
# copy config files
-cp $(dirname ${taoskeeper_binary})/config/taoskeeper.toml ${pkg_dir}${install_home_path}/cfg
-cp $(dirname ${taoskeeper_binary})/taoskeeper.service ${pkg_dir}${install_home_path}/cfg
+# cp $(dirname ${taoskeeper_binary})/config/taoskeeper.toml ${pkg_dir}${install_home_path}/cfg
+# cp $(dirname ${taoskeeper_binary})/taoskeeper.service ${pkg_dir}${install_home_path}/cfg
cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg
cp ${compile_dir}/../packaging/cfg/taosd.service ${pkg_dir}${install_home_path}/cfg
@@ -75,7 +75,12 @@ fi
if [ -f "${compile_dir}/test/cfg/taosadapter.service" ]; then
cp ${compile_dir}/test/cfg/taosadapter.service ${pkg_dir}${install_home_path}/cfg || :
fi
-
+if [ -f "${compile_dir}/test/cfg/taoskeeper.toml" ]; then
+ cp ${compile_dir}/test/cfg/taoskeeper.toml ${pkg_dir}${install_home_path}/cfg || :
+fi
+if [ -f "${compile_dir}/test/cfg/taoskeeper.service" ]; then
+ cp ${compile_dir}/test/cfg/taoskeeper.service ${pkg_dir}${install_home_path}/cfg || :
+fi
if [ -f "${compile_dir}/../../../explorer/target/taos-explorer.service" ]; then
cp ${compile_dir}/../../../explorer/target/taos-explorer.service ${pkg_dir}${install_home_path}/cfg || :
fi
@@ -83,7 +88,7 @@ if [ -f "${compile_dir}/../../../explorer/server/example/explorer.toml" ]; then
cp ${compile_dir}/../../../explorer/server/example/explorer.toml ${pkg_dir}${install_home_path}/cfg || :
fi
-cp ${taoskeeper_binary} ${pkg_dir}${install_home_path}/bin
+# cp ${taoskeeper_binary} ${pkg_dir}${install_home_path}/bin
#cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
cp ${compile_dir}/../packaging/tools/post.sh ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/tools/preun.sh ${pkg_dir}${install_home_path}/script
@@ -104,6 +109,9 @@ cp ${compile_dir}/build/bin/taosdump ${pkg_dir}${install_home_path
if [ -f "${compile_dir}/build/bin/taosadapter" ]; then
cp ${compile_dir}/build/bin/taosadapter ${pkg_dir}${install_home_path}/bin ||:
fi
+if [ -f "${compile_dir}/build/bin/taoskeeper" ]; then
+ cp ${compile_dir}/build/bin/taoskeeper ${pkg_dir}${install_home_path}/bin ||:
+fi
if [ -f "${compile_dir}/../../../explorer/target/release/taos-explorer" ]; then
cp ${compile_dir}/../../../explorer/target/release/taos-explorer ${pkg_dir}${install_home_path}/bin ||:
@@ -185,7 +193,7 @@ else
exit 1
fi
-rm -rf ${pkg_dir}/build-taoskeeper
+# rm -rf ${pkg_dir}/build-taoskeeper
# make deb package
dpkg -b ${pkg_dir} $debname
echo "make deb package success!"
diff --git a/packaging/rpm/makerpm.sh b/packaging/rpm/makerpm.sh
index f895193b6b..091e056a79 100755
--- a/packaging/rpm/makerpm.sh
+++ b/packaging/rpm/makerpm.sh
@@ -56,24 +56,23 @@ fi
${csudo}mkdir -p ${pkg_dir}
cd ${pkg_dir}
-# download taoskeeper and build
-if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
- arch=amd64
-elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
- arch=386
-elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
- arch=arm
-elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
- arch=arm64
-else
- arch=$cpuType
-fi
+# # download taoskeeper and build
+# if [ "$cpuType" = "x64" ] || [ "$cpuType" = "x86_64" ] || [ "$cpuType" = "amd64" ]; then
+# arch=amd64
+# elif [ "$cpuType" = "x32" ] || [ "$cpuType" = "i386" ] || [ "$cpuType" = "i686" ]; then
+# arch=386
+# elif [ "$cpuType" = "arm" ] || [ "$cpuType" = "aarch32" ]; then
+# arch=arm
+# elif [ "$cpuType" = "arm64" ] || [ "$cpuType" = "aarch64" ]; then
+# arch=arm64
+# else
+# arch=$cpuType
+# fi
-cd ${top_dir}
-echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper -t ver-${tdengine_ver}"
-taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper -t ver-${tdengine_ver}`
-echo "taoskeeper_binary: ${taoskeeper_binary}"
-cd ${package_dir}
+# cd ${top_dir}
+# echo "${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r ${arch} -e taoskeeper -t ver-${tdengine_ver}"
+# taoskeeper_binary=`${top_dir}/../enterprise/packaging/build_taoskeeper.sh -r $arch -e taoskeeper -t ver-${tdengine_ver}`
+# echo "taoskeeper_binary: ${taoskeeper_binary}"
${csudo}mkdir -p BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
@@ -106,4 +105,4 @@ mv ${output_dir}/TDengine-${tdengine_ver}.rpm ${output_dir}/${rpmname}
cd ..
${csudo}rm -rf ${pkg_dir}
-rm -rf ${top_dir}/build-taoskeeper
\ No newline at end of file
+# rm -rf ${top_dir}/build-taoskeeper
\ No newline at end of file
diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec
index 3e23e29a40..c8a6270456 100644
--- a/packaging/rpm/tdengine.spec
+++ b/packaging/rpm/tdengine.spec
@@ -68,12 +68,12 @@ if [ -f %{_compiledir}/test/cfg/taosadapter.service ]; then
cp %{_compiledir}/test/cfg/taosadapter.service %{buildroot}%{homepath}/cfg
fi
-if [ -f %{_compiledir}/../build-taoskeeper/config/taoskeeper.toml ]; then
- cp %{_compiledir}/../build-taoskeeper/config/taoskeeper.toml %{buildroot}%{homepath}/cfg ||:
+if [ -f %{_compiledir}/test/cfg/taoskeeper.toml ]; then
+ cp %{_compiledir}/test/cfg/taoskeeper.toml %{buildroot}%{homepath}/cfg ||:
fi
-if [ -f %{_compiledir}/../build-taoskeeper/taoskeeper.service ]; then
- cp %{_compiledir}/../build-taoskeeper/taoskeeper.service %{buildroot}%{homepath}/cfg ||:
+if [ -f %{_compiledir}/test/cfg/taoskeeper.service ]; then
+ cp %{_compiledir}/test/cfg/taoskeeper.service %{buildroot}%{homepath}/cfg ||:
fi
if [ -f %{_compiledir}/../../../explorer/target/taos-explorer.service ]; then
@@ -104,8 +104,8 @@ if [ -f %{_compiledir}/../../../explorer/target/release/taos-explorer ]; then
cp %{_compiledir}/../../../explorer/target/release/taos-explorer %{buildroot}%{homepath}/bin
fi
-if [ -f %{_compiledir}/../build-taoskeeper/taoskeeper ]; then
- cp %{_compiledir}/../build-taoskeeper/taoskeeper %{buildroot}%{homepath}/bin
+if [ -f %{_compiledir}/build/bin//taoskeeper ]; then
+ cp %{_compiledir}/build/bin//taoskeeper %{buildroot}%{homepath}/bin
fi
if [ -f %{_compiledir}/build/bin/taosadapter ]; then
diff --git a/packaging/tools/makeclient.sh b/packaging/tools/makeclient.sh
index d67d436fa7..87f4f57fd3 100755
--- a/packaging/tools/makeclient.sh
+++ b/packaging/tools/makeclient.sh
@@ -282,5 +282,3 @@ else
rm -rf ${install_dir} ||:
# mv ../"$(basename ${pkg_name}).tar.gz" .
fi
-
-cd ${curr_dir}
diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c
index b311a9e06d..f041e4b030 100644
--- a/source/client/src/clientMain.c
+++ b/source/client/src/clientMain.c
@@ -2201,6 +2201,11 @@ int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col
if (code) {
goto out;
}
+ } else if (pStmt->bInfo.tbType == TSDB_CHILD_TABLE && pStmt->sql.autoCreateTbl) {
+ code = stmtSetTbTags2(stmt, NULL);
+ if (code) {
+ return code;
+ }
}
if (bindv->bind_cols && bindv->bind_cols[i]) {
diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c
index 950444df52..acd118acc9 100644
--- a/source/client/src/clientStmt2.c
+++ b/source/client/src/clientStmt2.c
@@ -1012,10 +1012,10 @@ int stmtSetTbTags2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* tags) {
}
SBoundColInfo* tags_info = (SBoundColInfo*)pStmt->bInfo.boundTags;
- if (tags_info->numOfBound <= 0 || tags_info->numOfCols <= 0) {
- tscWarn("no tags or cols bound in sql, will not bound tags");
- return TSDB_CODE_SUCCESS;
- }
+ // if (tags_info->numOfBound <= 0 || tags_info->numOfCols <= 0) {
+ // tscWarn("no tags or cols bound in sql, will not bound tags");
+ // return TSDB_CODE_SUCCESS;
+ // }
STableDataCxt** pDataBlock =
(STableDataCxt**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName));
diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c
index 905dcb4fda..c58ad32a18 100644
--- a/source/common/src/tglobal.c
+++ b/source/common/src/tglobal.c
@@ -14,12 +14,12 @@
*/
#define _DEFAULT_SOURCE
+#include "tglobal.h"
#include "cJSON.h"
#include "defines.h"
#include "os.h"
#include "osString.h"
#include "tconfig.h"
-#include "tglobal.h"
#include "tgrant.h"
#include "tjson.h"
#include "tlog.h"
@@ -104,6 +104,7 @@ int32_t tsRetentionSpeedLimitMB = 0; // unlimited
const char *tsAlterCompactTaskKeywords = "max_compact_tasks";
int32_t tsNumOfCompactThreads = 2;
+int32_t tsNumOfRetentionThreads = 1;
// sync raft
int32_t tsElectInterval = 25 * 1000;
@@ -328,6 +329,7 @@ int64_t tsStreamBufferSize = 128 * 1024 * 1024;
bool tsFilterScalarMode = false;
int tsResolveFQDNRetryTime = 100; // seconds
int tsStreamAggCnt = 100000;
+bool tsStreamCoverage = false;
bool tsUpdateCacheBatch = true;
@@ -390,6 +392,16 @@ int32_t taosSetTfsCfg(SConfig *pCfg) {
int32_t taosSetTfsCfg(SConfig *pCfg);
#endif
+#ifndef _STORAGE
+int32_t cfgUpdateTfsItemDisable(SConfig *pCfg, const char *value, void *pTfs) { return TSDB_CODE_INVALID_CFG; }
+#else
+int32_t cfgUpdateTfsItemDisable(SConfig *pCfg, const char *value, void *pTfs);
+#endif
+
+int32_t taosUpdateTfsItemDisable(SConfig *pCfg, const char *value, void *pTfs) {
+ return cfgUpdateTfsItemDisable(pCfg, value, pTfs);
+}
+
static int32_t taosSplitS3Cfg(SConfig *pCfg, const char *name, char gVarible[TSDB_MAX_EP_NUM][TSDB_FQDN_LEN],
int8_t *pNum) {
int32_t code = TSDB_CODE_SUCCESS;
@@ -733,6 +745,9 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
CFG_DYN_CLIENT, CFG_CATEGORY_LOCAL));
TAOS_CHECK_RETURN(cfgAddInt32(pCfg, "tsmaDataDeleteMark", tsmaDataDeleteMark, 60 * 60 * 1000, INT64_MAX,
CFG_SCOPE_CLIENT, CFG_DYN_CLIENT, CFG_CATEGORY_LOCAL));
+
+ TAOS_CHECK_RETURN(cfgAddBool(pCfg, "streamCoverage", tsStreamCoverage, CFG_DYN_CLIENT, CFG_DYN_CLIENT, CFG_CATEGORY_LOCAL));
+
TAOS_RETURN(TSDB_CODE_SUCCESS);
}
@@ -1463,6 +1478,9 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "bypassFlag");
tsBypassFlag = pItem->i32;
+ TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "streamCoverage");
+ tsStreamCoverage = pItem->bval;
+
TAOS_RETURN(TSDB_CODE_SUCCESS);
}
@@ -2381,6 +2399,10 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
code = TSDB_CODE_SUCCESS;
goto _exit;
}
+ if (strcasecmp(name, "dataDir") == 0) {
+ code = TSDB_CODE_SUCCESS;
+ goto _exit;
+ }
{ // 'bool/int32_t/int64_t/float/double' variables with general modification function
static OptionNameAndVar debugOptions[] = {
@@ -2735,7 +2757,8 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
{"maxTsmaCalcDelay", &tsMaxTsmaCalcDelay},
{"tsmaDataDeleteMark", &tsmaDataDeleteMark},
{"numOfRpcSessions", &tsNumOfRpcSessions},
- {"bypassFlag", &tsBypassFlag}};
+ {"bypassFlag", &tsBypassFlag},
+ {"streamCoverage", &tsStreamCoverage}};
if ((code = taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true)) != TSDB_CODE_SUCCESS) {
code = taosCfgSetOption(options, tListLen(options), pItem, false);
diff --git a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
index 2108a097ee..45a597ec90 100644
--- a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
+++ b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h
@@ -25,6 +25,7 @@ extern "C" {
typedef struct SDnodeMgmt {
SDnodeData *pData;
SMsgCb msgCb;
+ STfs *pTfs;
const char *path;
const char *name;
TdThread statusThread;
@@ -69,6 +70,7 @@ int32_t dmStartStatusThread(SDnodeMgmt *pMgmt);
int32_t dmStartConfigThread(SDnodeMgmt *pMgmt);
int32_t dmStartStatusInfoThread(SDnodeMgmt *pMgmt);
void dmStopStatusThread(SDnodeMgmt *pMgmt);
+void dmStopConfigThread(SDnodeMgmt *pMgmt);
void dmStopStatusInfoThread(SDnodeMgmt *pMgmt);
int32_t dmStartNotifyThread(SDnodeMgmt *pMgmt);
void dmStopNotifyThread(SDnodeMgmt *pMgmt);
diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
index ccc6439b5d..8139e4aa98 100644
--- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
+++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c
@@ -475,7 +475,7 @@ int32_t dmProcessGrantRsp(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
return 0;
}
-extern void tsdbAlterMaxCompactTasks();
+extern void tsdbAlterNumCompactThreads();
static int32_t dmAlterMaxCompactTask(const char *value) {
int32_t max_compact_tasks;
char *endptr = NULL;
@@ -489,7 +489,7 @@ static int32_t dmAlterMaxCompactTask(const char *value) {
dInfo("alter max compact tasks from %d to %d", tsNumOfCompactThreads, max_compact_tasks);
tsNumOfCompactThreads = max_compact_tasks;
#ifdef TD_ENTERPRISE
- tsdbAlterMaxCompactTasks();
+ (void)tsdbAlterNumCompactThreads();
#endif
}
@@ -499,9 +499,15 @@ static int32_t dmAlterMaxCompactTask(const char *value) {
int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
int32_t code = 0;
SDCfgDnodeReq cfgReq = {0};
+ SConfig *pCfg = taosGetCfg();
+ SConfigItem *pItem = NULL;
+
if (tDeserializeSDCfgDnodeReq(pMsg->pCont, pMsg->contLen, &cfgReq) != 0) {
return TSDB_CODE_INVALID_MSG;
}
+ if (strcasecmp(cfgReq.config, "dataDir") == 0) {
+ return taosUpdateTfsItemDisable(pCfg, cfgReq.value, pMgmt->pTfs);
+ }
if (strncmp(cfgReq.config, tsAlterCompactTaskKeywords, strlen(tsAlterCompactTaskKeywords) + 1) == 0) {
return dmAlterMaxCompactTask(cfgReq.value);
@@ -509,9 +515,6 @@ int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
dInfo("start to config, option:%s, value:%s", cfgReq.config, cfgReq.value);
- SConfig *pCfg = taosGetCfg();
- SConfigItem *pItem = NULL;
-
code = cfgGetAndSetItem(pCfg, &pItem, cfgReq.config, cfgReq.value, CFG_STYPE_ALTER_SERVER_CMD, true);
if (code != 0) {
if (strncasecmp(cfgReq.config, "resetlog", strlen("resetlog")) == 0) {
diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
index b58c1a216d..ed6aff1b13 100644
--- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
+++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c
@@ -52,6 +52,7 @@ static void dmStopMgmt(SDnodeMgmt *pMgmt) {
dmStopMonitorThread(pMgmt);
dmStopAuditThread(pMgmt);
dmStopStatusThread(pMgmt);
+ dmStopConfigThread(pMgmt);
dmStopStatusInfoThread(pMgmt);
#if defined(TD_ENTERPRISE)
dmStopNotifyThread(pMgmt);
@@ -68,6 +69,7 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
pMgmt->pData = pInput->pData;
pMgmt->msgCb = pInput->msgCb;
+ pMgmt->pTfs = pInput->pTfs;
pMgmt->path = pInput->path;
pMgmt->name = pInput->name;
pMgmt->processCreateNodeFp = pInput->processCreateNodeFp;
diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c
index 8f890f6805..ef4e76031d 100644
--- a/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c
+++ b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c
@@ -343,7 +343,7 @@ int32_t dmStartConfigThread(SDnodeMgmt *pMgmt) {
int32_t code = 0;
TdThreadAttr thAttr;
(void)taosThreadAttrInit(&thAttr);
- (void)taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_DETACHED);
+ (void)taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_JOINABLE);
if (taosThreadCreate(&pMgmt->configThread, &thAttr, dmConfigThreadFp, pMgmt) != 0) {
code = TAOS_SYSTEM_ERROR(errno);
dError("failed to create config thread since %s", tstrerror(code));
@@ -378,6 +378,13 @@ void dmStopStatusThread(SDnodeMgmt *pMgmt) {
}
}
+void dmStopConfigThread(SDnodeMgmt *pMgmt) {
+ if (taosCheckPthreadValid(pMgmt->configThread)) {
+ (void)taosThreadJoin(pMgmt->configThread, NULL);
+ taosThreadClear(&pMgmt->configThread);
+ }
+}
+
void dmStopStatusInfoThread(SDnodeMgmt *pMgmt) {
if (taosCheckPthreadValid(pMgmt->statusInfoThread)) {
(void)taosThreadJoin(pMgmt->statusInfoThread, NULL);
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c
index 537c1f6297..6d5e117181 100644
--- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c
+++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c
@@ -896,7 +896,7 @@ static int32_t vmInit(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
}
tmsgReportStartup("vnode-sync", "initialized");
- if ((code = vnodeInit(tsNumOfCommitThreads, pInput->stopDnodeFp)) != 0) {
+ if ((code = vnodeInit(pInput->stopDnodeFp)) != 0) {
dError("failed to init vnode since %s", tstrerror(code));
goto _OVER;
}
diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c
index e1518d3752..5b2a5fa8aa 100644
--- a/source/dnode/mnode/impl/src/mndUser.c
+++ b/source/dnode/mnode/impl/src/mndUser.c
@@ -1805,12 +1805,21 @@ _OVER:
TAOS_RETURN(code);
}
-static int32_t mndCheckPasswordFmt(const char *pwd) {
- int32_t len = strlen(pwd);
- if (len < TSDB_PASSWORD_MIN_LEN || len > TSDB_PASSWORD_MAX_LEN) {
+static int32_t mndCheckPasswordMinLen(const char *pwd, int32_t len) {
+ if (len < TSDB_PASSWORD_MIN_LEN) {
return -1;
}
+ return 0;
+}
+static int32_t mndCheckPasswordMaxLen(const char *pwd, int32_t len) {
+ if (len > TSDB_PASSWORD_MAX_LEN) {
+ return -1;
+ }
+ return 0;
+}
+
+static int32_t mndCheckPasswordFmt(const char *pwd, int32_t len) {
if (strcmp(pwd, "taosdata") == 0) {
return 0;
}
@@ -1875,14 +1884,17 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
}
- if (mndCheckPasswordFmt(createReq.pass) != 0) {
- TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
- }
-
+ int32_t len = strlen(createReq.pass);
if (createReq.isImport != 1) {
- if (strlen(createReq.pass) >= TSDB_PASSWORD_LEN) {
+ if (mndCheckPasswordMinLen(createReq.pass, len) != 0) {
+ TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
+ }
+ if (mndCheckPasswordMaxLen(createReq.pass, len) != 0) {
TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
}
+ if (mndCheckPasswordFmt(createReq.pass, len) != 0) {
+ TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
+ }
}
code = mndAcquireUser(pMnode, createReq.user, &pUser);
@@ -2364,8 +2376,17 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER);
}
- if (TSDB_ALTER_USER_PASSWD == alterReq.alterType && mndCheckPasswordFmt(alterReq.pass) != 0) {
- TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
+ if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) {
+ int32_t len = strlen(alterReq.pass);
+ if (mndCheckPasswordMinLen(alterReq.pass, len) != 0) {
+ TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER);
+ }
+ if (mndCheckPasswordMaxLen(alterReq.pass, len) != 0) {
+ TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER);
+ }
+ if (mndCheckPasswordFmt(alterReq.pass, len) != 0) {
+ TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER);
+ }
}
TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER);
diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h
index f4a678e629..b33bdb0976 100644
--- a/source/dnode/vnode/inc/vnode.h
+++ b/source/dnode/vnode/inc/vnode.h
@@ -51,7 +51,7 @@ extern const SVnodeCfg vnodeCfgDefault;
typedef void (*StopDnodeFp)();
-int32_t vnodeInit(int32_t nthreads, StopDnodeFp stopDnodeFp);
+int32_t vnodeInit(StopDnodeFp stopDnodeFp);
void vnodeCleanup();
int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, int32_t diskPrimary, STfs *pTfs);
bool vnodeShouldRemoveWal(SVnode *pVnode);
diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h
index 29248e360a..47890e9b4b 100644
--- a/source/dnode/vnode/src/inc/tsdb.h
+++ b/source/dnode/vnode/src/inc/tsdb.h
@@ -1083,9 +1083,6 @@ void tsdbRemoveFile(const char *path);
} \
} while (0)
-int32_t tsdbInit();
-void tsdbCleanUp();
-
#ifdef __cplusplus
}
#endif
diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h
index ff622d2dab..b1a5ca4709 100644
--- a/source/dnode/vnode/src/inc/vnd.h
+++ b/source/dnode/vnode/src/inc/vnd.h
@@ -55,16 +55,32 @@ typedef enum {
EVA_PRIORITY_LOW,
} EVAPriority;
-int32_t vnodeAsyncOpen(int32_t numOfThreads);
+typedef enum {
+ EVA_TASK_COMMIT = 1,
+ EVA_TASK_MERGE,
+ EVA_TASK_COMPACT,
+ EVA_TASK_RETENTION,
+} EVATaskT;
+
+#define COMMIT_TASK_ASYNC 1
+#define MERGE_TASK_ASYNC 2
+#define COMPACT_TASK_ASYNC 3
+#define RETENTION_TASK_ASYNC 4
+
+int32_t vnodeAsyncOpen();
void vnodeAsyncClose();
int32_t vnodeAChannelInit(int64_t async, SVAChannelID* channelID);
int32_t vnodeAChannelDestroy(SVAChannelID* channelID, bool waitRunning);
-int32_t vnodeAsync(SVAChannelID* channelID, EVAPriority priority, int32_t (*execute)(void*), void (*complete)(void*),
- void* arg, SVATaskID* taskID);
+int32_t vnodeAsync(int64_t async, EVAPriority priority, int32_t (*execute)(void*), void (*complete)(void*), void* arg,
+ SVATaskID* taskID);
+int32_t vnodeAsyncC(SVAChannelID* channelID, EVAPriority priority, int32_t (*execute)(void*), void (*complete)(void*),
+ void* arg, SVATaskID* taskID);
void vnodeAWait(SVATaskID* taskID);
int32_t vnodeACancel(SVATaskID* taskID);
int32_t vnodeAsyncSetWorkers(int64_t async, int32_t numWorkers);
+const char* vnodeGetATaskName(EVATaskT task);
+
// vnodeBufPool.c
typedef struct SVBufPoolNode SVBufPoolNode;
struct SVBufPoolNode {
diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h
index ef4b233f94..4f1ecf81dd 100644
--- a/source/dnode/vnode/src/inc/vnodeInt.h
+++ b/source/dnode/vnode/src/inc/vnodeInt.h
@@ -479,8 +479,7 @@ struct SVnode {
SVBufPool* onRecycle;
// commit variables
- SVAChannelID commitChannel;
- SVATaskID commitTask;
+ SVATaskID commitTask;
SMeta* pMeta;
SSma* pSma;
diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c
index 8fd0d47969..2047b68101 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCache.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCache.c
@@ -2635,23 +2635,15 @@ _exit:
}
int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey) {
- int32_t code = 0, lino = 0;
- // fetch schema
+ int32_t code = 0, lino = 0;
STSchema *pTSchema = NULL;
int sver = -1;
+ int numKeys = 0;
+ SArray *remainCols = NULL;
TAOS_CHECK_RETURN(metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, uid, sver, &pTSchema));
- // build keys & multi get from rocks
- int numCols = pTSchema->numOfCols;
- int numKeys = 0;
- SArray *remainCols = NULL;
-
- code = tsdbCacheCommit(pTsdb);
- if (code != TSDB_CODE_SUCCESS) {
- tsdbTrace("vgId:%d, %s commit failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__,
- tstrerror(code));
- }
+ int numCols = pTSchema->numOfCols;
(void)taosThreadMutexLock(&pTsdb->lruMutex);
diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c
index e3c75760c8..5822463f9e 100644
--- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c
+++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c
@@ -574,7 +574,7 @@ static int32_t tsdbCommitInfoBuild(STsdb *tsdb) {
// begin tasks on file set
for (int i = 0; i < taosArrayGetSize(tsdb->commitInfo->arr); i++) {
SFileSetCommitInfo *info = *(SFileSetCommitInfo **)taosArrayGet(tsdb->commitInfo->arr, i);
- tsdbBeginTaskOnFileSet(tsdb, info->fid, &fset);
+ tsdbBeginTaskOnFileSet(tsdb, info->fid, EVA_TASK_COMMIT, &fset);
if (fset) {
code = tsdbTFileSetInitCopy(tsdb, fset, &info->fset);
if (code) {
@@ -712,7 +712,7 @@ int32_t tsdbCommitCommit(STsdb *tsdb) {
for (int32_t i = 0; i < taosArrayGetSize(tsdb->commitInfo->arr); i++) {
SFileSetCommitInfo *info = *(SFileSetCommitInfo **)taosArrayGet(tsdb->commitInfo->arr, i);
if (info->fset) {
- tsdbFinishTaskOnFileSet(tsdb, info->fid);
+ tsdbFinishTaskOnFileSet(tsdb, info->fid, EVA_TASK_COMMIT);
}
}
@@ -743,7 +743,7 @@ int32_t tsdbCommitAbort(STsdb *pTsdb) {
for (int32_t i = 0; i < taosArrayGetSize(pTsdb->commitInfo->arr); i++) {
SFileSetCommitInfo *info = *(SFileSetCommitInfo **)taosArrayGet(pTsdb->commitInfo->arr, i);
if (info->fset) {
- tsdbFinishTaskOnFileSet(pTsdb, info->fid);
+ tsdbFinishTaskOnFileSet(pTsdb, info->fid, EVA_TASK_COMMIT);
}
}
(void)taosThreadMutexUnlock(&pTsdb->mutex);
diff --git a/source/dnode/vnode/src/tsdb/tsdbFS2.c b/source/dnode/vnode/src/tsdb/tsdbFS2.c
index 9a7cdca8f7..82dd49b0e2 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFS2.c
+++ b/source/dnode/vnode/src/tsdb/tsdbFS2.c
@@ -770,8 +770,8 @@ extern void tsdbStopAllCompTask(STsdb *tsdb);
int32_t tsdbDisableAndCancelAllBgTask(STsdb *pTsdb) {
STFileSystem *fs = pTsdb->pFS;
- SArray *channelArray = taosArrayInit(0, sizeof(SVAChannelID));
- if (channelArray == NULL) {
+ SArray *asyncTasks = taosArrayInit(0, sizeof(SVATaskID));
+ if (asyncTasks == NULL) {
return terrno;
}
@@ -783,30 +783,31 @@ int32_t tsdbDisableAndCancelAllBgTask(STsdb *pTsdb) {
// collect channel
STFileSet *fset;
TARRAY2_FOREACH(fs->fSetArr, fset) {
- if (fset->channelOpened) {
- if (taosArrayPush(channelArray, &fset->channel) == NULL) {
- taosArrayDestroy(channelArray);
- (void)taosThreadMutexUnlock(&pTsdb->mutex);
- return terrno;
- }
- fset->channel = (SVAChannelID){0};
- fset->mergeScheduled = false;
- tsdbFSSetBlockCommit(fset, false);
- fset->channelOpened = false;
+ if (taosArrayPush(asyncTasks, &fset->mergeTask) == NULL //
+ || taosArrayPush(asyncTasks, &fset->compactTask) == NULL //
+ || taosArrayPush(asyncTasks, &fset->retentionTask) == NULL) {
+ taosArrayDestroy(asyncTasks);
+ (void)taosThreadMutexUnlock(&pTsdb->mutex);
+ return terrno;
}
+ fset->mergeScheduled = false;
+ tsdbFSSetBlockCommit(fset, false);
}
(void)taosThreadMutexUnlock(&pTsdb->mutex);
// destroy all channels
- for (int32_t i = 0; i < taosArrayGetSize(channelArray); i++) {
- SVAChannelID *channel = taosArrayGet(channelArray, i);
- int32_t code = vnodeAChannelDestroy(channel, true);
- if (code) {
- tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code));
+ for (int32_t k = 0; k < 2; k++) {
+ for (int32_t i = 0; i < taosArrayGetSize(asyncTasks); i++) {
+ SVATaskID *task = taosArrayGet(asyncTasks, i);
+ if (k == 0) {
+ (void)vnodeACancel(task);
+ } else {
+ vnodeAWait(task);
+ }
}
}
- taosArrayDestroy(channelArray);
+ taosArrayDestroy(asyncTasks);
#ifdef TD_ENTERPRISE
tsdbStopAllCompTask(pTsdb);
@@ -934,9 +935,6 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) {
// bool skipMerge = false;
int32_t numFile = TARRAY2_SIZE(lvl->fobjArr);
if (numFile >= sttTrigger && (!fset->mergeScheduled)) {
- code = tsdbTFileSetOpenChannel(fset);
- TSDB_CHECK_CODE(code, lino, _exit);
-
SMergeArg *arg = taosMemoryMalloc(sizeof(*arg));
if (arg == NULL) {
code = terrno;
@@ -946,7 +944,7 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) {
arg->tsdb = fs->tsdb;
arg->fid = fset->fid;
- code = vnodeAsync(&fset->channel, EVA_PRIORITY_HIGH, tsdbMerge, taosAutoMemoryFree, arg, NULL);
+ code = vnodeAsync(MERGE_TASK_ASYNC, EVA_PRIORITY_HIGH, tsdbMerge, taosAutoMemoryFree, arg, &fset->mergeTask);
TSDB_CHECK_CODE(code, lino, _exit);
fset->mergeScheduled = true;
}
@@ -1202,42 +1200,61 @@ _out:
void tsdbFSDestroyRefRangedSnapshot(TFileSetRangeArray **fsrArr) { tsdbTFileSetRangeArrayDestroy(fsrArr); }
-void tsdbBeginTaskOnFileSet(STsdb *tsdb, int32_t fid, STFileSet **fset) {
+void tsdbBeginTaskOnFileSet(STsdb *tsdb, int32_t fid, EVATaskT task, STFileSet **fset) {
+ // Here, sttTrigger is protected by tsdb->mutex, so it is safe to read it without lock
int16_t sttTrigger = tsdb->pVnode->config.sttTrigger;
tsdbFSGetFSet(tsdb->pFS, fid, fset);
- if (sttTrigger == 1 && (*fset)) {
- for (;;) {
- if ((*fset)->taskRunning) {
- (*fset)->numWaitTask++;
-
- (void)taosThreadCondWait(&(*fset)->beginTask, &tsdb->mutex);
-
- tsdbFSGetFSet(tsdb->pFS, fid, fset);
-
- (*fset)->numWaitTask--;
- } else {
- (*fset)->taskRunning = true;
- break;
- }
- }
- tsdbInfo("vgId:%d begin task on file set:%d", TD_VID(tsdb->pVnode), fid);
+ if (*fset == NULL) {
+ return;
}
+
+ struct STFileSetCond *cond = NULL;
+ if (sttTrigger == 1 || task == EVA_TASK_COMMIT) {
+ cond = &(*fset)->conds[0];
+ } else {
+ cond = &(*fset)->conds[1];
+ }
+
+ while (1) {
+ if (cond->running) {
+ cond->numWait++;
+ (void)taosThreadCondWait(&cond->cond, &tsdb->mutex);
+ cond->numWait--;
+ } else {
+ cond->running = true;
+ break;
+ }
+ }
+
+ tsdbInfo("vgId:%d begin %s task on file set:%d", TD_VID(tsdb->pVnode), vnodeGetATaskName(task), fid);
+ return;
}
-void tsdbFinishTaskOnFileSet(STsdb *tsdb, int32_t fid) {
+void tsdbFinishTaskOnFileSet(STsdb *tsdb, int32_t fid, EVATaskT task) {
+ // Here, sttTrigger is protected by tsdb->mutex, so it is safe to read it without lock
int16_t sttTrigger = tsdb->pVnode->config.sttTrigger;
- if (sttTrigger == 1) {
- STFileSet *fset = NULL;
- tsdbFSGetFSet(tsdb->pFS, fid, &fset);
- if (fset != NULL && fset->taskRunning) {
- fset->taskRunning = false;
- if (fset->numWaitTask > 0) {
- (void)taosThreadCondSignal(&fset->beginTask);
- }
- tsdbInfo("vgId:%d finish task on file set:%d", TD_VID(tsdb->pVnode), fid);
- }
+
+ STFileSet *fset = NULL;
+ tsdbFSGetFSet(tsdb->pFS, fid, &fset);
+ if (fset == NULL) {
+ return;
}
+
+ struct STFileSetCond *cond = NULL;
+ if (sttTrigger == 1 || task == EVA_TASK_COMMIT) {
+ cond = &fset->conds[0];
+ } else {
+ cond = &fset->conds[1];
+ }
+
+ cond->running = false;
+ if (cond->numWait > 0) {
+ (void)taosThreadCondSignal(&cond->cond);
+ }
+
+ tsdbInfo("vgId:%d finish %s task on file set:%d", TD_VID(tsdb->pVnode), vnodeGetATaskName(task), fid);
+ return;
}
struct SFileSetReader {
diff --git a/source/dnode/vnode/src/tsdb/tsdbFS2.h b/source/dnode/vnode/src/tsdb/tsdbFS2.h
index 119015636b..9694edcdd9 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFS2.h
+++ b/source/dnode/vnode/src/tsdb/tsdbFS2.h
@@ -14,6 +14,7 @@
*/
#include "tsdbFSet2.h"
+#include "vnd.h"
#ifndef _TSDB_FILE_SYSTEM_H
#define _TSDB_FILE_SYSTEM_H
@@ -61,8 +62,8 @@ int32_t tsdbFSEditAbort(STFileSystem *fs);
// other
void tsdbFSGetFSet(STFileSystem *fs, int32_t fid, STFileSet **fset);
void tsdbFSCheckCommit(STsdb *tsdb, int32_t fid);
-void tsdbBeginTaskOnFileSet(STsdb *tsdb, int32_t fid, STFileSet **fset);
-void tsdbFinishTaskOnFileSet(STsdb *tsdb, int32_t fid);
+void tsdbBeginTaskOnFileSet(STsdb *tsdb, int32_t fid, EVATaskT task, STFileSet **fset);
+void tsdbFinishTaskOnFileSet(STsdb *tsdb, int32_t fid, EVATaskT task);
// utils
int32_t save_fs(const TFileSetArray *arr, const char *fname);
void current_fname(STsdb *pTsdb, char *fname, EFCurrentT ftype);
diff --git a/source/dnode/vnode/src/tsdb/tsdbFSet2.c b/source/dnode/vnode/src/tsdb/tsdbFSet2.c
index a0ae58ac96..68914300e4 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFSet2.c
+++ b/source/dnode/vnode/src/tsdb/tsdbFSet2.c
@@ -480,16 +480,18 @@ int32_t tsdbTFileSetInit(int32_t fid, STFileSet **fset) {
fset[0]->maxVerValid = VERSION_MAX;
TARRAY2_INIT(fset[0]->lvlArr);
- // background task queue
- (void)taosThreadCondInit(&(*fset)->beginTask, NULL);
- (*fset)->taskRunning = false;
- (*fset)->numWaitTask = 0;
-
// block commit variables
(void)taosThreadCondInit(&fset[0]->canCommit, NULL);
(*fset)->numWaitCommit = 0;
(*fset)->blockCommit = false;
+ for (int32_t i = 0; i < sizeof((*fset)->conds) / sizeof((*fset)->conds[0]); ++i) {
+ struct STFileSetCond *cond = &(*fset)->conds[i];
+ cond->running = false;
+ cond->numWait = 0;
+ (void)taosThreadCondInit(&cond->cond, NULL);
+ }
+
return 0;
}
@@ -648,8 +650,10 @@ void tsdbTFileSetClear(STFileSet **fset) {
TARRAY2_DESTROY((*fset)->lvlArr, tsdbSttLvlClear);
- (void)taosThreadCondDestroy(&(*fset)->beginTask);
(void)taosThreadCondDestroy(&(*fset)->canCommit);
+ for (int32_t i = 0; i < sizeof((*fset)->conds) / sizeof((*fset)->conds[0]); ++i) {
+ (void)taosThreadCondDestroy(&(*fset)->conds[i].cond);
+ }
taosMemoryFreeClear(*fset);
}
}
@@ -703,14 +707,3 @@ bool tsdbTFileSetIsEmpty(const STFileSet *fset) {
}
return TARRAY2_SIZE(fset->lvlArr) == 0;
}
-
-int32_t tsdbTFileSetOpenChannel(STFileSet *fset) {
- int32_t code;
- if (!fset->channelOpened) {
- if ((code = vnodeAChannelInit(2, &fset->channel))) {
- return code;
- }
- fset->channelOpened = true;
- }
- return 0;
-}
diff --git a/source/dnode/vnode/src/tsdb/tsdbFSet2.h b/source/dnode/vnode/src/tsdb/tsdbFSet2.h
index 24ae59e300..83ef32e5e5 100644
--- a/source/dnode/vnode/src/tsdb/tsdbFSet2.h
+++ b/source/dnode/vnode/src/tsdb/tsdbFSet2.h
@@ -68,8 +68,6 @@ bool tsdbTFileSetIsEmpty(const STFileSet *fset);
// stt
int32_t tsdbSttLvlInit(int32_t level, SSttLvl **lvl);
void tsdbSttLvlClear(SSttLvl **lvl);
-// open channel
-int32_t tsdbTFileSetOpenChannel(STFileSet *fset);
struct STFileOp {
tsdb_fop_t optype;
@@ -83,26 +81,30 @@ struct SSttLvl {
TFileObjArray fobjArr[1];
};
+struct STFileSetCond {
+ bool running;
+ int32_t numWait;
+ TdThreadCond cond;
+};
+
struct STFileSet {
int32_t fid;
int64_t maxVerValid;
STFileObj *farr[TSDB_FTYPE_MAX]; // file array
TSttLvlArray lvlArr[1]; // level array
- // background task
- bool channelOpened;
- SVAChannelID channel;
- bool mergeScheduled;
-
- // sttTrigger = 1
- TdThreadCond beginTask;
- bool taskRunning;
- int32_t numWaitTask;
+ bool mergeScheduled;
+ SVATaskID mergeTask;
+ SVATaskID compactTask;
+ SVATaskID retentionTask;
// block commit variables
TdThreadCond canCommit;
int32_t numWaitCommit;
bool blockCommit;
+
+ // conditions
+ struct STFileSetCond conds[2];
};
struct STFileSetRange {
diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.c b/source/dnode/vnode/src/tsdb/tsdbMerge.c
index 61a82d828e..39d8a57692 100644
--- a/source/dnode/vnode/src/tsdb/tsdbMerge.c
+++ b/source/dnode/vnode/src/tsdb/tsdbMerge.c
@@ -462,21 +462,29 @@ _exit:
static int32_t tsdbMergeGetFSet(SMerger *merger) {
STFileSet *fset;
+ int32_t code;
+ STsdb *tsdb = merger->tsdb;
(void)taosThreadMutexLock(&merger->tsdb->mutex);
- tsdbFSGetFSet(merger->tsdb->pFS, merger->fid, &fset);
- if (fset == NULL) {
+
+ if (tsdb->bgTaskDisabled) {
(void)taosThreadMutexUnlock(&merger->tsdb->mutex);
return 0;
}
- fset->mergeScheduled = false;
+ tsdbBeginTaskOnFileSet(tsdb, merger->fid, EVA_TASK_MERGE, &fset);
+ if (NULL == fset) {
+ (void)taosThreadMutexUnlock(&merger->tsdb->mutex);
+ return 0;
+ }
- int32_t code = tsdbTFileSetInitCopy(merger->tsdb, fset, &merger->fset);
+ code = tsdbTFileSetInitCopy(merger->tsdb, fset, &merger->fset);
if (code) {
(void)taosThreadMutexUnlock(&merger->tsdb->mutex);
return code;
}
+
+ fset->mergeScheduled = false;
(void)taosThreadMutexUnlock(&merger->tsdb->mutex);
return 0;
}
@@ -493,10 +501,13 @@ int32_t tsdbMerge(void *arg) {
.sttTrigger = tsdb->pVnode->config.sttTrigger,
}};
- if (merger->sttTrigger <= 1) return 0;
+ if (merger->sttTrigger <= 1) {
+ return 0;
+ }
// copy snapshot
- TAOS_CHECK_GOTO(tsdbMergeGetFSet(merger), &lino, _exit);
+ code = tsdbMergeGetFSet(merger);
+ TSDB_CHECK_CODE(code, lino, _exit);
if (merger->fset == NULL) {
return 0;
@@ -509,12 +520,19 @@ int32_t tsdbMerge(void *arg) {
TSDB_CHECK_CODE(code, lino, _exit);
_exit:
+ if (merger->fset) {
+ (void)taosThreadMutexLock(&tsdb->mutex);
+ tsdbFinishTaskOnFileSet(tsdb, mergeArg->fid, EVA_TASK_MERGE);
+ (void)taosThreadMutexUnlock(&tsdb->mutex);
+ }
+
if (code) {
tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(tsdb->pVnode), __func__, __FILE__, lino, tstrerror(code));
tsdbFatal("vgId:%d, failed to merge stt files since %s. code:%d", TD_VID(tsdb->pVnode), terrstr(), code);
taosMsleep(100);
exit(EXIT_FAILURE);
}
+
tsdbTFileSetClear(&merger->fset);
taosMemoryFree(arg);
return code;
diff --git a/source/dnode/vnode/src/tsdb/tsdbOpen.c b/source/dnode/vnode/src/tsdb/tsdbOpen.c
index b2e4621878..c1f8f45d7e 100644
--- a/source/dnode/vnode/src/tsdb/tsdbOpen.c
+++ b/source/dnode/vnode/src/tsdb/tsdbOpen.c
@@ -18,22 +18,6 @@
extern int32_t tsdbOpenCompMonitor(STsdb *tsdb);
extern void tsdbCloseCompMonitor(STsdb *tsdb);
-extern int32_t tsdbInitCompact();
-extern void tsdbCleanupCompact();
-
-int32_t tsdbInit() {
-#ifdef TD_ENTERPRISE
- return tsdbInitCompact();
-#endif
- return 0;
-}
-
-void tsdbCleanUp() {
-#ifdef TD_ENTERPRISE
- tsdbCleanupCompact();
-#endif
- return;
-}
void tsdbSetKeepCfg(STsdb *pTsdb, STsdbCfg *pCfg) {
STsdbKeepCfg *pKeepCfg = &pTsdb->keepCfg;
diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c
index 05ae4be74b..a9f3893b96 100644
--- a/source/dnode/vnode/src/tsdb/tsdbRead2.c
+++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c
@@ -5791,7 +5791,6 @@ int32_t tsdbReaderSuspend2(STsdbReader* pReader) {
// make sure only release once
void* p = pReader->pReadSnap;
- TSDB_CHECK_NULL(p, code, lino, _end, TSDB_CODE_INVALID_PARA);
if ((p == atomic_val_compare_exchange_ptr((void**)&pReader->pReadSnap, p, NULL)) && (p != NULL)) {
tsdbUntakeReadSnap2(pReader, p, false);
pReader->pReadSnap = NULL;
diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c
index 7859ee4c66..fcce36b121 100644
--- a/source/dnode/vnode/src/tsdb/tsdbRetention.c
+++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c
@@ -325,11 +325,21 @@ static int32_t tsdbRetention(void *arg) {
// begin task
(void)taosThreadMutexLock(&pTsdb->mutex);
- tsdbBeginTaskOnFileSet(pTsdb, rtnArg->fid, &fset);
+
+ // check if background task is disabled
+ if (pTsdb->bgTaskDisabled) {
+ tsdbInfo("vgId:%d, background task is disabled, skip retention", TD_VID(pTsdb->pVnode));
+ (void)taosThreadMutexUnlock(&pTsdb->mutex);
+ return 0;
+ }
+
+ // set flag and copy
+ tsdbBeginTaskOnFileSet(pTsdb, rtnArg->fid, EVA_TASK_RETENTION, &fset);
if (fset && (code = tsdbTFileSetInitCopy(pTsdb, fset, &rtner.fset))) {
(void)taosThreadMutexUnlock(&pTsdb->mutex);
TSDB_CHECK_CODE(code, lino, _exit);
}
+
(void)taosThreadMutexUnlock(&pTsdb->mutex);
// do retention
@@ -346,7 +356,7 @@ static int32_t tsdbRetention(void *arg) {
_exit:
if (rtner.fset) {
(void)taosThreadMutexLock(&pTsdb->mutex);
- tsdbFinishTaskOnFileSet(pTsdb, rtnArg->fid);
+ tsdbFinishTaskOnFileSet(pTsdb, rtnArg->fid, EVA_TASK_RETENTION);
(void)taosThreadMutexUnlock(&pTsdb->mutex);
}
@@ -364,26 +374,29 @@ static int32_t tsdbAsyncRetentionImpl(STsdb *tsdb, int64_t now, bool s3Migrate)
int32_t code = 0;
int32_t lino = 0;
+ // check if background task is disabled
+ if (tsdb->bgTaskDisabled) {
+ tsdbInfo("vgId:%d, background task is disabled, skip retention", TD_VID(tsdb->pVnode));
+ return 0;
+ }
+
STFileSet *fset;
+ TARRAY2_FOREACH(tsdb->pFS->fSetArr, fset) {
+ SRtnArg *arg = taosMemoryMalloc(sizeof(*arg));
+ if (arg == NULL) {
+ TAOS_CHECK_GOTO(terrno, &lino, _exit);
+ }
- if (!tsdb->bgTaskDisabled) {
- TARRAY2_FOREACH(tsdb->pFS->fSetArr, fset) {
- TAOS_CHECK_GOTO(tsdbTFileSetOpenChannel(fset), &lino, _exit);
+ arg->tsdb = tsdb;
+ arg->now = now;
+ arg->fid = fset->fid;
+ arg->s3Migrate = s3Migrate;
- SRtnArg *arg = taosMemoryMalloc(sizeof(*arg));
- if (arg == NULL) {
- TAOS_CHECK_GOTO(terrno, &lino, _exit);
- }
-
- arg->tsdb = tsdb;
- arg->now = now;
- arg->fid = fset->fid;
- arg->s3Migrate = s3Migrate;
-
- if ((code = vnodeAsync(&fset->channel, EVA_PRIORITY_LOW, tsdbRetention, tsdbRetentionCancel, arg, NULL))) {
- taosMemoryFree(arg);
- TSDB_CHECK_CODE(code, lino, _exit);
- }
+ code = vnodeAsync(RETENTION_TASK_ASYNC, EVA_PRIORITY_LOW, tsdbRetention, tsdbRetentionCancel, arg,
+ &fset->retentionTask);
+ if (code) {
+ taosMemoryFree(arg);
+ TSDB_CHECK_CODE(code, lino, _exit);
}
}
diff --git a/source/dnode/vnode/src/vnd/vnodeAsync.c b/source/dnode/vnode/src/vnd/vnodeAsync.c
index 3f40ace6c4..49c1306736 100644
--- a/source/dnode/vnode/src/vnd/vnodeAsync.c
+++ b/source/dnode/vnode/src/vnd/vnodeAsync.c
@@ -118,9 +118,19 @@ struct SVAsync {
SVHashTable *taskTable;
};
-SVAsync *vnodeAsyncs[3];
+struct {
+ const char *label;
+ SVAsync *async;
+} GVnodeAsyncs[] = {
+ [0] = {NULL, NULL},
+ [1] = {"vnode-commit", NULL},
+ [2] = {"vnode-merge", NULL},
+ [3] = {"vnode-compact", NULL},
+ [4] = {"vnode-retention", NULL},
+};
+
#define MIN_ASYNC_ID 1
-#define MAX_ASYNC_ID (sizeof(vnodeAsyncs) / sizeof(vnodeAsyncs[0]) - 1)
+#define MAX_ASYNC_ID (sizeof(GVnodeAsyncs) / sizeof(GVnodeAsyncs[0]) - 1)
static void vnodeAsyncTaskDone(SVAsync *async, SVATask *task) {
int32_t ret;
@@ -447,36 +457,47 @@ static void vnodeAsyncLaunchWorker(SVAsync *async) {
}
}
-int32_t vnodeAsyncOpen(int32_t numOfThreads) {
+int32_t vnodeAsyncOpen() {
int32_t code = 0;
int32_t lino = 0;
- // vnode-commit
- code = vnodeAsyncInit(&vnodeAsyncs[1], "vnode-commit");
- TSDB_CHECK_CODE(code, lino, _exit);
+ int32_t numOfThreads[] = {
+ 0, //
+ tsNumOfCommitThreads, // vnode-commit
+ tsNumOfCommitThreads, // vnode-merge
+ tsNumOfCompactThreads, // vnode-compact
+ tsNumOfRetentionThreads, // vnode-retention
+ };
- code = vnodeAsyncSetWorkers(1, numOfThreads);
- TSDB_CHECK_CODE(code, lino, _exit);
+ for (int32_t i = 1; i < sizeof(GVnodeAsyncs) / sizeof(GVnodeAsyncs[0]); i++) {
+ code = vnodeAsyncInit(&GVnodeAsyncs[i].async, GVnodeAsyncs[i].label);
+ TSDB_CHECK_CODE(code, lino, _exit);
- // vnode-merge
- code = vnodeAsyncInit(&vnodeAsyncs[2], "vnode-merge");
- TSDB_CHECK_CODE(code, lino, _exit);
-
- code = vnodeAsyncSetWorkers(2, numOfThreads);
- TSDB_CHECK_CODE(code, lino, _exit);
+ code = vnodeAsyncSetWorkers(i, numOfThreads[i]);
+ TSDB_CHECK_CODE(code, lino, _exit);
+ }
_exit:
return code;
}
void vnodeAsyncClose() {
- int32_t ret;
- ret = vnodeAsyncDestroy(&vnodeAsyncs[1]);
- ret = vnodeAsyncDestroy(&vnodeAsyncs[2]);
+ for (int32_t i = 1; i < sizeof(GVnodeAsyncs) / sizeof(GVnodeAsyncs[0]); i++) {
+ int32_t ret = vnodeAsyncDestroy(&GVnodeAsyncs[i].async);
+ }
}
-int32_t vnodeAsync(SVAChannelID *channelID, EVAPriority priority, int32_t (*execute)(void *), void (*cancel)(void *),
- void *arg, SVATaskID *taskID) {
+int32_t vnodeAsync(int64_t async, EVAPriority priority, int32_t (*execute)(void *), void (*complete)(void *), void *arg,
+ SVATaskID *taskID) {
+ SVAChannelID channelID = {
+ .async = async,
+ .id = 0,
+ };
+ return vnodeAsyncC(&channelID, priority, execute, complete, arg, taskID);
+}
+
+int32_t vnodeAsyncC(SVAChannelID *channelID, EVAPriority priority, int32_t (*execute)(void *), void (*cancel)(void *),
+ void *arg, SVATaskID *taskID) {
if (channelID == NULL || channelID->async < MIN_ASYNC_ID || channelID->async > MAX_ASYNC_ID || execute == NULL ||
channelID->id < 0) {
return TSDB_CODE_INVALID_PARA;
@@ -484,7 +505,7 @@ int32_t vnodeAsync(SVAChannelID *channelID, EVAPriority priority, int32_t (*exec
int32_t ret;
int64_t id;
- SVAsync *async = vnodeAsyncs[channelID->async];
+ SVAsync *async = GVnodeAsyncs[channelID->async].async;
// create task object
SVATask *task = (SVATask *)taosMemoryCalloc(1, sizeof(SVATask));
@@ -594,7 +615,7 @@ void vnodeAWait(SVATaskID *taskID) {
return;
}
- SVAsync *async = vnodeAsyncs[taskID->async];
+ SVAsync *async = GVnodeAsyncs[taskID->async].async;
SVATask *task = NULL;
SVATask task2 = {
.taskId = taskID->id,
@@ -623,7 +644,7 @@ int32_t vnodeACancel(SVATaskID *taskID) {
}
int32_t ret = 0;
- SVAsync *async = vnodeAsyncs[taskID->async];
+ SVAsync *async = GVnodeAsyncs[taskID->async].async;
SVATask *task = NULL;
SVATask task2 = {
.taskId = taskID->id,
@@ -660,7 +681,7 @@ int32_t vnodeAsyncSetWorkers(int64_t asyncID, int32_t numWorkers) {
return TSDB_CODE_INVALID_PARA;
}
int32_t ret;
- SVAsync *async = vnodeAsyncs[asyncID];
+ SVAsync *async = GVnodeAsyncs[asyncID].async;
(void)taosThreadMutexLock(&async->mutex);
async->numWorkers = numWorkers;
if (async->numIdleWorkers > 0) {
@@ -676,7 +697,7 @@ int32_t vnodeAChannelInit(int64_t asyncID, SVAChannelID *channelID) {
return TSDB_CODE_INVALID_PARA;
}
- SVAsync *async = vnodeAsyncs[asyncID];
+ SVAsync *async = GVnodeAsyncs[asyncID].async;
// create channel object
SVAChannel *channel = (SVAChannel *)taosMemoryMalloc(sizeof(SVAChannel));
@@ -722,7 +743,7 @@ int32_t vnodeAChannelDestroy(SVAChannelID *channelID, bool waitRunning) {
return TSDB_CODE_INVALID_PARA;
}
- SVAsync *async = vnodeAsyncs[channelID->async];
+ SVAsync *async = GVnodeAsyncs[channelID->async].async;
SVAChannel *channel = NULL;
SVAChannel channel2 = {
.channelId = channelID->id,
@@ -806,4 +827,19 @@ int32_t vnodeAChannelDestroy(SVAChannelID *channelID, bool waitRunning) {
channelID->async = 0;
channelID->id = 0;
return 0;
+}
+
+const char *vnodeGetATaskName(EVATaskT taskType) {
+ switch (taskType) {
+ case EVA_TASK_COMMIT:
+ return "vnode-commit";
+ case EVA_TASK_MERGE:
+ return "vnode-merge";
+ case EVA_TASK_COMPACT:
+ return "vnode-compact";
+ case EVA_TASK_RETENTION:
+ return "vnode-retention";
+ default:
+ return "unknown";
+ }
}
\ No newline at end of file
diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c
index 28d27b8893..7fd3f9a8b6 100644
--- a/source/dnode/vnode/src/vnd/vnodeCommit.c
+++ b/source/dnode/vnode/src/vnd/vnodeCommit.c
@@ -389,8 +389,7 @@ int vnodeAsyncCommit(SVnode *pVnode) {
TSDB_CHECK_CODE(code, lino, _exit);
// schedule the task
- code =
- vnodeAsync(&pVnode->commitChannel, EVA_PRIORITY_HIGH, vnodeCommit, vnodeCommitCancel, pInfo, &pVnode->commitTask);
+ code = vnodeAsync(COMMIT_TASK_ASYNC, EVA_PRIORITY_HIGH, vnodeCommit, vnodeCommitCancel, pInfo, &pVnode->commitTask);
TSDB_CHECK_CODE(code, lino, _exit);
_exit:
diff --git a/source/dnode/vnode/src/vnd/vnodeModule.c b/source/dnode/vnode/src/vnd/vnodeModule.c
index 9d326defdd..ff537ef4a7 100644
--- a/source/dnode/vnode/src/vnd/vnodeModule.c
+++ b/source/dnode/vnode/src/vnd/vnodeModule.c
@@ -20,14 +20,13 @@
static volatile int32_t VINIT = 0;
-int vnodeInit(int nthreads, StopDnodeFp stopDnodeFp) {
+int vnodeInit(StopDnodeFp stopDnodeFp) {
if (atomic_val_compare_exchange_32(&VINIT, 0, 1)) {
return 0;
}
- TAOS_CHECK_RETURN(vnodeAsyncOpen(nthreads));
+ TAOS_CHECK_RETURN(vnodeAsyncOpen());
TAOS_CHECK_RETURN(walInit(stopDnodeFp));
- TAOS_CHECK_RETURN(tsdbInit());
monInitVnode();
@@ -36,7 +35,6 @@ int vnodeInit(int nthreads, StopDnodeFp stopDnodeFp) {
void vnodeCleanup() {
if (atomic_val_compare_exchange_32(&VINIT, 1, 0) == 0) return;
- tsdbCleanUp();
vnodeAsyncClose();
walCleanUp();
smaCleanUp();
diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c
index 945b4cbeae..6de5298728 100644
--- a/source/dnode/vnode/src/vnd/vnodeOpen.c
+++ b/source/dnode/vnode/src/vnd/vnodeOpen.c
@@ -438,11 +438,6 @@ SVnode *vnodeOpen(const char *path, int32_t diskPrimary, STfs *pTfs, SMsgCb msgC
(void)taosThreadMutexInit(&pVnode->mutex, NULL);
(void)taosThreadCondInit(&pVnode->poolNotEmpty, NULL);
- if (vnodeAChannelInit(1, &pVnode->commitChannel) != 0) {
- vError("vgId:%d, failed to init commit channel", TD_VID(pVnode));
- goto _err;
- }
-
int8_t rollback = vnodeShouldRollback(pVnode);
// open buffer pool
@@ -558,10 +553,6 @@ void vnodePostClose(SVnode *pVnode) { vnodeSyncPostClose(pVnode); }
void vnodeClose(SVnode *pVnode) {
if (pVnode) {
vnodeAWait(&pVnode->commitTask);
- if (vnodeAChannelDestroy(&pVnode->commitChannel, true) != 0) {
- vError("vgId:%d, failed to destroy commit channel", TD_VID(pVnode));
- }
-
vnodeSyncClose(pVnode);
vnodeQueryClose(pVnode);
tqClose(pVnode->pTq);
diff --git a/source/dnode/vnode/src/vnd/vnodeSnapshot.c b/source/dnode/vnode/src/vnd/vnodeSnapshot.c
index 0c11083367..9e3c6861c0 100644
--- a/source/dnode/vnode/src/vnd/vnodeSnapshot.c
+++ b/source/dnode/vnode/src/vnd/vnodeSnapshot.c
@@ -597,13 +597,11 @@ extern void tsdbEnableBgTask(STsdb *pTsdb);
static int32_t vnodeCancelAndDisableAllBgTask(SVnode *pVnode) {
TAOS_CHECK_RETURN(tsdbDisableAndCancelAllBgTask(pVnode->pTsdb));
TAOS_CHECK_RETURN(vnodeSyncCommit(pVnode));
- TAOS_CHECK_RETURN(vnodeAChannelDestroy(&pVnode->commitChannel, true));
return 0;
}
static int32_t vnodeEnableBgTask(SVnode *pVnode) {
tsdbEnableBgTask(pVnode->pTsdb);
- TAOS_CHECK_RETURN(vnodeAChannelInit(1, &pVnode->commitChannel));
return 0;
}
diff --git a/source/libs/catalog/CMakeLists.txt b/source/libs/catalog/CMakeLists.txt
index 3bdb0a9b1d..dd7220da15 100644
--- a/source/libs/catalog/CMakeLists.txt
+++ b/source/libs/catalog/CMakeLists.txt
@@ -11,6 +11,6 @@ target_link_libraries(
PRIVATE os util transport qcom nodes
)
-#if(${BUILD_TEST})
-# ADD_SUBDIRECTORY(test)
-#endif(${BUILD_TEST})
+if(${BUILD_TEST} AND NOT ${TD_WINDOWS})
+ ADD_SUBDIRECTORY(test)
+endif()
diff --git a/source/libs/executor/src/forecastoperator.c b/source/libs/executor/src/forecastoperator.c
index a56b0dd214..2985e5e000 100644
--- a/source/libs/executor/src/forecastoperator.c
+++ b/source/libs/executor/src/forecastoperator.c
@@ -72,17 +72,20 @@ static FORCE_INLINE int32_t forecastEnsureBlockCapacity(SSDataBlock* pBlock, int
return TSDB_CODE_SUCCESS;
}
-static int32_t forecastCacheBlock(SForecastSupp* pSupp, SSDataBlock* pBlock) {
- if (pSupp->cachedRows > ANAL_FORECAST_MAX_ROWS) {
- return TSDB_CODE_ANA_ANODE_TOO_MANY_ROWS;
- }
-
- int32_t code = TSDB_CODE_SUCCESS;
- int32_t lino = 0;
+static int32_t forecastCacheBlock(SForecastSupp* pSupp, SSDataBlock* pBlock, const char* id) {
+ int32_t code = TSDB_CODE_SUCCESS;
+ int32_t lino = 0;
SAnalyticBuf* pBuf = &pSupp->analBuf;
- qDebug("block:%d, %p rows:%" PRId64, pSupp->numOfBlocks, pBlock, pBlock->info.rows);
+ if (pSupp->cachedRows > ANAL_FORECAST_MAX_ROWS) {
+ code = TSDB_CODE_ANA_ANODE_TOO_MANY_ROWS;
+ qError("%s rows:%" PRId64 " for forecast cache, error happens, code:%s, upper limit:%d", id, pSupp->cachedRows,
+ tstrerror(code), ANAL_FORECAST_MAX_ROWS);
+ return code;
+ }
+
pSupp->numOfBlocks++;
+ qDebug("%s block:%d, %p rows:%" PRId64, id, pSupp->numOfBlocks, pBlock, pBlock->info.rows);
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
SColumnInfoData* pValCol = taosArrayGet(pBlock->pDataBlock, pSupp->inputValSlot);
@@ -98,10 +101,16 @@ static int32_t forecastCacheBlock(SForecastSupp* pSupp, SSDataBlock* pBlock) {
pSupp->numOfRows++;
code = taosAnalBufWriteColData(pBuf, 0, TSDB_DATA_TYPE_TIMESTAMP, &ts);
- if (TSDB_CODE_SUCCESS != code) return code;
+ if (TSDB_CODE_SUCCESS != code) {
+ qError("%s failed to write ts in buf, code:%s", id, tstrerror(code));
+ return code;
+ }
code = taosAnalBufWriteColData(pBuf, 1, valType, val);
- if (TSDB_CODE_SUCCESS != code) return code;
+ if (TSDB_CODE_SUCCESS != code) {
+ qError("%s failed to write val in buf, code:%s", id, tstrerror(code));
+ return code;
+ }
}
return 0;
@@ -394,7 +403,7 @@ static int32_t forecastNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
pSupp->cachedRows += pBlock->info.rows;
qDebug("%s group:%" PRId64 ", blocks:%d, rows:%" PRId64 ", total rows:%" PRId64, pId, pSupp->groupId, numOfBlocks,
pBlock->info.rows, pSupp->cachedRows);
- code = forecastCacheBlock(pSupp, pBlock);
+ code = forecastCacheBlock(pSupp, pBlock, pId);
QUERY_CHECK_CODE(code, lino, _end);
} else {
qDebug("%s group:%" PRId64 ", read finish for new group coming, blocks:%d", pId, pSupp->groupId, numOfBlocks);
@@ -405,7 +414,7 @@ static int32_t forecastNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
pSupp->cachedRows = pBlock->info.rows;
qDebug("%s group:%" PRId64 ", new group, rows:%" PRId64 ", total rows:%" PRId64, pId, pSupp->groupId,
pBlock->info.rows, pSupp->cachedRows);
- code = forecastCacheBlock(pSupp, pBlock);
+ code = forecastCacheBlock(pSupp, pBlock, pId);
QUERY_CHECK_CODE(code, lino, _end);
}
diff --git a/source/libs/executor/src/hashjoin.c b/source/libs/executor/src/hashjoin.c
index f63b4093db..da7686cce6 100755
--- a/source/libs/executor/src/hashjoin.c
+++ b/source/libs/executor/src/hashjoin.c
@@ -83,6 +83,8 @@ int32_t hInnerJoinDo(struct SOperatorInfo* pOperator) {
return code;
}
+#ifdef HASH_JOIN_FULL
+
int32_t hLeftJoinHandleSeqRowRemains(struct SOperatorInfo* pOperator, SHJoinOperatorInfo* pJoin, bool* loopCont) {
bool allFetched = false;
SHJoinCtx* pCtx = &pJoin->ctx;
@@ -346,4 +348,5 @@ int32_t hLeftJoinDo(struct SOperatorInfo* pOperator) {
return TSDB_CODE_SUCCESS;
}
+#endif
diff --git a/source/libs/executor/src/hashjoinoperator.c b/source/libs/executor/src/hashjoinoperator.c
index 64ce62cb66..73a5139e43 100644
--- a/source/libs/executor/src/hashjoinoperator.c
+++ b/source/libs/executor/src/hashjoinoperator.c
@@ -89,7 +89,7 @@ int32_t hJoinSetImplFp(SHJoinOperatorInfo* pJoin) {
case JOIN_TYPE_RIGHT: {
switch (pJoin->subType) {
case JOIN_STYPE_OUTER:
- pJoin->joinFp = hLeftJoinDo;
+ //pJoin->joinFp = hLeftJoinDo; TOOPEN
break;
default:
break;
diff --git a/source/libs/executor/test/CMakeLists.txt b/source/libs/executor/test/CMakeLists.txt
index cb1f951c94..4136640847 100644
--- a/source/libs/executor/test/CMakeLists.txt
+++ b/source/libs/executor/test/CMakeLists.txt
@@ -44,3 +44,15 @@ TARGET_INCLUDE_DIRECTORIES(
PUBLIC "${TD_SOURCE_DIR}/include/common"
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../inc"
)
+
+ADD_EXECUTABLE(execUtilTests execUtilTests.cpp)
+TARGET_LINK_LIBRARIES(
+ execUtilTests
+ PRIVATE os util common executor gtest_main qcom function planner scalar nodes vnode
+)
+
+TARGET_INCLUDE_DIRECTORIES(
+ execUtilTests
+ PUBLIC "${TD_SOURCE_DIR}/include/common"
+ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../inc"
+)
diff --git a/source/libs/executor/test/execUtilTests.cpp b/source/libs/executor/test/execUtilTests.cpp
new file mode 100644
index 0000000000..61b69fb9cf
--- /dev/null
+++ b/source/libs/executor/test/execUtilTests.cpp
@@ -0,0 +1,35 @@
+#include "gtest/gtest.h"
+
+#include "executil.h"
+
+TEST(execUtilTest, resRowTest) {
+ SDiskbasedBuf *pBuf = nullptr;
+ int32_t pageSize = 32;
+ int32_t numPages = 3;
+ int32_t code = createDiskbasedBuf(&pBuf, pageSize, pageSize * numPages, "test_buf", "/");
+ EXPECT_EQ(code, TSDB_CODE_SUCCESS);
+
+ std::vector pages(numPages);
+ std::vector pageIds(numPages);
+ for (int32_t i = 0; i < numPages; ++i) {
+ pages[i] = getNewBufPage(pBuf, &pageIds[i]);
+ EXPECT_NE(pages[i], nullptr);
+ EXPECT_EQ(pageIds[i], i);
+ }
+
+ EXPECT_EQ(getNewBufPage(pBuf, nullptr), nullptr);
+
+ SResultRowPosition pos;
+ pos.offset = 0;
+ for (int32_t i = 0; i < numPages; ++i) {
+ pos.pageId = pageIds[i];
+ bool forUpdate = i & 0x1;
+ SResultRow *row = getResultRowByPos(pBuf, &pos, forUpdate);
+ EXPECT_EQ((void *)row, pages[i]);
+ }
+
+ pos.pageId = numPages + 1;
+ EXPECT_EQ(getResultRowByPos(pBuf, &pos, true), nullptr);
+
+ destroyDiskbasedBuf(pBuf);
+}
diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c
index 4efa8764e5..b057194cdb 100644
--- a/source/libs/function/src/tudf.c
+++ b/source/libs/function/src/tudf.c
@@ -668,8 +668,8 @@ int32_t encodeUdfCallRequest(void **buf, const SUdfCallRequest *call) {
len += tEncodeDataBlock(buf, &call->block);
len += encodeUdfInterBuf(buf, &call->interBuf);
} else if (call->callType == TSDB_UDF_CALL_AGG_MERGE) {
- len += encodeUdfInterBuf(buf, &call->interBuf);
- len += encodeUdfInterBuf(buf, &call->interBuf2);
+ // len += encodeUdfInterBuf(buf, &call->interBuf);
+ // len += encodeUdfInterBuf(buf, &call->interBuf2);
} else if (call->callType == TSDB_UDF_CALL_AGG_FIN) {
len += encodeUdfInterBuf(buf, &call->interBuf);
}
@@ -690,10 +690,10 @@ void *decodeUdfCallRequest(const void *buf, SUdfCallRequest *call) {
buf = tDecodeDataBlock(buf, &call->block);
buf = decodeUdfInterBuf(buf, &call->interBuf);
break;
- case TSDB_UDF_CALL_AGG_MERGE:
- buf = decodeUdfInterBuf(buf, &call->interBuf);
- buf = decodeUdfInterBuf(buf, &call->interBuf2);
- break;
+ // case TSDB_UDF_CALL_AGG_MERGE:
+ // buf = decodeUdfInterBuf(buf, &call->interBuf);
+ // buf = decodeUdfInterBuf(buf, &call->interBuf2);
+ // break;
case TSDB_UDF_CALL_AGG_FIN:
buf = decodeUdfInterBuf(buf, &call->interBuf);
break;
@@ -779,9 +779,9 @@ int32_t encodeUdfCallResponse(void **buf, const SUdfCallResponse *callRsp) {
case TSDB_UDF_CALL_AGG_PROC:
len += encodeUdfInterBuf(buf, &callRsp->resultBuf);
break;
- case TSDB_UDF_CALL_AGG_MERGE:
- len += encodeUdfInterBuf(buf, &callRsp->resultBuf);
- break;
+ // case TSDB_UDF_CALL_AGG_MERGE:
+ // len += encodeUdfInterBuf(buf, &callRsp->resultBuf);
+ // break;
case TSDB_UDF_CALL_AGG_FIN:
len += encodeUdfInterBuf(buf, &callRsp->resultBuf);
break;
@@ -801,9 +801,9 @@ void *decodeUdfCallResponse(const void *buf, SUdfCallResponse *callRsp) {
case TSDB_UDF_CALL_AGG_PROC:
buf = decodeUdfInterBuf(buf, &callRsp->resultBuf);
break;
- case TSDB_UDF_CALL_AGG_MERGE:
- buf = decodeUdfInterBuf(buf, &callRsp->resultBuf);
- break;
+ // case TSDB_UDF_CALL_AGG_MERGE:
+ // buf = decodeUdfInterBuf(buf, &callRsp->resultBuf);
+ // break;
case TSDB_UDF_CALL_AGG_FIN:
buf = decodeUdfInterBuf(buf, &callRsp->resultBuf);
break;
@@ -1129,8 +1129,9 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
SSDataBlock *output, SUdfInterBuf *newState);
int32_t doCallUdfAggInit(UdfcFuncHandle handle, SUdfInterBuf *interBuf);
int32_t doCallUdfAggProcess(UdfcFuncHandle handle, SSDataBlock *block, SUdfInterBuf *state, SUdfInterBuf *newState);
-int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
- SUdfInterBuf *resultBuf);
+// udf todo: aggmerge
+// int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
+// SUdfInterBuf *resultBuf);
int32_t doCallUdfAggFinalize(UdfcFuncHandle handle, SUdfInterBuf *interBuf, SUdfInterBuf *resultData);
int32_t doCallUdfScalarFunc(UdfcFuncHandle handle, SScalarParam *input, int32_t numOfCols, SScalarParam *output);
int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols, SScalarParam *output);
@@ -2176,11 +2177,11 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
req->interBuf = *state;
break;
}
- case TSDB_UDF_CALL_AGG_MERGE: {
- req->interBuf = *state;
- req->interBuf2 = *state2;
- break;
- }
+ // case TSDB_UDF_CALL_AGG_MERGE: {
+ // req->interBuf = *state;
+ // req->interBuf2 = *state2;
+ // break;
+ // }
case TSDB_UDF_CALL_AGG_FIN: {
req->interBuf = *state;
break;
@@ -2205,10 +2206,10 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
*newState = rsp->resultBuf;
break;
}
- case TSDB_UDF_CALL_AGG_MERGE: {
- *newState = rsp->resultBuf;
- break;
- }
+ // case TSDB_UDF_CALL_AGG_MERGE: {
+ // *newState = rsp->resultBuf;
+ // break;
+ // }
case TSDB_UDF_CALL_AGG_FIN: {
*newState = rsp->resultBuf;
break;
@@ -2241,12 +2242,13 @@ int32_t doCallUdfAggProcess(UdfcFuncHandle handle, SSDataBlock *block, SUdfInter
// input: interbuf1, interbuf2
// output: resultBuf
-int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
- SUdfInterBuf *resultBuf) {
- int8_t callType = TSDB_UDF_CALL_AGG_MERGE;
- int32_t err = callUdf(handle, callType, NULL, interBuf1, interBuf2, NULL, resultBuf);
- return err;
-}
+// udf todo: aggmerge
+// int32_t doCallUdfAggMerge(UdfcFuncHandle handle, SUdfInterBuf *interBuf1, SUdfInterBuf *interBuf2,
+// SUdfInterBuf *resultBuf) {
+// int8_t callType = TSDB_UDF_CALL_AGG_MERGE;
+// int32_t err = callUdf(handle, callType, NULL, interBuf1, interBuf2, NULL, resultBuf);
+// return err;
+// }
// input: interBuf
// output: resultData
diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c
index bbfd43d5f7..ecb24fc77a 100644
--- a/source/libs/function/src/udfd.c
+++ b/source/libs/function/src/udfd.c
@@ -194,17 +194,17 @@ int32_t udfdCPluginUdfAggProc(SUdfDataBlock *block, SUdfInterBuf *interBuf, SUdf
}
}
-int32_t udfdCPluginUdfAggMerge(SUdfInterBuf *inputBuf1, SUdfInterBuf *inputBuf2, SUdfInterBuf *outputBuf,
- void *udfCtx) {
- TAOS_UDF_CHECK_PTR_RCODE(inputBuf1, inputBuf2, outputBuf, udfCtx);
- SUdfCPluginCtx *ctx = udfCtx;
- if (ctx->aggMergeFunc) {
- return ctx->aggMergeFunc(inputBuf1, inputBuf2, outputBuf);
- } else {
- fnError("udfd c plugin aggregation merge not implemented");
- return TSDB_CODE_UDF_FUNC_EXEC_FAILURE;
- }
-}
+// int32_t udfdCPluginUdfAggMerge(SUdfInterBuf *inputBuf1, SUdfInterBuf *inputBuf2, SUdfInterBuf *outputBuf,
+// void *udfCtx) {
+// TAOS_UDF_CHECK_PTR_RCODE(inputBuf1, inputBuf2, outputBuf, udfCtx);
+// SUdfCPluginCtx *ctx = udfCtx;
+// if (ctx->aggMergeFunc) {
+// return ctx->aggMergeFunc(inputBuf1, inputBuf2, outputBuf);
+// } else {
+// fnError("udfd c plugin aggregation merge not implemented");
+// return TSDB_CODE_UDF_FUNC_EXEC_FAILURE;
+// }
+// }
int32_t udfdCPluginUdfAggFinish(SUdfInterBuf *buf, SUdfInterBuf *resultData, void *udfCtx) {
TAOS_UDF_CHECK_PTR_RCODE(buf, resultData, udfCtx);
@@ -378,7 +378,7 @@ int32_t udfdInitializeCPlugin(SUdfScriptPlugin *plugin) {
plugin->udfScalarProcFunc = udfdCPluginUdfScalarProc;
plugin->udfAggStartFunc = udfdCPluginUdfAggStart;
plugin->udfAggProcFunc = udfdCPluginUdfAggProc;
- plugin->udfAggMergeFunc = udfdCPluginUdfAggMerge;
+ // plugin->udfAggMergeFunc = udfdCPluginUdfAggMerge;
plugin->udfAggFinishFunc = udfdCPluginUdfAggFinish;
SScriptUdfEnvItem items[1] = {{"LD_LIBRARY_PATH", tsUdfdLdLibPath}};
@@ -889,19 +889,19 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
break;
}
- case TSDB_UDF_CALL_AGG_MERGE: {
- SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
- if (outBuf.buf != NULL) {
- code = udf->scriptPlugin->udfAggMergeFunc(&call->interBuf, &call->interBuf2, &outBuf, udf->scriptUdfCtx);
- freeUdfInterBuf(&call->interBuf);
- freeUdfInterBuf(&call->interBuf2);
- subRsp->resultBuf = outBuf;
- } else {
- code = terrno;
- }
-
- break;
- }
+ // case TSDB_UDF_CALL_AGG_MERGE: {
+ // SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
+ // if (outBuf.buf != NULL) {
+ // code = udf->scriptPlugin->udfAggMergeFunc(&call->interBuf, &call->interBuf2, &outBuf, udf->scriptUdfCtx);
+ // freeUdfInterBuf(&call->interBuf);
+ // freeUdfInterBuf(&call->interBuf2);
+ // subRsp->resultBuf = outBuf;
+ // } else {
+ // code = terrno;
+ // }
+ //
+ // break;
+ // }
case TSDB_UDF_CALL_AGG_FIN: {
SUdfInterBuf outBuf = {.buf = taosMemoryMalloc(udf->bufSize), .bufLen = udf->bufSize, .numOfResult = 0};
if (outBuf.buf != NULL) {
@@ -959,10 +959,10 @@ _exit:
freeUdfInterBuf(&subRsp->resultBuf);
break;
}
- case TSDB_UDF_CALL_AGG_MERGE: {
- freeUdfInterBuf(&subRsp->resultBuf);
- break;
- }
+ // case TSDB_UDF_CALL_AGG_MERGE: {
+ // freeUdfInterBuf(&subRsp->resultBuf);
+ // break;
+ // }
case TSDB_UDF_CALL_AGG_FIN: {
freeUdfInterBuf(&subRsp->resultBuf);
break;
@@ -1667,7 +1667,6 @@ static int32_t udfdGlobalDataInit() {
}
static void udfdGlobalDataDeinit() {
- taosHashCleanup(global.udfsHash);
uv_mutex_destroy(&global.udfsMutex);
uv_mutex_destroy(&global.scriptPluginsMutex);
taosMemoryFreeClear(global.loop);
@@ -1720,8 +1719,11 @@ void udfdDeinitResidentFuncs() {
SUdf **udfInHash = taosHashGet(global.udfsHash, funcName, strlen(funcName));
if (udfInHash) {
SUdf *udf = *udfInHash;
- int32_t code = udf->scriptPlugin->udfDestroyFunc(udf->scriptUdfCtx);
- fnDebug("udfd destroy function returns %d", code);
+ int32_t code = 0;
+ if (udf->scriptPlugin->udfDestroyFunc) {
+ code = udf->scriptPlugin->udfDestroyFunc(udf->scriptUdfCtx);
+ fnDebug("udfd %s destroy function returns %d", funcName, code);
+ }
if(taosHashRemove(global.udfsHash, funcName, strlen(funcName)) != 0)
{
fnError("udfd remove resident function %s failed", funcName);
@@ -1729,6 +1731,7 @@ void udfdDeinitResidentFuncs() {
taosMemoryFree(udf);
}
}
+ taosHashCleanup(global.udfsHash);
taosArrayDestroy(global.residentFuncs);
fnInfo("udfd resident functions are deinit");
}
@@ -1838,15 +1841,15 @@ int main(int argc, char *argv[]) {
fnInfo("udfd exit normally");
removeListeningPipe();
- udfdDeinitScriptPlugins();
_exit:
- if (globalDataInited) {
- udfdGlobalDataDeinit();
- }
if (residentFuncsInited) {
udfdDeinitResidentFuncs();
}
+ udfdDeinitScriptPlugins();
+ if (globalDataInited) {
+ udfdGlobalDataDeinit();
+ }
if (udfSourceDirInited) {
udfdDestroyUdfSourceDir();
}
diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c
index 02e5bd34a6..1d1bc66414 100644
--- a/source/libs/index/src/indexFilter.c
+++ b/source/libs/index/src/indexFilter.c
@@ -326,7 +326,7 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
indexError("invalid length for node:%p, length: %d", node, LIST_LENGTH(nl->pNodeList));
SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
}
- SIF_ERR_RET(scalarGenerateSetFromList((void **)¶m->pFilter, node, nl->node.resType.type));
+ SIF_ERR_RET(scalarGenerateSetFromList((void **)¶m->pFilter, node, nl->node.resType.type, 0));
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
taosHashCleanup(param->pFilter);
param->pFilter = NULL;
diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c
index a13472620b..fa656667af 100644
--- a/source/libs/parser/src/parAstCreater.c
+++ b/source/libs/parser/src/parAstCreater.c
@@ -116,7 +116,7 @@ static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken,
strncpy(pPassword, pPasswordToken->z, pPasswordToken->n);
(void)strdequote(pPassword);
if (strtrim(pPassword) <= 0) {
- pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY);
+ pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY);
} else if (invalidPassword(pPassword)) {
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PASSWD);
}
diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c
index 502dbb57dd..ed1f498a32 100644
--- a/source/libs/parser/src/parInsertUtil.c
+++ b/source/libs/parser/src/parInsertUtil.c
@@ -101,10 +101,13 @@ int32_t insCreateSName(SName* pName, SToken* pTableName, int32_t acctId, const c
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
} else { // get current DB name first, and then set it into path
- if (pTableName->n >= TSDB_TABLE_NAME_LEN) {
+ char tbname[TSDB_TABLE_FNAME_LEN] = {0};
+ strncpy(tbname, pTableName->z, pTableName->n);
+ int32_t tbLen = strdequote(tbname);
+ if (tbLen >= TSDB_TABLE_NAME_LEN) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
- if (pTableName->n == 0) {
+ if (tbLen == 0) {
return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME, "invalid table name");
}
diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c
index feaa6910f2..342bd6d66e 100755
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -11411,7 +11411,7 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm
if (pSelect->hasInterpFunc) {
// Temporary code
- if (pStmt->pOptions->triggerType != STREAM_TRIGGER_FORCE_WINDOW_CLOSE) {
+ if (tsStreamCoverage == false && pStmt->pOptions->triggerType != STREAM_TRIGGER_FORCE_WINDOW_CLOSE) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
"Stream interp function only support force window close");
}
diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c
index 9706644324..0cda428487 100644
--- a/source/libs/parser/src/parUtil.c
+++ b/source/libs/parser/src/parUtil.c
@@ -57,8 +57,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Invalid tag name: %s";
case TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG:
return "Name or password too long";
- case TSDB_CODE_PAR_PASSWD_EMPTY:
- return "Password can not be empty";
+ case TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY:
+ return "Password too short or empty";
case TSDB_CODE_PAR_INVALID_PORT:
return "Port should be an integer that is less than 65535 and greater than 0";
case TSDB_CODE_PAR_INVALID_ENDPOINT:
diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c
index 690d38aac0..6d637bee98 100644
--- a/source/libs/qcom/src/queryUtil.c
+++ b/source/libs/qcom/src/queryUtil.c
@@ -137,6 +137,8 @@ static void processTaskQueue(SQueueInfo *pInfo, SSchedMsg *pSchedMsg) {
}
int32_t initTaskQueue() {
+ memset(&taskQueue, 0, sizeof(taskQueue));
+
taskQueue.wrokrerPool.name = "taskWorkPool";
taskQueue.wrokrerPool.min = tsNumOfTaskQueueThreads;
taskQueue.wrokrerPool.max = tsNumOfTaskQueueThreads;
diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c
index aae07c7512..4a9eea66e2 100644
--- a/source/libs/qworker/src/qworker.c
+++ b/source/libs/qworker/src/qworker.c
@@ -1049,12 +1049,16 @@ _return:
if (code || rsp) {
bool rsped = false;
+
+ ctx = NULL;
+ (void)qwAcquireTaskCtx(QW_FPARAMS(), &ctx);
+
if (ctx) {
qwDbgSimulateRedirect(qwMsg, ctx, &rsped);
qwDbgSimulateDead(QW_FPARAMS(), ctx, &rsped);
}
- if (!rsped) {
+ if (!rsped && ctx) {
code = qwBuildAndSendFetchRsp(ctx, qwMsg->msgType + 1, &qwMsg->connInfo, rsp, dataLen, code);
if (TSDB_CODE_SUCCESS != code) {
QW_TASK_ELOG("fetch rsp send fail, msgType:%s, handle:%p, code:%x - %s, dataLen:%d",
@@ -1067,6 +1071,8 @@ _return:
qwFreeFetchRsp(rsp);
rsp = NULL;
}
+
+ qwReleaseTaskCtx(mgmt, ctx);
} else {
// qwQuickRspFetchReq(QW_FPARAMS(), ctx, qwMsg, code);
}
diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h
index b04e26ac5d..8caa3edf42 100644
--- a/source/libs/scalar/inc/sclInt.h
+++ b/source/libs/scalar/inc/sclInt.h
@@ -143,7 +143,7 @@ int32_t sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode);
#define GET_PARAM_PRECISON(_c) ((_c)->columnData->info.precision)
void sclFreeParam(SScalarParam* param);
-int32_t doVectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
+int32_t doVectorCompare(SScalarParam* pLeft, SScalarParam *pLeftVar, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr);
int32_t vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr);
diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c
index a149384163..b329bbbd44 100644
--- a/source/libs/scalar/src/filter.c
+++ b/source/libs/scalar/src/filter.c
@@ -1298,7 +1298,6 @@ int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree,
if (node->opType == OP_TYPE_IN && (!IS_VAR_DATA_TYPE(type))) {
SNodeListNode *listNode = (SNodeListNode *)node->pRight;
- SListCell *cell = listNode->pNodeList->pHead;
SScalarParam out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
if (out.columnData == NULL) {
@@ -1308,8 +1307,9 @@ int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree,
out.columnData->info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; // reserved space for simple_copy
int32_t overflowCount = 0;
- for (int32_t i = 0; i < listNode->pNodeList->length; ++i) {
- SValueNode *valueNode = (SValueNode *)cell->pNode;
+ SNode* nodeItem = NULL;
+ FOREACH(nodeItem, listNode->pNodeList) {
+ SValueNode *valueNode = (SValueNode *)nodeItem;
if (valueNode->node.resType.type != type) {
int32_t overflow = 0;
code = sclConvertValueToSclParam(valueNode, &out, &overflow);
@@ -1319,7 +1319,6 @@ int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree,
}
if (overflow) {
- cell = cell->pNext;
++overflowCount;
continue;
}
@@ -1358,8 +1357,6 @@ int32_t fltAddGroupUnitFromNode(void *pContext, SFilterInfo *info, SNode *tree,
code = terrno;
break;
}
-
- cell = cell->pNext;
}
if(overflowCount == listNode->pNodeList->length) {
ctx->ignore = true;
@@ -2228,7 +2225,7 @@ int32_t fltInitValFieldData(SFilterInfo *info) {
}
if (unit->compare.optr == OP_TYPE_IN) {
- FLT_ERR_RET(scalarGenerateSetFromList((void **)&fi->data, fi->desc, type));
+ FLT_ERR_RET(scalarGenerateSetFromList((void **)&fi->data, fi->desc, type, 0));
if (fi->data == NULL) {
fltError("failed to convert in param");
FLT_ERR_RET(TSDB_CODE_APP_ERROR);
@@ -4765,7 +4762,7 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) {
return DEAL_RES_CONTINUE;
}
- if (node->opType == OP_TYPE_NOT_IN || node->opType == OP_TYPE_NOT_LIKE || node->opType > OP_TYPE_IS_NOT_NULL ||
+ if (node->opType == OP_TYPE_NOT_LIKE || node->opType > OP_TYPE_IS_NOT_NULL ||
node->opType == OP_TYPE_NOT_EQUAL) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
@@ -4839,7 +4836,7 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) {
}
}
- if (OP_TYPE_IN == node->opType && QUERY_NODE_NODE_LIST != nodeType(node->pRight)) {
+ if ((OP_TYPE_IN == node->opType || OP_TYPE_NOT_IN == node->opType) && QUERY_NODE_NODE_LIST != nodeType(node->pRight)) {
fltError("invalid IN operator node, rightType:%d", nodeType(node->pRight));
stat->code = TSDB_CODE_APP_ERROR;
return DEAL_RES_ERROR;
@@ -4847,25 +4844,37 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) {
SColumnNode *refNode = (SColumnNode *)node->pLeft;
SExprNode *exprNode = NULL;
- if (OP_TYPE_IN != node->opType) {
+ if (OP_TYPE_IN != node->opType && OP_TYPE_NOT_IN != node->opType) {
SValueNode *valueNode = (SValueNode *)node->pRight;
if (FILTER_GET_FLAG(stat->info->options, FLT_OPTION_TIMESTAMP) &&
TSDB_DATA_TYPE_UBIGINT == valueNode->node.resType.type && valueNode->datum.u <= INT64_MAX) {
valueNode->node.resType.type = TSDB_DATA_TYPE_BIGINT;
}
exprNode = &valueNode->node;
+ int32_t type = vectorGetConvertType(refNode->node.resType.type, exprNode->resType.type);
+ if (0 != type && type != refNode->node.resType.type) {
+ stat->scalarMode = true;
+ }
} else {
SNodeListNode *listNode = (SNodeListNode *)node->pRight;
- if (LIST_LENGTH(listNode->pNodeList) > 10) {
+ if (LIST_LENGTH(listNode->pNodeList) > 10 || OP_TYPE_NOT_IN == node->opType) {
stat->scalarMode = true;
- return DEAL_RES_CONTINUE;
}
+ int32_t type = refNode->node.resType.type;
exprNode = &listNode->node;
- }
- int32_t type = vectorGetConvertType(refNode->node.resType.type, exprNode->resType.type);
- if (0 != type && type != refNode->node.resType.type) {
- stat->scalarMode = true;
- return DEAL_RES_CONTINUE;
+ SNode* nodeItem = NULL;
+ FOREACH(nodeItem, listNode->pNodeList) {
+ SValueNode *valueNode = (SValueNode *)nodeItem;
+ int32_t tmp = vectorGetConvertType(type, valueNode->node.resType.type);
+ if (tmp != 0){
+ stat->scalarMode = true;
+ type = tmp;
+ }
+
+ }
+ if (IS_NUMERIC_TYPE(type)){
+ exprNode->resType.type = type;
+ }
}
}
@@ -5016,11 +5025,11 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_IN: {
SNodeListNode *listNode = (SNodeListNode *)oper->valNode;
- SListCell *cell = listNode->pNodeList->pHead;
SFltSclDatum minDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MAX, .type = oper->colNode->node.resType};
SFltSclDatum maxDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MIN, .type = oper->colNode->node.resType};
- for (int32_t i = 0; i < listNode->pNodeList->length; ++i) {
- SValueNode *valueNode = (SValueNode *)cell->pNode;
+ SNode* nodeItem = NULL;
+ FOREACH(nodeItem, listNode->pNodeList) {
+ SValueNode *valueNode = (SValueNode *)nodeItem;
SFltSclDatum valDatum;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, valueNode));
if(valueNode->node.resType.type == TSDB_DATA_TYPE_FLOAT || valueNode->node.resType.type == TSDB_DATA_TYPE_DOUBLE) {
@@ -5030,7 +5039,6 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
minDatum.i = TMIN(minDatum.i, valDatum.i);
maxDatum.i = TMAX(maxDatum.i, valDatum.i);
}
- cell = cell->pNext;
}
SFltSclPoint startPt = {.start = true, .excl = false, .val = minDatum};
SFltSclPoint endPt = {.start = false, .excl = false, .val = maxDatum};
diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c
index 6bd08f9ed2..9bab697772 100644
--- a/source/libs/scalar/src/scalar.c
+++ b/source/libs/scalar/src/scalar.c
@@ -116,7 +116,8 @@ _return:
SCL_RET(code);
}
-int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
+// processType = 0 means all type. 1 means number, 2 means var, 3 means float, 4 means var&integer
+int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type, int8_t processType) {
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
if (NULL == pObj) {
sclError("taosHashInit failed, size:%d", 256);
@@ -127,7 +128,6 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
int32_t code = 0;
SNodeListNode *nodeList = (SNodeListNode *)pNode;
- SListCell *cell = nodeList->pNodeList->pHead;
SScalarParam out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
if (out.columnData == NULL) {
SCL_ERR_JRET(terrno);
@@ -135,8 +135,14 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
int32_t len = 0;
void *buf = NULL;
- for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
- SValueNode *valueNode = (SValueNode *)cell->pNode;
+ SNode* nodeItem = NULL;
+ FOREACH(nodeItem, nodeList->pNodeList) {
+ SValueNode *valueNode = (SValueNode *)nodeItem;
+ if ((IS_VAR_DATA_TYPE(valueNode->node.resType.type) && (processType == 1 || processType == 3)) ||
+ (IS_INTEGER_TYPE(valueNode->node.resType.type) && (processType == 2 || processType == 3)) ||
+ (IS_FLOAT_TYPE(valueNode->node.resType.type) && (processType == 2 || processType == 4))) {
+ continue;
+ }
if (valueNode->node.resType.type != type) {
out.columnData->info.type = type;
@@ -158,7 +164,6 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
}
if (overflow) {
- cell = cell->pNext;
continue;
}
@@ -184,7 +189,6 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
}
colInfoDataCleanup(out.columnData, out.numOfRows);
- cell = cell->pNext;
}
*data = pObj;
@@ -230,6 +234,11 @@ void sclFreeParam(SScalarParam *param) {
taosHashCleanup(param->pHashFilter);
param->pHashFilter = NULL;
}
+
+ if (param->pHashFilterOthers != NULL) {
+ taosHashCleanup(param->pHashFilterOthers);
+ param->pHashFilterOthers = NULL;
+ }
}
int32_t sclCopyValueNodeValue(SValueNode *pNode, void **res) {
@@ -369,17 +378,37 @@ int32_t sclInitParam(SNode *node, SScalarParam *param, SScalarCtx *ctx, int32_t
SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
}
- int32_t type = vectorGetConvertType(ctx->type.selfType, ctx->type.peerType);
- if (type == 0) {
- type = nodeList->node.resType.type;
+ int32_t type = ctx->type.selfType;
+ SNode* nodeItem = NULL;
+ FOREACH(nodeItem, nodeList->pNodeList) {
+ SValueNode *valueNode = (SValueNode *)nodeItem;
+ int32_t tmp = vectorGetConvertType(type, valueNode->node.resType.type);
+ if (tmp != 0){
+ type = tmp;
+ }
+
+ }
+ if (IS_NUMERIC_TYPE(type)){
+ ctx->type.peerType = type;
+ }
+ type = ctx->type.peerType;
+ if (IS_VAR_DATA_TYPE(ctx->type.selfType) && IS_NUMERIC_TYPE(type)){
+ SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type, 1));
+ SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilterOthers, node, ctx->type.selfType, 2));
+ } else if (IS_INTEGER_TYPE(ctx->type.selfType) && IS_FLOAT_TYPE(type)){
+ SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type, 3));
+ SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilterOthers, node, ctx->type.selfType, 4));
+ } else {
+ SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type, 0));
}
- SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type));
param->hashValueType = type;
param->colAlloced = true;
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
taosHashCleanup(param->pHashFilter);
param->pHashFilter = NULL;
+ taosHashCleanup(param->pHashFilterOthers);
+ param->pHashFilterOthers = NULL;
sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
return terrno;
}
@@ -512,14 +541,15 @@ int32_t sclInitParamList(SScalarParam **pParams, SNodeList *pParamList, SScalarC
}
if (0 == *rowNum) {
- taosMemoryFreeClear(paramList);
+ sclFreeParamList(paramList, *paramNum);
+ paramList = NULL;
}
*pParams = paramList;
return TSDB_CODE_SUCCESS;
_return:
- taosMemoryFreeClear(paramList);
+ sclFreeParamList(paramList, *paramNum);
SCL_RET(code);
}
@@ -588,7 +618,6 @@ int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScal
SCL_ERR_JRET(sclInitParam(node->pLeft, ¶mList[0], ctx, rowNum));
setTzCharset(¶mList[0], node->tz, node->charsetCxt);
if (paramNum > 1) {
- TSWAP(ctx->type.selfType, ctx->type.peerType);
SCL_ERR_JRET(sclInitParam(node->pRight, ¶mList[1], ctx, rowNum));
setTzCharset(¶mList[1], node->tz, node->charsetCxt);
}
diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c
index 1da9a8f123..ce431c0b18 100644
--- a/source/libs/scalar/src/sclfunc.c
+++ b/source/libs/scalar/src/sclfunc.c
@@ -2985,279 +2985,93 @@ static int32_t doScalarFunction2(SScalarParam *pInput, int32_t inputNum, SScalar
bool hasNullType = (IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[0])) || IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[1])));
int32_t numOfRows = TMAX(pInput[0].numOfRows, pInput[1].numOfRows);
- if (pInput[0].numOfRows == pInput[1].numOfRows) {
- for (int32_t i = 0; i < numOfRows; ++i) {
- if (colDataIsNull_s(pInputData[0], i) || colDataIsNull_s(pInputData[1], i) || hasNullType) {
- colDataSetNULL(pOutputData, i);
- continue;
- }
- double in2;
- GET_TYPED_DATA(in2, double, GET_PARAM_TYPE(&pInput[1]), colDataGetData(pInputData[1], i));
- switch (GET_PARAM_TYPE(&pInput[0])) {
- case TSDB_DATA_TYPE_DOUBLE: {
- double *in = (double *)pInputData[0]->pData;
- double *out = (double *)pOutputData->pData;
- double result = d1(in[i], in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_FLOAT: {
- float *in = (float *)pInputData[0]->pData;
- float *out = (float *)pOutputData->pData;
- float result = f1(in[i], (float)in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_TINYINT: {
- int8_t *in = (int8_t *)pInputData[0]->pData;
- int8_t *out = (int8_t *)pOutputData->pData;
- int8_t result = (int8_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_SMALLINT: {
- int16_t *in = (int16_t *)pInputData[0]->pData;
- int16_t *out = (int16_t *)pOutputData->pData;
- int16_t result = (int16_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_INT: {
- int32_t *in = (int32_t *)pInputData[0]->pData;
- int32_t *out = (int32_t *)pOutputData->pData;
- int32_t result = (int32_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_BIGINT: {
- int64_t *in = (int64_t *)pInputData[0]->pData;
- int64_t *out = (int64_t *)pOutputData->pData;
- int64_t result = (int64_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UTINYINT: {
- uint8_t *in = (uint8_t *)pInputData[0]->pData;
- uint8_t *out = (uint8_t *)pOutputData->pData;
- uint8_t result = (uint8_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_USMALLINT: {
- uint16_t *in = (uint16_t *)pInputData[0]->pData;
- uint16_t *out = (uint16_t *)pOutputData->pData;
- uint16_t result = (uint16_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UINT: {
- uint32_t *in = (uint32_t *)pInputData[0]->pData;
- uint32_t *out = (uint32_t *)pOutputData->pData;
- uint32_t result = (uint32_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UBIGINT: {
- uint64_t *in = (uint64_t *)pInputData[0]->pData;
- uint64_t *out = (uint64_t *)pOutputData->pData;
- uint64_t result = (uint64_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- }
+ for (int32_t i = 0; i < numOfRows; ++i) {
+ int32_t colIdx1 = (pInput[0].numOfRows == 1) ? 0 : i;
+ int32_t colIdx2 = (pInput[1].numOfRows == 1) ? 0 : i;
+ if (colDataIsNull_s(pInputData[0], colIdx1) || colDataIsNull_s(pInputData[1], colIdx2) || hasNullType) {
+ colDataSetNULL(pOutputData, i);
+ continue;
}
- } else if (pInput[0].numOfRows == 1) { // left operand is constant
- if (colDataIsNull_s(pInputData[0], 0) || hasNullType) {
- colDataSetNNULL(pOutputData, 0, pInput[1].numOfRows);
- } else {
- for (int32_t i = 0; i < numOfRows; ++i) {
- if (colDataIsNull_s(pInputData[1], i)) {
+ double in2;
+ GET_TYPED_DATA(in2, double, GET_PARAM_TYPE(&pInput[1]), colDataGetData(pInputData[1], colIdx2));
+ switch (GET_PARAM_TYPE(&pInput[0])) {
+ case TSDB_DATA_TYPE_DOUBLE: {
+ double *in = (double *)pInputData[0]->pData;
+ double *out = (double *)pOutputData->pData;
+ double result = d1(in[colIdx1], in2);
+ if (isinf(result) || isnan(result)) {
colDataSetNULL(pOutputData, i);
- continue;
- }
- double in2;
- GET_TYPED_DATA(in2, double, GET_PARAM_TYPE(&pInput[1]), colDataGetData(pInputData[1], i));
- switch (GET_PARAM_TYPE(&pInput[0])) {
- case TSDB_DATA_TYPE_DOUBLE: {
- double *in = (double *)pInputData[0]->pData;
- double *out = (double *)pOutputData->pData;
- double result = d1(in[0], in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_FLOAT: {
- float *in = (float *)pInputData[0]->pData;
- float *out = (float *)pOutputData->pData;
- float result = f1(in[0], (float)in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_TINYINT: {
- int8_t *in = (int8_t *)pInputData[0]->pData;
- int8_t *out = (int8_t *)pOutputData->pData;
- int8_t result = (int8_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_SMALLINT: {
- int16_t *in = (int16_t *)pInputData[0]->pData;
- int16_t *out = (int16_t *)pOutputData->pData;
- int16_t result = (int16_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_INT: {
- int32_t *in = (int32_t *)pInputData[0]->pData;
- int32_t *out = (int32_t *)pOutputData->pData;
- int32_t result = (int32_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_BIGINT: {
- int64_t *in = (int64_t *)pInputData[0]->pData;
- int64_t *out = (int64_t *)pOutputData->pData;
- int64_t result = (int64_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UTINYINT: {
- uint8_t *in = (uint8_t *)pInputData[0]->pData;
- uint8_t *out = (uint8_t *)pOutputData->pData;
- uint8_t result = (uint8_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_USMALLINT: {
- uint16_t *in = (uint16_t *)pInputData[0]->pData;
- uint16_t *out = (uint16_t *)pOutputData->pData;
- uint16_t result = (uint16_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UINT: {
- uint32_t *in = (uint32_t *)pInputData[0]->pData;
- uint32_t *out = (uint32_t *)pOutputData->pData;
- uint32_t result = (uint32_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UBIGINT: {
- uint64_t *in = (uint64_t *)pInputData[0]->pData;
- uint64_t *out = (uint64_t *)pOutputData->pData;
- uint64_t result = (uint64_t)d1((double)in[0], in2);
- out[i] = result;
- break;
- }
+ } else {
+ out[i] = result;
}
+ break;
}
- }
- } else if (pInput[1].numOfRows == 1) {
- if (colDataIsNull_s(pInputData[1], 0) || hasNullType) {
- colDataSetNNULL(pOutputData, 0, pInput[0].numOfRows);
- } else {
- for (int32_t i = 0; i < numOfRows; ++i) {
- if (colDataIsNull_s(pInputData[0], i)) {
+ case TSDB_DATA_TYPE_FLOAT: {
+ float *in = (float *)pInputData[0]->pData;
+ float *out = (float *)pOutputData->pData;
+ float result = f1(in[colIdx1], (float)in2);
+ if (isinf(result) || isnan(result)) {
colDataSetNULL(pOutputData, i);
- continue;
- }
- double in2;
- GET_TYPED_DATA(in2, double, GET_PARAM_TYPE(&pInput[1]), colDataGetData(pInputData[1], 0));
- switch (GET_PARAM_TYPE(&pInput[0])) {
- case TSDB_DATA_TYPE_DOUBLE: {
- double *in = (double *)pInputData[0]->pData;
- double *out = (double *)pOutputData->pData;
- double result = d1(in[i], in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_FLOAT: {
- float *in = (float *)pInputData[0]->pData;
- float *out = (float *)pOutputData->pData;
- float result = f1(in[i], in2);
- if (isinf(result) || isnan(result)) {
- colDataSetNULL(pOutputData, i);
- } else {
- out[i] = result;
- }
- break;
- }
- case TSDB_DATA_TYPE_TINYINT: {
- int8_t *in = (int8_t *)pInputData[0]->pData;
- int8_t *out = (int8_t *)pOutputData->pData;
- int8_t result = (int8_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_SMALLINT: {
- int16_t *in = (int16_t *)pInputData[0]->pData;
- int16_t *out = (int16_t *)pOutputData->pData;
- int16_t result = (int16_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_INT: {
- int32_t *in = (int32_t *)pInputData[0]->pData;
- int32_t *out = (int32_t *)pOutputData->pData;
- int32_t result = (int32_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_BIGINT: {
- int64_t *in = (int64_t *)pInputData[0]->pData;
- int64_t *out = (int64_t *)pOutputData->pData;
- int64_t result = (int64_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UTINYINT: {
- uint8_t *in = (uint8_t *)pInputData[0]->pData;
- uint8_t *out = (uint8_t *)pOutputData->pData;
- uint8_t result = (uint8_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_USMALLINT: {
- uint16_t *in = (uint16_t *)pInputData[0]->pData;
- uint16_t *out = (uint16_t *)pOutputData->pData;
- uint16_t result = (uint16_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UINT: {
- uint32_t *in = (uint32_t *)pInputData[0]->pData;
- uint32_t *out = (uint32_t *)pOutputData->pData;
- uint32_t result = (uint32_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
- case TSDB_DATA_TYPE_UBIGINT: {
- uint64_t *in = (uint64_t *)pInputData[0]->pData;
- uint64_t *out = (uint64_t *)pOutputData->pData;
- uint64_t result = (uint64_t)d1((double)in[i], in2);
- out[i] = result;
- break;
- }
+ } else {
+ out[i] = result;
}
+ break;
+ }
+ case TSDB_DATA_TYPE_TINYINT: {
+ int8_t *in = (int8_t *)pInputData[0]->pData;
+ int8_t *out = (int8_t *)pOutputData->pData;
+ int8_t result = (int8_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_SMALLINT: {
+ int16_t *in = (int16_t *)pInputData[0]->pData;
+ int16_t *out = (int16_t *)pOutputData->pData;
+ int16_t result = (int16_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_INT: {
+ int32_t *in = (int32_t *)pInputData[0]->pData;
+ int32_t *out = (int32_t *)pOutputData->pData;
+ int32_t result = (int32_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_BIGINT: {
+ int64_t *in = (int64_t *)pInputData[0]->pData;
+ int64_t *out = (int64_t *)pOutputData->pData;
+ int64_t result = (int64_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_UTINYINT: {
+ uint8_t *in = (uint8_t *)pInputData[0]->pData;
+ uint8_t *out = (uint8_t *)pOutputData->pData;
+ uint8_t result = (uint8_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_USMALLINT: {
+ uint16_t *in = (uint16_t *)pInputData[0]->pData;
+ uint16_t *out = (uint16_t *)pOutputData->pData;
+ uint16_t result = (uint16_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_UINT: {
+ uint32_t *in = (uint32_t *)pInputData[0]->pData;
+ uint32_t *out = (uint32_t *)pOutputData->pData;
+ uint32_t result = (uint32_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
+ }
+ case TSDB_DATA_TYPE_UBIGINT: {
+ uint64_t *in = (uint64_t *)pInputData[0]->pData;
+ uint64_t *out = (uint64_t *)pOutputData->pData;
+ uint64_t result = (uint64_t)d1((double)in[colIdx1], in2);
+ out[i] = result;
+ break;
}
}
}
diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c
index 81ce23cb10..14dae1226d 100644
--- a/source/libs/scalar/src/sclvector.c
+++ b/source/libs/scalar/src/sclvector.c
@@ -121,19 +121,6 @@ _return:
SCL_RET(code);
}
-int32_t convertBinaryToDouble(const void *inData, void *outData) {
- char *tmp = taosMemoryCalloc(1, varDataTLen(inData));
- if (tmp == NULL) {
- *((double *)outData) = 0.;
- SCL_ERR_RET(terrno);
- }
- (void)memcpy(tmp, varDataVal(inData), varDataLen(inData));
- double ret = taosStr2Double(tmp, NULL);
- taosMemoryFree(tmp);
- *((double *)outData) = ret;
- SCL_RET(TSDB_CODE_SUCCESS);
-}
-
typedef int32_t (*_getBigintValue_fn_t)(void *src, int32_t index, int64_t *res);
int32_t getVectorBigintValue_TINYINT(void *src, int32_t index, int64_t *res) {
@@ -1009,28 +996,29 @@ int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut,
}
int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = {
- /* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/
- /*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 7, 11, 12, 13, 14, 0, -1, 0, 0, 0, -1,
- /*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 7, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1,
- /*SMAL*/ 0, 0, 0, 0, 4, 5, 6, 7, 5, 9, 7, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1,
- /*INT */ 0, 0, 0, 0, 0, 5, 6, 7, 5, 9, 7, 4, 4, 5, 7, 0, -1, 0, 0, 0, -1,
- /*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 7, 5, 5, 5, 7, 0, -1, 0, 0, 0, -1,
- /*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 7, 6, 7, 6, 6, 6, 6, 0, -1, 0, 0, 0, -1,
- /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, -1, 0, 0, 0, -1,
- /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 16, 0, 0, 0, 20,
- /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, -1, 0, 0, 0, -1,
- /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 16, 0, 0, 0, -1,
- /*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, -1, 0, 0, 0, -1,
- /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 0, -1, 0, 0, 0, -1,
- /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, -1, 0, 0, 0, -1,
- /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
- /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
- /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,-1, -1,
- /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
- /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
- /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
- /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0};
+ /*NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/
+ /*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 5, 11, 12, 13, 14, 0, -1, 0, 0, 0, -1,
+ /*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1,
+ /*SMAL*/ 0, 0, 0, 0, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1,
+ /*INT */ 0, 0, 0, 0, 0, 5, 6, 7, 5, 9, 5, 4, 4, 5, 7, 0, -1, 0, 0, 0, -1,
+ /*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 5, 5, 5, 5, 7, 0, -1, 0, 0, 0, -1,
+ /*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 6, 6, 6, 6, 6, 6, 6, 0, -1, 0, 0, 0, -1,
+ /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, -1, 0, 0, 0, -1,
+ /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 16, 0, 0, 0, 20,
+ /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, -1, 0, 0, 0, -1,
+ /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 16, 0, 0, 0, -1,
+ /*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, -1, 0, 0, 0, -1,
+ /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 0, -1, 0, 0, 0, -1,
+ /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, -1, 0, 0, 0, -1,
+ /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
+ /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
+ /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1,
+ /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
+ /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
+ /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1,
+ /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0
+};
int8_t gDisplyTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = {
/*NULL BOOL TINY SMAL INT BIGI FLOA DOUB VARC TIM NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/
@@ -1071,6 +1059,9 @@ int32_t vectorGetConvertType(int32_t type1, int32_t type2) {
int32_t vectorConvertSingleCol(SScalarParam *input, SScalarParam *output, int32_t type, int32_t startIndex,
int32_t numOfRows) {
+ if (input->columnData == NULL && (input->pHashFilter != NULL || input->pHashFilterOthers != NULL)){
+ return TSDB_CODE_SUCCESS;
+ }
output->numOfRows = input->numOfRows;
SDataType t = {.type = type};
@@ -1101,36 +1092,18 @@ int32_t vectorConvertCols(SScalarParam *pLeft, SScalarParam *pRight, SScalarPara
int8_t type = 0;
int32_t code = 0;
- SScalarParam *param1 = NULL, *paramOut1 = NULL;
- SScalarParam *param2 = NULL, *paramOut2 = NULL;
+ SScalarParam *param1 = pLeft, *paramOut1 = pLeftOut;
+ SScalarParam *param2 = pRight, *paramOut2 = pRightOut;
// always convert least data
if (IS_VAR_DATA_TYPE(leftType) && IS_VAR_DATA_TYPE(rightType) && (pLeft->numOfRows != pRight->numOfRows) &&
leftType != TSDB_DATA_TYPE_JSON && rightType != TSDB_DATA_TYPE_JSON) {
- param1 = pLeft;
- param2 = pRight;
- paramOut1 = pLeftOut;
- paramOut2 = pRightOut;
-
if (pLeft->numOfRows > pRight->numOfRows) {
type = leftType;
} else {
type = rightType;
}
} else {
- // we only define half value in the convert-matrix, so make sure param1 always less equal than param2
- if (leftType < rightType) {
- param1 = pLeft;
- param2 = pRight;
- paramOut1 = pLeftOut;
- paramOut2 = pRightOut;
- } else {
- param1 = pRight;
- param2 = pLeft;
- paramOut1 = pRightOut;
- paramOut2 = pLeftOut;
- }
-
type = vectorGetConvertType(GET_PARAM_TYPE(param1), GET_PARAM_TYPE(param2));
if (0 == type) {
return TSDB_CODE_SUCCESS;
@@ -1143,17 +1116,11 @@ int32_t vectorConvertCols(SScalarParam *pLeft, SScalarParam *pRight, SScalarPara
}
if (type != GET_PARAM_TYPE(param1)) {
- code = vectorConvertSingleCol(param1, paramOut1, type, startIndex, numOfRows);
- if (code) {
- return code;
- }
+ SCL_ERR_RET(vectorConvertSingleCol(param1, paramOut1, type, startIndex, numOfRows));
}
if (type != GET_PARAM_TYPE(param2)) {
- code = vectorConvertSingleCol(param2, paramOut2, type, startIndex, numOfRows);
- if (code) {
- return code;
- }
+ SCL_ERR_RET(vectorConvertSingleCol(param2, paramOut2, type, startIndex, numOfRows));
}
return TSDB_CODE_SUCCESS;
@@ -1222,22 +1189,16 @@ static int32_t vectorMathTsAddHelper(SColumnInfoData *pLeftCol, SColumnInfoData
static int32_t vectorConvertVarToDouble(SScalarParam *pInput, int32_t *converted, SColumnInfoData **pOutputCol) {
SScalarParam output = {0};
SColumnInfoData *pCol = pInput->columnData;
-
+ int32_t code = TSDB_CODE_SUCCESS;
+ *pOutputCol = NULL;
if (IS_VAR_DATA_TYPE(pCol->info.type) && pCol->info.type != TSDB_DATA_TYPE_JSON && pCol->info.type != TSDB_DATA_TYPE_VARBINARY) {
- int32_t code = vectorConvertSingleCol(pInput, &output, TSDB_DATA_TYPE_DOUBLE, -1, -1);
- if (code != TSDB_CODE_SUCCESS) {
- *pOutputCol = NULL;
- SCL_ERR_RET(code);
- }
-
+ SCL_ERR_RET(vectorConvertSingleCol(pInput, &output, TSDB_DATA_TYPE_DOUBLE, -1, -1));
*converted = VECTOR_DO_CONVERT;
-
*pOutputCol = output.columnData;
SCL_RET(code);
}
*converted = VECTOR_UN_CONVERT;
-
*pOutputCol = pInput->columnData;
SCL_RET(TSDB_CODE_SUCCESS);
}
@@ -1630,68 +1591,25 @@ int32_t vectorMathRemainder(SScalarParam *pLeft, SScalarParam *pRight, SScalarPa
double *output = (double *)pOutputCol->pData;
- if (pLeft->numOfRows == pRight->numOfRows) {
- for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) {
- if (IS_NULL) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- double lx = 0;
- double rx = 0;
- SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &lx));
- SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, i, &rx));
- if (isnan(lx) || isinf(lx) || isnan(rx) || isinf(rx) || FLT_EQUAL(rx, 0)) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- *output = lx - ((int64_t)(lx / rx)) * rx;
+ int32_t numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
+ for (; i < numOfRows && i >= 0; i += step, output += 1) {
+ int32_t leftidx = pLeft->numOfRows == 1 ? 0 : i;
+ int32_t rightidx = pRight->numOfRows == 1 ? 0 : i;
+ if (IS_HELPER_NULL(pLeftCol, leftidx) || IS_HELPER_NULL(pRightCol, rightidx)) {
+ colDataSetNULL(pOutputCol, i);
+ continue;
}
- } else if (pLeft->numOfRows == 1) {
+
double lx = 0;
- SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, 0, &lx));
- if (IS_HELPER_NULL(pLeftCol, 0)) { // Set pLeft->numOfRows NULL value
- colDataSetNNULL(pOutputCol, 0, pRight->numOfRows);
- } else {
- for (; i >= 0 && i < pRight->numOfRows; i += step, output += 1) {
- if (IS_HELPER_NULL(pRightCol, i)) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- double rx = 0;
- SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, i, &rx));
- if (isnan(rx) || isinf(rx) || FLT_EQUAL(rx, 0)) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- *output = lx - ((int64_t)(lx / rx)) * rx;
- }
- }
- } else if (pRight->numOfRows == 1) {
double rx = 0;
- SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, 0, &rx));
- if (IS_HELPER_NULL(pRightCol, 0) || FLT_EQUAL(rx, 0)) { // Set pLeft->numOfRows NULL value
- colDataSetNNULL(pOutputCol, 0, pLeft->numOfRows);
- } else {
- for (; i >= 0 && i < pLeft->numOfRows; i += step, output += 1) {
- if (IS_HELPER_NULL(pLeftCol, i)) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- double lx = 0;
- SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &lx));
- if (isnan(lx) || isinf(lx)) {
- colDataSetNULL(pOutputCol, i);
- continue;
- }
-
- *output = lx - ((int64_t)(lx / rx)) * rx;
- }
+ SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, leftidx, &lx));
+ SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, rightidx, &rx));
+ if (isnan(lx) || isinf(lx) || isnan(rx) || isinf(rx) || FLT_EQUAL(rx, 0)) {
+ colDataSetNULL(pOutputCol, i);
+ continue;
}
+
+ *output = lx - ((int64_t)(lx / rx)) * rx;
}
_return:
@@ -1753,33 +1671,6 @@ int32_t vectorAssign(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pO
return TSDB_CODE_SUCCESS;
}
-static int32_t vectorBitAndHelper(SColumnInfoData *pLeftCol, SColumnInfoData *pRightCol, SColumnInfoData *pOutputCol,
- int32_t numOfRows, int32_t step, int32_t i) {
- _getBigintValue_fn_t getVectorBigintValueFnLeft;
- _getBigintValue_fn_t getVectorBigintValueFnRight;
- SCL_ERR_RET(getVectorBigintValueFn(pLeftCol->info.type, &getVectorBigintValueFnLeft));
- SCL_ERR_RET(getVectorBigintValueFn(pRightCol->info.type, &getVectorBigintValueFnRight));
-
- int64_t *output = (int64_t *)pOutputCol->pData;
-
- if (IS_HELPER_NULL(pRightCol, 0)) { // Set pLeft->numOfRows NULL value
- colDataSetNNULL(pOutputCol, 0, numOfRows);
- } else {
- for (; i >= 0 && i < numOfRows; i += step, output += 1) {
- if (IS_HELPER_NULL(pLeftCol, i)) {
- colDataSetNULL(pOutputCol, i);
- continue; // TODO set null or ignore
- }
- int64_t leftRes = 0;
- int64_t rightRes = 0;
- SCL_ERR_RET(getVectorBigintValueFnLeft(LEFT_COL, i, &leftRes));
- SCL_ERR_RET(getVectorBigintValueFnRight(RIGHT_COL, 0, &rightRes));
- *output = leftRes & rightRes;
- }
- }
- SCL_RET(TSDB_CODE_SUCCESS);
-}
-
int32_t vectorBitAnd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord) {
SColumnInfoData *pOutputCol = pOut->columnData;
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
@@ -1800,22 +1691,19 @@ int32_t vectorBitAnd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pO
SCL_ERR_JRET(getVectorBigintValueFn(pRightCol->info.type, &getVectorBigintValueFnRight));
int64_t *output = (int64_t *)pOutputCol->pData;
- if (pLeft->numOfRows == pRight->numOfRows) {
- for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) {
- if (IS_NULL) {
- colDataSetNULL(pOutputCol, i);
- continue; // TODO set null or ignore
- }
- int64_t leftRes = 0;
- int64_t rightRes = 0;
- SCL_ERR_JRET(getVectorBigintValueFnLeft(LEFT_COL, i, &leftRes));
- SCL_ERR_JRET(getVectorBigintValueFnRight(RIGHT_COL, i, &rightRes));
- *output = leftRes & rightRes;
+ int32_t numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
+ for (; i < numOfRows && i >= 0; i += step, output += 1) {
+ int32_t leftidx = pLeft->numOfRows == 1 ? 0 : i;
+ int32_t rightidx = pRight->numOfRows == 1 ? 0 : i;
+ if (IS_HELPER_NULL(pRightCol, rightidx) || IS_HELPER_NULL(pLeftCol, leftidx)) {
+ colDataSetNULL(pOutputCol, i);
+ continue; // TODO set null or ignore
}
- } else if (pLeft->numOfRows == 1) {
- SCL_ERR_JRET(vectorBitAndHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i));
- } else if (pRight->numOfRows == 1) {
- SCL_ERR_JRET(vectorBitAndHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i));
+ int64_t leftRes = 0;
+ int64_t rightRes = 0;
+ SCL_ERR_JRET(getVectorBigintValueFnLeft(LEFT_COL, leftidx, &leftRes));
+ SCL_ERR_JRET(getVectorBigintValueFnRight(RIGHT_COL, rightidx, &rightRes));
+ *output = leftRes & rightRes;
}
_return:
@@ -1824,33 +1712,6 @@ _return:
SCL_RET(code);
}
-static int32_t vectorBitOrHelper(SColumnInfoData *pLeftCol, SColumnInfoData *pRightCol, SColumnInfoData *pOutputCol,
- int32_t numOfRows, int32_t step, int32_t i) {
- _getBigintValue_fn_t getVectorBigintValueFnLeft;
- _getBigintValue_fn_t getVectorBigintValueFnRight;
- SCL_ERR_RET(getVectorBigintValueFn(pLeftCol->info.type, &getVectorBigintValueFnLeft));
- SCL_ERR_RET(getVectorBigintValueFn(pRightCol->info.type, &getVectorBigintValueFnRight));
-
- int64_t *output = (int64_t *)pOutputCol->pData;
-
- if (IS_HELPER_NULL(pRightCol, 0)) { // Set pLeft->numOfRows NULL value
- colDataSetNNULL(pOutputCol, 0, numOfRows);
- } else {
- int64_t rx = 0;
- SCL_ERR_RET(getVectorBigintValueFnRight(RIGHT_COL, 0, &rx));
- for (; i >= 0 && i < numOfRows; i += step, output += 1) {
- if (IS_HELPER_NULL(pLeftCol, i)) {
- colDataSetNULL(pOutputCol, i);
- continue; // TODO set null or ignore
- }
- int64_t lx = 0;
- SCL_ERR_RET(getVectorBigintValueFnLeft(LEFT_COL, i, &lx));
- *output = lx | rx;
- }
- }
- SCL_RET(TSDB_CODE_SUCCESS);
-}
-
int32_t vectorBitOr(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord) {
SColumnInfoData *pOutputCol = pOut->columnData;
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
@@ -1871,22 +1732,20 @@ int32_t vectorBitOr(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOu
SCL_ERR_JRET(getVectorBigintValueFn(pRightCol->info.type, &getVectorBigintValueFnRight));
int64_t *output = (int64_t *)pOutputCol->pData;
- if (pLeft->numOfRows == pRight->numOfRows) {
- for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) {
- if (IS_NULL) {
- colDataSetNULL(pOutputCol, i);
- continue; // TODO set null or ignore
- }
- int64_t leftRes = 0;
- int64_t rightRes = 0;
- SCL_ERR_JRET(getVectorBigintValueFnLeft(LEFT_COL, i, &leftRes));
- SCL_ERR_JRET(getVectorBigintValueFnRight(RIGHT_COL, i, &rightRes));
- *output = leftRes | rightRes;
+ int32_t numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
+ for (; i < numOfRows && i >= 0; i += step, output += 1) {
+ int32_t leftidx = pLeft->numOfRows == 1 ? 0 : i;
+ int32_t rightidx = pRight->numOfRows == 1 ? 0 : i;
+ if (IS_HELPER_NULL(pRightCol, leftidx) || IS_HELPER_NULL(pLeftCol, rightidx)) {
+ colDataSetNULL(pOutputCol, i);
+ continue; // TODO set null or ignore
}
- } else if (pLeft->numOfRows == 1) {
- SCL_ERR_JRET(vectorBitOrHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i));
- } else if (pRight->numOfRows == 1) {
- SCL_ERR_JRET(vectorBitOrHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i));
+
+ int64_t leftRes = 0;
+ int64_t rightRes = 0;
+ SCL_ERR_JRET(getVectorBigintValueFnLeft(LEFT_COL, leftidx, &leftRes));
+ SCL_ERR_JRET(getVectorBigintValueFnRight(RIGHT_COL, rightidx, &rightRes));
+ *output = leftRes | rightRes;
}
_return:
@@ -1986,13 +1845,14 @@ int32_t doVectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarPa
return code;
}
-int32_t doVectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t startIndex,
+int32_t doVectorCompare(SScalarParam *pLeft, SScalarParam *pLeftVar, SScalarParam *pRight, SScalarParam *pOut, int32_t startIndex,
int32_t numOfRows, int32_t _ord, int32_t optr) {
int32_t i = 0;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t lType = GET_PARAM_TYPE(pLeft);
int32_t rType = GET_PARAM_TYPE(pRight);
__compar_fn_t fp = NULL;
+ __compar_fn_t fpVar = NULL;
int32_t compRows = 0;
if (lType == rType) {
SCL_ERR_RET(filterGetCompFunc(&fp, lType, optr));
@@ -2000,6 +1860,9 @@ int32_t doVectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam
fp = filterGetCompFuncEx(lType, rType, optr);
}
+ if (pLeftVar != NULL) {
+ SCL_ERR_RET(filterGetCompFunc(&fpVar, GET_PARAM_TYPE(pLeftVar), optr));
+ }
if (startIndex < 0) {
i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
@@ -2019,6 +1882,18 @@ int32_t doVectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam
char *pLeftData = colDataGetData(pLeft->columnData, i);
bool res = filterDoCompare(fp, optr, pLeftData, pRight->pHashFilter);
+ if (pLeftVar != NULL && taosHashGetSize(pRight->pHashFilterOthers) > 0){
+ do{
+ if (optr == OP_TYPE_IN && res){
+ break;
+ }
+ if (optr == OP_TYPE_NOT_IN && !res){
+ break;
+ }
+ pLeftData = colDataGetData(pLeftVar->columnData, i);
+ res = filterDoCompare(fpVar, optr, pLeftData, pRight->pHashFilterOthers);
+ }while(0);
+ }
colDataSetInt8(pOut->columnData, i, (int8_t *)&res);
if (res) {
pOut->numOfQualified++;
@@ -2036,6 +1911,7 @@ int32_t vectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarPara
SScalarParam pRightOut = {0};
SScalarParam *param1 = NULL;
SScalarParam *param2 = NULL;
+ SScalarParam *param3 = NULL;
int32_t code = TSDB_CODE_SUCCESS;
setTzCharset(&pLeftOut, pLeft->tz, pLeft->charsetCxt);
setTzCharset(&pRightOut, pLeft->tz, pLeft->charsetCxt);
@@ -2046,9 +1922,12 @@ int32_t vectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarPara
SCL_ERR_JRET(vectorConvertCols(pLeft, pRight, &pLeftOut, &pRightOut, startIndex, numOfRows));
param1 = (pLeftOut.columnData != NULL) ? &pLeftOut : pLeft;
param2 = (pRightOut.columnData != NULL) ? &pRightOut : pRight;
+ if (pRight->pHashFilterOthers != NULL){
+ param3 = pLeft;
+ }
}
- SCL_ERR_JRET(doVectorCompare(param1, param2, pOut, startIndex, numOfRows, _ord, optr));
+ SCL_ERR_JRET(doVectorCompare(param1, param3, param2, pOut, startIndex, numOfRows, _ord, optr));
_return:
sclFreeParam(&pLeftOut);
diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp
index 3eae06d9bb..fec9d14ae0 100644
--- a/source/libs/scalar/test/scalar/scalarTests.cpp
+++ b/source/libs/scalar/test/scalar/scalarTests.cpp
@@ -391,6 +391,26 @@ TEST(constantTest, bigint_add_bigint) {
nodesDestroyNode(res);
}
+TEST(constantTest, ubigint_add_ubigint) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ int32_t code = TSDB_CODE_SUCCESS;
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_UBIGINT, &scltLeftV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_UBIGINT, &scltRightV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_ADD, TSDB_DATA_TYPE_UBIGINT, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_UBIGINT);
+ ASSERT_FLOAT_EQ(v->datum.d, (scltLeftV + scltRightV));
+ nodesDestroyNode(res);
+}
+
TEST(constantTest, double_sub_bigint) {
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
int32_t code = TSDB_CODE_SUCCESS;
@@ -431,6 +451,66 @@ TEST(constantTest, tinyint_and_smallint) {
nodesDestroyNode(res);
}
+TEST(constantTest, utinyint_and_usmallint) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ int32_t code = TSDB_CODE_SUCCESS;
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_UTINYINT, &scltLeftV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_USMALLINT, &scltRightV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_BIT_AND, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BIGINT);
+ ASSERT_EQ(v->datum.i, (int64_t)scltLeftV & (int64_t)scltRightV);
+ nodesDestroyNode(res);
+}
+
+TEST(constantTest, uint_and_usmallint) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ int32_t code = TSDB_CODE_SUCCESS;
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_UINT, &scltLeftV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_USMALLINT, &scltRightV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_BIT_AND, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BIGINT);
+ ASSERT_EQ(v->datum.i, (int64_t)scltLeftV & (int64_t)scltRightV);
+ nodesDestroyNode(res);
+}
+
+TEST(constantTest, ubigint_and_uint) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ int32_t code = TSDB_CODE_SUCCESS;
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_UBIGINT, &scltLeftV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_UINT, &scltRightV);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_BIT_AND, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BIGINT);
+ ASSERT_EQ(v->datum.i, (int64_t)scltLeftV & (int64_t)scltRightV);
+ nodesDestroyNode(res);
+}
+
TEST(constantTest, bigint_or_double) {
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
int32_t code = TSDB_CODE_SUCCESS;
@@ -494,6 +574,53 @@ TEST(constantTest, int_greater_double) {
nodesDestroyNode(res);
}
+TEST(constantTest, binary_greater_equal_varbinary) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ char binaryStr[64] = {0};
+ int32_t code = TSDB_CODE_SUCCESS;
+ (void)sprintf(&binaryStr[2], "%d", scltRightV);
+ varDataSetLen(binaryStr, strlen(&binaryStr[2]));
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_VARBINARY, binaryStr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, binaryStr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_BOOL, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL);
+ ASSERT_EQ(v->datum.b, scltLeftV < scltRightVd);
+ nodesDestroyNode(res);
+}
+
+TEST(constantTest, binary_equal_geo) {
+ SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
+ char geoRawStr[64] = "POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))";
+ char geoStr[64] = {0};
+ int32_t code = TSDB_CODE_SUCCESS;
+ (void)sprintf(&geoStr[2], "%s", geoRawStr);
+ varDataSetLen(geoStr, strlen(&geoStr[2]));
+ code = scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_GEOMETRY, geoStr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, geoStr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ code = scltMakeOpNode(&opNode, OP_TYPE_EQUAL, TSDB_DATA_TYPE_BOOL, pLeft, pRight);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = scalarCalculateConstants(opNode, &res);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+ ASSERT_TRUE(res);
+ ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE);
+ SValueNode *v = (SValueNode *)res;
+ ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL);
+ ASSERT_EQ(v->datum.b, scltLeftV < scltRightVd);
+ nodesDestroyNode(res);
+}
+
TEST(constantTest, int_greater_equal_binary) {
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL;
char binaryStr[64] = {0};
@@ -2106,7 +2233,7 @@ TEST(columnTest, int_column_in_double_list) {
SNode *pLeft = NULL, *pRight = NULL, *listNode = NULL, *opNode = NULL;
int32_t leftv[5] = {1, 2, 3, 4, 5};
double rightv1 = 1.1, rightv2 = 2.2, rightv3 = 3.3;
- bool eRes[5] = {true, true, true, false, false};
+ bool eRes[5] = {false, false, false, false, false};
SSDataBlock *src = NULL;
int32_t rowNum = sizeof(leftv) / sizeof(leftv[0]);
int32_t code = TSDB_CODE_SUCCESS;
diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c
index d15ac7a791..a031bc08de 100644
--- a/source/libs/scheduler/src/schRemote.c
+++ b/source/libs/scheduler/src/schRemote.c
@@ -531,8 +531,8 @@ int32_t schHandleNotifyCallback(void *param, SDataBuf *pMsg, int32_t code) {
qDebug("QID:0x%" PRIx64 ",SID:0x%" PRIx64 ",CID:0x%" PRIx64 ",TID:0x%" PRIx64 " task notify rsp received, code:0x%x",
pParam->queryId, pParam->seriousId, pParam->clientId, pParam->taskId, code);
if (pMsg) {
- taosMemoryFree(pMsg->pData);
- taosMemoryFree(pMsg->pEpSet);
+ taosMemoryFreeClear(pMsg->pData);
+ taosMemoryFreeClear(pMsg->pEpSet);
}
return TSDB_CODE_SUCCESS;
}
@@ -545,8 +545,8 @@ int32_t schHandleLinkBrokenCallback(void *param, SDataBuf *pMsg, int32_t code) {
qDebug("handle %p is broken", pMsg->handle);
if (head->isHbParam) {
- taosMemoryFree(pMsg->pData);
- taosMemoryFree(pMsg->pEpSet);
+ taosMemoryFreeClear(pMsg->pData);
+ taosMemoryFreeClear(pMsg->pEpSet);
SSchHbCallbackParam *hbParam = (SSchHbCallbackParam *)param;
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL, .pHandleId = 0};
@@ -1293,6 +1293,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
}
break;
}
+/*
case TDMT_SCH_QUERY_HEARTBEAT: {
SCH_ERR_RET(schMakeHbRpcCtx(pJob, pTask, &rpcCtx));
@@ -1320,6 +1321,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
persistHandle = true;
break;
}
+*/
case TDMT_SCH_TASK_NOTIFY: {
ETaskNotifyType* pType = param;
STaskNotifyReq qMsg;
diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c
index cb8a68fe4f..b31353e97f 100644
--- a/source/libs/scheduler/src/schTask.c
+++ b/source/libs/scheduler/src/schTask.c
@@ -189,7 +189,6 @@ int32_t schProcessOnTaskFailure(SSchJob *pJob, SSchTask *pTask, int32_t errCode)
}
pTask->failedExecId = pTask->execId;
- pTask->failedSeriousId = pTask->seriousId;
int8_t jobStatus = 0;
if (schJobNeedToStop(pJob, &jobStatus)) {
@@ -438,7 +437,7 @@ void schResetTaskForRetry(SSchJob *pJob, SSchTask *pTask) {
pTask->waitRetry = true;
if (pTask->delayTimer) {
- taosTmrStop(pTask->delayTimer);
+ UNUSED(taosTmrStop(pTask->delayTimer));
}
schDropTaskOnExecNode(pJob, pTask);
@@ -452,6 +451,8 @@ void schResetTaskForRetry(SSchJob *pJob, SSchTask *pTask) {
TAOS_MEMSET(&pTask->succeedAddr, 0, sizeof(pTask->succeedAddr));
}
+#if 0
+
int32_t schDoTaskRedirect(SSchJob *pJob, SSchTask *pTask, SDataBuf *pData, int32_t rspCode) {
int32_t code = 0;
@@ -593,6 +594,7 @@ _return:
SCH_RET(schProcessOnTaskFailure(pJob, pTask, code));
}
+#endif
int32_t schPushTaskToExecList(SSchJob *pJob, SSchTask *pTask) {
int32_t code = taosHashPut(pJob->execTasks, &pTask->taskId, sizeof(pTask->taskId), &pTask, POINTER_BYTES);
@@ -759,7 +761,7 @@ int32_t schHandleTaskRetry(SSchJob *pJob, SSchTask *pTask) {
(void)atomic_sub_fetch_32(&pTask->level->taskLaunchedNum, 1);
if (pTask->delayTimer) {
- taosTmrStop(pTask->delayTimer);
+ UNUSED(taosTmrStop(pTask->delayTimer));
}
(void)schRemoveTaskFromExecList(pJob, pTask); // ignore error
@@ -869,6 +871,7 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) {
return TSDB_CODE_SUCCESS;
}
+#if 0
int32_t schUpdateTaskCandidateAddr(SSchJob *pJob, SSchTask *pTask, SEpSet *pEpSet) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == pTask->candidateAddrs || 1 != taosArrayGetSize(pTask->candidateAddrs)) {
@@ -900,6 +903,7 @@ _return:
return code;
}
+#endif
int32_t schSwitchTaskCandidateAddr(SSchJob *pJob, SSchTask *pTask) {
int32_t candidateNum = taosArrayGetSize(pTask->candidateAddrs);
@@ -1376,6 +1380,7 @@ int32_t schLaunchLevelTasks(SSchJob *pJob, SSchLevel *level) {
for (int32_t i = 0; i < level->taskNum; ++i) {
SSchTask *pTask = taosArrayGet(level->subTasks, i);
+ pTask->failedSeriousId = pJob->seriousId - 1;
pTask->seriousId = pJob->seriousId;
SCH_TASK_DLOG("task seriousId set to 0x%" PRIx64, pTask->seriousId);
diff --git a/source/libs/scheduler/test/schedulerTests.cpp b/source/libs/scheduler/test/schedulerTests.cpp
index a9878ec9a9..c13ea913f5 100644
--- a/source/libs/scheduler/test/schedulerTests.cpp
+++ b/source/libs/scheduler/test/schedulerTests.cpp
@@ -57,6 +57,9 @@ namespace {
extern "C" int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, uint64_t sId, int32_t execId, SDataBuf *pMsg,
int32_t rspCode);
extern "C" int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t rspCode);
+extern "C" int32_t schHandleNotifyCallback(void *param, SDataBuf *pMsg, int32_t code);
+extern "C" int32_t schHandleLinkBrokenCallback(void *param, SDataBuf *pMsg, int32_t code);
+extern "C" int32_t schRescheduleTask(SSchJob *pJob, SSchTask *pTask);
int64_t insertJobRefId = 0;
int64_t queryJobRefId = 0;
@@ -316,7 +319,7 @@ void schtBuildQueryFlowCtrlDag(SQueryPlan *dag) {
scanPlan->execNode.nodeId = 1 + i;
scanPlan->execNode.epSet.inUse = 0;
- scanPlan->execNodeStat.tableNum = taosRand() % 30;
+ scanPlan->execNodeStat.tableNum = taosRand() % 100;
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep0", 6030);
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep1", 6030);
addEpIntoEpSet(&scanPlan->execNode.epSet, "ep2", 6030);
@@ -982,8 +985,159 @@ TEST(queryTest, normalCase) {
schedulerFreeJob(&job, 0);
(void)taosThreadJoin(thread1, NULL);
+
+ schMgmt.jobRef = -1;
}
+TEST(queryTest, rescheduleCase) {
+ void *mockPointer = (void *)0x1;
+ char *clusterId = "cluster1";
+ char *dbname = "1.db1";
+ char *tablename = "table1";
+ SVgroupInfo vgInfo = {0};
+ int64_t job = 0;
+ SQueryPlan *dag = NULL;
+ int32_t code = nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN, (SNode**)&dag);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ SArray *qnodeList = taosArrayInit(1, sizeof(SQueryNodeLoad));
+
+ SQueryNodeLoad load = {0};
+ load.addr.epSet.numOfEps = 1;
+ TAOS_STRCPY(load.addr.epSet.eps[0].fqdn, "qnode0.ep");
+ load.addr.epSet.eps[0].port = 6031;
+ assert(taosArrayPush(qnodeList, &load) != NULL);
+
+ TAOS_STRCPY(load.addr.epSet.eps[0].fqdn, "qnode1.ep");
+ assert(taosArrayPush(qnodeList, &load) != NULL);
+
+ code = schedulerInit();
+ ASSERT_EQ(code, 0);
+
+ schtBuildQueryDag(dag);
+
+ schtSetPlanToString();
+ schtSetExecNode();
+ schtSetAsyncSendMsgToServer();
+
+ int32_t queryDone = 0;
+
+ SRequestConnInfo conn = {0};
+ conn.pTrans = mockPointer;
+ SSchedulerReq req = {0};
+ req.pConn = &conn;
+ req.pNodeList = qnodeList;
+ req.pDag = dag;
+ req.sql = "select * from tb";
+ req.execFp = schtQueryCb;
+ req.cbParam = &queryDone;
+
+ code = schedulerExecJob(&req, &job);
+ ASSERT_EQ(code, 0);
+
+ SSchJob *pJob = NULL;
+ code = schAcquireJob(job, &pJob);
+ ASSERT_EQ(code, 0);
+
+ schedulerEnableReSchedule(true);
+
+ void *pIter = taosHashIterate(pJob->execTasks, NULL);
+ while (pIter) {
+ SSchTask *task = *(SSchTask **)pIter;
+ task->timeoutUsec = -1;
+
+ code = schRescheduleTask(pJob, task);
+ ASSERT_EQ(code, 0);
+
+ task->timeoutUsec = SCH_DEFAULT_TASK_TIMEOUT_USEC;
+ pIter = taosHashIterate(pJob->execTasks, pIter);
+ }
+
+ pIter = taosHashIterate(pJob->execTasks, NULL);
+ while (pIter) {
+ SSchTask *task = *(SSchTask **)pIter;
+
+ SDataBuf msg = {0};
+ void *rmsg = NULL;
+ assert(0 == schtBuildQueryRspMsg(&msg.len, &rmsg));
+ msg.msgType = TDMT_SCH_QUERY_RSP;
+ msg.pData = rmsg;
+
+ code = schHandleResponseMsg(pJob, task, task->seriousId, task->execId, &msg, 0);
+
+ ASSERT_EQ(code, 0);
+ pIter = taosHashIterate(pJob->execTasks, pIter);
+ }
+
+
+ pIter = taosHashIterate(pJob->execTasks, NULL);
+ while (pIter) {
+ SSchTask *task = *(SSchTask **)pIter;
+ task->timeoutUsec = -1;
+
+ code = schRescheduleTask(pJob, task);
+ ASSERT_EQ(code, 0);
+
+ task->timeoutUsec = SCH_DEFAULT_TASK_TIMEOUT_USEC;
+ pIter = taosHashIterate(pJob->execTasks, pIter);
+ }
+
+ pIter = taosHashIterate(pJob->execTasks, NULL);
+ while (pIter) {
+ SSchTask *task = *(SSchTask **)pIter;
+ if (JOB_TASK_STATUS_EXEC == task->status) {
+ SDataBuf msg = {0};
+ void *rmsg = NULL;
+ assert(0 == schtBuildQueryRspMsg(&msg.len, &rmsg));
+ msg.msgType = TDMT_SCH_QUERY_RSP;
+ msg.pData = rmsg;
+
+ code = schHandleResponseMsg(pJob, task, task->seriousId, task->execId, &msg, 0);
+
+ ASSERT_EQ(code, 0);
+ }
+
+ pIter = taosHashIterate(pJob->execTasks, pIter);
+ }
+
+ while (true) {
+ if (queryDone) {
+ break;
+ }
+
+ taosUsleep(10000);
+ }
+
+ TdThreadAttr thattr;
+ assert(0 == taosThreadAttrInit(&thattr));
+
+ TdThread thread1;
+ assert(0 == taosThreadCreate(&(thread1), &thattr, schtCreateFetchRspThread, &job));
+
+ void *data = NULL;
+ req.syncReq = true;
+ req.pFetchRes = &data;
+
+ code = schedulerFetchRows(job, &req);
+ ASSERT_EQ(code, 0);
+
+ SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)data;
+ ASSERT_EQ(pRsp->completed, 1);
+ ASSERT_EQ(pRsp->numOfRows, 10);
+ taosMemoryFreeClear(data);
+
+ (void)schReleaseJob(job);
+
+ schedulerDestroy();
+
+ schedulerFreeJob(&job, 0);
+
+ (void)taosThreadJoin(thread1, NULL);
+
+ schMgmt.jobRef = -1;
+}
+
+
TEST(queryTest, readyFirstCase) {
void *mockPointer = (void *)0x1;
char *clusterId = "cluster1";
@@ -1097,6 +1251,7 @@ TEST(queryTest, readyFirstCase) {
schedulerFreeJob(&job, 0);
(void)taosThreadJoin(thread1, NULL);
+ schMgmt.jobRef = -1;
}
TEST(queryTest, flowCtrlCase) {
@@ -1196,6 +1351,9 @@ TEST(queryTest, flowCtrlCase) {
schedulerFreeJob(&job, 0);
(void)taosThreadJoin(thread1, NULL);
+ schMgmt.jobRef = -1;
+
+ cleanupTaskQueue();
}
TEST(insertTest, normalCase) {
@@ -1260,6 +1418,7 @@ TEST(insertTest, normalCase) {
schedulerDestroy();
(void)taosThreadJoin(thread1, NULL);
+ schMgmt.jobRef = -1;
}
TEST(multiThread, forceFree) {
@@ -1282,9 +1441,11 @@ TEST(multiThread, forceFree) {
schtTestStop = true;
// taosSsleep(3);
+
+ schMgmt.jobRef = -1;
}
-TEST(otherTest, otherCase) {
+TEST(otherTest, function) {
// excpet test
(void)schReleaseJob(0);
schFreeRpcCtx(NULL);
@@ -1293,6 +1454,39 @@ TEST(otherTest, otherCase) {
ASSERT_EQ(schDumpEpSet(NULL, &ep), TSDB_CODE_SUCCESS);
ASSERT_EQ(strcmp(schGetOpStr(SCH_OP_NULL), "NULL"), 0);
ASSERT_EQ(strcmp(schGetOpStr((SCH_OP_TYPE)100), "UNKNOWN"), 0);
+
+ SSchTaskCallbackParam param = {0};
+ SDataBuf dataBuf = {0};
+ dataBuf.pData = taosMemoryMalloc(1);
+ dataBuf.pEpSet = (SEpSet*)taosMemoryMalloc(sizeof(*dataBuf.pEpSet));
+ ASSERT_EQ(schHandleNotifyCallback(¶m, &dataBuf, TSDB_CODE_SUCCESS), TSDB_CODE_SUCCESS);
+
+ SSchCallbackParamHeader param2 = {0};
+ dataBuf.pData = taosMemoryMalloc(1);
+ dataBuf.pEpSet = (SEpSet*)taosMemoryMalloc(sizeof(*dataBuf.pEpSet));
+ schHandleLinkBrokenCallback(¶m2, &dataBuf, TSDB_CODE_SUCCESS);
+ param2.isHbParam = true;
+ dataBuf.pData = taosMemoryMalloc(1);
+ dataBuf.pEpSet = (SEpSet*)taosMemoryMalloc(sizeof(*dataBuf.pEpSet));
+ schHandleLinkBrokenCallback(¶m2, &dataBuf, TSDB_CODE_SUCCESS);
+
+ schMgmt.jobRef = -1;
+}
+
+void schtReset() {
+ insertJobRefId = 0;
+ queryJobRefId = 0;
+
+ schtJobDone = false;
+ schtMergeTemplateId = 0x4;
+ schtFetchTaskId = 0;
+ schtQueryId = 1;
+
+ schtTestStop = false;
+ schtTestDeadLoop = false;
+ schtTestMTRunSec = 1;
+ schtTestPrintNum = 1000;
+ schtStartFetch = 0;
}
int main(int argc, char **argv) {
@@ -1302,7 +1496,17 @@ int main(int argc, char **argv) {
}
taosSeedRand(taosGetTimestampSec());
testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
+
+ int code = 0;
+ for (int32_t i = 0; i < 10; ++i) {
+ schtReset();
+ code = RUN_ALL_TESTS();
+ if (code) {
+ break;
+ }
+ }
+
+ return code;
}
#pragma GCC diagnostic pop
diff --git a/source/libs/stream/inc/streamInt.h b/source/libs/stream/inc/streamInt.h
index c25b0f34fc..41ac0117f3 100644
--- a/source/libs/stream/inc/streamInt.h
+++ b/source/libs/stream/inc/streamInt.h
@@ -250,6 +250,9 @@ void chkptFailedByRetrieveReqToSource(SStreamTask* pTask, int64_t checkpointId);
// inject stream errors
void chkptFailedByRetrieveReqToSource(SStreamTask* pTask, int64_t checkpointId);
+int32_t uploadCheckpointData(SStreamTask* pTask, int64_t checkpointId, int64_t dbRefId, ECHECKPOINT_BACKUP_TYPE type);
+int32_t chkptTriggerRecvMonitorHelper(SStreamTask* pTask, void* param, SArray** ppNotSendList);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c
index 876cd1b472..0ec66cd2ce 100644
--- a/source/libs/stream/src/streamCheckpoint.c
+++ b/source/libs/stream/src/streamCheckpoint.c
@@ -21,7 +21,9 @@
static int32_t downloadCheckpointDataByName(const char* id, const char* fname, const char* dstName);
static int32_t deleteCheckpointFile(const char* id, const char* name);
static int32_t streamTaskUploadCheckpoint(const char* id, const char* path, int64_t checkpointId);
+#ifdef BUILD_NO_CALL
static int32_t deleteCheckpoint(const char* id);
+#endif
static int32_t downloadCheckpointByNameS3(const char* id, const char* fname, const char* dstName);
static int32_t continueDispatchCheckpointTriggerBlock(SStreamDataBlock* pBlock, SStreamTask* pTask);
static int32_t appendCheckpointIntoInputQ(SStreamTask* pTask, int32_t checkpointType, int64_t checkpointId,
@@ -998,7 +1000,7 @@ static int32_t doFindNotSendUpstream(SStreamTask* pTask, SArray* pList, SArray**
return 0;
}
-static int32_t chkptTriggerRecvMonitorHelper(SStreamTask* pTask, void* param, SArray** ppNotSendList) {
+int32_t chkptTriggerRecvMonitorHelper(SStreamTask* pTask, void* param, SArray** ppNotSendList) {
const char* id = pTask->id.idStr;
SArray* pList = pTask->upstreamInfo.pList; // send msg to retrieve checkpoint trigger msg
SActiveCheckpointInfo* pActiveInfo = pTask->chkInfo.pActiveInfo;
@@ -1492,6 +1494,7 @@ int32_t streamTaskDownloadCheckpointData(const char* id, char* path, int64_t che
return 0;
}
+#ifdef BUILD_NO_CALL
int32_t deleteCheckpoint(const char* id) {
if (id == NULL || strlen(id) == 0) {
stError("deleteCheckpoint parameters invalid");
@@ -1504,6 +1507,7 @@ int32_t deleteCheckpoint(const char* id) {
}
return 0;
}
+#endif
int32_t deleteCheckpointFile(const char* id, const char* name) {
char object[128] = {0};
diff --git a/source/libs/stream/test/streamCheckPointTest.cpp b/source/libs/stream/test/streamCheckPointTest.cpp
new file mode 100644
index 0000000000..80dd3ec142
--- /dev/null
+++ b/source/libs/stream/test/streamCheckPointTest.cpp
@@ -0,0 +1,270 @@
+#include
+#include "tstream.h"
+#include "streamInt.h"
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+
+void initTaskLock(SStreamTask* pTask) {
+ TdThreadMutexAttr attr = {0};
+ int32_t code = taosThreadMutexAttrInit(&attr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = taosThreadMutexAttrSetType(&attr, PTHREAD_MUTEX_RECURSIVE);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = taosThreadMutexInit(&pTask->lock, &attr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = taosThreadMutexAttrDestroy(&attr);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+}
+
+TEST(streamCheckpointTest, StreamTaskProcessCheckpointTriggerRsp) {
+ SStreamTask* pTask = NULL;
+ int64_t uid = 1111111111111111;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ pTask->chkInfo.pActiveInfo->activeId = 123111;
+ pTask->chkInfo.pActiveInfo->transId = 4561111;
+
+ streamTaskSetStatusReady(pTask);
+ code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_GEN_CHECKPOINT);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ SCheckpointTriggerRsp pRsp;
+ memset(&pRsp, 0, sizeof(SCheckpointTriggerRsp));
+ pRsp.rspCode = TSDB_CODE_SUCCESS;
+ pRsp.checkpointId = 123;
+ pRsp.transId = 456;
+ pRsp.upstreamTaskId = 789;
+
+ code = streamTaskProcessCheckpointTriggerRsp(pTask, &pRsp);
+ ASSERT_NE(code, TSDB_CODE_SUCCESS);
+
+ pRsp.rspCode = TSDB_CODE_FAILED;
+ code = streamTaskProcessCheckpointTriggerRsp(pTask, &pRsp);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ tFreeStreamTask(pTask);
+ taosArrayDestroy(array);
+}
+
+TEST(streamCheckpointTest, StreamTaskSetFailedCheckpointId) {
+ SStreamTask* pTask = NULL;
+ int64_t uid = 1111111111111111;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ SActiveCheckpointInfo* pInfo = pTask->chkInfo.pActiveInfo;
+ pInfo->failedId = 0;
+
+ int64_t failedCheckpointId = 123;
+
+ streamTaskSetFailedCheckpointId(pTask, failedCheckpointId);
+ ASSERT_EQ(pInfo->failedId, failedCheckpointId);
+
+ streamTaskSetFailedCheckpointId(pTask, 0);
+ ASSERT_EQ(pInfo->failedId, failedCheckpointId);
+
+ streamTaskSetFailedCheckpointId(pTask, pInfo->failedId - 1);
+ ASSERT_EQ(pInfo->failedId, failedCheckpointId);
+ tFreeStreamTask(pTask);
+ taosArrayDestroy(array);
+}
+
+TEST(UploadCheckpointDataTest, UploadSuccess) {
+ streamMetaInit();
+ SStreamTask* pTask = NULL;
+ int64_t uid = 1111111111111111;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ int64_t checkpointId = 123;
+ int64_t dbRefId = 1;
+ ECHECKPOINT_BACKUP_TYPE type = DATA_UPLOAD_S3;
+
+ STaskDbWrapper* pBackend = NULL;
+ int64_t processVer = -1;
+ const char *path = "/tmp/backend3/stream";
+ code = streamMetaOpen((path), NULL, NULL, NULL, 0, 0, NULL, &pTask->pMeta);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ SStreamState *pState = streamStateOpen((char *)path, pTask, 0, 0);
+ ASSERT(pState != NULL);
+
+ pTask->pBackend = pState->pTdbState->pOwner->pBackend;
+
+ code = taskDbDoCheckpoint(pTask->pBackend, checkpointId, 0);
+ ASSERT(code == 0);
+
+ int32_t result = uploadCheckpointData(pTask, checkpointId, dbRefId, type);
+
+ EXPECT_EQ(result, TSDB_CODE_SUCCESS) << "uploadCheckpointData should return 0 on success";
+ tFreeStreamTask(pTask);
+ taosRemoveDir(path);
+ streamStateClose(pState, true);
+ taosArrayDestroy(array);
+}
+
+TEST(UploadCheckpointDataTest, UploadDisabled) {
+ SStreamTask* pTask = NULL;
+ int64_t uid = 2222222222222;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ int64_t checkpointId = 123;
+ int64_t dbRefId = 1;
+
+ STaskDbWrapper* pBackend = NULL;
+ int64_t processVer = -1;
+ const char *path = "/tmp/backend4/stream";
+ code = streamMetaOpen((path), NULL, NULL, NULL, 0, 0, NULL, &pTask->pMeta);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ SStreamState *pState = streamStateOpen((char *)path, pTask, 0, 0);
+ ASSERT(pState != NULL);
+
+ pTask->pBackend = pState->pTdbState->pOwner->pBackend;
+
+ code = taskDbDoCheckpoint(pTask->pBackend, checkpointId, 0);
+ ASSERT(code == 0);
+
+ ECHECKPOINT_BACKUP_TYPE type = DATA_UPLOAD_DISABLE;
+
+ int32_t result = uploadCheckpointData(pTask, checkpointId, dbRefId, type);
+
+ EXPECT_NE(result, TSDB_CODE_SUCCESS) << "uploadCheckpointData should return 0 when backup type is disabled";
+
+ streamStateClose(pState, true);
+ tFreeStreamTask(pTask);
+ taosArrayDestroy(array);
+}
+
+TEST(StreamTaskAlreadySendTriggerTest, AlreadySendTrigger) {
+ SStreamTask* pTask = NULL;
+ int64_t uid = 2222222222222;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ pTask->chkInfo.pActiveInfo->activeId = 123111;
+ pTask->chkInfo.pActiveInfo->transId = 4561111;
+
+ streamTaskSetStatusReady(pTask);
+ code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_GEN_CHECKPOINT);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ int32_t downstreamNodeId = 1;
+ int64_t sendingCheckpointId = 123;
+ TSKEY ts = taosGetTimestampMs();
+
+ STaskTriggerSendInfo triggerInfo;
+ triggerInfo.sendTs = ts;
+ triggerInfo.recved = false;
+ triggerInfo.nodeId = downstreamNodeId;
+
+ taosArrayPush(pTask->chkInfo.pActiveInfo->pDispatchTriggerList, &triggerInfo);
+
+ pTask->chkInfo.pActiveInfo->dispatchTrigger = true;
+ bool result = streamTaskAlreadySendTrigger(pTask, downstreamNodeId);
+
+ EXPECT_TRUE(result) << "The trigger message should have been sent to the downstream node";
+
+ tFreeStreamTask(pTask);
+ taosArrayDestroy(array);
+}
+
+TEST(ChkptTriggerRecvMonitorHelperTest, chkptTriggerRecvMonitorHelper) {
+ SStreamTask* pTask = NULL;
+ int64_t uid = 2222222222222;
+ SArray* array = taosArrayInit(4, POINTER_BYTES);
+ int32_t code = tNewStreamTask(uid, TASK_LEVEL__SINK, NULL, false, 0, 0, array,
+ false, 1, &pTask);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ initTaskLock(pTask);
+
+ const char *path = "/tmp/backend5/stream";
+ code = streamMetaOpen((path), NULL, NULL, NULL, 0, 0, NULL, &pTask->pMeta);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ code = streamTaskCreateActiveChkptInfo(&pTask->chkInfo.pActiveInfo);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ pTask->chkInfo.pActiveInfo->activeId = 123111;
+ pTask->chkInfo.pActiveInfo->chkptTriggerMsgTmr.launchChkptId = pTask->chkInfo.pActiveInfo->activeId;
+ pTask->chkInfo.pActiveInfo->transId = 4561111;
+ pTask->chkInfo.startTs = 11111;
+
+ streamTaskSetStatusReady(pTask);
+ code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_GEN_CHECKPOINT);
+ ASSERT_EQ(code, TSDB_CODE_SUCCESS);
+
+ int32_t downstreamNodeId = 1;
+ int64_t sendingCheckpointId = 123;
+ TSKEY ts = taosGetTimestampMs();
+
+ STaskTriggerSendInfo triggerInfo;
+ triggerInfo.sendTs = ts;
+ triggerInfo.recved = false;
+ triggerInfo.nodeId = downstreamNodeId;
+
+ taosArrayPush(pTask->chkInfo.pActiveInfo->pDispatchTriggerList, &triggerInfo);
+
+ pTask->chkInfo.pActiveInfo->dispatchTrigger = true;
+ SArray* array1 = NULL;
+ code = chkptTriggerRecvMonitorHelper(pTask, NULL, &array1);
+ EXPECT_EQ(code, TSDB_CODE_SUCCESS);
+
+ pTask->pMeta->fatalInfo.code = TSDB_CODE_SUCCESS;
+ streamSetFatalError(pTask->pMeta, code, __func__, __LINE__);
+
+ pTask->pMeta->fatalInfo.code = TSDB_CODE_FAILED;
+ streamSetFatalError(pTask->pMeta, code, __func__, __LINE__);
+ tFreeStreamTask(pTask);
+ taosArrayDestroy(array);
+ taosArrayDestroy(array1);
+}
diff --git a/source/libs/tfs/src/tfs.c b/source/libs/tfs/src/tfs.c
index 4ac72e8918..ecc55517b3 100644
--- a/source/libs/tfs/src/tfs.c
+++ b/source/libs/tfs/src/tfs.c
@@ -726,3 +726,22 @@ int32_t tfsGetMonitorInfo(STfs *pTfs, SMonDiskInfo *pInfo) {
TAOS_RETURN(0);
}
+
+int32_t tfsUpdateDiskDisable(STfs *pTfs, const char *dir, int8_t disable) {
+ TAOS_UNUSED(tfsLock(pTfs));
+ for (int32_t level = 0; level < pTfs->nlevel; level++) {
+ STfsTier *pTier = &pTfs->tiers[level];
+ for (int32_t disk = 0; disk < pTier->ndisk; ++disk) {
+ STfsDisk *pDisk = pTier->disks[disk];
+ if (strcmp(pDisk->path, dir) == 0) {
+ pDisk->disable = disable;
+ TAOS_UNUSED(tfsUnLock(pTfs));
+ fInfo("disk %s is %s", dir, disable ? "disabled" : "enabled");
+ TAOS_RETURN(TSDB_CODE_SUCCESS);
+ }
+ }
+ }
+ TAOS_UNUSED(tfsUnLock(pTfs));
+ fError("failed to update disk disable since %s not found", dir);
+ TAOS_RETURN(TSDB_CODE_FS_NO_VALID_DISK);
+}
\ No newline at end of file
diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c
index ee88996c29..52794af4dd 100644
--- a/source/util/src/tconfig.c
+++ b/source/util/src/tconfig.c
@@ -501,11 +501,13 @@ int32_t cfgGetAndSetItem(SConfig *pCfg, SConfigItem **pItem, const char *name, c
*pItem = cfgGetItem(pCfg, name);
if (*pItem == NULL) {
- (void)taosThreadMutexUnlock(&pCfg->lock);
- TAOS_RETURN(TSDB_CODE_CFG_NOT_FOUND);
+ code = TSDB_CODE_CFG_NOT_FOUND;
+ goto _exit;
}
- TAOS_CHECK_RETURN(cfgSetItemVal(*pItem, name, value, stype));
+ TAOS_CHECK_GOTO(cfgSetItemVal(*pItem, name, value, stype), NULL, _exit);
+
+_exit:
if (lock) {
(void)taosThreadMutexUnlock(&pCfg->lock);
}
diff --git a/source/util/src/tdecompressavx.c b/source/util/src/tdecompressavx.c
index 143867b783..5077950c5d 100644
--- a/source/util/src/tdecompressavx.c
+++ b/source/util/src/tdecompressavx.c
@@ -22,7 +22,7 @@ char tsSIMDEnable = 0;
#endif
int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements, char *const output, const char type) {
-#ifdef __AVX2__
+#ifdef __AVX512F__
int32_t word_length = getWordLength(type);
// Selector value: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@@ -53,183 +53,79 @@ int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements,
int32_t gRemainder = (nelements - _pos);
int32_t num = (gRemainder > elems) ? elems : gRemainder;
- int32_t batch = 0;
- int32_t remain = 0;
- if (tsSIMDEnable && tsAVX512Supported && tsAVX512Enable) {
-#ifdef __AVX512F__
- batch = num >> 3;
- remain = num & 0x07;
-#endif
- } else if (tsSIMDEnable && tsAVX2Supported) {
-#ifdef __AVX2__
- batch = num >> 2;
- remain = num & 0x03;
-#endif
- }
+ int32_t batch = num >> 3;
+ int32_t remain = num & 0x07;
if (selector == 0 || selector == 1) {
- if (tsSIMDEnable && tsAVX512Supported && tsAVX512Enable) {
-#ifdef __AVX512F__
- for (int32_t i = 0; i < batch; ++i) {
- __m512i prev = _mm512_set1_epi64(prevValue);
- _mm512_storeu_si512((__m512i *)&p[_pos], prev);
- _pos += 8; // handle 64bit x 8 = 512bit
- }
- for (int32_t i = 0; i < remain; ++i) {
- p[_pos++] = prevValue;
- }
-#endif
- } else if (tsSIMDEnable && tsAVX2Supported) {
- for (int32_t i = 0; i < batch; ++i) {
- __m256i prev = _mm256_set1_epi64x(prevValue);
- _mm256_storeu_si256((__m256i *)&p[_pos], prev);
- _pos += 4;
- }
-
- for (int32_t i = 0; i < remain; ++i) {
- p[_pos++] = prevValue;
- }
-
- } else { // alternative implementation without SIMD instructions.
- for (int32_t i = 0; i < elems && count < nelements; i++, count++) {
- p[_pos++] = prevValue;
- v += bit;
- }
+ for (int32_t i = 0; i < batch; ++i) {
+ __m512i prev = _mm512_set1_epi64(prevValue);
+ _mm512_storeu_si512((__m512i *)&p[_pos], prev);
+ _pos += 8; // handle 64bit x 8 = 512bit
+ }
+ for (int32_t i = 0; i < remain; ++i) {
+ p[_pos++] = prevValue;
}
} else {
- if (tsSIMDEnable && tsAVX512Supported && tsAVX512Enable) {
-#ifdef __AVX512F__
- __m512i sum_mask1 = _mm512_set_epi64(6, 6, 4, 4, 2, 2, 0, 0);
- __m512i sum_mask2 = _mm512_set_epi64(5, 5, 5, 5, 1, 1, 1, 1);
- __m512i sum_mask3 = _mm512_set_epi64(3, 3, 3, 3, 3, 3, 3, 3);
- __m512i base = _mm512_set1_epi64(w);
- __m512i maskVal = _mm512_set1_epi64(mask);
- __m512i shiftBits = _mm512_set_epi64(bit * 7 + 4, bit * 6 + 4, bit * 5 + 4, bit * 4 + 4, bit * 3 + 4,
- bit * 2 + 4, bit + 4, 4);
- __m512i inc = _mm512_set1_epi64(bit << 3);
+ __m512i sum_mask1 = _mm512_set_epi64(6, 6, 4, 4, 2, 2, 0, 0);
+ __m512i sum_mask2 = _mm512_set_epi64(5, 5, 5, 5, 1, 1, 1, 1);
+ __m512i sum_mask3 = _mm512_set_epi64(3, 3, 3, 3, 3, 3, 3, 3);
+ __m512i base = _mm512_set1_epi64(w);
+ __m512i maskVal = _mm512_set1_epi64(mask);
+ __m512i shiftBits = _mm512_set_epi64(bit * 7 + 4, bit * 6 + 4, bit * 5 + 4, bit * 4 + 4, bit * 3 + 4,
+ bit * 2 + 4, bit + 4, 4);
+ __m512i inc = _mm512_set1_epi64(bit << 3);
- for (int32_t i = 0; i < batch; ++i) {
- __m512i after = _mm512_srlv_epi64(base, shiftBits);
- __m512i zigzagVal = _mm512_and_si512(after, maskVal);
+ for (int32_t i = 0; i < batch; ++i) {
+ __m512i after = _mm512_srlv_epi64(base, shiftBits);
+ __m512i zigzagVal = _mm512_and_si512(after, maskVal);
- // ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1)))
- __m512i signmask = _mm512_and_si512(_mm512_set1_epi64(1), zigzagVal);
- signmask = _mm512_sub_epi64(_mm512_setzero_si512(), signmask);
- __m512i delta = _mm512_xor_si512(_mm512_srli_epi64(zigzagVal, 1), signmask);
+ // ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1)))
+ __m512i signmask = _mm512_and_si512(_mm512_set1_epi64(1), zigzagVal);
+ signmask = _mm512_sub_epi64(_mm512_setzero_si512(), signmask);
+ __m512i delta = _mm512_xor_si512(_mm512_srli_epi64(zigzagVal, 1), signmask);
- // calculate the cumulative sum (prefix sum) for each number
- // decode[0] = prevValue + final[0]
- // decode[1] = decode[0] + final[1] -----> prevValue + final[0] + final[1]
- // decode[2] = decode[1] + final[2] -----> prevValue + final[0] + final[1] + final[2]
- // decode[3] = decode[2] + final[3] -----> prevValue + final[0] + final[1] + final[2] + final[3]
+ // calculate the cumulative sum (prefix sum) for each number
+ // decode[0] = prevValue + final[0]
+ // decode[1] = decode[0] + final[1] -----> prevValue + final[0] + final[1]
+ // decode[2] = decode[1] + final[2] -----> prevValue + final[0] + final[1] + final[2]
+ // decode[3] = decode[2] + final[3] -----> prevValue + final[0] + final[1] + final[2] + final[3]
- // 7 6 5 4 3 2 1
- // 0 D7 D6 D5 D4 D3 D2 D1
- // D0 D6 0 D4 0 D2 0 D0
- // 0 D7+D6 D6 D5+D4 D4 D3+D2 D2
- // D1+D0 D0 13 6 9 4 5 2
- // 1 0
- __m512i prev = _mm512_set1_epi64(prevValue);
- __m512i cum_sum = _mm512_add_epi64(delta, _mm512_maskz_permutexvar_epi64(0xaa, sum_mask1, delta));
- cum_sum = _mm512_add_epi64(cum_sum, _mm512_maskz_permutexvar_epi64(0xcc, sum_mask2, cum_sum));
- cum_sum = _mm512_add_epi64(cum_sum, _mm512_maskz_permutexvar_epi64(0xf0, sum_mask3, cum_sum));
+ // 7 6 5 4 3 2 1
+ // 0 D7 D6 D5 D4 D3 D2 D1
+ // D0 D6 0 D4 0 D2 0 D0
+ // 0 D7+D6 D6 D5+D4 D4 D3+D2 D2
+ // D1+D0 D0 13 6 9 4 5 2
+ // 1 0
+ __m512i prev = _mm512_set1_epi64(prevValue);
+ __m512i cum_sum = _mm512_add_epi64(delta, _mm512_maskz_permutexvar_epi64(0xaa, sum_mask1, delta));
+ cum_sum = _mm512_add_epi64(cum_sum, _mm512_maskz_permutexvar_epi64(0xcc, sum_mask2, cum_sum));
+ cum_sum = _mm512_add_epi64(cum_sum, _mm512_maskz_permutexvar_epi64(0xf0, sum_mask3, cum_sum));
- // 13 6 9 4 5 2 1
- // 0 D7,D6 D6 D5,D4 D4 D3,D2 D2
- // D1,D0 D0 +D5,D4 D5,D4, 0 0 D1,D0 D1,D0
- // 0 0 D7~D4 D6~D4 D5~D4 D4 D3~D0 D2~D0
- // D1~D0 D0 22 15 9 4 6 3
- // 1 0
- //
- // D3~D0 D3~D0 D3~D0 D3~D0 0 0 0
- // 0 28 21 15 10 6 3 1
- // 0
+ // 13 6 9 4 5 2 1
+ // 0 D7,D6 D6 D5,D4 D4 D3,D2 D2
+ // D1,D0 D0 +D5,D4 D5,D4, 0 0 D1,D0 D1,D0
+ // 0 0 D7~D4 D6~D4 D5~D4 D4 D3~D0 D2~D0
+ // D1~D0 D0 22 15 9 4 6 3
+ // 1 0
+ //
+ // D3~D0 D3~D0 D3~D0 D3~D0 0 0 0
+ // 0 28 21 15 10 6 3 1
+ // 0
- cum_sum = _mm512_add_epi64(cum_sum, prev);
- _mm512_storeu_si512((__m512i *)&p[_pos], cum_sum);
+ cum_sum = _mm512_add_epi64(cum_sum, prev);
+ _mm512_storeu_si512((__m512i *)&p[_pos], cum_sum);
- shiftBits = _mm512_add_epi64(shiftBits, inc);
- prevValue = p[_pos + 7];
- _pos += 8;
- }
- // handle the remain value
- for (int32_t i = 0; i < remain; i++) {
- zigzag_value = ((w >> (v + (batch * bit * 8))) & mask);
- prevValue += ZIGZAG_DECODE(int64_t, zigzag_value);
+ shiftBits = _mm512_add_epi64(shiftBits, inc);
+ prevValue = p[_pos + 7];
+ _pos += 8;
+ }
+ // handle the remain value
+ for (int32_t i = 0; i < remain; i++) {
+ zigzag_value = ((w >> (v + (batch * bit * 8))) & mask);
+ prevValue += ZIGZAG_DECODE(int64_t, zigzag_value);
- p[_pos++] = prevValue;
- v += bit;
- }
-#endif
- } else if (tsSIMDEnable && tsAVX2Supported) {
- __m256i base = _mm256_set1_epi64x(w);
- __m256i maskVal = _mm256_set1_epi64x(mask);
-
- __m256i shiftBits = _mm256_set_epi64x(bit * 3 + 4, bit * 2 + 4, bit + 4, 4);
- __m256i inc = _mm256_set1_epi64x(bit << 2);
-
- for (int32_t i = 0; i < batch; ++i) {
- __m256i after = _mm256_srlv_epi64(base, shiftBits);
- __m256i zigzagVal = _mm256_and_si256(after, maskVal);
-
- // ZIGZAG_DECODE(T, v) (((v) >> 1) ^ -((T)((v)&1)))
- __m256i signmask = _mm256_and_si256(_mm256_set1_epi64x(1), zigzagVal);
- signmask = _mm256_sub_epi64(_mm256_setzero_si256(), signmask);
-
- // get four zigzag values here
- __m256i delta = _mm256_xor_si256(_mm256_srli_epi64(zigzagVal, 1), signmask);
-
- // calculate the cumulative sum (prefix sum) for each number
- // decode[0] = prevValue + final[0]
- // decode[1] = decode[0] + final[1] -----> prevValue + final[0] + final[1]
- // decode[2] = decode[1] + final[2] -----> prevValue + final[0] + final[1] + final[2]
- // decode[3] = decode[2] + final[3] -----> prevValue + final[0] + final[1] + final[2] + final[3]
-
- // 1, 2, 3, 4
- //+ 0, 1, 0, 3
- // 1, 3, 3, 7
- // shift and add for the first round
- __m128i prev = _mm_set1_epi64x(prevValue);
- __m256i x = _mm256_slli_si256(delta, 8);
-
- delta = _mm256_add_epi64(delta, x);
- _mm256_storeu_si256((__m256i *)&p[_pos], delta);
-
- // 1, 3, 3, 7
- //+ 0, 0, 3, 3
- // 1, 3, 6, 10
- // shift and add operation for the second round
- __m128i firstPart = _mm_loadu_si128((__m128i *)&p[_pos]);
- __m128i secondItem = _mm_set1_epi64x(p[_pos + 1]);
- __m128i secPart = _mm_add_epi64(_mm_loadu_si128((__m128i *)&p[_pos + 2]), secondItem);
- firstPart = _mm_add_epi64(firstPart, prev);
- secPart = _mm_add_epi64(secPart, prev);
-
- // save it in the memory
- _mm_storeu_si128((__m128i *)&p[_pos], firstPart);
- _mm_storeu_si128((__m128i *)&p[_pos + 2], secPart);
-
- shiftBits = _mm256_add_epi64(shiftBits, inc);
- prevValue = p[_pos + 3];
- _pos += 4;
- }
-
- // handle the remain value
- for (int32_t i = 0; i < remain; i++) {
- zigzag_value = ((w >> (v + (batch * bit * 4))) & mask);
- prevValue += ZIGZAG_DECODE(int64_t, zigzag_value);
-
- p[_pos++] = prevValue;
- v += bit;
- }
- } else { // alternative implementation without SIMD instructions.
- for (int32_t i = 0; i < elems && count < nelements; i++, count++) {
- zigzag_value = ((w >> v) & mask);
- prevValue += ZIGZAG_DECODE(int64_t, zigzag_value);
-
- p[_pos++] = prevValue;
- v += bit;
- }
+ p[_pos++] = prevValue;
+ v += bit;
}
}
} break;
@@ -292,7 +188,7 @@ int32_t tsDecompressIntImpl_Hw(const char *const input, const int32_t nelements,
return nelements * word_length;
#else
- uError("unable run %s without avx2 instructions", __func__);
+ uError("unable run %s without avx512 instructions", __func__);
return -1;
#endif
}
diff --git a/source/util/src/terror.c b/source/util/src/terror.c
index 195cb21618..d2d551a539 100644
--- a/source/util/src/terror.c
+++ b/source/util/src/terror.c
@@ -648,7 +648,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_SINGLE_GROUP, "Not a single-group g
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TAGS_NOT_MATCHED, "Tags number not matched")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_TAG_NAME, "Invalid tag name")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, "Name or password too long")
-TAOS_DEFINE_ERROR(TSDB_CODE_PAR_PASSWD_EMPTY, "Password can not be empty")
+TAOS_DEFINE_ERROR(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, "Password too short or empty")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_PORT, "Port should be an integer that is less than 65535 and greater than 0")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_ENDPOINT, "Endpoint should be in the format of 'fqdn:port'")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_EXPRIE_STATEMENT, "This statement is no longer supported")
diff --git a/source/util/src/tworker.c b/source/util/src/tworker.c
index 6370e6ca50..dbd8cb159e 100644
--- a/source/util/src/tworker.c
+++ b/source/util/src/tworker.c
@@ -823,6 +823,8 @@ bool tQueryAutoQWorkerTryRecycleWorker(SQueryAutoQWorkerPool *pPool, SQueryAutoQ
int32_t tQueryAutoQWorkerInit(SQueryAutoQWorkerPool *pool) {
int32_t code;
+ pool->exit = false;
+
(void)taosThreadMutexInit(&pool->poolLock, NULL);
(void)taosThreadMutexInit(&pool->backupLock, NULL);
(void)taosThreadMutexInit(&pool->waitingAfterBlockLock, NULL);
diff --git a/source/util/test/CMakeLists.txt b/source/util/test/CMakeLists.txt
index 655557b180..cde1392216 100644
--- a/source/util/test/CMakeLists.txt
+++ b/source/util/test/CMakeLists.txt
@@ -138,6 +138,10 @@ add_test(
COMMAND logTest
)
+IF(COMPILER_SUPPORT_AVX2)
+ MESSAGE(STATUS "AVX2 instructions is ACTIVATED")
+ set_source_files_properties(decompressTest.cpp PROPERTIES COMPILE_FLAGS -mavx2)
+ENDIF()
add_executable(decompressTest "decompressTest.cpp")
target_link_libraries(decompressTest os util common gtest_main)
add_test(
@@ -145,6 +149,16 @@ add_test(
COMMAND decompressTest
)
+
+IF($TD_LINUX)
+ add_executable(utilTests "utilTests.cpp")
+ target_link_libraries(utilTests os util common gtest_main)
+ add_test(
+ NAME utilTests
+ COMMAND utilTests
+ )
+ENDIF()
+
if(${TD_LINUX})
# terrorTest
add_executable(terrorTest "terrorTest.cpp")
diff --git a/source/util/test/errorCodeTable.ini b/source/util/test/errorCodeTable.ini
index e837954a0b..f67c8ab834 100644
--- a/source/util/test/errorCodeTable.ini
+++ b/source/util/test/errorCodeTable.ini
@@ -463,7 +463,7 @@ TSDB_CODE_PAR_NOT_SINGLE_GROUP = 0x8000260C
TSDB_CODE_PAR_TAGS_NOT_MATCHED = 0x8000260D
TSDB_CODE_PAR_INVALID_TAG_NAME = 0x8000260E
TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG = 0x80002610
-TSDB_CODE_PAR_PASSWD_EMPTY = 0x80002611
+TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY = 0x80002611
TSDB_CODE_PAR_INVALID_PORT = 0x80002612
TSDB_CODE_PAR_INVALID_ENDPOINT = 0x80002613
TSDB_CODE_PAR_EXPRIE_STATEMENT = 0x80002614
diff --git a/source/util/test/utilTests.cpp b/source/util/test/utilTests.cpp
index cb78743018..9a42213929 100644
--- a/source/util/test/utilTests.cpp
+++ b/source/util/test/utilTests.cpp
@@ -6,6 +6,7 @@
#include "tarray.h"
#include "tcompare.h"
+#include "tdatablock.h"
namespace {
} // namespace
@@ -474,3 +475,67 @@ TEST(tsma, reverse_unit) {
ASSERT_FALSE(tsmaIntervalCheck(12, 'n', 1, 'y', TSDB_TIME_PRECISION_NANO));
ASSERT_TRUE(tsmaIntervalCheck(3, 'n', 1, 'y', TSDB_TIME_PRECISION_NANO));
}
+
+template
+void dataBlockNullTest(const F& setValFunc) {
+ int32_t totalRows = 16;
+ SColumnInfoData columnInfoData = createColumnInfoData(type, tDataTypes[type].bytes, 0);
+ SColumnDataAgg columnDataAgg = {.numOfNull = 0};
+
+ auto checkNull = [totalRows, &columnInfoData, &columnDataAgg](uint32_t row, bool expected) {
+ EXPECT_EQ(colDataIsNull_s(&columnInfoData, row), expected);
+ EXPECT_EQ(colDataIsNull_t(&columnInfoData, row, IS_VAR_DATA_TYPE(columnInfoData.info.type)), expected);
+ EXPECT_EQ(colDataIsNull(&columnInfoData, totalRows, row, NULL), expected);
+ columnDataAgg.numOfNull = totalRows;
+ EXPECT_EQ(colDataIsNull(&columnInfoData, totalRows, row, &columnDataAgg), columnInfoData.hasNull);
+ columnDataAgg.numOfNull = 0;
+ EXPECT_EQ(colDataIsNull(&columnInfoData, totalRows, row, &columnDataAgg), false);
+ };
+
+ columnInfoData.hasNull = false;
+ checkNull(0, false);
+ checkNull(1, false);
+ checkNull(2, false);
+ checkNull(totalRows - 2, false);
+ checkNull(totalRows - 1, false);
+
+ if (IS_VAR_DATA_TYPE(type)) {
+ columnInfoData.varmeta.offset = (int32_t*)taosMemoryCalloc(totalRows, sizeof(int32_t));
+ } else {
+ columnInfoData.pData = (char*)taosMemoryCalloc(totalRows, tDataTypes[type].bytes);
+ columnInfoData.nullbitmap = (char*)taosMemoryCalloc(((totalRows - 1) >> NBIT) + 1, 1);
+ ValType val = 1;
+ setValFunc(&columnInfoData, 1, &val);
+ val = 2;
+ setValFunc(&columnInfoData, 2, &val);
+ }
+ colDataSetNULL(&columnInfoData, 0);
+ colDataSetNNULL(&columnInfoData, 3, totalRows - 3);
+ checkNull(0, true);
+ checkNull(1, false);
+ checkNull(2, false);
+ checkNull(totalRows - 2, true);
+ checkNull(totalRows - 1, true);
+
+ if (IS_VAR_DATA_TYPE(type)) {
+ taosMemoryFreeClear(columnInfoData.varmeta.offset);
+ } else {
+ taosMemoryFreeClear(columnInfoData.pData);
+ taosMemoryFreeClear(columnInfoData.nullbitmap);
+ checkNull(0, false);
+ checkNull(1, false);
+ checkNull(2, false);
+ checkNull(totalRows - 2, false);
+ checkNull(totalRows - 1, false);
+ }
+}
+
+TEST(utilTest, tdatablockTestNull) {
+ dataBlockNullTest(colDataSetInt8);
+ dataBlockNullTest(colDataSetInt16);
+ dataBlockNullTest(colDataSetInt32);
+ dataBlockNullTest(colDataSetInt64);
+ dataBlockNullTest(colDataSetFloat);
+ dataBlockNullTest(colDataSetDouble);
+ dataBlockNullTest(colDataSetInt64);
+}
diff --git a/tests/army/query/function/ans/leastsquares.csv b/tests/army/query/function/ans/leastsquares.csv
new file mode 100644
index 0000000000..3d5cd33336
--- /dev/null
+++ b/tests/army/query/function/ans/leastsquares.csv
@@ -0,0 +1,56 @@
+
+taos> select leastsquares(1, 1, 1)
+ leastsquares(1, 1, 1) |
+=================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(1.1 as float), 1, 1)
+ leastsquares(cast(1.1 as float), 1, 1) |
+=========================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(1.1 as double), 1, 1)
+ leastsquares(cast(1.1 as double), 1, 1) |
+==========================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(1 as tinyint), 1, 1)
+ leastsquares(cast(1 as tinyint), 1, 1) |
+=========================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(100 as smallint), 1, 1)
+ leastsquares(cast(100 as smallint), 1, 1) |
+============================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(100000 as int), 1, 1)
+ leastsquares(cast(100000 as int), 1, 1) |
+==========================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(10000000000 as bigint), 1, 1)
+ leastsquares(cast(10000000000 as bigint), 1, 1) |
+==================================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(1 as tinyint unsigned), 1, 1)
+ leastsquares(cast(1 as tinyint unsigned), 1, 1) |
+==================================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(100 as smallint unsigned), 1, 1)
+ leastsquares(cast(100 as smallint unsigned), 1, 1) |
+=====================================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(100000 as int unsigned), 1, 1)
+ leastsquares(cast(100000 as int unsigned), 1, 1) |
+===================================================
+ {slop:-nan, intercept:-nan} |
+
+taos> select leastsquares(cast(10000000000 as bigint unsigned), 1, 1)
+ leastsquares(cast(10000000000 as bigint unsigned), 1, 1) |
+===========================================================
+ {slop:-nan, intercept:-nan} |
+
diff --git a/tests/army/query/function/ans/max.csv b/tests/army/query/function/ans/max.csv
index f150ad1208..1570e1ebc9 100644
--- a/tests/army/query/function/ans/max.csv
+++ b/tests/army/query/function/ans/max.csv
@@ -603,3 +603,58 @@ taos> select location, max(current) from ts_4893.meters group by location order
============================================
beijing | 11.9989996 |
+taos> select max(1)
+ max(1) |
+========================
+ 1 |
+
+taos> select max(cast(1 as tinyint))
+ max(cast(1 as tinyint)) |
+==========================
+ 1 |
+
+taos> select max(cast(100 as smallint))
+ max(cast(100 as smallint)) |
+=============================
+ 100 |
+
+taos> select max(cast(100000 as int))
+ max(cast(100000 as int)) |
+===========================
+ 100000 |
+
+taos> select max(cast(10000000000 as bigint))
+ max(cast(10000000000 as bigint)) |
+===================================
+ 10000000000 |
+
+taos> select max(cast(1 as tinyint unsigned))
+ max(cast(1 as tinyint unsigned)) |
+===================================
+ 1 |
+
+taos> select max(cast(100 as smallint unsigned))
+ max(cast(100 as smallint unsigned)) |
+======================================
+ 100 |
+
+taos> select max(cast(100000 as int unsigned))
+ max(cast(100000 as int unsigned)) |
+====================================
+ 100000 |
+
+taos> select max(cast(10000000000 as bigint unsigned))
+ max(cast(10000000000 as bigint unsigned)) |
+============================================
+ 10000000000 |
+
+taos> select max(cast(1.1 as float))
+ max(cast(1.1 as float)) |
+==========================
+ 1.1000000e+00 |
+
+taos> select max(cast(1.1 as double))
+ max(cast(1.1 as double)) |
+============================
+ 1.100000000000000 |
+
diff --git a/tests/army/query/function/ans/min.csv b/tests/army/query/function/ans/min.csv
index 9a8ba15287..1ea0c47e81 100644
--- a/tests/army/query/function/ans/min.csv
+++ b/tests/army/query/function/ans/min.csv
@@ -603,3 +603,58 @@ taos> select location, min(id) from ts_4893.meters group by location order by lo
===================================
beijing | 0 |
+taos> select min(1)
+ min(1) |
+========================
+ 1 |
+
+taos> select min(cast(1 as tinyint))
+ min(cast(1 as tinyint)) |
+==========================
+ 1 |
+
+taos> select min(cast(100 as smallint))
+ min(cast(100 as smallint)) |
+=============================
+ 100 |
+
+taos> select min(cast(100000 as int))
+ min(cast(100000 as int)) |
+===========================
+ 100000 |
+
+taos> select min(cast(10000000000 as bigint))
+ min(cast(10000000000 as bigint)) |
+===================================
+ 10000000000 |
+
+taos> select min(cast(1 as tinyint unsigned))
+ min(cast(1 as tinyint unsigned)) |
+===================================
+ 1 |
+
+taos> select min(cast(100 as smallint unsigned))
+ min(cast(100 as smallint unsigned)) |
+======================================
+ 100 |
+
+taos> select min(cast(100000 as int unsigned))
+ min(cast(100000 as int unsigned)) |
+====================================
+ 100000 |
+
+taos> select min(cast(10000000000 as bigint unsigned))
+ min(cast(10000000000 as bigint unsigned)) |
+============================================
+ 10000000000 |
+
+taos> select min(cast(1.1 as float))
+ min(cast(1.1 as float)) |
+==========================
+ 1.1000000e+00 |
+
+taos> select min(cast(1.1 as double))
+ min(cast(1.1 as double)) |
+============================
+ 1.100000000000000 |
+
diff --git a/tests/army/query/function/ans/round.csv b/tests/army/query/function/ans/round.csv
index 1b6ed548e7..4f9151c1ad 100644
--- a/tests/army/query/function/ans/round.csv
+++ b/tests/army/query/function/ans/round.csv
@@ -308,3 +308,53 @@ taos> select round(log(current), 2) from ts_4893.meters limit 1
============================
2.370000000000000 |
+taos> select round(cast(1.0e+400 as float), 0);
+ round(cast(1.0e+400 as float), 0) |
+====================================
+ NULL |
+
+taos> select round(cast(1.0e+400 as double), 0);
+ round(cast(1.0e+400 as double), 0) |
+=====================================
+ NULL |
+
+taos> select round(cast(5 as tinyint), 1);
+ round(cast(5 as tinyint), 1) |
+===============================
+ 5 |
+
+taos> select round(cast(50 as smallint), 1);
+ round(cast(50 as smallint), 1) |
+=================================
+ 50 |
+
+taos> select round(cast(500 as int), 1);
+ round(cast(500 as int), 1) |
+=============================
+ 500 |
+
+taos> select round(cast(50000 as bigint), 1);
+ round(cast(50000 as bigint), 1) |
+==================================
+ 50000 |
+
+taos> select round(cast(5 as TINYINT UNSIGNED), 1);
+ round(cast(5 as tinyint unsigned), 1) |
+========================================
+ 5 |
+
+taos> select round(cast(50 as smallint unsigned), 1);
+ round(cast(50 as smallint unsigned), 1) |
+==========================================
+ 50 |
+
+taos> select round(cast(500 as int unsigned), 1);
+ round(cast(500 as int unsigned), 1) |
+======================================
+ 500 |
+
+taos> select round(cast(50000 as bigint unsigned), 1)
+ round(cast(50000 as bigint unsigned), 1) |
+===========================================
+ 50000 |
+
diff --git a/tests/army/query/function/ans/sign.csv b/tests/army/query/function/ans/sign.csv
index e15b4a74c7..45679af07f 100644
--- a/tests/army/query/function/ans/sign.csv
+++ b/tests/army/query/function/ans/sign.csv
@@ -121,6 +121,106 @@ taos> select SIGN(id) + id from ts_4893.meters order by ts limit 5
4.000000000000000 |
5.000000000000000 |
+taos> select sign(cast(1 as tinyint))
+ sign(cast(1 as tinyint)) |
+===========================
+ 1 |
+
+taos> select sign(cast(1 as smallint))
+ sign(cast(1 as smallint)) |
+============================
+ 1 |
+
+taos> select sign(cast(1 as int))
+ sign(cast(1 as int)) |
+=======================
+ 1 |
+
+taos> select sign(cast(1 as bigint))
+ sign(cast(1 as bigint)) |
+==========================
+ 1 |
+
+taos> select sign(cast(1 as tinyint unsigned))
+ sign(cast(1 as tinyint unsigned)) |
+====================================
+ 1 |
+
+taos> select sign(cast(1 as smallint unsigned))
+ sign(cast(1 as smallint unsigned)) |
+=====================================
+ 1 |
+
+taos> select sign(cast(1 as int unsigned))
+ sign(cast(1 as int unsigned)) |
+================================
+ 1 |
+
+taos> select sign(cast(1 as bigint unsigned))
+ sign(cast(1 as bigint unsigned)) |
+===================================
+ 1 |
+
+taos> select sign(cast(1 as float))
+ sign(cast(1 as float)) |
+=========================
+ 1.0000000e+00 |
+
+taos> select sign(cast(1 as double))
+ sign(cast(1 as double)) |
+============================
+ 1.000000000000000 |
+
+taos> select sign(cast(NULL as tinyint))
+ sign(cast(null as tinyint)) |
+==============================
+ NULL |
+
+taos> select sign(cast(NULL as smallint))
+ sign(cast(null as smallint)) |
+===============================
+ NULL |
+
+taos> select sign(cast(NULL as int))
+ sign(cast(null as int)) |
+==========================
+ NULL |
+
+taos> select sign(cast(NULL as bigint))
+ sign(cast(null as bigint)) |
+=============================
+ NULL |
+
+taos> select sign(cast(NULL as tinyint unsigned))
+ sign(cast(null as tinyint unsigned)) |
+=======================================
+ NULL |
+
+taos> select sign(cast(NULL as smallint unsigned))
+ sign(cast(null as smallint unsigned)) |
+========================================
+ NULL |
+
+taos> select sign(cast(NULL as int unsigned))
+ sign(cast(null as int unsigned)) |
+===================================
+ NULL |
+
+taos> select sign(cast(NULL as bigint unsigned))
+ sign(cast(null as bigint unsigned)) |
+======================================
+ NULL |
+
+taos> select sign(cast(NULL as float))
+ sign(cast(null as float)) |
+============================
+ NULL |
+
+taos> select sign(cast(NULL as double))
+ sign(cast(null as double)) |
+=============================
+ NULL |
+
taos> select SIGN(abs(10))
sign(abs(10)) |
========================
@@ -213,6 +313,34 @@ taos> select sign(current) from ts_4893.meters order by ts limit 10
1.0000000 |
1.0000000 |
+taos> select sign(cast(current as float)) from ts_4893.d0 order by ts limit 10
+ sign(cast(current as float)) |
+===============================
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+
+taos> select sign(cast(current as float)) from ts_4893.meters order by ts limit 10
+ sign(cast(current as float)) |
+===============================
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+ 1.0000000e+00 |
+
taos> select sign(null)
sign(null) |
========================
diff --git a/tests/army/query/function/ans/statecount.csv b/tests/army/query/function/ans/statecount.csv
new file mode 100644
index 0000000000..d16b8443e2
--- /dev/null
+++ b/tests/army/query/function/ans/statecount.csv
@@ -0,0 +1,56 @@
+
+taos> select statecount(1, 'GT', 1)
+ statecount(1, 'GT', 1) |
+=========================
+ -1 |
+
+taos> select statecount(cast(1 as tinyint), 'GT', 1)
+ statecount(cast(1 as tinyint), 'GT', 1) |
+==========================================
+ -1 |
+
+taos> select statecount(cast(100 as smallint), 'GT', 1)
+ statecount(cast(100 as smallint), 'GT', 1) |
+=============================================
+ 1 |
+
+taos> select statecount(cast(100000 as int), 'GT', 1)
+ statecount(cast(100000 as int), 'GT', 1) |
+===========================================
+ 1 |
+
+taos> select statecount(cast(10000000000 as bigint), 'GT', 1)
+ statecount(cast(10000000000 as bigint), 'GT', 1) |
+===================================================
+ 1 |
+
+taos> select statecount(cast(1 as tinyint unsigned), 'GT', 1)
+ statecount(cast(1 as tinyint unsigned), 'GT', 1) |
+===================================================
+ -1 |
+
+taos> select statecount(cast(100 as smallint unsigned), 'GT', 1)
+ statecount(cast(100 as smallint unsigned), 'GT', 1) |
+======================================================
+ 1 |
+
+taos> select statecount(cast(100000 as int unsigned), 'GT', 1)
+ statecount(cast(100000 as int unsigned), 'GT', 1) |
+====================================================
+ 1 |
+
+taos> select statecount(cast(10000000000 as bigint unsigned), 'GT', 1)
+ statecount(cast(10000000000 as bigint unsigned), 'GT', 1) |
+============================================================
+ 1 |
+
+taos> select statecount(cast(1.1 as float), 'GT', 1)
+ statecount(cast(1.1 as float), 'GT', 1) |
+==========================================
+ 1 |
+
+taos> select statecount(cast(1.1 as double), 'GT', 1)
+ statecount(cast(1.1 as double), 'GT', 1) |
+===========================================
+ 1 |
+
diff --git a/tests/army/query/function/ans/sum.csv b/tests/army/query/function/ans/sum.csv
new file mode 100644
index 0000000000..3444b3f710
--- /dev/null
+++ b/tests/army/query/function/ans/sum.csv
@@ -0,0 +1,56 @@
+
+taos> select sum(1)
+ sum(1) |
+========================
+ 1 |
+
+taos> select sum(cast(1 as tinyint))
+ sum(cast(1 as tinyint)) |
+==========================
+ 1 |
+
+taos> select sum(cast(100 as smallint))
+ sum(cast(100 as smallint)) |
+=============================
+ 100 |
+
+taos> select sum(cast(100000 as int))
+ sum(cast(100000 as int)) |
+===========================
+ 100000 |
+
+taos> select sum(cast(10000000000 as bigint))
+ sum(cast(10000000000 as bigint)) |
+===================================
+ 10000000000 |
+
+taos> select sum(cast(1 as tinyint unsigned))
+ sum(cast(1 as tinyint unsigned)) |
+===================================
+ 1 |
+
+taos> select sum(cast(100 as smallint unsigned))
+ sum(cast(100 as smallint unsigned)) |
+======================================
+ 100 |
+
+taos> select sum(cast(100000 as int unsigned))
+ sum(cast(100000 as int unsigned)) |
+====================================
+ 100000 |
+
+taos> select sum(cast(10000000000 as bigint unsigned))
+ sum(cast(10000000000 as bigint unsigned)) |
+============================================
+ 10000000000 |
+
+taos> select sum(cast(1.1 as float))
+ sum(cast(1.1 as float)) |
+============================
+ 1.100000023841858 |
+
+taos> select sum(cast(1.1 as double))
+ sum(cast(1.1 as double)) |
+============================
+ 1.100000000000000 |
+
diff --git a/tests/army/query/function/ans/trim.csv b/tests/army/query/function/ans/trim.csv
index 6e2efbda51..eb821ffc91 100644
--- a/tests/army/query/function/ans/trim.csv
+++ b/tests/army/query/function/ans/trim.csv
@@ -179,6 +179,33 @@ taos> select trim(trailing '空格blank' from '空格blank空格中Tes空格blan
===================================================================
空格blank空格中Tes空格blank空 |
+taos> select trim(both from nch1) from ts_4893.meters order by ts limit 5
+ trim(both from nch1) |
+=================================
+ novel |
+ 一二三四五六七八九十 |
+ update |
+ prision |
+ novel |
+
+taos> select trim(leading from nch1) from ts_4893.meters order by ts limit 5
+ trim(leading from nch1) |
+=================================
+ novel |
+ 一二三四五六七八九十 |
+ update |
+ prision |
+ novel |
+
+taos> select trim(trailing from nch1) from ts_4893.meters order by ts limit 5
+ trim(trailing from nch1) |
+=================================
+ novel |
+ 一二三四五六七八九十 |
+ update |
+ prision |
+ novel |
+
taos> select trim(nch2 from nch1) from ts_4893.meters where position(nch2 in nch1) != 0 order by ts limit 5
trim(nch2 from nch1) |
=================================
diff --git a/tests/army/query/function/in/avg.in b/tests/army/query/function/in/avg.in
new file mode 100644
index 0000000000..9284e8b1b7
--- /dev/null
+++ b/tests/army/query/function/in/avg.in
@@ -0,0 +1,11 @@
+select avg(1)
+select avg(cast(1 as tinyint))
+select avg(cast(100 as smallint))
+select avg(cast(100000 as int))
+select avg(cast(10000000000 as bigint))
+select avg(cast(1 as tinyint unsigned))
+select avg(cast(100 as smallint unsigned))
+select avg(cast(100000 as int unsigned))
+select avg(cast(10000000000 as bigint unsigned))
+select avg(cast(1.1 as float))
+select avg(cast(1.1 as double))
\ No newline at end of file
diff --git a/tests/army/query/function/in/leastsquares.in b/tests/army/query/function/in/leastsquares.in
new file mode 100644
index 0000000000..2783a2a0c5
--- /dev/null
+++ b/tests/army/query/function/in/leastsquares.in
@@ -0,0 +1,11 @@
+select leastsquares(1, 1, 1)
+select leastsquares(cast(1.1 as float), 1, 1)
+select leastsquares(cast(1.1 as double), 1, 1)
+select leastsquares(cast(1 as tinyint), 1, 1)
+select leastsquares(cast(100 as smallint), 1, 1)
+select leastsquares(cast(100000 as int), 1, 1)
+select leastsquares(cast(10000000000 as bigint), 1, 1)
+select leastsquares(cast(1 as tinyint unsigned), 1, 1)
+select leastsquares(cast(100 as smallint unsigned), 1, 1)
+select leastsquares(cast(100000 as int unsigned), 1, 1)
+select leastsquares(cast(10000000000 as bigint unsigned), 1, 1)
diff --git a/tests/army/query/function/in/max.in b/tests/army/query/function/in/max.in
index efd4620f7b..336045afb5 100644
--- a/tests/army/query/function/in/max.in
+++ b/tests/army/query/function/in/max.in
@@ -26,3 +26,14 @@ select log(max(voltage) + 1) from ts_4893.meters
select groupid, max(voltage) from ts_4893.meters group by groupid order by groupid
select location, max(id) from ts_4893.meters group by location order by location
select location, max(current) from ts_4893.meters group by location order by location
+select max(1)
+select max(cast(1 as tinyint))
+select max(cast(100 as smallint))
+select max(cast(100000 as int))
+select max(cast(10000000000 as bigint))
+select max(cast(1 as tinyint unsigned))
+select max(cast(100 as smallint unsigned))
+select max(cast(100000 as int unsigned))
+select max(cast(10000000000 as bigint unsigned))
+select max(cast(1.1 as float))
+select max(cast(1.1 as double))
diff --git a/tests/army/query/function/in/min.in b/tests/army/query/function/in/min.in
index 910b8cc7bd..55d6853446 100644
--- a/tests/army/query/function/in/min.in
+++ b/tests/army/query/function/in/min.in
@@ -26,3 +26,14 @@ select log(min(voltage) + 1) from ts_4893.meters
select groupid, min(voltage) from ts_4893.meters group by groupid order by groupid
select location, min(current) from ts_4893.meters group by location order by location
select location, min(id) from ts_4893.meters group by location order by location
+select min(1)
+select min(cast(1 as tinyint))
+select min(cast(100 as smallint))
+select min(cast(100000 as int))
+select min(cast(10000000000 as bigint))
+select min(cast(1 as tinyint unsigned))
+select min(cast(100 as smallint unsigned))
+select min(cast(100000 as int unsigned))
+select min(cast(10000000000 as bigint unsigned))
+select min(cast(1.1 as float))
+select min(cast(1.1 as double))
diff --git a/tests/army/query/function/in/round.in b/tests/army/query/function/in/round.in
index bca293fc72..13dcb57117 100644
--- a/tests/army/query/function/in/round.in
+++ b/tests/army/query/function/in/round.in
@@ -47,3 +47,13 @@ select round(abs(voltage), 2) from ts_4893.meters limit 1
select round(pi() * phase, 3) from ts_4893.meters limit 1
select round(sqrt(voltage), 2) from ts_4893.meters limit 1
select round(log(current), 2) from ts_4893.meters limit 1
+select round(cast(1.0e+400 as float), 0);
+select round(cast(1.0e+400 as double), 0);
+select round(cast(5 as tinyint), 1);
+select round(cast(50 as smallint), 1);
+select round(cast(500 as int), 1);
+select round(cast(50000 as bigint), 1);
+select round(cast(5 as TINYINT UNSIGNED), 1);
+select round(cast(50 as smallint unsigned), 1);
+select round(cast(500 as int unsigned), 1);
+select round(cast(50000 as bigint unsigned), 1);
\ No newline at end of file
diff --git a/tests/army/query/function/in/sign.in b/tests/army/query/function/in/sign.in
index 436c884d36..25780eb31c 100644
--- a/tests/army/query/function/in/sign.in
+++ b/tests/army/query/function/in/sign.in
@@ -20,6 +20,26 @@ select SIGN(2) * SIGN(1) from ts_4893.meters limit 1
select SIGN(2) / SIGN(1) from ts_4893.meters limit 1
select SIGN(1) + id from ts_4893.meters order by ts limit 5
select SIGN(id) + id from ts_4893.meters order by ts limit 5
+select sign(cast(1 as tinyint))
+select sign(cast(1 as smallint))
+select sign(cast(1 as int))
+select sign(cast(1 as bigint))
+select sign(cast(1 as tinyint unsigned))
+select sign(cast(1 as smallint unsigned))
+select sign(cast(1 as int unsigned))
+select sign(cast(1 as bigint unsigned))
+select sign(cast(1 as float))
+select sign(cast(1 as double))
+select sign(cast(NULL as tinyint))
+select sign(cast(NULL as smallint))
+select sign(cast(NULL as int))
+select sign(cast(NULL as bigint))
+select sign(cast(NULL as tinyint unsigned))
+select sign(cast(NULL as smallint unsigned))
+select sign(cast(NULL as int unsigned))
+select sign(cast(NULL as bigint unsigned))
+select sign(cast(NULL as float))
+select sign(cast(NULL as double))
select SIGN(abs(10))
select SIGN(abs(-10))
select abs(SIGN(10))
@@ -34,6 +54,8 @@ select sign(-1)
select sign(-10)
select sign(current) from ts_4893.d0 order by ts limit 10
select sign(current) from ts_4893.meters order by ts limit 10
+select sign(cast(current as float)) from ts_4893.d0 order by ts limit 10
+select sign(cast(current as float)) from ts_4893.meters order by ts limit 10
select sign(null)
select sign(25)
select sign(-10)
diff --git a/tests/army/query/function/in/statecount.in b/tests/army/query/function/in/statecount.in
new file mode 100644
index 0000000000..df64918d61
--- /dev/null
+++ b/tests/army/query/function/in/statecount.in
@@ -0,0 +1,11 @@
+select statecount(1, 'GT', 1)
+select statecount(cast(1 as tinyint), 'GT', 1)
+select statecount(cast(100 as smallint), 'GT', 1)
+select statecount(cast(100000 as int), 'GT', 1)
+select statecount(cast(10000000000 as bigint), 'GT', 1)
+select statecount(cast(1 as tinyint unsigned), 'GT', 1)
+select statecount(cast(100 as smallint unsigned), 'GT', 1)
+select statecount(cast(100000 as int unsigned), 'GT', 1)
+select statecount(cast(10000000000 as bigint unsigned), 'GT', 1)
+select statecount(cast(1.1 as float), 'GT', 1)
+select statecount(cast(1.1 as double), 'GT', 1)
diff --git a/tests/army/query/function/in/sum.in b/tests/army/query/function/in/sum.in
new file mode 100644
index 0000000000..4caf5ecdbf
--- /dev/null
+++ b/tests/army/query/function/in/sum.in
@@ -0,0 +1,11 @@
+select sum(1)
+select sum(cast(1 as tinyint))
+select sum(cast(100 as smallint))
+select sum(cast(100000 as int))
+select sum(cast(10000000000 as bigint))
+select sum(cast(1 as tinyint unsigned))
+select sum(cast(100 as smallint unsigned))
+select sum(cast(100000 as int unsigned))
+select sum(cast(10000000000 as bigint unsigned))
+select sum(cast(1.1 as float))
+select sum(cast(1.1 as double))
diff --git a/tests/army/query/function/in/trim.in b/tests/army/query/function/in/trim.in
index a0ad54dd7c..e96fb08675 100644
--- a/tests/army/query/function/in/trim.in
+++ b/tests/army/query/function/in/trim.in
@@ -34,6 +34,9 @@ select trim('空格blank' from '空格blank空格中Tes空格blank空')
select trim(both '空格blank' from '空格blank空格中Tes空格blank空')
select trim(leading '空格blank' from '空格blank空格中Tes空格blank空')
select trim(trailing '空格blank' from '空格blank空格中Tes空格blank空')
+select trim(both from nch1) from ts_4893.meters order by ts limit 5
+select trim(leading from nch1) from ts_4893.meters order by ts limit 5
+select trim(trailing from nch1) from ts_4893.meters order by ts limit 5
select trim(nch2 from nch1) from ts_4893.meters where position(nch2 in nch1) != 0 order by ts limit 5
select trim(both nch2 from nch1) from ts_4893.meters where position(nch2 in nch1) != 0 order by ts limit 5
select trim(leading nch2 from nch1) from ts_4893.meters where position(nch2 in nch1) != 0 order by ts limit 5
diff --git a/tests/army/query/function/test_function.py b/tests/army/query/function/test_function.py
index d54460804a..c583d08cec 100644
--- a/tests/army/query/function/test_function.py
+++ b/tests/army/query/function/test_function.py
@@ -294,6 +294,18 @@ class TDTestCase(TBase):
tdSql.error("select min(nonexistent_column) from ts_4893.meters;")
+ def test_sum(self):
+ self.test_normal_query_new("sum")
+
+ def test_statecount(self):
+ self.test_normal_query_new("statecount")
+
+ def test_avg(self):
+ self.test_normal_query_new("avg")
+
+ def test_leastsquares(self):
+ self.test_normal_query_new("leastsquares")
+
def test_error(self):
tdSql.error("select * from (select to_iso8601(ts, timezone()), timezone() from ts_4893.meters \
order by ts desc) limit 1000;", expectErrInfo="Invalid parameter data type : to_iso8601") # TS-5340
@@ -336,6 +348,10 @@ class TDTestCase(TBase):
# agg function
self.test_stddev_pop()
self.test_varpop()
+ self.test_avg()
+ self.test_sum()
+ self.test_leastsquares()
+ self.test_statecount()
# select function
self.test_max()
diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task
index 00a17c8c96..c9d28e0623 100644
--- a/tests/parallel_test/cases.task
+++ b/tests/parallel_test/cases.task
@@ -218,6 +218,8 @@
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 2
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 3
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/slimit.py -Q 4
+,,n,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-5761.py
+,,n,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-5761-scalemode.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-5712.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 2
@@ -1420,34 +1422,36 @@
,,y,script,./test.sh -f tsim/stream/sliding.sim
,,y,script,./test.sh -f tsim/stream/state0.sim
,,y,script,./test.sh -f tsim/stream/state1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpDelete0.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpDelete1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpDelete2.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpError.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpDelete0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpDelete1.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpDelete2.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpError.sim
,,y,script,./test.sh -f tsim/stream/streamInterpForceWindowClose.sim
,,y,script,./test.sh -f tsim/stream/streamInterpForceWindowClose1.sim
,,y,script,./test.sh -f tsim/stream/streamInterpFwcError.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpHistory.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpHistory.sim
#,,y,script,./test.sh -f tsim/stream/streamInterpHistory1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpLarge.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpLinear0.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpNext0.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpOther.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpLarge.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpLinear0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpNext0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpOther.sim
#,,y,script,./test.sh -f tsim/stream/streamInterpOther1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpPartitionBy0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPartitionBy0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPartitionBy1.sim
#,,y,script,./test.sh -f tsim/stream/streamInterpPrev0.sim
#,,y,script,./test.sh -f tsim/stream/streamInterpPrev1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey0.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey2.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey3.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpUpdate.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpUpdate1.sim
-#,,y,script,./test.sh -f tsim/stream/streamInterpValue0.sim
-#,,y,script,./test.sh -f tsim/stream/streamPrimaryKey0.sim
-#,,y,script,./test.sh -f tsim/stream/streamPrimaryKey1.sim
-#,,y,script,./test.sh -f tsim/stream/streamPrimaryKey2.sim
-#,,y,script,./test.sh -f tsim/stream/streamPrimaryKey3.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey0.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey1.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey2.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpPrimaryKey3.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpUpdate.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpUpdate1.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpUpdate2.sim
+,,y,script,./test.sh -f tsim/stream/streamInterpValue0.sim
+,,y,script,./test.sh -f tsim/stream/streamPrimaryKey0.sim
+,,y,script,./test.sh -f tsim/stream/streamPrimaryKey1.sim
+,,y,script,./test.sh -f tsim/stream/streamPrimaryKey2.sim
+,,y,script,./test.sh -f tsim/stream/streamPrimaryKey3.sim
,,y,script,./test.sh -f tsim/stream/streamTwaError.sim
,,y,script,./test.sh -f tsim/stream/streamTwaFwcFill.sim
,,y,script,./test.sh -f tsim/stream/streamTwaFwcFillPrimaryKey.sim
diff --git a/tests/pytest/auto_crash_gen.py b/tests/pytest/auto_crash_gen.py
index f6b31b4691..316f2ead0f 100755
--- a/tests/pytest/auto_crash_gen.py
+++ b/tests/pytest/auto_crash_gen.py
@@ -384,7 +384,8 @@ Core dir: {core_dir}
if text_result == "success":
send_msg(notification_robot_url, get_msg(text))
else:
- send_msg(alert_robot_url, get_msg(text))
+ send_msg(alert_robot_url, get_msg(text))
+ send_msg(notification_robot_url, get_msg(text))
#send_msg(get_msg(text))
except Exception as e:
diff --git a/tests/pytest/auto_crash_gen_valgrind.py b/tests/pytest/auto_crash_gen_valgrind.py
index b346aca308..b7af68cd2f 100755
--- a/tests/pytest/auto_crash_gen_valgrind.py
+++ b/tests/pytest/auto_crash_gen_valgrind.py
@@ -419,6 +419,7 @@ Core dir: {core_dir}
send_msg(notification_robot_url, get_msg(text))
else:
send_msg(alert_robot_url, get_msg(text))
+ send_msg(notification_robot_url, get_msg(text))
#send_msg(get_msg(text))
except Exception as e:
diff --git a/tests/pytest/auto_crash_gen_valgrind_cluster.py b/tests/pytest/auto_crash_gen_valgrind_cluster.py
index 522ad48640..df40b60967 100755
--- a/tests/pytest/auto_crash_gen_valgrind_cluster.py
+++ b/tests/pytest/auto_crash_gen_valgrind_cluster.py
@@ -406,7 +406,8 @@ Core dir: {core_dir}
if text_result == "success":
send_msg(notification_robot_url, get_msg(text))
else:
- send_msg(alert_robot_url, get_msg(text))
+ send_msg(alert_robot_url, get_msg(text))
+ send_msg(notification_robot_url, get_msg(text))
#send_msg(get_msg(text))
except Exception as e:
diff --git a/tests/run_all_ci_cases.sh b/tests/run_all_ci_cases.sh
index 959af66d19..11670800b8 100644
--- a/tests/run_all_ci_cases.sh
+++ b/tests/run_all_ci_cases.sh
@@ -7,12 +7,120 @@ GREEN_DARK='\033[0;32m'
GREEN_UNDERLINE='\033[4;32m'
NC='\033[0m'
-TDENGINE_DIR=/root/TDinternal/community
+function print_color() {
+ local color="$1"
+ local message="$2"
+ echo -e "${color}${message}${NC}"
+}
+
+# 初始化参数
+TDENGINE_DIR="/root/TDinternal/community"
+BRANCH=""
+SAVE_LOG="notsave"
+
+# 解析命令行参数
+while getopts "hd:b:t:s:" arg; do
+ case $arg in
+ d)
+ TDENGINE_DIR=$OPTARG
+ ;;
+ b)
+ BRANCH=$OPTARG
+ ;;
+ s)
+ 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
+ ;;
+ ?)
+ echo "Usage: ./$(basename $0) -h"
+ exit 1
+ ;;
+ 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
-#echo "TDENGINE_DIR = $TDENGINE_DIR"
+echo "TDENGINE_DIR = $TDENGINE_DIR"
today=`date +"%Y%m%d"`
-TDENGINE_ALLCI_REPORT=$TDENGINE_DIR/tests/all-ci-report-$today.log
+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 *
+
+
+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
+
+ # 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_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
+ branch="$BRANCH"
+ print_color "$GREEN" "Testing branch: $branch "
+ print_color "$GREEN" "Build is required for this test!"
+ buildTDengine
+else
+ print_color "$GREEN" "Build is not required for this test!"
+fi
function runCasesOneByOne () {
@@ -20,23 +128,50 @@ function runCasesOneByOne () {
if [[ "$line" != "#"* ]]; then
cmd=`echo $line | cut -d',' -f 5`
if [[ "$2" == "sim" ]] && [[ $line == *"script"* ]]; then
+ echo $cmd
case=`echo $cmd | cut -d' ' -f 3`
+ case_file=`echo $case | tr -d ' /' `
start_time=`date +%s`
- date +%F\ %T | tee -a $TDENGINE_ALLCI_REPORT && timeout 20m $cmd > /dev/null 2>&1 && \
- echo -e "${GREEN}$case success${NC}" | tee -a $TDENGINE_ALLCI_REPORT \
- || echo -e "${RED}$case failed${NC}" | tee -a $TDENGINE_ALLCI_REPORT
+ 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`
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a $TDENGINE_ALLCI_REPORT
-
+
elif [[ "$line" == *"$2"* ]]; then
+ echo $cmd
if [[ "$cmd" == *"pytest.sh"* ]]; then
cmd=`echo $cmd | cut -d' ' -f 2-20`
fi
- case=`echo $cmd | cut -d' ' -f 4-20`
+ case=`echo $cmd | cut -d' ' -f 4-20`
+ case_file=`echo $case | tr -d ' /' `
start_time=`date +%s`
- date +%F\ %T | tee -a $TDENGINE_ALLCI_REPORT && timeout 20m $cmd > /dev/null 2>&1 && \
+ 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
+
+ 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`
echo execution time of $case was `expr $end_time - $start_time`s. | tee -a $TDENGINE_ALLCI_REPORT
fi
@@ -45,62 +180,62 @@ function runCasesOneByOne () {
}
function runUnitTest() {
- echo "=== Run unit test case ==="
- echo " $TDENGINE_DIR/debug"
- cd $TDENGINE_DIR/debug
+ print_color "$GREEN" "=== Run unit test case ==="
+ print_color "$GREEN" " $TDENGINE_DIR/../debug"
+ cd $TDENGINE_DIR/../debug
ctest -j12
- echo "3.0 unit test done"
+ print_color "$GREEN" "3.0 unit test done"
}
function runSimCases() {
- echo "=== Run sim cases ==="
+ print_color "$GREEN" "=== Run sim cases ==="
cd $TDENGINE_DIR/tests/script
- runCasesOneByOne $TDENGINE_DIR/tests/parallel_test/cases-test.task sim
+ runCasesOneByOne $TDENGINE_DIR/tests/parallel_test/cases.task sim
totalSuccess=`grep 'sim success' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalSuccess" -gt "0" ]; then
- echo "### Total $totalSuccess SIM test case(s) succeed! ###" | tee -a $TDENGINE_ALLCI_REPORT
+ print_color "$GREEN" "### Total $totalSuccess SIM test case(s) succeed! ###" | tee -a $TDENGINE_ALLCI_REPORT
fi
totalFailed=`grep 'sim failed\|fault' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalFailed" -ne "0" ]; then
- echo "### Total $totalFailed SIM test case(s) failed! ###" | tee -a $TDENGINE_ALLCI_REPORT
+ print_color "$RED" "### Total $totalFailed SIM test case(s) failed! ###" | tee -a $TDENGINE_ALLCI_REPORT
fi
}
function runPythonCases() {
- echo "=== Run python cases ==="
+ print_color "$GREEN" "=== Run python cases ==="
cd $TDENGINE_DIR/tests/parallel_test
- sed -i '/compatibility.py/d' cases-test.task
+ sed -i '/compatibility.py/d' cases.task
# army
cd $TDENGINE_DIR/tests/army
- runCasesOneByOne ../parallel_test/cases-test.task army
+ runCasesOneByOne ../parallel_test/cases.task army
# system-test
cd $TDENGINE_DIR/tests/system-test
- runCasesOneByOne ../parallel_test/cases-test.task system-test
+ runCasesOneByOne ../parallel_test/cases.task system-test
# develop-test
cd $TDENGINE_DIR/tests/develop-test
- runCasesOneByOne ../parallel_test/cases-test.task develop-test
+ runCasesOneByOne ../parallel_test/cases.task develop-test
totalSuccess=`grep 'py success' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalSuccess" -gt "0" ]; then
- echo "### Total $totalSuccess python test case(s) succeed! ###" | tee -a $TDENGINE_ALLCI_REPORT
+ print_color "$GREEN" "### Total $totalSuccess python test case(s) succeed! ###" | tee -a $TDENGINE_ALLCI_REPORT
fi
totalFailed=`grep 'py failed\|fault' $TDENGINE_ALLCI_REPORT | wc -l`
if [ "$totalFailed" -ne "0" ]; then
- echo "### Total $totalFailed python test case(s) failed! ###" | tee -a $TDENGINE_ALLCI_REPORT
+ print_color "$RED" "### Total $totalFailed python test case(s) failed! ###" | tee -a $TDENGINE_ALLCI_REPORT
fi
}
function runTest() {
- echo "run Test"
+ print_color "$GREEN" "run Test"
cd $TDENGINE_DIR
[ -d sim ] && rm -rf sim
@@ -119,20 +254,20 @@ function runTest() {
}
function stopTaosd {
- echo "Stop taosd start"
- systemctl stop taosd
- PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
+ print_color "$GREEN" "Stop taosd start"
+ systemctl stop taosd
+ PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
while [ -n "$PID" ]
do
- pkill -TERM -x taosd
- sleep 1
- PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
+ pkill -TERM -x taosd
+ sleep 1
+ PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
done
- echo "Stop tasod end"
+ print_color "$GREEN" "Stop tasod end"
}
function stopTaosadapter {
- echo "Stop taosadapter"
+ print_color "$GREEN" "Stop taosadapter"
systemctl stop taosadapter.service
PID=`ps -ef|grep -w taosadapter | grep -v grep | awk '{print $2}'`
while [ -n "$PID" ]
@@ -141,18 +276,18 @@ function stopTaosadapter {
sleep 1
PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'`
done
- echo "Stop tasoadapter end"
+ print_color "$GREEN" "Stop tasoadapter end"
}
WORK_DIR=/root/
date >> $WORK_DIR/date.log
-echo "Run ALL CI Test Cases" | tee -a $WORK_DIR/date.log
+print_color "$GREEN" "Run all ci test cases" | tee -a $WORK_DIR/date.log
stopTaosd
runTest
date >> $WORK_DIR/date.log
-echo "End of CI Test Cases" | tee -a $WORK_DIR/date.log
\ No newline at end of file
+print_color "$GREEN" "End of ci test cases" | tee -a $WORK_DIR/date.log
\ No newline at end of file
diff --git a/tests/run_local_coverage.sh b/tests/run_local_coverage.sh
index b2413c4065..dfb0e8f9b7 100755
--- a/tests/run_local_coverage.sh
+++ b/tests/run_local_coverage.sh
@@ -17,9 +17,10 @@ function print_color() {
TDENGINE_DIR="/root/TDinternal/community"
BRANCH=""
TDENGINE_GCDA_DIR="/root/TDinternal/community/debug/"
+LCOV_DIR="/usr/local/bin"
# Parse command line parameters
-while getopts "hd:b:f:c:u:i:" arg; do
+while getopts "hd:b:f:c:u:i:l:" arg; do
case $arg in
d)
TDENGINE_DIR=$OPTARG
@@ -39,14 +40,18 @@ while getopts "hd:b:f:c:u:i:" arg; do
i)
BRANCH_BUILD=$OPTARG
;;
+ l)
+ 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]"
+ 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
;;
?)
@@ -59,13 +64,14 @@ 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] "
+ 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
@@ -299,11 +305,18 @@ function lcovFunc {
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 "
+ else
+ print_color "$GREEN" "Lcov bin dir is default"
+ fi
+
# collect data
- 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 "$TDENGINE_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 --remove coverage.info \
+ $LCOV_DIR/lcov --remove coverage.info \
'*/contrib/*' '*/test/*' '*/packaging/*' '*/taos-tools/*' '*/taosadapter/*' '*/TSZ/*' \
'*/AccessBridgeCalls.c' '*/ttszip.c' '*/dataInserter.c' '*/tlinearhash.c' '*/tsimplehash.c' '*/tsdbDiskData.c' '/*/enterprise/*' '*/docs/*' '*/sim/*'\
'*/texpr.c' '*/runUdf.c' '*/schDbg.c' '*/syncIO.c' '*/tdbOs.c' '*/pushServer.c' '*/osLz4.c'\
@@ -316,7 +329,7 @@ function lcovFunc {
# generate result
echo "generate result"
- lcov -l --rc lcov_branch_coverage=1 coverage.info | tee -a $TDENGINE_COVERAGE_REPORT
+ $LCOV_DIR/lcov -l --rc lcov_branch_coverage=1 coverage.info | tee -a $TDENGINE_COVERAGE_REPORT
}
@@ -373,8 +386,14 @@ if [ ! -f "$COVERAGE_INFO" ]; then
exit 1
fi
+if [ -n "$LCOV_DIR" ]; then
+ LCOV_DIR="$LCOV_DIR"
+ print_color "$GREEN" "Lcov bin dir: $LCOV_DIR "
+else
+ print_color "$GREEN" "Lcov bin dir is default"
+fi
# Generate local HTML reports
-genhtml "$COVERAGE_INFO" --branch-coverage --function-coverage --output-directory "$OUTPUT_DIR"
+$LCOV_DIR/genhtml "$COVERAGE_INFO" --branch-coverage --function-coverage --output-directory "$OUTPUT_DIR"
# Check whether the report was generated successfully
if [ $? -eq 0 ]; then
diff --git a/tests/script/api/stmt2-performance.c b/tests/script/api/stmt2-performance.c
index aa8e5b9450..a539affaf1 100644
--- a/tests/script/api/stmt2-performance.c
+++ b/tests/script/api/stmt2-performance.c
@@ -5,9 +5,9 @@
#include
#include "taos.h"
-int CTB_NUMS = 1000;
-int ROW_NUMS = 10;
-int CYC_NUMS = 5;
+int CTB_NUMS = 2;
+int ROW_NUMS = 2;
+int CYC_NUMS = 2;
void do_query(TAOS* taos, const char* sql) {
TAOS_RES* result = taos_query(taos, sql);
@@ -57,7 +57,7 @@ void do_stmt(TAOS* taos, const char* sql) {
return;
}
int fieldNum = 0;
- TAOS_FIELD_STB* pFields = NULL;
+ TAOS_FIELD_ALL* pFields = NULL;
// code = taos_stmt2_get_stb_fields(stmt, &fieldNum, &pFields);
// if (code != 0) {
// printf("failed get col,ErrCode: 0x%x, ErrMessage: %s.\n", code, taos_stmt2_error(stmt));
@@ -74,7 +74,7 @@ void do_stmt(TAOS* taos, const char* sql) {
for (int i = 0; i < CTB_NUMS; i++) {
tbs[i] = (char*)malloc(sizeof(char) * 20);
sprintf(tbs[i], "ctb_%d", i);
- createCtb(taos, tbs[i]);
+ // createCtb(taos, tbs[i]);
}
for (int r = 0; r < CYC_NUMS; r++) {
// col params
@@ -138,7 +138,24 @@ void do_stmt(TAOS* taos, const char* sql) {
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("stmt2-exec [%s] insert Time used: %f seconds\n", sql, cpu_time_used);
+
+ for (int i = 0; i < CTB_NUMS; i++) {
+ free(tags[i]);
+ free(paramv[i]);
+ free(ts[i]);
+ free(b[i]);
+ }
+ free(ts);
+ free(b);
+ free(ts_len);
+ free(b_len);
+ free(paramv);
+ free(tags);
}
+ for (int i = 0; i < CTB_NUMS; i++) {
+ free(tbs[i]);
+ }
+ free(tbs);
// taos_stmt2_free_fields(stmt, pFields);
taos_stmt2_close(stmt);
@@ -200,10 +217,9 @@ int main() {
exit(1);
}
- sleep(3);
do_stmt(taos, "insert into db.stb(tbname,ts,b,t1,t2) values(?,?,?,?,?)");
// do_stmt(taos, "insert into db.? using db.stb tags(?,?)values(?,?)");
- do_taosc(taos);
+ // do_taosc(taos);
taos_close(taos);
taos_cleanup();
}
diff --git a/tests/script/tsim/join/join_explain.sim b/tests/script/tsim/join/join_explain.sim
index f9d2f3eac1..2858999de5 100644
--- a/tests/script/tsim/join/join_explain.sim
+++ b/tests/script/tsim/join/join_explain.sim
@@ -39,6 +39,7 @@ sql explain analyze verbose true select a.ts from sta a join sta b on a.col1 = b
sql explain analyze verbose true select a.ts from sta a join sta b where a.ts=b.ts;
sql_error explain analyze verbose true select a.ts from sta a ,sta b on a.ts=b.ts;
sql explain analyze verbose true select a.ts from sta a ,sta b where a.ts=b.ts;
+sql explain analyze verbose true select a.ts from sta a ,sta b where a.t1 = b.t1 and a.ts=b.ts;
sql explain analyze verbose true select a.ts from sta a ,sta b where a.ts=b.ts and a.col1 + 1 = b.col1;
sql explain analyze verbose true select b.col1 from sta a ,sta b where a.ts=b.ts and a.col1 + 1 = b.col1 order by a.ts;
sql explain analyze verbose true select b.col1 from sta a join sta b join sta c where a.ts=b.ts and b.ts = c.ts order by a.ts;
diff --git a/tests/script/tsim/scalar/in.sim b/tests/script/tsim/scalar/in.sim
index a2164675f0..0ffe6f5100 100644
--- a/tests/script/tsim/scalar/in.sim
+++ b/tests/script/tsim/scalar/in.sim
@@ -44,7 +44,7 @@ if $data20 != @ Time Range: [-9223372036854775808, 9223372036854775807]@ th
endi
sql select * from tb1 where fbool in (0, 3);
-if $rows != 5 then
+if $rows != 3 then
return -1
endi
@@ -69,7 +69,7 @@ if $rows != 10 then
endi
sql select * from st1 where tbool in (0, 3);
-if $rows != 15 then
+if $rows != 5 then
return -1
endi
diff --git a/tests/script/tsim/stream/streamInterpDelete0.sim b/tests/script/tsim/stream/streamInterpDelete0.sim
index 21bac13e4a..440d7ce413 100644
--- a/tests/script/tsim/stream/streamInterpDelete0.sim
+++ b/tests/script/tsim/stream/streamInterpDelete0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpDelete1.sim b/tests/script/tsim/stream/streamInterpDelete1.sim
index 162da175e8..9413cf8918 100644
--- a/tests/script/tsim/stream/streamInterpDelete1.sim
+++ b/tests/script/tsim/stream/streamInterpDelete1.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpDelete2.sim b/tests/script/tsim/stream/streamInterpDelete2.sim
index be27dcda49..fb53678eff 100644
--- a/tests/script/tsim/stream/streamInterpDelete2.sim
+++ b/tests/script/tsim/stream/streamInterpDelete2.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpError.sim b/tests/script/tsim/stream/streamInterpError.sim
index 53a92df772..f0f4e80ade 100644
--- a/tests/script/tsim/stream/streamInterpError.sim
+++ b/tests/script/tsim/stream/streamInterpError.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step2
sql create database test2 vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpHistory.sim b/tests/script/tsim/stream/streamInterpHistory.sim
index b9685ebf05..9737e7d155 100644
--- a/tests/script/tsim/stream/streamInterpHistory.sim
+++ b/tests/script/tsim/stream/streamInterpHistory.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpLarge.sim b/tests/script/tsim/stream/streamInterpLarge.sim
index 85203d2d9e..2626f49b6a 100644
--- a/tests/script/tsim/stream/streamInterpLarge.sim
+++ b/tests/script/tsim/stream/streamInterpLarge.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpLinear0.sim b/tests/script/tsim/stream/streamInterpLinear0.sim
index 7d4b28d545..c52540895b 100644
--- a/tests/script/tsim/stream/streamInterpLinear0.sim
+++ b/tests/script/tsim/stream/streamInterpLinear0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpNext0.sim b/tests/script/tsim/stream/streamInterpNext0.sim
index abdbeda634..4395031aec 100644
--- a/tests/script/tsim/stream/streamInterpNext0.sim
+++ b/tests/script/tsim/stream/streamInterpNext0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpOther.sim b/tests/script/tsim/stream/streamInterpOther.sim
index 8553e67ec8..4572bfca56 100644
--- a/tests/script/tsim/stream/streamInterpOther.sim
+++ b/tests/script/tsim/stream/streamInterpOther.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 4;
diff --git a/tests/script/tsim/stream/streamInterpPartitionBy0.sim b/tests/script/tsim/stream/streamInterpPartitionBy0.sim
index 6b222de228..543bb48a1c 100644
--- a/tests/script/tsim/stream/streamInterpPartitionBy0.sim
+++ b/tests/script/tsim/stream/streamInterpPartitionBy0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step prev
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpPartitionBy1.sim b/tests/script/tsim/stream/streamInterpPartitionBy1.sim
index ecb5e0ee62..c8138ac05f 100644
--- a/tests/script/tsim/stream/streamInterpPartitionBy1.sim
+++ b/tests/script/tsim/stream/streamInterpPartitionBy1.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step NULL
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpPrimaryKey0.sim b/tests/script/tsim/stream/streamInterpPrimaryKey0.sim
index 9edddff6db..1bbc2a9b5d 100644
--- a/tests/script/tsim/stream/streamInterpPrimaryKey0.sim
+++ b/tests/script/tsim/stream/streamInterpPrimaryKey0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpPrimaryKey1.sim b/tests/script/tsim/stream/streamInterpPrimaryKey1.sim
index 04a1f299be..0db33c9767 100644
--- a/tests/script/tsim/stream/streamInterpPrimaryKey1.sim
+++ b/tests/script/tsim/stream/streamInterpPrimaryKey1.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpPrimaryKey2.sim b/tests/script/tsim/stream/streamInterpPrimaryKey2.sim
index f06e1ecd03..0574a1ceec 100644
--- a/tests/script/tsim/stream/streamInterpPrimaryKey2.sim
+++ b/tests/script/tsim/stream/streamInterpPrimaryKey2.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpPrimaryKey3.sim b/tests/script/tsim/stream/streamInterpPrimaryKey3.sim
index 725cf8d850..23cb0a58e6 100644
--- a/tests/script/tsim/stream/streamInterpPrimaryKey3.sim
+++ b/tests/script/tsim/stream/streamInterpPrimaryKey3.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpUpdate.sim b/tests/script/tsim/stream/streamInterpUpdate.sim
index 59a188c2a6..394ac1a341 100644
--- a/tests/script/tsim/stream/streamInterpUpdate.sim
+++ b/tests/script/tsim/stream/streamInterpUpdate.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpUpdate1.sim b/tests/script/tsim/stream/streamInterpUpdate1.sim
index 45f16af35d..3987afa21e 100644
--- a/tests/script/tsim/stream/streamInterpUpdate1.sim
+++ b/tests/script/tsim/stream/streamInterpUpdate1.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpUpdate2.sim b/tests/script/tsim/stream/streamInterpUpdate2.sim
index 2a71474dd7..cde5b589e8 100644
--- a/tests/script/tsim/stream/streamInterpUpdate2.sim
+++ b/tests/script/tsim/stream/streamInterpUpdate2.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/stream/streamInterpValue0.sim b/tests/script/tsim/stream/streamInterpValue0.sim
index bce7f0ece6..2cbf61f4bd 100644
--- a/tests/script/tsim/stream/streamInterpValue0.sim
+++ b/tests/script/tsim/stream/streamInterpValue0.sim
@@ -4,6 +4,8 @@ system sh/exec.sh -n dnode1 -s start
sleep 50
sql connect
+sql alter local 'streamCoverage' '1';
+
print step1
print =============== create database
sql create database test vgroups 1;
diff --git a/tests/script/tsim/user/password.sim b/tests/script/tsim/user/password.sim
index 729097e7e1..7d1eff2f0b 100644
--- a/tests/script/tsim/user/password.sim
+++ b/tests/script/tsim/user/password.sim
@@ -271,5 +271,16 @@ sql create user u25 pass 'taosdata1~'
sql create user u26 pass 'taosdata1,'
sql create user u27 pass 'taosdata1.'
-return
+sql CREATE USER `_xTest1` PASS '2729c41a99b2c5222aa7dd9fc1ce3de7' SYSINFO 1 CREATEDB 0 IS_IMPORT 1 HOST '127.0.0.1';
+sql_error CREATE USER `_xTest2` PASS '2729c41a99b2c5222aa7dd9fc1ce3de7' SYSINFO 1 CREATEDB 0 IS_IMPORT 0 HOST '127.0.0.1';
+sql CREATE USER `_xTest3` PASS '2729c41' SYSINFO 1 CREATEDB 0 IS_IMPORT 1 HOST '127.0.0.1';
+sql_error CREATE USER `_xTest4` PASS '2729c417' SYSINFO 1 CREATEDB 0 IS_IMPORT 0 HOST '127.0.0.1';
+sql CREATE USER `_xTest5` PASS '2xF' SYSINFO 1 CREATEDB 0 IS_IMPORT 1 HOST '127.0.0.1';
+sql_error CREATE USER `_xTest6` PASS '2xF' SYSINFO 1 CREATEDB 0 IS_IMPORT 0 HOST '127.0.0.1';
+
+
+sql_error alter USER `_xTest1` PASS '2729c41a99b2c5222aa7dd9fc1ce3de7';
+sql_error alter USER `_xTest1` PASS '2729c417';
+sql_error alter USER `_xTest1` PASS '2xF';
+
system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
diff --git a/tests/setup-lcov.sh b/tests/setup-lcov.sh
new file mode 100644
index 0000000000..0d1861fc92
--- /dev/null
+++ b/tests/setup-lcov.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+
+function usage() {
+ echo "Usage: $0 -v "
+ echo "Example: $0 -v 1.14"
+}
+
+function download_lcov() {
+ local version=$1
+ local url="https://github.com/linux-test-project/lcov/releases/download/v${version}/lcov-${version}.tar.gz"
+ echo "Downloading lcov version ${version} from ${url}..."
+ curl -LO ${url}
+ tar -xzf lcov-${version}.tar.gz
+ echo "lcov version ${version} downloaded and extracted."
+}
+
+function install_lcov() {
+ echo -e "\nInstalling..."
+ local version=$1
+ cd lcov-${version}
+ sudo make uninstall && sudo make install
+ cd ..
+ echo "lcov version ${version} installed."
+}
+
+function verify_lcov() {
+ echo -e "\nVerify installation..."
+ lcov --version
+}
+
+function main() {
+ if [[ "$#" -ne 2 ]]; then
+ usage
+ exit 1
+ fi
+
+ while getopts "v:h" opt; do
+ case ${opt} in
+ v)
+ version=${OPTARG}
+ download_lcov ${version}
+ install_lcov ${version}
+ verify_lcov
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ done
+}
+
+main "$@"
\ No newline at end of file
diff --git a/tests/system-test/0-others/compatibility.py b/tests/system-test/0-others/compatibility.py
index 7c3eb48fe1..6a78a051ab 100644
--- a/tests/system-test/0-others/compatibility.py
+++ b/tests/system-test/0-others/compatibility.py
@@ -106,8 +106,8 @@ class TDTestCase:
my_file = Path(f"{packagePath}/{packageName}")
if not my_file.exists():
print(f"{packageName} is not exists")
- tdLog.info(f"cd {packagePath} && wget https://www.tdengine.com/assets-download/3.0/{packageName}")
- os.system(f"cd {packagePath} && wget https://www.tdengine.com/assets-download/3.0/{packageName}")
+ tdLog.info(f"cd {packagePath} && wget https://www.taosdata.com/assets-download/3.0/{packageName}")
+ os.system(f"cd {packagePath} && wget https://www.taosdata.com/assets-download/3.0/{packageName}")
else:
print(f"{packageName} has been exists")
os.system(f" cd {packagePath} && tar xvf {packageName} && cd {packageTPath} && ./install.sh -e no " )
diff --git a/tests/system-test/0-others/multilevel.py b/tests/system-test/0-others/multilevel.py
index 3ed4002fcd..971451a023 100644
--- a/tests/system-test/0-others/multilevel.py
+++ b/tests/system-test/0-others/multilevel.py
@@ -287,6 +287,55 @@ class TDTestCase:
checkFiles('/mnt/data3/vnode/*/tsdb/v*',0)
checkFiles('/mnt/data4/vnode/*/tsdb/v*',1)
+ def test_alter_disable_err_case(self):
+ tdLog.info("============== test_alter_disable_err_case test ===============")
+ tdDnodes.stop(1)
+ cfg={
+ '/mnt/data1 0 1 1' : 'dataDir',
+ '/mnt/data2 0 0 0' : 'dataDir'
+ }
+ tdSql.createDir('/mnt/data1')
+ tdSql.createDir('/mnt/data2')
+ tdDnodes.deploy(1,cfg)
+ tdDnodes.start(1)
+
+ tdSql.execute('alter dnode 1 "dataDir /mnt/data2 1"')
+ tdSql.error('alter dnode 1 "dataDir /mnt/errpath 1"')
+ tdSql.error('alter dnode 1 "dataDir /mnt/data2 3"')
+ tdSql.error('alter dnode 1 "dataDir /mnt/data2 ee"')
+
+ def test_alter_disable_case(self):
+ tdLog.info("============== test_alter_disable_case test ===============")
+ tdDnodes.stop(1)
+ cfg={
+ '/mnt/data1 0 1 1' : 'dataDir',
+ '/mnt/data2 0 0 0' : 'dataDir',
+ '/mnt/data3 0 0 0' : 'dataDir'
+ }
+ tdSql.createDir('/mnt/data1')
+ tdSql.createDir('/mnt/data2')
+ tdSql.createDir('/mnt/data3')
+ tdDnodes.deploy(1,cfg)
+ tdDnodes.start(1)
+
+ tdSql.execute('create database dbtest duration 3')
+ tdSql.execute('use dbtest')
+ tdSql.execute('create table stb (ts timestamp,c0 int) tags(t0 int)')
+ tdSql.execute('create table tb1 using stb tags(1)')
+ for i in range(1,600, 30):
+ tdSql.execute(f'insert into tb1 values(now-{i}d,10)')
+ tdSql.execute('flush database dbtest')
+
+ tdSql.execute('alter dnode 1 "dataDir /mnt/data2 1"')
+
+ tdSql.execute('create database dbtest1 duration 3')
+ tdSql.execute('use dbtest1')
+ tdSql.execute('create table stb (ts timestamp,c0 int) tags(t0 int)')
+ tdSql.execute('create table tb1 using stb tags(1)')
+ for i in range(1,600, 30):
+ tdSql.execute(f'insert into tb1 values(now-{i}d,10)')
+ tdSql.execute('flush database dbtest1')
+
def run(self):
self.basic()
self.dir_not_exist()
@@ -297,8 +346,8 @@ class TDTestCase:
self.trim_database()
self.missing_middle_level()
self.disable_create_new_file()
-
-
+ self.test_alter_disable_err_case()
+ self.test_alter_disable_case()
def stop(self):
tdSql.close()
diff --git a/tests/system-test/0-others/udfTest.py b/tests/system-test/0-others/udfTest.py
index 829a8aec27..d3efa61e04 100644
--- a/tests/system-test/0-others/udfTest.py
+++ b/tests/system-test/0-others/udfTest.py
@@ -4,6 +4,8 @@ import sys
import time
import os
import platform
+import random
+import string
from util.log import *
from util.sql import *
@@ -12,7 +14,7 @@ from util.dnodes import *
import subprocess
class TDTestCase:
-
+ updatecfgDict = {'udfdResFuncs': "udf1,udf2"}
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
@@ -652,10 +654,20 @@ class TDTestCase:
tdDnodes.start(1)
time.sleep(2)
+ def test_udfd_cmd(self):
+ tdLog.info(" test udfd -V ")
+ os.system("udfd -V")
+ tdLog.info(" test udfd -c ")
+ os.system("udfd -c")
+
+ letters = string.ascii_letters + string.digits + '\\'
+ path = ''.join(random.choice(letters) for i in range(5000))
- def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring
+ os.system(f"udfd -c {path}")
+ def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring
print(" env is ok for all ")
+ self.test_udfd_cmd()
self.prepare_udf_so()
self.prepare_data()
self.create_udf_function()
diff --git a/tests/system-test/0-others/udf_restart_taosd.py b/tests/system-test/0-others/udf_restart_taosd.py
index c99e864e71..f9a3f08bf5 100644
--- a/tests/system-test/0-others/udf_restart_taosd.py
+++ b/tests/system-test/0-others/udf_restart_taosd.py
@@ -11,7 +11,7 @@ from util.dnodes import *
import subprocess
class TDTestCase:
-
+ updatecfgDict = {'udfdResFuncs': "udf1,udf2"}
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
diff --git a/tests/system-test/1-insert/boundary.py b/tests/system-test/1-insert/boundary.py
index 25782fd0c3..129b0f275c 100644
--- a/tests/system-test/1-insert/boundary.py
+++ b/tests/system-test/1-insert/boundary.py
@@ -130,6 +130,8 @@ class TDTestCase:
tdSql.error(f'create user {username} pass "test123@#$"')
if "Name or password too long" in tdSql.error_info:
tdLog.info("error info is true!")
+ elif "Password too short or empty" in tdSql.error_info:
+ tdLog.info("error info is true!")
else:
tdLog.exit("error info is not true")
@@ -146,6 +148,10 @@ class TDTestCase:
tdSql.error(f'create user {username} pass "{password}@1"')
if "Invalid password format" in tdSql.error_info:
tdLog.info("error info is true!")
+ elif "Name or password too long" in tdSql.error_info:
+ tdLog.info("error info is true!")
+ elif "Password too short or empty" in tdSql.error_info:
+ tdLog.info("error info is true!")
else:
tdLog.exit("error info is not true")
def sql_length_check(self):
diff --git a/tests/system-test/2-query/ts-5761-scalemode.py b/tests/system-test/2-query/ts-5761-scalemode.py
new file mode 100644
index 0000000000..0eeabd3af6
--- /dev/null
+++ b/tests/system-test/2-query/ts-5761-scalemode.py
@@ -0,0 +1,150 @@
+import taos
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import *
+from util.common import *
+
+class TDTestCase:
+ updatecfgDict = {'filterScalarMode':1}
+ def init(self, conn, logSql, replicaVar=1):
+ self.replicaVar = int(replicaVar)
+ tdLog.debug(f"start to excute {__file__}")
+ tdSql.init(conn.cursor(), True)
+ self.dbname = 'db'
+ self.stbname = 'st'
+
+ def prepareData(self):
+ # db
+ tdSql.execute(f"create database db;")
+ tdSql.execute(f"use db")
+
+ # super tableUNSIGNED
+ tdSql.execute("CREATE TABLE st( time TIMESTAMP, c1 BIGINT, c2 smallint, c3 double, c4 int UNSIGNED, c5 bool, c6 binary(32), c7 nchar(32)) tags(t1 binary(32), t2 nchar(32))")
+ tdSql.execute("create table t1 using st tags('1', '1.7')")
+ tdSql.execute("create table t2 using st tags('0', '')")
+ tdSql.execute("create table t3 using st tags('1', 'er')")
+
+ # create index for all tags
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000000, 1, 1, 1, 1, 1, '1', '1.7')")
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000001, 0, 0, 1.7, 0, 0, '0', '')")
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+ tdSql.execute("INSERT INTO t2 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+ tdSql.execute("INSERT INTO t3 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+
+ tdSql.execute("CREATE TABLE stt( time TIMESTAMP, c1 BIGINT, c2 timestamp, c3 int, c4 int UNSIGNED, c5 bool, c6 binary(32), c7 nchar(32)) tags(t1 binary(32), t2 nchar(32))")
+ tdSql.execute("create table tt1 using stt tags('1', '1.7')")
+
+ # create index for all tags
+ tdSql.execute("INSERT INTO tt1 VALUES (1641024000000, 9223372036854775807, 1641024000000, 1, 1, 1, '1', '1.7')")
+
+ def check(self):
+ tdSql.query(f"SELECT * FROM tt1 WHERE c1 in (1.7, 9223372036854775803, '')")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM tt1 WHERE c1 = 9223372036854775803")
+ tdSql.checkRows(0)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 = 1.7")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 in (1.7, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 not in (1.7, 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 1")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (1, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (1, 2)")
+ tdSql.checkRows(1)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 0")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (0, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (0, 2, 'sef')")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = 1.7")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in (1.7, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in (1.7, 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = 0")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in (0, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in (0, 2)")
+ tdSql.checkRows(1)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = ''")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in ('', 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in ('', 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM st WHERE t2 in ('', 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t2 not in ('', 2)")
+ tdSql.checkRows(4)
+
+ tdSql.query(f"SELECT * FROM st WHERE t1 in ('d343', 0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t1 in (0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t1 not in (0, 2)")
+ tdSql.checkRows(4)
+
+ def run(self):
+ self.prepareData()
+ self.check()
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success(f"{__file__} successfully executed")
+
+
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
\ No newline at end of file
diff --git a/tests/system-test/2-query/ts-5761.py b/tests/system-test/2-query/ts-5761.py
new file mode 100644
index 0000000000..5c8430d856
--- /dev/null
+++ b/tests/system-test/2-query/ts-5761.py
@@ -0,0 +1,149 @@
+import taos
+
+from util.log import *
+from util.sql import *
+from util.cases import *
+from util.dnodes import *
+from util.common import *
+
+class TDTestCase:
+ def init(self, conn, logSql, replicaVar=1):
+ self.replicaVar = int(replicaVar)
+ tdLog.debug(f"start to excute {__file__}")
+ tdSql.init(conn.cursor(), True)
+ self.dbname = 'db'
+ self.stbname = 'st'
+
+ def prepareData(self):
+ # db
+ tdSql.execute(f"create database db;")
+ tdSql.execute(f"use db")
+
+ # super tableUNSIGNED
+ tdSql.execute("CREATE TABLE st( time TIMESTAMP, c1 BIGINT, c2 smallint, c3 double, c4 int UNSIGNED, c5 bool, c6 binary(32), c7 nchar(32)) tags(t1 binary(32), t2 nchar(32))")
+ tdSql.execute("create table t1 using st tags('1', '1.7')")
+ tdSql.execute("create table t2 using st tags('0', '')")
+ tdSql.execute("create table t3 using st tags('1', 'er')")
+
+ # create index for all tags
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000000, 1, 1, 1, 1, 1, '1', '1.7')")
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000001, 0, 0, 1.7, 0, 0, '0', '')")
+ tdSql.execute("INSERT INTO t1 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+ tdSql.execute("INSERT INTO t2 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+ tdSql.execute("INSERT INTO t3 VALUES (1641024000002, 1, 1, 1, 1, 1, '1', 'er')")
+
+ tdSql.execute("CREATE TABLE stt( time TIMESTAMP, c1 BIGINT, c2 timestamp, c3 int, c4 int UNSIGNED, c5 bool, c6 binary(32), c7 nchar(32)) tags(t1 binary(32), t2 nchar(32))")
+ tdSql.execute("create table tt1 using stt tags('1', '1.7')")
+
+ # create index for all tags
+ tdSql.execute("INSERT INTO tt1 VALUES (1641024000000, 9223372036854775807, 1641024000000, 1, 1, 1, '1', '1.7')")
+
+ def check(self):
+ tdSql.query(f"SELECT * FROM tt1 WHERE c1 in (1.7, 9223372036854775803, '')")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM tt1 WHERE c1 = 9223372036854775803")
+ tdSql.checkRows(0)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c1 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c2 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 = 1.7")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 in (1.7, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c3 not in (1.7, 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c4 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c5 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 1.7")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (1.7, 2)")
+ tdSql.checkRows(0)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (1.7, 2)")
+ tdSql.checkRows(3)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 1")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (1, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (1, 2)")
+ tdSql.checkRows(1)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 = 0")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 in (0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (0, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c6 not in (0, 2, 'sef')")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = 1.7")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in (1.7, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in (1.7, 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = 0")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in (0, 2)")
+ tdSql.checkRows(2)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in (0, 2)")
+ tdSql.checkRows(1)
+
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 = ''")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 in ('', 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM t1 WHERE c7 not in ('', 2)")
+ tdSql.checkRows(2)
+
+ tdSql.query(f"SELECT * FROM st WHERE t2 in ('', 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t2 not in ('', 2)")
+ tdSql.checkRows(4)
+
+ tdSql.query(f"SELECT * FROM st WHERE t1 in ('d343', 0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t1 in (0, 2)")
+ tdSql.checkRows(1)
+ tdSql.query(f"SELECT * FROM st WHERE t1 not in (0, 2)")
+ tdSql.checkRows(4)
+
+ def run(self):
+ self.prepareData()
+ self.check()
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success(f"{__file__} successfully executed")
+
+
+
+tdCases.addLinux(__file__, TDTestCase())
+tdCases.addWindows(__file__, TDTestCase())
\ No newline at end of file