diff --git a/README-CN.md b/README-CN.md index 189b7a059a..a6dfefc47a 100644 --- a/README-CN.md +++ b/README-CN.md @@ -52,7 +52,7 @@ TDengine 还提供一组辅助工具软件 taosTools,目前它包含 taosBench ### Ubuntu 18.04 及以上版本 & Debian: ```bash -sudo apt-get install -y gcc cmake build-essential git libssl-dev +sudo apt-get install -y gcc cmake build-essential git libssl-dev libgflags2.2 libgflags-dev ``` #### 为 taos-tools 安装编译需要的软件 @@ -352,4 +352,4 @@ TDengine 提供了丰富的应用程序开发接口,其中包括 C/C++、Java # 加入技术交流群 -TDengine 官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine",加小 T 为好友,即可入群。 +TDengine 官方社群「物联网大数据群」对外开放,欢迎您加入讨论。搜索微信号 "tdengine1",加小 T 为好友,即可入群。 diff --git a/README.md b/README.md index 5d4bb309a4..a088404c85 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ To build TDengine, use [CMake](https://cmake.org/) 3.0.2 or higher versions in t ### Ubuntu 18.04 and above or Debian ```bash -sudo apt-get install -y gcc cmake build-essential git libssl-dev +sudo apt-get install -y gcc cmake build-essential git libssl-dev libgflags2.2 libgflags-dev ``` #### Install build dependencies for taosTools diff --git a/cmake/cmake.define b/cmake/cmake.define index f55a9bdabc..1500858d9f 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) -set(CMAKE_VERBOSE_MAKEFILE OFF) +set(CMAKE_VERBOSE_MAKEFILE ON) set(TD_BUILD_TAOSA_INTERNAL FALSE) #set output directory diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 185ebae51e..536d4eae8e 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -242,6 +242,10 @@ if(${BUILD_WITH_ROCKSDB}) option(WITH_PERF_CONTEXT "" OFF) endif(${TD_DARWIN}) + if(${TD_WINDOWS}) + option(WITH_JNI "" ON) + endif(${TD_WINDOWS}) + if(${TD_WINDOWS}) option(WITH_MD_LIBRARY "build with MD" OFF) set(SYSTEM_LIBS ${SYSTEM_LIBS} shlwapi.lib rpcrt4.lib) diff --git a/contrib/test/rocksdb/CMakeLists.txt b/contrib/test/rocksdb/CMakeLists.txt index b500e0a661..5ae1b0395b 100644 --- a/contrib/test/rocksdb/CMakeLists.txt +++ b/contrib/test/rocksdb/CMakeLists.txt @@ -1,6 +1,8 @@ +message("contrib test/rocksdb:" ${BUILD_DEPENDENCY_TESTS}) + add_executable(rocksdbTest "") target_sources(rocksdbTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/main.c" ) -target_link_libraries(rocksdbTest rocksdb) \ No newline at end of file +target_link_libraries(rocksdbTest rocksdb) diff --git a/contrib/test/rocksdb/main.c b/contrib/test/rocksdb/main.c index 33652386d7..bda717f953 100644 --- a/contrib/test/rocksdb/main.c +++ b/contrib/test/rocksdb/main.c @@ -116,9 +116,20 @@ int main(int argc, char const *argv[]) { rocksdb_options_set_create_if_missing(opt, 1); rocksdb_options_set_create_missing_column_families(opt, 1); - const char *cfName[] = {"default", "cf1"}; - int len = sizeof(cfName) / sizeof(cfName[0]); + // Read + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + // rocksdb_readoptions_set_snapshot(readoptions, rocksdb_create_snapshot(db)); + int len = 1; + char buf[256] = {0}; + size_t vallen = 0; + char *val = rocksdb_get(db, readoptions, "key", 3, &vallen, &err); + snprintf(buf, vallen + 5, "val:%s", val); + printf("%ld %ld %s\n", strlen(val), vallen, buf); + char **cfName = calloc(len, sizeof(char *)); + for (int i = 0; i < len; i++) { + cfName[i] = "test"; + } const rocksdb_options_t **cfOpt = malloc(len * sizeof(rocksdb_options_t *)); for (int i = 0; i < len; i++) { cfOpt[i] = rocksdb_options_create_copy(opt); @@ -129,7 +140,7 @@ int main(int argc, char const *argv[]) { } rocksdb_column_family_handle_t **cfHandle = malloc(len * sizeof(rocksdb_column_family_handle_t *)); - db = rocksdb_open_column_families(opt, path, len, cfName, cfOpt, cfHandle, &err); + db = rocksdb_open_column_families(opt, path, len, (const char *const *)cfName, cfOpt, cfHandle, &err); { rocksdb_readoptions_t *rOpt = rocksdb_readoptions_create(); @@ -302,4 +313,4 @@ int main(int argc, char const *argv[]) { // rocksdb_close(db); return 0; -} \ No newline at end of file +} diff --git a/docs/en/02-intro/index.md b/docs/en/02-intro/index.md index 79d170eeb9..9324ca9f7e 100644 --- a/docs/en/02-intro/index.md +++ b/docs/en/02-intro/index.md @@ -44,7 +44,7 @@ For more details on features, please read through the entire documentation. ## Competitive Advantages -By making full use of [characteristics of time series data](https://tdengine.com/tsdb/characteristics-of-time-series-data/), TDengine differentiates itself from other [time series databases](https://tdengine.com/tsdb), with the following advantages. +By making full use of [characteristics of time series data](https://tdengine.com/tsdb/characteristics-of-time-series-data/), TDengine differentiates itself from other [time series databases](https://tdengine.com/tsdb/), with the following advantages. - **[High-Performance](https://tdengine.com/tdengine/high-performance-time-series-database/)**: TDengine is the only time-series database to solve the high cardinality issue to support billions of data collection points while out performing other time-series databases for data ingestion, querying and data compression. @@ -123,13 +123,12 @@ As a high-performance, scalable and SQL supported time-series database, TDengine ## Comparison with other databases -- [Writing Performance Comparison of TDengine and InfluxDB ](https://tdengine.com/performance-comparison-of-tdengine-and-influxdb/) -- [Query Performance Comparison of TDengine and InfluxDB](https://tdengine.com/query-performance-comparison-test-report-tdengine-vs-influxdb/) -- [TDengine vs OpenTSDB](https://tdengine.com/performance-tdengine-vs-opentsdb/) -- [TDengine vs Cassandra](https://tdengine.com/performance-tdengine-vs-cassandra/) -- [TDengine vs InfluxDB](https://tdengine.com/performance-tdengine-vs-influxdb/) +- [TDengine vs. InfluxDB](https://tdengine.com/tsdb-comparison-influxdb-vs-tdengine/) +- [TDengine vs. TimescaleDB](https://tdengine.com/tsdb-comparison-timescaledb-vs-tdengine/) +- [TDengine vs. OpenTSDB](https://tdengine.com/performance-tdengine-vs-opentsdb/) +- [TDengine vs. Cassandra](https://tdengine.com/performance-tdengine-vs-cassandra/) ## More readings - [Introduction to Time-Series Database](https://tdengine.com/tsdb/) - [Introduction to TDengine competitive advantages](https://tdengine.com/tdengine/) - + diff --git a/docs/en/05-get-started/01-docker.md b/docs/en/05-get-started/01-docker.md index 42e6861674..2049e1615f 100644 --- a/docs/en/05-get-started/01-docker.md +++ b/docs/en/05-get-started/01-docker.md @@ -6,7 +6,7 @@ description: This document describes how to install TDengine in a Docker contain This document describes how to install TDengine in a Docker container and perform queries and inserts. -- The easiest way to explore TDengine is through [TDengine Cloud](http://cloud.tdengine.com). +- The easiest way to explore TDengine is through [TDengine Cloud](https://cloud.tdengine.com). - To get started with TDengine in a non-containerized environment, see [Quick Install from Package](../../get-started/package). - If you want to view the source code, build TDengine yourself, or contribute to the project, see the [TDengine GitHub repository](https://github.com/taosdata/TDengine). diff --git a/docs/en/05-get-started/03-package.md b/docs/en/05-get-started/03-package.md index 3282f600ac..b47855103c 100644 --- a/docs/en/05-get-started/03-package.md +++ b/docs/en/05-get-started/03-package.md @@ -10,7 +10,7 @@ import PkgListV3 from "/components/PkgListV3"; This document describes how to install TDengine on Linux/Windows/macOS and perform queries and inserts. -- The easiest way to explore TDengine is through [TDengine Cloud](http://cloud.tdengine.com). +- The easiest way to explore TDengine is through [TDengine Cloud](https://cloud.tdengine.com). - To get started with TDengine on Docker, see [Quick Install on Docker](../../get-started/docker). - If you want to view the source code, build TDengine yourself, or contribute to the project, see the [TDengine GitHub repository](https://github.com/taosdata/TDengine). @@ -102,7 +102,7 @@ sudo apt-get install tdengine :::tip This installation method is supported only for Debian and Ubuntu. -:::: +::: @@ -208,6 +208,8 @@ The following `launchctl` commands can help you manage TDengine service: - Check TDengine Server status: `sudo launchctl list | grep taosd` +- Check TDengine Server status details: `launchctl print system/com.tdengine.taosd` + :::info - Please use `sudo` to run `launchctl` to manage _com.tdengine.taosd_ with administrator privileges. - The administrator privilege is required for service management to enhance security. diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md index 913c24f189..8cf3c463af 100644 --- a/docs/en/07-develop/01-connect/index.md +++ b/docs/en/07-develop/01-connect/index.md @@ -288,6 +288,6 @@ Prior to establishing connection, please make sure TDengine is already running a :::tip -If the connection fails, in most cases it's caused by improper configuration for FQDN or firewall. Please refer to the section "Unable to establish connection" in [FAQ](https://docs.tdengine.com/train-faq/faq). +If the connection fails, in most cases it's caused by improper configuration for FQDN or firewall. Please refer to the section "Unable to establish connection" in [FAQ](../../train-faq/faq). ::: diff --git a/docs/en/07-develop/03-insert-data/_rust_schemaless.mdx b/docs/en/07-develop/03-insert-data/_rust_schemaless.mdx new file mode 100644 index 0000000000..a26613bd15 --- /dev/null +++ b/docs/en/07-develop/03-insert-data/_rust_schemaless.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/nativeexample/examples/schemaless_insert_line.rs}} +``` diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx index 7465cc0a12..a4eb41bd7e 100644 --- a/docs/en/07-develop/07-tmq.mdx +++ b/docs/en/07-develop/07-tmq.mdx @@ -23,7 +23,7 @@ By subscribing to a topic, a consumer can obtain the latest data in that topic i To implement these features, TDengine indexes its write-ahead log (WAL) file for fast random access and provides configurable methods for replacing and retaining this file. You can define a retention period and size for this file. For information, see the CREATE DATABASE statement. In this way, the WAL file is transformed into a persistent storage engine that remembers the order in which events occur. However, note that configuring an overly long retention period for your WAL files makes database compression inefficient. TDengine then uses the WAL file instead of the time-series database as its storage engine for queries in the form of topics. TDengine reads the data from the WAL file; uses a unified query engine instance to perform filtering, transformations, and other operations; and finally pushes the data to consumers. -Tips:The default data subscription is to consume data from the wal. If the wal is deleted, the consumed data will be incomplete. At this time, you can set the parameter experimental.snapshot.enable to true to obtain all data from the tsdb, but in this way, the consumption order of the data cannot be guaranteed. Therefore, it is recommended to set a reasonable retention policy for WAL based on your consumption situation to ensure that you can subscribe all data from WAL. +Tips: Data subscription is to consume data from the wal. If some wal files are deleted according to WAL retention policy, the deleted data can't be consumed any more. So you need to set a reasonable value for parameter `WAL_RETENTION_PERIOD` or `WAL_RETENTION_SIZE` when creating the database and make sure your application consume the data in a timely way to make sure there is no data loss. This behavior is similar to Kafka and other widely used message queue products. ## Data Schema and API @@ -222,7 +222,7 @@ A database including one supertable and two subtables is created as follows: ```sql DROP DATABASE IF EXISTS tmqdb; -CREATE DATABASE tmqdb; +CREATE DATABASE tmqdb WAL_RETENTION_PERIOD 3600; CREATE TABLE tmqdb.stb (ts TIMESTAMP, c1 INT, c2 FLOAT, c3 VARCHAR(16)) TAGS(t1 INT, t3 VARCHAR(16)); CREATE TABLE tmqdb.ctb0 USING tmqdb.stb TAGS(0, "subtable0"); CREATE TABLE tmqdb.ctb1 USING tmqdb.stb TAGS(1, "subtable1"); @@ -294,7 +294,6 @@ You configure the following parameters when creating a consumer: | `auto.offset.reset` | enum | Initial offset for the consumer group | Specify `earliest`, `latest`, or `none`(default) | | `enable.auto.commit` | boolean | Commit automatically; true: user application doesn't need to explicitly commit; false: user application need to handle commit by itself | Default value is true | | `auto.commit.interval.ms` | integer | Interval for automatic commits, in milliseconds | -| `experimental.snapshot.enable` | boolean | Specify whether to consume data in TSDB; true: both data in WAL and in TSDB can be consumed; false: only data in WAL can be consumed | default value: false | | `msg.with.table.name` | boolean | Specify whether to deserialize table names from messages | default value: false The method of specifying these parameters depends on the language used: @@ -312,7 +311,6 @@ tmq_conf_set(conf, "group.id", "cgrpName"); tmq_conf_set(conf, "td.connect.user", "root"); tmq_conf_set(conf, "td.connect.pass", "taosdata"); tmq_conf_set(conf, "auto.offset.reset", "earliest"); -tmq_conf_set(conf, "experimental.snapshot.enable", "true"); tmq_conf_set(conf, "msg.with.table.name", "true"); tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); @@ -368,7 +366,6 @@ conf := &tmq.ConfigMap{ "td.connect.port": "6030", "client.id": "test_tmq_c", "enable.auto.commit": "false", - "experimental.snapshot.enable": "true", "msg.with.table.name": "true", } consumer, err := NewConsumer(conf) @@ -416,7 +413,6 @@ Python programs use the following parameters: | `enable.auto.commit` | string | Commit automatically | pecify `true` or `false` | | `auto.commit.interval.ms` | string | Interval for automatic commits, in milliseconds | | | `auto.offset.reset` | string | Initial offset for the consumer group | Specify `earliest`, `latest`, or `none`(default) | -| `experimental.snapshot.enable` | string | Specify whether it's allowed to consume messages from the WAL or from TSDB | Specify `true` or `false` | | `enable.heartbeat.background` | string | Backend heartbeat; if enabled, the consumer does not go offline even if it has not polled for a long time | Specify `true` or `false` | diff --git a/docs/en/07-develop/09-udf.md b/docs/en/07-develop/09-udf.md index dc42743b51..a7753647e3 100644 --- a/docs/en/07-develop/09-udf.md +++ b/docs/en/07-develop/09-udf.md @@ -6,10 +6,12 @@ description: This document describes how to create user-defined functions (UDF), The built-in functions of TDengine may not be sufficient for the use cases of every application. In this case, you can define custom functions for use in TDengine queries. These are known as user-defined functions (UDF). A user-defined function takes one column of data or the result of a subquery as its input. -TDengine supports user-defined functions written in C or C++. This document describes the usage of user-defined functions. - User-defined functions can be scalar functions or aggregate functions. Scalar functions, such as `abs`, `sin`, and `concat`, output a value for every row of data. Aggregate functions, such as `avg` and `max` output one value for multiple rows of data. +TDengine supports user-defined functions written in C or Python. This document describes the usage of user-defined functions. + +## Implement a UDF in C + When you create a user-defined function, you must implement standard interface functions: - For scalar functions, implement the `scalarfn` interface function. - For aggregate functions, implement the `aggfn_start`, `aggfn`, and `aggfn_finish` interface functions. @@ -17,7 +19,7 @@ When you create a user-defined function, you must implement standard interface f There are strict naming conventions for these interface functions. The names of the start, finish, init, and destroy interfaces must be _start, _finish, _init, and _destroy, respectively. Replace `scalarfn`, `aggfn`, and `udf` with the name of your user-defined function. -## Implementing a Scalar Function +### Implementing a Scalar Function in C The implementation of a scalar function is described as follows: ```c #include "taos.h" @@ -49,7 +51,7 @@ int32_t scalarfn_destroy() { ``` Replace `scalarfn` with the name of your function. -## Implementing an Aggregate Function +### Implementing an Aggregate Function in C The implementation of an aggregate function is described as follows: ```c @@ -100,7 +102,7 @@ int32_t aggfn_destroy() { ``` Replace `aggfn` with the name of your function. -## Interface Functions +### UDF Interface Definition in C There are strict naming conventions for interface functions. The names of the start, finish, init, and destroy interfaces must be _start, _finish, _init, and _destroy, respectively. Replace `scalarfn`, `aggfn`, and `udf` with the name of your user-defined function. @@ -108,8 +110,7 @@ Interface functions return a value that indicates whether the operation was succ For information about the parameters for interface functions, see Data Model -### Interfaces for Scalar Functions - +#### Scalar Interface `int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)` Replace `scalarfn` with the name of your function. This function performs scalar calculations on data blocks. You can configure a value through the parameters in the `resultColumn` structure. @@ -118,7 +119,7 @@ The parameters in the function are defined as follows: - inputDataBlock: The data block to input. - resultColumn: The column to output. The column to output. -### Interfaces for Aggregate Functions +#### Aggregate Interface `int32_t aggfn_start(SUdfInterBuf *interBuf)` @@ -126,7 +127,7 @@ The parameters in the function are defined as follows: `int32_t aggfn_finish(SUdfInterBuf* interBuf, SUdfInterBuf *result)` -Replace `aggfn` with the name of your function. In the function, aggfn_start is called to generate a result buffer. Data is then divided between multiple blocks, and aggfn is called on each block to update the result. Finally, aggfn_finish is called to generate final results from the intermediate results. The final result contains only one or zero data points. +Replace `aggfn` with the name of your function. In the function, aggfn_start is called to generate a result buffer. Data is then divided between multiple blocks, and the `aggfn` function is called on each block to update the result. Finally, aggfn_finish is called to generate the final results from the intermediate results. The final result contains only one or zero data points. The parameters in the function are defined as follows: - interBuf: The intermediate result buffer. @@ -135,15 +136,15 @@ The parameters in the function are defined as follows: - result: The final result. -### Initializing and Terminating User-Defined Functions +#### Initialization and Cleanup Interface `int32_t udf_init()` `int32_t udf_destroy()` -Replace `udf`with the name of your function. udf_init initializes the function. udf_destroy terminates the function. If it is not necessary to initialize your function, udf_init is not required. If it is not necessary to terminate your function, udf_destroy is not required. +Replace `udf` with the name of your function. udf_init initializes the function. udf_destroy terminates the function. If it is not necessary to initialize your function, udf_init is not required. If it is not necessary to terminate your function, udf_destroy is not required. -## Data Structure of User-Defined Functions +### Data Structures for UDF in C ```c typedef struct SUdfColumnMeta { int16_t type; @@ -193,7 +194,7 @@ typedef struct SUdfInterBuf { ``` The data structure is described as follows: -- The SUdfDataBlock block includes the number of rows (numOfRows) and number of columns (numCols). udfCols[i] (0 <= i <= numCols-1) indicates that each column is of type SUdfColumn. +- The SUdfDataBlock block includes the number of rows (numOfRows) and the number of columns (numCols). udfCols[i] (0 <= i <= numCols-1) indicates that each column is of type SUdfColumn. - SUdfColumn includes the definition of the data type of the column (colMeta) and the data in the column (colData). - The member definitions of SUdfColumnMeta are the same as the data type definitions in `taos.h`. - The data in SUdfColumnData can become longer. varLenCol indicates variable-length data, and fixLenCol indicates fixed-length data. @@ -201,9 +202,9 @@ The data structure is described as follows: Additional functions are defined in `taosudf.h` to make it easier to work with these structures. -## Compile UDF +### Compiling C UDF -To use your user-defined function in TDengine, first compile it to a dynamically linked library (DLL). +To use your user-defined function in TDengine, first, compile it to a shared library. For example, the sample UDF `bit_and.c` can be compiled into a DLL as follows: @@ -213,12 +214,9 @@ gcc -g -O0 -fPIC -shared bit_and.c -o libbitand.so The generated DLL file `libbitand.so` can now be used to implement your function. Note: GCC 7.5 or later is required. -## Manage and Use User-Defined Functions -After compiling your function into a DLL, you add it to TDengine. For more information, see [User-Defined Functions](../12-taos-sql/26-udf.md). +### UDF Sample Code in C -## Sample Code - -### Sample scalar function: [bit_and](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/bit_and.c) +#### Scalar function: [bit_and](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/bit_and.c) The bit_and function implements bitwise addition for multiple columns. If there is only one column, the column is returned. The bit_and function ignores null values. @@ -231,7 +229,7 @@ The bit_and function implements bitwise addition for multiple columns. If there -### Sample aggregate function: [l2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/l2norm.c) +#### Aggregate function 1: [l2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/l2norm.c) The l2norm function finds the second-order norm for all data in the input column. This squares the values, takes a cumulative sum, and finds the square root. @@ -243,3 +241,151 @@ The l2norm function finds the second-order norm for all data in the input column ``` + +#### Aggregate function 2: [max_vol](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/max_vol.c) + +The max_vol function returns a string concatenating the deviceId column, the row number and column number of the maximum voltage and the maximum voltage given several voltage columns as input. + +Create Table: +```bash +create table battery(ts timestamp, vol1 float, vol2 float, vol3 float, deviceId varchar(16)); +``` +Create the UDF: +```bash +create aggregate function max_vol as '/root/udf/libmaxvol.so' outputtype binary(64) bufsize 10240 language 'C'; +``` +Use the UDF in the query: +```bash +select max_vol(vol1,vol2,vol3,deviceid) from battery; +``` + +
+max_vol.c + +```c +{{#include tests/script/sh/max_vol.c}} +``` + +
+ +## Implement a UDF in Python + +Implement the specified interface functions when implementing a UDF in Python. +- implement `process` function for the scalar UDF。 +- implement `start`, `reduce`, `finish` for the aggregate UDF。 +- implement `init` for initialization and `destroy` for termination。 + +### Implement a Scalar UDF in Python + +The implementation of a scalar UDF is described as follows: + +```Python +def init(): + # initialization +def destroy(): + # destroy +def process(input: datablock) -> tuple[output_type]: + # process input datablock, + # datablock.data(row, col) is to access the python object in location(row,col) + # return tuple object consisted of object of type outputtype +``` + +### Implement an Aggregate UDF in Python + +The implementation of an aggregate function is described as follows: + +```Python +def init(): + #initialization +def destroy(): + #destroy +def start() -> bytes: + #return serialize(init_state) +def reduce(inputs: datablock, buf: bytes) -> bytes + # deserialize buf to state + # reduce the inputs and state into new_state. + # use inputs.data(i,j) to access python ojbect of location(i,j) + # serialize new_state into new_state_bytes + return new_state_bytes +def finish(buf: bytes) -> output_type: + #return obj of type outputtype +``` + +### Python UDF Interface Definition + +#### Scalar interface +```Python +def process(input: datablock) -> tuple[output_type]: +``` +- `input` is a data block two-dimension matrix-like object, of which method `data(row, col)` returns the Python object located at location (`row`, `col`) +- return a Python tuple object, of which each item is a Python object of type `output_type` + +#### Aggregate Interface +```Python +def start() -> bytes: +def reduce(input: datablock, buf: bytes) -> bytes +def finish(buf: bytes) -> output_type: +``` + +- first `start()` is called to return the initial result in type `bytes` +- then the input data are divided into multiple data blocks and for each block `input`, `reduce` is called with the data block `input` and the current result `buf` bytes and generates a new intermediate result buffer. +- finally, the `finish` function is called on the intermediate result `buf` and outputs 0 or 1 data of type `output_type` + + +#### Initialization and Cleanup Interface +```Python +def init() +def destroy() +``` +Implement `init` for initialization and `destroy` for termination. + +### Data Mapping between TDengine SQL and Python UDF + +The following table describes the mapping between TDengine SQL data type and Python UDF Data Type. The `NULL` value of all TDengine SQL types is mapped to the `None` value in Python. + +| **TDengine SQL Data Type** | **Python Data Type** | +| :-----------------------: | ------------ | +|TINYINT / SMALLINT / INT / BIGINT | int | +|TINYINT UNSIGNED / SMALLINT UNSIGNED / INT UNSIGNED / BIGINT UNSIGNED | int | +|FLOAT / DOUBLE | float | +|BOOL | bool | +|BINARY / VARCHAR / NCHAR | bytes| +|TIMESTAMP | int | +|JSON and other types | Not Supported | + +### Installing Python UDF +1. Install Python package `taospyudf` that executes Python UDF +```bash +sudo pip install taospyudf +ldconfig +``` +2. If PYTHONPATH is needed to find Python packages when the Python UDF executes, include the PYTHONPATH contents into the udfdLdLibPath variable of the taos.cfg configuration file + +### Python UDF Sample Code +#### Scalar Function [pybitand](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pybitand.py) + +The `pybitand` function implements bitwise addition for multiple columns. If there is only one column, the column is returned. The `pybitand` function ignores null values. + +
+pybitand.py + +```Python +{{#include tests/script/sh/pybitand.py}} +``` + +
+ +#### Aggregate Function [pyl2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pyl2norm.py) + +The `pyl2norm` function finds the second-order norm for all data in the input column. This squares the values, takes a cumulative sum, and finds the square root. +
+pyl2norm.py + +```c +{{#include tests/script/sh/pyl2norm.py}} +``` + +
+ +## Manage and Use UDF +You need to add UDF to TDengine before using it in SQL queries. For more information about how to manage UDF and how to invoke UDF, please see [Manage and Use UDF](../12-taos-sql/26-udf.md). diff --git a/docs/en/12-taos-sql/02-database.md b/docs/en/12-taos-sql/02-database.md index ec007d6830..8c579622c9 100644 --- a/docs/en/12-taos-sql/02-database.md +++ b/docs/en/12-taos-sql/02-database.md @@ -72,8 +72,8 @@ database_option: { - 0: The database can contain multiple supertables. - 1: The database can contain only one supertable. - STT_TRIGGER: specifies the number of file merges triggered by flushed files. The default is 8, ranging from 1 to 16. For high-frequency scenarios with few tables, it is recommended to use the default configuration or a smaller value for this parameter; For multi-table low-frequency scenarios, it is recommended to configure this parameter with a larger value. -- TABLE_PREFIX:The prefix length in the table name that is ignored when distributing table to vnode based on table name. -- TABLE_SUFFIX:The suffix length in the table name that is ignored when distributing table to vnode based on table name. +- TABLE_PREFIX: The prefix in the table name that is ignored when distributing a table to a vgroup when it's a positive number, or only the prefix is used when distributing a table to a vgroup, the default value is 0; For example, if the table name v30001, then "0001" is used if TSDB_PREFIX is set to 2 but "v3" is used if TSDB_PREFIX is set to -2; It can help you to control the distribution of tables. +- TABLE_SUFFIX:The suffix in the table name that is ignored when distributing a table to a vgroup when it's a positive number, or only the suffix is used when distributing a table to a vgroup, the default value is 0; For example, if the table name v30001, then "v300" is used if TSDB_SUFFIX is set to 2 but "01" is used if TSDB_SUFFIX is set to -2; It can help you to control the distribution of tables. - TSDB_PAGESIZE: The page size of the data storage engine in a vnode. The unit is KB. The default is 4 KB. The range is 1 to 16384, that is, 1 KB to 16 MB. - WAL_RETENTION_PERIOD: specifies the maximum time of which WAL files are to be kept for consumption. This parameter is used for data subscription. Enter a time in seconds. The default value 0. A value of 0 indicates that WAL files are not required to keep for consumption. Alter it with a proper value at first to create topics. - WAL_RETENTION_SIZE: specifies the maximum total size of which WAL files are to be kept for consumption. This parameter is used for data subscription. Enter a size in KB. The default value is 0. A value of 0 indicates that the total size of WAL files to keep for consumption has no upper limit. diff --git a/docs/en/12-taos-sql/04-stable.md b/docs/en/12-taos-sql/04-stable.md index a1d103eaf0..3a4d6cc590 100644 --- a/docs/en/12-taos-sql/04-stable.md +++ b/docs/en/12-taos-sql/04-stable.md @@ -33,7 +33,7 @@ column_definition: SHOW STABLES [LIKE tb_name_wildcard]; ``` -The preceding SQL statement shows all supertables in the current TDengine database, including the name, creation time, number of columns, number of tags, and number of subtables for each supertable. +The preceding SQL statement shows all supertables in the current TDengine database. ### View the CREATE Statement for a Supertable diff --git a/docs/en/12-taos-sql/06-select.md b/docs/en/12-taos-sql/06-select.md index de7294f7a9..070fd41653 100644 --- a/docs/en/12-taos-sql/06-select.md +++ b/docs/en/12-taos-sql/06-select.md @@ -55,7 +55,7 @@ window_clause: { | INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)] interp_clause: - RANGE(ts_val, ts_val), EVERY(every_val), FILL(fill_mod_and_val) + RANGE(ts_val, ts_val) EVERY(every_val) FILL(fill_mod_and_val) partition_by_clause: PARTITION BY expr [, expr] ... diff --git a/docs/en/12-taos-sql/07-tag-index.md b/docs/en/12-taos-sql/07-tag-index.md index cb2a61d3e8..af1d0a352e 100644 --- a/docs/en/12-taos-sql/07-tag-index.md +++ b/docs/en/12-taos-sql/07-tag-index.md @@ -6,7 +6,7 @@ description: Use Tag Index to Improve Query Performance ## Introduction -Prior to TDengine 3.0.3.0 (excluded),only one index is created by default on the first tag of each super talbe, but it's not allowed to dynamically create index on any other tags. From version 3.0.30, you can dynamically create index on any tag of any type. The index created automatically by TDengine is still valid. Query performance can benefit from indexes if you use properly. +Prior to TDengine 3.0.3.0 (excluded),only one index is created by default on the first tag of each super table, but it's not allowed to dynamically create index on any other tags. From version 3.0.30, you can dynamically create index on any tag of any type. The index created automatically by TDengine is still valid. Query performance can benefit from indexes if you use properly. ## Syntax @@ -48,4 +48,4 @@ You can also add filter conditions to limit the results. 6. You can' create index on a normal table or a child table. -7. If the unique values of a tag column are too few, it's better not to create index on such tag columns, the benefit would be very small. \ No newline at end of file +7. If the unique values of a tag column are too few, it's better not to create index on such tag columns, the benefit would be very small. diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index 5c1a833e05..5c0ad8a71d 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -5,9 +5,9 @@ description: This document describes the standard SQL functions available in TDe toc_max_heading_level: 4 --- -## Single Row Functions +## Scalar Functions -Single row functions return a result for each row. +Scalar functions return one result for each row. ### Mathematical Functions @@ -886,7 +886,7 @@ INTERP(expr) - The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1 <= timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified. - The number of rows in the result set of `INTERP` is determined by the parameter `EVERY(time_unit)`. Starting from timestamp1, one interpolation is performed for every time interval specified `time_unit` parameter. The parameter `time_unit` must be an integer, with no quotes, with a time unit of: a(millisecond)), s(second), m(minute), h(hour), d(day), or w(week). For example, `EVERY(500a)` will interpolate every 500 milliseconds. - Interpolation is performed based on `FILL` parameter. For more information about FILL clause, see [FILL Clause](../distinguished/#fill-clause). -- `INTERP` can only be used to interpolate in single timeline. So it must be used with `partition by tbname` when it's used on a STable. +- `INTERP` can be applied to supertable by interpolating primary key sorted data of all its childtables. It can also be used with `partition by tbname` when applied to supertable to generate interpolation on each single timeline. - Pseudocolumn `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.2.0). - Pseudocolumn `_isfilled` can be used along with `INTERP` to indicate whether the results are original records or data points generated by interpolation algorithm(support after version 3.0.3.0). diff --git a/docs/en/12-taos-sql/14-stream.md b/docs/en/12-taos-sql/14-stream.md index b8f6c3a163..43c49c03cd 100644 --- a/docs/en/12-taos-sql/14-stream.md +++ b/docs/en/12-taos-sql/14-stream.md @@ -13,8 +13,11 @@ Because stream processing is built in to TDengine, you are no longer reliant on ```sql CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name SUBTABLE(expression) AS subquery stream_options: { - TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time] - WATERMARK time + TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time] + WATERMARK time + IGNORE EXPIRED [0|1] + DELETE_MARK time + FILL_HISTORY [0|1] } ``` @@ -141,3 +144,27 @@ The data in expired windows is tagged as expired. TDengine stream processing pro 2. Recalculate the data. In this method, all data in the window is reobtained from the database and recalculated. The latest results are then returned. In both of these methods, configuring the watermark is essential for obtaining accurate results (if expired data is dropped) and avoiding repeated triggers that affect system performance (if expired data is recalculated). + +## Supported functions + +All [scalar functions](../function/#scalar-functions) are available in stream processing. All [Aggregate functions](../function/#aggregate-functions) and [Selection functions](../function/#selection-functions) are available in stream processing, except the followings: + - [leastsquares](../function/#leastsquares) + - [percentile](../function/#percentile) + - [top](../function/#top) + - [bottom](../function/#bottom) + - [elapsed](../function/#elapsed) + - [interp](../function/#interp) + - [derivative](../function/#derivative) + - [irate](../function/#irate) + - [twa](../function/#twa) + - [histogram](../function/#histogram) + - [diff](../function/#diff) + - [statecount](../function/#statecount) + - [stateduration](../function/#stateduration) + - [csum](../function/#csum) + - [mavg](../function/#mavg) + - [sample](../function/#sample) + - [tail](../function/#tail) + - [unique](../function/#unique) + - [mode](../function/#mode) + diff --git a/docs/en/12-taos-sql/22-meta.md b/docs/en/12-taos-sql/22-meta.md index 81284aeaed..e63f682761 100644 --- a/docs/en/12-taos-sql/22-meta.md +++ b/docs/en/12-taos-sql/22-meta.md @@ -120,6 +120,9 @@ Provides information about user-defined functions. | 5 | create_time | TIMESTAMP | Creation time | | 6 | code_len | INT | Length of the source code | | 7 | bufsize | INT | Buffer size | +| 8 | func_language | BINARY(31) | UDF programming language | +| 9 | func_body | BINARY(16384) | UDF function body | +| 10 | func_version | INT | UDF function version. starting from 0. Increasing by 1 each time it is updated| ## INS_INDEXES diff --git a/docs/en/12-taos-sql/24-show.md b/docs/en/12-taos-sql/24-show.md index 1f340cab30..7b3da109ca 100644 --- a/docs/en/12-taos-sql/24-show.md +++ b/docs/en/12-taos-sql/24-show.md @@ -129,6 +129,14 @@ SHOW QNODES; Shows information about qnodes in the system. +## SHOW QUERIES + +```sql +SHOW QUERIES; +``` + +Shows the queries in progress in the system. + ## SHOW SCORES ```sql diff --git a/docs/en/12-taos-sql/26-udf.md b/docs/en/12-taos-sql/26-udf.md index cb64873705..c4d6d4fca4 100644 --- a/docs/en/12-taos-sql/26-udf.md +++ b/docs/en/12-taos-sql/26-udf.md @@ -7,17 +7,18 @@ description: This document describes the SQL statements related to user-defined You can create user-defined functions and import them into TDengine. ## Create UDF -SQL command can be executed on the host where the generated UDF DLL resides to load the UDF DLL into TDengine. This operation cannot be done through REST interface or web console. Once created, any client of the current TDengine can use these UDF functions in their SQL commands. UDF are stored in the management node of TDengine. The UDFs loaded in TDengine would be still available after TDengine is restarted. +SQL command can be executed on the host where the generated UDF DLL resides to load the UDF DLL into TDengine. This operation cannot be done through REST interface or web console. Once created, any client of the current TDengine can use these UDF functions in their SQL commands. UDF is stored in the management node of TDengine. The UDFs loaded in TDengine would be still available after TDengine is restarted. When creating UDF, the type of UDF, i.e. a scalar function or aggregate function must be specified. If the specified type is wrong, the SQL statements using the function would fail with errors. The input data type and output data type must be consistent with the UDF definition. - Create Scalar Function ```sql -CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type; +CREATE [OR REPLACE] FUNCTION function_name AS library_path OUTPUTTYPE output_type [LANGUAGE 'C|Python']; ``` - - - function_name: The scalar function name to be used in SQL statement which must be consistent with the UDF name and is also the name of the compiled DLL (.so file). - - library_path: The absolute path of the DLL file including the name of the shared object file (.so). The path must be quoted with single or double quotes. + - OR REPLACE: if the UDF exists, the UDF properties are modified + - function_name: The scalar function name to be used in the SQL statement + - LANGUAGE 'C|Python': the programming language of UDF. Now C or Python is supported. If this clause is omitted, C is assumed as the programming language. + - library_path: For C programming language, The absolute path of the DLL file including the name of the shared object file (.so). For Python programming language, the absolute path of the Python UDF script. The path must be quoted with single or double quotes. - output_type: The data type of the results of the UDF. For example, the following SQL statement can be used to create a UDF from `libbitand.so`. @@ -25,14 +26,20 @@ CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type; ```sql CREATE FUNCTION bit_and AS "/home/taos/udf_example/libbitand.so" OUTPUTTYPE INT; ``` + For Example, the following SQL statement can be used to modify the existing function `bit_and`. The OUTPUT type is changed to BIGINT and the programming language is changed to Python. + + ```sql + CREATE OR REPLACE FUNCTION bit_and AS "/home/taos/udf_example/bit_and.py" OUTPUTTYPE BIGINT LANGUAGE 'Python'; + ``` - Create Aggregate Function ```sql CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ]; ``` - - - function_name: The aggregate function name to be used in SQL statement which must be consistent with the udfNormalFunc name and is also the name of the compiled DLL (.so file). - - library_path: The absolute path of the DLL file including the name of the shared object file (.so). The path must be quoted with single or double quotes. + - OR REPLACE: if the UDF exists, the UDF properties are modified + - function_name: The aggregate function name to be used in the SQL statement + - LANGUAGE 'C|Python': the programming language of the UDF. Now C or Python is supported. If this clause is omitted, C is assumed as the programming language. + - library_path: For C programming language, The absolute path of the DLL file including the name of the shared object file (.so). For Python programming language, the absolute path of the Python UDF script. The path must be quoted with single or double quotes. - output_type: The output data type, the value is the literal string of the supported TDengine data type. - buffer_size: The size of the intermediate buffer in bytes. This parameter is optional. @@ -41,6 +48,11 @@ CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ ```sql CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8; ``` + For example, the following SQL statement modifies the buffer size of existing UDF `l2norm` to 64 + ```sql + CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 64; + ``` + For more information about user-defined functions, see [User-Defined Functions](/develop/udf). ## Manage UDF @@ -61,9 +73,9 @@ SHOW FUNCTIONS; ## Call UDF -The function name specified when creating UDF can be used directly in SQL statements, just like builtin functions. For example: +The function name specified when creating UDF can be used directly in SQL statements, just like built-in functions. For example: ```sql SELECT bit_and(c1,c2) FROM table; ``` -The above SQL statement invokes function X for column c1 and c2 on table. You can use query keywords like WHERE with user-defined functions. +The above SQL statement invokes function X for columns c1 and c2 on the table. You can use query keywords like WHERE with user-defined functions. diff --git a/docs/en/12-taos-sql/29-changes.md b/docs/en/12-taos-sql/29-changes.md index f4606f263f..086aee59fe 100644 --- a/docs/en/12-taos-sql/29-changes.md +++ b/docs/en/12-taos-sql/29-changes.md @@ -27,7 +27,7 @@ The following data types can be used in the schema for standard tables. | - | :------- | :-------- | :------- | | 1 | ALTER ACCOUNT | Deprecated| This Enterprise Edition-only statement has been removed. It returns the error "This statement is no longer supported." | 2 | ALTER ALL DNODES | Added | Modifies the configuration of all dnodes. -| 3 | ALTER DATABASE | Modified | Deprecated
  • QUORUM: Specified the required number of confirmations. TDengine 3.0 provides strict consistency by default and doesn't allow to change to weak consitency.
  • BLOCKS: Specified the memory blocks used by each vnode. BUFFER is now used to specify the size of the write cache pool for each vnode.
  • UPDATE: Specified whether update operations were supported. All databases now support updating data in certain columns.
  • CACHELAST: Specified how to cache the newest row of data. CACHEMODEL now replaces CACHELAST.
  • COMP: Cannot be modified.
    Added
  • CACHEMODEL: Specifies whether to cache the latest subtable data.
  • CACHESIZE: Specifies the size of the cache for the newest subtable data.
  • WAL_FSYNC_PERIOD: Replaces the FSYNC parameter.
  • WAL_LEVEL: Replaces the WAL parameter.
  • WAL_RETENTION_PERIOD: specifies the time after which WAL files are deleted. This parameter is used for data subscription.
  • WAL_RETENTION_SIZE: specifies the size at which WAL files are deleted. This parameter is used for data subscription.
    Modified
  • REPLICA: Cannot be modified.
  • KEEP: Now supports units.
+| 3 | ALTER DATABASE | Modified | Deprecated
  • QUORUM: Specified the required number of confirmations. TDengine 3.0 provides strict consistency by default and doesn't allow to change to weak consistency.
  • BLOCKS: Specified the memory blocks used by each vnode. BUFFER is now used to specify the size of the write cache pool for each vnode.
  • UPDATE: Specified whether update operations were supported. All databases now support updating data in certain columns.
  • CACHELAST: Specified how to cache the newest row of data. CACHEMODEL now replaces CACHELAST.
  • COMP: Cannot be modified.
    Added
  • CACHEMODEL: Specifies whether to cache the latest subtable data.
  • CACHESIZE: Specifies the size of the cache for the newest subtable data.
  • WAL_FSYNC_PERIOD: Replaces the FSYNC parameter.
  • WAL_LEVEL: Replaces the WAL parameter.
  • WAL_RETENTION_PERIOD: specifies the time after which WAL files are deleted. This parameter is used for data subscription.
  • WAL_RETENTION_SIZE: specifies the size at which WAL files are deleted. This parameter is used for data subscription.
    Modified
  • REPLICA: Cannot be modified.
  • KEEP: Now supports units.
| 4 | ALTER STABLE | Modified | Deprecated
  • CHANGE TAG: Modified the name of a tag. Replaced by RENAME TAG.
    Added
  • RENAME TAG: Replaces CHANGE TAG.
  • COMMENT: Specifies comments for a supertable.
| 5 | ALTER TABLE | Modified | Deprecated
  • CHANGE TAG: Modified the name of a tag. Replaced by RENAME TAG.
    Added
  • RENAME TAG: Replaces CHANGE TAG.
  • COMMENT: Specifies comments for a standard table.
  • TTL: Specifies the time-to-live for a standard table.
| 6 | ALTER USER | Modified | Deprecated
  • PRIVILEGE: Specified user permissions. Replaced by GRANT and REVOKE.
    Added
  • ENABLE: Enables or disables a user.
  • SYSINFO: Specifies whether a user can query system information.
diff --git a/docs/en/13-operation/10-monitor.md b/docs/en/13-operation/10-monitor.md index 346b874059..19107240bf 100644 --- a/docs/en/13-operation/10-monitor.md +++ b/docs/en/13-operation/10-monitor.md @@ -42,3 +42,304 @@ An existing Grafana Notification Channel can be specified with parameter `-E`, t Launch `TDinsight.sh` with the command above and restart Grafana, then open Dashboard `http://localhost:3000/d/tdinsight`. For more use cases and restrictions please refer to [TDinsight](/reference/tdinsight/). + +## log database + +The data of tdinsight dashboard is stored in `log` database (default. You can change it in taoskeeper's config file. For more infrmation, please reference to [taoskeeper document](/reference/taosKeeper)). The taoskeeper will create log database on taoskeeper startup. + +### cluster\_info table + +`cluster_info` table contains cluster information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|first\_ep|VARCHAR||first ep of cluster| +|first\_ep\_dnode\_id|INT||dnode id or first\_ep| +|version|VARCHAR||tdengine version. such as: 3.0.4.0| +|master\_uptime|FLOAT||days of master's uptime| +|monitor\_interval|INT||monitor interval in second| +|dbs\_total|INT||total number of databases in cluster| +|tbs\_total|BIGINT||total number of tables in cluster| +|stbs\_total|INT||total number of stables in cluster| +|dnodes\_total|INT||total number of dnodes in cluster| +|dnodes\_alive|INT||total number of dnodes in ready state| +|mnodes\_total|INT||total number of mnodes in cluster| +|mnodes\_alive|INT||total number of mnodes in ready state| +|vgroups\_total|INT||total number of vgroups in cluster| +|vgroups\_alive|INT||total number of vgroups in ready state| +|vnodes\_total|INT||total number of vnode in cluster| +|vnodes\_alive|INT||total number of vnode in ready state| +|connections\_total|INT||total number of connections to cluster| +|topics\_total|INT||total number of topics in cluster| +|streams\_total|INT||total number of streams in cluster| +|protocol|INT||protocol version| +|cluster\_id|NCHAR|TAG|cluster id| + +### d\_info table + +`d_info` table contains dnodes information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|status|VARCHAR||dnode status| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### m\_info table + +`m_info` table contains mnode information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|role|VARCHAR||the role of mnode. leader or follower| +|mnode\_id|INT|TAG|master node id| +|mnode\_ep|NCHAR|TAG|master node endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### dnodes\_info table + +`dnodes_info` table contains dnodes information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|uptime|FLOAT||dnode uptime| +|cpu\_engine|FLOAT||cpu usage of tdengine. read from `/proc//stat`| +|cpu\_system|FLOAT||cpu usage of server. read from `/proc/stat`| +|cpu\_cores|FLOAT||cpu cores of server| +|mem\_engine|INT||memory usage of tdengine. read from `/proc//status`| +|mem\_system|INT||available memory on the server| +|mem\_total|INT||total memory of server in `KB`| +|disk\_engine|INT||| +|disk\_used|BIGINT||usage of data dir in `bytes`| +|disk\_total|BIGINT||the capacity of data dir in `bytes`| +|net\_in|FLOAT||network throughput rate in kb/s. read from `/proc/net/dev`| +|net\_out|FLOAT||network throughput rate in kb/s. read from `/proc/net/dev`| +|io\_read|FLOAT||io throughput rate in kb/s. read from `/proc//io`| +|io\_write|FLOAT||io throughput rate in kb/s. read from `/proc//io`| +|io\_read\_disk|FLOAT||io throughput rate of disk in kb/s. read from `/proc//io`| +|io\_write\_disk|FLOAT||io throughput rate of disk in kb/s. read from `/proc//io`| +|req\_select|INT||number of select queries received per dnode| +|req\_select\_rate|FLOAT||number of select queries received per dnode divided by monitor interval.| +|req\_insert|INT||number of insert queries received per dnode| +|req\_insert\_success|INT||number of successfully insert queries received per dnode| +|req\_insert\_rate|FLOAT||number of insert queries received per dnode divided by monitor interval| +|req\_insert\_batch|INT||number of batch insertions| +|req\_insert\_batch\_success|INT||number of successful batch insertions| +|req\_insert\_batch\_rate|FLOAT||number of batch insertions divided by monitor interval| +|errors|INT||dnode errors| +|vnodes\_num|INT||number of vnodes per dnode| +|masters|INT||number of master vnodes| +|has\_mnode|INT||if the dnode has mnode| +|has\_qnode|INT||if the dnode has qnode| +|has\_snode|INT||if the dnode has snode| +|has\_bnode|INT||if the dnode has bnode| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### data\_dir table + +`data_dir` table contains data directory information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|name|NCHAR||data directory. default is `/var/lib/taos`| +|level|INT||level for multi-level storage| +|avail|BIGINT||available space for data directory| +|used|BIGINT||used space for data directory| +|total|BIGINT||total space for data directory| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### log\_dir table + +`log_dir` table contains log directory information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|name|NCHAR||log directory. default is `/var/log/taos/`| +|avail|BIGINT||available space for log directory| +|used|BIGINT||used space for data directory| +|total|BIGINT||total space for data directory| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### temp\_dir table + +`temp_dir` table contains temp dir information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|name|NCHAR||temp directory. default is `/tmp/`| +|avail|BIGINT||available space for temp directory| +|used|BIGINT||used space for temp directory| +|total|BIGINT||total space for temp directory| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### vgroups\_info table + +`vgroups_info` table contains vgroups information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|vgroup\_id|INT||vgroup id| +|database\_name|VARCHAR||database for the vgroup| +|tables\_num|BIGINT||number of tables per vgroup| +|status|VARCHAR||status| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### vnodes\_role table + +`vnodes_role` table contains vnode role information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|vnode\_role|VARCHAR||role. leader or follower| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### logs table + +`logs` table contains login information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|level|VARCHAR||log level| +|content|NCHAR||log content| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### log\_summary table + +`log_summary` table contains log summary information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|error|INT||error count| +|info|INT||info count| +|debug|INT||debug count| +|trace|INT||trace count| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### grants\_info table + +`grants_info` table contains grants information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|expire\_time|BIGINT||time until grants expire in seconds| +|timeseries\_used|BIGINT||timeseries used| +|timeseries\_total|BIGINT||total timeseries| +|dnode\_id|INT|TAG|dnode id| +|dnode\_ep|NCHAR|TAG|dnode endpoint| +|cluster\_id|NCHAR|TAG|cluster id| + +### keeper\_monitor table + +`keeper_monitor` table contains keeper monitor information records. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|ts|TIMESTAMP||timestamp| +|cpu|FLOAT||cpu usage| +|mem|FLOAT||memory usage| +|identify|NCHAR|TAG|| + +### taosadapter\_restful\_http\_request\_total table + +`taosadapter_restful_http_request_total` table contains taosadapter rest request information record. The timestamp column of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|guage|DOUBLE||metric value| +|client\_ip|NCHAR|TAG|client ip| +|endpoint|NCHAR|TAG|taosadpater endpoint| +|request\_method|NCHAR|TAG|request method| +|request\_uri|NCHAR|TAG|request uri| +|status\_code|NCHAR|TAG|status code| + +### taosadapter\_restful\_http\_request\_fail table + +`taosadapter_restful_http_request_fail` table contains taosadapter failed rest request information record. The timestamp column of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|guage|DOUBLE||metric value| +|client\_ip|NCHAR|TAG|client ip| +|endpoint|NCHAR|TAG|taosadpater endpoint| +|request\_method|NCHAR|TAG|request method| +|request\_uri|NCHAR|TAG|request uri| +|status\_code|NCHAR|TAG|status code| + +### taosadapter\_restful\_http\_request\_in\_flight table + +`taosadapter_restful_http_request_in_flight` table contains taosadapter rest request information record in real time. The timestamp column of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|guage|DOUBLE||metric value| +|endpoint|NCHAR|TAG|taosadpater endpoint| + +### taosadapter\_restful\_http\_request\_summary\_milliseconds table + +`taosadapter_restful_http_request_summary_milliseconds` table contains the summary or rest information record. The timestamp column of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|count|DOUBLE||| +|sum|DOUBLE||| +|0.5|DOUBLE||| +|0.9|DOUBLE||| +|0.99|DOUBLE||| +|0.1|DOUBLE||| +|0.2|DOUBLE||| +|endpoint|NCHAR|TAG|taosadpater endpoint| +|request\_method|NCHAR|TAG|request method| +|request\_uri|NCHAR|TAG|request uri| + +### taosadapter\_system\_mem\_percent table + +`taosadapter_system_mem_percent` table contains taosadapter memory usage information. The timestamp of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|guage|DOUBLE||metric value| +|endpoint|NCHAR|TAG|taosadpater endpoint| + +### taosadapter\_system\_cpu\_percent table + +`taosadapter_system_cpu_percent` table contains taosadapter cup usage information. The timestamp of this table is `_ts`. + +|field|type|is\_tag|comment| +|:----|:---|:-----|:------| +|\_ts|TIMESTAMP||timestamp| +|guage|DOUBLE||mertic value| +|endpoint|NCHAR|TAG|taosadpater endpoint| + diff --git a/docs/en/14-reference/03-connector/03-cpp.mdx b/docs/en/14-reference/03-connector/03-cpp.mdx index b543879b3c..014109b77e 100644 --- a/docs/en/14-reference/03-connector/03-cpp.mdx +++ b/docs/en/14-reference/03-connector/03-cpp.mdx @@ -423,6 +423,6 @@ In addition to writing data using the SQL method or the parameter binding API, w **Description** - The above seven interfaces are extension interfaces, which are mainly used to pass ttl and reqid parameters, and can be used as needed. - - Withing _raw interfaces represent data through the passed parameters lines and len. In order to solve the problem that the original interface data contains '\0' and is truncated. The totalRows pointer returns the number of parsed data rows. - - Withing _ttl interfaces can pass the ttl parameter to control the ttl expiration time of the table. - - Withing _reqid interfaces can track the entire call chain by passing the reqid parameter. + - Within _raw interfaces represent data through the passed parameters lines and len. In order to solve the problem that the original interface data contains '\0' and is truncated. The totalRows pointer returns the number of parsed data rows. + - Within _ttl interfaces can pass the ttl parameter to control the ttl expiration time of the table. + - Within _reqid interfaces can track the entire call chain by passing the reqid parameter. diff --git a/docs/en/14-reference/03-connector/04-java.mdx b/docs/en/14-reference/03-connector/04-java.mdx index fd4b4641d7..65c7bc9bc5 100644 --- a/docs/en/14-reference/03-connector/04-java.mdx +++ b/docs/en/14-reference/03-connector/04-java.mdx @@ -36,23 +36,110 @@ REST connection supports all platforms that can run Java. Please refer to [version support list](/reference/connector#version-support) +## Recent update logs + +| taos-jdbcdriver version | major changes | +| :---------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------: | +| 3.2.1 | JDBC REST connection supports schemaless/prepareStatement over WebSocket | +| 3.2.0 | This version has been deprecated | +| 3.1.0 | JDBC REST connection supports subscription over WebSocket | +| 3.0.1 - 3.0.4 | fix the resultSet data is parsed incorrectly sometimes. 3.0.1 is compiled on JDK 11, you are advised to use other version in the JDK 8 environment | +| 3.0.0 | Support for TDengine 3.0 | +| 2.0.42 | fix wasNull interface return value in WebSocket connection | +| 2.0.41 | fix decode method of username and password in REST connection | +| 2.0.39 - 2.0.40 | Add REST connection/request timeout parameters | +| 2.0.38 | JDBC REST connections add bulk pull function | +| 2.0.37 | Support json tags | +| 2.0.36 | Support schemaless writing | + +**Note**: adding `batchfetch` to the REST connection and setting it to true will enable the WebSocket connection. + +### Handling exceptions + +After an error is reported, the error message and error code can be obtained through SQLException. + +```java +try (Statement statement = connection.createStatement()) { + // executeQuery + ResultSet resultSet = statement.executeQuery(sql); + // print result + printResult(resultSet); +} catch (SQLException e) { + System.out.println("ERROR Message: " + e.getMessage()); + System.out.println("ERROR Code: " + e.getErrorCode()); + e.printStackTrace(); +} +``` + +There are four types of error codes that the JDBC connector can report: + +- Error code of the JDBC driver itself (error code between 0x2301 and 0x2350), +- Error code of the native connection method (error code between 0x2351 and 0x2360) +- Error code of the consumer method (error code between 0x2371 and 0x2380) +- Error code of other TDengine function modules. + +For specific error codes, please refer to. + +| Error Code | Description | Suggested Actions | +| ---------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| 0x2301 | connection already closed | The connection has been closed, check the connection status, or recreate the connection to execute the relevant instructions. | +| 0x2302 | this operation is NOT supported currently! | The current interface does not support the connection. You can use another connection mode. | +| 0x2303 | invalid variables | The parameter is invalid. Check the interface specification and adjust the parameter type and size. | +| 0x2304 | statement is closed | The statement is closed. Check whether the statement is closed and used again, or whether the connection is normal. | +| 0x2305 | resultSet is closed | result set The result set is released. Check whether the result set is released and used again. | +| 0x2306 | Batch is empty! | prepare statement Add parameters and then execute batch. | +| 0x2307 | Can not issue data manipulation statements with executeQuery() | The update operation should use execute update(), not execute query(). | +| 0x2308 | Can not issue SELECT via executeUpdate() | The query operation should use execute query(), not execute update(). | +| 0x230d | parameter index out of range | The parameter is out of bounds. Check the proper range of the parameter. | +| 0x230e | connection already closed | The connection has been closed. Please check whether the connection is closed and used again, or whether the connection is normal. | +| 0x230f | unknown sql type in tdengine | Check the data type supported by TDengine. | +| 0x2310 | can't register JDBC-JNI driver | The native driver cannot be registered. Please check whether the url is correct. | +| 0x2312 | url is not set | Check whether the REST connection url is correct. | +| 0x2314 | numeric value out of range | Check that the correct interface is used for the numeric types in the obtained result set. | +| 0x2315 | unknown taos type in tdengine | Whether the correct TDengine data type is specified when converting the TDengine data type to the JDBC data type. | +| 0x2317 | | wrong request type was used in the REST connection. | +| 0x2318 | | data transmission exception occurred during the REST connection. Please check the network status and try again. | +| 0x2319 | user is required | The user name information is missing when creating the connection | +| 0x231a | password is required | Password information is missing when creating a connection | +| 0x231c | httpEntity is null, sql: | Execution exception occurred during the REST connection | +| 0x2350 | unknown error | Unknown exception, please return to the developer on github. | +| 0x2352 | Unsupported encoding | An unsupported character encoding set is specified under the native Connection. | +| 0x2353 | internal error of database, please see taoslog for more details | An error occurs when the prepare statement is executed on the native connection. Check the taos log to locate the fault. | +| 0x2354 | JNI connection is NULL | When the command is executed, the native Connection is closed. Check the connection to TDengine. | +| 0x2355 | JNI result set is NULL | The result set is abnormal. Please check the connection status and try again. | +| 0x2356 | invalid num of fields | The meta information of the result set obtained by the native connection does not match. | +| 0x2357 | empty sql string | Fill in the correct SQL for execution. | +| 0x2359 | JNI alloc memory failed, please see taoslog for more details | Memory allocation for the native connection failed. Check the taos log to locate the problem. | +| 0x2371 | consumer properties must not be null! | The parameter is empty when you create a subscription. Please fill in the correct parameter. | +| 0x2372 | configs contain empty key, failed to set consumer property | The parameter key contains a null value. Please enter the correct parameter. | +| 0x2373 | failed to set consumer property, | The parameter value contains a null value. Please enter the correct parameter. | +| 0x2375 | topic reference has been destroyed | The topic reference is released during the creation of the data subscription. Check the connection to TDengine. | +| 0x2376 | failed to set consumer topic, topic name is empty | During data subscription creation, the subscription topic name is empty. Check that the specified topic name is correct. | +| 0x2377 | consumer reference has been destroyed | The subscription data transfer channel has been closed. Please check the connection to TDengine. | +| 0x2378 | consumer create error | Failed to create a data subscription. Check the taos log according to the error message to locate the fault. | +| - | can't create connection with server within | Increase the connection time by adding the httpConnectTimeout parameter, or check the connection to the taos adapter. | +| - | failed to complete the task within the specified time | Increase the execution time by adding the messageWaitTimeout parameter, or check the connection to the taos adapter. | + +- [TDengine Java Connector](https://github.com/taosdata/taos-connector-jdbc/blob/main/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java) + + ## TDengine DataType vs. Java DataType TDengine currently supports timestamp, number, character, Boolean type, and the corresponding type conversion with Java is as follows: -| TDengine DataType | JDBCType | -| ----------------- | ---------------------------------- | -| TIMESTAMP | java.sql.Timestamp | -| INT | java.lang.Integer | -| BIGINT | java.lang.Long | -| FLOAT | java.lang.Float | -| DOUBLE | java.lang.Double | -| SMALLINT | java.lang.Short | -| TINYINT | java.lang.Byte | -| BOOL | java.lang.Boolean | -| BINARY | byte array | -| NCHAR | java.lang.String | -| JSON | java.lang.String | +| TDengine DataType | JDBCType | +| ----------------- | ------------------ | +| TIMESTAMP | java.sql.Timestamp | +| INT | java.lang.Integer | +| BIGINT | java.lang.Long | +| FLOAT | java.lang.Float | +| DOUBLE | java.lang.Double | +| SMALLINT | java.lang.Short | +| TINYINT | java.lang.Byte | +| BOOL | java.lang.Boolean | +| BINARY | byte array | +| NCHAR | java.lang.String | +| JSON | java.lang.String | **Note**: Only TAG supports JSON types @@ -82,7 +169,7 @@ Add following dependency in the `pom.xml` file of your Maven project: com.taosdata.jdbc taos-jdbcdriver - 3.0.0 + 3.2.1 ``` @@ -97,7 +184,7 @@ cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` -After you have compiled taos-jdbcdriver, the `taos-jdbcdriver-3.0.*-dist.jar` file is created in the target directory. The compiled JAR file is automatically stored in your local Maven repository. +After you have compiled taos-jdbcdriver, the `taos-jdbcdriver-3.2.*-dist.jar` file is created in the target directory. The compiled JAR file is automatically stored in your local Maven repository. @@ -227,7 +314,7 @@ In addition to getting the connection from the specified URL, you can use Proper Note: - The client parameter set in the application is process-level. If you want to update the parameters of the client, you need to restart the application. This is because the client parameter is a global parameter that takes effect only the first time the application is set. -- The following sample code is based on taos-jdbcdriver-3.0.0. +- The following sample code is based on taos-jdbcdriver-3.1.0. ```java public Connection getConn() throws Exception{ @@ -333,30 +420,6 @@ while(resultSet.next()){ > The query is consistent with operating a relational database. When using subscripts to get the contents of the returned fields, you have to start from 1. However, we recommend using the field names to get the values of the fields in the result set. -### Handling exceptions - -After an error is reported, the error message and error code can be obtained through SQLException. - -```java -try (Statement statement = connection.createStatement()) { - // executeQuery - ResultSet resultSet = statement.executeQuery(sql); - // print result - printResult(resultSet); -} catch (SQLException e) { - System.out.println("ERROR Message: " + e.getMessage()); - System.out.println("ERROR Code: " + e.getErrorCode()); - e.printStackTrace(); -} -``` - -There are three types of error codes that the JDBC connector can report: - Error code of the JDBC driver itself (error code between 0x2301 and 0x2350), - Error code of the native connection method (error code between 0x2351 and 0x2400), and - Error code of other TDengine function modules. - -For specific error codes, please refer to. - -- [TDengine Java Connector](https://github.com/taosdata/taos-connector-jdbc/blob/main/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java) - - ### Writing data via parameter binding TDengine has significantly improved the bind APIs to support data writing (INSERT) scenarios. Writing data in this way avoids the resource consumption of SQL syntax parsing, resulting in significant write performance improvements in many cases. @@ -364,9 +427,12 @@ TDengine has significantly improved the bind APIs to support data writing (INSER **Note:** - JDBC REST connections do not currently support bind interface -- The following sample code is based on taos-jdbcdriver-3.0.0 +- The following sample code is based on taos-jdbcdriver-3.2.1 - The setString method should be called for binary type data, and the setNString method should be called for nchar type data -- both setString and setNString require the user to declare the width of the corresponding column in the size parameter of the table definition +- Do not use `db.?` in prepareStatement when specify the database with the table name, should directly use `?`, then specify the database in setTableName, for example: `prepareStatement.setTableName("db.t1")`. + + + ```java public class ParameterBindingDemo { @@ -594,21 +660,7 @@ public class ParameterBindingDemo { } ``` -The methods to set TAGS values: - -```java -public void setTagNull(int index, int type) -public void setTagBoolean(int index, boolean value) -public void setTagInt(int index, int value) -public void setTagByte(int index, byte value) -public void setTagShort(int index, short value) -public void setTagLong(int index, long value) -public void setTagTimestamp(int index, long value) -public void setTagFloat(int index, float value) -public void setTagDouble(int index, double value) -public void setTagString(int index, String value) -public void setTagNString(int index, String value) -``` +**Note**: both setString and setNString require the user to declare the width of the corresponding column in the size parameter of the table definition The methods to set VALUES columns: @@ -625,17 +677,203 @@ public void setString(int columnIndex, ArrayList list, int size) throws public void setNString(int columnIndex, ArrayList list, int size) throws SQLException ``` + + + +```java +public class ParameterBindingDemo { + private static final String host = "127.0.0.1"; + private static final Random random = new Random(System.currentTimeMillis()); + private static final int BINARY_COLUMN_SIZE = 30; + private static final String[] schemaList = { + "create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)", + "create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)", + "create table stable3(ts timestamp, f1 bool) tags(t1 bool)", + "create table stable4(ts timestamp, f1 binary(" + BINARY_COLUMN_SIZE + ")) tags(t1 binary(" + BINARY_COLUMN_SIZE + "))", + "create table stable5(ts timestamp, f1 nchar(" + BINARY_COLUMN_SIZE + ")) tags(t1 nchar(" + BINARY_COLUMN_SIZE + "))" + }; + private static final int numOfSubTable = 10, numOfRow = 10; + + public static void main(String[] args) throws SQLException { + + String jdbcUrl = "jdbc:TAOS-RS://" + host + ":6041/?batchfetch=true"; + Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata"); + + init(conn); + + bindInteger(conn); + + bindFloat(conn); + + bindBoolean(conn); + + bindBytes(conn); + + bindString(conn); + + conn.close(); + } + + private static void init(Connection conn) throws SQLException { + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop database if exists test_ws_parabind"); + stmt.execute("create database if not exists test_ws_parabind"); + stmt.execute("use test_ws_parabind"); + for (int i = 0; i < schemaList.length; i++) { + stmt.execute(schemaList[i]); + } + } + } + + private static void bindInteger(Connection conn) throws SQLException { + String sql = "insert into ? using stable1 tags(?,?,?,?) values(?,?,?,?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t1_" + i); + // set tags + pstmt.setTagByte(1, Byte.parseByte(Integer.toString(random.nextInt(Byte.MAX_VALUE)))); + pstmt.setTagShort(2, Short.parseShort(Integer.toString(random.nextInt(Short.MAX_VALUE)))); + pstmt.setTagInt(3, random.nextInt(Integer.MAX_VALUE)); + pstmt.setTagLong(4, random.nextLong()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setByte(2, Byte.parseByte(Integer.toString(random.nextInt(Byte.MAX_VALUE)))); + pstmt.setShort(3, Short.parseShort(Integer.toString(random.nextInt(Short.MAX_VALUE)))); + pstmt.setInt(4, random.nextInt(Integer.MAX_VALUE)); + pstmt.setLong(5, random.nextLong()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindFloat(Connection conn) throws SQLException { + String sql = "insert into ? using stable2 tags(?,?) values(?,?,?)"; + + try(TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t2_" + i); + // set tags + pstmt.setTagFloat(1, random.nextFloat()); + pstmt.setTagDouble(2, random.nextDouble()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setFloat(2, random.nextFloat()); + pstmt.setDouble(3, random.nextDouble()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindBoolean(Connection conn) throws SQLException { + String sql = "insert into ? using stable3 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t3_" + i); + // set tags + pstmt.setTagBoolean(1, random.nextBoolean()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setBoolean(2, random.nextBoolean()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindBytes(Connection conn) throws SQLException { + String sql = "insert into ? using stable4 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t4_" + i); + // set tags + pstmt.setTagString(1, new String("abc")); + + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setString(2, "abc"); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindString(Connection conn) throws SQLException { + String sql = "insert into ? using stable5 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t5_" + i); + // set tags + pstmt.setTagNString(1, "California.SanFrancisco"); + + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(0, new Timestamp(current + j)); + pstmt.setNString(1, "California.SanFrancisco"); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } +} +``` + + + + +The methods to set TAGS values: + +```java +public void setTagNull(int index, int type) +public void setTagBoolean(int index, boolean value) +public void setTagInt(int index, int value) +public void setTagByte(int index, byte value) +public void setTagShort(int index, short value) +public void setTagLong(int index, long value) +public void setTagTimestamp(int index, long value) +public void setTagFloat(int index, float value) +public void setTagDouble(int index, double value) +public void setTagString(int index, String value) +public void setTagNString(int index, String value) +``` + ### Schemaless Writing TDengine supports schemaless writing. It is compatible with InfluxDB's Line Protocol, OpenTSDB's telnet line protocol, and OpenTSDB's JSON format protocol. For more information, see [Schemaless Writing](../../schemaless). -Note: - -- JDBC REST connections do not currently support schemaless writes -- The following sample code is based on taos-jdbcdriver-3.0.0 + + ```java -public class SchemalessInsertTest { +public class SchemalessJniTest { private static final String host = "127.0.0.1"; private static final String lineDemo = "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; private static final String telnetDemo = "stb0_0 1626006833 4 host=host0 interface=eth0"; @@ -663,6 +901,41 @@ public class SchemalessInsertTest { } ``` + + + +```java +public class SchemalessWsTest { + private static final String host = "127.0.0.1"; + private static final String lineDemo = "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; + private static final String telnetDemo = "stb0_0 1626006833 4 host=host0 interface=eth0"; + private static final String jsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + + public static void main(String[] args) throws SQLException { + final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata&batchfetch=true"; + Connection connection = DriverManager.getConnection(url); + init(connection); + + SchemalessWriter writer = new SchemalessWriter(connection, "test_ws_schemaless"); + writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS); + writer.write(telnetDemo, SchemalessProtocolType.TELNET, SchemalessTimestampType.MILLI_SECONDS); + writer.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.SECONDS); + System.exit(0); + } + + private static void init(Connection connection) throws SQLException { + try (Statement stmt = connection.createStatement()) { + stmt.executeUpdate("drop database if exists test_ws_schemaless"); + stmt.executeUpdate("create database if not exists test_ws_schemaless keep 36500"); + stmt.executeUpdate("use test_ws_schemaless"); + } + } +} +``` + + + + ### Data Subscription The TDengine Java Connector supports subscription functionality with the following application API. @@ -706,8 +979,9 @@ TaosConsumer consumer = new TaosConsumer<>(config); ```java while(true) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } ``` @@ -760,8 +1034,9 @@ public abstract class ConsumerLoop { while (!shutdown.get()) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } consumer.unsubscribe(); @@ -836,8 +1111,9 @@ public abstract class ConsumerLoop { while (!shutdown.get()) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } consumer.unsubscribe(); @@ -963,20 +1239,6 @@ The source code of the sample application is under `TDengine/examples/JDBC`: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC) -## Recent update logs - -| taos-jdbcdriver version | major changes | -| :---------------------: | :--------------------------------------------: | -| 3.1.0 | JDBC REST connection supports subscription over WebSocket | -| 3.0.1 - 3.0.4 | fix the resultSet data is parsed incorrectly sometimes. 3.0.1 is compiled on JDK 11, you are advised to use other version in the JDK 8 environment | -| 3.0.0 | Support for TDengine 3.0 | -| 2.0.42 | fix wasNull interface return value in WebSocket connection | -| 2.0.41 | fix decode method of username and password in REST connection | -| 2.0.39 - 2.0.40 | Add REST connection/request timeout parameters | -| 2.0.38 | JDBC REST connections add bulk pull function | -| 2.0.37 | Support json tags | -| 2.0.36 | Support schemaless writing | - ## Frequently Asked Questions 1. Why is there no performance improvement when using Statement's `addBatch()` and `executeBatch()` to perform `batch data writing/update`? @@ -999,9 +1261,9 @@ The source code of the sample application is under `TDengine/examples/JDBC`: 4. java.lang.NoSuchMethodError: setByteArray - **Cause**: taos-jbdcdriver 3.* only supports TDengine 3.0 and later. + **Cause**: taos-jbdcdriver 3.\* only supports TDengine 3.0 and later. - **Solution**: Use taos-jdbcdriver 2.* with your TDengine 2.* deployment. + **Solution**: Use taos-jdbcdriver 2.\* with your TDengine 2.\* deployment. 5. java.lang.NoSuchMethodError: java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer; ... taos-jdbcdriver-3.0.1.jar diff --git a/docs/en/14-reference/03-connector/06-rust.mdx b/docs/en/14-reference/03-connector/06-rust.mdx index ad522e9d2b..597a9b0f52 100644 --- a/docs/en/14-reference/03-connector/06-rust.mdx +++ b/docs/en/14-reference/03-connector/06-rust.mdx @@ -11,6 +11,7 @@ import TabItem from '@theme/TabItem'; import Preparition from "./_preparation.mdx" import RustInsert from "../../07-develop/03-insert-data/_rust_sql.mdx" import RustBind from "../../07-develop/03-insert-data/_rust_stmt.mdx" +import RustSml from "../../07-develop/03-insert-data/_rust_schemaless.mdx" import RustQuery from "../../07-develop/04-query-data/_rust.mdx" [![Crates.io](https://img.shields.io/crates/v/taos)](https://crates.io/crates/taos) ![Crates.io](https://img.shields.io/crates/d/taos) [![docs.rs](https://img.shields.io/docsrs/taos)](https://docs.rs/taos) @@ -232,6 +233,10 @@ There are two ways to query data: Using built-in types or the [serde](https://se +#### Schemaless Write + + + ### Query data diff --git a/docs/en/14-reference/03-connector/index.mdx b/docs/en/14-reference/03-connector/index.mdx index a35d5bc2d1..28b7b83b58 100644 --- a/docs/en/14-reference/03-connector/index.mdx +++ b/docs/en/14-reference/03-connector/index.mdx @@ -62,7 +62,7 @@ The different database framework specifications for various programming language | **Regular Query** | Support | Support | Support | Support | Support | Support | | **Parameter Binding** | Not Supported | Not Supported | Support | Support | Not Supported | Support | | **Subscription (TMQ) ** | Supported | Support | Support | Not Supported | Not Supported | Support | -| **Schemaless** | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported | +| **Schemaless** | Supported | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported | | **Bulk Pulling (based on WebSocket) ** | Support | Support | Support | Support | Support | Support | | **DataFrame** | Not Supported | Support | Not Supported | Not Supported | Not Supported | Not Supported | diff --git a/docs/en/14-reference/06-taosdump.md b/docs/en/14-reference/06-taosdump.md index dcfc068a3d..7348add4bd 100644 --- a/docs/en/14-reference/06-taosdump.md +++ b/docs/en/14-reference/06-taosdump.md @@ -76,6 +76,7 @@ Usage: taosdump [OPTION...] dbname [tbname ...] -A, --all-databases Dump all databases. -D, --databases=DATABASES Dump listed databases. Use comma to separate database names. + -e, --escape-character Use escaped character for database name -N, --without-property Dump database without its properties. -s, --schemaonly Only dump table schemas. -y, --answer-yes Input yes for prompt. It will skip data file diff --git a/docs/en/14-reference/07-tdinsight/index.md b/docs/en/14-reference/07-tdinsight/index.md index 652d5ded0b..8d97dafa7c 100644 --- a/docs/en/14-reference/07-tdinsight/index.md +++ b/docs/en/14-reference/07-tdinsight/index.md @@ -12,8 +12,8 @@ After TDengine starts, it automatically writes many metrics in specific interval To deploy TDinsight, we need - a single-node TDengine server or a multi-node TDengine cluster and a [Grafana] server are required. This dashboard requires TDengine 3.0.1.0 and above, with the monitoring feature enabled. For detailed configuration, please refer to [TDengine monitoring configuration](../config/#monitoring-parameters). -- taosAdapter has been instaleld and running, please refer to [taosAdapter](../taosadapter). -- taosKeeper has been installed and running, please refer to [taosKeeper](../taoskeeper). +- taosAdapter has been installed and running, please refer to [taosAdapter](../taosadapter). +- taosKeeper has been installed and running, please refer to [taosKeeper](../taosKeeper). Please record - The endpoint of taosAdapter REST service, for example `http://tdengine.local:6041` diff --git a/docs/en/14-reference/12-config/index.md b/docs/en/14-reference/12-config/index.md index 2e6f5ec1e2..715a68696b 100644 --- a/docs/en/14-reference/12-config/index.md +++ b/docs/en/14-reference/12-config/index.md @@ -358,6 +358,17 @@ The charset that takes effect is UTF-8. | Value Range | 0-4096 | | Default Value | 2x the CPU cores | +## Performance Tuning + +### numOfCommitThreads + +| Attribute | Description | +| ------------- | ----------------------------------- | +| Applicable | Server Only | +| Meaning | Maximum number of threads to commit | +| Value Range | 0-1024 | +| Default Value | | + ## Log Parameters ### logDir diff --git a/docs/en/14-reference/14-taosKeeper.md b/docs/en/14-reference/14-taosKeeper.md index 895bd82e19..cfc2554387 100644 --- a/docs/en/14-reference/14-taosKeeper.md +++ b/docs/en/14-reference/14-taosKeeper.md @@ -108,7 +108,7 @@ The following `launchctl` commands can help you manage taoskeeper service: #### Launch With Configuration File -You can quickly launch taosKeeper with the following commands. If you do not specify a configuration file, `/etc/taos/keeper.toml` is used by default. If this file does not specify configurations, the default values are used. +You can quickly launch taosKeeper with the following commands. If you do not specify a configuration file, `/etc/taos/taoskeeper.toml` is used by default. If this file does not specify configurations, the default values are used. ```shell $ taoskeeper -c @@ -153,6 +153,10 @@ database = "log" # standard tables to monitor tables = ["normal_table"] + +# database options for db storing metrics data +[metrics.databaseoptions] +cachemodel = "none" ``` ### Obtain Monitoring Metrics @@ -203,7 +207,7 @@ taos_cluster_info_dnodes_total{cluster_id="5981392874047724755"} 1 taos_cluster_info_first_ep{cluster_id="5981392874047724755",value="hlb:6030"} 1 ``` -### check_health +### check\_health ``` $ curl -i http://127.0.0.1:6043/check_health @@ -219,3 +223,29 @@ Content-Length: 19 {"version":"1.0.0"} ``` + +### taoskeeper with Prometheus + +There is `/metrics` api in taoskeeper provide TDengine metric data for Prometheus. + +#### scrape config + +Scrape config in Prometheus specifies a set of targets and parameters describing how to scrape metric data from endpoint. For more information, please reference to [Prometheus documents](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config). + +``` +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + - job_name: "taoskeeper" + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ["localhost:6043"] +``` + +#### Dashboard + +There is a dashboard named `TaosKeeper Prometheus Dashboard for 3.x`, which provides a monitoring dashboard similar to TInsight. + +In Grafana, click the Dashboard menu and click `import`, enter the dashboard ID `18587` and click the `Load` button. Then finished importing `TaosKeeper Prometheus Dashboard for 3.x` dashboard. + diff --git a/docs/en/20-third-party/11-kafka.md b/docs/en/20-third-party/11-kafka.md index 9e322d2a5b..3b0de6c349 100644 --- a/docs/en/20-third-party/11-kafka.md +++ b/docs/en/20-third-party/11-kafka.md @@ -46,15 +46,14 @@ Execute in any directory: ```` curl -O http://packages.confluent.io/archive/7.1/confluent-7.1.1.tar.gz -tar xzf confluent-7.1.1.tar.gz -C /opt/test +tar xzf confluent-7.1.1.tar.gz -C /opt/ ```` Then you need to add the `$CONFLUENT_HOME/bin` directory to the PATH. ```title=".profile" export CONFLUENT_HOME=/opt/confluent-7.1.1 -PATH=$CONFLUENT_HOME/bin -export PATH +export PATH=$CONFLUENT_HOME/bin:$PATH ``` Users can append the above script to the current user's profile file (~/.profile or ~/.bash_profile) @@ -329,7 +328,15 @@ DROP DATABASE IF EXISTS test; CREATE DATABASE test; USE test; CREATE STABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT); -INSERT INTO d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:05.000',10.30000,219,0.31000) d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:15.000',12.60000,218,0.33000) d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:16.800',12.30000,221,0.31000) d1002 USING meters TAGS(California.SanFrancisco, 3) VALUES('2018-10-03 14:38:16.650',10.30000,218,0.25000) d1003 USING meters TAGS(California.LoSangeles, 2) VALUES('2018-10-03 14:38:05.500',11.80000,221,0.28000) d1003 USING meters TAGS(California.LoSangeles, 2) VALUES('2018-10-03 14:38:16.600',13.40000,223,0.29000) d1004 USING meters TAGS(California.LoSangeles, 3) VALUES('2018-10-03 14:38:05.000',10.80000,223,0.29000) d1004 USING meters TAGS(California.LoSangeles, 3) VALUES('2018-10-03 14:38:06.500',11.50000,221,0.35000); + +INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:05.000',10.30000,219,0.31000) \ + d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:15.000',12.60000,218,0.33000) \ + d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:16.800',12.30000,221,0.31000) \ + d1002 USING meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650',10.30000,218,0.25000) \ + d1003 USING meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500',11.80000,221,0.28000) \ + d1003 USING meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:16.600',13.40000,223,0.29000) \ + d1004 USING meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000',10.80000,223,0.29000) \ + d1004 USING meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:06.500',11.50000,221,0.35000); ``` Use TDengine CLI to execute SQL script @@ -384,7 +391,7 @@ confluent local services connect connector status You should now have two active connectors if you followed the previous steps. Use the following command to unload: ```` -confluent local services connect connector unload TDengineSourceConnector +confluent local services connect connector unload TDengineSinkConnector confluent local services connect connector unload TDengineSourceConnector ```` diff --git a/docs/en/25-application/01-telegraf.md b/docs/en/25-application/01-telegraf.md index b84b30bb71..1e3325b2b2 100644 --- a/docs/en/25-application/01-telegraf.md +++ b/docs/en/25-application/01-telegraf.md @@ -35,7 +35,7 @@ Please refer to the [official documentation](https://grafana.com/grafana/downloa ### TDengine -Download the latest TDengine-server from the [Downloads](http://tdengine.com/en/all-downloads/) page on the TAOSData website and install it. +Download and install the [latest version of TDengine](https://docs.tdengine.com/releases/tdengine/). ## Data Connection Setup diff --git a/docs/en/25-application/02-collectd.md b/docs/en/25-application/02-collectd.md index 6ac7253fc4..ee1e944928 100644 --- a/docs/en/25-application/02-collectd.md +++ b/docs/en/25-application/02-collectd.md @@ -38,7 +38,7 @@ Please refer to the [official documentation](https://grafana.com/grafana/downloa ### Install TDengine -Download the latest TDengine-server from the [Downloads](http://tdengine.com/en/all-downloads/) page on the TAOSData website and install it. +Download and install the [latest version of TDengine](https://docs.tdengine.com/releases/tdengine/). ## Data Connection Setup diff --git a/docs/en/27-train-faq/01-faq.md b/docs/en/27-train-faq/01-faq.md index 9e7f4f8e0d..aa28303f5d 100644 --- a/docs/en/27-train-faq/01-faq.md +++ b/docs/en/27-train-faq/01-faq.md @@ -32,7 +32,7 @@ TDengine 3.0 is not compatible with the configuration and data files from previo 2. Run `sudo rm -rf /var/log/taos/` to delete your log files. 3. Run `sudo rm -rf /var/lib/taos/` to delete your data files. 4. Install TDengine 3.0. -5. For assistance in migrating data to TDengine 3.0, contact [TDengine Support](https://tdengine.com/support). +5. For assistance in migrating data to TDengine 3.0, contact [TDengine Support](https://tdengine.com/support/). ### 2. How can I resolve the "Unable to establish connection" error? diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index acfbf6a0ba..fb31ad67c0 100644 --- a/docs/en/28-releases/01-tdengine.md +++ b/docs/en/28-releases/01-tdengine.md @@ -10,6 +10,10 @@ For TDengine 2.x installation packages by version, please visit [here](https://w import Release from "/components/ReleaseV3"; +## 3.0.4.1 + + + ## 3.0.4.0 diff --git a/docs/en/28-releases/02-tools.md b/docs/en/28-releases/02-tools.md index e8f7a54566..9f8dbfee7e 100644 --- a/docs/en/28-releases/02-tools.md +++ b/docs/en/28-releases/02-tools.md @@ -10,6 +10,10 @@ For other historical version installers, please visit [here](https://www.taosdat import Release from "/components/ReleaseV3"; +## 2.5.0 + + + ## 2.4.12 diff --git a/docs/examples/c/async_query_example.c b/docs/examples/c/async_query_example.c index b370420b12..3807c4bfd7 100644 --- a/docs/examples/c/async_query_example.c +++ b/docs/examples/c/async_query_example.c @@ -8,7 +8,7 @@ #include #include -typedef int16_t VarDataLenT; +typedef uint16_t VarDataLenT; #define TSDB_NCHAR_SIZE sizeof(int32_t) #define VARSTR_HEADER_SIZE sizeof(VarDataLenT) diff --git a/docs/examples/c/query_example.c b/docs/examples/c/query_example.c index fcae95bcd4..c7d52115b5 100644 --- a/docs/examples/c/query_example.c +++ b/docs/examples/c/query_example.c @@ -6,7 +6,7 @@ #include #include -typedef int16_t VarDataLenT; +typedef uint16_t VarDataLenT; #define TSDB_NCHAR_SIZE sizeof(int32_t) #define VARSTR_HEADER_SIZE sizeof(VarDataLenT) diff --git a/docs/examples/java/pom.xml b/docs/examples/java/pom.xml index 01d0ce936c..4bdb2062b2 100644 --- a/docs/examples/java/pom.xml +++ b/docs/examples/java/pom.xml @@ -22,7 +22,7 @@ com.taosdata.jdbc taos-jdbcdriver - 3.1.0 + 3.2.1 diff --git a/docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java b/docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java index 8da6f77bae..b5cdedc34f 100644 --- a/docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java +++ b/docs/examples/java/src/main/java/com/taos/example/SubscribeDemo.java @@ -1,5 +1,6 @@ package com.taos.example; +import com.taosdata.jdbc.tmq.ConsumerRecord; import com.taosdata.jdbc.tmq.ConsumerRecords; import com.taosdata.jdbc.tmq.TMQConstants; import com.taosdata.jdbc.tmq.TaosConsumer; @@ -64,7 +65,8 @@ public class SubscribeDemo { consumer.subscribe(Collections.singletonList(TOPIC)); while (!shutdown.get()) { ConsumerRecords meters = consumer.poll(Duration.ofMillis(100)); - for (Meters meter : meters) { + for (ConsumerRecord recode : meters) { + Meters meter = recode.value(); System.out.println(meter); } } diff --git a/docs/examples/rust/nativeexample/examples/schemaless_insert_json.rs b/docs/examples/rust/nativeexample/examples/schemaless_insert_json.rs new file mode 100644 index 0000000000..d5aa45016e --- /dev/null +++ b/docs/examples/rust/nativeexample/examples/schemaless_insert_json.rs @@ -0,0 +1,74 @@ +use taos_query::common::SchemalessPrecision; +use taos_query::common::SchemalessProtocol; +use taos_query::common::SmlDataBuilder; + +use crate::AsyncQueryable; +use crate::AsyncTBuilder; +use crate::TaosBuilder; + +async fn put_json() -> anyhow::Result<()> { + // std::env::set_var("RUST_LOG", "taos=trace"); + std::env::set_var("RUST_LOG", "taos=debug"); + pretty_env_logger::init(); + let dsn = + std::env::var("TDENGINE_ClOUD_DSN").unwrap_or("http://localhost:6041".to_string()); + log::debug!("dsn: {:?}", &dsn); + + let client = TaosBuilder::from_dsn(dsn)?.build().await?; + + let db = "demo_schemaless_ws"; + + client.exec(format!("drop database if exists {db}")).await?; + + client + .exec(format!("create database if not exists {db}")) + .await?; + + // should specify database before insert + client.exec(format!("use {db}")).await?; + + // SchemalessProtocol::Json + let data = [ + r#"[{"metric": "meters.current", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"# + ] + .map(String::from) + .to_vec(); + + // demo with all fields + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Json) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(300u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default precision + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Json) + .data(data.clone()) + .ttl(1000) + .req_id(301u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default ttl + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Json) + .data(data.clone()) + .req_id(302u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default req_id + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Json) + .data(data.clone()) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + client.exec(format!("drop database if exists {db}")).await?; + + Ok(()) +} diff --git a/docs/examples/rust/nativeexample/examples/schemaless_insert_line.rs b/docs/examples/rust/nativeexample/examples/schemaless_insert_line.rs new file mode 100644 index 0000000000..3cf4d969ce --- /dev/null +++ b/docs/examples/rust/nativeexample/examples/schemaless_insert_line.rs @@ -0,0 +1,78 @@ +use taos_query::common::SchemalessPrecision; +use taos_query::common::SchemalessProtocol; +use taos_query::common::SmlDataBuilder; + +use crate::AsyncQueryable; +use crate::AsyncTBuilder; +use crate::TaosBuilder; + +async fn put_line() -> anyhow::Result<()> { + // std::env::set_var("RUST_LOG", "taos=trace"); + std::env::set_var("RUST_LOG", "taos=debug"); + pretty_env_logger::init(); + + let dsn = + std::env::var("TDENGINE_ClOUD_DSN").unwrap_or("http://localhost:6041".to_string()); + log::debug!("dsn: {:?}", &dsn); + + let client = TaosBuilder::from_dsn(dsn)?.build().await?; + + let db = "demo_schemaless_ws"; + + client.exec(format!("drop database if exists {db}")).await?; + + client + .exec(format!("create database if not exists {db}")) + .await?; + + // should specify database before insert + client.exec(format!("use {db}")).await?; + + let data = [ + "measurement,host=host1 field1=2i,field2=2.0 1577837300000", + "measurement,host=host1 field1=2i,field2=2.0 1577837400000", + "measurement,host=host1 field1=2i,field2=2.0 1577837500000", + "measurement,host=host1 field1=2i,field2=2.0 1577837600000", + ] + .map(String::from) + .to_vec(); + + // demo with all fields + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(100u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default ttl + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .req_id(101u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default ttl and req_id + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default precision + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .data(data) + .req_id(103u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + client.exec(format!("drop database if exists {db}")).await?; + + Ok(()) +} diff --git a/docs/examples/rust/nativeexample/examples/schemaless_insert_telnet.rs b/docs/examples/rust/nativeexample/examples/schemaless_insert_telnet.rs new file mode 100644 index 0000000000..d2bbc69261 --- /dev/null +++ b/docs/examples/rust/nativeexample/examples/schemaless_insert_telnet.rs @@ -0,0 +1,80 @@ +use taos_query::common::SchemalessPrecision; +use taos_query::common::SchemalessProtocol; +use taos_query::common::SmlDataBuilder; + +use crate::AsyncQueryable; +use crate::AsyncTBuilder; +use crate::TaosBuilder; + +async fn put_telnet() -> anyhow::Result<()> { + // std::env::set_var("RUST_LOG", "taos=trace"); + std::env::set_var("RUST_LOG", "taos=debug"); + pretty_env_logger::init(); + let dsn = + std::env::var("TDENGINE_ClOUD_DSN").unwrap_or("http://localhost:6041".to_string()); + log::debug!("dsn: {:?}", &dsn); + + let client = TaosBuilder::from_dsn(dsn)?.build().await?; + + let db = "demo_schemaless_ws"; + + client.exec(format!("drop database if exists {db}")).await?; + + client + .exec(format!("create database if not exists {db}")) + .await?; + + // should specify database before insert + client.exec(format!("use {db}")).await?; + + let data = [ + "meters.current 1648432611249 10.3 location=California.SanFrancisco group=2", + "meters.current 1648432611250 12.6 location=California.SanFrancisco group=2", + "meters.current 1648432611249 10.8 location=California.LosAngeles group=3", + "meters.current 1648432611250 11.3 location=California.LosAngeles group=3", + "meters.voltage 1648432611249 219 location=California.SanFrancisco group=2", + "meters.voltage 1648432611250 218 location=California.SanFrancisco group=2", + "meters.voltage 1648432611249 221 location=California.LosAngeles group=3", + "meters.voltage 1648432611250 217 location=California.LosAngeles group=3", + ] + .map(String::from) + .to_vec(); + + // demo with all fields + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Telnet) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(200u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default precision + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Telnet) + .data(data.clone()) + .ttl(1000) + .req_id(201u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default ttl + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Telnet) + .data(data.clone()) + .req_id(202u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // demo with default req_id + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Telnet) + .data(data.clone()) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + client.exec(format!("drop database if exists {db}")).await?; + + Ok(()) +} diff --git a/docs/zh/05-get-started/03-package.md b/docs/zh/05-get-started/03-package.md index bdf6a730d0..1cd0076ba5 100644 --- a/docs/zh/05-get-started/03-package.md +++ b/docs/zh/05-get-started/03-package.md @@ -100,7 +100,8 @@ sudo apt-get install tdengine :::tip apt-get 方式只适用于 Debian 或 Ubuntu 系统。 -:::: +::: + @@ -206,6 +207,8 @@ Active: inactive (dead) - 查看服务状态:`sudo launchctl list | grep taosd` +- 查看服务详细信息:`launchctl print system/com.tdengine.taosd` + :::info - `launchctl` 命令管理`com.tdengine.taosd`需要管理员权限,务必在前面加 `sudo` 来增强安全性。 diff --git a/docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx b/docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx index 876f123fe1..258adaaeed 100644 --- a/docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx +++ b/docs/zh/07-develop/03-insert-data/30-influxdb-line.mdx @@ -38,7 +38,7 @@ meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0 - field_set 中的每个数据项都需要对自身的数据类型进行描述, 比如 1.2f32 代表 FLOAT 类型的数值 1.2, 如果不带类型后缀会被当作 DOUBLE 处理; - timestamp 支持多种时间精度。写入数据的时候需要用参数指定时间精度,支持从小时到纳秒的 6 种时间精度。 - 为了提高写入的效率,默认假设同一个超级表中 field_set 的顺序是一样的(第一条数据包含所有的 field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数 smlDataFormat 为 false,否则,数据写入按照相同顺序写入,库中数据会异常。(3.0.1.3 之后的版本 smlDataFormat 默认为 false,从3.0.3.0开始,该配置废弃) [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) -- 默认产生的子表名是根据规则生成的唯一 ID 值。用户也可以通过在 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) +- 默认产生的子表名是根据规则生成的唯一 ID 值。用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) ::: 要了解更多可参考:[InfluxDB Line 协议官方文档](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) 和 [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议) diff --git a/docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx b/docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx index 3b2148ef4a..9da767a691 100644 --- a/docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx +++ b/docs/zh/07-develop/03-insert-data/40-opentsdb-telnet.mdx @@ -32,7 +32,7 @@ OpenTSDB 行协议同样采用一行字符串来表示一行数据。OpenTSDB meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3 ``` -- 默认生产的子表名是根据规则生成的唯一 ID 值。用户也可以通过在 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 meters.current 1648432611250 11.3 tname=cpu1 location=California.LosAngeles groupid=3 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 +- 默认生产的子表名是根据规则生成的唯一 ID 值。用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 meters.current 1648432611250 11.3 tname=cpu1 location=California.LosAngeles groupid=3 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 参考 [OpenTSDB Telnet API 文档](http://opentsdb.net/docs/build/html/api_telnet/put.html)。 ## 示例代码 diff --git a/docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx b/docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx index e1fd3dacc8..f2cfbc857b 100644 --- a/docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx +++ b/docs/zh/07-develop/03-insert-data/50-opentsdb-json.mdx @@ -47,7 +47,7 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据 :::note - 对于 JSON 格式协议,TDengine 并不会自动把所有标签转成 NCHAR 类型, 字符串将将转为 NCHAR 类型, 数值将同样转换为 DOUBLE 类型。 -- 默认生成的子表名是根据规则生成的唯一 ID 值。用户也可以通过在 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 `"tags": { "host": "web02","dc": "lga","tname":"cpu1"}` 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 +- 默认生成的子表名是根据规则生成的唯一 ID 值。用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 `"tags": { "host": "web02","dc": "lga","tname":"cpu1"}` 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。 ::: ## 示例代码 diff --git a/docs/zh/07-develop/03-insert-data/_rust_schemaless.mdx b/docs/zh/07-develop/03-insert-data/_rust_schemaless.mdx new file mode 100644 index 0000000000..a26613bd15 --- /dev/null +++ b/docs/zh/07-develop/03-insert-data/_rust_schemaless.mdx @@ -0,0 +1,3 @@ +```rust +{{#include docs/examples/rust/nativeexample/examples/schemaless_insert_line.rs}} +``` diff --git a/docs/zh/07-develop/07-tmq.mdx b/docs/zh/07-develop/07-tmq.mdx index 036c9aa86e..11aef1f7e8 100644 --- a/docs/zh/07-develop/07-tmq.mdx +++ b/docs/zh/07-develop/07-tmq.mdx @@ -25,7 +25,8 @@ import CDemo from "./_sub_c.mdx"; 本文档不对消息队列本身的基础知识做介绍,如果需要了解,请自行搜索。 -注意:默认是从wal消费数据,如果wal被删除,消费到的数据会不全,此时可以将参数 experimental.snapshot.enable 设置为true,从tsdb获取全部数据,但是这样的话就不能保证数据的消费顺序。所以建议根据自己的消费情况合理的设置wal的保留策略,保证可以从wal里订阅到全部数据。 +注意:数据订阅是从 WAL 消费数据,如果一些 WAL 文件被基于 WAL 保留策略删除,则已经删除的 WAL 文件中的数据就无法再消费到。需要根据业务需要在创建数据库时合理设置 `WAL_RETENTION_PERIOD` 或 `WAL_RETENTION_SIZE` ,并确保应用及时消费数据,这样才不会产生数据丢失的现象。数据订阅的行为与 Kafka 等广泛使用的消息队列类产品的行为相似。 + ## 主要数据结构和 API 不同语言下, TMQ 订阅相关的 API 及数据结构如下: @@ -221,7 +222,7 @@ void Close() ```sql DROP DATABASE IF EXISTS tmqdb; -CREATE DATABASE tmqdb; +CREATE DATABASE tmqdb WAL_RETENTION_PERIOD 3600; CREATE TABLE tmqdb.stb (ts TIMESTAMP, c1 INT, c2 FLOAT, c3 VARCHAR(16)) TAGS(t1 INT, t3 VARCHAR(16)); CREATE TABLE tmqdb.ctb0 USING tmqdb.stb TAGS(0, "subtable0"); CREATE TABLE tmqdb.ctb1 USING tmqdb.stb TAGS(1, "subtable1"); @@ -293,7 +294,6 @@ CREATE TOPIC topic_name AS DATABASE db_name; | `auto.offset.reset` | enum | 消费组订阅的初始位置 |
`earliest`: default;从头开始订阅;
`latest`: 仅从最新数据开始订阅;
`none`: 没有提交的 offset 无法订阅 | | `enable.auto.commit` | boolean | 是否启用消费位点自动提交,true: 自动提交,客户端应用无需commit;false:客户端应用需要自行commit | 默认值为 true | | `auto.commit.interval.ms` | integer | 消费记录自动提交消费位点时间间隔,单位为毫秒 | 默认值为 5000 | -| `experimental.snapshot.enable` | boolean | 是否允许从 TSDB 消费数据。当其关闭时,只能消费依据 WAL 保留策略仍然在WAL中的数据;当其打开时,除WAL中的数据以外,也能够消费已经从WAL中删除但落盘到TSDB中的数据 | 实验功能,默认关闭 | | `msg.with.table.name` | boolean | 是否允许从消息中解析表名, 不适用于列订阅(列订阅时可将 tbname 作为列写入 subquery 语句) |默认关闭 | 对于不同编程语言,其设置方式如下: @@ -311,7 +311,6 @@ tmq_conf_set(conf, "group.id", "cgrpName"); tmq_conf_set(conf, "td.connect.user", "root"); tmq_conf_set(conf, "td.connect.pass", "taosdata"); tmq_conf_set(conf, "auto.offset.reset", "earliest"); -tmq_conf_set(conf, "experimental.snapshot.enable", "true"); tmq_conf_set(conf, "msg.with.table.name", "true"); tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); @@ -367,7 +366,6 @@ conf := &tmq.ConfigMap{ "td.connect.port": "6030", "client.id": "test_tmq_c", "enable.auto.commit": "false", - "experimental.snapshot.enable": "true", "msg.with.table.name": "true", } consumer, err := NewConsumer(conf) @@ -417,7 +415,6 @@ consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"}) | `enable.auto.commit` | string | 启用自动提交 | 合法值:`true`, `false` | | `auto.commit.interval.ms` | string | 以毫秒为单位的自动提交时间间隔 | 默认值:5000 ms | | `auto.offset.reset` | string | 消费组订阅的初始位置 | 可选:`earliest`(default), `latest`, `none` | -| `experimental.snapshot.enable` | string | 是否允许从 TSDB 消费数据 | 合法值:`true`, `false` |
diff --git a/docs/zh/07-develop/09-udf.md b/docs/zh/07-develop/09-udf.md index 8a8ef82009..99ecd903b4 100644 --- a/docs/zh/07-develop/09-udf.md +++ b/docs/zh/07-develop/09-udf.md @@ -6,18 +6,20 @@ description: "支持用户编码的聚合函数和标量函数,在查询中嵌 在有些应用场景中,应用逻辑需要的查询无法直接使用系统内置的函数来表示。利用 UDF(User Defined Function) 功能,TDengine 可以插入用户编写的处理代码并在查询中使用它们,就能够很方便地解决特殊应用场景中的使用需求。 UDF 通常以数据表中的一列数据做为输入,同时支持以嵌套子查询的结果作为输入。 -TDengine 支持通过 C/C++ 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。 - 用户可以通过 UDF 实现两类函数:标量函数和聚合函数。标量函数对每行数据输出一个值,如求绝对值 abs,正弦函数 sin,字符串拼接函数 concat 等。聚合函数对多行数据进行输出一个值,如求平均数 avg,最大值 max 等。 -实现 UDF 时,需要实现规定的接口函数 +TDengine 支持通过 C/Python 语言进行 UDF 定义。接下来结合示例讲解 UDF 的使用方法。 + +## 用 C 语言实现 UDF + +使用 C 语言实现 UDF 时,需要实现规定的接口函数 - 标量函数需要实现标量接口函数 scalarfn 。 - 聚合函数需要实现聚合接口函数 aggfn_start , aggfn , aggfn_finish。 - 如果需要初始化,实现 udf_init;如果需要清理工作,实现udf_destroy。 接口函数的名称是 UDF 名称,或者是 UDF 名称和特定后缀(_start, _finish, _init, _destroy)的连接。列表中的scalarfn,aggfn, udf需要替换成udf函数名。 -## 实现标量函数 +### 用 C 语言实现标量函数 标量函数实现模板如下 ```c #include "taos.h" @@ -49,7 +51,7 @@ int32_t scalarfn_destroy() { ``` scalarfn 为函数名的占位符,需要替换成函数名,如bit_and。 -## 实现聚合函数 +### 用 C 语言实现聚合函数 聚合函数的实现模板如下 ```c @@ -100,7 +102,7 @@ int32_t aggfn_destroy() { ``` aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。 -## 接口函数定义 +### C 语言 UDF 接口函数定义 接口函数的名称是 udf 名称,或者是 udf 名称和特定后缀(_start, _finish, _init, _destroy)的连接。以下描述中函数名称中的 scalarfn,aggfn, udf 需要替换成udf函数名。 @@ -108,7 +110,7 @@ aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。 接口函数参数类型见数据结构定义。 -### 标量接口函数 +#### 标量函数接口 `int32_t scalarfn(SUdfDataBlock* inputDataBlock, SUdfColumn *resultColumn)` @@ -118,7 +120,7 @@ aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。 - inputDataBlock: 输入的数据块 - resultColumn: 输出列 -### 聚合接口函数 +#### 聚合函数接口 `int32_t aggfn_start(SUdfInterBuf *interBuf)` @@ -135,7 +137,7 @@ aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。 - result:最终结果。 -### UDF 初始化和销毁 +#### 初始化和销毁接口 `int32_t udf_init()` `int32_t udf_destroy()` @@ -143,7 +145,7 @@ aggfn为函数名的占位符,需要修改为自己的函数名,如l2norm。 其中 udf 是函数名的占位符。udf_init 完成初始化工作。 udf_destroy 完成清理工作。如果没有初始化工作,无需定义udf_init函数。如果没有清理工作,无需定义udf_destroy函数。 -## UDF 数据结构 +### C 语言 UDF 数据结构 ```c typedef struct SUdfColumnMeta { int16_t type; @@ -201,7 +203,7 @@ typedef struct SUdfInterBuf { 为了更好的操作以上数据结构,提供了一些便利函数,定义在 taosudf.h。 -## 编译 UDF +### 编译 C UDF 用户定义函数的 C 语言源代码无法直接被 TDengine 系统使用,而是需要先编译为 动态链接库,之后才能载入 TDengine 系统。 @@ -213,12 +215,9 @@ gcc -g -O0 -fPIC -shared bit_and.c -o libbitand.so 这样就准备好了动态链接库 libbitand.so 文件,可以供后文创建 UDF 时使用了。为了保证可靠的系统运行,编译器 GCC 推荐使用 7.5 及以上版本。 -## 管理和使用UDF -编译好的UDF,还需要将其加入到系统才能被正常的SQL调用。关于如何管理和使用UDF,参见[UDF使用说明](../12-taos-sql/26-udf.md) +### C UDF 示例代码 -## 示例代码 - -### 标量函数示例 [bit_and](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/bit_and.c) +#### 标量函数示例 [bit_and](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/bit_and.c) bit_add 实现多列的按位与功能。如果只有一列,返回这一列。bit_add 忽略空值。 @@ -231,7 +230,7 @@ bit_add 实现多列的按位与功能。如果只有一列,返回这一列。 -### 聚合函数示例1 返回值为数值类型 [l2norm](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/l2norm.c) +#### 聚合函数示例1 返回值为数值类型 [l2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/l2norm.c) l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。 @@ -244,7 +243,7 @@ l2norm 实现了输入列的所有数据的二阶范数,即对每个数据先 -### 聚合函数示例2 返回值为字符串类型 [max_vol](https://github.com/taosdata/TDengine/blob/develop/tests/script/sh/max_vol.c) +#### 聚合函数示例2 返回值为字符串类型 [max_vol](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/max_vol.c) max_vol 实现了从多个输入的电压列中找到最大电压,返回由设备ID + 最大电压所在(行,列)+ 最大电压值 组成的组合字符串值 @@ -268,4 +267,125 @@ select max_vol(vol1,vol2,vol3,deviceid) from battery; {{#include tests/script/sh/max_vol.c}} ``` - \ No newline at end of file + + +## 用 Python 语言实现 UDF + +使用 Python 语言实现 UDF 时,需要实现规定的接口函数 +- 标量函数需要实现标量接口函数 process 。 +- 聚合函数需要实现聚合接口函数 start ,reduce ,finish。 +- 如果需要初始化,实现 init;如果需要清理工作,实现 destroy。 + +### 用 Python 实现标量函数 + +标量函数实现模版如下 +```Python +def init(): + # initialization +def destroy(): + # destroy +def process(input: datablock) -> tuple[output_type]: + # process input datablock, + # datablock.data(row, col) is to access the python object in location(row,col) + # return tuple object consisted of object of type outputtype +``` + +### 用 Python 实现聚合函数 + +聚合函数实现模版如下 +```Python +def init(): + #initialization +def destroy(): + #destroy +def start() -> bytes: + #return serialize(init_state) +def reduce(inputs: datablock, buf: bytes) -> bytes + # deserialize buf to state + # reduce the inputs and state into new_state. + # use inputs.data(i,j) to access python ojbect of location(i,j) + # serialize new_state into new_state_bytes + return new_state_bytes +def finish(buf: bytes) -> output_type: + #return obj of type outputtype +``` + +### Python UDF 接口函数定义 + +#### 标量函数接口 +```Python +def process(input: datablock) -> tuple[output_type]: +``` +- input:datablock 类似二维矩阵,通过成员方法 data(row,col)返回位于 row 行,col 列的 python 对象 +- 返回值是一个 Python 对象元组,每个元素类型为输出类型。 + +#### 聚合函数接口 +```Python +def start() -> bytes: +def reduce(inputs: datablock, buf: bytes) -> bytes +def finish(buf: bytes) -> output_type: +``` + +首先调用 start 生成最初结果 buffer,然后输入数据会被分为多个行数据块,对每个数据块 inputs 和当前中间结果 buf 调用 reduce,得到新的中间结果,最后再调用 finish 从中间结果 buf 产生最终输出,最终输出只能含 0 或 1 条数据。 + + +#### 初始化和销毁接口 +```Python +def init() +def destroy() +``` + +其中 init 完成初始化工作。 destroy 完成清理工作。如果没有初始化工作,无需定义 init 函数。如果没有清理工作,无需定义 destroy 函数。 + +### Python 和 TDengine之间的数据类型映射 + +下表描述了TDengine SQL数据类型和Python数据类型的映射。任何类型的NULL值都映射成Python的None值。 + +| **TDengine SQL数据类型** | **Python数据类型** | +| :-----------------------: | ------------ | +|TINYINT / SMALLINT / INT / BIGINT | int | +|TINYINT UNSIGNED / SMALLINT UNSIGNED / INT UNSIGNED / BIGINT UNSIGNED | int | +|FLOAT / DOUBLE | float | +|BOOL | bool | +|BINARY / VARCHAR / NCHAR | bytes| +|TIMESTAMP | int | +|JSON and other types | 不支持 | + +### Python UDF 环境的安装 +1. 安装 taospyudf 包。此包执行Python UDF程序。 +```bash +sudo pip install taospyudf +ldconfig +``` +2. 如果 Python UDF 程序执行时,通过 PYTHONPATH 引用其它的包,可以设置 taos.cfg 的 UdfdLdLibPath 变量为PYTHONPATH的内容 + +### Python UDF 示例代码 +#### 标量函数示例 [pybitand](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pybitand.py) + +pybitand 实现多列的按位与功能。如果只有一列,返回这一列。pybitand 忽略空值。 + +
+pybitand.py + +```Python +{{#include tests/script/sh/pybitand.py}} +``` + +
+ +#### 聚合函数示例 [pyl2norm](https://github.com/taosdata/TDengine/blob/3.0/tests/script/sh/pyl2norm.py) + +pyl2norm 实现了输入列的所有数据的二阶范数,即对每个数据先平方,再累加求和,最后开方。 + +
+pyl2norm.py + +```c +{{#include tests/script/sh/pyl2norm.py}} +``` + +
+ +## 管理和使用 UDF +在使用 UDF 之前需要先将其加入到 TDengine 系统中。关于如何管理和使用 UDF,请参考[管理和使用 UDF](../12-taos-sql/26-udf.md) + diff --git a/docs/zh/08-connector/14-java.mdx b/docs/zh/08-connector/14-java.mdx index d1c1258365..35332a9602 100644 --- a/docs/zh/08-connector/14-java.mdx +++ b/docs/zh/08-connector/14-java.mdx @@ -36,23 +36,110 @@ REST 连接支持所有能运行 Java 的平台。 请参考[版本支持列表](../#版本支持) +## 最近更新记录 + +| taos-jdbcdriver 版本 | 主要变化 | +| :------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------: | +| 3.2.1 | 新增功能:WebSocket 连接支持 schemaless 与 prepareStatement 写入。变更:consumer poll 返回结果集为 ConsumerRecord,可通过 value() 获取指定结果集数据。 | +| 3.2.0 | 存在连接问题,不推荐使用 | +| 3.1.0 | WebSocket 连接支持订阅功能 | +| 3.0.1 - 3.0.4 | 修复一些情况下结果集数据解析错误的问题。3.0.1 在 JDK 11 环境编译,JDK 8 环境下建议使用其他版本 | +| 3.0.0 | 支持 TDengine 3.0 | +| 2.0.42 | 修在 WebSocket 连接中 wasNull 接口返回值 | +| 2.0.41 | 修正 REST 连接中用户名和密码转码方式 | +| 2.0.39 - 2.0.40 | 增加 REST 连接/请求 超时设置 | +| 2.0.38 | JDBC REST 连接增加批量拉取功能 | +| 2.0.37 | 增加对 json tag 支持 | +| 2.0.36 | 增加对 schemaless 写入支持 | + +**注**:REST 连接中增加 `batchfetch` 参数并设置为 true,将开启 WebSocket 连接。 + +## 处理异常 + +在报错后,通过 SQLException 可以获取到错误的信息和错误码: + +```java +try (Statement statement = connection.createStatement()) { + // executeQuery + ResultSet resultSet = statement.executeQuery(sql); + // print result + printResult(resultSet); +} catch (SQLException e) { + System.out.println("ERROR Message: " + e.getMessage()); + System.out.println("ERROR Code: " + e.getErrorCode()); + e.printStackTrace(); +} +``` + +JDBC 连接器可能报错的错误码包括 4 种: + +- JDBC driver 本身的报错(错误码在 0x2301 到 0x2350 之间) +- 原生连接方法的报错(错误码在 0x2351 到 0x2360 之间) +- 数据订阅的报错(错误码在 0x2371 到 0x2380 之间) +- TDengine 其他功能模块的报错。 + +具体的错误码请参考: + +| Error Code | Description | Suggested Actions | +| ---------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| 0x2301 | connection already closed | 连接已经关闭,检查连接情况,或重新创建连接去执行相关指令。 | +| 0x2302 | this operation is NOT supported currently! | 当前使用接口不支持,可以更换其他连接方式。 | +| 0x2303 | invalid variables | 参数不合法,请检查相应接口规范,调整参数类型及大小。 | +| 0x2304 | statement is closed | statement 已经关闭,请检查 statement 是否关闭后再次使用,或是连接是否正常。 | +| 0x2305 | resultSet is closed | resultSet 结果集已经释放,请检查 resultSet 是否释放后再次使用。 | +| 0x2306 | Batch is empty! | prepareStatement 添加参数后再执行 executeBatch。 | +| 0x2307 | Can not issue data manipulation statements with executeQuery() | 更新操作应该使用 executeUpdate(),而不是 executeQuery()。 | +| 0x2308 | Can not issue SELECT via executeUpdate() | 查询操作应该使用 executeQuery(),而不是 executeUpdate()。 | +| 0x230d | parameter index out of range | 参数越界,请检查参数的合理范围。 | +| 0x230e | connection already closed | 连接已经关闭,请检查 Connection 是否关闭后再次使用,或是连接是否正常。 | +| 0x230f | unknown sql type in tdengine | 请检查 TDengine 支持的 Data Type 类型。 | +| 0x2310 | can't register JDBC-JNI driver | 不能注册 JNI 驱动,请检查 url 是否填写正确。 | +| 0x2312 | url is not set | 请检查 REST 连接 url 是否填写正确。 | +| 0x2314 | numeric value out of range | 请检查获取结果集中数值类型是否使用了正确的接口。 | +| 0x2315 | unknown taos type in tdengine | 在 TDengine 数据类型与 JDBC 数据类型转换时,是否指定了正确的 TDengine 数据类型。 | +| 0x2317 | | REST 连接中使用了错误的请求类型。 | +| 0x2318 | | REST 连接中出现了数据传输异常,请检查网络情况并重试。 | +| 0x2319 | user is required | 创建连接时缺少用户名信息 | +| 0x231a | password is required | 创建连接时缺少密码信息 | +| 0x231c | httpEntity is null, sql: | REST 连接中执行出现异常 | +| 0x2350 | unknown error | 未知异常,请在 github 反馈给开发人员。 | +| 0x2352 | Unsupported encoding | 本地连接下指定了不支持的字符编码集 | +| 0x2353 | internal error of database, please see taoslog for more details | 本地连接执行 prepareStatement 时出现错误,请检查 taos log 进行问题定位。 | +| 0x2354 | JNI connection is NULL | 本地连接执行命令时,Connection 已经关闭。请检查与 TDengine 的连接情况。 | +| 0x2355 | JNI result set is NULL | 本地连接获取结果集,结果集异常,请检查连接情况,并重试。 | +| 0x2356 | invalid num of fields | 本地连接获取结果集的 meta 信息不匹配。 | +| 0x2357 | empty sql string | 填写正确的 SQL 进行执行。 | +| 0x2359 | JNI alloc memory failed, please see taoslog for more details | 本地连接分配内存错误,请检查 taos log 进行问题定位。 | +| 0x2371 | consumer properties must not be null! | 创建订阅时参数为空,请填写正确的参数。 | +| 0x2372 | configs contain empty key, failed to set consumer property | 参数 key 中包含空值,请填写正确的参数。 | +| 0x2373 | failed to set consumer property, | 参数 value 中包含空值,请填写正确的参数。 | +| 0x2375 | topic reference has been destroyed | 创建数据订阅过程中,topic 引用被释放。请检查与 TDengine 的连接情况。 | +| 0x2376 | failed to set consumer topic, topic name is empty | 创建数据订阅过程中,订阅 topic 名称为空。请检查指定的 topic 名称是否填写正确。 | +| 0x2377 | consumer reference has been destroyed | 订阅数据传输通道已经关闭,请检查与 TDengine 的连接情况。 | +| 0x2378 | consumer create error | 创建数据订阅失败,请根据错误信息检查 taos log 进行问题定位。 | +| - | can't create connection with server within | 通过增加参数 httpConnectTimeout 增加连接耗时,或是请检查与 taosAdapter 之间的连接情况。 | +| - | failed to complete the task within the specified time | 通过增加参数 messageWaitTimeout 增加执行耗时,或是请检查与 taosAdapter 之间的连接情况。 | + +- [TDengine Java Connector](https://github.com/taosdata/taos-connector-jdbc/blob/main/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java) + + ## TDengine DataType 和 Java DataType TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下: -| TDengine DataType | JDBCType | -| ----------------- | ---------------------------------- | -| TIMESTAMP | java.sql.Timestamp | -| INT | java.lang.Integer | -| BIGINT | java.lang.Long | -| FLOAT | java.lang.Float | -| DOUBLE | java.lang.Double | -| SMALLINT | java.lang.Short | -| TINYINT | java.lang.Byte | -| BOOL | java.lang.Boolean | -| BINARY | byte array | -| NCHAR | java.lang.String | -| JSON | java.lang.String | +| TDengine DataType | JDBCType | +| ----------------- | ------------------ | +| TIMESTAMP | java.sql.Timestamp | +| INT | java.lang.Integer | +| BIGINT | java.lang.Long | +| FLOAT | java.lang.Float | +| DOUBLE | java.lang.Double | +| SMALLINT | java.lang.Short | +| TINYINT | java.lang.Byte | +| BOOL | java.lang.Boolean | +| BINARY | byte array | +| NCHAR | java.lang.String | +| JSON | java.lang.String | **注意**:JSON 类型仅在 tag 中支持。 @@ -82,7 +169,7 @@ Maven 项目中,在 pom.xml 中添加以下依赖: com.taosdata.jdbc taos-jdbcdriver - 3.0.0 + 3.2.1 ``` @@ -97,7 +184,7 @@ cd taos-connector-jdbc mvn clean install -Dmaven.test.skip=true ``` -编译后,在 target 目录下会产生 taos-jdbcdriver-3.0.*-dist.jar 的 jar 包,并自动将编译的 jar 文件放在本地的 Maven 仓库中。 +编译后,在 target 目录下会产生 taos-jdbcdriver-3.2.\*-dist.jar 的 jar 包,并自动将编译的 jar 文件放在本地的 Maven 仓库中。 @@ -230,7 +317,7 @@ INSERT INTO test.t1 USING test.weather (ts, temperature) TAGS('California.SanFra **注意**: - 应用中设置的 client parameter 为进程级别的,即如果要更新 client 的参数,需要重启应用。这是因为 client parameter 是全局参数,仅在应用程序的第一次设置生效。 -- 以下示例代码基于 taos-jdbcdriver-3.0.0。 +- 以下示例代码基于 taos-jdbcdriver-3.1.0。 ```java public Connection getConn() throws Exception{ @@ -272,7 +359,7 @@ properties 中的配置参数如下: - TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 5000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 - TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 3000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 - TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 -此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 + 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](/reference/config/#仅客户端适用)。 ### 配置参数的优先级 @@ -336,30 +423,6 @@ while(resultSet.next()){ > 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。 -### 处理异常 - -在报错后,通过 SQLException 可以获取到错误的信息和错误码: - -```java -try (Statement statement = connection.createStatement()) { - // executeQuery - ResultSet resultSet = statement.executeQuery(sql); - // print result - printResult(resultSet); -} catch (SQLException e) { - System.out.println("ERROR Message: " + e.getMessage()); - System.out.println("ERROR Code: " + e.getErrorCode()); - e.printStackTrace(); -} -``` - -JDBC 连接器可能报错的错误码包括 3 种:JDBC driver 本身的报错(错误码在 0x2301 到 0x2350 之间),原生连接方法的报错(错误码在 0x2351 到 0x2400 之间),TDengine 其他功能模块的报错。 - -具体的错误码请参考: - -- [TDengine Java Connector](https://github.com/taosdata/taos-connector-jdbc/blob/main/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java) - - ### 通过参数绑定写入数据 TDengine 的 JDBC 原生连接实现大幅改进了参数绑定方式对数据写入(INSERT)场景的支持。采用这种方式写入数据时,能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。 @@ -367,9 +430,12 @@ TDengine 的 JDBC 原生连接实现大幅改进了参数绑定方式对数据 **注意**: - JDBC REST 连接目前不支持参数绑定 -- 以下示例代码基于 taos-jdbcdriver-3.0.0 +- 以下示例代码基于 taos-jdbcdriver-3.2.1 - binary 类型数据需要调用 setString 方法,nchar 类型数据需要调用 setNString 方法 -- setString 和 setNString 都要求用户在 size 参数里声明表定义中对应列的列宽 +- 预处理语句中指定数据库与子表名称不要使用 `db.?`,应直接使用 `?`,然后在 setTableName 中指定数据库,如:`prepareStatement.setTableName("db.t1")`。 + + + ```java public class ParameterBindingDemo { @@ -597,21 +663,7 @@ public class ParameterBindingDemo { } ``` -用于设定 TAGS 取值的方法总共有: - -```java -public void setTagNull(int index, int type) -public void setTagBoolean(int index, boolean value) -public void setTagInt(int index, int value) -public void setTagByte(int index, byte value) -public void setTagShort(int index, short value) -public void setTagLong(int index, long value) -public void setTagTimestamp(int index, long value) -public void setTagFloat(int index, float value) -public void setTagDouble(int index, double value) -public void setTagString(int index, String value) -public void setTagNString(int index, String value) -``` +**注**:setString 和 setNString 都要求用户在 size 参数里声明表定义中对应列的列宽 用于设定 VALUES 数据列的取值的方法总共有: @@ -628,17 +680,203 @@ public void setString(int columnIndex, ArrayList list, int size) throws public void setNString(int columnIndex, ArrayList list, int size) throws SQLException ``` + + + +```java +public class ParameterBindingDemo { + private static final String host = "127.0.0.1"; + private static final Random random = new Random(System.currentTimeMillis()); + private static final int BINARY_COLUMN_SIZE = 30; + private static final String[] schemaList = { + "create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)", + "create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)", + "create table stable3(ts timestamp, f1 bool) tags(t1 bool)", + "create table stable4(ts timestamp, f1 binary(" + BINARY_COLUMN_SIZE + ")) tags(t1 binary(" + BINARY_COLUMN_SIZE + "))", + "create table stable5(ts timestamp, f1 nchar(" + BINARY_COLUMN_SIZE + ")) tags(t1 nchar(" + BINARY_COLUMN_SIZE + "))" + }; + private static final int numOfSubTable = 10, numOfRow = 10; + + public static void main(String[] args) throws SQLException { + + String jdbcUrl = "jdbc:TAOS-RS://" + host + ":6041/?batchfetch=true"; + Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata"); + + init(conn); + + bindInteger(conn); + + bindFloat(conn); + + bindBoolean(conn); + + bindBytes(conn); + + bindString(conn); + + conn.close(); + } + + private static void init(Connection conn) throws SQLException { + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop database if exists test_ws_parabind"); + stmt.execute("create database if not exists test_ws_parabind"); + stmt.execute("use test_ws_parabind"); + for (int i = 0; i < schemaList.length; i++) { + stmt.execute(schemaList[i]); + } + } + } + + private static void bindInteger(Connection conn) throws SQLException { + String sql = "insert into ? using stable1 tags(?,?,?,?) values(?,?,?,?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t1_" + i); + // set tags + pstmt.setTagByte(1, Byte.parseByte(Integer.toString(random.nextInt(Byte.MAX_VALUE)))); + pstmt.setTagShort(2, Short.parseShort(Integer.toString(random.nextInt(Short.MAX_VALUE)))); + pstmt.setTagInt(3, random.nextInt(Integer.MAX_VALUE)); + pstmt.setTagLong(4, random.nextLong()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setByte(2, Byte.parseByte(Integer.toString(random.nextInt(Byte.MAX_VALUE)))); + pstmt.setShort(3, Short.parseShort(Integer.toString(random.nextInt(Short.MAX_VALUE)))); + pstmt.setInt(4, random.nextInt(Integer.MAX_VALUE)); + pstmt.setLong(5, random.nextLong()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindFloat(Connection conn) throws SQLException { + String sql = "insert into ? using stable2 tags(?,?) values(?,?,?)"; + + try(TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t2_" + i); + // set tags + pstmt.setTagFloat(1, random.nextFloat()); + pstmt.setTagDouble(2, random.nextDouble()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setFloat(2, random.nextFloat()); + pstmt.setDouble(3, random.nextDouble()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindBoolean(Connection conn) throws SQLException { + String sql = "insert into ? using stable3 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t3_" + i); + // set tags + pstmt.setTagBoolean(1, random.nextBoolean()); + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setBoolean(2, random.nextBoolean()); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindBytes(Connection conn) throws SQLException { + String sql = "insert into ? using stable4 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t4_" + i); + // set tags + pstmt.setTagString(1, new String("abc")); + + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setString(2, "abc"); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } + + private static void bindString(Connection conn) throws SQLException { + String sql = "insert into ? using stable5 tags(?) values(?,?)"; + + try (TSWSPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSWSPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("t5_" + i); + // set tags + pstmt.setTagNString(1, "California.SanFrancisco"); + + // set columns + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(0, new Timestamp(current + j)); + pstmt.setNString(1, "California.SanFrancisco"); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + } + } +} +``` + + + + +用于设定 TAGS 取值的方法总共有: + +```java +public void setTagNull(int index, int type) +public void setTagBoolean(int index, boolean value) +public void setTagInt(int index, int value) +public void setTagByte(int index, byte value) +public void setTagShort(int index, short value) +public void setTagLong(int index, long value) +public void setTagTimestamp(int index, long value) +public void setTagFloat(int index, float value) +public void setTagDouble(int index, double value) +public void setTagString(int index, String value) +public void setTagNString(int index, String value) +``` + ### 无模式写入 TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议(Line Protocol)、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。 -**注意**: - -- JDBC REST 连接目前不支持无模式写入 -- 以下示例代码基于 taos-jdbcdriver-3.0.0 + + ```java -public class SchemalessInsertTest { +public class SchemalessJniTest { private static final String host = "127.0.0.1"; private static final String lineDemo = "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; private static final String telnetDemo = "stb0_0 1626006833 4 host=host0 interface=eth0"; @@ -666,6 +904,41 @@ public class SchemalessInsertTest { } ``` + + + +```java +public class SchemalessWsTest { + private static final String host = "127.0.0.1"; + private static final String lineDemo = "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; + private static final String telnetDemo = "stb0_0 1626006833 4 host=host0 interface=eth0"; + private static final String jsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + + public static void main(String[] args) throws SQLException { + final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata&batchfetch=true"; + Connection connection = DriverManager.getConnection(url); + init(connection); + + SchemalessWriter writer = new SchemalessWriter(connection, "test_ws_schemaless"); + writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS); + writer.write(telnetDemo, SchemalessProtocolType.TELNET, SchemalessTimestampType.MILLI_SECONDS); + writer.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.SECONDS); + System.exit(0); + } + + private static void init(Connection connection) throws SQLException { + try (Statement stmt = connection.createStatement()) { + stmt.executeUpdate("drop database if exists test_ws_schemaless"); + stmt.executeUpdate("create database if not exists test_ws_schemaless keep 36500"); + stmt.executeUpdate("use test_ws_schemaless"); + } + } +} +``` + + + + ### 数据订阅 TDengine Java 连接器支持订阅功能,应用 API 如下: @@ -702,15 +975,16 @@ TaosConsumer consumer = new TaosConsumer<>(config); - td.connect.type: 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。默认为 jni 方式。 - httpConnectTimeout:创建连接超时参数,单位 ms,默认为 5000 ms。仅在 WebSocket 连接下有效。 - messageWaitTimeout:数据传输超时参数,单位 ms,默认为 10000 ms。仅在 WebSocket 连接下有效。 -其他参数请参考:[Consumer 参数列表](../../../develop/tmq#创建-consumer-以及consumer-group) + 其他参数请参考:[Consumer 参数列表](../../../develop/tmq#创建-consumer-以及consumer-group) #### 订阅消费数据 ```java while(true) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } ``` @@ -761,8 +1035,9 @@ public abstract class ConsumerLoop { while (!shutdown.get()) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } consumer.unsubscribe(); @@ -839,8 +1114,9 @@ public abstract class ConsumerLoop { while (!shutdown.get()) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ResultBean record : records) { - process(record); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); } } consumer.unsubscribe(); @@ -966,20 +1242,6 @@ public static void main(String[] args) throws Exception { 请参考:[JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC) -## 最近更新记录 - -| taos-jdbcdriver 版本 | 主要变化 | -| :------------------: | :----------------------------: | -| 3.1.0 | WebSocket 连接支持订阅功能 | -| 3.0.1 - 3.0.4 | 修复一些情况下结果集数据解析错误的问题。3.0.1 在 JDK 11 环境编译,JDK 8 环境下建议使用其他版本 | -| 3.0.0 | 支持 TDengine 3.0 | -| 2.0.42 | 修在 WebSocket 连接中 wasNull 接口返回值 | -| 2.0.41 | 修正 REST 连接中用户名和密码转码方式 | -| 2.0.39 - 2.0.40 | 增加 REST 连接/请求 超时设置 | -| 2.0.38 | JDBC REST 连接增加批量拉取功能 | -| 2.0.37 | 增加对 json tag 支持 | -| 2.0.36 | 增加对 schemaless 写入支持 | - ## 常见问题 1. 使用 Statement 的 `addBatch()` 和 `executeBatch()` 来执行“批量写入/更新”,为什么没有带来性能上的提升? @@ -1002,9 +1264,9 @@ public static void main(String[] args) throws Exception { 4. java.lang.NoSuchMethodError: setByteArray -**原因**:taos-jdbcdriver 3.* 版本仅支持 TDengine 3.0 及以上版本。 +**原因**:taos-jdbcdriver 3.\* 版本仅支持 TDengine 3.0 及以上版本。 -**解决方法**: 使用 taos-jdbcdriver 2.* 版本连接 TDengine 2.* 版本。 +**解决方法**: 使用 taos-jdbcdriver 2.\* 版本连接 TDengine 2.\* 版本。 5. java.lang.NoSuchMethodError: java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer; ... taos-jdbcdriver-3.0.1.jar diff --git a/docs/zh/08-connector/26-rust.mdx b/docs/zh/08-connector/26-rust.mdx index eeb93a6558..d4ca25be81 100644 --- a/docs/zh/08-connector/26-rust.mdx +++ b/docs/zh/08-connector/26-rust.mdx @@ -10,6 +10,7 @@ import TabItem from '@theme/TabItem'; import Preparation from "./_preparation.mdx" import RustInsert from "../07-develop/03-insert-data/_rust_sql.mdx" import RustBind from "../07-develop/03-insert-data/_rust_stmt.mdx" +import RustSml from "../07-develop/03-insert-data/_rust_schemaless.mdx" import RustQuery from "../07-develop/04-query-data/_rust.mdx" [![Crates.io](https://img.shields.io/crates/v/taos)](https://crates.io/crates/taos) ![Crates.io](https://img.shields.io/crates/d/taos) [![docs.rs](https://img.shields.io/docsrs/taos)](https://docs.rs/taos) @@ -230,6 +231,10 @@ async fn demo(taos: &Taos, db: &str) -> Result<(), Error> { +#### Schemaless 写入 + + + ### 查询数据 diff --git a/docs/zh/08-connector/index.md b/docs/zh/08-connector/index.md index eb1f3a9a9a..bb8c95a15a 100644 --- a/docs/zh/08-connector/index.md +++ b/docs/zh/08-connector/index.md @@ -61,7 +61,7 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器 | **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | | **参数绑定** | 暂不支持 | 暂不支持 | 支持 | 支持 | 暂不支持 | 支持 | | **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 暂不支持 | 暂不支持 | 支持 | -| **Schemaless** | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | +| **Schemaless** | 支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | | **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | | **DataFrame** | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | diff --git a/docs/zh/12-taos-sql/02-database.md b/docs/zh/12-taos-sql/02-database.md index dd30635660..a2a0914120 100644 --- a/docs/zh/12-taos-sql/02-database.md +++ b/docs/zh/12-taos-sql/02-database.md @@ -71,8 +71,8 @@ database_option: { - 0:表示可以创建多张超级表。 - 1:表示只可以创建一张超级表。 - STT_TRIGGER:表示落盘文件触发文件合并的个数。默认为 1,范围 1 到 16。对于少表高频场景,此参数建议使用默认配置,或较小的值;而对于多表低频场景,此参数建议配置较大的值。 -- TABLE_PREFIX:内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的前缀的长度。 -- TABLE_SUFFIX:内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的后缀的长度。 +- TABLE_PREFIX:当其为正值时,在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的前缀;当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的前缀;例如,假定表名为 "v30001",当 TSDB_PREFIX = 2 时 使用 "0001" 来决定分配到哪个 vgroup ,当 TSDB_PREFIX = -2 时使用 "v3" 来决定分配到哪个 vgroup +- TABLE_SUFFIX:当其为正值时,在决定把一个表分配到哪个 vgroup 时要忽略表名中指定长度的后缀;当其为负值时,在决定把一个表分配到哪个 vgroup 时只使用表名中指定长度的后缀;例如,假定表名为 "v30001",当 TSDB_SUFFIX = 2 时 使用 "v300" 来决定分配到哪个 vgroup ,当 TSDB_SUFFIX = -2 时使用 "01" 来决定分配到哪个 vgroup。 - TSDB_PAGESIZE:一个 VNODE 中时序数据存储引擎的页大小,单位为 KB,默认为 4 KB。范围为 1 到 16384,即 1 KB到 16 MB。 - WAL_RETENTION_PERIOD: 为了数据订阅消费,需要WAL日志文件额外保留的最大时长策略。WAL日志清理,不受订阅客户端消费状态影响。单位为 s。默认为 0,表示无需为订阅保留。新建订阅,应先设置恰当的时长策略。 - WAL_RETENTION_SIZE:为了数据订阅消费,需要WAL日志文件额外保留的最大累计大小策略。单位为 KB。默认为 0,表示累计大小无上限。 diff --git a/docs/zh/12-taos-sql/04-stable.md b/docs/zh/12-taos-sql/04-stable.md index 74ef52ee7c..93decf190d 100644 --- a/docs/zh/12-taos-sql/04-stable.md +++ b/docs/zh/12-taos-sql/04-stable.md @@ -33,7 +33,7 @@ column_definition: SHOW STABLES [LIKE tb_name_wildcard]; ``` -查看数据库内全部 STable,及其相关信息,包括 STable 的名称、创建时间、列数量、标签(TAG)数量、通过该 STable 建表的数量。 +查看数据库内全部超级表。 ### 显示一个超级表的创建语句 diff --git a/docs/zh/12-taos-sql/06-select.md b/docs/zh/12-taos-sql/06-select.md index e4ba5b76e4..870df73471 100644 --- a/docs/zh/12-taos-sql/06-select.md +++ b/docs/zh/12-taos-sql/06-select.md @@ -55,7 +55,7 @@ window_clause: { | INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)] interp_clause: - RANGE(ts_val, ts_val), EVERY(every_val), FILL(fill_mod_and_val) + RANGE(ts_val, ts_val) EVERY(every_val) FILL(fill_mod_and_val) partition_by_clause: PARTITION BY expr [, expr] ... diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md index 50e82e6b90..458fc9c7a2 100644 --- a/docs/zh/12-taos-sql/10-function.md +++ b/docs/zh/12-taos-sql/10-function.md @@ -888,7 +888,7 @@ INTERP(expr) - INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1 <= timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。 - INTERP 根据 EVERY(time_unit) 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(time_unit 值)进行插值,time_unit 可取值时间单位:1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。例如 EVERY(500a) 将对于指定数据每500毫秒间隔进行一次插值. - INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。关于 FILL 子句如何使用请参考 [FILL 子句](../distinguished/#fill-子句) -- INTERP 只能在一个时间序列内进行插值,因此当作用于超级表时必须跟 partition by tbname 一起使用。 +- INTERP 作用于超级表时, 会将该超级表下的所有子表数据按照主键列排序后进行插值计算,也可以搭配 PARTITION BY tbname 使用,将结果强制规约到单个时间线。 - INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.2.0版本以后支持)。 - INTERP 可以与伪列 _isfilled 一起使用,显示返回结果是否为原始记录或插值算法产生的数据(3.0.3.0版本以后支持)。 diff --git a/docs/zh/12-taos-sql/14-stream.md b/docs/zh/12-taos-sql/14-stream.md index 12e466f349..634f50356d 100644 --- a/docs/zh/12-taos-sql/14-stream.md +++ b/docs/zh/12-taos-sql/14-stream.md @@ -15,6 +15,7 @@ stream_options: { IGNORE EXPIRED [0|1] DELETE_MARK time FILL_HISTORY [0|1] + IGNORE UPDATE [0|1] } ``` @@ -169,7 +170,7 @@ T3 时刻,最新事件到达,T 向后推移超过了第二个窗口关闭的 在 window_close 或 max_delay 模式下,窗口关闭直接影响推送结果。在 at_once 模式下,窗口关闭只与内存占用有关。 -## 流式计算的过期数据处理策略 +## 流式计算对于过期数据的处理策略 对于已关闭的窗口,再次落入该窗口中的数据被标记为过期数据. @@ -177,11 +178,20 @@ TDengine 对于过期数据提供两种处理方式,由 IGNORE EXPIRED 选项 1. 重新计算,即 IGNORE EXPIRED 0:从 TSDB 中重新查找对应窗口的所有数据并重新计算得到最新结果 -2. 直接丢弃, 即 IGNORE EXPIRED 1:默认配置,忽略过期数据 +2. 直接丢弃,即 IGNORE EXPIRED 1:默认配置,忽略过期数据 无论在哪种模式下,watermark 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。 +## 流式计算对于修改数据的处理策略 + +TDengine 对于修改数据提供两种处理方式,由 IGNORE UPDATE 选项指定: + +1. 检查数据是否被修改,即 IGNORE UPDATE 0:默认配置,如果被修改,则重新计算对应窗口。 + +2. 不检查数据是否被修改,全部按增量数据计算,即 IGNORE UPDATE 1。 + + ## 写入已存在的超级表 ```sql [field1_name,...] @@ -213,3 +223,29 @@ DELETE_MARK time ``` DELETE_MARK用于删除缓存的窗口状态,也就是删除流计算的中间结果。如果不设置,默认值是10年 T = 最新事件时间 - DELETE_MARK + +## 流式计算支持的函数 + +1. 所有的 [单行函数](../function/#单行函数) 均可用于流计算。 +2. 以下 19 个聚合/选择函数 不能 应用在创建流计算的 SQL 语句。此外的其他类型的函数均可用于流计算。 + +- [leastsquares](../function/#leastsquares) +- [percentile](../function/#percentile) +- [top](../function/#top) +- [bottom](../function/#bottom) +- [elapsed](../function/#elapsed) +- [interp](../function/#interp) +- [derivative](../function/#derivative) +- [irate](../function/#irate) +- [twa](../function/#twa) +- [histogram](../function/#histogram) +- [diff](../function/#diff) +- [statecount](../function/#statecount) +- [stateduration](../function/#stateduration) +- [csum](../function/#csum) +- [mavg](../function/#mavg) +- [sample](../function/#sample) +- [tail](../function/#tail) +- [unique](../function/#unique) +- [mode](../function/#mode) + diff --git a/docs/zh/12-taos-sql/22-meta.md b/docs/zh/12-taos-sql/22-meta.md index 1f2e3fb7d5..7fb60b85a7 100644 --- a/docs/zh/12-taos-sql/22-meta.md +++ b/docs/zh/12-taos-sql/22-meta.md @@ -120,6 +120,10 @@ TDengine 内置了一个名为 `INFORMATION_SCHEMA` 的数据库,提供对数 | 5 | create_time | TIMESTAMP | 创建时间 | | 6 | code_len | INT | 代码长度 | | 7 | bufsize | INT | buffer 大小 | +| 8 | func_language | BINARY(31) | 自定义函数编程语言 | +| 9 | func_body | BINARY(16384) | 函数体定义 | +| 10 | func_version | INT | 函数版本号。初始版本为0,每次替换更新,版本号加1。| + ## INS_INDEXES diff --git a/docs/zh/12-taos-sql/24-show.md b/docs/zh/12-taos-sql/24-show.md index ab29a1ee50..12ad665e42 100644 --- a/docs/zh/12-taos-sql/24-show.md +++ b/docs/zh/12-taos-sql/24-show.md @@ -129,6 +129,14 @@ SHOW QNODES; 显示当前系统中 QNODE (查询节点)的信息。 +## SHOW QUERIES + +```sql +SHOW QUERIES; +``` + +显示当前系统中正在进行的查询。 + ## SHOW SCORES ```sql diff --git a/docs/zh/12-taos-sql/26-udf.md b/docs/zh/12-taos-sql/26-udf.md index 7697944f9a..c1d2761d7d 100644 --- a/docs/zh/12-taos-sql/26-udf.md +++ b/docs/zh/12-taos-sql/26-udf.md @@ -13,27 +13,34 @@ description: 使用 UDF 的详细指南 - 创建标量函数 ```sql -CREATE FUNCTION function_name AS library_path OUTPUTTYPE output_type; +CREATE [OR REPLACE] FUNCTION function_name AS library_path OUTPUTTYPE output_type [LANGUAGE 'C|Python']; ``` - - - function_name:标量函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udf 的实际名称一致; - - library_path:包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; + - OR REPLACE: 如果函数已经存在,会修改已有的函数属性。 + - function_name:标量函数未来在 SQL 中被调用时的函数名; + - LANGUAGE 'C|Python':函数编程语言,目前支持C语言和Python语言。 如果这个从句忽略,编程语言是C语言 + - library_path:如果编程语言是C,路径是包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件)。如果编程语言是Python,路径是包含 UDF 函数实现的Python文件路径。这个路径需要用英文单引号或英文双引号括起来; - output_type:此函数计算结果的数据类型名称; - 例如,如下语句可以把 libbitand.so 创建为系统中可用的 UDF: +例如,如下语句可以把 libbitand.so 创建为系统中可用的 UDF: ```sql CREATE FUNCTION bit_and AS "/home/taos/udf_example/libbitand.so" OUTPUTTYPE INT; ``` +例如,使用以下语句可以修改已经定义的 bit_and 函数,输出类型是 BIGINT,使用Python语言实现。 + + ```sql + CREATE OR REPLACE FUNCTION bit_and AS "/home/taos/udf_example/bit_and.py" OUTPUTTYPE BIGINT LANGUAGE 'Python'; + ``` - 创建聚合函数: ```sql -CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ]; +CREATE [OR REPLACE] AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ BUFSIZE buffer_size ] [LANGUAGE 'C|Python']; ``` - + - OR REPLACE: 如果函数已经存在,会修改已有的函数属性。 - function_name:聚合函数未来在 SQL 中被调用时的函数名,必须与函数实现中 udfNormalFunc 的实际名称一致; - - library_path:包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件),这个路径需要用英文单引号或英文双引号括起来; - - output_type:此函数计算结果的数据类型,与上文中 udfNormalFunc 的 itype 参数不同,这里不是使用数字表示法,而是直接写类型名称即可; + - LANGUAGE 'C|Python':函数编程语言,目前支持C语言和Python语言。 + - library_path:如果编程语言是C,路径是包含 UDF 函数实现的动态链接库的库文件绝对路径(指的是库文件在当前客户端所在主机上的保存路径,通常是指向一个 .so 文件)。如果编程语言是Python,路径是包含 UDF 函数实现的Python文件路径。这个路径需要用英文单引号或英文双引号括起来;; + - output_type:此函数计算结果的数据类型名称; - buffer_size:中间计算结果的缓冲区大小,单位是字节。如果不使用可以不设置。 例如,如下语句可以把 libl2norm.so 创建为系统中可用的 UDF: @@ -41,6 +48,11 @@ CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [ ```sql CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 8; ``` + 例如,使用以下语句可以修改已经定义的 l2norm 函数的缓冲区大小为64。 + ```sql + CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 64; + ``` + 关于如何开发自定义函数,请参考 [UDF使用说明](/develop/udf)。 ## 管理 UDF diff --git a/docs/zh/12-taos-sql/29-changes.md b/docs/zh/12-taos-sql/29-changes.md index a797966f57..27dd3294b7 100644 --- a/docs/zh/12-taos-sql/29-changes.md +++ b/docs/zh/12-taos-sql/29-changes.md @@ -27,13 +27,13 @@ description: "TDengine 3.0 版本的语法变更说明" | - | :------- | :-------- | :------- | | 1 | ALTER ACCOUNT | 废除 | 2.x中为企业版功能,3.0不再支持。语法暂时保留了,执行报“This statement is no longer supported”错误。 | 2 | ALTER ALL DNODES | 新增 | 修改所有DNODE的参数。 -| 3 | ALTER DATABASE | 调整 | 废除
  • QUORUM:写入需要的副本确认数。3.0 版本默认行为是强一致性,且不支持修改为弱一致性。
  • BLOCKS:VNODE使用的内存块数。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • UPDATE:更新操作的支持模式。3.0版本所有数据库都支持部分列更新。
  • CACHELAST:缓存最新一行数据的模式。3.0版本用CACHEMODEL代替。
  • COMP:3.0版本暂不支持修改。

  • 新增
  • CACHEMODEL:表示是否在内存中缓存子表的最近数据。
  • CACHESIZE:表示缓存子表最近数据的内存大小。
  • WAL_FSYNC_PERIOD:代替原FSYNC参数。
  • WAL_LEVEL:代替原WAL参数。
  • WAL_RETENTION_PERIOD:3.0.4.0版本新增,wal文件的额外保留策略,用于数据订阅。
  • WAL_RETENTION_SIZE:3.0.4.0版本新增,wal文件的额外保留策略,用于数据订阅。
    调整
  • REPLICA:3.0.0版本暂不支持修改。
  • KEEP:3.0版本新增支持带单位的设置方式。
+| 3 | ALTER DATABASE | 调整 |

废除

  • QUORUM:写入需要的副本确认数。3.0 版本默认行为是强一致性,且不支持修改为弱一致性。
  • BLOCKS:VNODE使用的内存块数。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • UPDATE:更新操作的支持模式。3.0版本所有数据库都支持部分列更新。
  • CACHELAST:缓存最新一行数据的模式。3.0版本用CACHEMODEL代替。
  • COMP:3.0版本暂不支持修改。

新增

  • CACHEMODEL:表示是否在内存中缓存子表的最近数据。
  • CACHESIZE:表示缓存子表最近数据的内存大小。
  • WAL_FSYNC_PERIOD:代替原FSYNC参数。
  • WAL_LEVEL:代替原WAL参数。
  • WAL_RETENTION_PERIOD:3.0.4.0版本新增,wal文件的额外保留策略,用于数据订阅。
  • WAL_RETENTION_SIZE:3.0.4.0版本新增,wal文件的额外保留策略,用于数据订阅。

调整

  • KEEP:3.0版本新增支持带单位的设置方式。
| 4 | ALTER STABLE | 调整 | 废除
  • CHANGE TAG:修改标签列的名称。3.0版本使用RENAME TAG代替。
    新增
  • RENAME TAG:代替原CHANGE TAG子句。
  • COMMENT:修改超级表的注释。
| 5 | ALTER TABLE | 调整 | 废除
  • CHANGE TAG:修改标签列的名称。3.0版本使用RENAME TAG代替。
    新增
  • RENAME TAG:代替原CHANGE TAG子句。
  • COMMENT:修改表的注释。
  • TTL:修改表的生命周期。
| 6 | ALTER USER | 调整 | 废除
  • PRIVILEGE:修改用户权限。3.0版本使用GRANT和REVOKE来授予和回收权限。
    新增
  • ENABLE:启用或停用此用户。
  • SYSINFO:修改用户是否可查看系统信息。
| 7 | COMPACT VNODES | 暂不支持 | 整理指定VNODE的数据。3.0.0版本暂不支持。 | 8 | CREATE ACCOUNT | 废除 | 2.x中为企业版功能,3.0不再支持。语法暂时保留了,执行报“This statement is no longer supported”错误。 -| 9 | CREATE DATABASE | 调整 | 废除
  • BLOCKS:VNODE使用的内存块数。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • CACHE:VNODE使用的内存块的大小。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • CACHELAST:缓存最新一行数据的模式。3.0版本用CACHEMODEL代替。
  • DAYS:数据文件存储数据的时间跨度。3.0版本使用DURATION代替。
  • FSYNC:当 WAL 设置为 2 时,执行 fsync 的周期。3.0版本使用WAL_FSYNC_PERIOD代替。
  • QUORUM:写入需要的副本确认数。3.0版本使用STRICT来指定强一致还是弱一致。
  • UPDATE:更新操作的支持模式。3.0版本所有数据库都支持部分列更新。
  • WAL:WAL 级别。3.0版本使用WAL_LEVEL代替。
    新增
  • BUFFER:一个 VNODE 写入内存池大小。
  • CACHEMODEL:表示是否在内存中缓存子表的最近数据。
  • CACHESIZE:表示缓存子表最近数据的内存大小。
  • DURATION:代替原DAYS参数。新增支持带单位的设置方式。
  • PAGES:一个 VNODE 中元数据存储引擎的缓存页个数。
  • PAGESIZE:一个 VNODE 中元数据存储引擎的页大小。
  • RETENTIONS:表示数据的聚合周期和保存时长。
  • STRICT:表示数据同步的一致性要求。
  • SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表。
  • VGROUPS:数据库中初始VGROUP的数目。
  • WAL_FSYNC_PERIOD:代替原FSYNC参数。
  • WAL_LEVEL:代替原WAL参数。
  • WAL_RETENTION_PERIOD:wal文件的额外保留策略,用于数据订阅。
  • WAL_RETENTION_SIZE:wal文件的额外保留策略,用于数据订阅。
  • WAL_ROLL_PERIOD:wal文件切换时长。
  • WAL_SEGMENT_SIZE:wal单个文件大小。
    调整
  • KEEP:3.0版本新增支持带单位的设置方式。
+| 9 | CREATE DATABASE | 调整 |

废除

  • BLOCKS:VNODE使用的内存块数。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • CACHE:VNODE使用的内存块的大小。3.0版本使用BUFFER来表示VNODE写入内存池的大小。
  • CACHELAST:缓存最新一行数据的模式。3.0版本用CACHEMODEL代替。
  • DAYS:数据文件存储数据的时间跨度。3.0版本使用DURATION代替。
  • FSYNC:当 WAL 设置为 2 时,执行 fsync 的周期。3.0版本使用WAL_FSYNC_PERIOD代替。
  • QUORUM:写入需要的副本确认数。3.0版本使用STRICT来指定强一致还是弱一致。
  • UPDATE:更新操作的支持模式。3.0版本所有数据库都支持部分列更新。
  • WAL:WAL 级别。3.0版本使用WAL_LEVEL代替。

新增

  • BUFFER:一个 VNODE 写入内存池大小。
  • CACHEMODEL:表示是否在内存中缓存子表的最近数据。
  • CACHESIZE:表示缓存子表最近数据的内存大小。
  • DURATION:代替原DAYS参数。新增支持带单位的设置方式。
  • PAGES:一个 VNODE 中元数据存储引擎的缓存页个数。
  • PAGESIZE:一个 VNODE 中元数据存储引擎的页大小。
  • RETENTIONS:表示数据的聚合周期和保存时长。
  • STRICT:表示数据同步的一致性要求。
  • SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表。
  • VGROUPS:数据库中初始VGROUP的数目。
  • WAL_FSYNC_PERIOD:代替原FSYNC参数。
  • WAL_LEVEL:代替原WAL参数。
  • WAL_RETENTION_PERIOD:wal文件的额外保留策略,用于数据订阅。
  • WAL_RETENTION_SIZE:wal文件的额外保留策略,用于数据订阅。
  • WAL_ROLL_PERIOD:wal文件切换时长。
  • WAL_SEGMENT_SIZE:wal单个文件大小。

调整

  • KEEP:3.0版本新增支持带单位的设置方式。
| 10 | CREATE DNODE | 调整 | 新增主机名和端口号分开指定语法
  • CREATE DNODE dnode_host_name PORT port_val
| 11 | CREATE INDEX | 新增 | 创建SMA索引。 | 12 | CREATE MNODE | 新增 | 创建管理节点。 diff --git a/docs/zh/14-reference/06-taosdump.md b/docs/zh/14-reference/06-taosdump.md index 8a031d1473..8ff1287c3e 100644 --- a/docs/zh/14-reference/06-taosdump.md +++ b/docs/zh/14-reference/06-taosdump.md @@ -79,6 +79,7 @@ Usage: taosdump [OPTION...] dbname [tbname ...] -A, --all-databases Dump all databases. -D, --databases=DATABASES Dump inputted databases. Use comma to separate databases' name. + -e, --escape-character Use escaped character for database name -N, --without-property Dump database without its properties. -s, --schemaonly Only dump tables' schema. -y, --answer-yes Input yes for prompt. It will skip data file diff --git a/docs/zh/14-reference/12-config/index.md b/docs/zh/14-reference/12-config/index.md index fe23684fde..2694086f59 100644 --- a/docs/zh/14-reference/12-config/index.md +++ b/docs/zh/14-reference/12-config/index.md @@ -356,7 +356,7 @@ charset 的有效值是 UTF-8。 | 适用范围 | 仅服务端适用 | | 含义 | dnode 支持的最大 vnode 数目 | | 取值范围 | 0-4096 | -| 缺省值 | CPU 核数的 2 倍 | +| 缺省值 | CPU 核数的 2 倍 | ## 性能调优 @@ -366,6 +366,7 @@ charset 的有效值是 UTF-8。 | -------- | ---------------------- | | 适用范围 | 仅服务端适用 | | 含义 | 设置写入线程的最大数量 | +| 取值范围 | 0-1024 | | 缺省值 | | ## 日志相关 @@ -734,7 +735,6 @@ charset 的有效值是 UTF-8。 | 16 | maxTmrCtrl | 是 | 否 | 3.0 行为未知 | | 17 | monitorReplica | 是 | 否 | 由 RAFT 协议管理多副本 | | 18 | smlTagNullName | 是 | 否 | 3.0 行为未知 | -| 19 | keepColumnName | 是 | 否 | 3.0 行为未知 | | 20 | ratioOfQueryCores | 是 | 否 | 由 线程池 相关配置参数决定 | | 21 | maxStreamCompDelay | 是 | 否 | 3.0 行为未知 | | 22 | maxFirstStreamCompDelay | 是 | 否 | 3.0 行为未知 | diff --git a/docs/zh/14-reference/14-taosKeeper.md b/docs/zh/14-reference/14-taosKeeper.md index 12b609584a..b4d35fb240 100644 --- a/docs/zh/14-reference/14-taosKeeper.md +++ b/docs/zh/14-reference/14-taosKeeper.md @@ -111,7 +111,7 @@ Active: inactive (dead) #### 配置文件启动 -执行以下命令即可快速体验 taosKeeper。当不指定 taosKeeper 配置文件时,优先使用 `/etc/taos/keeper.toml` 配置,否则将使用默认配置。 +执行以下命令即可快速体验 taosKeeper。当不指定 taosKeeper 配置文件时,优先使用 `/etc/taos/taoskeeper.toml` 配置,否则将使用默认配置。 ```shell $ taoskeeper -c @@ -156,6 +156,10 @@ database = "log" # 指定需要监控的普通表 tables = [] + +# database options for db storing metrics data +[metrics.databaseoptions] +cachemodel = "none" ``` ### 获取监控指标 @@ -206,7 +210,7 @@ taos_cluster_info_dnodes_total{cluster_id="5981392874047724755"} 1 taos_cluster_info_first_ep{cluster_id="5981392874047724755",value="hlb:6030"} 1 ``` -### check_health +### check\_health ``` $ curl -i http://127.0.0.1:6043/check_health @@ -222,3 +226,29 @@ Content-Length: 19 {"version":"1.0.0"} ``` + +### 集成 Prometheus + +taoskeeper 提供了 `/metrics` 接口,返回了 Prometheus 格式的监控数据,Prometheus 可以从 taoskeeper 抽取监控数据,实现通过 Prometheus 监控 TDengine 的目的。 + +#### 抽取配置 + +Prometheus 提供了 `scrape_configs` 配置如何从 endpoint 抽取监控数据,通常只需要修改 `static_configs` 中的 targets 配置为 taoskeeper 的 endpoint 地址,更多配置信息请参考 [Prometheus 配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)。 + +``` +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + - job_name: "taoskeeper" + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ["localhost:6043"] +``` + +#### Dashboard + +我们提供了 `TaosKeeper Prometheus Dashboard for 3.x` dashboard,提供了和 TDinsight 类似的监控 dashboard。 + +在 Grafana Dashboard 菜单点击 `import`,dashboard ID 填写 `18587`,点击 `Load` 按钮即可导入 `TaosKeeper Prometheus Dashboard for 3.x` dashboard。 + diff --git a/docs/zh/17-operation/10-monitor.md b/docs/zh/17-operation/10-monitor.md index 01a2257286..7def90916c 100644 --- a/docs/zh/17-operation/10-monitor.md +++ b/docs/zh/17-operation/10-monitor.md @@ -54,7 +54,7 @@ TDinsight dashboard 数据来源于 log 库(存放监控数据的默认db, |first\_ep\_dnode\_id|INT||集群 first ep 的 dnode id| |version|VARCHAR||tdengine version。例如:3.0.4.0| |master\_uptime|FLOAT||当前 master 节点的uptime。单位:天| -|monitor_interval|INT||monitor interval。单位:秒| +|monitor\_interval|INT||monitor interval。单位:秒| |dbs\_total|INT||database 总数| |tbs\_total|BIGINT||当前集群 table 总数| |stbs\_total|INT||当前集群 stable 总数| @@ -107,17 +107,17 @@ TDinsight dashboard 数据来源于 log 库(存放监控数据的默认db, |cpu\_system|FLOAT||服务器 cpu 使用率,从 `/proc/stat` 读取| |cpu\_cores|FLOAT||服务器 cpu 核数| |mem\_engine|INT||taosd 内存使用率,从 `/proc//status` 读取| -|mem\_system|INT||服务器内存使用率| +|mem\_system|INT||服务器可用内存| |mem\_total|INT||服务器内存总量,单位 KB| |disk\_engine|INT||| |disk\_used|BIGINT||data dir 挂载的磁盘使用量,单位 bytes| |disk\_total|BIGINT||data dir 挂载的磁盘总容量,单位 bytes| -|net\_in|FLOAT||网络吞吐率,从 `/proc/net/dev` 中读取的 received bytes。单位 bytes per second| -|net\_out|FLOAT||网络吞吐率,从 `/proc/net/dev` 中读取的 transmit bytes。单位 bytes per second| -|io\_read|FLOAT||io 吞吐率,从 `/proc//io` 中读取的 rchar 与上次数值计算之后,计算得到速度。单位 bytes per second| -|io\_write|FLOAT||io 吞吐率,从 `/proc//io` 中读取的 wchar 与上次数值计算之后,计算得到速度。单位 bytes per second| -|io\_read\_disk|FLOAT||磁盘 io 吞吐率,从 `/proc//io` 中读取的 read_bytes。单位 bytes per second| -|io\_write\_disk|FLOAT||磁盘 io 吞吐率,从 `/proc//io` 中读取的 write_bytes。单位 bytes per second| +|net\_in|FLOAT||网络吞吐率,从 `/proc/net/dev` 中读取的 received bytes。单位 kb/s| +|net\_out|FLOAT||网络吞吐率,从 `/proc/net/dev` 中读取的 transmit bytes。单位 kb/s| +|io\_read|FLOAT||io 吞吐率,从 `/proc//io` 中读取的 rchar 与上次数值计算之后,计算得到速度。单位 kb/s| +|io\_write|FLOAT||io 吞吐率,从 `/proc//io` 中读取的 wchar 与上次数值计算之后,计算得到速度。单位 kb/s| +|io\_read\_disk|FLOAT||磁盘 io 吞吐率,从 `/proc//io` 中读取的 read_bytes。单位 kb/s| +|io\_write\_disk|FLOAT||磁盘 io 吞吐率,从 `/proc//io` 中读取的 write_bytes。单位 kb/s| |req\_select|INT||两个间隔内发生的查询请求数目| |req\_select\_rate|FLOAT||两个间隔内的查询请求速度 = `req_select / monitorInterval`| |req\_insert|INT||两个间隔内发生的写入请求,包含的单条数据数目| diff --git a/docs/zh/20-third-party/11-kafka.md b/docs/zh/20-third-party/11-kafka.md index 7fb7738a4f..75d8deebb1 100644 --- a/docs/zh/20-third-party/11-kafka.md +++ b/docs/zh/20-third-party/11-kafka.md @@ -48,15 +48,14 @@ Confluent 提供了 Docker 和二进制包两种安装方式。本文仅介绍 ``` curl -O http://packages.confluent.io/archive/7.1/confluent-7.1.1.tar.gz -tar xzf confluent-7.1.1.tar.gz -C /opt/test +tar xzf confluent-7.1.1.tar.gz -C /opt/ ``` 然后需要把 `$CONFLUENT_HOME/bin` 目录加入 PATH。 ```title=".profile" export CONFLUENT_HOME=/opt/confluent-7.1.1 -PATH=$CONFLUENT_HOME/bin -export PATH +export PATH=$CONFLUENT_HOME/bin:$PATH ``` 以上脚本可以追加到当前用户的 profile 文件(~/.profile 或 ~/.bash_profile) @@ -333,7 +332,15 @@ DROP DATABASE IF EXISTS test; CREATE DATABASE test; USE test; CREATE STABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT); -INSERT INTO d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:05.000',10.30000,219,0.31000) d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:15.000',12.60000,218,0.33000) d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES('2018-10-03 14:38:16.800',12.30000,221,0.31000) d1002 USING meters TAGS(California.SanFrancisco, 3) VALUES('2018-10-03 14:38:16.650',10.30000,218,0.25000) d1003 USING meters TAGS(California.LosAngeles, 2) VALUES('2018-10-03 14:38:05.500',11.80000,221,0.28000) d1003 USING meters TAGS(California.LosAngeles, 2) VALUES('2018-10-03 14:38:16.600',13.40000,223,0.29000) d1004 USING meters TAGS(California.LosAngeles, 3) VALUES('2018-10-03 14:38:05.000',10.80000,223,0.29000) d1004 USING meters TAGS(California.LosAngeles, 3) VALUES('2018-10-03 14:38:06.500',11.50000,221,0.35000); + +INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:05.000',10.30000,219,0.31000) \ + d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:15.000',12.60000,218,0.33000) \ + d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES('2018-10-03 14:38:16.800',12.30000,221,0.31000) \ + d1002 USING meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650',10.30000,218,0.25000) \ + d1003 USING meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500',11.80000,221,0.28000) \ + d1003 USING meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:16.600',13.40000,223,0.29000) \ + d1004 USING meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000',10.80000,223,0.29000) \ + d1004 USING meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:06.500',11.50000,221,0.35000); ``` 使用 TDengine CLI, 执行 SQL 文件。 @@ -388,7 +395,7 @@ confluent local services connect connector status 如果按照前述操作,此时应有两个活跃的 connector。使用下面的命令 unload: ``` -confluent local services connect connector unload TDengineSourceConnector +confluent local services connect connector unload TDengineSinkConnector confluent local services connect connector unload TDengineSourceConnector ``` diff --git a/docs/zh/27-train-faq/01-faq.md b/docs/zh/27-train-faq/01-faq.md index b000619630..9e82ea0af0 100644 --- a/docs/zh/27-train-faq/01-faq.md +++ b/docs/zh/27-train-faq/01-faq.md @@ -77,7 +77,7 @@ description: 一些常见问题的解决方法汇总 - Windows 系统请使用 PowerShell 命令 Test-NetConnection -ComputerName {fqdn} -Port {port} 检测服务段端口是否访问 -11. 也可以使用 taos 程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅:[诊断及其他](https://docs.taosdata.com/3.0-preview/operation/diagnose/)。 +11. 也可以使用 taos 程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅:[诊断及其他](../../operation/diagnose/)。 ### 5. 遇到错误 Unable to resolve FQDN” 怎么办? diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index 0974289c1f..bea0adfa82 100644 --- a/docs/zh/28-releases/01-tdengine.md +++ b/docs/zh/28-releases/01-tdengine.md @@ -10,6 +10,10 @@ TDengine 2.x 各版本安装包请访问[这里](https://www.taosdata.com/all-do import Release from "/components/ReleaseV3"; +## 3.0.4.1 + + + ## 3.0.4.0 diff --git a/docs/zh/28-releases/02-tools.md b/docs/zh/28-releases/02-tools.md index 78926555f1..e13ec68c2e 100644 --- a/docs/zh/28-releases/02-tools.md +++ b/docs/zh/28-releases/02-tools.md @@ -10,6 +10,14 @@ taosTools 各版本安装包下载链接如下: import Release from "/components/ReleaseV3"; +## 2.5.0 + + + +## 2.5.0 + + + ## 2.4.12 diff --git a/examples/c/tmq.c b/examples/c/tmq.c index 83b40c4f20..94545dfaad 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -20,7 +20,8 @@ #include #include "taos.h" -static int running = 1; +static int running = 1; +const char* topic_name = "topicname"; static int32_t msg_process(TAOS_RES* msg) { char buf[1024]; @@ -243,7 +244,7 @@ _end: tmq_list_t* build_topic_list() { tmq_list_t* topicList = tmq_list_new(); - int32_t code = tmq_list_append(topicList, "topicname"); + int32_t code = tmq_list_append(topicList, topic_name); if (code) { tmq_list_destroy(topicList); return NULL; @@ -269,6 +270,31 @@ void basic_consume_loop(tmq_t* tmq) { fprintf(stderr, "%d msg consumed, include %d rows\n", msgCnt, totalRows); } +void consume_repeatly(tmq_t* tmq) { + int32_t numOfAssignment = 0; + tmq_topic_assignment* pAssign = NULL; + + int32_t code = tmq_get_topic_assignment(tmq, topic_name, &pAssign, &numOfAssignment); + if (code != 0) { + fprintf(stderr, "failed to get assignment, reason:%s", tmq_err2str(code)); + } + + // seek to the earliest offset + for(int32_t i = 0; i < numOfAssignment; ++i) { + tmq_topic_assignment* p = &pAssign[i]; + + code = tmq_offset_seek(tmq, topic_name, p->vgId, p->begin); + if (code != 0) { + fprintf(stderr, "failed to seek to %ld, reason:%s", p->begin, tmq_err2str(code)); + } + } + + free(pAssign); + + // let's do it again + basic_consume_loop(tmq); +} + int main(int argc, char* argv[]) { int32_t code; @@ -294,10 +320,13 @@ int main(int argc, char* argv[]) { if ((code = tmq_subscribe(tmq, topic_list))) { fprintf(stderr, "Failed to tmq_subscribe(): %s\n", tmq_err2str(code)); } + tmq_list_destroy(topic_list); basic_consume_loop(tmq); + consume_repeatly(tmq); + code = tmq_consumer_close(tmq); if (code) { fprintf(stderr, "Failed to close consumer: %s\n", tmq_err2str(code)); diff --git a/include/client/taos.h b/include/client/taos.h index a59e203644..d9fd1ca1b8 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -101,6 +101,7 @@ typedef struct TAOS_FIELD_E { #endif typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *res, int code); +typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type); typedef struct TAOS_MULTI_BIND { int buffer_type; @@ -121,6 +122,10 @@ typedef enum { SET_CONF_RET_ERR_TOO_LONG = -6 } SET_CONF_RET_CODE; +typedef enum { + TAOS_NOTIFY_PASSVER = 0, +} TAOS_NOTIFY_TYPE; + #define RET_MSG_LENGTH 1024 typedef struct setConfRet { SET_CONF_RET_CODE retCode; @@ -162,7 +167,7 @@ DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name DLL_EXPORT int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields); DLL_EXPORT int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields); // let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields` -DLL_EXPORT void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields); +DLL_EXPORT void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields); DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert); DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums); @@ -228,6 +233,8 @@ DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList); // set heart beat thread quit mode , if quicByKill 1 then kill thread else quit from inner DLL_EXPORT void taos_set_hb_quit(int8_t quitByKill); +DLL_EXPORT int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type); + /* --------------------------schemaless INTERFACE------------------------------- */ DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision); @@ -265,6 +272,12 @@ DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errst DLL_EXPORT const char *tmq_err2str(int32_t code); /* ------------------------TMQ CONSUMER INTERFACE------------------------ */ +typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; +} tmq_topic_assignment; DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); @@ -273,6 +286,9 @@ DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); +DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, + int32_t *numOfAssignment); +DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); /* ----------------------TMQ CONFIGURATION INTERFACE---------------------- */ diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 2bc67e439f..0544247da2 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -128,6 +128,7 @@ enum { TMQ_MSG_TYPE__POLL_META_RSP, TMQ_MSG_TYPE__EP_RSP, TMQ_MSG_TYPE__TAOSX_RSP, + TMQ_MSG_TYPE__WALINFO_RSP, TMQ_MSG_TYPE__END_RSP, }; diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 2368614e88..8509d39793 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -24,6 +24,12 @@ extern "C" { #endif +#define SLOW_LOG_TYPE_QUERY 0x1 +#define SLOW_LOG_TYPE_INSERT 0x2 +#define SLOW_LOG_TYPE_OTHERS 0x4 +#define SLOW_LOG_TYPE_ALL 0xFFFFFFFF + + // cluster extern char tsFirst[]; extern char tsSecond[]; @@ -118,6 +124,8 @@ extern int32_t tsRedirectFactor; extern int32_t tsRedirectMaxPeriod; extern int32_t tsMaxRetryWaitTime; extern bool tsUseAdapter; +extern int32_t tsSlowLogThreshold; +extern int32_t tsSlowLogScope; // client extern int32_t tsMinSlidingTime; diff --git a/include/common/tgrant.h b/include/common/tgrant.h index 8a47b850c4..46e09a56b6 100644 --- a/include/common/tgrant.h +++ b/include/common/tgrant.h @@ -26,6 +26,10 @@ extern "C" { #include "tgrantCfg.h" #endif +#ifndef GRANTS_COL_MAX_LEN +#define GRANTS_COL_MAX_LEN 196 +#endif + typedef enum { TSDB_GRANT_ALL, TSDB_GRANT_TIME, @@ -47,23 +51,49 @@ typedef enum { int32_t grantCheck(EGrantType grant); #ifndef GRANTS_CFG -#define GRANTS_SCHEMA \ - static const SSysDbTableSchema grantsSchema[] = { \ - {.name = "version", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "expire_time", .bytes = 19 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "expired", .bytes = 5 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "storage", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "timeseries", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "databases", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "users", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "accounts", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "dnodes", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "connections", .bytes = 11 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "streams", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "cpu_cores", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "speed", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ - {.name = "querytime", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ +#ifdef TD_ENTERPRISE +#define GRANTS_SCHEMA \ + static const SSysDbTableSchema grantsSchema[] = { \ + {.name = "version", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "expire_time", .bytes = 19 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "expired", .bytes = 5 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "storage", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "timeseries", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "databases", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "users", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "accounts", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "dnodes", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "connections", .bytes = 11 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "streams", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "cpu_cores", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "speed", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "querytime", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "opc_da", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "opc_ua", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "pi", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "kafka", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "influxdb", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "mqtt", .bytes = GRANTS_COL_MAX_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ } +#else +#define GRANTS_SCHEMA \ + static const SSysDbTableSchema grantsSchema[] = { \ + {.name = "version", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "expire_time", .bytes = 19 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "expired", .bytes = 5 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "storage", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "timeseries", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "databases", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "users", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "accounts", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "dnodes", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "connections", .bytes = 11 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "streams", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "cpu_cores", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "speed", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + {.name = "querytime", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, \ + } +#endif #define GRANT_CFG_ADD #define GRANT_CFG_SET #define GRANT_CFG_GET diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 4cca2d0311..2daa37d453 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -106,6 +106,7 @@ enum { HEARTBEAT_KEY_DBINFO, HEARTBEAT_KEY_STBINFO, HEARTBEAT_KEY_TMQ, + HEARTBEAT_KEY_USER_PASSINFO, }; typedef enum _mgmt_table { @@ -634,6 +635,7 @@ typedef struct { int8_t connType; SEpSet epSet; int32_t svrTimestamp; + int32_t passVer; char sVer[TSDB_VERSION_LEN]; char sDetailVer[128]; } SConnectRsp; @@ -717,6 +719,14 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp); +typedef struct SUserPassVersion { + char user[TSDB_USER_LEN]; + int32_t version; +} SUserPassVersion; + +typedef SGetUserAuthReq SGetUserPassReq; +typedef SUserPassVersion SGetUserPassRsp; + /* * for client side struct, only column id, type, bytes are necessary * But for data in vnode side, we need all the following information. @@ -1047,6 +1057,14 @@ int32_t tSerializeSUserAuthBatchRsp(void* buf, int32_t bufLen, SUserAuthBatchRsp int32_t tDeserializeSUserAuthBatchRsp(void* buf, int32_t bufLen, SUserAuthBatchRsp* pRsp); void tFreeSUserAuthBatchRsp(SUserAuthBatchRsp* pRsp); +typedef struct { + SArray* pArray; // Array of SGetUserPassRsp +} SUserPassBatchRsp; + +int32_t tSerializeSUserPassBatchRsp(void* buf, int32_t bufLen, SUserPassBatchRsp* pRsp); +int32_t tDeserializeSUserPassBatchRsp(void* buf, int32_t bufLen, SUserPassBatchRsp* pRsp); +void tFreeSUserPassBatchRsp(SUserPassBatchRsp* pRsp); + typedef struct { char db[TSDB_DB_FNAME_LEN]; STimeWindow timeRange; @@ -1215,6 +1233,14 @@ typedef struct { SEp ep; } SDnodeEp; +typedef struct { + int32_t id; + int8_t isMnode; + SEp ep; + char active[TSDB_ACTIVE_KEY_LEN]; + char connActive[TSDB_CONN_ACTIVE_KEY_LEN]; +} SDnodeInfo; + typedef struct { int64_t dnodeVer; SDnodeCfg dnodeCfg; @@ -1287,6 +1313,9 @@ typedef struct { int16_t hashSuffix; int32_t tsdbPageSize; int64_t reserved[8]; + int8_t learnerReplica; + int8_t learnerSelfIndex; + SReplica learnerReplicas[TSDB_MAX_LEARNER_REPLICA]; } SCreateVnodeReq; int32_t tSerializeSCreateVnodeReq(void* buf, int32_t bufLen, SCreateVnodeReq* pReq); @@ -1358,7 +1387,10 @@ typedef struct { int8_t replica; SReplica replicas[TSDB_MAX_REPLICA]; int64_t reserved[8]; -} SAlterVnodeReplicaReq; + int8_t learnerSelfIndex; + int8_t learnerReplica; + SReplica learnerReplicas[TSDB_MAX_LEARNER_REPLICA]; +} SAlterVnodeReplicaReq, SAlterVnodeTypeReq; int32_t tSerializeSAlterVnodeReplicaReq(void* buf, int32_t bufLen, SAlterVnodeReplicaReq* pReq); int32_t tDeserializeSAlterVnodeReplicaReq(void* buf, int32_t bufLen, SAlterVnodeReplicaReq* pReq); @@ -1602,6 +1634,21 @@ typedef struct { int32_t tSerializeSDropDnodeReq(void* buf, int32_t bufLen, SDropDnodeReq* pReq); int32_t tDeserializeSDropDnodeReq(void* buf, int32_t bufLen, SDropDnodeReq* pReq); +enum { + RESTORE_TYPE__ALL = 1, + RESTORE_TYPE__MNODE, + RESTORE_TYPE__VNODE, + RESTORE_TYPE__QNODE, +}; + +typedef struct { + int32_t dnodeId; + int8_t restoreType; +} SRestoreDnodeReq; + +int32_t tSerializeSRestoreDnodeReq(void* buf, int32_t bufLen, SRestoreDnodeReq* pReq); +int32_t tDeserializeSRestoreDnodeReq(void* buf, int32_t bufLen, SRestoreDnodeReq* pReq); + typedef struct { int32_t dnodeId; char config[TSDB_DNODE_CONFIG_LEN]; @@ -1630,7 +1677,10 @@ int32_t tDeserializeSCreateDropMQSNodeReq(void* buf, int32_t bufLen, SMCreateQno typedef struct { int8_t replica; SReplica replicas[TSDB_MAX_REPLICA]; -} SDCreateMnodeReq, SDAlterMnodeReq; + int8_t learnerReplica; + SReplica learnerReplicas[TSDB_MAX_LEARNER_REPLICA]; + int64_t lastIndex; +} SDCreateMnodeReq, SDAlterMnodeReq, SDAlterMnodeTypeReq; int32_t tSerializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq); int32_t tDeserializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq); @@ -2800,6 +2850,7 @@ typedef struct { } SMqOffset; typedef struct { + int64_t consumerId; int32_t num; SMqOffset* offsets; } SMqCMCommitOffsetReq; @@ -2867,6 +2918,14 @@ typedef struct { int32_t tEncodeSTqOffset(SEncoder* pEncoder, const STqOffset* pOffset); int32_t tDecodeSTqOffset(SDecoder* pDecoder, STqOffset* pOffset); +typedef struct SMqVgOffset { + int64_t consumerId; + STqOffset offset; +} SMqVgOffset; + +int32_t tEncodeMqVgOffset(SEncoder* pEncoder, const SMqVgOffset* pOffset); +int32_t tDecodeMqVgOffset(SDecoder* pDecoder, SMqVgOffset* pOffset); + typedef struct { SMsgHead head; int32_t taskId; @@ -3132,18 +3191,19 @@ typedef struct { int32_t code; int32_t epoch; int64_t consumerId; + int64_t walsver; + int64_t walever; } SMqRspHead; typedef struct { - SMsgHead head; - char subKey[TSDB_SUBSCRIBE_KEY_LEN]; - int8_t withTbName; - int8_t useSnapshot; - int32_t epoch; - uint64_t reqId; - int64_t consumerId; - int64_t timeout; - // int64_t currentOffset; + SMsgHead head; + char subKey[TSDB_SUBSCRIBE_KEY_LEN]; + int8_t withTbName; + int8_t useSnapshot; + int32_t epoch; + uint64_t reqId; + int64_t consumerId; + int64_t timeout; STqOffsetVal reqOffset; } SMqPollReq; @@ -3178,43 +3238,9 @@ typedef struct { SSchemaWrapper schema; } SMqSubTopicEp; -static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp) { - int32_t tlen = 0; - tlen += taosEncodeString(buf, pTopicEp->topic); - tlen += taosEncodeString(buf, pTopicEp->db); - int32_t sz = taosArrayGetSize(pTopicEp->vgs); - tlen += taosEncodeFixedI32(buf, sz); - for (int32_t i = 0; i < sz; i++) { - SMqSubVgEp* pVgEp = (SMqSubVgEp*)taosArrayGet(pTopicEp->vgs, i); - tlen += tEncodeSMqSubVgEp(buf, pVgEp); - } - tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema); - return tlen; -} - -static FORCE_INLINE void* tDecodeSMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp) { - buf = taosDecodeStringTo(buf, pTopicEp->topic); - buf = taosDecodeStringTo(buf, pTopicEp->db); - int32_t sz; - buf = taosDecodeFixedI32(buf, &sz); - pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp)); - if (pTopicEp->vgs == NULL) { - return NULL; - } - for (int32_t i = 0; i < sz; i++) { - SMqSubVgEp vgEp; - buf = tDecodeSMqSubVgEp(buf, &vgEp); - taosArrayPush(pTopicEp->vgs, &vgEp); - } - buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema); - return buf; -} - -static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) { - taosMemoryFreeClear(pSubTopicEp->schema.pSchema); - pSubTopicEp->schema.nCols = 0; - taosArrayDestroy(pSubTopicEp->vgs); -} +int32_t tEncodeMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp); +void* tDecodeMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp); +void tDeleteMqSubTopicEp(SMqSubTopicEp* pSubTopicEp); typedef struct { SMqRspHead head; @@ -3224,8 +3250,8 @@ typedef struct { void* metaRsp; } SMqMetaRsp; -int32_t tEncodeSMqMetaRsp(SEncoder* pEncoder, const SMqMetaRsp* pRsp); -int32_t tDecodeSMqMetaRsp(SDecoder* pDecoder, SMqMetaRsp* pRsp); +int32_t tEncodeMqMetaRsp(SEncoder* pEncoder, const SMqMetaRsp* pRsp); +int32_t tDecodeMqMetaRsp(SDecoder* pDecoder, SMqMetaRsp* pRsp); typedef struct { SMqRspHead head; @@ -3240,9 +3266,9 @@ typedef struct { SArray* blockSchema; } SMqDataRsp; -int32_t tEncodeSMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp); -int32_t tDecodeSMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp); -void tDeleteSMqDataRsp(SMqDataRsp* pRsp); +int32_t tEncodeMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp); +int32_t tDecodeMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp); +void tDeleteMqDataRsp(SMqDataRsp* pRsp); typedef struct { SMqRspHead head; @@ -3278,7 +3304,7 @@ static FORCE_INLINE int32_t tEncodeSMqAskEpRsp(void** buf, const SMqAskEpRsp* pR tlen += taosEncodeFixedI32(buf, sz); for (int32_t i = 0; i < sz; i++) { SMqSubTopicEp* pVgEp = (SMqSubTopicEp*)taosArrayGet(pRsp->topics, i); - tlen += tEncodeSMqSubTopicEp(buf, pVgEp); + tlen += tEncodeMqSubTopicEp(buf, pVgEp); } return tlen; } @@ -3293,14 +3319,14 @@ static FORCE_INLINE void* tDecodeSMqAskEpRsp(void* buf, SMqAskEpRsp* pRsp) { } for (int32_t i = 0; i < sz; i++) { SMqSubTopicEp topicEp; - buf = tDecodeSMqSubTopicEp(buf, &topicEp); + buf = tDecodeMqSubTopicEp(buf, &topicEp); taosArrayPush(pRsp->topics, &topicEp); } return buf; } static FORCE_INLINE void tDeleteSMqAskEpRsp(SMqAskEpRsp* pRsp) { - taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteSMqSubTopicEp); + taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteMqSubTopicEp); } #define TD_AUTO_CREATE_TABLE 0x1 diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 7e42f3ec59..1f2d597496 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -83,6 +83,8 @@ enum { TD_DEF_MSG_TYPE(TDMT_DND_CONFIG_DNODE, "config-dnode", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_DND_SYSTABLE_RETRIEVE, "dnode-retrieve", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_DND_MAX_MSG, "dnd-max", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_DND_ALTER_MNODE_TYPE, "dnode-alter-mnode-type", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_DND_ALTER_VNODE_TYPE, "dnode-alter-vnode-type", NULL, NULL) TD_NEW_MSG_SEG(TDMT_MND_MSG) TD_DEF_MSG_TYPE(TDMT_MND_CONNECT, "connect", NULL, NULL) @@ -176,6 +178,7 @@ enum { // TD_DEF_MSG_TYPE(TDMT_MND_STREAM_BEGIN_CHECKPOINT, "stream-begin-checkpoint", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_MAX_MSG, "mnd-max", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_BALANCE_VGROUP_LEADER, "balance-vgroup-leader", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_RESTORE_DNODE, "restore-dnode", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_PAUSE_STREAM, "pause-stream", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_RESUME_STREAM, "resume-stream", NULL, NULL) @@ -225,7 +228,6 @@ enum { TD_DEF_MSG_TYPE(TDMT_VND_COMMIT, "vnode-commit", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_CREATE_INDEX, "vnode-create-index", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_DROP_INDEX, "vnode-drop-index", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_VND_DISABLE_WRITE, "vnode-disable-write", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_MAX_MSG, "vnd-max", NULL, NULL) @@ -304,9 +306,11 @@ enum { TD_DEF_MSG_TYPE(TDMT_VND_TMQ_SUBSCRIBE, "vnode-tmq-subscribe", SMqRebVgReq, SMqRebVgRsp) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_DELETE_SUB, "vnode-tmq-delete-sub", SMqVDeleteReq, SMqVDeleteRsp) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_COMMIT_OFFSET, "vnode-tmq-commit-offset", STqOffset, STqOffset) + TD_DEF_MSG_TYPE(TDMT_VND_TMQ_SEEK_TO_OFFSET, "vnode-tmq-seekto-offset", STqOffset, STqOffset) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_ADD_CHECKINFO, "vnode-tmq-add-checkinfo", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_DEL_CHECKINFO, "vnode-del-checkinfo", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_CONSUME, "vnode-tmq-consume", SMqPollReq, SMqDataBlkRsp) + TD_DEF_MSG_TYPE(TDMT_VND_TMQ_VG_WALINFO, "vnode-tmq-vg-walinfo", SMqPollReq, SMqDataBlkRsp) TD_DEF_MSG_TYPE(TDMT_VND_TMQ_MAX_MSG, "vnd-tmq-max", NULL, NULL) diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index f27ed5cff4..79e8cc1bf1 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -16,338 +16,341 @@ #ifndef _TD_COMMON_TOKEN_H_ #define _TD_COMMON_TOKEN_H_ -#define TK_OR 1 -#define TK_AND 2 -#define TK_UNION 3 -#define TK_ALL 4 -#define TK_MINUS 5 -#define TK_EXCEPT 6 -#define TK_INTERSECT 7 -#define TK_NK_BITAND 8 -#define TK_NK_BITOR 9 -#define TK_NK_LSHIFT 10 -#define TK_NK_RSHIFT 11 -#define TK_NK_PLUS 12 -#define TK_NK_MINUS 13 -#define TK_NK_STAR 14 -#define TK_NK_SLASH 15 -#define TK_NK_REM 16 -#define TK_NK_CONCAT 17 -#define TK_CREATE 18 -#define TK_ACCOUNT 19 -#define TK_NK_ID 20 -#define TK_PASS 21 -#define TK_NK_STRING 22 -#define TK_ALTER 23 -#define TK_PPS 24 -#define TK_TSERIES 25 -#define TK_STORAGE 26 -#define TK_STREAMS 27 -#define TK_QTIME 28 -#define TK_DBS 29 -#define TK_USERS 30 -#define TK_CONNS 31 -#define TK_STATE 32 -#define TK_USER 33 -#define TK_ENABLE 34 -#define TK_NK_INTEGER 35 -#define TK_SYSINFO 36 -#define TK_DROP 37 -#define TK_GRANT 38 -#define TK_ON 39 -#define TK_TO 40 -#define TK_REVOKE 41 -#define TK_FROM 42 -#define TK_SUBSCRIBE 43 -#define TK_NK_COMMA 44 -#define TK_READ 45 -#define TK_WRITE 46 -#define TK_NK_DOT 47 -#define TK_WITH 48 -#define TK_DNODE 49 -#define TK_PORT 50 -#define TK_DNODES 51 -#define TK_NK_IPTOKEN 52 -#define TK_FORCE 53 -#define TK_LOCAL 54 -#define TK_QNODE 55 -#define TK_BNODE 56 -#define TK_SNODE 57 -#define TK_MNODE 58 -#define TK_DATABASE 59 -#define TK_USE 60 -#define TK_FLUSH 61 -#define TK_TRIM 62 -#define TK_COMPACT 63 -#define TK_IF 64 -#define TK_NOT 65 -#define TK_EXISTS 66 -#define TK_BUFFER 67 -#define TK_CACHEMODEL 68 -#define TK_CACHESIZE 69 -#define TK_COMP 70 -#define TK_DURATION 71 -#define TK_NK_VARIABLE 72 -#define TK_MAXROWS 73 -#define TK_MINROWS 74 -#define TK_KEEP 75 -#define TK_PAGES 76 -#define TK_PAGESIZE 77 -#define TK_TSDB_PAGESIZE 78 -#define TK_PRECISION 79 -#define TK_REPLICA 80 -#define TK_VGROUPS 81 -#define TK_SINGLE_STABLE 82 -#define TK_RETENTIONS 83 -#define TK_SCHEMALESS 84 -#define TK_WAL_LEVEL 85 -#define TK_WAL_FSYNC_PERIOD 86 -#define TK_WAL_RETENTION_PERIOD 87 -#define TK_WAL_RETENTION_SIZE 88 -#define TK_WAL_ROLL_PERIOD 89 -#define TK_WAL_SEGMENT_SIZE 90 -#define TK_STT_TRIGGER 91 -#define TK_TABLE_PREFIX 92 -#define TK_TABLE_SUFFIX 93 -#define TK_NK_COLON 94 -#define TK_MAX_SPEED 95 -#define TK_START 96 -#define TK_TIMESTAMP 97 -#define TK_END 98 -#define TK_TABLE 99 -#define TK_NK_LP 100 -#define TK_NK_RP 101 -#define TK_STABLE 102 -#define TK_ADD 103 -#define TK_COLUMN 104 -#define TK_MODIFY 105 -#define TK_RENAME 106 -#define TK_TAG 107 -#define TK_SET 108 -#define TK_NK_EQ 109 -#define TK_USING 110 -#define TK_TAGS 111 -#define TK_BOOL 112 -#define TK_TINYINT 113 -#define TK_SMALLINT 114 -#define TK_INT 115 -#define TK_INTEGER 116 -#define TK_BIGINT 117 -#define TK_FLOAT 118 -#define TK_DOUBLE 119 -#define TK_BINARY 120 -#define TK_NCHAR 121 -#define TK_UNSIGNED 122 -#define TK_JSON 123 -#define TK_VARCHAR 124 -#define TK_MEDIUMBLOB 125 -#define TK_BLOB 126 -#define TK_VARBINARY 127 -#define TK_DECIMAL 128 -#define TK_COMMENT 129 -#define TK_MAX_DELAY 130 -#define TK_WATERMARK 131 -#define TK_ROLLUP 132 -#define TK_TTL 133 -#define TK_SMA 134 -#define TK_DELETE_MARK 135 -#define TK_FIRST 136 -#define TK_LAST 137 -#define TK_SHOW 138 -#define TK_PRIVILEGES 139 -#define TK_DATABASES 140 -#define TK_TABLES 141 -#define TK_STABLES 142 -#define TK_MNODES 143 -#define TK_QNODES 144 -#define TK_FUNCTIONS 145 -#define TK_INDEXES 146 -#define TK_ACCOUNTS 147 -#define TK_APPS 148 -#define TK_CONNECTIONS 149 -#define TK_LICENCES 150 -#define TK_GRANTS 151 -#define TK_QUERIES 152 -#define TK_SCORES 153 -#define TK_TOPICS 154 -#define TK_VARIABLES 155 -#define TK_CLUSTER 156 -#define TK_BNODES 157 -#define TK_SNODES 158 -#define TK_TRANSACTIONS 159 -#define TK_DISTRIBUTED 160 -#define TK_CONSUMERS 161 -#define TK_SUBSCRIPTIONS 162 -#define TK_VNODES 163 -#define TK_ALIVE 164 -#define TK_LIKE 165 -#define TK_TBNAME 166 -#define TK_QTAGS 167 -#define TK_AS 168 -#define TK_INDEX 169 -#define TK_FUNCTION 170 -#define TK_INTERVAL 171 -#define TK_COUNT 172 -#define TK_LAST_ROW 173 -#define TK_TOPIC 174 -#define TK_META 175 -#define TK_CONSUMER 176 -#define TK_GROUP 177 -#define TK_DESC 178 -#define TK_DESCRIBE 179 -#define TK_RESET 180 -#define TK_QUERY 181 -#define TK_CACHE 182 -#define TK_EXPLAIN 183 -#define TK_ANALYZE 184 -#define TK_VERBOSE 185 -#define TK_NK_BOOL 186 -#define TK_RATIO 187 -#define TK_NK_FLOAT 188 -#define TK_OUTPUTTYPE 189 -#define TK_AGGREGATE 190 -#define TK_BUFSIZE 191 -#define TK_LANGUAGE 192 -#define TK_REPLACE 193 -#define TK_STREAM 194 -#define TK_INTO 195 -#define TK_PAUSE 196 -#define TK_RESUME 197 -#define TK_TRIGGER 198 -#define TK_AT_ONCE 199 -#define TK_WINDOW_CLOSE 200 -#define TK_IGNORE 201 -#define TK_EXPIRED 202 -#define TK_FILL_HISTORY 203 -#define TK_UPDATE 204 -#define TK_SUBTABLE 205 -#define TK_UNTREATED 206 -#define TK_KILL 207 -#define TK_CONNECTION 208 -#define TK_TRANSACTION 209 -#define TK_BALANCE 210 -#define TK_VGROUP 211 -#define TK_LEADER 212 -#define TK_MERGE 213 -#define TK_REDISTRIBUTE 214 -#define TK_SPLIT 215 -#define TK_DELETE 216 -#define TK_INSERT 217 -#define TK_NULL 218 -#define TK_NK_QUESTION 219 -#define TK_NK_ARROW 220 -#define TK_ROWTS 221 -#define TK_QSTART 222 -#define TK_QEND 223 -#define TK_QDURATION 224 -#define TK_WSTART 225 -#define TK_WEND 226 -#define TK_WDURATION 227 -#define TK_IROWTS 228 -#define TK_ISFILLED 229 -#define TK_CAST 230 -#define TK_NOW 231 -#define TK_TODAY 232 -#define TK_TIMEZONE 233 -#define TK_CLIENT_VERSION 234 -#define TK_SERVER_VERSION 235 -#define TK_SERVER_STATUS 236 -#define TK_CURRENT_USER 237 -#define TK_CASE 238 -#define TK_WHEN 239 -#define TK_THEN 240 -#define TK_ELSE 241 -#define TK_BETWEEN 242 -#define TK_IS 243 -#define TK_NK_LT 244 -#define TK_NK_GT 245 -#define TK_NK_LE 246 -#define TK_NK_GE 247 -#define TK_NK_NE 248 -#define TK_MATCH 249 -#define TK_NMATCH 250 -#define TK_CONTAINS 251 -#define TK_IN 252 -#define TK_JOIN 253 -#define TK_INNER 254 -#define TK_SELECT 255 -#define TK_DISTINCT 256 -#define TK_WHERE 257 -#define TK_PARTITION 258 -#define TK_BY 259 -#define TK_SESSION 260 -#define TK_STATE_WINDOW 261 -#define TK_EVENT_WINDOW 262 -#define TK_SLIDING 263 -#define TK_FILL 264 -#define TK_VALUE 265 -#define TK_VALUE_F 266 -#define TK_NONE 267 -#define TK_PREV 268 -#define TK_NULL_F 269 -#define TK_LINEAR 270 -#define TK_NEXT 271 -#define TK_HAVING 272 -#define TK_RANGE 273 -#define TK_EVERY 274 -#define TK_ORDER 275 -#define TK_SLIMIT 276 -#define TK_SOFFSET 277 -#define TK_LIMIT 278 -#define TK_OFFSET 279 -#define TK_ASC 280 -#define TK_NULLS 281 -#define TK_ABORT 282 -#define TK_AFTER 283 -#define TK_ATTACH 284 -#define TK_BEFORE 285 -#define TK_BEGIN 286 -#define TK_BITAND 287 -#define TK_BITNOT 288 -#define TK_BITOR 289 -#define TK_BLOCKS 290 -#define TK_CHANGE 291 -#define TK_COMMA 292 -#define TK_CONCAT 293 -#define TK_CONFLICT 294 -#define TK_COPY 295 -#define TK_DEFERRED 296 -#define TK_DELIMITERS 297 -#define TK_DETACH 298 -#define TK_DIVIDE 299 -#define TK_DOT 300 -#define TK_EACH 301 -#define TK_FAIL 302 -#define TK_FILE 303 -#define TK_FOR 304 -#define TK_GLOB 305 -#define TK_ID 306 -#define TK_IMMEDIATE 307 -#define TK_IMPORT 308 -#define TK_INITIALLY 309 -#define TK_INSTEAD 310 -#define TK_ISNULL 311 -#define TK_KEY 312 -#define TK_MODULES 313 -#define TK_NK_BITNOT 314 -#define TK_NK_SEMI 315 -#define TK_NOTNULL 316 -#define TK_OF 317 -#define TK_PLUS 318 -#define TK_PRIVILEGE 319 -#define TK_RAISE 320 -#define TK_RESTRICT 321 -#define TK_ROW 322 -#define TK_SEMI 323 -#define TK_STAR 324 -#define TK_STATEMENT 325 -#define TK_STRICT 326 -#define TK_STRING 327 -#define TK_TIMES 328 -#define TK_VALUES 329 -#define TK_VARIABLE 330 -#define TK_VIEW 331 -#define TK_WAL 332 +#define TK_OR 1 +#define TK_AND 2 +#define TK_UNION 3 +#define TK_ALL 4 +#define TK_MINUS 5 +#define TK_EXCEPT 6 +#define TK_INTERSECT 7 +#define TK_NK_BITAND 8 +#define TK_NK_BITOR 9 +#define TK_NK_LSHIFT 10 +#define TK_NK_RSHIFT 11 +#define TK_NK_PLUS 12 +#define TK_NK_MINUS 13 +#define TK_NK_STAR 14 +#define TK_NK_SLASH 15 +#define TK_NK_REM 16 +#define TK_NK_CONCAT 17 +#define TK_CREATE 18 +#define TK_ACCOUNT 19 +#define TK_NK_ID 20 +#define TK_PASS 21 +#define TK_NK_STRING 22 +#define TK_ALTER 23 +#define TK_PPS 24 +#define TK_TSERIES 25 +#define TK_STORAGE 26 +#define TK_STREAMS 27 +#define TK_QTIME 28 +#define TK_DBS 29 +#define TK_USERS 30 +#define TK_CONNS 31 +#define TK_STATE 32 +#define TK_USER 33 +#define TK_ENABLE 34 +#define TK_NK_INTEGER 35 +#define TK_SYSINFO 36 +#define TK_DROP 37 +#define TK_GRANT 38 +#define TK_ON 39 +#define TK_TO 40 +#define TK_REVOKE 41 +#define TK_FROM 42 +#define TK_SUBSCRIBE 43 +#define TK_NK_COMMA 44 +#define TK_READ 45 +#define TK_WRITE 46 +#define TK_NK_DOT 47 +#define TK_WITH 48 +#define TK_DNODE 49 +#define TK_PORT 50 +#define TK_DNODES 51 +#define TK_RESTORE 52 +#define TK_NK_IPTOKEN 53 +#define TK_FORCE 54 +#define TK_LOCAL 55 +#define TK_QNODE 56 +#define TK_BNODE 57 +#define TK_SNODE 58 +#define TK_MNODE 59 +#define TK_VNODE 60 +#define TK_DATABASE 61 +#define TK_USE 62 +#define TK_FLUSH 63 +#define TK_TRIM 64 +#define TK_COMPACT 65 +#define TK_IF 66 +#define TK_NOT 67 +#define TK_EXISTS 68 +#define TK_BUFFER 69 +#define TK_CACHEMODEL 70 +#define TK_CACHESIZE 71 +#define TK_COMP 72 +#define TK_DURATION 73 +#define TK_NK_VARIABLE 74 +#define TK_MAXROWS 75 +#define TK_MINROWS 76 +#define TK_KEEP 77 +#define TK_PAGES 78 +#define TK_PAGESIZE 79 +#define TK_TSDB_PAGESIZE 80 +#define TK_PRECISION 81 +#define TK_REPLICA 82 +#define TK_VGROUPS 83 +#define TK_SINGLE_STABLE 84 +#define TK_RETENTIONS 85 +#define TK_SCHEMALESS 86 +#define TK_WAL_LEVEL 87 +#define TK_WAL_FSYNC_PERIOD 88 +#define TK_WAL_RETENTION_PERIOD 89 +#define TK_WAL_RETENTION_SIZE 90 +#define TK_WAL_ROLL_PERIOD 91 +#define TK_WAL_SEGMENT_SIZE 92 +#define TK_STT_TRIGGER 93 +#define TK_TABLE_PREFIX 94 +#define TK_TABLE_SUFFIX 95 +#define TK_NK_COLON 96 +#define TK_MAX_SPEED 97 +#define TK_START 98 +#define TK_TIMESTAMP 99 +#define TK_END 100 +#define TK_TABLE 101 +#define TK_NK_LP 102 +#define TK_NK_RP 103 +#define TK_STABLE 104 +#define TK_ADD 105 +#define TK_COLUMN 106 +#define TK_MODIFY 107 +#define TK_RENAME 108 +#define TK_TAG 109 +#define TK_SET 110 +#define TK_NK_EQ 111 +#define TK_USING 112 +#define TK_TAGS 113 +#define TK_BOOL 114 +#define TK_TINYINT 115 +#define TK_SMALLINT 116 +#define TK_INT 117 +#define TK_INTEGER 118 +#define TK_BIGINT 119 +#define TK_FLOAT 120 +#define TK_DOUBLE 121 +#define TK_BINARY 122 +#define TK_NCHAR 123 +#define TK_UNSIGNED 124 +#define TK_JSON 125 +#define TK_VARCHAR 126 +#define TK_MEDIUMBLOB 127 +#define TK_BLOB 128 +#define TK_VARBINARY 129 +#define TK_DECIMAL 130 +#define TK_COMMENT 131 +#define TK_MAX_DELAY 132 +#define TK_WATERMARK 133 +#define TK_ROLLUP 134 +#define TK_TTL 135 +#define TK_SMA 136 +#define TK_DELETE_MARK 137 +#define TK_FIRST 138 +#define TK_LAST 139 +#define TK_SHOW 140 +#define TK_PRIVILEGES 141 +#define TK_DATABASES 142 +#define TK_TABLES 143 +#define TK_STABLES 144 +#define TK_MNODES 145 +#define TK_QNODES 146 +#define TK_FUNCTIONS 147 +#define TK_INDEXES 148 +#define TK_ACCOUNTS 149 +#define TK_APPS 150 +#define TK_CONNECTIONS 151 +#define TK_LICENCES 152 +#define TK_GRANTS 153 +#define TK_QUERIES 154 +#define TK_SCORES 155 +#define TK_TOPICS 156 +#define TK_VARIABLES 157 +#define TK_CLUSTER 158 +#define TK_BNODES 159 +#define TK_SNODES 160 +#define TK_TRANSACTIONS 161 +#define TK_DISTRIBUTED 162 +#define TK_CONSUMERS 163 +#define TK_SUBSCRIPTIONS 164 +#define TK_VNODES 165 +#define TK_ALIVE 166 +#define TK_LIKE 167 +#define TK_TBNAME 168 +#define TK_QTAGS 169 +#define TK_AS 170 +#define TK_INDEX 171 +#define TK_FUNCTION 172 +#define TK_INTERVAL 173 +#define TK_COUNT 174 +#define TK_LAST_ROW 175 +#define TK_TOPIC 176 +#define TK_META 177 +#define TK_CONSUMER 178 +#define TK_GROUP 179 +#define TK_DESC 180 +#define TK_DESCRIBE 181 +#define TK_RESET 182 +#define TK_QUERY 183 +#define TK_CACHE 184 +#define TK_EXPLAIN 185 +#define TK_ANALYZE 186 +#define TK_VERBOSE 187 +#define TK_NK_BOOL 188 +#define TK_RATIO 189 +#define TK_NK_FLOAT 190 +#define TK_OUTPUTTYPE 191 +#define TK_AGGREGATE 192 +#define TK_BUFSIZE 193 +#define TK_LANGUAGE 194 +#define TK_REPLACE 195 +#define TK_STREAM 196 +#define TK_INTO 197 +#define TK_PAUSE 198 +#define TK_RESUME 199 +#define TK_TRIGGER 200 +#define TK_AT_ONCE 201 +#define TK_WINDOW_CLOSE 202 +#define TK_IGNORE 203 +#define TK_EXPIRED 204 +#define TK_FILL_HISTORY 205 +#define TK_UPDATE 206 +#define TK_SUBTABLE 207 +#define TK_UNTREATED 208 +#define TK_KILL 209 +#define TK_CONNECTION 210 +#define TK_TRANSACTION 211 +#define TK_BALANCE 212 +#define TK_VGROUP 213 +#define TK_LEADER 214 +#define TK_MERGE 215 +#define TK_REDISTRIBUTE 216 +#define TK_SPLIT 217 +#define TK_DELETE 218 +#define TK_INSERT 219 +#define TK_NULL 220 +#define TK_NK_QUESTION 221 +#define TK_NK_ARROW 222 +#define TK_ROWTS 223 +#define TK_QSTART 224 +#define TK_QEND 225 +#define TK_QDURATION 226 +#define TK_WSTART 227 +#define TK_WEND 228 +#define TK_WDURATION 229 +#define TK_IROWTS 230 +#define TK_ISFILLED 231 +#define TK_CAST 232 +#define TK_NOW 233 +#define TK_TODAY 234 +#define TK_TIMEZONE 235 +#define TK_CLIENT_VERSION 236 +#define TK_SERVER_VERSION 237 +#define TK_SERVER_STATUS 238 +#define TK_CURRENT_USER 239 +#define TK_CASE 240 +#define TK_WHEN 241 +#define TK_THEN 242 +#define TK_ELSE 243 +#define TK_BETWEEN 244 +#define TK_IS 245 +#define TK_NK_LT 246 +#define TK_NK_GT 247 +#define TK_NK_LE 248 +#define TK_NK_GE 249 +#define TK_NK_NE 250 +#define TK_MATCH 251 +#define TK_NMATCH 252 +#define TK_CONTAINS 253 +#define TK_IN 254 +#define TK_JOIN 255 +#define TK_INNER 256 +#define TK_SELECT 257 +#define TK_DISTINCT 258 +#define TK_WHERE 259 +#define TK_PARTITION 260 +#define TK_BY 261 +#define TK_SESSION 262 +#define TK_STATE_WINDOW 263 +#define TK_EVENT_WINDOW 264 +#define TK_SLIDING 265 +#define TK_FILL 266 +#define TK_VALUE 267 +#define TK_VALUE_F 268 +#define TK_NONE 269 +#define TK_PREV 270 +#define TK_NULL_F 271 +#define TK_LINEAR 272 +#define TK_NEXT 273 +#define TK_HAVING 274 +#define TK_RANGE 275 +#define TK_EVERY 276 +#define TK_ORDER 277 +#define TK_SLIMIT 278 +#define TK_SOFFSET 279 +#define TK_LIMIT 280 +#define TK_OFFSET 281 +#define TK_ASC 282 +#define TK_NULLS 283 +#define TK_ABORT 284 +#define TK_AFTER 285 +#define TK_ATTACH 286 +#define TK_BEFORE 287 +#define TK_BEGIN 288 +#define TK_BITAND 289 +#define TK_BITNOT 290 +#define TK_BITOR 291 +#define TK_BLOCKS 292 +#define TK_CHANGE 293 +#define TK_COMMA 294 +#define TK_CONCAT 295 +#define TK_CONFLICT 296 +#define TK_COPY 297 +#define TK_DEFERRED 298 +#define TK_DELIMITERS 299 +#define TK_DETACH 300 +#define TK_DIVIDE 301 +#define TK_DOT 302 +#define TK_EACH 303 +#define TK_FAIL 304 +#define TK_FILE 305 +#define TK_FOR 306 +#define TK_GLOB 307 +#define TK_ID 308 +#define TK_IMMEDIATE 309 +#define TK_IMPORT 310 +#define TK_INITIALLY 311 +#define TK_INSTEAD 312 +#define TK_ISNULL 313 +#define TK_KEY 314 +#define TK_MODULES 315 +#define TK_NK_BITNOT 316 +#define TK_NK_SEMI 317 +#define TK_NOTNULL 318 +#define TK_OF 319 +#define TK_PLUS 320 +#define TK_PRIVILEGE 321 +#define TK_RAISE 322 +#define TK_RESTRICT 323 +#define TK_ROW 324 +#define TK_SEMI 325 +#define TK_STAR 326 +#define TK_STATEMENT 327 +#define TK_STRICT 328 +#define TK_STRING 329 +#define TK_TIMES 330 +#define TK_VALUES 331 +#define TK_VARIABLE 332 +#define TK_VIEW 333 +#define TK_WAL 334 + #define TK_NK_SPACE 600 #define TK_NK_COMMENT 601 diff --git a/include/dnode/mnode/mnode.h b/include/dnode/mnode/mnode.h index cdb1642a5c..6c3c7497b1 100644 --- a/include/dnode/mnode/mnode.h +++ b/include/dnode/mnode/mnode.h @@ -20,6 +20,7 @@ #include "tmsg.h" #include "tmsgcb.h" #include "trpc.h" +#include "sync.h" #ifdef __cplusplus extern "C" { @@ -33,8 +34,11 @@ typedef struct { bool deploy; int8_t selfIndex; int8_t numOfReplicas; - SReplica replicas[TSDB_MAX_REPLICA]; + int8_t numOfTotalReplicas; + SReplica replicas[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + int32_t nodeRoles[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; SMsgCb msgCb; + int64_t lastIndex; } SMnodeOpt; /* ------------------------ SMnode ------------------------ */ @@ -69,6 +73,9 @@ int32_t mndStart(SMnode *pMnode); */ void mndStop(SMnode *pMnode); +int32_t mndIsCatchUp(SMnode *pMnode); +ESyncRole mndGetRole(SMnode *pMnode); + /** * @brief Get mnode monitor info. * diff --git a/include/libs/function/function.h b/include/libs/function/function.h index aa5c78195a..85f7cf7e2c 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -99,11 +99,11 @@ typedef struct SSubsidiaryResInfo { } SSubsidiaryResInfo; typedef struct SResultDataInfo { - int16_t precision; - int16_t scale; - int16_t type; - int16_t bytes; - int32_t interBufSize; + int16_t precision; + int16_t scale; + int16_t type; + uint16_t bytes; + int32_t interBufSize; } SResultDataInfo; #define GET_RES_INFO(ctx) ((ctx)->resultInfo) diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index 3c68c1d4f3..d899307d74 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -350,6 +350,11 @@ typedef struct SDropComponentNodeStmt { int32_t dnodeId; } SDropComponentNodeStmt; +typedef struct SRestoreComponentNodeStmt { + ENodeType type; + int32_t dnodeId; +} SRestoreComponentNodeStmt; + typedef struct SCreateTopicStmt { ENodeType type; char topicName[TSDB_TABLE_NAME_LEN]; diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index eb449fb646..8eda9457c6 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -211,6 +211,10 @@ typedef enum ENodeType { QUERY_NODE_SHOW_DB_ALIVE_STMT, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT, QUERY_NODE_BALANCE_VGROUP_LEADER_STMT, + QUERY_NODE_RESTORE_DNODE_STMT, + QUERY_NODE_RESTORE_QNODE_STMT, + QUERY_NODE_RESTORE_MNODE_STMT, + QUERY_NODE_RESTORE_VNODE_STMT, QUERY_NODE_PAUSE_STREAM_STMT, QUERY_NODE_RESUME_STREAM_STMT, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index ad4b59714c..197a5ecaf9 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -185,6 +185,7 @@ typedef struct SMergeLogicNode { int32_t numOfChannels; int32_t srcGroupId; bool groupSort; + bool ignoreGroupId; } SMergeLogicNode; typedef enum EWindowType { @@ -444,6 +445,7 @@ typedef struct SMergePhysiNode { int32_t numOfChannels; int32_t srcGroupId; bool groupSort; + bool ignoreGroupId; } SMergePhysiNode; typedef struct SWinodwPhysiNode { diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 558203052f..94fb6824d2 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -114,7 +114,7 @@ STableDataCxt* smlInitTableDataCtx(SQuery* query, STableMeta* pTableMeta); int32_t smlBindData(SQuery* handle, bool dataFormat, SArray* tags, SArray* colsSchema, SArray* cols, STableMeta* pTableMeta, char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl, - char* msgBuf, int16_t msgBufLen); + char* msgBuf, int32_t msgBufLen); int32_t smlBuildOutput(SQuery* handle, SHashObj* pVgHash); int rawBlockBindData(SQuery *query, STableMeta* pTableMeta, void* data, SVCreateTbReq* pCreateTb, TAOS_FIELD *fields, int numFields, bool needChangeLength); diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index c5a7847803..c7e55650cd 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -204,8 +204,6 @@ static FORCE_INLINE void streamQueueProcessFail(SStreamQueue* queue) { atomic_store_8(&queue->status, STREAM_QUEUE__FAILED); } -static FORCE_INLINE void* streamQueueCurItem(SStreamQueue* queue) { return queue->qItem; } - void* streamQueueNextItem(SStreamQueue* queue); SStreamDataSubmit2* streamDataSubmitNew(SPackedData submit, int32_t type); @@ -238,6 +236,7 @@ typedef struct { void* vnode; // not available to encoder and decoder FTbSink* tbSinkFunc; STSchema* pTSchema; + SSHashObj* pTblInfo; } STaskSinkTb; typedef void FSmaSink(void* vnode, int64_t smaId, const SArray* data); diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index fdb4506cf3..e86a4f9690 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -55,6 +55,8 @@ extern "C" { #define SYNC_INDEX_INVALID -1 #define SYNC_TERM_INVALID -1 +#define SYNC_LEARNER_CATCHUP 10 + typedef enum { SYNC_STRATEGY_NO_SNAPSHOT = 0, SYNC_STRATEGY_STANDARD_SNAPSHOT = 1, @@ -76,19 +78,29 @@ typedef enum { TAOS_SYNC_STATE_CANDIDATE = 101, TAOS_SYNC_STATE_LEADER = 102, TAOS_SYNC_STATE_ERROR = 103, + TAOS_SYNC_STATE_LEARNER = 104, } ESyncState; +typedef enum { + TAOS_SYNC_ROLE_VOTER = 0, + TAOS_SYNC_ROLE_LEARNER = 1, + TAOS_SYNC_ROLE_ERROR = 2, +} ESyncRole; + typedef struct SNodeInfo { - int64_t clusterId; - int32_t nodeId; - uint16_t nodePort; - char nodeFqdn[TSDB_FQDN_LEN]; + int64_t clusterId; + int32_t nodeId; + uint16_t nodePort; + char nodeFqdn[TSDB_FQDN_LEN]; + ESyncRole nodeRole; } SNodeInfo; typedef struct SSyncCfg { + int32_t totalReplicaNum; int32_t replicaNum; int32_t myIndex; - SNodeInfo nodeInfo[TSDB_MAX_REPLICA]; + SNodeInfo nodeInfo[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SyncIndex lastIndex; } SSyncCfg; typedef struct SFsmCbMeta { @@ -155,6 +167,7 @@ typedef struct SSyncFSM { void (*FpBecomeLeaderCb)(const struct SSyncFSM* pFsm); void (*FpBecomeFollowerCb)(const struct SSyncFSM* pFsm); + void (*FpBecomeLearnerCb)(const struct SSyncFSM* pFsm); int32_t (*FpGetSnapshot)(const struct SSyncFSM* pFsm, SSnapshot* pSnapshot, void* pReaderParam, void** ppReader); void (*FpGetSnapshotInfo)(const struct SSyncFSM* pFsm, SSnapshot* pSnapshot); @@ -236,6 +249,8 @@ void syncStop(int64_t rid); void syncPreStop(int64_t rid); void syncPostStop(int64_t rid); int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak, int64_t* seq); +int32_t syncIsCatchUp(int64_t rid); +ESyncRole syncGetRole(int64_t rid); int32_t syncProcessMsg(int64_t rid, SRpcMsg* pMsg); int32_t syncReconfig(int64_t rid, SSyncCfg* pCfg); int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex); diff --git a/include/libs/tfs/tfs.h b/include/libs/tfs/tfs.h index cbf1d60e35..622cd615b8 100644 --- a/include/libs/tfs/tfs.h +++ b/include/libs/tfs/tfs.h @@ -133,6 +133,16 @@ int32_t tfsMkdirAt(STfs *pTfs, const char *rname, SDiskID diskId); */ int32_t tfsMkdirRecurAt(STfs *pTfs, const char *rname, SDiskID diskId); +/** + * @brief check directories exist in tfs. + * + * @param pTfs The fs object. + * @param rname The rel name of directory. + * @param diskId The disk ID. + * @return true for exist, false for not exist. + */ +bool tfsDirExistAt(STfs *pTfs, const char *rname, SDiskID diskId); + /** * @brief Remove directory at all levels in tfs. * diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h index 45050e5d64..f737499293 100644 --- a/include/libs/wal/wal.h +++ b/include/libs/wal/wal.h @@ -127,12 +127,12 @@ typedef struct SWal { typedef struct { int64_t refId; int64_t refVer; -// int64_t refFile; - SWal *pWal; + // int64_t refFile; + SWal *pWal; } SWalRef; typedef struct { -// int8_t scanUncommited; + int8_t scanUncommited; int8_t scanNotApplied; int8_t scanMeta; int8_t enableRef; @@ -190,15 +190,16 @@ int32_t walApplyVer(SWal *, int64_t ver); // int32_t walDataCorrupted(SWal*); -// read +// wal reader SWalReader *walOpenReader(SWal *, SWalFilterCond *pCond); void walCloseReader(SWalReader *pRead); void walReadReset(SWalReader *pReader); int32_t walReadVer(SWalReader *pRead, int64_t ver); int32_t walReaderSeekVer(SWalReader *pRead, int64_t ver); int32_t walNextValidMsg(SWalReader *pRead); -int64_t walReaderGetCurrentVer(const SWalReader* pReader); -int64_t walReaderGetValidFirstVer(const SWalReader* pReader); +int64_t walReaderGetCurrentVer(const SWalReader *pReader); +int64_t walReaderGetValidFirstVer(const SWalReader *pReader); +void walReaderValidVersionRange(SWalReader *pReader, int64_t *sver, int64_t *ever); // only for tq usage void walSetReaderCapacity(SWalReader *pRead, int32_t capacity); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 4688c8bb87..8bc6ed2ac8 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -103,7 +103,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_CHECKSUM_ERROR TAOS_DEF_ERROR_CODE(0, 0x011F) // internal #define TSDB_CODE_COMPRESS_ERROR TAOS_DEF_ERROR_CODE(0, 0x0120) -#define TSDB_CODE_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0121) // +#define TSDB_CODE_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0121) #define TSDB_CODE_CFG_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0122) #define TSDB_CODE_REPEAT_INIT TAOS_DEF_ERROR_CODE(0, 0x0123) #define TSDB_CODE_DUP_KEY TAOS_DEF_ERROR_CODE(0, 0x0124) @@ -118,9 +118,10 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MSG_ENCODE_ERROR TAOS_DEF_ERROR_CODE(0, 0x012D) #define TSDB_CODE_NO_ENOUGH_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x012E) -#define TSDB_CODE_APP_IS_STARTING TAOS_DEF_ERROR_CODE(0, 0x0130) // -#define TSDB_CODE_APP_IS_STOPPING TAOS_DEF_ERROR_CODE(0, 0x0131) // -#define TSDB_CODE_IVLD_DATA_FMT TAOS_DEF_ERROR_CODE(0, 0x0132) // +#define TSDB_CODE_APP_IS_STARTING TAOS_DEF_ERROR_CODE(0, 0x0130) +#define TSDB_CODE_APP_IS_STOPPING TAOS_DEF_ERROR_CODE(0, 0x0131) +#define TSDB_CODE_INVALID_DATA_FMT TAOS_DEF_ERROR_CODE(0, 0x0132) +#define TSDB_CODE_INVALID_CFG_VALUE TAOS_DEF_ERROR_CODE(0, 0x0133) //client #define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) @@ -404,6 +405,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_SNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x040F) #define TSDB_CODE_SNODE_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0410) #define TSDB_CODE_SNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0411) +#define TSDB_CODE_MNODE_NOT_CATCH_UP TAOS_DEF_ERROR_CODE(0, 0x0412) // internal +#define TSDB_CODE_MNODE_ALREADY_IS_VOTER TAOS_DEF_ERROR_CODE(0, 0x0413) // internal +#define TSDB_CODE_MNODE_ONLY_TWO_MNODE TAOS_DEF_ERROR_CODE(0, 0x0414) // internal // vnode // #define TSDB_CODE_VND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0500) // 2.x @@ -438,6 +442,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_STOPPED TAOS_DEF_ERROR_CODE(0, 0x0529) #define TSDB_CODE_VND_DUP_REQUEST TAOS_DEF_ERROR_CODE(0, 0x0530) #define TSDB_CODE_VND_QUERY_BUSY TAOS_DEF_ERROR_CODE(0, 0x0531) +#define TSDB_CODE_VND_NOT_CATCH_UP TAOS_DEF_ERROR_CODE(0, 0x0532) // internal +#define TSDB_CODE_VND_ALREADY_IS_VOTER TAOS_DEF_ERROR_CODE(0, 0x0533) // internal +#define TSDB_CODE_VND_DIR_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0534) // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) @@ -535,20 +542,20 @@ int32_t* taosGetErrno(); // #define TSDB_CODE_SYN_INVALID_CHECKSUM TAOS_DEF_ERROR_CODE(0, 0x0908) // 2.x // #define TSDB_CODE_SYN_INVALID_MSGLEN TAOS_DEF_ERROR_CODE(0, 0x0909) // 2.x // #define TSDB_CODE_SYN_INVALID_MSGTYPE TAOS_DEF_ERROR_CODE(0, 0x090A) // 2.x -#define TSDB_CODE_SYN_IS_LEADER TAOS_DEF_ERROR_CODE(0, 0x090B) +// #define TSDB_CODE_SYN_IS_LEADER TAOS_DEF_ERROR_CODE(0, 0x090B) // unused #define TSDB_CODE_SYN_NOT_LEADER TAOS_DEF_ERROR_CODE(0, 0x090C) -#define TSDB_CODE_SYN_ONE_REPLICA TAOS_DEF_ERROR_CODE(0, 0x090D) -#define TSDB_CODE_SYN_NOT_IN_NEW_CONFIG TAOS_DEF_ERROR_CODE(0, 0x090E) -#define TSDB_CODE_SYN_NEW_CONFIG_ERROR TAOS_DEF_ERROR_CODE(0, 0x090F) // internal -#define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910) +// #define TSDB_CODE_SYN_ONE_REPLICA TAOS_DEF_ERROR_CODE(0, 0x090D) // unused +// #define TSDB_CODE_SYN_NOT_IN_NEW_CONFIG TAOS_DEF_ERROR_CODE(0, 0x090E) // unused +#define TSDB_CODE_SYN_NEW_CONFIG_ERROR TAOS_DEF_ERROR_CODE(0, 0x090F) // internal +// #define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910) // unused #define TSDB_CODE_SYN_PROPOSE_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0911) -#define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912) -#define TSDB_CODE_SYN_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913) +// #define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912) // unused +// #define TSDB_CODE_SYN_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913) // unused #define TSDB_CODE_SYN_RESTORING TAOS_DEF_ERROR_CODE(0, 0x0914) -#define TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG TAOS_DEF_ERROR_CODE(0, 0x0915) // internal +#define TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG TAOS_DEF_ERROR_CODE(0, 0x0915) // internal #define TSDB_CODE_SYN_BUFFER_FULL TAOS_DEF_ERROR_CODE(0, 0x0916) #define TSDB_CODE_SYN_WRITE_STALL TAOS_DEF_ERROR_CODE(0, 0x0917) -#define TSDB_CODE_SYN_NEGO_WIN_EXCEEDED TAOS_DEF_ERROR_CODE(0, 0X0918) +#define TSDB_CODE_SYN_NEGOTIATION_WIN_FULL TAOS_DEF_ERROR_CODE(0, 0x0918) #define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF) // tq @@ -569,7 +576,7 @@ int32_t* taosGetErrno(); // wal // #define TSDB_CODE_WAL_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x1000) // 2.x #define TSDB_CODE_WAL_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x1001) -#define TSDB_CODE_WAL_SIZE_LIMIT TAOS_DEF_ERROR_CODE(0, 0x1002) +// #define TSDB_CODE_WAL_SIZE_LIMIT TAOS_DEF_ERROR_CODE(0, 0x1002) // unused #define TSDB_CODE_WAL_INVALID_VER TAOS_DEF_ERROR_CODE(0, 0x1003) // #define TSDB_CODE_WAL_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x1004) // 2.x #define TSDB_CODE_WAL_LOG_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x1005) @@ -713,15 +720,13 @@ int32_t* taosGetErrno(); #define TSDB_CODE_UDF_STOPPING TAOS_DEF_ERROR_CODE(0, 0x2901) #define TSDB_CODE_UDF_PIPE_READ_ERR TAOS_DEF_ERROR_CODE(0, 0x2902) #define TSDB_CODE_UDF_PIPE_CONNECT_ERR TAOS_DEF_ERROR_CODE(0, 0x2903) -#define TSDB_CODE_UDF_PIPE_NO_PIPE TAOS_DEF_ERROR_CODE(0, 0x2904) +#define TSDB_CODE_UDF_PIPE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2904) #define TSDB_CODE_UDF_LOAD_UDF_FAILURE TAOS_DEF_ERROR_CODE(0, 0x2905) -#define TSDB_CODE_UDF_INVALID_STATE TAOS_DEF_ERROR_CODE(0, 0x2906) -#define TSDB_CODE_UDF_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2907) -#define TSDB_CODE_UDF_NO_FUNC_HANDLE TAOS_DEF_ERROR_CODE(0, 0x2908) -#define TSDB_CODE_UDF_INVALID_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x2909) -#define TSDB_CODE_UDF_INVALID_OUTPUT_TYPE TAOS_DEF_ERROR_CODE(0, 0x290A) -#define TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED TAOS_DEF_ERROR_CODE(0, 0x290B) -#define TSDB_CODE_UDF_FUNC_EXEC_FAILURE TAOS_DEF_ERROR_CODE(0, 0x290C) +#define TSDB_CODE_UDF_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2906) +#define TSDB_CODE_UDF_INVALID_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x2907) +#define TSDB_CODE_UDF_INVALID_OUTPUT_TYPE TAOS_DEF_ERROR_CODE(0, 0x2908) +#define TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED TAOS_DEF_ERROR_CODE(0, 0x2909) +#define TSDB_CODE_UDF_FUNC_EXEC_FAILURE TAOS_DEF_ERROR_CODE(0, 0x290A) // sml #define TSDB_CODE_SML_INVALID_PROTOCOL_TYPE TAOS_DEF_ERROR_CODE(0, 0x3000) @@ -734,28 +739,21 @@ int32_t* taosGetErrno(); //tsma #define TSDB_CODE_TSMA_INIT_FAILED TAOS_DEF_ERROR_CODE(0, 0x3100) #define TSDB_CODE_TSMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x3101) -#define TSDB_CODE_TSMA_NO_INDEX_IN_META TAOS_DEF_ERROR_CODE(0, 0x3102) -#define TSDB_CODE_TSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3103) -#define TSDB_CODE_TSMA_INVALID_STAT TAOS_DEF_ERROR_CODE(0, 0x3104) -#define TSDB_CODE_TSMA_INVALID_PTR TAOS_DEF_ERROR_CODE(0, 0x3105) -#define TSDB_CODE_TSMA_INVALID_PARA TAOS_DEF_ERROR_CODE(0, 0x3106) -#define TSDB_CODE_TSMA_NO_INDEX_IN_CACHE TAOS_DEF_ERROR_CODE(0, 0x3107) +#define TSDB_CODE_TSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3102) +#define TSDB_CODE_TSMA_INVALID_STAT TAOS_DEF_ERROR_CODE(0, 0x3103) +#define TSDB_CODE_TSMA_INVALID_PTR TAOS_DEF_ERROR_CODE(0, 0x3104) +#define TSDB_CODE_TSMA_INVALID_PARA TAOS_DEF_ERROR_CODE(0, 0x3105) //rsma #define TSDB_CODE_RSMA_INVALID_ENV TAOS_DEF_ERROR_CODE(0, 0x3150) #define TSDB_CODE_RSMA_INVALID_STAT TAOS_DEF_ERROR_CODE(0, 0x3151) #define TSDB_CODE_RSMA_QTASKINFO_CREATE TAOS_DEF_ERROR_CODE(0, 0x3152) -#define TSDB_CODE_RSMA_FS_COMMIT TAOS_DEF_ERROR_CODE(0, 0x3153) -#define TSDB_CODE_RSMA_REMOVE_EXISTS TAOS_DEF_ERROR_CODE(0, 0x3154) -#define TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x3155) -#define TSDB_CODE_RSMA_EMPTY_INFO TAOS_DEF_ERROR_CODE(0, 0x3156) -#define TSDB_CODE_RSMA_INVALID_SCHEMA TAOS_DEF_ERROR_CODE(0, 0x3157) -#define TSDB_CODE_RSMA_REGEX_MATCH TAOS_DEF_ERROR_CODE(0, 0x3158) -#define TSDB_CODE_RSMA_STREAM_STATE_OPEN TAOS_DEF_ERROR_CODE(0, 0x3159) -#define TSDB_CODE_RSMA_STREAM_STATE_COMMIT TAOS_DEF_ERROR_CODE(0, 0x3160) -#define TSDB_CODE_RSMA_FS_REF TAOS_DEF_ERROR_CODE(0, 0x3161) -#define TSDB_CODE_RSMA_FS_SYNC TAOS_DEF_ERROR_CODE(0, 0x3162) -#define TSDB_CODE_RSMA_FS_UPDATE TAOS_DEF_ERROR_CODE(0, 0x3163) +#define TSDB_CODE_RSMA_INVALID_SCHEMA TAOS_DEF_ERROR_CODE(0, 0x3153) +#define TSDB_CODE_RSMA_STREAM_STATE_OPEN TAOS_DEF_ERROR_CODE(0, 0x3154) +#define TSDB_CODE_RSMA_STREAM_STATE_COMMIT TAOS_DEF_ERROR_CODE(0, 0x3155) +#define TSDB_CODE_RSMA_FS_REF TAOS_DEF_ERROR_CODE(0, 0x3156) +#define TSDB_CODE_RSMA_FS_SYNC TAOS_DEF_ERROR_CODE(0, 0x3157) +#define TSDB_CODE_RSMA_FS_UPDATE TAOS_DEF_ERROR_CODE(0, 0x3158) //index #define TSDB_CODE_INDEX_REBUILDING TAOS_DEF_ERROR_CODE(0, 0x3200) diff --git a/include/util/tdef.h b/include/util/tdef.h index a77663fad6..427a49fd4e 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -232,13 +232,7 @@ typedef enum ELogicConditionType { #define TSDB_QUERY_ID_LEN 26 #define TSDB_TRANS_OPER_LEN 16 -/** - * In some scenarios uint16_t (0~65535) is used to store the row len. - * - Firstly, we use 65531(65535 - 4), as the SDataRow/SKVRow contains 4 bits header. - * - Secondly, if all cols are VarDataT type except primary key, we need 4 bits to store the offset, thus - * the final value is 65531-(4096-1)*4 = 49151. - */ -#define TSDB_MAX_BYTES_PER_ROW 49151 +#define TSDB_MAX_BYTES_PER_ROW 65531 // 49151:65531 #define TSDB_MAX_TAGS_LEN 16384 #define TSDB_MAX_TAGS 128 @@ -273,6 +267,9 @@ typedef enum ELogicConditionType { #define TSDB_DNODE_CONFIG_LEN 128 #define TSDB_DNODE_VALUE_LEN 256 +#define TSDB_ACTIVE_KEY_LEN 109 // history 109:? +#define TSDB_CONN_ACTIVE_KEY_LEN 257 // history 257:? + #define TSDB_DEFAULT_PKT_SIZE 65480 // same as RPC_MAX_UDP_SIZE #define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE @@ -285,7 +282,7 @@ typedef enum ELogicConditionType { #define TSDB_DNODE_ROLE_VNODE 2 #define TSDB_MAX_REPLICA 5 - +#define TSDB_MAX_LEARNER_REPLICA 10 #define TSDB_SYNC_LOG_BUFFER_SIZE 4096 #define TSDB_SYNC_LOG_BUFFER_RETENTION 256 #define TSDB_SYNC_APPLYQ_SIZE_LIMIT 512 @@ -410,9 +407,9 @@ typedef enum ELogicConditionType { #define TSDB_EXPLAIN_RESULT_ROW_SIZE (16 * 1024) #define TSDB_EXPLAIN_RESULT_COLUMN_NAME "QUERY_PLAN" -#define TSDB_MAX_FIELD_LEN 16384 -#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN - TSDB_KEYSIZE) // keep 16384 -#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN - TSDB_KEYSIZE) // keep 16384 +#define TSDB_MAX_FIELD_LEN 65519 // 16384:65519 +#define TSDB_MAX_BINARY_LEN TSDB_MAX_FIELD_LEN // 16384-8:65519 +#define TSDB_MAX_NCHAR_LEN TSDB_MAX_FIELD_LEN // 16384-8:65519 #define PRIMARYKEY_TIMESTAMP_COL_ID 1 #define COL_REACH_END(colId, maxColId) ((colId) > (maxColId)) diff --git a/include/util/tlog.h b/include/util/tlog.h index 541b7589b7..5a421033c9 100644 --- a/include/util/tlog.h +++ b/include/util/tlog.h @@ -83,6 +83,12 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons #endif ; +void taosPrintSlowLog(const char *format, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 1, 2))) +#endif + ; + bool taosAssertDebug(bool condition, const char *file, int32_t line, const char *format, ...); bool taosAssertRelease(bool condition); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 46d44d7443..18891bb932 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -63,6 +63,7 @@ typedef struct { // statistics int32_t reportCnt; int32_t connKeyCnt; + int32_t passKeyCnt; // with passVer call back int64_t reportBytes; // not implemented int64_t startTime; // ctl @@ -126,6 +127,12 @@ typedef struct SAppInfo { TdThreadMutex mutex; } SAppInfo; +typedef struct { + int32_t ver; + void* param; + __taos_notify_fn_t fp; +} SPassInfo; + typedef struct STscObj { char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; @@ -141,6 +148,7 @@ typedef struct STscObj { int32_t numOfReqs; // number of sqlObj bound to this connection SAppInstInfo* pAppInfo; SHashObj* pRequests; + SPassInfo passInfo; } STscObj; typedef struct STscDbg { @@ -354,7 +362,7 @@ void stopAllRequests(SHashObj* pRequests); // conn level int hbRegisterConn(SAppHbMgr* pAppHbMgr, int64_t tscRefId, int64_t clusterId, int8_t connType); -void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey); +void hbDeregisterConn(STscObj* pTscObj, SClientHbKey connKey); typedef struct SSqlCallbackWrapper { SParseContext* pParseCtx; diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 418103f2a6..c8f3feb2d4 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -42,7 +42,7 @@ SAppInfo appInfo; int64_t lastClusterId = 0; int32_t clientReqRefPool = -1; int32_t clientConnRefPool = -1; -int32_t clientStop = 0; +int32_t clientStop = -1; int32_t timestampDeltaLimit = 900; // s @@ -69,7 +69,6 @@ static int32_t registerRequest(SRequestObj *pRequest, STscObj *pTscObj) { } static void deregisterRequest(SRequestObj *pRequest) { - const static int64_t SLOW_QUERY_INTERVAL = 3000000L; // todo configurable if (pRequest == NULL) { tscError("pRequest == NULL"); return; @@ -80,6 +79,7 @@ static void deregisterRequest(SRequestObj *pRequest) { int32_t currentInst = atomic_sub_fetch_64((int64_t *)&pActivity->currentRequests, 1); int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1); + int32_t reqType = SLOW_LOG_TYPE_OTHERS; int64_t duration = taosGetTimestampUs() - pRequest->metric.start; tscDebug("0x%" PRIx64 " free Request from connObj: 0x%" PRIx64 ", reqId:0x%" PRIx64 @@ -95,6 +95,7 @@ static void deregisterRequest(SRequestObj *pRequest) { duration, pRequest->metric.parseCostUs, pRequest->metric.ctgCostUs, pRequest->metric.analyseCostUs, pRequest->metric.planCostUs, pRequest->metric.execCostUs); atomic_add_fetch_64((int64_t *)&pActivity->insertElapsedTime, duration); + reqType = SLOW_LOG_TYPE_INSERT; } else if (QUERY_NODE_SELECT_STMT == pRequest->stmtType) { tscDebug("query duration %" PRId64 "us: parseCost:%" PRId64 "us, ctgCost:%" PRId64 "us, analyseCost:%" PRId64 "us, planCost:%" PRId64 "us, exec:%" PRId64 "us", @@ -102,12 +103,16 @@ static void deregisterRequest(SRequestObj *pRequest) { pRequest->metric.planCostUs, pRequest->metric.execCostUs); atomic_add_fetch_64((int64_t *)&pActivity->queryElapsedTime, duration); + reqType = SLOW_LOG_TYPE_QUERY; } } - if (duration >= SLOW_QUERY_INTERVAL) { + if (duration >= (tsSlowLogThreshold * 1000000UL)) { atomic_add_fetch_64((int64_t *)&pActivity->numOfSlowQueries, 1); - tscWarnL("slow query: %s, duration:%" PRId64, pRequest->sqlstr, duration); + if (tsSlowLogScope & reqType) { + taosPrintSlowLog("PID:%d, Conn:%u, QID:0x%" PRIx64 ", Start:%" PRId64 ", Duration:%" PRId64 "us, SQL:%s", + taosGetPId(), pTscObj->connId, pRequest->requestId, pRequest->metric.start, duration, pRequest->sqlstr); + } } releaseTscObj(pTscObj->id); @@ -239,7 +244,7 @@ void destroyTscObj(void *pObj) { tscTrace("begin to destroy tscObj %" PRIx64 " p:%p", tscId, pTscObj); SClientHbKey connKey = {.tscRid = pTscObj->id, .connType = pTscObj->connType}; - hbDeregisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey); + hbDeregisterConn(pTscObj, connKey); destroyAllRequests(pTscObj->pRequests); taosHashCleanup(pTscObj->pRequests); @@ -427,8 +432,12 @@ static void *tscCrashReportThreadFp(void *param) { } #endif + if (-1 != atomic_val_compare_exchange_32(&clientStop, -1, 0)) { + return NULL; + } + while (1) { - if (clientStop) break; + if (clientStop > 0) break; if (loopTimes++ < reportPeriodNum) { taosMsleep(sleepTime); continue; @@ -466,7 +475,7 @@ static void *tscCrashReportThreadFp(void *param) { loopTimes = 0; } - clientStop = -1; + clientStop = -2; return NULL; } diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 8d082ab60b..10c42bb67d 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -19,6 +19,15 @@ #include "scheduler.h" #include "trpc.h" +typedef struct { + union { + struct { + int64_t clusterId; + int32_t passKeyCnt; + }; + }; +} SHbParam; + static SClientHbMgr clientHbMgr = {0}; static int32_t hbCreateThread(); @@ -49,14 +58,60 @@ static int32_t hbProcessUserAuthInfoRsp(void *value, int32_t valueLen, struct SC return TSDB_CODE_SUCCESS; } +static int32_t hbProcessUserPassInfoRsp(void *value, int32_t valueLen, SClientHbKey *connKey, SAppHbMgr *pAppHbMgr) { + int32_t code = 0; + int32_t numOfBatchs = 0; + SUserPassBatchRsp batchRsp = {0}; + if (tDeserializeSUserPassBatchRsp(value, valueLen, &batchRsp) != 0) { + code = TSDB_CODE_INVALID_MSG; + return code; + } + + numOfBatchs = taosArrayGetSize(batchRsp.pArray); + + SClientHbReq *pReq = NULL; + while ((pReq = taosHashIterate(pAppHbMgr->activeInfo, pReq))) { + STscObj *pTscObj = (STscObj *)acquireTscObj(pReq->connKey.tscRid); + if (!pTscObj) { + continue; + } + SPassInfo *passInfo = &pTscObj->passInfo; + if (!passInfo->fp) { + releaseTscObj(pReq->connKey.tscRid); + continue; + } + + for (int32_t i = 0; i < numOfBatchs; ++i) { + SGetUserPassRsp *rsp = taosArrayGet(batchRsp.pArray, i); + if (0 == strncmp(rsp->user, pTscObj->user, TSDB_USER_LEN)) { + int32_t oldVer = atomic_load_32(&passInfo->ver); + if (oldVer < rsp->version) { + atomic_store_32(&passInfo->ver, rsp->version); + if (passInfo->fp) { + (*passInfo->fp)(passInfo->param, &passInfo->ver, TAOS_NOTIFY_PASSVER); + } + tscDebug("update passVer of user %s from %d to %d, tscRid:%" PRIi64, rsp->user, oldVer, + atomic_load_32(&passInfo->ver), pTscObj->id); + } + break; + } + } + releaseTscObj(pReq->connKey.tscRid); + } + + taosArrayDestroy(batchRsp.pArray); + + return code; +} + static int32_t hbGenerateVgInfoFromRsp(SDBVgInfo **pInfo, SUseDbRsp *rsp) { - int32_t code = 0; + int32_t code = 0; SDBVgInfo *vgInfo = taosMemoryCalloc(1, sizeof(SDBVgInfo)); if (NULL == vgInfo) { code = TSDB_CODE_OUT_OF_MEMORY; return code; } - + vgInfo->vgVersion = rsp->vgVersion; vgInfo->stateTs = rsp->stateTs; vgInfo->hashMethod = rsp->hashMethod; @@ -69,7 +124,7 @@ static int32_t hbGenerateVgInfoFromRsp(SDBVgInfo **pInfo, SUseDbRsp *rsp) { code = TSDB_CODE_OUT_OF_MEMORY; goto _return; } - + for (int32_t j = 0; j < rsp->vgNum; ++j) { SVgroupInfo *pInfo = taosArrayGet(rsp->pVgroupInfos, j); if (taosHashPut(vgInfo->vgHash, &pInfo->vgId, sizeof(int32_t), pInfo, sizeof(SVgroupInfo)) != 0) { @@ -123,7 +178,8 @@ static int32_t hbProcessDBInfoRsp(void *value, int32_t valueLen, struct SCatalog goto _return; } - catalogUpdateDBVgInfo(pCatalog, (rsp->db[0] == 'i') ? TSDB_PERFORMANCE_SCHEMA_DB : TSDB_INFORMATION_SCHEMA_DB, rsp->uid, vgInfo); + catalogUpdateDBVgInfo(pCatalog, (rsp->db[0] == 'i') ? TSDB_PERFORMANCE_SCHEMA_DB : TSDB_INFORMATION_SCHEMA_DB, + rsp->uid, vgInfo); } } @@ -291,6 +347,15 @@ static int32_t hbQueryHbRspHandle(SAppHbMgr *pAppHbMgr, SClientHbRsp *pRsp) { hbProcessStbInfoRsp(kv->value, kv->valueLen, pCatalog); break; } + case HEARTBEAT_KEY_USER_PASSINFO: { + if (kv->valueLen <= 0 || NULL == kv->value) { + tscError("invalid hb user pass info, len:%d, value:%p", kv->valueLen, kv->value); + break; + } + + hbProcessUserPassInfoRsp(kv->value, kv->valueLen, &pRsp->connKey, pAppHbMgr); + break; + } default: tscError("invalid hb key type:%d", kv->key); break; @@ -308,7 +373,7 @@ static int32_t hbAsyncCallBack(void *param, SDataBuf *pMsg, int32_t code) { } static int32_t emptyRspNum = 0; - int32_t idx = *(int32_t *)param; + int32_t idx = *(int32_t *)param; SClientHbBatchRsp pRsp = {0}; if (TSDB_CODE_SUCCESS == code) { tDeserializeSClientHbBatchRsp(pMsg->pData, pMsg->len, &pRsp); @@ -339,8 +404,7 @@ static int32_t hbAsyncCallBack(void *param, SDataBuf *pMsg, int32_t code) { if (code != 0) { pInst->onlineDnodes = pInst->totalDnodes ? 0 : -1; - tscDebug("hb rsp error %s, update server status %d/%d", tstrerror(code), pInst->onlineDnodes, - pInst->totalDnodes); + tscDebug("hb rsp error %s, update server status %d/%d", tstrerror(code), pInst->onlineDnodes, pInst->totalDnodes); } if (rspNum) { @@ -472,6 +536,49 @@ int32_t hbGetQueryBasicInfo(SClientHbKey *connKey, SClientHbReq *req) { return TSDB_CODE_SUCCESS; } +static int32_t hbGetUserBasicInfo(SClientHbKey *connKey, SClientHbReq *req) { + STscObj *pTscObj = (STscObj *)acquireTscObj(connKey->tscRid); + if (!pTscObj) { + tscWarn("tscObj rid %" PRIx64 " not exist", connKey->tscRid); + return TSDB_CODE_APP_ERROR; + } + + int32_t code = 0; + SUserPassVersion *user = taosMemoryMalloc(sizeof(SUserPassVersion)); + if (!user) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _return; + } + strncpy(user->user, pTscObj->user, TSDB_USER_LEN); + user->version = htonl(pTscObj->passInfo.ver); + + SKv kv = { + .key = HEARTBEAT_KEY_USER_PASSINFO, + .valueLen = sizeof(SUserPassVersion), + .value = user, + }; + + tscDebug("hb got user basic info, valueLen:%d, user:%s, passVer:%d, tscRid:%" PRIi64, kv.valueLen, user->user, + pTscObj->passInfo.ver, connKey->tscRid); + + if (!req->info) { + req->info = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK); + } + + if (taosHashPut(req->info, &kv.key, sizeof(kv.key), &kv, sizeof(kv)) < 0) { + code = terrno ? terrno : TSDB_CODE_APP_ERROR; + goto _return; + } + +_return: + releaseTscObj(connKey->tscRid); + if (code) { + tscError("hb got user basic info failed since %s", terrstr(code)); + } + + return code; +} + int32_t hbGetExpiredUserInfo(SClientHbKey *connKey, struct SCatalog *pCatalog, SClientHbReq *req) { SUserAuthVersion *users = NULL; uint32_t userNum = 0; @@ -526,8 +633,8 @@ int32_t hbGetExpiredDBInfo(SClientHbKey *connKey, struct SCatalog *pCatalog, SCl for (int32_t i = 0; i < dbNum; ++i) { SDbVgVersion *db = &dbs[i]; - tscDebug("the %dth expired dbFName:%s, dbId:%" PRId64 ", vgVersion:%d, numOfTable:%d, startTs:%" PRId64, - i, db->dbFName, db->dbId, db->vgVersion, db->numOfTable, db->stateTs); + tscDebug("the %dth expired dbFName:%s, dbId:%" PRId64 ", vgVersion:%d, numOfTable:%d, startTs:%" PRId64, i, + db->dbFName, db->dbId, db->vgVersion, db->numOfTable, db->stateTs); db->dbId = htobe64(db->dbId); db->vgVersion = htonl(db->vgVersion); @@ -607,19 +714,23 @@ int32_t hbGetAppInfo(int64_t clusterId, SClientHbReq *req) { } int32_t hbQueryHbReqHandle(SClientHbKey *connKey, void *param, SClientHbReq *req) { - int64_t *clusterId = (int64_t *)param; + SHbParam *hbParam = (SHbParam *)param; struct SCatalog *pCatalog = NULL; - int32_t code = catalogGetHandle(*clusterId, &pCatalog); + int32_t code = catalogGetHandle(hbParam->clusterId, &pCatalog); if (code != TSDB_CODE_SUCCESS) { - tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", *clusterId, tstrerror(code)); + tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", hbParam->clusterId, tstrerror(code)); return code; } - hbGetAppInfo(*clusterId, req); + hbGetAppInfo(hbParam->clusterId, req); hbGetQueryBasicInfo(connKey, req); + if (hbParam->passKeyCnt > 0) { + hbGetUserBasicInfo(connKey, req); + } + code = hbGetExpiredUserInfo(connKey, pCatalog, req); if (TSDB_CODE_SUCCESS != code) { return code; @@ -673,7 +784,26 @@ SClientHbBatchReq *hbGatherAllInfo(SAppHbMgr *pAppHbMgr) { while (pIter != NULL) { pOneReq = taosArrayPush(pBatchReq->reqs, pOneReq); - code = (*clientHbMgr.reqHandle[pOneReq->connKey.connType])(&pOneReq->connKey, &pOneReq->clusterId, pOneReq); + SHbParam param; + switch (pOneReq->connKey.connType) { + case CONN_TYPE__QUERY: { + param.clusterId = pOneReq->clusterId; + param.passKeyCnt = atomic_load_32(&pAppHbMgr->passKeyCnt); + break; + } + default: + break; + } + if (clientHbMgr.reqHandle[pOneReq->connKey.connType]) { + code = (*clientHbMgr.reqHandle[pOneReq->connKey.connType])(&pOneReq->connKey, ¶m, pOneReq); + if (code) { + tscWarn("hbGatherAllInfo failed since %s, tscRid:%" PRIi64 ", connType:%" PRIi8, tstrerror(code), + pOneReq->connKey.tscRid, pOneReq->connKey.connType); + } + } + break; + +#if 0 if (code) { pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); pOneReq = pIter; @@ -682,6 +812,7 @@ SClientHbBatchReq *hbGatherAllInfo(SAppHbMgr *pAppHbMgr) { pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter); pOneReq = pIter; +#endif } releaseTscObj(rid); @@ -856,7 +987,7 @@ static void hbStopThread() { } SAppHbMgr *appHbMgrInit(SAppInstInfo *pAppInstInfo, char *key) { - if(hbMgrInit() != 0){ + if (hbMgrInit() != 0) { terrno = TSDB_CODE_TSC_INTERNAL_ERROR; return NULL; } @@ -868,6 +999,7 @@ SAppHbMgr *appHbMgrInit(SAppInstInfo *pAppInstInfo, char *key) { // init stat pAppHbMgr->startTime = taosGetTimestampMs(); pAppHbMgr->connKeyCnt = 0; + pAppHbMgr->passKeyCnt = 0; pAppHbMgr->reportCnt = 0; pAppHbMgr->reportBytes = 0; pAppHbMgr->key = taosStrdup(key); @@ -946,27 +1078,23 @@ int hbMgrInit() { TdThreadMutexAttr attr = {0}; int ret = taosThreadMutexAttrInit(&attr); - if(ret != 0){ - uError("hbMgrInit:taosThreadMutexAttrInit error") - return ret; + if (ret != 0) { + uError("hbMgrInit:taosThreadMutexAttrInit error") return ret; } ret = taosThreadMutexAttrSetType(&attr, PTHREAD_MUTEX_RECURSIVE); - if(ret != 0){ - uError("hbMgrInit:taosThreadMutexAttrSetType error") - return ret; + if (ret != 0) { + uError("hbMgrInit:taosThreadMutexAttrSetType error") return ret; } ret = taosThreadMutexInit(&clientHbMgr.lock, &attr); - if(ret != 0){ - uError("hbMgrInit:taosThreadMutexInit error") - return ret; + if (ret != 0) { + uError("hbMgrInit:taosThreadMutexInit error") return ret; } ret = taosThreadMutexAttrDestroy(&attr); - if(ret != 0){ - uError("hbMgrInit:taosThreadMutexAttrDestroy error") - return ret; + if (ret != 0) { + uError("hbMgrInit:taosThreadMutexAttrDestroy error") return ret; } // init handle funcs @@ -1028,7 +1156,8 @@ int hbRegisterConn(SAppHbMgr *pAppHbMgr, int64_t tscRefId, int64_t clusterId, in } } -void hbDeregisterConn(SAppHbMgr *pAppHbMgr, SClientHbKey connKey) { +void hbDeregisterConn(STscObj *pTscObj, SClientHbKey connKey) { + SAppHbMgr *pAppHbMgr = pTscObj->pAppInfo->pAppHbMgr; SClientHbReq *pReq = taosHashAcquire(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey)); if (pReq) { tFreeClientHbReq(pReq); @@ -1041,6 +1170,12 @@ void hbDeregisterConn(SAppHbMgr *pAppHbMgr, SClientHbKey connKey) { } atomic_sub_fetch_32(&pAppHbMgr->connKeyCnt, 1); + + taosThreadMutexLock(&pTscObj->mutex); + if (pTscObj->passInfo.fp) { + atomic_sub_fetch_32(&pAppHbMgr->passKeyCnt, 1); + } + taosThreadMutexUnlock(&pTscObj->mutex); } // set heart beat thread quit mode , if quicByKill 1 then kill thread else quit from inner diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index ce174744ef..f8eade1d7c 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -1248,6 +1248,11 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t return NULL; } + pRequest->sqlstr = taosStrdup("taos_connect"); + if (pRequest->sqlstr) { + pRequest->sqlLen = strlen(pRequest->sqlstr); + } + SMsgSendInfo* body = buildConnectMsg(pRequest); int64_t transporterId = 0; @@ -1257,7 +1262,7 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t if (pRequest->code != TSDB_CODE_SUCCESS) { const char* errorMsg = (pRequest->code == TSDB_CODE_RPC_FQDN_ERROR) ? taos_errstr(pRequest) : tstrerror(pRequest->code); - fprintf(stderr, "failed to connect to server, reason: %s\n\n", errorMsg); + tscError("failed to connect to server, reason: %s", errorMsg); terrno = pRequest->code; destroyRequest(pRequest); diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index fd70598efb..55337d4a0b 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -119,6 +119,43 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha return NULL; } +int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) { + if (taos == NULL) { + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + STscObj *pObj = acquireTscObj(*(int64_t *)taos); + if (NULL == pObj) { + terrno = TSDB_CODE_TSC_DISCONNECTED; + tscError("invalid parameter for %s", __func__); + return terrno; + } + + switch (type) { + case TAOS_NOTIFY_PASSVER: { + taosThreadMutexLock(&pObj->mutex); + if (fp && !pObj->passInfo.fp) { + atomic_add_fetch_32(&pObj->pAppInfo->pAppHbMgr->passKeyCnt, 1); + } else if (!fp && pObj->passInfo.fp) { + atomic_sub_fetch_32(&pObj->pAppInfo->pAppHbMgr->passKeyCnt, 1); + } + pObj->passInfo.fp = fp; + pObj->passInfo.param = param; + taosThreadMutexUnlock(&pObj->mutex); + break; + } + default: { + terrno = TSDB_CODE_INVALID_PARA; + releaseTscObj(*(int64_t *)taos); + return terrno; + } + } + + releaseTscObj(*(int64_t *)taos); + return 0; +} + void taos_close_internal(void *taos) { if (taos == NULL) { return; @@ -1307,6 +1344,8 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { goto _return; } + pRequest->syncQuery = true; + STscObj *pTscObj = pRequest->pTscObj; code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta); if (code) { @@ -1333,7 +1372,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { tsem_wait(&pParam->sem); _return: - taosArrayDestroy(catalogReq.pTableMeta); + taosArrayDestroyEx(catalogReq.pTableMeta, destoryTablesReq); destroyRequest(pRequest); return code; } diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 032517cafc..6d53f2b4c5 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -129,6 +129,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { lastClusterId = connectRsp.clusterId; pTscObj->connType = connectRsp.connType; + pTscObj->passInfo.ver = connectRsp.passVer; hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType); diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index a09780dc15..32f28e4563 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -1511,7 +1511,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) { rspObj.resType = RES_TYPE__TMQ; tDecoderInit(&decoder, data, dataLen); - code = tDecodeSMqDataRsp(&decoder, &rspObj.rsp); + code = tDecodeMqDataRsp(&decoder, &rspObj.rsp); if (code != 0) { uError("WriteRaw:decode smqDataRsp error"); code = TSDB_CODE_INVALID_MSG; @@ -1615,7 +1615,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) { code = pRequest->code; end: - tDeleteSMqDataRsp(&rspObj.rsp); + tDeleteMqDataRsp(&rspObj.rsp); tDecoderClear(&decoder); qDestroyQuery(pQuery); destroyRequest(pRequest); @@ -1858,7 +1858,7 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { int32_t len = 0; int32_t code = 0; - tEncodeSize(tEncodeSMqDataRsp, &rspObj->rsp, len, code); + tEncodeSize(tEncodeMqDataRsp, &rspObj->rsp, len, code); if (code < 0) { return -1; } @@ -1866,7 +1866,7 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { void* buf = taosMemoryCalloc(1, len); SEncoder encoder = {0}; tEncoderInit(&encoder, buf, len); - tEncodeSMqDataRsp(&encoder, &rspObj->rsp); + tEncodeMqDataRsp(&encoder, &rspObj->rsp); tEncoderClear(&encoder); raw->raw = buf; diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 105934f1b3..6170b0a056 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -195,17 +195,19 @@ int32_t smlSetCTableName(SSmlTableInfo *oneTable) { return TSDB_CODE_SUCCESS; } -void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo){ - char key[TSDB_TABLE_NAME_LEN * 2 + 1] = {0}; +void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo) { + char key[TSDB_TABLE_NAME_LEN * 2 + 1] = {0}; size_t nLen = strlen(tinfo->childTableName); memcpy(key, currElement->measure, currElement->measureLen); memcpy(key + currElement->measureLen + 1, tinfo->childTableName, nLen); - void *uid = taosHashGet(info->tableUids, key, currElement->measureLen + 1 + nLen); // use \0 as separator for stable name and child table name + void *uid = + taosHashGet(info->tableUids, key, + currElement->measureLen + 1 + nLen); // use \0 as separator for stable name and child table name if (uid == NULL) { tinfo->uid = info->uid++; taosHashPut(info->tableUids, key, currElement->measureLen + 1 + nLen, &tinfo->uid, sizeof(uint64_t)); - }else{ - tinfo->uid = *(uint64_t*)uid; + } else { + tinfo->uid = *(uint64_t *)uid; } } @@ -548,7 +550,8 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm uint16_t *index = colHash ? (uint16_t *)taosHashGet(colHash, kv->key, kv->keyLen) : NULL; if (index) { if (colField[*index].type != kv->type) { - uError("SML:0x%" PRIx64 " point type and db type mismatch. db type: %d, point type: %d, key: %s", info->id, colField[*index].type, kv->type, kv->key); + uError("SML:0x%" PRIx64 " point type and db type mismatch. db type: %d, point type: %d, key: %s", info->id, + colField[*index].type, kv->type, kv->key); return TSDB_CODE_SML_INVALID_DATA; } @@ -575,17 +578,18 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm #define BOUNDARY 1024 static int32_t smlFindNearestPowerOf2(int32_t length, uint8_t type) { int32_t result = 1; - if (length >= BOUNDARY){ + if (length >= BOUNDARY) { result = length; - }else{ + } else { while (result <= length) { - result *= 2; + result <<= 1; } } + if (type == TSDB_DATA_TYPE_BINARY && result > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) { result = TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE; - } else if (type == TSDB_DATA_TYPE_NCHAR && result > (TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { - result = (TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE; + } else if (type == TSDB_DATA_TYPE_NCHAR && result > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { + result = (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE; } if (type == TSDB_DATA_TYPE_NCHAR) { @@ -690,6 +694,7 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns, SMCreateStbReq pReq = {0}; int32_t code = TSDB_CODE_SUCCESS; SCmdMsgInfo pCmdMsg = {0}; + char *pSql = NULL; // put front for free pReq.numOfColumns = taosArrayGetSize(pColumns); @@ -697,7 +702,27 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns, pReq.numOfTags = taosArrayGetSize(pTags); pReq.pTags = pTags; - code = buildRequest(info->taos->id, "", 0, NULL, false, &pRequest, 0); + if (action == SCHEMA_ACTION_CREATE_STABLE) { + pReq.colVer = 1; + pReq.tagVer = 1; + pReq.suid = 0; + pReq.source = TD_REQ_FROM_APP; + pSql = "sml_create_stable"; + } else if (action == SCHEMA_ACTION_ADD_TAG || action == SCHEMA_ACTION_CHANGE_TAG_SIZE) { + pReq.colVer = pTableMeta->sversion; + pReq.tagVer = pTableMeta->tversion + 1; + pReq.suid = pTableMeta->uid; + pReq.source = TD_REQ_FROM_TAOX; + pSql = (action == SCHEMA_ACTION_ADD_TAG) ? "sml_add_tag" : "sml_modify_tag_size"; + } else if (action == SCHEMA_ACTION_ADD_COLUMN || action == SCHEMA_ACTION_CHANGE_COLUMN_SIZE) { + pReq.colVer = pTableMeta->sversion + 1; + pReq.tagVer = pTableMeta->tversion; + pReq.suid = pTableMeta->uid; + pReq.source = TD_REQ_FROM_TAOX; + pSql = (action == SCHEMA_ACTION_ADD_COLUMN) ? "sml_add_column" : "sml_modify_column_size"; + } + + code = buildRequest(info->taos->id, pSql, strlen(pSql), NULL, false, &pRequest, 0); if (code != TSDB_CODE_SUCCESS) { goto end; } @@ -708,23 +733,6 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns, goto end; } - if (action == SCHEMA_ACTION_CREATE_STABLE) { - pReq.colVer = 1; - pReq.tagVer = 1; - pReq.suid = 0; - pReq.source = TD_REQ_FROM_APP; - } else if (action == SCHEMA_ACTION_ADD_TAG || action == SCHEMA_ACTION_CHANGE_TAG_SIZE) { - pReq.colVer = pTableMeta->sversion; - pReq.tagVer = pTableMeta->tversion + 1; - pReq.suid = pTableMeta->uid; - pReq.source = TD_REQ_FROM_TAOX; - } else if (action == SCHEMA_ACTION_ADD_COLUMN || action == SCHEMA_ACTION_CHANGE_COLUMN_SIZE) { - pReq.colVer = pTableMeta->sversion + 1; - pReq.tagVer = pTableMeta->tversion; - pReq.suid = pTableMeta->uid; - pReq.source = TD_REQ_FROM_TAOX; - } - if (pReq.numOfTags == 0) { pReq.numOfTags = 1; SField field = {0}; @@ -1336,7 +1344,7 @@ static int32_t smlInsertData(SSmlHandle *info) { if (info->pRequest->dbList == NULL) { info->pRequest->dbList = taosArrayInit(1, TSDB_DB_FNAME_LEN); } - char *data = (char*)taosArrayReserve(info->pRequest->dbList, 1); + char *data = (char *)taosArrayReserve(info->pRequest->dbList, 1); SName pName = {TSDB_TABLE_NAME_T, info->taos->acctId, {0}, {0}}; tstrncpy(pName.dbname, info->pRequest->pDb, sizeof(pName.dbname)); tNameGetFullDbName(&pName, data); @@ -1602,6 +1610,44 @@ static int smlProcess(SSmlHandle *info, char *lines[], char *rawLine, char *rawL return code; } +void smlSetReqSQL(SRequestObj *request, char *lines[], char *rawLine, char *rawLineEnd) { + if (tsSlowLogScope & SLOW_LOG_TYPE_INSERT) { + int32_t len = 0; + int32_t rlen = 0; + char* p = NULL; + + if (lines && lines[0]) { + len = strlen(lines[0]); + p = lines[0]; + } else if (rawLine) { + if (rawLineEnd) { + len = rawLineEnd - rawLine; + } else { + len = strlen(rawLine); + } + p = rawLine; + } + + if (NULL == p) { + return; + } + + rlen = TMIN(len, TSDB_MAX_ALLOWED_SQL_LEN); + rlen = TMAX(rlen, 0); + + char *sql = taosMemoryMalloc(rlen + 1); + if (NULL == sql) { + uError("malloc %d for sml sql failed", rlen + 1); + return; + } + memcpy(sql, p, rlen); + sql[rlen] = 0; + + request->sqlstr = sql; + request->sqlLen = rlen; + } +} + TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine, char *rawLineEnd, int numLines, int protocol, int precision, int32_t ttl, int64_t reqid) { int32_t code = TSDB_CODE_SUCCESS; @@ -1634,6 +1680,8 @@ TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine, info->msgBuf.len = ERROR_MSG_BUF_DEFAULT_SIZE; info->lineNum = numLines; + smlSetReqSQL(request, lines, rawLine, rawLineEnd); + SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf}; if (request->pDb == NULL) { request->code = TSDB_CODE_PAR_DB_NOT_SPECIFIED; diff --git a/source/client/src/clientSmlLine.c b/source/client/src/clientSmlLine.c index 2f7e8a0f97..e79093398e 100644 --- a/source/client/src/clientSmlLine.c +++ b/source/client/src/clientSmlLine.c @@ -27,29 +27,28 @@ // equal = #define IS_EQUAL(sql) (*(sql) == EQUAL && *((sql)-1) != SLASH) // quote " -//#define IS_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) != SLASH) +// #define IS_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) != SLASH) // SLASH -#define IS_SLASH_LETTER_IN_FIELD_VALUE(sql) \ - (*((sql)-1) == SLASH && (*(sql) == QUOTE || *(sql) == SLASH)) +#define IS_SLASH_LETTER_IN_FIELD_VALUE(sql) (*((sql)-1) == SLASH && (*(sql) == QUOTE || *(sql) == SLASH)) -#define IS_SLASH_LETTER_IN_TAG_FIELD_KEY(sql) \ +#define IS_SLASH_LETTER_IN_TAG_FIELD_KEY(sql) \ (*((sql)-1) == SLASH && (*(sql) == COMMA || *(sql) == SPACE || *(sql) == EQUAL)) -#define PROCESS_SLASH_IN_FIELD_VALUE(key, keyLen) \ - for (int i = 1; i < keyLen; ++i) { \ - if (IS_SLASH_LETTER_IN_FIELD_VALUE(key + i)) { \ - MOVE_FORWARD_ONE(key + i, keyLen - i); \ - keyLen--; \ - } \ +#define PROCESS_SLASH_IN_FIELD_VALUE(key, keyLen) \ + for (int i = 1; i < keyLen; ++i) { \ + if (IS_SLASH_LETTER_IN_FIELD_VALUE(key + i)) { \ + MOVE_FORWARD_ONE(key + i, keyLen - i); \ + keyLen--; \ + } \ } -#define PROCESS_SLASH_IN_TAG_FIELD_KEY(key, keyLen) \ - for (int i = 1; i < keyLen; ++i) { \ - if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(key + i)) { \ - MOVE_FORWARD_ONE(key + i, keyLen - i); \ - keyLen--; \ - } \ +#define PROCESS_SLASH_IN_TAG_FIELD_KEY(key, keyLen) \ + for (int i = 1; i < keyLen; ++i) { \ + if (IS_SLASH_LETTER_IN_TAG_FIELD_KEY(key + i)) { \ + MOVE_FORWARD_ONE(key + i, keyLen - i); \ + keyLen--; \ + } \ } #define BINARY_ADD_LEN 2 // "binary" 2 means " " @@ -152,15 +151,15 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin SSmlSTableMeta *sMeta = NULL; if (unlikely(tmp == NULL)) { - char* measure = currElement->measure; + char *measure = currElement->measure; int measureLen = currElement->measureLen; - if(currElement->measureEscaped){ - measure = (char*)taosMemoryMalloc(currElement->measureLen); + if (currElement->measureEscaped) { + measure = (char *)taosMemoryMalloc(currElement->measureLen); memcpy(measure, currElement->measure, currElement->measureLen); PROCESS_SLASH_IN_MEASUREMENT(measure, measureLen); } STableMeta *pTableMeta = smlGetMeta(info, measure, measureLen); - if(currElement->measureEscaped){ + if (currElement->measureEscaped) { taosMemoryFree(measure); } if (pTableMeta == NULL) { @@ -171,9 +170,13 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin sMeta = smlBuildSTableMeta(info->dataFormat); sMeta->tableMeta = pTableMeta; taosHashPut(info->superTables, currElement->measure, currElement->measureLen, &sMeta, POINTER_BYTES); - for(int i = pTableMeta->tableInfo.numOfColumns; i < pTableMeta->tableInfo.numOfTags + pTableMeta->tableInfo.numOfColumns; i++){ + for (int i = pTableMeta->tableInfo.numOfColumns; + i < pTableMeta->tableInfo.numOfTags + pTableMeta->tableInfo.numOfColumns; i++) { SSchema *tag = pTableMeta->schema + i; - SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type, .length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE }; + SSmlKv kv = {.key = tag->name, + .keyLen = strlen(tag->name), + .type = tag->type, + .length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE}; taosArrayPush(sMeta->tags, &kv); } tmp = &sMeta; @@ -248,19 +251,25 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN; } - if (keyEscaped){ - char *tmp = (char*)taosMemoryMalloc(keyLen); + if (keyEscaped) { + char *tmp = (char *)taosMemoryMalloc(keyLen); memcpy(tmp, key, keyLen); PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, keyLen); key = tmp; } - if (valueEscaped){ - char *tmp = (char*)taosMemoryMalloc(valueLen); + if (valueEscaped) { + char *tmp = (char *)taosMemoryMalloc(valueLen); memcpy(tmp, value, valueLen); PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, valueLen); value = tmp; } - SSmlKv kv = {.key = key, .keyLen = keyLen, .type = TSDB_DATA_TYPE_NCHAR, .value = value, .length = valueLen, .keyEscaped = keyEscaped, .valueEscaped = valueEscaped}; + SSmlKv kv = {.key = key, + .keyLen = keyLen, + .type = TSDB_DATA_TYPE_NCHAR, + .value = value, + .length = valueLen, + .keyEscaped = keyEscaped, + .valueEscaped = valueEscaped}; taosArrayPush(preLineKV, &kv); if (info->dataFormat) { if (unlikely(cnt + 1 > info->currSTableMeta->tableInfo.numOfTags)) { @@ -305,10 +314,10 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin return TSDB_CODE_OUT_OF_MEMORY; } tinfo->tags = taosArrayDup(preLineKV, NULL); - for(size_t i = 0; i < taosArrayGetSize(preLineKV); i++){ + for (size_t i = 0; i < taosArrayGetSize(preLineKV); i++) { SSmlKv *kv = (SSmlKv *)taosArrayGet(preLineKV, i); - if(kv->keyEscaped)kv->key = NULL; - if(kv->valueEscaped)kv->value = NULL; + if (kv->keyEscaped) kv->key = NULL; + if (kv->valueEscaped) kv->value = NULL; } smlSetCTableName(tinfo); @@ -330,7 +339,7 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLineInfo *currElement, bool isSameMeasure, bool isSameCTable) { - int cnt = 0; + int cnt = 0; if (info->dataFormat) { if (unlikely(!isSameCTable)) { SSmlTableInfo **oneTable = @@ -346,15 +355,15 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin SSmlSTableMeta **tmp = (SSmlSTableMeta **)taosHashGet(info->superTables, currElement->measure, currElement->measureLen); if (unlikely(tmp == NULL)) { - char* measure = currElement->measure; + char *measure = currElement->measure; int measureLen = currElement->measureLen; - if(currElement->measureEscaped){ - measure = (char*)taosMemoryMalloc(currElement->measureLen); + if (currElement->measureEscaped) { + measure = (char *)taosMemoryMalloc(currElement->measureLen); memcpy(measure, currElement->measure, currElement->measureLen); PROCESS_SLASH_IN_MEASUREMENT(measure, measureLen); } STableMeta *pTableMeta = smlGetMeta(info, measure, measureLen); - if(currElement->measureEscaped){ + if (currElement->measureEscaped) { taosMemoryFree(measure); } if (pTableMeta == NULL) { @@ -366,12 +375,12 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin (*tmp)->tableMeta = pTableMeta; taosHashPut(info->superTables, currElement->measure, currElement->measureLen, tmp, POINTER_BYTES); - for(int i = 0; i < pTableMeta->tableInfo.numOfColumns; i++){ + for (int i = 0; i < pTableMeta->tableInfo.numOfColumns; i++) { SSchema *tag = pTableMeta->schema + i; - SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type }; - if(tag->type == TSDB_DATA_TYPE_NCHAR){ + SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type}; + if (tag->type == TSDB_DATA_TYPE_NCHAR) { kv.length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE; - }else if(tag->type == TSDB_DATA_TYPE_BINARY){ + } else if (tag->type == TSDB_DATA_TYPE_BINARY) { kv.length = tag->bytes - VARSTR_HEADER_SIZE; } taosArrayPush((*tmp)->cols, &kv); @@ -459,16 +468,16 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin return ret; } - if (keyEscaped){ - char *tmp = (char*)taosMemoryMalloc(kv.keyLen); + if (keyEscaped) { + char *tmp = (char *)taosMemoryMalloc(kv.keyLen); memcpy(tmp, key, kv.keyLen); PROCESS_SLASH_IN_TAG_FIELD_KEY(tmp, kv.keyLen); kv.key = tmp; kv.keyEscaped = keyEscaped; } - if (valueEscaped){ - char *tmp = (char*)taosMemoryMalloc(kv.length); + if (valueEscaped) { + char *tmp = (char *)taosMemoryMalloc(kv.length); memcpy(tmp, kv.value, kv.length); PROCESS_SLASH_IN_FIELD_VALUE(tmp, kv.length); kv.value = tmp; @@ -643,9 +652,13 @@ int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLine if (info->dataFormat) { uDebug("SML:0x%" PRIx64 " smlParseInfluxString format true, ts:%" PRId64, info->id, ts); ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, &kv, 0); - if(ret != TSDB_CODE_SUCCESS){return ret;} + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } ret = smlBuildRow(info->currTableDataCtx); - if(ret != TSDB_CODE_SUCCESS){return ret;} + if (ret != TSDB_CODE_SUCCESS) { + return ret; + } clearColValArray(info->currTableDataCtx->pValues); } else { uDebug("SML:0x%" PRIx64 " smlParseInfluxString format false, ts:%" PRId64, info->id, ts); diff --git a/source/client/src/clientSmlTelnet.c b/source/client/src/clientSmlTelnet.c index c5dd20ba7b..42b8001e59 100644 --- a/source/client/src/clientSmlTelnet.c +++ b/source/client/src/clientSmlTelnet.c @@ -158,7 +158,7 @@ static int32_t smlParseTelnetTags(SSmlHandle *info, char *data, char *sqlEnd, SS return TSDB_CODE_TSC_INVALID_VALUE; } - if (unlikely(valueLen > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)) { + if (unlikely(valueLen > (TSDB_MAX_TAGS_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)) { return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN; } diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index b488af9ba1..87aee4a8a3 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -133,16 +133,23 @@ enum { TMQ_DELAYED_TASK__COMMIT, }; -typedef struct { - int64_t pollCnt; - int64_t numOfRows; +typedef struct SVgOffsetInfo { STqOffsetVal committedOffset; STqOffsetVal currentOffset; - int32_t vgId; - int32_t vgStatus; - int32_t vgSkipCnt; - int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data - SEpSet epSet; + int64_t walVerBegin; + int64_t walVerEnd; +} SVgOffsetInfo; + +typedef struct { + int64_t pollCnt; + int64_t numOfRows; + SVgOffsetInfo offsetInfo; + int32_t vgId; + int32_t vgStatus; + int32_t vgSkipCnt; // here used to mark the slow vgroups + bool receiveInfo; + int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data + SEpSet epSet; } SMqClientVg; typedef struct { @@ -190,6 +197,23 @@ typedef struct { uint64_t requestId; // request id for debug purpose } SMqPollCbParam; +typedef struct SMqVgCommon { + tsem_t rsp; + int32_t numOfRsp; + SArray* pList; + TdThreadMutex mutex; + int64_t consumerId; + char* pTopicName; + int32_t code; +} SMqVgCommon; + +typedef struct SMqVgWalInfoParam { + int32_t vgId; + int32_t epoch; + int32_t totalReq; + SMqVgCommon* pCommon; +} SMqVgWalInfoParam; + typedef struct { int64_t refId; int32_t epoch; @@ -204,7 +228,7 @@ typedef struct { typedef struct { SMqCommitCbParamSet* params; - STqOffset* pOffset; + SMqVgOffset* pOffset; char topicName[TSDB_TOPIC_FNAME_LEN]; int32_t vgId; tmq_t* pTmq; @@ -219,7 +243,7 @@ static int32_t doAskEp(tmq_t* tmq); static int32_t makeTopicVgroupKey(char* dst, const char* topicName, int32_t vg); static int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet); static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicName, SMqCommitCbParamSet* pParamSet, - int32_t index, int32_t totalVgroups); + int32_t index, int32_t totalVgroups, int32_t type); static void commitRspCountDown(SMqCommitCbParamSet* pParamSet, int64_t consumerId, const char* pTopic, int32_t vgId); static void asyncAskEp(tmq_t* pTmq, __tmq_askep_fn_t askEpFn, void* param); static void addToQueueCallbackFn(tmq_t* pTmq, int32_t code, SDataBuf* pDataBuf, void* param); @@ -438,7 +462,7 @@ static int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) { // if (code1 != TSDB_CODE_SUCCESS) { // retry failed. // tscError("consumer:0x%" PRIx64 " topic:%s vgId:%d offset:%" PRId64 // " retry failed, ignore this commit. code:%s ordinal:%d/%d", - // pParam->pTmq->consumerId, pParam->topicName, pVg->vgId, pVg->committedOffset.version, + // pParam->pTmq->consumerId, pParam->topicName, pVg->vgId, pVg->offsetInfo.committedOffset.version, // tstrerror(terrno), index + 1, numOfVgroups); // } // } @@ -464,22 +488,23 @@ static int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) { } static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicName, SMqCommitCbParamSet* pParamSet, - int32_t index, int32_t totalVgroups) { - STqOffset* pOffset = taosMemoryCalloc(1, sizeof(STqOffset)); + int32_t index, int32_t totalVgroups, int32_t type) { + SMqVgOffset* pOffset = taosMemoryCalloc(1, sizeof(SMqVgOffset)); if (pOffset == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } - pOffset->val = pVg->currentOffset; + pOffset->consumerId = tmq->consumerId; + pOffset->offset.val = pVg->offsetInfo.currentOffset; int32_t groupLen = strlen(tmq->groupId); - memcpy(pOffset->subKey, tmq->groupId, groupLen); - pOffset->subKey[groupLen] = TMQ_SEPARATOR; - strcpy(pOffset->subKey + groupLen + 1, pTopicName); + memcpy(pOffset->offset.subKey, tmq->groupId, groupLen); + pOffset->offset.subKey[groupLen] = TMQ_SEPARATOR; + strcpy(pOffset->offset.subKey + groupLen + 1, pTopicName); int32_t len = 0; int32_t code = 0; - tEncodeSize(tEncodeSTqOffset, pOffset, len, code); + tEncodeSize(tEncodeMqVgOffset, pOffset, len, code); if (code < 0) { return TSDB_CODE_INVALID_PARA; } @@ -496,7 +521,7 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN SEncoder encoder; tEncoderInit(&encoder, abuf, len); - tEncodeSTqOffset(&encoder, pOffset); + tEncodeMqVgOffset(&encoder, pOffset); tEncoderClear(&encoder); // build param @@ -530,19 +555,19 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN pMsgSendInfo->param = pParam; pMsgSendInfo->paramFreeFp = taosMemoryFree; pMsgSendInfo->fp = tmqCommitCb; - pMsgSendInfo->msgType = TDMT_VND_TMQ_COMMIT_OFFSET; + pMsgSendInfo->msgType = type; atomic_add_fetch_32(&pParamSet->waitingRspNum, 1); atomic_add_fetch_32(&pParamSet->totalRspNum, 1); SEp* pEp = GET_ACTIVE_EP(&pVg->epSet); char offsetBuf[80] = {0}; - tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->val); + tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->offset.val); char commitBuf[80] = {0}; - tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->committedOffset); + tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->offsetInfo.committedOffset); tscDebug("consumer:0x%" PRIx64 " topic:%s on vgId:%d send offset:%s prev:%s, ep:%s:%d, ordinal:%d/%d, req:0x%" PRIx64, - tmq->consumerId, pOffset->subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1, + tmq->consumerId, pOffset->offset.subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1, totalVgroups, pMsgSendInfo->requestId); int64_t transporterId = 0; @@ -551,7 +576,22 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN return TSDB_CODE_SUCCESS; } -static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* pCommitFp, void* userParam) { +static SMqClientTopic* getTopicByName(tmq_t* tmq, const char* pTopicName) { + int32_t numOfTopics = taosArrayGetSize(tmq->clientTopics); + for (int32_t i = 0; i < numOfTopics; ++i) { + SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i); + if (strcmp(pTopic->topicName, pTopicName) != 0) { + continue; + } + + return pTopic; + } + + tscError("consumer:0x%" PRIx64 ", total:%d, failed to find topic:%s", tmq->consumerId, numOfTopics, pTopicName); + return NULL; +} + +static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, int32_t type, tmq_commit_cb* pCommitFp, void* userParam) { char* pTopicName = NULL; int32_t vgId = 0; int32_t code = 0; @@ -593,15 +633,8 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p tscDebug("consumer:0x%" PRIx64 " do manual commit offset for %s, vgId:%d", tmq->consumerId, pTopicName, vgId); - int32_t i = 0; - for (; i < numOfTopics; i++) { - SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i); - if (strcmp(pTopic->topicName, pTopicName) == 0) { - break; - } - } - - if (i == numOfTopics) { + SMqClientTopic* pTopic = getTopicByName(tmq, pTopicName); + if (pTopic == NULL) { tscWarn("consumer:0x%" PRIx64 " failed to find the specified topic:%s, total topics:%d", tmq->consumerId, pTopicName, numOfTopics); taosMemoryFree(pParamSet); @@ -609,8 +642,6 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p return; } - SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i); - int32_t j = 0; int32_t numOfVgroups = taosArrayGetSize(pTopic->vgs); for (j = 0; j < numOfVgroups; j++) { @@ -629,8 +660,8 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p } SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j); - if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) { - code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups); + if (pVg->offsetInfo.currentOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.currentOffset, &pVg->offsetInfo.committedOffset)) { + code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups, type); // failed to commit, callback user function directly. if (code != TSDB_CODE_SUCCESS) { @@ -670,20 +701,20 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us for (int32_t j = 0; j < numOfVgroups; j++) { SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j); - if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) { - int32_t code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups); + if (pVg->offsetInfo.currentOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.currentOffset, &pVg->offsetInfo.committedOffset)) { + int32_t code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups, TDMT_VND_TMQ_COMMIT_OFFSET); if (code != TSDB_CODE_SUCCESS) { tscError("consumer:0x%" PRIx64 " topic:%s vgId:%d offset:%" PRId64 " failed, code:%s ordinal:%d/%d", - tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->committedOffset.version, tstrerror(terrno), + tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->offsetInfo.committedOffset.version, tstrerror(terrno), j + 1, numOfVgroups); continue; } // update the offset value. - pVg->committedOffset = pVg->currentOffset; + pVg->offsetInfo.committedOffset = pVg->offsetInfo.currentOffset; } else { tscDebug("consumer:0x%" PRIx64 " topic:%s vgId:%d, no commit, current:%" PRId64 ", ordinal:%d/%d", - tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->currentOffset.version, j + 1, numOfVgroups); + tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->offsetInfo.currentOffset.version, j + 1, numOfVgroups); } } } @@ -1085,7 +1116,7 @@ _failed: } int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) { - const int32_t MAX_RETRY_COUNT = 120 * 2; // let's wait for 2 mins at most + const int32_t MAX_RETRY_COUNT = 120 * 4; // let's wait for 4 mins at most const SArray* container = &topic_list->container; int32_t sz = taosArrayGetSize(container); void* buf = NULL; @@ -1138,22 +1169,13 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) { goto FAIL; } - SMqSubscribeCbParam param = { - .rspErr = 0, - .refId = tmq->refId, - .epoch = tmq->epoch, - }; - + SMqSubscribeCbParam param = { .rspErr = 0, .refId = tmq->refId, .epoch = tmq->epoch }; if (tsem_init(¶m.rspSem, 0, 0) != 0) { code = TSDB_CODE_TSC_INTERNAL_ERROR; goto FAIL; } - sendInfo->msgInfo = (SDataBuf){ - .pData = buf, - .len = tlen, - .handle = NULL, - }; + sendInfo->msgInfo = (SDataBuf){.pData = buf, .len = tlen, .handle = NULL}; sendInfo->requestId = generateRequestId(); sendInfo->requestObjRefId = 0; @@ -1181,7 +1203,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) { int32_t retryCnt = 0; while (TSDB_CODE_MND_CONSUMER_NOT_READY == doAskEp(tmq)) { if (retryCnt++ > MAX_RETRY_COUNT) { - tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, retry:%d in 500ms", tmq->consumerId, retryCnt); + tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, max retry reached:%d", tmq->consumerId, retryCnt); code = TSDB_CODE_TSC_INTERNAL_ERROR; goto FAIL; } @@ -1217,7 +1239,7 @@ void tmq_conf_set_auto_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb, void* para conf->commitCbUserParam = param; } -int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { +static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { SMqPollCbParam* pParam = (SMqPollCbParam*)param; int64_t refId = pParam->refId; @@ -1270,12 +1292,12 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { } int32_t msgEpoch = ((SMqRspHead*)pMsg->pData)->epoch; - int32_t tmqEpoch = atomic_load_32(&tmq->epoch); - if (msgEpoch < tmqEpoch) { + int32_t clientEpoch = atomic_load_32(&tmq->epoch); + if (msgEpoch < clientEpoch) { // do not write into queue since updating epoch reset tscWarn("consumer:0x%" PRIx64 " msg discard from vgId:%d since from earlier epoch, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64, - tmq->consumerId, vgId, msgEpoch, tmqEpoch, requestId); + tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId); tsem_post(&tmq->rspSem); taosReleaseRef(tmqMgmt.rsetId, refId); @@ -1285,9 +1307,9 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { return 0; } - if (msgEpoch != tmqEpoch) { + if (msgEpoch != clientEpoch) { tscWarn("consumer:0x%" PRIx64 " mismatch rsp from vgId:%d, epoch %d, current epoch %d, reqId:0x%" PRIx64, - tmq->consumerId, vgId, msgEpoch, tmqEpoch, requestId); + tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId); } // handle meta rsp @@ -1313,7 +1335,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { if (rspType == TMQ_MSG_TYPE__POLL_RSP) { SDecoder decoder; tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); - tDecodeSMqDataRsp(&decoder, &pRspWrapper->dataRsp); + tDecodeMqDataRsp(&decoder, &pRspWrapper->dataRsp); tDecoderClear(&decoder); memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead)); @@ -1324,7 +1346,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { } else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) { SDecoder decoder; tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); - tDecodeSMqMetaRsp(&decoder, &pRspWrapper->metaRsp); + tDecodeMqMetaRsp(&decoder, &pRspWrapper->metaRsp); tDecoderClear(&decoder); memcpy(&pRspWrapper->metaRsp, pMsg->pData, sizeof(SMqRspHead)); } else if (rspType == TMQ_MSG_TYPE__TAOSX_RSP) { @@ -1395,7 +1417,6 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic SMqClientVg clientVg = { .pollCnt = 0, - .currentOffset = offsetNew, .vgId = pVgEp->vgId, .epSet = pVgEp->epSet, .vgStatus = TMQ_VG_STATUS__IDLE, @@ -1404,6 +1425,10 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic .numOfRows = numOfRows, }; + clientVg.offsetInfo.currentOffset = offsetNew; + clientVg.offsetInfo.committedOffset = offsetNew; + clientVg.offsetInfo.walVerBegin = -1; + clientVg.offsetInfo.walVerEnd = -1; taosArrayPush(pTopic->vgs, &clientVg); } } @@ -1453,11 +1478,11 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp) makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId); char buf[80]; - tFormatOffset(buf, 80, &pVgCur->currentOffset); - tscDebug("consumer:0x%" PRIx64 ", doUpdateLocalEp current vg, epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, tmq->epoch, pVgCur->vgId, + tFormatOffset(buf, 80, &pVgCur->offsetInfo.currentOffset); + tscDebug("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId, vgKey, buf); - SVgroupSaveInfo info = {.offset = pVgCur->currentOffset, .numOfRows = pVgCur->numOfRows}; + SVgroupSaveInfo info = {.offset = pVgCur->offsetInfo.currentOffset, .numOfRows = pVgCur->numOfRows}; taosHashPut(pVgOffsetHashMap, vgKey, strlen(vgKey), &info, sizeof(SVgroupSaveInfo)); } } @@ -1533,8 +1558,8 @@ int32_t askEpCallbackFn(void* param, SDataBuf* pMsg, int32_t code) { tscDebug("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, update local ep", tmq->consumerId, head->epoch, epoch); } - pParam->pUserFn(tmq, code, pMsg, pParam->pParam); + pParam->pUserFn(tmq, code, pMsg, pParam->pParam); taosReleaseRef(tmqMgmt.rsetId, pParam->refId); taosMemoryFree(pMsg->pEpSet); @@ -1553,8 +1578,7 @@ void tmqBuildConsumeReqImpl(SMqPollReq* pReq, tmq_t* tmq, int64_t timeout, SMqCl pReq->consumerId = tmq->consumerId; pReq->timeout = timeout; pReq->epoch = tmq->epoch; - /*pReq->currentOffset = reqOffset;*/ - pReq->reqOffset = pVg->currentOffset; + pReq->reqOffset = pVg->offsetInfo.currentOffset; pReq->head.vgId = pVg->vgId; pReq->useSnapshot = tmq->useSnapshot; pReq->reqId = generateRequestId(); @@ -1652,7 +1676,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p pParam->refId = pTmq->refId; pParam->epoch = pTmq->epoch; - pParam->pVg = pVg; // pVg may be released,fix it + pParam->pVg = pVg; pParam->pTopic = pTopic; pParam->vgId = pVg->vgId; pParam->requestId = req.reqId; @@ -1664,8 +1688,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p return handleErrorBeforePoll(pVg, pTmq); } - sendInfo->msgInfo = (SDataBuf){ .pData = msg, .len = msgSize, .handle = NULL }; - + sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL}; sendInfo->requestId = req.reqId; sendInfo->requestObjRefId = 0; sendInfo->param = pParam; @@ -1674,7 +1697,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p int64_t transporterId = 0; char offsetFormatBuf[80]; - tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->currentOffset); + tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.currentOffset); tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64, pTmq->consumerId, pTopic->topicName, pVg->vgId, pTmq->epoch, offsetFormatBuf, req.reqId); @@ -1709,13 +1732,6 @@ static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) { tscTrace("consumer:0x%" PRIx64 " epoch %d wait poll-rsp, skip vgId:%d skip cnt %d", tmq->consumerId, tmq->epoch, pVg->vgId, vgSkipCnt); continue; -#if 0 - if (skipCnt < 30000) { - continue; - } else { - tscDebug("consumer:0x%" PRIx64 ",skip vgId:%d skip too much reset", tmq->consumerId, pVg->vgId); - } -#endif } atomic_store_32(&pVg->vgSkipCnt, 0); @@ -1790,11 +1806,17 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { pVg->epSet = *pollRspWrapper->pEpset; } - if(pDataRsp->rspOffset.type != 0){ // if offset is validate - pVg->currentOffset = pDataRsp->rspOffset; // update the local offset value only for the returned values. - } + // update the local offset value only for the returned values. + pVg->offsetInfo.currentOffset = pDataRsp->rspOffset; + + // update the status atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE); + // update the valid wal version range + pVg->offsetInfo.walVerBegin = pDataRsp->head.walsver; + pVg->offsetInfo.walVerEnd = pDataRsp->head.walever; + pVg->receiveInfo = true; + char buf[80]; tFormatOffset(buf, 80, &pDataRsp->rspOffset); if (pDataRsp->blockNum == 0) { @@ -1823,6 +1845,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { taosFreeQitem(pollRspWrapper); } } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { + // todo handle the wal range and epset for each vgroup SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)pRspWrapper; int32_t consumerEpoch = atomic_load_32(&tmq->epoch); @@ -1831,7 +1854,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) { SMqClientVg* pVg = pollRspWrapper->vgHandle; if(pollRspWrapper->metaRsp.rspOffset.type != 0){ // if offset is validate - pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset; + pVg->offsetInfo.currentOffset = pollRspWrapper->metaRsp.rspOffset; } atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE); // build rsp @@ -1851,7 +1874,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) { SMqClientVg* pVg = pollRspWrapper->vgHandle; if(pollRspWrapper->taosxRsp.rspOffset.type != 0){ // if offset is validate - pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset; + pVg->offsetInfo.currentOffset = pollRspWrapper->taosxRsp.rspOffset; } atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE); @@ -1878,7 +1901,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { tmq->totalRows += numOfRows; char buf[80]; - tFormatOffset(buf, 80, &pVg->currentOffset); + tFormatOffset(buf, 80, &pVg->offsetInfo.currentOffset); tscDebug("consumer:0x%" PRIx64 " process taosx poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64 ", vg total:%" PRId64 " total:%" PRId64 " reqId:0x%" PRIx64, tmq->consumerId, pVg->vgId, buf, pollRspWrapper->dataRsp.blockNum, numOfRows, pVg->numOfRows, @@ -1914,15 +1937,6 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) { tscDebug("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime, timeout); -#if 0 - tmqHandleAllDelayedTask(tmq); - tmqPollImpl(tmq, timeout); - rspObj = tmqHandleAllRsp(tmq, timeout, false); - if (rspObj) { - return (TAOS_RES*)rspObj; - } -#endif - // in no topic status, delayed task also need to be processed if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) { tscDebug("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId); @@ -2118,11 +2132,11 @@ void tmq_commit_async(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* cb, void* if (pRes == NULL) { // here needs to commit all offsets. asyncCommitAllOffsets(tmq, cb, param); } else { // only commit one offset - asyncCommitOffset(tmq, pRes, cb, param); + asyncCommitOffset(tmq, pRes, TDMT_VND_TMQ_COMMIT_OFFSET, cb, param); } } -static void commitCallBackFn(tmq_t *pTmq, int32_t code, void* param) { +static void commitCallBackFn(tmq_t *UNUSED_PARAM(tmq), int32_t code, void* param) { SSyncCommitInfo* pInfo = (SSyncCommitInfo*) param; pInfo->code = code; tsem_post(&pInfo->sem); @@ -2138,7 +2152,7 @@ int32_t tmq_commit_sync(tmq_t* tmq, const TAOS_RES* pRes) { if (pRes == NULL) { asyncCommitAllOffsets(tmq, commitCallBackFn, pInfo); } else { - asyncCommitOffset(tmq, pRes, commitCallBackFn, pInfo); + asyncCommitOffset(tmq, pRes, TDMT_VND_TMQ_COMMIT_OFFSET, commitCallBackFn, pInfo); } tsem_wait(&pInfo->sem); @@ -2322,4 +2336,298 @@ SReqResultInfo* tmqGetNextResInfo(TAOS_RES* res, bool convertUcs4) { } return NULL; +} + +static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) { + SMqVgWalInfoParam* pParam = param; + SMqVgCommon* pCommon = pParam->pCommon; + + int32_t total = atomic_add_fetch_32(&pCommon->numOfRsp, 1); + if (code != TSDB_CODE_SUCCESS) { + tscError("consumer:0x%" PRIx64 " failed to get the wal info from vgId:%d for topic:%s", pCommon->consumerId, + pParam->vgId, pCommon->pTopicName); + pCommon->code = code; + } else { + SMqDataRsp rsp; + SDecoder decoder; + tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); + tDecodeMqDataRsp(&decoder, &rsp); + tDecoderClear(&decoder); + + SMqRspHead* pHead = pMsg->pData; + + tmq_topic_assignment assignment = {.begin = pHead->walsver, + .end = pHead->walever, + .currentOffset = rsp.rspOffset.version, + .vgId = pParam->vgId}; + + taosThreadMutexLock(&pCommon->mutex); + taosArrayPush(pCommon->pList, &assignment); + taosThreadMutexUnlock(&pCommon->mutex); + } + + if (total == pParam->totalReq) { + tsem_post(&pCommon->rsp); + } + + taosMemoryFree(pParam); + return 0; +} + +static void destroyCommonInfo(SMqVgCommon* pCommon) { + taosArrayDestroy(pCommon->pList); + tsem_destroy(&pCommon->rsp); + taosThreadMutexDestroy(&pCommon->mutex); + taosMemoryFree(pCommon->pTopicName); + taosMemoryFree(pCommon); +} + +int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_assignment** assignment, + int32_t* numOfAssignment) { + *numOfAssignment = 0; + *assignment = NULL; + + int32_t accId = tmq->pTscObj->acctId; + char tname[128] = {0}; + sprintf(tname, "%d.%s", accId, pTopicName); + + SMqClientTopic* pTopic = getTopicByName(tmq, tname); + if (pTopic == NULL) { + return TSDB_CODE_INVALID_PARA; + } + + // in case of snapshot is opened, no valid offset will return + *numOfAssignment = taosArrayGetSize(pTopic->vgs); + + *assignment = taosMemoryCalloc(*numOfAssignment, sizeof(tmq_topic_assignment)); + if (*assignment == NULL) { + tscError("consumer:0x%" PRIx64 " failed to malloc buffer, size:%" PRIzu, tmq->consumerId, + (*numOfAssignment) * sizeof(tmq_topic_assignment)); + return TSDB_CODE_OUT_OF_MEMORY; + } + + bool needFetch = false; + + for (int32_t j = 0; j < (*numOfAssignment); ++j) { + SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, j); + if (!pClientVg->receiveInfo) { + needFetch = true; + break; + } + + tmq_topic_assignment* pAssignment = &(*assignment)[j]; + if (pClientVg->offsetInfo.currentOffset.type == TMQ_OFFSET__LOG) { + pAssignment->currentOffset = pClientVg->offsetInfo.currentOffset.version; + } else { + pAssignment->currentOffset = 0; + } + + pAssignment->begin = pClientVg->offsetInfo.walVerBegin; + pAssignment->end = pClientVg->offsetInfo.walVerEnd; + pAssignment->vgId = pClientVg->vgId; + } + + if (needFetch) { + SMqVgCommon* pCommon = taosMemoryCalloc(1, sizeof(SMqVgCommon)); + if (pCommon == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return terrno; + } + + pCommon->pList= taosArrayInit(4, sizeof(tmq_topic_assignment)); + tsem_init(&pCommon->rsp, 0, 0); + taosThreadMutexInit(&pCommon->mutex, 0); + pCommon->pTopicName = taosStrdup(pTopic->topicName); + pCommon->consumerId = tmq->consumerId; + + terrno = TSDB_CODE_OUT_OF_MEMORY; + for (int32_t i = 0; i < (*numOfAssignment); ++i) { + SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, i); + + SMqVgWalInfoParam* pParam = taosMemoryMalloc(sizeof(SMqVgWalInfoParam)); + if (pParam == NULL) { + destroyCommonInfo(pCommon); + return terrno; + } + + pParam->epoch = tmq->epoch; + pParam->vgId = pClientVg->vgId; + pParam->totalReq = *numOfAssignment; + pParam->pCommon = pCommon; + + SMqPollReq req = {0}; + tmqBuildConsumeReqImpl(&req, tmq, 10, pTopic, pClientVg); + + int32_t msgSize = tSerializeSMqPollReq(NULL, 0, &req); + if (msgSize < 0) { + taosMemoryFree(pParam); + destroyCommonInfo(pCommon); + return terrno; + } + + char* msg = taosMemoryCalloc(1, msgSize); + if (NULL == msg) { + taosMemoryFree(pParam); + destroyCommonInfo(pCommon); + return terrno; + } + + if (tSerializeSMqPollReq(msg, msgSize, &req) < 0) { + taosMemoryFree(msg); + taosMemoryFree(pParam); + destroyCommonInfo(pCommon); + return terrno; + } + + SMsgSendInfo* sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo)); + if (sendInfo == NULL) { + taosMemoryFree(pParam); + taosMemoryFree(msg); + destroyCommonInfo(pCommon); + return terrno; + } + + sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL}; + sendInfo->requestId = req.reqId; + sendInfo->requestObjRefId = 0; + sendInfo->param = pParam; + sendInfo->fp = tmqGetWalInfoCb; + sendInfo->msgType = TDMT_VND_TMQ_VG_WALINFO; + + int64_t transporterId = 0; + char offsetFormatBuf[80]; + tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pClientVg->offsetInfo.currentOffset); + + tscDebug("consumer:0x%" PRIx64 " %s retrieve wal info vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64, + tmq->consumerId, pTopic->topicName, pClientVg->vgId, tmq->epoch, offsetFormatBuf, req.reqId); + asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pClientVg->epSet, &transporterId, sendInfo); + } + + tsem_wait(&pCommon->rsp); + int32_t code = pCommon->code; + + terrno = code; + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFree(*assignment); + *assignment = NULL; + *numOfAssignment = 0; + } else { + int32_t num = taosArrayGetSize(pCommon->pList); + for(int32_t i = 0; i < num; ++i) { + (*assignment)[i] = *(tmq_topic_assignment*)taosArrayGet(pCommon->pList, i); + } + *numOfAssignment = num; + } + + for (int32_t j = 0; j < (*numOfAssignment); ++j) { + tmq_topic_assignment* p = &(*assignment)[j]; + + for(int32_t i = 0; i < taosArrayGetSize(pTopic->vgs); ++i) { + SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, i); + if (pClientVg->vgId != p->vgId) { + continue; + } + + SVgOffsetInfo* pOffsetInfo = &pClientVg->offsetInfo; + + pOffsetInfo->currentOffset.type = TMQ_OFFSET__LOG; + + char offsetBuf[80] = {0}; + tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffsetInfo->currentOffset); + + tscDebug("vgId:%d offset is update to:%s", p->vgId, offsetBuf); + + pOffsetInfo->walVerBegin = p->begin; + pOffsetInfo->walVerEnd = p->end; + pOffsetInfo->currentOffset.version = p->currentOffset; + pOffsetInfo->committedOffset.version = p->currentOffset; + } + } + + destroyCommonInfo(pCommon); + return code; + } else { + return TSDB_CODE_SUCCESS; + } +} + +int32_t tmq_offset_seek(tmq_t* tmq, const char* pTopicName, int32_t vgId, int64_t offset) { + if (tmq == NULL) { + tscError("invalid tmq handle, null"); + return TSDB_CODE_INVALID_PARA; + } + + int32_t accId = tmq->pTscObj->acctId; + char tname[128] = {0}; + sprintf(tname, "%d.%s", accId, pTopicName); + + SMqClientTopic* pTopic = getTopicByName(tmq, tname); + if (pTopic == NULL) { + tscError("consumer:0x%" PRIx64 " invalid topic name:%s", tmq->consumerId, pTopicName); + return TSDB_CODE_INVALID_PARA; + } + + SMqClientVg* pVg = NULL; + int32_t numOfVgs = taosArrayGetSize(pTopic->vgs); + for (int32_t i = 0; i < numOfVgs; ++i) { + SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, i); + if (pClientVg->vgId == vgId) { + pVg = pClientVg; + break; + } + } + + if (pVg == NULL) { + tscError("consumer:0x%" PRIx64 " invalid vgroup id:%d", tmq->consumerId, vgId); + return TSDB_CODE_INVALID_PARA; + } + + SVgOffsetInfo* pOffsetInfo = &pVg->offsetInfo; + + int32_t type = pOffsetInfo->currentOffset.type; + if (type != TMQ_OFFSET__LOG) { + tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, seek not allowed", tmq->consumerId, type); + return TSDB_CODE_INVALID_PARA; + } + + if (offset < pOffsetInfo->walVerBegin || offset > pOffsetInfo->walVerEnd) { + tscError("consumer:0x%" PRIx64 " invalid seek params, offset:%" PRId64 ", valid range:[%" PRId64 ", %" PRId64 "]", + tmq->consumerId, offset, pOffsetInfo->walVerBegin, pOffsetInfo->walVerEnd); + return TSDB_CODE_INVALID_PARA; + } + + // update the offset, and then commit to vnode + if (pOffsetInfo->currentOffset.type == TMQ_OFFSET__LOG) { + pOffsetInfo->currentOffset.version = offset; + pOffsetInfo->committedOffset.version = INT64_MIN; + } + + SMqRspObj rspObj = {.resType = RES_TYPE__TMQ, .vgId = pVg->vgId}; + tstrncpy(rspObj.topic, tname, tListLen(rspObj.topic)); + + tscDebug("consumer:0x%" PRIx64 " seek to %" PRId64 " on vgId:%d", tmq->consumerId, offset, pVg->vgId); + + SSyncCommitInfo* pInfo = taosMemoryMalloc(sizeof(SSyncCommitInfo)); + if (pInfo == NULL) { + tscError("consumer:0x%"PRIx64" failed to prepare seek operation", tmq->consumerId); + return TSDB_CODE_OUT_OF_MEMORY; + } + + tsem_init(&pInfo->sem, 0, 0); + pInfo->code = 0; + + asyncCommitOffset(tmq, &rspObj, TDMT_VND_TMQ_SEEK_TO_OFFSET, commitCallBackFn, pInfo); + + tsem_wait(&pInfo->sem); + int32_t code = pInfo->code; + + tsem_destroy(&pInfo->sem); + taosMemoryFree(pInfo); + + if (code != TSDB_CODE_SUCCESS) { + tscError("consumer:0x%" PRIx64 " failed to send seek to vgId:%d, code:%s", tmq->consumerId, pVg->vgId, + tstrerror(code)); + } + + return code; } \ No newline at end of file diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 56f68e5972..b04727bfc0 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -30,6 +30,27 @@ #include "taos.h" namespace { + +void printSubResults(void* pRes, int32_t* totalRows) { + char buf[1024]; + + while (1) { + TAOS_ROW row = taos_fetch_row(pRes); + if (row == NULL) { + break; + } + + TAOS_FIELD* fields = taos_fetch_fields(pRes); + int32_t numOfFields = taos_field_count(pRes); + int32_t precision = taos_result_precision(pRes); + taos_print_row(buf, row, fields, numOfFields); + *totalRows += 1; + printf("precision: %d, row content: %s\n", precision, buf); + } + +// taos_free_result(pRes); +} + void showDB(TAOS* pConn) { TAOS_RES* pRes = taos_query(pConn, "show databases"); TAOS_ROW pRow = NULL; @@ -112,7 +133,7 @@ void createNewTable(TAOS* pConn, int32_t index) { } taos_free_result(pRes); - for (int32_t i = 0; i < 100; i += 20) { + for (int32_t i = 0; i < 10000; i += 20) { char sql[1024] = {0}; sprintf(sql, "insert into tu%d values(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)" @@ -803,7 +824,7 @@ TEST(clientCase, projection_query_tables) { } taos_free_result(pRes); - for (int32_t i = 0; i < 10000; ++i) { + for (int32_t i = 0; i < 1; ++i) { printf("create table :%d\n", i); createNewTable(pConn, i); } @@ -990,7 +1011,7 @@ TEST(clientCase, sub_db_test) { tmq_conf_set(conf, "td.connect.user", "root"); tmq_conf_set(conf, "td.connect.pass", "taosdata"); tmq_conf_set(conf, "auto.offset.reset", "earliest"); - tmq_conf_set(conf, "experimental.snapshot.enable", "true"); + tmq_conf_set(conf, "experimental.snapshot.enable", "false"); tmq_conf_set(conf, "msg.with.table.name", "true"); tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); @@ -1000,7 +1021,7 @@ TEST(clientCase, sub_db_test) { // 创建订阅 topics 列表 tmq_list_t* topicList = tmq_list_new(); tmq_list_append(topicList, "topic_t1"); - tmq_list_append(topicList, "topic_s2"); +// tmq_list_append(topicList, "topic_s2"); // 启动订阅 tmq_subscribe(tmq, topicList); @@ -1083,7 +1104,6 @@ TEST(clientCase, sub_tb_test) { // 启动订阅 tmq_subscribe(tmq, topicList); - tmq_list_destroy(topicList); TAOS_FIELD* fields = NULL; @@ -1095,6 +1115,20 @@ TEST(clientCase, sub_tb_test) { int32_t count = 0; + tmq_topic_assignment* pAssign = NULL; + int32_t numOfAssign = 0; + + int32_t code = tmq_get_topic_assignment(tmq, "topic_t1", &pAssign, &numOfAssign); + if (code != 0) { + printf("error occurs:%s\n", tmq_err2str(code)); + tmq_consumer_close(tmq); + taos_close(pConn); + fprintf(stderr, "%d msg consumed, include %d rows\n", msgCnt, totalRows); + return; + } + + tmq_offset_seek(tmq, "topic_t1", pAssign[0].vgId, 0); + while (1) { TAOS_RES* pRes = tmq_consumer_poll(tmq, timeout); if (pRes) { @@ -1108,25 +1142,23 @@ TEST(clientCase, sub_tb_test) { // printf("db: %s\n", dbName); // printf("vgroup id: %d\n", vgroupId); - while (1) { - TAOS_ROW row = taos_fetch_row(pRes); - if (row == NULL) { - break; - } - - fields = taos_fetch_fields(pRes); - numOfFields = taos_field_count(pRes); - totalRows += 1; -// if (totalRows % 100000 == 0) { - taos_print_row(buf, row, fields, numOfFields); - printf("row content: %s\n", buf); -// } - } + printSubResults(pRes, &totalRows); + } else { +// tmq_offset_seek(tmq, "topic_t1", pAssign[0].vgroupHandle, pAssign[0].begin); +// break; + } + tmq_commit_sync(tmq, pRes); + if (pRes != NULL) { taos_free_result(pRes); + // if ((++count) > 1) { + // break; + // } } else { break; } + + tmq_offset_seek(tmq, "topic_t1", pAssign[0].vgId, pAssign[0].begin); } tmq_consumer_close(tmq); diff --git a/source/common/src/systable.c b/source/common/src/systable.c index cd3dd63ef0..062bae68c8 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -35,6 +35,10 @@ static const SSysDbTableSchema dnodesSchema[] = { {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "reboot_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "note", .bytes = 256 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, +#ifdef TD_ENTERPRISE + {.name = "active_code", .bytes = TSDB_ACTIVE_KEY_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "c_active_code", .bytes = TSDB_CONN_ACTIVE_KEY_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, +#endif }; static const SSysDbTableSchema mnodesSchema[] = { diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index b18bd882ae..846ca44b83 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -500,7 +500,7 @@ int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) break; default: ASSERTS(0, "invalid row format"); - return TSDB_CODE_IVLD_DATA_FMT; + return TSDB_CODE_INVALID_DATA_FMT; } if (bv == BIT_FLG_NONE) { @@ -755,7 +755,7 @@ SColVal *tRowIterNext(SRowIter *pIter) { } if (pIter->pRow->flag == HAS_NULL) { - pIter->cv = COL_VAL_NULL(pTColumn->type, pTColumn->colId); + pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type); goto _exit; } @@ -938,7 +938,7 @@ static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData * break; default: ASSERTS(0, "Invalid row flag"); - return TSDB_CODE_IVLD_DATA_FMT; + return TSDB_CODE_INVALID_DATA_FMT; } while (pColData) { @@ -963,7 +963,7 @@ static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData * break; default: ASSERTS(0, "Invalid row flag"); - return TSDB_CODE_IVLD_DATA_FMT; + return TSDB_CODE_INVALID_DATA_FMT; } if (bv == BIT_FLG_NONE) { @@ -1054,7 +1054,7 @@ static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aCo pData = pv + ((uint32_t *)pKVIdx->idx)[iCol]; } else { ASSERTS(0, "Invalid KV row format"); - return TSDB_CODE_IVLD_DATA_FMT; + return TSDB_CODE_INVALID_DATA_FMT; } int16_t cid; @@ -2441,7 +2441,7 @@ _exit: int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t bytes, int32_t nRows, char *lengthOrbitmap, char *data) { int32_t code = 0; - if(data == NULL){ + if (data == NULL) { for (int32_t i = 0; i < nRows; ++i) { code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NONE](pColData, NULL, 0); } @@ -2455,8 +2455,9 @@ int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t byt code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0); if (code) goto _exit; } else { - if(ASSERT(varDataTLen(data + offset) <= bytes)){ - uError("var data length invalid, varDataTLen(data + offset):%d <= bytes:%d", (int)varDataTLen(data + offset), bytes); + if (ASSERT(varDataTLen(data + offset) <= bytes)) { + uError("var data length invalid, varDataTLen(data + offset):%d <= bytes:%d", (int)varDataTLen(data + offset), + bytes); code = TSDB_CODE_INVALID_PARA; goto _exit; } diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 75db9600ee..237a52efe5 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -117,6 +117,10 @@ int32_t tsRedirectFactor = 2; int32_t tsRedirectMaxPeriod = 1000; int32_t tsMaxRetryWaitTime = 10000; bool tsUseAdapter = false; +int32_t tsSlowLogThreshold = 3; // seconds +int32_t tsSlowLogScope = SLOW_LOG_TYPE_ALL; + + /* @@ -347,6 +351,8 @@ static int32_t taosAddClientCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "useAdapter", tsUseAdapter, true) != 0) return -1; if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, true) != 0) return -1; if (cfgAddInt64(pCfg, "queryMaxConcurrentTables", tsQueryMaxConcurrentTables, INT64_MIN, INT64_MAX, 1) != 0) return -1; + if (cfgAddInt32(pCfg, "slowLogThreshold", tsSlowLogThreshold, 0, INT32_MAX, true) != 0) return -1; + if (cfgAddString(pCfg, "slowLogScope", "", true) != 0) return -1; tsNumOfRpcThreads = tsNumOfCores / 2; tsNumOfRpcThreads = TRANGE(tsNumOfRpcThreads, 2, TSDB_MAX_RPC_THREADS); @@ -696,6 +702,42 @@ static void taosSetServerLogCfg(SConfig *pCfg) { metaDebugFlag = cfgGetItem(pCfg, "metaDebugFlag")->i32; } +static int32_t taosSetSlowLogScope(char *pScope) { + if (NULL == pScope || 0 == strlen(pScope)) { + tsSlowLogScope = SLOW_LOG_TYPE_ALL; + return 0; + } + + if (0 == strcasecmp(pScope, "all")) { + tsSlowLogScope = SLOW_LOG_TYPE_ALL; + return 0; + } + + if (0 == strcasecmp(pScope, "query")) { + tsSlowLogScope = SLOW_LOG_TYPE_QUERY; + return 0; + } + + if (0 == strcasecmp(pScope, "insert")) { + tsSlowLogScope = SLOW_LOG_TYPE_INSERT; + return 0; + } + + if (0 == strcasecmp(pScope, "others")) { + tsSlowLogScope = SLOW_LOG_TYPE_OTHERS; + return 0; + } + + if (0 == strcasecmp(pScope, "none")) { + tsSlowLogScope = 0; + return 0; + } + + uError("Invalid slowLog scope value:%s", pScope); + terrno = TSDB_CODE_INVALID_CFG_VALUE; + return -1; +} + static int32_t taosSetClientCfg(SConfig *pCfg) { tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN); tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32; @@ -746,6 +788,10 @@ static int32_t taosSetClientCfg(SConfig *pCfg) { tsUseAdapter = cfgGetItem(pCfg, "useAdapter")->bval; tsEnableCrashReport = cfgGetItem(pCfg, "crashReporting")->bval; tsQueryMaxConcurrentTables = cfgGetItem(pCfg, "queryMaxConcurrentTables")->i64; + tsSlowLogThreshold = cfgGetItem(pCfg, "slowLogThreshold")->i32; + if (taosSetSlowLogScope(cfgGetItem(pCfg, "slowLogScope")->str)) { + return -1; + } tsMaxRetryWaitTime = cfgGetItem(pCfg, "maxRetryWaitTime")->i32; @@ -1162,6 +1208,12 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) { sDebugFlag = cfgGetItem(pCfg, "sDebugFlag")->i32; } else if (strcasecmp("smaDebugFlag", name) == 0) { smaDebugFlag = cfgGetItem(pCfg, "smaDebugFlag")->i32; + } else if (strcasecmp("slowLogThreshold", name) == 0) { + tsSlowLogThreshold = cfgGetItem(pCfg, "slowLogThreshold")->i32; + } else if (strcasecmp("slowLogScope", name) == 0) { + if (taosSetSlowLogScope(cfgGetItem(pCfg, "slowLogScope")->str)) { + return -1; + } } break; } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 40fd55f0a6..aff213fea3 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1723,6 +1723,33 @@ int32_t tDeserializeSDropDnodeReq(void *buf, int32_t bufLen, SDropDnodeReq *pReq return 0; } +int32_t tSerializeSRestoreDnodeReq(void *buf, int32_t bufLen, SRestoreDnodeReq *pReq) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeI32(&encoder, pReq->dnodeId) < 0) return -1; + if (tEncodeI8(&encoder, pReq->restoreType) < 0) return -1; + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSRestoreDnodeReq(void *buf, int32_t bufLen, SRestoreDnodeReq *pReq) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeI32(&decoder, &pReq->dnodeId) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->restoreType) < 0) return -1; + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + int32_t tSerializeSMCfgDnodeReq(void *buf, int32_t bufLen, SMCfgDnodeReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); @@ -2937,6 +2964,59 @@ void tFreeSUserAuthBatchRsp(SUserAuthBatchRsp *pRsp) { taosArrayDestroy(pRsp->pArray); } +int32_t tSerializeSUserPassBatchRsp(void *buf, int32_t bufLen, SUserPassBatchRsp *pRsp) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + + int32_t numOfBatch = taosArrayGetSize(pRsp->pArray); + if (tEncodeI32(&encoder, numOfBatch) < 0) return -1; + for (int32_t i = 0; i < numOfBatch; ++i) { + SGetUserPassRsp *pUserPassRsp = taosArrayGet(pRsp->pArray, i); + if (tEncodeCStr(&encoder, pUserPassRsp->user) < 0) return -1; + if (tEncodeI32(&encoder, pUserPassRsp->version) < 0) return -1; + } + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSUserPassBatchRsp(void *buf, int32_t bufLen, SUserPassBatchRsp *pRsp) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + + int32_t numOfBatch = taosArrayGetSize(pRsp->pArray); + if (tDecodeI32(&decoder, &numOfBatch) < 0) return -1; + + pRsp->pArray = taosArrayInit(numOfBatch, sizeof(SGetUserPassRsp)); + if (pRsp->pArray == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + for (int32_t i = 0; i < numOfBatch; ++i) { + SGetUserPassRsp rsp = {0}; + if (tDecodeCStrTo(&decoder, rsp.user) < 0) return -1; + if (tDecodeI32(&decoder, &rsp.version) < 0) return -1; + taosArrayPush(pRsp->pArray, &rsp); + } + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + +void tFreeSUserPassBatchRsp(SUserPassBatchRsp *pRsp) { + if(pRsp) { + taosArrayDestroy(pRsp->pArray); + } +} + int32_t tSerializeSDbCfgReq(void *buf, int32_t bufLen, SDbCfgReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); @@ -3977,6 +4057,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { if (tEncodeI32(&encoder, pRsp->svrTimestamp) < 0) return -1; if (tEncodeCStr(&encoder, pRsp->sVer) < 0) return -1; if (tEncodeCStr(&encoder, pRsp->sDetailVer) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->passVer) < 0) return -1; tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4000,6 +4081,13 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) { if (tDecodeI32(&decoder, &pRsp->svrTimestamp) < 0) return -1; if (tDecodeCStrTo(&decoder, pRsp->sVer) < 0) return -1; if (tDecodeCStrTo(&decoder, pRsp->sDetailVer) < 0) return -1; + + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI32(&decoder, &pRsp->passVer) < 0) return -1; + } else { + pRsp->passVer = 0; + } + tEndDecode(&decoder); tDecoderClear(&decoder); @@ -4130,6 +4218,12 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR for (int32_t i = 0; i < 8; ++i) { if (tEncodeI64(&encoder, pReq->reserved[i]) < 0) return -1; } + if (tEncodeI8(&encoder, pReq->learnerReplica) < 0) return -1; + if (tEncodeI8(&encoder, pReq->learnerSelfIndex) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tEncodeSReplica(&encoder, pReplica) < 0) return -1; + } tEndEncode(&encoder); @@ -4208,6 +4302,14 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq * for (int32_t i = 0; i < 8; ++i) { if (tDecodeI64(&decoder, &pReq->reserved[i]) < 0) return -1; } + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI8(&decoder, &pReq->learnerReplica) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->learnerSelfIndex) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tDecodeSReplica(&decoder, pReplica) < 0) return -1; + } + } tEndDecode(&decoder); tDecoderClear(&decoder); @@ -4434,6 +4536,12 @@ int32_t tSerializeSAlterVnodeReplicaReq(void *buf, int32_t bufLen, SAlterVnodeRe for (int32_t i = 0; i < 8; ++i) { if (tEncodeI64(&encoder, pReq->reserved[i]) < 0) return -1; } + if (tEncodeI8(&encoder, pReq->learnerSelfIndex) < 0) return -1; + if (tEncodeI8(&encoder, pReq->learnerReplica) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tEncodeSReplica(&encoder, pReplica) < 0) return -1; + } tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4457,7 +4565,15 @@ int32_t tDeserializeSAlterVnodeReplicaReq(void *buf, int32_t bufLen, SAlterVnode for (int32_t i = 0; i < 8; ++i) { if (tDecodeI64(&decoder, &pReq->reserved[i]) < 0) return -1; } - + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI8(&decoder, &pReq->learnerSelfIndex) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->learnerReplica) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tDecodeSReplica(&decoder, pReplica) < 0) return -1; + } + } + tEndDecode(&decoder); tDecoderClear(&decoder); return 0; @@ -4768,6 +4884,12 @@ int32_t tSerializeSDCreateMnodeReq(void *buf, int32_t bufLen, SDCreateMnodeReq * SReplica *pReplica = &pReq->replicas[i]; if (tEncodeSReplica(&encoder, pReplica) < 0) return -1; } + if (tEncodeI8(&encoder, pReq->learnerReplica) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tEncodeSReplica(&encoder, pReplica) < 0) return -1; + } + if (tEncodeI64(&encoder, pReq->lastIndex) < 0) return -1; tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -4785,6 +4907,14 @@ int32_t tDeserializeSDCreateMnodeReq(void *buf, int32_t bufLen, SDCreateMnodeReq SReplica *pReplica = &pReq->replicas[i]; if (tDecodeSReplica(&decoder, pReplica) < 0) return -1; } + if (!tDecodeIsEnd(&decoder)) { + if (tDecodeI8(&decoder, &pReq->learnerReplica) < 0) return -1; + for (int32_t i = 0; i < TSDB_MAX_LEARNER_REPLICA; ++i) { + SReplica *pReplica = &pReq->learnerReplicas[i]; + if (tDecodeSReplica(&decoder, pReplica) < 0) return -1; + } + if (tDecodeI64(&decoder, &pReq->lastIndex) < 0) return -1; + } tEndDecode(&decoder); tDecoderClear(&decoder); @@ -6906,6 +7036,18 @@ int32_t tDecodeSTqOffset(SDecoder *pDecoder, STqOffset *pOffset) { return 0; } +int32_t tEncodeMqVgOffset(SEncoder* pEncoder, const SMqVgOffset* pOffset) { + if (tEncodeSTqOffset(pEncoder, &pOffset->offset) < 0) return -1; + if (tEncodeI64(pEncoder, pOffset->consumerId) < 0) return -1; + return 0; +} + +int32_t tDecodeMqVgOffset(SDecoder* pDecoder, SMqVgOffset* pOffset) { + if (tDecodeSTqOffset(pDecoder, &pOffset->offset) < 0) return -1; + if (tDecodeI64(pDecoder, &pOffset->consumerId) < 0) return -1; + return 0; +} + int32_t tEncodeSTqCheckInfo(SEncoder *pEncoder, const STqCheckInfo *pInfo) { if (tEncodeCStr(pEncoder, pInfo->topic) < 0) return -1; if (tEncodeI64(pEncoder, pInfo->ntbUid) < 0) return -1; @@ -6970,21 +7112,21 @@ int32_t tDecodeDeleteRes(SDecoder *pCoder, SDeleteRes *pRes) { return 0; } -int32_t tEncodeSMqMetaRsp(SEncoder *pEncoder, const SMqMetaRsp *pRsp) { +int32_t tEncodeMqMetaRsp(SEncoder *pEncoder, const SMqMetaRsp *pRsp) { if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1; if (tEncodeI16(pEncoder, pRsp->resMsgType)) return -1; if (tEncodeBinary(pEncoder, pRsp->metaRsp, pRsp->metaRspLen)) return -1; return 0; } -int32_t tDecodeSMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) { +int32_t tDecodeMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) { if (tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset) < 0) return -1; if (tDecodeI16(pDecoder, &pRsp->resMsgType) < 0) return -1; if (tDecodeBinaryAlloc(pDecoder, &pRsp->metaRsp, (uint64_t *)&pRsp->metaRspLen) < 0) return -1; return 0; } -int32_t tEncodeSMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) { +int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) { if (tEncodeSTqOffsetVal(pEncoder, &pRsp->reqOffset) < 0) return -1; if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1; if (tEncodeI32(pEncoder, pRsp->blockNum) < 0) return -1; @@ -7009,7 +7151,7 @@ int32_t tEncodeSMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) { return 0; } -int32_t tDecodeSMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) { +int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) { if (tDecodeSTqOffsetVal(pDecoder, &pRsp->reqOffset) < 0) return -1; if (tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset) < 0) return -1; if (tDecodeI32(pDecoder, &pRsp->blockNum) < 0) return -1; @@ -7054,7 +7196,7 @@ int32_t tDecodeSMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) { return 0; } -void tDeleteSMqDataRsp(SMqDataRsp *pRsp) { +void tDeleteMqDataRsp(SMqDataRsp *pRsp) { pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen); taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree); pRsp->blockData = NULL; @@ -7155,8 +7297,7 @@ int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp) { } void tDeleteSTaosxRsp(STaosxRsp *pRsp) { - taosArrayDestroy(pRsp->blockDataLen); - pRsp->blockDataLen = NULL; + pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen); taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree); pRsp->blockData = NULL; taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper); @@ -7164,8 +7305,7 @@ void tDeleteSTaosxRsp(STaosxRsp *pRsp) { taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree); pRsp->blockTbName = NULL; - taosArrayDestroy(pRsp->createTableLen); - pRsp->createTableLen = NULL; + pRsp->createTableLen = taosArrayDestroy(pRsp->createTableLen); taosArrayDestroyP(pRsp->createTableReq, (FDelete)taosMemoryFree); pRsp->createTableReq = NULL; } @@ -7591,3 +7731,40 @@ int32_t tDeserializeSMResumeStreamReq(void *buf, int32_t bufLen, SMResumeStreamR return 0; } +int32_t tEncodeMqSubTopicEp(void **buf, const SMqSubTopicEp *pTopicEp) { + int32_t tlen = 0; + tlen += taosEncodeString(buf, pTopicEp->topic); + tlen += taosEncodeString(buf, pTopicEp->db); + int32_t sz = taosArrayGetSize(pTopicEp->vgs); + tlen += taosEncodeFixedI32(buf, sz); + for (int32_t i = 0; i < sz; i++) { + SMqSubVgEp *pVgEp = (SMqSubVgEp *)taosArrayGet(pTopicEp->vgs, i); + tlen += tEncodeSMqSubVgEp(buf, pVgEp); + } + tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema); + return tlen; +} + +void *tDecodeMqSubTopicEp(void *buf, SMqSubTopicEp *pTopicEp) { + buf = taosDecodeStringTo(buf, pTopicEp->topic); + buf = taosDecodeStringTo(buf, pTopicEp->db); + int32_t sz; + buf = taosDecodeFixedI32(buf, &sz); + pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp)); + if (pTopicEp->vgs == NULL) { + return NULL; + } + for (int32_t i = 0; i < sz; i++) { + SMqSubVgEp vgEp; + buf = tDecodeSMqSubVgEp(buf, &vgEp); + taosArrayPush(pTopicEp->vgs, &vgEp); + } + buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema); + return buf; +} + +void tDeleteMqSubTopicEp(SMqSubTopicEp *pSubTopicEp) { + taosMemoryFreeClear(pSubTopicEp->schema.pSchema); + pSubTopicEp->schema.nCols = 0; + taosArrayDestroy(pSubTopicEp->vgs); +} diff --git a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h index 600a1f6829..6c40fa808f 100644 --- a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h +++ b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h @@ -32,6 +32,7 @@ typedef struct SDnodeMgmt { TdThread crashReportThread; SSingleWorker mgmtWorker; ProcessCreateNodeFp processCreateNodeFp; + ProcessAlterNodeTypeFp processAlterNodeTypeFp; ProcessDropNodeFp processDropNodeFp; SendMonitorReportFp sendMonitorReportFp; GetVnodeLoadsFp getVnodeLoadsFp; diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c index 228f301aec..1998269896 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c @@ -352,6 +352,7 @@ SArray *dmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_SERVER_STATUS, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_SYSTABLE_RETRIEVE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; // Requests handled by MNODE if (dmSetMgmtHandle(pArray, TDMT_MND_GRANT, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c index 51df293ba7..09783a5ea9 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c @@ -48,6 +48,7 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { pMgmt->path = pInput->path; pMgmt->name = pInput->name; pMgmt->processCreateNodeFp = pInput->processCreateNodeFp; + pMgmt->processAlterNodeTypeFp = pInput->processAlterNodeTypeFp; pMgmt->processDropNodeFp = pInput->processDropNodeFp; pMgmt->sendMonitorReportFp = pInput->sendMonitorReportFp; pMgmt->getVnodeLoadsFp = pInput->getVnodeLoadsFp; diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c index 0d3b423771..06b6221940 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c @@ -227,6 +227,9 @@ static void dmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { case TDMT_DND_DROP_SNODE: code = (*pMgmt->processDropNodeFp)(SNODE, pMsg); break; + case TDMT_DND_ALTER_MNODE_TYPE: + code = (*pMgmt->processAlterNodeTypeFp)(MNODE, pMsg); + break; case TDMT_DND_SERVER_STATUS: code = dmProcessServerRunStatus(pMgmt, pMsg); break; diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c index f06669a610..cb0849f4b9 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c @@ -24,12 +24,16 @@ static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) { if (code < 0) return -1; tjsonGetInt32ValueFromDouble(pJson, "selfIndex", pOption->selfIndex, code); if (code < 0) return 0; + tjsonGetInt32ValueFromDouble(pJson, "lastIndex", pOption->lastIndex, code); + if (code < 0) return 0; SJson *replicas = tjsonGetObjectItem(pJson, "replicas"); if (replicas == NULL) return 0; - pOption->numOfReplicas = tjsonGetArraySize(replicas); + pOption->numOfTotalReplicas = tjsonGetArraySize(replicas); - for (int32_t i = 0; i < pOption->numOfReplicas; ++i) { + pOption->numOfReplicas = 0; + + for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) { SJson *replica = tjsonGetArrayItem(replicas, i); if (replica == NULL) return -1; @@ -40,6 +44,14 @@ static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) { if (code < 0) return -1; tjsonGetUInt16ValueFromDouble(replica, "port", pReplica->port, code); if (code < 0) return -1; + tjsonGetInt32ValueFromDouble(replica, "role", pOption->nodeRoles[i], code); + if (code < 0) return -1; + if(pOption->nodeRoles[i] == TAOS_SYNC_ROLE_VOTER){ + pOption->numOfReplicas++; + } + } + + for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) { } return 0; @@ -112,14 +124,14 @@ _OVER: } static int32_t mmEncodeOption(SJson *pJson, const SMnodeOpt *pOption) { - if (pOption->deploy && pOption->numOfReplicas > 0) { + if (pOption->deploy && pOption->numOfTotalReplicas > 0) { if (tjsonAddDoubleToObject(pJson, "selfIndex", pOption->selfIndex) < 0) return -1; SJson *replicas = tjsonCreateArray(); if (replicas == NULL) return -1; if (tjsonAddItemToObject(pJson, "replicas", replicas) < 0) return -1; - for (int32_t i = 0; i < pOption->numOfReplicas; ++i) { + for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) { SJson *replica = tjsonCreateObject(); if (replica == NULL) return -1; @@ -127,10 +139,13 @@ static int32_t mmEncodeOption(SJson *pJson, const SMnodeOpt *pOption) { if (tjsonAddDoubleToObject(replica, "id", pReplica->id) < 0) return -1; if (tjsonAddStringToObject(replica, "fqdn", pReplica->fqdn) < 0) return -1; if (tjsonAddDoubleToObject(replica, "port", pReplica->port) < 0) return -1; + if (tjsonAddDoubleToObject(replica, "role", pOption->nodeRoles[i]) < 0) return -1; if (tjsonAddItemToArray(replicas, replica) < 0) return -1; } } + if (tjsonAddDoubleToObject(pJson, "lastIndex", pOption->lastIndex) < 0) return -1; + if (tjsonAddDoubleToObject(pJson, "deployed", pOption->deploy) < 0) return -1; return 0; diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c index 3bf748ea29..7f8f6a48fa 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c @@ -33,12 +33,24 @@ int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { return -1; } - SMnodeOpt option = {.deploy = true, .numOfReplicas = createReq.replica, .selfIndex = -1}; + SMnodeOpt option = {.deploy = true, .numOfReplicas = createReq.replica, + .numOfTotalReplicas = createReq.replica + createReq.learnerReplica, + .selfIndex = -1, .lastIndex = createReq.lastIndex}; + memcpy(option.replicas, createReq.replicas, sizeof(createReq.replicas)); - for (int32_t i = 0; i < option.numOfReplicas; ++i) { + for (int32_t i = 0; i < createReq.replica; ++i) { if (createReq.replicas[i].id == pInput->pData->dnodeId) { option.selfIndex = i; } + option.nodeRoles[i] = TAOS_SYNC_ROLE_VOTER; + } + + memcpy(&(option.replicas[createReq.replica]), createReq.learnerReplicas, sizeof(createReq.learnerReplicas)); + for (int32_t i = 0; i < createReq.learnerReplica; ++i) { + if (createReq.learnerReplicas[i].id == pInput->pData->dnodeId) { + option.selfIndex = createReq.replica + i; + } + option.nodeRoles[createReq.replica + i] = TAOS_SYNC_ROLE_LEARNER; } if (option.selfIndex == -1) { @@ -92,6 +104,8 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CONNECT, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ACCT, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; @@ -163,6 +177,7 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_MND_SERVER_VERSION, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_INDEX, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_INDEX, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_RESTORE_DNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SCH_QUERY, mmPutMsgToQueryQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SCH_MERGE_QUERY, mmPutMsgToQueryQueue, 1) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmInt.c b/source/dnode/mgmt/mgmt_mnode/src/mmInt.c index e7f71ad420..7840528db9 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmInt.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmInt.c @@ -45,9 +45,11 @@ static void mmBuildOptionForDeploy(SMnodeMgmt *pMgmt, const SMgmtInputOpt *pInpu pOption->dnodeId = pMgmt->pData->dnodeId; pOption->selfIndex = 0; pOption->numOfReplicas = 1; + pOption->numOfTotalReplicas = 1; pOption->replicas[0].id = 1; pOption->replicas[0].port = tsServerPort; tstrncpy(pOption->replicas[0].fqdn, tsLocalFqdn, TSDB_FQDN_LEN); + pOption->lastIndex = SYNC_INDEX_INVALID; } static void mmBuildOptionForOpen(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { @@ -123,9 +125,10 @@ static int32_t mmOpen(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { } tmsgReportStartup("mnode-worker", "initialized"); - if (option.numOfReplicas > 0) { + if (option.numOfTotalReplicas > 0) { option.deploy = true; option.numOfReplicas = 0; + option.numOfTotalReplicas = 0; if (mmWriteFile(pMgmt->path, &option) != 0) { dError("failed to write mnode file since %s", terrstr()); return -1; @@ -152,6 +155,14 @@ static void mmStop(SMnodeMgmt *pMgmt) { mndStop(pMgmt->pMnode); } +static int32_t mmSyncIsCatchUp(SMnodeMgmt *pMgmt) { + return mndIsCatchUp(pMgmt->pMnode); +} + +static ESyncRole mmSyncGetRole(SMnodeMgmt *pMgmt) { + return mndGetRole(pMgmt->pMnode); +} + SMgmtFunc mmGetMgmtFunc() { SMgmtFunc mgmtFunc = {0}; mgmtFunc.openFp = mmOpen; @@ -162,6 +173,8 @@ SMgmtFunc mmGetMgmtFunc() { mgmtFunc.dropFp = (NodeDropFp)mmProcessDropReq; mgmtFunc.requiredFp = mmRequire; mgmtFunc.getHandlesFp = mmGetMsgHandles; + mgmtFunc.isCatchUpFp = (NodeIsCatchUpFp)mmSyncIsCatchUp; + mgmtFunc.nodeRoleFp = (NodeRole)mmSyncGetRole; return mgmtFunc; } diff --git a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h index 4374ae363c..83fb331dbd 100644 --- a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h +++ b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h @@ -90,6 +90,7 @@ int32_t vmProcessDropVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmProcessAlterVnodeReplicaReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmProcessDisableVnodeWriteReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmProcessAlterHashRangeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmProcessAlterVnodeTypeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); // vmFile.c int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index 5edc183c84..814a155cfb 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -131,15 +131,34 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) { pCfg->tsdbPageSize = pCreate->tsdbPageSize * 1024; pCfg->standby = 0; - pCfg->syncCfg.myIndex = pCreate->selfIndex; - pCfg->syncCfg.replicaNum = pCreate->replica; + pCfg->syncCfg.replicaNum = 0; + pCfg->syncCfg.totalReplicaNum = 0; + memset(&pCfg->syncCfg.nodeInfo, 0, sizeof(pCfg->syncCfg.nodeInfo)); for (int32_t i = 0; i < pCreate->replica; ++i) { SNodeInfo *pNode = &pCfg->syncCfg.nodeInfo[i]; - pNode->nodeId = pCreate->replicas[i].id; - pNode->nodePort = pCreate->replicas[i].port; - tstrncpy(pNode->nodeFqdn, pCreate->replicas[i].fqdn, TSDB_FQDN_LEN); + pNode->nodeId = pCreate->replicas[pCfg->syncCfg.replicaNum].id; + pNode->nodePort = pCreate->replicas[pCfg->syncCfg.replicaNum].port; + pNode->nodeRole = TAOS_SYNC_ROLE_VOTER; + tstrncpy(pNode->nodeFqdn, pCreate->replicas[pCfg->syncCfg.replicaNum].fqdn, TSDB_FQDN_LEN); tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); + pCfg->syncCfg.replicaNum++; + } + if(pCreate->selfIndex != -1){ + pCfg->syncCfg.myIndex = pCreate->selfIndex; + } + for (int32_t i = pCfg->syncCfg.replicaNum; i < pCreate->replica + pCreate->learnerReplica; ++i) { + SNodeInfo *pNode = &pCfg->syncCfg.nodeInfo[i]; + pNode->nodeId = pCreate->learnerReplicas[pCfg->syncCfg.totalReplicaNum].id; + pNode->nodePort = pCreate->learnerReplicas[pCfg->syncCfg.totalReplicaNum].port; + pNode->nodeRole = TAOS_SYNC_ROLE_LEARNER; + tstrncpy(pNode->nodeFqdn, pCreate->learnerReplicas[pCfg->syncCfg.totalReplicaNum].fqdn, TSDB_FQDN_LEN); + tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); + pCfg->syncCfg.totalReplicaNum++; + } + pCfg->syncCfg.totalReplicaNum += pCfg->syncCfg.replicaNum; + if(pCreate->learnerSelfIndex != -1){ + pCfg->syncCfg.myIndex = pCreate->replica + pCreate->learnerSelfIndex; } } @@ -182,23 +201,40 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return -1; } - dInfo("vgId:%d, start to create vnode, page:%d pageSize:%d buffer:%d szPage:%d szBuf:%" PRIu64 + if(req.learnerReplica == 0) + { + req.learnerSelfIndex = -1; + } + + dInfo("vgId:%d, vnode management handle msgType:%s, start to create vnode, page:%d pageSize:%d buffer:%d szPage:%d szBuf:%" PRIu64 ", cacheLast:%d cacheLastSize:%d sstTrigger:%d tsdbPageSize:%d %d dbname:%s dbId:%" PRId64 ", days:%d keep0:%d keep1:%d keep2:%d tsma:%d precision:%d compression:%d minRows:%d maxRows:%d" ", wal fsync:%d level:%d retentionPeriod:%d retentionSize:%" PRId64 " rollPeriod:%d segSize:%" PRId64 - ", hash method:%d begin:%u end:%u prefix:%d surfix:%d replica:%d selfIndex:%d strict:%d", - req.vgId, req.pages, req.pageSize, req.buffer, req.pageSize * 1024, (uint64_t)req.buffer * 1024 * 1024, + ", hash method:%d begin:%u end:%u prefix:%d surfix:%d replica:%d selfIndex:%d " + "learnerReplica:%d learnerSelfIndex:%d strict:%d", + req.vgId, TMSG_INFO(pMsg->msgType), req.pages, req.pageSize, req.buffer, req.pageSize * 1024, + (uint64_t)req.buffer * 1024 * 1024, req.cacheLast, req.cacheLastSize, req.sstTrigger, req.tsdbPageSize, req.tsdbPageSize * 1024, req.db, req.dbUid, req.daysPerFile, req.daysToKeep0, req.daysToKeep1, req.daysToKeep2, req.isTsma, req.precision, req.compression, req.minRows, req.maxRows, req.walFsyncPeriod, req.walLevel, req.walRetentionPeriod, req.walRetentionSize, req.walRollPeriod, req.walSegmentSize, req.hashMethod, req.hashBegin, req.hashEnd, req.hashPrefix, - req.hashSuffix, req.replica, req.selfIndex, req.strict); + req.hashSuffix, req.replica, req.selfIndex, req.learnerReplica, req.learnerSelfIndex, req.strict); for (int32_t i = 0; i < req.replica; ++i) { dInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d", req.vgId, i, req.replicas[i].fqdn, req.replicas[i].port, req.replicas[i].id); } + for (int32_t i = 0; i < req.learnerReplica; ++i) { + dInfo("vgId:%d, learnerReplica:%d ep:%s:%u dnode:%d", req.vgId, i, req.learnerReplicas[i].fqdn, + req.learnerReplicas[i].port, req.replicas[i].id); + } - SReplica *pReplica = &req.replicas[req.selfIndex]; + SReplica *pReplica = NULL; + if(req.selfIndex != -1){ + pReplica = &req.replicas[req.selfIndex]; + } + else{ + pReplica = &req.learnerReplicas[req.learnerSelfIndex]; + } if (pReplica->id != pMgmt->pData->dnodeId || pReplica->port != tsServerPort || strcmp(pReplica->fqdn, tsLocalFqdn) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -219,7 +255,7 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { SVnodeObj *pVnode = vmAcquireVnode(pMgmt, req.vgId); if (pVnode != NULL) { - dInfo("vgId:%d, already exist", req.vgId); + dError("vgId:%d, already exist", req.vgId); tFreeSCreateVnodeReq(&req); vmReleaseVnode(pMgmt, pVnode); terrno = TSDB_CODE_VND_ALREADY_EXIST; @@ -228,7 +264,22 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { } snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId); - if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) { + + if (pMgmt->pTfs) { + if (tfsDirExistAt(pMgmt->pTfs, path, (SDiskID){0})) { + terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST; + dError("vgId:%d, failed to restore vnode since %s", req.vgId, terrstr()); + return -1; + } + } else { + if (taosDirExist(path)) { + terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST; + dError("vgId:%d, failed to restore vnode since %s", req.vgId, terrstr()); + return -1; + } + } + +if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) { tFreeSCreateVnodeReq(&req); dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr()); code = terrno; @@ -275,7 +326,8 @@ _OVER: vnodeClose(pImpl); vnodeDestroy(path, pMgmt->pTfs); } else { - dInfo("vgId:%d, vnode is created", req.vgId); + dInfo("vgId:%d, vnode management handle msgType:%s, end to create vnode, vnode is created", + req.vgId, TMSG_INFO(pMsg->msgType)); } tFreeSCreateVnodeReq(&req); @@ -283,6 +335,123 @@ _OVER: return code; } +int32_t vmProcessAlterVnodeTypeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { + SAlterVnodeTypeReq req = {0}; + if (tDeserializeSAlterVnodeReplicaReq(pMsg->pCont, pMsg->contLen, &req) != 0) { + terrno = TSDB_CODE_INVALID_MSG; + return -1; + } + + if(req.learnerReplicas == 0){ + req.learnerSelfIndex = -1; + } + + dInfo("vgId:%d, vnode management handle msgType:%s, start to process alter-node-type-request", + req.vgId, TMSG_INFO(pMsg->msgType)); + + SVnodeObj *pVnode = vmAcquireVnode(pMgmt, req.vgId); + if (pVnode == NULL) { + dError("vgId:%d, failed to alter vnode type since %s", req.vgId, terrstr()); + terrno = TSDB_CODE_VND_NOT_EXIST; + return -1; + } + + ESyncRole role = vnodeGetRole(pVnode->pImpl); + dInfo("vgId:%d, checking node role:%d", req.vgId, role); + if(role == TAOS_SYNC_ROLE_VOTER){ + dError("vgId:%d, failed to alter vnode type since node already is role:%d", req.vgId, role); + terrno = TSDB_CODE_VND_ALREADY_IS_VOTER; + vmReleaseVnode(pMgmt, pVnode); + return -1; + } + + dInfo("vgId:%d, checking node catch up", req.vgId); + if(vnodeIsCatchUp(pVnode->pImpl) != 1){ + terrno = TSDB_CODE_VND_NOT_CATCH_UP; + vmReleaseVnode(pMgmt, pVnode); + return -1; + } + + dInfo("node:%s, catched up leader, continue to process alter-node-type-request", pMgmt->name); + + int32_t vgId = req.vgId; + dInfo("vgId:%d, start to alter vnode type replica:%d selfIndex:%d strict:%d", vgId, req.replica, req.selfIndex, + req.strict); + for (int32_t i = 0; i < req.replica; ++i) { + SReplica *pReplica = &req.replicas[i]; + dInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d", vgId, i, pReplica->fqdn, pReplica->port, pReplica->id); + } + for (int32_t i = 0; i < req.learnerReplica; ++i) { + SReplica *pReplica = &req.learnerReplicas[i]; + dInfo("vgId:%d, learnerReplicas:%d ep:%s:%u dnode:%d", vgId, i, pReplica->fqdn, pReplica->port, pReplica->id); + } + + if (req.replica <= 0 || + (req.selfIndex < 0 && req.learnerSelfIndex <0)|| + req.selfIndex >= req.replica || req.learnerSelfIndex >= req.learnerReplica) { + terrno = TSDB_CODE_INVALID_MSG; + dError("vgId:%d, failed to alter replica since invalid msg", vgId); + vmReleaseVnode(pMgmt, pVnode); + return -1; + } + + SReplica *pReplica = NULL; + if(req.selfIndex != -1){ + pReplica = &req.replicas[req.selfIndex]; + } + else{ + pReplica = &req.learnerReplicas[req.learnerSelfIndex]; + } + + if (pReplica->id != pMgmt->pData->dnodeId || pReplica->port != tsServerPort || + strcmp(pReplica->fqdn, tsLocalFqdn) != 0) { + terrno = TSDB_CODE_INVALID_MSG; + dError("vgId:%d, dnodeId:%d ep:%s:%u not matched with local dnode", vgId, pReplica->id, pReplica->fqdn, + pReplica->port); + vmReleaseVnode(pMgmt, pVnode); + return -1; + } + + dInfo("vgId:%d, start to close vnode", vgId); + SWrapperCfg wrapperCfg = { + .dropped = pVnode->dropped, + .vgId = pVnode->vgId, + .vgVersion = pVnode->vgVersion, + }; + tstrncpy(wrapperCfg.path, pVnode->path, sizeof(wrapperCfg.path)); + vmCloseVnode(pMgmt, pVnode, false); + + char path[TSDB_FILENAME_LEN] = {0}; + snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vgId); + + dInfo("vgId:%d, start to alter vnode replica at %s", vgId, path); + if (vnodeAlterReplica(path, &req, pMgmt->pTfs) < 0) { + dError("vgId:%d, failed to alter vnode at %s since %s", vgId, path, terrstr()); + return -1; + } + + dInfo("vgId:%d, begin to open vnode", vgId); + SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb); + if (pImpl == NULL) { + dError("vgId:%d, failed to open vnode at %s since %s", vgId, path, terrstr()); + return -1; + } + + if (vmOpenVnode(pMgmt, &wrapperCfg, pImpl) != 0) { + dError("vgId:%d, failed to open vnode mgmt since %s", vgId, terrstr()); + return -1; + } + + if (vnodeStart(pImpl) != 0) { + dError("vgId:%d, failed to start sync since %s", vgId, terrstr()); + return -1; + } + + dInfo("vgId:%d, vnode management handle msgType:%s, end to process alter-node-type-request, vnode config is altered", + req.vgId, TMSG_INFO(pMsg->msgType)); + return 0; +} + int32_t vmProcessDisableVnodeWriteReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { SDisableVnodeWriteReq req = {0}; if (tDeserializeSDisableVnodeWriteReq(pMsg->pCont, pMsg->contLen, &req) != 0) { @@ -377,21 +546,40 @@ int32_t vmProcessAlterVnodeReplicaReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return -1; } + if(alterReq.learnerReplica == 0){ + alterReq.learnerSelfIndex = -1; + } + int32_t vgId = alterReq.vgId; - dInfo("vgId:%d, start to alter vnode replica:%d selfIndex:%d strict:%d", vgId, alterReq.replica, alterReq.selfIndex, - alterReq.strict); + dInfo("vgId:%d,vnode management handle msgType:%s, start to alter vnode replica:%d selfIndex:%d leanerReplica:%d " + "learnerSelfIndex:%d strict:%d", + vgId, TMSG_INFO(pMsg->msgType), alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, + alterReq.learnerSelfIndex, alterReq.strict); for (int32_t i = 0; i < alterReq.replica; ++i) { SReplica *pReplica = &alterReq.replicas[i]; dInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d", vgId, i, pReplica->fqdn, pReplica->port, pReplica->port); } + for (int32_t i = 0; i < alterReq.learnerReplica; ++i) { + SReplica *pReplica = &alterReq.learnerReplicas[i]; + dInfo("vgId:%d, learnerReplicas:%d ep:%s:%u dnode:%d", vgId, i, pReplica->fqdn, pReplica->port, pReplica->port); + } - if (alterReq.replica <= 0 || alterReq.selfIndex < 0 || alterReq.selfIndex >= alterReq.replica) { + if (alterReq.replica <= 0 || + (alterReq.selfIndex < 0 && alterReq.learnerSelfIndex <0)|| + alterReq.selfIndex >= alterReq.replica || alterReq.learnerSelfIndex >= alterReq.learnerReplica) { terrno = TSDB_CODE_INVALID_MSG; dError("vgId:%d, failed to alter replica since invalid msg", vgId); return -1; } - SReplica *pReplica = &alterReq.replicas[alterReq.selfIndex]; + SReplica *pReplica = NULL; + if(alterReq.selfIndex != -1){ + pReplica = &alterReq.replicas[alterReq.selfIndex]; + } + else{ + pReplica = &alterReq.learnerReplicas[alterReq.learnerSelfIndex]; + } + if (pReplica->id != pMgmt->pData->dnodeId || pReplica->port != tsServerPort || strcmp(pReplica->fqdn, tsLocalFqdn) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -425,7 +613,7 @@ int32_t vmProcessAlterVnodeReplicaReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return -1; } - dInfo("vgId:%d, close vnode", vgId); + dInfo("vgId:%d, begin to open vnode", vgId); SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb); if (pImpl == NULL) { dError("vgId:%d, failed to open vnode at %s since %s", vgId, path, terrstr()); @@ -442,7 +630,10 @@ int32_t vmProcessAlterVnodeReplicaReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return -1; } - dInfo("vgId:%d, vnode config is altered", vgId); + dInfo("vgId:%d, vnode management handle msgType:%s, end to alter vnode replica:%d selfIndex:%d leanerReplica:%d " + "learnerSelfIndex:%d strict:%d", + vgId, TMSG_INFO(pMsg->msgType), alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, + alterReq.learnerSelfIndex, alterReq.strict); return 0; } @@ -517,9 +708,11 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SUBSCRIBE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DELETE_SUB, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_COMMIT_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SEEK_TO_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_ADD_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DEL_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_VG_WALINFO, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; @@ -550,6 +743,7 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_TRIM, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SYNC_TIMEOUT_ELECTION, vmPutMsgToSyncQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SYNC_CLIENT_REQUEST, vmPutMsgToSyncQueue, 0) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c index a318b9886e..a5f53c8703 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -49,6 +49,9 @@ static void vmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { case TDMT_VND_ALTER_HASHRANGE: code = vmProcessAlterHashRangeReq(pMgmt, pMsg); break; + case TDMT_DND_ALTER_VNODE_TYPE: + code = vmProcessAlterVnodeTypeReq(pMgmt, pMsg); + break; default: terrno = TSDB_CODE_MSG_NOT_PROCESSED; dGError("msg:%p, not processed in vnode-mgmt queue", pMsg); @@ -57,7 +60,7 @@ static void vmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { if (IsReq(pMsg)) { if (code != 0) { if (terrno != 0) code = terrno; - dGError("msg:%p, failed to process since %s, type:%s", pMsg, terrstr(code), TMSG_INFO(pMsg->msgType)); + dGError("msg:%p, failed to process since %s, type:%s", pMsg, tstrerror(code), TMSG_INFO(pMsg->msgType)); } vmSendRsp(pMsg, code); } diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index acf96ad397..56bff0c760 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -169,6 +169,8 @@ static int32_t dmProcessCreateNodeReq(EDndNodeType ntype, SRpcMsg *pMsg) { return -1; } + dInfo("start to process create-node-request"); + pWrapper = &pDnode->wrappers[ntype]; if (taosMkDir(pWrapper->path) != 0) { dmReleaseWrapper(pWrapper); @@ -198,6 +200,75 @@ static int32_t dmProcessCreateNodeReq(EDndNodeType ntype, SRpcMsg *pMsg) { return code; } +static int32_t dmProcessAlterNodeTypeReq(EDndNodeType ntype, SRpcMsg *pMsg) { + SDnode *pDnode = dmInstance(); + + SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype); + if (pWrapper == NULL) { + dError("fail to process alter node type since node not exist"); + return -1; + } + dmReleaseWrapper(pWrapper); + + dInfo("node:%s, start to process alter-node-type-request", pWrapper->name); + + pWrapper = &pDnode->wrappers[ntype]; + + if(pWrapper->func.nodeRoleFp != NULL){ + ESyncRole role = (*pWrapper->func.nodeRoleFp)(pWrapper->pMgmt); + dInfo("node:%s, checking node role:%d", pWrapper->name, role); + if(role == TAOS_SYNC_ROLE_VOTER){ + dError("node:%s, failed to alter node type since node already is role:%d", pWrapper->name, role); + terrno = TSDB_CODE_MNODE_ALREADY_IS_VOTER; + return -1; + } + } + + if(pWrapper->func.isCatchUpFp != NULL){ + dInfo("node:%s, checking node catch up", pWrapper->name); + if((*pWrapper->func.isCatchUpFp)(pWrapper->pMgmt) != 1){ + terrno = TSDB_CODE_MNODE_NOT_CATCH_UP; + return -1; + } + } + + dInfo("node:%s, catched up leader, continue to process alter-node-type-request", pWrapper->name); + + taosThreadMutexLock(&pDnode->mutex); + + dInfo("node:%s, stopping node", pWrapper->name); + dmStopNode(pWrapper); + dInfo("node:%s, closing node", pWrapper->name); + dmCloseNode(pWrapper); + + pWrapper = &pDnode->wrappers[ntype]; + if (taosMkDir(pWrapper->path) != 0) { + dmReleaseWrapper(pWrapper); + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to create dir:%s since %s", pWrapper->path, terrstr()); + return -1; + } + + SMgmtInputOpt input = dmBuildMgmtInputOpt(pWrapper); + + dInfo("node:%s, start to create", pWrapper->name); + int32_t code = (*pWrapper->func.createFp)(&input, pMsg); + if (code != 0) { + dError("node:%s, failed to create since %s", pWrapper->name, terrstr()); + } else { + dInfo("node:%s, has been created", pWrapper->name); + code = dmOpenNode(pWrapper); + if (code == 0) { + code = dmStartNode(pWrapper); + } + pWrapper->deployed = true; + pWrapper->required = true; + } + + taosThreadMutexUnlock(&pDnode->mutex); + return code; +} + static int32_t dmProcessDropNodeReq(EDndNodeType ntype, SRpcMsg *pMsg) { SDnode *pDnode = dmInstance(); @@ -251,6 +322,7 @@ SMgmtInputOpt dmBuildMgmtInputOpt(SMgmtWrapper *pWrapper) { .name = pWrapper->name, .pData = &pWrapper->pDnode->data, .processCreateNodeFp = dmProcessCreateNodeReq, + .processAlterNodeTypeFp = dmProcessAlterNodeTypeReq, .processDropNodeFp = dmProcessDropNodeReq, .sendMonitorReportFp = dmSendMonitorReport, .getVnodeLoadsFp = dmGetVnodeLoads, diff --git a/source/dnode/mgmt/node_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h index cfdea40477..98ef8cd95b 100644 --- a/source/dnode/mgmt/node_util/inc/dmUtil.h +++ b/source/dnode/mgmt/node_util/inc/dmUtil.h @@ -89,6 +89,7 @@ typedef void (*SendMonitorReportFp)(); typedef void (*GetVnodeLoadsFp)(SMonVloadInfo *pInfo); typedef void (*GetMnodeLoadsFp)(SMonMloadInfo *pInfo); typedef void (*GetQnodeLoadsFp)(SQnodeLoad *pInfo); +typedef int32_t (*ProcessAlterNodeTypeFp)(EDndNodeType ntype, SRpcMsg *pMsg); typedef struct { int32_t dnodeId; @@ -112,6 +113,7 @@ typedef struct { SDnodeData *pData; SMsgCb msgCb; ProcessCreateNodeFp processCreateNodeFp; + ProcessAlterNodeTypeFp processAlterNodeTypeFp; ProcessDropNodeFp processDropNodeFp; SendMonitorReportFp sendMonitorReportFp; GetVnodeLoadsFp getVnodeLoadsFp; @@ -132,6 +134,8 @@ typedef int32_t (*NodeCreateFp)(const SMgmtInputOpt *pInput, SRpcMsg *pMsg); typedef int32_t (*NodeDropFp)(const SMgmtInputOpt *pInput, SRpcMsg *pMsg); typedef int32_t (*NodeRequireFp)(const SMgmtInputOpt *pInput, bool *required); typedef SArray *(*NodeGetHandlesFp)(); // array of SMgmtHandle +typedef bool (*NodeIsCatchUpFp)(void *pMgmt); +typedef bool (*NodeRole)(void *pMgmt); typedef struct { NodeOpenFp openFp; @@ -142,6 +146,8 @@ typedef struct { NodeDropFp dropFp; NodeRequireFp requiredFp; NodeGetHandlesFp getHandlesFp; + NodeIsCatchUpFp isCatchUpFp; + NodeRole nodeRoleFp; } SMgmtFunc; typedef struct { diff --git a/source/dnode/mgmt/node_util/src/dmEps.c b/source/dnode/mgmt/node_util/src/dmEps.c index 784d2b425b..45cc4bb711 100644 --- a/source/dnode/mgmt/node_util/src/dmEps.c +++ b/source/dnode/mgmt/node_util/src/dmEps.c @@ -173,7 +173,7 @@ _OVER: dmResetEps(pData, pData->dnodeEps); if (pData->oldDnodeEps == NULL && dmIsEpChanged(pData, pData->dnodeId, tsLocalEp)) { - dError("localEp %s different with %s and need reconfigured", tsLocalEp, file); + dError("localEp %s different with %s and need to be reconfigured", tsLocalEp, file); terrno = TSDB_CODE_INVALID_CFG; return -1; } diff --git a/source/dnode/mnode/impl/CMakeLists.txt b/source/dnode/mnode/impl/CMakeLists.txt index b9aa8eb674..010067e99f 100644 --- a/source/dnode/mnode/impl/CMakeLists.txt +++ b/source/dnode/mnode/impl/CMakeLists.txt @@ -6,6 +6,7 @@ IF (TD_ENTERPRISE) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/privilege/src/privilege.c) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndDb.c) LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndVgroup.c) + LIST(APPEND MNODE_SRC ${TD_ENTERPRISE_DIR}/src/plugins/mnode/src/mndDnode.c) ENDIF () add_library(mnode STATIC ${MNODE_SRC}) diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 2579ff5231..b14f7a9023 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -118,7 +118,7 @@ typedef enum { } ETrnPolicy; typedef enum { - TRN_EXEC_PRARLLEL = 0, + TRN_EXEC_PARALLEL = 0, TRN_EXEC_SERIAL = 1, } ETrnExec; @@ -177,6 +177,7 @@ typedef struct { SArray* pRpcArray; SRWLatch lockRpcArray; int64_t mTraceId; + TdThreadMutex mutex; } STrans; typedef struct { @@ -205,6 +206,8 @@ typedef struct { uint16_t port; char fqdn[TSDB_FQDN_LEN]; char ep[TSDB_EP_LEN]; + char active[TSDB_ACTIVE_KEY_LEN]; + char connActive[TSDB_CONN_ACTIVE_KEY_LEN]; } SDnodeObj; typedef struct { @@ -215,6 +218,8 @@ typedef struct { bool syncRestore; int64_t stateStartTime; SDnodeObj* pDnode; + int32_t role; + SyncIndex lastIndex; } SMnodeObj; typedef struct { @@ -278,6 +283,7 @@ typedef struct { int8_t reserve; int32_t acctId; int32_t authVersion; + int32_t passVersion; SHashObj* readDbs; SHashObj* writeDbs; SHashObj* topics; @@ -341,6 +347,7 @@ typedef struct { ESyncState syncState; bool syncRestore; bool syncCanRead; + ESyncRole nodeRole; } SVnodeGid; typedef struct { @@ -361,7 +368,7 @@ typedef struct { int8_t compact; int8_t isTsma; int8_t replica; - SVnodeGid vnodeGid[TSDB_MAX_REPLICA]; + SVnodeGid vnodeGid[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; void* pTsma; int32_t numOfCachedTables; } SVgObj; diff --git a/source/dnode/mnode/impl/inc/mndDnode.h b/source/dnode/mnode/impl/inc/mndDnode.h index ebbabdfa33..83c2277612 100644 --- a/source/dnode/mnode/impl/inc/mndDnode.h +++ b/source/dnode/mnode/impl/inc/mndDnode.h @@ -29,7 +29,7 @@ void mndReleaseDnode(SMnode *pMnode, SDnodeObj *pDnode); SEpSet mndGetDnodeEpset(SDnodeObj *pDnode); int32_t mndGetDnodeSize(SMnode *pMnode); bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs); -void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeEps); +void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeInfo); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index ffb2443808..ec83f8a7e6 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -92,8 +92,11 @@ typedef struct { int64_t transSeq; TdThreadMutex lock; int8_t selfIndex; + int8_t numOfTotalReplicas; int8_t numOfReplicas; - SReplica replicas[TSDB_MAX_REPLICA]; + SReplica replicas[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + ESyncRole nodeRoles[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SyncIndex lastIndex; } SSyncMgmt; typedef struct { diff --git a/source/dnode/mnode/impl/inc/mndMnode.h b/source/dnode/mnode/impl/inc/mndMnode.h index 320d3651f0..44eddb0617 100644 --- a/source/dnode/mnode/impl/inc/mndMnode.h +++ b/source/dnode/mnode/impl/inc/mndMnode.h @@ -29,6 +29,10 @@ void mndReleaseMnode(SMnode *pMnode, SMnodeObj *pObj); bool mndIsMnode(SMnode *pMnode, int32_t dnodeId); void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet); int32_t mndSetDropMnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj, bool force); +int32_t mndSetRestoreCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj); +int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj); +int32_t mndSetRestoreAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj); +int32_t mndSetRestoreCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndQnode.h b/source/dnode/mnode/impl/inc/mndQnode.h index 36eebd3157..d4f364d821 100644 --- a/source/dnode/mnode/impl/inc/mndQnode.h +++ b/source/dnode/mnode/impl/inc/mndQnode.h @@ -30,6 +30,9 @@ SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId); void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj); int32_t mndCreateQnodeList(SMnode *pMnode, SArray **pList, int32_t limit); int32_t mndSetDropQnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SQnodeObj *pObj, bool force); +bool mndQnodeInDnode(SQnodeObj *pQnode, int32_t dnodeId); +int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj); +int32_t mndSetCreateQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndTrans.h b/source/dnode/mnode/impl/inc/mndTrans.h index 057e3efbbc..03434573c4 100644 --- a/source/dnode/mnode/impl/inc/mndTrans.h +++ b/source/dnode/mnode/impl/inc/mndTrans.h @@ -76,6 +76,7 @@ void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen); void mndTransSetCb(STrans *pTrans, ETrnFunc startFunc, ETrnFunc stopFunc, void *param, int32_t paramLen); void mndTransSetDbName(STrans *pTrans, const char *dbname, const char *stbname); void mndTransSetSerial(STrans *pTrans); +void mndTransSetParallel(STrans *pTrans); void mndTransSetOper(STrans *pTrans, EOperType oper); int32_t mndTrancCheckConflict(SMnode *pMnode, STrans *pTrans); diff --git a/source/dnode/mnode/impl/inc/mndUser.h b/source/dnode/mnode/impl/inc/mndUser.h index 95d15f6e5a..aa7f97f087 100644 --- a/source/dnode/mnode/impl/inc/mndUser.h +++ b/source/dnode/mnode/impl/inc/mndUser.h @@ -35,6 +35,8 @@ SHashObj *mndDupTableHash(SHashObj *pOld); SHashObj *mndDupTopicHash(SHashObj *pOld); int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp, int32_t *pRspLen); +int32_t mndValidateUserPassInfo(SMnode *pMnode, SUserPassVersion *pUsers, int32_t numOfUses, void **ppRsp, + int32_t *pRspLen); int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db); int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic); diff --git a/source/dnode/mnode/impl/inc/mndVgroup.h b/source/dnode/mnode/impl/inc/mndVgroup.h index 94c4eae83f..2ece0da5eb 100644 --- a/source/dnode/mnode/impl/inc/mndVgroup.h +++ b/source/dnode/mnode/impl/inc/mndVgroup.h @@ -49,6 +49,9 @@ int32_t mndBuildCompactVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, void *mndBuildCreateVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen); void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen); bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid); +bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId); +int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *db, SVgObj *pVgroup, + SDnodeObj *pDnode); int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup); diff --git a/source/dnode/mnode/impl/src/mndConsumer.c b/source/dnode/mnode/impl/src/mndConsumer.c index d144747e81..117c1082a5 100644 --- a/source/dnode/mnode/impl/src/mndConsumer.c +++ b/source/dnode/mnode/impl/src/mndConsumer.c @@ -564,9 +564,14 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) { return -1; } - ((SMqRspHead *)buf)->mqMsgType = TMQ_MSG_TYPE__EP_RSP; - ((SMqRspHead *)buf)->epoch = serverEpoch; - ((SMqRspHead *)buf)->consumerId = pConsumer->consumerId; + SMqRspHead* pHead = buf; + + pHead->mqMsgType = TMQ_MSG_TYPE__EP_RSP; + pHead->epoch = serverEpoch; + pHead->consumerId = pConsumer->consumerId; + pHead->walsver = 0; + pHead->walever = 0; + void *abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); tEncodeSMqAskEpRsp(&abuf, &rsp); @@ -811,6 +816,7 @@ SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw) { SMqConsumerObj *pConsumer = NULL; void *buf = NULL; + terrno = 0; int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) { goto CM_DECODE_OVER; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 1f58ae97a3..002407ce8a 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -27,7 +27,7 @@ #include "tmisce.h" #include "mndCluster.h" -#define TSDB_DNODE_VER_NUMBER 1 +#define TSDB_DNODE_VER_NUMBER 2 #define TSDB_DNODE_RESERVE_SIZE 64 static const char *offlineReason[] = { @@ -58,6 +58,7 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq); static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq); static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp); static int32_t mndProcessStatusReq(SRpcMsg *pReq); +static int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq); static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter); @@ -83,6 +84,7 @@ int32_t mndInitDnode(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_STATUS, mndProcessStatusReq); mndSetMsgHandle(pMnode, TDMT_MND_DNODE_LIST, mndProcessDnodeListReq); mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq); + mndSetMsgHandle(pMnode, TDMT_MND_RESTORE_DNODE, mndProcessRestoreDnodeReq); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs); mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig); @@ -139,6 +141,10 @@ static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) { SDB_SET_INT16(pRaw, dataPos, pDnode->port, _OVER) SDB_SET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER) SDB_SET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER) + SDB_SET_INT16(pRaw, dataPos, TSDB_ACTIVE_KEY_LEN, _OVER) + SDB_SET_BINARY(pRaw, dataPos, pDnode->active, TSDB_ACTIVE_KEY_LEN, _OVER) + SDB_SET_INT16(pRaw, dataPos, TSDB_CONN_ACTIVE_KEY_LEN, _OVER) + SDB_SET_BINARY(pRaw, dataPos, pDnode->connActive, TSDB_CONN_ACTIVE_KEY_LEN, _OVER) SDB_SET_DATALEN(pRaw, dataPos, _OVER); terrno = 0; @@ -161,7 +167,7 @@ static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) { int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER; - if (sver != TSDB_DNODE_VER_NUMBER) { + if (sver < 1 || sver > TSDB_DNODE_VER_NUMBER) { terrno = TSDB_CODE_SDB_INVALID_DATA_VER; goto _OVER; } @@ -179,6 +185,13 @@ static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) { SDB_GET_INT16(pRaw, dataPos, &pDnode->port, _OVER) SDB_GET_BINARY(pRaw, dataPos, pDnode->fqdn, TSDB_FQDN_LEN, _OVER) SDB_GET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER) + if (sver > 1) { + int16_t keyLen = 0; + SDB_GET_INT16(pRaw, dataPos, &keyLen, _OVER) + SDB_GET_BINARY(pRaw, dataPos, pDnode->active, keyLen, _OVER) + SDB_GET_INT16(pRaw, dataPos, &keyLen, _OVER) + SDB_GET_BINARY(pRaw, dataPos, pDnode->connActive, keyLen, _OVER) + } terrno = 0; if (tmsgUpdateDnodeInfo(&pDnode->id, NULL, pDnode->fqdn, &pDnode->port)) { @@ -294,6 +307,11 @@ int32_t mndGetDnodeSize(SMnode *pMnode) { return sdbGetSize(pSdb, SDB_DNODE); } +int32_t mndGetDbSize(SMnode *pMnode) { + SSdb *pSdb = pMnode->pSdb; + return sdbGetSize(pSdb, SDB_DB); +} + bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) { int64_t interval = TABS(pDnode->lastAccessTime - curMs); if (interval > 5000 * (int64_t)tsStatusInterval) { @@ -305,7 +323,7 @@ bool mndIsDnodeOnline(SDnodeObj *pDnode, int64_t curMs) { return true; } -void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeEps) { +static void mndGetDnodeEps(SMnode *pMnode, SArray *pDnodeEps) { SSdb *pSdb = pMnode->pSdb; int32_t numOfEps = 0; @@ -330,6 +348,34 @@ void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeEps) { } } +void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeInfo) { + SSdb *pSdb = pMnode->pSdb; + + int32_t numOfEps = 0; + void *pIter = NULL; + while (1) { + SDnodeObj *pDnode = NULL; + ESdbStatus objStatus = 0; + pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true); + if (pIter == NULL) break; + + SDnodeInfo dInfo; + dInfo.id = pDnode->id; + dInfo.ep.port = pDnode->port; + tstrncpy(dInfo.ep.fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + tstrncpy(dInfo.active, pDnode->active, TSDB_ACTIVE_KEY_LEN); + tstrncpy(dInfo.connActive, pDnode->connActive, TSDB_CONN_ACTIVE_KEY_LEN); + sdbRelease(pSdb, pDnode); + if (mndIsMnode(pMnode, pDnode->id)) { + dInfo.isMnode = 1; + } else { + dInfo.isMnode = 0; + } + + taosArrayPush(pDnodeInfo, &dInfo); + } +} + static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const SClusterCfg *pCfg) { if (pCfg->statusInterval != tsStatusInterval) { mError("dnode:%d, statusInterval:%d inconsistent with cluster:%d", pDnode->id, pCfg->statusInterval, @@ -536,7 +582,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) { goto _OVER; } - mndGetDnodeData(pMnode, statusRsp.pDnodeEps); + mndGetDnodeEps(pMnode, statusRsp.pDnodeEps); int32_t contLen = tSerializeSStatusRsp(NULL, 0, &statusRsp); void *pHead = rpcMallocCont(contLen); @@ -745,6 +791,18 @@ _OVER: return code; } +extern int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq); + +int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq){ + return mndProcessRestoreDnodeReqImpl(pReq); +} + +#ifndef TD_ENTERPRISE +int32_t mndProcessRestoreDnodeReqImpl(SRpcMsg *pReq){ + return 0; +} +#endif + static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj, SSnodeObj *pSObj, int32_t numOfVnodes, bool force) { int32_t code = -1; @@ -1041,6 +1099,7 @@ static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB ESdbStatus objStatus = 0; SDnodeObj *pDnode = NULL; int64_t curMs = taosGetTimestampMs(); + char buf[TSDB_CONN_ACTIVE_KEY_LEN + VARSTR_HEADER_SIZE]; // make sure TSDB_CONN_ACTIVE_KEY_LEN >= TSDB_EP_LEN while (numOfRows < rows) { pShow->pIter = sdbFetchAll(pSdb, SDB_DNODE, pShow->pIter, (void **)&pDnode, &objStatus, true); @@ -1052,7 +1111,6 @@ static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->id, false); - char buf[tListLen(pDnode->ep) + VARSTR_HEADER_SIZE] = {0}; STR_WITH_MAXSIZE_TO_VARSTR(buf, pDnode->ep, pShow->pMeta->pSchemas[cols].bytes); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); @@ -1077,10 +1135,9 @@ static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB status = "offline"; } - char b1[16] = {0}; - STR_TO_VARSTR(b1, status); + STR_TO_VARSTR(buf, status); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, numOfRows, b1, false); + colDataSetVal(pColInfo, numOfRows, buf, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)&pDnode->createdTime, false); @@ -1095,6 +1152,16 @@ static int32_t mndRetrieveDnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB colDataSetVal(pColInfo, numOfRows, b, false); taosMemoryFreeClear(b); +#ifdef TD_ENTERPRISE + STR_TO_VARSTR(buf, pDnode->active); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, buf, false); + + STR_TO_VARSTR(buf, pDnode->connActive); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, buf, false); +#endif + numOfRows++; sdbRelease(pSdb, pDnode); } diff --git a/source/dnode/mnode/impl/src/mndDump.c b/source/dnode/mnode/impl/src/mndDump.c index 44a7d49fff..a991bddda8 100644 --- a/source/dnode/mnode/impl/src/mndDump.c +++ b/source/dnode/mnode/impl/src/mndDump.c @@ -421,6 +421,7 @@ void dumpUser(SSdb *pSdb, SJson *json) { tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime)); tjsonAddStringToObject(item, "superUser", i642str(pObj->superUser)); tjsonAddStringToObject(item, "authVersion", i642str(pObj->authVersion)); + tjsonAddStringToObject(item, "passVersion", i642str(pObj->passVersion)); tjsonAddStringToObject(item, "numOfReadDbs", i642str(taosHashGetSize(pObj->readDbs))); tjsonAddStringToObject(item, "numOfWriteDbs", i642str(taosHashGetSize(pObj->writeDbs))); sdbRelease(pSdb, pObj); diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index 51a231daf4..af9bedd220 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -556,7 +556,7 @@ RETRIEVE_FUNC_OVER: return code; } -static void *mnodeGenTypeStr(char *buf, int32_t buflen, uint8_t type, int16_t len) { +static void *mnodeGenTypeStr(char *buf, int32_t buflen, uint8_t type, int32_t len) { char *msg = "unknown"; if (type >= sizeof(tDataTypes) / sizeof(tDataTypes[0])) { return msg; diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index 92ff550895..381b1e64ed 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -487,7 +487,10 @@ static void mndSetOptions(SMnode *pMnode, const SMnodeOpt *pOption) { pMnode->selfDnodeId = pOption->dnodeId; pMnode->syncMgmt.selfIndex = pOption->selfIndex; pMnode->syncMgmt.numOfReplicas = pOption->numOfReplicas; + pMnode->syncMgmt.numOfTotalReplicas = pOption->numOfTotalReplicas; + pMnode->syncMgmt.lastIndex = pOption->lastIndex; memcpy(pMnode->syncMgmt.replicas, pOption->replicas, sizeof(pOption->replicas)); + memcpy(pMnode->syncMgmt.nodeRoles, pOption->nodeRoles, sizeof(pOption->nodeRoles)); } SMnode *mndOpen(const char *path, const SMnodeOpt *pOption) { @@ -578,6 +581,16 @@ int32_t mndStart(SMnode *pMnode) { return mndInitTimer(pMnode); } +int32_t mndIsCatchUp(SMnode *pMnode) { + int64_t rid = pMnode->syncMgmt.sync; + return syncIsCatchUp(rid); +} + +ESyncRole mndGetRole(SMnode *pMnode){ + int64_t rid = pMnode->syncMgmt.sync; + return syncGetRole(rid); +} + void mndStop(SMnode *pMnode) { mndSetStop(pMnode); mndSyncStop(pMnode); diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 50fab447e3..19c3d59167 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -23,7 +23,7 @@ #include "mndTrans.h" #include "tmisce.h" -#define MNODE_VER_NUMBER 1 +#define MNODE_VER_NUMBER 2 #define MNODE_RESERVE_SIZE 64 static int32_t mndCreateDefaultMnode(SMnode *pMnode); @@ -53,6 +53,7 @@ int32_t mndInitMnode(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_CREATE_MNODE, mndProcessCreateMnodeReq); mndSetMsgHandle(pMnode, TDMT_DND_CREATE_MNODE_RSP, mndTransProcessRsp); + mndSetMsgHandle(pMnode, TDMT_DND_ALTER_MNODE_TYPE_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_MND_ALTER_MNODE, mndProcessAlterMnodeReq); mndSetMsgHandle(pMnode, TDMT_MND_ALTER_MNODE_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_MND_DROP_MNODE, mndProcessDropMnodeReq); @@ -126,6 +127,8 @@ static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj) { SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER) SDB_SET_INT64(pRaw, dataPos, pObj->createdTime, _OVER) SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER) + SDB_SET_INT32(pRaw, dataPos, pObj->role, _OVER) + SDB_SET_INT64(pRaw, dataPos, pObj->lastIndex, _OVER) SDB_SET_RESERVE(pRaw, dataPos, MNODE_RESERVE_SIZE, _OVER) terrno = 0; @@ -149,7 +152,7 @@ static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw) { int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL; - if (sver != MNODE_VER_NUMBER) { + if (sver != 1 && sver != 2) { terrno = TSDB_CODE_SDB_INVALID_DATA_VER; goto _OVER; } @@ -164,6 +167,10 @@ static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw) { SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER) SDB_GET_INT64(pRaw, dataPos, &pObj->createdTime, _OVER) SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER) + if(sver >=2){ + SDB_GET_INT32(pRaw, dataPos, &pObj->role, _OVER) + SDB_GET_INT64(pRaw, dataPos, &pObj->lastIndex, _OVER) + } SDB_GET_RESERVE(pRaw, dataPos, MNODE_RESERVE_SIZE, _OVER) terrno = 0; @@ -204,7 +211,9 @@ static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj) { static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOld, SMnodeObj *pNew) { mTrace("mnode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew); + pOld->role = pNew->role; pOld->updateTime = pNew->updateTime; + pOld->lastIndex = pNew->lastIndex; mndReloadSyncConfig(pSdb->pMnode); return 0; @@ -266,6 +275,14 @@ static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeO return 0; } +int32_t mndSetRestoreCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); + if (pRedoRaw == NULL) return -1; + if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1; + if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1; + return 0; +} + static int32_t mndSetCreateMnodeUndoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { SSdbRaw *pUndoRaw = mndMnodeActionEncode(pObj); if (pUndoRaw == NULL) return -1; @@ -274,7 +291,7 @@ static int32_t mndSetCreateMnodeUndoLogs(SMnode *pMnode, STrans *pTrans, SMnodeO return 0; } -static int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { +int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj); if (pCommitRaw == NULL) return -1; if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1; @@ -302,6 +319,28 @@ static int32_t mndBuildCreateMnodeRedoAction(STrans *pTrans, SDCreateMnodeReq *p return 0; } +static int32_t mndBuildAlterMnodeTypeRedoAction(STrans *pTrans, + SDAlterMnodeTypeReq *pAlterMnodeTypeReq, SEpSet *pAlterMnodeTypeEpSet) { + int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pAlterMnodeTypeReq); + void *pReq = taosMemoryMalloc(contLen); + tSerializeSDCreateMnodeReq(pReq, contLen, pAlterMnodeTypeReq); + + STransAction action = { + .epSet = *pAlterMnodeTypeEpSet, + .pCont = pReq, + .contLen = contLen, + .msgType = TDMT_DND_ALTER_MNODE_TYPE, + .retryCode = TSDB_CODE_MNODE_NOT_CATCH_UP, + .acceptableCode = TSDB_CODE_MNODE_ALREADY_IS_VOTER, + }; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + taosMemoryFree(pReq); + return -1; + } + return 0; +} + static int32_t mndBuildAlterMnodeRedoAction(STrans *pTrans, SDCreateMnodeReq *pAlterReq, SEpSet *pAlterEpSet) { int32_t contLen = tSerializeSDCreateMnodeReq(NULL, 0, pAlterReq); void *pReq = taosMemoryMalloc(contLen); @@ -347,6 +386,7 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno SSdb *pSdb = pMnode->pSdb; void *pIter = NULL; int32_t numOfReplicas = 0; + int32_t numOfLearnerReplicas = 0; SDCreateMnodeReq createReq = {0}; SEpSet createEpset = {0}; @@ -355,18 +395,29 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); if (pIter == NULL) break; - createReq.replicas[numOfReplicas].id = pMObj->id; - createReq.replicas[numOfReplicas].port = pMObj->pDnode->port; - memcpy(createReq.replicas[numOfReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + if(pMObj->role == TAOS_SYNC_ROLE_VOTER){ + createReq.replicas[numOfReplicas].id = pMObj->id; + createReq.replicas[numOfReplicas].port = pMObj->pDnode->port; + memcpy(createReq.replicas[numOfReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + numOfReplicas++; + } + else{ + createReq.learnerReplicas[numOfLearnerReplicas].id = pMObj->id; + createReq.learnerReplicas[numOfLearnerReplicas].port = pMObj->pDnode->port; + memcpy(createReq.learnerReplicas[numOfLearnerReplicas].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + numOfLearnerReplicas++; + } - numOfReplicas++; sdbRelease(pSdb, pMObj); } - createReq.replica = numOfReplicas + 1; - createReq.replicas[numOfReplicas].id = pDnode->id; - createReq.replicas[numOfReplicas].port = pDnode->port; - memcpy(createReq.replicas[numOfReplicas].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + createReq.replica = numOfReplicas; + createReq.learnerReplica = numOfLearnerReplicas + 1; + createReq.learnerReplicas[numOfLearnerReplicas].id = pDnode->id; + createReq.learnerReplicas[numOfLearnerReplicas].port = pDnode->port; + memcpy(createReq.learnerReplicas[numOfLearnerReplicas].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + + createReq.lastIndex = pObj->lastIndex; createEpset.inUse = 0; createEpset.numOfEps = 1; @@ -378,23 +429,176 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno return 0; } +int32_t mndSetRestoreCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + SDCreateMnodeReq createReq = {0}; + SEpSet createEpset = {0}; + + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; + + if(pMObj->id == pDnode->id) { + sdbRelease(pSdb, pMObj); + continue; + } + + if(pMObj->role == TAOS_SYNC_ROLE_VOTER){ + createReq.replicas[createReq.replica].id = pMObj->id; + createReq.replicas[createReq.replica].port = pMObj->pDnode->port; + memcpy(createReq.replicas[createReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + createReq.replica++; + } + else{ + createReq.learnerReplicas[createReq.learnerReplica].id = pMObj->id; + createReq.learnerReplicas[createReq.learnerReplica].port = pMObj->pDnode->port; + memcpy(createReq.learnerReplicas[createReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + createReq.learnerReplica++; + } + + sdbRelease(pSdb, pMObj); + } + + createReq.learnerReplicas[createReq.learnerReplica].id = pDnode->id; + createReq.learnerReplicas[createReq.learnerReplica].port = pDnode->port; + memcpy(createReq.learnerReplicas[createReq.learnerReplica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + createReq.learnerReplica++; + + createReq.lastIndex = pObj->lastIndex; + + createEpset.inUse = 0; + createEpset.numOfEps = 1; + createEpset.eps[0].port = pDnode->port; + memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + + if (mndBuildCreateMnodeRedoAction(pTrans, &createReq, &createEpset) != 0) return -1; + + return 0; +} + +static int32_t mndSetAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + SDAlterMnodeTypeReq alterReq = {0}; + SEpSet createEpset = {0}; + + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; + + if(pMObj->role == TAOS_SYNC_ROLE_VOTER){ + alterReq.replicas[alterReq.replica].id = pMObj->id; + alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port; + memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.replica++; + } + else{ + alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id; + alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port; + memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.learnerReplica++; + } + + sdbRelease(pSdb, pMObj); + } + + alterReq.replicas[alterReq.replica].id = pDnode->id; + alterReq.replicas[alterReq.replica].port = pDnode->port; + memcpy(alterReq.replicas[alterReq.replica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.replica++; + + alterReq.lastIndex = pObj->lastIndex; + + createEpset.inUse = 0; + createEpset.numOfEps = 1; + createEpset.eps[0].port = pDnode->port; + memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + + if (mndBuildAlterMnodeTypeRedoAction(pTrans, &alterReq, &createEpset) != 0) return -1; + + return 0; +} + +int32_t mndSetRestoreAlterMnodeTypeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + SDAlterMnodeTypeReq alterReq = {0}; + SEpSet createEpset = {0}; + + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; + + if(pMObj->id == pDnode->id) { + sdbRelease(pSdb, pMObj); + continue; + } + + if(pMObj->role == TAOS_SYNC_ROLE_VOTER){ + alterReq.replicas[alterReq.replica].id = pMObj->id; + alterReq.replicas[alterReq.replica].port = pMObj->pDnode->port; + memcpy(alterReq.replicas[alterReq.replica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.replica++; + } + else{ + alterReq.learnerReplicas[alterReq.learnerReplica].id = pMObj->id; + alterReq.learnerReplicas[alterReq.learnerReplica].port = pMObj->pDnode->port; + memcpy(alterReq.learnerReplicas[alterReq.learnerReplica].fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.learnerReplica++; + } + + sdbRelease(pSdb, pMObj); + } + + alterReq.replicas[alterReq.replica].id = pDnode->id; + alterReq.replicas[alterReq.replica].port = pDnode->port; + memcpy(alterReq.replicas[alterReq.replica].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + alterReq.replica++; + + alterReq.lastIndex = pObj->lastIndex; + + createEpset.inUse = 0; + createEpset.numOfEps = 1; + createEpset.eps[0].port = pDnode->port; + memcpy(createEpset.eps[0].fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + + if (mndBuildAlterMnodeTypeRedoAction(pTrans, &alterReq, &createEpset) != 0) return -1; + + return 0; +} + static int32_t mndCreateMnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMCreateMnodeReq *pCreate) { int32_t code = -1; - SMnodeObj mnodeObj = {0}; - mnodeObj.id = pDnode->id; - mnodeObj.createdTime = taosGetTimestampMs(); - mnodeObj.updateTime = mnodeObj.createdTime; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "create-mnode"); if (pTrans == NULL) goto _OVER; mndTransSetSerial(pTrans); mInfo("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId); if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER; + SMnodeObj mnodeObj = {0}; + mnodeObj.id = pDnode->id; + mnodeObj.createdTime = taosGetTimestampMs(); + mnodeObj.updateTime = mnodeObj.createdTime; + mnodeObj.role = TAOS_SYNC_ROLE_LEARNER; + mnodeObj.lastIndex = pMnode->applied; + if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) goto _OVER; if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER; - if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) goto _OVER; + + SMnodeObj mnodeLeaderObj = {0}; + mnodeLeaderObj.id = pDnode->id; + mnodeLeaderObj.createdTime = taosGetTimestampMs(); + mnodeLeaderObj.updateTime = mnodeLeaderObj.createdTime; + mnodeLeaderObj.role = TAOS_SYNC_ROLE_VOTER; + mnodeLeaderObj.lastIndex = pMnode->applied + 1; + + if (mndSetAlterMnodeTypeRedoActions(pMnode, pTrans, pDnode, &mnodeLeaderObj) != 0) goto _OVER; + if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeLeaderObj) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; @@ -514,6 +718,7 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode int32_t mndSetDropMnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj, bool force) { if (pObj == NULL) return 0; + pObj->lastIndex = pMnode->applied; if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj, force) != 0) return -1; if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) return -1; return 0; @@ -730,7 +935,8 @@ static void mndReloadSyncConfig(SMnode *pMnode) { void *pIter = NULL; int32_t updatingMnodes = 0; int32_t readyMnodes = 0; - SSyncCfg cfg = {.myIndex = -1}; + SSyncCfg cfg = {.myIndex = -1, .lastIndex = 0,}; + SyncIndex maxIndex = 0; while (1) { pIter = sdbFetchAll(pSdb, SDB_MNODE, pIter, (void **)&pObj, &objStatus, false); @@ -745,26 +951,41 @@ static void mndReloadSyncConfig(SMnode *pMnode) { } if (objStatus == SDB_STATUS_READY || objStatus == SDB_STATUS_CREATING) { - SNodeInfo *pNode = &cfg.nodeInfo[cfg.replicaNum]; + SNodeInfo *pNode = &cfg.nodeInfo[cfg.totalReplicaNum]; pNode->nodeId = pObj->pDnode->id; pNode->clusterId = mndGetClusterId(pMnode); pNode->nodePort = pObj->pDnode->port; + pNode->nodeRole = pObj->role; tstrncpy(pNode->nodeFqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN); (void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); mInfo("vgId:1, ep:%s:%u dnode:%d", pNode->nodeFqdn, pNode->nodePort, pNode->nodeId); if (pObj->pDnode->id == pMnode->selfDnodeId) { - cfg.myIndex = cfg.replicaNum; + cfg.myIndex = cfg.totalReplicaNum; + } + if(pNode->nodeRole == TAOS_SYNC_ROLE_VOTER){ + cfg.replicaNum++; + } + cfg.totalReplicaNum++; + if(pObj->lastIndex > cfg.lastIndex){ + cfg.lastIndex = pObj->lastIndex; } - cfg.replicaNum++; } + if (objStatus == SDB_STATUS_DROPPING) { + if(pObj->lastIndex > cfg.lastIndex){ + cfg.lastIndex = pObj->lastIndex; + } + } + + mInfo("vgId:1, mnode:%d, role:%d, lastIndex:%" PRId64, pObj->id, pObj->role, pObj->lastIndex); + sdbReleaseLock(pSdb, pObj, false); } - if (readyMnodes <= 0 || updatingMnodes <= 0) { - mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes); - return; - } + //if (readyMnodes <= 0 || updatingMnodes <= 0) { + // mInfo("vgId:1, mnode sync not reconfig since readyMnodes:%d updatingMnodes:%d", readyMnodes, updatingMnodes); + // return; + //} if (cfg.myIndex == -1) { #if 1 @@ -777,12 +998,14 @@ static void mndReloadSyncConfig(SMnode *pMnode) { return; } - if (updatingMnodes > 0) { - mInfo("vgId:1, mnode sync reconfig, replica:%d myIndex:%d", cfg.replicaNum, cfg.myIndex); - for (int32_t i = 0; i < cfg.replicaNum; ++i) { + if (pMnode->syncMgmt.sync > 0) { + mInfo("vgId:1, mnode sync reconfig, totalReplica:%d replica:%d myIndex:%d", + cfg.totalReplicaNum, cfg.replicaNum, cfg.myIndex); + + for (int32_t i = 0; i < cfg.totalReplicaNum; ++i) { SNodeInfo *pNode = &cfg.nodeInfo[i]; - mInfo("vgId:1, index:%d, ep:%s:%u dnode:%d cluster:%" PRId64, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId, - pNode->clusterId); + mInfo("vgId:1, index:%d, ep:%s:%u dnode:%d cluster:%" PRId64 " role:%d", i, pNode->nodeFqdn, pNode->nodePort, + pNode->nodeId, pNode->clusterId, pNode->nodeRole); } int32_t code = syncReconfig(pMnode->syncMgmt.sync, &cfg); diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index ff6a2f460a..d0f88940a9 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -286,6 +286,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { connectRsp.connType = connReq.connType; connectRsp.dnodeNum = mndGetDnodeSize(pMnode); connectRsp.svrTimestamp = taosGetTimestampSec(); + connectRsp.passVer = pUser->passVersion; strcpy(connectRsp.sVer, version); snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo, @@ -550,6 +551,16 @@ static int32_t mndProcessQueryHeartBeat(SMnode *pMnode, SRpcMsg *pMsg, SClientHb } break; } + case HEARTBEAT_KEY_USER_PASSINFO: { + void *rspMsg = NULL; + int32_t rspLen = 0; + mndValidateUserPassInfo(pMnode, kv->value, kv->valueLen / sizeof(SUserPassVersion), &rspMsg, &rspLen); + if (rspMsg && rspLen > 0) { + SKv kv1 = {.key = HEARTBEAT_KEY_USER_PASSINFO, .valueLen = rspLen, .value = rspMsg}; + taosArrayPush(hbRsp.info, &kv1); + } + break; + } default: mError("invalid kv key:%d", kv->key); hbRsp.status = TSDB_CODE_APP_ERROR; diff --git a/source/dnode/mnode/impl/src/mndQnode.c b/source/dnode/mnode/impl/src/mndQnode.c index a8b2d5f4bb..b5c9ce1f65 100644 --- a/source/dnode/mnode/impl/src/mndQnode.c +++ b/source/dnode/mnode/impl/src/mndQnode.c @@ -180,7 +180,7 @@ static int32_t mndSetCreateQnodeUndoLogs(STrans *pTrans, SQnodeObj *pObj) { return 0; } -static int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { +int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { SSdbRaw *pCommitRaw = mndQnodeActionEncode(pObj); if (pCommitRaw == NULL) return -1; if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1; @@ -188,7 +188,11 @@ static int32_t mndSetCreateQnodeCommitLogs(STrans *pTrans, SQnodeObj *pObj) { return 0; } -static int32_t mndSetCreateQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj) { +bool mndQnodeInDnode(SQnodeObj *pQnode, int32_t dnodeId) { + return pQnode->pDnode->id == dnodeId; +} + +int32_t mndSetCreateQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQnodeObj *pObj) { SDCreateQnodeReq createReq = {0}; createReq.dnodeId = pDnode->id; diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 4965d5c34a..0a6df02f5f 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -237,6 +237,23 @@ static void mndBecomeFollower(const SSyncFSM *pFsm) { taosThreadMutexUnlock(&pMgmt->lock); } +static void mndBecomeLearner(const SSyncFSM *pFsm) { + SMnode *pMnode = pFsm->data; + SSyncMgmt *pMgmt = &pMnode->syncMgmt; + mInfo("vgId:1, become learner"); + + taosThreadMutexLock(&pMgmt->lock); + if (pMgmt->transId != 0) { + mInfo("vgId:1, become learner and post sem, trans:%d, failed to propose since not leader", pMgmt->transId); + pMgmt->transId = 0; + pMgmt->transSec = 0; + pMgmt->transSeq = 0; + pMgmt->errCode = TSDB_CODE_SYN_NOT_LEADER; + tsem_post(&pMgmt->syncSem); + } + taosThreadMutexUnlock(&pMgmt->lock); +} + static void mndBecomeLeader(const SSyncFSM *pFsm) { mInfo("vgId:1, become leader"); SMnode *pMnode = pFsm->data; @@ -278,6 +295,7 @@ SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) { pFsm->FpReConfigCb = NULL; pFsm->FpBecomeLeaderCb = mndBecomeLeader; pFsm->FpBecomeFollowerCb = mndBecomeFollower; + pFsm->FpBecomeLearnerCb = mndBecomeLearner; pFsm->FpGetSnapshot = mndSyncGetSnapshot; pFsm->FpGetSnapshotInfo = mndSyncGetSnapshotInfo; pFsm->FpSnapshotStartRead = mndSnapshotStartRead; @@ -317,13 +335,16 @@ int32_t mndInitSync(SMnode *pMnode) { mInfo("vgId:1, start to open sync, replica:%d selfIndex:%d", pMgmt->numOfReplicas, pMgmt->selfIndex); SSyncCfg *pCfg = &syncInfo.syncCfg; + pCfg->totalReplicaNum = pMgmt->numOfTotalReplicas; pCfg->replicaNum = pMgmt->numOfReplicas; pCfg->myIndex = pMgmt->selfIndex; - for (int32_t i = 0; i < pMgmt->numOfReplicas; ++i) { + pCfg->lastIndex = pMgmt->lastIndex; + for (int32_t i = 0; i < pMgmt->numOfTotalReplicas; ++i) { SNodeInfo *pNode = &pCfg->nodeInfo[i]; pNode->nodeId = pMgmt->replicas[i].id; pNode->nodePort = pMgmt->replicas[i].port; tstrncpy(pNode->nodeFqdn, pMgmt->replicas[i].fqdn, sizeof(pNode->nodeFqdn)); + pNode->nodeRole = pMgmt->nodeRoles[i]; (void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); mInfo("vgId:1, index:%d ep:%s:%u dnode:%d cluster:%" PRId64, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId, pNode->clusterId); diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 106eea0313..cfb5bef9d0 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -546,6 +546,7 @@ static void mndTransDropData(STrans *pTrans) { pTrans->param = NULL; pTrans->paramLen = 0; } + (void)taosThreadMutexDestroy(&pTrans->mutex); } static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) { @@ -643,7 +644,7 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnConflct conflict, pTrans->stage = TRN_STAGE_PREPARE; pTrans->policy = policy; pTrans->conflict = conflict; - pTrans->exec = TRN_EXEC_PRARLLEL; + pTrans->exec = TRN_EXEC_PARALLEL; pTrans->createdTime = taosGetTimestampMs(); pTrans->redoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction)); pTrans->undoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction)); @@ -651,6 +652,7 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnConflct conflict, pTrans->pRpcArray = taosArrayInit(1, sizeof(SRpcHandleInfo)); pTrans->mTraceId = pReq ? TRACE_GET_ROOTID(&pReq->info.traceId) : 0; taosInitRWLatch(&pTrans->lockRpcArray); + taosThreadMutexInit(&pTrans->mutex, NULL); if (pTrans->redoActions == NULL || pTrans->undoActions == NULL || pTrans->commitActions == NULL || pTrans->pRpcArray == NULL) { @@ -793,6 +795,8 @@ void mndTransSetDbName(STrans *pTrans, const char *dbname, const char *stbname) void mndTransSetSerial(STrans *pTrans) { pTrans->exec = TRN_EXEC_SERIAL; } +void mndTransSetParallel(STrans *pTrans) { pTrans->exec = TRN_EXEC_PARALLEL; } + void mndTransSetOper(STrans *pTrans, EOperType oper) { pTrans->oper = oper; } static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) { @@ -1307,7 +1311,13 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans) int32_t code = 0; int32_t numOfActions = taosArrayGetSize(pTrans->redoActions); if (numOfActions == 0) return code; - if (pTrans->redoActionPos >= numOfActions) return code; + + taosThreadMutexLock(&pTrans->mutex); + + if (pTrans->redoActionPos >= numOfActions) { + taosThreadMutexUnlock(&pTrans->mutex); + return code; + } mInfo("trans:%d, execute %d actions serial, current redoAction:%d", pTrans->id, numOfActions, pTrans->redoActionPos); @@ -1377,6 +1387,8 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans) } } + taosThreadMutexUnlock(&pTrans->mutex); + return code; } diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 2a0d753722..3da594109a 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -23,7 +23,7 @@ #include "mndTrans.h" #include "tbase64.h" -#define USER_VER_NUMBER 3 +#define USER_VER_NUMBER 4 #define USER_RESERVE_SIZE 64 static int32_t mndCreateDefaultUsers(SMnode *pMnode); @@ -174,6 +174,7 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER) SDB_SET_INT8(pRaw, dataPos, pUser->reserve, _OVER) SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER) + SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER) @@ -263,7 +264,7 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER; - if (sver != 1 && sver != 2 && sver != 3) { + if (sver < 1 || sver > USER_VER_NUMBER) { terrno = TSDB_CODE_SDB_INVALID_DATA_VER; goto _OVER; } @@ -285,6 +286,9 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER) SDB_GET_INT8(pRaw, dataPos, &pUser->reserve, _OVER) SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER) + if (sver >= 4) { + SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER) + } int32_t numOfReadDbs = 0; int32_t numOfWriteDbs = 0; @@ -530,6 +534,7 @@ static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) { taosWLockLatch(&pOld->lock); pOld->updateTime = pNew->updateTime; pOld->authVersion = pNew->authVersion; + pOld->passVersion = pNew->passVersion; pOld->sysInfo = pNew->sysInfo; pOld->enable = pNew->enable; memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN); @@ -819,10 +824,14 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { if (mndUserDupObj(pUser, &newUser) != 0) goto _OVER; + newUser.passVersion = pUser->passVersion; if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) { char pass[TSDB_PASSWORD_LEN + 1] = {0}; taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass); memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN); + if (0 != strncmp(pUser->pass, pass, TSDB_PASSWORD_LEN)) { + ++newUser.passVersion; + } } if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) { @@ -1422,6 +1431,69 @@ _OVER: return code; } +int32_t mndValidateUserPassInfo(SMnode *pMnode, SUserPassVersion *pUsers, int32_t numOfUses, void **ppRsp, + int32_t *pRspLen) { + int32_t code = 0; + SUserPassBatchRsp batchRsp = {0}; + + for (int32_t i = 0; i < numOfUses; ++i) { + SUserObj *pUser = mndAcquireUser(pMnode, pUsers[i].user); + if (pUser == NULL) { + mError("user:%s, failed to validate user pass since %s", pUsers[i].user, terrstr()); + continue; + } + + pUsers[i].version = ntohl(pUsers[i].version); + if (pUser->passVersion <= pUsers[i].version) { + mTrace("user:%s, not update since mnd passVer %d <= client passVer %d", pUsers[i].user, pUser->passVersion, + pUsers[i].version); + mndReleaseUser(pMnode, pUser); + continue; + } + + SGetUserPassRsp rsp = {0}; + memcpy(rsp.user, pUser->user, TSDB_USER_LEN); + rsp.version = pUser->passVersion; + + if (!batchRsp.pArray && !(batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserPassRsp)))) { + code = TSDB_CODE_OUT_OF_MEMORY; + mndReleaseUser(pMnode, pUser); + goto _OVER; + } + + taosArrayPush(batchRsp.pArray, &rsp); + mndReleaseUser(pMnode, pUser); + } + + if (taosArrayGetSize(batchRsp.pArray) <= 0) { + goto _OVER; + } + + int32_t rspLen = tSerializeSUserPassBatchRsp(NULL, 0, &batchRsp); + if (rspLen < 0) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + void *pRsp = taosMemoryMalloc(rspLen); + if (pRsp == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + tSerializeSUserPassBatchRsp(pRsp, rspLen, &batchRsp); + + *ppRsp = pRsp; + *pRspLen = rspLen; + +_OVER: + if (code) { + *ppRsp = NULL; + *pRspLen = 0; + } + + tFreeSUserPassBatchRsp(&batchRsp); + return code; +} + int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) { int32_t code = 0; SSdb *pSdb = pMnode->pSdb; diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index 0003d07fd6..a8e9db28e9 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -62,6 +62,7 @@ int32_t mndInitVgroup(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_VND_COMPACT_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_VND_DISABLE_WRITE_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_SYNC_FORCE_FOLLOWER_RSP, mndTransProcessRsp); + mndSetMsgHandle(pMnode, TDMT_DND_ALTER_VNODE_TYPE_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_MND_REDISTRIBUTE_VGROUP, mndProcessRedistributeVgroupMsg); mndSetMsgHandle(pMnode, TDMT_MND_SPLIT_VGROUP, mndProcessSplitVgroupMsg); @@ -203,7 +204,7 @@ static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) { pNew->compStorage = pOld->compStorage; pNew->pointsWritten = pOld->pointsWritten; pNew->compact = pOld->compact; - memcpy(pOld->vnodeGid, pNew->vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid)); + memcpy(pOld->vnodeGid, pNew->vnodeGid, (TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA) * sizeof(SVnodeGid)); return 0; } @@ -244,8 +245,10 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg createReq.compression = pDb->cfg.compression; createReq.strict = pDb->cfg.strict; createReq.cacheLast = pDb->cfg.cacheLast; - createReq.replica = pVgroup->replica; + createReq.replica = 0; + createReq.learnerReplica = 0; createReq.selfIndex = -1; + createReq.learnerSelfIndex = -1; createReq.hashBegin = pVgroup->hashBegin; createReq.hashEnd = pVgroup->hashEnd; createReq.hashMethod = pDb->cfg.hashMethod; @@ -263,7 +266,15 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg createReq.tsdbPageSize = pDb->cfg.tsdbPageSize; for (int32_t v = 0; v < pVgroup->replica; ++v) { - SReplica *pReplica = &createReq.replicas[v]; + SReplica *pReplica = NULL; + + if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){ + pReplica = &createReq.replicas[createReq.replica]; + } + else{ + pReplica = &createReq.learnerReplicas[createReq.learnerReplica]; + } + SVnodeGid *pVgid = &pVgroup->vnodeGid[v]; SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId); if (pVgidDnode == NULL) { @@ -275,21 +286,40 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN); mndReleaseDnode(pMnode, pVgidDnode); - if (pDnode->id == pVgid->dnodeId) { - createReq.selfIndex = v; + if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){ + if (pDnode->id == pVgid->dnodeId) { + createReq.selfIndex = createReq.replica; + } + } + else{ + if (pDnode->id == pVgid->dnodeId) { + createReq.learnerSelfIndex = createReq.learnerReplica; + } + } + + if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){ + createReq.replica++; + } + else{ + createReq.learnerReplica++; } } - if (createReq.selfIndex == -1) { + if (createReq.selfIndex == -1 && createReq.learnerSelfIndex == -1) { terrno = TSDB_CODE_APP_ERROR; return NULL; } - mInfo("vgId:%d, build create vnode req, replica:%d selfIndex:%d strict:%d", createReq.vgId, createReq.replica, - createReq.selfIndex, createReq.strict); + mInfo("vgId:%d, build create vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d", + createReq.vgId, createReq.replica, createReq.selfIndex, createReq.learnerReplica, + createReq.learnerReplica, createReq.strict); for (int32_t i = 0; i < createReq.replica; ++i) { mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.replicas[i].fqdn, createReq.replicas[i].port); } + for (int32_t i = 0; i < createReq.learnerReplica; ++i) { + mInfo("vgId:%d, replica:%d ep:%s:%u", createReq.vgId, i, createReq.learnerReplicas[i].fqdn, + createReq.learnerReplicas[i].port); + } int32_t contLen = tSerializeSCreateVnodeReq(NULL, 0, &createReq); if (contLen < 0) { @@ -356,12 +386,24 @@ static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p SAlterVnodeReplicaReq alterReq = { .vgId = pVgroup->vgId, .strict = pDb->cfg.strict, - .replica = pVgroup->replica, + .replica = 0, + .learnerReplica = 0, .selfIndex = -1, + .learnerSelfIndex = -1, }; for (int32_t v = 0; v < pVgroup->replica; ++v) { - SReplica *pReplica = &alterReq.replicas[v]; + SReplica *pReplica = NULL; + + if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){ + pReplica = &alterReq.replicas[alterReq.replica]; + alterReq.replica++; + } + else{ + pReplica = &alterReq.learnerReplicas[alterReq.learnerReplica]; + alterReq.learnerReplica++; + } + SVnodeGid *pVgid = &pVgroup->vnodeGid[v]; SDnodeObj *pVgidDnode = mndAcquireDnode(pMnode, pVgid->dnodeId); if (pVgidDnode == NULL) return NULL; @@ -371,18 +413,30 @@ static void *mndBuildAlterVnodeReplicaReq(SMnode *pMnode, SDbObj *pDb, SVgObj *p memcpy(pReplica->fqdn, pVgidDnode->fqdn, TSDB_FQDN_LEN); mndReleaseDnode(pMnode, pVgidDnode); - if (dnodeId == pVgid->dnodeId) { - alterReq.selfIndex = v; + if(pVgroup->vnodeGid[v].nodeRole == TAOS_SYNC_ROLE_VOTER){ + if (dnodeId == pVgid->dnodeId) { + alterReq.selfIndex = v; + } + } + else{ + if (dnodeId == pVgid->dnodeId) { + alterReq.learnerSelfIndex = v; + } } } - alterReq.replica = pVgroup->replica; - mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d strict:%d", alterReq.vgId, alterReq.replica, - alterReq.selfIndex, alterReq.strict); + + mInfo("vgId:%d, build alter vnode req, replica:%d selfIndex:%d learnerReplica:%d learnerSelfIndex:%d strict:%d", + alterReq.vgId, alterReq.replica, alterReq.selfIndex, alterReq.learnerReplica, + alterReq.learnerSelfIndex, alterReq.strict); for (int32_t i = 0; i < alterReq.replica; ++i) { mInfo("vgId:%d, replica:%d ep:%s:%u", alterReq.vgId, i, alterReq.replicas[i].fqdn, alterReq.replicas[i].port); } + for (int32_t i = 0; i < alterReq.learnerReplica; ++i) { + mInfo("vgId:%d, learnerReplica:%d ep:%s:%u", alterReq.vgId, i, + alterReq.learnerReplicas[i].fqdn, alterReq.learnerReplicas[i].port); + } - if (alterReq.selfIndex == -1) { + if (alterReq.selfIndex == -1 && alterReq.learnerSelfIndex == -1) { terrno = TSDB_CODE_APP_ERROR; return NULL; } @@ -1101,6 +1155,28 @@ int32_t mndAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVg return 0; } +int32_t mndRestoreAddCreateVnodeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pDnode) { + STransAction action = {0}; + + action.epSet = mndGetDnodeEpset(pDnode); + + int32_t contLen = 0; + void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen); + if (pReq == NULL) return -1; + + action.pCont = pReq; + action.contLen = contLen; + action.msgType = TDMT_DND_CREATE_VNODE; + action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + taosMemoryFree(pReq); + return -1; + } + + return 0; +} + int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) { STransAction action = {0}; action.epSet = mndGetVgroupEpset(pMnode, pVgroup); @@ -1194,6 +1270,55 @@ int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pD return 0; } +int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) { + SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId); + if (pDnode == NULL) return -1; + + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + mndReleaseDnode(pMnode, pDnode); + + int32_t contLen = 0; + void *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, dnodeId, &contLen); + if (pReq == NULL) return -1; + + action.pCont = pReq; + action.contLen = contLen; + action.msgType = TDMT_DND_ALTER_VNODE_TYPE; + action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER; + action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + taosMemoryFree(pReq); + return -1; + } + + return 0; +} + +int32_t mndRestoreAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, + SDnodeObj *pDnode) { + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + + int32_t contLen = 0; + void *pReq = mndBuildAlterVnodeReplicaReq(pMnode, pDb, pVgroup, pDnode->id, &contLen); + if (pReq == NULL) return -1; + + action.pCont = pReq; + action.contLen = contLen; + action.msgType = TDMT_DND_ALTER_VNODE_TYPE; + action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER; + action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + taosMemoryFree(pReq); + return -1; + } + + return 0; +} + static int32_t mndAddDisableVnodeWriteAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) { SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId); @@ -1837,7 +1962,7 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra int32_t vgid = pVgroup->vgId; int8_t replica = pVgroup->replica; - if(pVgroup->replica <= 1) { + if(pVgroup->replica <= 1) { mInfo("trans:%d, vgid:%d no need to balance, replica:%d", pTrans->id, vgid, replica); return -1; } @@ -1871,6 +1996,19 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra return -1; } + SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName); + if (pDb == NULL) { + mError("trans:%d, vgid:%d failed to be balanced to dnode:%d, because db not exist", pTrans->id, vgid, dnodeId); + return -1; + } + + if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup) != 0) { + mError("trans:%d, vgid:%d failed to be balanced to dnode:%d", pTrans->id, vgid, dnodeId); + return -1; + } + + mndReleaseDb(pMnode, pDb); + SSdbRaw *pRaw = mndVgroupActionEncode(pVgroup); if (pRaw == NULL) { mError("trans:%d, vgid:%d failed to encode action to dnode:%d", pTrans->id, vgid, dnodeId); @@ -1885,7 +2023,8 @@ int32_t mndAddVgroupBalanceToTrans(SMnode *pMnode, SVgObj *pVgroup, STrans *pTra } else { - mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", pTrans->id, vgid, dnodeId, exist, online); + mInfo("trans:%d, vgid:%d cant be balanced to dnode:%d, exist:%d, online:%d", + pTrans->id, vgid, dnodeId, exist, online); } return 0; @@ -1953,18 +2092,33 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb mInfo("db:%s, vgId:%d, will add 2 vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId, pVgroup->vnodeGid[0].dnodeId); + //add first if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1; + + newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER; + newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_LEARNER; if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0) return -1; + if (mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[1]) != 0) return -1; + newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER; + if (mndAddAlterVnodeTypeAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0) + return -1; + if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup) != 0) return -1; + //add second if (mndAddVnodeToVgroup(pMnode, pTrans, &newVgroup, pArray) != 0) return -1; + newVgroup.vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER; + newVgroup.vnodeGid[1].nodeRole = TAOS_SYNC_ROLE_VOTER; + newVgroup.vnodeGid[2].nodeRole = TAOS_SYNC_ROLE_VOTER; + if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[0].dnodeId) != 0) return -1; if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, &newVgroup, newVgroup.vnodeGid[1].dnodeId) != 0) return -1; if (mndAddCreateVnodeAction(pMnode, pTrans, pNewDb, &newVgroup, &newVgroup.vnodeGid[2]) != 0) return -1; + if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, &newVgroup) != 0) return -1; } else if (newVgroup.replica == 3 && pNewDb->cfg.replications == 1) { mInfo("db:%s, vgId:%d, will remove 2 vnodes, vn:0 dnode:%d vn:1 dnode:%d vn:2 dnode:%d", pVgroup->dbName, @@ -1989,6 +2143,8 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb return -1; } + mndSortVnodeGid(&newVgroup); + { SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup); if (pVgRaw == NULL) return -1; @@ -2002,10 +2158,71 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb return 0; } +int32_t mndBuildRestoreAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *db, SVgObj *pVgroup, + SDnodeObj *pDnode) { + SVgObj newVgroup = {0}; + memcpy(&newVgroup, pVgroup, sizeof(SVgObj)); + + mInfo("db:%s, vgId:%d, restore vnodes, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId, + pVgroup->vnodeGid[0].dnodeId); + + if(newVgroup.replica == 1){ + int selected = 0; + for(int i = 0; i < newVgroup.replica; i++){ + newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER; + if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){ + selected = i; + } + } + if (mndAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, &newVgroup.vnodeGid[selected]) != 0) return -1; + } + else if(newVgroup.replica == 3){ + for(int i = 0; i < newVgroup.replica; i++){ + if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){ + newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_LEARNER; + } + else{ + newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER; + } + } + if (mndRestoreAddCreateVnodeAction(pMnode, pTrans, db, &newVgroup, pDnode) != 0) return -1; + + for(int i = 0; i < newVgroup.replica; i++){ + newVgroup.vnodeGid[i].nodeRole = TAOS_SYNC_ROLE_VOTER; + if(newVgroup.vnodeGid[i].dnodeId == pDnode->id){ + } + } + if (mndRestoreAddAlterVnodeTypeAction(pMnode, pTrans, db, &newVgroup, pDnode) != 0) + return -1; + } + + SSdbRaw *pVgRaw = mndVgroupActionEncode(&newVgroup); + if (pVgRaw == NULL) return -1; + if (mndTransAppendCommitlog(pTrans, pVgRaw) != 0) { + sdbFreeRaw(pVgRaw); + return -1; + } + (void)sdbSetRawStatus(pVgRaw, SDB_STATUS_READY); + + return 0; +} + static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup) { return 0; } +static int32_t mndTransCommitVgStatus(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus) { + SSdbRaw *pRaw = mndVgroupActionEncode(pVg); + if (pRaw == NULL) goto _err; + if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _err; + (void)sdbSetRawStatus(pRaw, vgStatus); + pRaw = NULL; + return 0; +_err: + sdbFreeRaw(pRaw); + return -1; +} + int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) { int32_t code = -1; STrans *pTrans = NULL; @@ -2067,6 +2284,7 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro mInfo("vgId:%d, vnode:%d dnode:%d", newVg2.vgId, i, newVg2.vnodeGid[i].dnodeId); } + // alter vgId and hash range int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP); if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, &newVg1, maxVgId) != 0) goto _OVER; newVg1.vgId = maxVgId; @@ -2075,31 +2293,24 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, &newVg2, maxVgId) != 0) goto _OVER; newVg2.vgId = maxVgId; + if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1) != 0) goto _OVER; + + if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2) != 0) goto _OVER; + // adjust vgroup replica if (pDb->cfg.replications != newVg1.replica) { if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray) != 0) goto _OVER; + } else { + if (mndTransCommitVgStatus(pTrans, &newVg1, SDB_STATUS_READY) < 0) goto _OVER; } + if (pDb->cfg.replications != newVg2.replica) { if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray) != 0) goto _OVER; + } else { + if (mndTransCommitVgStatus(pTrans, &newVg2, SDB_STATUS_READY) < 0) goto _OVER; } - pRaw = mndVgroupActionEncode(&newVg1); - if (pRaw == NULL) goto _OVER; - if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER; - (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY); - pRaw = NULL; - - pRaw = mndVgroupActionEncode(&newVg2); - if (pRaw == NULL) goto _OVER; - if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER; - (void)sdbSetRawStatus(pRaw, SDB_STATUS_READY); - pRaw = NULL; - - pRaw = mndVgroupActionEncode(pVgroup); - if (pRaw == NULL) goto _OVER; - if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER; - (void)sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED); - pRaw = NULL; + if (mndTransCommitVgStatus(pTrans, pVgroup, SDB_STATUS_DROPPED) < 0) goto _OVER; memcpy(&dbObj, pDb, sizeof(SDbObj)); if (dbObj.cfg.pRetensions != NULL) { @@ -2126,37 +2337,13 @@ _OVER: return code; } -static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { - SMnode *pMnode = pReq->info.node; - int32_t code = -1; - SVgObj *pVgroup = NULL; - SDbObj *pDb = NULL; +extern int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq); - SSplitVgroupReq req = {0}; - if (tDeserializeSSplitVgroupReq(pReq->pCont, pReq->contLen, &req) != 0) { - terrno = TSDB_CODE_INVALID_MSG; - goto _OVER; - } +static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) { return mndProcessSplitVgroupMsgImp(pReq); } - mInfo("vgId:%d, start to split", req.vgId); - if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_SPLIT_VGROUP) != 0) { - goto _OVER; - } - - pVgroup = mndAcquireVgroup(pMnode, req.vgId); - if (pVgroup == NULL) goto _OVER; - - pDb = mndAcquireDb(pMnode, pVgroup->dbName); - if (pDb == NULL) goto _OVER; - - code = mndSplitVgroup(pMnode, pReq, pDb, pVgroup); - if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; - -_OVER: - mndReleaseVgroup(pMnode, pVgroup); - mndReleaseDb(pMnode, pDb); - return code; -} +#ifndef TD_ENTERPRISE +int32_t mndProcessSplitVgroupMsgImp(SRpcMsg *pReq) { return 0; } +#endif static int32_t mndSetBalanceVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SDnodeObj *pSrc, SDnodeObj *pDst) { @@ -2344,6 +2531,13 @@ _OVER: bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid) { return !pVgroup->isTsma && pVgroup->dbUid == dbUid; } +bool mndVgroupInDnode(SVgObj *pVgroup, int32_t dnodeId) { + for(int i = 0; i < pVgroup->replica; i++){ + if(pVgroup->vnodeGid[i].dnodeId == dnodeId) return true; + } + return false; +} + static void *mndBuildCompactVnodeReq(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen, int64_t compactTs, STimeWindow tw) { SCompactVnodeReq compactReq = {0}; diff --git a/source/dnode/vnode/CMakeLists.txt b/source/dnode/vnode/CMakeLists.txt index f3087e3662..e8660cd6ad 100644 --- a/source/dnode/vnode/CMakeLists.txt +++ b/source/dnode/vnode/CMakeLists.txt @@ -84,6 +84,7 @@ target_include_directories( PUBLIC "inc" PUBLIC "src/inc" PUBLIC "${TD_SOURCE_DIR}/include/libs/scalar" + PUBLIC "${TD_SOURCE_DIR}/contrib/rocksdb/include" ) target_link_libraries( vnode @@ -100,6 +101,7 @@ target_link_libraries( # PUBLIC bdb # PUBLIC scalar + PUBLIC rocksdb PUBLIC transport PUBLIC stream PUBLIC index diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 88460cd3ca..d098ec9be2 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -61,13 +61,15 @@ void vnodeClose(SVnode *pVnode); int32_t vnodeSyncCommit(SVnode *pVnode); int32_t vnodeBegin(SVnode *pVnode); -int32_t vnodeStart(SVnode *pVnode); -void vnodeStop(SVnode *pVnode); -int64_t vnodeGetSyncHandle(SVnode *pVnode); -void vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnapshot); -void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId); -int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen); -int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list); +int32_t vnodeStart(SVnode *pVnode); +void vnodeStop(SVnode *pVnode); +int64_t vnodeGetSyncHandle(SVnode *pVnode); +void vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnapshot); +void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId); +int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen); +int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list); +int32_t vnodeIsCatchUp(SVnode *pVnode); +ESyncRole vnodeGetRole(SVnode *pVnode); int32_t vnodeGetCtbIdList(SVnode *pVnode, int64_t suid, SArray *list); int32_t vnodeGetCtbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bool (*filter)(void *arg), void *arg); @@ -175,8 +177,11 @@ typedef struct STsdbReader STsdbReader; #define CACHESCAN_RETRIEVE_LAST_ROW 0x4 #define CACHESCAN_RETRIEVE_LAST 0x8 -int32_t tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, void *pTableList, int32_t numOfTables, - SSDataBlock *pResBlock, STsdbReader **ppReader, const char *idstr, bool countOnly); +int32_t tsdbSetTableList(STsdbReader *pReader, const void *pTableList, int32_t num); +int32_t tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, void *pTableList, int32_t numOfTables, + SSDataBlock *pResBlock, STsdbReader **ppReader, const char *idstr, bool countOnly); + +void tsdbReaderSetId(STsdbReader *pReader, const char *idstr); void tsdbReaderClose(STsdbReader *pReader); int32_t tsdbNextDataBlock(STsdbReader *pReader, bool *hasNext); int32_t tsdbRetrieveDatablockSMA(STsdbReader *pReader, SSDataBlock *pDataBlock, bool *allHave); @@ -193,8 +198,9 @@ void tsdbReaderSetId(STsdbReader *pReader, const char *idstr); void tsdbReaderSetCloseFlag(STsdbReader *pReader); int32_t tsdbCacherowsReaderOpen(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols, - uint64_t suid, void **pReader, const char *idstr); -int32_t tsdbRetrieveCacheRows(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, SArray *pTableUids); + SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr); +int32_t tsdbRetrieveCacheRows(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds, + SArray *pTableUids); void *tsdbCacherowsReaderClose(void *pReader); int32_t tsdbGetTableSchema(SVnode *pVnode, int64_t uid, STSchema **pSchema, int64_t *suid); @@ -256,12 +262,12 @@ int32_t tqReaderRemoveTbUidList(STqReader *pReader, const SArray *tbUidList); int32_t tqSeekVer(STqReader *pReader, int64_t ver, const char *id); int32_t tqNextBlockInWal(STqReader* pReader); -bool tqNextBlockImpl(STqReader *pReader); +bool tqNextBlockImpl(STqReader *pReader, const char* idstr); int32_t extractSubmitMsgFromWal(SWalReader *pReader, SPackedData *pPackedData); int32_t tqReaderSetSubmitMsg(STqReader *pReader, void *msgStr, int32_t msgLen, int64_t ver); bool tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids); -int32_t tqRetrieveDataBlock(STqReader *pReader, SSubmitTbData **pSubmitTbDataRet); +int32_t tqRetrieveDataBlock(STqReader *pReader, const char* idstr); int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet); int32_t vnodeEnqueueStreamMsg(SVnode *pVnode, SRpcMsg *pMsg); @@ -333,6 +339,7 @@ struct SVnodeCfg { SVnodeStats vndStats; uint32_t hashBegin; uint32_t hashEnd; + bool hashChange; int16_t sttTrigger; int16_t hashPrefix; int16_t hashSuffix; diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index e50bbfb6f2..edaf72c41f 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -102,14 +102,9 @@ typedef struct { STqExecHandle execHandle; // exec SRpcMsg* msg; int32_t noDataPollCnt; + int8_t exec; } STqHandle; -typedef struct { - SMqDataRsp* pDataRsp; - char subKey[TSDB_SUBSCRIBE_KEY_LEN]; - SRpcHandleInfo info; -} STqPushEntry; - struct STQ { SVnode* pVnode; char* path; @@ -147,8 +142,9 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea // tqExec int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows); int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision); -int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type); -int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle); +int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type, + int32_t vgId); +int32_t tqPushDataRsp(STqHandle* pHandle, int32_t vgId); // tqMeta int32_t tqMetaOpen(STQ* pTq); @@ -184,7 +180,10 @@ int32_t tqStreamTasksScanWal(STQ* pTq); char* createStreamTaskIdStr(int64_t streamId, int32_t taskId); int32_t tqAddInputBlockNLaunchTask(SStreamTask* pTask, SStreamQueueItem* pQueueItem, int64_t ver); int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg); - +int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, + int32_t type, int64_t sver, int64_t ever); +int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq); +bool tqIsHandleExecuting(STqHandle* pHandle); #ifdef __cplusplus } #endif diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index 6102487400..b2bc9abf33 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -345,6 +345,16 @@ struct STsdbFS { SArray *aDFileSet; // SArray }; +typedef struct { + rocksdb_t *db; + rocksdb_options_t *options; + rocksdb_flushoptions_t *flushoptions; + rocksdb_writeoptions_t *writeoptions; + rocksdb_readoptions_t *readoptions; + rocksdb_writebatch_t *writebatch; + TdThreadMutex rMutex; +} SRocksCache; + struct STsdb { char *path; SVnode *pVnode; @@ -357,6 +367,7 @@ struct STsdb { TdThreadMutex lruMutex; SLRUCache *biCache; TdThreadMutex biMutex; + SRocksCache rCache; }; struct TSDBKEY { @@ -794,6 +805,8 @@ typedef struct SCacheRowsReader { uint64_t suid; char **transferBuf; // todo remove it soon int32_t numOfCols; + SArray *pCidList; + int32_t *pSlotIds; int32_t type; int32_t tableIndex; // currently returned result tables STableKeyInfo *pTableList; // table id list @@ -814,6 +827,10 @@ typedef struct { int32_t tsdbOpenCache(STsdb *pTsdb); void tsdbCloseCache(STsdb *pTsdb); +int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *row); +int32_t tsdbCacheGet(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCacheRowsReader *pr, int32_t ltype); +int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey); + int32_t tsdbCacheInsertLast(SLRUCache *pCache, tb_uid_t uid, TSDBROW *row, STsdb *pTsdb); int32_t tsdbCacheInsertLastrow(SLRUCache *pCache, STsdb *pTsdb, tb_uid_t uid, TSDBROW *row, bool dup); int32_t tsdbCacheGetLastH(SLRUCache *pCache, tb_uid_t uid, SCacheRowsReader *pr, LRUHandle **h); diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index d58263ab86..d7f0ef041a 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -19,6 +19,7 @@ #include "executor.h" #include "filter.h" #include "qworker.h" +#include "rocksdb/c.h" #include "sync.h" #include "tRealloc.h" #include "tchecksum.h" @@ -177,6 +178,7 @@ int tsdbClose(STsdb** pTsdb); int32_t tsdbBegin(STsdb* pTsdb); int32_t tsdbPrepareCommit(STsdb* pTsdb); int32_t tsdbCommit(STsdb* pTsdb, SCommitInfo* pInfo); +int32_t tsdbCacheCommit(STsdb* pTsdb); int32_t tsdbCompact(STsdb* pTsdb, SCompactInfo* pInfo); int32_t tsdbFinishCommit(STsdb* pTsdb); int32_t tsdbRollbackCommit(STsdb* pTsdb); @@ -206,7 +208,10 @@ int32_t tqProcessDelCheckInfoReq(STQ* pTq, int64_t version, char* msg, int32_t m int32_t tqProcessSubscribeReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); +int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen); int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg); +int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg); + // tq-stream int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index a0f913ec10..f6f2b3ec53 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -182,7 +182,7 @@ static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqData int32_t code = 0; if (type == TMQ_MSG_TYPE__POLL_RSP) { - tEncodeSize(tEncodeSMqDataRsp, pRsp, len, code); + tEncodeSize(tEncodeMqDataRsp, pRsp, len, code); } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { tEncodeSize(tEncodeSTaosxRsp, (STaosxRsp*)pRsp, len, code); } @@ -207,7 +207,7 @@ static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqData tEncoderInit(&encoder, abuf, len); if (type == TMQ_MSG_TYPE__POLL_RSP) { - tEncodeSMqDataRsp(&encoder, pRsp); + tEncodeMqDataRsp(&encoder, pRsp); } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp); } @@ -225,24 +225,31 @@ static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqData return 0; } -int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle) { +int32_t tqPushDataRsp(STqHandle* pHandle, int32_t vgId) { SMqDataRsp dataRsp = {0}; dataRsp.head.consumerId = pHandle->consumerId; dataRsp.head.epoch = pHandle->epoch; dataRsp.head.mqMsgType = TMQ_MSG_TYPE__POLL_RSP; - doSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP); + + int64_t sver = 0, ever = 0; + walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); + tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP, sver, ever); char buf1[80] = {0}; char buf2[80] = {0}; tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset); tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset); tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s", - TD_VID(pTq->pVnode), dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2); + vgId, dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2); return 0; } -int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type) { - doSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type); +int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, + int32_t type, int32_t vgId) { + int64_t sver = 0, ever = 0; + walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); + + tqDoSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type, sver, ever); char buf1[80] = {0}; char buf2[80] = {0}; @@ -250,50 +257,54 @@ int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, con tFormatOffset(buf2, 80, &pRsp->rspOffset); tqDebug("vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64, - TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId); + vgId, pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId); return 0; } int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { - STqOffset offset = {0}; - int32_t vgId = TD_VID(pTq->pVnode); + SMqVgOffset vgOffset = {0}; + int32_t vgId = TD_VID(pTq->pVnode); SDecoder decoder; tDecoderInit(&decoder, (uint8_t*)msg, msgLen); - if (tDecodeSTqOffset(&decoder, &offset) < 0) { + if (tDecodeMqVgOffset(&decoder, &vgOffset) < 0) { return -1; } tDecoderClear(&decoder); - if (offset.val.type == TMQ_OFFSET__SNAPSHOT_DATA || offset.val.type == TMQ_OFFSET__SNAPSHOT_META) { + STqOffset* pOffset = &vgOffset.offset; + + if (pOffset->val.type == TMQ_OFFSET__SNAPSHOT_DATA || pOffset->val.type == TMQ_OFFSET__SNAPSHOT_META) { tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:snapshot) uid:%" PRId64 ", ts:%" PRId64, - offset.subKey, vgId, offset.val.uid, offset.val.ts); - } else if (offset.val.type == TMQ_OFFSET__LOG) { - tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, offset.subKey, vgId, - offset.val.version); - if (offset.val.version + 1 == sversion) { - offset.val.version += 1; + pOffset->subKey, vgId, pOffset->val.uid, pOffset->val.ts); + } else if (pOffset->val.type == TMQ_OFFSET__LOG) { + tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, pOffset->subKey, vgId, + pOffset->val.version); + if (pOffset->val.version + 1 == sversion) { + pOffset->val.version += 1; } } else { - tqError("invalid commit offset type:%d", offset.val.type); + tqError("invalid commit offset type:%d", pOffset->val.type); return -1; } - STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, offset.subKey); - if (pSavedOffset != NULL && tqOffsetLessOrEqual(&offset, pSavedOffset)) { + STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey); + if (pSavedOffset != NULL && tqOffsetLessOrEqual(pOffset, pSavedOffset)) { + tqDebug("not update the offset, vgId:%d sub:%s since committed:%" PRId64 " less than/equal to existed:%" PRId64, + vgId, pOffset->subKey, pOffset->val.version, pSavedOffset->val.version); return 0; // no need to update the offset value } // save the new offset value - if (tqOffsetWrite(pTq->pOffsetStore, &offset) < 0) { + if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) { return -1; } - if (offset.val.type == TMQ_OFFSET__LOG) { - STqHandle* pHandle = taosHashGet(pTq->pHandle, offset.subKey, strlen(offset.subKey)); - if (pHandle && (walRefVer(pHandle->pRef, offset.val.version) < 0)) { + if (pOffset->val.type == TMQ_OFFSET__LOG) { + STqHandle* pHandle = taosHashGet(pTq->pHandle, pOffset->subKey, strlen(pOffset->subKey)); + if (pHandle && (walRefVer(pHandle->pRef, pOffset->val.version) < 0)) { return -1; } } @@ -301,6 +312,82 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t return 0; } +int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { + SMqVgOffset vgOffset = {0}; + int32_t vgId = TD_VID(pTq->pVnode); + + SDecoder decoder; + tDecoderInit(&decoder, (uint8_t*)msg, msgLen); + if (tDecodeMqVgOffset(&decoder, &vgOffset) < 0) { + return -1; + } + + tDecoderClear(&decoder); + + STqOffset* pOffset = &vgOffset.offset; + if (pOffset->val.type != TMQ_OFFSET__LOG) { + tqError("vgId:%d, subKey:%s invalid seek offset type:%d", vgId, pOffset->subKey, pOffset->val.type); + return -1; + } + + STqHandle* pHandle = taosHashGet(pTq->pHandle, pOffset->subKey, strlen(pOffset->subKey)); + if (pHandle == NULL) { + tqError("tmq seek: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", vgOffset.consumerId, vgId, + pOffset->subKey); + terrno = TSDB_CODE_INVALID_MSG; + return -1; + } + + // 2. check consumer-vg assignment status + taosRLockLatch(&pTq->lock); + if (pHandle->consumerId != vgOffset.consumerId) { + tqDebug("ERROR tmq seek: consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64, + vgOffset.consumerId, vgId, pOffset->subKey, pHandle->consumerId); + terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH; + taosRUnLockLatch(&pTq->lock); + return -1; + } + taosRUnLockLatch(&pTq->lock); + + //3. check the offset info + STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey); + if (pSavedOffset != NULL) { + if (pSavedOffset->val.type != TMQ_OFFSET__LOG) { + tqError("invalid saved offset type, vgId:%d sub:%s", vgId, pOffset->subKey); + return 0; // no need to update the offset value + } + + if (pSavedOffset->val.version == pOffset->val.version) { + tqDebug("vgId:%d subKey:%s no need to seek to %" PRId64 " prev offset:%" PRId64, vgId, pOffset->subKey, + pOffset->val.version, pSavedOffset->val.version); + return 0; + } + } + + int64_t sver = 0, ever = 0; + walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); + if (pOffset->val.version < sver) { + pOffset->val.version = sver; + } else if (pOffset->val.version > ever) { + pOffset->val.version = ever; + } + + // save the new offset value + if (pSavedOffset != NULL) { + tqDebug("vgId:%d sub:%s seek to:%" PRId64 " prev offset:%" PRId64, vgId, pOffset->subKey, pOffset->val.version, + pSavedOffset->val.version); + } else { + tqDebug("vgId:%d sub:%s seek to:%"PRId64" not saved yet", vgId, pOffset->subKey, pOffset->val.version); + } + + if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) { + tqError("failed to save offset, vgId:%d sub:%s seek to %" PRId64, vgId, pOffset->subKey, pOffset->val.version); + return -1; + } + + return 0; +} + int32_t tqCheckColModifiable(STQ* pTq, int64_t tbUid, int32_t colId) { void* pIter = NULL; @@ -352,7 +439,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) { taosRLockLatch(&pTq->lock); if (pHandle->consumerId != consumerId) { tqDebug("ERROR tmq poll: consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64, - consumerId, TD_VID(pTq->pVnode), req.subKey, pHandle->consumerId); + consumerId, vgId, req.subKey, pHandle->consumerId); terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH; taosRUnLockLatch(&pTq->lock); return -1; @@ -377,10 +464,90 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) { return tqExtractDataForMq(pTq, pHandle, &req, pMsg); } +int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) { + SMqPollReq req = {0}; + if (tDeserializeSMqPollReq(pMsg->pCont, pMsg->contLen, &req) < 0) { + tqError("tDeserializeSMqPollReq %d failed", pMsg->contLen); + terrno = TSDB_CODE_INVALID_MSG; + return -1; + } + + int64_t consumerId = req.consumerId; + STqOffsetVal reqOffset = req.reqOffset; + int32_t vgId = TD_VID(pTq->pVnode); + + // 1. find handle + STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey)); + if (pHandle == NULL) { + tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s not found", consumerId, vgId, req.subKey); + terrno = TSDB_CODE_INVALID_MSG; + return -1; + } + + // 2. check re-balance status + taosRLockLatch(&pTq->lock); + if (pHandle->consumerId != consumerId) { + tqDebug("ERROR consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64, + consumerId, vgId, req.subKey, pHandle->consumerId); + terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH; + taosRUnLockLatch(&pTq->lock); + return -1; + } + taosRUnLockLatch(&pTq->lock); + + int64_t sver = 0, ever = 0; + walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); + + int64_t currentVer = walReaderGetCurrentVer(pHandle->execHandle.pTqReader->pWalReader); + + SMqDataRsp dataRsp = {0}; + tqInitDataRsp(&dataRsp, &req); + + STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, req.subKey); + if (pOffset != NULL) { + if (pOffset->val.type != TMQ_OFFSET__LOG) { + tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s use snapshot, no valid wal info", consumerId, vgId, req.subKey); + terrno = TSDB_CODE_INVALID_PARA; + tDeleteMqDataRsp(&dataRsp); + return -1; + } + + dataRsp.rspOffset.type = TMQ_OFFSET__LOG; + dataRsp.rspOffset.version = pOffset->val.version; + } else { + if (req.useSnapshot == true) { + tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s snapshot not support wal info", consumerId, vgId, req.subKey); + terrno = TSDB_CODE_INVALID_PARA; + tDeleteMqDataRsp(&dataRsp); + return -1; + } + + dataRsp.rspOffset.type = TMQ_OFFSET__LOG; + + if (reqOffset.type == TMQ_OFFSET__LOG) { + dataRsp.rspOffset.version = currentVer; // return current consume offset value + } else if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) { + dataRsp.rspOffset.version = sver; // not consume yet, set the earliest position + } else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) { + dataRsp.rspOffset.version = ever; + } else { + tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s invalid offset type:%d", consumerId, vgId, req.subKey, + reqOffset.type); + terrno = TSDB_CODE_INVALID_PARA; + tDeleteMqDataRsp(&dataRsp); + return -1; + } + } + + tqDoSendDataRsp(&pMsg->info, &dataRsp, req.epoch, req.consumerId, TMQ_MSG_TYPE__WALINFO_RSP, sver, ever); + return 0; +} + int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg; + int32_t vgId = TD_VID(pTq->pVnode); - tqDebug("vgId:%d, tq process delete sub req %s", pTq->pVnode->config.vgId, pReq->subKey); + tqDebug("vgId:%d, tq process delete sub req %s", vgId, pReq->subKey); int32_t code = 0; // taosWLockLatch(&pTq->lock); // int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey)); @@ -395,6 +562,12 @@ int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg if (pHandle->pRef) { walCloseRef(pTq->pVnode->pWal, pHandle->pRef->refId); } + + while (tqIsHandleExecuting(pHandle)) { + tqDebug("vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", vgId, pHandle->subKey); + taosMsleep(5); + } + code = taosHashRemove(pTq->pHandle, pReq->subKey, strlen(pReq->subKey)); if (code != 0) { tqError("cannot process tq delete req %s, since no such handle", pReq->subKey); @@ -572,6 +745,10 @@ end: return ret; } +void freePtr(void *ptr) { + taosMemoryFree(*(void**)ptr); +} + int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { int32_t vgId = TD_VID(pTq->pVnode); pTask->id.idStr = createStreamTaskIdStr(pTask->id.streamId, pTask->id.taskId); @@ -608,6 +785,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { return -1; } + qSetTaskId(pTask->exec.pExecutor, pTask->id.taskId, pTask->id.streamId); } else if (pTask->taskLevel == TASK_LEVEL__AGG) { pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1); if (pTask->pState == NULL) { @@ -621,10 +799,11 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { if (pTask->exec.pExecutor == NULL) { return -1; } + + qSetTaskId(pTask->exec.pExecutor, pTask->id.taskId, pTask->id.streamId); } // sink - /*pTask->ahandle = pTq->pVnode;*/ if (pTask->outputType == TASK_OUTPUT__SMA) { pTask->smaSink.vnode = pTq->pVnode; pTask->smaSink.smaSink = smaHandleRes; @@ -644,6 +823,8 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { if (pTask->tbSink.pTSchema == NULL) { return -1; } + pTask->tbSink.pTblInfo = tSimpleHashInit(10240, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT)); + tSimpleHashSetFreeFp(pTask->tbSink.pTblInfo, freePtr); } if (pTask->taskLevel == TASK_LEVEL__SOURCE) { @@ -747,11 +928,9 @@ int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t sversion, char* msg, int32 } int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { - int32_t code; -#if 0 - code = streamMetaAddSerializedTask(pTq->pStreamMeta, version, msg, msgLen); - if (code < 0) return code; -#endif + int32_t code = 0; + int32_t vgId = TD_VID(pTq->pVnode); + if (tsDisableStream) { return 0; } @@ -777,7 +956,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms taosWLockLatch(&pTq->pStreamMeta->lock); code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask); if (code < 0) { - tqError("vgId:%d failed to add s-task:%s, total:%d", TD_VID(pTq->pVnode), pTask->id.idStr, + tqError("vgId:%d failed to add s-task:%s, total:%d", vgId, pTask->id.idStr, streamMetaGetNumOfTasks(pTq->pStreamMeta)); taosWUnLockLatch(&pTq->pStreamMeta->lock); return -1; @@ -790,8 +969,8 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms streamTaskCheckDownstream(pTask, sversion); } - tqDebug("vgId:%d s-task:%s is deployed and add meta from mnd, status:%d, total:%d", TD_VID(pTq->pVnode), - pTask->id.idStr, pTask->status.taskStatus, streamMetaGetNumOfTasks(pTq->pStreamMeta)); + tqDebug("vgId:%d s-task:%s is deployed and add meta from mnd, status:%d, total:%d", vgId, pTask->id.idStr, + pTask->status.taskStatus, streamMetaGetNumOfTasks(pTq->pStreamMeta)); return 0; } diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c index 950c5ea96b..e1e9bec348 100644 --- a/source/dnode/vnode/src/tq/tqPush.c +++ b/source/dnode/vnode/src/tq/tqPush.c @@ -55,6 +55,7 @@ int32_t tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg) { memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg)); pHandle->msg->pCont = rpcMallocCont(pMsg->contLen); } else { + tqPushDataRsp(pHandle, vgId); void* tmp = pHandle->msg->pCont; memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg)); pHandle->msg->pCont = tmp; @@ -76,7 +77,7 @@ int32_t tqUnregisterPushHandle(STQ* pTq, void *handle) { tqError("vgId:%d remove pHandle:%p,ret:%d consumer Id:0x%" PRIx64, vgId, pHandle, ret, pHandle->consumerId); if(pHandle->msg != NULL) { - tqPushDataRsp(pTq, pHandle); + tqPushDataRsp(pHandle, vgId); rpcFreeCont(pHandle->msg->pCont); taosMemoryFree(pHandle->msg); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index e13c0288be..e9eb9d05fc 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -419,15 +419,15 @@ int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, i return 0; } -bool tqNextBlockImpl(STqReader* pReader) { +bool tqNextBlockImpl(STqReader* pReader, const char* idstr) { if (pReader->msg.msgStr == NULL) { return false; } - int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData); - while (pReader->nextBlk < blockSz) { - tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg.msgStr, pReader->msg.msgLen, - pReader->msg.ver, pReader->nextBlk); + int32_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData); + while (pReader->nextBlk < numOfBlocks) { + tqDebug("tq reader next data block, len:%d ver:%" PRId64 " index:%d/%d, %s", pReader->msg.msgLen, + pReader->msg.ver, pReader->nextBlk, numOfBlocks, idstr); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk); if (pReader->tbIdHash == NULL) { @@ -503,13 +503,11 @@ int32_t tqMaskBlock(SSchemaWrapper* pDst, SSDataBlock* pBlock, const SSchemaWrap return 0; } -int32_t tqRetrieveDataBlock(STqReader* pReader, SSubmitTbData** pSubmitTbDataRet) { - tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk); +int32_t tqRetrieveDataBlock(STqReader* pReader, const char* idstr) { + tqDebug("tq reader retrieve data block %p, index:%d/%d, %s", pReader->msg.msgStr, pReader->nextBlk, + (int32_t)taosArrayGetSize(pReader->submit.aSubmitTbData), idstr); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk++); - if (pSubmitTbDataRet) { - *pSubmitTbDataRet = pSubmitTbData; - } SSDataBlock* pBlock = pReader->pResBlock; blockDataCleanup(pBlock); @@ -674,12 +672,10 @@ int32_t tqRetrieveDataBlock(STqReader* pReader, SSubmitTbData** pSubmitTbDataRet SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j); while (1) { SColVal colVal; - tqDebug("start to extract column id:%d, index:%d", pColData->info.colId, sourceIdx); - tRowGet(pRow, pTSchema, sourceIdx, &colVal); if (colVal.cid < pColData->info.colId) { - tqDebug("colIndex:%d column id:%d in row, ignore, the required colId:%d, total cols in schema:%d", - sourceIdx, colVal.cid, pColData->info.colId, pTSchema->numOfCols); +// tqDebug("colIndex:%d column id:%d in row, ignore, the required colId:%d, total cols in schema:%d", +// sourceIdx, colVal.cid, pColData->info.colId, pTSchema->numOfCols); sourceIdx++; continue; } else if (colVal.cid == pColData->info.colId) { diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index 800bcf2469..ea7e9ee715 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -57,25 +57,6 @@ int32_t tqStreamTasksScanWal(STQ* pTq) { return 0; } -static SArray* extractTaskIdList(SStreamMeta* pStreamMeta, int32_t numOfTasks) { - SArray* pTaskIdList = taosArrayInit(numOfTasks, sizeof(int32_t)); - void* pIter = NULL; - - taosWLockLatch(&pStreamMeta->lock); - while (1) { - pIter = taosHashIterate(pStreamMeta->pTasks, pIter); - if (pIter == NULL) { - break; - } - - SStreamTask* pTask = *(SStreamTask**)pIter; - taosArrayPush(pTaskIdList, &pTask->id.taskId); - } - - taosWUnLockLatch(&pStreamMeta->lock); - return pTaskIdList; -} - int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { *pScanIdle = true; bool noNewDataInWal = true; @@ -139,6 +120,8 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } + + // append the data for the stream tqDebug("vgId:%d s-task:%s wal reader seek to ver:%" PRId64, vgId, pTask->id.idStr, pTask->chkInfo.currentVer); } else { diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 800bcc8b71..52f92cd229 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -205,7 +205,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR if (pExec->subType == TOPIC_SUB_TYPE__TABLE) { STqReader* pReader = pExec->pTqReader; tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver); - while (tqNextBlockImpl(pReader)) { + while (tqNextBlockImpl(pReader, NULL)) { taosArrayClear(pBlocks); taosArrayClear(pSchemas); SSubmitTbData* pSubmitTbDataRet = NULL; diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index 9373f23c02..4a9e3dcee7 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -17,6 +17,13 @@ #include "tmsg.h" #include "tq.h" +#define MAX_CATCH_NUM 10240 + +typedef struct STblInfo { + uint64_t uid; + char tbName[TSDB_TABLE_NAME_LEN]; +} STblInfo; + int32_t tqBuildDeleteReq(const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq, const char* pIdStr) { int32_t totalRows = pDataBlock->info.rows; @@ -90,6 +97,22 @@ end: return ret; } +int32_t tqGetTableInfo(SSHashObj* tblInfo ,uint64_t groupId, STblInfo** pTbl) { + void* pVal = tSimpleHashGet(tblInfo, &groupId, sizeof(uint64_t)); + if (pVal) { + *pTbl = *(STblInfo**)pVal; + return TSDB_CODE_SUCCESS; + } + return TSDB_CODE_FAILED; +} + +int32_t tqPutTableInfo(SSHashObj* tblInfo ,uint64_t groupId, STblInfo* pTbl) { + if (tSimpleHashGetSize(tblInfo) > MAX_CATCH_NUM) { + return TSDB_CODE_SUCCESS; + } + return tSimpleHashPut(tblInfo, &groupId, sizeof(uint64_t), &pTbl, POINTER_BYTES); +} + int32_t tqPutReqToQueue(SVnode* pVnode, SVCreateTbBatchReq* pReqs) { void* buf = NULL; int32_t tlen = 0; @@ -260,100 +283,112 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d tbData.suid = suid; tbData.uid = 0; // uid is assigned by vnode tbData.sver = pTSchema->version; + STblInfo* pTblMeta = NULL; - char* ctbName = NULL; - tqDebug("vgId:%d, stream write into %s, table auto created", TD_VID(pVnode), pDataBlock->info.parTbName); - if (pDataBlock->info.parTbName[0]) { - ctbName = taosStrdup(pDataBlock->info.parTbName); - } else { - ctbName = buildCtbNameByGroupId(stbFullName, pDataBlock->info.id.groupId); + int32_t res = tqGetTableInfo(pTask->tbSink.pTblInfo, pDataBlock->info.id.groupId, &pTblMeta); + if (res != TSDB_CODE_SUCCESS) { + pTblMeta = taosMemoryCalloc(1, sizeof(STblInfo)); } - SMetaReader mr = {0}; - metaReaderInit(&mr, pVnode->pMeta, 0); - if (metaGetTableEntryByName(&mr, ctbName) < 0) { - metaReaderClear(&mr); - tqDebug("vgId:%d, stream write into %s, table auto created", TD_VID(pVnode), ctbName); - - SVCreateTbReq* pCreateTbReq = NULL; - - if (!(pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateStbReq)))) { - taosMemoryFree(ctbName); - goto _end; - }; - - // set const - pCreateTbReq->flags = 0; - pCreateTbReq->type = TSDB_CHILD_TABLE; - pCreateTbReq->ctb.suid = suid; - - // set super table name - SName name = {0}; - tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); - pCreateTbReq->ctb.stbName = taosStrdup((char*)tNameGetTableName(&name)); // taosStrdup(stbFullName); - - // set tag content - tagArray = taosArrayInit(1, sizeof(STagVal)); - if (!tagArray) { - taosMemoryFree(ctbName); - tdDestroySVCreateTbReq(pCreateTbReq); - goto _end; + char* ctbName = pDataBlock->info.parTbName; + if (!ctbName[0]) { + if (res == TSDB_CODE_SUCCESS) { + memcpy(ctbName, pTblMeta->tbName, strlen(pTblMeta->tbName)); + } else { + char* tmp = buildCtbNameByGroupId(stbFullName, pDataBlock->info.id.groupId); + memcpy(ctbName, tmp, strlen(tmp)); + memcpy(pTblMeta->tbName, tmp, strlen(tmp)); + taosMemoryFree(tmp); + tqDebug("vgId:%d, gropuid:%" PRIu64 " datablock tabel name is null", TD_VID(pVnode), + pDataBlock->info.id.groupId); } - STagVal tagVal = { - .cid = pTSchema->numOfCols + 1, - .type = TSDB_DATA_TYPE_UBIGINT, - .i64 = (int64_t)pDataBlock->info.id.groupId, - }; - taosArrayPush(tagArray, &tagVal); - pCreateTbReq->ctb.tagNum = taosArrayGetSize(tagArray); + } - STag* pTag = NULL; - tTagNew(tagArray, 1, false, &pTag); - tagArray = taosArrayDestroy(tagArray); - if (pTag == NULL) { - taosMemoryFree(ctbName); - tdDestroySVCreateTbReq(pCreateTbReq); - terrno = TSDB_CODE_OUT_OF_MEMORY; - taosMemoryFree(ctbName); - tdDestroySVCreateTbReq(pCreateTbReq); - goto _end; - } - pCreateTbReq->ctb.pTag = (uint8_t*)pTag; - - // set tag name - SArray* tagName = taosArrayInit(1, TSDB_COL_NAME_LEN); - char tagNameStr[TSDB_COL_NAME_LEN] = {0}; - strcpy(tagNameStr, "group_id"); - taosArrayPush(tagName, tagNameStr); - pCreateTbReq->ctb.tagName = tagName; - - // set table name - pCreateTbReq->name = ctbName; - ctbName = NULL; - - tbData.pCreateTbReq = pCreateTbReq; - tbData.flags = SUBMIT_REQ_AUTO_CREATE_TABLE; + if (res == TSDB_CODE_SUCCESS) { + tbData.uid = pTblMeta->uid; } else { - if (mr.me.type != TSDB_CHILD_TABLE) { - tqError("vgId:%d, failed to write into %s, since table type incorrect, type %d", TD_VID(pVnode), ctbName, - mr.me.type); + SMetaReader mr = {0}; + metaReaderInit(&mr, pVnode->pMeta, 0); + if (metaGetTableEntryByName(&mr, ctbName) < 0) { metaReaderClear(&mr); - taosMemoryFree(ctbName); - continue; - } + taosMemoryFree(pTblMeta); + tqDebug("vgId:%d, stream write into %s, table auto created", TD_VID(pVnode), ctbName); - if (mr.me.ctbEntry.suid != suid) { - tqError("vgId:%d, failed to write into %s, since suid mismatch, expect suid: %" PRId64 - ", actual suid %" PRId64 "", - TD_VID(pVnode), ctbName, suid, mr.me.ctbEntry.suid); + SVCreateTbReq* pCreateTbReq = NULL; + + if (!(pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateStbReq)))) { + goto _end; + }; + + // set const + pCreateTbReq->flags = 0; + pCreateTbReq->type = TSDB_CHILD_TABLE; + pCreateTbReq->ctb.suid = suid; + + // set super table name + SName name = {0}; + tNameFromString(&name, stbFullName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); + pCreateTbReq->ctb.stbName = taosStrdup((char*)tNameGetTableName(&name)); // taosStrdup(stbFullName); + + // set tag content + tagArray = taosArrayInit(1, sizeof(STagVal)); + if (!tagArray) { + tdDestroySVCreateTbReq(pCreateTbReq); + goto _end; + } + STagVal tagVal = { + .cid = pTSchema->numOfCols + 1, + .type = TSDB_DATA_TYPE_UBIGINT, + .i64 = (int64_t)pDataBlock->info.id.groupId, + }; + taosArrayPush(tagArray, &tagVal); + pCreateTbReq->ctb.tagNum = taosArrayGetSize(tagArray); + + STag* pTag = NULL; + tTagNew(tagArray, 1, false, &pTag); + tagArray = taosArrayDestroy(tagArray); + if (pTag == NULL) { + tdDestroySVCreateTbReq(pCreateTbReq); + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _end; + } + pCreateTbReq->ctb.pTag = (uint8_t*)pTag; + + // set tag name + SArray* tagName = taosArrayInit(1, TSDB_COL_NAME_LEN); + char tagNameStr[TSDB_COL_NAME_LEN] = {0}; + strcpy(tagNameStr, "group_id"); + taosArrayPush(tagName, tagNameStr); + pCreateTbReq->ctb.tagName = tagName; + + // set table name + pCreateTbReq->name = taosStrdup(ctbName); + + tbData.pCreateTbReq = pCreateTbReq; + tbData.flags = SUBMIT_REQ_AUTO_CREATE_TABLE; + } else { + if (mr.me.type != TSDB_CHILD_TABLE) { + tqError("vgId:%d, failed to write into %s, since table type incorrect, type %d", TD_VID(pVnode), ctbName, + mr.me.type); + metaReaderClear(&mr); + taosMemoryFree(pTblMeta); + continue; + } + + if (mr.me.ctbEntry.suid != suid) { + tqError("vgId:%d, failed to write into %s, since suid mismatch, expect suid: %" PRId64 + ", actual suid %" PRId64 "", + TD_VID(pVnode), ctbName, suid, mr.me.ctbEntry.suid); + metaReaderClear(&mr); + taosMemoryFree(pTblMeta); + continue; + } + + tbData.uid = mr.me.uid; + pTblMeta->uid = mr.me.uid; + tqPutTableInfo(pTask->tbSink.pTblInfo, pDataBlock->info.id.groupId, pTblMeta); metaReaderClear(&mr); - taosMemoryFree(ctbName); - continue; } - - tbData.uid = mr.me.uid; - metaReaderClear(&mr); - taosMemoryFreeClear(ctbName); } // rows diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 94803ef438..885eb65160 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -18,11 +18,11 @@ #define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0) #define NO_POLL_CNT 5 -static int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp); +static int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp, int32_t vgId); char* createStreamTaskIdStr(int64_t streamId, int32_t taskId) { char buf[128] = {0}; - sprintf(buf, "0x%" PRIx64 "-%d", streamId, taskId); + sprintf(buf, "0x%" PRIx64 "-0x%x", streamId, taskId); return taosStrdup(buf); } @@ -41,7 +41,7 @@ int32_t tqAddInputBlockNLaunchTask(SStreamTask* pTask, SStreamQueueItem* pQueueI return TSDB_CODE_SUCCESS; } -static int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq, int8_t subType) { +int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq) { pRsp->reqOffset = pReq->reqOffset; pRsp->blockData = taosArrayInit(0, sizeof(void*)); @@ -131,13 +131,13 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand } else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) { if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType); + tqInitDataRsp(&dataRsp, pRequest); tqOffsetResetToLog(&dataRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal)); tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, (latest) offset reset to %" PRId64, consumerId, pHandle->subKey, vgId, dataRsp.rspOffset.version); - int32_t code = tqSendDataRsp(pTq, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP); - tDeleteSMqDataRsp(&dataRsp); + int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId); + tDeleteMqDataRsp(&dataRsp); *pBlockReturned = true; return code; @@ -145,7 +145,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand STaosxRsp taosxRsp = {0}; tqInitTaosxRsp(&taosxRsp, pRequest); tqOffsetResetToLog(&taosxRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal)); - int32_t code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); + int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); tDeleteSTaosxRsp(&taosxRsp); *pBlockReturned = true; @@ -162,6 +162,8 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand return 0; } +bool tqIsHandleExecuting(STqHandle* pHandle) { return 1 == atomic_load_8(&pHandle->exec); } + static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, STqOffsetVal* pOffset) { uint64_t consumerId = pRequest->consumerId; @@ -169,41 +171,47 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, int code = 0; SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType); - qTaskInfo_t task = pHandle->execHandle.task; - if(qTaskIsExecuting(task)){ - code = tqSendDataRsp(pTq, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP); - tDeleteSMqDataRsp(&dataRsp); - return code; + tqInitDataRsp(&dataRsp, pRequest); +// qTaskInfo_t task = pHandle->execHandle.task; +// if (qTaskIsExecuting(task)) { +// code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId); +// tDeleteMqDataRsp(&dataRsp); +// return code; +// } + + // todo add more status check to avoid race condition + while (tqIsHandleExecuting(pHandle)) { + tqDebug("vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", vgId, pHandle->subKey); + taosMsleep(5); } + atomic_store_8(&pHandle->exec, 1); + qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId); code = tqScanData(pTq, pHandle, &dataRsp, pOffset); - if(code != 0) { + if (code != 0) { goto end; } // till now, all data has been transferred to consumer, new data needs to push client once arrived. if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG && dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) { - if(pHandle->noDataPollCnt >= NO_POLL_CNT){ // send poll result to client if no data 5 times to avoid lost data + if (pHandle->noDataPollCnt >= NO_POLL_CNT) { // send poll result to client if no data 5 times to avoid lost data pHandle->noDataPollCnt = 0; // lock taosWLockLatch(&pTq->lock); code = tqRegisterPushHandle(pTq, pHandle, pMsg); taosWUnLockLatch(&pTq->lock); - tDeleteSMqDataRsp(&dataRsp); + tDeleteMqDataRsp(&dataRsp); + atomic_store_8(&pHandle->exec, 0); return code; - } - else{ + } else { pHandle->noDataPollCnt++; } } - - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP); - // NOTE: this pHandle->consumerId may have been changed already. + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId); end: { @@ -211,79 +219,83 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, tFormatOffset(buf, 80, &dataRsp.rspOffset); tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64 " code:%d", consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code); -// taosWUnLockLatch(&pTq->lock); - tDeleteSMqDataRsp(&dataRsp); + tDeleteMqDataRsp(&dataRsp); } + + atomic_store_8(&pHandle->exec, 0); return code; } - static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, STqOffsetVal *offset) { - int code = 0; + int code = 0; int32_t vgId = TD_VID(pTq->pVnode); SWalCkHead* pCkHead = NULL; SMqMetaRsp metaRsp = {0}; STaosxRsp taosxRsp = {0}; tqInitTaosxRsp(&taosxRsp, pRequest); - qTaskInfo_t task = pHandle->execHandle.task; - if(qTaskIsExecuting(task)){ - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); - tDeleteSTaosxRsp(&taosxRsp); - return code; +// qTaskInfo_t task = pHandle->execHandle.task; +// if(qTaskIsExecuting(task)){ +// code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); +// tDeleteSTaosxRsp(&taosxRsp); +// return code; +// } + + while (tqIsHandleExecuting(pHandle)) { + tqDebug("vgId:%d, topic:%s, subscription is executing, wait for 5ms and retry", vgId, pHandle->subKey); + taosMsleep(5); } + atomic_store_8(&pHandle->exec, 1); + if (offset->type != TMQ_OFFSET__LOG) { if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) { - tDeleteSTaosxRsp(&taosxRsp); - return -1; + code = -1; + goto end; } if (metaRsp.metaRspLen > 0) { - code = tqSendMetaPollRsp(pTq, pMsg, pRequest, &metaRsp); + code = tqSendMetaPollRsp(pHandle, pMsg, pRequest, &metaRsp, vgId); tqDebug("tmq poll: consumer:0x%" PRIx64 " subkey:%s vgId:%d, send meta offset type:%d,uid:%" PRId64 ",ts:%" PRId64, pRequest->consumerId, pHandle->subKey, vgId, metaRsp.rspOffset.type, metaRsp.rspOffset.uid, metaRsp.rspOffset.ts); taosMemoryFree(metaRsp.metaRsp); - tDeleteSTaosxRsp(&taosxRsp); - return code; + goto end; } tqDebug("taosx poll: consumer:0x%" PRIx64 " subkey:%s vgId:%d, send data blockNum:%d, offset type:%d,uid:%" PRId64 ",ts:%" PRId64,pRequest->consumerId, pHandle->subKey, vgId, taosxRsp.blockNum, taosxRsp.rspOffset.type, taosxRsp.rspOffset.uid,taosxRsp.rspOffset.ts); if (taosxRsp.blockNum > 0) { - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); - tDeleteSTaosxRsp(&taosxRsp); - return code; + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + goto end; }else { *offset = taosxRsp.rspOffset; } } - if (offset->type == TMQ_OFFSET__LOG) { verifyOffset(pHandle->pWalReader, offset); int64_t fetchVer = offset->version + 1; pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048); if (pCkHead == NULL) { - tDeleteSTaosxRsp(&taosxRsp); terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; + code = -1; + goto end; } + walSetReaderCapacity(pHandle->pWalReader, 2048); int totalRows = 0; while (1) { int32_t savedEpoch = atomic_load_32(&pHandle->epoch); if (savedEpoch > pRequest->epoch) { tqWarn("tmq poll: consumer:0x%" PRIx64 " (epoch %d), subkey:%s vgId:%d offset %" PRId64 - ", found new consumer epoch %d, discard req epoch %d", pRequest->consumerId, pRequest->epoch, pHandle->subKey, vgId, fetchVer, savedEpoch, pRequest->epoch); + ", found new consumer epoch %d, discard req epoch %d", + pRequest->consumerId, pRequest->epoch, pHandle->subKey, vgId, fetchVer, savedEpoch, pRequest->epoch); break; } if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead, pRequest->reqId) < 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); - tDeleteSTaosxRsp(&taosxRsp); - taosMemoryFreeClear(pCkHead); - return code; + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + goto end; } SWalCont* pHead = &pCkHead->head; @@ -294,10 +306,8 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (pHead->msgType != TDMT_VND_SUBMIT) { if(totalRows > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer - 1); - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); - tDeleteSTaosxRsp(&taosxRsp); - taosMemoryFreeClear(pCkHead); - return code; + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + goto end; } tqDebug("fetch meta msg, ver:%" PRId64 ", type:%s", pHead->version, TMSG_INFO(pHead->msgType)); @@ -305,17 +315,8 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, metaRsp.resMsgType = pHead->msgType; metaRsp.metaRspLen = pHead->bodyLen; metaRsp.metaRsp = pHead->body; - if (tqSendMetaPollRsp(pTq, pMsg, pRequest, &metaRsp) < 0) { - code = -1; - taosMemoryFreeClear(pCkHead); - tDeleteSTaosxRsp(&taosxRsp); - return code; - } - - code = 0; - taosMemoryFreeClear(pCkHead); - tDeleteSTaosxRsp(&taosxRsp); - return code; + code = tqSendMetaPollRsp(pHandle, pMsg, pRequest, &metaRsp, vgId); + goto end; } // process data @@ -325,29 +326,28 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, .ver = pHead->version, }; - if (tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows) < 0) { - tqError("tmq poll: tqTaosxScanLog error %" PRId64 ", in vgId:%d, subkey %s", pRequest->consumerId, vgId, - pRequest->subKey); - taosMemoryFreeClear(pCkHead); - tDeleteSTaosxRsp(&taosxRsp); - return -1; + code = tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows); + if (code < 0) { + tqError("tmq poll: tqTaosxScanLog error %" PRId64 ", in vgId:%d, subkey %s", pRequest->consumerId, vgId, pRequest->subKey); + goto end; } if (totalRows >= 4096 || taosxRsp.createTableNum > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP); - tDeleteSTaosxRsp(&taosxRsp); - taosMemoryFreeClear(pCkHead); - return code; + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + goto end; } else { fetchVer++; } } } +end: + atomic_store_8(&pHandle->exec, 0); + tDeleteSTaosxRsp(&taosxRsp); taosMemoryFreeClear(pCkHead); - return 0; + return code; } int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg) { @@ -382,10 +382,19 @@ int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequ } } -int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) { +static void initMqRspHead(SMqRspHead* pMsgHead, int32_t type, int32_t epoch, int64_t consumerId, int64_t sver, + int64_t ever) { + pMsgHead->consumerId = consumerId; + pMsgHead->epoch = epoch; + pMsgHead->mqMsgType = type; + pMsgHead->walsver = sver; + pMsgHead->walever = ever; +} + +int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp, int32_t vgId) { int32_t len = 0; int32_t code = 0; - tEncodeSize(tEncodeSMqMetaRsp, pRsp, len, code); + tEncodeSize(tEncodeMqMetaRsp, pRsp, len, code); if (code < 0) { return -1; } @@ -395,27 +404,64 @@ int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, return -1; } - ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_META_RSP; - ((SMqRspHead*)buf)->epoch = pReq->epoch; - ((SMqRspHead*)buf)->consumerId = pReq->consumerId; + int64_t sver = 0, ever = 0; + walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever); + initMqRspHead(buf, TMQ_MSG_TYPE__POLL_META_RSP, pReq->epoch, pReq->consumerId, sver, ever); void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); SEncoder encoder = {0}; tEncoderInit(&encoder, abuf, len); - tEncodeSMqMetaRsp(&encoder, pRsp); + tEncodeMqMetaRsp(&encoder, pRsp); tEncoderClear(&encoder); - SRpcMsg resp = { - .info = pMsg->info, - .pCont = buf, - .contLen = tlen, - .code = 0, - }; - tmsgSendRsp(&resp); + SRpcMsg resp = { .info = pMsg->info, .pCont = buf, .contLen = tlen, .code = 0 }; - tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) send rsp, res msg type %d, offset type:%d", - TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->resMsgType, pRsp->rspOffset.type); + tmsgSendRsp(&resp); + tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) send rsp, res msg type %d, offset type:%d", vgId, + pReq->consumerId, pReq->epoch, pRsp->resMsgType, pRsp->rspOffset.type); return 0; } + +int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, + int32_t type, int64_t sver, int64_t ever) { + int32_t len = 0; + int32_t code = 0; + + if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + tEncodeSize(tEncodeMqDataRsp, pRsp, len, code); + } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { + tEncodeSize(tEncodeSTaosxRsp, (STaosxRsp*)pRsp, len, code); + } + + if (code < 0) { + return -1; + } + + int32_t tlen = sizeof(SMqRspHead) + len; + void* buf = rpcMallocCont(tlen); + if (buf == NULL) { + return -1; + } + + SMqRspHead* pHead = (SMqRspHead*)buf; + initMqRspHead(pHead, type, epoch, consumerId, sver, ever); + + void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); + + SEncoder encoder = {0}; + tEncoderInit(&encoder, abuf, len); + + if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + tEncodeMqDataRsp(&encoder, pRsp); + } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { + tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp); + } + + tEncoderClear(&encoder); + SRpcMsg rsp = { .info = *pRpcHandleInfo, .pCont = buf, .contLen = tlen, .code = 0 }; + + tmsgSendRsp(&rsp); + return 0; +} \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 65fc086f8d..c0a8de5743 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -12,7 +12,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - #include "tsdb.h" static int32_t tsdbOpenBICache(STsdb *pTsdb) { @@ -47,6 +46,513 @@ static void tsdbCloseBICache(STsdb *pTsdb) { } } +#define ROCKS_KEY_LEN 64 + +static void tsdbGetRocksPath(STsdb *pTsdb, char *path) { + SVnode *pVnode = pTsdb->pVnode; + if (pVnode->pTfs) { + if (path) { + snprintf(path, TSDB_FILENAME_LEN, "%s%s%s%scache.rdb", tfsGetPrimaryPath(pTsdb->pVnode->pTfs), TD_DIRSEP, + pTsdb->path, TD_DIRSEP); + } + } else { + if (path) { + snprintf(path, TSDB_FILENAME_LEN, "%s%scache.rdb", pTsdb->path, TD_DIRSEP); + } + } +} + +static int32_t tsdbOpenRocksCache(STsdb *pTsdb) { + int32_t code = 0; + + rocksdb_options_t *options = rocksdb_options_create(); + if (NULL == options) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + + rocksdb_options_set_create_if_missing(options, 1); + // rocksdb_options_set_inplace_update_support(options, 1); + // rocksdb_options_set_allow_concurrent_memtable_write(options, 0); + + rocksdb_writeoptions_t *writeoptions = rocksdb_writeoptions_create(); + if (NULL == writeoptions) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err2; + } + // rocksdb_writeoptions_disable_WAL(writeoptions, 1); + + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + if (NULL == readoptions) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err2; + } + + char *err = NULL; + char cachePath[TSDB_FILENAME_LEN] = {0}; + tsdbGetRocksPath(pTsdb, cachePath); + + rocksdb_t *db = rocksdb_open(options, cachePath, &err); + if (NULL == db) { + code = -1; + goto _err3; + } + + rocksdb_flushoptions_t *flushoptions = rocksdb_flushoptions_create(); + if (NULL == flushoptions) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err4; + } + + rocksdb_writebatch_t *writebatch = rocksdb_writebatch_create(); + + pTsdb->rCache.writebatch = writebatch; + pTsdb->rCache.options = options; + pTsdb->rCache.writeoptions = writeoptions; + pTsdb->rCache.readoptions = readoptions; + pTsdb->rCache.flushoptions = flushoptions; + pTsdb->rCache.db = db; + + taosThreadMutexInit(&pTsdb->rCache.rMutex, NULL); + + return code; + +_err4: + rocksdb_readoptions_destroy(readoptions); +_err3: + rocksdb_writeoptions_destroy(writeoptions); +_err2: + rocksdb_options_destroy(options); +_err: + return code; +} + +static void tsdbCloseRocksCache(STsdb *pTsdb) { + rocksdb_close(pTsdb->rCache.db); + rocksdb_flushoptions_destroy(pTsdb->rCache.flushoptions); + rocksdb_writebatch_destroy(pTsdb->rCache.writebatch); + rocksdb_readoptions_destroy(pTsdb->rCache.readoptions); + rocksdb_writeoptions_destroy(pTsdb->rCache.writeoptions); + rocksdb_options_destroy(pTsdb->rCache.options); + taosThreadMutexDestroy(&pTsdb->rCache.rMutex); +} + +int32_t tsdbCacheCommit(STsdb *pTsdb) { + int32_t code = 0; + char *err = NULL; + + rocksdb_flush(pTsdb->rCache.db, pTsdb->rCache.flushoptions, &err); + if (NULL != err) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err); + rocksdb_free(err); + code = -1; + } + + return code; +} + +SLastCol *tsdbCacheDeserialize(char const *value) { + if (!value) { + return NULL; + } + + SLastCol *pLastCol = (SLastCol *)value; + SColVal *pColVal = &pLastCol->colVal; + if (IS_VAR_DATA_TYPE(pColVal->type)) { + if (pColVal->value.nData > 0) { + pColVal->value.pData = (char *)value + sizeof(*pLastCol); + } else { + pColVal->value.pData = NULL; + } + } + + return pLastCol; +} + +void tsdbCacheSerialize(SLastCol *pLastCol, char **value, size_t *size) { + SColVal *pColVal = &pLastCol->colVal; + size_t length = sizeof(*pLastCol); + if (IS_VAR_DATA_TYPE(pColVal->type)) { + length += pColVal->value.nData; + } + *value = taosMemoryMalloc(length); + + *(SLastCol *)(*value) = *pLastCol; + if (IS_VAR_DATA_TYPE(pColVal->type)) { + uint8_t *pVal = pColVal->value.pData; + SColVal *pDColVal = &((SLastCol *)(*value))->colVal; + pDColVal->value.pData = *value + sizeof(*pLastCol); + if (pColVal->value.nData > 0) { + memcpy(pDColVal->value.pData, pVal, pColVal->value.nData); + } else { + pDColVal->value.pData = NULL; + } + } + *size = length; +} + +static SLastCol *tsdbCacheLookup(STsdb *pTsdb, tb_uid_t uid, int16_t cid, char const *lstring) { + SLastCol *pLastCol = NULL; + + char *err = NULL; + size_t vlen = 0; + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":%s", uid, cid, lstring); + char *value = NULL; + value = rocksdb_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, key, klen, &vlen, &err); + if (NULL != err) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err); + rocksdb_free(err); + } + + pLastCol = tsdbCacheDeserialize(value); + + return pLastCol; +} + +int32_t tsdbCacheUpdate(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSDBROW *pRow) { + int32_t code = 0; + + // 1, fetch schema + STSchema *pTSchema = NULL; + int32_t sver = TSDBROW_SVERSION(pRow); + code = metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, uid, sver, &pTSchema); + if (code != TSDB_CODE_SUCCESS) { + terrno = code; + return -1; + } + + // 2, iterate col values into array + SArray *aColVal = taosArrayInit(32, sizeof(SColVal)); + + STSDBRowIter iter = {0}; + tsdbRowIterOpen(&iter, pRow, pTSchema); + + for (SColVal *pColVal = tsdbRowIterNext(&iter); pColVal; pColVal = tsdbRowIterNext(&iter)) { + /* + if (IS_VAR_DATA_TYPE(pColVal->type)) { + uint8_t *pVal = pColVal->value.pData; + + pColVal->value.pData = NULL; + code = tRealloc(&pColVal->value.pData, pColVal->value.nData); + if (code) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _exit; + } + + if (pColVal->value.nData) { + memcpy(pColVal->value.pData, pVal, pColVal->value.nData); + } + } + */ + taosArrayPush(aColVal, pColVal); + } + + tsdbRowClose(&iter); + + // 3, build keys & multi get from rocks + int num_keys = TARRAY_SIZE(aColVal); + char **keys_list = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + size_t *keys_list_sizes = taosMemoryCalloc(num_keys * 2, sizeof(size_t)); + for (int i = 0; i < num_keys; ++i) { + SColVal *pColVal = (SColVal *)taosArrayGet(aColVal, i); + int16_t cid = pColVal->cid; + + char *keys = taosMemoryCalloc(2, ROCKS_KEY_LEN); + int last_key_len = snprintf(keys, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last", uid, cid); + if (last_key_len >= ROCKS_KEY_LEN) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code)); + } + int lr_key_len = snprintf(keys + ROCKS_KEY_LEN, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last_row", uid, cid); + if (lr_key_len >= ROCKS_KEY_LEN) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code)); + } + keys_list[i] = keys; + keys_list[num_keys + i] = keys + ROCKS_KEY_LEN; + keys_list_sizes[i] = last_key_len; + keys_list_sizes[num_keys + i] = lr_key_len; + } + char **values_list = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + size_t *values_list_sizes = taosMemoryCalloc(num_keys * 2, sizeof(size_t)); + char **errs = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + taosThreadMutexLock(&pTsdb->rCache.rMutex); + rocksdb_multi_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, num_keys * 2, (const char *const *)keys_list, + keys_list_sizes, values_list, values_list_sizes, errs); + for (int i = 0; i < num_keys; ++i) { + taosMemoryFree(keys_list[i]); + } + for (int i = 0; i < num_keys * 2; ++i) { + rocksdb_free(errs[i]); + } + taosMemoryFree(keys_list); + taosMemoryFree(keys_list_sizes); + taosMemoryFree(errs); + + TSKEY keyTs = TSDBROW_TS(pRow); + rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch; + for (int i = 0; i < num_keys; ++i) { + SColVal *pColVal = (SColVal *)taosArrayGet(aColVal, i); + if (COL_VAL_IS_VALUE(pColVal)) { + SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]); + + if (NULL == pLastCol || pLastCol->ts <= keyTs) { + char *value = NULL; + size_t vlen = 0; + tsdbCacheSerialize(&(SLastCol){.ts = keyTs, .colVal = *pColVal}, &value, &vlen); + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last", uid, pColVal->cid); + rocksdb_writebatch_put(wb, key, klen, value, vlen); + taosMemoryFree(value); + } + } + + if (!COL_VAL_IS_NONE(pColVal)) { + SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i + num_keys]); + + if (NULL == pLastCol || pLastCol->ts <= keyTs) { + char *value = NULL; + size_t vlen = 0; + tsdbCacheSerialize(&(SLastCol){.ts = keyTs, .colVal = *pColVal}, &value, &vlen); + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last_row", uid, pColVal->cid); + rocksdb_writebatch_put(wb, key, klen, value, vlen); + taosMemoryFree(value); + } + } + + rocksdb_free(values_list[i]); + rocksdb_free(values_list[i + num_keys]); + } + taosMemoryFree(values_list); + taosMemoryFree(values_list_sizes); + + char *err = NULL; + rocksdb_write(pTsdb->rCache.db, pTsdb->rCache.writeoptions, wb, &err); + if (NULL != err) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err); + rocksdb_free(err); + } + taosThreadMutexUnlock(&pTsdb->rCache.rMutex); + rocksdb_writebatch_clear(wb); + +_exit: + taosArrayDestroy(aColVal); + taosMemoryFree(pTSchema); + return code; +} + +static void reallocVarData(SColVal *pColVal) { + if (IS_VAR_DATA_TYPE(pColVal->type)) { + uint8_t *pVal = pColVal->value.pData; + pColVal->value.pData = taosMemoryMalloc(pColVal->value.nData); + if (pColVal->value.nData) { + memcpy(pColVal->value.pData, pVal, pColVal->value.nData); + } + } +} + +static int32_t mergeLastCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SCacheRowsReader *pr, int16_t *aCols, + int nCols, int16_t *slotIds); + +static int32_t mergeLastRowCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SCacheRowsReader *pr, int16_t *aCols, + int nCols, int16_t *slotIds); + +int32_t tsdbCacheGet(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCacheRowsReader *pr, int32_t ltype) { + static char const *alstring[2] = {"last_row", "last"}; + char const *lstring = alstring[ltype]; + rocksdb_writebatch_t *wb = NULL; + int32_t code = 0; + + SArray *pCidList = pr->pCidList; + int num_keys = TARRAY_SIZE(pCidList); + char **keys_list = taosMemoryCalloc(num_keys, sizeof(char *)); + size_t *keys_list_sizes = taosMemoryCalloc(num_keys, sizeof(size_t)); + for (int i = 0; i < num_keys; ++i) { + int16_t cid = *(int16_t *)taosArrayGet(pCidList, i); + + char *keys = taosMemoryCalloc(2, ROCKS_KEY_LEN); + int last_key_len = snprintf(keys, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":%s", uid, cid, lstring); + if (last_key_len >= ROCKS_KEY_LEN) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code)); + } + + keys_list[i] = keys; + keys_list_sizes[i] = last_key_len; + } + char **values_list = taosMemoryCalloc(num_keys, sizeof(char *)); + size_t *values_list_sizes = taosMemoryCalloc(num_keys, sizeof(size_t)); + char **errs = taosMemoryCalloc(num_keys, sizeof(char *)); + rocksdb_multi_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, num_keys, (const char *const *)keys_list, + keys_list_sizes, values_list, values_list_sizes, errs); + for (int i = 0; i < num_keys; ++i) { + taosMemoryFree(keys_list[i]); + rocksdb_free(errs[i]); + } + taosMemoryFree(keys_list); + taosMemoryFree(keys_list_sizes); + taosMemoryFree(errs); + + for (int i = 0; i < num_keys; ++i) { + bool freeCol = true; + SArray *pTmpColArray = NULL; + SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]); + int16_t cid = *(int16_t *)taosArrayGet(pCidList, i); + SLastCol noneCol = {.ts = TSKEY_MIN, .colVal = COL_VAL_NONE(cid, pr->pSchema->columns[pr->pSlotIds[i]].type)}; + if (pLastCol) { + reallocVarData(&pLastCol->colVal); + } else { + taosThreadMutexLock(&pTsdb->rCache.rMutex); + + pLastCol = tsdbCacheLookup(pTsdb, uid, cid, lstring); + if (!pLastCol) { + // recalc: load from tsdb + int16_t aCols[1] = {cid}; + int16_t slotIds[1] = {pr->pSlotIds[i]}; + pTmpColArray = NULL; + + if (ltype) { + mergeLastCid(uid, pTsdb, &pTmpColArray, pr, aCols, 1, slotIds); + } else { + mergeLastRowCid(uid, pTsdb, &pTmpColArray, pr, aCols, 1, slotIds); + } + + if (pTmpColArray && TARRAY_SIZE(pTmpColArray) >= 1) { + pLastCol = taosArrayGet(pTmpColArray, 0); + freeCol = false; + } + + // still null, then make up a none col value + if (!pLastCol) { + pLastCol = &noneCol; + freeCol = false; + } + + // store result back to rocks cache + wb = pTsdb->rCache.writebatch; + char *value = NULL; + size_t vlen = 0; + tsdbCacheSerialize(pLastCol, &value, &vlen); + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":%s", uid, pLastCol->colVal.cid, lstring); + rocksdb_writebatch_put(wb, key, klen, value, vlen); + + taosMemoryFree(value); + } else { + reallocVarData(&pLastCol->colVal); + } + + if (wb) { + char *err = NULL; + rocksdb_write(pTsdb->rCache.db, pTsdb->rCache.writeoptions, wb, &err); + if (NULL != err) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err); + rocksdb_free(err); + } + + rocksdb_writebatch_clear(wb); + } + + taosThreadMutexUnlock(&pTsdb->rCache.rMutex); + } + + taosArrayPush(pLastArray, pLastCol); + + taosArrayDestroy(pTmpColArray); + if (freeCol) { + taosMemoryFree(pLastCol); + } + } + taosMemoryFree(values_list); + taosMemoryFree(values_list_sizes); + + return code; +} + +int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey) { + int32_t code = 0; + // 1, fetch schema + STSchema *pTSchema = NULL; + int32_t sver = -1; + code = metaGetTbTSchemaEx(pTsdb->pVnode->pMeta, suid, uid, sver, &pTSchema); + if (code != TSDB_CODE_SUCCESS) { + terrno = code; + return -1; + } + + // 3, build keys & multi get from rocks + int num_keys = pTSchema->numOfCols; + char **keys_list = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + size_t *keys_list_sizes = taosMemoryCalloc(num_keys * 2, sizeof(size_t)); + for (int i = 0; i < num_keys; ++i) { + int16_t cid = pTSchema->columns[i].colId; + + char *keys = taosMemoryCalloc(2, ROCKS_KEY_LEN); + int last_key_len = snprintf(keys, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last", uid, cid); + if (last_key_len >= ROCKS_KEY_LEN) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code)); + } + int lr_key_len = snprintf(keys + ROCKS_KEY_LEN, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last_row", uid, cid); + if (lr_key_len >= ROCKS_KEY_LEN) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, tstrerror(code)); + } + keys_list[i] = keys; + keys_list[num_keys + i] = keys + ROCKS_KEY_LEN; + keys_list_sizes[i] = last_key_len; + keys_list_sizes[num_keys + i] = lr_key_len; + } + char **values_list = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + size_t *values_list_sizes = taosMemoryCalloc(num_keys * 2, sizeof(size_t)); + char **errs = taosMemoryCalloc(num_keys * 2, sizeof(char *)); + taosThreadMutexLock(&pTsdb->rCache.rMutex); + rocksdb_multi_get(pTsdb->rCache.db, pTsdb->rCache.readoptions, num_keys * 2, (const char *const *)keys_list, + keys_list_sizes, values_list, values_list_sizes, errs); + for (int i = 0; i < num_keys; ++i) { + taosMemoryFree(keys_list[i]); + } + for (int i = 0; i < num_keys * 2; ++i) { + rocksdb_free(errs[i]); + } + taosMemoryFree(keys_list); + taosMemoryFree(keys_list_sizes); + taosMemoryFree(errs); + + rocksdb_writebatch_t *wb = pTsdb->rCache.writebatch; + for (int i = 0; i < num_keys; ++i) { + SLastCol *pLastCol = tsdbCacheDeserialize(values_list[i]); + if (NULL != pLastCol && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) { + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last", uid, pLastCol->colVal.cid); + rocksdb_writebatch_delete(wb, key, klen); + } + + pLastCol = tsdbCacheDeserialize(values_list[i + num_keys]); + if (NULL != pLastCol && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) { + char key[ROCKS_KEY_LEN]; + size_t klen = snprintf(key, ROCKS_KEY_LEN, "%" PRIi64 ":%" PRIi16 ":last_row", uid, pLastCol->colVal.cid); + rocksdb_writebatch_delete(wb, key, klen); + } + + rocksdb_free(values_list[i]); + rocksdb_free(values_list[i + num_keys]); + } + taosMemoryFree(values_list); + taosMemoryFree(values_list_sizes); + + char *err = NULL; + rocksdb_write(pTsdb->rCache.db, pTsdb->rCache.writeoptions, wb, &err); + if (NULL != err) { + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, __LINE__, err); + rocksdb_free(err); + } + taosThreadMutexUnlock(&pTsdb->rCache.rMutex); + rocksdb_writebatch_clear(wb); + +_exit: + taosMemoryFree(pTSchema); + + return code; +} + int32_t tsdbOpenCache(STsdb *pTsdb) { int32_t code = 0; SLRUCache *pCache = NULL; @@ -64,6 +570,12 @@ int32_t tsdbOpenCache(STsdb *pTsdb) { goto _err; } + code = tsdbOpenRocksCache(pTsdb); + if (code != TSDB_CODE_SUCCESS) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + taosLRUCacheSetStrictCapacity(pCache, false); taosThreadMutexInit(&pTsdb->lruMutex, NULL); @@ -84,6 +596,7 @@ void tsdbCloseCache(STsdb *pTsdb) { } tsdbCloseBICache(pTsdb); + tsdbCloseRocksCache(pTsdb); } static void getTableCacheKey(tb_uid_t uid, int cacheType, char *key, int *len) { @@ -170,7 +683,7 @@ int32_t tsdbCacheDeleteLast(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey) { return code; } - +/* int32_t tsdbCacheDelete(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey) { int32_t code = 0; char key[32] = {0}; @@ -225,7 +738,7 @@ int32_t tsdbCacheDelete(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey) { return code; } - +*/ int32_t tsdbCacheInsertLastrow(SLRUCache *pCache, STsdb *pTsdb, tb_uid_t uid, TSDBROW *row, bool dup) { int32_t code = 0; STSRow *cacheRow = NULL; @@ -880,7 +1393,12 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow, bool *pIgnoreEarlie *pIgnoreEarlierTs = false; tBlockDataReset(state->pBlockData); TABLEID tid = {.suid = state->suid, .uid = state->uid}; - code = tBlockDataInit(state->pBlockData, &tid, state->pTSchema, aCols, nCols); + int nTmpCols = nCols; + if (aCols[0] == PRIMARYKEY_TIMESTAMP_COL_ID && nCols == 1) { + nTmpCols = 0; + skipBlock = false; + } + code = tBlockDataInit(state->pBlockData, &tid, state->pTSchema, aCols, nTmpCols); if (code) goto _err; code = tsdbReadDataBlock(*state->pDataFReader, &block, state->pBlockData); @@ -1425,6 +1943,21 @@ static int32_t initLastColArray(STSchema *pTSchema, SArray **ppColArray) { return TSDB_CODE_SUCCESS; } +static int32_t initLastColArrayPartial(STSchema *pTSchema, SArray **ppColArray, int16_t *slotIds, int nCols) { + SArray *pColArray = taosArrayInit(nCols, sizeof(SLastCol)); + if (NULL == pColArray) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < nCols; ++i) { + int16_t slotId = slotIds[i]; + SLastCol col = {.ts = 0, .colVal = COL_VAL_NULL(pTSchema->columns[slotId].colId, pTSchema->columns[slotId].type)}; + taosArrayPush(pColArray, &col); + } + *ppColArray = pColArray; + return TSDB_CODE_SUCCESS; +} + static int32_t cloneTSchema(STSchema *pSrc, STSchema **ppDst) { int32_t len = sizeof(STSchema) + sizeof(STColumn) * pSrc->numOfCols; *ppDst = taosMemoryMalloc(len); @@ -1763,6 +2296,342 @@ _err: return code; } +static int32_t mergeLastCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SCacheRowsReader *pr, int16_t *aCols, + int nCols, int16_t *slotIds) { + STSchema *pTSchema = pr->pSchema; // metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1, 1); + int16_t nLastCol = nCols; + int16_t noneCol = 0; + bool setNoneCol = false; + bool hasRow = false; + bool ignoreEarlierTs = false; + SArray *pColArray = NULL; + SColVal *pColVal = &(SColVal){0}; + + int32_t code = initLastColArrayPartial(pTSchema, &pColArray, slotIds, nCols); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + SArray *aColArray = taosArrayInit(nCols, sizeof(int16_t)); + if (NULL == aColArray) { + taosArrayDestroy(pColArray); + + return TSDB_CODE_OUT_OF_MEMORY; + } + + for (int i = 0; i < nCols; ++i) { + taosArrayPush(aColArray, &aCols[i]); + } + + TSKEY lastRowTs = TSKEY_MAX; + + CacheNextRowIter iter = {0}; + nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pDataIter, pr->pReadSnap, &pr->pDataFReader, + &pr->pDataFReaderLast, pr->lastTs); + + do { + TSDBROW *pRow = NULL; + nextRowIterGet(&iter, &pRow, &ignoreEarlierTs, true, TARRAY_DATA(aColArray), TARRAY_SIZE(aColArray)); + + if (!pRow) { + break; + } + + hasRow = true; + + int32_t sversion = TSDBROW_SVERSION(pRow); + if (sversion != -1) { + code = updateTSchema(sversion, pr, uid); + if (TSDB_CODE_SUCCESS != code) { + goto _err; + } + pTSchema = pr->pCurrSchema; + } + // int16_t nCol = pTSchema->numOfCols; + + TSKEY rowTs = TSDBROW_TS(pRow); + + if (lastRowTs == TSKEY_MAX) { + lastRowTs = rowTs; + + for (int16_t iCol = noneCol; iCol < nCols; ++iCol) { + if (iCol >= nLastCol) { + break; + } + SLastCol *pCol = taosArrayGet(pColArray, iCol); + if (pCol->colVal.cid != pTSchema->columns[slotIds[iCol]].colId) { + continue; + } + if (slotIds[iCol] == 0) { + STColumn *pTColumn = &pTSchema->columns[0]; + + *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = rowTs}); + taosArraySet(pColArray, 0, &(SLastCol){.ts = rowTs, .colVal = *pColVal}); + continue; + } + tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal); + + *pCol = (SLastCol){.ts = rowTs, .colVal = *pColVal}; + if (IS_VAR_DATA_TYPE(pColVal->type) && pColVal->value.nData > 0) { + pCol->colVal.value.pData = taosMemoryMalloc(pCol->colVal.value.nData); + if (pCol->colVal.value.pData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + memcpy(pCol->colVal.value.pData, pColVal->value.pData, pColVal->value.nData); + } + + if (!COL_VAL_IS_VALUE(pColVal)) { + if (!setNoneCol) { + noneCol = iCol; + setNoneCol = true; + } + } else { + int32_t aColIndex = taosArraySearchIdx(aColArray, &pColVal->cid, compareInt16Val, TD_EQ); + if (aColIndex >= 0) { + taosArrayRemove(aColArray, aColIndex); + } + } + } + if (!setNoneCol) { + // done, goto return pColArray + break; + } else { + continue; + } + } + + // merge into pColArray + setNoneCol = false; + for (int16_t iCol = noneCol; iCol < nCols; ++iCol) { + if (iCol >= nLastCol) { + break; + } + // high version's column value + SLastCol *lastColVal = (SLastCol *)taosArrayGet(pColArray, iCol); + if (lastColVal->colVal.cid != pTSchema->columns[slotIds[iCol]].colId) { + continue; + } + SColVal *tColVal = &lastColVal->colVal; + + tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal); + if (!COL_VAL_IS_VALUE(tColVal) && COL_VAL_IS_VALUE(pColVal)) { + SLastCol lastCol = {.ts = rowTs, .colVal = *pColVal}; + if (IS_VAR_DATA_TYPE(pColVal->type) && pColVal->value.nData > 0) { + SLastCol *pLastCol = (SLastCol *)taosArrayGet(pColArray, iCol); + taosMemoryFree(pLastCol->colVal.value.pData); + + lastCol.colVal.value.pData = taosMemoryMalloc(lastCol.colVal.value.nData); + if (lastCol.colVal.value.pData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + memcpy(lastCol.colVal.value.pData, pColVal->value.pData, pColVal->value.nData); + } + + taosArraySet(pColArray, iCol, &lastCol); + int32_t aColIndex = taosArraySearchIdx(aColArray, &lastCol.colVal.cid, compareInt16Val, TD_EQ); + taosArrayRemove(aColArray, aColIndex); + } else if (!COL_VAL_IS_VALUE(tColVal) && !COL_VAL_IS_VALUE(pColVal) && !setNoneCol) { + noneCol = iCol; + setNoneCol = true; + } + } + } while (setNoneCol); + + if (!hasRow) { + if (ignoreEarlierTs) { + taosArrayDestroy(pColArray); + pColArray = NULL; + } else { + taosArrayClear(pColArray); + } + } + *ppLastArray = pColArray; + + nextRowIterClose(&iter); + taosArrayDestroy(aColArray); + + return code; + +_err: + nextRowIterClose(&iter); + // taosMemoryFreeClear(pTSchema); + *ppLastArray = NULL; + taosArrayDestroy(pColArray); + taosArrayDestroy(aColArray); + return code; +} + +static int32_t mergeLastRowCid(tb_uid_t uid, STsdb *pTsdb, SArray **ppLastArray, SCacheRowsReader *pr, int16_t *aCols, + int nCols, int16_t *slotIds) { + STSchema *pTSchema = pr->pSchema; // metaGetTbTSchema(pTsdb->pVnode->pMeta, uid, -1, 1); + int16_t nLastCol = nCols; + int16_t noneCol = 0; + bool setNoneCol = false; + bool hasRow = false; + bool ignoreEarlierTs = false; + SArray *pColArray = NULL; + SColVal *pColVal = &(SColVal){0}; + + int32_t code = initLastColArrayPartial(pTSchema, &pColArray, slotIds, nCols); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + SArray *aColArray = taosArrayInit(nCols, sizeof(int16_t)); + if (NULL == aColArray) { + taosArrayDestroy(pColArray); + + return TSDB_CODE_OUT_OF_MEMORY; + } + + for (int i = 0; i < nCols; ++i) { + taosArrayPush(aColArray, &aCols[i]); + } + + TSKEY lastRowTs = TSKEY_MAX; + + CacheNextRowIter iter = {0}; + nextRowIterOpen(&iter, uid, pTsdb, pTSchema, pr->suid, pr->pLoadInfo, pr->pDataIter, pr->pReadSnap, &pr->pDataFReader, + &pr->pDataFReaderLast, pr->lastTs); + + do { + TSDBROW *pRow = NULL; + nextRowIterGet(&iter, &pRow, &ignoreEarlierTs, true, TARRAY_DATA(aColArray), TARRAY_SIZE(aColArray)); + + if (!pRow) { + break; + } + + hasRow = true; + + int32_t sversion = TSDBROW_SVERSION(pRow); + if (sversion != -1) { + code = updateTSchema(sversion, pr, uid); + if (TSDB_CODE_SUCCESS != code) { + goto _err; + } + pTSchema = pr->pCurrSchema; + } + // int16_t nCol = pTSchema->numOfCols; + + TSKEY rowTs = TSDBROW_TS(pRow); + + if (lastRowTs == TSKEY_MAX) { + lastRowTs = rowTs; + + for (int16_t iCol = noneCol; iCol < nCols; ++iCol) { + if (iCol >= nLastCol) { + break; + } + SLastCol *pCol = taosArrayGet(pColArray, iCol); + if (pCol->colVal.cid != pTSchema->columns[slotIds[iCol]].colId) { + continue; + } + if (slotIds[iCol] == 0) { + STColumn *pTColumn = &pTSchema->columns[0]; + + *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, (SValue){.val = rowTs}); + taosArraySet(pColArray, 0, &(SLastCol){.ts = rowTs, .colVal = *pColVal}); + continue; + } + tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal); + + *pCol = (SLastCol){.ts = rowTs, .colVal = *pColVal}; + if (IS_VAR_DATA_TYPE(pColVal->type) && pColVal->value.nData > 0) { + pCol->colVal.value.pData = taosMemoryMalloc(pCol->colVal.value.nData); + if (pCol->colVal.value.pData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + memcpy(pCol->colVal.value.pData, pColVal->value.pData, pColVal->value.nData); + } + + if (COL_VAL_IS_NONE(pColVal)) { + if (!setNoneCol) { + noneCol = iCol; + setNoneCol = true; + } + } else { + int32_t aColIndex = taosArraySearchIdx(aColArray, &pColVal->cid, compareInt16Val, TD_EQ); + if (aColIndex >= 0) { + taosArrayRemove(aColArray, aColIndex); + } + } + } + if (!setNoneCol) { + // done, goto return pColArray + break; + } else { + continue; + } + } + + // merge into pColArray + setNoneCol = false; + for (int16_t iCol = noneCol; iCol < nCols; ++iCol) { + if (iCol >= nLastCol) { + break; + } + // high version's column value + SLastCol *lastColVal = (SLastCol *)taosArrayGet(pColArray, iCol); + if (lastColVal->colVal.cid != pTSchema->columns[slotIds[iCol]].colId) { + continue; + } + SColVal *tColVal = &lastColVal->colVal; + + tsdbRowGetColVal(pRow, pTSchema, slotIds[iCol], pColVal); + if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) { + SLastCol lastCol = {.ts = rowTs, .colVal = *pColVal}; + if (IS_VAR_DATA_TYPE(pColVal->type) && pColVal->value.nData > 0) { + SLastCol *pLastCol = (SLastCol *)taosArrayGet(pColArray, iCol); + taosMemoryFree(pLastCol->colVal.value.pData); + + lastCol.colVal.value.pData = taosMemoryMalloc(lastCol.colVal.value.nData); + if (lastCol.colVal.value.pData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + memcpy(lastCol.colVal.value.pData, pColVal->value.pData, pColVal->value.nData); + } + + taosArraySet(pColArray, iCol, &lastCol); + int32_t aColIndex = taosArraySearchIdx(aColArray, &lastCol.colVal.cid, compareInt16Val, TD_EQ); + taosArrayRemove(aColArray, aColIndex); + } else if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal) && !setNoneCol) { + noneCol = iCol; + setNoneCol = true; + } + } + } while (setNoneCol); + + if (!hasRow) { + if (ignoreEarlierTs) { + taosArrayDestroy(pColArray); + pColArray = NULL; + } else { + taosArrayClear(pColArray); + } + } + *ppLastArray = pColArray; + + nextRowIterClose(&iter); + taosArrayDestroy(aColArray); + + return code; + +_err: + nextRowIterClose(&iter); + + *ppLastArray = NULL; + taosArrayDestroy(pColArray); + taosArrayDestroy(aColArray); + return code; +} + int32_t tsdbCacheGetLastrowH(SLRUCache *pCache, tb_uid_t uid, SCacheRowsReader *pr, LRUHandle **handle) { int32_t code = 0; char key[32] = {0}; diff --git a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c index 061cbc17f3..53103e9fbb 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c @@ -21,47 +21,30 @@ #define HASTYPE(_type, _t) (((_type) & (_t)) == (_t)) static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds, - void** pRes, const char* idStr) { + const int32_t* dstSlotIds, void** pRes, const char* idStr) { int32_t numOfRows = pBlock->info.rows; + bool allNullRow = true; if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) { - bool allNullRow = true; - for (int32_t i = 0; i < pReader->numOfCols; ++i) { - SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]); SFirstLastRes* p = (SFirstLastRes*)varDataVal(pRes[i]); + int32_t slotId = slotIds[i]; + SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i); - if (slotIds[i] == -1) { // the primary timestamp - SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, 0); - p->ts = pColVal->ts; - p->bytes = TSDB_KEYSIZE; - *(int64_t*)p->buf = pColVal->ts; - allNullRow = false; - } else { - int32_t slotId = slotIds[i]; - // add check for null value, caused by the modification of table schema (new column added). - if (slotId >= taosArrayGetSize(pRow)) { - p->ts = 0; - p->isNull = true; - colDataSetNULL(pColInfoData, numOfRows); - continue; - } + p->ts = pColVal->ts; + p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal); + allNullRow = p->isNull & allNullRow; - SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, slotId); + if (!p->isNull) { + if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) { + varDataSetLen(p->buf, pColVal->colVal.value.nData); - p->ts = pColVal->ts; - p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal); - allNullRow = p->isNull & allNullRow; - - if (!p->isNull) { - if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) { - varDataSetLen(p->buf, pColVal->colVal.value.nData); - memcpy(varDataVal(p->buf), pColVal->colVal.value.pData, pColVal->colVal.value.nData); - p->bytes = pColVal->colVal.value.nData + VARSTR_HEADER_SIZE; // binary needs to plus the header size - } else { - memcpy(p->buf, &pColVal->colVal.value, pReader->pSchema->columns[slotId].bytes); - p->bytes = pReader->pSchema->columns[slotId].bytes; - } + memcpy(varDataVal(p->buf), pColVal->colVal.value.pData, pColVal->colVal.value.nData); + p->bytes = pColVal->colVal.value.nData + VARSTR_HEADER_SIZE; // binary needs to plus the header size + } else { + memcpy(p->buf, &pColVal->colVal.value, pReader->pSchema->columns[slotId].bytes); + p->bytes = pReader->pSchema->columns[slotId].bytes; } } @@ -74,36 +57,31 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p pBlock->info.rows += allNullRow ? 0 : 1; } else if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST_ROW)) { for (int32_t i = 0; i < pReader->numOfCols; ++i) { - SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]); - if (slotIds[i] == -1) { - SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, 0); - colDataSetVal(pColInfoData, numOfRows, (const char*)&pColVal->ts, false); - } else { - int32_t slotId = slotIds[i]; - // add check for null value, caused by the modification of table schema (new column added). - if (slotId >= taosArrayGetSize(pRow)) { + int32_t slotId = slotIds[i]; + SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i); + SColVal* pVal = &pColVal->colVal; + + if (COL_VAL_IS_NONE(&pColVal->colVal)) { + continue; + } + allNullRow = false; + if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) { + if (!COL_VAL_IS_VALUE(&pColVal->colVal)) { colDataSetNULL(pColInfoData, numOfRows); - continue; - } - SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, slotId); - SColVal* pVal = &pColVal->colVal; - - if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) { - if (!COL_VAL_IS_VALUE(&pColVal->colVal)) { - colDataSetNULL(pColInfoData, numOfRows); - } else { - varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData); - memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData); - colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false); - } } else { - colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal)); + varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData); + + memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData); + colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false); } + } else { + colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal)); } } - pBlock->info.rows += 1; + pBlock->info.rows += allNullRow ? 0 : 1; } else { tsdbError("invalid retrieve type:%d, %s", pReader->type, idStr); return TSDB_CODE_INVALID_PARA; @@ -143,7 +121,7 @@ static int32_t setTableSchema(SCacheRowsReader* p, uint64_t suid, const char* id } int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList, int32_t numOfTables, int32_t numOfCols, - uint64_t suid, void** pReader, const char* idstr) { + SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr) { *pReader = NULL; SCacheRowsReader* p = taosMemoryCalloc(1, sizeof(SCacheRowsReader)); if (p == NULL) { @@ -155,6 +133,8 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList, p->pTsdb = p->pVnode->pTsdb; p->verRange = (SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}; p->numOfCols = numOfCols; + p->pCidList = pCidList; + p->pSlotIds = pSlotIds; p->suid = suid; if (numOfTables == 0) { @@ -235,32 +215,9 @@ void* tsdbCacherowsReaderClose(void* pReader) { return NULL; } -static int32_t doExtractCacheRow(SCacheRowsReader* pr, SLRUCache* lruCache, uint64_t uid, SArray** pRow, - LRUHandle** h) { - int32_t code = TSDB_CODE_SUCCESS; - *pRow = NULL; - - if (HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST_ROW)) { - code = tsdbCacheGetLastrowH(lruCache, uid, pr, h); - } else { - code = tsdbCacheGetLastH(lruCache, uid, pr, h); - } - - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - // no data in the table of Uid - if (*h != NULL) { - *pRow = (SArray*)taosLRUCacheValue(lruCache, *h); - } - - return code; -} - static void freeItem(void* pItem) { SLastCol* pCol = (SLastCol*)pItem; - if (IS_VAR_DATA_TYPE(pCol->colVal.type)) { + if (IS_VAR_DATA_TYPE(pCol->colVal.type) && pCol->colVal.value.pData) { taosMemoryFree(pCol->colVal.value.pData); } } @@ -286,19 +243,17 @@ static int32_t tsdbCacheQueryReseek(void* pQHandle) { } } -int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32_t* slotIds, SArray* pTableUidList) { +int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32_t* slotIds, const int32_t* dstSlotIds, + SArray* pTableUidList) { if (pReader == NULL || pResBlock == NULL) { return TSDB_CODE_INVALID_PARA; } SCacheRowsReader* pr = pReader; - - int32_t code = TSDB_CODE_SUCCESS; - SLRUCache* lruCache = pr->pVnode->pTsdb->lruCache; - LRUHandle* h = NULL; - SArray* pRow = NULL; - bool hasRes = false; - SArray* pLastCols = NULL; + int32_t code = TSDB_CODE_SUCCESS; + SArray* pRow = taosArrayInit(TARRAY_SIZE(pr->pCidList), sizeof(SLastCol)); + bool hasRes = false; + SArray* pLastCols = NULL; void** pRes = taosMemoryCalloc(pr->numOfCols, POINTER_BYTES); if (pRes == NULL) { @@ -307,20 +262,22 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 } for (int32_t j = 0; j < pr->numOfCols; ++j) { - pRes[j] = taosMemoryCalloc( - 1, sizeof(SFirstLastRes) + pr->pSchema->columns[-1 == slotIds[j] ? 0 : slotIds[j]].bytes + VARSTR_HEADER_SIZE); + pRes[j] = + taosMemoryCalloc(1, sizeof(SFirstLastRes) + pr->pSchema->columns[/*-1 == slotIds[j] ? 0 : */ slotIds[j]].bytes + + VARSTR_HEADER_SIZE); SFirstLastRes* p = (SFirstLastRes*)varDataVal(pRes[j]); p->ts = INT64_MIN; } - pLastCols = taosArrayInit(pr->pSchema->numOfCols, sizeof(SLastCol)); + pLastCols = taosArrayInit(pr->numOfCols, sizeof(SLastCol)); if (pLastCols == NULL) { code = TSDB_CODE_OUT_OF_MEMORY; goto _end; } - for (int32_t i = 0; i < pr->pSchema->numOfCols; ++i) { - struct STColumn* pCol = &pr->pSchema->columns[i]; + for (int32_t i = 0; i < pr->numOfCols; ++i) { + int32_t slotId = slotIds[i]; + struct STColumn* pCol = &pr->pSchema->columns[slotId]; SLastCol p = {.ts = INT64_MIN, .colVal.type = pCol->type, .colVal.flag = CV_FLAG_NULL}; if (IS_VAR_DATA_TYPE(pCol->type)) { @@ -337,6 +294,8 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 pr->pDataFReader = NULL; pr->pDataFReaderLast = NULL; + int32_t ltype = (pr->type & CACHESCAN_RETRIEVE_LAST) >> 3; + // retrieve the only one last row of all tables in the uid list. if (HASTYPE(pr->type, CACHESCAN_RETRIEVE_TYPE_SINGLE)) { int64_t st = taosGetTimestampUs(); @@ -344,16 +303,14 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 for (int32_t i = 0; i < pr->numOfTables; ++i) { STableKeyInfo* pKeyInfo = &pr->pTableList[i]; - code = doExtractCacheRow(pr, lruCache, pKeyInfo->uid, &pRow, &h); - if (code != TSDB_CODE_SUCCESS) { - goto _end; - } - - if (h == NULL) { + tsdbCacheGet(pr->pTsdb, pKeyInfo->uid, pRow, pr, ltype); + if (TARRAY_SIZE(pRow) <= 0) { + taosArrayClearEx(pRow, freeItem); continue; } - if (taosArrayGetSize(pRow) <= 0) { - tsdbCacheRelease(lruCache, h); + SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, 0); + if (COL_VAL_IS_NONE(&pColVal->colVal)) { + taosArrayClearEx(pRow, freeItem); continue; } @@ -361,47 +318,34 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 bool hasNotNullRow = true; int64_t singleTableLastTs = INT64_MAX; for (int32_t k = 0; k < pr->numOfCols; ++k) { - int32_t slotId = slotIds[k]; + SLastCol* p = taosArrayGet(pLastCols, k); + SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, k); - if (slotId == -1) { // the primary timestamp - SLastCol* p = taosArrayGet(pLastCols, 0); - SLastCol* pCol = (SLastCol*)taosArrayGet(pRow, 0); - if (pCol->ts > p->ts) { - hasRes = true; - p->ts = pCol->ts; - p->colVal = pCol->colVal; - singleTableLastTs = pCol->ts; + if (pColVal->ts > p->ts) { + if (!COL_VAL_IS_VALUE(&pColVal->colVal) && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) { + if (!COL_VAL_IS_VALUE(&p->colVal)) { + hasNotNullRow = false; + } + continue; } - } else { - SLastCol* p = taosArrayGet(pLastCols, slotId); - SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, slotId); - if (pColVal->ts > p->ts) { - if (!COL_VAL_IS_VALUE(&pColVal->colVal) && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) { - if (!COL_VAL_IS_VALUE(&p->colVal)) { - hasNotNullRow = false; - } - continue; + hasRes = true; + p->ts = pColVal->ts; + if (pColVal->ts < singleTableLastTs && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) { + singleTableLastTs = pColVal->ts; + } + + if (!IS_VAR_DATA_TYPE(pColVal->colVal.type)) { + p->colVal = pColVal->colVal; + } else { + if (COL_VAL_IS_VALUE(&pColVal->colVal)) { + memcpy(p->colVal.value.pData, pColVal->colVal.value.pData, pColVal->colVal.value.nData); } - hasRes = true; - p->ts = pColVal->ts; - if (pColVal->ts < singleTableLastTs && HASTYPE(pr->type, CACHESCAN_RETRIEVE_LAST)) { - singleTableLastTs = pColVal->ts; - } - - if (!IS_VAR_DATA_TYPE(pColVal->colVal.type)) { - p->colVal = pColVal->colVal; - } else { - if (COL_VAL_IS_VALUE(&pColVal->colVal)) { - memcpy(p->colVal.value.pData, pColVal->colVal.value.pData, pColVal->colVal.value.nData); - } - - p->colVal.value.nData = pColVal->colVal.value.nData; - p->colVal.type = pColVal->colVal.type; - p->colVal.flag = pColVal->colVal.flag; - p->colVal.cid = pColVal->colVal.cid; - } + p->colVal.value.nData = pColVal->colVal.value.nData; + p->colVal.type = pColVal->colVal.type; + p->colVal.flag = pColVal->colVal.flag; + p->colVal.cid = pColVal->colVal.cid; } } } @@ -423,33 +367,31 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32 taosArraySet(pTableUidList, 0, &pKeyInfo->uid); } - tsdbCacheRelease(lruCache, h); + taosArrayClearEx(pRow, freeItem); } if (hasRes) { - saveOneRow(pLastCols, pResBlock, pr, slotIds, pRes, pr->idstr); + saveOneRow(pLastCols, pResBlock, pr, slotIds, dstSlotIds, pRes, pr->idstr); } } else if (HASTYPE(pr->type, CACHESCAN_RETRIEVE_TYPE_ALL)) { for (int32_t i = pr->tableIndex; i < pr->numOfTables; ++i) { STableKeyInfo* pKeyInfo = &pr->pTableList[i]; - code = doExtractCacheRow(pr, lruCache, pKeyInfo->uid, &pRow, &h); - if (code != TSDB_CODE_SUCCESS) { - goto _end; - } - if (h == NULL) { + tsdbCacheGet(pr->pTsdb, pKeyInfo->uid, pRow, pr, ltype); + if (TARRAY_SIZE(pRow) <= 0) { + taosArrayClearEx(pRow, freeItem); continue; } - if (taosArrayGetSize(pRow) <= 0) { - tsdbCacheRelease(lruCache, h); + SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, 0); + if (COL_VAL_IS_NONE(&pColVal->colVal)) { + taosArrayClearEx(pRow, freeItem); continue; } - saveOneRow(pRow, pResBlock, pr, slotIds, pRes, pr->idstr); - // TODO reset the pRes + saveOneRow(pRow, pResBlock, pr, slotIds, dstSlotIds, pRes, pr->idstr); + taosArrayClearEx(pRow, freeItem); taosArrayPush(pTableUidList, &pKeyInfo->uid); - tsdbCacheRelease(lruCache, h); pr->tableIndex += 1; if (pResBlock->info.rows >= pResBlock->info.capacity) { @@ -475,6 +417,7 @@ _end: } taosMemoryFree(pRes); + taosArrayDestroyEx(pRow, freeItem); taosArrayDestroyEx(pLastCols, freeItem); return code; } diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable.c b/source/dnode/vnode/src/tsdb/tsdbMemTable.c index f27a28acb3..97b648201c 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable.c @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#include #include "tsdb.h" +#include "util/tsimplehash.h" #define MEM_MIN_HASH 1024 #define SL_MAX_LEVEL 5 @@ -141,7 +141,6 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid SMemTable *pMemTable = pTsdb->mem; STbData *pTbData = NULL; SVBufPool *pPool = pTsdb->pVnode->inUse; - TSDBKEY lastKey = {.version = version, .ts = eKey}; // check if table exists SMetaInfo info; @@ -182,7 +181,7 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid pMemTable->nDel++; pMemTable->minVer = TMIN(pMemTable->minVer, version); pMemTable->maxVer = TMIN(pMemTable->maxVer, version); - + /* if (TSDB_CACHE_LAST_ROW(pMemTable->pTsdb->pVnode->config) && tsdbKeyCmprFn(&lastKey, &pTbData->maxKey) >= 0) { tsdbCacheDeleteLastrow(pTsdb->lruCache, pTbData->uid, eKey); } @@ -190,6 +189,10 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid if (TSDB_CACHE_LAST(pMemTable->pTsdb->pVnode->config)) { tsdbCacheDeleteLast(pTsdb->lruCache, pTbData->uid, eKey); } + */ + if (eKey >= pTbData->maxKey && sKey <= pTbData->maxKey) { + tsdbCacheDel(pTsdb, suid, uid, sKey, eKey); + } tsdbTrace("vgId:%d, delete data from table suid:%" PRId64 " uid:%" PRId64 " skey:%" PRId64 " eKey:%" PRId64 " at version %" PRId64, @@ -285,8 +288,8 @@ bool tsdbTbDataIterNext(STbDataIter *pIter) { int64_t tsdbCountTbDataRows(STbData *pTbData) { SMemSkipListNode *pNode = pTbData->sl.pHead; - int64_t rowsNum = 0; - + int64_t rowsNum = 0; + while (NULL != pNode) { pNode = SL_GET_NODE_FORWARD(pNode, 0); if (pNode == pTbData->sl.pTail) { @@ -309,7 +312,7 @@ void tsdbMemTableCountRows(SMemTable *pMemTable, SSHashObj* pTableMap, int64_t * pTbData = pTbData->next; continue; } - + *rowsNum += tsdbCountTbDataRows(pTbData); pTbData = pTbData->next; } @@ -669,15 +672,8 @@ static int32_t tsdbInsertColDataToTable(SMemTable *pMemTable, STbData *pTbData, if (key.ts >= pTbData->maxKey) { pTbData->maxKey = key.ts; - - if (TSDB_CACHE_LAST_ROW(pMemTable->pTsdb->pVnode->config)) { - tsdbCacheInsertLastrow(pMemTable->pTsdb->lruCache, pMemTable->pTsdb, pTbData->uid, &lRow, true); - } - } - - if (TSDB_CACHE_LAST(pMemTable->pTsdb->pVnode->config)) { - tsdbCacheInsertLast(pMemTable->pTsdb->lruCache, pTbData->uid, &lRow, pMemTable->pTsdb); } + tsdbCacheUpdate(pMemTable->pTsdb, pTbData->suid, pTbData->uid, &lRow); // SMemTable pMemTable->minKey = TMIN(pMemTable->minKey, pTbData->minKey); @@ -737,15 +733,8 @@ static int32_t tsdbInsertRowDataToTable(SMemTable *pMemTable, STbData *pTbData, if (key.ts >= pTbData->maxKey) { pTbData->maxKey = key.ts; - - if (TSDB_CACHE_LAST_ROW(pMemTable->pTsdb->pVnode->config)) { - tsdbCacheInsertLastrow(pMemTable->pTsdb->lruCache, pMemTable->pTsdb, pTbData->uid, &lRow, true); - } - } - - if (TSDB_CACHE_LAST(pMemTable->pTsdb->pVnode->config)) { - tsdbCacheInsertLast(pMemTable->pTsdb->lruCache, pTbData->uid, &lRow, pMemTable->pTsdb); } + tsdbCacheUpdate(pMemTable->pTsdb, pTbData->suid, pTbData->uid, &lRow); // SMemTable pMemTable->minKey = TMIN(pMemTable->minKey, pTbData->minKey); diff --git a/source/dnode/vnode/src/vnd/vnodeCfg.c b/source/dnode/vnode/src/vnd/vnodeCfg.c index c326c8bfac..faa4d2fc57 100644 --- a/source/dnode/vnode/src/vnd/vnodeCfg.c +++ b/source/dnode/vnode/src/vnd/vnodeCfg.c @@ -57,6 +57,28 @@ int vnodeCheckCfg(const SVnodeCfg *pCfg) { return 0; } +const char* vnodeRoleToStr(ESyncRole role) { + switch (role) { + case TAOS_SYNC_ROLE_VOTER: + return "true"; + case TAOS_SYNC_ROLE_LEARNER: + return "false"; + default: + return "unknown"; + } +} + +const ESyncRole vnodeStrToRole(char* str) { + if(strcmp(str, "true") == 0){ + return TAOS_SYNC_ROLE_VOTER; + } + if(strcmp(str, "false") == 0){ + return TAOS_SYNC_ROLE_LEARNER; + } + + return TAOS_SYNC_ROLE_ERROR; +} + int vnodeEncodeConfig(const void *pObj, SJson *pJson) { const SVnodeCfg *pCfg = (SVnodeCfg *)pObj; @@ -112,6 +134,7 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) { if (tjsonAddIntegerToObject(pJson, "sstTrigger", pCfg->sttTrigger) < 0) return -1; if (tjsonAddIntegerToObject(pJson, "hashBegin", pCfg->hashBegin) < 0) return -1; if (tjsonAddIntegerToObject(pJson, "hashEnd", pCfg->hashEnd) < 0) return -1; + if (tjsonAddIntegerToObject(pJson, "hashChange", pCfg->hashChange) < 0) return -1; if (tjsonAddIntegerToObject(pJson, "hashMethod", pCfg->hashMethod) < 0) return -1; if (tjsonAddIntegerToObject(pJson, "hashPrefix", pCfg->hashPrefix) < 0) return -1; if (tjsonAddIntegerToObject(pJson, "hashSuffix", pCfg->hashSuffix) < 0) return -1; @@ -128,9 +151,9 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) { SJson *nodeInfo = tjsonCreateArray(); if (nodeInfo == NULL) return -1; if (tjsonAddItemToObject(pJson, "syncCfg.nodeInfo", nodeInfo) < 0) return -1; - vDebug("vgId:%d, encode config, replicas:%d selfIndex:%d", pCfg->vgId, pCfg->syncCfg.replicaNum, - pCfg->syncCfg.myIndex); - for (int i = 0; i < pCfg->syncCfg.replicaNum; ++i) { + vDebug("vgId:%d, encode config, replicas:%d totalReplicas:%d selfIndex:%d", pCfg->vgId, pCfg->syncCfg.replicaNum, + pCfg->syncCfg.totalReplicaNum, pCfg->syncCfg.myIndex); + for (int i = 0; i < pCfg->syncCfg.totalReplicaNum; ++i) { SJson *info = tjsonCreateObject(); SNodeInfo *pNode = (SNodeInfo *)&pCfg->syncCfg.nodeInfo[i]; if (info == NULL) return -1; @@ -138,6 +161,7 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) { if (tjsonAddStringToObject(info, "nodeFqdn", pNode->nodeFqdn) < 0) return -1; if (tjsonAddIntegerToObject(info, "nodeId", pNode->nodeId) < 0) return -1; if (tjsonAddIntegerToObject(info, "clusterId", pNode->clusterId) < 0) return -1; + if (tjsonAddStringToObject(info, "isReplica", vnodeRoleToStr(pNode->nodeRole)) < 0) return -1; if (tjsonAddItemToArray(nodeInfo, info) < 0) return -1; vDebug("vgId:%d, encode config, replica:%d ep:%s:%u dnode:%d", pCfg->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId); @@ -226,6 +250,8 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) { if (code < 0) return -1; tjsonGetNumberValue(pJson, "hashEnd", pCfg->hashEnd, code); if (code < 0) return -1; + tjsonGetNumberValue(pJson, "hashChange", pCfg->hashChange, code); + if (code < 0) return -1; tjsonGetNumberValue(pJson, "hashMethod", pCfg->hashMethod, code); if (code < 0) return -1; tjsonGetNumberValue(pJson, "hashPrefix", pCfg->hashPrefix, code); @@ -251,10 +277,10 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) { SJson *nodeInfo = tjsonGetObjectItem(pJson, "syncCfg.nodeInfo"); int arraySize = tjsonGetArraySize(nodeInfo); - if (arraySize != pCfg->syncCfg.replicaNum) return -1; + pCfg->syncCfg.totalReplicaNum = arraySize; - vDebug("vgId:%d, decode config, replicas:%d selfIndex:%d", pCfg->vgId, pCfg->syncCfg.replicaNum, - pCfg->syncCfg.myIndex); + vDebug("vgId:%d, decode config, replicas:%d totalReplicas:%d selfIndex:%d", pCfg->vgId, pCfg->syncCfg.replicaNum, + pCfg->syncCfg.totalReplicaNum, pCfg->syncCfg.myIndex); for (int i = 0; i < arraySize; ++i) { SJson *info = tjsonGetArrayItem(nodeInfo, i); SNodeInfo *pNode = &pCfg->syncCfg.nodeInfo[i]; @@ -266,6 +292,15 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) { if (code < 0) return -1; tjsonGetNumberValue(info, "clusterId", pNode->clusterId, code); if (code < 0) return -1; + char role[10] = {0}; + code = tjsonGetStringValue(info, "isReplica", role); + if (code < 0) return -1; + if(strlen(role) != 0){ + pNode->nodeRole = vnodeStrToRole(role); + } + else{ + pNode->nodeRole = TAOS_SYNC_ROLE_VOTER; + } vDebug("vgId:%d, decode config, replica:%d ep:%s:%u dnode:%d", pCfg->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId); } diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c index 847125018c..74168591d2 100644 --- a/source/dnode/vnode/src/vnd/vnodeCommit.c +++ b/source/dnode/vnode/src/vnd/vnodeCommit.c @@ -144,8 +144,8 @@ _exit: } int vnodeShouldCommit(SVnode *pVnode, bool atExit) { - bool diskAvail = osDataSpaceAvailable(); - bool needCommit = false; + bool diskAvail = osDataSpaceAvailable(); + bool needCommit = false; taosThreadMutexLock(&pVnode->mutex); if (pVnode->inUse && diskAvail) { @@ -439,6 +439,9 @@ static int vnodeCommitImpl(SCommitInfo *pInfo) { code = tsdbCommit(pVnode->pTsdb, pInfo); TSDB_CHECK_CODE(code, lino, _exit); + code = tsdbCacheCommit(pVnode->pTsdb); + TSDB_CHECK_CODE(code, lino, _exit); + if (VND_IS_RSMA(pVnode)) { code = smaCommit(pVnode->pSma, pInfo); TSDB_CHECK_CODE(code, lino, _exit); diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c index e8f34d27ac..b5e7c6875b 100644 --- a/source/dnode/vnode/src/vnd/vnodeOpen.c +++ b/source/dnode/vnode/src/vnd/vnodeOpen.c @@ -76,19 +76,41 @@ int32_t vnodeAlterReplica(const char *path, SAlterVnodeReplicaReq *pReq, STfs *p } SSyncCfg *pCfg = &info.config.syncCfg; - pCfg->myIndex = pReq->selfIndex; - pCfg->replicaNum = pReq->replica; + + pCfg->replicaNum = 0; + pCfg->totalReplicaNum = 0; memset(&pCfg->nodeInfo, 0, sizeof(pCfg->nodeInfo)); - vInfo("vgId:%d, save config while alter, replicas:%d selfIndex:%d", pReq->vgId, pCfg->replicaNum, pCfg->myIndex); for (int i = 0; i < pReq->replica; ++i) { SNodeInfo *pNode = &pCfg->nodeInfo[i]; pNode->nodeId = pReq->replicas[i].id; pNode->nodePort = pReq->replicas[i].port; tstrncpy(pNode->nodeFqdn, pReq->replicas[i].fqdn, sizeof(pNode->nodeFqdn)); + pNode->nodeRole = TAOS_SYNC_ROLE_VOTER; (void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); vInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId); + pCfg->replicaNum++; } + if(pReq->selfIndex != -1){ + pCfg->myIndex = pReq->selfIndex; + } + for (int i = pCfg->replicaNum; i < pReq->replica + pReq->learnerReplica; ++i) { + SNodeInfo *pNode = &pCfg->nodeInfo[i]; + pNode->nodeId = pReq->learnerReplicas[pCfg->totalReplicaNum].id; + pNode->nodePort = pReq->learnerReplicas[pCfg->totalReplicaNum].port; + pNode->nodeRole = TAOS_SYNC_ROLE_LEARNER; + tstrncpy(pNode->nodeFqdn, pReq->learnerReplicas[pCfg->totalReplicaNum].fqdn, sizeof(pNode->nodeFqdn)); + (void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort); + vInfo("vgId:%d, replica:%d ep:%s:%u dnode:%d", pReq->vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId); + pCfg->totalReplicaNum++; + } + pCfg->totalReplicaNum += pReq->replica; + if(pReq->learnerSelfIndex != -1){ + pCfg->myIndex = pReq->replica + pReq->learnerSelfIndex; + } + + vInfo("vgId:%d, save config while alter, replicas:%d totalReplicas:%d selfIndex:%d", + pReq->vgId, pCfg->replicaNum, pCfg->totalReplicaNum, pCfg->myIndex); info.config.syncCfg = *pCfg; ret = vnodeSaveInfo(dir, &info); @@ -176,11 +198,13 @@ int32_t vnodeAlterHashRange(const char *srcPath, const char *dstPath, SAlterVnod info.config.vgId = pReq->dstVgId; info.config.hashBegin = pReq->hashBegin; info.config.hashEnd = pReq->hashEnd; + info.config.hashChange = true; info.config.walCfg.vgId = pReq->dstVgId; SSyncCfg *pCfg = &info.config.syncCfg; pCfg->myIndex = 0; pCfg->replicaNum = 1; + pCfg->totalReplicaNum = 1; memset(&pCfg->nodeInfo, 0, sizeof(pCfg->nodeInfo)); vInfo("vgId:%d, alter vnode replicas to 1", pReq->srcVgId); @@ -212,8 +236,6 @@ int32_t vnodeAlterHashRange(const char *srcPath, const char *dstPath, SAlterVnod return -1; } - // todo vnode compact here - vInfo("vgId:%d, vnode hashrange is altered", info.config.vgId); return 0; } @@ -248,7 +270,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) { // save vnode info on dnode ep changed bool updated = false; SSyncCfg *pCfg = &info.config.syncCfg; - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SNodeInfo *pNode = &pCfg->nodeInfo[i]; if (tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort)) { updated = true; @@ -404,6 +426,14 @@ void vnodeClose(SVnode *pVnode) { // start the sync timer after the queue is ready int32_t vnodeStart(SVnode *pVnode) { return vnodeSyncStart(pVnode); } +int32_t vnodeIsCatchUp(SVnode *pVnode){ + return syncIsCatchUp(pVnode->sync); +} + +ESyncRole vnodeGetRole(SVnode *pVnode){ + return syncGetRole(pVnode->sync); +} + void vnodeStop(SVnode *pVnode) {} int64_t vnodeGetSyncHandle(SVnode *pVnode) { return pVnode->sync; } diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index bd4a20b07e..fe1ccf90c8 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -389,6 +389,11 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp goto _err; } break; + case TDMT_VND_TMQ_SEEK_TO_OFFSET: + if (tqProcessSeekReq(pVnode->pTq, version, pReq, pMsg->contLen - sizeof(SMsgHead)) < 0) { + goto _err; + } + break; case TDMT_VND_TMQ_ADD_CHECKINFO: if (tqProcessAddCheckInfoReq(pVnode->pTq, version, pReq, len) < 0) { goto _err; @@ -430,7 +435,10 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp } } break; case TDMT_VND_ALTER_CONFIRM: - vnodeProcessAlterConfirmReq(pVnode, version, pReq, len, pRsp); + needCommit = pVnode->config.hashChange; + if (vnodeProcessAlterConfirmReq(pVnode, version, pReq, len, pRsp) < 0) { + goto _err; + } break; case TDMT_VND_ALTER_CONFIG: vnodeProcessAlterConfigReq(pVnode, version, pReq, len, pRsp); @@ -548,6 +556,10 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { return vnodeGetTableCfg(pVnode, pMsg, true); case TDMT_VND_BATCH_META: return vnodeGetBatchMeta(pVnode, pMsg); + case TDMT_VND_TMQ_CONSUME: + return tqProcessPollReq(pVnode->pTq, pMsg); + case TDMT_VND_TMQ_VG_WALINFO: + return tqProcessVgWalInfoReq(pVnode->pTq, pMsg); case TDMT_STREAM_TASK_RUN: return tqProcessTaskRunReq(pVnode->pTq, pMsg); case TDMT_STREAM_TASK_DISPATCH: @@ -1066,7 +1078,7 @@ static int32_t vnodeCellValConvertToColVal(STColumn *pCol, SCellVal *pCellVal, S if (IS_VAR_DATA_TYPE(pCol->type)) { pColVal->value.nData = varDataLen(pCellVal->val); - pColVal->value.pData = varDataVal(pCellVal->val); + pColVal->value.pData = (uint8_t *)varDataVal(pCellVal->val); } else if (TSDB_DATA_TYPE_FLOAT == pCol->type) { float f = GET_FLOAT_VAL(pCellVal->val); memcpy(&pColVal->value.val, &f, sizeof(f)); @@ -1105,7 +1117,7 @@ static int32_t vnodeDecodeCreateTbReq(SSubmitReqConvertCxt *pCxt) { } SDecoder decoder = {0}; - tDecoderInit(&decoder, pCxt->pBlock->data, pCxt->msgIter.schemaLen); + tDecoderInit(&decoder, (uint8_t *)pCxt->pBlock->data, pCxt->msgIter.schemaLen); int32_t code = tDecodeSVCreateTbReq(&decoder, pCxt->pTbData->pCreateTbReq); tDecoderClear(&decoder); @@ -1167,7 +1179,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) { } if (TSDB_CODE_SUCCESS == code) { SEncoder encoder; - tEncoderInit(&encoder, pMsg, msglen); + tEncoderInit(&encoder, (uint8_t *)pMsg, msglen); code = tEncodeSubmitReq(&encoder, pSubmitReq); tEncoderClear(&encoder); } @@ -1456,14 +1468,39 @@ int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen) { return vnodeProcessCreateTSmaReq(pVnode, 1, pCont, contLen, NULL); } +static int32_t vnodeConsolidateAlterHashRange(SVnode *pVnode, int64_t version) { + int32_t code = TSDB_CODE_SUCCESS; + + vInfo("vgId:%d, trim meta of tables per hash range [%" PRIu32 ", %" PRIu32 "]. apply-index:%" PRId64, TD_VID(pVnode), + pVnode->config.hashBegin, pVnode->config.hashEnd, version); + + // TODO: trim meta of tables from TDB per hash range [pVnode->config.hashBegin, pVnode->config.hashEnd] + + return code; +} + static int32_t vnodeProcessAlterConfirmReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) { - vInfo("vgId:%d, alter replica confim msg is processed", TD_VID(pVnode)); + vInfo("vgId:%d, vnode handle msgType:alter-confirm, alter confim msg is processed", TD_VID(pVnode)); + int32_t code = TSDB_CODE_SUCCESS; + if (!pVnode->config.hashChange) { + goto _exit; + } + + code = vnodeConsolidateAlterHashRange(pVnode, version); + if (code < 0) { + vError("vgId:%d, failed to consolidate alter hashrange since %s. version:%" PRId64, TD_VID(pVnode), terrstr(), + version); + goto _exit; + } + pVnode->config.hashChange = false; + +_exit: pRsp->msgType = TDMT_VND_ALTER_CONFIRM_RSP; - pRsp->code = TSDB_CODE_SUCCESS; + pRsp->code = code; pRsp->pCont = NULL; pRsp->contLen = 0; - return 0; + return code; } static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) { diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index f2ee5358cc..4ea5e3c6ec 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -571,6 +571,19 @@ static void vnodeBecomeFollower(const SSyncFSM *pFsm) { taosThreadMutexUnlock(&pVnode->lock); } +static void vnodeBecomeLearner(const SSyncFSM *pFsm) { + SVnode *pVnode = pFsm->data; + vInfo("vgId:%d, become learner", pVnode->config.vgId); + + taosThreadMutexLock(&pVnode->lock); + if (pVnode->blocked) { + pVnode->blocked = false; + vDebug("vgId:%d, become learner and post block", pVnode->config.vgId); + tsem_post(&pVnode->syncSem); + } + taosThreadMutexUnlock(&pVnode->lock); +} + static void vnodeBecomeLeader(const SSyncFSM *pFsm) { SVnode *pVnode = pFsm->data; vDebug("vgId:%d, become leader", pVnode->config.vgId); @@ -612,6 +625,7 @@ static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) { pFsm->FpApplyQueueItems = vnodeApplyQueueItems; pFsm->FpBecomeLeaderCb = vnodeBecomeLeader; pFsm->FpBecomeFollowerCb = vnodeBecomeFollower; + pFsm->FpBecomeLearnerCb = vnodeBecomeLearner; pFsm->FpReConfigCb = NULL; pFsm->FpSnapshotStartRead = vnodeSnapshotStartRead; pFsm->FpSnapshotStopRead = vnodeSnapshotStopRead; @@ -644,7 +658,7 @@ int32_t vnodeSyncOpen(SVnode *pVnode, char *path) { SSyncCfg *pCfg = &syncInfo.syncCfg; vInfo("vgId:%d, start to open sync, replica:%d selfIndex:%d", pVnode->config.vgId, pCfg->replicaNum, pCfg->myIndex); - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SNodeInfo *pNode = &pCfg->nodeInfo[i]; vInfo("vgId:%d, index:%d ep:%s:%u dnode:%d cluster:%" PRId64, pVnode->config.vgId, i, pNode->nodeFqdn, pNode->nodePort, pNode->nodeId, pNode->clusterId); diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 56c79eac1f..9e654e89d9 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -1437,12 +1437,12 @@ _return: SMetaRes* pRes = taosArrayGet(ctx->pResList, pFetch->resIdx); pRes->code = code; pRes->pRes = NULL; + ctgTaskError("Get table %d.%s.%s meta failed with error %s", pName->acctId, pName->dbname, pName->tname, + tstrerror(code)); if (0 == atomic_sub_fetch_32(&ctx->fetchNum, 1)) { TSWAP(pTask->res, ctx->pResList); taskDone = true; } - ctgTaskError("Get table %d.%s.%s meta failed with error %s", pName->acctId, pName->dbname, pName->tname, - tstrerror(code)); } if (pTask->res && taskDone) { diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index 4302302d7a..c5b9eb7475 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -1128,6 +1128,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); + EXPLAIN_ROW_APPEND(EXPLAIN_IGNORE_GROUPID_FORMAT, pMergeNode->ignoreGroupId ? "true" : "false"); + EXPLAIN_ROW_END(); + QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); + EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT); if (pMergeNode->groupSort) { EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc"); diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index c9d0eebe2b..3f365c7048 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -250,6 +250,7 @@ typedef struct STagScanInfo { SSDataBlock* pRes; SColMatchInfo matchInfo; int32_t curPos; + SLimitNode* pSlimit; SReadHandle readHandle; STableListInfo* pTableListInfo; } STagScanInfo; diff --git a/source/libs/executor/src/aggregateoperator.c b/source/libs/executor/src/aggregateoperator.c index 9b463a3dee..5cd95d3311 100644 --- a/source/libs/executor/src/aggregateoperator.c +++ b/source/libs/executor/src/aggregateoperator.c @@ -464,8 +464,8 @@ int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t n getBufferPgSize(pAggSup->resultRowSize, &defaultPgsz, &defaultBufsz); if (!osTempSpaceAvailable()) { - code = TSDB_CODE_NO_AVAIL_DISK; - qError("Init stream agg supporter failed since %s, %s", terrstr(code), pKey); + code = TSDB_CODE_NO_DISKSPACE; + qError("Init stream agg supporter failed since %s, key:%s, tempDir:%s", terrstr(code), pKey, tsTempDir); return code; } diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 00eb042478..430b0b11ed 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -33,18 +33,21 @@ typedef struct SCacheRowsScanInfo { void* pLastrowReader; SColMatchInfo matchInfo; int32_t* pSlotIds; + int32_t* pDstSlotIds; SExprSupp pseudoExprSup; int32_t retrieveType; int32_t currentGroupIndex; SSDataBlock* pBufferredRes; SArray* pUidList; + SArray* pCidList; int32_t indexOfBufferedRes; STableListInfo* pTableList; } SCacheRowsScanInfo; static SSDataBlock* doScanCache(SOperatorInfo* pOperator); static void destroyCacheScanOperator(void* param); -static int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTaskInfo, int32_t** pSlotIds); +static int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTaskInfo, int32_t** pSlotIds, + int32_t** pDstSlotIds); static int32_t removeRedundantTsCol(SLastRowScanPhysiNode* pScanNode, SColMatchInfo* pColMatchInfo); #define SCAN_ROW_TYPE(_t) ((_t) ? CACHESCAN_RETRIEVE_LAST : CACHESCAN_RETRIEVE_LAST_ROW) @@ -73,9 +76,16 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe goto _error; } + SArray* pCidList = taosArrayInit(numOfCols, sizeof(int16_t)); + for (int i = 0; i < TARRAY_SIZE(pInfo->matchInfo.pList); ++i) { + SColMatchItem* pColInfo = taosArrayGet(pInfo->matchInfo.pList, i); + taosArrayPush(pCidList, &pColInfo->colId); + } + pInfo->pCidList = pCidList; + removeRedundantTsCol(pScanNode, &pInfo->matchInfo); - code = extractCacheScanSlotId(pInfo->matchInfo.pList, pTaskInfo, &pInfo->pSlotIds); + code = extractCacheScanSlotId(pInfo->matchInfo.pList, pTaskInfo, &pInfo->pSlotIds, &pInfo->pDstSlotIds); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -93,8 +103,8 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe uint64_t suid = tableListGetSuid(pTableListInfo); code = tsdbCacherowsReaderOpen(pInfo->readHandle.vnode, pInfo->retrieveType, pList, totalTables, - taosArrayGetSize(pInfo->matchInfo.pList), suid, &pInfo->pLastrowReader, - pTaskInfo->id.str); + taosArrayGetSize(pInfo->matchInfo.pList), pCidList, pInfo->pSlotIds, suid, + &pInfo->pLastrowReader, pTaskInfo->id.str); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -162,8 +172,8 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) { blockDataCleanup(pInfo->pBufferredRes); taosArrayClear(pInfo->pUidList); - int32_t code = - tsdbRetrieveCacheRows(pInfo->pLastrowReader, pInfo->pBufferredRes, pInfo->pSlotIds, pInfo->pUidList); + int32_t code = tsdbRetrieveCacheRows(pInfo->pLastrowReader, pInfo->pBufferredRes, pInfo->pSlotIds, + pInfo->pDstSlotIds, pInfo->pUidList); if (code != TSDB_CODE_SUCCESS) { T_LONG_JMP(pTaskInfo->env, code); } @@ -229,8 +239,8 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) { } code = tsdbCacherowsReaderOpen(pInfo->readHandle.vnode, pInfo->retrieveType, pList, num, - taosArrayGetSize(pInfo->matchInfo.pList), suid, &pInfo->pLastrowReader, - pTaskInfo->id.str); + taosArrayGetSize(pInfo->matchInfo.pList), pInfo->pCidList, pInfo->pSlotIds, suid, + &pInfo->pLastrowReader, pTaskInfo->id.str); if (code != TSDB_CODE_SUCCESS) { pInfo->currentGroupIndex += 1; taosArrayClear(pInfo->pUidList); @@ -239,7 +249,8 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) { taosArrayClear(pInfo->pUidList); - code = tsdbRetrieveCacheRows(pInfo->pLastrowReader, pInfo->pRes, pInfo->pSlotIds, pInfo->pUidList); + code = tsdbRetrieveCacheRows(pInfo->pLastrowReader, pInfo->pRes, pInfo->pSlotIds, pInfo->pDstSlotIds, + pInfo->pUidList); if (code != TSDB_CODE_SUCCESS) { T_LONG_JMP(pTaskInfo->env, code); } @@ -282,6 +293,8 @@ void destroyCacheScanOperator(void* param) { blockDataDestroy(pInfo->pRes); blockDataDestroy(pInfo->pBufferredRes); taosMemoryFree(pInfo->pSlotIds); + taosMemoryFree(pInfo->pDstSlotIds); + taosArrayDestroy(pInfo->pCidList); taosArrayDestroy(pInfo->pUidList); taosArrayDestroy(pInfo->matchInfo.pList); tableListDestroy(pInfo->pTableList); @@ -294,7 +307,8 @@ void destroyCacheScanOperator(void* param) { taosMemoryFreeClear(param); } -int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTaskInfo, int32_t** pSlotIds) { +int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTaskInfo, int32_t** pSlotIds, + int32_t** pDstSlotIds) { size_t numOfCols = taosArrayGetSize(pColMatchInfo); *pSlotIds = taosMemoryMalloc(numOfCols * sizeof(int32_t)); @@ -302,18 +316,25 @@ int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTask return TSDB_CODE_OUT_OF_MEMORY; } + *pDstSlotIds = taosMemoryMalloc(numOfCols * sizeof(int32_t)); + if (*pDstSlotIds == NULL) { + taosMemoryFree(*pSlotIds); + return TSDB_CODE_OUT_OF_MEMORY; + } + SSchemaWrapper* pWrapper = pTaskInfo->schemaInfo.sw; for (int32_t i = 0; i < numOfCols; ++i) { SColMatchItem* pColMatch = taosArrayGet(pColMatchInfo, i); for (int32_t j = 0; j < pWrapper->nCols; ++j) { - if (pColMatch->colId == pWrapper->pSchema[j].colId && pColMatch->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + /* if (pColMatch->colId == pWrapper->pSchema[j].colId && pColMatch->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { (*pSlotIds)[pColMatch->dstSlotId] = -1; break; - } + }*/ if (pColMatch->colId == pWrapper->pSchema[j].colId) { - (*pSlotIds)[pColMatch->dstSlotId] = j; + (*pSlotIds)[i] = j; + (*pDstSlotIds)[i] = pColMatch->dstSlotId; break; } } diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index c51dc39b5b..c8b16ad83b 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1484,14 +1484,23 @@ static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutpu return TSDB_CODE_OUT_OF_MEMORY; } + SHashObj *pSelectFuncs = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); for (int32_t i = 0; i < numOfOutput; ++i) { const char* pName = pCtx[i].pExpr->pExpr->_function.functionName; if ((strcmp(pName, "_select_value") == 0) || (strcmp(pName, "_group_key") == 0)) { pValCtx[num++] = &pCtx[i]; } else if (fmIsSelectFunc(pCtx[i].functionId)) { - p = &pCtx[i]; + void* data = taosHashGet(pSelectFuncs, pName, strlen(pName)); + if (taosHashGetSize(pSelectFuncs) != 0 && data == NULL) { + p = NULL; + break; + } else { + taosHashPut(pSelectFuncs, pName, strlen(pName), &num, sizeof(num)); + p = &pCtx[i]; + } } } + taosHashCleanup(pSelectFuncs); if (p != NULL) { p->subsidiaries.pCtx = pValCtx; diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 8bbbd3524d..cafed977b7 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -112,7 +112,7 @@ void resetTaskInfo(qTaskInfo_t tinfo) { clearStreamBlock(pTaskInfo->pRoot); } -static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t numOfBlocks, int32_t type, char* id) { +static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t numOfBlocks, int32_t type, const char* id) { if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { if (pOperator->numOfDownstream == 0) { qError("failed to find stream scan operator to set the input data block, %s" PRIx64, id); @@ -129,7 +129,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu pOperator->status = OP_NOT_OPENED; SStreamScanInfo* pInfo = pOperator->info; - qDebug("s-task set source blocks:%d %s", (int32_t)numOfBlocks, id); + qDebug("s-task:%s set source blocks:%d", id, (int32_t)numOfBlocks); ASSERT(pInfo->validBlockIndex == 0 && taosArrayGetSize(pInfo->pBlockLists) == 0); if (type == STREAM_INPUT__MERGED_SUBMIT) { @@ -144,9 +144,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu } else if (type == STREAM_INPUT__DATA_BLOCK) { for (int32_t i = 0; i < numOfBlocks; ++i) { SSDataBlock* pDataBlock = &((SSDataBlock*)input)[i]; - SPackedData tmp = { - .pDataBlock = pDataBlock, - }; + SPackedData tmp = { .pDataBlock = pDataBlock }; taosArrayPush(pInfo->pBlockLists, &tmp); } pInfo->blockType = STREAM_INPUT__DATA_BLOCK; @@ -162,9 +160,11 @@ void doSetTaskId(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { SStreamScanInfo* pStreamScanInfo = pOperator->info; - STableScanInfo* pScanInfo = pStreamScanInfo->pTableScanOp->info; - if (pScanInfo->base.dataReader != NULL) { - tsdbReaderSetId(pScanInfo->base.dataReader, pTaskInfo->id.str); + if (pStreamScanInfo->pTableScanOp != NULL) { + STableScanInfo* pScanInfo = pStreamScanInfo->pTableScanOp->info; + if (pScanInfo->base.dataReader != NULL) { + tsdbReaderSetId(pScanInfo->base.dataReader, pTaskInfo->id.str); + } } } else { doSetTaskId(pOperator->pDownstream[0]); diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 280edf8b53..7ad8821ff9 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -872,9 +872,9 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition getBufferPgSize(pInfo->binfo.pRes->info.rowSize, &defaultPgsz, &defaultBufsz); if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; + terrno = TSDB_CODE_NO_DISKSPACE; pTaskInfo->code = terrno; - qError("Create partition operator info failed since %s", terrstr(terrno)); + qError("Create partition operator info failed since %s, tempDir:%s", terrstr(), tsTempDir); goto _error; } diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index e1fa7a282b..8909d83d31 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1583,7 +1583,7 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock // currently only the tbname pseudo column if (pInfo->numOfPseudoExpr > 0) { int32_t code = addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes, - pInfo->pRes->info.rows, GET_TASKID(pTaskInfo), NULL); + pInfo->pRes->info.rows, GET_TASKID(pTaskInfo), &pTableScanInfo->base.metaCache); // ignore the table not exists error, since this table may have been dropped during the scan procedure. if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_PAR_TABLE_NOT_EXIST) { blockDataFreeRes((SSDataBlock*)pBlock); @@ -1626,7 +1626,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) { blockDataCleanup(pInfo->pRes); SDataBlockInfo* pBlockInfo = &pInfo->pRes->info; - while (tqNextBlockImpl(pInfo->tqReader)) { + while (tqNextBlockImpl(pInfo->tqReader, NULL)) { int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL); if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) { continue; @@ -2046,17 +2046,18 @@ FETCH_NEXT_BLOCK: return pInfo->pUpdateRes; } + const char* id = GET_TASKID(pTaskInfo); SDataBlockInfo* pBlockInfo = &pInfo->pRes->info; - - int32_t totBlockNum = taosArrayGetSize(pInfo->pBlockLists); + int32_t totalBlocks = taosArrayGetSize(pInfo->pBlockLists); NEXT_SUBMIT_BLK: while (1) { if (pInfo->tqReader->msg.msgStr == NULL) { - if (pInfo->validBlockIndex >= totBlockNum) { + if (pInfo->validBlockIndex >= totalBlocks) { updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo); doClearBufferedBlocks(pInfo); - qDebug("stream scan return empty, consume block %d", totBlockNum); + + qDebug("stream scan return empty, all %d submit blocks consumed, %s", totalBlocks, id); void* buff = NULL; // int32_t len = streamScanOperatorEncode(pInfo, &buff); // if (len > 0) { @@ -2068,17 +2069,18 @@ FETCH_NEXT_BLOCK: int32_t current = pInfo->validBlockIndex++; SPackedData* pSubmit = taosArrayGet(pInfo->pBlockLists, current); + + qDebug("set %d/%d as the input submit block, %s", current, totalBlocks, id); if (tqReaderSetSubmitMsg(pInfo->tqReader, pSubmit->msgStr, pSubmit->msgLen, pSubmit->ver) < 0) { - qError("submit msg messed up when initing stream submit block %p, current %d, total %d", pSubmit, current, - totBlockNum); + qError("submit msg messed up when initializing stream submit block %p, current %d/%d, %s", pSubmit, current, totalBlocks, id); continue; } } blockDataCleanup(pInfo->pRes); - while (tqNextBlockImpl(pInfo->tqReader)) { - int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL); + while (tqNextBlockImpl(pInfo->tqReader, id)) { + int32_t code = tqRetrieveDataBlock(pInfo->tqReader, id); if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) { continue; } @@ -2099,6 +2101,7 @@ FETCH_NEXT_BLOCK: break; } } + if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) { break; } else { @@ -2110,7 +2113,7 @@ FETCH_NEXT_BLOCK: pInfo->numOfExec++; pOperator->resultInfo.totalRows += pBlockInfo->rows; - qDebug("scan rows: %" PRId64, pBlockInfo->rows); + qDebug("stream scan get source rows:%" PRId64", %s", pBlockInfo->rows, id); if (pBlockInfo->rows > 0) { return pInfo->pRes; } @@ -2515,6 +2518,51 @@ _error: return NULL; } +static void doTagScanOneTable(SOperatorInfo* pOperator, const SSDataBlock* pRes, int32_t count, SMetaReader* mr) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + STagScanInfo* pInfo = pOperator->info; + SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[0]; + + STableKeyInfo* item = tableListGetInfo(pInfo->pTableListInfo, pInfo->curPos); + int32_t code = metaGetTableEntryByUid(mr, item->uid); + tDecoderClear(&(*mr).coder); + if (code != TSDB_CODE_SUCCESS) { + qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", item->uid, tstrerror(terrno), + GET_TASKID(pTaskInfo)); + metaReaderClear(mr); + T_LONG_JMP(pTaskInfo->env, terrno); + } + + char str[512]; + for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { + SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId); + + // refactor later + if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) { + STR_TO_VARSTR(str, (*mr).me.name); + colDataSetVal(pDst, (count), str, false); + } else { // it is a tag value + STagVal val = {0}; + val.cid = pExprInfo[j].base.pParam[0].pCol->colId; + const char* p = metaGetTableTagVal((*mr).me.ctbEntry.pTags, pDst->info.type, &val); + + char* data = NULL; + if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL) { + data = tTagValToData((const STagVal*)p, false); + } else { + data = (char*)p; + } + colDataSetVal(pDst, (count), data, + (data == NULL) || (pDst->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data))); + + if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL && IS_VAR_DATA_TYPE(((const STagVal*)p)->type) && + data != NULL) { + taosMemoryFree(data); + } + } + } +} + static SSDataBlock* doTagScan(SOperatorInfo* pOperator) { if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -2539,48 +2587,22 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) { metaReaderInit(&mr, pInfo->readHandle.meta, 0); while (pInfo->curPos < size && count < pOperator->resultInfo.capacity) { - STableKeyInfo* item = tableListGetInfo(pInfo->pTableListInfo, pInfo->curPos); - int32_t code = metaGetTableEntryByUid(&mr, item->uid); - tDecoderClear(&mr.coder); - if (code != TSDB_CODE_SUCCESS) { - qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", item->uid, tstrerror(terrno), - GET_TASKID(pTaskInfo)); - metaReaderClear(&mr); - T_LONG_JMP(pTaskInfo->env, terrno); - } - - for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { - SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId); - - // refactor later - if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) { - STR_TO_VARSTR(str, mr.me.name); - colDataSetVal(pDst, count, str, false); - } else { // it is a tag value - STagVal val = {0}; - val.cid = pExprInfo[j].base.pParam[0].pCol->colId; - const char* p = metaGetTableTagVal(mr.me.ctbEntry.pTags, pDst->info.type, &val); - - char* data = NULL; - if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL) { - data = tTagValToData((const STagVal*)p, false); - } else { - data = (char*)p; - } - colDataSetVal(pDst, count, data, - (data == NULL) || (pDst->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data))); - - if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL && IS_VAR_DATA_TYPE(((const STagVal*)p)->type) && - data != NULL) { - taosMemoryFree(data); - } - } - } - - count += 1; + doTagScanOneTable(pOperator, pRes, count, &mr); + ++count; if (++pInfo->curPos >= size) { setOperatorCompleted(pOperator); } + // each table with tbname is a group, hence its own block, but only group when slimit exists for performance reason. + if (pInfo->pSlimit != NULL) { + if (pInfo->curPos < pInfo->pSlimit->offset) { + continue; + } + pInfo->pRes->info.id.groupId = calcGroupId(mr.me.name, strlen(mr.me.name)); + if (pInfo->curPos >= (pInfo->pSlimit->offset + pInfo->pSlimit->limit) - 1) { + setOperatorCompleted(pOperator); + } + break; + } } metaReaderClear(&mr); @@ -2631,6 +2653,7 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi pInfo->pRes = createDataBlockFromDescNode(pDescNode); pInfo->readHandle = *pReadHandle; pInfo->curPos = 0; + pInfo->pSlimit = (SLimitNode*)pPhyNode->node.pSlimit; //TODO: slimit now only indicate group setOperatorInfo(pOperator, "TagScanOperator", QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN, false, OP_NOT_OPENED, pInfo, pTaskInfo); diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index 10933f285c..718bb596c5 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -547,6 +547,7 @@ typedef struct SMultiwayMergeOperatorInfo { SSDataBlock* pIntermediateBlock; // to hold the intermediate result int64_t startTs; // sort start time bool groupSort; + bool ignoreGroupId; uint64_t groupId; STupleHandle* prefetchedTuple; } SMultiwayMergeOperatorInfo; @@ -696,7 +697,11 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData } pDataBlock->info.rows = p->info.rows; - pDataBlock->info.id.groupId = pInfo->groupId; + if (pInfo->ignoreGroupId) { + pDataBlock->info.id.groupId = 0; + } else { + pDataBlock->info.id.groupId = pInfo->groupId; + } pDataBlock->info.dataLoad = 1; } @@ -787,6 +792,7 @@ SOperatorInfo* createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); pInfo->groupSort = pMergePhyNode->groupSort; + pInfo->ignoreGroupId = pMergePhyNode->ignoreGroupId; pInfo->pSortInfo = createSortInfo(pMergePhyNode->pMergeKeys); pInfo->pInputBlock = pInputBlock; size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock); diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 29e3668ec4..d56595dae9 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -38,6 +38,11 @@ typedef struct STimeSliceOperatorInfo { SColumn tsCol; // primary timestamp column SExprSupp scalarSup; // scalar calculation struct SFillColInfo* pFillColInfo; // fill column info + int64_t prevTs; + bool prevTsSet; + uint64_t groupId; + SGroupKeys* pPrevGroupKey; + SSDataBlock* pNextGroupRes; } STimeSliceOperatorInfo; static void destroyTimeSliceOperatorInfo(void* param); @@ -168,18 +173,55 @@ static bool isIsfilledPseudoColumn(SExprInfo* pExprInfo) { return (IS_BOOLEAN_TYPE(pExprInfo->base.resSchema.type) && strcasecmp(name, "_isfilled") == 0); } +static bool checkDuplicateTimestamps(STimeSliceOperatorInfo* pSliceInfo, SColumnInfoData* pTsCol, + int32_t curIndex, int32_t rows) { + + + int64_t currentTs = *(int64_t*)colDataGetData(pTsCol, curIndex); + if (currentTs > pSliceInfo->win.ekey) { + return false; + } + + if ((pSliceInfo->prevTsSet == true) && (currentTs == pSliceInfo->prevTs)) { + return true; + } + + pSliceInfo->prevTsSet = true; + pSliceInfo->prevTs = currentTs; + + if (currentTs == pSliceInfo->win.ekey && curIndex < rows - 1) { + int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, curIndex + 1); + if (currentTs == nextTs) { + return true; + } + } + + return false; +} + +static bool isInterpFunc(SExprInfo* pExprInfo) { + int32_t functionType = pExprInfo->pExpr->_function.functionType; + return (functionType == FUNCTION_TYPE_INTERP); +} + +static bool isGroupKeyFunc(SExprInfo* pExprInfo) { + int32_t functionType = pExprInfo->pExpr->_function.functionType; + return (functionType == FUNCTION_TYPE_GROUP_KEY); +} + static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* pExprSup, SSDataBlock* pResBlock, - bool beforeTs) { + SSDataBlock* pSrcBlock, int32_t index, bool beforeTs) { int32_t rows = pResBlock->info.rows; timeSliceEnsureBlockCapacity(pSliceInfo, pResBlock); // todo set the correct primary timestamp column + // output the result bool hasInterp = true; for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) { SExprInfo* pExprInfo = &pExprSup->pExprInfo[j]; - int32_t dstSlot = pExprInfo->base.resSchema.slotId; + int32_t dstSlot = pExprInfo->base.resSchema.slotId; SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); if (isIrowtsPseudoColumn(pExprInfo)) { @@ -189,6 +231,30 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp bool isFilled = true; colDataAppend(pDst, pResBlock->info.rows, (char*)&isFilled, false); continue; + } else if (!isInterpFunc(pExprInfo)) { + if (isGroupKeyFunc(pExprInfo)) { + if (pSrcBlock != NULL) { + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); + + if (colDataIsNull_s(pSrc, index)) { + colDataSetNULL(pDst, pResBlock->info.rows); + continue; + } + + char* v = colDataGetData(pSrc, index); + colDataSetVal(pDst, pResBlock->info.rows, v, false); + } else { + // use stored group key + SGroupKeys* pkey = pSliceInfo->pPrevGroupKey; + if (pkey->isNull == false) { + colDataSetVal(pDst, rows, pkey->pData, false); + } else { + colDataSetNULL(pDst, rows); + } + } + } + continue; } int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; @@ -314,7 +380,7 @@ static void addCurrentRowToResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp* bool isFilled = false; colDataSetVal(pDst, pResBlock->info.rows, (char*)&isFilled, false); } else { - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); if (colDataIsNull_s(pSrc, index)) { @@ -414,7 +480,31 @@ static int32_t initFillLinearInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pB return TSDB_CODE_SUCCESS; } -static int32_t initKeeperInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock) { +static int32_t initGroupKeyKeeper(STimeSliceOperatorInfo* pInfo, SExprSupp* pExprSup) { + if (pInfo->pPrevGroupKey != NULL) { + return TSDB_CODE_SUCCESS; + } + + pInfo->pPrevGroupKey = taosMemoryCalloc(1, sizeof(SGroupKeys)); + if (pInfo->pPrevGroupKey == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pExprSup->numOfExprs; ++i) { + SExprInfo* pExprInfo = &pExprSup->pExprInfo[i]; + + if (isGroupKeyFunc(pExprInfo)) { + pInfo->pPrevGroupKey->bytes = pExprInfo->base.resSchema.bytes; + pInfo->pPrevGroupKey->type = pExprInfo->base.resSchema.type; + pInfo->pPrevGroupKey->isNull = false; + pInfo->pPrevGroupKey->pData = taosMemoryCalloc(1, pInfo->pPrevGroupKey->bytes); + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t initKeeperInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock, SExprSupp* pExprSup) { int32_t code; code = initPrevRowsKeeper(pInfo, pBlock); if (code != TSDB_CODE_SUCCESS) { @@ -431,9 +521,202 @@ static int32_t initKeeperInfo(STimeSliceOperatorInfo* pInfo, SSDataBlock* pBlock return TSDB_CODE_FAILED; } + code = initGroupKeyKeeper(pInfo, pExprSup); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_FAILED; + } + + return TSDB_CODE_SUCCESS; } +static int32_t resetPrevRowsKeeper(STimeSliceOperatorInfo* pInfo) { + if (pInfo->pPrevRow == NULL) { + return TSDB_CODE_SUCCESS; + } + + for (int32_t i = 0; i < taosArrayGetSize(pInfo->pLinearInfo); ++i) { + SGroupKeys *pKey = taosArrayGet(pInfo->pPrevRow, i); + pKey->isNull = false; + } + + pInfo->isPrevRowSet = false; + + return TSDB_CODE_SUCCESS; +} + +static int32_t resetNextRowsKeeper(STimeSliceOperatorInfo* pInfo) { + if (pInfo->pNextRow == NULL) { + return TSDB_CODE_SUCCESS; + } + + for (int32_t i = 0; i < taosArrayGetSize(pInfo->pLinearInfo); ++i) { + SGroupKeys *pKey = taosArrayGet(pInfo->pPrevRow, i); + pKey->isNull = false; + } + + pInfo->isNextRowSet = false; + + return TSDB_CODE_SUCCESS; +} + +static int32_t resetFillLinearInfo(STimeSliceOperatorInfo* pInfo) { + if (pInfo->pLinearInfo == NULL) { + return TSDB_CODE_SUCCESS; + } + + for (int32_t i = 0; i < taosArrayGetSize(pInfo->pLinearInfo); ++i) { + SFillLinearInfo *pLinearInfo = taosArrayGet(pInfo->pLinearInfo, i); + pLinearInfo->start.key = INT64_MIN; + pLinearInfo->end.key = INT64_MIN; + pLinearInfo->isStartSet = false; + pLinearInfo->isEndSet = false; + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t resetKeeperInfo(STimeSliceOperatorInfo* pInfo) { + resetPrevRowsKeeper(pInfo); + resetNextRowsKeeper(pInfo); + resetFillLinearInfo(pInfo); + + return TSDB_CODE_SUCCESS; +} + +static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pSliceInfo, SSDataBlock* pBlock, + SExecTaskInfo* pTaskInfo) { + SSDataBlock* pResBlock = pSliceInfo->pRes; + SInterval* pInterval = &pSliceInfo->interval; + + SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); + for (int32_t i = 0; i < pBlock->info.rows; ++i) { + int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); + + // check for duplicate timestamps + if (checkDuplicateTimestamps(pSliceInfo, pTsCol, i, pBlock->info.rows)) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_FUNC_DUP_TIMESTAMP); + } + + if (pSliceInfo->current > pSliceInfo->win.ekey) { + break; + } + + if (ts == pSliceInfo->current) { + addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); + + doKeepPrevRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); + + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + if (pSliceInfo->current > pSliceInfo->win.ekey) { + break; + } + } else if (ts < pSliceInfo->current) { + // in case of interpolation window starts and ends between two datapoints, fill(prev) need to interpolate + doKeepPrevRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); + + if (i < pBlock->info.rows - 1) { + // in case of interpolation window starts and ends between two datapoints, fill(next) need to interpolate + doKeepNextRows(pSliceInfo, pBlock, i + 1); + int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); + if (nextTs > pSliceInfo->current) { + while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, false) && + pSliceInfo->fillType == TSDB_FILL_LINEAR) { + break; + } else { + pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, + pInterval->precision); + } + } + + if (pSliceInfo->current > pSliceInfo->win.ekey) { + break; + } + } else { + // ignore current row, and do nothing + } + } else { // it is the last row of current block + doKeepPrevRows(pSliceInfo, pBlock, i); + } + } else { // ts > pSliceInfo->current + // in case of interpolation window starts and ends between two datapoints, fill(next) need to interpolate + doKeepNextRows(pSliceInfo, pBlock, i); + doKeepLinearInfo(pSliceInfo, pBlock, i); + + while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { + if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i, true) && + pSliceInfo->fillType == TSDB_FILL_LINEAR) { + break; + } else { + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + } + } + + // add current row if timestamp match + if (ts == pSliceInfo->current && pSliceInfo->current <= pSliceInfo->win.ekey) { + addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); + + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + } + doKeepPrevRows(pSliceInfo, pBlock, i); + + if (pSliceInfo->current > pSliceInfo->win.ekey) { + break; + } + } + } +} + +static void genInterpAfterDataBlock(STimeSliceOperatorInfo* pSliceInfo, SOperatorInfo* pOperator, int32_t index) { + SSDataBlock* pResBlock = pSliceInfo->pRes; + SInterval* pInterval = &pSliceInfo->interval; + + while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT && + pSliceInfo->fillType != TSDB_FILL_LINEAR) { + genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, NULL, index, false); + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + } +} + +static void copyPrevGroupKey(SExprSupp* pExprSup, SGroupKeys* pGroupKey, SSDataBlock* pSrcBlock) { + for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) { + SExprInfo* pExprInfo = &pExprSup->pExprInfo[j]; + + if (isGroupKeyFunc(pExprInfo)) { + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, srcSlot); + + if (colDataIsNull_s(pSrc, 0)) { + pGroupKey->isNull = true; + break; + } + + char* v = colDataGetData(pSrc, 0); + if (IS_VAR_DATA_TYPE(pGroupKey->type)) { + memcpy(pGroupKey->pData, v, varDataTLen(v)); + } else { + memcpy(pGroupKey->pData, v, pGroupKey->bytes); + } + + pGroupKey->isNull = false; + break; + } + } +} + +static void resetTimesliceInfo(STimeSliceOperatorInfo* pSliceInfo) { + pSliceInfo->current = pSliceInfo->win.skey; + pSliceInfo->prevTsSet = false; + resetKeeperInfo(pSliceInfo); +} + static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -452,118 +735,62 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - break; + if (pSliceInfo->pNextGroupRes != NULL) { + setInputDataBlock(pSup, pSliceInfo->pNextGroupRes, order, MAIN_SCAN, true); + doTimesliceImpl(pOperator, pSliceInfo, pSliceInfo->pNextGroupRes, pTaskInfo); + copyPrevGroupKey(&pOperator->exprSupp, pSliceInfo->pPrevGroupKey, pSliceInfo->pNextGroupRes); + pSliceInfo->pNextGroupRes = NULL; } - if (pSliceInfo->scalarSup.pExprInfo != NULL) { - SExprSupp* pExprSup = &pSliceInfo->scalarSup; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - - int32_t code = initKeeperInfo(pSliceInfo, pBlock); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, code); - } - - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); - - SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); - for (int32_t i = 0; i < pBlock->info.rows; ++i) { - int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); - - if (pSliceInfo->current > pSliceInfo->win.ekey) { + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { setOperatorCompleted(pOperator); break; } - if (ts == pSliceInfo->current) { - addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); - - doKeepPrevRows(pSliceInfo, pBlock, i); - doKeepLinearInfo(pSliceInfo, pBlock, i); - - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - if (pSliceInfo->current > pSliceInfo->win.ekey) { - setOperatorCompleted(pOperator); - break; - } - } else if (ts < pSliceInfo->current) { - // in case of interpolation window starts and ends between two datapoints, fill(prev) need to interpolate - doKeepPrevRows(pSliceInfo, pBlock, i); - doKeepLinearInfo(pSliceInfo, pBlock, i); - - if (i < pBlock->info.rows - 1) { - // in case of interpolation window starts and ends between two datapoints, fill(next) need to interpolate - doKeepNextRows(pSliceInfo, pBlock, i + 1); - int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); - if (nextTs > pSliceInfo->current) { - while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, false) && - pSliceInfo->fillType == TSDB_FILL_LINEAR) { - break; - } else { - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, - pInterval->precision); - } - } - - if (pSliceInfo->current > pSliceInfo->win.ekey) { - setOperatorCompleted(pOperator); - break; - } - } else { - // ignore current row, and do nothing - } - } else { // it is the last row of current block - doKeepPrevRows(pSliceInfo, pBlock, i); - } - } else { // ts > pSliceInfo->current - // in case of interpolation window starts and ends between two datapoints, fill(next) need to interpolate - doKeepNextRows(pSliceInfo, pBlock, i); - doKeepLinearInfo(pSliceInfo, pBlock, i); - - while (pSliceInfo->current < ts && pSliceInfo->current <= pSliceInfo->win.ekey) { - if (!genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, true) && - pSliceInfo->fillType == TSDB_FILL_LINEAR) { - break; - } else { - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - } - } - - // add current row if timestamp match - if (ts == pSliceInfo->current && pSliceInfo->current <= pSliceInfo->win.ekey) { - addCurrentRowToResult(pSliceInfo, &pOperator->exprSupp, pResBlock, pBlock, i); - - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - } - doKeepPrevRows(pSliceInfo, pBlock, i); - - if (pSliceInfo->current > pSliceInfo->win.ekey) { - setOperatorCompleted(pOperator); + if (pSliceInfo->groupId == 0 && pBlock->info.id.groupId != 0) { + pSliceInfo->groupId = pBlock->info.id.groupId; + } else { + if (pSliceInfo->groupId != pBlock->info.id.groupId) { + pSliceInfo->groupId = pBlock->info.id.groupId; + pSliceInfo->pNextGroupRes = pBlock; break; } } + + if (pSliceInfo->scalarSup.pExprInfo != NULL) { + SExprSupp* pExprSup = &pSliceInfo->scalarSup; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + + int32_t code = initKeeperInfo(pSliceInfo, pBlock, &pOperator->exprSupp); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, code); + } + + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true); + doTimesliceImpl(pOperator, pSliceInfo, pBlock, pTaskInfo); + copyPrevGroupKey(&pOperator->exprSupp, pSliceInfo->pPrevGroupKey, pBlock); + } + + // check if need to interpolate after last datablock + // except for fill(next), fill(linear) + genInterpAfterDataBlock(pSliceInfo, pOperator, 0); + + doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); + if (pOperator->status == OP_EXEC_DONE) { + break; + } + + // restore initial value for next group + resetTimesliceInfo(pSliceInfo); + if (pResBlock->info.rows >= 4096) { + break; } } - // check if need to interpolate after last datablock - // except for fill(next), fill(linear) - while (pSliceInfo->current <= pSliceInfo->win.ekey && pSliceInfo->fillType != TSDB_FILL_NEXT && - pSliceInfo->fillType != TSDB_FILL_LINEAR) { - genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, false); - pSliceInfo->current = - taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); - } - - doFilter(pResBlock, pOperator->exprSupp.pFilterInfo, NULL); - // restore the value setTaskStatus(pOperator->pTaskInfo, TASK_COMPLETED); if (pResBlock->info.rows == 0) { @@ -614,6 +841,11 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->win = pInterpPhyNode->timeRange; pInfo->interval.interval = pInterpPhyNode->interval; pInfo->current = pInfo->win.skey; + pInfo->prevTsSet = false; + pInfo->prevTs = 0; + pInfo->groupId = 0; + pInfo->pPrevGroupKey = NULL; + pInfo->pNextGroupRes = NULL; if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { STableScanInfo* pScanInfo = (STableScanInfo*)downstream->info; @@ -661,6 +893,10 @@ void destroyTimeSliceOperatorInfo(void* param) { taosMemoryFree(pKey->end.val); } taosArrayDestroy(pInfo->pLinearInfo); + + taosMemoryFree(pInfo->pPrevGroupKey->pData); + taosMemoryFree(pInfo->pPrevGroupKey); + cleanupExprSupp(&pInfo->scalarSup); for (int32_t i = 0; i < pInfo->pFillColInfo->numOfFillExpr; ++i) { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 27f9a1ac28..652825165c 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1106,7 +1106,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI bool masterScan = true; int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - int16_t bytes = pStateColInfoData->info.bytes; + int32_t bytes = pStateColInfoData->info.bytes; SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId); TSKEY* tsList = (TSKEY*)pColInfoData->pData; @@ -2564,7 +2564,9 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); if (IS_FINAL_OP(pInfo)) { addRetriveWindow(delWins, pInfo); - taosArrayAddAll(pInfo->pDelWins, delWins); + if (pBlock->info.type != STREAM_CLEAR) { + taosArrayAddAll(pInfo->pDelWins, delWins); + } taosArrayDestroy(delWins); continue; } @@ -2576,6 +2578,11 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { if (pInfo->pDelRes->info.rows != 0) { // process the rest of the data printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); + if (pBlock->info.type == STREAM_CLEAR) { + pInfo->pDelRes->info.type = STREAM_CLEAR; + } else { + pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; + } return pInfo->pDelRes; } @@ -2892,8 +2899,8 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, bufSize = pageSize * 4; } if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; - qError("Init stream agg supporter failed since %s", terrstr(terrno)); + terrno = TSDB_CODE_NO_DISKSPACE; + qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir); return terrno; } int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir); diff --git a/source/libs/executor/src/tlinearhash.c b/source/libs/executor/src/tlinearhash.c index 2cba3855c7..023583fcde 100644 --- a/source/libs/executor/src/tlinearhash.c +++ b/source/libs/executor/src/tlinearhash.c @@ -248,8 +248,8 @@ SLHashObj* tHashInit(int32_t inMemPages, int32_t pageSize, _hash_fn_t fn, int32_ } if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; - printf("tHash Init failed since %s", terrstr(terrno)); + terrno = TSDB_CODE_NO_DISKSPACE; + printf("tHash Init failed since %s, tempDir:%s", terrstr(), tsTempDir); taosMemoryFree(pHashObj); return NULL; } diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 36e41b0c5d..211f78b981 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -195,8 +195,8 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) { if (pHandle->pBuf == NULL) { if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; - qError("Add to buf failed since %s", terrstr(terrno)); + terrno = TSDB_CODE_NO_DISKSPACE; + qError("Add to buf failed since %s, tempDir:%s", terrstr(), tsTempDir); return terrno; } @@ -261,9 +261,8 @@ static int32_t sortComparInit(SMsortComparParam* pParam, SArray* pSources, int32 // multi-pass internal merge sort is required if (pHandle->pBuf == NULL) { if (!osTempSpaceAvailable()) { - code = TSDB_CODE_NO_AVAIL_DISK; - terrno = code; - qError("Sort compare init failed since %s, %s", tstrerror(code), pHandle->idStr); + code = terrno = TSDB_CODE_NO_DISKSPACE; + qError("Sort compare init failed since %s, tempDir:%s, idStr:%s", terrstr(), tsTempDir, pHandle->idStr); return code; } diff --git a/source/libs/function/inc/tpercentile.h b/source/libs/function/inc/tpercentile.h index 80159460f5..65b7b38a05 100644 --- a/source/libs/function/inc/tpercentile.h +++ b/source/libs/function/inc/tpercentile.h @@ -53,7 +53,7 @@ typedef int32_t (*__perc_hash_func_t)(struct tMemBucket *pBucket, const void *va typedef struct tMemBucket { int16_t numOfSlots; int16_t type; - int16_t bytes; + int32_t bytes; int32_t total; int32_t elemPerPage; // number of elements for each object int32_t maxCapacity; // maximum allowed number of elements that can be sort directly to get the result @@ -67,7 +67,7 @@ typedef struct tMemBucket { SHashObj *groupPagesMap; // disk page map for different groups; } tMemBucket; -tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, double maxval); +tMemBucket *tMemBucketCreate(int32_t nElemSize, int16_t dataType, double minval, double maxval); void tMemBucketDestroy(tMemBucket *pBucket); diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index af318a6bc5..80b26bd39b 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -196,11 +196,11 @@ typedef struct SMavgInfo { } SMavgInfo; typedef struct SSampleInfo { - int32_t samples; - int32_t totalPoints; - int32_t numSampled; - uint8_t colType; - int16_t colBytes; + int32_t samples; + int32_t totalPoints; + int32_t numSampled; + uint8_t colType; + uint16_t colBytes; STuplePos nullTuplePos; bool nullTupleSaved; @@ -220,7 +220,7 @@ typedef struct STailInfo { int32_t numAdded; int32_t offset; uint8_t colType; - int16_t colBytes; + uint16_t colBytes; STailItem** pItems; } STailInfo; @@ -233,7 +233,7 @@ typedef struct SUniqueItem { typedef struct SUniqueInfo { int32_t numOfPoints; uint8_t colType; - int16_t colBytes; + uint16_t colBytes; bool hasNull; // null is not hashable, handle separately SHashObj* pHash; char pItems[]; @@ -247,13 +247,13 @@ typedef struct SModeItem { typedef struct SModeInfo { uint8_t colType; - int16_t colBytes; + uint16_t colBytes; SHashObj* pHash; STuplePos nullTuplePos; bool nullTupleSaved; - char* buf; // serialize data buffer + char* buf; // serialize data buffer } SModeInfo; typedef struct SDerivInfo { @@ -855,7 +855,9 @@ int32_t setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STu int32_t numOfCols = pCtx->subsidiaries.num; const char* p = loadTupleData(pCtx, pTuplePos); if (p == NULL) { - terrno = TSDB_CODE_NO_AVAIL_DISK; + terrno = TSDB_CODE_NOT_FOUND; + qError("Load tuple data failed since %s, groupId:%" PRIu64 ", ts:%" PRId64, terrstr(), + pTuplePos->streamTupleKey.groupId, pTuplePos->streamTupleKey.ts); return terrno; } @@ -5098,7 +5100,9 @@ int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { if (maxCount != 0) { const char* pData = loadTupleData(pCtx, &resDataPos); if (pData == NULL) { - code = TSDB_CODE_NO_AVAIL_DISK; + code = terrno = TSDB_CODE_NOT_FOUND; + qError("Load tuple data failed since %s, groupId:%" PRIu64 ", ts:%" PRId64, terrstr(), + resDataPos.streamTupleKey.groupId, resDataPos.streamTupleKey.ts); modeFunctionCleanup(pInfo); return code; } diff --git a/source/libs/function/src/tpercentile.c b/source/libs/function/src/tpercentile.c index de381fadbd..3ec802a7ce 100644 --- a/source/libs/function/src/tpercentile.c +++ b/source/libs/function/src/tpercentile.c @@ -236,7 +236,7 @@ static void resetSlotInfo(tMemBucket *pBucket) { } } -tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, double maxval) { +tMemBucket *tMemBucketCreate(int32_t nElemSize, int16_t dataType, double minval, double maxval) { tMemBucket *pBucket = (tMemBucket *)taosMemoryCalloc(1, sizeof(tMemBucket)); if (pBucket == NULL) { return NULL; @@ -277,7 +277,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, resetSlotInfo(pBucket); if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; + terrno = TSDB_CODE_NO_DISKSPACE; // qError("MemBucket create disk based Buf failed since %s", terrstr(terrno)); tMemBucketDestroy(pBucket); return NULL; diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 8c8b99a6f8..6b70422ac8 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -1580,7 +1580,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) { case UV_TASK_REQ_RSP: { uv_pipe_t *pipe = uvTask->pipe; if (pipe == NULL) { - code = TSDB_CODE_UDF_PIPE_NO_PIPE; + code = TSDB_CODE_UDF_PIPE_NOT_EXIST; } else { uv_write_t *write = taosMemoryMalloc(sizeof(uv_write_t)); write->data = pipe->data; @@ -1598,7 +1598,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) { case UV_TASK_DISCONNECT: { uv_pipe_t *pipe = uvTask->pipe; if (pipe == NULL) { - code = TSDB_CODE_UDF_PIPE_NO_PIPE; + code = TSDB_CODE_UDF_PIPE_NOT_EXIST; } else { SClientUvConn *conn = pipe->data; QUEUE_INSERT_TAIL(&conn->taskQueue, &uvTask->connTaskQueue); @@ -1759,9 +1759,6 @@ int32_t udfcRunUdfUvTask(SClientUdfTask *task, int8_t uvTaskType) { } int32_t doSetupUdf(char udfName[], UdfcFuncHandle *funcHandle) { - if (gUdfcProxy.udfcState != UDFC_STATE_READY) { - return TSDB_CODE_UDF_INVALID_STATE; - } SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask)); task->errCode = 0; task->session = taosMemoryCalloc(1, sizeof(SUdfcUvSession)); @@ -1804,7 +1801,7 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf SUdfcUvSession *session = (SUdfcUvSession *)handle; if (session->udfUvPipe == NULL) { fnError("No pipe to udfd"); - return TSDB_CODE_UDF_PIPE_NO_PIPE; + return TSDB_CODE_UDF_PIPE_NOT_EXIST; } SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask)); task->errCode = 0; @@ -1928,7 +1925,7 @@ int32_t doTeardownUdf(UdfcFuncHandle handle) { if (session->udfUvPipe == NULL) { fnError("tear down udf. pipe to udfd does not exist. udf name: %s", session->udfName); taosMemoryFree(session); - return TSDB_CODE_UDF_PIPE_NO_PIPE; + return TSDB_CODE_UDF_PIPE_NOT_EXIST; } SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask)); diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c index 5034af2f82..d2553ba96d 100644 --- a/source/libs/function/src/udfd.c +++ b/source/libs/function/src/udfd.c @@ -844,7 +844,7 @@ void udfdGetFuncBodyPath(const SUdf *udf, char *path) { int32_t udfdSaveFuncBodyToFile(SFuncInfo *pFuncInfo, SUdf *udf) { if (!osDataSpaceAvailable()) { - terrno = TSDB_CODE_NO_AVAIL_DISK; + terrno = TSDB_CODE_NO_DISKSPACE; fnError("udfd create shared library failed since %s", terrstr(terrno)); return terrno; } diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index d9a4c5178f..0f4e7bde63 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -455,6 +455,7 @@ static int32_t logicMergeCopy(const SMergeLogicNode* pSrc, SMergeLogicNode* pDst COPY_SCALAR_FIELD(numOfChannels); COPY_SCALAR_FIELD(srcGroupId); COPY_SCALAR_FIELD(groupSort); + COPY_SCALAR_FIELD(ignoreGroupId); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 919be78125..136d1fc391 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -261,6 +261,14 @@ const char* nodesNodeName(ENodeType type) { return "DeleteStmt"; case QUERY_NODE_INSERT_STMT: return "InsertStmt"; + case QUERY_NODE_RESTORE_DNODE_STMT: + return "RestoreDnodeStmt"; + case QUERY_NODE_RESTORE_QNODE_STMT: + return "RestoreQnodeStmt"; + case QUERY_NODE_RESTORE_MNODE_STMT: + return "RestoreMnodeStmt"; + case QUERY_NODE_RESTORE_VNODE_STMT: + return "RestoreVnodeStmt"; case QUERY_NODE_LOGIC_PLAN_SCAN: return "LogicScan"; case QUERY_NODE_LOGIC_PLAN_JOIN: @@ -2031,6 +2039,7 @@ static const char* jkMergePhysiPlanTargets = "Targets"; static const char* jkMergePhysiPlanNumOfChannels = "NumOfChannels"; static const char* jkMergePhysiPlanSrcGroupId = "SrcGroupId"; static const char* jkMergePhysiPlanGroupSort = "GroupSort"; +static const char* jkMergePhysiPlanIgnoreGroupID = "IgnoreGroupID"; static int32_t physiMergeNodeToJson(const void* pObj, SJson* pJson) { const SMergePhysiNode* pNode = (const SMergePhysiNode*)pObj; @@ -2051,6 +2060,9 @@ static int32_t physiMergeNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkMergePhysiPlanGroupSort, pNode->groupSort); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkMergePhysiPlanIgnoreGroupID, pNode->ignoreGroupId); + } return code; } @@ -2074,6 +2086,9 @@ static int32_t jsonToPhysiMergeNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkMergePhysiPlanGroupSort, &pNode->groupSort); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkMergePhysiPlanIgnoreGroupID, &pNode->ignoreGroupId); + } return code; } @@ -5530,6 +5545,35 @@ static int32_t jsonToDropDnodeStmt(const SJson* pJson, void* pObj) { return code; } +static const char* jkRestoreComponentNodeStmtDnodeId = "DnodeId"; + +static int32_t restoreComponentNodeStmtToJson(const void* pObj, SJson* pJson) { + const SRestoreComponentNodeStmt* pNode = (const SRestoreComponentNodeStmt*)pObj; + return tjsonAddIntegerToObject(pJson, jkRestoreComponentNodeStmtDnodeId, pNode->dnodeId); +} + +static int32_t jsonToRestoreComponentNodeStmt(const SJson* pJson, void* pObj) { + SRestoreComponentNodeStmt* pNode = (SRestoreComponentNodeStmt*)pObj; + return tjsonGetIntValue(pJson, jkRestoreComponentNodeStmtDnodeId, &pNode->dnodeId); +} + +static int32_t jsonToRestoreDnodeStmt(const SJson* pJson, void* pObj) { + return jsonToRestoreComponentNodeStmt(pJson, pObj); +} +static int32_t jsonToRestoreQnodeStmt(const SJson* pJson, void* pObj) { + return jsonToRestoreComponentNodeStmt(pJson, pObj); +} +static int32_t jsonToRestoreMnodeStmt(const SJson* pJson, void* pObj) { + return jsonToRestoreComponentNodeStmt(pJson, pObj); +} +static int32_t jsonToRestoreVnodeStmt(const SJson* pJson, void* pObj) { + return jsonToRestoreComponentNodeStmt(pJson, pObj); +} + + + + + static const char* jkCreateTopicStmtTopicName = "TopicName"; static const char* jkCreateTopicStmtSubscribeDbName = "SubscribeDbName"; static const char* jkCreateTopicStmtIgnoreExists = "IgnoreExists"; @@ -6817,6 +6861,14 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToDeleteStmt(pJson, pObj); case QUERY_NODE_INSERT_STMT: return jsonToInsertStmt(pJson, pObj); + case QUERY_NODE_RESTORE_DNODE_STMT: + return jsonToRestoreDnodeStmt(pJson, pObj); + case QUERY_NODE_RESTORE_QNODE_STMT: + return jsonToRestoreQnodeStmt(pJson, pObj); + case QUERY_NODE_RESTORE_MNODE_STMT: + return jsonToRestoreMnodeStmt(pJson, pObj); + case QUERY_NODE_RESTORE_VNODE_STMT: + return jsonToRestoreVnodeStmt(pJson, pObj); case QUERY_NODE_LOGIC_PLAN_SCAN: return jsonToLogicScanNode(pJson, pObj); case QUERY_NODE_LOGIC_PLAN_JOIN: diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 6c6b6c0e81..c06eb62771 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -2512,7 +2512,8 @@ enum { PHY_MERGE_CODE_TARGETS, PHY_MERGE_CODE_NUM_OF_CHANNELS, PHY_MERGE_CODE_SRC_GROUP_ID, - PHY_MERGE_CODE_GROUP_SORT + PHY_MERGE_CODE_GROUP_SORT, + PHY_MERGE_CODE_IGNORE_GROUP_ID, }; static int32_t physiMergeNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { @@ -2534,6 +2535,9 @@ static int32_t physiMergeNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeBool(pEncoder, PHY_MERGE_CODE_GROUP_SORT, pNode->groupSort); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeBool(pEncoder, PHY_MERGE_CODE_IGNORE_GROUP_ID, pNode->ignoreGroupId); + } return code; } @@ -2563,6 +2567,9 @@ static int32_t msgToPhysiMergeNode(STlvDecoder* pDecoder, void* pObj) { case PHY_MERGE_CODE_GROUP_SORT: code = tlvDecodeBool(pTlv, &pNode->groupSort); break; + case PHY_MERGE_CODE_IGNORE_GROUP_ID: + code = tlvDecodeBool(pTlv, &pNode->ignoreGroupId); + break; default: break; } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 1f79616465..13c5a34084 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -459,6 +459,11 @@ SNode* nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SInsertStmt)); case QUERY_NODE_QUERY: return makeNode(type, sizeof(SQuery)); + case QUERY_NODE_RESTORE_DNODE_STMT: + case QUERY_NODE_RESTORE_QNODE_STMT: + case QUERY_NODE_RESTORE_MNODE_STMT: + case QUERY_NODE_RESTORE_VNODE_STMT: + return makeNode(type, sizeof(SRestoreComponentNodeStmt)); case QUERY_NODE_LOGIC_PLAN_SCAN: return makeNode(type, sizeof(SScanLogicNode)); case QUERY_NODE_LOGIC_PLAN_JOIN: @@ -1058,6 +1063,11 @@ void nodesDestroyNode(SNode* pNode) { nodesDestroyNode(pQuery->pPrepareRoot); break; } + case QUERY_NODE_RESTORE_DNODE_STMT: // no pointer field + case QUERY_NODE_RESTORE_QNODE_STMT: // no pointer field + case QUERY_NODE_RESTORE_MNODE_STMT: // no pointer field + case QUERY_NODE_RESTORE_VNODE_STMT: // no pointer field + break; case QUERY_NODE_LOGIC_PLAN_SCAN: { SScanLogicNode* pLogicNode = (SScanLogicNode*)pNode; destroyLogicNode((SLogicNode*)pLogicNode); diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 8f18797c83..1d1a522d01 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -202,6 +202,7 @@ SNode* createIndexOption(SAstCreateContext* pCxt, SNodeList* pFuncs, SNode* pInt SNode* createDropIndexStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pIndexName); SNode* createCreateComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pDnodeId); SNode* createDropComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pDnodeId); +SNode* createRestoreComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pDnodeId); SNode* createCreateTopicStmtUseQuery(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pQuery); SNode* createCreateTopicStmtUseDb(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SToken* pSubDbName, bool withMeta); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index e69fdf40d1..b682cdd4fd 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -123,7 +123,7 @@ priv_level(A) ::= topic_name(B). with_opt(A) ::= . { A = NULL; } with_opt(A) ::= WITH search_condition(B). { A = B; } -/************************************************ create/drop/alter dnode *********************************************/ +/************************************************ create/drop/alter/restore dnode *********************************************/ cmd ::= CREATE DNODE dnode_endpoint(A). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, NULL); } cmd ::= CREATE DNODE dnode_endpoint(A) PORT NK_INTEGER(B). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, &B); } cmd ::= DROP DNODE NK_INTEGER(A) force_opt(B). { pCxt->pRootNode = createDropDnodeStmt(pCxt, &A, B); } @@ -132,6 +132,7 @@ cmd ::= ALTER DNODE NK_INTEGER(A) NK_STRING(B). cmd ::= ALTER DNODE NK_INTEGER(A) NK_STRING(B) NK_STRING(C). { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &A, &B, &C); } cmd ::= ALTER ALL DNODES NK_STRING(A). { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &A, NULL); } cmd ::= ALTER ALL DNODES NK_STRING(A) NK_STRING(B). { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &A, &B); } +cmd ::= RESTORE DNODE NK_INTEGER(A). { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_DNODE_STMT, &A); } %type dnode_endpoint { SToken } %destructor dnode_endpoint { } @@ -148,9 +149,10 @@ force_opt(A) ::= FORCE. cmd ::= ALTER LOCAL NK_STRING(A). { pCxt->pRootNode = createAlterLocalStmt(pCxt, &A, NULL); } cmd ::= ALTER LOCAL NK_STRING(A) NK_STRING(B). { pCxt->pRootNode = createAlterLocalStmt(pCxt, &A, &B); } -/************************************************ create/drop qnode ***************************************************/ +/************************************************ create/drop/restore qnode ***************************************************/ cmd ::= CREATE QNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_QNODE_STMT, &A); } cmd ::= DROP QNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_QNODE_STMT, &A); } +cmd ::= RESTORE QNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_QNODE_STMT, &A); } /************************************************ create/drop bnode ***************************************************/ cmd ::= CREATE BNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_BNODE_STMT, &A); } @@ -160,9 +162,13 @@ cmd ::= DROP BNODE ON DNODE NK_INTEGER(A). cmd ::= CREATE SNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_SNODE_STMT, &A); } cmd ::= DROP SNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_SNODE_STMT, &A); } -/************************************************ create/drop mnode ***************************************************/ +/************************************************ create/drop/restore mnode ***************************************************/ cmd ::= CREATE MNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_MNODE_STMT, &A); } cmd ::= DROP MNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_MNODE_STMT, &A); } +cmd ::= RESTORE MNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_MNODE_STMT, &A); } + +/************************************************ restore vnode ***************************************************/ +cmd ::= RESTORE VNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_VNODE_STMT, &A); } /************************************************ create/drop/use database ********************************************/ cmd ::= CREATE DATABASE not_exists_opt(A) db_name(B) db_options(C). { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, A, &B, C); } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 41648175b9..eeccf18c7b 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1224,7 +1224,7 @@ SDataType createDataType(uint8_t type) { } SDataType createVarLenDataType(uint8_t type, const SToken* pLen) { - SDataType dt = {.type = type, .precision = 0, .scale = 0, .bytes = taosStr2Int16(pLen->z, NULL, 10)}; + SDataType dt = {.type = type, .precision = 0, .scale = 0, .bytes = taosStr2Int32(pLen->z, NULL, 10)}; return dt; } @@ -1674,6 +1674,14 @@ SNode* createDropComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, cons return (SNode*)pStmt; } +SNode* createRestoreComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pDnodeId) { + CHECK_PARSER_STATUS(pCxt); + SRestoreComponentNodeStmt* pStmt = (SRestoreComponentNodeStmt*)nodesMakeNode(type); + CHECK_OUT_OF_MEM(pStmt); + pStmt->dnodeId = taosStr2Int32(pDnodeId->z, NULL, 10); + return (SNode*)pStmt; +} + SNode* createCreateTopicStmtUseQuery(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pQuery) { CHECK_PARSER_STATUS(pCxt); if (!checkTopicName(pCxt, pTopicName)) { diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index c25d0e7036..01b62a9051 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -388,6 +388,9 @@ static bool isSetUselessCol(SSetOperator* pSetOp, int32_t index, SExprNode* pPro } static int32_t calcConstSetOpProjections(SCalcConstContext* pCxt, SSetOperator* pSetOp, bool subquery) { + if (subquery && pSetOp->opType == SET_OP_TYPE_UNION) { + return TSDB_CODE_SUCCESS; + } int32_t index = 0; SNode* pProj = NULL; WHERE_EACH(pProj, pSetOp->pProjectionList) { diff --git a/source/libs/parser/src/parInsertSml.c b/source/libs/parser/src/parInsertSml.c index 1c921b2d7c..dbf5931e8a 100644 --- a/source/libs/parser/src/parInsertSml.c +++ b/source/libs/parser/src/parInsertSml.c @@ -250,7 +250,7 @@ end: int32_t smlBindData(SQuery* query, bool dataFormat, SArray* tags, SArray* colsSchema, SArray* cols, STableMeta* pTableMeta, char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl, - char* msgBuf, int16_t msgBufLen) { + char* msgBuf, int32_t msgBufLen) { SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; SSchema* pTagsSchema = getTableTagSchema(pTableMeta); diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index b2b2d99d38..5c1f4bf98c 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -183,6 +183,7 @@ static SKeyword keywordTable[] = { {"REPLICA", TK_REPLICA}, {"RESET", TK_RESET}, {"RESUME", TK_RESUME}, + {"RESTORE", TK_RESTORE}, {"RETENTIONS", TK_RETENTIONS}, {"REVOKE", TK_REVOKE}, {"ROLLUP", TK_ROLLUP}, @@ -255,6 +256,7 @@ static SKeyword keywordTable[] = { {"VERBOSE", TK_VERBOSE}, {"VGROUP", TK_VGROUP}, {"VGROUPS", TK_VGROUPS}, + {"VNODE", TK_VNODE}, {"VNODES", TK_VNODES}, {"WAL_FSYNC_PERIOD", TK_WAL_FSYNC_PERIOD}, {"WAL_LEVEL", TK_WAL_LEVEL}, diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index d1bd47b884..c5fe3a1f73 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1523,9 +1523,7 @@ static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; SNode* pTable = pSelect->pFromTable; - if ((NULL != pTable && (QUERY_NODE_REAL_TABLE != nodeType(pTable) || - (TSDB_CHILD_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType && - TSDB_NORMAL_TABLE != ((SRealTableNode*)pTable)->pMeta->tableType)))) { + if ((NULL != pTable && QUERY_NODE_REAL_TABLE != nodeType(pTable))) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE, "%s is only supported in single table query", pFunc->functionName); } @@ -2294,6 +2292,25 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) return TSDB_CODE_SUCCESS; } +static int32_t checkHavingGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) { + int32_t code = TSDB_CODE_SUCCESS; + if (NULL == getGroupByList(pCxt) && NULL == pSelect->pPartitionByList && NULL == pSelect->pWindow) { + return code; + } + if (NULL != pSelect->pHaving) { + code = checkExprForGroupBy(pCxt, &pSelect->pHaving); + } +/* + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pProjectionList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); + } + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pOrderByList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList); + } +*/ + return code; +} + static int32_t checkWindowFuncCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) { if (NULL == pSelect->pWindow) { return TSDB_CODE_SUCCESS; @@ -3092,7 +3109,7 @@ static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect } if (TSDB_CODE_SUCCESS == code) { code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); - } + } if (TSDB_CODE_SUCCESS == code) { code = translateFillValues(pCxt, pSelect); } @@ -3109,9 +3126,6 @@ static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) { } pCxt->currClause = SQL_CLAUSE_HAVING; int32_t code = translateExpr(pCxt, &pSelect->pHaving); - if (TSDB_CODE_SUCCESS == code && (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow)) { - code = checkExprForGroupBy(pCxt, &pSelect->pHaving); - } return code; } @@ -3694,6 +3708,9 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect if (TSDB_CODE_SUCCESS == code) { code = translateSelectList(pCxt, pSelect); } + if (TSDB_CODE_SUCCESS == code) { + code = checkHavingGroupBy(pCxt, pSelect); + } if (TSDB_CODE_SUCCESS == code) { code = translateOrderBy(pCxt, pSelect); } @@ -4593,8 +4610,8 @@ static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SN code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); } if (TSDB_CODE_SUCCESS == code) { - if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_BINARY_LEN) || - (TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_NCHAR_LEN)) { + if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_TAGS_LEN) || + (TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && calcTypeBytes(pTag->dataType) > TSDB_MAX_TAGS_LEN)) { code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); } } @@ -5330,7 +5347,8 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable } if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType) { - if (calcTypeBytes(pStmt->dataType) > TSDB_MAX_FIELD_LEN) { + if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) || + (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); } @@ -5340,7 +5358,7 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable } if (TSDB_ALTER_TABLE_UPDATE_TAG_BYTES == pStmt->alterType) { - if (calcTypeBytes(pStmt->dataType) > TSDB_MAX_FIELD_LEN) { + if (calcTypeBytes(pStmt->dataType) > TSDB_MAX_TAGS_LEN) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); } @@ -5355,6 +5373,11 @@ static int32_t checkAlterSuperTableBySchema(STranslateContext* pCxt, SAlterTable return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS); } + if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) || + (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); + } + if (pTableMeta->tableInfo.rowSize + calcTypeBytes(pStmt->dataType) > TSDB_MAX_BYTES_PER_ROW) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW); } @@ -5507,6 +5530,29 @@ static int32_t translateAlterDnode(STranslateContext* pCxt, SAlterDnodeStmt* pSt return buildCmdMsg(pCxt, TDMT_MND_CONFIG_DNODE, (FSerializeFunc)tSerializeSMCfgDnodeReq, &cfgReq); } +static int32_t translateRestoreDnode(STranslateContext* pCxt, SRestoreComponentNodeStmt* pStmt) { + SRestoreDnodeReq restoreReq = {0}; + restoreReq.dnodeId = pStmt->dnodeId; + switch (nodeType((SNode*)pStmt)) { + case QUERY_NODE_RESTORE_DNODE_STMT: + restoreReq.restoreType = RESTORE_TYPE__ALL; + break; + case QUERY_NODE_RESTORE_QNODE_STMT: + restoreReq.restoreType = RESTORE_TYPE__QNODE; + break; + case QUERY_NODE_RESTORE_MNODE_STMT: + restoreReq.restoreType = RESTORE_TYPE__MNODE; + break; + case QUERY_NODE_RESTORE_VNODE_STMT: + restoreReq.restoreType = RESTORE_TYPE__VNODE; + break; + default: + return -1; + } + return buildCmdMsg(pCxt, TDMT_MND_RESTORE_DNODE, (FSerializeFunc)tSerializeSRestoreDnodeReq, &restoreReq); +} + + static int32_t getSmaIndexDstVgId(STranslateContext* pCxt, const char* pDbName, const char* pTableName, int32_t* pVgId) { SVgroupInfo vg = {0}; @@ -7069,6 +7115,12 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { case QUERY_NODE_SHOW_CREATE_STABLE_STMT: code = translateShowCreateTable(pCxt, (SShowCreateTableStmt*)pNode); break; + case QUERY_NODE_RESTORE_DNODE_STMT: + case QUERY_NODE_RESTORE_QNODE_STMT: + case QUERY_NODE_RESTORE_MNODE_STMT: + case QUERY_NODE_RESTORE_VNODE_STMT: + code = translateRestoreDnode(pCxt, (SRestoreComponentNodeStmt*)pNode); + break; default: break; } @@ -8359,6 +8411,11 @@ static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL); } + if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) || + (TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); + } + if (pTableMeta->tableInfo.rowSize + pReq->colModBytes - pSchema->bytes > TSDB_MAX_BYTES_PER_ROW) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW); } diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index c46dd65804..bb0b040035 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -25,6 +25,7 @@ #include #include /************ Begin %include sections from the grammar ************************/ +#line 11 "sql.y" #include #include @@ -41,6 +42,7 @@ #include "parAst.h" #define YYSTACKDEPTH 0 +#line 46 "sql.c" /**************** End of %include directives **********************************/ /* These constants specify the various numeric values for terminal symbols ** in a format understandable to "makeheaders". This section is blank unless @@ -104,27 +106,27 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 480 +#define YYNOCODE 482 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SToken typedef union { int yyinit; ParseTOKENTYPE yy0; - STokenPair yy57; - EFillMode yy294; - EOperatorType yy380; - ENullOrder yy457; - int8_t yy503; - EOrder yy578; - int32_t yy580; - SAlterOption yy605; - SNodeList* yy664; - int64_t yy669; - SDataType yy784; - EJoinType yy852; - bool yy857; - SNode* yy872; - SToken yy929; + SNodeList* yy72; + SNode* yy164; + EJoinType yy196; + bool yy441; + EFillMode yy446; + SToken yy497; + ENullOrder yy517; + EOrder yy550; + int32_t yy560; + int8_t yy563; + int64_t yy693; + SDataType yy700; + SAlterOption yy761; + EOperatorType yy796; + STokenPair yy953; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -140,17 +142,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 772 -#define YYNRULE 587 -#define YYNTOKEN 333 -#define YY_MAX_SHIFT 771 -#define YY_MIN_SHIFTREDUCE 1147 -#define YY_MAX_SHIFTREDUCE 1733 -#define YY_ERROR_ACTION 1734 -#define YY_ACCEPT_ACTION 1735 -#define YY_NO_ACTION 1736 -#define YY_MIN_REDUCE 1737 -#define YY_MAX_REDUCE 2323 +#define YYNSTATE 787 +#define YYNRULE 591 +#define YYNRULE_WITH_ACTION 591 +#define YYNTOKEN 335 +#define YY_MAX_SHIFT 786 +#define YY_MIN_SHIFTREDUCE 1162 +#define YY_MAX_SHIFTREDUCE 1752 +#define YY_ERROR_ACTION 1753 +#define YY_ACCEPT_ACTION 1754 +#define YY_NO_ACTION 1755 +#define YY_MIN_REDUCE 1756 +#define YY_MAX_REDUCE 2346 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -217,816 +220,842 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (3028) +#define YY_ACTTAB_COUNT (2980) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 2135, 2025, 511, 2004, 403, 512, 1773, 1952, 1954, 1896, - /* 10 */ 682, 2025, 48, 46, 1661, 1738, 2023, 652, 34, 168, - /* 20 */ 398, 1749, 1510, 391, 41, 40, 2022, 652, 47, 45, - /* 30 */ 44, 43, 42, 1591, 1806, 1508, 123, 2153, 1535, 122, - /* 40 */ 121, 120, 119, 118, 117, 116, 115, 114, 199, 2103, - /* 50 */ 392, 681, 1202, 1202, 1201, 1201, 41, 40, 165, 1586, - /* 60 */ 47, 45, 44, 43, 42, 19, 1909, 233, 1538, 1735, - /* 70 */ 528, 123, 1516, 2238, 122, 121, 120, 119, 118, 117, - /* 80 */ 116, 115, 114, 2134, 1203, 1203, 2170, 665, 1907, 169, - /* 90 */ 2136, 685, 2138, 2139, 680, 66, 675, 768, 664, 2235, - /* 100 */ 15, 745, 744, 743, 742, 410, 191, 741, 740, 144, - /* 110 */ 735, 734, 733, 732, 731, 730, 729, 157, 725, 724, - /* 120 */ 723, 409, 408, 720, 719, 718, 175, 174, 203, 604, - /* 130 */ 2260, 519, 1331, 182, 512, 1773, 1593, 1594, 665, 1907, - /* 140 */ 413, 1536, 444, 62, 412, 1946, 443, 1322, 707, 706, - /* 150 */ 705, 1326, 704, 1328, 1329, 703, 700, 133, 1337, 697, - /* 160 */ 1339, 1340, 694, 691, 549, 1535, 1566, 1576, 84, 664, - /* 170 */ 1959, 83, 1592, 1595, 650, 41, 40, 363, 51, 47, - /* 180 */ 45, 44, 43, 42, 101, 1957, 1511, 603, 1509, 603, - /* 190 */ 2294, 62, 2294, 294, 295, 41, 40, 623, 293, 47, - /* 200 */ 45, 44, 43, 42, 1286, 2300, 186, 2300, 186, 1900, - /* 210 */ 2295, 629, 2295, 629, 640, 140, 262, 1285, 1514, 1515, - /* 220 */ 664, 1565, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, - /* 230 */ 677, 673, 1584, 1585, 1587, 1588, 1589, 1590, 2, 48, - /* 240 */ 46, 1989, 665, 1907, 348, 1622, 1533, 398, 628, 1510, - /* 250 */ 450, 2294, 357, 481, 665, 1907, 495, 1365, 1366, 494, - /* 260 */ 1591, 133, 1508, 717, 2135, 234, 627, 186, 554, 2113, - /* 270 */ 622, 2295, 629, 57, 679, 464, 516, 496, 1737, 497, - /* 280 */ 466, 172, 513, 1898, 38, 303, 1586, 545, 541, 537, - /* 290 */ 533, 231, 19, 2117, 345, 1534, 1620, 2153, 189, 1516, - /* 300 */ 51, 2153, 132, 131, 130, 129, 128, 127, 126, 125, - /* 310 */ 124, 1420, 1421, 2103, 432, 681, 282, 2231, 639, 590, - /* 320 */ 134, 638, 35, 2294, 768, 366, 1180, 15, 52, 1188, - /* 330 */ 2119, 88, 1627, 189, 229, 1534, 1510, 454, 627, 186, - /* 340 */ 675, 434, 430, 2295, 629, 1730, 189, 2134, 1537, 1508, - /* 350 */ 2170, 621, 1621, 339, 2136, 685, 2138, 2139, 680, 678, - /* 360 */ 675, 666, 2188, 1593, 1594, 1182, 492, 1185, 1186, 486, - /* 370 */ 485, 484, 483, 480, 479, 478, 477, 476, 472, 471, - /* 380 */ 470, 469, 347, 461, 460, 459, 1516, 456, 455, 364, - /* 390 */ 44, 43, 42, 1566, 1576, 1760, 468, 2299, 166, 1592, - /* 400 */ 1595, 228, 222, 323, 628, 467, 227, 2294, 524, 640, - /* 410 */ 140, 768, 249, 1511, 1537, 1509, 248, 321, 73, 563, - /* 420 */ 562, 72, 627, 186, 1953, 1954, 220, 2295, 629, 37, - /* 430 */ 396, 1615, 1616, 1617, 1618, 1619, 1623, 1624, 1625, 1626, - /* 440 */ 214, 507, 505, 502, 2103, 1514, 1515, 1729, 1565, 1568, - /* 450 */ 1569, 1570, 1571, 1572, 1573, 1574, 1575, 677, 673, 1584, - /* 460 */ 1585, 1587, 1588, 1589, 1590, 2, 12, 48, 46, 47, - /* 470 */ 45, 44, 43, 42, 1535, 398, 90, 1510, 1290, 352, - /* 480 */ 62, 2238, 377, 189, 583, 567, 566, 565, 1591, 2135, - /* 490 */ 1508, 1289, 557, 137, 561, 1723, 284, 1689, 560, 682, - /* 500 */ 1511, 62, 1509, 559, 564, 373, 372, 2234, 179, 558, - /* 510 */ 642, 184, 2231, 2232, 1586, 138, 2236, 216, 109, 1759, - /* 520 */ 19, 514, 167, 1780, 665, 1907, 2153, 1516, 365, 2008, - /* 530 */ 1848, 218, 1514, 1515, 618, 514, 2124, 1780, 2103, 12, - /* 540 */ 681, 10, 2113, 448, 615, 614, 1687, 1688, 1690, 1691, - /* 550 */ 1692, 602, 768, 499, 62, 15, 2122, 401, 81, 80, - /* 560 */ 447, 2135, 284, 198, 2004, 165, 2117, 646, 2103, 12, - /* 570 */ 250, 682, 2134, 1909, 1275, 2170, 439, 437, 170, 2136, - /* 580 */ 685, 2138, 2139, 680, 2068, 675, 442, 346, 441, 2126, - /* 590 */ 428, 1593, 1594, 426, 422, 418, 415, 440, 2153, 142, - /* 600 */ 41, 40, 2194, 2119, 47, 45, 44, 43, 42, 201, - /* 610 */ 2103, 1277, 681, 675, 603, 665, 1907, 2294, 440, 651, - /* 620 */ 1516, 1566, 1576, 624, 619, 612, 1758, 1592, 1595, 630, - /* 630 */ 2315, 251, 2300, 186, 449, 189, 30, 2295, 629, 1481, - /* 640 */ 1482, 1511, 1884, 1509, 2134, 1809, 581, 2170, 665, 1907, - /* 650 */ 110, 2136, 685, 2138, 2139, 680, 189, 675, 2096, 579, - /* 660 */ 143, 577, 150, 2194, 2223, 739, 737, 458, 394, 2219, - /* 670 */ 526, 55, 2018, 1514, 1515, 2103, 1565, 1568, 1569, 1570, - /* 680 */ 1571, 1572, 1573, 1574, 1575, 677, 673, 1584, 1585, 1587, - /* 690 */ 1588, 1589, 1590, 2, 48, 46, 1596, 665, 1907, 651, - /* 700 */ 2135, 1232, 398, 2299, 1510, 603, 2294, 1757, 2294, 189, - /* 710 */ 643, 1756, 567, 566, 565, 1591, 644, 1508, 1755, 557, - /* 720 */ 137, 561, 2298, 2300, 186, 560, 2295, 2297, 2295, 629, - /* 730 */ 559, 564, 373, 372, 665, 1907, 558, 2153, 1233, 41, - /* 740 */ 40, 1586, 1665, 47, 45, 44, 43, 42, 1535, 2103, - /* 750 */ 649, 681, 2018, 473, 1516, 667, 2103, 2195, 41, 40, - /* 760 */ 2103, 632, 47, 45, 44, 43, 42, 2103, 665, 1907, - /* 770 */ 285, 715, 155, 154, 712, 711, 710, 152, 1601, 768, - /* 780 */ 665, 1907, 49, 2134, 1535, 179, 2170, 474, 2135, 110, - /* 790 */ 2136, 685, 2138, 2139, 680, 572, 675, 708, 682, 527, - /* 800 */ 1782, 183, 1959, 2223, 407, 406, 2009, 394, 2219, 378, - /* 810 */ 582, 62, 2299, 93, 1538, 2294, 2238, 1957, 1593, 1594, - /* 820 */ 188, 1882, 665, 1907, 247, 2153, 709, 1517, 2249, 1950, - /* 830 */ 727, 2298, 1700, 640, 140, 2295, 2296, 2103, 1883, 681, - /* 840 */ 575, 1904, 2233, 87, 1892, 569, 1959, 87, 1566, 1576, - /* 850 */ 246, 1677, 36, 388, 1592, 1595, 665, 1907, 41, 40, - /* 860 */ 367, 1957, 47, 45, 44, 43, 42, 2086, 1511, 1902, - /* 870 */ 1509, 2134, 651, 1903, 2170, 252, 1538, 110, 2136, 685, - /* 880 */ 2138, 2139, 680, 1754, 675, 259, 640, 140, 2004, 2314, - /* 890 */ 70, 2223, 1753, 69, 1567, 394, 2219, 14, 13, 2097, - /* 900 */ 1514, 1515, 717, 1565, 1568, 1569, 1570, 1571, 1572, 1573, - /* 910 */ 1574, 1575, 677, 673, 1584, 1585, 1587, 1588, 1589, 1590, - /* 920 */ 2, 48, 46, 660, 2135, 2018, 665, 1907, 1959, 398, - /* 930 */ 1567, 1510, 2103, 205, 643, 185, 2231, 2232, 1752, 138, - /* 940 */ 2236, 2103, 1591, 1958, 1508, 599, 603, 2135, 2298, 2294, - /* 950 */ 715, 155, 154, 712, 711, 710, 152, 682, 669, 2257, - /* 960 */ 2195, 2153, 200, 401, 2300, 186, 189, 1658, 1586, 2295, - /* 970 */ 629, 162, 1751, 2103, 107, 681, 665, 1907, 379, 1909, - /* 980 */ 1520, 1516, 665, 1907, 2153, 9, 1957, 2103, 187, 2231, - /* 990 */ 2232, 141, 138, 2236, 633, 648, 2103, 1634, 681, 1899, - /* 1000 */ 1748, 298, 370, 404, 665, 1907, 768, 2134, 553, 49, - /* 1010 */ 2170, 165, 552, 110, 2136, 685, 2138, 2139, 680, 1909, - /* 1020 */ 675, 2103, 588, 662, 261, 183, 1894, 2223, 1747, 488, - /* 1030 */ 2134, 394, 2219, 2170, 1536, 1890, 110, 2136, 685, 2138, - /* 1040 */ 2139, 680, 2113, 675, 713, 1593, 1594, 1950, 2314, 2103, - /* 1050 */ 2223, 1746, 2250, 635, 394, 2219, 2121, 41, 40, 665, - /* 1060 */ 1907, 47, 45, 44, 43, 42, 2117, 1911, 371, 603, - /* 1070 */ 369, 368, 2294, 551, 2135, 1566, 1576, 2103, 663, 427, - /* 1080 */ 1745, 1592, 1595, 165, 682, 1535, 2270, 2300, 186, 207, - /* 1090 */ 206, 1910, 2295, 629, 553, 1511, 317, 1509, 552, 1936, - /* 1100 */ 2103, 41, 40, 2119, 395, 47, 45, 44, 43, 42, - /* 1110 */ 1744, 2153, 487, 675, 715, 155, 154, 712, 711, 710, - /* 1120 */ 152, 728, 256, 2103, 1869, 681, 676, 1514, 1515, 2103, - /* 1130 */ 1565, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 677, - /* 1140 */ 673, 1584, 1585, 1587, 1588, 1589, 1590, 2, 48, 46, - /* 1150 */ 1437, 1438, 714, 1185, 1186, 1950, 398, 2134, 1510, 2103, - /* 1160 */ 2170, 1743, 2135, 110, 2136, 685, 2138, 2139, 680, 1591, - /* 1170 */ 675, 1508, 682, 1959, 610, 2314, 1742, 2223, 665, 1907, - /* 1180 */ 393, 394, 2219, 1959, 153, 1741, 1436, 1439, 1957, 1740, - /* 1190 */ 402, 2135, 2243, 1654, 54, 1586, 3, 304, 1957, 2153, - /* 1200 */ 1654, 682, 451, 2288, 665, 1907, 1885, 146, 1516, 135, - /* 1210 */ 2103, 2103, 2089, 681, 585, 452, 584, 164, 74, 1657, - /* 1220 */ 631, 239, 555, 405, 237, 2103, 241, 556, 2153, 240, - /* 1230 */ 1849, 1567, 243, 768, 2103, 242, 15, 1796, 2103, 672, - /* 1240 */ 2103, 56, 681, 245, 1273, 2134, 244, 153, 2170, 1271, - /* 1250 */ 148, 110, 2136, 685, 2138, 2139, 680, 1789, 675, 568, - /* 1260 */ 1519, 420, 1783, 2314, 1787, 2223, 153, 82, 50, 394, - /* 1270 */ 2219, 50, 1593, 1594, 2134, 260, 266, 2170, 153, 570, - /* 1280 */ 110, 2136, 685, 2138, 2139, 680, 573, 675, 636, 1732, - /* 1290 */ 1733, 50, 2314, 1518, 2223, 291, 407, 406, 394, 2219, - /* 1300 */ 14, 13, 1566, 1576, 1476, 106, 1524, 1750, 1592, 1595, - /* 1310 */ 2263, 616, 763, 279, 1847, 103, 721, 1591, 91, 1517, - /* 1320 */ 71, 151, 1511, 1479, 1509, 1686, 153, 64, 1685, 50, - /* 1330 */ 232, 50, 689, 268, 151, 647, 153, 136, 1251, 151, - /* 1340 */ 1846, 273, 2154, 1586, 411, 2013, 1774, 1779, 1434, 2253, - /* 1350 */ 1947, 641, 296, 281, 1514, 1515, 1516, 1565, 1568, 1569, - /* 1360 */ 1570, 1571, 1572, 1573, 1574, 1575, 677, 673, 1584, 1585, - /* 1370 */ 1587, 1588, 1589, 1590, 2, 2135, 722, 657, 300, 278, - /* 1380 */ 1, 671, 5, 1316, 1628, 682, 1577, 2242, 316, 1343, - /* 1390 */ 419, 1347, 1612, 1354, 1352, 414, 156, 361, 1249, 1541, - /* 1400 */ 436, 435, 193, 194, 438, 196, 311, 1457, 204, 453, - /* 1410 */ 1538, 2014, 2153, 1522, 457, 490, 462, 1533, 475, 2006, - /* 1420 */ 482, 489, 491, 500, 2103, 501, 681, 498, 208, 209, - /* 1430 */ 503, 504, 211, 506, 508, 1539, 509, 4, 510, 517, - /* 1440 */ 520, 518, 1536, 219, 521, 221, 1521, 1540, 1542, 522, - /* 1450 */ 523, 525, 1205, 224, 548, 529, 226, 587, 2134, 85, - /* 1460 */ 2077, 2170, 86, 546, 110, 2136, 685, 2138, 2139, 680, - /* 1470 */ 1525, 675, 1520, 230, 2135, 112, 2314, 547, 2223, 351, - /* 1480 */ 2074, 589, 394, 2219, 682, 550, 149, 1897, 236, 593, - /* 1490 */ 2073, 1893, 238, 89, 158, 312, 159, 2135, 253, 1895, - /* 1500 */ 592, 257, 1528, 1530, 1891, 160, 161, 682, 1464, 594, - /* 1510 */ 617, 2153, 600, 2269, 2268, 673, 1584, 1585, 1587, 1588, - /* 1520 */ 1589, 1590, 255, 2103, 597, 681, 655, 607, 8, 2254, - /* 1530 */ 2264, 613, 2245, 383, 2153, 626, 620, 173, 274, 598, - /* 1540 */ 272, 608, 606, 264, 267, 277, 2103, 605, 681, 275, - /* 1550 */ 637, 276, 384, 139, 2293, 634, 1654, 2134, 280, 2317, - /* 1560 */ 2170, 1537, 645, 110, 2136, 685, 2138, 2139, 680, 2239, - /* 1570 */ 675, 286, 96, 387, 1543, 2198, 2019, 2223, 653, 313, - /* 1580 */ 2134, 394, 2219, 2170, 654, 2135, 110, 2136, 685, 2138, - /* 1590 */ 2139, 680, 314, 675, 658, 682, 2033, 591, 2196, 659, - /* 1600 */ 2223, 61, 315, 2032, 394, 2219, 98, 1908, 2204, 102, - /* 1610 */ 100, 2135, 687, 2031, 390, 771, 1951, 1870, 318, 307, - /* 1620 */ 764, 682, 2153, 2095, 342, 765, 53, 327, 2094, 310, - /* 1630 */ 320, 353, 767, 341, 2103, 322, 681, 354, 2093, 78, - /* 1640 */ 2090, 331, 416, 417, 1501, 178, 1502, 192, 2153, 421, - /* 1650 */ 2088, 761, 757, 753, 749, 308, 423, 424, 425, 2135, - /* 1660 */ 2103, 362, 681, 2087, 2085, 429, 2084, 431, 2134, 682, - /* 1670 */ 2083, 2170, 433, 1492, 110, 2136, 685, 2138, 2139, 680, - /* 1680 */ 2064, 675, 195, 2063, 197, 1460, 668, 79, 2223, 1459, - /* 1690 */ 2045, 2044, 394, 2219, 2134, 108, 2153, 2170, 301, 2043, - /* 1700 */ 111, 2136, 685, 2138, 2139, 680, 445, 675, 2103, 446, - /* 1710 */ 681, 2042, 2041, 1997, 2223, 1411, 1996, 1994, 2222, 2219, - /* 1720 */ 145, 1993, 2135, 1992, 1995, 1991, 1990, 1988, 1987, 1986, - /* 1730 */ 661, 202, 682, 463, 1985, 465, 1999, 1984, 1983, 1982, - /* 1740 */ 1981, 1980, 2134, 1979, 1978, 2170, 1977, 1976, 111, 2136, - /* 1750 */ 685, 2138, 2139, 680, 1975, 675, 1974, 1973, 1972, 2153, - /* 1760 */ 1971, 1970, 2223, 493, 147, 288, 670, 2219, 1969, 1968, - /* 1770 */ 287, 2103, 1967, 681, 1998, 1966, 1965, 1413, 1964, 1963, - /* 1780 */ 1962, 1961, 1960, 349, 1287, 1812, 1291, 1283, 1811, 210, - /* 1790 */ 254, 212, 1810, 350, 1808, 1769, 2123, 180, 76, 1768, - /* 1800 */ 1187, 213, 2062, 2052, 77, 683, 217, 2135, 2170, 215, - /* 1810 */ 2040, 111, 2136, 685, 2138, 2139, 680, 682, 675, 225, - /* 1820 */ 181, 2039, 223, 2017, 515, 2223, 530, 1803, 534, 356, - /* 1830 */ 2219, 1886, 1807, 1805, 1801, 532, 1225, 536, 531, 535, - /* 1840 */ 2135, 538, 1799, 540, 2153, 1786, 539, 542, 544, 543, - /* 1850 */ 682, 1785, 1765, 1888, 1359, 1887, 2103, 63, 681, 1358, - /* 1860 */ 1274, 736, 738, 1272, 1270, 1269, 1797, 1790, 1261, 1788, - /* 1870 */ 1268, 2135, 374, 1267, 1266, 1263, 375, 2153, 235, 1262, - /* 1880 */ 376, 682, 1260, 574, 1764, 1763, 1762, 571, 113, 2103, - /* 1890 */ 2134, 681, 576, 2170, 578, 580, 111, 2136, 685, 2138, - /* 1900 */ 2139, 680, 2135, 675, 2061, 1486, 1488, 1485, 2153, 1490, - /* 1910 */ 2223, 29, 682, 381, 67, 2220, 1466, 1468, 58, 2051, - /* 1920 */ 2103, 595, 681, 2134, 1470, 2038, 2170, 2036, 17, 169, - /* 1930 */ 2136, 685, 2138, 2139, 680, 2135, 675, 2299, 20, 2153, - /* 1940 */ 163, 6, 65, 31, 382, 682, 7, 21, 271, 22, - /* 1950 */ 1702, 2103, 596, 681, 2134, 380, 263, 2170, 609, 611, - /* 1960 */ 340, 2136, 685, 2138, 2139, 680, 265, 675, 270, 2124, - /* 1970 */ 2261, 258, 2153, 33, 23, 1684, 171, 269, 32, 92, - /* 1980 */ 601, 1676, 24, 1722, 2103, 2134, 681, 1717, 2170, 1723, - /* 1990 */ 1716, 340, 2136, 685, 2138, 2139, 680, 2135, 675, 385, - /* 2000 */ 1721, 1720, 386, 1651, 283, 176, 60, 682, 1650, 2037, - /* 2010 */ 2035, 2034, 2135, 2016, 94, 95, 289, 25, 2134, 290, - /* 2020 */ 292, 2170, 682, 297, 333, 2136, 685, 2138, 2139, 680, - /* 2030 */ 68, 675, 1682, 2135, 2153, 656, 2015, 97, 103, 302, - /* 2040 */ 99, 26, 1603, 679, 299, 1602, 2103, 13, 681, 2153, - /* 2050 */ 1526, 2173, 177, 11, 389, 1581, 674, 1558, 688, 190, - /* 2060 */ 1579, 2103, 400, 681, 1578, 692, 18, 625, 59, 1550, - /* 2070 */ 2153, 39, 16, 27, 28, 695, 1344, 690, 693, 1613, - /* 2080 */ 2134, 686, 2103, 2170, 681, 1341, 170, 2136, 685, 2138, - /* 2090 */ 2139, 680, 1338, 675, 696, 2134, 1332, 698, 2170, 2135, - /* 2100 */ 699, 340, 2136, 685, 2138, 2139, 680, 684, 675, 682, - /* 2110 */ 701, 1336, 1335, 305, 1353, 1330, 2134, 702, 1334, 2170, - /* 2120 */ 104, 1333, 339, 2136, 685, 2138, 2139, 680, 1349, 675, - /* 2130 */ 1223, 2189, 105, 75, 1255, 716, 2153, 1254, 2316, 1253, - /* 2140 */ 1252, 397, 726, 1250, 1248, 1247, 1246, 306, 2103, 1281, - /* 2150 */ 681, 1244, 1243, 1242, 1241, 1240, 1239, 1238, 1278, 1276, - /* 2160 */ 1235, 1234, 2135, 1231, 1230, 1229, 1228, 1804, 746, 748, - /* 2170 */ 1802, 750, 682, 754, 752, 1800, 747, 2135, 756, 1798, - /* 2180 */ 758, 760, 2134, 751, 1784, 2170, 755, 682, 340, 2136, - /* 2190 */ 685, 2138, 2139, 680, 762, 675, 759, 1177, 1761, 2153, - /* 2200 */ 309, 766, 770, 1512, 399, 319, 769, 1736, 1736, 1736, - /* 2210 */ 1736, 2103, 1736, 681, 2153, 1736, 1736, 1736, 1736, 1736, - /* 2220 */ 1736, 1736, 1736, 1736, 1736, 1736, 2103, 2135, 681, 1736, - /* 2230 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 682, 1736, 1736, - /* 2240 */ 1736, 1736, 1736, 1736, 1736, 2134, 1736, 2135, 2170, 1736, - /* 2250 */ 1736, 340, 2136, 685, 2138, 2139, 680, 682, 675, 1736, - /* 2260 */ 586, 1736, 1736, 2170, 2153, 1736, 335, 2136, 685, 2138, - /* 2270 */ 2139, 680, 1736, 675, 1736, 1736, 2103, 1736, 681, 1736, - /* 2280 */ 1736, 1736, 1736, 1736, 2153, 1736, 1736, 1736, 1736, 1736, - /* 2290 */ 1736, 1736, 1736, 1736, 1736, 1736, 2103, 2135, 681, 1736, - /* 2300 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 682, 1736, 1736, - /* 2310 */ 2134, 1736, 1736, 2170, 1736, 1736, 324, 2136, 685, 2138, - /* 2320 */ 2139, 680, 2135, 675, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2330 */ 2134, 1736, 682, 2170, 2153, 1736, 325, 2136, 685, 2138, - /* 2340 */ 2139, 680, 1736, 675, 1736, 1736, 2103, 1736, 681, 1736, - /* 2350 */ 1736, 1736, 1736, 1736, 1736, 2135, 1736, 1736, 1736, 2153, - /* 2360 */ 1736, 1736, 1736, 1736, 1736, 682, 1736, 1736, 1736, 1736, - /* 2370 */ 1736, 2103, 1736, 681, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2380 */ 2134, 1736, 1736, 2170, 1736, 2135, 326, 2136, 685, 2138, - /* 2390 */ 2139, 680, 2153, 675, 1736, 682, 1736, 1736, 1736, 1736, - /* 2400 */ 1736, 1736, 1736, 1736, 2103, 2134, 681, 1736, 2170, 1736, - /* 2410 */ 1736, 332, 2136, 685, 2138, 2139, 680, 1736, 675, 1736, - /* 2420 */ 1736, 2135, 2153, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2430 */ 1736, 682, 1736, 1736, 2103, 1736, 681, 1736, 2134, 1736, - /* 2440 */ 1736, 2170, 1736, 2135, 336, 2136, 685, 2138, 2139, 680, - /* 2450 */ 1736, 675, 1736, 682, 1736, 1736, 1736, 1736, 2153, 1736, - /* 2460 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2134, 1736, - /* 2470 */ 2103, 2170, 681, 1736, 328, 2136, 685, 2138, 2139, 680, - /* 2480 */ 2153, 675, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2490 */ 1736, 1736, 2103, 1736, 681, 1736, 1736, 1736, 1736, 1736, - /* 2500 */ 1736, 1736, 1736, 1736, 2134, 1736, 1736, 2170, 1736, 2135, - /* 2510 */ 337, 2136, 685, 2138, 2139, 680, 1736, 675, 1736, 682, - /* 2520 */ 1736, 1736, 1736, 1736, 1736, 1736, 2134, 1736, 2135, 2170, - /* 2530 */ 1736, 1736, 329, 2136, 685, 2138, 2139, 680, 682, 675, - /* 2540 */ 1736, 1736, 1736, 1736, 1736, 1736, 2153, 1736, 1736, 1736, - /* 2550 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2103, 1736, - /* 2560 */ 681, 1736, 1736, 1736, 1736, 2153, 1736, 1736, 1736, 1736, - /* 2570 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2103, 1736, 681, - /* 2580 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2590 */ 1736, 1736, 2134, 1736, 2135, 2170, 1736, 1736, 338, 2136, - /* 2600 */ 685, 2138, 2139, 680, 682, 675, 1736, 1736, 1736, 1736, - /* 2610 */ 1736, 2134, 1736, 2135, 2170, 1736, 1736, 330, 2136, 685, - /* 2620 */ 2138, 2139, 680, 682, 675, 1736, 1736, 1736, 1736, 1736, - /* 2630 */ 1736, 2153, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2640 */ 1736, 1736, 1736, 2103, 2135, 681, 1736, 1736, 1736, 1736, - /* 2650 */ 2153, 1736, 1736, 1736, 682, 1736, 1736, 1736, 1736, 1736, - /* 2660 */ 1736, 1736, 2103, 1736, 681, 1736, 1736, 1736, 1736, 1736, - /* 2670 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2134, 1736, 1736, - /* 2680 */ 2170, 2153, 1736, 343, 2136, 685, 2138, 2139, 680, 1736, - /* 2690 */ 675, 1736, 1736, 2103, 1736, 681, 2134, 1736, 1736, 2170, - /* 2700 */ 1736, 1736, 344, 2136, 685, 2138, 2139, 680, 2135, 675, - /* 2710 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 682, 1736, - /* 2720 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2134, 1736, 2135, - /* 2730 */ 2170, 1736, 1736, 2147, 2136, 685, 2138, 2139, 680, 682, - /* 2740 */ 675, 1736, 1736, 1736, 1736, 2153, 1736, 1736, 1736, 1736, - /* 2750 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2103, 2135, 681, - /* 2760 */ 1736, 1736, 1736, 1736, 1736, 1736, 2153, 1736, 682, 1736, - /* 2770 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 2103, 1736, - /* 2780 */ 681, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2790 */ 1736, 2134, 1736, 1736, 2170, 2153, 1736, 2146, 2136, 685, - /* 2800 */ 2138, 2139, 680, 1736, 675, 1736, 1736, 2103, 1736, 681, - /* 2810 */ 1736, 1736, 2134, 1736, 1736, 2170, 2135, 1736, 2145, 2136, - /* 2820 */ 685, 2138, 2139, 680, 1736, 675, 682, 1736, 1736, 1736, - /* 2830 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2840 */ 1736, 2134, 1736, 1736, 2170, 1736, 2135, 358, 2136, 685, - /* 2850 */ 2138, 2139, 680, 2153, 675, 1736, 682, 1736, 1736, 1736, - /* 2860 */ 1736, 1736, 1736, 1736, 1736, 2103, 2135, 681, 1736, 1736, - /* 2870 */ 1736, 1736, 1736, 1736, 1736, 1736, 682, 1736, 1736, 1736, - /* 2880 */ 1736, 1736, 1736, 2153, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2890 */ 1736, 1736, 1736, 1736, 1736, 2103, 1736, 681, 1736, 2134, - /* 2900 */ 1736, 1736, 2170, 2153, 1736, 359, 2136, 685, 2138, 2139, - /* 2910 */ 680, 1736, 675, 1736, 2135, 2103, 1736, 681, 1736, 1736, - /* 2920 */ 1736, 1736, 1736, 1736, 682, 1736, 1736, 1736, 1736, 2134, - /* 2930 */ 1736, 2135, 2170, 1736, 1736, 355, 2136, 685, 2138, 2139, - /* 2940 */ 680, 682, 675, 1736, 1736, 1736, 1736, 1736, 1736, 2134, - /* 2950 */ 1736, 2153, 2170, 1736, 1736, 360, 2136, 685, 2138, 2139, - /* 2960 */ 680, 1736, 675, 2103, 1736, 681, 1736, 1736, 2153, 1736, - /* 2970 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2980 */ 2103, 1736, 681, 1736, 1736, 1736, 1736, 1736, 1736, 1736, - /* 2990 */ 1736, 1736, 1736, 1736, 1736, 1736, 1736, 683, 1736, 1736, - /* 3000 */ 2170, 1736, 1736, 335, 2136, 685, 2138, 2139, 680, 1736, - /* 3010 */ 675, 1736, 1736, 1736, 2134, 1736, 1736, 2170, 1736, 1736, - /* 3020 */ 334, 2136, 685, 2138, 2139, 680, 1736, 675, + /* 0 */ 2158, 402, 680, 1930, 38, 303, 182, 2091, 643, 162, + /* 10 */ 694, 2317, 48, 46, 1680, 1757, 380, 1932, 1969, 216, + /* 20 */ 399, 133, 1529, 529, 1980, 1799, 642, 186, 564, 655, + /* 30 */ 140, 2318, 644, 1610, 1829, 1527, 123, 2176, 107, 122, + /* 40 */ 121, 120, 119, 118, 117, 116, 115, 114, 1555, 2126, + /* 50 */ 1907, 696, 41, 40, 251, 141, 47, 45, 44, 43, + /* 60 */ 42, 1605, 531, 1922, 1557, 41, 40, 19, 528, 47, + /* 70 */ 45, 44, 43, 42, 1535, 1905, 1554, 47, 45, 44, + /* 80 */ 43, 42, 142, 2157, 526, 2217, 2193, 527, 1792, 339, + /* 90 */ 2159, 700, 2161, 2162, 695, 693, 690, 681, 2211, 783, + /* 100 */ 167, 30, 15, 760, 759, 758, 757, 411, 1871, 756, + /* 110 */ 755, 144, 750, 749, 748, 747, 746, 745, 744, 157, + /* 120 */ 740, 739, 738, 410, 409, 735, 734, 733, 175, 174, + /* 130 */ 657, 184, 2254, 2255, 1350, 138, 2259, 123, 1612, 1613, + /* 140 */ 122, 121, 120, 119, 118, 117, 116, 115, 114, 1341, + /* 150 */ 722, 721, 720, 1345, 719, 1347, 1348, 718, 715, 679, + /* 160 */ 1356, 712, 1358, 1359, 709, 706, 1384, 1385, 1585, 1595, + /* 170 */ 680, 1930, 41, 40, 1611, 1614, 47, 45, 44, 43, + /* 180 */ 42, 730, 155, 154, 727, 726, 725, 152, 1530, 133, + /* 190 */ 1528, 62, 666, 408, 407, 568, 569, 41, 40, 567, + /* 200 */ 661, 47, 45, 44, 43, 42, 730, 155, 154, 727, + /* 210 */ 726, 725, 152, 665, 262, 534, 1536, 1554, 527, 1792, + /* 220 */ 1533, 1534, 543, 1584, 1587, 1588, 1589, 1590, 1591, 1592, + /* 230 */ 1593, 1594, 692, 688, 1603, 1604, 1606, 1607, 1608, 1609, + /* 240 */ 2, 48, 46, 541, 2158, 2041, 349, 618, 1552, 399, + /* 250 */ 2317, 1529, 14, 13, 658, 482, 358, 2048, 496, 638, + /* 260 */ 679, 495, 1610, 52, 1527, 2323, 186, 582, 581, 580, + /* 270 */ 2318, 644, 2046, 667, 572, 137, 576, 465, 2136, 497, + /* 280 */ 575, 2176, 234, 467, 1195, 574, 579, 374, 373, 1756, + /* 290 */ 1605, 573, 1921, 2126, 1982, 696, 19, 1982, 172, 1677, + /* 300 */ 1639, 379, 2140, 1535, 389, 560, 556, 552, 548, 1980, + /* 310 */ 231, 179, 1980, 132, 131, 130, 129, 128, 127, 126, + /* 320 */ 125, 124, 168, 1197, 1768, 1200, 1201, 2157, 783, 367, + /* 330 */ 2193, 15, 2032, 110, 2159, 700, 2161, 2162, 695, 2142, + /* 340 */ 690, 455, 51, 2261, 1749, 183, 189, 2246, 1982, 690, + /* 350 */ 88, 395, 2242, 229, 1653, 394, 1640, 404, 445, 732, + /* 360 */ 1975, 1977, 444, 1980, 188, 1439, 1440, 1612, 1613, 2258, + /* 370 */ 493, 1539, 2272, 487, 486, 485, 484, 481, 480, 479, + /* 380 */ 478, 477, 473, 472, 471, 470, 348, 462, 461, 460, + /* 390 */ 218, 457, 456, 365, 529, 679, 1799, 1585, 1595, 2012, + /* 400 */ 1555, 655, 140, 1611, 1614, 618, 41, 40, 2317, 2322, + /* 410 */ 47, 45, 44, 43, 42, 1982, 371, 1530, 189, 1528, + /* 420 */ 228, 222, 364, 2323, 186, 227, 1556, 539, 2318, 644, + /* 430 */ 1980, 1754, 2048, 37, 397, 1634, 1635, 1636, 1637, 1638, + /* 440 */ 1642, 1643, 1644, 1645, 392, 220, 1748, 2045, 667, 1533, + /* 450 */ 1534, 637, 1584, 1587, 1588, 1589, 1590, 1591, 1592, 1593, + /* 460 */ 1594, 692, 688, 1603, 1604, 1606, 1607, 1608, 1609, 2, + /* 470 */ 12, 48, 46, 87, 87, 393, 666, 51, 2176, 399, + /* 480 */ 451, 1529, 1779, 165, 372, 666, 370, 369, 2158, 566, + /* 490 */ 368, 1932, 1610, 643, 1527, 1708, 2317, 189, 697, 1925, + /* 500 */ 1926, 1719, 414, 185, 2254, 2255, 413, 138, 2259, 1742, + /* 510 */ 568, 642, 186, 2158, 567, 1982, 2318, 644, 1456, 1457, + /* 520 */ 1605, 680, 1930, 697, 345, 2176, 19, 664, 489, 2041, + /* 530 */ 1981, 2126, 636, 1535, 655, 140, 675, 2126, 2041, 696, + /* 540 */ 191, 633, 630, 629, 1706, 1707, 1709, 1710, 1711, 618, + /* 550 */ 2176, 1778, 2317, 1676, 1455, 1458, 469, 66, 783, 523, + /* 560 */ 101, 15, 2126, 1553, 696, 468, 521, 2323, 186, 517, + /* 570 */ 513, 2157, 2318, 644, 2193, 1832, 284, 169, 2159, 700, + /* 580 */ 2161, 2162, 695, 12, 690, 1923, 41, 40, 207, 206, + /* 590 */ 47, 45, 44, 43, 42, 596, 2157, 1612, 1613, 2193, + /* 600 */ 2126, 605, 110, 2159, 700, 2161, 2162, 695, 594, 690, + /* 610 */ 592, 488, 143, 1684, 150, 2217, 2246, 619, 2283, 1554, + /* 620 */ 395, 2242, 179, 1554, 294, 295, 1529, 1585, 1595, 293, + /* 630 */ 639, 634, 627, 1611, 1614, 2261, 187, 2254, 2255, 1527, + /* 640 */ 138, 2259, 366, 2031, 582, 581, 580, 1530, 165, 1528, + /* 650 */ 249, 572, 137, 576, 248, 62, 1933, 575, 1777, 723, + /* 660 */ 1620, 2257, 574, 579, 374, 373, 1554, 2158, 573, 730, + /* 670 */ 155, 154, 727, 726, 725, 152, 260, 658, 1535, 1533, + /* 680 */ 1534, 1696, 1584, 1587, 1588, 1589, 1590, 1591, 1592, 1593, + /* 690 */ 1594, 692, 688, 1603, 1604, 1606, 1607, 1608, 1609, 2, + /* 700 */ 48, 46, 1615, 783, 2176, 62, 1535, 2126, 399, 1294, + /* 710 */ 1529, 1218, 62, 1217, 90, 2158, 2126, 353, 696, 91, + /* 720 */ 378, 1610, 598, 1527, 34, 697, 233, 1801, 680, 1930, + /* 730 */ 41, 40, 680, 1930, 47, 45, 44, 43, 42, 9, + /* 740 */ 655, 140, 1776, 2261, 1219, 285, 742, 57, 1296, 1605, + /* 750 */ 2157, 449, 2176, 2193, 680, 1930, 110, 2159, 700, 2161, + /* 760 */ 2162, 695, 1535, 690, 2126, 2119, 696, 1586, 183, 2256, + /* 770 */ 2246, 36, 1775, 450, 395, 2242, 1538, 41, 40, 408, + /* 780 */ 407, 47, 45, 44, 43, 42, 62, 783, 93, 1543, + /* 790 */ 49, 2126, 1530, 1906, 1528, 2273, 153, 443, 2157, 442, + /* 800 */ 1610, 2193, 1536, 2158, 110, 2159, 700, 2161, 2162, 695, + /* 810 */ 189, 690, 618, 697, 1586, 2317, 2337, 570, 2246, 680, + /* 820 */ 1930, 2126, 395, 2242, 1533, 1534, 1612, 1613, 1605, 441, + /* 830 */ 2323, 186, 680, 1930, 1919, 2318, 644, 402, 459, 1292, + /* 840 */ 2176, 1535, 282, 2254, 654, 165, 134, 653, 12, 2317, + /* 850 */ 10, 474, 2126, 1932, 696, 56, 1585, 1595, 1774, 732, + /* 860 */ 189, 1773, 1611, 1614, 642, 186, 686, 189, 1982, 2318, + /* 870 */ 644, 680, 1930, 578, 577, 403, 1530, 2136, 1528, 2322, + /* 880 */ 1915, 2322, 2317, 1980, 2317, 1772, 2157, 680, 1930, 2193, + /* 890 */ 475, 2145, 170, 2159, 700, 2161, 2162, 695, 2321, 690, + /* 900 */ 2321, 2140, 2318, 2320, 2318, 2319, 542, 2126, 1533, 1534, + /* 910 */ 2126, 1584, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, + /* 920 */ 692, 688, 1603, 1604, 1606, 1607, 1608, 1609, 2, 48, + /* 930 */ 46, 1541, 680, 1930, 2126, 2158, 1771, 399, 2142, 1529, + /* 940 */ 1305, 189, 2321, 645, 2338, 697, 405, 2280, 690, 1917, + /* 950 */ 1610, 1927, 1527, 1304, 165, 1544, 1673, 1539, 1770, 41, + /* 960 */ 40, 1767, 1932, 47, 45, 44, 43, 42, 317, 41, + /* 970 */ 40, 1959, 2176, 47, 45, 44, 43, 42, 1605, 1554, + /* 980 */ 680, 1930, 1976, 1977, 2126, 2126, 696, 1547, 1549, 680, + /* 990 */ 1930, 1535, 680, 1930, 680, 1930, 1309, 2109, 2120, 252, + /* 1000 */ 688, 1603, 1604, 1606, 1607, 1608, 1609, 2126, 614, 1308, + /* 1010 */ 2126, 659, 2027, 663, 1556, 1913, 783, 498, 2157, 49, + /* 1020 */ 1218, 2193, 1217, 2158, 110, 2159, 700, 2161, 2162, 695, + /* 1030 */ 250, 690, 587, 697, 724, 2293, 2337, 1973, 2246, 680, + /* 1040 */ 1930, 728, 395, 2242, 1973, 618, 1641, 597, 2317, 1766, + /* 1050 */ 203, 680, 1930, 1219, 433, 1612, 1613, 199, 298, 1765, + /* 1060 */ 2176, 247, 1764, 2323, 186, 680, 1930, 1557, 2318, 644, + /* 1070 */ 677, 1763, 2126, 500, 696, 680, 1930, 590, 680, 1930, + /* 1080 */ 1557, 435, 431, 584, 678, 1585, 1595, 754, 752, 246, + /* 1090 */ 84, 1611, 1614, 83, 304, 1200, 1201, 406, 2126, 1500, + /* 1100 */ 1501, 44, 43, 42, 1203, 1530, 2157, 1528, 2126, 2193, + /* 1110 */ 1553, 2126, 110, 2159, 700, 2161, 2162, 695, 1762, 690, + /* 1120 */ 2126, 164, 603, 35, 2337, 1761, 2246, 1586, 1760, 70, + /* 1130 */ 395, 2242, 69, 1646, 1759, 2266, 1673, 1533, 1534, 2027, + /* 1140 */ 1584, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 692, + /* 1150 */ 688, 1603, 1604, 1606, 1607, 1608, 1609, 2, 48, 46, + /* 1160 */ 2027, 2158, 2136, 682, 284, 2218, 399, 2126, 1529, 618, + /* 1170 */ 2112, 697, 2317, 625, 2126, 743, 2144, 2126, 1892, 1610, + /* 1180 */ 684, 1527, 2218, 2126, 201, 74, 2140, 2323, 186, 452, + /* 1190 */ 617, 729, 2318, 644, 1973, 54, 1908, 3, 2176, 146, + /* 1200 */ 239, 135, 453, 237, 1816, 205, 241, 1605, 153, 240, + /* 1210 */ 2126, 428, 696, 571, 1808, 243, 646, 200, 242, 421, + /* 1220 */ 1535, 1806, 245, 2142, 396, 244, 583, 600, 153, 599, + /* 1230 */ 261, 50, 50, 690, 82, 1290, 585, 266, 153, 647, + /* 1240 */ 148, 1751, 1752, 588, 2157, 783, 50, 2193, 15, 687, + /* 1250 */ 110, 2159, 700, 2161, 2162, 695, 650, 690, 2147, 291, + /* 1260 */ 71, 1802, 2337, 1537, 2246, 106, 151, 1495, 395, 2242, + /* 1270 */ 153, 14, 13, 64, 50, 103, 50, 736, 737, 704, + /* 1280 */ 151, 153, 136, 151, 1612, 1613, 1934, 1498, 1251, 256, + /* 1290 */ 1705, 1704, 691, 259, 1872, 1769, 268, 662, 2286, 1270, + /* 1300 */ 1268, 279, 631, 166, 232, 1453, 273, 1870, 323, 1869, + /* 1310 */ 2177, 778, 55, 2149, 1585, 1595, 412, 2036, 296, 672, + /* 1320 */ 1611, 1614, 321, 73, 1793, 300, 72, 1252, 1798, 1335, + /* 1330 */ 2276, 1970, 1647, 1596, 1530, 316, 1528, 346, 1362, 1366, + /* 1340 */ 1373, 1371, 156, 656, 278, 281, 1, 214, 508, 506, + /* 1350 */ 503, 5, 415, 420, 362, 2158, 1560, 437, 436, 194, + /* 1360 */ 193, 196, 439, 1476, 204, 697, 1533, 1534, 311, 1584, + /* 1370 */ 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 692, 688, + /* 1380 */ 1603, 1604, 1606, 1607, 1608, 1609, 2, 62, 1557, 454, + /* 1390 */ 2037, 491, 2176, 458, 463, 1552, 476, 483, 2029, 490, + /* 1400 */ 492, 501, 1631, 502, 2126, 499, 696, 504, 209, 211, + /* 1410 */ 208, 505, 507, 509, 1558, 524, 535, 4, 1540, 532, + /* 1420 */ 525, 533, 219, 1555, 2158, 109, 536, 1559, 221, 537, + /* 1430 */ 1561, 538, 540, 224, 697, 544, 2311, 226, 2157, 85, + /* 1440 */ 86, 2193, 1221, 561, 110, 2159, 700, 2161, 2162, 695, + /* 1450 */ 230, 690, 563, 562, 352, 112, 2221, 2100, 2246, 602, + /* 1460 */ 604, 2176, 395, 2242, 565, 81, 80, 448, 1920, 89, + /* 1470 */ 198, 236, 1916, 2126, 648, 696, 149, 238, 312, 158, + /* 1480 */ 159, 1918, 1914, 440, 438, 160, 2158, 253, 161, 608, + /* 1490 */ 607, 257, 1483, 651, 347, 609, 697, 429, 2265, 615, + /* 1500 */ 427, 423, 419, 416, 441, 2097, 2096, 2157, 2277, 612, + /* 1510 */ 2193, 255, 2158, 110, 2159, 700, 2161, 2162, 695, 2287, + /* 1520 */ 690, 632, 697, 2176, 622, 2337, 2292, 2246, 670, 613, + /* 1530 */ 264, 395, 2242, 2291, 628, 2126, 384, 696, 267, 2268, + /* 1540 */ 8, 635, 189, 641, 623, 385, 621, 620, 277, 2176, + /* 1550 */ 2340, 649, 652, 139, 1673, 1556, 2262, 660, 388, 286, + /* 1560 */ 274, 2126, 1562, 696, 313, 2042, 96, 668, 669, 2157, + /* 1570 */ 2056, 314, 2193, 2055, 276, 110, 2159, 700, 2161, 2162, + /* 1580 */ 695, 673, 690, 275, 2054, 272, 2158, 2337, 173, 2246, + /* 1590 */ 391, 674, 61, 395, 2242, 2157, 697, 98, 2193, 2316, + /* 1600 */ 100, 110, 2159, 700, 2161, 2162, 695, 280, 690, 102, + /* 1610 */ 2227, 315, 702, 2219, 1974, 2246, 1893, 1931, 779, 395, + /* 1620 */ 2242, 318, 780, 2176, 782, 327, 53, 341, 307, 331, + /* 1630 */ 320, 2118, 322, 2117, 342, 2126, 2116, 696, 78, 2113, + /* 1640 */ 417, 418, 1520, 1521, 354, 355, 192, 2158, 2111, 422, + /* 1650 */ 424, 425, 426, 2110, 363, 2108, 430, 697, 434, 432, + /* 1660 */ 2106, 1511, 2087, 195, 2086, 197, 1479, 79, 1478, 2157, + /* 1670 */ 2107, 2068, 2193, 2158, 2067, 110, 2159, 700, 2161, 2162, + /* 1680 */ 695, 2066, 690, 697, 2176, 446, 447, 683, 2065, 2246, + /* 1690 */ 2064, 1430, 2020, 395, 2242, 2019, 2126, 2017, 696, 145, + /* 1700 */ 2016, 2015, 2018, 2014, 2013, 2011, 2010, 2009, 202, 2158, + /* 1710 */ 2176, 464, 2008, 466, 2022, 2007, 2006, 2005, 2004, 697, + /* 1720 */ 147, 1992, 2126, 2003, 696, 2002, 2001, 2000, 1999, 1998, + /* 1730 */ 2157, 1997, 1996, 2193, 1995, 1994, 111, 2159, 700, 2161, + /* 1740 */ 2162, 695, 1993, 690, 1991, 1990, 2176, 2021, 1989, 1988, + /* 1750 */ 2246, 1987, 1432, 1986, 2245, 2242, 2157, 1985, 2126, 2193, + /* 1760 */ 696, 494, 111, 2159, 700, 2161, 2162, 695, 1984, 690, + /* 1770 */ 1983, 1835, 1306, 2158, 1310, 1302, 2246, 1834, 1833, 1831, + /* 1780 */ 685, 2242, 225, 697, 350, 351, 1828, 511, 1827, 1820, + /* 1790 */ 510, 1810, 698, 514, 210, 2193, 518, 2158, 111, 2159, + /* 1800 */ 700, 2161, 2162, 695, 212, 690, 512, 697, 515, 519, + /* 1810 */ 2176, 516, 2246, 520, 1788, 213, 357, 2242, 215, 522, + /* 1820 */ 76, 1202, 2126, 1787, 696, 2085, 77, 2146, 2075, 180, + /* 1830 */ 2063, 2062, 2040, 217, 2176, 223, 1909, 181, 1830, 530, + /* 1840 */ 1826, 1244, 547, 545, 546, 1824, 2126, 549, 696, 550, + /* 1850 */ 551, 1822, 553, 554, 555, 1819, 2157, 557, 558, 2193, + /* 1860 */ 559, 2158, 111, 2159, 700, 2161, 2162, 695, 1805, 690, + /* 1870 */ 1804, 697, 1784, 1911, 63, 235, 2246, 1378, 1377, 1910, + /* 1880 */ 2157, 2243, 606, 2193, 1293, 1291, 169, 2159, 700, 2161, + /* 1890 */ 2162, 695, 751, 690, 1289, 1288, 1287, 1286, 2176, 1285, + /* 1900 */ 786, 1282, 753, 382, 1281, 1280, 1279, 1817, 375, 1809, + /* 1910 */ 2126, 376, 696, 1807, 310, 377, 586, 589, 1783, 2158, + /* 1920 */ 591, 1782, 593, 1781, 595, 113, 1505, 2284, 29, 697, + /* 1930 */ 178, 1507, 1504, 2084, 58, 2158, 1509, 776, 772, 768, + /* 1940 */ 764, 67, 308, 1485, 2157, 697, 1487, 2193, 2074, 610, + /* 1950 */ 340, 2159, 700, 2161, 2162, 695, 2176, 690, 2061, 2059, + /* 1960 */ 1489, 383, 6, 2322, 611, 31, 163, 624, 2126, 258, + /* 1970 */ 696, 381, 2176, 20, 17, 616, 7, 1721, 263, 21, + /* 1980 */ 22, 265, 108, 1703, 2126, 301, 696, 1695, 626, 271, + /* 1990 */ 171, 270, 65, 2147, 269, 33, 2158, 32, 24, 1736, + /* 2000 */ 92, 1735, 2157, 1741, 1742, 2193, 697, 23, 340, 2159, + /* 2010 */ 700, 2161, 2162, 695, 386, 690, 1740, 676, 2157, 1739, + /* 2020 */ 387, 2193, 2158, 18, 333, 2159, 700, 2161, 2162, 695, + /* 2030 */ 283, 690, 697, 2176, 1670, 1669, 60, 176, 59, 2060, + /* 2040 */ 2058, 2057, 2039, 94, 95, 2126, 289, 696, 671, 2038, + /* 2050 */ 97, 25, 288, 290, 302, 1701, 103, 287, 2158, 2176, + /* 2060 */ 26, 11, 177, 292, 390, 297, 13, 640, 694, 68, + /* 2070 */ 299, 2126, 99, 696, 1622, 1621, 1545, 254, 2196, 2157, + /* 2080 */ 1600, 1598, 2193, 1597, 689, 170, 2159, 700, 2161, 2162, + /* 2090 */ 695, 190, 690, 39, 2158, 2176, 16, 27, 1577, 1569, + /* 2100 */ 28, 701, 703, 1363, 697, 2157, 401, 2126, 2193, 696, + /* 2110 */ 705, 340, 2159, 700, 2161, 2162, 695, 1360, 690, 707, + /* 2120 */ 2158, 708, 710, 1632, 1357, 711, 699, 1351, 713, 714, + /* 2130 */ 697, 2176, 1349, 716, 717, 104, 398, 2339, 305, 105, + /* 2140 */ 1372, 2157, 1355, 2126, 2193, 696, 1354, 339, 2159, 700, + /* 2150 */ 2161, 2162, 695, 75, 690, 1353, 2212, 2176, 1352, 1368, + /* 2160 */ 1242, 1274, 400, 731, 1273, 1272, 1271, 1269, 1267, 2126, + /* 2170 */ 1266, 696, 306, 1300, 1265, 741, 1263, 2157, 1262, 1261, + /* 2180 */ 2193, 1260, 1259, 340, 2159, 700, 2161, 2162, 695, 1258, + /* 2190 */ 690, 1257, 1297, 1295, 1248, 2158, 1254, 1253, 1250, 1249, + /* 2200 */ 1247, 1825, 761, 2157, 762, 697, 2193, 763, 1823, 340, + /* 2210 */ 2159, 700, 2161, 2162, 695, 2158, 690, 765, 766, 767, + /* 2220 */ 1821, 1818, 769, 770, 771, 697, 773, 774, 775, 1803, + /* 2230 */ 777, 1192, 2176, 1780, 309, 781, 1755, 1531, 319, 784, + /* 2240 */ 1755, 1755, 785, 1755, 2126, 1755, 696, 1755, 1755, 1755, + /* 2250 */ 1755, 1755, 2176, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2260 */ 1755, 1755, 1755, 1755, 2126, 1755, 696, 1755, 1755, 1755, + /* 2270 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 601, 1755, + /* 2280 */ 1755, 2193, 1755, 2158, 335, 2159, 700, 2161, 2162, 695, + /* 2290 */ 1755, 690, 1755, 697, 1755, 1755, 1755, 1755, 2157, 1755, + /* 2300 */ 2158, 2193, 1755, 1755, 324, 2159, 700, 2161, 2162, 695, + /* 2310 */ 697, 690, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2320 */ 2176, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2330 */ 1755, 1755, 2126, 1755, 696, 1755, 1755, 2176, 1755, 1755, + /* 2340 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 2158, 2126, + /* 2350 */ 1755, 696, 1755, 1755, 1755, 1755, 1755, 1755, 697, 1755, + /* 2360 */ 1755, 1755, 1755, 1755, 1755, 1755, 2157, 1755, 2158, 2193, + /* 2370 */ 1755, 1755, 325, 2159, 700, 2161, 2162, 695, 697, 690, + /* 2380 */ 1755, 1755, 1755, 2157, 1755, 2176, 2193, 1755, 1755, 326, + /* 2390 */ 2159, 700, 2161, 2162, 695, 1755, 690, 2126, 2158, 696, + /* 2400 */ 1755, 1755, 1755, 1755, 1755, 2176, 1755, 1755, 697, 1755, + /* 2410 */ 1755, 1755, 1755, 1755, 1755, 1755, 2158, 2126, 1755, 696, + /* 2420 */ 1755, 1755, 1755, 1755, 1755, 1755, 697, 1755, 1755, 1755, + /* 2430 */ 1755, 2157, 1755, 1755, 2193, 2176, 1755, 332, 2159, 700, + /* 2440 */ 2161, 2162, 695, 1755, 690, 1755, 2158, 2126, 1755, 696, + /* 2450 */ 1755, 2157, 1755, 2176, 2193, 1755, 697, 336, 2159, 700, + /* 2460 */ 2161, 2162, 695, 1755, 690, 2126, 1755, 696, 1755, 1755, + /* 2470 */ 1755, 1755, 1755, 1755, 1755, 1755, 2158, 1755, 1755, 1755, + /* 2480 */ 1755, 2157, 1755, 2176, 2193, 1755, 697, 328, 2159, 700, + /* 2490 */ 2161, 2162, 695, 1755, 690, 2126, 1755, 696, 1755, 2157, + /* 2500 */ 1755, 1755, 2193, 1755, 1755, 337, 2159, 700, 2161, 2162, + /* 2510 */ 695, 1755, 690, 2176, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2520 */ 1755, 1755, 1755, 1755, 2158, 2126, 1755, 696, 1755, 2157, + /* 2530 */ 1755, 1755, 2193, 1755, 697, 329, 2159, 700, 2161, 2162, + /* 2540 */ 695, 1755, 690, 1755, 2158, 1755, 1755, 1755, 1755, 1755, + /* 2550 */ 1755, 1755, 1755, 1755, 697, 1755, 1755, 1755, 1755, 2157, + /* 2560 */ 1755, 2176, 2193, 1755, 1755, 338, 2159, 700, 2161, 2162, + /* 2570 */ 695, 1755, 690, 2126, 1755, 696, 1755, 1755, 1755, 1755, + /* 2580 */ 1755, 2176, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2590 */ 1755, 1755, 1755, 2126, 1755, 696, 1755, 1755, 1755, 1755, + /* 2600 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 2157, 1755, 1755, + /* 2610 */ 2193, 1755, 1755, 330, 2159, 700, 2161, 2162, 695, 1755, + /* 2620 */ 690, 1755, 2158, 1755, 1755, 1755, 1755, 2157, 1755, 1755, + /* 2630 */ 2193, 1755, 697, 343, 2159, 700, 2161, 2162, 695, 2158, + /* 2640 */ 690, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 697, + /* 2650 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 2176, + /* 2660 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2670 */ 1755, 2126, 1755, 696, 1755, 1755, 2176, 1755, 1755, 1755, + /* 2680 */ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 2158, 2126, 1755, + /* 2690 */ 696, 1755, 1755, 1755, 1755, 1755, 1755, 697, 1755, 1755, + /* 2700 */ 1755, 1755, 1755, 1755, 1755, 2157, 1755, 2158, 2193, 1755, + /* 2710 */ 1755, 344, 2159, 700, 2161, 2162, 695, 697, 690, 1755, + /* 2720 */ 1755, 1755, 2157, 1755, 2176, 2193, 1755, 1755, 2170, 2159, + /* 2730 */ 700, 2161, 2162, 695, 1755, 690, 2126, 2158, 696, 1755, + /* 2740 */ 1755, 1755, 1755, 1755, 2176, 1755, 1755, 697, 1755, 1755, + /* 2750 */ 1755, 1755, 1755, 1755, 1755, 2158, 2126, 1755, 696, 1755, + /* 2760 */ 1755, 1755, 1755, 1755, 1755, 697, 1755, 1755, 1755, 1755, + /* 2770 */ 2157, 1755, 1755, 2193, 2176, 1755, 2169, 2159, 700, 2161, + /* 2780 */ 2162, 695, 1755, 690, 1755, 2158, 2126, 1755, 696, 1755, + /* 2790 */ 2157, 1755, 2176, 2193, 1755, 697, 2168, 2159, 700, 2161, + /* 2800 */ 2162, 695, 1755, 690, 2126, 1755, 696, 1755, 1755, 1755, + /* 2810 */ 1755, 1755, 1755, 1755, 1755, 2158, 1755, 1755, 1755, 1755, + /* 2820 */ 2157, 1755, 2176, 2193, 1755, 697, 359, 2159, 700, 2161, + /* 2830 */ 2162, 695, 1755, 690, 2126, 1755, 696, 1755, 2157, 1755, + /* 2840 */ 1755, 2193, 1755, 1755, 360, 2159, 700, 2161, 2162, 695, + /* 2850 */ 1755, 690, 2176, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2860 */ 1755, 1755, 1755, 2158, 2126, 1755, 696, 1755, 2157, 1755, + /* 2870 */ 1755, 2193, 1755, 697, 356, 2159, 700, 2161, 2162, 695, + /* 2880 */ 1755, 690, 1755, 2158, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2890 */ 1755, 1755, 1755, 697, 1755, 1755, 1755, 1755, 2157, 1755, + /* 2900 */ 2176, 2193, 1755, 1755, 361, 2159, 700, 2161, 2162, 695, + /* 2910 */ 1755, 690, 2126, 1755, 696, 1755, 1755, 1755, 1755, 1755, + /* 2920 */ 2176, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755, + /* 2930 */ 1755, 1755, 2126, 1755, 696, 1755, 1755, 1755, 1755, 1755, + /* 2940 */ 1755, 1755, 1755, 1755, 1755, 1755, 698, 1755, 1755, 2193, + /* 2950 */ 1755, 1755, 335, 2159, 700, 2161, 2162, 695, 1755, 690, + /* 2960 */ 1755, 1755, 1755, 1755, 1755, 1755, 2157, 1755, 1755, 2193, + /* 2970 */ 1755, 1755, 334, 2159, 700, 2161, 2162, 695, 1755, 690, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 336, 387, 340, 346, 383, 343, 344, 386, 387, 374, - /* 10 */ 346, 387, 12, 13, 14, 0, 402, 403, 2, 335, - /* 20 */ 20, 337, 22, 399, 8, 9, 402, 403, 12, 13, - /* 30 */ 14, 15, 16, 33, 0, 35, 21, 373, 20, 24, - /* 40 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 385, - /* 50 */ 365, 387, 20, 20, 22, 22, 8, 9, 373, 59, - /* 60 */ 12, 13, 14, 15, 16, 65, 381, 35, 20, 333, - /* 70 */ 64, 21, 72, 424, 24, 25, 26, 27, 28, 29, - /* 80 */ 30, 31, 32, 419, 52, 52, 422, 345, 346, 425, - /* 90 */ 426, 427, 428, 429, 430, 4, 432, 97, 20, 450, - /* 100 */ 100, 67, 68, 69, 70, 71, 364, 73, 74, 75, + /* 0 */ 338, 367, 347, 348, 442, 443, 374, 371, 453, 375, + /* 10 */ 348, 456, 12, 13, 14, 0, 382, 383, 386, 343, + /* 20 */ 20, 366, 22, 347, 390, 349, 471, 472, 373, 347, + /* 30 */ 348, 476, 477, 33, 0, 35, 21, 375, 353, 24, + /* 40 */ 25, 26, 27, 28, 29, 30, 31, 32, 20, 387, + /* 50 */ 0, 389, 8, 9, 418, 370, 12, 13, 14, 15, + /* 60 */ 16, 61, 14, 378, 20, 8, 9, 67, 20, 12, + /* 70 */ 13, 14, 15, 16, 74, 0, 20, 12, 13, 14, + /* 80 */ 15, 16, 437, 421, 342, 440, 424, 345, 346, 427, + /* 90 */ 428, 429, 430, 431, 432, 433, 434, 435, 436, 99, + /* 100 */ 356, 44, 102, 69, 70, 71, 72, 73, 364, 75, /* 110 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - /* 120 */ 86, 87, 88, 89, 90, 91, 92, 93, 59, 465, - /* 130 */ 466, 340, 97, 372, 343, 344, 136, 137, 345, 346, - /* 140 */ 404, 20, 404, 100, 408, 384, 408, 112, 113, 114, - /* 150 */ 115, 116, 117, 118, 119, 120, 121, 364, 123, 124, - /* 160 */ 125, 126, 127, 128, 371, 20, 166, 167, 99, 20, - /* 170 */ 373, 102, 172, 173, 20, 8, 9, 380, 100, 12, - /* 180 */ 13, 14, 15, 16, 351, 388, 186, 451, 188, 451, - /* 190 */ 454, 100, 454, 130, 131, 8, 9, 20, 135, 12, - /* 200 */ 13, 14, 15, 16, 22, 469, 470, 469, 470, 376, - /* 210 */ 474, 475, 474, 475, 345, 346, 168, 35, 218, 219, - /* 220 */ 20, 221, 222, 223, 224, 225, 226, 227, 228, 229, - /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 12, - /* 240 */ 13, 0, 345, 346, 18, 165, 20, 20, 451, 22, - /* 250 */ 345, 454, 65, 27, 345, 346, 30, 136, 137, 33, - /* 260 */ 33, 364, 35, 64, 336, 33, 469, 470, 371, 361, - /* 270 */ 346, 474, 475, 364, 346, 49, 14, 51, 0, 97, - /* 280 */ 54, 49, 20, 375, 440, 441, 59, 55, 56, 57, - /* 290 */ 58, 59, 65, 385, 389, 20, 109, 373, 255, 72, - /* 300 */ 100, 373, 24, 25, 26, 27, 28, 29, 30, 31, - /* 310 */ 32, 166, 167, 385, 181, 387, 447, 448, 449, 111, - /* 320 */ 451, 452, 242, 454, 97, 99, 4, 100, 100, 14, - /* 330 */ 422, 99, 252, 255, 102, 20, 22, 111, 469, 470, - /* 340 */ 432, 208, 209, 474, 475, 178, 255, 419, 20, 35, - /* 350 */ 422, 427, 165, 425, 426, 427, 428, 429, 430, 431, - /* 360 */ 432, 433, 434, 136, 137, 43, 140, 45, 46, 143, - /* 370 */ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - /* 380 */ 154, 155, 156, 157, 158, 159, 72, 161, 162, 163, - /* 390 */ 14, 15, 16, 166, 167, 336, 155, 3, 18, 172, - /* 400 */ 173, 169, 170, 23, 451, 164, 174, 454, 176, 345, - /* 410 */ 346, 97, 131, 186, 20, 188, 135, 37, 38, 358, - /* 420 */ 359, 41, 469, 470, 386, 387, 194, 474, 475, 242, - /* 430 */ 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - /* 440 */ 60, 61, 62, 63, 385, 218, 219, 280, 221, 222, - /* 450 */ 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - /* 460 */ 233, 234, 235, 236, 237, 238, 239, 12, 13, 12, - /* 470 */ 13, 14, 15, 16, 20, 20, 195, 22, 22, 198, - /* 480 */ 100, 424, 201, 255, 203, 67, 68, 69, 33, 336, - /* 490 */ 35, 35, 74, 75, 76, 101, 168, 218, 80, 346, - /* 500 */ 186, 100, 188, 85, 86, 87, 88, 450, 373, 91, - /* 510 */ 446, 447, 448, 449, 59, 451, 452, 341, 138, 336, - /* 520 */ 65, 345, 354, 347, 345, 346, 373, 72, 393, 394, - /* 530 */ 362, 341, 218, 219, 171, 345, 47, 347, 385, 239, - /* 540 */ 387, 241, 361, 364, 265, 266, 267, 268, 269, 270, - /* 550 */ 271, 48, 97, 97, 100, 100, 375, 365, 178, 179, - /* 560 */ 180, 336, 168, 183, 346, 373, 385, 404, 385, 239, - /* 570 */ 130, 346, 419, 381, 35, 422, 196, 197, 425, 426, - /* 580 */ 427, 428, 429, 430, 369, 432, 185, 207, 187, 100, - /* 590 */ 210, 136, 137, 213, 214, 215, 216, 217, 373, 435, - /* 600 */ 8, 9, 438, 422, 12, 13, 14, 15, 16, 391, - /* 610 */ 385, 72, 387, 432, 451, 345, 346, 454, 217, 345, - /* 620 */ 72, 166, 167, 260, 261, 262, 336, 172, 173, 476, - /* 630 */ 477, 416, 469, 470, 364, 255, 44, 474, 475, 199, - /* 640 */ 200, 186, 0, 188, 419, 0, 21, 422, 345, 346, - /* 650 */ 425, 426, 427, 428, 429, 430, 255, 432, 404, 34, - /* 660 */ 435, 36, 437, 438, 439, 358, 359, 364, 443, 444, - /* 670 */ 396, 168, 398, 218, 219, 385, 221, 222, 223, 224, - /* 680 */ 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - /* 690 */ 235, 236, 237, 238, 12, 13, 14, 345, 346, 345, - /* 700 */ 336, 35, 20, 451, 22, 451, 454, 336, 454, 255, - /* 710 */ 346, 336, 67, 68, 69, 33, 364, 35, 336, 74, - /* 720 */ 75, 76, 470, 469, 470, 80, 474, 475, 474, 475, - /* 730 */ 85, 86, 87, 88, 345, 346, 91, 373, 72, 8, - /* 740 */ 9, 59, 14, 12, 13, 14, 15, 16, 20, 385, - /* 750 */ 396, 387, 398, 364, 72, 436, 385, 438, 8, 9, - /* 760 */ 385, 44, 12, 13, 14, 15, 16, 385, 345, 346, - /* 770 */ 59, 129, 130, 131, 132, 133, 134, 135, 14, 97, - /* 780 */ 345, 346, 100, 419, 20, 373, 422, 364, 336, 425, - /* 790 */ 426, 427, 428, 429, 430, 4, 432, 111, 346, 364, - /* 800 */ 348, 437, 373, 439, 12, 13, 394, 443, 444, 380, - /* 810 */ 19, 100, 451, 102, 20, 454, 424, 388, 136, 137, - /* 820 */ 456, 0, 345, 346, 33, 373, 382, 35, 464, 385, - /* 830 */ 72, 470, 101, 345, 346, 474, 475, 385, 0, 387, - /* 840 */ 49, 364, 450, 353, 374, 54, 373, 353, 166, 167, - /* 850 */ 59, 101, 2, 380, 172, 173, 345, 346, 8, 9, - /* 860 */ 370, 388, 12, 13, 14, 15, 16, 0, 186, 379, - /* 870 */ 188, 419, 345, 379, 422, 364, 20, 425, 426, 427, - /* 880 */ 428, 429, 430, 336, 432, 409, 345, 346, 346, 437, - /* 890 */ 99, 439, 336, 102, 166, 443, 444, 1, 2, 404, - /* 900 */ 218, 219, 64, 221, 222, 223, 224, 225, 226, 227, - /* 910 */ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - /* 920 */ 238, 12, 13, 396, 336, 398, 345, 346, 373, 20, - /* 930 */ 166, 22, 385, 391, 346, 447, 448, 449, 336, 451, - /* 940 */ 452, 385, 33, 388, 35, 364, 451, 336, 3, 454, - /* 950 */ 129, 130, 131, 132, 133, 134, 135, 346, 436, 348, - /* 960 */ 438, 373, 168, 365, 469, 470, 255, 4, 59, 474, - /* 970 */ 475, 373, 336, 385, 351, 387, 345, 346, 380, 381, - /* 980 */ 188, 72, 345, 346, 373, 39, 388, 385, 447, 448, - /* 990 */ 449, 368, 451, 452, 277, 364, 385, 101, 387, 376, - /* 1000 */ 336, 364, 37, 365, 345, 346, 97, 419, 129, 100, - /* 1010 */ 422, 373, 133, 425, 426, 427, 428, 429, 430, 381, - /* 1020 */ 432, 385, 404, 364, 168, 437, 374, 439, 336, 81, - /* 1030 */ 419, 443, 444, 422, 20, 374, 425, 426, 427, 428, - /* 1040 */ 429, 430, 361, 432, 382, 136, 137, 385, 437, 385, - /* 1050 */ 439, 336, 464, 44, 443, 444, 375, 8, 9, 345, - /* 1060 */ 346, 12, 13, 14, 15, 16, 385, 374, 103, 451, - /* 1070 */ 105, 106, 454, 108, 336, 166, 167, 385, 364, 212, - /* 1080 */ 336, 172, 173, 373, 346, 20, 348, 469, 470, 141, - /* 1090 */ 142, 381, 474, 475, 129, 186, 366, 188, 133, 369, - /* 1100 */ 385, 8, 9, 422, 423, 12, 13, 14, 15, 16, - /* 1110 */ 336, 373, 164, 432, 129, 130, 131, 132, 133, 134, - /* 1120 */ 135, 360, 374, 385, 363, 387, 374, 218, 219, 385, - /* 1130 */ 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - /* 1140 */ 231, 232, 233, 234, 235, 236, 237, 238, 12, 13, - /* 1150 */ 136, 137, 382, 45, 46, 385, 20, 419, 22, 385, - /* 1160 */ 422, 336, 336, 425, 426, 427, 428, 429, 430, 33, - /* 1170 */ 432, 35, 346, 373, 348, 437, 336, 439, 345, 346, - /* 1180 */ 380, 443, 444, 373, 44, 336, 172, 173, 388, 336, - /* 1190 */ 380, 336, 253, 254, 42, 59, 44, 364, 388, 373, - /* 1200 */ 254, 346, 22, 348, 345, 346, 0, 42, 72, 44, - /* 1210 */ 385, 385, 0, 387, 202, 35, 204, 168, 111, 256, - /* 1220 */ 275, 104, 13, 364, 107, 385, 104, 13, 373, 107, - /* 1230 */ 362, 166, 104, 97, 385, 107, 100, 0, 385, 65, - /* 1240 */ 385, 101, 387, 104, 35, 419, 107, 44, 422, 35, - /* 1250 */ 44, 425, 426, 427, 428, 429, 430, 0, 432, 22, - /* 1260 */ 35, 49, 0, 437, 0, 439, 44, 160, 44, 443, - /* 1270 */ 444, 44, 136, 137, 419, 59, 44, 422, 44, 22, - /* 1280 */ 425, 426, 427, 428, 429, 430, 22, 432, 279, 136, - /* 1290 */ 137, 44, 437, 35, 439, 44, 12, 13, 443, 444, - /* 1300 */ 1, 2, 166, 167, 101, 100, 22, 337, 172, 173, - /* 1310 */ 395, 467, 50, 478, 361, 110, 13, 33, 102, 35, - /* 1320 */ 44, 44, 186, 101, 188, 101, 44, 44, 101, 44, - /* 1330 */ 349, 44, 44, 101, 44, 101, 44, 44, 35, 44, - /* 1340 */ 361, 461, 373, 59, 349, 395, 344, 346, 101, 395, - /* 1350 */ 384, 453, 101, 471, 218, 219, 72, 221, 222, 223, - /* 1360 */ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - /* 1370 */ 234, 235, 236, 237, 238, 336, 13, 101, 101, 445, - /* 1380 */ 455, 97, 257, 101, 101, 346, 101, 348, 101, 101, - /* 1390 */ 49, 101, 218, 101, 101, 421, 101, 420, 35, 20, - /* 1400 */ 413, 201, 418, 353, 413, 353, 406, 184, 42, 392, - /* 1410 */ 20, 395, 373, 188, 392, 165, 390, 20, 345, 345, - /* 1420 */ 392, 390, 390, 98, 385, 357, 387, 96, 356, 345, - /* 1430 */ 95, 355, 345, 345, 345, 20, 338, 48, 342, 338, - /* 1440 */ 413, 342, 20, 353, 387, 353, 188, 20, 20, 347, - /* 1450 */ 405, 347, 53, 353, 338, 345, 353, 205, 419, 353, - /* 1460 */ 385, 422, 353, 350, 425, 426, 427, 428, 429, 430, - /* 1470 */ 186, 432, 188, 353, 336, 345, 437, 350, 439, 338, - /* 1480 */ 385, 417, 443, 444, 346, 373, 415, 373, 373, 192, - /* 1490 */ 385, 373, 373, 100, 373, 413, 373, 336, 351, 373, - /* 1500 */ 191, 351, 218, 219, 373, 373, 373, 346, 190, 412, - /* 1510 */ 264, 373, 345, 460, 460, 231, 232, 233, 234, 235, - /* 1520 */ 236, 237, 411, 385, 387, 387, 263, 385, 272, 395, - /* 1530 */ 395, 385, 463, 385, 373, 177, 385, 460, 459, 410, - /* 1540 */ 462, 274, 273, 400, 400, 421, 385, 258, 387, 458, - /* 1550 */ 278, 457, 281, 346, 473, 276, 254, 419, 472, 479, - /* 1560 */ 422, 20, 345, 425, 426, 427, 428, 429, 430, 424, - /* 1570 */ 432, 351, 351, 347, 20, 437, 398, 439, 385, 400, - /* 1580 */ 419, 443, 444, 422, 385, 336, 425, 426, 427, 428, - /* 1590 */ 429, 430, 400, 432, 170, 346, 385, 1, 437, 397, - /* 1600 */ 439, 100, 369, 385, 443, 444, 351, 346, 442, 100, - /* 1610 */ 351, 336, 377, 385, 385, 19, 385, 363, 345, 351, - /* 1620 */ 36, 346, 373, 0, 414, 339, 407, 367, 0, 33, - /* 1630 */ 352, 401, 338, 367, 385, 334, 387, 401, 0, 42, - /* 1640 */ 0, 367, 35, 211, 35, 49, 35, 35, 373, 211, - /* 1650 */ 0, 55, 56, 57, 58, 59, 35, 35, 211, 336, - /* 1660 */ 385, 211, 387, 0, 0, 35, 0, 22, 419, 346, - /* 1670 */ 0, 422, 35, 206, 425, 426, 427, 428, 429, 430, - /* 1680 */ 0, 432, 194, 0, 194, 188, 437, 195, 439, 186, - /* 1690 */ 0, 0, 443, 444, 419, 99, 373, 422, 102, 0, - /* 1700 */ 425, 426, 427, 428, 429, 430, 182, 432, 385, 181, - /* 1710 */ 387, 0, 0, 0, 439, 47, 0, 0, 443, 444, - /* 1720 */ 42, 0, 336, 0, 0, 0, 0, 0, 0, 0, - /* 1730 */ 134, 155, 346, 35, 0, 155, 0, 0, 0, 0, - /* 1740 */ 0, 0, 419, 0, 0, 422, 0, 0, 425, 426, - /* 1750 */ 427, 428, 429, 430, 0, 432, 0, 0, 0, 373, - /* 1760 */ 0, 0, 439, 139, 42, 169, 443, 444, 0, 0, - /* 1770 */ 174, 385, 0, 387, 0, 0, 0, 22, 0, 0, - /* 1780 */ 0, 0, 0, 48, 22, 0, 22, 35, 0, 59, - /* 1790 */ 194, 59, 0, 48, 0, 0, 47, 44, 39, 0, - /* 1800 */ 14, 59, 0, 0, 39, 419, 40, 336, 422, 42, - /* 1810 */ 0, 425, 426, 427, 428, 429, 430, 346, 432, 177, - /* 1820 */ 47, 0, 39, 0, 47, 439, 35, 0, 35, 443, - /* 1830 */ 444, 0, 0, 0, 0, 39, 66, 39, 49, 49, - /* 1840 */ 336, 35, 0, 39, 373, 0, 49, 35, 39, 49, - /* 1850 */ 346, 0, 0, 0, 35, 0, 385, 109, 387, 22, - /* 1860 */ 35, 44, 44, 35, 35, 35, 0, 0, 22, 0, - /* 1870 */ 35, 336, 22, 35, 35, 35, 22, 373, 107, 35, - /* 1880 */ 22, 346, 35, 35, 0, 0, 0, 51, 20, 385, - /* 1890 */ 419, 387, 35, 422, 35, 22, 425, 426, 427, 428, - /* 1900 */ 429, 430, 336, 432, 0, 35, 35, 35, 373, 101, - /* 1910 */ 439, 100, 346, 378, 100, 444, 35, 22, 168, 0, - /* 1920 */ 385, 22, 387, 419, 193, 0, 422, 0, 259, 425, - /* 1930 */ 426, 427, 428, 429, 430, 336, 432, 3, 44, 373, - /* 1940 */ 189, 48, 3, 100, 378, 346, 48, 44, 47, 44, - /* 1950 */ 101, 385, 168, 387, 419, 168, 100, 422, 98, 96, - /* 1960 */ 425, 426, 427, 428, 429, 430, 101, 432, 44, 47, - /* 1970 */ 466, 170, 373, 44, 259, 101, 100, 100, 100, 100, - /* 1980 */ 175, 101, 44, 101, 385, 419, 387, 35, 422, 101, - /* 1990 */ 35, 425, 426, 427, 428, 429, 430, 336, 432, 35, - /* 2000 */ 35, 35, 35, 101, 47, 47, 44, 346, 101, 0, - /* 2010 */ 0, 0, 336, 0, 100, 39, 47, 100, 419, 101, - /* 2020 */ 100, 422, 346, 100, 425, 426, 427, 428, 429, 430, - /* 2030 */ 100, 432, 101, 336, 373, 171, 0, 39, 110, 47, - /* 2040 */ 100, 44, 98, 346, 169, 98, 385, 2, 387, 373, - /* 2050 */ 22, 100, 47, 240, 378, 101, 100, 22, 35, 47, - /* 2060 */ 101, 385, 35, 387, 101, 35, 259, 468, 253, 101, - /* 2070 */ 373, 100, 100, 100, 100, 35, 101, 100, 100, 218, - /* 2080 */ 419, 111, 385, 422, 387, 101, 425, 426, 427, 428, - /* 2090 */ 429, 430, 101, 432, 100, 419, 101, 35, 422, 336, - /* 2100 */ 100, 425, 426, 427, 428, 429, 430, 220, 432, 346, - /* 2110 */ 35, 122, 122, 44, 35, 101, 419, 100, 122, 422, - /* 2120 */ 100, 122, 425, 426, 427, 428, 429, 430, 22, 432, - /* 2130 */ 66, 434, 100, 100, 35, 65, 373, 35, 477, 35, - /* 2140 */ 35, 378, 94, 35, 35, 35, 35, 44, 385, 72, - /* 2150 */ 387, 35, 35, 35, 22, 35, 35, 35, 72, 35, - /* 2160 */ 35, 35, 336, 35, 35, 22, 35, 0, 35, 39, - /* 2170 */ 0, 35, 346, 35, 39, 0, 49, 336, 39, 0, - /* 2180 */ 35, 39, 419, 49, 0, 422, 49, 346, 425, 426, - /* 2190 */ 427, 428, 429, 430, 35, 432, 49, 35, 0, 373, - /* 2200 */ 22, 21, 20, 22, 378, 22, 21, 480, 480, 480, - /* 2210 */ 480, 385, 480, 387, 373, 480, 480, 480, 480, 480, - /* 2220 */ 480, 480, 480, 480, 480, 480, 385, 336, 387, 480, - /* 2230 */ 480, 480, 480, 480, 480, 480, 480, 346, 480, 480, - /* 2240 */ 480, 480, 480, 480, 480, 419, 480, 336, 422, 480, - /* 2250 */ 480, 425, 426, 427, 428, 429, 430, 346, 432, 480, - /* 2260 */ 419, 480, 480, 422, 373, 480, 425, 426, 427, 428, - /* 2270 */ 429, 430, 480, 432, 480, 480, 385, 480, 387, 480, - /* 2280 */ 480, 480, 480, 480, 373, 480, 480, 480, 480, 480, - /* 2290 */ 480, 480, 480, 480, 480, 480, 385, 336, 387, 480, - /* 2300 */ 480, 480, 480, 480, 480, 480, 480, 346, 480, 480, - /* 2310 */ 419, 480, 480, 422, 480, 480, 425, 426, 427, 428, - /* 2320 */ 429, 430, 336, 432, 480, 480, 480, 480, 480, 480, - /* 2330 */ 419, 480, 346, 422, 373, 480, 425, 426, 427, 428, - /* 2340 */ 429, 430, 480, 432, 480, 480, 385, 480, 387, 480, - /* 2350 */ 480, 480, 480, 480, 480, 336, 480, 480, 480, 373, - /* 2360 */ 480, 480, 480, 480, 480, 346, 480, 480, 480, 480, - /* 2370 */ 480, 385, 480, 387, 480, 480, 480, 480, 480, 480, - /* 2380 */ 419, 480, 480, 422, 480, 336, 425, 426, 427, 428, - /* 2390 */ 429, 430, 373, 432, 480, 346, 480, 480, 480, 480, - /* 2400 */ 480, 480, 480, 480, 385, 419, 387, 480, 422, 480, - /* 2410 */ 480, 425, 426, 427, 428, 429, 430, 480, 432, 480, - /* 2420 */ 480, 336, 373, 480, 480, 480, 480, 480, 480, 480, - /* 2430 */ 480, 346, 480, 480, 385, 480, 387, 480, 419, 480, - /* 2440 */ 480, 422, 480, 336, 425, 426, 427, 428, 429, 430, - /* 2450 */ 480, 432, 480, 346, 480, 480, 480, 480, 373, 480, - /* 2460 */ 480, 480, 480, 480, 480, 480, 480, 480, 419, 480, - /* 2470 */ 385, 422, 387, 480, 425, 426, 427, 428, 429, 430, - /* 2480 */ 373, 432, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2490 */ 480, 480, 385, 480, 387, 480, 480, 480, 480, 480, - /* 2500 */ 480, 480, 480, 480, 419, 480, 480, 422, 480, 336, - /* 2510 */ 425, 426, 427, 428, 429, 430, 480, 432, 480, 346, - /* 2520 */ 480, 480, 480, 480, 480, 480, 419, 480, 336, 422, - /* 2530 */ 480, 480, 425, 426, 427, 428, 429, 430, 346, 432, - /* 2540 */ 480, 480, 480, 480, 480, 480, 373, 480, 480, 480, - /* 2550 */ 480, 480, 480, 480, 480, 480, 480, 480, 385, 480, - /* 2560 */ 387, 480, 480, 480, 480, 373, 480, 480, 480, 480, - /* 2570 */ 480, 480, 480, 480, 480, 480, 480, 385, 480, 387, - /* 2580 */ 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2590 */ 480, 480, 419, 480, 336, 422, 480, 480, 425, 426, - /* 2600 */ 427, 428, 429, 430, 346, 432, 480, 480, 480, 480, - /* 2610 */ 480, 419, 480, 336, 422, 480, 480, 425, 426, 427, - /* 2620 */ 428, 429, 430, 346, 432, 480, 480, 480, 480, 480, - /* 2630 */ 480, 373, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2640 */ 480, 480, 480, 385, 336, 387, 480, 480, 480, 480, - /* 2650 */ 373, 480, 480, 480, 346, 480, 480, 480, 480, 480, - /* 2660 */ 480, 480, 385, 480, 387, 480, 480, 480, 480, 480, - /* 2670 */ 480, 480, 480, 480, 480, 480, 480, 419, 480, 480, - /* 2680 */ 422, 373, 480, 425, 426, 427, 428, 429, 430, 480, - /* 2690 */ 432, 480, 480, 385, 480, 387, 419, 480, 480, 422, - /* 2700 */ 480, 480, 425, 426, 427, 428, 429, 430, 336, 432, - /* 2710 */ 480, 480, 480, 480, 480, 480, 480, 480, 346, 480, - /* 2720 */ 480, 480, 480, 480, 480, 480, 480, 419, 480, 336, - /* 2730 */ 422, 480, 480, 425, 426, 427, 428, 429, 430, 346, - /* 2740 */ 432, 480, 480, 480, 480, 373, 480, 480, 480, 480, - /* 2750 */ 480, 480, 480, 480, 480, 480, 480, 385, 336, 387, - /* 2760 */ 480, 480, 480, 480, 480, 480, 373, 480, 346, 480, - /* 2770 */ 480, 480, 480, 480, 480, 480, 480, 480, 385, 480, - /* 2780 */ 387, 480, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2790 */ 480, 419, 480, 480, 422, 373, 480, 425, 426, 427, - /* 2800 */ 428, 429, 430, 480, 432, 480, 480, 385, 480, 387, - /* 2810 */ 480, 480, 419, 480, 480, 422, 336, 480, 425, 426, - /* 2820 */ 427, 428, 429, 430, 480, 432, 346, 480, 480, 480, - /* 2830 */ 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2840 */ 480, 419, 480, 480, 422, 480, 336, 425, 426, 427, - /* 2850 */ 428, 429, 430, 373, 432, 480, 346, 480, 480, 480, - /* 2860 */ 480, 480, 480, 480, 480, 385, 336, 387, 480, 480, - /* 2870 */ 480, 480, 480, 480, 480, 480, 346, 480, 480, 480, - /* 2880 */ 480, 480, 480, 373, 480, 480, 480, 480, 480, 480, - /* 2890 */ 480, 480, 480, 480, 480, 385, 480, 387, 480, 419, - /* 2900 */ 480, 480, 422, 373, 480, 425, 426, 427, 428, 429, - /* 2910 */ 430, 480, 432, 480, 336, 385, 480, 387, 480, 480, - /* 2920 */ 480, 480, 480, 480, 346, 480, 480, 480, 480, 419, - /* 2930 */ 480, 336, 422, 480, 480, 425, 426, 427, 428, 429, - /* 2940 */ 430, 346, 432, 480, 480, 480, 480, 480, 480, 419, - /* 2950 */ 480, 373, 422, 480, 480, 425, 426, 427, 428, 429, - /* 2960 */ 430, 480, 432, 385, 480, 387, 480, 480, 373, 480, - /* 2970 */ 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - /* 2980 */ 385, 480, 387, 480, 480, 480, 480, 480, 480, 480, - /* 2990 */ 480, 480, 480, 480, 480, 480, 480, 419, 480, 480, - /* 3000 */ 422, 480, 480, 425, 426, 427, 428, 429, 430, 480, - /* 3010 */ 432, 480, 480, 480, 419, 480, 480, 422, 480, 480, - /* 3020 */ 425, 426, 427, 428, 429, 430, 480, 432, + /* 120 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* 130 */ 448, 449, 450, 451, 99, 453, 454, 21, 138, 139, + /* 140 */ 24, 25, 26, 27, 28, 29, 30, 31, 32, 114, + /* 150 */ 115, 116, 117, 118, 119, 120, 121, 122, 123, 20, + /* 160 */ 125, 126, 127, 128, 129, 130, 138, 139, 168, 169, + /* 170 */ 347, 348, 8, 9, 174, 175, 12, 13, 14, 15, + /* 180 */ 16, 131, 132, 133, 134, 135, 136, 137, 188, 366, + /* 190 */ 190, 102, 347, 12, 13, 131, 373, 8, 9, 135, + /* 200 */ 406, 12, 13, 14, 15, 16, 131, 132, 133, 134, + /* 210 */ 135, 136, 137, 20, 170, 342, 35, 20, 345, 346, + /* 220 */ 220, 221, 66, 223, 224, 225, 226, 227, 228, 229, + /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + /* 240 */ 240, 12, 13, 398, 338, 400, 18, 453, 20, 20, + /* 250 */ 456, 22, 1, 2, 348, 27, 67, 389, 30, 20, + /* 260 */ 20, 33, 33, 102, 35, 471, 472, 69, 70, 71, + /* 270 */ 476, 477, 404, 405, 76, 77, 78, 49, 363, 51, + /* 280 */ 82, 375, 33, 55, 4, 87, 88, 89, 90, 0, + /* 290 */ 61, 93, 377, 387, 375, 389, 67, 375, 49, 4, + /* 300 */ 111, 382, 387, 74, 382, 56, 57, 58, 59, 390, + /* 310 */ 61, 375, 390, 24, 25, 26, 27, 28, 29, 30, + /* 320 */ 31, 32, 337, 43, 339, 45, 46, 421, 99, 101, + /* 330 */ 424, 102, 396, 427, 428, 429, 430, 431, 432, 424, + /* 340 */ 434, 113, 102, 426, 180, 439, 257, 441, 375, 434, + /* 350 */ 101, 445, 446, 104, 103, 382, 167, 385, 406, 66, + /* 360 */ 388, 389, 410, 390, 458, 168, 169, 138, 139, 452, + /* 370 */ 142, 190, 466, 145, 146, 147, 148, 149, 150, 151, + /* 380 */ 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + /* 390 */ 343, 163, 164, 165, 347, 20, 349, 168, 169, 0, + /* 400 */ 20, 347, 348, 174, 175, 453, 8, 9, 456, 3, + /* 410 */ 12, 13, 14, 15, 16, 375, 37, 188, 257, 190, + /* 420 */ 171, 172, 382, 471, 472, 176, 20, 178, 476, 477, + /* 430 */ 390, 335, 389, 244, 245, 246, 247, 248, 249, 250, + /* 440 */ 251, 252, 253, 254, 401, 196, 282, 404, 405, 220, + /* 450 */ 221, 348, 223, 224, 225, 226, 227, 228, 229, 230, + /* 460 */ 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + /* 470 */ 241, 12, 13, 355, 355, 367, 347, 102, 375, 20, + /* 480 */ 347, 22, 338, 375, 105, 347, 107, 108, 338, 110, + /* 490 */ 372, 383, 33, 453, 35, 220, 456, 257, 348, 381, + /* 500 */ 381, 103, 406, 449, 450, 451, 410, 453, 454, 103, + /* 510 */ 131, 471, 472, 338, 135, 375, 476, 477, 138, 139, + /* 520 */ 61, 347, 348, 348, 391, 375, 67, 398, 83, 400, + /* 530 */ 390, 387, 429, 74, 347, 348, 398, 387, 400, 389, + /* 540 */ 366, 173, 267, 268, 269, 270, 271, 272, 273, 453, + /* 550 */ 375, 338, 456, 258, 174, 175, 157, 4, 99, 49, + /* 560 */ 353, 102, 387, 20, 389, 166, 56, 471, 472, 59, + /* 570 */ 60, 421, 476, 477, 424, 0, 170, 427, 428, 429, + /* 580 */ 430, 431, 432, 241, 434, 378, 8, 9, 143, 144, + /* 590 */ 12, 13, 14, 15, 16, 21, 421, 138, 139, 424, + /* 600 */ 387, 113, 427, 428, 429, 430, 431, 432, 34, 434, + /* 610 */ 36, 166, 437, 14, 439, 440, 441, 467, 468, 20, + /* 620 */ 445, 446, 375, 20, 132, 133, 22, 168, 169, 137, + /* 630 */ 262, 263, 264, 174, 175, 426, 449, 450, 451, 35, + /* 640 */ 453, 454, 395, 396, 69, 70, 71, 188, 375, 190, + /* 650 */ 133, 76, 77, 78, 137, 102, 383, 82, 338, 113, + /* 660 */ 14, 452, 87, 88, 89, 90, 20, 338, 93, 131, + /* 670 */ 132, 133, 134, 135, 136, 137, 61, 348, 74, 220, + /* 680 */ 221, 103, 223, 224, 225, 226, 227, 228, 229, 230, + /* 690 */ 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + /* 700 */ 12, 13, 14, 99, 375, 102, 74, 387, 20, 35, + /* 710 */ 22, 20, 102, 22, 197, 338, 387, 200, 389, 104, + /* 720 */ 203, 33, 205, 35, 2, 348, 35, 350, 347, 348, + /* 730 */ 8, 9, 347, 348, 12, 13, 14, 15, 16, 39, + /* 740 */ 347, 348, 338, 426, 53, 61, 74, 366, 74, 61, + /* 750 */ 421, 366, 375, 424, 347, 348, 427, 428, 429, 430, + /* 760 */ 431, 432, 74, 434, 387, 406, 389, 168, 439, 452, + /* 770 */ 441, 2, 338, 366, 445, 446, 35, 8, 9, 12, + /* 780 */ 13, 12, 13, 14, 15, 16, 102, 99, 104, 22, + /* 790 */ 102, 387, 188, 0, 190, 466, 44, 187, 421, 189, + /* 800 */ 33, 424, 35, 338, 427, 428, 429, 430, 431, 432, + /* 810 */ 257, 434, 453, 348, 168, 456, 439, 13, 441, 347, + /* 820 */ 348, 387, 445, 446, 220, 221, 138, 139, 61, 219, + /* 830 */ 471, 472, 347, 348, 376, 476, 477, 367, 366, 35, + /* 840 */ 375, 74, 449, 450, 451, 375, 453, 454, 241, 456, + /* 850 */ 243, 366, 387, 383, 389, 103, 168, 169, 338, 66, + /* 860 */ 257, 338, 174, 175, 471, 472, 99, 257, 375, 476, + /* 870 */ 477, 347, 348, 360, 361, 382, 188, 363, 190, 453, + /* 880 */ 376, 453, 456, 390, 456, 338, 421, 347, 348, 424, + /* 890 */ 366, 377, 427, 428, 429, 430, 431, 432, 472, 434, + /* 900 */ 472, 387, 476, 477, 476, 477, 366, 387, 220, 221, + /* 910 */ 387, 223, 224, 225, 226, 227, 228, 229, 230, 231, + /* 920 */ 232, 233, 234, 235, 236, 237, 238, 239, 240, 12, + /* 930 */ 13, 190, 347, 348, 387, 338, 338, 20, 424, 22, + /* 940 */ 22, 257, 3, 478, 479, 348, 367, 350, 434, 376, + /* 950 */ 33, 366, 35, 35, 375, 188, 256, 190, 338, 8, + /* 960 */ 9, 338, 383, 12, 13, 14, 15, 16, 368, 8, + /* 970 */ 9, 371, 375, 12, 13, 14, 15, 16, 61, 20, + /* 980 */ 347, 348, 388, 389, 387, 387, 389, 220, 221, 347, + /* 990 */ 348, 74, 347, 348, 347, 348, 22, 0, 406, 366, + /* 1000 */ 233, 234, 235, 236, 237, 238, 239, 387, 366, 35, + /* 1010 */ 387, 366, 348, 366, 20, 376, 99, 99, 421, 102, + /* 1020 */ 20, 424, 22, 338, 427, 428, 429, 430, 431, 432, + /* 1030 */ 132, 434, 4, 348, 384, 350, 439, 387, 441, 347, + /* 1040 */ 348, 384, 445, 446, 387, 453, 167, 19, 456, 338, + /* 1050 */ 61, 347, 348, 53, 183, 138, 139, 393, 366, 338, + /* 1060 */ 375, 33, 338, 471, 472, 347, 348, 20, 476, 477, + /* 1070 */ 366, 338, 387, 99, 389, 347, 348, 49, 347, 348, + /* 1080 */ 20, 210, 211, 55, 366, 168, 169, 360, 361, 61, + /* 1090 */ 101, 174, 175, 104, 366, 45, 46, 366, 387, 201, + /* 1100 */ 202, 14, 15, 16, 14, 188, 421, 190, 387, 424, + /* 1110 */ 20, 387, 427, 428, 429, 430, 431, 432, 338, 434, + /* 1120 */ 387, 170, 406, 244, 439, 338, 441, 168, 338, 101, + /* 1130 */ 445, 446, 104, 254, 338, 255, 256, 220, 221, 348, + /* 1140 */ 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + /* 1150 */ 233, 234, 235, 236, 237, 238, 239, 240, 12, 13, + /* 1160 */ 348, 338, 363, 438, 170, 440, 20, 387, 22, 453, + /* 1170 */ 0, 348, 456, 350, 387, 362, 377, 387, 365, 33, + /* 1180 */ 438, 35, 440, 387, 393, 113, 387, 471, 472, 22, + /* 1190 */ 48, 384, 476, 477, 387, 42, 0, 44, 375, 42, + /* 1200 */ 106, 44, 35, 109, 0, 393, 106, 61, 44, 109, + /* 1210 */ 387, 214, 389, 13, 0, 106, 277, 170, 109, 49, + /* 1220 */ 74, 0, 106, 424, 425, 109, 22, 204, 44, 206, + /* 1230 */ 170, 44, 44, 434, 162, 35, 22, 44, 44, 44, + /* 1240 */ 44, 138, 139, 22, 421, 99, 44, 424, 102, 67, + /* 1250 */ 427, 428, 429, 430, 431, 432, 44, 434, 47, 44, + /* 1260 */ 44, 0, 439, 35, 441, 102, 44, 103, 445, 446, + /* 1270 */ 44, 1, 2, 44, 44, 112, 44, 13, 13, 44, + /* 1280 */ 44, 44, 44, 44, 138, 139, 376, 103, 35, 376, + /* 1290 */ 103, 103, 376, 411, 364, 339, 103, 103, 397, 35, + /* 1300 */ 35, 480, 469, 18, 351, 103, 463, 363, 23, 363, + /* 1310 */ 375, 50, 170, 102, 168, 169, 351, 397, 103, 103, + /* 1320 */ 174, 175, 37, 38, 346, 103, 41, 74, 348, 103, + /* 1330 */ 397, 386, 103, 103, 188, 103, 190, 52, 103, 103, + /* 1340 */ 103, 103, 103, 455, 447, 473, 457, 62, 63, 64, + /* 1350 */ 65, 259, 423, 49, 422, 338, 20, 415, 203, 355, + /* 1360 */ 420, 355, 415, 186, 42, 348, 220, 221, 408, 223, + /* 1370 */ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + /* 1380 */ 234, 235, 236, 237, 238, 239, 240, 102, 20, 394, + /* 1390 */ 397, 167, 375, 394, 392, 20, 347, 394, 347, 392, + /* 1400 */ 392, 100, 220, 359, 387, 98, 389, 97, 347, 347, + /* 1410 */ 358, 357, 347, 347, 20, 340, 415, 48, 190, 340, + /* 1420 */ 344, 344, 355, 20, 338, 140, 389, 20, 355, 349, + /* 1430 */ 20, 407, 349, 355, 348, 347, 350, 355, 421, 355, + /* 1440 */ 355, 424, 54, 352, 427, 428, 429, 430, 431, 432, + /* 1450 */ 355, 434, 340, 352, 340, 347, 439, 387, 441, 207, + /* 1460 */ 419, 375, 445, 446, 375, 180, 181, 182, 375, 102, + /* 1470 */ 185, 375, 375, 387, 279, 389, 417, 375, 415, 375, + /* 1480 */ 375, 375, 375, 198, 199, 375, 338, 353, 375, 194, + /* 1490 */ 193, 353, 192, 281, 209, 414, 348, 212, 350, 347, + /* 1500 */ 215, 216, 217, 218, 219, 387, 387, 421, 397, 389, + /* 1510 */ 424, 413, 338, 427, 428, 429, 430, 431, 432, 397, + /* 1520 */ 434, 266, 348, 375, 387, 439, 462, 441, 265, 412, + /* 1530 */ 402, 445, 446, 462, 387, 387, 387, 389, 402, 465, + /* 1540 */ 274, 387, 257, 179, 276, 283, 275, 260, 423, 375, + /* 1550 */ 481, 278, 280, 348, 256, 20, 426, 347, 349, 353, + /* 1560 */ 461, 387, 20, 389, 402, 400, 353, 387, 387, 421, + /* 1570 */ 387, 402, 424, 387, 459, 427, 428, 429, 430, 431, + /* 1580 */ 432, 172, 434, 460, 387, 464, 338, 439, 462, 441, + /* 1590 */ 387, 399, 102, 445, 446, 421, 348, 353, 424, 475, + /* 1600 */ 353, 427, 428, 429, 430, 431, 432, 474, 434, 102, + /* 1610 */ 444, 371, 379, 439, 387, 441, 365, 348, 36, 445, + /* 1620 */ 446, 347, 341, 375, 340, 369, 409, 369, 353, 369, + /* 1630 */ 354, 0, 336, 0, 416, 387, 0, 389, 42, 0, + /* 1640 */ 35, 213, 35, 35, 403, 403, 35, 338, 0, 213, + /* 1650 */ 35, 35, 213, 0, 213, 0, 35, 348, 35, 22, + /* 1660 */ 0, 208, 0, 196, 0, 196, 190, 197, 188, 421, + /* 1670 */ 0, 0, 424, 338, 0, 427, 428, 429, 430, 431, + /* 1680 */ 432, 0, 434, 348, 375, 184, 183, 439, 0, 441, + /* 1690 */ 0, 47, 0, 445, 446, 0, 387, 0, 389, 42, + /* 1700 */ 0, 0, 0, 0, 0, 0, 0, 0, 157, 338, + /* 1710 */ 375, 35, 0, 157, 0, 0, 0, 0, 0, 348, + /* 1720 */ 42, 0, 387, 0, 389, 0, 0, 0, 0, 0, + /* 1730 */ 421, 0, 0, 424, 0, 0, 427, 428, 429, 430, + /* 1740 */ 431, 432, 0, 434, 0, 0, 375, 0, 0, 0, + /* 1750 */ 441, 0, 22, 0, 445, 446, 421, 0, 387, 424, + /* 1760 */ 389, 141, 427, 428, 429, 430, 431, 432, 0, 434, + /* 1770 */ 0, 0, 22, 338, 22, 35, 441, 0, 0, 0, + /* 1780 */ 445, 446, 179, 348, 48, 48, 0, 49, 0, 0, + /* 1790 */ 35, 0, 421, 35, 61, 424, 35, 338, 427, 428, + /* 1800 */ 429, 430, 431, 432, 61, 434, 39, 348, 49, 49, + /* 1810 */ 375, 39, 441, 39, 0, 61, 445, 446, 42, 35, + /* 1820 */ 39, 14, 387, 0, 389, 0, 39, 47, 0, 44, + /* 1830 */ 0, 0, 0, 40, 375, 39, 0, 47, 0, 47, + /* 1840 */ 0, 68, 39, 35, 49, 0, 387, 35, 389, 49, + /* 1850 */ 39, 0, 35, 49, 39, 0, 421, 35, 49, 424, + /* 1860 */ 39, 338, 427, 428, 429, 430, 431, 432, 0, 434, + /* 1870 */ 0, 348, 0, 0, 111, 109, 441, 35, 22, 0, + /* 1880 */ 421, 446, 1, 424, 35, 35, 427, 428, 429, 430, + /* 1890 */ 431, 432, 44, 434, 35, 35, 35, 35, 375, 35, + /* 1900 */ 19, 35, 44, 380, 35, 22, 35, 0, 22, 0, + /* 1910 */ 387, 22, 389, 0, 33, 22, 51, 35, 0, 338, + /* 1920 */ 35, 0, 35, 0, 22, 20, 35, 468, 102, 348, + /* 1930 */ 49, 35, 35, 0, 170, 338, 103, 56, 57, 58, + /* 1940 */ 59, 102, 61, 35, 421, 348, 22, 424, 0, 22, + /* 1950 */ 427, 428, 429, 430, 431, 432, 375, 434, 0, 0, + /* 1960 */ 195, 380, 48, 3, 170, 102, 191, 100, 387, 172, + /* 1970 */ 389, 170, 375, 44, 261, 177, 48, 103, 102, 44, + /* 1980 */ 44, 103, 101, 103, 387, 104, 389, 103, 98, 47, + /* 1990 */ 102, 44, 3, 47, 102, 44, 338, 102, 44, 35, + /* 2000 */ 102, 35, 421, 103, 103, 424, 348, 261, 427, 428, + /* 2010 */ 429, 430, 431, 432, 35, 434, 35, 136, 421, 35, + /* 2020 */ 35, 424, 338, 261, 427, 428, 429, 430, 431, 432, + /* 2030 */ 47, 434, 348, 375, 103, 103, 44, 47, 255, 0, + /* 2040 */ 0, 0, 0, 102, 39, 387, 47, 389, 173, 0, + /* 2050 */ 39, 102, 171, 103, 47, 103, 112, 176, 338, 375, + /* 2060 */ 44, 242, 47, 102, 380, 102, 2, 470, 348, 102, + /* 2070 */ 171, 387, 102, 389, 100, 100, 22, 196, 102, 421, + /* 2080 */ 103, 103, 424, 103, 102, 427, 428, 429, 430, 431, + /* 2090 */ 432, 47, 434, 102, 338, 375, 102, 102, 22, 103, + /* 2100 */ 102, 113, 35, 103, 348, 421, 35, 387, 424, 389, + /* 2110 */ 102, 427, 428, 429, 430, 431, 432, 103, 434, 35, + /* 2120 */ 338, 102, 35, 220, 103, 102, 222, 103, 35, 102, + /* 2130 */ 348, 375, 103, 35, 102, 102, 380, 479, 44, 102, + /* 2140 */ 35, 421, 124, 387, 424, 389, 124, 427, 428, 429, + /* 2150 */ 430, 431, 432, 102, 434, 124, 436, 375, 124, 22, + /* 2160 */ 68, 35, 380, 67, 35, 35, 35, 35, 35, 387, + /* 2170 */ 35, 389, 44, 74, 35, 96, 35, 421, 35, 35, + /* 2180 */ 424, 22, 35, 427, 428, 429, 430, 431, 432, 35, + /* 2190 */ 434, 35, 74, 35, 22, 338, 35, 35, 35, 35, + /* 2200 */ 35, 0, 35, 421, 49, 348, 424, 39, 0, 427, + /* 2210 */ 428, 429, 430, 431, 432, 338, 434, 35, 49, 39, + /* 2220 */ 0, 0, 35, 49, 39, 348, 35, 49, 39, 0, + /* 2230 */ 35, 35, 375, 0, 22, 21, 482, 22, 22, 21, + /* 2240 */ 482, 482, 20, 482, 387, 482, 389, 482, 482, 482, + /* 2250 */ 482, 482, 375, 482, 482, 482, 482, 482, 482, 482, + /* 2260 */ 482, 482, 482, 482, 387, 482, 389, 482, 482, 482, + /* 2270 */ 482, 482, 482, 482, 482, 482, 482, 482, 421, 482, + /* 2280 */ 482, 424, 482, 338, 427, 428, 429, 430, 431, 432, + /* 2290 */ 482, 434, 482, 348, 482, 482, 482, 482, 421, 482, + /* 2300 */ 338, 424, 482, 482, 427, 428, 429, 430, 431, 432, + /* 2310 */ 348, 434, 482, 482, 482, 482, 482, 482, 482, 482, + /* 2320 */ 375, 482, 482, 482, 482, 482, 482, 482, 482, 482, + /* 2330 */ 482, 482, 387, 482, 389, 482, 482, 375, 482, 482, + /* 2340 */ 482, 482, 482, 482, 482, 482, 482, 482, 338, 387, + /* 2350 */ 482, 389, 482, 482, 482, 482, 482, 482, 348, 482, + /* 2360 */ 482, 482, 482, 482, 482, 482, 421, 482, 338, 424, + /* 2370 */ 482, 482, 427, 428, 429, 430, 431, 432, 348, 434, + /* 2380 */ 482, 482, 482, 421, 482, 375, 424, 482, 482, 427, + /* 2390 */ 428, 429, 430, 431, 432, 482, 434, 387, 338, 389, + /* 2400 */ 482, 482, 482, 482, 482, 375, 482, 482, 348, 482, + /* 2410 */ 482, 482, 482, 482, 482, 482, 338, 387, 482, 389, + /* 2420 */ 482, 482, 482, 482, 482, 482, 348, 482, 482, 482, + /* 2430 */ 482, 421, 482, 482, 424, 375, 482, 427, 428, 429, + /* 2440 */ 430, 431, 432, 482, 434, 482, 338, 387, 482, 389, + /* 2450 */ 482, 421, 482, 375, 424, 482, 348, 427, 428, 429, + /* 2460 */ 430, 431, 432, 482, 434, 387, 482, 389, 482, 482, + /* 2470 */ 482, 482, 482, 482, 482, 482, 338, 482, 482, 482, + /* 2480 */ 482, 421, 482, 375, 424, 482, 348, 427, 428, 429, + /* 2490 */ 430, 431, 432, 482, 434, 387, 482, 389, 482, 421, + /* 2500 */ 482, 482, 424, 482, 482, 427, 428, 429, 430, 431, + /* 2510 */ 432, 482, 434, 375, 482, 482, 482, 482, 482, 482, + /* 2520 */ 482, 482, 482, 482, 338, 387, 482, 389, 482, 421, + /* 2530 */ 482, 482, 424, 482, 348, 427, 428, 429, 430, 431, + /* 2540 */ 432, 482, 434, 482, 338, 482, 482, 482, 482, 482, + /* 2550 */ 482, 482, 482, 482, 348, 482, 482, 482, 482, 421, + /* 2560 */ 482, 375, 424, 482, 482, 427, 428, 429, 430, 431, + /* 2570 */ 432, 482, 434, 387, 482, 389, 482, 482, 482, 482, + /* 2580 */ 482, 375, 482, 482, 482, 482, 482, 482, 482, 482, + /* 2590 */ 482, 482, 482, 387, 482, 389, 482, 482, 482, 482, + /* 2600 */ 482, 482, 482, 482, 482, 482, 482, 421, 482, 482, + /* 2610 */ 424, 482, 482, 427, 428, 429, 430, 431, 432, 482, + /* 2620 */ 434, 482, 338, 482, 482, 482, 482, 421, 482, 482, + /* 2630 */ 424, 482, 348, 427, 428, 429, 430, 431, 432, 338, + /* 2640 */ 434, 482, 482, 482, 482, 482, 482, 482, 482, 348, + /* 2650 */ 482, 482, 482, 482, 482, 482, 482, 482, 482, 375, + /* 2660 */ 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + /* 2670 */ 482, 387, 482, 389, 482, 482, 375, 482, 482, 482, + /* 2680 */ 482, 482, 482, 482, 482, 482, 482, 338, 387, 482, + /* 2690 */ 389, 482, 482, 482, 482, 482, 482, 348, 482, 482, + /* 2700 */ 482, 482, 482, 482, 482, 421, 482, 338, 424, 482, + /* 2710 */ 482, 427, 428, 429, 430, 431, 432, 348, 434, 482, + /* 2720 */ 482, 482, 421, 482, 375, 424, 482, 482, 427, 428, + /* 2730 */ 429, 430, 431, 432, 482, 434, 387, 338, 389, 482, + /* 2740 */ 482, 482, 482, 482, 375, 482, 482, 348, 482, 482, + /* 2750 */ 482, 482, 482, 482, 482, 338, 387, 482, 389, 482, + /* 2760 */ 482, 482, 482, 482, 482, 348, 482, 482, 482, 482, + /* 2770 */ 421, 482, 482, 424, 375, 482, 427, 428, 429, 430, + /* 2780 */ 431, 432, 482, 434, 482, 338, 387, 482, 389, 482, + /* 2790 */ 421, 482, 375, 424, 482, 348, 427, 428, 429, 430, + /* 2800 */ 431, 432, 482, 434, 387, 482, 389, 482, 482, 482, + /* 2810 */ 482, 482, 482, 482, 482, 338, 482, 482, 482, 482, + /* 2820 */ 421, 482, 375, 424, 482, 348, 427, 428, 429, 430, + /* 2830 */ 431, 432, 482, 434, 387, 482, 389, 482, 421, 482, + /* 2840 */ 482, 424, 482, 482, 427, 428, 429, 430, 431, 432, + /* 2850 */ 482, 434, 375, 482, 482, 482, 482, 482, 482, 482, + /* 2860 */ 482, 482, 482, 338, 387, 482, 389, 482, 421, 482, + /* 2870 */ 482, 424, 482, 348, 427, 428, 429, 430, 431, 432, + /* 2880 */ 482, 434, 482, 338, 482, 482, 482, 482, 482, 482, + /* 2890 */ 482, 482, 482, 348, 482, 482, 482, 482, 421, 482, + /* 2900 */ 375, 424, 482, 482, 427, 428, 429, 430, 431, 432, + /* 2910 */ 482, 434, 387, 482, 389, 482, 482, 482, 482, 482, + /* 2920 */ 375, 482, 482, 482, 482, 482, 482, 482, 482, 482, + /* 2930 */ 482, 482, 387, 482, 389, 482, 482, 482, 482, 482, + /* 2940 */ 482, 482, 482, 482, 482, 482, 421, 482, 482, 424, + /* 2950 */ 482, 482, 427, 428, 429, 430, 431, 432, 482, 434, + /* 2960 */ 482, 482, 482, 482, 482, 482, 421, 482, 482, 424, + /* 2970 */ 482, 482, 427, 428, 429, 430, 431, 432, 482, 434, + /* 2980 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 2990 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3000 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3010 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3020 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3030 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3040 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3050 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3060 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3070 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3080 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3090 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3100 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3110 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3120 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3130 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3140 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3150 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3160 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3170 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3180 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3190 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3200 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3210 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3220 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3230 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3240 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3250 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3260 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3270 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3280 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3290 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3300 */ 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, + /* 3310 */ 335, 335, 335, 335, 335, }; -#define YY_SHIFT_COUNT (771) +#define YY_SHIFT_COUNT (786) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2198) +#define YY_SHIFT_MAX (2233) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 380, 0, 227, 0, 455, 455, 455, 455, 455, 455, - /* 10 */ 455, 455, 455, 455, 455, 455, 682, 909, 909, 1136, - /* 20 */ 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - /* 30 */ 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - /* 40 */ 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - /* 50 */ 909, 78, 454, 401, 200, 711, 43, 228, 43, 200, - /* 60 */ 200, 1284, 43, 1284, 1284, 91, 43, 18, 1014, 149, - /* 70 */ 149, 1014, 322, 322, 145, 121, 262, 262, 149, 149, - /* 80 */ 149, 149, 149, 149, 149, 154, 149, 149, 6, 18, - /* 90 */ 149, 149, 177, 149, 18, 149, 154, 149, 154, 18, - /* 100 */ 149, 149, 18, 149, 18, 18, 18, 149, 199, 226, - /* 110 */ 187, 187, 418, 50, 314, 314, 314, 314, 314, 314, - /* 120 */ 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - /* 130 */ 314, 314, 314, 965, 394, 145, 121, 539, 328, 328, - /* 140 */ 328, 838, 300, 300, 539, 275, 275, 275, 6, 208, - /* 150 */ 330, 18, 548, 18, 548, 548, 686, 758, 35, 35, - /* 160 */ 35, 35, 35, 35, 35, 35, 1596, 645, 15, 48, - /* 170 */ 167, 279, 32, 363, 792, 792, 728, 764, 33, 794, - /* 180 */ 1108, 315, 879, 856, 939, 946, 945, 939, 1152, 963, - /* 190 */ 1065, 1125, 1341, 1379, 1200, 6, 1379, 6, 1223, 1366, - /* 200 */ 1390, 1366, 1250, 1397, 1397, 1366, 1250, 1250, 1325, 1331, - /* 210 */ 1397, 1335, 1397, 1397, 1397, 1415, 1389, 1415, 1389, 1379, - /* 220 */ 6, 1422, 6, 1427, 1428, 6, 1427, 6, 6, 6, - /* 230 */ 1397, 6, 1399, 1399, 1415, 18, 18, 18, 18, 18, - /* 240 */ 18, 18, 18, 18, 18, 18, 1397, 1415, 548, 548, - /* 250 */ 548, 1252, 1393, 1379, 199, 1297, 1309, 1422, 199, 1318, - /* 260 */ 1397, 1390, 1390, 548, 1246, 1263, 548, 1246, 1263, 548, - /* 270 */ 548, 18, 1256, 1358, 1246, 1267, 1269, 1289, 1125, 1271, - /* 280 */ 1272, 1279, 1302, 275, 1541, 1397, 1427, 199, 199, 1554, - /* 290 */ 1263, 548, 548, 548, 548, 548, 1263, 548, 1424, 199, - /* 300 */ 686, 199, 275, 1501, 1509, 548, 758, 1397, 199, 1584, - /* 310 */ 1415, 3028, 3028, 3028, 3028, 3028, 3028, 3028, 3028, 3028, - /* 320 */ 34, 232, 278, 791, 731, 592, 750, 642, 16, 850, - /* 330 */ 1049, 821, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 340 */ 1093, 985, 281, 457, 457, 948, 133, 241, 69, 182, - /* 350 */ 456, 625, 440, 63, 63, 376, 896, 80, 376, 376, - /* 360 */ 376, 1212, 867, 1140, 1180, 1165, 1107, 1206, 1117, 1122, - /* 370 */ 1128, 1139, 1209, 1214, 1237, 1257, 1264, 1012, 1203, 1222, - /* 380 */ 1216, 1224, 1227, 1232, 1153, 717, 1009, 503, 1234, 1247, - /* 390 */ 1251, 1276, 1277, 1282, 1299, 1283, 1174, 1285, 489, 1287, - /* 400 */ 1288, 1290, 1292, 1293, 1295, 1205, 1225, 1258, 1303, 1363, - /* 410 */ 666, 1262, 1623, 1628, 1638, 1597, 1640, 1607, 1432, 1609, - /* 420 */ 1611, 1612, 1438, 1650, 1621, 1622, 1447, 1663, 1450, 1664, - /* 430 */ 1630, 1666, 1645, 1670, 1637, 1467, 1680, 1488, 1683, 1490, - /* 440 */ 1492, 1497, 1503, 1690, 1691, 1699, 1524, 1528, 1711, 1712, - /* 450 */ 1668, 1713, 1716, 1717, 1678, 1721, 1723, 1724, 1725, 1726, - /* 460 */ 1727, 1728, 1729, 1576, 1698, 1734, 1580, 1736, 1737, 1738, - /* 470 */ 1739, 1740, 1741, 1743, 1744, 1746, 1747, 1754, 1756, 1757, - /* 480 */ 1758, 1760, 1761, 1722, 1768, 1769, 1772, 1774, 1775, 1776, - /* 490 */ 1755, 1778, 1779, 1780, 1624, 1781, 1782, 1762, 1735, 1764, - /* 500 */ 1745, 1785, 1730, 1752, 1788, 1732, 1792, 1742, 1794, 1795, - /* 510 */ 1767, 1759, 1753, 1749, 1773, 1786, 1777, 1799, 1766, 1765, - /* 520 */ 1802, 1803, 1810, 1783, 1642, 1821, 1823, 1831, 1770, 1832, - /* 530 */ 1833, 1791, 1789, 1796, 1827, 1793, 1790, 1798, 1834, 1806, - /* 540 */ 1797, 1804, 1842, 1812, 1800, 1809, 1845, 1851, 1852, 1853, - /* 550 */ 1748, 1771, 1819, 1837, 1855, 1825, 1828, 1829, 1830, 1835, - /* 560 */ 1838, 1839, 1817, 1818, 1840, 1844, 1846, 1847, 1866, 1850, - /* 570 */ 1867, 1854, 1836, 1869, 1858, 1848, 1884, 1857, 1885, 1859, - /* 580 */ 1886, 1873, 1868, 1870, 1871, 1872, 1808, 1811, 1904, 1750, - /* 590 */ 1814, 1731, 1881, 1895, 1919, 1751, 1899, 1784, 1801, 1925, - /* 600 */ 1927, 1787, 1805, 1934, 1894, 1669, 1843, 1849, 1856, 1893, - /* 610 */ 1860, 1898, 1863, 1865, 1903, 1905, 1874, 1876, 1877, 1878, - /* 620 */ 1880, 1924, 1901, 1922, 1879, 1929, 1715, 1882, 1888, 1939, - /* 630 */ 1938, 1807, 1952, 1955, 1964, 1965, 1966, 1967, 1902, 1907, - /* 640 */ 1957, 1815, 1962, 1958, 2009, 2010, 2011, 2013, 1914, 1976, - /* 650 */ 1749, 1969, 1917, 1918, 1931, 1920, 1923, 1864, 1930, 2036, - /* 660 */ 1998, 1875, 1940, 1928, 1749, 1992, 1997, 1944, 1813, 1947, - /* 670 */ 2045, 2028, 1861, 1951, 1954, 1956, 1959, 1971, 1963, 2005, - /* 680 */ 1972, 1973, 2012, 1968, 2035, 1887, 1974, 1970, 1975, 2023, - /* 690 */ 2027, 1977, 1984, 2030, 1978, 1991, 2040, 1994, 1995, 2062, - /* 700 */ 2000, 2014, 2075, 2017, 1989, 1990, 1996, 1999, 2020, 2069, - /* 710 */ 2032, 2079, 2033, 2069, 2069, 2106, 2064, 2070, 2099, 2102, - /* 720 */ 2104, 2105, 2108, 2109, 2110, 2111, 2077, 2048, 2103, 2116, - /* 730 */ 2117, 2118, 2132, 2120, 2121, 2122, 2086, 1817, 2124, 1818, - /* 740 */ 2125, 2126, 2128, 2129, 2143, 2131, 2167, 2133, 2127, 2130, - /* 750 */ 2170, 2136, 2134, 2135, 2175, 2138, 2137, 2139, 2179, 2145, - /* 760 */ 2147, 2142, 2184, 2159, 2162, 2198, 2178, 2180, 2181, 2183, - /* 770 */ 2185, 2182, + /* 0 */ 1285, 0, 229, 0, 459, 459, 459, 459, 459, 459, + /* 10 */ 459, 459, 459, 459, 459, 459, 688, 917, 917, 1146, + /* 20 */ 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, + /* 30 */ 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, + /* 40 */ 917, 917, 917, 917, 917, 917, 917, 917, 917, 917, + /* 50 */ 917, 240, 603, 610, 375, 684, 89, 161, 89, 375, + /* 60 */ 375, 767, 89, 767, 767, 553, 89, 56, 380, 139, + /* 70 */ 139, 380, 280, 280, 197, 28, 48, 48, 139, 139, + /* 80 */ 139, 139, 139, 139, 139, 193, 139, 139, 156, 56, + /* 90 */ 139, 139, 239, 139, 56, 139, 193, 139, 193, 56, + /* 100 */ 139, 139, 56, 139, 56, 56, 56, 139, 293, 228, + /* 110 */ 189, 189, 198, 116, 604, 604, 604, 604, 604, 604, + /* 120 */ 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, + /* 130 */ 604, 604, 604, 379, 406, 197, 28, 674, 994, 994, + /* 140 */ 994, 793, 607, 607, 674, 543, 543, 543, 156, 488, + /* 150 */ 342, 56, 632, 56, 632, 632, 546, 672, 35, 35, + /* 160 */ 35, 35, 35, 35, 35, 35, 1881, 575, 15, 44, + /* 170 */ 164, 275, 691, 368, 181, 181, 599, 646, 1000, 1047, + /* 180 */ 1050, 1090, 64, 1060, 880, 700, 939, 880, 1153, 295, + /* 190 */ 959, 1092, 1304, 1336, 1155, 156, 1336, 156, 1177, 1322, + /* 200 */ 1368, 1322, 1224, 1375, 1375, 1322, 1224, 1224, 1301, 1307, + /* 210 */ 1375, 1310, 1375, 1375, 1375, 1394, 1369, 1394, 1369, 1336, + /* 220 */ 156, 1403, 156, 1407, 1410, 156, 1407, 156, 156, 156, + /* 230 */ 1375, 156, 1388, 1388, 1394, 56, 56, 56, 56, 56, + /* 240 */ 56, 56, 56, 56, 56, 56, 1375, 1394, 632, 632, + /* 250 */ 632, 1252, 1367, 1336, 293, 1295, 1297, 1403, 293, 1300, + /* 260 */ 1375, 1368, 1368, 632, 1255, 1263, 632, 1255, 1263, 632, + /* 270 */ 632, 56, 1266, 1364, 1255, 1268, 1271, 1287, 1092, 1262, + /* 280 */ 1272, 1273, 1298, 543, 1535, 1375, 1407, 293, 293, 1542, + /* 290 */ 1263, 632, 632, 632, 632, 632, 1263, 632, 1409, 293, + /* 300 */ 546, 293, 543, 1490, 1507, 632, 672, 1375, 293, 1582, + /* 310 */ 1394, 2980, 2980, 2980, 2980, 2980, 2980, 2980, 2980, 2980, + /* 320 */ 34, 249, 289, 1028, 398, 57, 578, 50, 722, 769, + /* 330 */ 951, 75, 961, 961, 961, 961, 961, 961, 961, 961, + /* 340 */ 961, 538, 517, 65, 65, 445, 510, 871, 399, 989, + /* 350 */ 918, 974, 574, 898, 492, 492, 1087, 251, 879, 1087, + /* 360 */ 1087, 1087, 1170, 997, 752, 1167, 1157, 1072, 1196, 1094, + /* 370 */ 1100, 1109, 1116, 804, 1200, 1204, 1214, 1221, 1023, 1164, + /* 380 */ 1184, 615, 1187, 1188, 1193, 1103, 1195, 1212, 1142, 1194, + /* 390 */ 1202, 1215, 1216, 1222, 1226, 1270, 1229, 1182, 1230, 1211, + /* 400 */ 1232, 1235, 1236, 1237, 1238, 1239, 1163, 741, 1228, 1264, + /* 410 */ 1265, 1253, 1261, 1631, 1633, 1636, 1596, 1639, 1605, 1428, + /* 420 */ 1607, 1608, 1611, 1436, 1648, 1615, 1616, 1439, 1653, 1441, + /* 430 */ 1655, 1621, 1670, 1637, 1660, 1623, 1453, 1662, 1467, 1664, + /* 440 */ 1469, 1470, 1476, 1480, 1671, 1674, 1681, 1501, 1503, 1688, + /* 450 */ 1690, 1644, 1692, 1695, 1697, 1657, 1700, 1701, 1702, 1703, + /* 460 */ 1704, 1705, 1706, 1707, 1551, 1676, 1712, 1556, 1714, 1715, + /* 470 */ 1716, 1717, 1718, 1723, 1725, 1726, 1727, 1728, 1729, 1731, + /* 480 */ 1732, 1734, 1735, 1742, 1678, 1721, 1744, 1745, 1747, 1748, + /* 490 */ 1749, 1730, 1751, 1753, 1757, 1620, 1768, 1770, 1750, 1736, + /* 500 */ 1752, 1737, 1771, 1733, 1740, 1777, 1743, 1778, 1754, 1779, + /* 510 */ 1786, 1755, 1738, 1767, 1788, 1758, 1759, 1772, 1789, 1761, + /* 520 */ 1760, 1774, 1791, 1784, 1814, 1776, 1781, 1785, 1780, 1790, + /* 530 */ 1807, 1792, 1823, 1793, 1787, 1825, 1828, 1830, 1796, 1603, + /* 540 */ 1831, 1832, 1836, 1773, 1838, 1840, 1808, 1795, 1803, 1845, + /* 550 */ 1812, 1800, 1811, 1851, 1817, 1804, 1815, 1855, 1822, 1809, + /* 560 */ 1821, 1868, 1870, 1872, 1873, 1763, 1766, 1842, 1856, 1879, + /* 570 */ 1849, 1850, 1859, 1860, 1861, 1862, 1864, 1848, 1858, 1866, + /* 580 */ 1869, 1883, 1871, 1907, 1886, 1909, 1889, 1865, 1913, 1893, + /* 590 */ 1882, 1918, 1885, 1921, 1887, 1923, 1902, 1905, 1891, 1896, + /* 600 */ 1897, 1833, 1826, 1933, 1764, 1839, 1765, 1908, 1924, 1948, + /* 610 */ 1775, 1927, 1794, 1797, 1958, 1959, 1801, 1798, 1960, 1929, + /* 620 */ 1713, 1863, 1874, 1876, 1914, 1867, 1928, 1890, 1878, 1935, + /* 630 */ 1936, 1880, 1888, 1892, 1895, 1884, 1947, 1942, 1946, 1898, + /* 640 */ 1951, 1746, 1900, 1901, 1989, 1954, 1762, 1964, 1966, 1979, + /* 650 */ 1981, 1984, 1985, 1931, 1932, 1983, 1783, 1992, 1990, 2039, + /* 660 */ 2040, 2041, 2042, 1941, 2005, 1780, 1999, 1949, 1950, 1952, + /* 670 */ 1961, 1963, 1875, 1967, 2049, 2011, 1899, 1970, 1944, 1780, + /* 680 */ 2007, 2016, 1974, 1819, 1975, 2064, 2054, 1903, 1976, 1977, + /* 690 */ 1982, 1978, 1991, 1980, 2015, 1994, 1995, 2044, 1996, 2076, + /* 700 */ 1904, 1998, 1988, 2000, 2067, 2071, 2008, 2014, 2084, 2019, + /* 710 */ 2021, 2087, 2023, 2024, 2093, 2027, 2029, 2098, 2032, 2018, + /* 720 */ 2022, 2031, 2034, 2033, 2094, 2037, 2105, 2051, 2094, 2094, + /* 730 */ 2137, 2092, 2096, 2126, 2129, 2130, 2131, 2132, 2133, 2135, + /* 740 */ 2139, 2099, 2079, 2128, 2141, 2143, 2144, 2159, 2147, 2154, + /* 750 */ 2156, 2118, 1848, 2158, 1858, 2161, 2162, 2163, 2164, 2172, + /* 760 */ 2165, 2201, 2167, 2155, 2168, 2208, 2182, 2169, 2180, 2220, + /* 770 */ 2187, 2174, 2185, 2221, 2191, 2178, 2189, 2229, 2195, 2196, + /* 780 */ 2233, 2212, 2214, 2215, 2216, 2218, 2222, }; #define YY_REDUCE_COUNT (319) -#define YY_REDUCE_MIN (-386) -#define YY_REDUCE_MAX (2595) +#define YY_REDUCE_MIN (-445) +#define YY_REDUCE_MAX (2545) static const short yy_reduce_ofst[] = { - /* 0 */ -264, 364, 225, 588, 452, 611, 738, 826, 855, 1039, - /* 10 */ 1138, 1161, 1249, 1275, 1323, 1386, -72, -336, 153, 1471, - /* 20 */ 1504, 1535, 1566, 1599, 1661, 1676, 1697, 1763, 1826, 1841, - /* 30 */ 1891, 1911, 1961, 1986, 2019, 2049, 2085, 2107, 2173, 2192, - /* 40 */ 2258, 2277, 2308, 2372, 2393, 2422, 2480, 2510, 2530, 2578, - /* 50 */ 2595, -131, -203, -262, 64, 163, 254, 495, 618, 488, - /* 60 */ 541, 681, -47, -92, 181, 252, 361, 598, -376, -207, - /* 70 */ -103, -386, -338, -209, 135, -379, 176, 190, -258, -91, - /* 80 */ 179, 270, 303, 389, 423, 274, 435, 477, 490, 429, - /* 90 */ 511, 581, -76, 352, 473, 631, 354, 637, 527, -315, - /* 100 */ 659, 714, 800, 833, 192, 810, 638, 859, 623, -95, - /* 110 */ -156, -156, 168, -316, 59, 183, 290, 371, 375, 382, - /* 120 */ 547, 556, 602, 636, 664, 692, 715, 744, 774, 825, - /* 130 */ 840, 849, 853, -239, -351, 412, 38, 61, -351, 57, - /* 140 */ 392, -167, 319, 522, 307, -343, 218, 542, 494, 215, - /* 150 */ 164, 710, 444, 555, 662, 770, 730, 761, -365, 470, - /* 160 */ 652, 661, 693, 748, 752, 693, 476, 868, 970, 915, - /* 170 */ 835, 844, 981, 880, 953, 979, 969, 969, 995, 950, - /* 180 */ 1002, 1001, 966, 954, 898, 898, 882, 898, 934, 925, - /* 190 */ 969, 974, 977, 987, 984, 1050, 991, 1052, 1000, 1017, - /* 200 */ 1016, 1022, 1026, 1073, 1074, 1028, 1031, 1032, 1068, 1072, - /* 210 */ 1084, 1076, 1087, 1088, 1089, 1098, 1096, 1101, 1099, 1027, - /* 220 */ 1090, 1057, 1092, 1102, 1045, 1100, 1104, 1103, 1106, 1109, - /* 230 */ 1110, 1120, 1113, 1127, 1116, 1112, 1114, 1115, 1118, 1119, - /* 240 */ 1121, 1123, 1126, 1131, 1132, 1133, 1130, 1141, 1075, 1095, - /* 250 */ 1105, 1064, 1071, 1082, 1147, 1097, 1111, 1137, 1150, 1129, - /* 260 */ 1167, 1134, 1135, 1142, 1053, 1143, 1146, 1054, 1144, 1148, - /* 270 */ 1151, 969, 1069, 1078, 1077, 1079, 1091, 1094, 1124, 1080, - /* 280 */ 1081, 1086, 898, 1207, 1145, 1217, 1226, 1220, 1221, 1178, - /* 290 */ 1179, 1193, 1199, 1211, 1218, 1228, 1192, 1229, 1202, 1255, - /* 300 */ 1233, 1259, 1261, 1166, 1235, 1231, 1254, 1273, 1268, 1286, - /* 310 */ 1294, 1219, 1210, 1230, 1236, 1260, 1266, 1274, 1278, 1301, + /* 0 */ 96, -94, 175, 329, 377, 597, 685, 823, 1086, 1148, + /* 10 */ 1017, 1174, 1248, 1309, 1335, 1371, -338, 150, 465, 1435, + /* 20 */ 1459, 1523, 1581, 1597, 1658, 1684, 1720, 1756, 1782, 1857, + /* 30 */ 1877, 1945, 1962, 2010, 2030, 2060, 2078, 2108, 2138, 2186, + /* 40 */ 2206, 2284, 2301, 2349, 2369, 2399, 2417, 2447, 2477, 2525, + /* 50 */ 2545, 393, 40, -48, -318, -206, 359, 592, 716, 54, + /* 60 */ 187, 799, -445, -85, 514, 426, 428, -366, 43, -345, + /* 70 */ -177, -132, -258, -127, 247, -28, -324, 47, 174, 381, + /* 80 */ 385, 407, 472, 485, 524, -155, 540, 585, 118, -81, + /* 90 */ 633, 642, 103, 645, -78, 647, 129, 692, 138, 108, + /* 100 */ 704, 718, -27, 728, 470, 493, 579, 731, -315, 133, + /* 110 */ -438, -438, -256, -15, 144, 213, 320, 404, 434, 520, + /* 120 */ 523, 547, 598, 620, 623, 711, 721, 724, 733, 780, + /* 130 */ 787, 790, 796, -368, -83, -64, 594, 513, -83, 209, + /* 140 */ 317, 207, 725, 742, 727, 664, 791, 812, 119, -364, + /* 150 */ -355, 273, 650, 140, 657, 807, 600, 813, 458, 504, + /* 160 */ 573, 639, 910, 913, 916, 910, 882, 930, 956, 901, + /* 170 */ 821, 833, 953, 843, 944, 946, 935, 935, 965, 920, + /* 180 */ 978, 980, 945, 933, 888, 888, 872, 888, 897, 889, + /* 190 */ 935, 929, 932, 942, 940, 1004, 947, 1006, 960, 995, + /* 200 */ 993, 999, 1002, 1049, 1051, 1003, 1007, 1008, 1044, 1052, + /* 210 */ 1061, 1054, 1062, 1065, 1066, 1075, 1076, 1079, 1077, 1001, + /* 220 */ 1067, 1037, 1073, 1080, 1024, 1078, 1083, 1082, 1084, 1085, + /* 230 */ 1088, 1095, 1091, 1101, 1112, 1089, 1093, 1096, 1097, 1102, + /* 240 */ 1104, 1105, 1106, 1107, 1110, 1113, 1108, 1114, 1070, 1118, + /* 250 */ 1119, 1041, 1059, 1063, 1134, 1081, 1098, 1120, 1138, 1117, + /* 260 */ 1152, 1111, 1122, 1137, 1064, 1128, 1147, 1071, 1136, 1149, + /* 270 */ 1154, 935, 1074, 1121, 1126, 1099, 1123, 1115, 1125, 1069, + /* 280 */ 1124, 1133, 888, 1205, 1130, 1210, 1209, 1206, 1213, 1165, + /* 290 */ 1162, 1180, 1181, 1183, 1186, 1197, 1169, 1203, 1192, 1244, + /* 300 */ 1240, 1247, 1269, 1166, 1233, 1227, 1251, 1274, 1275, 1281, + /* 310 */ 1284, 1217, 1218, 1241, 1242, 1256, 1258, 1260, 1276, 1296, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 10 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 20 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 30 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 40 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 50 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 60 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 70 */ 1734, 1734, 1734, 1734, 2007, 1734, 1734, 1734, 1734, 1734, - /* 80 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1816, 1734, - /* 90 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 100 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1814, 2000, - /* 110 */ 2225, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 120 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 130 */ 1734, 1734, 1734, 1734, 2237, 1734, 1734, 1734, 2237, 2237, - /* 140 */ 2237, 1814, 2197, 2197, 1734, 1734, 1734, 1734, 1816, 2067, - /* 150 */ 1734, 1734, 1734, 1734, 1734, 1734, 1935, 1734, 1734, 1734, - /* 160 */ 1734, 1734, 1959, 1734, 1734, 1734, 2059, 1734, 1734, 2262, - /* 170 */ 2318, 1734, 1734, 2265, 1734, 1734, 1734, 1734, 1734, 2012, - /* 180 */ 1734, 1734, 1889, 2252, 2229, 2243, 2302, 2230, 2227, 2246, - /* 190 */ 1734, 2256, 1734, 1734, 2081, 1816, 1734, 1816, 2046, 2005, - /* 200 */ 1734, 2005, 2002, 1734, 1734, 2005, 2002, 2002, 1878, 1874, - /* 210 */ 1734, 1872, 1734, 1734, 1734, 1734, 1781, 1734, 1781, 1734, - /* 220 */ 1816, 1734, 1816, 1734, 1734, 1816, 1734, 1816, 1816, 1816, - /* 230 */ 1734, 1816, 1794, 1794, 1734, 1734, 1734, 1734, 1734, 1734, - /* 240 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 250 */ 1734, 2079, 2065, 1734, 1814, 2057, 2055, 1734, 1814, 2053, - /* 260 */ 1734, 1734, 1734, 1734, 2273, 2271, 1734, 2273, 2271, 1734, - /* 270 */ 1734, 1734, 2287, 2283, 2273, 2291, 2289, 2258, 2256, 2321, - /* 280 */ 2308, 2304, 2243, 1734, 1734, 1734, 1734, 1814, 1814, 1734, - /* 290 */ 2271, 1734, 1734, 1734, 1734, 1734, 2271, 1734, 1734, 1814, - /* 300 */ 1734, 1814, 1734, 1734, 1905, 1734, 1734, 1734, 1814, 1766, - /* 310 */ 1734, 2048, 2070, 2030, 2030, 1938, 1938, 1938, 1817, 1739, - /* 320 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 330 */ 1734, 1734, 2286, 2285, 2152, 1734, 2201, 2200, 2199, 2190, - /* 340 */ 2151, 1901, 1734, 2150, 2149, 1734, 1734, 1734, 1734, 1734, - /* 350 */ 1734, 1734, 1734, 2021, 2020, 2143, 1734, 1734, 2144, 2142, - /* 360 */ 2141, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 370 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 380 */ 1734, 1734, 1734, 1734, 1734, 2305, 2309, 1734, 1734, 1734, - /* 390 */ 1734, 1734, 1734, 1734, 2226, 1734, 1734, 1734, 2125, 1734, - /* 400 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 410 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 420 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 430 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 440 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 450 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 460 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 470 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 480 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 490 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 500 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 510 */ 1734, 1734, 1771, 2130, 1734, 1734, 1734, 1734, 1734, 1734, - /* 520 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 530 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 540 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 550 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 560 */ 1734, 1734, 1855, 1854, 1734, 1734, 1734, 1734, 1734, 1734, - /* 570 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 580 */ 1734, 1734, 1734, 1734, 1734, 1734, 2134, 1734, 1734, 1734, - /* 590 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 600 */ 1734, 1734, 1734, 2301, 2259, 1734, 1734, 1734, 1734, 1734, - /* 610 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 620 */ 1734, 1734, 1734, 2125, 1734, 2284, 1734, 1734, 2299, 1734, - /* 630 */ 2303, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 2236, 2232, - /* 640 */ 1734, 1734, 2228, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 650 */ 2133, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 660 */ 1734, 1734, 1734, 1734, 2124, 1734, 2187, 1734, 1734, 1734, - /* 670 */ 2221, 1734, 1734, 2172, 1734, 1734, 1734, 1734, 1734, 1734, - /* 680 */ 1734, 1734, 1734, 2134, 1734, 2137, 1734, 1734, 1734, 1734, - /* 690 */ 1734, 1932, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 700 */ 1734, 1734, 1734, 1734, 1917, 1915, 1914, 1913, 1734, 1945, - /* 710 */ 1734, 1734, 1734, 1941, 1940, 1734, 1734, 1734, 1734, 1734, - /* 720 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1835, 1734, - /* 730 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1827, 1734, 1826, - /* 740 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 750 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 760 */ 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734, - /* 770 */ 1734, 1734, + /* 0 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 10 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 20 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 30 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 40 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 50 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 60 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 70 */ 1753, 1753, 1753, 1753, 2030, 1753, 1753, 1753, 1753, 1753, + /* 80 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1839, 1753, + /* 90 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 100 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1837, 2023, + /* 110 */ 2248, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 120 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 130 */ 1753, 1753, 1753, 1753, 2260, 1753, 1753, 1753, 2260, 2260, + /* 140 */ 2260, 1837, 2220, 2220, 1753, 1753, 1753, 1753, 1839, 2090, + /* 150 */ 1753, 1753, 1753, 1753, 1753, 1753, 1958, 1753, 1753, 1753, + /* 160 */ 1753, 1753, 1982, 1753, 1753, 1753, 2082, 1753, 1753, 2285, + /* 170 */ 2341, 1753, 1753, 2288, 1753, 1753, 1753, 1753, 1753, 2035, + /* 180 */ 1753, 1753, 1912, 2275, 2252, 2266, 2325, 2253, 2250, 2269, + /* 190 */ 1753, 2279, 1753, 1753, 2104, 1839, 1753, 1839, 2069, 2028, + /* 200 */ 1753, 2028, 2025, 1753, 1753, 2028, 2025, 2025, 1901, 1897, + /* 210 */ 1753, 1895, 1753, 1753, 1753, 1753, 1800, 1753, 1800, 1753, + /* 220 */ 1839, 1753, 1839, 1753, 1753, 1839, 1753, 1839, 1839, 1839, + /* 230 */ 1753, 1839, 1814, 1814, 1753, 1753, 1753, 1753, 1753, 1753, + /* 240 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 250 */ 1753, 2102, 2088, 1753, 1837, 2080, 2078, 1753, 1837, 2076, + /* 260 */ 1753, 1753, 1753, 1753, 2296, 2294, 1753, 2296, 2294, 1753, + /* 270 */ 1753, 1753, 2310, 2306, 2296, 2314, 2312, 2281, 2279, 2344, + /* 280 */ 2331, 2327, 2266, 1753, 1753, 1753, 1753, 1837, 1837, 1753, + /* 290 */ 2294, 1753, 1753, 1753, 1753, 1753, 2294, 1753, 1753, 1837, + /* 300 */ 1753, 1837, 1753, 1753, 1928, 1753, 1753, 1753, 1837, 1785, + /* 310 */ 1753, 2071, 2093, 2053, 2053, 1961, 1961, 1961, 1840, 1758, + /* 320 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 330 */ 1753, 1753, 2309, 2308, 2175, 1753, 2224, 2223, 2222, 2213, + /* 340 */ 2174, 1924, 1753, 2173, 2172, 1753, 1753, 1753, 1753, 1753, + /* 350 */ 1753, 1753, 1753, 1753, 2044, 2043, 2166, 1753, 1753, 2167, + /* 360 */ 2165, 2164, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 370 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 380 */ 1753, 1753, 1753, 1753, 1753, 1753, 2328, 2332, 1753, 1753, + /* 390 */ 1753, 1753, 1753, 1753, 1753, 2249, 1753, 1753, 1753, 2148, + /* 400 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 410 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 420 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 430 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 440 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 450 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 460 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 470 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 480 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 490 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 500 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 510 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 520 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1790, 2153, 1753, + /* 530 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 540 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 550 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 560 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 570 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1878, 1877, 1753, + /* 580 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 590 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 600 */ 1753, 2157, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 610 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 2324, 2282, + /* 620 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 630 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 2148, 1753, + /* 640 */ 2307, 1753, 1753, 2322, 1753, 2326, 1753, 1753, 1753, 1753, + /* 650 */ 1753, 1753, 1753, 2259, 2255, 1753, 1753, 2251, 1753, 1753, + /* 660 */ 1753, 1753, 1753, 1753, 1753, 2156, 1753, 1753, 1753, 1753, + /* 670 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 2147, + /* 680 */ 1753, 2210, 1753, 1753, 1753, 2244, 1753, 1753, 2195, 1753, + /* 690 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 2157, 1753, + /* 700 */ 2160, 1753, 1753, 1753, 1753, 1753, 1955, 1753, 1753, 1753, + /* 710 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1940, + /* 720 */ 1938, 1937, 1936, 1753, 1968, 1753, 1753, 1753, 1964, 1963, + /* 730 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 740 */ 1753, 1753, 1753, 1858, 1753, 1753, 1753, 1753, 1753, 1753, + /* 750 */ 1753, 1753, 1850, 1753, 1849, 1753, 1753, 1753, 1753, 1753, + /* 760 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 770 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + /* 780 */ 1753, 1753, 1753, 1753, 1753, 1753, 1753, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1098,6 +1127,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* DNODE => nothing */ 0, /* PORT => nothing */ 0, /* DNODES => nothing */ + 0, /* RESTORE => nothing */ 0, /* NK_IPTOKEN => nothing */ 0, /* FORCE => nothing */ 0, /* LOCAL => nothing */ @@ -1105,6 +1135,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* BNODE => nothing */ 0, /* SNODE => nothing */ 0, /* MNODE => nothing */ + 0, /* VNODE => nothing */ 0, /* DATABASE => nothing */ 0, /* USE => nothing */ 0, /* FLUSH => nothing */ @@ -1144,7 +1175,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* MAX_SPEED => nothing */ 0, /* START => nothing */ 0, /* TIMESTAMP => nothing */ - 282, /* END => ABORT */ + 284, /* END => ABORT */ 0, /* TABLE => nothing */ 0, /* NK_LP => nothing */ 0, /* NK_RP => nothing */ @@ -1329,56 +1360,56 @@ static const YYCODETYPE yyFallback[] = { 0, /* ASC => nothing */ 0, /* NULLS => nothing */ 0, /* ABORT => nothing */ - 282, /* AFTER => ABORT */ - 282, /* ATTACH => ABORT */ - 282, /* BEFORE => ABORT */ - 282, /* BEGIN => ABORT */ - 282, /* BITAND => ABORT */ - 282, /* BITNOT => ABORT */ - 282, /* BITOR => ABORT */ - 282, /* BLOCKS => ABORT */ - 282, /* CHANGE => ABORT */ - 282, /* COMMA => ABORT */ - 282, /* CONCAT => ABORT */ - 282, /* CONFLICT => ABORT */ - 282, /* COPY => ABORT */ - 282, /* DEFERRED => ABORT */ - 282, /* DELIMITERS => ABORT */ - 282, /* DETACH => ABORT */ - 282, /* DIVIDE => ABORT */ - 282, /* DOT => ABORT */ - 282, /* EACH => ABORT */ - 282, /* FAIL => ABORT */ - 282, /* FILE => ABORT */ - 282, /* FOR => ABORT */ - 282, /* GLOB => ABORT */ - 282, /* ID => ABORT */ - 282, /* IMMEDIATE => ABORT */ - 282, /* IMPORT => ABORT */ - 282, /* INITIALLY => ABORT */ - 282, /* INSTEAD => ABORT */ - 282, /* ISNULL => ABORT */ - 282, /* KEY => ABORT */ - 282, /* MODULES => ABORT */ - 282, /* NK_BITNOT => ABORT */ - 282, /* NK_SEMI => ABORT */ - 282, /* NOTNULL => ABORT */ - 282, /* OF => ABORT */ - 282, /* PLUS => ABORT */ - 282, /* PRIVILEGE => ABORT */ - 282, /* RAISE => ABORT */ - 282, /* RESTRICT => ABORT */ - 282, /* ROW => ABORT */ - 282, /* SEMI => ABORT */ - 282, /* STAR => ABORT */ - 282, /* STATEMENT => ABORT */ - 282, /* STRICT => ABORT */ - 282, /* STRING => ABORT */ - 282, /* TIMES => ABORT */ - 282, /* VALUES => ABORT */ - 282, /* VARIABLE => ABORT */ - 282, /* VIEW => ABORT */ - 282, /* WAL => ABORT */ + 284, /* AFTER => ABORT */ + 284, /* ATTACH => ABORT */ + 284, /* BEFORE => ABORT */ + 284, /* BEGIN => ABORT */ + 284, /* BITAND => ABORT */ + 284, /* BITNOT => ABORT */ + 284, /* BITOR => ABORT */ + 284, /* BLOCKS => ABORT */ + 284, /* CHANGE => ABORT */ + 284, /* COMMA => ABORT */ + 284, /* CONCAT => ABORT */ + 284, /* CONFLICT => ABORT */ + 284, /* COPY => ABORT */ + 284, /* DEFERRED => ABORT */ + 284, /* DELIMITERS => ABORT */ + 284, /* DETACH => ABORT */ + 284, /* DIVIDE => ABORT */ + 284, /* DOT => ABORT */ + 284, /* EACH => ABORT */ + 284, /* FAIL => ABORT */ + 284, /* FILE => ABORT */ + 284, /* FOR => ABORT */ + 284, /* GLOB => ABORT */ + 284, /* ID => ABORT */ + 284, /* IMMEDIATE => ABORT */ + 284, /* IMPORT => ABORT */ + 284, /* INITIALLY => ABORT */ + 284, /* INSTEAD => ABORT */ + 284, /* ISNULL => ABORT */ + 284, /* KEY => ABORT */ + 284, /* MODULES => ABORT */ + 284, /* NK_BITNOT => ABORT */ + 284, /* NK_SEMI => ABORT */ + 284, /* NOTNULL => ABORT */ + 284, /* OF => ABORT */ + 284, /* PLUS => ABORT */ + 284, /* PRIVILEGE => ABORT */ + 284, /* RAISE => ABORT */ + 284, /* RESTRICT => ABORT */ + 284, /* ROW => ABORT */ + 284, /* SEMI => ABORT */ + 284, /* STAR => ABORT */ + 284, /* STATEMENT => ABORT */ + 284, /* STRICT => ABORT */ + 284, /* STRING => ABORT */ + 284, /* TIMES => ABORT */ + 284, /* VALUES => ABORT */ + 284, /* VARIABLE => ABORT */ + 284, /* VIEW => ABORT */ + 284, /* WAL => ABORT */ }; #endif /* YYFALLBACK */ @@ -1518,434 +1549,436 @@ static const char *const yyTokenName[] = { /* 49 */ "DNODE", /* 50 */ "PORT", /* 51 */ "DNODES", - /* 52 */ "NK_IPTOKEN", - /* 53 */ "FORCE", - /* 54 */ "LOCAL", - /* 55 */ "QNODE", - /* 56 */ "BNODE", - /* 57 */ "SNODE", - /* 58 */ "MNODE", - /* 59 */ "DATABASE", - /* 60 */ "USE", - /* 61 */ "FLUSH", - /* 62 */ "TRIM", - /* 63 */ "COMPACT", - /* 64 */ "IF", - /* 65 */ "NOT", - /* 66 */ "EXISTS", - /* 67 */ "BUFFER", - /* 68 */ "CACHEMODEL", - /* 69 */ "CACHESIZE", - /* 70 */ "COMP", - /* 71 */ "DURATION", - /* 72 */ "NK_VARIABLE", - /* 73 */ "MAXROWS", - /* 74 */ "MINROWS", - /* 75 */ "KEEP", - /* 76 */ "PAGES", - /* 77 */ "PAGESIZE", - /* 78 */ "TSDB_PAGESIZE", - /* 79 */ "PRECISION", - /* 80 */ "REPLICA", - /* 81 */ "VGROUPS", - /* 82 */ "SINGLE_STABLE", - /* 83 */ "RETENTIONS", - /* 84 */ "SCHEMALESS", - /* 85 */ "WAL_LEVEL", - /* 86 */ "WAL_FSYNC_PERIOD", - /* 87 */ "WAL_RETENTION_PERIOD", - /* 88 */ "WAL_RETENTION_SIZE", - /* 89 */ "WAL_ROLL_PERIOD", - /* 90 */ "WAL_SEGMENT_SIZE", - /* 91 */ "STT_TRIGGER", - /* 92 */ "TABLE_PREFIX", - /* 93 */ "TABLE_SUFFIX", - /* 94 */ "NK_COLON", - /* 95 */ "MAX_SPEED", - /* 96 */ "START", - /* 97 */ "TIMESTAMP", - /* 98 */ "END", - /* 99 */ "TABLE", - /* 100 */ "NK_LP", - /* 101 */ "NK_RP", - /* 102 */ "STABLE", - /* 103 */ "ADD", - /* 104 */ "COLUMN", - /* 105 */ "MODIFY", - /* 106 */ "RENAME", - /* 107 */ "TAG", - /* 108 */ "SET", - /* 109 */ "NK_EQ", - /* 110 */ "USING", - /* 111 */ "TAGS", - /* 112 */ "BOOL", - /* 113 */ "TINYINT", - /* 114 */ "SMALLINT", - /* 115 */ "INT", - /* 116 */ "INTEGER", - /* 117 */ "BIGINT", - /* 118 */ "FLOAT", - /* 119 */ "DOUBLE", - /* 120 */ "BINARY", - /* 121 */ "NCHAR", - /* 122 */ "UNSIGNED", - /* 123 */ "JSON", - /* 124 */ "VARCHAR", - /* 125 */ "MEDIUMBLOB", - /* 126 */ "BLOB", - /* 127 */ "VARBINARY", - /* 128 */ "DECIMAL", - /* 129 */ "COMMENT", - /* 130 */ "MAX_DELAY", - /* 131 */ "WATERMARK", - /* 132 */ "ROLLUP", - /* 133 */ "TTL", - /* 134 */ "SMA", - /* 135 */ "DELETE_MARK", - /* 136 */ "FIRST", - /* 137 */ "LAST", - /* 138 */ "SHOW", - /* 139 */ "PRIVILEGES", - /* 140 */ "DATABASES", - /* 141 */ "TABLES", - /* 142 */ "STABLES", - /* 143 */ "MNODES", - /* 144 */ "QNODES", - /* 145 */ "FUNCTIONS", - /* 146 */ "INDEXES", - /* 147 */ "ACCOUNTS", - /* 148 */ "APPS", - /* 149 */ "CONNECTIONS", - /* 150 */ "LICENCES", - /* 151 */ "GRANTS", - /* 152 */ "QUERIES", - /* 153 */ "SCORES", - /* 154 */ "TOPICS", - /* 155 */ "VARIABLES", - /* 156 */ "CLUSTER", - /* 157 */ "BNODES", - /* 158 */ "SNODES", - /* 159 */ "TRANSACTIONS", - /* 160 */ "DISTRIBUTED", - /* 161 */ "CONSUMERS", - /* 162 */ "SUBSCRIPTIONS", - /* 163 */ "VNODES", - /* 164 */ "ALIVE", - /* 165 */ "LIKE", - /* 166 */ "TBNAME", - /* 167 */ "QTAGS", - /* 168 */ "AS", - /* 169 */ "INDEX", - /* 170 */ "FUNCTION", - /* 171 */ "INTERVAL", - /* 172 */ "COUNT", - /* 173 */ "LAST_ROW", - /* 174 */ "TOPIC", - /* 175 */ "META", - /* 176 */ "CONSUMER", - /* 177 */ "GROUP", - /* 178 */ "DESC", - /* 179 */ "DESCRIBE", - /* 180 */ "RESET", - /* 181 */ "QUERY", - /* 182 */ "CACHE", - /* 183 */ "EXPLAIN", - /* 184 */ "ANALYZE", - /* 185 */ "VERBOSE", - /* 186 */ "NK_BOOL", - /* 187 */ "RATIO", - /* 188 */ "NK_FLOAT", - /* 189 */ "OUTPUTTYPE", - /* 190 */ "AGGREGATE", - /* 191 */ "BUFSIZE", - /* 192 */ "LANGUAGE", - /* 193 */ "REPLACE", - /* 194 */ "STREAM", - /* 195 */ "INTO", - /* 196 */ "PAUSE", - /* 197 */ "RESUME", - /* 198 */ "TRIGGER", - /* 199 */ "AT_ONCE", - /* 200 */ "WINDOW_CLOSE", - /* 201 */ "IGNORE", - /* 202 */ "EXPIRED", - /* 203 */ "FILL_HISTORY", - /* 204 */ "UPDATE", - /* 205 */ "SUBTABLE", - /* 206 */ "UNTREATED", - /* 207 */ "KILL", - /* 208 */ "CONNECTION", - /* 209 */ "TRANSACTION", - /* 210 */ "BALANCE", - /* 211 */ "VGROUP", - /* 212 */ "LEADER", - /* 213 */ "MERGE", - /* 214 */ "REDISTRIBUTE", - /* 215 */ "SPLIT", - /* 216 */ "DELETE", - /* 217 */ "INSERT", - /* 218 */ "NULL", - /* 219 */ "NK_QUESTION", - /* 220 */ "NK_ARROW", - /* 221 */ "ROWTS", - /* 222 */ "QSTART", - /* 223 */ "QEND", - /* 224 */ "QDURATION", - /* 225 */ "WSTART", - /* 226 */ "WEND", - /* 227 */ "WDURATION", - /* 228 */ "IROWTS", - /* 229 */ "ISFILLED", - /* 230 */ "CAST", - /* 231 */ "NOW", - /* 232 */ "TODAY", - /* 233 */ "TIMEZONE", - /* 234 */ "CLIENT_VERSION", - /* 235 */ "SERVER_VERSION", - /* 236 */ "SERVER_STATUS", - /* 237 */ "CURRENT_USER", - /* 238 */ "CASE", - /* 239 */ "WHEN", - /* 240 */ "THEN", - /* 241 */ "ELSE", - /* 242 */ "BETWEEN", - /* 243 */ "IS", - /* 244 */ "NK_LT", - /* 245 */ "NK_GT", - /* 246 */ "NK_LE", - /* 247 */ "NK_GE", - /* 248 */ "NK_NE", - /* 249 */ "MATCH", - /* 250 */ "NMATCH", - /* 251 */ "CONTAINS", - /* 252 */ "IN", - /* 253 */ "JOIN", - /* 254 */ "INNER", - /* 255 */ "SELECT", - /* 256 */ "DISTINCT", - /* 257 */ "WHERE", - /* 258 */ "PARTITION", - /* 259 */ "BY", - /* 260 */ "SESSION", - /* 261 */ "STATE_WINDOW", - /* 262 */ "EVENT_WINDOW", - /* 263 */ "SLIDING", - /* 264 */ "FILL", - /* 265 */ "VALUE", - /* 266 */ "VALUE_F", - /* 267 */ "NONE", - /* 268 */ "PREV", - /* 269 */ "NULL_F", - /* 270 */ "LINEAR", - /* 271 */ "NEXT", - /* 272 */ "HAVING", - /* 273 */ "RANGE", - /* 274 */ "EVERY", - /* 275 */ "ORDER", - /* 276 */ "SLIMIT", - /* 277 */ "SOFFSET", - /* 278 */ "LIMIT", - /* 279 */ "OFFSET", - /* 280 */ "ASC", - /* 281 */ "NULLS", - /* 282 */ "ABORT", - /* 283 */ "AFTER", - /* 284 */ "ATTACH", - /* 285 */ "BEFORE", - /* 286 */ "BEGIN", - /* 287 */ "BITAND", - /* 288 */ "BITNOT", - /* 289 */ "BITOR", - /* 290 */ "BLOCKS", - /* 291 */ "CHANGE", - /* 292 */ "COMMA", - /* 293 */ "CONCAT", - /* 294 */ "CONFLICT", - /* 295 */ "COPY", - /* 296 */ "DEFERRED", - /* 297 */ "DELIMITERS", - /* 298 */ "DETACH", - /* 299 */ "DIVIDE", - /* 300 */ "DOT", - /* 301 */ "EACH", - /* 302 */ "FAIL", - /* 303 */ "FILE", - /* 304 */ "FOR", - /* 305 */ "GLOB", - /* 306 */ "ID", - /* 307 */ "IMMEDIATE", - /* 308 */ "IMPORT", - /* 309 */ "INITIALLY", - /* 310 */ "INSTEAD", - /* 311 */ "ISNULL", - /* 312 */ "KEY", - /* 313 */ "MODULES", - /* 314 */ "NK_BITNOT", - /* 315 */ "NK_SEMI", - /* 316 */ "NOTNULL", - /* 317 */ "OF", - /* 318 */ "PLUS", - /* 319 */ "PRIVILEGE", - /* 320 */ "RAISE", - /* 321 */ "RESTRICT", - /* 322 */ "ROW", - /* 323 */ "SEMI", - /* 324 */ "STAR", - /* 325 */ "STATEMENT", - /* 326 */ "STRICT", - /* 327 */ "STRING", - /* 328 */ "TIMES", - /* 329 */ "VALUES", - /* 330 */ "VARIABLE", - /* 331 */ "VIEW", - /* 332 */ "WAL", - /* 333 */ "cmd", - /* 334 */ "account_options", - /* 335 */ "alter_account_options", - /* 336 */ "literal", - /* 337 */ "alter_account_option", - /* 338 */ "user_name", - /* 339 */ "sysinfo_opt", - /* 340 */ "privileges", - /* 341 */ "priv_level", - /* 342 */ "with_opt", - /* 343 */ "priv_type_list", - /* 344 */ "priv_type", - /* 345 */ "db_name", - /* 346 */ "table_name", - /* 347 */ "topic_name", - /* 348 */ "search_condition", - /* 349 */ "dnode_endpoint", - /* 350 */ "force_opt", - /* 351 */ "not_exists_opt", - /* 352 */ "db_options", - /* 353 */ "exists_opt", - /* 354 */ "alter_db_options", - /* 355 */ "speed_opt", - /* 356 */ "start_opt", - /* 357 */ "end_opt", - /* 358 */ "integer_list", - /* 359 */ "variable_list", - /* 360 */ "retention_list", - /* 361 */ "signed", - /* 362 */ "alter_db_option", - /* 363 */ "retention", - /* 364 */ "full_table_name", - /* 365 */ "column_def_list", - /* 366 */ "tags_def_opt", - /* 367 */ "table_options", - /* 368 */ "multi_create_clause", - /* 369 */ "tags_def", - /* 370 */ "multi_drop_clause", - /* 371 */ "alter_table_clause", - /* 372 */ "alter_table_options", - /* 373 */ "column_name", - /* 374 */ "type_name", - /* 375 */ "signed_literal", - /* 376 */ "create_subtable_clause", - /* 377 */ "specific_cols_opt", - /* 378 */ "expression_list", - /* 379 */ "drop_table_clause", - /* 380 */ "col_name_list", - /* 381 */ "column_def", - /* 382 */ "duration_list", - /* 383 */ "rollup_func_list", - /* 384 */ "alter_table_option", - /* 385 */ "duration_literal", - /* 386 */ "rollup_func_name", - /* 387 */ "function_name", - /* 388 */ "col_name", - /* 389 */ "db_name_cond_opt", - /* 390 */ "like_pattern_opt", - /* 391 */ "table_name_cond", - /* 392 */ "from_db_opt", - /* 393 */ "tag_list_opt", - /* 394 */ "tag_item", - /* 395 */ "column_alias", - /* 396 */ "full_index_name", - /* 397 */ "index_options", - /* 398 */ "index_name", - /* 399 */ "func_list", - /* 400 */ "sliding_opt", - /* 401 */ "sma_stream_opt", - /* 402 */ "func", - /* 403 */ "sma_func_name", - /* 404 */ "query_or_subquery", - /* 405 */ "cgroup_name", - /* 406 */ "analyze_opt", - /* 407 */ "explain_options", - /* 408 */ "insert_query", - /* 409 */ "or_replace_opt", - /* 410 */ "agg_func_opt", - /* 411 */ "bufsize_opt", - /* 412 */ "language_opt", - /* 413 */ "stream_name", - /* 414 */ "stream_options", - /* 415 */ "col_list_opt", - /* 416 */ "tag_def_or_ref_opt", - /* 417 */ "subtable_opt", - /* 418 */ "ignore_opt", - /* 419 */ "expression", - /* 420 */ "dnode_list", - /* 421 */ "where_clause_opt", - /* 422 */ "literal_func", - /* 423 */ "literal_list", - /* 424 */ "table_alias", - /* 425 */ "expr_or_subquery", - /* 426 */ "pseudo_column", - /* 427 */ "column_reference", - /* 428 */ "function_expression", - /* 429 */ "case_when_expression", - /* 430 */ "star_func", - /* 431 */ "star_func_para_list", - /* 432 */ "noarg_func", - /* 433 */ "other_para_list", - /* 434 */ "star_func_para", - /* 435 */ "when_then_list", - /* 436 */ "case_when_else_opt", - /* 437 */ "common_expression", - /* 438 */ "when_then_expr", - /* 439 */ "predicate", - /* 440 */ "compare_op", - /* 441 */ "in_op", - /* 442 */ "in_predicate_value", - /* 443 */ "boolean_value_expression", - /* 444 */ "boolean_primary", - /* 445 */ "from_clause_opt", - /* 446 */ "table_reference_list", - /* 447 */ "table_reference", - /* 448 */ "table_primary", - /* 449 */ "joined_table", - /* 450 */ "alias_opt", - /* 451 */ "subquery", - /* 452 */ "parenthesized_joined_table", - /* 453 */ "join_type", - /* 454 */ "query_specification", - /* 455 */ "set_quantifier_opt", - /* 456 */ "select_list", - /* 457 */ "partition_by_clause_opt", - /* 458 */ "range_opt", - /* 459 */ "every_opt", - /* 460 */ "fill_opt", - /* 461 */ "twindow_clause_opt", - /* 462 */ "group_by_clause_opt", - /* 463 */ "having_clause_opt", - /* 464 */ "select_item", - /* 465 */ "partition_list", - /* 466 */ "partition_item", - /* 467 */ "fill_mode", - /* 468 */ "group_by_list", - /* 469 */ "query_expression", - /* 470 */ "query_simple", - /* 471 */ "order_by_clause_opt", - /* 472 */ "slimit_clause_opt", - /* 473 */ "limit_clause_opt", - /* 474 */ "union_query_expression", - /* 475 */ "query_simple_or_subquery", - /* 476 */ "sort_specification_list", - /* 477 */ "sort_specification", - /* 478 */ "ordering_specification_opt", - /* 479 */ "null_ordering_opt", + /* 52 */ "RESTORE", + /* 53 */ "NK_IPTOKEN", + /* 54 */ "FORCE", + /* 55 */ "LOCAL", + /* 56 */ "QNODE", + /* 57 */ "BNODE", + /* 58 */ "SNODE", + /* 59 */ "MNODE", + /* 60 */ "VNODE", + /* 61 */ "DATABASE", + /* 62 */ "USE", + /* 63 */ "FLUSH", + /* 64 */ "TRIM", + /* 65 */ "COMPACT", + /* 66 */ "IF", + /* 67 */ "NOT", + /* 68 */ "EXISTS", + /* 69 */ "BUFFER", + /* 70 */ "CACHEMODEL", + /* 71 */ "CACHESIZE", + /* 72 */ "COMP", + /* 73 */ "DURATION", + /* 74 */ "NK_VARIABLE", + /* 75 */ "MAXROWS", + /* 76 */ "MINROWS", + /* 77 */ "KEEP", + /* 78 */ "PAGES", + /* 79 */ "PAGESIZE", + /* 80 */ "TSDB_PAGESIZE", + /* 81 */ "PRECISION", + /* 82 */ "REPLICA", + /* 83 */ "VGROUPS", + /* 84 */ "SINGLE_STABLE", + /* 85 */ "RETENTIONS", + /* 86 */ "SCHEMALESS", + /* 87 */ "WAL_LEVEL", + /* 88 */ "WAL_FSYNC_PERIOD", + /* 89 */ "WAL_RETENTION_PERIOD", + /* 90 */ "WAL_RETENTION_SIZE", + /* 91 */ "WAL_ROLL_PERIOD", + /* 92 */ "WAL_SEGMENT_SIZE", + /* 93 */ "STT_TRIGGER", + /* 94 */ "TABLE_PREFIX", + /* 95 */ "TABLE_SUFFIX", + /* 96 */ "NK_COLON", + /* 97 */ "MAX_SPEED", + /* 98 */ "START", + /* 99 */ "TIMESTAMP", + /* 100 */ "END", + /* 101 */ "TABLE", + /* 102 */ "NK_LP", + /* 103 */ "NK_RP", + /* 104 */ "STABLE", + /* 105 */ "ADD", + /* 106 */ "COLUMN", + /* 107 */ "MODIFY", + /* 108 */ "RENAME", + /* 109 */ "TAG", + /* 110 */ "SET", + /* 111 */ "NK_EQ", + /* 112 */ "USING", + /* 113 */ "TAGS", + /* 114 */ "BOOL", + /* 115 */ "TINYINT", + /* 116 */ "SMALLINT", + /* 117 */ "INT", + /* 118 */ "INTEGER", + /* 119 */ "BIGINT", + /* 120 */ "FLOAT", + /* 121 */ "DOUBLE", + /* 122 */ "BINARY", + /* 123 */ "NCHAR", + /* 124 */ "UNSIGNED", + /* 125 */ "JSON", + /* 126 */ "VARCHAR", + /* 127 */ "MEDIUMBLOB", + /* 128 */ "BLOB", + /* 129 */ "VARBINARY", + /* 130 */ "DECIMAL", + /* 131 */ "COMMENT", + /* 132 */ "MAX_DELAY", + /* 133 */ "WATERMARK", + /* 134 */ "ROLLUP", + /* 135 */ "TTL", + /* 136 */ "SMA", + /* 137 */ "DELETE_MARK", + /* 138 */ "FIRST", + /* 139 */ "LAST", + /* 140 */ "SHOW", + /* 141 */ "PRIVILEGES", + /* 142 */ "DATABASES", + /* 143 */ "TABLES", + /* 144 */ "STABLES", + /* 145 */ "MNODES", + /* 146 */ "QNODES", + /* 147 */ "FUNCTIONS", + /* 148 */ "INDEXES", + /* 149 */ "ACCOUNTS", + /* 150 */ "APPS", + /* 151 */ "CONNECTIONS", + /* 152 */ "LICENCES", + /* 153 */ "GRANTS", + /* 154 */ "QUERIES", + /* 155 */ "SCORES", + /* 156 */ "TOPICS", + /* 157 */ "VARIABLES", + /* 158 */ "CLUSTER", + /* 159 */ "BNODES", + /* 160 */ "SNODES", + /* 161 */ "TRANSACTIONS", + /* 162 */ "DISTRIBUTED", + /* 163 */ "CONSUMERS", + /* 164 */ "SUBSCRIPTIONS", + /* 165 */ "VNODES", + /* 166 */ "ALIVE", + /* 167 */ "LIKE", + /* 168 */ "TBNAME", + /* 169 */ "QTAGS", + /* 170 */ "AS", + /* 171 */ "INDEX", + /* 172 */ "FUNCTION", + /* 173 */ "INTERVAL", + /* 174 */ "COUNT", + /* 175 */ "LAST_ROW", + /* 176 */ "TOPIC", + /* 177 */ "META", + /* 178 */ "CONSUMER", + /* 179 */ "GROUP", + /* 180 */ "DESC", + /* 181 */ "DESCRIBE", + /* 182 */ "RESET", + /* 183 */ "QUERY", + /* 184 */ "CACHE", + /* 185 */ "EXPLAIN", + /* 186 */ "ANALYZE", + /* 187 */ "VERBOSE", + /* 188 */ "NK_BOOL", + /* 189 */ "RATIO", + /* 190 */ "NK_FLOAT", + /* 191 */ "OUTPUTTYPE", + /* 192 */ "AGGREGATE", + /* 193 */ "BUFSIZE", + /* 194 */ "LANGUAGE", + /* 195 */ "REPLACE", + /* 196 */ "STREAM", + /* 197 */ "INTO", + /* 198 */ "PAUSE", + /* 199 */ "RESUME", + /* 200 */ "TRIGGER", + /* 201 */ "AT_ONCE", + /* 202 */ "WINDOW_CLOSE", + /* 203 */ "IGNORE", + /* 204 */ "EXPIRED", + /* 205 */ "FILL_HISTORY", + /* 206 */ "UPDATE", + /* 207 */ "SUBTABLE", + /* 208 */ "UNTREATED", + /* 209 */ "KILL", + /* 210 */ "CONNECTION", + /* 211 */ "TRANSACTION", + /* 212 */ "BALANCE", + /* 213 */ "VGROUP", + /* 214 */ "LEADER", + /* 215 */ "MERGE", + /* 216 */ "REDISTRIBUTE", + /* 217 */ "SPLIT", + /* 218 */ "DELETE", + /* 219 */ "INSERT", + /* 220 */ "NULL", + /* 221 */ "NK_QUESTION", + /* 222 */ "NK_ARROW", + /* 223 */ "ROWTS", + /* 224 */ "QSTART", + /* 225 */ "QEND", + /* 226 */ "QDURATION", + /* 227 */ "WSTART", + /* 228 */ "WEND", + /* 229 */ "WDURATION", + /* 230 */ "IROWTS", + /* 231 */ "ISFILLED", + /* 232 */ "CAST", + /* 233 */ "NOW", + /* 234 */ "TODAY", + /* 235 */ "TIMEZONE", + /* 236 */ "CLIENT_VERSION", + /* 237 */ "SERVER_VERSION", + /* 238 */ "SERVER_STATUS", + /* 239 */ "CURRENT_USER", + /* 240 */ "CASE", + /* 241 */ "WHEN", + /* 242 */ "THEN", + /* 243 */ "ELSE", + /* 244 */ "BETWEEN", + /* 245 */ "IS", + /* 246 */ "NK_LT", + /* 247 */ "NK_GT", + /* 248 */ "NK_LE", + /* 249 */ "NK_GE", + /* 250 */ "NK_NE", + /* 251 */ "MATCH", + /* 252 */ "NMATCH", + /* 253 */ "CONTAINS", + /* 254 */ "IN", + /* 255 */ "JOIN", + /* 256 */ "INNER", + /* 257 */ "SELECT", + /* 258 */ "DISTINCT", + /* 259 */ "WHERE", + /* 260 */ "PARTITION", + /* 261 */ "BY", + /* 262 */ "SESSION", + /* 263 */ "STATE_WINDOW", + /* 264 */ "EVENT_WINDOW", + /* 265 */ "SLIDING", + /* 266 */ "FILL", + /* 267 */ "VALUE", + /* 268 */ "VALUE_F", + /* 269 */ "NONE", + /* 270 */ "PREV", + /* 271 */ "NULL_F", + /* 272 */ "LINEAR", + /* 273 */ "NEXT", + /* 274 */ "HAVING", + /* 275 */ "RANGE", + /* 276 */ "EVERY", + /* 277 */ "ORDER", + /* 278 */ "SLIMIT", + /* 279 */ "SOFFSET", + /* 280 */ "LIMIT", + /* 281 */ "OFFSET", + /* 282 */ "ASC", + /* 283 */ "NULLS", + /* 284 */ "ABORT", + /* 285 */ "AFTER", + /* 286 */ "ATTACH", + /* 287 */ "BEFORE", + /* 288 */ "BEGIN", + /* 289 */ "BITAND", + /* 290 */ "BITNOT", + /* 291 */ "BITOR", + /* 292 */ "BLOCKS", + /* 293 */ "CHANGE", + /* 294 */ "COMMA", + /* 295 */ "CONCAT", + /* 296 */ "CONFLICT", + /* 297 */ "COPY", + /* 298 */ "DEFERRED", + /* 299 */ "DELIMITERS", + /* 300 */ "DETACH", + /* 301 */ "DIVIDE", + /* 302 */ "DOT", + /* 303 */ "EACH", + /* 304 */ "FAIL", + /* 305 */ "FILE", + /* 306 */ "FOR", + /* 307 */ "GLOB", + /* 308 */ "ID", + /* 309 */ "IMMEDIATE", + /* 310 */ "IMPORT", + /* 311 */ "INITIALLY", + /* 312 */ "INSTEAD", + /* 313 */ "ISNULL", + /* 314 */ "KEY", + /* 315 */ "MODULES", + /* 316 */ "NK_BITNOT", + /* 317 */ "NK_SEMI", + /* 318 */ "NOTNULL", + /* 319 */ "OF", + /* 320 */ "PLUS", + /* 321 */ "PRIVILEGE", + /* 322 */ "RAISE", + /* 323 */ "RESTRICT", + /* 324 */ "ROW", + /* 325 */ "SEMI", + /* 326 */ "STAR", + /* 327 */ "STATEMENT", + /* 328 */ "STRICT", + /* 329 */ "STRING", + /* 330 */ "TIMES", + /* 331 */ "VALUES", + /* 332 */ "VARIABLE", + /* 333 */ "VIEW", + /* 334 */ "WAL", + /* 335 */ "cmd", + /* 336 */ "account_options", + /* 337 */ "alter_account_options", + /* 338 */ "literal", + /* 339 */ "alter_account_option", + /* 340 */ "user_name", + /* 341 */ "sysinfo_opt", + /* 342 */ "privileges", + /* 343 */ "priv_level", + /* 344 */ "with_opt", + /* 345 */ "priv_type_list", + /* 346 */ "priv_type", + /* 347 */ "db_name", + /* 348 */ "table_name", + /* 349 */ "topic_name", + /* 350 */ "search_condition", + /* 351 */ "dnode_endpoint", + /* 352 */ "force_opt", + /* 353 */ "not_exists_opt", + /* 354 */ "db_options", + /* 355 */ "exists_opt", + /* 356 */ "alter_db_options", + /* 357 */ "speed_opt", + /* 358 */ "start_opt", + /* 359 */ "end_opt", + /* 360 */ "integer_list", + /* 361 */ "variable_list", + /* 362 */ "retention_list", + /* 363 */ "signed", + /* 364 */ "alter_db_option", + /* 365 */ "retention", + /* 366 */ "full_table_name", + /* 367 */ "column_def_list", + /* 368 */ "tags_def_opt", + /* 369 */ "table_options", + /* 370 */ "multi_create_clause", + /* 371 */ "tags_def", + /* 372 */ "multi_drop_clause", + /* 373 */ "alter_table_clause", + /* 374 */ "alter_table_options", + /* 375 */ "column_name", + /* 376 */ "type_name", + /* 377 */ "signed_literal", + /* 378 */ "create_subtable_clause", + /* 379 */ "specific_cols_opt", + /* 380 */ "expression_list", + /* 381 */ "drop_table_clause", + /* 382 */ "col_name_list", + /* 383 */ "column_def", + /* 384 */ "duration_list", + /* 385 */ "rollup_func_list", + /* 386 */ "alter_table_option", + /* 387 */ "duration_literal", + /* 388 */ "rollup_func_name", + /* 389 */ "function_name", + /* 390 */ "col_name", + /* 391 */ "db_name_cond_opt", + /* 392 */ "like_pattern_opt", + /* 393 */ "table_name_cond", + /* 394 */ "from_db_opt", + /* 395 */ "tag_list_opt", + /* 396 */ "tag_item", + /* 397 */ "column_alias", + /* 398 */ "full_index_name", + /* 399 */ "index_options", + /* 400 */ "index_name", + /* 401 */ "func_list", + /* 402 */ "sliding_opt", + /* 403 */ "sma_stream_opt", + /* 404 */ "func", + /* 405 */ "sma_func_name", + /* 406 */ "query_or_subquery", + /* 407 */ "cgroup_name", + /* 408 */ "analyze_opt", + /* 409 */ "explain_options", + /* 410 */ "insert_query", + /* 411 */ "or_replace_opt", + /* 412 */ "agg_func_opt", + /* 413 */ "bufsize_opt", + /* 414 */ "language_opt", + /* 415 */ "stream_name", + /* 416 */ "stream_options", + /* 417 */ "col_list_opt", + /* 418 */ "tag_def_or_ref_opt", + /* 419 */ "subtable_opt", + /* 420 */ "ignore_opt", + /* 421 */ "expression", + /* 422 */ "dnode_list", + /* 423 */ "where_clause_opt", + /* 424 */ "literal_func", + /* 425 */ "literal_list", + /* 426 */ "table_alias", + /* 427 */ "expr_or_subquery", + /* 428 */ "pseudo_column", + /* 429 */ "column_reference", + /* 430 */ "function_expression", + /* 431 */ "case_when_expression", + /* 432 */ "star_func", + /* 433 */ "star_func_para_list", + /* 434 */ "noarg_func", + /* 435 */ "other_para_list", + /* 436 */ "star_func_para", + /* 437 */ "when_then_list", + /* 438 */ "case_when_else_opt", + /* 439 */ "common_expression", + /* 440 */ "when_then_expr", + /* 441 */ "predicate", + /* 442 */ "compare_op", + /* 443 */ "in_op", + /* 444 */ "in_predicate_value", + /* 445 */ "boolean_value_expression", + /* 446 */ "boolean_primary", + /* 447 */ "from_clause_opt", + /* 448 */ "table_reference_list", + /* 449 */ "table_reference", + /* 450 */ "table_primary", + /* 451 */ "joined_table", + /* 452 */ "alias_opt", + /* 453 */ "subquery", + /* 454 */ "parenthesized_joined_table", + /* 455 */ "join_type", + /* 456 */ "query_specification", + /* 457 */ "set_quantifier_opt", + /* 458 */ "select_list", + /* 459 */ "partition_by_clause_opt", + /* 460 */ "range_opt", + /* 461 */ "every_opt", + /* 462 */ "fill_opt", + /* 463 */ "twindow_clause_opt", + /* 464 */ "group_by_clause_opt", + /* 465 */ "having_clause_opt", + /* 466 */ "select_item", + /* 467 */ "partition_list", + /* 468 */ "partition_item", + /* 469 */ "fill_mode", + /* 470 */ "group_by_list", + /* 471 */ "query_expression", + /* 472 */ "query_simple", + /* 473 */ "order_by_clause_opt", + /* 474 */ "slimit_clause_opt", + /* 475 */ "limit_clause_opt", + /* 476 */ "union_query_expression", + /* 477 */ "query_simple_or_subquery", + /* 478 */ "sort_specification_list", + /* 479 */ "sort_specification", + /* 480 */ "ordering_specification_opt", + /* 481 */ "null_ordering_opt", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -2007,539 +2040,543 @@ static const char *const yyRuleName[] = { /* 51 */ "cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING", /* 52 */ "cmd ::= ALTER ALL DNODES NK_STRING", /* 53 */ "cmd ::= ALTER ALL DNODES NK_STRING NK_STRING", - /* 54 */ "dnode_endpoint ::= NK_STRING", - /* 55 */ "dnode_endpoint ::= NK_ID", - /* 56 */ "dnode_endpoint ::= NK_IPTOKEN", - /* 57 */ "force_opt ::=", - /* 58 */ "force_opt ::= FORCE", - /* 59 */ "cmd ::= ALTER LOCAL NK_STRING", - /* 60 */ "cmd ::= ALTER LOCAL NK_STRING NK_STRING", - /* 61 */ "cmd ::= CREATE QNODE ON DNODE NK_INTEGER", - /* 62 */ "cmd ::= DROP QNODE ON DNODE NK_INTEGER", - /* 63 */ "cmd ::= CREATE BNODE ON DNODE NK_INTEGER", - /* 64 */ "cmd ::= DROP BNODE ON DNODE NK_INTEGER", - /* 65 */ "cmd ::= CREATE SNODE ON DNODE NK_INTEGER", - /* 66 */ "cmd ::= DROP SNODE ON DNODE NK_INTEGER", - /* 67 */ "cmd ::= CREATE MNODE ON DNODE NK_INTEGER", - /* 68 */ "cmd ::= DROP MNODE ON DNODE NK_INTEGER", - /* 69 */ "cmd ::= CREATE DATABASE not_exists_opt db_name db_options", - /* 70 */ "cmd ::= DROP DATABASE exists_opt db_name", - /* 71 */ "cmd ::= USE db_name", - /* 72 */ "cmd ::= ALTER DATABASE db_name alter_db_options", - /* 73 */ "cmd ::= FLUSH DATABASE db_name", - /* 74 */ "cmd ::= TRIM DATABASE db_name speed_opt", - /* 75 */ "cmd ::= COMPACT DATABASE db_name start_opt end_opt", - /* 76 */ "not_exists_opt ::= IF NOT EXISTS", - /* 77 */ "not_exists_opt ::=", - /* 78 */ "exists_opt ::= IF EXISTS", - /* 79 */ "exists_opt ::=", - /* 80 */ "db_options ::=", - /* 81 */ "db_options ::= db_options BUFFER NK_INTEGER", - /* 82 */ "db_options ::= db_options CACHEMODEL NK_STRING", - /* 83 */ "db_options ::= db_options CACHESIZE NK_INTEGER", - /* 84 */ "db_options ::= db_options COMP NK_INTEGER", - /* 85 */ "db_options ::= db_options DURATION NK_INTEGER", - /* 86 */ "db_options ::= db_options DURATION NK_VARIABLE", - /* 87 */ "db_options ::= db_options MAXROWS NK_INTEGER", - /* 88 */ "db_options ::= db_options MINROWS NK_INTEGER", - /* 89 */ "db_options ::= db_options KEEP integer_list", - /* 90 */ "db_options ::= db_options KEEP variable_list", - /* 91 */ "db_options ::= db_options PAGES NK_INTEGER", - /* 92 */ "db_options ::= db_options PAGESIZE NK_INTEGER", - /* 93 */ "db_options ::= db_options TSDB_PAGESIZE NK_INTEGER", - /* 94 */ "db_options ::= db_options PRECISION NK_STRING", - /* 95 */ "db_options ::= db_options REPLICA NK_INTEGER", - /* 96 */ "db_options ::= db_options VGROUPS NK_INTEGER", - /* 97 */ "db_options ::= db_options SINGLE_STABLE NK_INTEGER", - /* 98 */ "db_options ::= db_options RETENTIONS retention_list", - /* 99 */ "db_options ::= db_options SCHEMALESS NK_INTEGER", - /* 100 */ "db_options ::= db_options WAL_LEVEL NK_INTEGER", - /* 101 */ "db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER", - /* 102 */ "db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER", - /* 103 */ "db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER", - /* 104 */ "db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER", - /* 105 */ "db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER", - /* 106 */ "db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER", - /* 107 */ "db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER", - /* 108 */ "db_options ::= db_options STT_TRIGGER NK_INTEGER", - /* 109 */ "db_options ::= db_options TABLE_PREFIX signed", - /* 110 */ "db_options ::= db_options TABLE_SUFFIX signed", - /* 111 */ "alter_db_options ::= alter_db_option", - /* 112 */ "alter_db_options ::= alter_db_options alter_db_option", - /* 113 */ "alter_db_option ::= BUFFER NK_INTEGER", - /* 114 */ "alter_db_option ::= CACHEMODEL NK_STRING", - /* 115 */ "alter_db_option ::= CACHESIZE NK_INTEGER", - /* 116 */ "alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER", - /* 117 */ "alter_db_option ::= KEEP integer_list", - /* 118 */ "alter_db_option ::= KEEP variable_list", - /* 119 */ "alter_db_option ::= PAGES NK_INTEGER", - /* 120 */ "alter_db_option ::= REPLICA NK_INTEGER", - /* 121 */ "alter_db_option ::= WAL_LEVEL NK_INTEGER", - /* 122 */ "alter_db_option ::= STT_TRIGGER NK_INTEGER", - /* 123 */ "alter_db_option ::= MINROWS NK_INTEGER", - /* 124 */ "alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER", - /* 125 */ "alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER", - /* 126 */ "alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER", - /* 127 */ "alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER", - /* 128 */ "integer_list ::= NK_INTEGER", - /* 129 */ "integer_list ::= integer_list NK_COMMA NK_INTEGER", - /* 130 */ "variable_list ::= NK_VARIABLE", - /* 131 */ "variable_list ::= variable_list NK_COMMA NK_VARIABLE", - /* 132 */ "retention_list ::= retention", - /* 133 */ "retention_list ::= retention_list NK_COMMA retention", - /* 134 */ "retention ::= NK_VARIABLE NK_COLON NK_VARIABLE", - /* 135 */ "speed_opt ::=", - /* 136 */ "speed_opt ::= MAX_SPEED NK_INTEGER", - /* 137 */ "start_opt ::=", - /* 138 */ "start_opt ::= START WITH NK_INTEGER", - /* 139 */ "start_opt ::= START WITH NK_STRING", - /* 140 */ "start_opt ::= START WITH TIMESTAMP NK_STRING", - /* 141 */ "end_opt ::=", - /* 142 */ "end_opt ::= END WITH NK_INTEGER", - /* 143 */ "end_opt ::= END WITH NK_STRING", - /* 144 */ "end_opt ::= END WITH TIMESTAMP NK_STRING", - /* 145 */ "cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options", - /* 146 */ "cmd ::= CREATE TABLE multi_create_clause", - /* 147 */ "cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options", - /* 148 */ "cmd ::= DROP TABLE multi_drop_clause", - /* 149 */ "cmd ::= DROP STABLE exists_opt full_table_name", - /* 150 */ "cmd ::= ALTER TABLE alter_table_clause", - /* 151 */ "cmd ::= ALTER STABLE alter_table_clause", - /* 152 */ "alter_table_clause ::= full_table_name alter_table_options", - /* 153 */ "alter_table_clause ::= full_table_name ADD COLUMN column_name type_name", - /* 154 */ "alter_table_clause ::= full_table_name DROP COLUMN column_name", - /* 155 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name", - /* 156 */ "alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name", - /* 157 */ "alter_table_clause ::= full_table_name ADD TAG column_name type_name", - /* 158 */ "alter_table_clause ::= full_table_name DROP TAG column_name", - /* 159 */ "alter_table_clause ::= full_table_name MODIFY TAG column_name type_name", - /* 160 */ "alter_table_clause ::= full_table_name RENAME TAG column_name column_name", - /* 161 */ "alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal", - /* 162 */ "multi_create_clause ::= create_subtable_clause", - /* 163 */ "multi_create_clause ::= multi_create_clause create_subtable_clause", - /* 164 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options", - /* 165 */ "multi_drop_clause ::= drop_table_clause", - /* 166 */ "multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause", - /* 167 */ "drop_table_clause ::= exists_opt full_table_name", - /* 168 */ "specific_cols_opt ::=", - /* 169 */ "specific_cols_opt ::= NK_LP col_name_list NK_RP", - /* 170 */ "full_table_name ::= table_name", - /* 171 */ "full_table_name ::= db_name NK_DOT table_name", - /* 172 */ "column_def_list ::= column_def", - /* 173 */ "column_def_list ::= column_def_list NK_COMMA column_def", - /* 174 */ "column_def ::= column_name type_name", - /* 175 */ "type_name ::= BOOL", - /* 176 */ "type_name ::= TINYINT", - /* 177 */ "type_name ::= SMALLINT", - /* 178 */ "type_name ::= INT", - /* 179 */ "type_name ::= INTEGER", - /* 180 */ "type_name ::= BIGINT", - /* 181 */ "type_name ::= FLOAT", - /* 182 */ "type_name ::= DOUBLE", - /* 183 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", - /* 184 */ "type_name ::= TIMESTAMP", - /* 185 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", - /* 186 */ "type_name ::= TINYINT UNSIGNED", - /* 187 */ "type_name ::= SMALLINT UNSIGNED", - /* 188 */ "type_name ::= INT UNSIGNED", - /* 189 */ "type_name ::= BIGINT UNSIGNED", - /* 190 */ "type_name ::= JSON", - /* 191 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", - /* 192 */ "type_name ::= MEDIUMBLOB", - /* 193 */ "type_name ::= BLOB", - /* 194 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", - /* 195 */ "type_name ::= DECIMAL", - /* 196 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", - /* 197 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", - /* 198 */ "tags_def_opt ::=", - /* 199 */ "tags_def_opt ::= tags_def", - /* 200 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", - /* 201 */ "table_options ::=", - /* 202 */ "table_options ::= table_options COMMENT NK_STRING", - /* 203 */ "table_options ::= table_options MAX_DELAY duration_list", - /* 204 */ "table_options ::= table_options WATERMARK duration_list", - /* 205 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", - /* 206 */ "table_options ::= table_options TTL NK_INTEGER", - /* 207 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", - /* 208 */ "table_options ::= table_options DELETE_MARK duration_list", - /* 209 */ "alter_table_options ::= alter_table_option", - /* 210 */ "alter_table_options ::= alter_table_options alter_table_option", - /* 211 */ "alter_table_option ::= COMMENT NK_STRING", - /* 212 */ "alter_table_option ::= TTL NK_INTEGER", - /* 213 */ "duration_list ::= duration_literal", - /* 214 */ "duration_list ::= duration_list NK_COMMA duration_literal", - /* 215 */ "rollup_func_list ::= rollup_func_name", - /* 216 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", - /* 217 */ "rollup_func_name ::= function_name", - /* 218 */ "rollup_func_name ::= FIRST", - /* 219 */ "rollup_func_name ::= LAST", - /* 220 */ "col_name_list ::= col_name", - /* 221 */ "col_name_list ::= col_name_list NK_COMMA col_name", - /* 222 */ "col_name ::= column_name", - /* 223 */ "cmd ::= SHOW DNODES", - /* 224 */ "cmd ::= SHOW USERS", - /* 225 */ "cmd ::= SHOW USER PRIVILEGES", - /* 226 */ "cmd ::= SHOW DATABASES", - /* 227 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", - /* 228 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", - /* 229 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", - /* 230 */ "cmd ::= SHOW MNODES", - /* 231 */ "cmd ::= SHOW QNODES", - /* 232 */ "cmd ::= SHOW FUNCTIONS", - /* 233 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", - /* 234 */ "cmd ::= SHOW STREAMS", - /* 235 */ "cmd ::= SHOW ACCOUNTS", - /* 236 */ "cmd ::= SHOW APPS", - /* 237 */ "cmd ::= SHOW CONNECTIONS", - /* 238 */ "cmd ::= SHOW LICENCES", - /* 239 */ "cmd ::= SHOW GRANTS", - /* 240 */ "cmd ::= SHOW CREATE DATABASE db_name", - /* 241 */ "cmd ::= SHOW CREATE TABLE full_table_name", - /* 242 */ "cmd ::= SHOW CREATE STABLE full_table_name", - /* 243 */ "cmd ::= SHOW QUERIES", - /* 244 */ "cmd ::= SHOW SCORES", - /* 245 */ "cmd ::= SHOW TOPICS", - /* 246 */ "cmd ::= SHOW VARIABLES", - /* 247 */ "cmd ::= SHOW CLUSTER VARIABLES", - /* 248 */ "cmd ::= SHOW LOCAL VARIABLES", - /* 249 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", - /* 250 */ "cmd ::= SHOW BNODES", - /* 251 */ "cmd ::= SHOW SNODES", - /* 252 */ "cmd ::= SHOW CLUSTER", - /* 253 */ "cmd ::= SHOW TRANSACTIONS", - /* 254 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", - /* 255 */ "cmd ::= SHOW CONSUMERS", - /* 256 */ "cmd ::= SHOW SUBSCRIPTIONS", - /* 257 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", - /* 258 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", - /* 259 */ "cmd ::= SHOW VNODES NK_INTEGER", - /* 260 */ "cmd ::= SHOW VNODES NK_STRING", - /* 261 */ "cmd ::= SHOW db_name_cond_opt ALIVE", - /* 262 */ "cmd ::= SHOW CLUSTER ALIVE", - /* 263 */ "db_name_cond_opt ::=", - /* 264 */ "db_name_cond_opt ::= db_name NK_DOT", - /* 265 */ "like_pattern_opt ::=", - /* 266 */ "like_pattern_opt ::= LIKE NK_STRING", - /* 267 */ "table_name_cond ::= table_name", - /* 268 */ "from_db_opt ::=", - /* 269 */ "from_db_opt ::= FROM db_name", - /* 270 */ "tag_list_opt ::=", - /* 271 */ "tag_list_opt ::= tag_item", - /* 272 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", - /* 273 */ "tag_item ::= TBNAME", - /* 274 */ "tag_item ::= QTAGS", - /* 275 */ "tag_item ::= column_name", - /* 276 */ "tag_item ::= column_name column_alias", - /* 277 */ "tag_item ::= column_name AS column_alias", - /* 278 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", - /* 279 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", - /* 280 */ "cmd ::= DROP INDEX exists_opt full_index_name", - /* 281 */ "full_index_name ::= index_name", - /* 282 */ "full_index_name ::= db_name NK_DOT index_name", - /* 283 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", - /* 284 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", - /* 285 */ "func_list ::= func", - /* 286 */ "func_list ::= func_list NK_COMMA func", - /* 287 */ "func ::= sma_func_name NK_LP expression_list NK_RP", - /* 288 */ "sma_func_name ::= function_name", - /* 289 */ "sma_func_name ::= COUNT", - /* 290 */ "sma_func_name ::= FIRST", - /* 291 */ "sma_func_name ::= LAST", - /* 292 */ "sma_func_name ::= LAST_ROW", - /* 293 */ "sma_stream_opt ::=", - /* 294 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", - /* 295 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", - /* 296 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", - /* 297 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", - /* 298 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name", - /* 299 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name", - /* 300 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name", - /* 301 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name", - /* 302 */ "cmd ::= DROP TOPIC exists_opt topic_name", - /* 303 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", - /* 304 */ "cmd ::= DESC full_table_name", - /* 305 */ "cmd ::= DESCRIBE full_table_name", - /* 306 */ "cmd ::= RESET QUERY CACHE", - /* 307 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", - /* 308 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", - /* 309 */ "analyze_opt ::=", - /* 310 */ "analyze_opt ::= ANALYZE", - /* 311 */ "explain_options ::=", - /* 312 */ "explain_options ::= explain_options VERBOSE NK_BOOL", - /* 313 */ "explain_options ::= explain_options RATIO NK_FLOAT", - /* 314 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", - /* 315 */ "cmd ::= DROP FUNCTION exists_opt function_name", - /* 316 */ "agg_func_opt ::=", - /* 317 */ "agg_func_opt ::= AGGREGATE", - /* 318 */ "bufsize_opt ::=", - /* 319 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", - /* 320 */ "language_opt ::=", - /* 321 */ "language_opt ::= LANGUAGE NK_STRING", - /* 322 */ "or_replace_opt ::=", - /* 323 */ "or_replace_opt ::= OR REPLACE", - /* 324 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", - /* 325 */ "cmd ::= DROP STREAM exists_opt stream_name", - /* 326 */ "cmd ::= PAUSE STREAM exists_opt stream_name", - /* 327 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", - /* 328 */ "col_list_opt ::=", - /* 329 */ "col_list_opt ::= NK_LP col_name_list NK_RP", - /* 330 */ "tag_def_or_ref_opt ::=", - /* 331 */ "tag_def_or_ref_opt ::= tags_def", - /* 332 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", - /* 333 */ "stream_options ::=", - /* 334 */ "stream_options ::= stream_options TRIGGER AT_ONCE", - /* 335 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", - /* 336 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", - /* 337 */ "stream_options ::= stream_options WATERMARK duration_literal", - /* 338 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", - /* 339 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", - /* 340 */ "stream_options ::= stream_options DELETE_MARK duration_literal", - /* 341 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", - /* 342 */ "subtable_opt ::=", - /* 343 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", - /* 344 */ "ignore_opt ::=", - /* 345 */ "ignore_opt ::= IGNORE UNTREATED", - /* 346 */ "cmd ::= KILL CONNECTION NK_INTEGER", - /* 347 */ "cmd ::= KILL QUERY NK_STRING", - /* 348 */ "cmd ::= KILL TRANSACTION NK_INTEGER", - /* 349 */ "cmd ::= BALANCE VGROUP", - /* 350 */ "cmd ::= BALANCE VGROUP LEADER", - /* 351 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", - /* 352 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", - /* 353 */ "cmd ::= SPLIT VGROUP NK_INTEGER", - /* 354 */ "dnode_list ::= DNODE NK_INTEGER", - /* 355 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", - /* 356 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", - /* 357 */ "cmd ::= query_or_subquery", - /* 358 */ "cmd ::= insert_query", - /* 359 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", - /* 360 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", - /* 361 */ "literal ::= NK_INTEGER", - /* 362 */ "literal ::= NK_FLOAT", - /* 363 */ "literal ::= NK_STRING", - /* 364 */ "literal ::= NK_BOOL", - /* 365 */ "literal ::= TIMESTAMP NK_STRING", - /* 366 */ "literal ::= duration_literal", - /* 367 */ "literal ::= NULL", - /* 368 */ "literal ::= NK_QUESTION", - /* 369 */ "duration_literal ::= NK_VARIABLE", - /* 370 */ "signed ::= NK_INTEGER", - /* 371 */ "signed ::= NK_PLUS NK_INTEGER", - /* 372 */ "signed ::= NK_MINUS NK_INTEGER", - /* 373 */ "signed ::= NK_FLOAT", - /* 374 */ "signed ::= NK_PLUS NK_FLOAT", - /* 375 */ "signed ::= NK_MINUS NK_FLOAT", - /* 376 */ "signed_literal ::= signed", - /* 377 */ "signed_literal ::= NK_STRING", - /* 378 */ "signed_literal ::= NK_BOOL", - /* 379 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 380 */ "signed_literal ::= duration_literal", - /* 381 */ "signed_literal ::= NULL", - /* 382 */ "signed_literal ::= literal_func", - /* 383 */ "signed_literal ::= NK_QUESTION", - /* 384 */ "literal_list ::= signed_literal", - /* 385 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 386 */ "db_name ::= NK_ID", - /* 387 */ "table_name ::= NK_ID", - /* 388 */ "column_name ::= NK_ID", - /* 389 */ "function_name ::= NK_ID", - /* 390 */ "table_alias ::= NK_ID", - /* 391 */ "column_alias ::= NK_ID", - /* 392 */ "user_name ::= NK_ID", - /* 393 */ "topic_name ::= NK_ID", - /* 394 */ "stream_name ::= NK_ID", - /* 395 */ "cgroup_name ::= NK_ID", - /* 396 */ "index_name ::= NK_ID", - /* 397 */ "expr_or_subquery ::= expression", - /* 398 */ "expression ::= literal", - /* 399 */ "expression ::= pseudo_column", - /* 400 */ "expression ::= column_reference", - /* 401 */ "expression ::= function_expression", - /* 402 */ "expression ::= case_when_expression", - /* 403 */ "expression ::= NK_LP expression NK_RP", - /* 404 */ "expression ::= NK_PLUS expr_or_subquery", - /* 405 */ "expression ::= NK_MINUS expr_or_subquery", - /* 406 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", - /* 407 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", - /* 408 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", - /* 409 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", - /* 410 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", - /* 411 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 412 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", - /* 413 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", - /* 414 */ "expression_list ::= expr_or_subquery", - /* 415 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", - /* 416 */ "column_reference ::= column_name", - /* 417 */ "column_reference ::= table_name NK_DOT column_name", - /* 418 */ "pseudo_column ::= ROWTS", - /* 419 */ "pseudo_column ::= TBNAME", - /* 420 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 421 */ "pseudo_column ::= QSTART", - /* 422 */ "pseudo_column ::= QEND", - /* 423 */ "pseudo_column ::= QDURATION", - /* 424 */ "pseudo_column ::= WSTART", - /* 425 */ "pseudo_column ::= WEND", - /* 426 */ "pseudo_column ::= WDURATION", - /* 427 */ "pseudo_column ::= IROWTS", - /* 428 */ "pseudo_column ::= ISFILLED", - /* 429 */ "pseudo_column ::= QTAGS", - /* 430 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 431 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 432 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", - /* 433 */ "function_expression ::= literal_func", - /* 434 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 435 */ "literal_func ::= NOW", - /* 436 */ "noarg_func ::= NOW", - /* 437 */ "noarg_func ::= TODAY", - /* 438 */ "noarg_func ::= TIMEZONE", - /* 439 */ "noarg_func ::= DATABASE", - /* 440 */ "noarg_func ::= CLIENT_VERSION", - /* 441 */ "noarg_func ::= SERVER_VERSION", - /* 442 */ "noarg_func ::= SERVER_STATUS", - /* 443 */ "noarg_func ::= CURRENT_USER", - /* 444 */ "noarg_func ::= USER", - /* 445 */ "star_func ::= COUNT", - /* 446 */ "star_func ::= FIRST", - /* 447 */ "star_func ::= LAST", - /* 448 */ "star_func ::= LAST_ROW", - /* 449 */ "star_func_para_list ::= NK_STAR", - /* 450 */ "star_func_para_list ::= other_para_list", - /* 451 */ "other_para_list ::= star_func_para", - /* 452 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 453 */ "star_func_para ::= expr_or_subquery", - /* 454 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 455 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", - /* 456 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", - /* 457 */ "when_then_list ::= when_then_expr", - /* 458 */ "when_then_list ::= when_then_list when_then_expr", - /* 459 */ "when_then_expr ::= WHEN common_expression THEN common_expression", - /* 460 */ "case_when_else_opt ::=", - /* 461 */ "case_when_else_opt ::= ELSE common_expression", - /* 462 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", - /* 463 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", - /* 464 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", - /* 465 */ "predicate ::= expr_or_subquery IS NULL", - /* 466 */ "predicate ::= expr_or_subquery IS NOT NULL", - /* 467 */ "predicate ::= expr_or_subquery in_op in_predicate_value", - /* 468 */ "compare_op ::= NK_LT", - /* 469 */ "compare_op ::= NK_GT", - /* 470 */ "compare_op ::= NK_LE", - /* 471 */ "compare_op ::= NK_GE", - /* 472 */ "compare_op ::= NK_NE", - /* 473 */ "compare_op ::= NK_EQ", - /* 474 */ "compare_op ::= LIKE", - /* 475 */ "compare_op ::= NOT LIKE", - /* 476 */ "compare_op ::= MATCH", - /* 477 */ "compare_op ::= NMATCH", - /* 478 */ "compare_op ::= CONTAINS", - /* 479 */ "in_op ::= IN", - /* 480 */ "in_op ::= NOT IN", - /* 481 */ "in_predicate_value ::= NK_LP literal_list NK_RP", - /* 482 */ "boolean_value_expression ::= boolean_primary", - /* 483 */ "boolean_value_expression ::= NOT boolean_primary", - /* 484 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 485 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 486 */ "boolean_primary ::= predicate", - /* 487 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 488 */ "common_expression ::= expr_or_subquery", - /* 489 */ "common_expression ::= boolean_value_expression", - /* 490 */ "from_clause_opt ::=", - /* 491 */ "from_clause_opt ::= FROM table_reference_list", - /* 492 */ "table_reference_list ::= table_reference", - /* 493 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 494 */ "table_reference ::= table_primary", - /* 495 */ "table_reference ::= joined_table", - /* 496 */ "table_primary ::= table_name alias_opt", - /* 497 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 498 */ "table_primary ::= subquery alias_opt", - /* 499 */ "table_primary ::= parenthesized_joined_table", - /* 500 */ "alias_opt ::=", - /* 501 */ "alias_opt ::= table_alias", - /* 502 */ "alias_opt ::= AS table_alias", - /* 503 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 504 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 505 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 506 */ "join_type ::=", - /* 507 */ "join_type ::= INNER", - /* 508 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 509 */ "set_quantifier_opt ::=", - /* 510 */ "set_quantifier_opt ::= DISTINCT", - /* 511 */ "set_quantifier_opt ::= ALL", - /* 512 */ "select_list ::= select_item", - /* 513 */ "select_list ::= select_list NK_COMMA select_item", - /* 514 */ "select_item ::= NK_STAR", - /* 515 */ "select_item ::= common_expression", - /* 516 */ "select_item ::= common_expression column_alias", - /* 517 */ "select_item ::= common_expression AS column_alias", - /* 518 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 519 */ "where_clause_opt ::=", - /* 520 */ "where_clause_opt ::= WHERE search_condition", - /* 521 */ "partition_by_clause_opt ::=", - /* 522 */ "partition_by_clause_opt ::= PARTITION BY partition_list", - /* 523 */ "partition_list ::= partition_item", - /* 524 */ "partition_list ::= partition_list NK_COMMA partition_item", - /* 525 */ "partition_item ::= expr_or_subquery", - /* 526 */ "partition_item ::= expr_or_subquery column_alias", - /* 527 */ "partition_item ::= expr_or_subquery AS column_alias", - /* 528 */ "twindow_clause_opt ::=", - /* 529 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 530 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", - /* 531 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 532 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 533 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", - /* 534 */ "sliding_opt ::=", - /* 535 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 536 */ "fill_opt ::=", - /* 537 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 538 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", - /* 539 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", - /* 540 */ "fill_mode ::= NONE", - /* 541 */ "fill_mode ::= PREV", - /* 542 */ "fill_mode ::= NULL", - /* 543 */ "fill_mode ::= NULL_F", - /* 544 */ "fill_mode ::= LINEAR", - /* 545 */ "fill_mode ::= NEXT", - /* 546 */ "group_by_clause_opt ::=", - /* 547 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 548 */ "group_by_list ::= expr_or_subquery", - /* 549 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", - /* 550 */ "having_clause_opt ::=", - /* 551 */ "having_clause_opt ::= HAVING search_condition", - /* 552 */ "range_opt ::=", - /* 553 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", - /* 554 */ "every_opt ::=", - /* 555 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 556 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 557 */ "query_simple ::= query_specification", - /* 558 */ "query_simple ::= union_query_expression", - /* 559 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", - /* 560 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", - /* 561 */ "query_simple_or_subquery ::= query_simple", - /* 562 */ "query_simple_or_subquery ::= subquery", - /* 563 */ "query_or_subquery ::= query_expression", - /* 564 */ "query_or_subquery ::= subquery", - /* 565 */ "order_by_clause_opt ::=", - /* 566 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 567 */ "slimit_clause_opt ::=", - /* 568 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 569 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 570 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 571 */ "limit_clause_opt ::=", - /* 572 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 573 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 574 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 575 */ "subquery ::= NK_LP query_expression NK_RP", - /* 576 */ "subquery ::= NK_LP subquery NK_RP", - /* 577 */ "search_condition ::= common_expression", - /* 578 */ "sort_specification_list ::= sort_specification", - /* 579 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 580 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", - /* 581 */ "ordering_specification_opt ::=", - /* 582 */ "ordering_specification_opt ::= ASC", - /* 583 */ "ordering_specification_opt ::= DESC", - /* 584 */ "null_ordering_opt ::=", - /* 585 */ "null_ordering_opt ::= NULLS FIRST", - /* 586 */ "null_ordering_opt ::= NULLS LAST", + /* 54 */ "cmd ::= RESTORE DNODE NK_INTEGER", + /* 55 */ "dnode_endpoint ::= NK_STRING", + /* 56 */ "dnode_endpoint ::= NK_ID", + /* 57 */ "dnode_endpoint ::= NK_IPTOKEN", + /* 58 */ "force_opt ::=", + /* 59 */ "force_opt ::= FORCE", + /* 60 */ "cmd ::= ALTER LOCAL NK_STRING", + /* 61 */ "cmd ::= ALTER LOCAL NK_STRING NK_STRING", + /* 62 */ "cmd ::= CREATE QNODE ON DNODE NK_INTEGER", + /* 63 */ "cmd ::= DROP QNODE ON DNODE NK_INTEGER", + /* 64 */ "cmd ::= RESTORE QNODE ON DNODE NK_INTEGER", + /* 65 */ "cmd ::= CREATE BNODE ON DNODE NK_INTEGER", + /* 66 */ "cmd ::= DROP BNODE ON DNODE NK_INTEGER", + /* 67 */ "cmd ::= CREATE SNODE ON DNODE NK_INTEGER", + /* 68 */ "cmd ::= DROP SNODE ON DNODE NK_INTEGER", + /* 69 */ "cmd ::= CREATE MNODE ON DNODE NK_INTEGER", + /* 70 */ "cmd ::= DROP MNODE ON DNODE NK_INTEGER", + /* 71 */ "cmd ::= RESTORE MNODE ON DNODE NK_INTEGER", + /* 72 */ "cmd ::= RESTORE VNODE ON DNODE NK_INTEGER", + /* 73 */ "cmd ::= CREATE DATABASE not_exists_opt db_name db_options", + /* 74 */ "cmd ::= DROP DATABASE exists_opt db_name", + /* 75 */ "cmd ::= USE db_name", + /* 76 */ "cmd ::= ALTER DATABASE db_name alter_db_options", + /* 77 */ "cmd ::= FLUSH DATABASE db_name", + /* 78 */ "cmd ::= TRIM DATABASE db_name speed_opt", + /* 79 */ "cmd ::= COMPACT DATABASE db_name start_opt end_opt", + /* 80 */ "not_exists_opt ::= IF NOT EXISTS", + /* 81 */ "not_exists_opt ::=", + /* 82 */ "exists_opt ::= IF EXISTS", + /* 83 */ "exists_opt ::=", + /* 84 */ "db_options ::=", + /* 85 */ "db_options ::= db_options BUFFER NK_INTEGER", + /* 86 */ "db_options ::= db_options CACHEMODEL NK_STRING", + /* 87 */ "db_options ::= db_options CACHESIZE NK_INTEGER", + /* 88 */ "db_options ::= db_options COMP NK_INTEGER", + /* 89 */ "db_options ::= db_options DURATION NK_INTEGER", + /* 90 */ "db_options ::= db_options DURATION NK_VARIABLE", + /* 91 */ "db_options ::= db_options MAXROWS NK_INTEGER", + /* 92 */ "db_options ::= db_options MINROWS NK_INTEGER", + /* 93 */ "db_options ::= db_options KEEP integer_list", + /* 94 */ "db_options ::= db_options KEEP variable_list", + /* 95 */ "db_options ::= db_options PAGES NK_INTEGER", + /* 96 */ "db_options ::= db_options PAGESIZE NK_INTEGER", + /* 97 */ "db_options ::= db_options TSDB_PAGESIZE NK_INTEGER", + /* 98 */ "db_options ::= db_options PRECISION NK_STRING", + /* 99 */ "db_options ::= db_options REPLICA NK_INTEGER", + /* 100 */ "db_options ::= db_options VGROUPS NK_INTEGER", + /* 101 */ "db_options ::= db_options SINGLE_STABLE NK_INTEGER", + /* 102 */ "db_options ::= db_options RETENTIONS retention_list", + /* 103 */ "db_options ::= db_options SCHEMALESS NK_INTEGER", + /* 104 */ "db_options ::= db_options WAL_LEVEL NK_INTEGER", + /* 105 */ "db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER", + /* 106 */ "db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER", + /* 107 */ "db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER", + /* 108 */ "db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER", + /* 109 */ "db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER", + /* 110 */ "db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER", + /* 111 */ "db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER", + /* 112 */ "db_options ::= db_options STT_TRIGGER NK_INTEGER", + /* 113 */ "db_options ::= db_options TABLE_PREFIX signed", + /* 114 */ "db_options ::= db_options TABLE_SUFFIX signed", + /* 115 */ "alter_db_options ::= alter_db_option", + /* 116 */ "alter_db_options ::= alter_db_options alter_db_option", + /* 117 */ "alter_db_option ::= BUFFER NK_INTEGER", + /* 118 */ "alter_db_option ::= CACHEMODEL NK_STRING", + /* 119 */ "alter_db_option ::= CACHESIZE NK_INTEGER", + /* 120 */ "alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER", + /* 121 */ "alter_db_option ::= KEEP integer_list", + /* 122 */ "alter_db_option ::= KEEP variable_list", + /* 123 */ "alter_db_option ::= PAGES NK_INTEGER", + /* 124 */ "alter_db_option ::= REPLICA NK_INTEGER", + /* 125 */ "alter_db_option ::= WAL_LEVEL NK_INTEGER", + /* 126 */ "alter_db_option ::= STT_TRIGGER NK_INTEGER", + /* 127 */ "alter_db_option ::= MINROWS NK_INTEGER", + /* 128 */ "alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER", + /* 129 */ "alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER", + /* 130 */ "alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER", + /* 131 */ "alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER", + /* 132 */ "integer_list ::= NK_INTEGER", + /* 133 */ "integer_list ::= integer_list NK_COMMA NK_INTEGER", + /* 134 */ "variable_list ::= NK_VARIABLE", + /* 135 */ "variable_list ::= variable_list NK_COMMA NK_VARIABLE", + /* 136 */ "retention_list ::= retention", + /* 137 */ "retention_list ::= retention_list NK_COMMA retention", + /* 138 */ "retention ::= NK_VARIABLE NK_COLON NK_VARIABLE", + /* 139 */ "speed_opt ::=", + /* 140 */ "speed_opt ::= MAX_SPEED NK_INTEGER", + /* 141 */ "start_opt ::=", + /* 142 */ "start_opt ::= START WITH NK_INTEGER", + /* 143 */ "start_opt ::= START WITH NK_STRING", + /* 144 */ "start_opt ::= START WITH TIMESTAMP NK_STRING", + /* 145 */ "end_opt ::=", + /* 146 */ "end_opt ::= END WITH NK_INTEGER", + /* 147 */ "end_opt ::= END WITH NK_STRING", + /* 148 */ "end_opt ::= END WITH TIMESTAMP NK_STRING", + /* 149 */ "cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options", + /* 150 */ "cmd ::= CREATE TABLE multi_create_clause", + /* 151 */ "cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options", + /* 152 */ "cmd ::= DROP TABLE multi_drop_clause", + /* 153 */ "cmd ::= DROP STABLE exists_opt full_table_name", + /* 154 */ "cmd ::= ALTER TABLE alter_table_clause", + /* 155 */ "cmd ::= ALTER STABLE alter_table_clause", + /* 156 */ "alter_table_clause ::= full_table_name alter_table_options", + /* 157 */ "alter_table_clause ::= full_table_name ADD COLUMN column_name type_name", + /* 158 */ "alter_table_clause ::= full_table_name DROP COLUMN column_name", + /* 159 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name", + /* 160 */ "alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name", + /* 161 */ "alter_table_clause ::= full_table_name ADD TAG column_name type_name", + /* 162 */ "alter_table_clause ::= full_table_name DROP TAG column_name", + /* 163 */ "alter_table_clause ::= full_table_name MODIFY TAG column_name type_name", + /* 164 */ "alter_table_clause ::= full_table_name RENAME TAG column_name column_name", + /* 165 */ "alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal", + /* 166 */ "multi_create_clause ::= create_subtable_clause", + /* 167 */ "multi_create_clause ::= multi_create_clause create_subtable_clause", + /* 168 */ "create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options", + /* 169 */ "multi_drop_clause ::= drop_table_clause", + /* 170 */ "multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause", + /* 171 */ "drop_table_clause ::= exists_opt full_table_name", + /* 172 */ "specific_cols_opt ::=", + /* 173 */ "specific_cols_opt ::= NK_LP col_name_list NK_RP", + /* 174 */ "full_table_name ::= table_name", + /* 175 */ "full_table_name ::= db_name NK_DOT table_name", + /* 176 */ "column_def_list ::= column_def", + /* 177 */ "column_def_list ::= column_def_list NK_COMMA column_def", + /* 178 */ "column_def ::= column_name type_name", + /* 179 */ "type_name ::= BOOL", + /* 180 */ "type_name ::= TINYINT", + /* 181 */ "type_name ::= SMALLINT", + /* 182 */ "type_name ::= INT", + /* 183 */ "type_name ::= INTEGER", + /* 184 */ "type_name ::= BIGINT", + /* 185 */ "type_name ::= FLOAT", + /* 186 */ "type_name ::= DOUBLE", + /* 187 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", + /* 188 */ "type_name ::= TIMESTAMP", + /* 189 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", + /* 190 */ "type_name ::= TINYINT UNSIGNED", + /* 191 */ "type_name ::= SMALLINT UNSIGNED", + /* 192 */ "type_name ::= INT UNSIGNED", + /* 193 */ "type_name ::= BIGINT UNSIGNED", + /* 194 */ "type_name ::= JSON", + /* 195 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", + /* 196 */ "type_name ::= MEDIUMBLOB", + /* 197 */ "type_name ::= BLOB", + /* 198 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", + /* 199 */ "type_name ::= DECIMAL", + /* 200 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", + /* 201 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", + /* 202 */ "tags_def_opt ::=", + /* 203 */ "tags_def_opt ::= tags_def", + /* 204 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", + /* 205 */ "table_options ::=", + /* 206 */ "table_options ::= table_options COMMENT NK_STRING", + /* 207 */ "table_options ::= table_options MAX_DELAY duration_list", + /* 208 */ "table_options ::= table_options WATERMARK duration_list", + /* 209 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", + /* 210 */ "table_options ::= table_options TTL NK_INTEGER", + /* 211 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", + /* 212 */ "table_options ::= table_options DELETE_MARK duration_list", + /* 213 */ "alter_table_options ::= alter_table_option", + /* 214 */ "alter_table_options ::= alter_table_options alter_table_option", + /* 215 */ "alter_table_option ::= COMMENT NK_STRING", + /* 216 */ "alter_table_option ::= TTL NK_INTEGER", + /* 217 */ "duration_list ::= duration_literal", + /* 218 */ "duration_list ::= duration_list NK_COMMA duration_literal", + /* 219 */ "rollup_func_list ::= rollup_func_name", + /* 220 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", + /* 221 */ "rollup_func_name ::= function_name", + /* 222 */ "rollup_func_name ::= FIRST", + /* 223 */ "rollup_func_name ::= LAST", + /* 224 */ "col_name_list ::= col_name", + /* 225 */ "col_name_list ::= col_name_list NK_COMMA col_name", + /* 226 */ "col_name ::= column_name", + /* 227 */ "cmd ::= SHOW DNODES", + /* 228 */ "cmd ::= SHOW USERS", + /* 229 */ "cmd ::= SHOW USER PRIVILEGES", + /* 230 */ "cmd ::= SHOW DATABASES", + /* 231 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", + /* 232 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", + /* 233 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", + /* 234 */ "cmd ::= SHOW MNODES", + /* 235 */ "cmd ::= SHOW QNODES", + /* 236 */ "cmd ::= SHOW FUNCTIONS", + /* 237 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", + /* 238 */ "cmd ::= SHOW STREAMS", + /* 239 */ "cmd ::= SHOW ACCOUNTS", + /* 240 */ "cmd ::= SHOW APPS", + /* 241 */ "cmd ::= SHOW CONNECTIONS", + /* 242 */ "cmd ::= SHOW LICENCES", + /* 243 */ "cmd ::= SHOW GRANTS", + /* 244 */ "cmd ::= SHOW CREATE DATABASE db_name", + /* 245 */ "cmd ::= SHOW CREATE TABLE full_table_name", + /* 246 */ "cmd ::= SHOW CREATE STABLE full_table_name", + /* 247 */ "cmd ::= SHOW QUERIES", + /* 248 */ "cmd ::= SHOW SCORES", + /* 249 */ "cmd ::= SHOW TOPICS", + /* 250 */ "cmd ::= SHOW VARIABLES", + /* 251 */ "cmd ::= SHOW CLUSTER VARIABLES", + /* 252 */ "cmd ::= SHOW LOCAL VARIABLES", + /* 253 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", + /* 254 */ "cmd ::= SHOW BNODES", + /* 255 */ "cmd ::= SHOW SNODES", + /* 256 */ "cmd ::= SHOW CLUSTER", + /* 257 */ "cmd ::= SHOW TRANSACTIONS", + /* 258 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", + /* 259 */ "cmd ::= SHOW CONSUMERS", + /* 260 */ "cmd ::= SHOW SUBSCRIPTIONS", + /* 261 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", + /* 262 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", + /* 263 */ "cmd ::= SHOW VNODES NK_INTEGER", + /* 264 */ "cmd ::= SHOW VNODES NK_STRING", + /* 265 */ "cmd ::= SHOW db_name_cond_opt ALIVE", + /* 266 */ "cmd ::= SHOW CLUSTER ALIVE", + /* 267 */ "db_name_cond_opt ::=", + /* 268 */ "db_name_cond_opt ::= db_name NK_DOT", + /* 269 */ "like_pattern_opt ::=", + /* 270 */ "like_pattern_opt ::= LIKE NK_STRING", + /* 271 */ "table_name_cond ::= table_name", + /* 272 */ "from_db_opt ::=", + /* 273 */ "from_db_opt ::= FROM db_name", + /* 274 */ "tag_list_opt ::=", + /* 275 */ "tag_list_opt ::= tag_item", + /* 276 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", + /* 277 */ "tag_item ::= TBNAME", + /* 278 */ "tag_item ::= QTAGS", + /* 279 */ "tag_item ::= column_name", + /* 280 */ "tag_item ::= column_name column_alias", + /* 281 */ "tag_item ::= column_name AS column_alias", + /* 282 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", + /* 283 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", + /* 284 */ "cmd ::= DROP INDEX exists_opt full_index_name", + /* 285 */ "full_index_name ::= index_name", + /* 286 */ "full_index_name ::= db_name NK_DOT index_name", + /* 287 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", + /* 288 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", + /* 289 */ "func_list ::= func", + /* 290 */ "func_list ::= func_list NK_COMMA func", + /* 291 */ "func ::= sma_func_name NK_LP expression_list NK_RP", + /* 292 */ "sma_func_name ::= function_name", + /* 293 */ "sma_func_name ::= COUNT", + /* 294 */ "sma_func_name ::= FIRST", + /* 295 */ "sma_func_name ::= LAST", + /* 296 */ "sma_func_name ::= LAST_ROW", + /* 297 */ "sma_stream_opt ::=", + /* 298 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", + /* 299 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", + /* 300 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", + /* 301 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", + /* 302 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name", + /* 303 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name", + /* 304 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name", + /* 305 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name", + /* 306 */ "cmd ::= DROP TOPIC exists_opt topic_name", + /* 307 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", + /* 308 */ "cmd ::= DESC full_table_name", + /* 309 */ "cmd ::= DESCRIBE full_table_name", + /* 310 */ "cmd ::= RESET QUERY CACHE", + /* 311 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", + /* 312 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", + /* 313 */ "analyze_opt ::=", + /* 314 */ "analyze_opt ::= ANALYZE", + /* 315 */ "explain_options ::=", + /* 316 */ "explain_options ::= explain_options VERBOSE NK_BOOL", + /* 317 */ "explain_options ::= explain_options RATIO NK_FLOAT", + /* 318 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", + /* 319 */ "cmd ::= DROP FUNCTION exists_opt function_name", + /* 320 */ "agg_func_opt ::=", + /* 321 */ "agg_func_opt ::= AGGREGATE", + /* 322 */ "bufsize_opt ::=", + /* 323 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", + /* 324 */ "language_opt ::=", + /* 325 */ "language_opt ::= LANGUAGE NK_STRING", + /* 326 */ "or_replace_opt ::=", + /* 327 */ "or_replace_opt ::= OR REPLACE", + /* 328 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", + /* 329 */ "cmd ::= DROP STREAM exists_opt stream_name", + /* 330 */ "cmd ::= PAUSE STREAM exists_opt stream_name", + /* 331 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", + /* 332 */ "col_list_opt ::=", + /* 333 */ "col_list_opt ::= NK_LP col_name_list NK_RP", + /* 334 */ "tag_def_or_ref_opt ::=", + /* 335 */ "tag_def_or_ref_opt ::= tags_def", + /* 336 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", + /* 337 */ "stream_options ::=", + /* 338 */ "stream_options ::= stream_options TRIGGER AT_ONCE", + /* 339 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", + /* 340 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", + /* 341 */ "stream_options ::= stream_options WATERMARK duration_literal", + /* 342 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", + /* 343 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", + /* 344 */ "stream_options ::= stream_options DELETE_MARK duration_literal", + /* 345 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", + /* 346 */ "subtable_opt ::=", + /* 347 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", + /* 348 */ "ignore_opt ::=", + /* 349 */ "ignore_opt ::= IGNORE UNTREATED", + /* 350 */ "cmd ::= KILL CONNECTION NK_INTEGER", + /* 351 */ "cmd ::= KILL QUERY NK_STRING", + /* 352 */ "cmd ::= KILL TRANSACTION NK_INTEGER", + /* 353 */ "cmd ::= BALANCE VGROUP", + /* 354 */ "cmd ::= BALANCE VGROUP LEADER", + /* 355 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", + /* 356 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", + /* 357 */ "cmd ::= SPLIT VGROUP NK_INTEGER", + /* 358 */ "dnode_list ::= DNODE NK_INTEGER", + /* 359 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", + /* 360 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", + /* 361 */ "cmd ::= query_or_subquery", + /* 362 */ "cmd ::= insert_query", + /* 363 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", + /* 364 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", + /* 365 */ "literal ::= NK_INTEGER", + /* 366 */ "literal ::= NK_FLOAT", + /* 367 */ "literal ::= NK_STRING", + /* 368 */ "literal ::= NK_BOOL", + /* 369 */ "literal ::= TIMESTAMP NK_STRING", + /* 370 */ "literal ::= duration_literal", + /* 371 */ "literal ::= NULL", + /* 372 */ "literal ::= NK_QUESTION", + /* 373 */ "duration_literal ::= NK_VARIABLE", + /* 374 */ "signed ::= NK_INTEGER", + /* 375 */ "signed ::= NK_PLUS NK_INTEGER", + /* 376 */ "signed ::= NK_MINUS NK_INTEGER", + /* 377 */ "signed ::= NK_FLOAT", + /* 378 */ "signed ::= NK_PLUS NK_FLOAT", + /* 379 */ "signed ::= NK_MINUS NK_FLOAT", + /* 380 */ "signed_literal ::= signed", + /* 381 */ "signed_literal ::= NK_STRING", + /* 382 */ "signed_literal ::= NK_BOOL", + /* 383 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 384 */ "signed_literal ::= duration_literal", + /* 385 */ "signed_literal ::= NULL", + /* 386 */ "signed_literal ::= literal_func", + /* 387 */ "signed_literal ::= NK_QUESTION", + /* 388 */ "literal_list ::= signed_literal", + /* 389 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 390 */ "db_name ::= NK_ID", + /* 391 */ "table_name ::= NK_ID", + /* 392 */ "column_name ::= NK_ID", + /* 393 */ "function_name ::= NK_ID", + /* 394 */ "table_alias ::= NK_ID", + /* 395 */ "column_alias ::= NK_ID", + /* 396 */ "user_name ::= NK_ID", + /* 397 */ "topic_name ::= NK_ID", + /* 398 */ "stream_name ::= NK_ID", + /* 399 */ "cgroup_name ::= NK_ID", + /* 400 */ "index_name ::= NK_ID", + /* 401 */ "expr_or_subquery ::= expression", + /* 402 */ "expression ::= literal", + /* 403 */ "expression ::= pseudo_column", + /* 404 */ "expression ::= column_reference", + /* 405 */ "expression ::= function_expression", + /* 406 */ "expression ::= case_when_expression", + /* 407 */ "expression ::= NK_LP expression NK_RP", + /* 408 */ "expression ::= NK_PLUS expr_or_subquery", + /* 409 */ "expression ::= NK_MINUS expr_or_subquery", + /* 410 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", + /* 411 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", + /* 412 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", + /* 413 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", + /* 414 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", + /* 415 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 416 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", + /* 417 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", + /* 418 */ "expression_list ::= expr_or_subquery", + /* 419 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", + /* 420 */ "column_reference ::= column_name", + /* 421 */ "column_reference ::= table_name NK_DOT column_name", + /* 422 */ "pseudo_column ::= ROWTS", + /* 423 */ "pseudo_column ::= TBNAME", + /* 424 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 425 */ "pseudo_column ::= QSTART", + /* 426 */ "pseudo_column ::= QEND", + /* 427 */ "pseudo_column ::= QDURATION", + /* 428 */ "pseudo_column ::= WSTART", + /* 429 */ "pseudo_column ::= WEND", + /* 430 */ "pseudo_column ::= WDURATION", + /* 431 */ "pseudo_column ::= IROWTS", + /* 432 */ "pseudo_column ::= ISFILLED", + /* 433 */ "pseudo_column ::= QTAGS", + /* 434 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 435 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 436 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", + /* 437 */ "function_expression ::= literal_func", + /* 438 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 439 */ "literal_func ::= NOW", + /* 440 */ "noarg_func ::= NOW", + /* 441 */ "noarg_func ::= TODAY", + /* 442 */ "noarg_func ::= TIMEZONE", + /* 443 */ "noarg_func ::= DATABASE", + /* 444 */ "noarg_func ::= CLIENT_VERSION", + /* 445 */ "noarg_func ::= SERVER_VERSION", + /* 446 */ "noarg_func ::= SERVER_STATUS", + /* 447 */ "noarg_func ::= CURRENT_USER", + /* 448 */ "noarg_func ::= USER", + /* 449 */ "star_func ::= COUNT", + /* 450 */ "star_func ::= FIRST", + /* 451 */ "star_func ::= LAST", + /* 452 */ "star_func ::= LAST_ROW", + /* 453 */ "star_func_para_list ::= NK_STAR", + /* 454 */ "star_func_para_list ::= other_para_list", + /* 455 */ "other_para_list ::= star_func_para", + /* 456 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 457 */ "star_func_para ::= expr_or_subquery", + /* 458 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 459 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", + /* 460 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", + /* 461 */ "when_then_list ::= when_then_expr", + /* 462 */ "when_then_list ::= when_then_list when_then_expr", + /* 463 */ "when_then_expr ::= WHEN common_expression THEN common_expression", + /* 464 */ "case_when_else_opt ::=", + /* 465 */ "case_when_else_opt ::= ELSE common_expression", + /* 466 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", + /* 467 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", + /* 468 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", + /* 469 */ "predicate ::= expr_or_subquery IS NULL", + /* 470 */ "predicate ::= expr_or_subquery IS NOT NULL", + /* 471 */ "predicate ::= expr_or_subquery in_op in_predicate_value", + /* 472 */ "compare_op ::= NK_LT", + /* 473 */ "compare_op ::= NK_GT", + /* 474 */ "compare_op ::= NK_LE", + /* 475 */ "compare_op ::= NK_GE", + /* 476 */ "compare_op ::= NK_NE", + /* 477 */ "compare_op ::= NK_EQ", + /* 478 */ "compare_op ::= LIKE", + /* 479 */ "compare_op ::= NOT LIKE", + /* 480 */ "compare_op ::= MATCH", + /* 481 */ "compare_op ::= NMATCH", + /* 482 */ "compare_op ::= CONTAINS", + /* 483 */ "in_op ::= IN", + /* 484 */ "in_op ::= NOT IN", + /* 485 */ "in_predicate_value ::= NK_LP literal_list NK_RP", + /* 486 */ "boolean_value_expression ::= boolean_primary", + /* 487 */ "boolean_value_expression ::= NOT boolean_primary", + /* 488 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 489 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 490 */ "boolean_primary ::= predicate", + /* 491 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 492 */ "common_expression ::= expr_or_subquery", + /* 493 */ "common_expression ::= boolean_value_expression", + /* 494 */ "from_clause_opt ::=", + /* 495 */ "from_clause_opt ::= FROM table_reference_list", + /* 496 */ "table_reference_list ::= table_reference", + /* 497 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 498 */ "table_reference ::= table_primary", + /* 499 */ "table_reference ::= joined_table", + /* 500 */ "table_primary ::= table_name alias_opt", + /* 501 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 502 */ "table_primary ::= subquery alias_opt", + /* 503 */ "table_primary ::= parenthesized_joined_table", + /* 504 */ "alias_opt ::=", + /* 505 */ "alias_opt ::= table_alias", + /* 506 */ "alias_opt ::= AS table_alias", + /* 507 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 508 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 509 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 510 */ "join_type ::=", + /* 511 */ "join_type ::= INNER", + /* 512 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", + /* 513 */ "set_quantifier_opt ::=", + /* 514 */ "set_quantifier_opt ::= DISTINCT", + /* 515 */ "set_quantifier_opt ::= ALL", + /* 516 */ "select_list ::= select_item", + /* 517 */ "select_list ::= select_list NK_COMMA select_item", + /* 518 */ "select_item ::= NK_STAR", + /* 519 */ "select_item ::= common_expression", + /* 520 */ "select_item ::= common_expression column_alias", + /* 521 */ "select_item ::= common_expression AS column_alias", + /* 522 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 523 */ "where_clause_opt ::=", + /* 524 */ "where_clause_opt ::= WHERE search_condition", + /* 525 */ "partition_by_clause_opt ::=", + /* 526 */ "partition_by_clause_opt ::= PARTITION BY partition_list", + /* 527 */ "partition_list ::= partition_item", + /* 528 */ "partition_list ::= partition_list NK_COMMA partition_item", + /* 529 */ "partition_item ::= expr_or_subquery", + /* 530 */ "partition_item ::= expr_or_subquery column_alias", + /* 531 */ "partition_item ::= expr_or_subquery AS column_alias", + /* 532 */ "twindow_clause_opt ::=", + /* 533 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 534 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", + /* 535 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 536 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 537 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", + /* 538 */ "sliding_opt ::=", + /* 539 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 540 */ "fill_opt ::=", + /* 541 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 542 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", + /* 543 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", + /* 544 */ "fill_mode ::= NONE", + /* 545 */ "fill_mode ::= PREV", + /* 546 */ "fill_mode ::= NULL", + /* 547 */ "fill_mode ::= NULL_F", + /* 548 */ "fill_mode ::= LINEAR", + /* 549 */ "fill_mode ::= NEXT", + /* 550 */ "group_by_clause_opt ::=", + /* 551 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 552 */ "group_by_list ::= expr_or_subquery", + /* 553 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", + /* 554 */ "having_clause_opt ::=", + /* 555 */ "having_clause_opt ::= HAVING search_condition", + /* 556 */ "range_opt ::=", + /* 557 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", + /* 558 */ "every_opt ::=", + /* 559 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 560 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 561 */ "query_simple ::= query_specification", + /* 562 */ "query_simple ::= union_query_expression", + /* 563 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", + /* 564 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", + /* 565 */ "query_simple_or_subquery ::= query_simple", + /* 566 */ "query_simple_or_subquery ::= subquery", + /* 567 */ "query_or_subquery ::= query_expression", + /* 568 */ "query_or_subquery ::= subquery", + /* 569 */ "order_by_clause_opt ::=", + /* 570 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 571 */ "slimit_clause_opt ::=", + /* 572 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 573 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 574 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 575 */ "limit_clause_opt ::=", + /* 576 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 577 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 578 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 579 */ "subquery ::= NK_LP query_expression NK_RP", + /* 580 */ "subquery ::= NK_LP subquery NK_RP", + /* 581 */ "search_condition ::= common_expression", + /* 582 */ "sort_specification_list ::= sort_specification", + /* 583 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 584 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", + /* 585 */ "ordering_specification_opt ::=", + /* 586 */ "ordering_specification_opt ::= ASC", + /* 587 */ "ordering_specification_opt ::= DESC", + /* 588 */ "null_ordering_opt ::=", + /* 589 */ "null_ordering_opt ::= NULLS FIRST", + /* 590 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -2666,211 +2703,241 @@ static void yy_destructor( */ /********* Begin destructor definitions ***************************************/ /* Default NON-TERMINAL Destructor */ - case 333: /* cmd */ - case 336: /* literal */ - case 342: /* with_opt */ - case 348: /* search_condition */ - case 352: /* db_options */ - case 354: /* alter_db_options */ - case 356: /* start_opt */ - case 357: /* end_opt */ - case 361: /* signed */ - case 363: /* retention */ - case 364: /* full_table_name */ - case 367: /* table_options */ - case 371: /* alter_table_clause */ - case 372: /* alter_table_options */ - case 375: /* signed_literal */ - case 376: /* create_subtable_clause */ - case 379: /* drop_table_clause */ - case 381: /* column_def */ - case 385: /* duration_literal */ - case 386: /* rollup_func_name */ - case 388: /* col_name */ - case 389: /* db_name_cond_opt */ - case 390: /* like_pattern_opt */ - case 391: /* table_name_cond */ - case 392: /* from_db_opt */ - case 394: /* tag_item */ - case 396: /* full_index_name */ - case 397: /* index_options */ - case 400: /* sliding_opt */ - case 401: /* sma_stream_opt */ - case 402: /* func */ - case 404: /* query_or_subquery */ - case 407: /* explain_options */ - case 408: /* insert_query */ - case 414: /* stream_options */ - case 417: /* subtable_opt */ - case 419: /* expression */ - case 421: /* where_clause_opt */ - case 422: /* literal_func */ - case 425: /* expr_or_subquery */ - case 426: /* pseudo_column */ - case 427: /* column_reference */ - case 428: /* function_expression */ - case 429: /* case_when_expression */ - case 434: /* star_func_para */ - case 436: /* case_when_else_opt */ - case 437: /* common_expression */ - case 438: /* when_then_expr */ - case 439: /* predicate */ - case 442: /* in_predicate_value */ - case 443: /* boolean_value_expression */ - case 444: /* boolean_primary */ - case 445: /* from_clause_opt */ - case 446: /* table_reference_list */ - case 447: /* table_reference */ - case 448: /* table_primary */ - case 449: /* joined_table */ - case 451: /* subquery */ - case 452: /* parenthesized_joined_table */ - case 454: /* query_specification */ - case 458: /* range_opt */ - case 459: /* every_opt */ - case 460: /* fill_opt */ - case 461: /* twindow_clause_opt */ - case 463: /* having_clause_opt */ - case 464: /* select_item */ - case 466: /* partition_item */ - case 469: /* query_expression */ - case 470: /* query_simple */ - case 472: /* slimit_clause_opt */ - case 473: /* limit_clause_opt */ - case 474: /* union_query_expression */ - case 475: /* query_simple_or_subquery */ - case 477: /* sort_specification */ + case 335: /* cmd */ + case 338: /* literal */ + case 344: /* with_opt */ + case 350: /* search_condition */ + case 354: /* db_options */ + case 356: /* alter_db_options */ + case 358: /* start_opt */ + case 359: /* end_opt */ + case 363: /* signed */ + case 365: /* retention */ + case 366: /* full_table_name */ + case 369: /* table_options */ + case 373: /* alter_table_clause */ + case 374: /* alter_table_options */ + case 377: /* signed_literal */ + case 378: /* create_subtable_clause */ + case 381: /* drop_table_clause */ + case 383: /* column_def */ + case 387: /* duration_literal */ + case 388: /* rollup_func_name */ + case 390: /* col_name */ + case 391: /* db_name_cond_opt */ + case 392: /* like_pattern_opt */ + case 393: /* table_name_cond */ + case 394: /* from_db_opt */ + case 396: /* tag_item */ + case 398: /* full_index_name */ + case 399: /* index_options */ + case 402: /* sliding_opt */ + case 403: /* sma_stream_opt */ + case 404: /* func */ + case 406: /* query_or_subquery */ + case 409: /* explain_options */ + case 410: /* insert_query */ + case 416: /* stream_options */ + case 419: /* subtable_opt */ + case 421: /* expression */ + case 423: /* where_clause_opt */ + case 424: /* literal_func */ + case 427: /* expr_or_subquery */ + case 428: /* pseudo_column */ + case 429: /* column_reference */ + case 430: /* function_expression */ + case 431: /* case_when_expression */ + case 436: /* star_func_para */ + case 438: /* case_when_else_opt */ + case 439: /* common_expression */ + case 440: /* when_then_expr */ + case 441: /* predicate */ + case 444: /* in_predicate_value */ + case 445: /* boolean_value_expression */ + case 446: /* boolean_primary */ + case 447: /* from_clause_opt */ + case 448: /* table_reference_list */ + case 449: /* table_reference */ + case 450: /* table_primary */ + case 451: /* joined_table */ + case 453: /* subquery */ + case 454: /* parenthesized_joined_table */ + case 456: /* query_specification */ + case 460: /* range_opt */ + case 461: /* every_opt */ + case 462: /* fill_opt */ + case 463: /* twindow_clause_opt */ + case 465: /* having_clause_opt */ + case 466: /* select_item */ + case 468: /* partition_item */ + case 471: /* query_expression */ + case 472: /* query_simple */ + case 474: /* slimit_clause_opt */ + case 475: /* limit_clause_opt */ + case 476: /* union_query_expression */ + case 477: /* query_simple_or_subquery */ + case 479: /* sort_specification */ { - nodesDestroyNode((yypminor->yy872)); +#line 7 "sql.y" + nodesDestroyNode((yypminor->yy164)); +#line 2784 "sql.c" } break; - case 334: /* account_options */ - case 335: /* alter_account_options */ - case 337: /* alter_account_option */ - case 355: /* speed_opt */ - case 411: /* bufsize_opt */ + case 336: /* account_options */ + case 337: /* alter_account_options */ + case 339: /* alter_account_option */ + case 357: /* speed_opt */ + case 413: /* bufsize_opt */ { +#line 54 "sql.y" +#line 2795 "sql.c" } break; - case 338: /* user_name */ - case 345: /* db_name */ - case 346: /* table_name */ - case 347: /* topic_name */ - case 349: /* dnode_endpoint */ - case 373: /* column_name */ - case 387: /* function_name */ - case 395: /* column_alias */ - case 398: /* index_name */ - case 403: /* sma_func_name */ - case 405: /* cgroup_name */ - case 412: /* language_opt */ - case 413: /* stream_name */ - case 424: /* table_alias */ - case 430: /* star_func */ - case 432: /* noarg_func */ - case 450: /* alias_opt */ + case 340: /* user_name */ + case 347: /* db_name */ + case 348: /* table_name */ + case 349: /* topic_name */ + case 351: /* dnode_endpoint */ + case 375: /* column_name */ + case 389: /* function_name */ + case 397: /* column_alias */ + case 400: /* index_name */ + case 405: /* sma_func_name */ + case 407: /* cgroup_name */ + case 414: /* language_opt */ + case 415: /* stream_name */ + case 426: /* table_alias */ + case 432: /* star_func */ + case 434: /* noarg_func */ + case 452: /* alias_opt */ { +#line 728 "sql.y" +#line 2818 "sql.c" } break; - case 339: /* sysinfo_opt */ + case 341: /* sysinfo_opt */ { +#line 92 "sql.y" +#line 2825 "sql.c" } break; - case 340: /* privileges */ - case 343: /* priv_type_list */ - case 344: /* priv_type */ + case 342: /* privileges */ + case 345: /* priv_type_list */ + case 346: /* priv_type */ { +#line 101 "sql.y" +#line 2834 "sql.c" } break; - case 341: /* priv_level */ + case 343: /* priv_level */ { +#line 117 "sql.y" +#line 2841 "sql.c" } break; - case 350: /* force_opt */ - case 351: /* not_exists_opt */ - case 353: /* exists_opt */ - case 406: /* analyze_opt */ - case 409: /* or_replace_opt */ - case 410: /* agg_func_opt */ - case 418: /* ignore_opt */ - case 455: /* set_quantifier_opt */ + case 352: /* force_opt */ + case 353: /* not_exists_opt */ + case 355: /* exists_opt */ + case 408: /* analyze_opt */ + case 411: /* or_replace_opt */ + case 412: /* agg_func_opt */ + case 420: /* ignore_opt */ + case 457: /* set_quantifier_opt */ { +#line 144 "sql.y" +#line 2855 "sql.c" } break; - case 358: /* integer_list */ - case 359: /* variable_list */ - case 360: /* retention_list */ - case 365: /* column_def_list */ - case 366: /* tags_def_opt */ - case 368: /* multi_create_clause */ - case 369: /* tags_def */ - case 370: /* multi_drop_clause */ - case 377: /* specific_cols_opt */ - case 378: /* expression_list */ - case 380: /* col_name_list */ - case 382: /* duration_list */ - case 383: /* rollup_func_list */ - case 393: /* tag_list_opt */ - case 399: /* func_list */ - case 415: /* col_list_opt */ - case 416: /* tag_def_or_ref_opt */ - case 420: /* dnode_list */ - case 423: /* literal_list */ - case 431: /* star_func_para_list */ - case 433: /* other_para_list */ - case 435: /* when_then_list */ - case 456: /* select_list */ - case 457: /* partition_by_clause_opt */ - case 462: /* group_by_clause_opt */ - case 465: /* partition_list */ - case 468: /* group_by_list */ - case 471: /* order_by_clause_opt */ - case 476: /* sort_specification_list */ + case 360: /* integer_list */ + case 361: /* variable_list */ + case 362: /* retention_list */ + case 367: /* column_def_list */ + case 368: /* tags_def_opt */ + case 370: /* multi_create_clause */ + case 371: /* tags_def */ + case 372: /* multi_drop_clause */ + case 379: /* specific_cols_opt */ + case 380: /* expression_list */ + case 382: /* col_name_list */ + case 384: /* duration_list */ + case 385: /* rollup_func_list */ + case 395: /* tag_list_opt */ + case 401: /* func_list */ + case 417: /* col_list_opt */ + case 418: /* tag_def_or_ref_opt */ + case 422: /* dnode_list */ + case 425: /* literal_list */ + case 433: /* star_func_para_list */ + case 435: /* other_para_list */ + case 437: /* when_then_list */ + case 458: /* select_list */ + case 459: /* partition_by_clause_opt */ + case 464: /* group_by_clause_opt */ + case 467: /* partition_list */ + case 470: /* group_by_list */ + case 473: /* order_by_clause_opt */ + case 478: /* sort_specification_list */ { - nodesDestroyList((yypminor->yy664)); +#line 264 "sql.y" + nodesDestroyList((yypminor->yy72)); +#line 2890 "sql.c" } break; - case 362: /* alter_db_option */ - case 384: /* alter_table_option */ + case 364: /* alter_db_option */ + case 386: /* alter_table_option */ { +#line 237 "sql.y" +#line 2898 "sql.c" } break; - case 374: /* type_name */ + case 376: /* type_name */ { +#line 358 "sql.y" +#line 2905 "sql.c" } break; - case 440: /* compare_op */ - case 441: /* in_op */ + case 442: /* compare_op */ + case 443: /* in_op */ { +#line 916 "sql.y" +#line 2913 "sql.c" } break; - case 453: /* join_type */ + case 455: /* join_type */ { +#line 992 "sql.y" +#line 2920 "sql.c" } break; - case 467: /* fill_mode */ + case 469: /* fill_mode */ { +#line 1067 "sql.y" +#line 2927 "sql.c" } break; - case 478: /* ordering_specification_opt */ + case 480: /* ordering_specification_opt */ { +#line 1150 "sql.y" +#line 2934 "sql.c" } break; - case 479: /* null_ordering_opt */ + case 481: /* null_ordering_opt */ { +#line 1156 "sql.y" +#line 2941 "sql.c" } break; /********* End destructor definitions *****************************************/ @@ -2996,15 +3063,18 @@ static YYACTIONTYPE yy_find_shift_action( do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); - /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ + assert( i<=YY_ACTTAB_COUNT ); + assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ + assert( i<(int)YY_NLOOKAHEAD ); + if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", @@ -3019,16 +3089,8 @@ static YYACTIONTYPE yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( -#if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && -#endif -#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 - ){ + assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); + if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", @@ -3042,6 +3104,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ + assert( i>=0 && iyytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; + yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", yyTracePrompt, - yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno); + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ yypParser->yyhwm++; @@ -3841,15 +4503,21 @@ static YYACTIONTYPE yy_reduce( /********** Begin reduce actions **********************************************/ YYMINORTYPE yylhsminor; case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ +#line 50 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,334,&yymsp[0].minor); +#line 4509 "sql.c" + yy_destructor(yypParser,336,&yymsp[0].minor); break; case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ +#line 51 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,335,&yymsp[0].minor); +#line 4515 "sql.c" + yy_destructor(yypParser,337,&yymsp[0].minor); break; case 2: /* account_options ::= */ +#line 55 "sql.y" { } +#line 4521 "sql.c" break; case 3: /* account_options ::= account_options PPS literal */ case 4: /* account_options ::= account_options TSERIES literal */ yytestcase(yyruleno==4); @@ -3860,20 +4528,26 @@ static YYACTIONTYPE yy_reduce( case 9: /* account_options ::= account_options USERS literal */ yytestcase(yyruleno==9); case 10: /* account_options ::= account_options CONNS literal */ yytestcase(yyruleno==10); case 11: /* account_options ::= account_options STATE literal */ yytestcase(yyruleno==11); -{ yy_destructor(yypParser,334,&yymsp[-2].minor); +{ yy_destructor(yypParser,336,&yymsp[-2].minor); +#line 56 "sql.y" { } - yy_destructor(yypParser,336,&yymsp[0].minor); +#line 4535 "sql.c" + yy_destructor(yypParser,338,&yymsp[0].minor); } break; case 12: /* alter_account_options ::= alter_account_option */ -{ yy_destructor(yypParser,337,&yymsp[0].minor); +{ yy_destructor(yypParser,339,&yymsp[0].minor); +#line 68 "sql.y" { } +#line 4543 "sql.c" } break; case 13: /* alter_account_options ::= alter_account_options alter_account_option */ -{ yy_destructor(yypParser,335,&yymsp[-1].minor); +{ yy_destructor(yypParser,337,&yymsp[-1].minor); +#line 69 "sql.y" { } - yy_destructor(yypParser,337,&yymsp[0].minor); +#line 4550 "sql.c" + yy_destructor(yypParser,339,&yymsp[0].minor); } break; case 14: /* alter_account_option ::= PASS literal */ @@ -3886,1617 +4560,2413 @@ static YYACTIONTYPE yy_reduce( case 21: /* alter_account_option ::= USERS literal */ yytestcase(yyruleno==21); case 22: /* alter_account_option ::= CONNS literal */ yytestcase(yyruleno==22); case 23: /* alter_account_option ::= STATE literal */ yytestcase(yyruleno==23); +#line 73 "sql.y" { } - yy_destructor(yypParser,336,&yymsp[0].minor); +#line 4566 "sql.c" + yy_destructor(yypParser,338,&yymsp[0].minor); break; case 24: /* cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ -{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy929, &yymsp[-1].minor.yy0, yymsp[0].minor.yy503); } +#line 85 "sql.y" +{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy497, &yymsp[-1].minor.yy0, yymsp[0].minor.yy563); } +#line 4572 "sql.c" break; case 25: /* cmd ::= ALTER USER user_name PASS NK_STRING */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy929, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } +#line 86 "sql.y" +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy497, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } +#line 4577 "sql.c" break; case 26: /* cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy929, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } +#line 87 "sql.y" +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy497, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } +#line 4582 "sql.c" break; case 27: /* cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy929, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } +#line 88 "sql.y" +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy497, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } +#line 4587 "sql.c" break; case 28: /* cmd ::= DROP USER user_name */ -{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy929); } +#line 89 "sql.y" +{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy497); } +#line 4592 "sql.c" break; case 29: /* sysinfo_opt ::= */ -{ yymsp[1].minor.yy503 = 1; } +#line 93 "sql.y" +{ yymsp[1].minor.yy563 = 1; } +#line 4597 "sql.c" break; case 30: /* sysinfo_opt ::= SYSINFO NK_INTEGER */ -{ yymsp[-1].minor.yy503 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } +#line 94 "sql.y" +{ yymsp[-1].minor.yy563 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } +#line 4602 "sql.c" break; case 31: /* cmd ::= GRANT privileges ON priv_level with_opt TO user_name */ -{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-5].minor.yy669, &yymsp[-3].minor.yy57, &yymsp[0].minor.yy929, yymsp[-2].minor.yy872); } +#line 97 "sql.y" +{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-5].minor.yy693, &yymsp[-3].minor.yy953, &yymsp[0].minor.yy497, yymsp[-2].minor.yy164); } +#line 4607 "sql.c" break; case 32: /* cmd ::= REVOKE privileges ON priv_level with_opt FROM user_name */ -{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-5].minor.yy669, &yymsp[-3].minor.yy57, &yymsp[0].minor.yy929, yymsp[-2].minor.yy872); } +#line 98 "sql.y" +{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-5].minor.yy693, &yymsp[-3].minor.yy953, &yymsp[0].minor.yy497, yymsp[-2].minor.yy164); } +#line 4612 "sql.c" break; case 33: /* privileges ::= ALL */ -{ yymsp[0].minor.yy669 = PRIVILEGE_TYPE_ALL; } +#line 102 "sql.y" +{ yymsp[0].minor.yy693 = PRIVILEGE_TYPE_ALL; } +#line 4617 "sql.c" break; case 34: /* privileges ::= priv_type_list */ case 36: /* priv_type_list ::= priv_type */ yytestcase(yyruleno==36); -{ yylhsminor.yy669 = yymsp[0].minor.yy669; } - yymsp[0].minor.yy669 = yylhsminor.yy669; +#line 103 "sql.y" +{ yylhsminor.yy693 = yymsp[0].minor.yy693; } +#line 4623 "sql.c" + yymsp[0].minor.yy693 = yylhsminor.yy693; break; case 35: /* privileges ::= SUBSCRIBE */ -{ yymsp[0].minor.yy669 = PRIVILEGE_TYPE_SUBSCRIBE; } +#line 104 "sql.y" +{ yymsp[0].minor.yy693 = PRIVILEGE_TYPE_SUBSCRIBE; } +#line 4629 "sql.c" break; case 37: /* priv_type_list ::= priv_type_list NK_COMMA priv_type */ -{ yylhsminor.yy669 = yymsp[-2].minor.yy669 | yymsp[0].minor.yy669; } - yymsp[-2].minor.yy669 = yylhsminor.yy669; +#line 109 "sql.y" +{ yylhsminor.yy693 = yymsp[-2].minor.yy693 | yymsp[0].minor.yy693; } +#line 4634 "sql.c" + yymsp[-2].minor.yy693 = yylhsminor.yy693; break; case 38: /* priv_type ::= READ */ -{ yymsp[0].minor.yy669 = PRIVILEGE_TYPE_READ; } +#line 113 "sql.y" +{ yymsp[0].minor.yy693 = PRIVILEGE_TYPE_READ; } +#line 4640 "sql.c" break; case 39: /* priv_type ::= WRITE */ -{ yymsp[0].minor.yy669 = PRIVILEGE_TYPE_WRITE; } +#line 114 "sql.y" +{ yymsp[0].minor.yy693 = PRIVILEGE_TYPE_WRITE; } +#line 4645 "sql.c" break; case 40: /* priv_level ::= NK_STAR NK_DOT NK_STAR */ -{ yylhsminor.yy57.first = yymsp[-2].minor.yy0; yylhsminor.yy57.second = yymsp[0].minor.yy0; } - yymsp[-2].minor.yy57 = yylhsminor.yy57; +#line 118 "sql.y" +{ yylhsminor.yy953.first = yymsp[-2].minor.yy0; yylhsminor.yy953.second = yymsp[0].minor.yy0; } +#line 4650 "sql.c" + yymsp[-2].minor.yy953 = yylhsminor.yy953; break; case 41: /* priv_level ::= db_name NK_DOT NK_STAR */ -{ yylhsminor.yy57.first = yymsp[-2].minor.yy929; yylhsminor.yy57.second = yymsp[0].minor.yy0; } - yymsp[-2].minor.yy57 = yylhsminor.yy57; +#line 119 "sql.y" +{ yylhsminor.yy953.first = yymsp[-2].minor.yy497; yylhsminor.yy953.second = yymsp[0].minor.yy0; } +#line 4656 "sql.c" + yymsp[-2].minor.yy953 = yylhsminor.yy953; break; case 42: /* priv_level ::= db_name NK_DOT table_name */ -{ yylhsminor.yy57.first = yymsp[-2].minor.yy929; yylhsminor.yy57.second = yymsp[0].minor.yy929; } - yymsp[-2].minor.yy57 = yylhsminor.yy57; +#line 120 "sql.y" +{ yylhsminor.yy953.first = yymsp[-2].minor.yy497; yylhsminor.yy953.second = yymsp[0].minor.yy497; } +#line 4662 "sql.c" + yymsp[-2].minor.yy953 = yylhsminor.yy953; break; case 43: /* priv_level ::= topic_name */ -{ yylhsminor.yy57.first = yymsp[0].minor.yy929; yylhsminor.yy57.second = nil_token; } - yymsp[0].minor.yy57 = yylhsminor.yy57; +#line 121 "sql.y" +{ yylhsminor.yy953.first = yymsp[0].minor.yy497; yylhsminor.yy953.second = nil_token; } +#line 4668 "sql.c" + yymsp[0].minor.yy953 = yylhsminor.yy953; break; case 44: /* with_opt ::= */ - case 137: /* start_opt ::= */ yytestcase(yyruleno==137); - case 141: /* end_opt ::= */ yytestcase(yyruleno==141); - case 265: /* like_pattern_opt ::= */ yytestcase(yyruleno==265); - case 342: /* subtable_opt ::= */ yytestcase(yyruleno==342); - case 460: /* case_when_else_opt ::= */ yytestcase(yyruleno==460); - case 490: /* from_clause_opt ::= */ yytestcase(yyruleno==490); - case 519: /* where_clause_opt ::= */ yytestcase(yyruleno==519); - case 528: /* twindow_clause_opt ::= */ yytestcase(yyruleno==528); - case 534: /* sliding_opt ::= */ yytestcase(yyruleno==534); - case 536: /* fill_opt ::= */ yytestcase(yyruleno==536); - case 550: /* having_clause_opt ::= */ yytestcase(yyruleno==550); - case 552: /* range_opt ::= */ yytestcase(yyruleno==552); - case 554: /* every_opt ::= */ yytestcase(yyruleno==554); - case 567: /* slimit_clause_opt ::= */ yytestcase(yyruleno==567); - case 571: /* limit_clause_opt ::= */ yytestcase(yyruleno==571); -{ yymsp[1].minor.yy872 = NULL; } + case 141: /* start_opt ::= */ yytestcase(yyruleno==141); + case 145: /* end_opt ::= */ yytestcase(yyruleno==145); + case 269: /* like_pattern_opt ::= */ yytestcase(yyruleno==269); + case 346: /* subtable_opt ::= */ yytestcase(yyruleno==346); + case 464: /* case_when_else_opt ::= */ yytestcase(yyruleno==464); + case 494: /* from_clause_opt ::= */ yytestcase(yyruleno==494); + case 523: /* where_clause_opt ::= */ yytestcase(yyruleno==523); + case 532: /* twindow_clause_opt ::= */ yytestcase(yyruleno==532); + case 538: /* sliding_opt ::= */ yytestcase(yyruleno==538); + case 540: /* fill_opt ::= */ yytestcase(yyruleno==540); + case 554: /* having_clause_opt ::= */ yytestcase(yyruleno==554); + case 556: /* range_opt ::= */ yytestcase(yyruleno==556); + case 558: /* every_opt ::= */ yytestcase(yyruleno==558); + case 571: /* slimit_clause_opt ::= */ yytestcase(yyruleno==571); + case 575: /* limit_clause_opt ::= */ yytestcase(yyruleno==575); +#line 123 "sql.y" +{ yymsp[1].minor.yy164 = NULL; } +#line 4689 "sql.c" break; case 45: /* with_opt ::= WITH search_condition */ - case 491: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==491); - case 520: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==520); - case 551: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==551); -{ yymsp[-1].minor.yy872 = yymsp[0].minor.yy872; } + case 495: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==495); + case 524: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==524); + case 555: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==555); +#line 124 "sql.y" +{ yymsp[-1].minor.yy164 = yymsp[0].minor.yy164; } +#line 4697 "sql.c" break; case 46: /* cmd ::= CREATE DNODE dnode_endpoint */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy929, NULL); } +#line 127 "sql.y" +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy497, NULL); } +#line 4702 "sql.c" break; case 47: /* cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy0); } +#line 128 "sql.y" +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy0); } +#line 4707 "sql.c" break; case 48: /* cmd ::= DROP DNODE NK_INTEGER force_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy857); } +#line 129 "sql.y" +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy441); } +#line 4712 "sql.c" break; case 49: /* cmd ::= DROP DNODE dnode_endpoint force_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy929, yymsp[0].minor.yy857); } +#line 130 "sql.y" +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy497, yymsp[0].minor.yy441); } +#line 4717 "sql.c" break; case 50: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ +#line 131 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, NULL); } +#line 4722 "sql.c" break; case 51: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ +#line 132 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-2].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } +#line 4727 "sql.c" break; case 52: /* cmd ::= ALTER ALL DNODES NK_STRING */ +#line 133 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &yymsp[0].minor.yy0, NULL); } +#line 4732 "sql.c" break; case 53: /* cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ +#line 134 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } +#line 4737 "sql.c" break; - case 54: /* dnode_endpoint ::= NK_STRING */ - case 55: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==55); - case 56: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==56); - case 289: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==289); - case 290: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==290); - case 291: /* sma_func_name ::= LAST */ yytestcase(yyruleno==291); - case 292: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==292); - case 386: /* db_name ::= NK_ID */ yytestcase(yyruleno==386); - case 387: /* table_name ::= NK_ID */ yytestcase(yyruleno==387); - case 388: /* column_name ::= NK_ID */ yytestcase(yyruleno==388); - case 389: /* function_name ::= NK_ID */ yytestcase(yyruleno==389); - case 390: /* table_alias ::= NK_ID */ yytestcase(yyruleno==390); - case 391: /* column_alias ::= NK_ID */ yytestcase(yyruleno==391); - case 392: /* user_name ::= NK_ID */ yytestcase(yyruleno==392); - case 393: /* topic_name ::= NK_ID */ yytestcase(yyruleno==393); - case 394: /* stream_name ::= NK_ID */ yytestcase(yyruleno==394); - case 395: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==395); - case 396: /* index_name ::= NK_ID */ yytestcase(yyruleno==396); - case 436: /* noarg_func ::= NOW */ yytestcase(yyruleno==436); - case 437: /* noarg_func ::= TODAY */ yytestcase(yyruleno==437); - case 438: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==438); - case 439: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==439); - case 440: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==440); - case 441: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==441); - case 442: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==442); - case 443: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==443); - case 444: /* noarg_func ::= USER */ yytestcase(yyruleno==444); - case 445: /* star_func ::= COUNT */ yytestcase(yyruleno==445); - case 446: /* star_func ::= FIRST */ yytestcase(yyruleno==446); - case 447: /* star_func ::= LAST */ yytestcase(yyruleno==447); - case 448: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==448); -{ yylhsminor.yy929 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy929 = yylhsminor.yy929; + case 54: /* cmd ::= RESTORE DNODE NK_INTEGER */ +#line 135 "sql.y" +{ pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_DNODE_STMT, &yymsp[0].minor.yy0); } +#line 4742 "sql.c" break; - case 57: /* force_opt ::= */ - case 77: /* not_exists_opt ::= */ yytestcase(yyruleno==77); - case 79: /* exists_opt ::= */ yytestcase(yyruleno==79); - case 309: /* analyze_opt ::= */ yytestcase(yyruleno==309); - case 316: /* agg_func_opt ::= */ yytestcase(yyruleno==316); - case 322: /* or_replace_opt ::= */ yytestcase(yyruleno==322); - case 344: /* ignore_opt ::= */ yytestcase(yyruleno==344); - case 509: /* set_quantifier_opt ::= */ yytestcase(yyruleno==509); -{ yymsp[1].minor.yy857 = false; } + case 55: /* dnode_endpoint ::= NK_STRING */ + case 56: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==56); + case 57: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==57); + case 293: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==293); + case 294: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==294); + case 295: /* sma_func_name ::= LAST */ yytestcase(yyruleno==295); + case 296: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==296); + case 390: /* db_name ::= NK_ID */ yytestcase(yyruleno==390); + case 391: /* table_name ::= NK_ID */ yytestcase(yyruleno==391); + case 392: /* column_name ::= NK_ID */ yytestcase(yyruleno==392); + case 393: /* function_name ::= NK_ID */ yytestcase(yyruleno==393); + case 394: /* table_alias ::= NK_ID */ yytestcase(yyruleno==394); + case 395: /* column_alias ::= NK_ID */ yytestcase(yyruleno==395); + case 396: /* user_name ::= NK_ID */ yytestcase(yyruleno==396); + case 397: /* topic_name ::= NK_ID */ yytestcase(yyruleno==397); + case 398: /* stream_name ::= NK_ID */ yytestcase(yyruleno==398); + case 399: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==399); + case 400: /* index_name ::= NK_ID */ yytestcase(yyruleno==400); + case 440: /* noarg_func ::= NOW */ yytestcase(yyruleno==440); + case 441: /* noarg_func ::= TODAY */ yytestcase(yyruleno==441); + case 442: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==442); + case 443: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==443); + case 444: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==444); + case 445: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==445); + case 446: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==446); + case 447: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==447); + case 448: /* noarg_func ::= USER */ yytestcase(yyruleno==448); + case 449: /* star_func ::= COUNT */ yytestcase(yyruleno==449); + case 450: /* star_func ::= FIRST */ yytestcase(yyruleno==450); + case 451: /* star_func ::= LAST */ yytestcase(yyruleno==451); + case 452: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==452); +#line 139 "sql.y" +{ yylhsminor.yy497 = yymsp[0].minor.yy0; } +#line 4777 "sql.c" + yymsp[0].minor.yy497 = yylhsminor.yy497; break; - case 58: /* force_opt ::= FORCE */ - case 310: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==310); - case 317: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==317); - case 510: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==510); -{ yymsp[0].minor.yy857 = true; } + case 58: /* force_opt ::= */ + case 81: /* not_exists_opt ::= */ yytestcase(yyruleno==81); + case 83: /* exists_opt ::= */ yytestcase(yyruleno==83); + case 313: /* analyze_opt ::= */ yytestcase(yyruleno==313); + case 320: /* agg_func_opt ::= */ yytestcase(yyruleno==320); + case 326: /* or_replace_opt ::= */ yytestcase(yyruleno==326); + case 348: /* ignore_opt ::= */ yytestcase(yyruleno==348); + case 513: /* set_quantifier_opt ::= */ yytestcase(yyruleno==513); +#line 145 "sql.y" +{ yymsp[1].minor.yy441 = false; } +#line 4790 "sql.c" break; - case 59: /* cmd ::= ALTER LOCAL NK_STRING */ + case 59: /* force_opt ::= FORCE */ + case 314: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==314); + case 321: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==321); + case 514: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==514); +#line 146 "sql.y" +{ yymsp[0].minor.yy441 = true; } +#line 4798 "sql.c" + break; + case 60: /* cmd ::= ALTER LOCAL NK_STRING */ +#line 149 "sql.y" { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[0].minor.yy0, NULL); } +#line 4803 "sql.c" break; - case 60: /* cmd ::= ALTER LOCAL NK_STRING NK_STRING */ + case 61: /* cmd ::= ALTER LOCAL NK_STRING NK_STRING */ +#line 150 "sql.y" { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } +#line 4808 "sql.c" break; - case 61: /* cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ + case 62: /* cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ +#line 153 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_QNODE_STMT, &yymsp[0].minor.yy0); } +#line 4813 "sql.c" break; - case 62: /* cmd ::= DROP QNODE ON DNODE NK_INTEGER */ + case 63: /* cmd ::= DROP QNODE ON DNODE NK_INTEGER */ +#line 154 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_QNODE_STMT, &yymsp[0].minor.yy0); } +#line 4818 "sql.c" break; - case 63: /* cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ + case 64: /* cmd ::= RESTORE QNODE ON DNODE NK_INTEGER */ +#line 155 "sql.y" +{ pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_QNODE_STMT, &yymsp[0].minor.yy0); } +#line 4823 "sql.c" + break; + case 65: /* cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ +#line 158 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_BNODE_STMT, &yymsp[0].minor.yy0); } +#line 4828 "sql.c" break; - case 64: /* cmd ::= DROP BNODE ON DNODE NK_INTEGER */ + case 66: /* cmd ::= DROP BNODE ON DNODE NK_INTEGER */ +#line 159 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_BNODE_STMT, &yymsp[0].minor.yy0); } +#line 4833 "sql.c" break; - case 65: /* cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ + case 67: /* cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ +#line 162 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_SNODE_STMT, &yymsp[0].minor.yy0); } +#line 4838 "sql.c" break; - case 66: /* cmd ::= DROP SNODE ON DNODE NK_INTEGER */ + case 68: /* cmd ::= DROP SNODE ON DNODE NK_INTEGER */ +#line 163 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_SNODE_STMT, &yymsp[0].minor.yy0); } +#line 4843 "sql.c" break; - case 67: /* cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ + case 69: /* cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ +#line 166 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_MNODE_STMT, &yymsp[0].minor.yy0); } +#line 4848 "sql.c" break; - case 68: /* cmd ::= DROP MNODE ON DNODE NK_INTEGER */ + case 70: /* cmd ::= DROP MNODE ON DNODE NK_INTEGER */ +#line 167 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_MNODE_STMT, &yymsp[0].minor.yy0); } +#line 4853 "sql.c" break; - case 69: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ -{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy857, &yymsp[-1].minor.yy929, yymsp[0].minor.yy872); } + case 71: /* cmd ::= RESTORE MNODE ON DNODE NK_INTEGER */ +#line 168 "sql.y" +{ pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_MNODE_STMT, &yymsp[0].minor.yy0); } +#line 4858 "sql.c" break; - case 70: /* cmd ::= DROP DATABASE exists_opt db_name */ -{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 72: /* cmd ::= RESTORE VNODE ON DNODE NK_INTEGER */ +#line 171 "sql.y" +{ pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_VNODE_STMT, &yymsp[0].minor.yy0); } +#line 4863 "sql.c" break; - case 71: /* cmd ::= USE db_name */ -{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy929); } + case 73: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ +#line 174 "sql.y" +{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy441, &yymsp[-1].minor.yy497, yymsp[0].minor.yy164); } +#line 4868 "sql.c" break; - case 72: /* cmd ::= ALTER DATABASE db_name alter_db_options */ -{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy929, yymsp[0].minor.yy872); } + case 74: /* cmd ::= DROP DATABASE exists_opt db_name */ +#line 175 "sql.y" +{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 4873 "sql.c" break; - case 73: /* cmd ::= FLUSH DATABASE db_name */ -{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy929); } + case 75: /* cmd ::= USE db_name */ +#line 176 "sql.y" +{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy497); } +#line 4878 "sql.c" break; - case 74: /* cmd ::= TRIM DATABASE db_name speed_opt */ -{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[-1].minor.yy929, yymsp[0].minor.yy580); } + case 76: /* cmd ::= ALTER DATABASE db_name alter_db_options */ +#line 177 "sql.y" +{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy497, yymsp[0].minor.yy164); } +#line 4883 "sql.c" break; - case 75: /* cmd ::= COMPACT DATABASE db_name start_opt end_opt */ -{ pCxt->pRootNode = createCompactStmt(pCxt, &yymsp[-2].minor.yy929, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 77: /* cmd ::= FLUSH DATABASE db_name */ +#line 178 "sql.y" +{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy497); } +#line 4888 "sql.c" break; - case 76: /* not_exists_opt ::= IF NOT EXISTS */ -{ yymsp[-2].minor.yy857 = true; } + case 78: /* cmd ::= TRIM DATABASE db_name speed_opt */ +#line 179 "sql.y" +{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[-1].minor.yy497, yymsp[0].minor.yy560); } +#line 4893 "sql.c" break; - case 78: /* exists_opt ::= IF EXISTS */ - case 323: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==323); - case 345: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==345); -{ yymsp[-1].minor.yy857 = true; } + case 79: /* cmd ::= COMPACT DATABASE db_name start_opt end_opt */ +#line 180 "sql.y" +{ pCxt->pRootNode = createCompactStmt(pCxt, &yymsp[-2].minor.yy497, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 4898 "sql.c" break; - case 80: /* db_options ::= */ -{ yymsp[1].minor.yy872 = createDefaultDatabaseOptions(pCxt); } + case 80: /* not_exists_opt ::= IF NOT EXISTS */ +#line 184 "sql.y" +{ yymsp[-2].minor.yy441 = true; } +#line 4903 "sql.c" break; - case 81: /* db_options ::= db_options BUFFER NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 82: /* exists_opt ::= IF EXISTS */ + case 327: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==327); + case 349: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==349); +#line 189 "sql.y" +{ yymsp[-1].minor.yy441 = true; } +#line 4910 "sql.c" break; - case 82: /* db_options ::= db_options CACHEMODEL NK_STRING */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_CACHEMODEL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 84: /* db_options ::= */ +#line 192 "sql.y" +{ yymsp[1].minor.yy164 = createDefaultDatabaseOptions(pCxt); } +#line 4915 "sql.c" break; - case 83: /* db_options ::= db_options CACHESIZE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_CACHESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 85: /* db_options ::= db_options BUFFER NK_INTEGER */ +#line 193 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } +#line 4920 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 84: /* db_options ::= db_options COMP NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_COMP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 86: /* db_options ::= db_options CACHEMODEL NK_STRING */ +#line 194 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_CACHEMODEL, &yymsp[0].minor.yy0); } +#line 4926 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 85: /* db_options ::= db_options DURATION NK_INTEGER */ - case 86: /* db_options ::= db_options DURATION NK_VARIABLE */ yytestcase(yyruleno==86); -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 87: /* db_options ::= db_options CACHESIZE NK_INTEGER */ +#line 195 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_CACHESIZE, &yymsp[0].minor.yy0); } +#line 4932 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 87: /* db_options ::= db_options MAXROWS NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 88: /* db_options ::= db_options COMP NK_INTEGER */ +#line 196 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_COMP, &yymsp[0].minor.yy0); } +#line 4938 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 88: /* db_options ::= db_options MINROWS NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 89: /* db_options ::= db_options DURATION NK_INTEGER */ + case 90: /* db_options ::= db_options DURATION NK_VARIABLE */ yytestcase(yyruleno==90); +#line 197 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } +#line 4945 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 89: /* db_options ::= db_options KEEP integer_list */ - case 90: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==90); -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_KEEP, yymsp[0].minor.yy664); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 91: /* db_options ::= db_options MAXROWS NK_INTEGER */ +#line 199 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } +#line 4951 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 91: /* db_options ::= db_options PAGES NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 92: /* db_options ::= db_options MINROWS NK_INTEGER */ +#line 200 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } +#line 4957 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 92: /* db_options ::= db_options PAGESIZE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 93: /* db_options ::= db_options KEEP integer_list */ + case 94: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==94); +#line 201 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_KEEP, yymsp[0].minor.yy72); } +#line 4964 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 93: /* db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_TSDB_PAGESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 95: /* db_options ::= db_options PAGES NK_INTEGER */ +#line 203 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } +#line 4970 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 94: /* db_options ::= db_options PRECISION NK_STRING */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 96: /* db_options ::= db_options PAGESIZE NK_INTEGER */ +#line 204 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } +#line 4976 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 95: /* db_options ::= db_options REPLICA NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 97: /* db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ +#line 205 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_TSDB_PAGESIZE, &yymsp[0].minor.yy0); } +#line 4982 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 96: /* db_options ::= db_options VGROUPS NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 98: /* db_options ::= db_options PRECISION NK_STRING */ +#line 206 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } +#line 4988 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 97: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 99: /* db_options ::= db_options REPLICA NK_INTEGER */ +#line 207 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } +#line 4994 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 98: /* db_options ::= db_options RETENTIONS retention_list */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_RETENTIONS, yymsp[0].minor.yy664); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 100: /* db_options ::= db_options VGROUPS NK_INTEGER */ +#line 209 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } +#line 5000 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 99: /* db_options ::= db_options SCHEMALESS NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 101: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ +#line 210 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } +#line 5006 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 100: /* db_options ::= db_options WAL_LEVEL NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_WAL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 102: /* db_options ::= db_options RETENTIONS retention_list */ +#line 211 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_RETENTIONS, yymsp[0].minor.yy72); } +#line 5012 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 101: /* db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 103: /* db_options ::= db_options SCHEMALESS NK_INTEGER */ +#line 212 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } +#line 5018 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 102: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_WAL_RETENTION_PERIOD, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 104: /* db_options ::= db_options WAL_LEVEL NK_INTEGER */ +#line 213 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_WAL, &yymsp[0].minor.yy0); } +#line 5024 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 103: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ + case 105: /* db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ +#line 214 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } +#line 5030 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 106: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ +#line 215 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_WAL_RETENTION_PERIOD, &yymsp[0].minor.yy0); } +#line 5036 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 107: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ +#line 216 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-3].minor.yy872, DB_OPTION_WAL_RETENTION_PERIOD, &t); + yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-3].minor.yy164, DB_OPTION_WAL_RETENTION_PERIOD, &t); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; +#line 5046 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 104: /* db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_WAL_RETENTION_SIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 108: /* db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ +#line 221 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_WAL_RETENTION_SIZE, &yymsp[0].minor.yy0); } +#line 5052 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 105: /* db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ + case 109: /* db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ +#line 222 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-3].minor.yy872, DB_OPTION_WAL_RETENTION_SIZE, &t); + yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-3].minor.yy164, DB_OPTION_WAL_RETENTION_SIZE, &t); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; +#line 5062 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 106: /* db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_WAL_ROLL_PERIOD, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 110: /* db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ +#line 227 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_WAL_ROLL_PERIOD, &yymsp[0].minor.yy0); } +#line 5068 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 107: /* db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_WAL_SEGMENT_SIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 111: /* db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ +#line 228 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_WAL_SEGMENT_SIZE, &yymsp[0].minor.yy0); } +#line 5074 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 108: /* db_options ::= db_options STT_TRIGGER NK_INTEGER */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 112: /* db_options ::= db_options STT_TRIGGER NK_INTEGER */ +#line 229 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); } +#line 5080 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 109: /* db_options ::= db_options TABLE_PREFIX signed */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy872); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 113: /* db_options ::= db_options TABLE_PREFIX signed */ +#line 230 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy164); } +#line 5086 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 110: /* db_options ::= db_options TABLE_SUFFIX signed */ -{ yylhsminor.yy872 = setDatabaseOption(pCxt, yymsp[-2].minor.yy872, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy872); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 114: /* db_options ::= db_options TABLE_SUFFIX signed */ +#line 231 "sql.y" +{ yylhsminor.yy164 = setDatabaseOption(pCxt, yymsp[-2].minor.yy164, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy164); } +#line 5092 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 111: /* alter_db_options ::= alter_db_option */ -{ yylhsminor.yy872 = createAlterDatabaseOptions(pCxt); yylhsminor.yy872 = setAlterDatabaseOption(pCxt, yylhsminor.yy872, &yymsp[0].minor.yy605); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 115: /* alter_db_options ::= alter_db_option */ +#line 233 "sql.y" +{ yylhsminor.yy164 = createAlterDatabaseOptions(pCxt); yylhsminor.yy164 = setAlterDatabaseOption(pCxt, yylhsminor.yy164, &yymsp[0].minor.yy761); } +#line 5098 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 112: /* alter_db_options ::= alter_db_options alter_db_option */ -{ yylhsminor.yy872 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy872, &yymsp[0].minor.yy605); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 116: /* alter_db_options ::= alter_db_options alter_db_option */ +#line 234 "sql.y" +{ yylhsminor.yy164 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy164, &yymsp[0].minor.yy761); } +#line 5104 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 113: /* alter_db_option ::= BUFFER NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 117: /* alter_db_option ::= BUFFER NK_INTEGER */ +#line 238 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5110 "sql.c" break; - case 114: /* alter_db_option ::= CACHEMODEL NK_STRING */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_CACHEMODEL; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 118: /* alter_db_option ::= CACHEMODEL NK_STRING */ +#line 239 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_CACHEMODEL; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5115 "sql.c" break; - case 115: /* alter_db_option ::= CACHESIZE NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_CACHESIZE; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 119: /* alter_db_option ::= CACHESIZE NK_INTEGER */ +#line 240 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_CACHESIZE; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5120 "sql.c" break; - case 116: /* alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 120: /* alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ +#line 241 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5125 "sql.c" break; - case 117: /* alter_db_option ::= KEEP integer_list */ - case 118: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==118); -{ yymsp[-1].minor.yy605.type = DB_OPTION_KEEP; yymsp[-1].minor.yy605.pList = yymsp[0].minor.yy664; } + case 121: /* alter_db_option ::= KEEP integer_list */ + case 122: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==122); +#line 242 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_KEEP; yymsp[-1].minor.yy761.pList = yymsp[0].minor.yy72; } +#line 5131 "sql.c" break; - case 119: /* alter_db_option ::= PAGES NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_PAGES; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 123: /* alter_db_option ::= PAGES NK_INTEGER */ +#line 244 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_PAGES; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5136 "sql.c" break; - case 120: /* alter_db_option ::= REPLICA NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 124: /* alter_db_option ::= REPLICA NK_INTEGER */ +#line 245 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5141 "sql.c" break; - case 121: /* alter_db_option ::= WAL_LEVEL NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_WAL; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 125: /* alter_db_option ::= WAL_LEVEL NK_INTEGER */ +#line 247 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_WAL; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5146 "sql.c" break; - case 122: /* alter_db_option ::= STT_TRIGGER NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_STT_TRIGGER; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 126: /* alter_db_option ::= STT_TRIGGER NK_INTEGER */ +#line 248 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_STT_TRIGGER; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5151 "sql.c" break; - case 123: /* alter_db_option ::= MINROWS NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_MINROWS; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 127: /* alter_db_option ::= MINROWS NK_INTEGER */ +#line 249 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_MINROWS; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5156 "sql.c" break; - case 124: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 128: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ +#line 250 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5161 "sql.c" break; - case 125: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ + case 129: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ +#line 251 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yymsp[-2].minor.yy605.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-2].minor.yy605.val = t; + yymsp[-2].minor.yy761.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-2].minor.yy761.val = t; } +#line 5170 "sql.c" break; - case 126: /* alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } + case 130: /* alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ +#line 256 "sql.y" +{ yymsp[-1].minor.yy761.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5175 "sql.c" break; - case 127: /* alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ + case 131: /* alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ +#line 257 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yymsp[-2].minor.yy605.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-2].minor.yy605.val = t; + yymsp[-2].minor.yy761.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-2].minor.yy761.val = t; } - break; - case 128: /* integer_list ::= NK_INTEGER */ -{ yylhsminor.yy664 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy664 = yylhsminor.yy664; - break; - case 129: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ - case 355: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==355); -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-2].minor.yy664, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy664 = yylhsminor.yy664; - break; - case 130: /* variable_list ::= NK_VARIABLE */ -{ yylhsminor.yy664 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy664 = yylhsminor.yy664; - break; - case 131: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */ -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-2].minor.yy664, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy664 = yylhsminor.yy664; - break; - case 132: /* retention_list ::= retention */ - case 162: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==162); - case 165: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==165); - case 172: /* column_def_list ::= column_def */ yytestcase(yyruleno==172); - case 215: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==215); - case 220: /* col_name_list ::= col_name */ yytestcase(yyruleno==220); - case 271: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==271); - case 285: /* func_list ::= func */ yytestcase(yyruleno==285); - case 384: /* literal_list ::= signed_literal */ yytestcase(yyruleno==384); - case 451: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==451); - case 457: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==457); - case 512: /* select_list ::= select_item */ yytestcase(yyruleno==512); - case 523: /* partition_list ::= partition_item */ yytestcase(yyruleno==523); - case 578: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==578); -{ yylhsminor.yy664 = createNodeList(pCxt, yymsp[0].minor.yy872); } - yymsp[0].minor.yy664 = yylhsminor.yy664; - break; - case 133: /* retention_list ::= retention_list NK_COMMA retention */ - case 166: /* multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ yytestcase(yyruleno==166); - case 173: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==173); - case 216: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==216); - case 221: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==221); - case 272: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==272); - case 286: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==286); - case 385: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==385); - case 452: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==452); - case 513: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==513); - case 524: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==524); - case 579: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==579); -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-2].minor.yy664, yymsp[0].minor.yy872); } - yymsp[-2].minor.yy664 = yylhsminor.yy664; - break; - case 134: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ -{ yylhsminor.yy872 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 135: /* speed_opt ::= */ - case 318: /* bufsize_opt ::= */ yytestcase(yyruleno==318); -{ yymsp[1].minor.yy580 = 0; } - break; - case 136: /* speed_opt ::= MAX_SPEED NK_INTEGER */ - case 319: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==319); -{ yymsp[-1].minor.yy580 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } - break; - case 138: /* start_opt ::= START WITH NK_INTEGER */ - case 142: /* end_opt ::= END WITH NK_INTEGER */ yytestcase(yyruleno==142); -{ yymsp[-2].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } - break; - case 139: /* start_opt ::= START WITH NK_STRING */ - case 143: /* end_opt ::= END WITH NK_STRING */ yytestcase(yyruleno==143); -{ yymsp[-2].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } - break; - case 140: /* start_opt ::= START WITH TIMESTAMP NK_STRING */ - case 144: /* end_opt ::= END WITH TIMESTAMP NK_STRING */ yytestcase(yyruleno==144); -{ yymsp[-3].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } - break; - case 145: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ - case 147: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==147); -{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy857, yymsp[-5].minor.yy872, yymsp[-3].minor.yy664, yymsp[-1].minor.yy664, yymsp[0].minor.yy872); } - break; - case 146: /* cmd ::= CREATE TABLE multi_create_clause */ -{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy664); } - break; - case 148: /* cmd ::= DROP TABLE multi_drop_clause */ -{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy664); } - break; - case 149: /* cmd ::= DROP STABLE exists_opt full_table_name */ -{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy857, yymsp[0].minor.yy872); } - break; - case 150: /* cmd ::= ALTER TABLE alter_table_clause */ - case 357: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==357); - case 358: /* cmd ::= insert_query */ yytestcase(yyruleno==358); -{ pCxt->pRootNode = yymsp[0].minor.yy872; } - break; - case 151: /* cmd ::= ALTER STABLE alter_table_clause */ -{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy872); } - break; - case 152: /* alter_table_clause ::= full_table_name alter_table_options */ -{ yylhsminor.yy872 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; - break; - case 153: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ -{ yylhsminor.yy872 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy929, yymsp[0].minor.yy784); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 154: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ -{ yylhsminor.yy872 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy872, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy929); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; - break; - case 155: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ -{ yylhsminor.yy872 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy929, yymsp[0].minor.yy784); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 156: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ -{ yylhsminor.yy872 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy929, &yymsp[0].minor.yy929); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 157: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ -{ yylhsminor.yy872 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy929, yymsp[0].minor.yy784); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 158: /* alter_table_clause ::= full_table_name DROP TAG column_name */ -{ yylhsminor.yy872 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy872, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy929); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; - break; - case 159: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ -{ yylhsminor.yy872 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy929, yymsp[0].minor.yy784); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 160: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ -{ yylhsminor.yy872 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy872, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy929, &yymsp[0].minor.yy929); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 161: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ -{ yylhsminor.yy872 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy872, &yymsp[-2].minor.yy929, yymsp[0].minor.yy872); } - yymsp[-5].minor.yy872 = yylhsminor.yy872; - break; - case 163: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ - case 458: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==458); -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-1].minor.yy664, yymsp[0].minor.yy872); } - yymsp[-1].minor.yy664 = yylhsminor.yy664; - break; - case 164: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ -{ yylhsminor.yy872 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy857, yymsp[-8].minor.yy872, yymsp[-6].minor.yy872, yymsp[-5].minor.yy664, yymsp[-2].minor.yy664, yymsp[0].minor.yy872); } - yymsp[-9].minor.yy872 = yylhsminor.yy872; - break; - case 167: /* drop_table_clause ::= exists_opt full_table_name */ -{ yylhsminor.yy872 = createDropTableClause(pCxt, yymsp[-1].minor.yy857, yymsp[0].minor.yy872); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; - break; - case 168: /* specific_cols_opt ::= */ - case 198: /* tags_def_opt ::= */ yytestcase(yyruleno==198); - case 270: /* tag_list_opt ::= */ yytestcase(yyruleno==270); - case 328: /* col_list_opt ::= */ yytestcase(yyruleno==328); - case 330: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==330); - case 521: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==521); - case 546: /* group_by_clause_opt ::= */ yytestcase(yyruleno==546); - case 565: /* order_by_clause_opt ::= */ yytestcase(yyruleno==565); -{ yymsp[1].minor.yy664 = NULL; } - break; - case 169: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ - case 329: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==329); -{ yymsp[-2].minor.yy664 = yymsp[-1].minor.yy664; } - break; - case 170: /* full_table_name ::= table_name */ -{ yylhsminor.yy872 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy929, NULL); } - yymsp[0].minor.yy872 = yylhsminor.yy872; - break; - case 171: /* full_table_name ::= db_name NK_DOT table_name */ -{ yylhsminor.yy872 = createRealTableNode(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy929, NULL); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 174: /* column_def ::= column_name type_name */ -{ yylhsminor.yy872 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy929, yymsp[0].minor.yy784, NULL); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; - break; - case 175: /* type_name ::= BOOL */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_BOOL); } - break; - case 176: /* type_name ::= TINYINT */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_TINYINT); } - break; - case 177: /* type_name ::= SMALLINT */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_SMALLINT); } - break; - case 178: /* type_name ::= INT */ - case 179: /* type_name ::= INTEGER */ yytestcase(yyruleno==179); -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_INT); } - break; - case 180: /* type_name ::= BIGINT */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_BIGINT); } - break; - case 181: /* type_name ::= FLOAT */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_FLOAT); } - break; - case 182: /* type_name ::= DOUBLE */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_DOUBLE); } - break; - case 183: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy784 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } - break; - case 184: /* type_name ::= TIMESTAMP */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } - break; - case 185: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy784 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } - break; - case 186: /* type_name ::= TINYINT UNSIGNED */ -{ yymsp[-1].minor.yy784 = createDataType(TSDB_DATA_TYPE_UTINYINT); } - break; - case 187: /* type_name ::= SMALLINT UNSIGNED */ -{ yymsp[-1].minor.yy784 = createDataType(TSDB_DATA_TYPE_USMALLINT); } - break; - case 188: /* type_name ::= INT UNSIGNED */ -{ yymsp[-1].minor.yy784 = createDataType(TSDB_DATA_TYPE_UINT); } - break; - case 189: /* type_name ::= BIGINT UNSIGNED */ -{ yymsp[-1].minor.yy784 = createDataType(TSDB_DATA_TYPE_UBIGINT); } - break; - case 190: /* type_name ::= JSON */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_JSON); } - break; - case 191: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy784 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } - break; - case 192: /* type_name ::= MEDIUMBLOB */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } - break; - case 193: /* type_name ::= BLOB */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_BLOB); } - break; - case 194: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy784 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } - break; - case 195: /* type_name ::= DECIMAL */ -{ yymsp[0].minor.yy784 = createDataType(TSDB_DATA_TYPE_DECIMAL); } - break; - case 196: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy784 = createDataType(TSDB_DATA_TYPE_DECIMAL); } - break; - case 197: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ -{ yymsp[-5].minor.yy784 = createDataType(TSDB_DATA_TYPE_DECIMAL); } - break; - case 199: /* tags_def_opt ::= tags_def */ - case 331: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==331); - case 450: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==450); -{ yylhsminor.yy664 = yymsp[0].minor.yy664; } - yymsp[0].minor.yy664 = yylhsminor.yy664; - break; - case 200: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ - case 332: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==332); -{ yymsp[-3].minor.yy664 = yymsp[-1].minor.yy664; } - break; - case 201: /* table_options ::= */ -{ yymsp[1].minor.yy872 = createDefaultTableOptions(pCxt); } - break; - case 202: /* table_options ::= table_options COMMENT NK_STRING */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-2].minor.yy872, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 203: /* table_options ::= table_options MAX_DELAY duration_list */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-2].minor.yy872, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy664); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 204: /* table_options ::= table_options WATERMARK duration_list */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-2].minor.yy872, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy664); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 205: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-4].minor.yy872, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy664); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 206: /* table_options ::= table_options TTL NK_INTEGER */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-2].minor.yy872, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 207: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-4].minor.yy872, TABLE_OPTION_SMA, yymsp[-1].minor.yy664); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; - break; - case 208: /* table_options ::= table_options DELETE_MARK duration_list */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-2].minor.yy872, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy664); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; - break; - case 209: /* alter_table_options ::= alter_table_option */ -{ yylhsminor.yy872 = createAlterTableOptions(pCxt); yylhsminor.yy872 = setTableOption(pCxt, yylhsminor.yy872, yymsp[0].minor.yy605.type, &yymsp[0].minor.yy605.val); } - yymsp[0].minor.yy872 = yylhsminor.yy872; - break; - case 210: /* alter_table_options ::= alter_table_options alter_table_option */ -{ yylhsminor.yy872 = setTableOption(pCxt, yymsp[-1].minor.yy872, yymsp[0].minor.yy605.type, &yymsp[0].minor.yy605.val); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; - break; - case 211: /* alter_table_option ::= COMMENT NK_STRING */ -{ yymsp[-1].minor.yy605.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } - break; - case 212: /* alter_table_option ::= TTL NK_INTEGER */ -{ yymsp[-1].minor.yy605.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy605.val = yymsp[0].minor.yy0; } - break; - case 213: /* duration_list ::= duration_literal */ - case 414: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==414); -{ yylhsminor.yy664 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } - yymsp[0].minor.yy664 = yylhsminor.yy664; - break; - case 214: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 415: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==415); -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-2].minor.yy664, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } - yymsp[-2].minor.yy664 = yylhsminor.yy664; - break; - case 217: /* rollup_func_name ::= function_name */ -{ yylhsminor.yy872 = createFunctionNode(pCxt, &yymsp[0].minor.yy929, NULL); } - yymsp[0].minor.yy872 = yylhsminor.yy872; - break; - case 218: /* rollup_func_name ::= FIRST */ - case 219: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==219); - case 274: /* tag_item ::= QTAGS */ yytestcase(yyruleno==274); -{ yylhsminor.yy872 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } - yymsp[0].minor.yy872 = yylhsminor.yy872; - break; - case 222: /* col_name ::= column_name */ - case 275: /* tag_item ::= column_name */ yytestcase(yyruleno==275); -{ yylhsminor.yy872 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy929); } - yymsp[0].minor.yy872 = yylhsminor.yy872; - break; - case 223: /* cmd ::= SHOW DNODES */ +#line 5184 "sql.c" + break; + case 132: /* integer_list ::= NK_INTEGER */ +#line 265 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } +#line 5189 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; + break; + case 133: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ + case 359: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==359); +#line 266 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-2].minor.yy72, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } +#line 5196 "sql.c" + yymsp[-2].minor.yy72 = yylhsminor.yy72; + break; + case 134: /* variable_list ::= NK_VARIABLE */ +#line 270 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } +#line 5202 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; + break; + case 135: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */ +#line 271 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-2].minor.yy72, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } +#line 5208 "sql.c" + yymsp[-2].minor.yy72 = yylhsminor.yy72; + break; + case 136: /* retention_list ::= retention */ + case 166: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==166); + case 169: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==169); + case 176: /* column_def_list ::= column_def */ yytestcase(yyruleno==176); + case 219: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==219); + case 224: /* col_name_list ::= col_name */ yytestcase(yyruleno==224); + case 275: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==275); + case 289: /* func_list ::= func */ yytestcase(yyruleno==289); + case 388: /* literal_list ::= signed_literal */ yytestcase(yyruleno==388); + case 455: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==455); + case 461: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==461); + case 516: /* select_list ::= select_item */ yytestcase(yyruleno==516); + case 527: /* partition_list ::= partition_item */ yytestcase(yyruleno==527); + case 582: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==582); +#line 275 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, yymsp[0].minor.yy164); } +#line 5227 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; + break; + case 137: /* retention_list ::= retention_list NK_COMMA retention */ + case 170: /* multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ yytestcase(yyruleno==170); + case 177: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==177); + case 220: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==220); + case 225: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==225); + case 276: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==276); + case 290: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==290); + case 389: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==389); + case 456: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==456); + case 517: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==517); + case 528: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==528); + case 583: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==583); +#line 276 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-2].minor.yy72, yymsp[0].minor.yy164); } +#line 5244 "sql.c" + yymsp[-2].minor.yy72 = yylhsminor.yy72; + break; + case 138: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ +#line 278 "sql.y" +{ yylhsminor.yy164 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } +#line 5250 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 139: /* speed_opt ::= */ + case 322: /* bufsize_opt ::= */ yytestcase(yyruleno==322); +#line 282 "sql.y" +{ yymsp[1].minor.yy560 = 0; } +#line 5257 "sql.c" + break; + case 140: /* speed_opt ::= MAX_SPEED NK_INTEGER */ + case 323: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==323); +#line 283 "sql.y" +{ yymsp[-1].minor.yy560 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } +#line 5263 "sql.c" + break; + case 142: /* start_opt ::= START WITH NK_INTEGER */ + case 146: /* end_opt ::= END WITH NK_INTEGER */ yytestcase(yyruleno==146); +#line 286 "sql.y" +{ yymsp[-2].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } +#line 5269 "sql.c" + break; + case 143: /* start_opt ::= START WITH NK_STRING */ + case 147: /* end_opt ::= END WITH NK_STRING */ yytestcase(yyruleno==147); +#line 287 "sql.y" +{ yymsp[-2].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } +#line 5275 "sql.c" + break; + case 144: /* start_opt ::= START WITH TIMESTAMP NK_STRING */ + case 148: /* end_opt ::= END WITH TIMESTAMP NK_STRING */ yytestcase(yyruleno==148); +#line 288 "sql.y" +{ yymsp[-3].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } +#line 5281 "sql.c" + break; + case 149: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ + case 151: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==151); +#line 297 "sql.y" +{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy441, yymsp[-5].minor.yy164, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, yymsp[0].minor.yy164); } +#line 5287 "sql.c" + break; + case 150: /* cmd ::= CREATE TABLE multi_create_clause */ +#line 298 "sql.y" +{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy72); } +#line 5292 "sql.c" + break; + case 152: /* cmd ::= DROP TABLE multi_drop_clause */ +#line 301 "sql.y" +{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy72); } +#line 5297 "sql.c" + break; + case 153: /* cmd ::= DROP STABLE exists_opt full_table_name */ +#line 302 "sql.y" +{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy441, yymsp[0].minor.yy164); } +#line 5302 "sql.c" + break; + case 154: /* cmd ::= ALTER TABLE alter_table_clause */ + case 361: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==361); + case 362: /* cmd ::= insert_query */ yytestcase(yyruleno==362); +#line 304 "sql.y" +{ pCxt->pRootNode = yymsp[0].minor.yy164; } +#line 5309 "sql.c" + break; + case 155: /* cmd ::= ALTER STABLE alter_table_clause */ +#line 305 "sql.y" +{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy164); } +#line 5314 "sql.c" + break; + case 156: /* alter_table_clause ::= full_table_name alter_table_options */ +#line 307 "sql.y" +{ yylhsminor.yy164 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 5319 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; + break; + case 157: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ +#line 309 "sql.y" +{ yylhsminor.yy164 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy497, yymsp[0].minor.yy700); } +#line 5325 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 158: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ +#line 310 "sql.y" +{ yylhsminor.yy164 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy164, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy497); } +#line 5331 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; + break; + case 159: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ +#line 312 "sql.y" +{ yylhsminor.yy164 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy497, yymsp[0].minor.yy700); } +#line 5337 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 160: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ +#line 314 "sql.y" +{ yylhsminor.yy164 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy497, &yymsp[0].minor.yy497); } +#line 5343 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 161: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ +#line 316 "sql.y" +{ yylhsminor.yy164 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy497, yymsp[0].minor.yy700); } +#line 5349 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 162: /* alter_table_clause ::= full_table_name DROP TAG column_name */ +#line 317 "sql.y" +{ yylhsminor.yy164 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy164, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy497); } +#line 5355 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; + break; + case 163: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ +#line 319 "sql.y" +{ yylhsminor.yy164 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy497, yymsp[0].minor.yy700); } +#line 5361 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 164: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ +#line 321 "sql.y" +{ yylhsminor.yy164 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy164, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy497, &yymsp[0].minor.yy497); } +#line 5367 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 165: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ +#line 323 "sql.y" +{ yylhsminor.yy164 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy164, &yymsp[-2].minor.yy497, yymsp[0].minor.yy164); } +#line 5373 "sql.c" + yymsp[-5].minor.yy164 = yylhsminor.yy164; + break; + case 167: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ + case 462: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==462); +#line 328 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-1].minor.yy72, yymsp[0].minor.yy164); } +#line 5380 "sql.c" + yymsp[-1].minor.yy72 = yylhsminor.yy72; + break; + case 168: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ +#line 332 "sql.y" +{ yylhsminor.yy164 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy441, yymsp[-8].minor.yy164, yymsp[-6].minor.yy164, yymsp[-5].minor.yy72, yymsp[-2].minor.yy72, yymsp[0].minor.yy164); } +#line 5386 "sql.c" + yymsp[-9].minor.yy164 = yylhsminor.yy164; + break; + case 171: /* drop_table_clause ::= exists_opt full_table_name */ +#line 339 "sql.y" +{ yylhsminor.yy164 = createDropTableClause(pCxt, yymsp[-1].minor.yy441, yymsp[0].minor.yy164); } +#line 5392 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; + break; + case 172: /* specific_cols_opt ::= */ + case 202: /* tags_def_opt ::= */ yytestcase(yyruleno==202); + case 274: /* tag_list_opt ::= */ yytestcase(yyruleno==274); + case 332: /* col_list_opt ::= */ yytestcase(yyruleno==332); + case 334: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==334); + case 525: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==525); + case 550: /* group_by_clause_opt ::= */ yytestcase(yyruleno==550); + case 569: /* order_by_clause_opt ::= */ yytestcase(yyruleno==569); +#line 343 "sql.y" +{ yymsp[1].minor.yy72 = NULL; } +#line 5405 "sql.c" + break; + case 173: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ + case 333: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==333); +#line 344 "sql.y" +{ yymsp[-2].minor.yy72 = yymsp[-1].minor.yy72; } +#line 5411 "sql.c" + break; + case 174: /* full_table_name ::= table_name */ +#line 346 "sql.y" +{ yylhsminor.yy164 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy497, NULL); } +#line 5416 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; + break; + case 175: /* full_table_name ::= db_name NK_DOT table_name */ +#line 347 "sql.y" +{ yylhsminor.yy164 = createRealTableNode(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy497, NULL); } +#line 5422 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 178: /* column_def ::= column_name type_name */ +#line 354 "sql.y" +{ yylhsminor.yy164 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy497, yymsp[0].minor.yy700, NULL); } +#line 5428 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; + break; + case 179: /* type_name ::= BOOL */ +#line 359 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_BOOL); } +#line 5434 "sql.c" + break; + case 180: /* type_name ::= TINYINT */ +#line 360 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_TINYINT); } +#line 5439 "sql.c" + break; + case 181: /* type_name ::= SMALLINT */ +#line 361 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_SMALLINT); } +#line 5444 "sql.c" + break; + case 182: /* type_name ::= INT */ + case 183: /* type_name ::= INTEGER */ yytestcase(yyruleno==183); +#line 362 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_INT); } +#line 5450 "sql.c" + break; + case 184: /* type_name ::= BIGINT */ +#line 364 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_BIGINT); } +#line 5455 "sql.c" + break; + case 185: /* type_name ::= FLOAT */ +#line 365 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_FLOAT); } +#line 5460 "sql.c" + break; + case 186: /* type_name ::= DOUBLE */ +#line 366 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_DOUBLE); } +#line 5465 "sql.c" + break; + case 187: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ +#line 367 "sql.y" +{ yymsp[-3].minor.yy700 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } +#line 5470 "sql.c" + break; + case 188: /* type_name ::= TIMESTAMP */ +#line 368 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } +#line 5475 "sql.c" + break; + case 189: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ +#line 369 "sql.y" +{ yymsp[-3].minor.yy700 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } +#line 5480 "sql.c" + break; + case 190: /* type_name ::= TINYINT UNSIGNED */ +#line 370 "sql.y" +{ yymsp[-1].minor.yy700 = createDataType(TSDB_DATA_TYPE_UTINYINT); } +#line 5485 "sql.c" + break; + case 191: /* type_name ::= SMALLINT UNSIGNED */ +#line 371 "sql.y" +{ yymsp[-1].minor.yy700 = createDataType(TSDB_DATA_TYPE_USMALLINT); } +#line 5490 "sql.c" + break; + case 192: /* type_name ::= INT UNSIGNED */ +#line 372 "sql.y" +{ yymsp[-1].minor.yy700 = createDataType(TSDB_DATA_TYPE_UINT); } +#line 5495 "sql.c" + break; + case 193: /* type_name ::= BIGINT UNSIGNED */ +#line 373 "sql.y" +{ yymsp[-1].minor.yy700 = createDataType(TSDB_DATA_TYPE_UBIGINT); } +#line 5500 "sql.c" + break; + case 194: /* type_name ::= JSON */ +#line 374 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_JSON); } +#line 5505 "sql.c" + break; + case 195: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ +#line 375 "sql.y" +{ yymsp[-3].minor.yy700 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } +#line 5510 "sql.c" + break; + case 196: /* type_name ::= MEDIUMBLOB */ +#line 376 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } +#line 5515 "sql.c" + break; + case 197: /* type_name ::= BLOB */ +#line 377 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_BLOB); } +#line 5520 "sql.c" + break; + case 198: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ +#line 378 "sql.y" +{ yymsp[-3].minor.yy700 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } +#line 5525 "sql.c" + break; + case 199: /* type_name ::= DECIMAL */ +#line 379 "sql.y" +{ yymsp[0].minor.yy700 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +#line 5530 "sql.c" + break; + case 200: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ +#line 380 "sql.y" +{ yymsp[-3].minor.yy700 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +#line 5535 "sql.c" + break; + case 201: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ +#line 381 "sql.y" +{ yymsp[-5].minor.yy700 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +#line 5540 "sql.c" + break; + case 203: /* tags_def_opt ::= tags_def */ + case 335: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==335); + case 454: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==454); +#line 386 "sql.y" +{ yylhsminor.yy72 = yymsp[0].minor.yy72; } +#line 5547 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; + break; + case 204: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ + case 336: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==336); +#line 390 "sql.y" +{ yymsp[-3].minor.yy72 = yymsp[-1].minor.yy72; } +#line 5554 "sql.c" + break; + case 205: /* table_options ::= */ +#line 392 "sql.y" +{ yymsp[1].minor.yy164 = createDefaultTableOptions(pCxt); } +#line 5559 "sql.c" + break; + case 206: /* table_options ::= table_options COMMENT NK_STRING */ +#line 393 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-2].minor.yy164, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } +#line 5564 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 207: /* table_options ::= table_options MAX_DELAY duration_list */ +#line 394 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-2].minor.yy164, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy72); } +#line 5570 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 208: /* table_options ::= table_options WATERMARK duration_list */ +#line 395 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-2].minor.yy164, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy72); } +#line 5576 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 209: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ +#line 396 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-4].minor.yy164, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy72); } +#line 5582 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 210: /* table_options ::= table_options TTL NK_INTEGER */ +#line 397 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-2].minor.yy164, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } +#line 5588 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 211: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ +#line 398 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-4].minor.yy164, TABLE_OPTION_SMA, yymsp[-1].minor.yy72); } +#line 5594 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; + break; + case 212: /* table_options ::= table_options DELETE_MARK duration_list */ +#line 399 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-2].minor.yy164, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy72); } +#line 5600 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; + break; + case 213: /* alter_table_options ::= alter_table_option */ +#line 401 "sql.y" +{ yylhsminor.yy164 = createAlterTableOptions(pCxt); yylhsminor.yy164 = setTableOption(pCxt, yylhsminor.yy164, yymsp[0].minor.yy761.type, &yymsp[0].minor.yy761.val); } +#line 5606 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; + break; + case 214: /* alter_table_options ::= alter_table_options alter_table_option */ +#line 402 "sql.y" +{ yylhsminor.yy164 = setTableOption(pCxt, yymsp[-1].minor.yy164, yymsp[0].minor.yy761.type, &yymsp[0].minor.yy761.val); } +#line 5612 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; + break; + case 215: /* alter_table_option ::= COMMENT NK_STRING */ +#line 406 "sql.y" +{ yymsp[-1].minor.yy761.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5618 "sql.c" + break; + case 216: /* alter_table_option ::= TTL NK_INTEGER */ +#line 407 "sql.y" +{ yymsp[-1].minor.yy761.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy761.val = yymsp[0].minor.yy0; } +#line 5623 "sql.c" + break; + case 217: /* duration_list ::= duration_literal */ + case 418: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==418); +#line 411 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 5629 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; + break; + case 218: /* duration_list ::= duration_list NK_COMMA duration_literal */ + case 419: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==419); +#line 412 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-2].minor.yy72, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 5636 "sql.c" + yymsp[-2].minor.yy72 = yylhsminor.yy72; + break; + case 221: /* rollup_func_name ::= function_name */ +#line 419 "sql.y" +{ yylhsminor.yy164 = createFunctionNode(pCxt, &yymsp[0].minor.yy497, NULL); } +#line 5642 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; + break; + case 222: /* rollup_func_name ::= FIRST */ + case 223: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==223); + case 278: /* tag_item ::= QTAGS */ yytestcase(yyruleno==278); +#line 420 "sql.y" +{ yylhsminor.yy164 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } +#line 5650 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; + break; + case 226: /* col_name ::= column_name */ + case 279: /* tag_item ::= column_name */ yytestcase(yyruleno==279); +#line 428 "sql.y" +{ yylhsminor.yy164 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy497); } +#line 5657 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; + break; + case 227: /* cmd ::= SHOW DNODES */ +#line 431 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT); } +#line 5663 "sql.c" break; - case 224: /* cmd ::= SHOW USERS */ + case 228: /* cmd ::= SHOW USERS */ +#line 432 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USERS_STMT); } +#line 5668 "sql.c" break; - case 225: /* cmd ::= SHOW USER PRIVILEGES */ + case 229: /* cmd ::= SHOW USER PRIVILEGES */ +#line 433 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USER_PRIVILEGES_STMT); } +#line 5673 "sql.c" break; - case 226: /* cmd ::= SHOW DATABASES */ + case 230: /* cmd ::= SHOW DATABASES */ +#line 434 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); } +#line 5678 "sql.c" break; - case 227: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy872, yymsp[0].minor.yy872, OP_TYPE_LIKE); } + case 231: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ +#line 435 "sql.y" +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy164, yymsp[0].minor.yy164, OP_TYPE_LIKE); } +#line 5683 "sql.c" break; - case 228: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy872, yymsp[0].minor.yy872, OP_TYPE_LIKE); } + case 232: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ +#line 436 "sql.y" +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy164, yymsp[0].minor.yy164, OP_TYPE_LIKE); } +#line 5688 "sql.c" break; - case 229: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy872, NULL, OP_TYPE_LIKE); } + case 233: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ +#line 437 "sql.y" +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy164, NULL, OP_TYPE_LIKE); } +#line 5693 "sql.c" break; - case 230: /* cmd ::= SHOW MNODES */ + case 234: /* cmd ::= SHOW MNODES */ +#line 438 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } +#line 5698 "sql.c" break; - case 231: /* cmd ::= SHOW QNODES */ + case 235: /* cmd ::= SHOW QNODES */ +#line 440 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); } +#line 5703 "sql.c" break; - case 232: /* cmd ::= SHOW FUNCTIONS */ + case 236: /* cmd ::= SHOW FUNCTIONS */ +#line 441 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); } +#line 5708 "sql.c" break; - case 233: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy872, yymsp[-1].minor.yy872, OP_TYPE_EQUAL); } + case 237: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ +#line 442 "sql.y" +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy164, yymsp[-1].minor.yy164, OP_TYPE_EQUAL); } +#line 5713 "sql.c" break; - case 234: /* cmd ::= SHOW STREAMS */ + case 238: /* cmd ::= SHOW STREAMS */ +#line 443 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); } +#line 5718 "sql.c" break; - case 235: /* cmd ::= SHOW ACCOUNTS */ + case 239: /* cmd ::= SHOW ACCOUNTS */ +#line 444 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } +#line 5723 "sql.c" break; - case 236: /* cmd ::= SHOW APPS */ + case 240: /* cmd ::= SHOW APPS */ +#line 445 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT); } +#line 5728 "sql.c" break; - case 237: /* cmd ::= SHOW CONNECTIONS */ + case 241: /* cmd ::= SHOW CONNECTIONS */ +#line 446 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT); } +#line 5733 "sql.c" break; - case 238: /* cmd ::= SHOW LICENCES */ - case 239: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==239); + case 242: /* cmd ::= SHOW LICENCES */ + case 243: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==243); +#line 447 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCES_STMT); } +#line 5739 "sql.c" break; - case 240: /* cmd ::= SHOW CREATE DATABASE db_name */ -{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy929); } + case 244: /* cmd ::= SHOW CREATE DATABASE db_name */ +#line 449 "sql.y" +{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy497); } +#line 5744 "sql.c" break; - case 241: /* cmd ::= SHOW CREATE TABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy872); } + case 245: /* cmd ::= SHOW CREATE TABLE full_table_name */ +#line 450 "sql.y" +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy164); } +#line 5749 "sql.c" break; - case 242: /* cmd ::= SHOW CREATE STABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy872); } + case 246: /* cmd ::= SHOW CREATE STABLE full_table_name */ +#line 451 "sql.y" +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy164); } +#line 5754 "sql.c" break; - case 243: /* cmd ::= SHOW QUERIES */ + case 247: /* cmd ::= SHOW QUERIES */ +#line 452 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } +#line 5759 "sql.c" break; - case 244: /* cmd ::= SHOW SCORES */ + case 248: /* cmd ::= SHOW SCORES */ +#line 453 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SCORES_STMT); } +#line 5764 "sql.c" break; - case 245: /* cmd ::= SHOW TOPICS */ + case 249: /* cmd ::= SHOW TOPICS */ +#line 454 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT); } +#line 5769 "sql.c" break; - case 246: /* cmd ::= SHOW VARIABLES */ - case 247: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==247); + case 250: /* cmd ::= SHOW VARIABLES */ + case 251: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==251); +#line 455 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLES_STMT); } +#line 5775 "sql.c" break; - case 248: /* cmd ::= SHOW LOCAL VARIABLES */ + case 252: /* cmd ::= SHOW LOCAL VARIABLES */ +#line 457 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } +#line 5780 "sql.c" break; - case 249: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-2].minor.yy0), yymsp[0].minor.yy872); } + case 253: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ +#line 458 "sql.y" +{ pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-2].minor.yy0), yymsp[0].minor.yy164); } +#line 5785 "sql.c" break; - case 250: /* cmd ::= SHOW BNODES */ + case 254: /* cmd ::= SHOW BNODES */ +#line 459 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } +#line 5790 "sql.c" break; - case 251: /* cmd ::= SHOW SNODES */ + case 255: /* cmd ::= SHOW SNODES */ +#line 460 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT); } +#line 5795 "sql.c" break; - case 252: /* cmd ::= SHOW CLUSTER */ + case 256: /* cmd ::= SHOW CLUSTER */ +#line 461 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT); } +#line 5800 "sql.c" break; - case 253: /* cmd ::= SHOW TRANSACTIONS */ + case 257: /* cmd ::= SHOW TRANSACTIONS */ +#line 462 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } +#line 5805 "sql.c" break; - case 254: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ -{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy872); } + case 258: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ +#line 463 "sql.y" +{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy164); } +#line 5810 "sql.c" break; - case 255: /* cmd ::= SHOW CONSUMERS */ + case 259: /* cmd ::= SHOW CONSUMERS */ +#line 464 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); } +#line 5815 "sql.c" break; - case 256: /* cmd ::= SHOW SUBSCRIPTIONS */ + case 260: /* cmd ::= SHOW SUBSCRIPTIONS */ +#line 465 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); } +#line 5820 "sql.c" break; - case 257: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy872, yymsp[-1].minor.yy872, OP_TYPE_EQUAL); } + case 261: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ +#line 466 "sql.y" +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy164, yymsp[-1].minor.yy164, OP_TYPE_EQUAL); } +#line 5825 "sql.c" break; - case 258: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy872, yymsp[0].minor.yy872, yymsp[-3].minor.yy664); } + case 262: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ +#line 467 "sql.y" +{ pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy164, yymsp[0].minor.yy164, yymsp[-3].minor.yy72); } +#line 5830 "sql.c" break; - case 259: /* cmd ::= SHOW VNODES NK_INTEGER */ + case 263: /* cmd ::= SHOW VNODES NK_INTEGER */ +#line 468 "sql.y" { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0), NULL); } +#line 5835 "sql.c" break; - case 260: /* cmd ::= SHOW VNODES NK_STRING */ + case 264: /* cmd ::= SHOW VNODES NK_STRING */ +#line 469 "sql.y" { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, createValueNode(pCxt, TSDB_DATA_TYPE_VARCHAR, &yymsp[0].minor.yy0)); } +#line 5840 "sql.c" break; - case 261: /* cmd ::= SHOW db_name_cond_opt ALIVE */ -{ pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy872, QUERY_NODE_SHOW_DB_ALIVE_STMT); } + case 265: /* cmd ::= SHOW db_name_cond_opt ALIVE */ +#line 471 "sql.y" +{ pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy164, QUERY_NODE_SHOW_DB_ALIVE_STMT); } +#line 5845 "sql.c" break; - case 262: /* cmd ::= SHOW CLUSTER ALIVE */ + case 266: /* cmd ::= SHOW CLUSTER ALIVE */ +#line 472 "sql.y" { pCxt->pRootNode = createShowAliveStmt(pCxt, NULL, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT); } +#line 5850 "sql.c" break; - case 263: /* db_name_cond_opt ::= */ - case 268: /* from_db_opt ::= */ yytestcase(yyruleno==268); -{ yymsp[1].minor.yy872 = createDefaultDatabaseCondValue(pCxt); } + case 267: /* db_name_cond_opt ::= */ + case 272: /* from_db_opt ::= */ yytestcase(yyruleno==272); +#line 474 "sql.y" +{ yymsp[1].minor.yy164 = createDefaultDatabaseCondValue(pCxt); } +#line 5856 "sql.c" break; - case 264: /* db_name_cond_opt ::= db_name NK_DOT */ -{ yylhsminor.yy872 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy929); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 268: /* db_name_cond_opt ::= db_name NK_DOT */ +#line 475 "sql.y" +{ yylhsminor.yy164 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy497); } +#line 5861 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 266: /* like_pattern_opt ::= LIKE NK_STRING */ -{ yymsp[-1].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } + case 270: /* like_pattern_opt ::= LIKE NK_STRING */ +#line 478 "sql.y" +{ yymsp[-1].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } +#line 5867 "sql.c" break; - case 267: /* table_name_cond ::= table_name */ -{ yylhsminor.yy872 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy929); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 271: /* table_name_cond ::= table_name */ +#line 480 "sql.y" +{ yylhsminor.yy164 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy497); } +#line 5872 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 269: /* from_db_opt ::= FROM db_name */ -{ yymsp[-1].minor.yy872 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy929); } + case 273: /* from_db_opt ::= FROM db_name */ +#line 483 "sql.y" +{ yymsp[-1].minor.yy164 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy497); } +#line 5878 "sql.c" break; - case 273: /* tag_item ::= TBNAME */ -{ yylhsminor.yy872 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 277: /* tag_item ::= TBNAME */ +#line 491 "sql.y" +{ yylhsminor.yy164 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } +#line 5883 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 276: /* tag_item ::= column_name column_alias */ -{ yylhsminor.yy872 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy929), &yymsp[0].minor.yy929); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 280: /* tag_item ::= column_name column_alias */ +#line 494 "sql.y" +{ yylhsminor.yy164 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy497), &yymsp[0].minor.yy497); } +#line 5889 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 277: /* tag_item ::= column_name AS column_alias */ -{ yylhsminor.yy872 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy929), &yymsp[0].minor.yy929); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 281: /* tag_item ::= column_name AS column_alias */ +#line 495 "sql.y" +{ yylhsminor.yy164 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy497), &yymsp[0].minor.yy497); } +#line 5895 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 278: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ -{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy857, yymsp[-3].minor.yy872, yymsp[-1].minor.yy872, NULL, yymsp[0].minor.yy872); } + case 282: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ +#line 499 "sql.y" +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy441, yymsp[-3].minor.yy164, yymsp[-1].minor.yy164, NULL, yymsp[0].minor.yy164); } +#line 5901 "sql.c" break; - case 279: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ -{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_NORMAL, yymsp[-6].minor.yy857, yymsp[-5].minor.yy872, yymsp[-3].minor.yy872, yymsp[-1].minor.yy664, NULL); } + case 283: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ +#line 501 "sql.y" +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_NORMAL, yymsp[-6].minor.yy441, yymsp[-5].minor.yy164, yymsp[-3].minor.yy164, yymsp[-1].minor.yy72, NULL); } +#line 5906 "sql.c" break; - case 280: /* cmd ::= DROP INDEX exists_opt full_index_name */ -{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy857, yymsp[0].minor.yy872); } + case 284: /* cmd ::= DROP INDEX exists_opt full_index_name */ +#line 502 "sql.y" +{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy441, yymsp[0].minor.yy164); } +#line 5911 "sql.c" break; - case 281: /* full_index_name ::= index_name */ -{ yylhsminor.yy872 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy929); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 285: /* full_index_name ::= index_name */ +#line 504 "sql.y" +{ yylhsminor.yy164 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy497); } +#line 5916 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 282: /* full_index_name ::= db_name NK_DOT index_name */ -{ yylhsminor.yy872 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy929); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 286: /* full_index_name ::= db_name NK_DOT index_name */ +#line 505 "sql.y" +{ yylhsminor.yy164 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy497); } +#line 5922 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 283: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ -{ yymsp[-9].minor.yy872 = createIndexOption(pCxt, yymsp[-7].minor.yy664, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), NULL, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 287: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ +#line 508 "sql.y" +{ yymsp[-9].minor.yy164 = createIndexOption(pCxt, yymsp[-7].minor.yy72, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), NULL, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 5928 "sql.c" break; - case 284: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ -{ yymsp[-11].minor.yy872 = createIndexOption(pCxt, yymsp[-9].minor.yy664, releaseRawExprNode(pCxt, yymsp[-5].minor.yy872), releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 288: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ +#line 511 "sql.y" +{ yymsp[-11].minor.yy164 = createIndexOption(pCxt, yymsp[-9].minor.yy72, releaseRawExprNode(pCxt, yymsp[-5].minor.yy164), releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 5933 "sql.c" break; - case 287: /* func ::= sma_func_name NK_LP expression_list NK_RP */ -{ yylhsminor.yy872 = createFunctionNode(pCxt, &yymsp[-3].minor.yy929, yymsp[-1].minor.yy664); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 291: /* func ::= sma_func_name NK_LP expression_list NK_RP */ +#line 518 "sql.y" +{ yylhsminor.yy164 = createFunctionNode(pCxt, &yymsp[-3].minor.yy497, yymsp[-1].minor.yy72); } +#line 5938 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 288: /* sma_func_name ::= function_name */ - case 501: /* alias_opt ::= table_alias */ yytestcase(yyruleno==501); -{ yylhsminor.yy929 = yymsp[0].minor.yy929; } - yymsp[0].minor.yy929 = yylhsminor.yy929; + case 292: /* sma_func_name ::= function_name */ + case 505: /* alias_opt ::= table_alias */ yytestcase(yyruleno==505); +#line 522 "sql.y" +{ yylhsminor.yy497 = yymsp[0].minor.yy497; } +#line 5945 "sql.c" + yymsp[0].minor.yy497 = yylhsminor.yy497; break; - case 293: /* sma_stream_opt ::= */ - case 333: /* stream_options ::= */ yytestcase(yyruleno==333); -{ yymsp[1].minor.yy872 = createStreamOptions(pCxt); } + case 297: /* sma_stream_opt ::= */ + case 337: /* stream_options ::= */ yytestcase(yyruleno==337); +#line 528 "sql.y" +{ yymsp[1].minor.yy164 = createStreamOptions(pCxt); } +#line 5952 "sql.c" break; - case 294: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy872)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy872); yylhsminor.yy872 = yymsp[-2].minor.yy872; } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 298: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ +#line 529 "sql.y" +{ ((SStreamOptions*)yymsp[-2].minor.yy164)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy164); yylhsminor.yy164 = yymsp[-2].minor.yy164; } +#line 5957 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 295: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy872)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy872); yylhsminor.yy872 = yymsp[-2].minor.yy872; } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 299: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ +#line 530 "sql.y" +{ ((SStreamOptions*)yymsp[-2].minor.yy164)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy164); yylhsminor.yy164 = yymsp[-2].minor.yy164; } +#line 5963 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 296: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy872)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy872); yylhsminor.yy872 = yymsp[-2].minor.yy872; } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 300: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ +#line 531 "sql.y" +{ ((SStreamOptions*)yymsp[-2].minor.yy164)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy164); yylhsminor.yy164 = yymsp[-2].minor.yy164; } +#line 5969 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 297: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ -{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy857, &yymsp[-2].minor.yy929, yymsp[0].minor.yy872); } + case 301: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ +#line 534 "sql.y" +{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy441, &yymsp[-2].minor.yy497, yymsp[0].minor.yy164); } +#line 5975 "sql.c" break; - case 298: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy857, &yymsp[-3].minor.yy929, &yymsp[0].minor.yy929, false); } + case 302: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ +#line 535 "sql.y" +{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy441, &yymsp[-3].minor.yy497, &yymsp[0].minor.yy497, false); } +#line 5980 "sql.c" break; - case 299: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-6].minor.yy857, &yymsp[-5].minor.yy929, &yymsp[0].minor.yy929, true); } + case 303: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ +#line 537 "sql.y" +{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-6].minor.yy441, &yymsp[-5].minor.yy497, &yymsp[0].minor.yy497, true); } +#line 5985 "sql.c" break; - case 300: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-4].minor.yy857, &yymsp[-3].minor.yy929, yymsp[0].minor.yy872, false); } + case 304: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ +#line 539 "sql.y" +{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-4].minor.yy441, &yymsp[-3].minor.yy497, yymsp[0].minor.yy164, false); } +#line 5990 "sql.c" break; - case 301: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-6].minor.yy857, &yymsp[-5].minor.yy929, yymsp[0].minor.yy872, true); } + case 305: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name */ +#line 541 "sql.y" +{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-6].minor.yy441, &yymsp[-5].minor.yy497, yymsp[0].minor.yy164, true); } +#line 5995 "sql.c" break; - case 302: /* cmd ::= DROP TOPIC exists_opt topic_name */ -{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 306: /* cmd ::= DROP TOPIC exists_opt topic_name */ +#line 542 "sql.y" +{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 6000 "sql.c" break; - case 303: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ -{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy857, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy929); } + case 307: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ +#line 543 "sql.y" +{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy441, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy497); } +#line 6005 "sql.c" break; - case 304: /* cmd ::= DESC full_table_name */ - case 305: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==305); -{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy872); } + case 308: /* cmd ::= DESC full_table_name */ + case 309: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==309); +#line 546 "sql.y" +{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy164); } +#line 6011 "sql.c" break; - case 306: /* cmd ::= RESET QUERY CACHE */ + case 310: /* cmd ::= RESET QUERY CACHE */ +#line 550 "sql.y" { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } +#line 6016 "sql.c" break; - case 307: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - case 308: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==308); -{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy857, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 311: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + case 312: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==312); +#line 553 "sql.y" +{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy441, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 6022 "sql.c" break; - case 311: /* explain_options ::= */ -{ yymsp[1].minor.yy872 = createDefaultExplainOptions(pCxt); } + case 315: /* explain_options ::= */ +#line 561 "sql.y" +{ yymsp[1].minor.yy164 = createDefaultExplainOptions(pCxt); } +#line 6027 "sql.c" break; - case 312: /* explain_options ::= explain_options VERBOSE NK_BOOL */ -{ yylhsminor.yy872 = setExplainVerbose(pCxt, yymsp[-2].minor.yy872, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 316: /* explain_options ::= explain_options VERBOSE NK_BOOL */ +#line 562 "sql.y" +{ yylhsminor.yy164 = setExplainVerbose(pCxt, yymsp[-2].minor.yy164, &yymsp[0].minor.yy0); } +#line 6032 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 313: /* explain_options ::= explain_options RATIO NK_FLOAT */ -{ yylhsminor.yy872 = setExplainRatio(pCxt, yymsp[-2].minor.yy872, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 317: /* explain_options ::= explain_options RATIO NK_FLOAT */ +#line 563 "sql.y" +{ yylhsminor.yy164 = setExplainRatio(pCxt, yymsp[-2].minor.yy164, &yymsp[0].minor.yy0); } +#line 6038 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 314: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ -{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-7].minor.yy857, yymsp[-9].minor.yy857, &yymsp[-6].minor.yy929, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy784, yymsp[-1].minor.yy580, &yymsp[0].minor.yy929, yymsp[-10].minor.yy857); } + case 318: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ +#line 568 "sql.y" +{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-7].minor.yy441, yymsp[-9].minor.yy441, &yymsp[-6].minor.yy497, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy700, yymsp[-1].minor.yy560, &yymsp[0].minor.yy497, yymsp[-10].minor.yy441); } +#line 6044 "sql.c" break; - case 315: /* cmd ::= DROP FUNCTION exists_opt function_name */ -{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 319: /* cmd ::= DROP FUNCTION exists_opt function_name */ +#line 569 "sql.y" +{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 6049 "sql.c" break; - case 320: /* language_opt ::= */ -{ yymsp[1].minor.yy929 = nil_token; } + case 324: /* language_opt ::= */ +#line 583 "sql.y" +{ yymsp[1].minor.yy497 = nil_token; } +#line 6054 "sql.c" break; - case 321: /* language_opt ::= LANGUAGE NK_STRING */ -{ yymsp[-1].minor.yy929 = yymsp[0].minor.yy0; } + case 325: /* language_opt ::= LANGUAGE NK_STRING */ +#line 584 "sql.y" +{ yymsp[-1].minor.yy497 = yymsp[0].minor.yy0; } +#line 6059 "sql.c" break; - case 324: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ -{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-9].minor.yy857, &yymsp[-8].minor.yy929, yymsp[-5].minor.yy872, yymsp[-7].minor.yy872, yymsp[-3].minor.yy664, yymsp[-2].minor.yy872, yymsp[0].minor.yy872, yymsp[-4].minor.yy664); } + case 328: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ +#line 594 "sql.y" +{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-9].minor.yy441, &yymsp[-8].minor.yy497, yymsp[-5].minor.yy164, yymsp[-7].minor.yy164, yymsp[-3].minor.yy72, yymsp[-2].minor.yy164, yymsp[0].minor.yy164, yymsp[-4].minor.yy72); } +#line 6064 "sql.c" break; - case 325: /* cmd ::= DROP STREAM exists_opt stream_name */ -{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 329: /* cmd ::= DROP STREAM exists_opt stream_name */ +#line 595 "sql.y" +{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 6069 "sql.c" break; - case 326: /* cmd ::= PAUSE STREAM exists_opt stream_name */ -{ pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 330: /* cmd ::= PAUSE STREAM exists_opt stream_name */ +#line 596 "sql.y" +{ pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 6074 "sql.c" break; - case 327: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ -{ pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy857, yymsp[-1].minor.yy857, &yymsp[0].minor.yy929); } + case 331: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ +#line 597 "sql.y" +{ pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy441, yymsp[-1].minor.yy441, &yymsp[0].minor.yy497); } +#line 6079 "sql.c" break; - case 334: /* stream_options ::= stream_options TRIGGER AT_ONCE */ - case 335: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==335); -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-2].minor.yy872, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 338: /* stream_options ::= stream_options TRIGGER AT_ONCE */ + case 339: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==339); +#line 611 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-2].minor.yy164, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } +#line 6085 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 336: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-3].minor.yy872, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 340: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ +#line 613 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-3].minor.yy164, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 6091 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 337: /* stream_options ::= stream_options WATERMARK duration_literal */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-2].minor.yy872, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 341: /* stream_options ::= stream_options WATERMARK duration_literal */ +#line 614 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-2].minor.yy164, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 6097 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 338: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-3].minor.yy872, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 342: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ +#line 615 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-3].minor.yy164, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } +#line 6103 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 339: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-2].minor.yy872, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 343: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ +#line 616 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-2].minor.yy164, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } +#line 6109 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 340: /* stream_options ::= stream_options DELETE_MARK duration_literal */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-2].minor.yy872, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 344: /* stream_options ::= stream_options DELETE_MARK duration_literal */ +#line 617 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-2].minor.yy164, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 6115 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 341: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ -{ yylhsminor.yy872 = setStreamOptions(pCxt, yymsp[-3].minor.yy872, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 345: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ +#line 618 "sql.y" +{ yylhsminor.yy164 = setStreamOptions(pCxt, yymsp[-3].minor.yy164, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } +#line 6121 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 343: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - case 535: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==535); - case 555: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==555); -{ yymsp[-3].minor.yy872 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy872); } + case 347: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + case 539: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==539); + case 559: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==559); +#line 621 "sql.y" +{ yymsp[-3].minor.yy164 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy164); } +#line 6129 "sql.c" break; - case 346: /* cmd ::= KILL CONNECTION NK_INTEGER */ + case 350: /* cmd ::= KILL CONNECTION NK_INTEGER */ +#line 629 "sql.y" { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } +#line 6134 "sql.c" break; - case 347: /* cmd ::= KILL QUERY NK_STRING */ + case 351: /* cmd ::= KILL QUERY NK_STRING */ +#line 630 "sql.y" { pCxt->pRootNode = createKillQueryStmt(pCxt, &yymsp[0].minor.yy0); } +#line 6139 "sql.c" break; - case 348: /* cmd ::= KILL TRANSACTION NK_INTEGER */ + case 352: /* cmd ::= KILL TRANSACTION NK_INTEGER */ +#line 631 "sql.y" { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); } +#line 6144 "sql.c" break; - case 349: /* cmd ::= BALANCE VGROUP */ + case 353: /* cmd ::= BALANCE VGROUP */ +#line 634 "sql.y" { pCxt->pRootNode = createBalanceVgroupStmt(pCxt); } +#line 6149 "sql.c" break; - case 350: /* cmd ::= BALANCE VGROUP LEADER */ + case 354: /* cmd ::= BALANCE VGROUP LEADER */ +#line 635 "sql.y" { pCxt->pRootNode = createBalanceVgroupLeaderStmt(pCxt); } +#line 6154 "sql.c" break; - case 351: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + case 355: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ +#line 636 "sql.y" { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } +#line 6159 "sql.c" break; - case 352: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ -{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy664); } + case 356: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ +#line 637 "sql.y" +{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy72); } +#line 6164 "sql.c" break; - case 353: /* cmd ::= SPLIT VGROUP NK_INTEGER */ + case 357: /* cmd ::= SPLIT VGROUP NK_INTEGER */ +#line 638 "sql.y" { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } +#line 6169 "sql.c" break; - case 354: /* dnode_list ::= DNODE NK_INTEGER */ -{ yymsp[-1].minor.yy664 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + case 358: /* dnode_list ::= DNODE NK_INTEGER */ +#line 642 "sql.y" +{ yymsp[-1].minor.yy72 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } +#line 6174 "sql.c" break; - case 356: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ -{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 360: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ +#line 649 "sql.y" +{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 6179 "sql.c" break; - case 359: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ -{ yymsp[-6].minor.yy872 = createInsertStmt(pCxt, yymsp[-4].minor.yy872, yymsp[-2].minor.yy664, yymsp[0].minor.yy872); } + case 363: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ +#line 658 "sql.y" +{ yymsp[-6].minor.yy164 = createInsertStmt(pCxt, yymsp[-4].minor.yy164, yymsp[-2].minor.yy72, yymsp[0].minor.yy164); } +#line 6184 "sql.c" break; - case 360: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ -{ yymsp[-3].minor.yy872 = createInsertStmt(pCxt, yymsp[-1].minor.yy872, NULL, yymsp[0].minor.yy872); } + case 364: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ +#line 659 "sql.y" +{ yymsp[-3].minor.yy164 = createInsertStmt(pCxt, yymsp[-1].minor.yy164, NULL, yymsp[0].minor.yy164); } +#line 6189 "sql.c" break; - case 361: /* literal ::= NK_INTEGER */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 365: /* literal ::= NK_INTEGER */ +#line 662 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } +#line 6194 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 362: /* literal ::= NK_FLOAT */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 366: /* literal ::= NK_FLOAT */ +#line 663 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } +#line 6200 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 363: /* literal ::= NK_STRING */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 367: /* literal ::= NK_STRING */ +#line 664 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } +#line 6206 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 364: /* literal ::= NK_BOOL */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 368: /* literal ::= NK_BOOL */ +#line 665 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } +#line 6212 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 365: /* literal ::= TIMESTAMP NK_STRING */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 369: /* literal ::= TIMESTAMP NK_STRING */ +#line 666 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } +#line 6218 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 366: /* literal ::= duration_literal */ - case 376: /* signed_literal ::= signed */ yytestcase(yyruleno==376); - case 397: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==397); - case 398: /* expression ::= literal */ yytestcase(yyruleno==398); - case 399: /* expression ::= pseudo_column */ yytestcase(yyruleno==399); - case 400: /* expression ::= column_reference */ yytestcase(yyruleno==400); - case 401: /* expression ::= function_expression */ yytestcase(yyruleno==401); - case 402: /* expression ::= case_when_expression */ yytestcase(yyruleno==402); - case 433: /* function_expression ::= literal_func */ yytestcase(yyruleno==433); - case 482: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==482); - case 486: /* boolean_primary ::= predicate */ yytestcase(yyruleno==486); - case 488: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==488); - case 489: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==489); - case 492: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==492); - case 494: /* table_reference ::= table_primary */ yytestcase(yyruleno==494); - case 495: /* table_reference ::= joined_table */ yytestcase(yyruleno==495); - case 499: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==499); - case 557: /* query_simple ::= query_specification */ yytestcase(yyruleno==557); - case 558: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==558); - case 561: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==561); - case 563: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==563); -{ yylhsminor.yy872 = yymsp[0].minor.yy872; } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 370: /* literal ::= duration_literal */ + case 380: /* signed_literal ::= signed */ yytestcase(yyruleno==380); + case 401: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==401); + case 402: /* expression ::= literal */ yytestcase(yyruleno==402); + case 403: /* expression ::= pseudo_column */ yytestcase(yyruleno==403); + case 404: /* expression ::= column_reference */ yytestcase(yyruleno==404); + case 405: /* expression ::= function_expression */ yytestcase(yyruleno==405); + case 406: /* expression ::= case_when_expression */ yytestcase(yyruleno==406); + case 437: /* function_expression ::= literal_func */ yytestcase(yyruleno==437); + case 486: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==486); + case 490: /* boolean_primary ::= predicate */ yytestcase(yyruleno==490); + case 492: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==492); + case 493: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==493); + case 496: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==496); + case 498: /* table_reference ::= table_primary */ yytestcase(yyruleno==498); + case 499: /* table_reference ::= joined_table */ yytestcase(yyruleno==499); + case 503: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==503); + case 561: /* query_simple ::= query_specification */ yytestcase(yyruleno==561); + case 562: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==562); + case 565: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==565); + case 567: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==567); +#line 667 "sql.y" +{ yylhsminor.yy164 = yymsp[0].minor.yy164; } +#line 6244 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 367: /* literal ::= NULL */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 371: /* literal ::= NULL */ +#line 668 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } +#line 6250 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 368: /* literal ::= NK_QUESTION */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 372: /* literal ::= NK_QUESTION */ +#line 669 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } +#line 6256 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 369: /* duration_literal ::= NK_VARIABLE */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 373: /* duration_literal ::= NK_VARIABLE */ +#line 671 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } +#line 6262 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 370: /* signed ::= NK_INTEGER */ -{ yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 374: /* signed ::= NK_INTEGER */ +#line 673 "sql.y" +{ yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } +#line 6268 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 371: /* signed ::= NK_PLUS NK_INTEGER */ -{ yymsp[-1].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } + case 375: /* signed ::= NK_PLUS NK_INTEGER */ +#line 674 "sql.y" +{ yymsp[-1].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } +#line 6274 "sql.c" break; - case 372: /* signed ::= NK_MINUS NK_INTEGER */ + case 376: /* signed ::= NK_MINUS NK_INTEGER */ +#line 675 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); + yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; +#line 6283 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 373: /* signed ::= NK_FLOAT */ -{ yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 377: /* signed ::= NK_FLOAT */ +#line 680 "sql.y" +{ yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } +#line 6289 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 374: /* signed ::= NK_PLUS NK_FLOAT */ -{ yymsp[-1].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } + case 378: /* signed ::= NK_PLUS NK_FLOAT */ +#line 681 "sql.y" +{ yymsp[-1].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } +#line 6295 "sql.c" break; - case 375: /* signed ::= NK_MINUS NK_FLOAT */ + case 379: /* signed ::= NK_MINUS NK_FLOAT */ +#line 682 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); + yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; +#line 6304 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 377: /* signed_literal ::= NK_STRING */ -{ yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 381: /* signed_literal ::= NK_STRING */ +#line 689 "sql.y" +{ yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } +#line 6310 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 378: /* signed_literal ::= NK_BOOL */ -{ yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 382: /* signed_literal ::= NK_BOOL */ +#line 690 "sql.y" +{ yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } +#line 6316 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 379: /* signed_literal ::= TIMESTAMP NK_STRING */ -{ yymsp[-1].minor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } + case 383: /* signed_literal ::= TIMESTAMP NK_STRING */ +#line 691 "sql.y" +{ yymsp[-1].minor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } +#line 6322 "sql.c" break; - case 380: /* signed_literal ::= duration_literal */ - case 382: /* signed_literal ::= literal_func */ yytestcase(yyruleno==382); - case 453: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==453); - case 515: /* select_item ::= common_expression */ yytestcase(yyruleno==515); - case 525: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==525); - case 562: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==562); - case 564: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==564); - case 577: /* search_condition ::= common_expression */ yytestcase(yyruleno==577); -{ yylhsminor.yy872 = releaseRawExprNode(pCxt, yymsp[0].minor.yy872); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 384: /* signed_literal ::= duration_literal */ + case 386: /* signed_literal ::= literal_func */ yytestcase(yyruleno==386); + case 457: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==457); + case 519: /* select_item ::= common_expression */ yytestcase(yyruleno==519); + case 529: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==529); + case 566: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==566); + case 568: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==568); + case 581: /* search_condition ::= common_expression */ yytestcase(yyruleno==581); +#line 692 "sql.y" +{ yylhsminor.yy164 = releaseRawExprNode(pCxt, yymsp[0].minor.yy164); } +#line 6334 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 381: /* signed_literal ::= NULL */ -{ yylhsminor.yy872 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 385: /* signed_literal ::= NULL */ +#line 693 "sql.y" +{ yylhsminor.yy164 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } +#line 6340 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 383: /* signed_literal ::= NK_QUESTION */ -{ yylhsminor.yy872 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 387: /* signed_literal ::= NK_QUESTION */ +#line 695 "sql.y" +{ yylhsminor.yy164 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } +#line 6346 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 403: /* expression ::= NK_LP expression NK_RP */ - case 487: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==487); - case 576: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==576); -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy872)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 407: /* expression ::= NK_LP expression NK_RP */ + case 491: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==491); + case 580: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==580); +#line 756 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy164)); } +#line 6354 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 404: /* expression ::= NK_PLUS expr_or_subquery */ + case 408: /* expression ::= NK_PLUS expr_or_subquery */ +#line 757 "sql.y" { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; +#line 6363 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 405: /* expression ::= NK_MINUS expr_or_subquery */ + case 409: /* expression ::= NK_MINUS expr_or_subquery */ +#line 761 "sql.y" { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy872), NULL)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy164), NULL)); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; +#line 6372 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 406: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + case 410: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ +#line 765 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6382 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 407: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + case 411: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ +#line 770 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6392 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 408: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + case 412: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ +#line 775 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6402 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 409: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + case 413: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ +#line 780 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6412 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 410: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ + case 414: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ +#line 785 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6422 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 411: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 415: /* expression ::= column_reference NK_ARROW NK_STRING */ +#line 790 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6431 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 412: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + case 416: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ +#line 794 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6441 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 413: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + case 417: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ +#line 799 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6451 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 416: /* column_reference ::= column_name */ -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy929, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy929)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 420: /* column_reference ::= column_name */ +#line 810 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy497, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy497)); } +#line 6457 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 417: /* column_reference ::= table_name NK_DOT column_name */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy929, createColumnNode(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy929)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 421: /* column_reference ::= table_name NK_DOT column_name */ +#line 811 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy497, createColumnNode(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy497)); } +#line 6463 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 418: /* pseudo_column ::= ROWTS */ - case 419: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==419); - case 421: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==421); - case 422: /* pseudo_column ::= QEND */ yytestcase(yyruleno==422); - case 423: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==423); - case 424: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==424); - case 425: /* pseudo_column ::= WEND */ yytestcase(yyruleno==425); - case 426: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==426); - case 427: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==427); - case 428: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==428); - case 429: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==429); - case 435: /* literal_func ::= NOW */ yytestcase(yyruleno==435); -{ yylhsminor.yy872 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 422: /* pseudo_column ::= ROWTS */ + case 423: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==423); + case 425: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==425); + case 426: /* pseudo_column ::= QEND */ yytestcase(yyruleno==426); + case 427: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==427); + case 428: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==428); + case 429: /* pseudo_column ::= WEND */ yytestcase(yyruleno==429); + case 430: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==430); + case 431: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==431); + case 432: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==432); + case 433: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==433); + case 439: /* literal_func ::= NOW */ yytestcase(yyruleno==439); +#line 813 "sql.y" +{ yylhsminor.yy164 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } +#line 6480 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 420: /* pseudo_column ::= table_name NK_DOT TBNAME */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy929)))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 424: /* pseudo_column ::= table_name NK_DOT TBNAME */ +#line 815 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy497)))); } +#line 6486 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 430: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 431: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==431); -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy929, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy929, yymsp[-1].minor.yy664)); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 434: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 435: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==435); +#line 826 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy497, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy497, yymsp[-1].minor.yy72)); } +#line 6493 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 432: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), yymsp[-1].minor.yy784)); } - yymsp[-5].minor.yy872 = yylhsminor.yy872; + case 436: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ +#line 829 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), yymsp[-1].minor.yy700)); } +#line 6499 "sql.c" + yymsp[-5].minor.yy164 = yylhsminor.yy164; break; - case 434: /* literal_func ::= noarg_func NK_LP NK_RP */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy929, NULL)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 438: /* literal_func ::= noarg_func NK_LP NK_RP */ +#line 832 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy497, NULL)); } +#line 6505 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 449: /* star_func_para_list ::= NK_STAR */ -{ yylhsminor.yy664 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy664 = yylhsminor.yy664; + case 453: /* star_func_para_list ::= NK_STAR */ +#line 856 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } +#line 6511 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; break; - case 454: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 518: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==518); -{ yylhsminor.yy872 = createColumnNode(pCxt, &yymsp[-2].minor.yy929, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 458: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 522: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==522); +#line 865 "sql.y" +{ yylhsminor.yy164 = createColumnNode(pCxt, &yymsp[-2].minor.yy497, &yymsp[0].minor.yy0); } +#line 6518 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 455: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy664, yymsp[-1].minor.yy872)); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 459: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ +#line 868 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy72, yymsp[-1].minor.yy164)); } +#line 6524 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 456: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), yymsp[-2].minor.yy664, yymsp[-1].minor.yy872)); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; + case 460: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ +#line 870 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), yymsp[-2].minor.yy72, yymsp[-1].minor.yy164)); } +#line 6530 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; break; - case 459: /* when_then_expr ::= WHEN common_expression THEN common_expression */ -{ yymsp[-3].minor.yy872 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872)); } + case 463: /* when_then_expr ::= WHEN common_expression THEN common_expression */ +#line 877 "sql.y" +{ yymsp[-3].minor.yy164 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164)); } +#line 6536 "sql.c" break; - case 461: /* case_when_else_opt ::= ELSE common_expression */ -{ yymsp[-1].minor.yy872 = releaseRawExprNode(pCxt, yymsp[0].minor.yy872); } + case 465: /* case_when_else_opt ::= ELSE common_expression */ +#line 880 "sql.y" +{ yymsp[-1].minor.yy164 = releaseRawExprNode(pCxt, yymsp[0].minor.yy164); } +#line 6541 "sql.c" break; - case 462: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ - case 467: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==467); + case 466: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ + case 471: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==471); +#line 883 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy380, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy796, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6551 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 463: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + case 467: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ +#line 890 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy872), releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy164), releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-4].minor.yy872 = yylhsminor.yy872; +#line 6561 "sql.c" + yymsp[-4].minor.yy164 = yylhsminor.yy164; break; - case 464: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + case 468: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ +#line 896 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy872), releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy164), releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-5].minor.yy872 = yylhsminor.yy872; +#line 6571 "sql.c" + yymsp[-5].minor.yy164 = yylhsminor.yy164; break; - case 465: /* predicate ::= expr_or_subquery IS NULL */ + case 469: /* predicate ::= expr_or_subquery IS NULL */ +#line 901 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), NULL)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6580 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 466: /* predicate ::= expr_or_subquery IS NOT NULL */ + case 470: /* predicate ::= expr_or_subquery IS NOT NULL */ +#line 905 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), NULL)); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; +#line 6589 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 468: /* compare_op ::= NK_LT */ -{ yymsp[0].minor.yy380 = OP_TYPE_LOWER_THAN; } + case 472: /* compare_op ::= NK_LT */ +#line 917 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_LOWER_THAN; } +#line 6595 "sql.c" break; - case 469: /* compare_op ::= NK_GT */ -{ yymsp[0].minor.yy380 = OP_TYPE_GREATER_THAN; } + case 473: /* compare_op ::= NK_GT */ +#line 918 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_GREATER_THAN; } +#line 6600 "sql.c" break; - case 470: /* compare_op ::= NK_LE */ -{ yymsp[0].minor.yy380 = OP_TYPE_LOWER_EQUAL; } + case 474: /* compare_op ::= NK_LE */ +#line 919 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_LOWER_EQUAL; } +#line 6605 "sql.c" break; - case 471: /* compare_op ::= NK_GE */ -{ yymsp[0].minor.yy380 = OP_TYPE_GREATER_EQUAL; } + case 475: /* compare_op ::= NK_GE */ +#line 920 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_GREATER_EQUAL; } +#line 6610 "sql.c" break; - case 472: /* compare_op ::= NK_NE */ -{ yymsp[0].minor.yy380 = OP_TYPE_NOT_EQUAL; } + case 476: /* compare_op ::= NK_NE */ +#line 921 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_NOT_EQUAL; } +#line 6615 "sql.c" break; - case 473: /* compare_op ::= NK_EQ */ -{ yymsp[0].minor.yy380 = OP_TYPE_EQUAL; } + case 477: /* compare_op ::= NK_EQ */ +#line 922 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_EQUAL; } +#line 6620 "sql.c" break; - case 474: /* compare_op ::= LIKE */ -{ yymsp[0].minor.yy380 = OP_TYPE_LIKE; } + case 478: /* compare_op ::= LIKE */ +#line 923 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_LIKE; } +#line 6625 "sql.c" break; - case 475: /* compare_op ::= NOT LIKE */ -{ yymsp[-1].minor.yy380 = OP_TYPE_NOT_LIKE; } + case 479: /* compare_op ::= NOT LIKE */ +#line 924 "sql.y" +{ yymsp[-1].minor.yy796 = OP_TYPE_NOT_LIKE; } +#line 6630 "sql.c" break; - case 476: /* compare_op ::= MATCH */ -{ yymsp[0].minor.yy380 = OP_TYPE_MATCH; } + case 480: /* compare_op ::= MATCH */ +#line 925 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_MATCH; } +#line 6635 "sql.c" break; - case 477: /* compare_op ::= NMATCH */ -{ yymsp[0].minor.yy380 = OP_TYPE_NMATCH; } + case 481: /* compare_op ::= NMATCH */ +#line 926 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_NMATCH; } +#line 6640 "sql.c" break; - case 478: /* compare_op ::= CONTAINS */ -{ yymsp[0].minor.yy380 = OP_TYPE_JSON_CONTAINS; } + case 482: /* compare_op ::= CONTAINS */ +#line 927 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_JSON_CONTAINS; } +#line 6645 "sql.c" break; - case 479: /* in_op ::= IN */ -{ yymsp[0].minor.yy380 = OP_TYPE_IN; } + case 483: /* in_op ::= IN */ +#line 931 "sql.y" +{ yymsp[0].minor.yy796 = OP_TYPE_IN; } +#line 6650 "sql.c" break; - case 480: /* in_op ::= NOT IN */ -{ yymsp[-1].minor.yy380 = OP_TYPE_NOT_IN; } + case 484: /* in_op ::= NOT IN */ +#line 932 "sql.y" +{ yymsp[-1].minor.yy796 = OP_TYPE_NOT_IN; } +#line 6655 "sql.c" break; - case 481: /* in_predicate_value ::= NK_LP literal_list NK_RP */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy664)); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 485: /* in_predicate_value ::= NK_LP literal_list NK_RP */ +#line 934 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy72)); } +#line 6660 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 483: /* boolean_value_expression ::= NOT boolean_primary */ + case 487: /* boolean_value_expression ::= NOT boolean_primary */ +#line 938 "sql.y" { - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy872), NULL)); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy164), NULL)); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; +#line 6669 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 484: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 488: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ +#line 943 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6679 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 485: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 489: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ +#line 949 "sql.y" { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy872); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy872); - yylhsminor.yy872 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy164); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy164); + yylhsminor.yy164 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; +#line 6689 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 493: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ -{ yylhsminor.yy872 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy872, yymsp[0].minor.yy872, NULL); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 497: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ +#line 967 "sql.y" +{ yylhsminor.yy164 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy164, yymsp[0].minor.yy164, NULL); } +#line 6695 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 496: /* table_primary ::= table_name alias_opt */ -{ yylhsminor.yy872 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy929, &yymsp[0].minor.yy929); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 500: /* table_primary ::= table_name alias_opt */ +#line 973 "sql.y" +{ yylhsminor.yy164 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy497, &yymsp[0].minor.yy497); } +#line 6701 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 497: /* table_primary ::= db_name NK_DOT table_name alias_opt */ -{ yylhsminor.yy872 = createRealTableNode(pCxt, &yymsp[-3].minor.yy929, &yymsp[-1].minor.yy929, &yymsp[0].minor.yy929); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 501: /* table_primary ::= db_name NK_DOT table_name alias_opt */ +#line 974 "sql.y" +{ yylhsminor.yy164 = createRealTableNode(pCxt, &yymsp[-3].minor.yy497, &yymsp[-1].minor.yy497, &yymsp[0].minor.yy497); } +#line 6707 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 498: /* table_primary ::= subquery alias_opt */ -{ yylhsminor.yy872 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy872), &yymsp[0].minor.yy929); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 502: /* table_primary ::= subquery alias_opt */ +#line 975 "sql.y" +{ yylhsminor.yy164 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy164), &yymsp[0].minor.yy497); } +#line 6713 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 500: /* alias_opt ::= */ -{ yymsp[1].minor.yy929 = nil_token; } + case 504: /* alias_opt ::= */ +#line 980 "sql.y" +{ yymsp[1].minor.yy497 = nil_token; } +#line 6719 "sql.c" break; - case 502: /* alias_opt ::= AS table_alias */ -{ yymsp[-1].minor.yy929 = yymsp[0].minor.yy929; } + case 506: /* alias_opt ::= AS table_alias */ +#line 982 "sql.y" +{ yymsp[-1].minor.yy497 = yymsp[0].minor.yy497; } +#line 6724 "sql.c" break; - case 503: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 504: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==504); -{ yymsp[-2].minor.yy872 = yymsp[-1].minor.yy872; } + case 507: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 508: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==508); +#line 984 "sql.y" +{ yymsp[-2].minor.yy164 = yymsp[-1].minor.yy164; } +#line 6730 "sql.c" break; - case 505: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ -{ yylhsminor.yy872 = createJoinTableNode(pCxt, yymsp[-4].minor.yy852, yymsp[-5].minor.yy872, yymsp[-2].minor.yy872, yymsp[0].minor.yy872); } - yymsp[-5].minor.yy872 = yylhsminor.yy872; + case 509: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ +#line 989 "sql.y" +{ yylhsminor.yy164 = createJoinTableNode(pCxt, yymsp[-4].minor.yy196, yymsp[-5].minor.yy164, yymsp[-2].minor.yy164, yymsp[0].minor.yy164); } +#line 6735 "sql.c" + yymsp[-5].minor.yy164 = yylhsminor.yy164; break; - case 506: /* join_type ::= */ -{ yymsp[1].minor.yy852 = JOIN_TYPE_INNER; } + case 510: /* join_type ::= */ +#line 993 "sql.y" +{ yymsp[1].minor.yy196 = JOIN_TYPE_INNER; } +#line 6741 "sql.c" break; - case 507: /* join_type ::= INNER */ -{ yymsp[0].minor.yy852 = JOIN_TYPE_INNER; } + case 511: /* join_type ::= INNER */ +#line 994 "sql.y" +{ yymsp[0].minor.yy196 = JOIN_TYPE_INNER; } +#line 6746 "sql.c" break; - case 508: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 512: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ +#line 1000 "sql.y" { - yymsp[-11].minor.yy872 = createSelectStmt(pCxt, yymsp[-10].minor.yy857, yymsp[-9].minor.yy664, yymsp[-8].minor.yy872); - yymsp[-11].minor.yy872 = addWhereClause(pCxt, yymsp[-11].minor.yy872, yymsp[-7].minor.yy872); - yymsp[-11].minor.yy872 = addPartitionByClause(pCxt, yymsp[-11].minor.yy872, yymsp[-6].minor.yy664); - yymsp[-11].minor.yy872 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy872, yymsp[-2].minor.yy872); - yymsp[-11].minor.yy872 = addGroupByClause(pCxt, yymsp[-11].minor.yy872, yymsp[-1].minor.yy664); - yymsp[-11].minor.yy872 = addHavingClause(pCxt, yymsp[-11].minor.yy872, yymsp[0].minor.yy872); - yymsp[-11].minor.yy872 = addRangeClause(pCxt, yymsp[-11].minor.yy872, yymsp[-5].minor.yy872); - yymsp[-11].minor.yy872 = addEveryClause(pCxt, yymsp[-11].minor.yy872, yymsp[-4].minor.yy872); - yymsp[-11].minor.yy872 = addFillClause(pCxt, yymsp[-11].minor.yy872, yymsp[-3].minor.yy872); + yymsp[-11].minor.yy164 = createSelectStmt(pCxt, yymsp[-10].minor.yy441, yymsp[-9].minor.yy72, yymsp[-8].minor.yy164); + yymsp[-11].minor.yy164 = addWhereClause(pCxt, yymsp[-11].minor.yy164, yymsp[-7].minor.yy164); + yymsp[-11].minor.yy164 = addPartitionByClause(pCxt, yymsp[-11].minor.yy164, yymsp[-6].minor.yy72); + yymsp[-11].minor.yy164 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy164, yymsp[-2].minor.yy164); + yymsp[-11].minor.yy164 = addGroupByClause(pCxt, yymsp[-11].minor.yy164, yymsp[-1].minor.yy72); + yymsp[-11].minor.yy164 = addHavingClause(pCxt, yymsp[-11].minor.yy164, yymsp[0].minor.yy164); + yymsp[-11].minor.yy164 = addRangeClause(pCxt, yymsp[-11].minor.yy164, yymsp[-5].minor.yy164); + yymsp[-11].minor.yy164 = addEveryClause(pCxt, yymsp[-11].minor.yy164, yymsp[-4].minor.yy164); + yymsp[-11].minor.yy164 = addFillClause(pCxt, yymsp[-11].minor.yy164, yymsp[-3].minor.yy164); } +#line 6761 "sql.c" break; - case 511: /* set_quantifier_opt ::= ALL */ -{ yymsp[0].minor.yy857 = false; } + case 515: /* set_quantifier_opt ::= ALL */ +#line 1016 "sql.y" +{ yymsp[0].minor.yy441 = false; } +#line 6766 "sql.c" break; - case 514: /* select_item ::= NK_STAR */ -{ yylhsminor.yy872 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy872 = yylhsminor.yy872; + case 518: /* select_item ::= NK_STAR */ +#line 1023 "sql.y" +{ yylhsminor.yy164 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } +#line 6771 "sql.c" + yymsp[0].minor.yy164 = yylhsminor.yy164; break; - case 516: /* select_item ::= common_expression column_alias */ - case 526: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==526); -{ yylhsminor.yy872 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy872), &yymsp[0].minor.yy929); } - yymsp[-1].minor.yy872 = yylhsminor.yy872; + case 520: /* select_item ::= common_expression column_alias */ + case 530: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==530); +#line 1025 "sql.y" +{ yylhsminor.yy164 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy164), &yymsp[0].minor.yy497); } +#line 6778 "sql.c" + yymsp[-1].minor.yy164 = yylhsminor.yy164; break; - case 517: /* select_item ::= common_expression AS column_alias */ - case 527: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==527); -{ yylhsminor.yy872 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), &yymsp[0].minor.yy929); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 521: /* select_item ::= common_expression AS column_alias */ + case 531: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==531); +#line 1026 "sql.y" +{ yylhsminor.yy164 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), &yymsp[0].minor.yy497); } +#line 6785 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 522: /* partition_by_clause_opt ::= PARTITION BY partition_list */ - case 547: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==547); - case 566: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==566); -{ yymsp[-2].minor.yy664 = yymsp[0].minor.yy664; } + case 526: /* partition_by_clause_opt ::= PARTITION BY partition_list */ + case 551: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==551); + case 570: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==570); +#line 1035 "sql.y" +{ yymsp[-2].minor.yy72 = yymsp[0].minor.yy72; } +#line 6793 "sql.c" break; - case 529: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ -{ yymsp[-5].minor.yy872 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), releaseRawExprNode(pCxt, yymsp[-1].minor.yy872)); } + case 533: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ +#line 1048 "sql.y" +{ yymsp[-5].minor.yy164 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), releaseRawExprNode(pCxt, yymsp[-1].minor.yy164)); } +#line 6798 "sql.c" break; - case 530: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ -{ yymsp[-3].minor.yy872 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy872)); } + case 534: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ +#line 1049 "sql.y" +{ yymsp[-3].minor.yy164 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy164)); } +#line 6803 "sql.c" break; - case 531: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-5].minor.yy872 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), NULL, yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 535: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ +#line 1051 "sql.y" +{ yymsp[-5].minor.yy164 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), NULL, yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 6808 "sql.c" break; - case 532: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-7].minor.yy872 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy872), releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), yymsp[-1].minor.yy872, yymsp[0].minor.yy872); } + case 536: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ +#line 1054 "sql.y" +{ yymsp[-7].minor.yy164 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy164), releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), yymsp[-1].minor.yy164, yymsp[0].minor.yy164); } +#line 6813 "sql.c" break; - case 533: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ -{ yymsp[-6].minor.yy872 = createEventWindowNode(pCxt, yymsp[-3].minor.yy872, yymsp[0].minor.yy872); } + case 537: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ +#line 1056 "sql.y" +{ yymsp[-6].minor.yy164 = createEventWindowNode(pCxt, yymsp[-3].minor.yy164, yymsp[0].minor.yy164); } +#line 6818 "sql.c" break; - case 537: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ -{ yymsp[-3].minor.yy872 = createFillNode(pCxt, yymsp[-1].minor.yy294, NULL); } + case 541: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ +#line 1062 "sql.y" +{ yymsp[-3].minor.yy164 = createFillNode(pCxt, yymsp[-1].minor.yy446, NULL); } +#line 6823 "sql.c" break; - case 538: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ -{ yymsp[-5].minor.yy872 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy664)); } + case 542: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ +#line 1063 "sql.y" +{ yymsp[-5].minor.yy164 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy72)); } +#line 6828 "sql.c" break; - case 539: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ -{ yymsp[-5].minor.yy872 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy664)); } + case 543: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ +#line 1064 "sql.y" +{ yymsp[-5].minor.yy164 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy72)); } +#line 6833 "sql.c" break; - case 540: /* fill_mode ::= NONE */ -{ yymsp[0].minor.yy294 = FILL_MODE_NONE; } + case 544: /* fill_mode ::= NONE */ +#line 1068 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_NONE; } +#line 6838 "sql.c" break; - case 541: /* fill_mode ::= PREV */ -{ yymsp[0].minor.yy294 = FILL_MODE_PREV; } + case 545: /* fill_mode ::= PREV */ +#line 1069 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_PREV; } +#line 6843 "sql.c" break; - case 542: /* fill_mode ::= NULL */ -{ yymsp[0].minor.yy294 = FILL_MODE_NULL; } + case 546: /* fill_mode ::= NULL */ +#line 1070 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_NULL; } +#line 6848 "sql.c" break; - case 543: /* fill_mode ::= NULL_F */ -{ yymsp[0].minor.yy294 = FILL_MODE_NULL_F; } + case 547: /* fill_mode ::= NULL_F */ +#line 1071 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_NULL_F; } +#line 6853 "sql.c" break; - case 544: /* fill_mode ::= LINEAR */ -{ yymsp[0].minor.yy294 = FILL_MODE_LINEAR; } + case 548: /* fill_mode ::= LINEAR */ +#line 1072 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_LINEAR; } +#line 6858 "sql.c" break; - case 545: /* fill_mode ::= NEXT */ -{ yymsp[0].minor.yy294 = FILL_MODE_NEXT; } + case 549: /* fill_mode ::= NEXT */ +#line 1073 "sql.y" +{ yymsp[0].minor.yy446 = FILL_MODE_NEXT; } +#line 6863 "sql.c" break; - case 548: /* group_by_list ::= expr_or_subquery */ -{ yylhsminor.yy664 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); } - yymsp[0].minor.yy664 = yylhsminor.yy664; + case 552: /* group_by_list ::= expr_or_subquery */ +#line 1082 "sql.y" +{ yylhsminor.yy72 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } +#line 6868 "sql.c" + yymsp[0].minor.yy72 = yylhsminor.yy72; break; - case 549: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ -{ yylhsminor.yy664 = addNodeToList(pCxt, yymsp[-2].minor.yy664, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy872))); } - yymsp[-2].minor.yy664 = yylhsminor.yy664; + case 553: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ +#line 1083 "sql.y" +{ yylhsminor.yy72 = addNodeToList(pCxt, yymsp[-2].minor.yy72, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy164))); } +#line 6874 "sql.c" + yymsp[-2].minor.yy72 = yylhsminor.yy72; break; - case 553: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ -{ yymsp[-5].minor.yy872 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy872), releaseRawExprNode(pCxt, yymsp[-1].minor.yy872)); } + case 557: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ +#line 1090 "sql.y" +{ yymsp[-5].minor.yy164 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy164), releaseRawExprNode(pCxt, yymsp[-1].minor.yy164)); } +#line 6880 "sql.c" break; - case 556: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 560: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ +#line 1097 "sql.y" { - yylhsminor.yy872 = addOrderByClause(pCxt, yymsp[-3].minor.yy872, yymsp[-2].minor.yy664); - yylhsminor.yy872 = addSlimitClause(pCxt, yylhsminor.yy872, yymsp[-1].minor.yy872); - yylhsminor.yy872 = addLimitClause(pCxt, yylhsminor.yy872, yymsp[0].minor.yy872); + yylhsminor.yy164 = addOrderByClause(pCxt, yymsp[-3].minor.yy164, yymsp[-2].minor.yy72); + yylhsminor.yy164 = addSlimitClause(pCxt, yylhsminor.yy164, yymsp[-1].minor.yy164); + yylhsminor.yy164 = addLimitClause(pCxt, yylhsminor.yy164, yymsp[0].minor.yy164); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; +#line 6889 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 559: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ -{ yylhsminor.yy872 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy872, yymsp[0].minor.yy872); } - yymsp[-3].minor.yy872 = yylhsminor.yy872; + case 563: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ +#line 1107 "sql.y" +{ yylhsminor.yy164 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy164, yymsp[0].minor.yy164); } +#line 6895 "sql.c" + yymsp[-3].minor.yy164 = yylhsminor.yy164; break; - case 560: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ -{ yylhsminor.yy872 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy872, yymsp[0].minor.yy872); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 564: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ +#line 1109 "sql.y" +{ yylhsminor.yy164 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy164, yymsp[0].minor.yy164); } +#line 6901 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 568: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 572: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==572); -{ yymsp[-1].minor.yy872 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } + case 572: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 576: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==576); +#line 1123 "sql.y" +{ yymsp[-1].minor.yy164 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } +#line 6908 "sql.c" break; - case 569: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 573: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==573); -{ yymsp[-3].minor.yy872 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } + case 573: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 577: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==577); +#line 1124 "sql.y" +{ yymsp[-3].minor.yy164 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } +#line 6914 "sql.c" break; - case 570: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 574: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==574); -{ yymsp[-3].minor.yy872 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } + case 574: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 578: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==578); +#line 1125 "sql.y" +{ yymsp[-3].minor.yy164 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } +#line 6920 "sql.c" break; - case 575: /* subquery ::= NK_LP query_expression NK_RP */ -{ yylhsminor.yy872 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy872); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 579: /* subquery ::= NK_LP query_expression NK_RP */ +#line 1133 "sql.y" +{ yylhsminor.yy164 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy164); } +#line 6925 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 580: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ -{ yylhsminor.yy872 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy872), yymsp[-1].minor.yy578, yymsp[0].minor.yy457); } - yymsp[-2].minor.yy872 = yylhsminor.yy872; + case 584: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ +#line 1147 "sql.y" +{ yylhsminor.yy164 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy164), yymsp[-1].minor.yy550, yymsp[0].minor.yy517); } +#line 6931 "sql.c" + yymsp[-2].minor.yy164 = yylhsminor.yy164; break; - case 581: /* ordering_specification_opt ::= */ -{ yymsp[1].minor.yy578 = ORDER_ASC; } + case 585: /* ordering_specification_opt ::= */ +#line 1151 "sql.y" +{ yymsp[1].minor.yy550 = ORDER_ASC; } +#line 6937 "sql.c" break; - case 582: /* ordering_specification_opt ::= ASC */ -{ yymsp[0].minor.yy578 = ORDER_ASC; } + case 586: /* ordering_specification_opt ::= ASC */ +#line 1152 "sql.y" +{ yymsp[0].minor.yy550 = ORDER_ASC; } +#line 6942 "sql.c" break; - case 583: /* ordering_specification_opt ::= DESC */ -{ yymsp[0].minor.yy578 = ORDER_DESC; } + case 587: /* ordering_specification_opt ::= DESC */ +#line 1153 "sql.y" +{ yymsp[0].minor.yy550 = ORDER_DESC; } +#line 6947 "sql.c" break; - case 584: /* null_ordering_opt ::= */ -{ yymsp[1].minor.yy457 = NULL_ORDER_DEFAULT; } + case 588: /* null_ordering_opt ::= */ +#line 1157 "sql.y" +{ yymsp[1].minor.yy517 = NULL_ORDER_DEFAULT; } +#line 6952 "sql.c" break; - case 585: /* null_ordering_opt ::= NULLS FIRST */ -{ yymsp[-1].minor.yy457 = NULL_ORDER_FIRST; } + case 589: /* null_ordering_opt ::= NULLS FIRST */ +#line 1158 "sql.y" +{ yymsp[-1].minor.yy517 = NULL_ORDER_FIRST; } +#line 6957 "sql.c" break; - case 586: /* null_ordering_opt ::= NULLS LAST */ -{ yymsp[-1].minor.yy457 = NULL_ORDER_LAST; } + case 590: /* null_ordering_opt ::= NULLS LAST */ +#line 1159 "sql.y" +{ yymsp[-1].minor.yy517 = NULL_ORDER_LAST; } +#line 6962 "sql.c" break; default: break; /********** End reduce actions ************************************************/ }; - assert( yyrulenoerrCode) { if(TOKEN.z) { @@ -5560,6 +7031,7 @@ static void yy_syntax_error( } else if (TSDB_CODE_PAR_DB_NOT_SPECIFIED == pCxt->errCode && TK_NK_FLOAT == TOKEN.type) { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z); } +#line 7035 "sql.c" /************ End %syntax_error code ******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE @@ -5785,11 +7257,10 @@ void Parse( */ int ParseFallback(int iToken){ #ifdef YYFALLBACK - if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ - return yyFallback[iToken]; - } + assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); + return yyFallback[iToken]; #else (void)iToken; -#endif return 0; +#endif } diff --git a/source/libs/parser/test/parAlterToBalanceTest.cpp b/source/libs/parser/test/parAlterToBalanceTest.cpp index db74e66d2b..d137029a14 100644 --- a/source/libs/parser/test/parAlterToBalanceTest.cpp +++ b/source/libs/parser/test/parAlterToBalanceTest.cpp @@ -875,4 +875,4 @@ TEST_F(ParserInitialATest, balanceVgroupLeader) { run("BALANCE VGROUP LEADER"); } -} // namespace ParserTest \ No newline at end of file +} // namespace ParserTest diff --git a/source/libs/parser/test/parExplainToSyncdbTest.cpp b/source/libs/parser/test/parExplainToSyncdbTest.cpp index 7f2cc05204..014374af7e 100644 --- a/source/libs/parser/test/parExplainToSyncdbTest.cpp +++ b/source/libs/parser/test/parExplainToSyncdbTest.cpp @@ -187,6 +187,63 @@ TEST_F(ParserExplainToSyncdbTest, redistributeVgroup) { run("REDISTRIBUTE VGROUP 5 DNODE 10 DNODE 20 DNODE 30"); } +TEST_F(ParserExplainToSyncdbTest, restoreDnode) { + useDb("root", "test"); + + SRestoreDnodeReq expect = {0}; + + auto clearRestoreDnodeReq = [&]() { memset(&expect, 0, sizeof(SRestoreDnodeReq)); }; + + auto setRestoreDnodeReq = [&](int32_t dnodeId, int8_t type) { + expect.dnodeId = dnodeId; + expect.restoreType = type; + }; + + setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { + int32_t expectNodeType = 0; + switch (expect.restoreType) { + case RESTORE_TYPE__ALL: + expectNodeType = QUERY_NODE_RESTORE_DNODE_STMT; + break; + case RESTORE_TYPE__MNODE: + expectNodeType = QUERY_NODE_RESTORE_MNODE_STMT; + break; + case RESTORE_TYPE__VNODE: + expectNodeType = QUERY_NODE_RESTORE_VNODE_STMT; + break; + case RESTORE_TYPE__QNODE: + expectNodeType = QUERY_NODE_RESTORE_QNODE_STMT; + break; + default: + break; + } + ASSERT_EQ(nodeType(pQuery->pRoot), expectNodeType); + ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_RESTORE_DNODE); + SRestoreDnodeReq req = {0}; + ASSERT_EQ(tDeserializeSRestoreDnodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS); + ASSERT_EQ(req.dnodeId, expect.dnodeId); + ASSERT_EQ(req.restoreType, expect.restoreType); + }); + + setRestoreDnodeReq(1, RESTORE_TYPE__ALL); + run("RESTORE DNODE 1"); + clearRestoreDnodeReq(); + + setRestoreDnodeReq(2, RESTORE_TYPE__MNODE); + run("RESTORE MNODE ON DNODE 2"); + clearRestoreDnodeReq(); + + setRestoreDnodeReq(1, RESTORE_TYPE__VNODE); + run("RESTORE VNODE ON DNODE 1"); + clearRestoreDnodeReq(); + + setRestoreDnodeReq(2, RESTORE_TYPE__QNODE); + run("RESTORE QNODE ON DNODE 2"); + clearRestoreDnodeReq(); +} + + + // todo reset query cache TEST_F(ParserExplainToSyncdbTest, revoke) { diff --git a/source/libs/parser/test/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp index ec6c69ea8d..2d8ce55b72 100644 --- a/source/libs/parser/test/parSelectTest.cpp +++ b/source/libs/parser/test/parSelectTest.cpp @@ -239,6 +239,19 @@ TEST_F(ParserSelectTest, groupBySemanticCheck) { run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 GROUP BY c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); } +TEST_F(ParserSelectTest, havingCheck) { + useDb("root", "test"); + + run("select tbname,count(*) from st1 partition by tbname having c1>0", TSDB_CODE_PAR_INVALID_OPTR_USAGE); + + run("select tbname,count(*) from st1 group by tbname having c1>0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); + + run("select max(c1) from st1 group by tbname having c1>0"); + + run("select max(c1) from st1 partition by tbname having c1>0"); +} + + TEST_F(ParserSelectTest, orderBy) { useDb("root", "test"); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 0216a214c2..ea6ffed1f6 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2418,6 +2418,36 @@ static bool tagScanOptShouldBeOptimized(SLogicNode* pNode) { return true; } +static SLogicNode* tagScanOptFindAncestorWithSlimit(SLogicNode* pTableScanNode) { + SLogicNode* pNode = pTableScanNode->pParent; + while (NULL != pNode) { + if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode) || QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode) || + QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode) || QUERY_NODE_LOGIC_PLAN_SORT == nodeType(pNode)) { + return NULL; + } + if (NULL != pNode->pSlimit) { + return pNode; + } + pNode = pNode->pParent; + } + return NULL; +} + +static void tagScanOptCloneAncestorSlimit(SLogicNode* pTableScanNode) { + if (NULL != pTableScanNode->pSlimit) { + return; + } + + SLogicNode* pNode = tagScanOptFindAncestorWithSlimit(pTableScanNode); + if (NULL != pNode) { + //TODO: only set the slimit now. push down slimit later + pTableScanNode->pSlimit = nodesCloneNode(pNode->pSlimit); + ((SLimitNode*)pTableScanNode->pSlimit)->limit += ((SLimitNode*)pTableScanNode->pSlimit)->offset; + ((SLimitNode*)pTableScanNode->pSlimit)->offset = 0; + } + return; +} + static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { SScanLogicNode* pScanNode = (SScanLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, tagScanOptShouldBeOptimized); if (NULL == pScanNode) { @@ -2458,6 +2488,7 @@ static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubp NODES_CLEAR_LIST(pAgg->pChildren); } nodesDestroyNode((SNode*)pAgg); + tagScanOptCloneAncestorSlimit((SLogicNode*)pScanNode); pCxt->optimized = true; return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index e2c2e4c655..be43bb008c 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1559,6 +1559,7 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SMergeLogicNode* pM pMerge->numOfChannels = pMergeLogicNode->numOfChannels; pMerge->srcGroupId = pMergeLogicNode->srcGroupId; pMerge->groupSort = pMergeLogicNode->groupSort; + pMerge->ignoreGroupId = pMergeLogicNode->ignoreGroupId; int32_t code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index fd77261818..504db0d07b 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -532,6 +532,25 @@ static int32_t stbSplGetNumOfVgroups(SLogicNode* pNode) { return 0; } +static int32_t stbSplRewriteFromMergeNode(SMergeLogicNode* pMerge, SLogicNode* pNode) { + int32_t code = TSDB_CODE_SUCCESS; + + switch (nodeType(pNode)) { + case QUERY_NODE_LOGIC_PLAN_PROJECT: { + SProjectLogicNode *pLogicNode = (SProjectLogicNode*)pNode; + if (pLogicNode->ignoreGroupId && (pMerge->node.pLimit || pMerge->node.pSlimit)) { + pMerge->ignoreGroupId = true; + pLogicNode->ignoreGroupId = false; + } + break; + } + default: + break; + } + + return code; +} + static int32_t stbSplCreateMergeNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pSplitNode, SNodeList* pMergeKeys, SLogicNode* pPartChild, bool groupSort) { SMergeLogicNode* pMerge = (SMergeLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_MERGE); @@ -563,6 +582,9 @@ static int32_t stbSplCreateMergeNode(SSplitContext* pCxt, SLogicSubplan* pSubpla ((SLimitNode*)pSplitNode->pLimit)->limit += ((SLimitNode*)pSplitNode->pLimit)->offset; ((SLimitNode*)pSplitNode->pLimit)->offset = 0; } + if (TSDB_CODE_SUCCESS == code) { + code = stbSplRewriteFromMergeNode(pMerge, pSplitNode); + } if (TSDB_CODE_SUCCESS == code) { if (NULL == pSubplan) { code = nodesListMakeAppend(&pSplitNode->pChildren, (SNode*)pMerge); diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index c6a4a97f6e..58b8e53478 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -19,6 +19,14 @@ #include "scalar.h" #include "tglobal.h" +static void debugPrintNode(SNode* pNode) { + char* pStr = NULL; + nodesNodeToString(pNode, false, &pStr, NULL); + printf("%s\n", pStr); + taosMemoryFree(pStr); + return; +} + static void dumpQueryPlan(SQueryPlan* pPlan) { if (!tsQueryPlannerTrace) { return; diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 42c2c7f360..1afcf44958 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -12,7 +12,7 @@ typedef double (*_double_fn)(double); typedef double (*_double_fn_2)(double, double); typedef int (*_conv_fn)(int); typedef void (*_trim_fn)(char *, char *, int32_t, int32_t); -typedef int16_t (*_len_fn)(char *, int32_t); +typedef uint16_t (*_len_fn)(char *, int32_t); /** Math functions **/ static double tlog(double v) { return log(v); } @@ -286,9 +286,9 @@ static int32_t doScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarP } /** String functions **/ -static int16_t tlength(char *input, int32_t type) { return varDataLen(input); } +static VarDataLenT tlength(char *input, int32_t type) { return varDataLen(input); } -static int16_t tcharlength(char *input, int32_t type) { +static VarDataLenT tcharlength(char *input, int32_t type) { if (type == TSDB_DATA_TYPE_VARCHAR) { return varDataLen(input); } else { // NCHAR @@ -377,7 +377,7 @@ static int32_t doLengthFunction(SScalarParam *pInput, int32_t inputNum, SScalarP return TSDB_CODE_SUCCESS; } -static int32_t concatCopyHelper(const char *input, char *output, bool hasNchar, int32_t type, int16_t *dataLen) { +static int32_t concatCopyHelper(const char *input, char *output, bool hasNchar, int32_t type, VarDataLenT *dataLen) { if (hasNchar && type == TSDB_DATA_TYPE_VARCHAR) { TdUcs4 *newBuf = taosMemoryCalloc((varDataLen(input) + 1) * TSDB_NCHAR_SIZE, 1); int32_t len = varDataLen(input); @@ -457,7 +457,7 @@ int32_t concatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu continue; } - int16_t dataLen = 0; + VarDataLenT dataLen = 0; for (int32_t i = 0; i < inputNum; ++i) { int32_t rowIdx = (pInput[i].numOfRows == 1) ? 0 : k; input[i] = colDataGetData(pInputData[i], rowIdx); @@ -526,8 +526,8 @@ int32_t concatWsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p continue; } - int16_t dataLen = 0; - bool hasNull = false; + VarDataLenT dataLen = 0; + bool hasNull = false; for (int32_t i = 1; i < inputNum; ++i) { if (colDataIsNull_s(pInputData[i], k) || IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[i]))) { hasNull = true; @@ -695,7 +695,7 @@ int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu /** Conversion functions **/ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int16_t inputType = GET_PARAM_TYPE(&pInput[0]); - int16_t inputLen = GET_PARAM_BYTES(&pInput[0]); + int32_t inputLen = GET_PARAM_BYTES(&pInput[0]); int16_t outputType = GET_PARAM_TYPE(&pOutput[0]); int64_t outputLen = GET_PARAM_BYTES(&pOutput[0]); diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 9a39bb09dc..635024519e 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -299,9 +299,8 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { int32_t numOfBlocks = taosQueueItemSize(pTask->inputQueue->queue) + 1; double size = taosQueueMemorySize(pTask->inputQueue->queue) / 1048576.0; - qDebug("s-task:%s submit enqueue %p %p msgLen:%d ver:%" PRId64 ", total in queue:%d, size:%.2fMiB", pTask->id.idStr, - pItem, pSubmitBlock->submit.msgStr, pSubmitBlock->submit.msgLen, - pSubmitBlock->submit.ver, numOfBlocks, size); + qDebug("s-task:%s submit enqueue msgLen:%d ver:%" PRId64 ", total in queue:%d, size:%.2fMiB", pTask->id.idStr, + pSubmitBlock->submit.msgLen, pSubmitBlock->submit.ver, numOfBlocks, size); if ((pTask->taskLevel == TASK_LEVEL__SOURCE) && (numOfBlocks > STREAM_TASK_INPUT_QUEUEU_CAPACITY || (size >= STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE))) { @@ -345,6 +344,8 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { return 0; } +static void* streamQueueCurItem(SStreamQueue* queue) { return queue->qItem; } + void* streamQueueNextItem(SStreamQueue* queue) { int8_t dequeueFlag = atomic_exchange_8(&queue->status, STREAM_QUEUE__PROCESSING); if (dequeueFlag == STREAM_QUEUE__FAILED) { diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index 7fb35ad2ad..e574cdbe8a 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -159,7 +159,8 @@ SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* return dst; } else if (dst->type == STREAM_INPUT__DATA_SUBMIT && pElem->type == STREAM_INPUT__DATA_SUBMIT) { SStreamMergedSubmit2* pMerged = streamMergedSubmitNew(); - ASSERT(pMerged); + // todo handle error + streamMergeSubmit(pMerged, (SStreamDataSubmit2*)dst); streamMergeSubmit(pMerged, (SStreamDataSubmit2*)pElem); taosFreeQitem(dst); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 78a1f3e967..0fb78fb589 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -15,7 +15,8 @@ #include "streamInc.h" -#define MAX_STREAM_EXEC_BATCH_NUM 10240 +// maximum allowed processed block batches. One block may include several submit blocks +#define MAX_STREAM_EXEC_BATCH_NUM 128 #define MIN_STREAM_EXEC_BATCH_NUM 16 bool streamTaskShouldStop(const SStreamStatus* pStatus) { @@ -66,7 +67,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, const void* data, SArray* SArray* pBlockList = pMerged->submits; int32_t numOfBlocks = taosArrayGetSize(pBlockList); - qDebug("st-task:%s %p set submit input (merged), batch num:%d", pTask->id.idStr, pTask, numOfBlocks); + qDebug("s-task:%s %p set submit input (merged), numOfblocks:%d", pTask->id.idStr, pTask, numOfBlocks); qSetMultiStreamInput(pExecutor, pBlockList->pData, numOfBlocks, STREAM_INPUT__MERGED_SUBMIT); } else if (pItem->type == STREAM_INPUT__REF_DATA_BLOCK) { const SStreamRefDataBlock* pRefBlock = (const SStreamRefDataBlock*)data; @@ -259,9 +260,10 @@ int32_t streamExecForAll(SStreamTask* pTask) { int32_t code = 0; while (1) { int32_t batchSize = 1; - void* pInput = NULL; int16_t times = 0; + SStreamQueueItem* pInput = NULL; + // merge multiple input data if possible in the input queue. qDebug("s-task:%s start to extract data block from inputQ", pTask->id.idStr); @@ -271,10 +273,11 @@ int32_t streamExecForAll(SStreamTask* pTask) { if (pTask->taskLevel == TASK_LEVEL__SOURCE && batchSize < MIN_STREAM_EXEC_BATCH_NUM && times < 5) { times++; taosMsleep(1); - qDebug("===stream===try agian batchSize:%d", batchSize); + qDebug("===stream===try again batchSize:%d", batchSize); continue; } + qDebug("===stream===break batchSize:%d", batchSize); break; } @@ -285,6 +288,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { break; } } else { + // todo we need to sort the data block, instead of just appending into the array list. void* newRet = NULL; if ((newRet = streamMergeQueueItem(pInput, qItem)) == NULL) { streamQueueProcessFail(pTask->inputQueue); @@ -294,6 +298,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { pInput = newRet; streamQueueProcessSuccess(pTask->inputQueue); if (batchSize > MAX_STREAM_EXEC_BATCH_NUM) { + qDebug("maximum batch limit:%d reached, processing, %s", MAX_STREAM_EXEC_BATCH_NUM, pTask->id.idStr); break; } } @@ -304,6 +309,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { if (pInput) { streamFreeQitem(pInput); } + return 0; } @@ -312,14 +318,14 @@ int32_t streamExecForAll(SStreamTask* pTask) { } if (pTask->taskLevel == TASK_LEVEL__SINK) { - ASSERT(((SStreamQueueItem*)pInput)->type == STREAM_INPUT__DATA_BLOCK); + ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); qDebug("s-task:%s sink node start to sink result. numOfBlocks:%d", pTask->id.idStr, batchSize); - streamTaskOutput(pTask, pInput); + streamTaskOutput(pTask, (SStreamDataBlock*)pInput); continue; } SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock)); - qDebug("s-task:%s start to execute, numOfBlocks:%d", pTask->id.idStr, batchSize); + qDebug("s-task:%s start to execute, block batches:%d", pTask->id.idStr, batchSize); streamTaskExecImpl(pTask, pInput, pRes); diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index a8af310bad..682ce08c7f 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -220,8 +220,12 @@ int32_t streamMetaAddDeployedTask(SStreamMeta* pMeta, int64_t ver, SStreamTask* return -1; } - taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(int32_t), &pTask, POINTER_BYTES); - taosArrayPush(pMeta->pTaskList, &pTask->id.taskId); + void* p = taosHashGet(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId)); + if (p == NULL) { + taosArrayPush(pMeta->pTaskList, &pTask->id.taskId); + } + + taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, POINTER_BYTES); return 0; } @@ -356,15 +360,18 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) { return -1; } - if (taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(int32_t), &pTask, sizeof(void*)) < 0) { + void* p = taosHashGet(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId)); + if (p == NULL) { + taosArrayPush(pMeta->pTaskList, &pTask->id.taskId); + } + + if (taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, sizeof(void*)) < 0) { tdbFree(pKey); tdbFree(pVal); tdbTbcClose(pCur); return -1; } - taosArrayPush(pMeta->pTaskList, &pTask->id.taskId); - if (pTask->fillHistory) { pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM; streamTaskCheckDownstream(pTask, ver); diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index db530aa5a2..373cb27941 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -93,10 +93,6 @@ int stateKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) { SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath, int32_t szPage, int32_t pages) { qWarn("open stream state, %s", path); - if (pTask == NULL) { - qWarn("failed to open stream state, %s", path); - return NULL; - } SStreamState* pState = taosMemoryCalloc(1, sizeof(SStreamState)); if (pState == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -127,7 +123,6 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath, int taosMemoryFree(pState); pState = NULL; } - // qWarn("open stream state2, %s", statePath); pState->pTdbState->pOwner = pTask; pState->pFileState = NULL; _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT); diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c index af084cb1b5..8a03896978 100644 --- a/source/libs/stream/src/streamTask.c +++ b/source/libs/stream/src/streamTask.c @@ -195,6 +195,7 @@ void tFreeStreamTask(SStreamTask* pTask) { if (pTask->outputType == TASK_OUTPUT__TABLE) { tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper); taosMemoryFree(pTask->tbSink.pTSchema); + tSimpleHashCleanup(pTask->tbSink.pTblInfo); } if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { diff --git a/source/libs/sync/inc/syncIndexMgr.h b/source/libs/sync/inc/syncIndexMgr.h index 4e6ab284f8..a4e83dc495 100644 --- a/source/libs/sync/inc/syncIndexMgr.h +++ b/source/libs/sync/inc/syncIndexMgr.h @@ -24,12 +24,13 @@ extern "C" { // SIndexMgr ----------------------------- typedef struct SSyncIndexMgr { - SRaftId (*replicas)[TSDB_MAX_REPLICA]; - SyncIndex index[TSDB_MAX_REPLICA]; - SyncTerm privateTerm[TSDB_MAX_REPLICA]; // for advanced function - int64_t startTimeArr[TSDB_MAX_REPLICA]; - int64_t recvTimeArr[TSDB_MAX_REPLICA]; + SRaftId (*replicas)[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SyncIndex index[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SyncTerm privateTerm[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; // for advanced function + int64_t startTimeArr[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + int64_t recvTimeArr[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; int32_t replicaNum; + int32_t totalReplicaNum; SSyncNode *pNode; } SSyncIndexMgr; diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h index 6f2c1a1ad0..7d336c8313 100644 --- a/source/libs/sync/inc/syncInt.h +++ b/source/libs/sync/inc/syncInt.h @@ -54,13 +54,13 @@ typedef struct SSyncLogReplMgr SSyncLogReplMgr; #define MAX_CONFIG_INDEX_COUNT 256 typedef struct SRaftCfg { - SSyncCfg cfg; - int32_t batchSize; - int8_t isStandBy; - int8_t snapshotStrategy; - SyncIndex lastConfigIndex; - int32_t configIndexCount; - SyncIndex configIndexArr[MAX_CONFIG_INDEX_COUNT]; + SSyncCfg cfg; + int32_t batchSize; + int8_t isStandBy; + int8_t snapshotStrategy; + SyncIndex lastConfigIndex; + int32_t configIndexCount; + SyncIndex configIndexArr[MAX_CONFIG_INDEX_COUNT]; } SRaftCfg; typedef struct SRaftId { @@ -127,12 +127,13 @@ typedef struct SSyncNode { SRaftId myRaftId; int32_t peersNum; - SNodeInfo peersNodeInfo[TSDB_MAX_REPLICA]; - SEpSet peersEpset[TSDB_MAX_REPLICA]; - SRaftId peersId[TSDB_MAX_REPLICA]; + SNodeInfo peersNodeInfo[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SEpSet peersEpset[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + SRaftId peersId[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; int32_t replicaNum; - SRaftId replicasId[TSDB_MAX_REPLICA]; + int32_t totalReplicaNum; + SRaftId replicasId[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; // raft algorithm SSyncFSM* pFsm; @@ -188,7 +189,7 @@ typedef struct SSyncNode { uint64_t heartbeatTimerCounter; // peer heartbeat timer - SSyncTimer peerHeartbeatTimerArr[TSDB_MAX_REPLICA]; + SSyncTimer peerHeartbeatTimerArr[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; // tools SSyncRespMgr* pSyncRespMgr; @@ -196,13 +197,13 @@ typedef struct SSyncNode { // restore state bool restoreFinish; // SSnapshot* pSnapshot; - SSyncSnapshotSender* senders[TSDB_MAX_REPLICA]; + SSyncSnapshotSender* senders[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; SSyncSnapshotReceiver* pNewNodeReceiver; // log replication mgr - SSyncLogReplMgr* logReplMgrs[TSDB_MAX_REPLICA]; + SSyncLogReplMgr* logReplMgrs[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; - SPeerState peerStates[TSDB_MAX_REPLICA]; + SPeerState peerStates[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; // is config changing bool changing; @@ -275,6 +276,7 @@ void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term); void syncNodeUpdateTermWithoutStepDown(SSyncNode* pSyncNode, SyncTerm term); void syncNodeStepDown(SSyncNode* pSyncNode, SyncTerm newTerm); void syncNodeBecomeFollower(SSyncNode* pSyncNode, const char* debugStr); +void syncNodeBecomeLearner(SSyncNode* pSyncNode, const char* debugStr); void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr); void syncNodeCandidate2Leader(SSyncNode* pSyncNode); void syncNodeFollower2Candidate(SSyncNode* pSyncNode); diff --git a/source/libs/sync/inc/syncMessage.h b/source/libs/sync/inc/syncMessage.h index c3566c7c82..f8c96d8be2 100644 --- a/source/libs/sync/inc/syncMessage.h +++ b/source/libs/sync/inc/syncMessage.h @@ -237,6 +237,7 @@ typedef struct SyncLeaderTransfer { typedef enum { SYNC_LOCAL_CMD_STEP_DOWN = 100, SYNC_LOCAL_CMD_FOLLOWER_CMT, + SYNC_LOCAL_CMD_LEARNER_CMT, } ESyncLocalCmd; typedef struct SyncLocalCmd { diff --git a/source/libs/sync/inc/syncPipeline.h b/source/libs/sync/inc/syncPipeline.h index d709e33cd4..02790732a2 100644 --- a/source/libs/sync/inc/syncPipeline.h +++ b/source/libs/sync/inc/syncPipeline.h @@ -56,6 +56,8 @@ typedef struct SSyncLogBuffer { int64_t size; TdThreadMutex mutex; TdThreadMutexAttr attr; + int64_t totalIndex; + bool isCatchup; } SSyncLogBuffer; // SSyncLogRepMgr diff --git a/source/libs/sync/src/syncAppendEntries.c b/source/libs/sync/src/syncAppendEntries.c index deae4b0b3f..6f065f56e8 100644 --- a/source/libs/sync/src/syncAppendEntries.c +++ b/source/libs/sync/src/syncAppendEntries.c @@ -126,8 +126,10 @@ int32_t syncNodeOnAppendEntries(SSyncNode* ths, const SRpcMsg* pRpcMsg) { pReply->term = pMsg->term; } - syncNodeStepDown(ths, pMsg->term); - resetElect = true; + if(ths->raftCfg.cfg.nodeInfo[ths->raftCfg.cfg.myIndex].nodeRole != TAOS_SYNC_ROLE_LEARNER){ + syncNodeStepDown(ths, pMsg->term); + resetElect = true; + } if (pMsg->dataLen < sizeof(SSyncRaftEntry)) { sError("vgId:%d, incomplete append entries received. prev index:%" PRId64 ", term:%" PRId64 ", datalen:%d", diff --git a/source/libs/sync/src/syncCommit.c b/source/libs/sync/src/syncCommit.c index 01f1f00c8b..47e4049c73 100644 --- a/source/libs/sync/src/syncCommit.c +++ b/source/libs/sync/src/syncCommit.c @@ -59,10 +59,12 @@ bool syncNodeAgreedUpon(SSyncNode* pNode, SyncIndex index) { SSyncIndexMgr* pMatches = pNode->pMatchIndex; ASSERT(pNode->replicaNum == pMatches->replicaNum); - for (int i = 0; i < pNode->replicaNum; i++) { - SyncIndex matchIndex = pMatches->index[i]; - if (matchIndex >= index) { - count++; + for (int i = 0; i < pNode->totalReplicaNum; i++) { + if(pNode->raftCfg.cfg.nodeInfo[i].nodeRole == TAOS_SYNC_ROLE_VOTER){ + SyncIndex matchIndex = pMatches->index[i]; + if (matchIndex >= index) { + count++; + } } } diff --git a/source/libs/sync/src/syncElection.c b/source/libs/sync/src/syncElection.c index 3699efbc59..86e28db90c 100644 --- a/source/libs/sync/src/syncElection.c +++ b/source/libs/sync/src/syncElection.c @@ -41,6 +41,8 @@ static int32_t syncNodeRequestVotePeers(SSyncNode* pNode) { int32_t ret = 0; for (int i = 0; i < pNode->peersNum; ++i) { + if(pNode->peersNodeInfo[i].nodeRole == TAOS_SYNC_ROLE_LEARNER) continue; + SRpcMsg rpcMsg = {0}; ret = syncBuildRequestVote(&rpcMsg, pNode->vgId); if (ret < 0) { diff --git a/source/libs/sync/src/syncIndexMgr.c b/source/libs/sync/src/syncIndexMgr.c index 7ecb9d7782..e3c3f63a4f 100644 --- a/source/libs/sync/src/syncIndexMgr.c +++ b/source/libs/sync/src/syncIndexMgr.c @@ -26,6 +26,7 @@ SSyncIndexMgr *syncIndexMgrCreate(SSyncNode *pNode) { pIndexMgr->replicas = &pNode->replicasId; pIndexMgr->replicaNum = pNode->replicaNum; + pIndexMgr->totalReplicaNum = pNode->totalReplicaNum; pIndexMgr->pNode = pNode; syncIndexMgrClear(pIndexMgr); @@ -35,6 +36,7 @@ SSyncIndexMgr *syncIndexMgrCreate(SSyncNode *pNode) { void syncIndexMgrUpdate(SSyncIndexMgr *pIndexMgr, SSyncNode *pNode) { pIndexMgr->replicas = &pNode->replicasId; pIndexMgr->replicaNum = pNode->replicaNum; + pIndexMgr->totalReplicaNum = pNode->totalReplicaNum; pIndexMgr->pNode = pNode; syncIndexMgrClear(pIndexMgr); } @@ -50,14 +52,14 @@ void syncIndexMgrClear(SSyncIndexMgr *pIndexMgr) { memset(pIndexMgr->privateTerm, 0, sizeof(pIndexMgr->privateTerm)); int64_t timeNow = taosGetTimestampMs(); - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { pIndexMgr->startTimeArr[i] = 0; pIndexMgr->recvTimeArr[i] = timeNow; } } void syncIndexMgrSetIndex(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, SyncIndex index) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { (pIndexMgr->index)[i] = index; return; @@ -69,7 +71,7 @@ void syncIndexMgrSetIndex(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, Sync } SSyncLogReplMgr *syncNodeGetLogReplMgr(SSyncNode *pNode, SRaftId *pRaftId) { - for (int i = 0; i < pNode->replicaNum; i++) { + for (int i = 0; i < pNode->totalReplicaNum; i++) { if (syncUtilSameId(&pNode->replicasId[i], pRaftId)) { return pNode->logReplMgrs[i]; } @@ -80,7 +82,7 @@ SSyncLogReplMgr *syncNodeGetLogReplMgr(SSyncNode *pNode, SRaftId *pRaftId) { } SyncIndex syncIndexMgrGetIndex(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { SyncIndex idx = (pIndexMgr->index)[i]; return idx; @@ -93,7 +95,7 @@ SyncIndex syncIndexMgrGetIndex(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId) } void syncIndexMgrSetStartTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, int64_t startTime) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { (pIndexMgr->startTimeArr)[i] = startTime; return; @@ -105,7 +107,7 @@ void syncIndexMgrSetStartTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, } int64_t syncIndexMgrGetStartTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { int64_t startTime = (pIndexMgr->startTimeArr)[i]; return startTime; @@ -118,7 +120,7 @@ int64_t syncIndexMgrGetStartTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftI } void syncIndexMgrSetRecvTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, int64_t recvTime) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { (pIndexMgr->recvTimeArr)[i] = recvTime; return; @@ -130,7 +132,7 @@ void syncIndexMgrSetRecvTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, i } int64_t syncIndexMgrGetRecvTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { int64_t recvTime = (pIndexMgr->recvTimeArr)[i]; return recvTime; @@ -143,7 +145,7 @@ int64_t syncIndexMgrGetRecvTime(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId } void syncIndexMgrSetTerm(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, SyncTerm term) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { (pIndexMgr->privateTerm)[i] = term; return; @@ -155,7 +157,7 @@ void syncIndexMgrSetTerm(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId, SyncT } SyncTerm syncIndexMgrGetTerm(SSyncIndexMgr *pIndexMgr, const SRaftId *pRaftId) { - for (int i = 0; i < pIndexMgr->replicaNum; ++i) { + for (int i = 0; i < pIndexMgr->totalReplicaNum; ++i) { if (syncUtilSameId(&((*(pIndexMgr->replicas))[i]), pRaftId)) { SyncTerm term = (pIndexMgr->privateTerm)[i]; return term; diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index 966b3ed093..499df4a98b 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -141,6 +141,13 @@ int32_t syncReconfig(int64_t rid, SSyncCfg* pNewCfg) { SSyncNode* pSyncNode = syncNodeAcquire(rid); if (pSyncNode == NULL) return -1; + if(pSyncNode->raftCfg.lastConfigIndex >= pNewCfg->lastIndex){ + syncNodeRelease(pSyncNode); + sInfo("vgId:%d, no need Reconfig, current index:%" PRId64 ", new index:%" PRId64, pSyncNode->vgId, + pSyncNode->raftCfg.lastConfigIndex, pNewCfg->lastIndex); + return 0; + } + if (!syncNodeCheckNewConfig(pSyncNode, pNewCfg)) { syncNodeRelease(pSyncNode); terrno = TSDB_CODE_SYN_NEW_CONFIG_ERROR; @@ -149,12 +156,12 @@ int32_t syncReconfig(int64_t rid, SSyncCfg* pNewCfg) { } syncNodeUpdateNewConfigIndex(pSyncNode, pNewCfg); - syncNodeDoConfigChange(pSyncNode, pNewCfg, SYNC_INDEX_INVALID); + syncNodeDoConfigChange(pSyncNode, pNewCfg, pNewCfg->lastIndex); if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) { syncNodeStopHeartbeatTimer(pSyncNode); - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { syncHbTimerInit(pSyncNode, &pSyncNode->peerHeartbeatTimerArr[i], pSyncNode->replicasId[i]); } @@ -315,8 +322,9 @@ int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex) { } } - if (pSyncNode->replicaNum > 1) { - if (pSyncNode->state != TAOS_SYNC_STATE_LEADER && pSyncNode->state != TAOS_SYNC_STATE_FOLLOWER) { + if (pSyncNode->totalReplicaNum > 1) { + if (pSyncNode->state != TAOS_SYNC_STATE_LEADER && pSyncNode->state != TAOS_SYNC_STATE_FOLLOWER + && pSyncNode->state != TAOS_SYNC_STATE_LEARNER) { sNTrace(pSyncNode, "new-snapshot-index:%" PRId64 " candidate or unknown state, do not delete wal", lastApplyIndex); syncNodeRelease(pSyncNode); @@ -455,8 +463,7 @@ bool syncSnapshotRecving(int64_t rid) { int32_t syncNodeLeaderTransfer(SSyncNode* pSyncNode) { if (pSyncNode->peersNum == 0) { sDebug("vgId:%d, only one replica, cannot leader transfer", pSyncNode->vgId); - terrno = TSDB_CODE_SYN_ONE_REPLICA; - return -1; + return 0; } int32_t ret = 0; @@ -478,7 +485,6 @@ int32_t syncNodeLeaderTransfer(SSyncNode* pSyncNode) { int32_t syncNodeLeaderTransferTo(SSyncNode* pSyncNode, SNodeInfo newLeader) { if (pSyncNode->replicaNum == 1) { sDebug("vgId:%d, only one replica, cannot leader transfer", pSyncNode->vgId); - terrno = TSDB_CODE_SYN_ONE_REPLICA; return -1; } @@ -537,7 +543,8 @@ void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet) { SSyncNode* pSyncNode = syncNodeAcquire(rid); if (pSyncNode == NULL) return; - for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.replicaNum; ++i) { + for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) { + if(pSyncNode->raftCfg.cfg.nodeInfo[i].nodeRole == TAOS_SYNC_ROLE_LEARNER) continue; SEp* pEp = &pEpSet->eps[i]; tstrncpy(pEp->fqdn, pSyncNode->raftCfg.cfg.nodeInfo[i].nodeFqdn, TSDB_FQDN_LEN); pEp->port = (pSyncNode->raftCfg.cfg.nodeInfo)[i].nodePort; @@ -564,6 +571,46 @@ int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak, int64_t* seq) { return ret; } +int32_t syncIsCatchUp(int64_t rid) { + SSyncNode* pSyncNode = syncNodeAcquire(rid); + if (pSyncNode == NULL) { + sError("sync Node Acquire error since %d", errno); + return -1; + } + + int32_t isCatchUp = 0; + if(pSyncNode->pLogBuf->totalIndex < 0 || pSyncNode->pLogBuf->commitIndex < 0 || + pSyncNode->pLogBuf->totalIndex < pSyncNode->pLogBuf->commitIndex || + pSyncNode->pLogBuf->totalIndex - pSyncNode->pLogBuf->commitIndex > SYNC_LEARNER_CATCHUP){ + sInfo("vgId:%d, Not catch up, wait one second, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64, + pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex, + pSyncNode->pLogBuf->matchIndex); + isCatchUp = 0; + } + else{ + sInfo("vgId:%d, Catch up, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64, + pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex, + pSyncNode->pLogBuf->matchIndex); + isCatchUp = 1; + } + + syncNodeRelease(pSyncNode); + return isCatchUp; +} + +ESyncRole syncGetRole(int64_t rid) { + SSyncNode* pSyncNode = syncNodeAcquire(rid); + if (pSyncNode == NULL) { + sError("sync Node Acquire error since %d", errno); + return -1; + } + + ESyncRole role = pSyncNode->raftCfg.cfg.nodeInfo[pSyncNode->raftCfg.cfg.myIndex].nodeRole; + + syncNodeRelease(pSyncNode); + return role; +} + int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak, int64_t* seq) { if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) { terrno = TSDB_CODE_SYN_NOT_LEADER; @@ -655,6 +702,8 @@ static int32_t syncHbTimerStart(SSyncNode* pSyncNode, SSyncTimer* pSyncTimer) { pData->logicClock = pSyncTimer->logicClock; pData->execTime = tsNow + pSyncTimer->timerMS; + sTrace("vgId:%d, start hb timer, rid:%" PRId64 " addr:%" PRId64, pSyncNode->vgId, pData->rid, pData->destId.addr); + taosTmrReset(pSyncTimer->timerCb, pSyncTimer->timerMS / HEARTBEAT_TICK_NUM, (void*)(pData->rid), syncEnv()->pTimerManager, &pSyncTimer->pTimer); } else { @@ -719,7 +768,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { sInfo("vgId:%d, create a new raft config file", pSyncNode->vgId); pSyncNode->raftCfg.isStandBy = pSyncInfo->isStandBy; pSyncNode->raftCfg.snapshotStrategy = pSyncInfo->snapshotStrategy; - pSyncNode->raftCfg.lastConfigIndex = SYNC_INDEX_INVALID; + pSyncNode->raftCfg.lastConfigIndex = pSyncInfo->syncCfg.lastIndex; pSyncNode->raftCfg.batchSize = pSyncInfo->batchSize; pSyncNode->raftCfg.cfg = pSyncInfo->syncCfg; pSyncNode->raftCfg.configIndexCount = 1; @@ -736,7 +785,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { goto _error; } - if (pSyncInfo->syncCfg.replicaNum > 0 && syncIsConfigChanged(&pSyncNode->raftCfg.cfg, &pSyncInfo->syncCfg)) { + if (pSyncInfo->syncCfg.totalReplicaNum > 0 && syncIsConfigChanged(&pSyncNode->raftCfg.cfg, &pSyncInfo->syncCfg)) { sInfo("vgId:%d, use sync config from input options and write to cfg file", pSyncNode->vgId); pSyncNode->raftCfg.cfg = pSyncInfo->syncCfg; if (syncWriteCfgFile(pSyncNode) != 0) { @@ -753,8 +802,9 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { pSyncNode->vgId = pSyncInfo->vgId; SSyncCfg* pCfg = &pSyncNode->raftCfg.cfg; bool updated = false; - sInfo("vgId:%d, start to open sync node, replica:%d selfIndex:%d", pSyncNode->vgId, pCfg->replicaNum, pCfg->myIndex); - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + sInfo("vgId:%d, start to open sync node, totalReplicaNum:%d replicaNum:%d selfIndex:%d", + pSyncNode->vgId, pCfg->totalReplicaNum, pCfg->replicaNum, pCfg->myIndex); + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SNodeInfo* pNode = &pCfg->nodeInfo[i]; if (tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort)) { updated = true; @@ -792,9 +842,9 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { } // init peersNum, peers, peersId - pSyncNode->peersNum = pSyncNode->raftCfg.cfg.replicaNum - 1; + pSyncNode->peersNum = pSyncNode->raftCfg.cfg.totalReplicaNum - 1; int32_t j = 0; - for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.replicaNum; ++i) { + for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) { if (i != pSyncNode->raftCfg.cfg.myIndex) { pSyncNode->peersNodeInfo[j] = pSyncNode->raftCfg.cfg.nodeInfo[i]; syncUtilNodeInfo2EpSet(&pSyncNode->peersNodeInfo[j], &pSyncNode->peersEpset[j]); @@ -810,7 +860,8 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { // init replicaNum, replicasId pSyncNode->replicaNum = pSyncNode->raftCfg.cfg.replicaNum; - for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.replicaNum; ++i) { + pSyncNode->totalReplicaNum = pSyncNode->raftCfg.cfg.totalReplicaNum; + for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) { if (!syncUtilNodeInfo2RaftId(&pSyncNode->raftCfg.cfg.nodeInfo[i], pSyncNode->vgId, &pSyncNode->replicasId[i])) { sError("vgId:%d, failed to determine raft member id, replica:%d", pSyncNode->vgId, i); goto _error; @@ -934,7 +985,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { pSyncNode->heartbeatTimerCounter = 0; // init peer heartbeat timer - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { syncHbTimerInit(pSyncNode, &(pSyncNode->peerHeartbeatTimerArr[i]), (pSyncNode->replicasId)[i]); } @@ -949,7 +1000,7 @@ SSyncNode* syncNodeOpen(SSyncInfo* pSyncInfo) { pSyncNode->restoreFinish = false; // snapshot senders - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { SSyncSnapshotSender* pSender = snapshotSenderCreate(pSyncNode, i); if (pSender == NULL) return NULL; @@ -1059,14 +1110,19 @@ int32_t syncNodeRestore(SSyncNode* pSyncNode) { int32_t syncNodeStart(SSyncNode* pSyncNode) { // start raft - if (pSyncNode->replicaNum == 1) { - raftStoreNextTerm(pSyncNode); - syncNodeBecomeLeader(pSyncNode, "one replica start"); + if(pSyncNode->raftCfg.cfg.nodeInfo[pSyncNode->raftCfg.cfg.myIndex].nodeRole == TAOS_SYNC_ROLE_LEARNER){ + syncNodeBecomeLearner(pSyncNode, "first start"); + } + else{ + if (pSyncNode->replicaNum == 1) { + raftStoreNextTerm(pSyncNode); + syncNodeBecomeLeader(pSyncNode, "one replica start"); - // Raft 3.6.2 Committing entries from previous terms - syncNodeAppendNoop(pSyncNode); - } else { - syncNodeBecomeFollower(pSyncNode, "first start"); + // Raft 3.6.2 Committing entries from previous terms + syncNodeAppendNoop(pSyncNode); + } else { + syncNodeBecomeFollower(pSyncNode, "first start"); + } } int32_t ret = 0; @@ -1157,7 +1213,7 @@ void syncNodeClose(SSyncNode* pSyncNode) { syncLogBufferDestroy(pSyncNode->pLogBuf); pSyncNode->pLogBuf = NULL; - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { if (pSyncNode->senders[i] != NULL) { sDebug("vgId:%d, snapshot sender destroy while close, data:%p", pSyncNode->vgId, pSyncNode->senders[i]); @@ -1350,7 +1406,7 @@ inline bool syncNodeInConfig(SSyncNode* pNode, const SSyncCfg* pCfg) { bool b1 = false; bool b2 = false; - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { if (strcmp(pCfg->nodeInfo[i].nodeFqdn, pNode->myNodeInfo.nodeFqdn) == 0 && pCfg->nodeInfo[i].nodePort == pNode->myNodeInfo.nodePort) { b1 = true; @@ -1358,7 +1414,7 @@ inline bool syncNodeInConfig(SSyncNode* pNode, const SSyncCfg* pCfg) { } } - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SRaftId raftId = { .addr = SYNC_ADDR(&pCfg->nodeInfo[i]), .vgId = pNode->vgId, @@ -1375,13 +1431,14 @@ inline bool syncNodeInConfig(SSyncNode* pNode, const SSyncCfg* pCfg) { } static bool syncIsConfigChanged(const SSyncCfg* pOldCfg, const SSyncCfg* pNewCfg) { - if (pOldCfg->replicaNum != pNewCfg->replicaNum) return true; + if (pOldCfg->totalReplicaNum != pNewCfg->totalReplicaNum) return true; if (pOldCfg->myIndex != pNewCfg->myIndex) return true; - for (int32_t i = 0; i < pOldCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pOldCfg->totalReplicaNum; ++i) { const SNodeInfo* pOldInfo = &pOldCfg->nodeInfo[i]; const SNodeInfo* pNewInfo = &pNewCfg->nodeInfo[i]; if (strcmp(pOldInfo->nodeFqdn, pNewInfo->nodeFqdn) != 0) return true; if (pOldInfo->nodePort != pNewInfo->nodePort) return true; + if(pOldInfo->nodeRole != pNewInfo->nodeRole) return true; } return false; @@ -1418,8 +1475,10 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde } // log begin config change - sNInfo(pSyncNode, "begin do config change, from %d to %d, replicas:%d", pSyncNode->vgId, oldConfig.replicaNum, - pNewConfig->replicaNum); + sNInfo(pSyncNode, "begin do config change, from %d to %d, from %" PRId64 " to %" PRId64 ", replicas:%d", + pSyncNode->vgId, + oldConfig.totalReplicaNum, pNewConfig->totalReplicaNum, + oldConfig.lastIndex, pNewConfig->lastIndex); if (IamInNew) { pSyncNode->raftCfg.isStandBy = 0; // change isStandBy to normal @@ -1436,11 +1495,10 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde int32_t ret = 0; // save snapshot senders - int32_t oldReplicaNum = pSyncNode->replicaNum; - SRaftId oldReplicasId[TSDB_MAX_REPLICA]; + SRaftId oldReplicasId[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; memcpy(oldReplicasId, pSyncNode->replicasId, sizeof(oldReplicasId)); - SSyncSnapshotSender* oldSenders[TSDB_MAX_REPLICA]; - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + SSyncSnapshotSender* oldSenders[TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA]; + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { oldSenders[i] = pSyncNode->senders[i]; sSTrace(oldSenders[i], "snapshot sender save old"); } @@ -1450,9 +1508,9 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde syncUtilNodeInfo2RaftId(&pSyncNode->myNodeInfo, pSyncNode->vgId, &pSyncNode->myRaftId); // init peersNum, peers, peersId - pSyncNode->peersNum = pSyncNode->raftCfg.cfg.replicaNum - 1; + pSyncNode->peersNum = pSyncNode->raftCfg.cfg.totalReplicaNum - 1; int32_t j = 0; - for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.replicaNum; ++i) { + for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) { if (i != pSyncNode->raftCfg.cfg.myIndex) { pSyncNode->peersNodeInfo[j] = pSyncNode->raftCfg.cfg.nodeInfo[i]; syncUtilNodeInfo2EpSet(&pSyncNode->peersNodeInfo[j], &pSyncNode->peersEpset[j]); @@ -1465,7 +1523,8 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde // init replicaNum, replicasId pSyncNode->replicaNum = pSyncNode->raftCfg.cfg.replicaNum; - for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.replicaNum; ++i) { + pSyncNode->totalReplicaNum = pSyncNode->raftCfg.cfg.totalReplicaNum; + for (int32_t i = 0; i < pSyncNode->raftCfg.cfg.totalReplicaNum; ++i) { syncUtilNodeInfo2RaftId(&pSyncNode->raftCfg.cfg.nodeInfo[i], pSyncNode->vgId, &pSyncNode->replicasId[i]); } @@ -1480,15 +1539,15 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde // reset snapshot senders // clear new - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { pSyncNode->senders[i] = NULL; } // reset new - for (int32_t i = 0; i < pSyncNode->replicaNum; ++i) { + for (int32_t i = 0; i < pSyncNode->totalReplicaNum; ++i) { // reset sender bool reset = false; - for (int32_t j = 0; j < TSDB_MAX_REPLICA; ++j) { + for (int32_t j = 0; j < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++j) { if (syncUtilSameId(&(pSyncNode->replicasId)[i], &oldReplicasId[j]) && oldSenders[j] != NULL) { sNTrace(pSyncNode, "snapshot sender reset for:%" PRId64 ", newIndex:%d, dnode:%d, %p", (pSyncNode->replicasId)[i].addr, i, DID(&pSyncNode->replicasId[i]), oldSenders[j]); @@ -1510,7 +1569,7 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde } // create new - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { if (pSyncNode->senders[i] == NULL) { pSyncNode->senders[i] = snapshotSenderCreate(pSyncNode, i); if (pSyncNode->senders[i] == NULL) { @@ -1525,7 +1584,7 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde } // free old - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { if (oldSenders[i] != NULL) { sSDebug(oldSenders[i], "snapshot sender destroy old, data:%p replica-index:%d", oldSenders[i], i); snapshotSenderDestroy(oldSenders[i]); @@ -1550,12 +1609,12 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde } else { // persist cfg syncWriteCfgFile(pSyncNode); - sNInfo(pSyncNode, "do not config change from %d to %d", oldConfig.replicaNum, pNewConfig->replicaNum); + sNInfo(pSyncNode, "do not config change from %d to %d", oldConfig.totalReplicaNum, pNewConfig->totalReplicaNum); } _END: // log end config change - sNInfo(pSyncNode, "end do config change, from %d to %d", oldConfig.replicaNum, pNewConfig->replicaNum); + sNInfo(pSyncNode, "end do config change, from %d to %d", oldConfig.totalReplicaNum, pNewConfig->totalReplicaNum); } // raft state change -------------- @@ -1635,6 +1694,27 @@ void syncNodeBecomeFollower(SSyncNode* pSyncNode, const char* debugStr) { syncNodeResetElectTimer(pSyncNode); } +void syncNodeBecomeLearner(SSyncNode* pSyncNode, const char* debugStr) { + pSyncNode->hbSlowNum = 0; + + // state change + pSyncNode->state = TAOS_SYNC_STATE_LEARNER; + + // trace log + sNTrace(pSyncNode, "become learner %s", debugStr); + + // call back + if (pSyncNode->pFsm != NULL && pSyncNode->pFsm->FpBecomeLearnerCb != NULL) { + pSyncNode->pFsm->FpBecomeLearnerCb(pSyncNode->pFsm); + } + + // min match index + pSyncNode->minMatchIndex = SYNC_INDEX_INVALID; + + // reset log buffer + syncLogBufferReset(pSyncNode->pLogBuf, pSyncNode); +} + // TLA+ Spec // \* Candidate i transitions to leader. // BecomeLeader(i) == @@ -1752,7 +1832,7 @@ void syncNodeCandidate2Leader(SSyncNode* pSyncNode) { bool syncNodeIsMnode(SSyncNode* pSyncNode) { return (pSyncNode->vgId == 1); } int32_t syncNodePeerStateInit(SSyncNode* pSyncNode) { - for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { + for (int32_t i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; ++i) { pSyncNode->peerStates[i].lastSendIndex = SYNC_INDEX_INVALID; pSyncNode->peerStates[i].lastSendTime = 0; } @@ -2039,7 +2119,7 @@ static void syncNodeEqHeartbeatTimer(void* param, void* tmrId) { if (!syncIsInit()) return; SSyncNode* pNode = param; - if (pNode->replicaNum > 1) { + if (pNode->totalReplicaNum > 1) { if (atomic_load_64(&pNode->heartbeatTimerLogicClockUser) <= atomic_load_64(&pNode->heartbeatTimerLogicClock)) { SRpcMsg rpcMsg = {0}; int32_t code = syncBuildTimeout(&rpcMsg, SYNC_TIMEOUT_HEARTBEAT, atomic_load_64(&pNode->heartbeatTimerLogicClock), @@ -2101,9 +2181,9 @@ static void syncNodeEqPeerHeartbeatTimer(void* param, void* tmrId) { return; } - // sTrace("vgId:%d, eq peer hb timer", pSyncNode->vgId); + sTrace("vgId:%d, eq peer hb timer, rid:%" PRId64 " addr:%" PRId64, pSyncNode->vgId, hbDataRid, pData->destId.addr); - if (pSyncNode->replicaNum > 1) { + if (pSyncNode->totalReplicaNum > 1) { int64_t timerLogicClock = atomic_load_64(&pSyncTimer->logicClock); int64_t msgLogicClock = atomic_load_64(&pData->logicClock); @@ -2130,6 +2210,7 @@ static void syncNodeEqPeerHeartbeatTimer(void* param, void* tmrId) { pSyncTimer->timeStamp = tsNow; // send msg + sTrace("vgId:%d, send heartbeat to dnode:%d", pSyncNode->vgId, DID(&(pSyncMsg->destId))); syncLogSendHeartbeat(pSyncNode, pSyncMsg, false, timerElapsed, pData->execTime); syncNodeSendHeartbeat(pSyncNode, &pSyncMsg->destId, &rpcMsg); } else { @@ -2212,7 +2293,7 @@ int32_t syncNodeAppend(SSyncNode* ths, SSyncRaftEntry* pEntry) { } bool syncNodeHeartbeatReplyTimeout(SSyncNode* pSyncNode) { - if (pSyncNode->replicaNum == 1) { + if (pSyncNode->totalReplicaNum == 1) { return false; } @@ -2237,7 +2318,7 @@ bool syncNodeHeartbeatReplyTimeout(SSyncNode* pSyncNode) { bool syncNodeSnapshotSending(SSyncNode* pSyncNode) { if (pSyncNode == NULL) return false; bool b = false; - for (int32_t i = 0; i < pSyncNode->replicaNum; ++i) { + for (int32_t i = 0; i < pSyncNode->totalReplicaNum; ++i) { if (pSyncNode->senders[i] != NULL && pSyncNode->senders[i]->start) { b = true; break; @@ -2328,35 +2409,40 @@ int32_t syncNodeOnHeartbeat(SSyncNode* ths, const SRpcMsg* pRpcMsg) { pMsgReply->startTime = ths->startTime; pMsgReply->timeStamp = tsMs; + sTrace( + "vgId:%d, heartbeat msg from dnode:%d, cluster:%d, Msgterm:%" PRId64 " currentTerm:%" PRId64, + ths->vgId, DID(&(pMsg->srcId)), CID(&(pMsg->srcId)), pMsg->term, currentTerm); + if (pMsg->term == currentTerm && ths->state != TAOS_SYNC_STATE_LEADER) { syncIndexMgrSetRecvTime(ths->pNextIndex, &(pMsg->srcId), tsMs); resetElect = true; ths->minMatchIndex = pMsg->minMatchIndex; - if (ths->state == TAOS_SYNC_STATE_FOLLOWER) { + if (ths->state == TAOS_SYNC_STATE_FOLLOWER || ths->state == TAOS_SYNC_STATE_LEARNER) { SRpcMsg rpcMsgLocalCmd = {0}; (void)syncBuildLocalCmd(&rpcMsgLocalCmd, ths->vgId); SyncLocalCmd* pSyncMsg = rpcMsgLocalCmd.pCont; - pSyncMsg->cmd = SYNC_LOCAL_CMD_FOLLOWER_CMT; + pSyncMsg->cmd = + (ths->state == TAOS_SYNC_STATE_LEARNER) ? SYNC_LOCAL_CMD_LEARNER_CMT : SYNC_LOCAL_CMD_FOLLOWER_CMT; pSyncMsg->commitIndex = pMsg->commitIndex; pSyncMsg->currentTerm = pMsg->term; - SyncIndex fcIndex = pSyncMsg->commitIndex; if (ths->syncEqMsg != NULL && ths->msgcb != NULL) { int32_t code = ths->syncEqMsg(ths->msgcb, &rpcMsgLocalCmd); if (code != 0) { - sError("vgId:%d, sync enqueue fc-commit msg error, code:%d", ths->vgId, code); + sError("vgId:%d, failed to enqueue commit msg from heartbeat since %s, code:%d", ths->vgId, terrstr(), code); rpcFreeCont(rpcMsgLocalCmd.pCont); } else { - sTrace("vgId:%d, sync enqueue fc-commit msg, fc-index:%" PRId64, ths->vgId, fcIndex); + sTrace("vgId:%d, enqueue commit msg from heartbeat, commit-index:%" PRId64 ", term:%" PRId64, ths->vgId, + pMsg->commitIndex, pMsg->term); } } } } - if (pMsg->term >= currentTerm && ths->state != TAOS_SYNC_STATE_FOLLOWER) { + if (pMsg->term >= currentTerm && ths->state == TAOS_SYNC_STATE_LEADER) { SRpcMsg rpcMsgLocalCmd = {0}; (void)syncBuildLocalCmd(&rpcMsgLocalCmd, ths->vgId); @@ -2371,7 +2457,7 @@ int32_t syncNodeOnHeartbeat(SSyncNode* ths, const SRpcMsg* pRpcMsg) { sError("vgId:%d, sync enqueue step-down msg error, code:%d", ths->vgId, code); rpcFreeCont(rpcMsgLocalCmd.pCont); } else { - sTrace("vgId:%d, sync enqueue step-down msg, new-term:%" PRId64, ths->vgId, pSyncMsg->currentTerm); + sTrace("vgId:%d, sync enqueue step-down msg, new-term:%" PRId64, ths->vgId, pMsg->term); } } } @@ -2426,7 +2512,7 @@ int32_t syncNodeOnLocalCmd(SSyncNode* ths, const SRpcMsg* pRpcMsg) { if (pMsg->cmd == SYNC_LOCAL_CMD_STEP_DOWN) { syncNodeStepDown(ths, pMsg->currentTerm); - } else if (pMsg->cmd == SYNC_LOCAL_CMD_FOLLOWER_CMT) { + } else if (pMsg->cmd == SYNC_LOCAL_CMD_FOLLOWER_CMT || pMsg->cmd == SYNC_LOCAL_CMD_LEARNER_CMT) { if (syncLogBufferIsEmpty(ths->pLogBuf)) { sError("vgId:%d, sync log buffer is empty.", ths->vgId); return 0; @@ -2502,13 +2588,15 @@ const char* syncStr(ESyncState state) { return "error"; case TAOS_SYNC_STATE_OFFLINE: return "offline"; + case TAOS_SYNC_STATE_LEARNER: + return "learner"; default: return "unknown"; } } int32_t syncNodeUpdateNewConfigIndex(SSyncNode* ths, SSyncCfg* pNewCfg) { - for (int32_t i = 0; i < pNewCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pNewCfg->totalReplicaNum; ++i) { SRaftId raftId = { .addr = SYNC_ADDR(&pNewCfg->nodeInfo[i]), .vgId = ths->vgId, @@ -2528,7 +2616,7 @@ bool syncNodeIsOptimizedOneReplica(SSyncNode* ths, SRpcMsg* pMsg) { } bool syncNodeInRaftGroup(SSyncNode* ths, SRaftId* pRaftId) { - for (int32_t i = 0; i < ths->replicaNum; ++i) { + for (int32_t i = 0; i < ths->totalReplicaNum; ++i) { if (syncUtilSameId(&((ths->replicasId)[i]), pRaftId)) { return true; } @@ -2538,7 +2626,7 @@ bool syncNodeInRaftGroup(SSyncNode* ths, SRaftId* pRaftId) { SSyncSnapshotSender* syncNodeGetSnapshotSender(SSyncNode* ths, SRaftId* pDestId) { SSyncSnapshotSender* pSender = NULL; - for (int32_t i = 0; i < ths->replicaNum; ++i) { + for (int32_t i = 0; i < ths->totalReplicaNum; ++i) { if (syncUtilSameId(pDestId, &((ths->replicasId)[i]))) { pSender = (ths->senders)[i]; } @@ -2548,7 +2636,7 @@ SSyncSnapshotSender* syncNodeGetSnapshotSender(SSyncNode* ths, SRaftId* pDestId) SSyncTimer* syncNodeGetHbTimer(SSyncNode* ths, SRaftId* pDestId) { SSyncTimer* pTimer = NULL; - for (int32_t i = 0; i < ths->replicaNum; ++i) { + for (int32_t i = 0; i < ths->totalReplicaNum; ++i) { if (syncUtilSameId(pDestId, &((ths->replicasId)[i]))) { pTimer = &((ths->peerHeartbeatTimerArr)[i]); } @@ -2558,7 +2646,7 @@ SSyncTimer* syncNodeGetHbTimer(SSyncNode* ths, SRaftId* pDestId) { SPeerState* syncNodeGetPeerState(SSyncNode* ths, const SRaftId* pDestId) { SPeerState* pState = NULL; - for (int32_t i = 0; i < ths->replicaNum; ++i) { + for (int32_t i = 0; i < ths->totalReplicaNum; ++i) { if (syncUtilSameId(pDestId, &((ths->replicasId)[i]))) { pState = &((ths->peerStates)[i]); } diff --git a/source/libs/sync/src/syncPipeline.c b/source/libs/sync/src/syncPipeline.c index 5e6058ef03..8bb72de518 100644 --- a/source/libs/sync/src/syncPipeline.c +++ b/source/libs/sync/src/syncPipeline.c @@ -54,7 +54,7 @@ int32_t syncLogBufferAppend(SSyncLogBuffer* pBuf, SSyncNode* pNode, SSyncRaftEnt } if (pNode->restoreFinish && index - pBuf->commitIndex >= TSDB_SYNC_NEGOTIATION_WIN) { - terrno = TSDB_CODE_SYN_NEGO_WIN_EXCEEDED; + terrno = TSDB_CODE_SYN_NEGOTIATION_WIN_FULL; sError("vgId:%d, failed to append since %s, index:%" PRId64 ", commit-index:%" PRId64, pNode->vgId, terrstr(), index, pBuf->commitIndex); goto _err; @@ -250,6 +250,8 @@ int32_t syncLogBufferInitWithoutLock(SSyncLogBuffer* pBuf, SSyncNode* pNode) { // update startIndex pBuf->startIndex = takeDummy ? index : index + 1; + pBuf->isCatchup = false; + sInfo("vgId:%d, init sync log buffer. buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")", pNode->vgId, pBuf->startIndex, pBuf->commitIndex, pBuf->matchIndex, pBuf->endIndex); @@ -332,6 +334,15 @@ int32_t syncLogBufferAccept(SSyncLogBuffer* pBuf, SSyncNode* pNode, SSyncRaftEnt goto _out; } + if(pNode->raftCfg.cfg.nodeInfo[pNode->raftCfg.cfg.myIndex].nodeRole == TAOS_SYNC_ROLE_LEARNER && + index > 0 && index > pBuf->totalIndex){ + pBuf->totalIndex = index; + sTrace("vgId:%d, update learner progress. index:%" PRId64 ", term:%" PRId64 ": prevterm:%" PRId64 + " != lastmatch:%" PRId64 ". log buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")", + pNode->vgId, pEntry->index, pEntry->term, prevTerm, lastMatchTerm, pBuf->startIndex, pBuf->commitIndex, + pBuf->matchIndex, pBuf->endIndex); + } + if (index - pBuf->startIndex >= pBuf->size) { sWarn("vgId:%d, out of buffer range. index:%" PRId64 ", term:%" PRId64 ". log buffer: [%" PRId64 " %" PRId64 " %" PRId64 ", %" PRId64 ")", @@ -491,7 +502,7 @@ _out: } int32_t syncFsmExecute(SSyncNode* pNode, SSyncFSM* pFsm, ESyncState role, SyncTerm term, SSyncRaftEntry* pEntry, - int32_t applyCode) { + int32_t applyCode) { if (pNode->replicaNum == 1 && pNode->restoreFinish && pNode->vgId != 1) { return 0; } @@ -965,7 +976,7 @@ void syncLogReplDestroy(SSyncLogReplMgr* pMgr) { } int32_t syncNodeLogReplInit(SSyncNode* pNode) { - for (int i = 0; i < TSDB_MAX_REPLICA; i++) { + for (int i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; i++) { ASSERT(pNode->logReplMgrs[i] == NULL); pNode->logReplMgrs[i] = syncLogReplCreate(); if (pNode->logReplMgrs[i] == NULL) { @@ -978,7 +989,7 @@ int32_t syncNodeLogReplInit(SSyncNode* pNode) { } void syncNodeLogReplDestroy(SSyncNode* pNode) { - for (int i = 0; i < TSDB_MAX_REPLICA; i++) { + for (int i = 0; i < TSDB_MAX_REPLICA + TSDB_MAX_LEARNER_REPLICA; i++) { syncLogReplDestroy(pNode->logReplMgrs[i]); pNode->logReplMgrs[i] = NULL; } @@ -1108,7 +1119,7 @@ int32_t syncLogBufferReset(SSyncLogBuffer* pBuf, SSyncNode* pNode) { pBuf->endIndex = pBuf->matchIndex + 1; // reset repl mgr - for (int i = 0; i < pNode->replicaNum; i++) { + for (int i = 0; i < pNode->totalReplicaNum; i++) { SSyncLogReplMgr* pMgr = pNode->logReplMgrs[i]; syncLogReplReset(pMgr); } diff --git a/source/libs/sync/src/syncRaftCfg.c b/source/libs/sync/src/syncRaftCfg.c index f780e255ce..480ed4b2af 100644 --- a/source/libs/sync/src/syncRaftCfg.c +++ b/source/libs/sync/src/syncRaftCfg.c @@ -18,6 +18,28 @@ #include "syncUtil.h" #include "tjson.h" +const char* syncRoleToStr(ESyncRole role) { + switch (role) { + case TAOS_SYNC_ROLE_VOTER: + return "true"; + case TAOS_SYNC_ROLE_LEARNER: + return "false"; + default: + return "unknown"; + } +} + +const ESyncRole syncStrToRole(char* str) { + if(strcmp(str, "true") == 0){ + return TAOS_SYNC_ROLE_VOTER; + } + if(strcmp(str, "false") == 0){ + return TAOS_SYNC_ROLE_LEARNER; + } + + return TAOS_SYNC_ROLE_ERROR; +} + static int32_t syncEncodeSyncCfg(const void *pObj, SJson *pJson) { SSyncCfg *pCfg = (SSyncCfg *)pObj; if (tjsonAddDoubleToObject(pJson, "replicaNum", pCfg->replicaNum) < 0) return -1; @@ -26,13 +48,14 @@ static int32_t syncEncodeSyncCfg(const void *pObj, SJson *pJson) { SJson *nodeInfo = tjsonCreateArray(); if (nodeInfo == NULL) return -1; if (tjsonAddItemToObject(pJson, "nodeInfo", nodeInfo) < 0) return -1; - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SJson *info = tjsonCreateObject(); if (info == NULL) return -1; if (tjsonAddDoubleToObject(info, "nodePort", pCfg->nodeInfo[i].nodePort) < 0) return -1; if (tjsonAddStringToObject(info, "nodeFqdn", pCfg->nodeInfo[i].nodeFqdn) < 0) return -1; if (tjsonAddIntegerToObject(info, "nodeId", pCfg->nodeInfo[i].nodeId) < 0) return -1; if (tjsonAddIntegerToObject(info, "clusterId", pCfg->nodeInfo[i].clusterId) < 0) return -1; + if (tjsonAddStringToObject(info, "isReplica", syncRoleToStr(pCfg->nodeInfo[i].nodeRole)) < 0) return -1; if (tjsonAddItemToArray(nodeInfo, info) < 0) return -1; } @@ -90,7 +113,8 @@ int32_t syncWriteCfgFile(SSyncNode *pNode) { if (taosRenameFile(file, realfile) != 0) goto _OVER; code = 0; - sInfo("vgId:%d, succeed to write sync cfg file:%s, len:%d", pNode->vgId, realfile, len); + sInfo("vgId:%d, succeed to write sync cfg file:%s, len:%d, lastConfigIndex:%" PRId64, pNode->vgId, + realfile, len, pNode->raftCfg.lastConfigIndex); _OVER: if (pJson != NULL) tjsonDelete(pJson); @@ -115,9 +139,9 @@ static int32_t syncDecodeSyncCfg(const SJson *pJson, void *pObj) { SJson *nodeInfo = tjsonGetObjectItem(pJson, "nodeInfo"); if (nodeInfo == NULL) return -1; - pCfg->replicaNum = tjsonGetArraySize(nodeInfo); + pCfg->totalReplicaNum = tjsonGetArraySize(nodeInfo); - for (int32_t i = 0; i < pCfg->replicaNum; ++i) { + for (int32_t i = 0; i < pCfg->totalReplicaNum; ++i) { SJson *info = tjsonGetArrayItem(nodeInfo, i); if (info == NULL) return -1; tjsonGetUInt16ValueFromDouble(info, "nodePort", pCfg->nodeInfo[i].nodePort, code); @@ -126,6 +150,15 @@ static int32_t syncDecodeSyncCfg(const SJson *pJson, void *pObj) { if (code < 0) return -1; tjsonGetNumberValue(info, "nodeId", pCfg->nodeInfo[i].nodeId, code); tjsonGetNumberValue(info, "clusterId", pCfg->nodeInfo[i].clusterId, code); + char role[10] = {0}; + code = tjsonGetStringValue(info, "isReplica", role); + if(code < 0) return -1; + if(strlen(role) != 0){ + pCfg->nodeInfo[i].nodeRole = syncStrToRole(role); + } + else{ + pCfg->nodeInfo[i].nodeRole = TAOS_SYNC_ROLE_VOTER; + } } return 0; diff --git a/source/libs/sync/src/syncReplication.c b/source/libs/sync/src/syncReplication.c index 2776225a39..5a3a3bbb70 100644 --- a/source/libs/sync/src/syncReplication.c +++ b/source/libs/sync/src/syncReplication.c @@ -64,10 +64,10 @@ int32_t syncNodeReplicate(SSyncNode* pNode) { } int32_t syncNodeReplicateWithoutLock(SSyncNode* pNode) { - if (pNode->state != TAOS_SYNC_STATE_LEADER || pNode->replicaNum == 1) { + if (pNode->state != TAOS_SYNC_STATE_LEADER || pNode->raftCfg.cfg.totalReplicaNum == 1) { return -1; } - for (int32_t i = 0; i < pNode->replicaNum; i++) { + for (int32_t i = 0; i < pNode->totalReplicaNum; i++) { if (syncUtilSameId(&pNode->replicasId[i], &pNode->myRaftId)) { continue; } diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index a9d0ddad17..763d4ec5d6 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -795,13 +795,18 @@ int32_t syncNodeOnSnapshot(SSyncNode *pSyncNode, const SRpcMsg *pRpcMsg) { return -1; } - if (pMsg->term > raftStoreGetTerm(pSyncNode)) { - syncNodeStepDown(pSyncNode, pMsg->term); + if(pSyncNode->raftCfg.cfg.nodeInfo[pSyncNode->raftCfg.cfg.myIndex].nodeRole != TAOS_SYNC_ROLE_LEARNER){ + if (pMsg->term > raftStoreGetTerm(pSyncNode)) { + syncNodeStepDown(pSyncNode, pMsg->term); + } + } + else{ + syncNodeUpdateTermWithoutStepDown(pSyncNode, pMsg->term); } // state, term, seq/ack int32_t code = 0; - if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) { + if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER || pSyncNode->state == TAOS_SYNC_STATE_LEARNER) { if (pMsg->term == raftStoreGetTerm(pSyncNode)) { if (pMsg->seq == SYNC_SNAPSHOT_SEQ_PREP_SNAPSHOT) { syncLogRecvSyncSnapshotSend(pSyncNode, pMsg, "process seq pre-snapshot"); diff --git a/source/libs/sync/src/syncTimeout.c b/source/libs/sync/src/syncTimeout.c index a27be2853e..5ee67da9ab 100644 --- a/source/libs/sync/src/syncTimeout.c +++ b/source/libs/sync/src/syncTimeout.c @@ -58,7 +58,7 @@ static void syncNodeCleanConfigIndex(SSyncNode* ths) { static int32_t syncNodeTimerRoutine(SSyncNode* ths) { ths->tmrRoutineNum++; - if (ths->tmrRoutineNum % 60 == 0 && ths->replicaNum > 1) { + if (ths->tmrRoutineNum % 60 == 0 && ths->totalReplicaNum > 1) { sNInfo(ths, "timer routines"); } else { sNTrace(ths, "timer routines"); diff --git a/source/libs/sync/src/syncVoteMgr.c b/source/libs/sync/src/syncVoteMgr.c index 6bd9625276..83b0dde8e0 100644 --- a/source/libs/sync/src/syncVoteMgr.c +++ b/source/libs/sync/src/syncVoteMgr.c @@ -30,7 +30,7 @@ SVotesGranted *voteGrantedCreate(SSyncNode *pNode) { return NULL; } - pVotesGranted->replicas = &pNode->replicasId; + pVotesGranted->replicas = (void*)&pNode->replicasId; pVotesGranted->replicaNum = pNode->replicaNum; voteGrantedClearVotes(pVotesGranted); @@ -49,7 +49,7 @@ void voteGrantedDestroy(SVotesGranted *pVotesGranted) { } void voteGrantedUpdate(SVotesGranted *pVotesGranted, SSyncNode *pNode) { - pVotesGranted->replicas = &pNode->replicasId; + pVotesGranted->replicas = (void*)&pNode->replicasId; pVotesGranted->replicaNum = pNode->replicaNum; voteGrantedClearVotes(pVotesGranted); @@ -115,7 +115,7 @@ SVotesRespond *votesRespondCreate(SSyncNode *pNode) { return NULL; } - pVotesRespond->replicas = &pNode->replicasId; + pVotesRespond->replicas = (void*)&pNode->replicasId; pVotesRespond->replicaNum = pNode->replicaNum; pVotesRespond->term = 0; pVotesRespond->pNode = pNode; @@ -130,7 +130,7 @@ void votesRespondDestory(SVotesRespond *pVotesRespond) { } void votesRespondUpdate(SVotesRespond *pVotesRespond, SSyncNode *pNode) { - pVotesRespond->replicas = &pNode->replicasId; + pVotesRespond->replicas = (void*)&pNode->replicasId; pVotesRespond->replicaNum = pNode->replicaNum; pVotesRespond->term = 0; pVotesRespond->pNode = pNode; diff --git a/source/libs/tfs/src/tfs.c b/source/libs/tfs/src/tfs.c index 86b36b9b12..bedd14353f 100644 --- a/source/libs/tfs/src/tfs.c +++ b/source/libs/tfs/src/tfs.c @@ -283,6 +283,14 @@ int32_t tfsMkdir(STfs *pTfs, const char *rname) { return 0; } +bool tfsDirExistAt(STfs *pTfs, const char *rname, SDiskID diskId) { + STfsDisk *pDisk = TFS_DISK_AT(pTfs, diskId); + char aname[TMPNAME_LEN]; + + snprintf(aname, TMPNAME_LEN, "%s%s%s", pDisk->path, TD_DIRSEP, rname); + return taosDirExist(aname); +} + int32_t tfsRmdir(STfs *pTfs, const char *rname) { if (rname[0] == 0) { return 0; diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index fbd4b77a3d..bdf091022e 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -107,6 +107,13 @@ int32_t walNextValidMsg(SWalReader *pReader) { int64_t walReaderGetCurrentVer(const SWalReader *pReader) { return pReader->curVersion; } int64_t walReaderGetValidFirstVer(const SWalReader *pReader) { return walGetFirstVer(pReader->pWal); } +void walReaderValidVersionRange(SWalReader *pReader, int64_t *sver, int64_t *ever) { + *sver = walGetFirstVer(pReader->pWal); + int64_t lastVer = walGetLastVer(pReader->pWal); + int64_t committedVer = walGetCommittedVer(pReader->pWal); + *ever = pReader->cond.scanUncommited ? lastVer : committedVer; +} + static int64_t walReadSeekFilePos(SWalReader *pReader, int64_t fileFirstVer, int64_t ver) { int64_t ret = 0; diff --git a/source/util/src/tcompare.c b/source/util/src/tcompare.c index dc57ed97b2..d6f0e898ef 100644 --- a/source/util/src/tcompare.c +++ b/source/util/src/tcompare.c @@ -1255,7 +1255,7 @@ int32_t taosArrayCompareString(const void *a, const void *b) { int32_t comparestrPatternMatch(const void *pLeft, const void *pRight) { SPatternCompareInfo pInfo = PATTERN_COMPARE_INFO_INITIALIZER; - ASSERT(varDataLen(pRight) <= TSDB_MAX_FIELD_LEN); + ASSERT(varDataTLen(pRight) <= TSDB_MAX_FIELD_LEN); size_t pLen = varDataLen(pRight); size_t sz = varDataLen(pLeft); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index d9247a4e83..58c7300bee 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -98,7 +98,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_NO_ENOUGH_DISKSPACE, "No enough disk space" TAOS_DEFINE_ERROR(TSDB_CODE_APP_IS_STARTING, "Database is starting up") TAOS_DEFINE_ERROR(TSDB_CODE_APP_IS_STOPPING, "Database is closing down") -TAOS_DEFINE_ERROR(TSDB_CODE_IVLD_DATA_FMT, "Invalid data format") +TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DATA_FMT, "Invalid data format") +TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CFG_VALUE, "Invalid configuration value") //client TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation") @@ -320,6 +321,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QNODE_NOT_DEPLOYED, "Qnode not deployed") TAOS_DEFINE_ERROR(TSDB_CODE_SNODE_NOT_FOUND, "Snode not found") TAOS_DEFINE_ERROR(TSDB_CODE_SNODE_ALREADY_DEPLOYED, "Snode already deployed") TAOS_DEFINE_ERROR(TSDB_CODE_SNODE_NOT_DEPLOYED, "Snode not deployed") +TAOS_DEFINE_ERROR(TSDB_CODE_MNODE_NOT_CATCH_UP, "Mnode didn't catch the leader") +TAOS_DEFINE_ERROR(TSDB_CODE_MNODE_ALREADY_IS_VOTER, "Mnode already is a leader") +TAOS_DEFINE_ERROR(TSDB_CODE_MNODE_ONLY_TWO_MNODE, "Only two mnodes exist") // vnode TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_VGROUP_ID, "Vnode is closed or removed") @@ -335,6 +339,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_AVAIL_BUFPOOL, "No availabe buffer po TAOS_DEFINE_ERROR(TSDB_CODE_VND_STOPPED, "Vnode stopped") TAOS_DEFINE_ERROR(TSDB_CODE_VND_DUP_REQUEST, "Duplicate write request") TAOS_DEFINE_ERROR(TSDB_CODE_VND_QUERY_BUSY, "Query busy") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_CATCH_UP, "Vnode didn't catch up its leader") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_ALREADY_IS_VOTER, "Vnode already is a voter") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_DIR_ALREADY_EXIST, "Vnode directory already exist") // tsdb TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, "Invalid table ID") @@ -398,9 +405,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitti // grant TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired") -TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DNODE_LIMITED, "DNode creation limited by licence") +TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DNODE_LIMITED, "DNode creation limited by license") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_ACCT_LIMITED, "Account creation limited by license") -TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TIMESERIES_LIMITED, "Table creation limited by license") +TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TIMESERIES_LIMITED, "Time series limited by license") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DB_LIMITED, "DB creation limited by license") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_USER_LIMITED, "User creation limited by license") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CONN_LIMITED, "Conn creation limited by license") @@ -414,20 +421,14 @@ TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TABLE_LIMITED, "Table creation limite // sync TAOS_DEFINE_ERROR(TSDB_CODE_SYN_TIMEOUT, "Sync timeout") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_IS_LEADER, "Sync is leader") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_LEADER, "Sync leader is unreachable") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_ONE_REPLICA, "Sync one replica") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_IN_NEW_CONFIG, "Sync not in new config") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEW_CONFIG_ERROR, "Sync new config error") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RECONFIG_NOT_READY, "Sync not ready for reconfig") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready for propose") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_STANDBY_NOT_READY, "Sync not ready for standby") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_BATCH_ERROR, "Sync batch error") +TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready to propose") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RESTORING, "Sync leader is restoring") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG, "Sync invalid snapshot msg") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_BUFFER_FULL, "Sync buffer is full") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_WRITE_STALL, "Sync write stall") -TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEGO_WIN_EXCEEDED, "Sync negotiation win exceeded") +TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEGOTIATION_WIN_FULL, "Sync negotiation win is full") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INTERNAL_ERROR, "Sync internal error") //tq @@ -445,8 +446,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TQ_NO_COMMITTED_OFFSET, "TQ no committed offse // wal TAOS_DEFINE_ERROR(TSDB_CODE_WAL_FILE_CORRUPTED, "WAL file is corrupted") -TAOS_DEFINE_ERROR(TSDB_CODE_WAL_SIZE_LIMIT, "WAL size exceeds limit") -TAOS_DEFINE_ERROR(TSDB_CODE_WAL_INVALID_VER, "WAL use invalid version") +TAOS_DEFINE_ERROR(TSDB_CODE_WAL_INVALID_VER, "WAL invalid version") TAOS_DEFINE_ERROR(TSDB_CODE_WAL_LOG_NOT_EXIST, "WAL log not exist") TAOS_DEFINE_ERROR(TSDB_CODE_WAL_CHKSUM_MISMATCH, "WAL checksum mismatch") TAOS_DEFINE_ERROR(TSDB_CODE_WAL_LOG_INCOMPLETE, "WAL log incomplete") @@ -582,11 +582,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_DUP_TIMESTAMP, "Duplicate timestamps TAOS_DEFINE_ERROR(TSDB_CODE_UDF_STOPPING, "udf is stopping") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_READ_ERR, "udf pipe read error") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_CONNECT_ERR, "udf pipe connect error") -TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_NO_PIPE, "udf no pipe") +TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_NOT_EXIST, "udf pipe not exist") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_LOAD_UDF_FAILURE, "udf load failure") -TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_STATE, "udf invalid state") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_INPUT, "udf invalid function input") -TAOS_DEFINE_ERROR(TSDB_CODE_UDF_NO_FUNC_HANDLE, "udf no function handle") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_BUFSIZE, "udf invalid bufsize") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_OUTPUT_TYPE, "udf invalid output type") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED, "udf program language not supported") @@ -603,23 +601,16 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SML_INTERNAL_ERROR, "Internal error") //tsma TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INIT_FAILED, "Tsma init failed") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_ALREADY_EXIST, "Tsma already exists") -TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_NO_INDEX_IN_META, "No tsma index in meta") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_ENV, "Invalid tsma env") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_STAT, "Invalid tsma state") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PTR, "Invalid tsma pointer") TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_INVALID_PARA, "Invalid tsma parameters") -TAOS_DEFINE_ERROR(TSDB_CODE_TSMA_NO_INDEX_IN_CACHE, "No tsma index in cache") //rsma TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_ENV, "Invalid rsma env") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_STAT, "Invalid rsma state") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_QTASKINFO_CREATE, "Rsma qtaskinfo creation error") -TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_FS_COMMIT, "Rsma fs commit error") -TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_REMOVE_EXISTS, "Rsma remove exists") -TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_FETCH_MSG_MSSED_UP, "Rsma fetch msg is messed up") -TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_EMPTY_INFO, "Rsma info is empty") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_INVALID_SCHEMA, "Rsma invalid schema") -TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_REGEX_MATCH, "Rsma regex match") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_STREAM_STATE_OPEN, "Rsma stream state open") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_STREAM_STATE_COMMIT, "Rsma stream state commit") TAOS_DEFINE_ERROR(TSDB_CODE_RSMA_FS_REF, "Rsma fs ref error") diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index d415379f92..c8ac15786f 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -23,10 +23,11 @@ #define LOG_MAX_LINE_SIZE (10024) #define LOG_MAX_LINE_BUFFER_SIZE (LOG_MAX_LINE_SIZE + 3) #define LOG_MAX_LINE_DUMP_SIZE (1024 * 1024) -#define LOG_MAX_LINE_DUMP_BUFFER_SIZE (LOG_MAX_LINE_DUMP_SIZE + 3) +#define LOG_MAX_LINE_DUMP_BUFFER_SIZE (LOG_MAX_LINE_DUMP_SIZE + 128) #define LOG_FILE_NAME_LEN 300 #define LOG_DEFAULT_BUF_SIZE (20 * 1024 * 1024) // 20MB +#define LOG_SLOW_BUF_SIZE (10 * 1024 * 1024) // 10MB #define LOG_DEFAULT_INTERVAL 25 #define LOG_INTERVAL_STEP 5 @@ -50,6 +51,8 @@ typedef struct { int32_t stop; TdThread asyncThread; TdThreadMutex buffMutex; + int32_t writeInterval; + int32_t lastDuration; } SLogBuff; typedef struct { @@ -61,6 +64,7 @@ typedef struct { pid_t pid; char logName[LOG_FILE_NAME_LEN]; SLogBuff *logHandle; + SLogBuff *slowHandle; TdThreadMutex logMutex; } SLogObj; @@ -68,7 +72,6 @@ extern SConfig *tsCfg; static int8_t tsLogInited = 0; static SLogObj tsLogObj = {.fileNum = 1}; static int64_t tsAsyncLogLostLines = 0; -static int32_t tsWriteInterval = LOG_DEFAULT_INTERVAL; static int32_t tsDaylightActive; /* Currently in daylight saving time. */ bool tsLogEmbedded = 0; @@ -81,6 +84,7 @@ int64_t tsNumOfErrorLogs = 0; int64_t tsNumOfInfoLogs = 0; int64_t tsNumOfDebugLogs = 0; int64_t tsNumOfTraceLogs = 0; +int64_t tsNumOfSlowLogs = 0; // log int32_t dDebugFlag = 131; @@ -135,6 +139,34 @@ static int32_t taosStartLog() { return 0; } +int32_t taosInitSlowLog() { + char fullName[PATH_MAX] = {0}; + char logFileName[64] = {0}; +#ifdef CUS_PROMPT + snprintf(logFileName, 64, "%sSlowLog", CUS_PROMPT); +#else + snprintf(logFileName, 64, "taosSlowLog"); +#endif + + if (strlen(tsLogDir) != 0) { + snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logFileName); + } else { + snprintf(fullName, PATH_MAX, "%s", logFileName); + } + + tsLogObj.slowHandle = taosLogBuffNew(LOG_SLOW_BUF_SIZE); + if (tsLogObj.slowHandle == NULL) return -1; + + taosUmaskFile(0); + tsLogObj.slowHandle->pFile = taosOpenFile(fullName, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_APPEND); + if (tsLogObj.slowHandle->pFile == NULL) { + printf("\nfailed to open slow log file:%s, reason:%s\n", fullName, strerror(errno)); + return -1; + } + + return 0; +} + int32_t taosInitLog(const char *logName, int32_t maxFiles) { if (atomic_val_compare_exchange_8(&tsLogInited, 0, 1) != 0) return 0; osUpdate(); @@ -150,6 +182,8 @@ int32_t taosInitLog(const char *logName, int32_t maxFiles) { tsLogObj.logHandle = taosLogBuffNew(LOG_DEFAULT_BUF_SIZE); if (tsLogObj.logHandle == NULL) return -1; if (taosOpenLogFile(fullName, tsNumOfLogLines, maxFiles) < 0) return -1; + + if (taosInitSlowLog() < 0) return -1; if (taosStartLog() < 0) return -1; return 0; } @@ -158,25 +192,34 @@ static void taosStopLog() { if (tsLogObj.logHandle) { tsLogObj.logHandle->stop = 1; } + if (tsLogObj.slowHandle) { + tsLogObj.slowHandle->stop = 1; + } } void taosCloseLog() { + taosStopLog(); + + if (tsLogObj.logHandle != NULL && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) { + taosThreadJoin(tsLogObj.logHandle->asyncThread, NULL); + taosThreadClear(&tsLogObj.logHandle->asyncThread); + } + + if (tsLogObj.slowHandle != NULL) { + taosThreadMutexDestroy(&tsLogObj.slowHandle->buffMutex); + taosCloseFile(&tsLogObj.slowHandle->pFile); + taosMemoryFreeClear(tsLogObj.slowHandle->buffer); + taosMemoryFreeClear(tsLogObj.slowHandle); + } + if (tsLogObj.logHandle != NULL) { - taosStopLog(); - if (tsLogObj.logHandle != NULL && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) { - taosThreadJoin(tsLogObj.logHandle->asyncThread, NULL); - taosThreadClear(&tsLogObj.logHandle->asyncThread); - } tsLogInited = 0; taosThreadMutexDestroy(&tsLogObj.logHandle->buffMutex); taosCloseFile(&tsLogObj.logHandle->pFile); taosMemoryFreeClear(tsLogObj.logHandle->buffer); - memset(&tsLogObj.logHandle->buffer, 0, sizeof(tsLogObj.logHandle->buffer)); taosThreadMutexDestroy(&tsLogObj.logMutex); taosMemoryFreeClear(tsLogObj.logHandle); - memset(&tsLogObj.logHandle, 0, sizeof(tsLogObj.logHandle)); - tsLogObj.logHandle = NULL; } } @@ -510,10 +553,9 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons va_list argpointer; va_start(argpointer, format); - len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - len, format, argpointer); + len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - 2 - len, format, argpointer); va_end(argpointer); - if (len > LOG_MAX_LINE_DUMP_SIZE) len = LOG_MAX_LINE_DUMP_SIZE; buffer[len++] = '\n'; buffer[len] = 0; @@ -521,6 +563,31 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons taosMemoryFree(buffer); } +void taosPrintSlowLog(const char *format, ...) { + if (!osLogSpaceAvailable()) return; + + char *buffer = taosMemoryMalloc(LOG_MAX_LINE_DUMP_BUFFER_SIZE); + int32_t len = taosBuildLogHead(buffer, ""); + + va_list argpointer; + va_start(argpointer, format); + len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - 2 - len, format, argpointer); + va_end(argpointer); + + buffer[len++] = '\n'; + buffer[len] = 0; + + atomic_add_fetch_64(&tsNumOfSlowLogs, 1); + + if (tsAsyncLog) { + taosPushLogBuffer(tsLogObj.slowHandle, buffer, len); + } else { + taosWriteFile(tsLogObj.slowHandle->pFile, buffer, len); + } + + taosMemoryFree(buffer); +} + void taosDumpData(unsigned char *msg, int32_t len) { if (!osLogSpaceAvailable()) return; taosUpdateLogNums(DEBUG_DUMP); @@ -565,6 +632,7 @@ static SLogBuff *taosLogBuffNew(int32_t bufSize) { LOG_BUF_SIZE(pLogBuf) = bufSize; pLogBuf->minBuffSize = bufSize / 10; pLogBuf->stop = 0; + pLogBuf->writeInterval = LOG_DEFAULT_INTERVAL; if (taosThreadMutexInit(&LOG_BUF_MUTEX(pLogBuf), NULL) < 0) goto _err; // tsem_init(&(pLogBuf->buffNotEmpty), 0, 0); @@ -648,83 +716,78 @@ static int32_t taosGetLogRemainSize(SLogBuff *pLogBuf, int32_t start, int32_t en } static void taosWriteLog(SLogBuff *pLogBuf) { - static int32_t lastDuration = 0; - int32_t remainChecked = 0; - int32_t start, end, pollSize; + int32_t start = LOG_BUF_START(pLogBuf); + int32_t end = LOG_BUF_END(pLogBuf); - do { - if (remainChecked == 0) { - start = LOG_BUF_START(pLogBuf); - end = LOG_BUF_END(pLogBuf); + if (start == end) { + dbgEmptyW++; + pLogBuf->writeInterval = LOG_MAX_INTERVAL; + return; + } - if (start == end) { - dbgEmptyW++; - tsWriteInterval = LOG_MAX_INTERVAL; - return; - } - - pollSize = taosGetLogRemainSize(pLogBuf, start, end); - if (pollSize < pLogBuf->minBuffSize) { - lastDuration += tsWriteInterval; - if (lastDuration < LOG_MAX_WAIT_MSEC) { - break; - } - } - - lastDuration = 0; + int32_t pollSize = taosGetLogRemainSize(pLogBuf, start, end); + if (pollSize < pLogBuf->minBuffSize) { + pLogBuf->lastDuration += pLogBuf->writeInterval; + if (pLogBuf->lastDuration < LOG_MAX_WAIT_MSEC) { + return; } + } - if (start < end) { - taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, pollSize); - } else { - int32_t tsize = LOG_BUF_SIZE(pLogBuf) - start; - taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, tsize); + pLogBuf->lastDuration = 0; - taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf), end); + if (start < end) { + taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, pollSize); + } else { + int32_t tsize = LOG_BUF_SIZE(pLogBuf) - start; + taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, tsize); + + taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf), end); + } + + dbgWN++; + dbgWSize += pollSize; + + if (pollSize < pLogBuf->minBuffSize) { + dbgSmallWN++; + if (pLogBuf->writeInterval < LOG_MAX_INTERVAL) { + pLogBuf->writeInterval += LOG_INTERVAL_STEP; } - - dbgWN++; - dbgWSize += pollSize; - - if (pollSize < pLogBuf->minBuffSize) { - dbgSmallWN++; - if (tsWriteInterval < LOG_MAX_INTERVAL) { - tsWriteInterval += LOG_INTERVAL_STEP; - } - } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 3) { - dbgBigWN++; - tsWriteInterval = LOG_MIN_INTERVAL; - } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 4) { - if (tsWriteInterval > LOG_MIN_INTERVAL) { - tsWriteInterval -= LOG_INTERVAL_STEP; - } + } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 3) { + dbgBigWN++; + pLogBuf->writeInterval = LOG_MIN_INTERVAL; + } else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 4) { + if (pLogBuf->writeInterval > LOG_MIN_INTERVAL) { + pLogBuf->writeInterval -= LOG_INTERVAL_STEP; } + } - LOG_BUF_START(pLogBuf) = (LOG_BUF_START(pLogBuf) + pollSize) % LOG_BUF_SIZE(pLogBuf); + LOG_BUF_START(pLogBuf) = (LOG_BUF_START(pLogBuf) + pollSize) % LOG_BUF_SIZE(pLogBuf); - start = LOG_BUF_START(pLogBuf); - end = LOG_BUF_END(pLogBuf); + start = LOG_BUF_START(pLogBuf); + end = LOG_BUF_END(pLogBuf); - pollSize = taosGetLogRemainSize(pLogBuf, start, end); - if (pollSize < pLogBuf->minBuffSize) { - break; - } + pollSize = taosGetLogRemainSize(pLogBuf, start, end); + if (pollSize < pLogBuf->minBuffSize) { + return; + } - tsWriteInterval = LOG_MIN_INTERVAL; - - remainChecked = 1; - } while (1); + pLogBuf->writeInterval = 0; } static void *taosAsyncOutputLog(void *param) { - SLogBuff *pLogBuf = (SLogBuff *)param; + SLogBuff *pLogBuf = (SLogBuff *)tsLogObj.logHandle; + SLogBuff *pSlowBuf = (SLogBuff *)tsLogObj.slowHandle; + setThreadName("log"); int32_t count = 0; int32_t updateCron = 0; + int32_t writeInterval = 0; + while (1) { - count += tsWriteInterval; + writeInterval = TMIN(pLogBuf->writeInterval, pSlowBuf->writeInterval); + count += writeInterval; updateCron++; - taosMsleep(tsWriteInterval); + taosMsleep(writeInterval); if (count > 1000) { osUpdate(); count = 0; @@ -732,13 +795,14 @@ static void *taosAsyncOutputLog(void *param) { // Polling the buffer taosWriteLog(pLogBuf); + taosWriteLog(pSlowBuf); if (updateCron >= 3600 * 24 * 40 / 2) { taosUpdateDaylight(); updateCron = 0; } - if (pLogBuf->stop) break; + if (pLogBuf->stop || pSlowBuf->stop) break; } return NULL; diff --git a/test1 b/test1 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/ci/Dockerfile b/tests/ci/Dockerfile index 594bcc902d..213570dfb2 100644 --- a/tests/ci/Dockerfile +++ b/tests/ci/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.8 RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple RUN pip3 install pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro RUN apt-get update -RUN apt-get install -y psmisc sudo tree libjansson-dev libsnappy-dev liblzma-dev libz-dev zlib1g pkg-config build-essential valgrind \ +RUN apt-get install -y psmisc sudo tree libgeos-dev libjansson-dev libsnappy-dev liblzma-dev libz-dev zlib1g pkg-config build-essential valgrind \ vim libjemalloc-dev openssh-server screen sshpass net-tools dirmngr gnupg apt-transport-https ca-certificates software-properties-common r-base iputils-ping RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 RUN add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/' @@ -45,4 +45,4 @@ RUN pip3 uninstall -y taostest COPY repository/TDinternal /home/TDinternal COPY repository/taos-connector-python /home/taos-connector-python RUN sh -c "cd /home/taos-connector-python; pip3 install ." -COPY setup.sh /home/setup.sh \ No newline at end of file +COPY setup.sh /home/setup.sh diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index cbb62d2ae7..3e656c0302 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -57,9 +57,9 @@ ,,y,script,./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v2.sim ,,y,script,./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim ,,y,script,./test.sh -f tsim/dnode/vnode_clean.sim -,,y,script,./test.sh -f tsim/dnode/use_dropped_dnode.sim -,,y,script,./test.sh -f tsim/dnode/split_vgroup_replica1.sim -,,y,script,./test.sh -f tsim/dnode/split_vgroup_replica3.sim +,,y,script,./test.sh -f tsim/dnode/use_dropped_dnode.sim +,,y,script,./test.sh -f tsim/dnode/split_vgroup_replica1.sim +,,y,script,./test.sh -f tsim/dnode/split_vgroup_replica3.sim ,,y,script,./test.sh -f tsim/import/basic.sim ,,y,script,./test.sh -f tsim/import/commit.sim ,,y,script,./test.sh -f tsim/import/large.sim @@ -332,9 +332,9 @@ ,,y,script,./test.sh -f tsim/catalog/alterInCurrent.sim ,,y,script,./test.sh -f tsim/scalar/in.sim ,,y,script,./test.sh -f tsim/scalar/scalar.sim -,,y,script,./test.sh -f tsim/scalar/filter.sim -,,y,script,./test.sh -f tsim/scalar/caseWhen.sim -,,y,script,./test.sh -f tsim/scalar/tsConvert.sim +,,y,script,./test.sh -f tsim/scalar/filter.sim +,,y,script,./test.sh -f tsim/scalar/caseWhen.sim +,,y,script,./test.sh -f tsim/scalar/tsConvert.sim ,,y,script,./test.sh -f tsim/alter/cached_schema_after_alter.sim ,,y,script,./test.sh -f tsim/alter/dnode.sim ,,y,script,./test.sh -f tsim/alter/table.sim @@ -564,7 +564,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_replica.py -N 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/influxdb_line_taosc_insert.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/opentsdb_telnet_line_taosc_insert.py -#,,n,system-test,./pytest.sh python3 ./test.py -f 1-insert/opentsdb_json_taosc_insert.py +#,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/opentsdb_json_taosc_insert.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/test_stmt_muti_insert_query.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/test_stmt_set_tbname_tag.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/alter_stable.py @@ -769,6 +769,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_normaltable.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/delete_systable.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/keep_expired.py +,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/stmt_error.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/drop.py ,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/drop.py -N 3 -M 3 -i False -n 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/join2.py @@ -810,7 +811,8 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeRestartDnodeInsertData.py -N 6 -M 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeRestartDnodeInsertData.py -N 6 -M 3 -n 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeRestartDnodeInsertDataAsync.py -N 6 -M 3 -#,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeRestartDnodeInsertDataAsync.py -N 6 -M 3 -n 3 +#,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeRestartDnodeInsertDataAsync.py -N 6 -M 3 -n 3 +,,n,system-test,python3 ./test.py -f 6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py -N 6 -M 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeAdd1Ddnoe.py -N 7 -M 3 -C 6 ,,y,system-test,./pytest.sh python3 ./test.py -f 6-cluster/5dnode3mnodeAdd1Ddnoe.py -N 7 -M 3 -C 6 -n 3 @@ -1320,6 +1322,7 @@ ,,y,script,./test.sh -f tsim/query/emptyTsRange.sim ,,y,script,./test.sh -f tsim/query/partitionby.sim ,,y,script,./test.sh -f tsim/query/tableCount.sim +,,y,script,./test.sh -f tsim/query/tag_scan.sim ,,y,script,./test.sh -f tsim/query/nullColSma.sim ,,y,script,./test.sh -f tsim/qnode/basic1.sim ,,y,script,./test.sh -f tsim/snode/basic1.sim diff --git a/tests/parallel_test/container_build.sh b/tests/parallel_test/container_build.sh index c6de1778a6..0fc29c241b 100755 --- a/tests/parallel_test/container_build.sh +++ b/tests/parallel_test/container_build.sh @@ -68,8 +68,8 @@ docker run \ -v ${REP_REAL_PATH}/community/contrib/libuv/:${REP_DIR}/community/contrib/libuv \ -v ${REP_REAL_PATH}/community/contrib/lz4/:${REP_DIR}/community/contrib/lz4 \ -v ${REP_REAL_PATH}/community/contrib/zlib/:${REP_DIR}/community/contrib/zlib \ - -v ${REP_REAL_PATH}/community/contrib/jemalloc/:${REP_DIR}/community/contrib/jemalloc \ - --rm --ulimit core=-1 taos_test:v1.0 sh -c "pip uninstall taospy -y;pip3 install taospy==2.7.2;cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_TAOSX=true -DJEMALLOC_ENABLED=false;make -j || exit 1" + --rm --ulimit core=-1 taos_test:v1.0 sh -c "pip uninstall taospy -y;pip3 install taospy==2.7.2;cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_TAOSX=true -DJEMALLOC_ENABLED=0;make -j || exit 1" + # -v ${REP_REAL_PATH}/community/contrib/jemalloc/:${REP_DIR}/community/contrib/jemalloc \ if [[ -d ${WORKDIR}/debugNoSan ]] ;then echo "delete ${WORKDIR}/debugNoSan" @@ -97,7 +97,7 @@ docker run \ -v ${REP_REAL_PATH}/community/contrib/lz4/:${REP_DIR}/community/contrib/lz4 \ -v ${REP_REAL_PATH}/community/contrib/zlib/:${REP_DIR}/community/contrib/zlib \ -v ${REP_REAL_PATH}/community/contrib/jemalloc/:${REP_DIR}/community/contrib/jemalloc \ - --rm --ulimit core=-1 taos_test:v1.0 sh -c "pip uninstall taospy -y;pip3 install taospy==2.7.2;cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_SANITIZER=1 -DTOOLS_SANITIZE=true -DTOOLS_BUILD_TYPE=Debug -DBUILD_TAOSX=true -DJEMALLOC_ENABLED=false -DPORTABLE=true -DWITH_GFLAGS=false;make -j || exit 1 " + --rm --ulimit core=-1 taos_test:v1.0 sh -c "pip uninstall taospy -y;pip3 install taospy==2.7.2;cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true -DBUILD_TEST=true -DWEBSOCKET=true -DBUILD_SANITIZER=1 -DTOOLS_SANITIZE=true -DTOOLS_BUILD_TYPE=Debug -DBUILD_TAOSX=true -DJEMALLOC_ENABLED=0;make -j || exit 1 " mv ${REP_REAL_PATH}/debug ${WORKDIR}/debugSan diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py index 783ee476cb..c041282bfc 100644 --- a/tests/pytest/util/sql.py +++ b/tests/pytest/util/sql.py @@ -431,7 +431,7 @@ class TDSql: time.sleep(1) continue - def execute(self, sql,queryTimes=10): + def execute(self, sql,queryTimes=30): self.sql = sql i=1 while i <= queryTimes: diff --git a/tests/script/api/makefile b/tests/script/api/makefile index 6739794cc8..6d55d8a75f 100644 --- a/tests/script/api/makefile +++ b/tests/script/api/makefile @@ -15,8 +15,11 @@ exe: gcc $(CFLAGS) ./stopquery.c -o $(ROOT)stopquery $(LFLAGS) gcc $(CFLAGS) ./dbTableRoute.c -o $(ROOT)dbTableRoute $(LFLAGS) gcc $(CFLAGS) ./insertSameTs.c -o $(ROOT)insertSameTs $(LFLAGS) + gcc $(CFLAGS) ./passwdTest.c -o $(ROOT)passwdTest $(LFLAGS) clean: rm $(ROOT)batchprepare rm $(ROOT)stopquery rm $(ROOT)dbTableRoute + rm $(ROOT)insertSameTs + rm $(ROOT)passwdTest diff --git a/tests/script/api/passwdTest.c b/tests/script/api/passwdTest.c new file mode 100644 index 0000000000..1bf4987689 --- /dev/null +++ b/tests/script/api/passwdTest.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// TAOS standard API example. The same syntax as MySQL, but only a subset +// to compile: gcc -o demo demo.c -ltaos + +/** + * passwdTest.c + * - Run the test case in clear TDengine environment with default root passwd 'taosdata' + */ + +#include +#include +#include +#include +#include +#include "taos.h" // TAOS header file + +#define nDup 1 +#define nRoot 10 +#define nUser 10 +#define USER_LEN 24 + +void createUsers(TAOS *taos, const char *host, char *qstr); +void passVerTestMulti(const char *host, char *qstr); + +int nPassVerNotified = 0; +TAOS *taosu[nRoot] = {0}; +char users[nUser][USER_LEN] = {0}; + +void __taos_notify_cb(void *param, void *ext, int type) { + switch (type) { + case TAOS_NOTIFY_PASSVER: { + ++nPassVerNotified; + printf("%s:%d type:%d user:%s ver:%d\n", __func__, __LINE__, type, param ? (char *)param : "NULL", *(int *)ext); + break; + } + default: + printf("%s:%d unknown type:%d\n", __func__, __LINE__, type); + break; + } +} + +static void queryDB(TAOS *taos, char *command) { + int i; + TAOS_RES *pSql = NULL; + int32_t code = -1; + + for (i = 0; i < nDup; ++i) { + if (NULL != pSql) { + taos_free_result(pSql); + pSql = NULL; + } + + pSql = taos_query(taos, command); + code = taos_errno(pSql); + if (0 == code) { + break; + } + } + + if (code != 0) { + fprintf(stderr, "failed to run: %s, reason: %s\n", command, taos_errstr(pSql)); + taos_free_result(pSql); + taos_close(taos); + exit(EXIT_FAILURE); + } else { + fprintf(stderr, "success to run: %s\n", command); + } + + taos_free_result(pSql); +} + +int main(int argc, char *argv[]) { + char qstr[1024]; + + // connect to server + if (argc < 2) { + printf("please input server-ip \n"); + return 0; + } + + TAOS *taos = taos_connect(argv[1], "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/); + exit(1); + } + createUsers(taos, argv[1], qstr); + passVerTestMulti(argv[1], qstr); + + taos_close(taos); + taos_cleanup(); +} + +void createUsers(TAOS *taos, const char *host, char *qstr) { + // users + for (int i = 0; i < nUser; ++i) { + sprintf(users[i], "user%d", i); + sprintf(qstr, "CREATE USER %s PASS 'taosdata'", users[i]); + queryDB(taos, qstr); + + taosu[i] = taos_connect(host, users[i], "taosdata", NULL, 0); + if (taosu[i] == NULL) { + printf("failed to connect to server, user:%s, reason:%s\n", users[i], "null taos" /*taos_errstr(taos)*/); + exit(1); + } + + int code = taos_set_notify_cb(taosu[i], __taos_notify_cb, users[i], TAOS_NOTIFY_PASSVER); + + if (code != 0) { + fprintf(stderr, "failed to run: taos_set_notify_cb for user:%s since %d\n", users[i], code); + } else { + fprintf(stderr, "success to run: taos_set_notify_cb for user:%s\n", users[i]); + } + + // alter pass for users + sprintf(qstr, "alter user %s pass 'taos'", users[i]); + queryDB(taos, qstr); + } +} + +void passVerTestMulti(const char *host, char *qstr) { + // root + TAOS *taos[nRoot] = {0}; + char userName[USER_LEN] = "root"; + + for (int i = 0; i < nRoot; ++i) { + taos[i] = taos_connect(host, "root", "taosdata", NULL, 0); + if (taos[i] == NULL) { + printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/); + exit(1); + } + + int code = taos_set_notify_cb(taos[i], __taos_notify_cb, userName, TAOS_NOTIFY_PASSVER); + + if (code != 0) { + fprintf(stderr, "failed to run: taos_set_notify_cb since %d\n", code); + } else { + fprintf(stderr, "success to run: taos_set_notify_cb\n"); + } + } + + queryDB(taos[0], "create database if not exists demo1 vgroups 1 minrows 10"); + queryDB(taos[0], "create database if not exists demo2 vgroups 1 minrows 10"); + queryDB(taos[0], "create database if not exists demo3 vgroups 1 minrows 10"); + + queryDB(taos[0], "create table demo1.stb (ts timestamp, c1 int) tags(t1 int)"); + queryDB(taos[0], "create table demo2.stb (ts timestamp, c1 int) tags(t1 int)"); + queryDB(taos[0], "create table demo3.stb (ts timestamp, c1 int) tags(t1 int)"); + + strcpy(qstr, "alter user root pass 'taos'"); + queryDB(taos[0], qstr); + + // calculate the nPassVerNotified for root and users + int nConn = nRoot + nUser; + + for (int i = 0; i < 15; ++i) { + if (nPassVerNotified >= nConn) break; + sleep(1); + } + + // close the taos_conn + for (int i = 0; i < nRoot; ++i) { + taos_close(taos[i]); + printf("%s:%d close taos[%d]\n", __func__, __LINE__, i); + sleep(1); + } + + for (int i = 0; i < nUser; ++i) { + taos_close(taosu[i]); + printf("%s:%d close taosu[%d]\n", __func__, __LINE__, i); + sleep(1); + } + + if (nPassVerNotified >= nConn) { + fprintf(stderr, "succeed to get passVer notification since nNotify %d >= nConn %d\n", nPassVerNotified, nConn); + } else { + fprintf(stderr, "failed to get passVer notification since nNotify %d < nConn %d\n", nPassVerNotified, nConn); + } + // sleep(300); +} \ No newline at end of file diff --git a/tests/script/local.supp b/tests/script/local.supp new file mode 100644 index 0000000000..562cddba46 --- /dev/null +++ b/tests/script/local.supp @@ -0,0 +1,227 @@ +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN9__gnu_cxx13new_allocatorINSt8__detail10_Hash_nodeISt4pairIKjPFvPvEELb0EEEE8allocateEmPKv + fun:_ZNSt16allocator_traitsISaINSt8__detail10_Hash_nodeISt4pairIKjPFvPvEELb0EEEEE8allocateERS9_m + fun:_ZNSt8__detail16_Hashtable_allocISaINS_10_Hash_nodeISt4pairIKjPFvPvEELb0EEEEE16_M_allocate_nodeIJRKSt21piecewise_construct_tSt5tupleIJRS3_EESF_IJEEEEEPS8_DpOT_ + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE12_Scoped_nodeC1IJRKSt21piecewise_construct_tSt5tupleIJRS1_EESO_IJEEEEEPNS7_16_Hashtable_allocISaINS7_10_Hash_nodeIS5_Lb0EEEEEEDpOT_ + fun:_ZNSt8__detail9_Map_baseIjSt4pairIKjPFvPvEESaIS6_ENS_10_Select1stESt8equal_toIjESt4hashIjENS_18_Mod_range_hashingENS_20_Default_ranged_hashENS_20_Prime_rehash_policyENS_17_Hashtable_traitsILb0ELb0ELb1EEELb1EEixERS2_ + fun:_ZNSt13unordered_mapIjPFvPvESt4hashIjESt8equal_toIjESaISt4pairIKjS2_EEEixERS8_ + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta10SetHandlerEjPFvPvE + fun:_ZN7rocksdb14ThreadLocalPtrC1EPFvPvE + fun:_ZN7rocksdb16ColumnFamilyDataC1EjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_7VersionEPNS_5CacheEPNS_18WriteBufferManagerERKNS_19ColumnFamilyOptionsERKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_15ColumnFamilySetEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb15ColumnFamilySetC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_5CacheEPNS_18WriteBufferManagerEPNS_15WriteControllerEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb10VersionSetC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_5CacheEPNS_18WriteBufferManagerEPNS_15WriteControllerEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb6DBImplC1ERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbb + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb2DB4OpenERKNS_7OptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPS0_ + fun:rocksdb_open + fun:tsdbOpenRocksCache + fun:tsdbOpenCache + fun:tsdbOpen +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN9__gnu_cxx13new_allocatorINSt8__detail10_Hash_nodeISt4pairIKjPFvPvEELb0EEEE8allocateEmPKv + fun:_ZNSt16allocator_traitsISaINSt8__detail10_Hash_nodeISt4pairIKjPFvPvEELb0EEEEE8allocateERS9_m + fun:_ZNSt8__detail16_Hashtable_allocISaINS_10_Hash_nodeISt4pairIKjPFvPvEELb0EEEEE16_M_allocate_nodeIJRKSt21piecewise_construct_tSt5tupleIJRS3_EESF_IJEEEEEPS8_DpOT_ + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE12_Scoped_nodeC1IJRKSt21piecewise_construct_tSt5tupleIJRS1_EESO_IJEEEEEPNS7_16_Hashtable_allocISaINS7_10_Hash_nodeIS5_Lb0EEEEEEDpOT_ + fun:_ZNSt8__detail9_Map_baseIjSt4pairIKjPFvPvEESaIS6_ENS_10_Select1stESt8equal_toIjESt4hashIjENS_18_Mod_range_hashingENS_20_Default_ranged_hashENS_20_Prime_rehash_policyENS_17_Hashtable_traitsILb0ELb0ELb1EEELb1EEixERS2_ + fun:_ZNSt13unordered_mapIjPFvPvESt4hashIjESt8equal_toIjESaISt4pairIKjS2_EEEixERS8_ + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta10SetHandlerEjPFvPvE + fun:_ZN7rocksdb14ThreadLocalPtrC1EPFvPvE + fun:_ZN7rocksdb16ColumnFamilyDataC1EjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_7VersionEPNS_5CacheEPNS_18WriteBufferManagerERKNS_19ColumnFamilyOptionsERKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_15ColumnFamilySetEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb15ColumnFamilySet18CreateColumnFamilyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjPNS_7VersionERKNS_19ColumnFamilyOptionsE + fun:_ZN7rocksdb10VersionSet18CreateColumnFamilyERKNS_19ColumnFamilyOptionsEPKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler15CreateCfAndInitERKNS_19ColumnFamilyOptionsERKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler10InitializeEv + fun:_ZN7rocksdb22VersionEditHandlerBase7IterateERNS_3log6ReaderEPNS_6StatusE + fun:_ZN7rocksdb10VersionSet7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE + fun:_ZN7rocksdb6DBImpl7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbbbPm + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb2DB4OpenERKNS_7OptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPS0_ +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + fun:__cxa_thread_atexit_impl + fun:__cxa_thread_atexit + fun:__tls_init + fun:_ZTWN7rocksdb12perf_contextE + fun:_ZN7rocksdb17InstrumentedMutex4LockEv + fun:_ZN7rocksdb21InstrumentedMutexLockC1EPNS_17InstrumentedMutexE + fun:_ZN7rocksdb5Timer8ShutdownEv + fun:_ZN7rocksdb5TimerD1Ev + fun:_ZNKSt14default_deleteIN7rocksdb5TimerEEclEPS1_ + fun:_ZNSt10unique_ptrIN7rocksdb5TimerESt14default_deleteIS1_EED1Ev + fun:_ZN7rocksdb21PeriodicWorkSchedulerD1Ev + fun:__run_exit_handlers + fun:exit + fun:(below main) +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7rocksdb24CacheEntryStatsCollectorINS_13InternalStats19CacheEntryRoleStatsEE9GetSharedEPNS_5CacheEPNS_11SystemClockEPSt10shared_ptrIS3_E + fun:_ZN7rocksdb13InternalStatsC1EiPNS_11SystemClockEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb16ColumnFamilyDataC1EjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_7VersionEPNS_5CacheEPNS_18WriteBufferManagerERKNS_19ColumnFamilyOptionsERKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_15ColumnFamilySetEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb15ColumnFamilySet18CreateColumnFamilyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjPNS_7VersionERKNS_19ColumnFamilyOptionsE + fun:_ZN7rocksdb10VersionSet18CreateColumnFamilyERKNS_19ColumnFamilyOptionsEPKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler15CreateCfAndInitERKNS_19ColumnFamilyOptionsERKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler10InitializeEv + fun:_ZN7rocksdb22VersionEditHandlerBase7IterateERNS_3log6ReaderEPNS_6StatusE + fun:_ZN7rocksdb10VersionSet7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE + fun:_ZN7rocksdb6DBImpl7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbbbPm + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb2DB4OpenERKNS_7OptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPS0_ + fun:rocksdb_open + fun:tsdbOpenRocksCache + fun:tsdbOpenCache + fun:tsdbOpen + fun:vnodeOpen + fun:vmProcessCreateVnodeReq +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7rocksdb12_GLOBAL__N_111GetRegistryEv + fun:_ZN7rocksdb23CopyCacheDeleterRoleMapEv + fun:_ZN7rocksdb13InternalStats19CacheEntryRoleStats15BeginCollectionEPNS_5CacheEPNS_11SystemClockEm + fun:_ZN7rocksdb24CacheEntryStatsCollectorINS_13InternalStats19CacheEntryRoleStatsEE12CollectStatsEii + fun:_ZN7rocksdb13InternalStats22CollectCacheEntryStatsEb + fun:_ZN7rocksdb6DBImpl9DumpStatsEv + fun:_ZZN7rocksdb21PeriodicWorkScheduler8RegisterEPNS_6DBImplEjjENKUlvE_clEv + fun:_ZSt13__invoke_implIvRZN7rocksdb21PeriodicWorkScheduler8RegisterEPNS0_6DBImplEjjEUlvE_JEET_St14__invoke_otherOT0_DpOT1_ + fun:_ZSt10__invoke_rIvRZN7rocksdb21PeriodicWorkScheduler8RegisterEPNS0_6DBImplEjjEUlvE_JEENSt9enable_ifIXsrSt6__and_IJSt7is_voidIT_ESt14__is_invocableIT0_JDpT1_EEEE5valueES9_E4typeEOSC_DpOSD_ + fun:_ZNSt17_Function_handlerIFvvEZN7rocksdb21PeriodicWorkScheduler8RegisterEPNS1_6DBImplEjjEUlvE_E9_M_invokeERKSt9_Any_data + fun:_ZNKSt8functionIFvvEEclEv + fun:_ZN7rocksdb5Timer3RunEv + fun:_ZSt13__invoke_implIvMN7rocksdb5TimerEFvvEPS1_JEET_St21__invoke_memfun_derefOT0_OT1_DpOT2_ + fun:_ZSt8__invokeIMN7rocksdb5TimerEFvvEJPS1_EENSt15__invoke_resultIT_JDpT0_EE4typeEOS6_DpOS7_ + fun:_ZNSt6thread8_InvokerISt5tupleIJMN7rocksdb5TimerEFvvEPS3_EEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE + fun:_ZNSt6thread8_InvokerISt5tupleIJMN7rocksdb5TimerEFvvEPS3_EEEclEv + fun:_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN7rocksdb5TimerEFvvEPS4_EEEEE6_M_runEv + obj:/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28 + fun:start_thread +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN9__gnu_cxx13new_allocatorIPNSt8__detail15_Hash_node_baseEE8allocateEmPKv + fun:_ZNSt16allocator_traitsISaIPNSt8__detail15_Hash_node_baseEEE8allocateERS3_m + fun:_ZNSt8__detail16_Hashtable_allocISaINS_10_Hash_nodeIPN7rocksdb16ThreadStatusDataELb0EEEEE19_M_allocate_bucketsEm + fun:_ZNSt10_HashtableIPN7rocksdb16ThreadStatusDataES2_SaIS2_ENSt8__detail9_IdentityESt8equal_toIS2_ESt4hashIS2_ENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb1ELb1EEEE19_M_allocate_bucketsEm + fun:_ZNSt10_HashtableIPN7rocksdb16ThreadStatusDataES2_SaIS2_ENSt8__detail9_IdentityESt8equal_toIS2_ESt4hashIS2_ENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb1ELb1EEEE13_M_rehash_auxEmSt17integral_constantIbLb1EE + fun:_ZNSt10_HashtableIPN7rocksdb16ThreadStatusDataES2_SaIS2_ENSt8__detail9_IdentityESt8equal_toIS2_ESt4hashIS2_ENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb1ELb1EEEE9_M_rehashEmRKm + fun:_ZNSt10_HashtableIPN7rocksdb16ThreadStatusDataES2_SaIS2_ENSt8__detail9_IdentityESt8equal_toIS2_ESt4hashIS2_ENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb1ELb1EEEE21_M_insert_unique_nodeERKS2_mmPNS4_10_Hash_nodeIS2_Lb0EEEm + fun:_ZNSt10_HashtableIPN7rocksdb16ThreadStatusDataES2_SaIS2_ENSt8__detail9_IdentityESt8equal_toIS2_ESt4hashIS2_ENS4_18_Mod_range_hashingENS4_20_Default_ranged_hashENS4_20_Prime_rehash_policyENS4_17_Hashtable_traitsILb0ELb1ELb1EEEE9_M_insertIRKS2_NS4_10_AllocNodeISaINS4_10_Hash_nodeIS2_Lb0EEEEEEEESt4pairINS4_14_Node_iteratorIS2_Lb1ELb0EEEbEOT_RKT0_St17integral_constantIbLb1EEm + fun:_ZNSt8__detail12_Insert_baseIPN7rocksdb16ThreadStatusDataES3_SaIS3_ENS_9_IdentityESt8equal_toIS3_ESt4hashIS3_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashENS_20_Prime_rehash_policyENS_17_Hashtable_traitsILb0ELb1ELb1EEEE6insertERKS3_ + fun:_ZNSt13unordered_setIPN7rocksdb16ThreadStatusDataESt4hashIS2_ESt8equal_toIS2_ESaIS2_EE6insertERKS2_ + fun:_ZN7rocksdb19ThreadStatusUpdater14RegisterThreadENS_12ThreadStatus10ThreadTypeEm + fun:_ZN7rocksdb16ThreadStatusUtil14RegisterThreadEPKNS_3EnvENS_12ThreadStatus10ThreadTypeE + fun:_ZN7rocksdb14ThreadPoolImpl4Impl15BGThreadWrapperEPv + fun:_ZSt13__invoke_implIvPFvPvEJPN7rocksdb16BGThreadMetadataEEET_St14__invoke_otherOT0_DpOT1_ + fun:_ZSt8__invokeIPFvPvEJPN7rocksdb16BGThreadMetadataEEENSt15__invoke_resultIT_JDpT0_EE4typeEOS7_DpOS8_ + fun:_ZNSt6thread8_InvokerISt5tupleIJPFvPvEPN7rocksdb16BGThreadMetadataEEEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE + fun:_ZNSt6thread8_InvokerISt5tupleIJPFvPvEPN7rocksdb16BGThreadMetadataEEEEclEv + fun:_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJPFvPvEPN7rocksdb16BGThreadMetadataEEEEEE6_M_runEv + obj:/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28 +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN9__gnu_cxx13new_allocatorIPNSt8__detail15_Hash_node_baseEE8allocateEmPKv + fun:_ZNSt16allocator_traitsISaIPNSt8__detail15_Hash_node_baseEEE8allocateERS3_m + fun:_ZNSt8__detail16_Hashtable_allocISaINS_10_Hash_nodeISt4pairIKjPFvPvEELb0EEEEE19_M_allocate_bucketsEm + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE19_M_allocate_bucketsEm + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE13_M_rehash_auxEmSt17integral_constantIbLb1EE + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE9_M_rehashEmRKm + fun:_ZNSt10_HashtableIjSt4pairIKjPFvPvEESaIS5_ENSt8__detail10_Select1stESt8equal_toIjESt4hashIjENS7_18_Mod_range_hashingENS7_20_Default_ranged_hashENS7_20_Prime_rehash_policyENS7_17_Hashtable_traitsILb0ELb0ELb1EEEE21_M_insert_unique_nodeERS1_mmPNS7_10_Hash_nodeIS5_Lb0EEEm + fun:_ZNSt8__detail9_Map_baseIjSt4pairIKjPFvPvEESaIS6_ENS_10_Select1stESt8equal_toIjESt4hashIjENS_18_Mod_range_hashingENS_20_Default_ranged_hashENS_20_Prime_rehash_policyENS_17_Hashtable_traitsILb0ELb0ELb1EEELb1EEixERS2_ + fun:_ZNSt13unordered_mapIjPFvPvESt4hashIjESt8equal_toIjESaISt4pairIKjS2_EEEixERS8_ + fun:_ZN7rocksdb14ThreadLocalPtr10StaticMeta10SetHandlerEjPFvPvE + fun:_ZN7rocksdb14ThreadLocalPtrC1EPFvPvE + fun:_ZN7rocksdb16ColumnFamilyDataC1EjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_7VersionEPNS_5CacheEPNS_18WriteBufferManagerERKNS_19ColumnFamilyOptionsERKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_15ColumnFamilySetEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb15ColumnFamilySetC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_5CacheEPNS_18WriteBufferManagerEPNS_15WriteControllerEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb10VersionSetC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_5CacheEPNS_18WriteBufferManagerEPNS_15WriteControllerEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb6DBImplC1ERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbb + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb2DB4OpenERKNS_7OptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPS0_ + fun:rocksdb_open +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7rocksdb12_GLOBAL__N_125CreateThreadStatusUpdaterEv + fun:_ZN7rocksdb12_GLOBAL__N_18PosixEnvC1Ev + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + fun:_ZN7rocksdb7OptionsC1Ev + fun:_ZN7rocksdb18ImmutableCFOptionsC1Ev + fun:_Z41__static_initialization_and_destruction_0ii + fun:_GLOBAL__sub_I_cf_options.cc + fun:__libc_csu_init + fun:(below main) +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7rocksdb14ThreadLocalPtr8InstanceEv + fun:_ZN7rocksdb14ThreadLocalPtr14InitSingletonsEv + fun:_ZN7rocksdb3Env7DefaultEv + fun:_ZN7rocksdb9DBOptionsC1Ev + fun:_ZN7rocksdb7OptionsC1Ev + fun:_ZN7rocksdb18ImmutableCFOptionsC1Ev + fun:_Z41__static_initialization_and_destruction_0ii + fun:_GLOBAL__sub_I_cf_options.cc + fun:__libc_csu_init + fun:(below main) +} +{ + + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_ZN7rocksdb24CacheEntryStatsCollectorINS_13InternalStats19CacheEntryRoleStatsEE9GetSharedEPNS_5CacheEPNS_11SystemClockEPSt10shared_ptrIS3_E + fun:_ZN7rocksdb13InternalStatsC1EiPNS_11SystemClockEPNS_16ColumnFamilyDataE + fun:_ZN7rocksdb16ColumnFamilyDataC1EjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS_7VersionEPNS_5CacheEPNS_18WriteBufferManagerERKNS_19ColumnFamilyOptionsERKNS_18ImmutableDBOptionsERKNS_11FileOptionsEPNS_15ColumnFamilySetEPNS_16BlockCacheTracerERKSt10shared_ptrINS_8IOTracerEES8_ + fun:_ZN7rocksdb15ColumnFamilySet18CreateColumnFamilyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjPNS_7VersionERKNS_19ColumnFamilyOptionsE + fun:_ZN7rocksdb10VersionSet18CreateColumnFamilyERKNS_19ColumnFamilyOptionsEPKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler15CreateCfAndInitERKNS_19ColumnFamilyOptionsERKNS_11VersionEditE + fun:_ZN7rocksdb18VersionEditHandler10InitializeEv + fun:_ZN7rocksdb22VersionEditHandlerBase7IterateERNS_3log6ReaderEPNS_6StatusE + fun:_ZN7rocksdb10VersionSet7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE + fun:_ZN7rocksdb6DBImpl7RecoverERKSt6vectorINS_22ColumnFamilyDescriptorESaIS2_EEbbbPm + fun:_ZN7rocksdb6DBImpl4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPNS_2DBEbb + fun:_ZN7rocksdb2DB4OpenERKNS_9DBOptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_22ColumnFamilyDescriptorESaISD_EEPSC_IPNS_18ColumnFamilyHandleESaISJ_EEPPS0_ + fun:_ZN7rocksdb2DB4OpenERKNS_7OptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPPS0_ + fun:rocksdb_open + fun:tsdbOpenRocksCache + fun:tsdbOpenCache + fun:tsdbOpen + fun:vnodeOpen + fun:vmOpenVnodeInThread +} diff --git a/tests/script/sh/checkAsan.sh b/tests/script/sh/checkAsan.sh index b6cb4f6280..0077ca4e0e 100755 --- a/tests/script/sh/checkAsan.sh +++ b/tests/script/sh/checkAsan.sh @@ -55,7 +55,9 @@ python_error=`cat ${LOG_DIR}/*.info | grep -w "stack" | wc -l` # /home/chr/TDengine/source/libs/scalar/src/filter.c:3149:14: runtime error: applying non-zero offset 18446744073709551615 to null pointer # /home/TDinternal/community/source/libs/scalar/src/sclvector.c:1109:66: runtime error: signed integer overflow: 9223372034707292160 + 1676867897049 cannot be represented in type 'long int' -runtime_error=`cat ${LOG_DIR}/*.asan | grep "runtime error" | grep -v "trees.c:873" | grep -v "sclfunc.c.*outside the range of representable values of type"| grep -v "signed integer overflow" |grep -v "strerror.c"| grep -v "asan_malloc_linux.cc" |wc -l` +#0 0x7f2d64f5a808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144 +#1 0x7f2d63fcf459 in strerror /build/glibc-SzIz7B/glibc-2.31/string/strerror.c:38 +runtime_error=`cat ${LOG_DIR}/*.asan | grep "runtime error" | grep -v "trees.c:873" | grep -v "sclfunc.c.*outside the range of representable values of type"| grep -v "signed integer overflow" |grep -v "strerror.c"| grep -v "asan_malloc_linux.cc" |grep -v "strerror.c"|wc -l` echo -e "\033[44;32;1m"asan error_num: $error_num"\033[0m" echo -e "\033[44;32;1m"asan memory_leak: $memory_leak"\033[0m" diff --git a/tests/script/sh/exec.sh b/tests/script/sh/exec.sh index f548a4cc41..5061688de2 100755 --- a/tests/script/sh/exec.sh +++ b/tests/script/sh/exec.sh @@ -109,8 +109,10 @@ if [ "$EXEC_OPTON" = "start" ]; then if [ "$VALGRIND_OPTION" = "true" ]; then TT=`date +%s` #mkdir ${LOG_DIR}/${TT} - echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &" - nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 & + #echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &" + #nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --gen-suppressions=all --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 & + echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --suppressions=${SCRIPT_DIR}/local.supp --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &" + nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --suppressions=${SCRIPT_DIR}/local.supp --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 & else echo "nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &" nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2> $ASAN_DIR/$NODE_NAME.asan & diff --git a/tests/script/tsim/alter/table.sim b/tests/script/tsim/alter/table.sim index ded5d6f78a..db2a22205f 100644 --- a/tests/script/tsim/alter/table.sim +++ b/tests/script/tsim/alter/table.sim @@ -657,17 +657,37 @@ if $data20 != null then return -1 endi -print =============== error -sql create table tb2023(ts timestamp, f int); -sql_error alter table tb2023 add column v varchar(16375); -sql_error alter table tb2023 add column v varchar(16385); -sql_error alter table tb2023 add column v varchar(33100); -sql alter table tb2023 add column v varchar(16374); -sql desc tb2023 -sql alter table tb2023 drop column v -sql_error alter table tb2023 add column v nchar(4094); -sql alter table tb2023 add column v nchar(4093); -sql desc tb2023 +#print =============== error for normal table +#sql create table tb2023(ts timestamp, f int); +#sql_error alter table tb2023 add column v varchar(65535); +#sql_error alter table tb2023 add column v varchar(65535); +#sql_error alter table tb2023 add column v varchar(65530); +#sql alter table tb2023 add column v varchar(16374); +#sql_error alter table tb2023 modify column v varchar(65536); +#sql desc tb2023 +#sql alter table tb2023 drop column v +#sql_error alter table tb2023 add column v nchar(16384); +#sql alter table tb2023 add column v nchar(4093); +#sql_error alter table tb2023 modify column v nchar(16384); +#sql_error alter table tb2023 add column v nchar(16384); +#sql alter table tb2023 drop column v +#sql alter table tb2023 add column v nchar(16374); +#sql desc tb2023 +# +#print =============== error for super table +#sql create table stb2023(ts timestamp, f int) tags(t1 int); +#sql_error alter table stb2023 add column v varchar(65535); +#sql_error alter table stb2023 add column v varchar(65536); +#sql_error alter table stb2023 add column v varchar(33100); +#sql alter table stb2023 add column v varchar(16374); +#sql_error alter table stb2023 modify column v varchar(16375); +#sql desc stb2023 +#sql alter table stb2023 drop column v +#sql_error alter table stb2023 add column v nchar(4094); +#sql alter table stb2023 add column v nchar(4093); +#sql_error alter table stb2023 modify column v nchar(4094); +#sql desc stb2023 + print ======= over sql drop database d1 sql select * from information_schema.ins_databases diff --git a/tests/script/tsim/dnode/split_vgroup_replica1.sim b/tests/script/tsim/dnode/split_vgroup_replica1.sim index 51d63d25f4..135f7a579e 100644 --- a/tests/script/tsim/dnode/split_vgroup_replica1.sim +++ b/tests/script/tsim/dnode/split_vgroup_replica1.sim @@ -93,6 +93,19 @@ endi print =============== step4: split print split vgroup 2 sql split vgroup 2 +$wt = 0 + stepwt1: + $wt = $wt + 1 + sleep 1000 + if $wt == 200 then + print ====> split vgroup not completed! + return -1 + endi +sql show transactions +if $rows != 0 then + print wait 1 seconds to alter + goto stepwt1 +endi print =============== step5: check split result sql show d1.tables diff --git a/tests/script/tsim/parser/alter_column.sim b/tests/script/tsim/parser/alter_column.sim index c70a604c73..f892115735 100644 --- a/tests/script/tsim/parser/alter_column.sim +++ b/tests/script/tsim/parser/alter_column.sim @@ -48,7 +48,7 @@ sql_error alter table tb modify column c2 binary(10); sql_error alter table tb modify column c2 binary(9); sql_error alter table tb modify column c2 binary(-9); sql_error alter table tb modify column c2 binary(0); -sql alter table tb modify column c2 binary(17000); +sql_error alter table tb modify column c2 binary(65600); sql_error alter table tb modify column c2 nchar(30); sql_error alter table tb modify column c3 double; sql_error alter table tb modify column c3 nchar(10); diff --git a/tests/script/tsim/query/partitionby.sim b/tests/script/tsim/query/partitionby.sim index 8babd1aa8d..4c221e02d3 100644 --- a/tests/script/tsim/query/partitionby.sim +++ b/tests/script/tsim/query/partitionby.sim @@ -36,4 +36,34 @@ if $rows != 0 then return -1 endi +sql insert into tb0 values (now, 0); +sql insert into tb1 values (now, 1); +sql insert into tb2 values (now, 2); +sql insert into tb3 values (now, 3); +sql insert into tb4 values (now, 4); +sql insert into tb5 values (now, 5); +sql insert into tb6 values (now, 6); +sql insert into tb7 values (now, 7); + +sql select * from (select 1 from $mt1 where ts is not null partition by tbname limit 1); +if $rows != 8 then + return -1 +endi + +sql select count(*) from (select ts from $mt1 where ts is not null partition by tbname slimit 2); +if $rows != 1 then + return -1 +endi +if $data00 != 2 then + return -1 +endi + +sql select count(*) from (select ts from $mt1 where ts is not null partition by tbname limit 2); +if $rows != 1 then + return -1 +endi +if $data00 != 8 then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/query/tag_scan.sim b/tests/script/tsim/query/tag_scan.sim new file mode 100644 index 0000000000..03e3a20632 --- /dev/null +++ b/tests/script/tsim/query/tag_scan.sim @@ -0,0 +1,48 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect +sql drop database if exists test +sql create database test; +sql use test; + +sql create table st(ts timestamp, f int) tags (t int); +sql insert into ct1 using st tags(1) values(now, 1); +sql insert into ct2 using st tags(2) values(now, 2); +sql insert into ct3 using st tags(3) values(now, 3); +sql insert into ct4 using st tags(4) values(now, 4); + +sql create table st2(ts timestamp, f int) tags (t int); +sql insert into ct21 using st2 tags(1) values(now, 1); +sql insert into ct22 using st2 tags(2) values(now, 2); +sql insert into ct23 using st2 tags(3) values(now, 3); +sql insert into ct24 using st2 tags(4) values(now, 4); + +sql select tbname, 1 from st group by tbname order by tbname; +print $rows $data00 $data10 $data20 +if $rows != 4 then + return -1 +endi +if $data00 != @ct1@ then + return -1 +endi +if $data10 != @ct2@ then + return -1 +endi +sql select tbname, 1 from st group by tbname slimit 0, 1; +print $rows +if $rows != 1 then + return -1 +endi +sql select tbname, 1 from st group by tbname slimit 2, 2; +print $rows $data00 $data10 +if $rows != 2 then + return -1 +endi +sql select tbname, 1 from st group by tbname order by tbname slimit 0, 1; +print $rows $data00 $data10 $data20 +if $rows != 4 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/query/unionall_as_table.sim b/tests/script/tsim/query/unionall_as_table.sim index dc3d2cbec4..4d8f990718 100644 --- a/tests/script/tsim/query/unionall_as_table.sim +++ b/tests/script/tsim/query/unionall_as_table.sim @@ -25,4 +25,21 @@ if $data05 != @0021001@ then return -1 endi +sql create table st (ts timestamp, f int) tags (t int); +sql insert into ct1 using st tags(1) values(now, 1)(now+1s, 2) +sql insert into ct2 using st tags(2) values(now+2s, 3)(now+3s, 4) +sql select count(*) from (select * from ct1 union all select * from ct2) +if $rows != 1 then + return -1 +endi +if $data00 != 4 then + return -1 +endi +sql select count(*) from (select * from ct1 union select * from ct2) +if $rows != 1 then + return -1 +endi +if $data00 != 4 then + return -1 +endi system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/system-test/0-others/user_privilege.py b/tests/system-test/0-others/user_privilege.py index 6d49ebfbfe..d1b93f6942 100644 --- a/tests/system-test/0-others/user_privilege.py +++ b/tests/system-test/0-others/user_privilege.py @@ -29,6 +29,7 @@ class TDTestCase: self.stbname = 'stb' self.binary_length = 20 # the length of binary for column_dict self.nchar_length = 20 # the length of nchar for column_dict + self.dbnames = ['db1', 'db2'] self.column_dict = { 'ts': 'timestamp', 'col1': 'float', @@ -57,21 +58,25 @@ class TDTestCase: def create_user(self): user_name = 'test' tdSql.execute(f'create user {user_name} pass "test"') - tdSql.execute(f'grant read on db.stb with t2 = "Beijing" to {user_name}') + tdSql.execute(f'grant read on {self.dbnames[0]}.{self.stbname} with t2 = "Beijing" to {user_name}') + tdSql.execute(f'grant write on {self.dbnames[1]}.{self.stbname} with t1 = 2 to {user_name}') def prepare_data(self): - tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict)) - for i in range(self.tbnum): - tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_list[i]})') - for j in self.values_list: - tdSql.execute(f'insert into {self.stbname}_{i} values({j})') + for db in self.dbnames: + tdSql.execute(f"create database {db}") + tdSql.execute(f"use {db}") + tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict)) + for i in range(self.tbnum): + tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_list[i]})') + for j in self.values_list: + tdSql.execute(f'insert into {self.stbname}_{i} values({j})') - def user_privilege_check(self): + def user_read_privilege_check(self, dbname): testconn = taos.connect(user='test', password='test') expectErrNotOccured = False try: - sql = "select count(*) from db.stb where t2 = 'Beijing'" + sql = f"select count(*) from {dbname}.stb where t2 = 'Beijing'" res = testconn.query(sql) data = res.fetch_all() count = data[0][0] @@ -85,11 +90,30 @@ class TDTestCase: tdLog.exit(f"{sql}, expect result doesn't match") pass + def user_write_privilege_check(self, dbname): + testconn = taos.connect(user='test', password='test') + expectErrNotOccured = False + + try: + sql = f"insert into {dbname}.stb_1 values(now, 1.1, 200, 0.3)" + testconn.execute(sql) + except BaseException: + expectErrNotOccured = True + + if expectErrNotOccured: + caller = inspect.getframeinfo(inspect.stack()[1][0]) + tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured") + else: + pass + def user_privilege_error_check(self): testconn = taos.connect(user='test', password='test') expectErrNotOccured = False - sql_list = ["alter talbe db.stb_1 set t2 = 'Wuhan'", "drop table db.stb_1"] + sql_list = [f"alter talbe {self.dbnames[0]}.stb_1 set t2 = 'Wuhan'", + f"insert into {self.dbnames[0]}.stb_1 values(now, 1.1, 200, 0.3)", + f"drop table {self.dbnames[0]}.stb_1", + f"select count(*) from {self.dbnames[1]}.stb"] for sql in sql_list: try: @@ -104,11 +128,11 @@ class TDTestCase: tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured") pass - def run(self): - tdSql.prepare() + def run(self): self.prepare_data() self.create_user() - self.user_privilege_check() + self.user_read_privilege_check(self.dbnames[0]) + self.user_write_privilege_check(self.dbnames[1]) self.user_privilege_error_check() def stop(self): diff --git a/tests/system-test/1-insert/boundary.py b/tests/system-test/1-insert/boundary.py index d3742ef5f9..29dcbc7c46 100644 --- a/tests/system-test/1-insert/boundary.py +++ b/tests/system-test/1-insert/boundary.py @@ -166,6 +166,61 @@ class TDTestCase: else: tdLog.exit("error info is not true") tdSql.execute('drop database db') + + def row_col_tag_maxlen_check(self): + tdSql.prepare() + tdSql.execute('use db') + tdSql.execute('create table if not exists stb1 (ts timestamp, c1 int,c2 binary(1000)) tags (city binary(16382))') + tdSql.error('create table if not exists stb1 (ts timestamp, c1 int,c2 binary(1000)) tags (city binary(16383))') + tdSql.execute('create table if not exists stb2 (ts timestamp, c0 tinyint, c1 int, c2 nchar(16379)) tags (city binary(16382))') + tdSql.error('create table if not exists stb2 (ts timestamp, c0 smallint, c1 int, c2 nchar(16379)) tags (city binary(16382))') + tdSql.execute('create table if not exists stb3 (ts timestamp, c1 int, c2 binary(65517)) tags (city binary(16382))') + tdSql.error('create table if not exists stb3 (ts timestamp, c0 bool, c1 int, c2 binary(65517)) tags (city binary(16382))') + # prepare the column and tag data + char100='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN0123456789' + tag_max_16382='' + binary_max_65517 = '' + nchar_max_16379='' + for num in range(163): + nchar_max_16379 += char100 + for num in range(4): + binary_max_65517 += char100 + + nchar_max_16379 += '0123456789012345678901234567890123456789012345678901234567890123456789012345678' + tag_max_16382 = nchar_max_16379 + tag_max_16382 += '9ab' + + for num in range(3): + binary_max_65517 += char100 + binary_max_65517 += '01234567890123456' + + # insert/query and check + tdSql.execute(f"create table ct1 using stb1 tags('{tag_max_16382}')") + tdSql.execute(f"create table ct2 using stb2 tags('{tag_max_16382}')") + tdSql.execute(f"create table ct3 using stb3 tags('{tag_max_16382}')") + tdSql.execute(f"insert into ct1 values (now,1,'nchar_max_16379')") + tdSql.execute(f"insert into ct2 values (now,1,1,'{nchar_max_16379}')") + tdSql.execute(f"insert into ct3 values (now,1,'{binary_max_65517}')") + + tdSql.query("select * from stb1") + tdSql.checkEqual(tdSql.queryResult[0][3],tag_max_16382) + + tdSql.query("select * from ct2") + tdSql.checkEqual(tdSql.queryResult[0][3],nchar_max_16379) + + tdSql.query("select * from stb2") + tdSql.checkEqual(tdSql.queryResult[0][3],nchar_max_16379) + tdSql.checkEqual(tdSql.queryResult[0][4],tag_max_16382) + + tdSql.query("select * from ct3") + tdSql.checkEqual(tdSql.queryResult[0][2],binary_max_65517) + + tdSql.query("select * from stb3") + tdSql.checkEqual(tdSql.queryResult[0][2],binary_max_65517) + tdSql.checkEqual(tdSql.queryResult[0][3],tag_max_16382) + + tdSql.execute('drop database db') + def run(self): self.dbname_length_check() self.tbname_length_check() @@ -174,6 +229,7 @@ class TDTestCase: self.username_length_check() self.password_length_check() self.sql_length_check() + self.row_col_tag_maxlen_check() def stop(self): tdSql.close() diff --git a/tests/system-test/1-insert/influxdb_line_taosc_insert.py b/tests/system-test/1-insert/influxdb_line_taosc_insert.py index 6372502484..3e9bad4efd 100644 --- a/tests/system-test/1-insert/influxdb_line_taosc_insert.py +++ b/tests/system-test/1-insert/influxdb_line_taosc_insert.py @@ -439,7 +439,7 @@ class TDTestCase: for input_sql in [self.genLongSql(127, 1)[0], self.genLongSql(1, 4093)[0]]: tdCom.cleanTb(dbname="test") self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - for input_sql in [self.genLongSql(129, 1)[0], self.genLongSql(1, 4095)[0]]: + for input_sql in [self.genLongSql(128, 1)[0], self.genLongSql(1, 4094)[0]]: tdCom.cleanTb(dbname="test") try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) @@ -578,10 +578,16 @@ class TDTestCase: # binary stb_name = tdCom.getLongName(7, "letters") - input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(16374, "letters")}" c0=f 1626006833639000000' + input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(4091, "letters")}" c0=f 1626006833639000000' self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(16375, "letters")}" c0=f 1626006833639000000' + input_sql = f'{stb_name},t0="a",t1="{tdCom.getLongName(4088, "letters")}" c0=f 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) + + input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(4092, "letters")}" c0=f 1626006833639000000' try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError as err: @@ -590,10 +596,10 @@ class TDTestCase: # nchar # * legal nchar could not be larger than 16374/4 stb_name = tdCom.getLongName(7, "letters") - input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4093, "letters")}" c0=f 1626006833639000000' + input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4090, "letters")}" c0=f 1626006833639000000' self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4094, "letters")}" c0=f 1626006833639000000' + input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4091, "letters")}" c0=f 1626006833639000000' try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError as err: @@ -672,28 +678,34 @@ class TDTestCase: except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) - # # # binary - # stb_name = tdCom.getLongName(7, "letters") - # input_sql = f'{stb_name},t0=t c0=f,c1="{tdCom.getLongName(16374, "letters")}" 1626006833639000000' - # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + # binary + stb_name = tdCom.getLongName(7, "letters") + input_sql = f'{stb_name},t0=t c0=1i32,c1="{tdCom.getLongName(65517, "letters")}" 1626006833639000000' + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - # input_sql = f'{stb_name},t0=t c0=f,c1="{tdCom.getLongName(16375, "letters")}" 1626006833639000000' - # try: - # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - # except SchemalessError as err: - # tdSql.checkNotEqual(err.errno, 0) + input_sql = f'{stb_name},t0=t c0=1i32,c1="{tdCom.getLongName(65517, "letters")},c2=f" 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) - # # nchar - # # * legal nchar could not be larger than 16374/4 - # stb_name = tdCom.getLongName(7, "letters") - # input_sql = f'{stb_name},t0=t c0=f,c1=L"{tdCom.getLongName(4093, "letters")}" 1626006833639000000' - # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + input_sql = f'{stb_name},t0=t c0=f,c1="{tdCom.getLongName(65518, "letters")}" 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) - # input_sql = f'{stb_name},t0=t c0=f,c1=L"{tdCom.getLongName(4094, "letters")}" 1626006833639000000' - # try: - # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - # except SchemalessError as err: - # tdSql.checkNotEqual(err.errno, 0) + # nchar + # * legal nchar could not be larger than 16374/4 + stb_name = tdCom.getLongName(7, "letters") + input_sql = f'{stb_name},t0=t c0=1i32,c1=L"{tdCom.getLongName(16379, "letters")}",c2=f 1626006833639000000' + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + + input_sql = f'{stb_name},t0=t c0=1i32,c1=L"{tdCom.getLongName(16380, "letters")}",c2=1i16 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) def tagColIllegalValueCheckCase(self): @@ -884,7 +896,7 @@ class TDTestCase: tdSql.checkRows(2) tdSql.checkNotEqual(tb_name1, tb_name3) - # * tag binary max is 16384, col+ts binary max 49151 + # * tag binary max is 16384-2, col+ts binary max 65531 def tagColBinaryMaxLengthCheckCase(self): """ every binary and nchar must be length+2 @@ -896,35 +908,59 @@ class TDTestCase: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) # * every binary and nchar must be length+2, so here is two tag, max length could not larger than 16384-2*2 - input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(16374, "letters")}",t2="{tdCom.getLongName(5, "letters")}" c0=f 1626006833639000000' + stb_name = tdCom.getLongName(8, "letters") + input_sql = f'{stb_name},t0=f,t1="{tdCom.getLongName(4091, "letters")}", c0=f 1626006833639000000' self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(2) - input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(16374, "letters")}",t2="{tdCom.getLongName(6, "letters")}" c0=f 1626006833639000000' + tdSql.checkRows(1) + + input_sql = f'{stb_name},t0=t,t1="{tdCom.getLongName(4092, "letters")}", c0=f 1626006833639000000' try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) raise Exception("should not reach here") except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(2) + tdSql.checkRows(1) + + stb_name = tdCom.getLongName(9, "letters") # # * check col,col+ts max in describe ---> 16143 - input_sql = f'{stb_name},t0=t c0=f,c1="{tdCom.getLongName(16374, "letters")}",c2="{tdCom.getLongName(16374, "letters")}",c3="{tdCom.getLongName(16374, "letters")}",c4="{tdCom.getLongName(12, "letters")}" 1626006833639000000' + input_sql = f'{stb_name},t0=t c0=1i32,c1="{tdCom.getLongName(65517, "letters")}" 1626006833639000000' self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + input_sql = f'{stb_name},t0=t c0=1i32,c1="{tdCom.getLongName(65517, "letters")}",c2=f 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) + tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(3) + tdSql.checkRows(1) + + + stb_name = tdCom.getLongName(10, "letters") + input_sql = f'{stb_name},t0=t c0=1i16,c1="{tdCom.getLongName(49133, "letters")}",c2="{tdCom.getLongName(16384, "letters")}" 1626006833639000000' + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + + input_sql = f'{stb_name},t0=t c0=1i16,c1="{tdCom.getLongName(49133, "letters")}",c2="{tdCom.getLongName(16384, "letters")},c3=t" 1626006833639000000' + try: + self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + except SchemalessError as err: + tdSql.checkNotEqual(err.errno, 0) + + tdSql.query(f"select * from {stb_name}") + tdSql.checkRows(1) + input_sql = f'{stb_name},t0=t c0=f,c1="{tdCom.getLongName(16374, "letters")}",c2="{tdCom.getLongName(16374, "letters")}",c3="{tdCom.getLongName(16374, "letters")}",c4="{tdCom.getLongName(13, "letters")}" 1626006833639000000' try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) - tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(3) - # * tag nchar max is 16374/4, col+ts nchar max 49151 + + # * tag nchar max is (16384-2)/4, col+ts nchar max 65531 def tagColNcharMaxLengthCheckCase(self): """ check nchar length limit @@ -935,30 +971,31 @@ class TDTestCase: input_sql = f'{stb_name},id="{tb_name}",t0=t c0=f 1626006833639000000' code = self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - # * legal nchar could not be larger than 16374/4 - input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4093, "letters")}",t2=L"{tdCom.getLongName(1, "letters")}" c0=f 1626006833639000000' - self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(2) - input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4093, "letters")}",t2=L"{tdCom.getLongName(2, "letters")}" c0=f 1626006833639000000' - try: - self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) - except SchemalessError as err: - tdSql.checkNotEqual(err.errno, 0) - tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(2) + # * legal tag nchar could not be larger than (16384-2)/4 + # input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4093, "letters")}",t2=L"{tdCom.getLongName(1, "letters")}" c0=f 1626006833639000000' + # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + # tdSql.query(f"select * from {stb_name}") + # tdSql.checkRows(2) + # input_sql = f'{stb_name},t0=t,t1=L"{tdCom.getLongName(4093, "letters")}",t2=L"{tdCom.getLongName(2, "letters")}" c0=f 1626006833639000000' + # try: + # self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) + # except SchemalessError as err: + # tdSql.checkNotEqual(err.errno, 0) + # tdSql.query(f"select * from {stb_name}") + # tdSql.checkRows(2) input_sql = f'{stb_name},t0=t c0=f,c1=L"{tdCom.getLongName(4093, "letters")}",c2=L"{tdCom.getLongName(4093, "letters")}",c3=L"{tdCom.getLongName(4093, "letters")}",c4=L"{tdCom.getLongName(4, "letters")}" 1626006833639000000' self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(3) + tdSql.checkRows(2) + input_sql = f'{stb_name},t0=t c0=f,c1=L"{tdCom.getLongName(4093, "letters")}",c2=L"{tdCom.getLongName(4093, "letters")}",c3=L"{tdCom.getLongName(4093, "letters")}",c4=L"{tdCom.getLongName(5, "letters")}" 1626006833639000000' try: self._conn.schemaless_insert([input_sql], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value) except SchemalessError as err: tdSql.checkNotEqual(err.errno, 0) tdSql.query(f"select * from {stb_name}") - tdSql.checkRows(3) + tdSql.checkRows(2) def batchInsertCheckCase(self): """ @@ -1274,13 +1311,13 @@ class TDTestCase: self.idSeqCheckCase() self.idUpperCheckCase() self.noIdCheckCase() - # self.maxColTagCheckCase() + self.maxColTagCheckCase() self.idIllegalNameCheckCase() self.idStartWithNumCheckCase() self.nowTsCheckCase() self.dateFormatTsCheckCase() self.illegalTsCheckCase() - # self.tagValueLengthCheckCase() + self.tagValueLengthCheckCase() self.colValueLengthCheckCase() self.tagColIllegalValueCheckCase() self.duplicateIdTagColInsertCheckCase() @@ -1290,8 +1327,8 @@ class TDTestCase: self.tagColAddDupIDCheckCase() self.tagColAddCheckCase() self.tagMd5Check() - # self.tagColBinaryMaxLengthCheckCase() - # self.tagColNcharMaxLengthCheckCase() + self.tagColBinaryMaxLengthCheckCase() + self.tagColNcharMaxLengthCheckCase() self.batchInsertCheckCase() self.multiInsertCheckCase(10) self.batchErrorInsertCheckCase() diff --git a/tests/system-test/1-insert/stmt_error.py b/tests/system-test/1-insert/stmt_error.py new file mode 100644 index 0000000000..c6d747c317 --- /dev/null +++ b/tests/system-test/1-insert/stmt_error.py @@ -0,0 +1,224 @@ +# encoding:UTF-8 +from taos import * + +from ctypes import * +from datetime import datetime +import taos + +import taos +import time + +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + +class TDTestCase: + def __init__(self): + self.err_case = 0 + self.curret_case = 0 + + def caseDescription(self): + + ''' + case1 : [TD-11899] : this is an test case for check stmt error use . + ''' + return + + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def conn(self): + # type: () -> taos.TaosConnection + return connect() + + def test_stmt_insert(self,conn): + # type: (TaosConnection) -> None + + dbname = "pytest_taos_stmt" + try: + conn.execute("drop database if exists %s" % dbname) + conn.execute("create database if not exists %s" % dbname) + conn.select_db(dbname) + + conn.execute( + "create table if not exists log(ts timestamp, bo bool, nil tinyint, ti tinyint, si smallint, ii int,\ + bi bigint, tu tinyint unsigned, su smallint unsigned, iu int unsigned, bu bigint unsigned, \ + ff float, dd double, bb binary(65059), nn nchar(100), tt timestamp)", + ) + conn.load_table_info("log") + + + stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + params = new_bind_params(16) + params[0].timestamp(1626861392589, PrecisionEnum.Milliseconds) + params[1].bool(True) + params[2].tinyint(None) + params[3].tinyint(2) + params[4].smallint(3) + params[5].int(4) + params[6].bigint(5) + params[7].tinyint_unsigned(6) + params[8].smallint_unsigned(7) + params[9].int_unsigned(8) + params[10].bigint_unsigned(9) + params[11].float(10.1) + params[12].double(10.11) + binaryStr = '123456789' + for i in range(1301): + binaryStr += "1234567890abcdefghij1234567890abcdefghij12345hello" + params[13].binary(binaryStr) + params[14].nchar("stmt") + params[15].timestamp(1626861392589, PrecisionEnum.Milliseconds) + + stmt.bind_param(params) + stmt.execute() + + assert stmt.affected_rows == 1 + stmt.close() + + querystmt=conn.statement("select ?, bo, nil, ti, si, ii,bi, tu, su, iu, bu, ff, dd, bb, nn, tt from log") + queryparam=new_bind_params(1) + print(type(queryparam)) + queryparam[0].binary("ts") + querystmt.bind_param(queryparam) + querystmt.execute() + result=querystmt.use_result() + + row=result.fetch_all() + print(row) + + assert row[0][1] == True + assert row[0][2] == None + for i in range(3, 10): + assert row[0][i] == i - 1 + #float == may not work as expected + # assert row[0][11] == c_float(10.1) + assert row[0][12] == 10.11 + assert row[0][13][65054:] == "hello" + assert row[0][14] == "stmt" + + conn.execute("drop database if exists %s" % dbname) + conn.close() + + except Exception as err: + conn.execute("drop database if exists %s" % dbname) + conn.close() + raise err + + def test_stmt_insert_error(self,conn): + # type: (TaosConnection) -> None + + dbname = "pytest_taos_stmt_error" + try: + conn.execute("drop database if exists %s" % dbname) + conn.execute("create database if not exists %s" % dbname) + conn.select_db(dbname) + + conn.execute( + "create table if not exists log(ts timestamp, bo bool, nil tinyint, ti tinyint, si smallint, ii int,\ + bi bigint, tu tinyint unsigned, su smallint unsigned, iu int unsigned, bu bigint unsigned, \ + ff float, dd double, bb binary(100), nn nchar(100), tt timestamp , error_data int )", + ) + conn.load_table_info("log") + + + stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1000)") + params = new_bind_params(16) + params[0].timestamp(1626861392589, PrecisionEnum.Milliseconds) + params[1].bool(True) + params[2].tinyint(None) + params[3].tinyint(2) + params[4].smallint(3) + params[5].int(4) + params[6].bigint(5) + params[7].tinyint_unsigned(6) + params[8].smallint_unsigned(7) + params[9].int_unsigned(8) + params[10].bigint_unsigned(9) + params[11].float(10.1) + params[12].double(10.11) + params[13].binary("hello") + params[14].nchar("stmt") + params[15].timestamp(1626861392589, PrecisionEnum.Milliseconds) + + stmt.bind_param(params) + stmt.execute() + + conn.close() + + except Exception as err: + conn.execute("drop database if exists %s" % dbname) + conn.close() + raise err + + def test_stmt_insert_error_null_timestamp(self,conn): + + dbname = "pytest_taos_stmt_error_null_ts" + try: + conn.execute("drop database if exists %s" % dbname) + conn.execute("create database if not exists %s" % dbname) + conn.execute("alter database %s keep 36500" % dbname) + conn.select_db(dbname) + + conn.execute("create stable STB(ts timestamp, n int) tags(b int)") + + stmt = conn.statement("insert into ? using STB tags(?) values(?, ?)") + params = new_bind_params(1) + params[0].int(4); + stmt.set_tbname_tags("ct", params); + + multi_params = new_multi_binds(2); + multi_params[0].timestamp([9223372036854775808]) + multi_params[1].int([123]) + stmt.bind_param_batch(multi_params) + + stmt.execute() + result = stmt.use_result() + + result.close() + stmt.close() + + stmt = conn.statement("select * from STB") + stmt.execute() + result = stmt.use_result() + print(result.affected_rows) + row = result.next() + print(row) + + result.close() + stmt.close() + conn.close() + + except Exception as err: + conn.close() + raise err + + def run(self): + + self.test_stmt_insert(self.conn()) + try: + self.test_stmt_insert_error(self.conn()) + except Exception as error : + + if str(error)=='[0x0200]: no mix usage for ? and values': + tdLog.info('=========stmt error occured for bind part column ==============') + else: + tdLog.exit("expect error(%s) not occured" % str(error)) + + try: + self.test_stmt_insert_error_null_timestamp(self.conn()) + tdLog.exit("expect error not occured - 1") + except Exception as error : + if str(error)=='[0x060b]: Timestamp data out of range': + tdLog.info('=========stmt error occured for bind part column(NULL Timestamp) ==============') + else: + tdLog.exit("expect error(%s) not occured - 2" % str(error)) + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index ddf3f2534d..cdbfa0de84 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -23,6 +23,8 @@ class TDTestCase: stbname = "stb" ctbname1 = "ctb1" ctbname2 = "ctb2" + ctbname3 = "ctb3" + num_of_ctables = 3 tdSql.prepare() @@ -816,17 +818,26 @@ class TDTestCase: ) tdSql.execute( - f'''create table if not exists {dbname}.{ctbname2} using {dbname}.{stbname} tags(1) + f'''create table if not exists {dbname}.{ctbname2} using {dbname}.{stbname} tags(2) ''' ) - tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:05', 5, 5, 5, 5, 5.0, 5.0, true, 'varchar', 'nchar')") - tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:10', 10, 10, 10, 10, 10.0, 10.0, true, 'varchar', 'nchar')") - tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar')") + tdSql.execute( + f'''create table if not exists {dbname}.{ctbname3} using {dbname}.{stbname} tags(3) + ''' + ) - tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-02 00:00:05', 5, 5, 5, 5, 5.0, 5.0, true, 'varchar', 'nchar')") - tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-02 00:00:10', 10, 10, 10, 10, 10.0, 10.0, true, 'varchar', 'nchar')") - tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-02 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:01', 1, 1, 1, 1, 1.0, 1.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:07', 7, 7, 7, 7, 7.0, 7.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:13', 13, 13, 13, 13, 13.0, 13.0, true, 'varchar', 'nchar')") + + tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-01 00:00:03', 3, 3, 3, 3, 3.0, 3.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-01 00:00:09', 9, 9, 9, 9, 9.0, 9.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname2} values ('2020-02-01 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar')") + + tdSql.execute(f"insert into {dbname}.{ctbname3} values ('2020-02-01 00:00:05', 5, 5, 5, 5, 5.0, 5.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname3} values ('2020-02-01 00:00:11', 11, 11, 11, 11, 11.0, 11.0, true, 'varchar', 'nchar')") + tdSql.execute(f"insert into {dbname}.{ctbname3} values ('2020-02-01 00:00:17', 17, 17, 17, 17, 17.0, 17.0, true, 'varchar', 'nchar')") tdSql.execute(f"flush database {dbname}"); @@ -834,7 +845,7 @@ class TDTestCase: # test fill null ## | {. | | .} | - tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(null)") + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:06') every(1d) fill(null)") tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, None) @@ -881,7 +892,7 @@ class TDTestCase: # test fill value ## | {. | | .} | - tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(value, 1)") + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:06') every(1d) fill(value, 1)") tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 1) @@ -895,7 +906,7 @@ class TDTestCase: tdSql.checkData(9, 0, 1) tdSql.checkData(10, 0, 15) - ## | . | {} | . | + # | . | {} | . | tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-03 00:00:05', '2020-02-07 00:00:05') every(1d) fill(value, 1)") tdSql.checkRows(5) tdSql.checkData(0, 0, 1) @@ -928,7 +939,7 @@ class TDTestCase: # test fill prev ## | {. | | .} | - tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(prev)") + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:06') every(1d) fill(prev)") tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 5) @@ -973,7 +984,7 @@ class TDTestCase: # test fill next ## | {. | | .} | - tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(next)") + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:06') every(1d) fill(next)") tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 15) @@ -1015,7 +1026,7 @@ class TDTestCase: # test fill linear ## | {. | | .} | - tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:05') every(1d) fill(linear)") + tdSql.query(f"select interp(c0) from {dbname}.{tbname} range('2020-02-01 00:00:05', '2020-02-11 00:00:06') every(1d) fill(linear)") tdSql.checkRows(11) tdSql.checkData(0, 0, 5) tdSql.checkData(1, 0, 6) @@ -2391,19 +2402,516 @@ class TDTestCase: - tdLog.printNoPrefix("==========step13:stable cases") + tdLog.printNoPrefix("==========step13:test stable cases") - tdSql.error(f"select interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(null)") - #tdSql.checkRows(13) + # select interp from supertable + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") + tdSql.checkRows(19) - #tdSql.query(f"select interp(c0) from {dbname}.{ctbname1} range('2020-02-01 00:00:04', '2020-02-01 00:00:16') every(1s) fill(null)") - #tdSql.checkRows(13) + tdSql.checkData(0, 2, None) + tdSql.checkData(1, 2, 1) + tdSql.checkData(2, 2, None) + tdSql.checkData(3, 2, 3) + tdSql.checkData(4, 2, None) + tdSql.checkData(5, 2, 5) + tdSql.checkData(6, 2, None) + tdSql.checkData(7, 2, 7) + tdSql.checkData(8, 2, None) + tdSql.checkData(9, 2, 9) + tdSql.checkData(10, 2, None) + tdSql.checkData(11, 2, 11) + tdSql.checkData(12, 2, None) + tdSql.checkData(13, 2, 13) + tdSql.checkData(14, 2, None) + tdSql.checkData(15, 2, 15) + tdSql.checkData(16, 2, None) + tdSql.checkData(17, 2, 17) + tdSql.checkData(18, 2, None) - tdSql.error(f"select interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:04', '2020-02-02 00:00:16') every(1s) fill(null)") - #tdSql.checkRows(13) + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(value, 0)") + tdSql.checkRows(19) + + tdSql.checkData(0, 2, 0) + tdSql.checkData(1, 2, 1) + tdSql.checkData(2, 2, 0) + tdSql.checkData(3, 2, 3) + tdSql.checkData(4, 2, 0) + tdSql.checkData(5, 2, 5) + tdSql.checkData(6, 2, 0) + tdSql.checkData(7, 2, 7) + tdSql.checkData(8, 2, 0) + tdSql.checkData(9, 2, 9) + tdSql.checkData(10, 2, 0) + tdSql.checkData(11, 2, 11) + tdSql.checkData(12, 2, 0) + tdSql.checkData(13, 2, 13) + tdSql.checkData(14, 2, 0) + tdSql.checkData(15, 2, 15) + tdSql.checkData(16, 2, 0) + tdSql.checkData(17, 2, 17) + tdSql.checkData(18, 2, 0) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(prev)") + tdSql.checkRows(18) + + tdSql.checkData(0, 0, '2020-02-01 00:00:01.000') + tdSql.checkData(0, 1, False) + + tdSql.checkData(0, 2, 1) + tdSql.checkData(1, 2, 1) + tdSql.checkData(2, 2, 3) + tdSql.checkData(3, 2, 3) + tdSql.checkData(4, 2, 5) + tdSql.checkData(5, 2, 5) + tdSql.checkData(6, 2, 7) + tdSql.checkData(7, 2, 7) + tdSql.checkData(8, 2, 9) + tdSql.checkData(9, 2, 9) + tdSql.checkData(10, 2, 11) + tdSql.checkData(11, 2, 11) + tdSql.checkData(12, 2, 13) + tdSql.checkData(13, 2, 13) + tdSql.checkData(14, 2, 15) + tdSql.checkData(15, 2, 15) + tdSql.checkData(16, 2, 17) + tdSql.checkData(17, 2, 17) + + tdSql.checkData(17, 0, '2020-02-01 00:00:18.000') + tdSql.checkData(17, 1, True) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(next)") + tdSql.checkRows(18) + + tdSql.checkData(0, 0, '2020-02-01 00:00:00.000') + tdSql.checkData(0, 1, True) + + tdSql.checkData(0, 2, 1) + tdSql.checkData(1, 2, 1) + tdSql.checkData(2, 2, 3) + tdSql.checkData(3, 2, 3) + tdSql.checkData(4, 2, 5) + tdSql.checkData(5, 2, 5) + tdSql.checkData(6, 2, 7) + tdSql.checkData(7, 2, 7) + tdSql.checkData(8, 2, 9) + tdSql.checkData(9, 2, 9) + tdSql.checkData(10, 2, 11) + tdSql.checkData(11, 2, 11) + tdSql.checkData(12, 2, 13) + tdSql.checkData(13, 2, 13) + tdSql.checkData(14, 2, 15) + tdSql.checkData(15, 2, 15) + tdSql.checkData(16, 2, 17) + tdSql.checkData(17, 2, 17) + + tdSql.checkData(17, 0, '2020-02-01 00:00:17.000') + tdSql.checkData(17, 1, False) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(17) + + tdSql.checkData(0, 2, 1) + tdSql.checkData(1, 2, 2) + tdSql.checkData(2, 2, 3) + tdSql.checkData(3, 2, 4) + tdSql.checkData(4, 2, 5) + tdSql.checkData(5, 2, 6) + tdSql.checkData(6, 2, 7) + tdSql.checkData(7, 2, 8) + tdSql.checkData(8, 2, 9) + tdSql.checkData(9, 2, 10) + tdSql.checkData(10, 2, 11) + tdSql.checkData(11, 2, 12) + tdSql.checkData(12, 2, 13) + tdSql.checkData(13, 2, 14) + tdSql.checkData(14, 2, 15) + tdSql.checkData(15, 2, 16) + tdSql.checkData(16, 2, 17) + + # select interp from supertable partition by tbname + + tdSql.query(f"select tbname, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") + + point_idx = {1, 7, 13, 22, 28, 34, 43, 49, 55} + point_dict = {1:1, 7:7, 13:13, 22:3, 28:9, 34:15, 43:5, 49:11, 55:17} + rows_per_partition = 19 + tdSql.checkRows(rows_per_partition * num_of_ctables) + for i in range(num_of_ctables): + for j in range(rows_per_partition): + row = j + i * rows_per_partition + tdSql.checkData(row, 0, f'ctb{i + 1}') + tdSql.checkData(j, 1, f'2020-02-01 00:00:{j}.000') + if row in point_idx: + tdSql.checkData(row, 2, False) + else: + tdSql.checkData(row, 2, True) + + if row in point_idx: + tdSql.checkData(row, 3, point_dict[row]) + else: + tdSql.checkData(row, 3, None) + + tdSql.query(f"select tbname, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(value, 0)") + + point_idx = {1, 7, 13, 22, 28, 34, 43, 49, 55} + point_dict = {1:1, 7:7, 13:13, 22:3, 28:9, 34:15, 43:5, 49:11, 55:17} + rows_per_partition = 19 + tdSql.checkRows(rows_per_partition * num_of_ctables) + for i in range(num_of_ctables): + for j in range(rows_per_partition): + row = j + i * rows_per_partition + tdSql.checkData(row, 0, f'ctb{i + 1}') + tdSql.checkData(j, 1, f'2020-02-01 00:00:{j}.000') + if row in point_idx: + tdSql.checkData(row, 2, False) + else: + tdSql.checkData(row, 2, True) + + if row in point_idx: + tdSql.checkData(row, 3, point_dict[row]) + else: + tdSql.checkData(row, 3, 0) + + tdSql.query(f"select tbname, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(prev)") + + tdSql.checkRows(48) + for i in range(0, 18): + tdSql.checkData(i, 0, 'ctb1') + + for i in range(18, 34): + tdSql.checkData(i, 0, 'ctb2') + + for i in range(34, 48): + tdSql.checkData(i, 0, 'ctb3') + + tdSql.checkData(0, 1, '2020-02-01 00:00:01.000') + tdSql.checkData(17, 1, '2020-02-01 00:00:18.000') + + tdSql.checkData(18, 1, '2020-02-01 00:00:03.000') + tdSql.checkData(33, 1, '2020-02-01 00:00:18.000') + + tdSql.checkData(34, 1, '2020-02-01 00:00:05.000') + tdSql.checkData(47, 1, '2020-02-01 00:00:18.000') + + for i in range(0, 6): + tdSql.checkData(i, 3, 1) + + for i in range(6, 12): + tdSql.checkData(i, 3, 7) + + for i in range(12, 18): + tdSql.checkData(i, 3, 13) + + for i in range(18, 24): + tdSql.checkData(i, 3, 3) + + for i in range(24, 30): + tdSql.checkData(i, 3, 9) + + for i in range(30, 34): + tdSql.checkData(i, 3, 15) + + for i in range(34, 40): + tdSql.checkData(i, 3, 5) + + for i in range(40, 46): + tdSql.checkData(i, 3, 11) + + for i in range(46, 48): + tdSql.checkData(i, 3, 17) + + tdSql.query(f"select tbname, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(next)") + + tdSql.checkRows(48) + for i in range(0, 14): + tdSql.checkData(i, 0, 'ctb1') + + for i in range(14, 30): + tdSql.checkData(i, 0, 'ctb2') + + for i in range(30, 48): + tdSql.checkData(i, 0, 'ctb3') + + tdSql.checkData(0, 1, '2020-02-01 00:00:00.000') + tdSql.checkData(13, 1, '2020-02-01 00:00:13.000') + + tdSql.checkData(14, 1, '2020-02-01 00:00:00.000') + tdSql.checkData(29, 1, '2020-02-01 00:00:15.000') + + tdSql.checkData(30, 1, '2020-02-01 00:00:00.000') + tdSql.checkData(47, 1, '2020-02-01 00:00:17.000') + + for i in range(0, 2): + tdSql.checkData(i, 3, 1) + + for i in range(2, 8): + tdSql.checkData(i, 3, 7) + + for i in range(8, 14): + tdSql.checkData(i, 3, 13) + + for i in range(14, 18): + tdSql.checkData(i, 3, 3) + + for i in range(18, 24): + tdSql.checkData(i, 3, 9) + + for i in range(24, 30): + tdSql.checkData(i, 3, 15) + + for i in range(30, 36): + tdSql.checkData(i, 3, 5) + + for i in range(36, 42): + tdSql.checkData(i, 3, 11) + + for i in range(42, 48): + tdSql.checkData(i, 3, 17) + + tdSql.query(f"select tbname, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + + tdSql.checkRows(39) + for i in range(0, 13): + tdSql.checkData(i, 0, 'ctb1') + + for i in range(13, 26): + tdSql.checkData(i, 0, 'ctb2') + + for i in range(26, 39): + tdSql.checkData(i, 0, 'ctb3') + + tdSql.checkData(0, 1, '2020-02-01 00:00:01.000') + tdSql.checkData(12, 1, '2020-02-01 00:00:13.000') + + tdSql.checkData(13, 1, '2020-02-01 00:00:03.000') + tdSql.checkData(25, 1, '2020-02-01 00:00:15.000') + + tdSql.checkData(26, 1, '2020-02-01 00:00:05.000') + tdSql.checkData(38, 1, '2020-02-01 00:00:17.000') + + for i in range(0, 13): + tdSql.checkData(i, 3, i + 1) + + for i in range(13, 26): + tdSql.checkData(i, 3, i - 10) + + for i in range(26, 39): + tdSql.checkData(i, 3, i - 21) + + # select interp from supertable partition by column + + tdSql.query(f"select c0, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by c0 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") + tdSql.checkRows(171) + + tdSql.query(f"select c0, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by c0 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(value, 0)") + tdSql.checkRows(171) + + tdSql.query(f"select c0, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by c0 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(prev)") + tdSql.checkRows(90) + + tdSql.query(f"select c0, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by c0 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(next)") + tdSql.checkRows(90) + + tdSql.query(f"select c0, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by c0 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(9) + + # select interp from supertable partition by tag + + tdSql.query(f"select t1, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by t1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") + tdSql.checkRows(57) + + tdSql.query(f"select t1, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by t1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(value, 0)") + tdSql.checkRows(57) + + tdSql.query(f"select t1, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by t1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(prev)") + tdSql.checkRows(48) + + tdSql.query(f"select t1, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by t1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(next)") + tdSql.checkRows(48) + + tdSql.query(f"select t1, _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by t1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(39) + + # select interp from supertable filter + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where ts between '2020-02-01 00:00:01.000' and '2020-02-01 00:00:13.000' range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where c0 <= 13 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where t1 = 1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where tbname = 'ctb1' range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where ts between '2020-02-01 00:00:01.000' and '2020-02-01 00:00:13.000' partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(27) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where c0 <= 13 partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(27) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where t1 = 1 partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where tbname = 'ctb1' partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + # select interp from supertable filter limit + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 13") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 20") + tdSql.checkRows(17) + + for i in range(17): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where ts between '2020-02-01 00:00:01.000' and '2020-02-01 00:00:13.000' range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where c0 <= 13 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where t1 = 1 range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where tbname = 'ctb1' range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 13") + tdSql.checkRows(13) + + for i in range(13): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 40") + tdSql.checkRows(39) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where ts between '2020-02-01 00:00:01.000' and '2020-02-01 00:00:13.000' partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where c0 <= 13 partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where t1 = 1 partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} where tbname = 'ctb1' partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear) limit 10") + tdSql.checkRows(10) + + for i in range(10): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 1) + + # select interp from supertable with scalar expression + + tdSql.query(f"select _irowts, _isfilled, interp(1 + 1) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(17) + + for i in range(17): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, 2.0) + + tdSql.query(f"select _irowts, _isfilled, interp(c0 + 1) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(17) + + for i in range(17): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, i + 2) + + tdSql.query(f"select _irowts, _isfilled, interp(c0 * 2) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(17) + + for i in range(17): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, (i + 1) * 2) + + tdSql.query(f"select _irowts, _isfilled, interp(c0 + c1) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(linear)") + tdSql.checkRows(17) + + for i in range(17): + tdSql.checkData(i, 0, f'2020-02-01 00:00:{i + 1}.000') + tdSql.checkData(i, 2, (i + 1) * 2) + + # check duplicate timestamp + + # add duplicate timestamp for different child tables + tdSql.execute(f"insert into {dbname}.{ctbname1} values ('2020-02-01 00:00:15', 15, 15, 15, 15, 15.0, 15.0, true, 'varchar', 'nchar')") + + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:14') every(1s) fill(null)") + tdSql.error(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:15') every(1s) fill(null)") + tdSql.error(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") + tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:00', '2020-02-01 00:00:18') every(1s) fill(null)") - #tdSql.query(f"select _irowts,interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:04', '2020-02-02 00:00:16') every(1h) fill(prev)") - #tdSql.query(f"select tbname,_irowts,interp(c0) from {dbname}.{stbname} partition by tbname range('2020-02-01 00:00:04', '2020-02-02 00:00:16') every(1h) fill(prev)") tdLog.printNoPrefix("======step 14: test interp pseudo columns") tdSql.error(f"select _irowts, c6 from {dbname}.{tbname}") diff --git a/tests/system-test/2-query/odbc.py b/tests/system-test/2-query/odbc.py index a05e057042..f7851ad04b 100644 --- a/tests/system-test/2-query/odbc.py +++ b/tests/system-test/2-query/odbc.py @@ -22,7 +22,8 @@ class TDTestCase: tdSql.execute("insert into db.ctb using db.stb tags(1) (ts, c1) values (now, 1)") tdSql.query("select count(*) from information_schema.ins_columns") - tdSql.checkData(0, 0, 277) + # enterprise version: 285, community version: 277 + tdSql.checkData(0, 0, 285) tdSql.query("select * from information_schema.ins_columns where table_name = 'ntb'") tdSql.checkRows(14) diff --git a/tests/system-test/6-cluster/clusterCommonCheck.py b/tests/system-test/6-cluster/clusterCommonCheck.py index f5926321da..7aa2ba06b9 100644 --- a/tests/system-test/6-cluster/clusterCommonCheck.py +++ b/tests/system-test/6-cluster/clusterCommonCheck.py @@ -251,17 +251,17 @@ class ClusterComCheck: count+=1 elif self.db_replica == 3 : vgroup_status_first=[tdSql.queryResult[0][4],tdSql.queryResult[0][6],tdSql.queryResult[0][8]] - + vgroup_status_last=[tdSql.queryResult[last_number][4],tdSql.queryResult[last_number][6],tdSql.queryResult[last_number][8]] if vgroup_status_first.count('leader') == 1 and vgroup_status_first.count('follower') == 2: if vgroup_status_last.count('leader') == 1 and vgroup_status_last.count('follower') == 2: ready_time= (count + 1) - tdLog.success(f"all vgroups of {db_name} are ready in {ready_time} s") + tdLog.success(f"elections of {db_name} all vgroups are ready in {ready_time} s") return True count+=1 else: tdLog.debug(tdSql.queryResult) - tdLog.notice(f"all vgroups leader of {db_name} is selected {count}s ") + tdLog.notice(f"elections of {db_name} all vgroups are failed in{count}s ") caller = inspect.getframeinfo(inspect.stack()[1][0]) args = (caller.filename, caller.lineno) tdLog.exit("%s(%d) failed " % args) diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootAlterRep1-3.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootAlterRep1-3.py new file mode 100644 index 0000000000..aa3ed8e3fd --- /dev/null +++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertDataRebootAlterRep1-3.py @@ -0,0 +1,222 @@ +import taos +import sys +import time +import os + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import TDDnodes +from util.dnodes import TDDnode +from util.cluster import * +sys.path.append("./6-cluster") +from clusterCommonCreate import * +from clusterCommonCheck import clusterComCheck + +import time +import socket +import subprocess +from multiprocessing import Process +import threading +import time +import inspect +import ctypes + +class TDTestCase: + + def init(self, conn, logSql, replicaVar=1): + tdLog.debug(f"start to excute {__file__}") + self.TDDnodes = None + tdSql.init(conn.cursor()) + self.host = socket.gethostname() + + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def _async_raise(self, tid, exctype): + """raises the exception, performs cleanup if needed""" + if not inspect.isclass(exctype): + exctype = type(exctype) + res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) + if res == 0: + raise ValueError("invalid thread id") + elif res != 1: + # """if it returns a number greater than one, you're in trouble, + # and you should call it again with exc=NULL to revert the effect""" + ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None) + raise SystemError("PyThreadState_SetAsyncExc failed") + + def stopThread(self,thread): + self._async_raise(thread.ident, SystemExit) + + + def insertData(self,countstart,countstop): + # fisrt add data : db\stable\childtable\general table + + for couti in range(countstart,countstop): + tdLog.debug("drop database if exists db%d" %couti) + tdSql.execute("drop database if exists db%d" %couti) + print("create database if not exists db%d replica 1 duration 300" %couti) + tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti) + tdSql.execute("use db%d" %couti) + tdSql.execute( + '''create table stb1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + tags (t1 int) + ''' + ) + tdSql.execute( + ''' + create table t1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + ''' + ) + for i in range(4): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )') + + + def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'db0_0', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'replica': 1, + 'stbName': 'stb', + 'stbNumbers': 2, + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbNum': 1000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + "rowsPerTbl": 100, + "batchNum": 5000 + } + + dnodeNumbers = int(dnodeNumbers) + mnodeNums = int(mnodeNums) + vnodeNumbers = int(dnodeNumbers-mnodeNums) + allctbNumbers = (paraDict['stbNumbers']*paraDict["ctbNum"]) + rowsPerStb = paraDict["ctbNum"]*paraDict["rowsPerTbl"] + rowsall = rowsPerStb*paraDict['stbNumbers'] + dbNumbers = 1 + replica3 = 3 + tdLog.info("first check dnode and mnode") + tdSql.query("select * from information_schema.ins_dnodes;") + tdSql.checkData(0,1,'%s:6030'%self.host) + tdSql.checkData(4,1,'%s:6430'%self.host) + clusterComCheck.checkDnodes(dnodeNumbers) + + #check mnode status + tdLog.info("check mnode status") + clusterComCheck.checkMnodeStatus(mnodeNums) + + # add some error operations and + tdLog.info("Confirm the status of the dnode again") + tdSql.error("create mnode on dnode 2") + tdSql.query("select * from information_schema.ins_dnodes;") + print(tdSql.queryResult) + clusterComCheck.checkDnodes(dnodeNumbers) + + # create database and stable + clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica']) + tdLog.info("Take turns stopping Mnodes ") + + tdDnodes=cluster.dnodes + stopcount =0 + threads=[] + + # create stable:stb_0 + stableName= paraDict['stbName'] + newTdSql=tdCom.newTdSql() + clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers']) + #create child table:ctb_0 + for i in range(paraDict['stbNumbers']): + stableName= '%s_%d'%(paraDict['stbName'],i) + newTdSql=tdCom.newTdSql() + clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum']) + #insert date + for i in range(paraDict['stbNumbers']): + stableName= '%s_%d'%(paraDict['stbName'],i) + newTdSql=tdCom.newTdSql() + threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"]))) + for tr in threads: + tr.start() + TdSqlEx=tdCom.newTdSql() + tdLog.info("alter database db0_0 replica 3") + TdSqlEx.execute('alter database db0_0 replica 3') + while stopcount < restartNumbers: + tdLog.info(" restart loop: %d"%stopcount ) + if stopRole == "mnode": + for i in range(mnodeNums): + tdDnodes[i].stoptaosd() + # sleep(10) + tdDnodes[i].starttaosd() + # sleep(10) + elif stopRole == "vnode": + for i in range(vnodeNumbers): + tdDnodes[i+mnodeNums].stoptaosd() + # sleep(10) + tdDnodes[i+mnodeNums].starttaosd() + # sleep(10) + elif stopRole == "dnode": + for i in range(dnodeNumbers): + tdDnodes[i].stoptaosd() + # tdLog.info('select cast(c2 as nchar(10)) from db0_0.stb_1;') + # TdSqlEx.execute('select cast(c2 as nchar(10)) from db0_0.stb_1;') + # tdLog.info('select avg(c1) from db0_0.stb_0 interval(10s);') + # TdSqlEx.execute('select avg(c1) from db0_0.stb_0 interval(10s);') + # sleep(10) + tdDnodes[i].starttaosd() + # sleep(10) + # dnodeNumbers don't include database of schema + if clusterComCheck.checkDnodes(dnodeNumbers): + tdLog.info("123") + else: + print("456") + + self.stopThread(threads) + tdLog.exit("one or more of dnodes failed to start ") + # self.check3mnode() + stopcount+=1 + + for tr in threads: + tr.join() + clusterComCheck.checkDnodes(dnodeNumbers) + clusterComCheck.checkDbRows(dbNumbers) + # clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"]) + + # tdSql.execute("use %s" %(paraDict["dbName"])) + tdSql.query("show %s.stables"%(paraDict["dbName"])) + tdSql.checkRows(paraDict["stbNumbers"]) + # for i in range(paraDict['stbNumbers']): + # stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i) + # tdSql.query("select count(*) from %s"%stableName) + # tdSql.checkData(0,0,rowsPerStb) + clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica3,db_name=paraDict["dbName"],count_number=240) + def run(self): + # print(self.master_dnode.cfgDict) + self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode') + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py index ed7b99a880..fede19ca3a 100644 --- a/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py +++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeInsertLessDataAlterRep3to1to3.py @@ -177,7 +177,7 @@ class TDTestCase: tdSql.query("select count(*) from %s"%stableName) tdSql.checkData(0,0,rowsPerStb) - clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica1,db_name=paraDict["dbName"],count_number=20) + clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica1,db_name=paraDict["dbName"],count_number=40) sleep(5) tdLog.info(f"show transactions;alter database db0_0 replica {replica3};") TdSqlEx.execute(f'show transactions;') diff --git a/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py b/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py index e02af29a05..ee48b973c9 100644 --- a/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py +++ b/tests/system-test/6-cluster/manually-test/6dnode3mnodeStopDnodeInsertDatatb.py @@ -64,11 +64,11 @@ class TDTestCase: self._async_raise(thread.ident, SystemExit) - def insertData(self,dbname,tableCount,rowsPerCount): + def insertData(self,dbname,tableCount,rowsPerCount,vgroups): # tableCount : create table number # rowsPerCount : rows per table # fisrt add data : db\stable\childtable\general table - os.system(f"taosBenchmark -d {dbname} -n {tableCount} -t {rowsPerCount} -z 1 -k 10000 -y ") + os.system(f"taosBenchmark -d {dbname} -n {tableCount} -t {rowsPerCount} -v {vgroups} -z 1 -k 10000 -y ") def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole): @@ -76,10 +76,10 @@ class TDTestCase: paraDict = {'dbName': 'db0_0', 'dropFlag': 1, 'event': '', - 'vgroups': 4, + 'vgroups': 6, 'replica': 1, - 'stbName': 'stb', - 'stbNumbers': 2, + 'stbName': 'meters', + 'stbNumbers': 1, 'colPrefix': 'c', 'tagPrefix': 't', 'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], @@ -124,7 +124,7 @@ class TDTestCase: threads=[] # create stable:stb_0 - threads.append(threading.Thread(target=self.insertData, args=(paraDict["dbName"],paraDict["ctbNum"],paraDict["rowsPerTbl"]))) + threads.append(threading.Thread(target=self.insertData, args=(paraDict["dbName"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["vgroups"]))) for tr in threads: tr.start() TdSqlEx=tdCom.newTdSql() @@ -174,10 +174,13 @@ class TDTestCase: # tdSql.execute("use %s" %(paraDict["dbName"])) tdSql.query("show %s.stables"%(paraDict["dbName"])) tdSql.checkRows(paraDict["stbNumbers"]) - for i in range(paraDict['stbNumbers']): - stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i) - tdSql.query("select count(*) from %s"%stableName) - tdSql.checkData(0,0,rowsPerStb) + # for i in range(paraDict['stbNumbers']): + # stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i) + # tdSql.query("select count(*) from %s"%stableName) + # tdSql.checkData(0,0,rowsPerStb) + stableName= '%s.%s'%(paraDict["dbName"],paraDict['stbName']) + tdSql.query("select count(*) from %s"%stableName) + tdSql.checkData(0,0,rowsall) clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=3,db_name=paraDict["dbName"],count_number=240) def run(self): # print(self.master_dnode.cfgDict) diff --git a/tests/system-test/runAllOne.sh b/tests/system-test/runAllOne.sh index 58548f43db..a870e36935 100644 --- a/tests/system-test/runAllOne.sh +++ b/tests/system-test/runAllOne.sh @@ -287,6 +287,7 @@ python3 ./test.py -f 1-insert/tb_100w_data_order.py -P python3 ./test.py -f 1-insert/delete_childtable.py -P python3 ./test.py -f 1-insert/delete_normaltable.py -P python3 ./test.py -f 1-insert/keep_expired.py -P +python3 ./test.py -f 1-insert/stmt_error.py -P python3 ./test.py -f 1-insert/drop.py -P python3 ./test.py -f 2-query/join2.py -P python3 ./test.py -f 2-query/union1.py -P diff --git a/tests/system-test/win-test-file b/tests/system-test/win-test-file index 6baa82ac46..96ffa63707 100644 --- a/tests/system-test/win-test-file +++ b/tests/system-test/win-test-file @@ -218,6 +218,7 @@ python3 ./test.py -f 1-insert/delete_stable.py python3 ./test.py -f 1-insert/delete_childtable.py python3 ./test.py -f 1-insert/delete_normaltable.py python3 ./test.py -f 1-insert/keep_expired.py +python3 ./test.py -f 1-insert/stmt_error.py python3 ./test.py -f 1-insert/drop.py python3 ./test.py -f 1-insert/drop.py -N 3 -M 3 -i False -n 3 python3 ./test.py -f 2-query/join2.py diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 0f91bdeeda..e2752f7899 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -716,7 +716,7 @@ int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision) { case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_JSON: { - int16_t bytes = field->bytes * TSDB_NCHAR_SIZE; + uint16_t bytes = field->bytes * TSDB_NCHAR_SIZE; if (bytes > shell.args.displayWidth) { return TMAX(shell.args.displayWidth, width); } else { @@ -1118,6 +1118,7 @@ int32_t shellExecute() { } if (shell.conn == NULL) { + printf("failed to connect to server, reason: %s\n", taos_errstr(NULL)); fflush(stdout); return -1; } diff --git a/utils/test/c/sml_test.c b/utils/test/c/sml_test.c index f1dc8ebe79..ac5aff4727 100644 --- a/utils/test/c/sml_test.c +++ b/utils/test/c/sml_test.c @@ -989,7 +989,7 @@ int sml_ts2164_Test() { TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); TAOS_RES *pRes = - taos_query(taos, "CREATE DATABASE IF NOT EXISTS line_test BUFFER 384 MINROWS 1000 PAGES 256 PRECISION 'ns'"); + taos_query(taos, "CREATE DATABASE IF NOT EXISTS line_test MINROWS 1000 PRECISION 'ns'"); taos_free_result(pRes); const char *sql[] = { @@ -1139,8 +1139,8 @@ int sml_td23881_Test() { taos_query(taos, "CREATE DATABASE IF NOT EXISTS line_23881 PRECISION 'ns'"); taos_free_result(pRes); - char tmp[16375] = {0}; - memset(tmp, 'a', 16374); + char tmp[26375] = {0}; + memset(tmp, 'a', 26374); char sql[102400] = {0}; sprintf(sql,"lujixfvqor,t0=t c0=f,c1=\"%s\",c2=\"%s\",c3=\"%s\",c4=\"wthvqxcsrlps\" 1626006833639000000", tmp, tmp, tmp); @@ -1385,8 +1385,8 @@ int main(int argc, char *argv[]) { ASSERT(!ret); ret = sml_ts3116_Test(); ASSERT(!ret); - ret = sml_ts2385_Test(); // this test case need config sml table name using ./sml_test config_file - ASSERT(!ret); +// ret = sml_ts2385_Test(); // this test case need config sml table name using ./sml_test config_file +// ASSERT(!ret); ret = sml_ts3303_Test(); // this test case need config sml table name using ./sml_test config_file ASSERT(!ret);