diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..b873e47b74 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: check-json + - id: end-of-file-fixer + - id: trailing-whitespace + +repos: + - repo: https://github.com/psf/black + rev: stable + hooks: + - id: black + +repos: + - repo: https://github.com/pocc/pre-commit-hooks + rev: master + hooks: + - id: cppcheck + args: ["--error-exitcode=0"] + +repos: + - repo: https://github.com/crate-ci/typos + rev: v1.15.7 + hooks: + - id: typos + diff --git a/Jenkinsfile2 b/Jenkinsfile2 index 55bd5466ed..f4dcdb242e 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -314,7 +314,7 @@ def pre_test_build_win() { cd %WIN_CONNECTOR_ROOT% python.exe -m pip install --upgrade pip python -m pip uninstall taospy -y - python -m pip install taospy==2.7.6 + python -m pip install taospy==2.7.10 xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32 ''' return 1 diff --git a/cmake/cmake.version b/cmake/cmake.version index edc51f206c..fe35fbe7bd 100644 --- a/cmake/cmake.version +++ b/cmake/cmake.version @@ -2,7 +2,7 @@ IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "3.0.6.0.alpha") + SET(TD_VER_NUMBER "3.1.0.0.alpha") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/cmake/geos_CMakeLists.txt.in b/cmake/geos_CMakeLists.txt.in index 44b3ec027c..f939ccead0 100644 --- a/cmake/geos_CMakeLists.txt.in +++ b/cmake/geos_CMakeLists.txt.in @@ -2,11 +2,11 @@ # geos ExternalProject_Add(geos GIT_REPOSITORY https://github.com/libgeos/geos.git - GIT_TAG 3.11.2 + GIT_TAG 3.12.0 SOURCE_DIR "${TD_CONTRIB_DIR}/geos" BINARY_DIR "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" TEST_COMMAND "" - ) \ No newline at end of file + ) diff --git a/cmake/rocksdb_CMakeLists.txt.in b/cmake/rocksdb_CMakeLists.txt.in index f238ed20af..45599d82e3 100644 --- a/cmake/rocksdb_CMakeLists.txt.in +++ b/cmake/rocksdb_CMakeLists.txt.in @@ -5,8 +5,8 @@ if (${BUILD_CONTRIB}) URL https://github.com/facebook/rocksdb/archive/refs/tags/v8.1.1.tar.gz URL_HASH MD5=3b4c97ee45df9c8a5517308d31ab008b DOWNLOAD_NO_PROGRESS 1 - DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" - SOURCE_DIR "${TD_CONTRIB_DIR}/rocksdb" + DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" + SOURCE_DIR "${TD_CONTRIB_DIR}/rocksdb" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -18,8 +18,8 @@ else() URL https://github.com/facebook/rocksdb/archive/refs/tags/v8.1.1.tar.gz URL_HASH MD5=3b4c97ee45df9c8a5517308d31ab008b DOWNLOAD_NO_PROGRESS 1 - DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" - SOURCE_DIR "${TD_CONTRIB_DIR}/rocksdb" + DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" + SOURCE_DIR "${TD_CONTRIB_DIR}/rocksdb" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/docs/en/07-develop/03-insert-data/01-sql-writing.mdx b/docs/en/07-develop/03-insert-data/01-sql-writing.mdx index 3731882fb2..4d1b67e451 100644 --- a/docs/en/07-develop/03-insert-data/01-sql-writing.mdx +++ b/docs/en/07-develop/03-insert-data/01-sql-writing.mdx @@ -33,7 +33,7 @@ The below SQL statement is used to insert one row into table "d1001". INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31); ``` -`ts1` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detial, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). +`ts1` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detail, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). ### Insert Multiple Rows @@ -43,7 +43,7 @@ Multiple rows can be inserted in a single SQL statement. The example below inser INSERT INTO d1001 VALUES (ts2, 10.2, 220, 0.23) (ts2, 10.3, 218, 0.25); ``` -`ts1` and `ts2` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detial, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). +`ts1` and `ts2` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detail, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). ### Insert into Multiple Tables @@ -53,7 +53,7 @@ Data can be inserted into multiple tables in the same SQL statement. The example INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31) (ts2, 12.6, 218, 0.33) d1002 VALUES (ts3, 12.3, 221, 0.31); ``` -`ts1`, `ts2` and `ts3` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detial, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). +`ts1`, `ts2` and `ts3` is Unix timestamp, the timestamps which is larger than the difference between current time and KEEP in config is only allowed. For further detail, refer to [TDengine SQL insert timestamp section](/taos-sql/insert). For more details about `INSERT` please refer to [INSERT](/taos-sql/insert). diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx index 578f38e73d..f5e0378a00 100644 --- a/docs/en/07-develop/07-tmq.mdx +++ b/docs/en/07-develop/07-tmq.mdx @@ -244,6 +244,8 @@ The following SQL statement creates a topic in TDengine: CREATE TOPIC topic_name AS SELECT ts, c1, c2, c3 FROM tmqdb.stb WHERE c1 > 1; ``` +- There is an upper limit to the number of topics created, controlled by the parameter tmqMaxTopicNum, with a default of 20 + Multiple subscription types are supported. #### Subscribe to a Column @@ -265,14 +267,15 @@ You can subscribe to a topic through a SELECT statement. Statements that specify Syntax: ```sql -CREATE TOPIC topic_name AS STABLE stb_name +CREATE TOPIC topic_name [with meta] AS STABLE stb_name [where_condition] ``` Creating a topic in this manner differs from a `SELECT * from stbName` statement as follows: - The table schema can be modified. - Unstructured data is returned. The format of the data returned changes based on the supertable schema. -- A different table schema may exist for every data block to be processed. +- The 'with meta' parameter is optional. When selected, statements such as creating super tables and sub tables will be returned, mainly used for Taosx to perform super table migration +- The 'where_condition' parameter is optional and will be used to filter and subscribe to sub tables that meet the criteria. Where conditions cannot have ordinary columns, only tags or tbnames. Functions can be used in where conditions to filter tags, but cannot be aggregate functions because sub table tag values cannot be aggregated. It can also be a constant expression, such as 2>1 (subscribing to all child tables), Or false (subscribe to 0 sub tables) - The data returned does not include tags. ### Subscribe to a Database @@ -280,10 +283,12 @@ Creating a topic in this manner differs from a `SELECT * from stbName` statement Syntax: ```sql -CREATE TOPIC topic_name [WITH META] AS DATABASE db_name; +CREATE TOPIC topic_name [with meta] AS DATABASE db_name; ``` -This SQL statement creates a subscription to all tables in the database. You can add the `WITH META` parameter to include schema changes in the subscription, including creating and deleting supertables; adding, deleting, and modifying columns; and creating, deleting, and modifying the tags of subtables. Consumers can determine the message type from the API. Note that this differs from Kafka. +This SQL statement creates a subscription to all tables in the database. + +- The 'with meta' parameter is optional. When selected, it will return statements for creating all super tables and sub tables in the database, mainly used for Taosx database migration ## Create a Consumer @@ -295,7 +300,7 @@ You configure the following parameters when creating a consumer: | `td.connect.user` | string | User Name | | | `td.connect.pass` | string | Password | | | `td.connect.port` | string | Port of the server side | | -| `group.id` | string | Consumer group ID; consumers with the same ID are in the same group | **Required**. Maximum length: 192. | +| `group.id` | string | Consumer group ID; consumers with the same ID are in the same group | **Required**. Maximum length: 192. Each topic can create up to 100 consumer groups. | | `client.id` | string | Client ID | Maximum length: 192. | | `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 | diff --git a/docs/en/07-develop/09-udf.md b/docs/en/07-develop/09-udf.md index 825d3c6f8b..5137e35c0a 100644 --- a/docs/en/07-develop/09-udf.md +++ b/docs/en/07-develop/09-udf.md @@ -17,7 +17,7 @@ When you create a user-defined function, you must implement standard interface f - For aggregate functions, implement the `aggfn_start`, `aggfn`, and `aggfn_finish` interface functions. - To initialize your function, implement the `udf_init` function. To terminate your function, implement the `udf_destroy` function. -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. +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 in C The implementation of a scalar function is described as follows: @@ -318,7 +318,7 @@ The implementation of a scalar UDF is described as follows: def process(input: datablock) -> tuple[output_type]: ``` -Description: this function prcesses datablock, which is the input; you can use datablock.data(row, col) to access the python object at location(row,col); the output is a tuple object consisted of objects of type outputtype +Description: this function processes datablock, which is the input; you can use datablock.data(row, col) to access the python object at location(row,col); the output is a tuple object consisted of objects of type outputtype #### Aggregate UDF Interface @@ -356,7 +356,7 @@ def process(input: datablock) -> tuple[output_type]: # return tuple object consisted of object of type outputtype ``` -Note:process() must be implemeted, init() and destroy() must be defined too but they can do nothing. +Note:process() must be implemented, init() and destroy() must be defined too but they can do nothing. #### Aggregate Template @@ -377,7 +377,7 @@ def finish(buf: bytes) -> output_type: #return obj of type outputtype ``` -Note: aggregate UDF requires init(), destroy(), start(), reduce() and finish() to be impemented. start() generates the initial result in buffer, then the input data is divided into multiple row data blocks, reduce() is invoked for each data block `inputs` and intermediate `buf`, finally finish() is invoked to generate final result from the intermediate result `buf`. +Note: aggregate UDF requires init(), destroy(), start(), reduce() and finish() to be implemented. start() generates the initial result in buffer, then the input data is divided into multiple row data blocks, reduce() is invoked for each data block `inputs` and intermediate `buf`, finally finish() is invoked to generate final result from the intermediate result `buf`. ### Data Mapping between TDengine SQL and Python UDF @@ -559,7 +559,7 @@ Note: Prior to TDengine 3.0.5.0 (excluding), updating a UDF requires to restart #### Sample 3: UDF with n arguments -A UDF which accepts n intergers, likee (x1, x2, ..., xn) and output the sum of the product of each value and its sequence number: 1 * x1 + 2 * x2 + ... + n * xn. If there is `null` in the input, then the result is `null`. The difference from sample 1 is that it can accept any number of columns as input and process each column. Assume the program is written in /root/udf/nsum.py: +A UDF which accepts n integers, likee (x1, x2, ..., xn) and output the sum of the product of each value and its sequence number: 1 * x1 + 2 * x2 + ... + n * xn. If there is `null` in the input, then the result is `null`. The difference from sample 1 is that it can accept any number of columns as input and process each column. Assume the program is written in /root/udf/nsum.py: ```python def init(): @@ -607,7 +607,7 @@ Query OK, 4 row(s) in set (0.010653s) #### Sample 4: Utilize 3rd party package -A UDF which accepts a timestamp and output the next closed Sunday. This sample requires to use third party package `moment`, you need to install it firslty. +A UDF which accepts a timestamp and output the next closed Sunday. This sample requires to use third party package `moment`, you need to install it firstly. ```shell pip3 install moment @@ -701,7 +701,7 @@ Query OK, 4 row(s) in set (1.011474s) #### Sample 5: Aggregate Function -An aggregate function which calculates the difference of the maximum and the minimum in a column. An aggregate funnction takes multiple rows as input and output only one data. The execution process of an aggregate UDF is like map-reduce, the framework divides the input into multiple parts, each mapper processes one block and the reducer aggregates the result of the mappers. The reduce() of Python UDF has the functionality of both map() and reduce(). The reduce() takes two arguments: the data to be processed; and the result of other tasks executing reduce(). For exmaple, assume the code is in `/root/udf/myspread.py`. +An aggregate function which calculates the difference of the maximum and the minimum in a column. An aggregate funnction takes multiple rows as input and output only one data. The execution process of an aggregate UDF is like map-reduce, the framework divides the input into multiple parts, each mapper processes one block and the reducer aggregates the result of the mappers. The reduce() of Python UDF has the functionality of both map() and reduce(). The reduce() takes two arguments: the data to be processed; and the result of other tasks executing reduce(). For example, assume the code is in `/root/udf/myspread.py`. ```python import io @@ -755,7 +755,7 @@ In this example, we implemented an aggregate function, and added some logging. 2. log() is the function for logging, it converts the input object to string and output with an end of line 3. destroy() closes the log file \ 4. start() returns the initial buffer for storing the intermediate result -5. reduce() processes each daa block and aggregates the result +5. reduce() processes each data block and aggregates the result 6. finish() converts the final buffer() to final result\ Create the UDF. diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index b517bcb3cc..afc1581c22 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -672,7 +672,7 @@ If you input a specific column, the number of non-null values in the column is r ELAPSED(ts_primary_key [, time_unit]) ``` -**Description**: `elapsed` function can be used to calculate the continuous time length in which there is valid data. If it's used with `INTERVAL` clause, the returned result is the calculated time length within each time window. If it's used without `INTERVAL` caluse, the returned result is the calculated time length within the specified time range. Please be noted that the return value of `elapsed` is the number of `time_unit` in the calculated time length. +**Description**: `elapsed` function can be used to calculate the continuous time length in which there is valid data. If it's used with `INTERVAL` clause, the returned result is the calculated time length within each time window. If it's used without `INTERVAL` clause, the returned result is the calculated time length within the specified time range. Please be noted that the return value of `elapsed` is the number of `time_unit` in the calculated time length. **Return value type**: Double if the input value is not NULL; @@ -999,18 +999,14 @@ SAMPLE(expr, k) **Description**: _k_ sampling values of a specific column. The applicable range of _k_ is [1,1000]. -**Return value type**: Same as the column being operated plus the associated timestamp +**Return value type**: Same as the column being operated -**Applicable data types**: Any data type except for tags of STable +**Applicable data types**: Any data type **Applicable nested query**: Inner query and Outer query **Applicable table types**: standard tables and supertables -**More explanations**: - -- This function cannot be used in expression calculation. - ### TAIL @@ -1055,11 +1051,11 @@ TOP(expr, k) UNIQUE(expr) ``` -**Description**: The values that occur the first time in the specified column. The effect is similar to `distinct` keyword, but it can also be used to match tags or timestamp. The first occurrence of a timestamp or tag is used. +**Description**: The values that occur the first time in the specified column. The effect is similar to `distinct` keyword. **Return value type**:Same as the data type of the column being operated upon -**Applicable column types**: Any data types except for timestamp +**Applicable column types**: Any data types **Applicable table types**: table, STable diff --git a/docs/en/12-taos-sql/12-distinguished.md b/docs/en/12-taos-sql/12-distinguished.md index b082f7b888..7f0b8c7769 100644 --- a/docs/en/12-taos-sql/12-distinguished.md +++ b/docs/en/12-taos-sql/12-distinguished.md @@ -21,7 +21,7 @@ part_list can be any scalar expression, such as a column, constant, scalar funct A PARTITION BY clause is processed as follows: - The PARTITION BY clause must occur after the WHERE clause -- The PARTITION BY caluse partitions the data according to the specified dimensions, then perform computation on each partition. The performed computation is determined by the rest of the statement - a window clause, GROUP BY clause, or SELECT clause. +- The PARTITION BY clause partitions the data according to the specified dimensions, then perform computation on each partition. The performed computation is determined by the rest of the statement - a window clause, GROUP BY clause, or SELECT clause. - The PARTITION BY clause can be used together with a window clause or GROUP BY clause. In this case, the window or GROUP BY clause takes effect on every partition. For example, the following statement partitions the table by the location tag, performs downsampling over a 10 minute window, and returns the maximum value: ```sql diff --git a/docs/en/12-taos-sql/24-show.md b/docs/en/12-taos-sql/24-show.md index eb70a7664b..bd4a60b20e 100644 --- a/docs/en/12-taos-sql/24-show.md +++ b/docs/en/12-taos-sql/24-show.md @@ -36,7 +36,7 @@ Shows information about connections to the system. SHOW CONSUMERS; ``` -Shows information about all active consumers in the system. +Shows information about all consumers in the system. ## SHOW CREATE DATABASE diff --git a/docs/en/14-reference/03-connector/04-java.mdx b/docs/en/14-reference/03-connector/04-java.mdx index ebd2891a9e..e8c407b125 100644 --- a/docs/en/14-reference/03-connector/04-java.mdx +++ b/docs/en/14-reference/03-connector/04-java.mdx @@ -36,7 +36,8 @@ REST connection supports all platforms that can run Java. | taos-jdbcdriver version | major changes | TDengine version | | :---------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------: | -| 3.2.1 | subscription add seek function | 3.0.5.0 or later | +| 3.2.3 | Fixed resultSet data parsing failure in some cases | 3.0.5.0 or later | +| 3.2.2 | subscription add seek function | 3.0.5.0 or later | | 3.2.1 | JDBC REST connection supports schemaless/prepareStatement over WebSocket | 3.0.3.0 or later | | 3.2.0 | This version has been deprecated | - | | 3.1.0 | JDBC REST connection supports subscription over WebSocket | - | @@ -284,9 +285,9 @@ The configuration parameters in the URL are as follows: - batchfetch: true: pulls result sets in batches when executing queries; false: pulls result sets row by row. The default value is: false. batchfetch uses HTTP for data transfer. JDBC REST supports batch pulls. taos-jdbcdriver and TDengine transfer data via WebSocket connection. Compared with HTTP, WebSocket enables JDBC REST connection to support large data volume querying and improve query performance. - charset: specify the charset to parse the string, this parameter is valid only when set batchfetch to true. - batchErrorIgnore: true: when executing executeBatch of Statement, if one SQL execution fails in the middle, continue to execute the following SQL. false: no longer execute any statement after the failed SQL. The default value is: false. -- httpConnectTimeout: REST connection timeout in milliseconds, the default value is 5000 ms. -- httpSocketTimeout: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when batchfetch is false. -- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when batchfetch is true. +- httpConnectTimeout: REST connection timeout in milliseconds, the default value is 60000 ms. +- httpSocketTimeout: socket timeout in milliseconds, the default value is 60000 ms. It only takes effect when batchfetch is false. +- messageWaitTimeout: message transmission timeout in milliseconds, the default value is 60000 ms. It only takes effect when batchfetch is true. - useSSL: connecting Securely Using SSL. true: using SSL connection, false: not using SSL connection. - httpPoolSize: size of REST concurrent requests. The default value is 20. @@ -352,9 +353,9 @@ The configuration parameters in properties are as follows. - TSDBDriver.PROPERTY_KEY_CHARSET: In the character set used by the client, the default value is the system character set. - TSDBDriver.PROPERTY_KEY_LOCALE: this only takes effect when using JDBC native connection. Client language environment, the default value is system current locale. - TSDBDriver.PROPERTY_KEY_TIME_ZONE: only takes effect when using JDBC native connection. In the time zone used by the client, the default value is the system's current time zone. -- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection. -- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 5000 ms. It only takes effect when using JDBC REST connection and batchfetch is false. -- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 3000 ms. It only takes effect when using JDBC REST connection and batchfetch is true. +- TSDBDriver.HTTP_CONNECT_TIMEOUT: REST connection timeout in milliseconds, the default value is 60000 ms. It only takes effect when using JDBC REST connection. +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket timeout in milliseconds, the default value is 60000 ms. It only takes effect when using JDBC REST connection and batchfetch is false. +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: message transmission timeout in milliseconds, the default value is 60000 ms. It only takes effect when using JDBC REST connection and batchfetch is true. - TSDBDriver.PROPERTY_KEY_USE_SSL: connecting Securely Using SSL. true: using SSL connection, false: not using SSL connection. It only takes effect when using JDBC REST connection. - TSDBDriver.HTTP_POOL_SIZE: size of REST concurrent requests. The default value is 20. For JDBC native connections, you can specify other parameters, such as log level, SQL length, etc., by specifying URL and Properties. For more detailed configuration, please refer to [Client Configuration](/reference/config/#Client-Only). diff --git a/docs/en/14-reference/03-connector/05-go.mdx b/docs/en/14-reference/03-connector/05-go.mdx index 06d643c6c8..b3d4857d75 100644 --- a/docs/en/14-reference/03-connector/05-go.mdx +++ b/docs/en/14-reference/03-connector/05-go.mdx @@ -31,63 +31,78 @@ REST connections are supported on all platforms that can run Go. Please refer to [version support list](https://github.com/taosdata/driver-go#remind) -## Supported features +## Handling exceptions -### Native connections +If it is a TDengine error, you can get the error code and error information in the following ways. +```go +// import "github.com/taosdata/driver-go/v3/errors" + if err != nil { + tError, is := err.(*errors.TaosError) + if is { + fmt.Println("errorCode:", int(tError.Code)) + fmt.Println("errorMessage:", tError.ErrStr) + } else { + fmt.Println(err.Error()) + } + } +``` -A "native connection" is established by the connector directly to the TDengine instance via the TDengine client driver (taosc). The supported functional features are: +## TDengine DataType vs. Go DataType -* Normal queries -* Continuous queries -* Subscriptions -* Schemaless interface -* Parameter binding interface +| TDengine DataType | Go Type | +|-------------------|-----------| +| TIMESTAMP | time.Time | +| TINYINT | int8 | +| SMALLINT | int16 | +| INT | int32 | +| BIGINT | int64 | +| TINYINT UNSIGNED | uint8 | +| SMALLINT UNSIGNED | uint16 | +| INT UNSIGNED | uint32 | +| BIGINT UNSIGNED | uint64 | +| FLOAT | float32 | +| DOUBLE | float64 | +| BOOL | bool | +| BINARY | string | +| NCHAR | string | +| JSON | []byte | -### REST connection - -A "REST connection" is a connection between the application and the TDengine instance via the REST API provided by the taosAdapter component. The following features are supported: - -* Normal queries -* Continuous queries +**Note**: Only TAG supports JSON types ## Installation Steps ### Pre-installation preparation * Install Go development environment (Go 1.14 and above, GCC 4.8.5 and above) -- If you use the native connector, please install the TDengine client driver. Please refer to [Install Client Driver](/reference/connector/#install-client-driver) for specific steps +* If you use the native connector, please install the TDengine client driver. Please refer to [Install Client Driver](/reference/connector/#install-client-driver) for specific steps Configure the environment variables and check the command. * ```go env``` * ```gcc -v``` -### Use go get to install - -`go get -u github.com/taosdata/driver-go/v3@latest` - -### Manage with go mod +### Install the connectors 1. Initialize the project with the `go mod` command. - ```text - go mod init taos-demo - ``` + ```text + go mod init taos-demo + ``` 2. Introduce taosSql - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v3/taosSql" - ) - ``` + ```go + import ( + "database/sql" + _ "github.com/taosdata/driver-go/v3/taosSql" + ) + ``` 3. Update the dependency packages with `go mod tidy`. - ```text - go mod tidy - ``` + ```text + go mod tidy + ``` 4. Run the program with `go run taos-demo` or compile the binary with the `go build` command. @@ -98,8 +113,6 @@ Configure the environment variables and check the command. ## Establishing a connection -### Data source name (DSN) - Data source names have a standard format, e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php), but no type prefix (square brackets indicate optionally): ``` text @@ -111,9 +124,7 @@ DSN in full form. ```text username:password@protocol(address)/dbname?param=value ``` -### Connecting via connector - - + _taosSql_ implements Go's `database/sql/driver` interface via cgo. You can use the [`database/sql`](https://golang.org/pkg/database/sql/) interface by simply introducing the driver. @@ -209,42 +220,165 @@ func main() { +### Specify the URL and Properties to get the connection + +The Go connector does not support this feature + +### Priority of configuration parameters + +The Go connector does not support this feature + ## Usage examples -### Write data +### Create database and tables -#### SQL Write +```go +var taosDSN = "root:taosdata@tcp(localhost:6030)/" +taos, err := sql.Open("taosSql", taosDSN) +if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) +} +defer taos.Close() +_, err := taos.Exec("CREATE DATABASE power") +if err != nil { + log.Fatalln("failed to create database, err:", err) +} +_, err = taos.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)") +if err != nil { + log.Fatalln("failed to create stable, err:", err) +} +``` + +### Insert data -#### InfluxDB line protocol write - - - -#### OpenTSDB Telnet line protocol write - - - -#### OpenTSDB JSON line protocol write - - - -### Query data +### Querying data -### More sample programs +### execute SQL with reqId -* [sample program](https://github.com/taosdata/driver-go/tree/3.0/examples) +This reqId can be used to request link tracing. +```go +db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") +if err != nil { + panic(err) +} +defer db.Close() +ctx := context.WithValue(context.Background(), common.ReqIDKey, common.GetReqID()) +_, err = db.ExecContext(ctx, "create database if not exists example_taos_sql") +if err != nil { + panic(err) +} +``` -## Usage limitations +### Writing data via parameter binding -Since the REST interface is stateless, the `use db` syntax will not work. You need to put the db name into the SQL command, e.g. `create table if not exists tb1 (ts timestamp, a int)` to `create table if not exists test.tb1 (ts timestamp, a int)` otherwise it will report the error `[0x217] Database not specified or available`. + + -You can also put the db name in the DSN by changing `root:taosdata@http(localhost:6041)/` to `root:taosdata@http(localhost:6041)/test`. Executing the `create database` statement when the specified db does not exist will not report an error while executing other queries or writing against that db will report an error. +```go +package main -The complete example is as follows. +import ( + "time" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" +) + +func main() { + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_stmt") + if err != nil { + panic(err) + } + _, err = db.Exec("create table if not exists example_stmt.tb1(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")") + if err != nil { + panic(err) + } + stmt := db.InsertStmt() + err = stmt.Prepare("insert into example_stmt.tb1 values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + if err != nil { + panic(err) + } + now := time.Now() + params := make([]*param.Param, 14) + params[0] = param.NewParam(2). + AddTimestamp(now, common.PrecisionMilliSecond). + AddTimestamp(now.Add(time.Second), common.PrecisionMilliSecond) + params[1] = param.NewParam(2).AddBool(true).AddNull() + params[2] = param.NewParam(2).AddTinyint(2).AddNull() + params[3] = param.NewParam(2).AddSmallint(3).AddNull() + params[4] = param.NewParam(2).AddInt(4).AddNull() + params[5] = param.NewParam(2).AddBigint(5).AddNull() + params[6] = param.NewParam(2).AddUTinyint(6).AddNull() + params[7] = param.NewParam(2).AddUSmallint(7).AddNull() + params[8] = param.NewParam(2).AddUInt(8).AddNull() + params[9] = param.NewParam(2).AddUBigint(9).AddNull() + params[10] = param.NewParam(2).AddFloat(10).AddNull() + params[11] = param.NewParam(2).AddDouble(11).AddNull() + params[12] = param.NewParam(2).AddBinary([]byte("binary")).AddNull() + params[13] = param.NewParam(2).AddNchar("nchar").AddNull() + + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(6). + AddNchar(5) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Execute() + if err != nil { + panic(err) + } + err = stmt.Close() + if err != nil { + panic(err) + } + // select * from example_stmt.tb1 +} +``` + + + ```go package main @@ -254,295 +388,734 @@ import ( "fmt" "time" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/stmt" ) func main() { - var taosDSN = "root:taosdata@http(localhost:6041)/test" - taos, err := sql.Open("taosRestful", taosDSN) + db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/") if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } - defer taos.Close() - taos.Exec("create database if not exists test") - taos.Exec("create table if not exists tb1 (ts timestamp, a int)") - _, err = taos.Exec("insert into tb1 values(now, 0)(now+1s,1)(now+2s,2)(now+3s,3)") - if err != nil { - fmt.Println("failed to insert, err:", err) - return - } - rows, err := taos.Query("select * from tb1") - if err != nil { - fmt.Println("failed to select from table, err:", err) - return + panic(err) } + defer db.Close() + prepareEnv(db) - defer rows.Close() - for rows.Next() { - var r struct { - ts time.Time - a int - } - err := rows.Scan(&r.ts, &r.a) + config := stmt.NewConfig("ws://127.0.0.1:6041/rest/stmt", 0) + config.SetConnectUser("root") + config.SetConnectPass("taosdata") + config.SetConnectDB("example_ws_stmt") + config.SetMessageTimeout(common.DefaultMessageTimeout) + config.SetWriteWait(common.DefaultWriteWait) + config.SetErrorHandler(func(connector *stmt.Connector, err error) { + panic(err) + }) + config.SetCloseHandler(func() { + fmt.Println("stmt connector closed") + }) + + connector, err := stmt.NewConnector(config) + if err != nil { + panic(err) + } + now := time.Now() + { + stmt, err := connector.Init() if err != nil { - fmt.Println("scan error:\n", err) - return + panic(err) } - fmt.Println(r.ts, r.a) + err = stmt.Prepare("insert into ? using all_json tags(?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + if err != nil { + panic(err) + } + err = stmt.SetTableName("tb1") + if err != nil { + panic(err) + } + err = stmt.SetTags(param.NewParam(1).AddJson([]byte(`{"tb":1}`)), param.NewColumnType(1).AddJson(0)) + if err != nil { + panic(err) + } + params := []*param.Param{ + param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0), + param.NewParam(3).AddBool(true).AddNull().AddBool(true), + param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1), + param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1), + param.NewParam(3).AddInt(1).AddNull().AddInt(1), + param.NewParam(3).AddBigint(1).AddNull().AddBigint(1), + param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1), + param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1), + param.NewParam(3).AddUInt(1).AddNull().AddUInt(1), + param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1), + param.NewParam(3).AddFloat(1).AddNull().AddFloat(1), + param.NewParam(3).AddDouble(1).AddNull().AddDouble(1), + param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")), + param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"), + } + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Exec() + if err != nil { + panic(err) + } + affected := stmt.GetAffectedRows() + fmt.Println("all_json affected rows:", affected) + err = stmt.Close() + if err != nil { + panic(err) + } + } + { + stmt, err := connector.Init() + if err != nil { + panic(err) + } + err = stmt.Prepare("insert into ? using all_all tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + err = stmt.SetTableName("tb1") + if err != nil { + panic(err) + } + + err = stmt.SetTableName("tb2") + if err != nil { + panic(err) + } + err = stmt.SetTags( + param.NewParam(14). + AddTimestamp(now, 0). + AddBool(true). + AddTinyint(2). + AddSmallint(2). + AddInt(2). + AddBigint(2). + AddUTinyint(2). + AddUSmallint(2). + AddUInt(2). + AddUBigint(2). + AddFloat(2). + AddDouble(2). + AddBinary([]byte("tb2")). + AddNchar("tb2"), + param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0), + ) + if err != nil { + panic(err) + } + params := []*param.Param{ + param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0), + param.NewParam(3).AddBool(true).AddNull().AddBool(true), + param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1), + param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1), + param.NewParam(3).AddInt(1).AddNull().AddInt(1), + param.NewParam(3).AddBigint(1).AddNull().AddBigint(1), + param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1), + param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1), + param.NewParam(3).AddUInt(1).AddNull().AddUInt(1), + param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1), + param.NewParam(3).AddFloat(1).AddNull().AddFloat(1), + param.NewParam(3).AddDouble(1).AddNull().AddDouble(1), + param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")), + param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"), + } + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Exec() + if err != nil { + panic(err) + } + affected := stmt.GetAffectedRows() + fmt.Println("all_all affected rows:", affected) + err = stmt.Close() + if err != nil { + panic(err) + } + + } +} + +func prepareEnv(db *sql.DB) { + steps := []string{ + "create database example_ws_stmt", + "create table example_ws_stmt.all_json(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")" + + "tags(t json)", + "create table example_ws_stmt.all_all(" + + "ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")" + + "tags(" + + "tts timestamp," + + "tc1 bool," + + "tc2 tinyint," + + "tc3 smallint," + + "tc4 int," + + "tc5 bigint," + + "tc6 tinyint unsigned," + + "tc7 smallint unsigned," + + "tc8 int unsigned," + + "tc9 bigint unsigned," + + "tc10 float," + + "tc11 double," + + "tc12 binary(20)," + + "tc13 nchar(20))", + } + for _, step := range steps { + _, err := db.Exec(step) + if err != nil { + panic(err) + } + } +} + +``` + + + + + +### Schemaless Writing + + + + +```go +import ( + "fmt" + + "github.com/taosdata/driver-go/v3/af" +) + +func main() { + conn, err := af.Open("localhost", "root", "taosdata", "", 6030) + if err != nil { + fmt.Println("fail to connect, err:", err) + } + defer conn.Close() + _, err = conn.Exec("create database if not exists example") + if err != nil { + panic(err) + } + _, err = conn.Exec("use example") + if err != nil { + panic(err) + } + influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000" + err = conn.InfluxDBInsertLines([]string{influxdbData}, "ns") + if err != nil { + panic(err) + } + telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0" + err = conn.OpenTSDBInsertTelnetLines([]string{telnetData}) + if err != nil { + panic(err) + } + jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + err = conn.OpenTSDBInsertJsonPayload(jsonData) + if err != nil { + panic(err) + } +} +``` + + + + +```go +import ( + "database/sql" + "log" + "time" + + "github.com/taosdata/driver-go/v3/common" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/schemaless" +) + +func main() { + db, err := sql.Open("taosWS", "root:taosdata@ws(localhost:6041)/") + if err != nil { + log.Fatal(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists schemaless_ws") + if err != nil { + log.Fatal(err) + } + s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041/rest/schemaless", 1, + schemaless.SetDb("schemaless_ws"), + schemaless.SetReadTimeout(10*time.Second), + schemaless.SetWriteTimeout(10*time.Second), + schemaless.SetUser("root"), + schemaless.SetPassword("taosdata"), + schemaless.SetErrorHandler(func(err error) { + log.Fatal(err) + }), + )) + if err != nil { + panic(err) + } + influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000" + telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0" + jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + err = s.Insert(influxdbData, schemaless.InfluxDBLineProtocol, "ns", 0, common.GetReqID()) + if err != nil { + panic(err) + } + err = s.Insert(telnetData, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + err = s.Insert(jsonData, schemaless.OpenTSDBJsonFormatProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) } } ``` + + + + +### Schemaless with reqId + +```go +func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error +``` + +You can get the unique id by `common.GetReqID()`. + +### Data Subscription + +The TDengine Go Connector supports subscription functionality with the following application API. + +#### Create a Topic + +```go + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq") + if err != nil { + panic(err) + } +``` + +#### Create a Consumer + +```go + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "group.id": "test", + "auto.offset.reset": "earliest", + "td.connect.ip": "127.0.0.1", + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "td.connect.port": "6030", + "client.id": "test_tmq_client", + "enable.auto.commit": "false", + "msg.with.table.name": "true", + }) + if err != nil { + panic(err) + } +``` + +#### Subscribe to consume data + +```go + err = consumer.Subscribe("example_tmq_topic", nil) + if err != nil { + panic(err) + } + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } +``` + +#### Assignment subscription Offset + +```go + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } +``` + +#### Close subscriptions + +```go + err = consumer.Close() + if err != nil { + panic(err) + } +``` + +#### Full Sample Code + + + + +```go +package main + +import ( + "fmt" + "os" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/af/tmq" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" +) + +func main() { + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq") + if err != nil { + panic(err) + } + if err != nil { + panic(err) + } + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "group.id": "test", + "auto.offset.reset": "earliest", + "td.connect.ip": "127.0.0.1", + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "td.connect.port": "6030", + "client.id": "test_tmq_client", + "enable.auto.commit": "false", + "msg.with.table.name": "true", + }) + if err != nil { + panic(err) + } + err = consumer.Subscribe("example_tmq_topic", nil) + if err != nil { + panic(err) + } + _, err = db.Exec("create table example_tmq.t1 (ts timestamp,v int)") + if err != nil { + panic(err) + } + _, err = db.Exec("insert into example_tmq.t1 values(now,1)") + if err != nil { + panic(err) + } + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + + partitions, err = consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + } + + err = consumer.Close() + if err != nil { + panic(err) + } +} +``` + + + + +```go +package main + +import ( + "database/sql" + "fmt" + + "github.com/taosdata/driver-go/v3/common" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/tmq" +) + +func main() { + db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/") + if err != nil { + panic(err) + } + defer db.Close() + prepareEnv(db) + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "ws.url": "ws://127.0.0.1:6041/rest/tmq", + "ws.message.channelLen": uint(0), + "ws.message.timeout": common.DefaultMessageTimeout, + "ws.message.writeWait": common.DefaultWriteWait, + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "group.id": "example", + "client.id": "example_consumer", + "auto.offset.reset": "earliest", + }) + if err != nil { + panic(err) + } + err = consumer.Subscribe("example_ws_tmq_topic", nil) + if err != nil { + panic(err) + } + go func() { + _, err := db.Exec("create table example_ws_tmq.t_all(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")") + if err != nil { + panic(err) + } + _, err = db.Exec("insert into example_ws_tmq.t_all values(now,true,2,3,4,5,6,7,8,9,10.123,11.123,'binary','nchar')") + if err != nil { + panic(err) + } + }() + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + + partitions, err = consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + } + + err = consumer.Close() + if err != nil { + panic(err) + } +} + +func prepareEnv(db *sql.DB) { + _, err := db.Exec("create database example_ws_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic example_ws_tmq_topic as database example_ws_tmq") + if err != nil { + panic(err) + } +} +``` + + + + +### More sample programs + +* [sample program](https://github.com/taosdata/driver-go/tree/3.0/examples) + + ## Frequently Asked Questions 1. bind interface in database/sql crashes - REST does not support parameter binding related interface. It is recommended to use `db.Exec` and `db.Query`. + REST does not support parameter binding related interface. It is recommended to use `db.Exec` and `db.Query`. 2. error `[0x217] Database not specified or available` after executing other statements with `use db` statement - The execution of SQL command in the REST interface is not contextual, so using `use db` statement will not work, see the usage restrictions section above. + The execution of SQL command in the REST interface is not contextual, so using `use db` statement will not work, see the usage restrictions section above. 3. use `taosSql` without error but use `taosRestful` with error `[0x217] Database not specified or available` - Because the REST interface is stateless, using the `use db` statement will not take effect. See the usage restrictions section above. + Because the REST interface is stateless, using the `use db` statement will not take effect. See the usage restrictions section above. 4. `readBufferSize` parameter has no significant effect after being increased - Increasing `readBufferSize` will reduce the number of `syscall` calls when fetching results. If the query result is smaller, modifying this parameter will not improve performance significantly. If you increase the parameter value too much, the bottleneck will be parsing JSON data. If you need to optimize the query speed, you must adjust the value based on the actual situation to achieve the best query performance. + Increasing `readBufferSize` will reduce the number of `syscall` calls when fetching results. If the query result is smaller, modifying this parameter will not improve performance significantly. If you increase the parameter value too much, the bottleneck will be parsing JSON data. If you need to optimize the query speed, you must adjust the value based on the actual situation to achieve the best query performance. 5. `disableCompression` parameter is set to `false` when the query efficiency is reduced - When set `disableCompression` parameter to `false`, the query result will be compressed by `gzip` and then transmitted, so you have to decompress the data by `gzip` after getting it. + When set `disableCompression` parameter to `false`, the query result will be compressed by `gzip` and then transmitted, so you have to decompress the data by `gzip` after getting it. 6. `go get` command can't get the package, or timeout to get the package - Set Go proxy `go env -w GOPROXY=https://goproxy.cn,direct`. - -## Common APIs - -### database/sql API - -* `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` - - Use This API to open a DB, returning an object of type \*DB. - -:::info -This API is created successfully without checking permissions, but only when you execute a Query or Exec, and check if user/password/host/port is legal. -::: - -* `func (db *DB) Exec(query string, args ...interface{}) (Result, error)` - - `sql.Open` built-in method to execute non-query related SQL. - -* `func (db *DB) Query(query string, args ...interface{}) (*Rows, error)` - - `sql.Open` Built-in method to execute query statements. - -### Advanced functions (af) API - -The `af` package encapsulates TDengine advanced functions such as connection management, subscriptions, schemaless, parameter binding, etc. - -#### Connection management - -* `af.Open(host, user, pass, db string, port int) (*Connector, error)` - - This API creates a connection to taosd via cgo. - -* `func (conn *Connector) Close() error` - - Closes the connection. - -#### Subscribe - -* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)` - -Creates consumer group. - -* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` -Note: `rebalanceCb` is reserved for compatibility purpose - -Subscribes a topic. - -* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error` -Note: `rebalanceCb` is reserved for compatibility purpose - -Subscribes to topics. - -* `func (c *Consumer) Poll(timeoutMs int) tmq.Event` - -Polling information. - -* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)` -Note: `tmq.TopicPartition` is reserved for compatibility purpose - -Commit information. - -* `func (c *Consumer) Assignment() (partitions []tmq.TopicPartition, err error)` - -Get Assignment(TDengine >= 3.0.5.0 and driver-go >= v3.5.0 are required). - -* `func (c *Consumer) Seek(partition tmq.TopicPartition, ignoredTimeoutMs int) error` -Note: `ignoredTimeoutMs` is reserved for compatibility purpose - -Seek offset(TDengine >= 3.0.5.0 and driver-go >= v3.5.0 are required). - -* `func (c *Consumer) Unsubscribe() error` - -Unsubscribe. - -* `func (c *Consumer) Close() error` - -Close consumer. - -#### schemaless - -* `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` - - Write to InfluxDB line protocol. - -* `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` - - Write OpenTDSB telnet protocol data. - -* `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` - - Writes OpenTSDB JSON protocol data. - -#### parameter binding - -* `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` - - Parameter bound single row insert. - -* `func (conn *Connector) InsertStmt() *insertstmt.InsertStmt` - - Initialize the parameters. - -* `func (stmt *InsertStmt) Prepare(sql string) error` - - Parameter binding preprocessing SQL statement. - -* `func (stmt *InsertStmt) SetTableName(name string) error` - - Bind the table name parameter. - -* `func (stmt *InsertStmt) SetSubTableName(name string) error` - - Parameter binding to set the sub table name. - -* `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` - - Parameter bind multiple rows of data. - -* `func (stmt *InsertStmt) AddBatch() error` - - Add to a parameter-bound batch. - -* `func (stmt *InsertStmt) Execute() error` - - Execute a parameter binding. - -* `func (stmt *InsertStmt) GetAffectedRows() int` - - Gets the number of affected rows inserted by the parameter binding. - -* `func (stmt *InsertStmt) Close() error` - - Closes the parameter binding. - -### Subscribe via WebSocket - -* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)` - -Creates consumer group. - -* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` -Note: `rebalanceCb` is reserved for compatibility purpose - -Subscribes a topic. - -* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error` -Note: `rebalanceCb` is reserved for compatibility purpose - -Subscribes to topics. - -* `func (c *Consumer) Poll(timeoutMs int) tmq.Event` - -Polling information. - -* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)` -Note: `tmq.TopicPartition` is reserved for compatibility purpose - -Commit information. - -* `func (c *Consumer) Assignment() (partitions []tmq.TopicPartition, err error)` - -Get Assignment(TDengine >= 3.0.5.0 and driver-go >= v3.5.0 are required). - -* `func (c *Consumer) Seek(partition tmq.TopicPartition, ignoredTimeoutMs int) error` -Note: `ignoredTimeoutMs` is reserved for compatibility purpose - -Seek offset(TDengine >= 3.0.5.0 and driver-go >= v3.5.0 are required). - -* `func (c *Consumer) Unsubscribe() error` - -Unsubscribe. - -* `func (c *Consumer) Close() error` - -Close consumer. - -For a complete example see [GitHub sample file](https://github.com/taosdata/driver-go/blob/main/examples/tmqoverws/main.go) - -### parameter binding via WebSocket - -* `func NewConnector(config *Config) (*Connector, error)` - - Create a connection. - -* `func (c *Connector) Init() (*Stmt, error)` - - Initialize the parameters. - -* `func (c *Connector) Close() error` - - Close the connection. - -* `func (s *Stmt) Prepare(sql string) error` - - Parameter binding preprocessing SQL statement. - -* `func (s *Stmt) SetTableName(name string) error` - - Bind the table name parameter. - -* `func (s *Stmt) SetTags(tags *param.Param, bindType *param.ColumnType) error` - - Set tags. - -* `func (s *Stmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` - - Parameter bind multiple rows of data. - -* `func (s *Stmt) AddBatch() error` - - Add to a parameter-bound batch. - -* `func (s *Stmt) Exec() error` - - Execute a parameter binding. - -* `func (s *Stmt) GetAffectedRows() int` - - Gets the number of affected rows inserted by the parameter binding. - -* `func (s *Stmt) Close() error` - - Closes the parameter binding. - -For a complete example see [GitHub sample file](https://github.com/taosdata/driver-go/blob/main/examples/stmtoverws/main.go) + Set Go proxy `go env -w GOPROXY=https://goproxy.cn,direct`. ## API Reference diff --git a/docs/en/14-reference/03-connector/06-rust.mdx b/docs/en/14-reference/03-connector/06-rust.mdx index 344bd3590e..986b5cd104 100644 --- a/docs/en/14-reference/03-connector/06-rust.mdx +++ b/docs/en/14-reference/03-connector/06-rust.mdx @@ -31,21 +31,57 @@ Websocket connections are supported on all platforms that can run Go. | connector-rust version | TDengine version | major features | | :----------------: | :--------------: | :--------------------------------------------------: | -| v0.8.10 | 3.0.5.0 or later | TMQ: Get consuming progress and seek offset to consume. | +| v0.8.12 | 3.0.5.0 or later | TMQ: Get consuming progress and seek offset to consume. | | v0.8.0 | 3.0.4.0 | Support schemaless insert. | | v0.7.6 | 3.0.3.0 | Support req_id in query. | | v0.6.0 | 3.0.0.0 | Base features. | The Rust Connector is still under rapid development and is not guaranteed to be backward compatible before 1.0. We recommend using TDengine version 3.0 or higher to avoid known issues. -## Installation +## Handling exceptions + +After the error is reported, the specific information of the error can be obtained: + +```rust +match conn.exec(sql) { + Ok(_) => { + Ok(()) + } + Err(e) => { + eprintln!("ERROR: {:?}", e); + Err(e) + } +} +``` + +## TDengine DataType vs. Rust DataType + +TDengine currently supports timestamp, number, character, Boolean type, and the corresponding type conversion with Rust is as follows: + +| TDengine DataType | Rust DataType | +| ----------------- | ----------------- | +| TIMESTAMP | Timestamp | +| INT | i32 | +| BIGINT | i64 | +| FLOAT | f32 | +| DOUBLE | f64 | +| SMALLINT | i16 | +| TINYINT | i8 | +| BOOL | bool | +| BINARY | Vec | +| NCHAR | String | +| JSON | serde_json::Value | + +Note: Only TAG supports JSON types + +## Installation Steps ### Pre-installation preparation * Install the Rust development toolchain * If using the native connection, please install the TDengine client driver. Please refer to [install client driver](/reference/connector#install-client-driver) -### Add taos dependency +### Install the connectors Depending on the connection method, add the [taos][taos] dependency in your Rust project as follows: @@ -146,7 +182,8 @@ let builder = TaosBuilder::from_dsn("taos://localhost:6030")?; let conn1 = builder.build(); // use websocket protocol. -let conn2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?; +let builder2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?; +let conn2 = builder2.build(); ``` After the connection is established, you can perform operations on your database. @@ -228,41 +265,191 @@ There are two ways to query data: Using built-in types or the [serde](https://se ## Usage examples -### Write data +### Create database and tables -#### SQL Write +```rust +use taos::*; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let dsn = "taos://localhost:6030"; + let builder = TaosBuilder::from_dsn(dsn)?; + + let taos = builder.build()?; + + let db = "query"; + + // create database + taos.exec_many([ + format!("DROP DATABASE IF EXISTS `{db}`"), + format!("CREATE DATABASE `{db}`"), + format!("USE `{db}`"), + ]) + .await?; + + // create table + taos.exec_many([ + // create super table + "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ + TAGS (`groupid` INT, `location` BINARY(16))", + // create child table + "CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')", + ]).await?; +} +``` + +> 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. + +### Insert data -#### STMT Write - - - -#### Schemaless Write - - - ### Query data -## API Reference +### execute SQL with req_id -### Connector Constructor - -You create a connector constructor by using a DSN. +This req_id can be used to request link tracing. ```rust -let cfg = TaosBuilder::default().build()?; +let rs = taos.query_with_req_id("select * from stable where tag1 is null", 1)?; ``` -You use the builder object to create multiple connections. +### 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. + +Parameter binding details see [API Reference](#stmt-api) + + + +### 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). + + + +### Schemaless with req_id + +This req_id can be used to request link tracing. ```rust -let conn: Taos = cfg.build(); +let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .data(data) + .req_id(100u64) + .build()?; + +client.put(&sml_data)? ``` -### Connection pooling +### Data Subscription + +TDengine starts subscriptions through [TMQ](../../../taos-sql/tmq/). + +#### Create a Topic + +```rust +taos.exec_many([ + // create topic for subscription + format!("CREATE TOPIC tmq_meters with META AS DATABASE {db}") +]) +.await?; +``` + +#### Create a Consumer + +You create a TMQ connector by using a DSN. + +```rust +let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; +``` + +Create a consumer: + +```rust +let mut consumer = tmq.build()?; +``` + +#### Subscribe to consume data + +A single consumer can subscribe to one or more topics. + +```rust +consumer.subscribe(["tmq_meters"]).await?; +``` + +The TMQ is of [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) type. You can use the corresponding API to consume each message in the queue and then use `.commit` to mark them as consumed. + +```rust +{ + let mut stream = consumer.stream(); + + while let Some((offset, message)) = stream.try_next().await? { + // get information from offset + + // the topic + let topic = offset.topic(); + // the vgroup id, like partition id in kafka. + let vgroup_id = offset.vgroup_id(); + println!("* in vgroup id {vgroup_id} of topic {topic}\n"); + + if let Some(data) = message.into_data() { + while let Some(block) = data.fetch_raw_block().await? { + // one block for one table, get table name if needed + let name = block.table_name(); + let records: Vec = block.deserialize().try_collect()?; + println!( + "** table: {}, got {} records: {:#?}\n", + name.unwrap(), + records.len(), + records + ); + } + } + consumer.commit(offset).await?; + } +} +``` + +Get assignments: + +Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0 + +```rust +let assignments = consumer.assignments().await.unwrap(); +``` + +#### Assignment subscription Offset + +Seek offset: + +Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0 + +```rust +consumer.offset_seek(topic, vgroup_id, offset).await; +``` + +#### Close subscriptions + +```rust +consumer.unsubscribe().await; +``` + +The following parameters can be configured for the TMQ DSN. Only `group.id` is mandatory. + +- `group.id`: Within a consumer group, load balancing is implemented by consuming messages on an at-least-once basis. +- `client.id`: Subscriber client ID. +- `auto.offset.reset`: Initial point of subscription. *earliest* subscribes from the beginning, and *latest* subscribes from the newest message. The default is earliest. Note: This parameter is set per consumer group. +- `enable.auto.commit`: Automatically commits. This can be enabled when data consistency is not essential. +- `auto.commit.interval.ms`: Interval for automatic commits. + +#### Full Sample Code + +For more information, see [GitHub sample file](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/subscribe_demo.rs). + +### Use with connection pool In complex applications, we recommend enabling connection pools. [taos] implements connection pools based on [r2d2]. @@ -292,7 +479,17 @@ In the application code, use `pool.get()? ` to get a connection object [Taos]. let taos = pool.get()?; ``` -### Connectors +### More sample programs + +The source code of the sample application is under `TDengine/examples/rust` : + +[rust example](https://github.com/taosdata/TDengine/tree/3.0/examples/rust) + +## Frequently Asked Questions + +For additional troubleshooting, see [FAQ](../../../train-faq/faq). + +## API Reference The [Taos][struct.Taos] object provides an API to perform operations on multiple databases. @@ -378,9 +575,13 @@ Note that Rust asynchronous functions and an asynchronous runtime are required. - `.create_database(database: &str)`: Executes the `CREATE DATABASE` statement. - `.use_database(database: &str)`: Executes the `USE` statement. -In addition, this structure is also the entry point for [Parameter Binding](#Parameter Binding Interface) and [Line Protocol Interface](#Line Protocol Interface). Please refer to the specific API descriptions for usage. +In addition, this structure is also the entry point for Parameter Binding and Line Protocol Interface. Please refer to the specific API descriptions for usage. -### Bind Interface +

+ +Bind Interface + +

Similar to the C interface, Rust provides the bind interface's wrapping. First, the [Taos][struct.taos] object creates a parameter binding object [Stmt] for an SQL statement. @@ -391,7 +592,7 @@ stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)")?; The bind object provides a set of interfaces for implementing parameter binding. -#### `.set_tbname(name)` +`.set_tbname(name)` To bind table names. @@ -400,7 +601,7 @@ let mut stmt = taos.stmt("insert into ? values(? ,?)")?; stmt.set_tbname("d0")?; ``` -#### `.set_tags(&[tag])` +`.set_tags(&[tag])` Bind sub-table table names and tag values when the SQL statement uses a super table. @@ -410,7 +611,7 @@ stmt.set_tbname("d0")?; stmt.set_tags(&[Value::VarChar("taos".to_string())])?; ``` -#### `.bind(&[column])` +`.bind(&[column])` Bind value types. Use the [ColumnView] structure to create and bind the required types. @@ -434,7 +635,7 @@ let params = vec![ let rows = stmt.bind(¶ms)?.add_batch()?.execute()?; ``` -#### `.execute()` +`.execute()` Execute SQL. [Stmt] objects can be reused, re-binded, and executed after execution. Before execution, ensure that all data has been added to the queue with `.add_batch`. @@ -449,92 +650,6 @@ stmt.execute()?; For a working example, see [GitHub](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs). -### Subscriptions - -TDengine starts subscriptions through [TMQ](../../../taos-sql/tmq/). - -You create a TMQ connector by using a DSN. - -```rust -let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; -``` - -Create a consumer: - -```rust -let mut consumer = tmq.build()?; -``` - -A single consumer can subscribe to one or more topics. - -```rust -consumer.subscribe(["tmq_meters"]).await?; -``` - -The TMQ is of [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) type. You can use the corresponding API to consume each message in the queue and then use `.commit` to mark them as consumed. - -```rust -{ - let mut stream = consumer.stream(); - - while let Some((offset, message)) = stream.try_next().await? { - // get information from offset - - // the topic - let topic = offset.topic(); - // the vgroup id, like partition id in kafka. - let vgroup_id = offset.vgroup_id(); - println!("* in vgroup id {vgroup_id} of topic {topic}\n"); - - if let Some(data) = message.into_data() { - while let Some(block) = data.fetch_raw_block().await? { - // one block for one table, get table name if needed - let name = block.table_name(); - let records: Vec = block.deserialize().try_collect()?; - println!( - "** table: {}, got {} records: {:#?}\n", - name.unwrap(), - records.len(), - records - ); - } - } - consumer.commit(offset).await?; - } -} -``` - -Get assignments: - -Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -let assignments = consumer.assignments().await.unwrap(); -``` - -Seek offset: - -Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -consumer.offset_seek(topic, vgroup_id, offset).await; -``` - -Unsubscribe: - -```rust -consumer.unsubscribe().await; -``` - -The following parameters can be configured for the TMQ DSN. Only `group.id` is mandatory. - -- `group.id`: Within a consumer group, load balancing is implemented by consuming messages on an at-least-once basis. -- `client.id`: Subscriber client ID. -- `auto.offset.reset`: Initial point of subscription. *earliest* subscribes from the beginning, and *latest* subscribes from the newest message. The default is earliest. Note: This parameter is set per consumer group. -- `enable.auto.commit`: Automatically commits. This can be enabled when data consistency is not essential. -- `auto.commit.interval.ms`: Interval for automatic commits. - -For more information, see [GitHub sample file](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/subscribe_demo.rs). For information about other structure APIs, see the [Rust documentation](https://docs.rs/taos). diff --git a/docs/en/14-reference/03-connector/07-python.mdx b/docs/en/14-reference/03-connector/07-python.mdx index 461bdfbf16..2a6cd9ecf7 100644 --- a/docs/en/14-reference/03-connector/07-python.mdx +++ b/docs/en/14-reference/03-connector/07-python.mdx @@ -20,10 +20,25 @@ The source code for the Python connector is hosted on [GitHub](https://github.co - The [supported platforms](/reference/connector/#supported-platforms) for the native connection are the same as the ones supported by the TDengine client. - REST connections are supported on all platforms that can run Python. +### Supported features + +- Native connections support all the core features of TDengine, including connection management, SQL execution, bind interface, subscriptions, and schemaless writing. +- REST connections support features such as connection management and SQL execution. (SQL execution allows you to: manage databases, tables, and supertables, write data, query data, create continuous queries, etc.). + ## Version selection We recommend using the latest version of `taospy`, regardless of the version of TDengine. +|Python Connector Version|major changes| +|:-------------------:|:----:| +|2.7.9|support for getting assignment and seek function on subscription| +|2.7.8|add `execute_many` method| + +|Python Websocket Connector Version|major changes| +|:----------------------------:|:-----:| +|0.2.5|1. support for getting assignment and seek function on subscription
2. support schemaless
3. support STMT| +|0.2.4|support `unsubscribe` on subscription| + ## Handling Exceptions There are 4 types of exception in python connector. @@ -54,10 +69,23 @@ All exceptions from the Python Connector are thrown directly. Applications shoul {{#include docs/examples/python/handle_exception.py}} ``` -## Supported features +## TDengine DataType vs. Python DataType -- Native connections support all the core features of TDengine, including connection management, SQL execution, bind interface, subscriptions, and schemaless writing. -- REST connections support features such as connection management and SQL execution. (SQL execution allows you to: manage databases, tables, and supertables, write data, query data, create continuous queries, etc.). +TDengine currently supports timestamp, number, character, Boolean type, and the corresponding type conversion with Python is as follows: + +|TDengine DataType|Python DataType| +|:---------------:|:-------------:| +|TIMESTAMP|datetime| +|INT|int| +|BIGINT|int| +|FLOAT|float| +|DOUBLE|int| +|SMALLINT|int| +|TINYINT|int| +|BOOL|bool| +|BINARY|str| +|NCHAR|str| +|JSON|str| ## Installation @@ -534,7 +562,7 @@ Connector support data subscription. For more information about subscroption, pl The `consumer` in the connector contains the subscription api. -#### Create Consumer +##### Create Consumer The syntax for creating a consumer is `consumer = Consumer(configs)`. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/). @@ -544,7 +572,7 @@ from taos.tmq import Consumer consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"}) ``` -#### Subscribe topics +##### Subscribe topics The `subscribe` function is used to subscribe to a list of topics. @@ -552,7 +580,7 @@ The `subscribe` function is used to subscribe to a list of topics. consumer.subscribe(['topic1', 'topic2']) ``` -#### Consume +##### Consume The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data. @@ -570,7 +598,7 @@ while True: print(block.fetchall()) ``` -#### assignment +##### assignment The `assignment` function is used to get the assignment of the topic. @@ -578,7 +606,7 @@ The `assignment` function is used to get the assignment of the topic. assignments = consumer.assignment() ``` -#### Seek +##### Seek The `seek` function is used to reset the assignment of the topic. @@ -587,7 +615,7 @@ tp = TopicPartition(topic='topic1', partition=0, offset=0) consumer.seek(tp) ``` -#### After consuming data +##### After consuming data You should unsubscribe to the topics and close the consumer after consuming. @@ -596,13 +624,13 @@ consumer.unsubscribe() consumer.close() ``` -#### Tmq subscription example +##### Tmq subscription example ```python {{#include docs/examples/python/tmq_example.py}} ``` -#### assignment and seek example +##### assignment and seek example ```python {{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}} @@ -614,7 +642,7 @@ consumer.close() In addition to native connections, the connector also supports subscriptions via websockets. -#### Create Consumer +##### Create Consumer The syntax for creating a consumer is "consumer = consumer = Consumer(conf=configs)". You need to specify that the `td.connect.websocket.scheme` parameter is set to "ws" in the configuration. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/#create-a-consumer). @@ -624,7 +652,7 @@ import taosws consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"}) ``` -#### subscribe topics +##### subscribe topics The `subscribe` function is used to subscribe to a list of topics. @@ -632,7 +660,7 @@ The `subscribe` function is used to subscribe to a list of topics. consumer.subscribe(['topic1', 'topic2']) ``` -#### Consume +##### Consume The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data. @@ -649,7 +677,7 @@ while True: print(row) ``` -#### assignment +##### assignment The `assignment` function is used to get the assignment of the topic. @@ -657,7 +685,7 @@ The `assignment` function is used to get the assignment of the topic. assignments = consumer.assignment() ``` -#### Seek +##### Seek The `seek` function is used to reset the assignment of the topic. @@ -665,7 +693,7 @@ The `seek` function is used to reset the assignment of the topic. consumer.seek(topic='topic1', partition=0, offset=0) ``` -#### After consuming data +##### After consuming data You should unsubscribe to the topics and close the consumer after consuming. @@ -674,13 +702,13 @@ consumer.unsubscribe() consumer.close() ``` -#### Subscription example +##### Subscription example ```python {{#include docs/examples/python/tmq_websocket_example.py}} ``` -#### Assignment and seek example +##### Assignment and seek example ```python {{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}} @@ -696,19 +724,19 @@ Connector support schemaless insert. -Simple insert +##### Simple insert ```python {{#include docs/examples/python/schemaless_insert.py}} ``` -Insert with ttl argument +##### Insert with ttl argument ```python {{#include docs/examples/python/schemaless_insert_ttl.py}} ``` -Insert with req_id argument +##### Insert with req_id argument ```python {{#include docs/examples/python/schemaless_insert_req_id.py}} @@ -718,19 +746,19 @@ Insert with req_id argument -Simple insert +##### Simple insert ```python {{#include docs/examples/python/schemaless_insert_raw.py}} ``` -Insert with ttl argument +##### Insert with ttl argument ```python {{#include docs/examples/python/schemaless_insert_raw_ttl.py}} ``` -Insert with req_id argument +##### Insert with req_id argument ```python {{#include docs/examples/python/schemaless_insert_raw_req_id.py}} @@ -746,7 +774,7 @@ The Python connector provides a parameter binding api for inserting data. Simila -#### Create Stmt +##### Create Stmt Call the `statement` method in `Connection` to create the `stmt` for parameter binding. @@ -757,7 +785,7 @@ conn = taos.connect() stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") ``` -#### parameter binding +##### parameter binding Call the `new_multi_binds` function to create the parameter list for parameter bindings. @@ -787,7 +815,7 @@ Call the `bind_param` (for a single row) method or the `bind_param_batch` (for m stmt.bind_param_batch(params) ``` -#### execute sql +##### execute sql Call `execute` method to execute sql. @@ -795,13 +823,13 @@ Call `execute` method to execute sql. stmt.execute() ``` -#### Close Stmt +##### Close Stmt ``` stmt.close() ``` -#### Example +##### Example ```python {{#include docs/examples/python/stmt_example.py}} @@ -810,7 +838,7 @@ stmt.close() -#### Create Stmt +##### Create Stmt Call the `statement` method in `Connection` to create the `stmt` for parameter binding. @@ -821,7 +849,7 @@ conn = taosws.connect('taosws://localhost:6041/test') stmt = conn.statement() ``` -#### Prepare sql +##### Prepare sql Call `prepare` method in stmt to prepare sql. @@ -829,7 +857,7 @@ Call `prepare` method in stmt to prepare sql. stmt.prepare("insert into t1 values (?, ?, ?, ?)") ``` -#### parameter binding +##### parameter binding Call the `bind_param` method to bind parameters. @@ -848,7 +876,7 @@ Call the `add_batch` method to add parameters to the batch. stmt.add_batch() ``` -#### execute sql +##### execute sql Call `execute` method to execute sql. @@ -856,13 +884,13 @@ Call `execute` method to execute sql. stmt.execute() ``` -#### Close Stmt +##### Close Stmt ``` stmt.close() ``` -#### Example +##### Example ```python {{#include docs/examples/python/stmt_websocket_example.py}} diff --git a/docs/en/28-releases/01-tdengine.md b/docs/en/28-releases/01-tdengine.md index f4d9ba8e42..a5c1553402 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.6.0 + + + ## 3.0.5.1 diff --git a/docs/zh/07-develop/07-tmq.mdx b/docs/zh/07-develop/07-tmq.mdx index a87a1f64f8..54a8af2287 100644 --- a/docs/zh/07-develop/07-tmq.mdx +++ b/docs/zh/07-develop/07-tmq.mdx @@ -243,6 +243,7 @@ TDengine 使用 SQL åˆ›å»ŗäø€äøŖ topic: ```sql CREATE TOPIC topic_name AS SELECT ts, c1, c2, c3 FROM tmqdb.stb WHERE c1 > 1; ``` +- topicåˆ›å»ŗäøŖę•°ęœ‰äøŠé™ļ¼Œé€ščæ‡å‚ę•° tmqMaxTopicNum ęŽ§åˆ¶ļ¼Œé»˜č®¤ 20 äøŖ TMQ ę”ÆęŒå¤šē§č®¢é˜…ē±»åž‹ļ¼š @@ -265,14 +266,15 @@ CREATE TOPIC topic_name as subquery čÆ­ę³•ļ¼š ```sql -CREATE TOPIC topic_name AS STABLE stb_name +CREATE TOPIC topic_name [with meta] AS STABLE stb_name [where_condition] ``` äøŽ `SELECT * from stbName` č®¢é˜…ēš„åŒŗåˆ«ę˜Æļ¼š - äøä¼šé™åˆ¶ē”Øęˆ·ēš„č”Øē»“ęž„å˜ę›“ć€‚ - čæ”å›žēš„ę˜Æéžē»“ęž„åŒ–ēš„ę•°ę®ļ¼ščæ”å›žę•°ę®ēš„ē»“ęž„ä¼šéšä¹‹č¶…ēŗ§č”Øēš„č”Øē»“ęž„å˜åŒ–č€Œå˜åŒ–ć€‚ -- ē”Øęˆ·åÆ¹äŗŽč¦å¤„ē†ēš„ęÆäø€äøŖę•°ę®å—éƒ½åÆčƒ½ęœ‰äøåŒēš„č”Øē»“ęž„ć€‚ +- with meta å‚ę•°åÆé€‰ļ¼Œé€‰ę‹©ę—¶å°†čæ”å›žåˆ›å»ŗč¶…ēŗ§č”Øļ¼Œå­č”Øē­‰čÆ­å„ļ¼Œäø»č¦ē”ØäŗŽtaosxåšč¶…ēŗ§č”Øčæē§» +- where_condition å‚ę•°åÆé€‰ļ¼Œé€‰ę‹©ę—¶å°†ē”Øę„čæ‡ę»¤ē¬¦åˆę”ä»¶ēš„å­č”Øļ¼Œč®¢é˜…čæ™äŗ›å­č”Øć€‚where ę”ä»¶é‡Œäøčƒ½ęœ‰ę™®é€šåˆ—ļ¼ŒåŖčƒ½ę˜Ætagꈖtbname,whereę”ä»¶é‡ŒåÆä»„ē”Øå‡½ę•°ļ¼Œē”Øę„čæ‡ę»¤tagļ¼Œä½†ę˜Æäøčƒ½ę˜Æčšåˆå‡½ę•°ļ¼Œå› äøŗå­č”Øtagå€¼ę— ę³•åščšåˆć€‚ä¹ŸåÆä»„ę˜Æåøøé‡č”Øč¾¾å¼ļ¼ŒęÆ”å¦‚ 2 > 1ļ¼ˆč®¢é˜…å…ØéƒØå­č”Øļ¼‰ļ¼Œęˆ–č€… falseļ¼ˆč®¢é˜…0个子蔨) - čæ”å›žę•°ę®äøåŒ…å«ę ‡ē­¾ć€‚ ### ę•°ę®åŗ“č®¢é˜… @@ -280,11 +282,13 @@ CREATE TOPIC topic_name AS STABLE stb_name čÆ­ę³•ļ¼š ```sql -CREATE TOPIC topic_name AS DATABASE db_name; +CREATE TOPIC topic_name [with meta] AS DATABASE db_name; ``` é€ščæ‡čÆ„čÆ­å„åÆåˆ›å»ŗäø€äøŖåŒ…å«ę•°ę®åŗ“ę‰€ęœ‰č”Øę•°ę®ēš„č®¢é˜… +- with meta å‚ę•°åÆé€‰ļ¼Œé€‰ę‹©ę—¶å°†čæ”å›žåˆ›å»ŗę•°ę®åŗ“é‡Œę‰€ęœ‰č¶…ēŗ§č”Øļ¼Œå­č”Øēš„čÆ­å„ļ¼Œäø»č¦ē”ØäŗŽtaosxåšę•°ę®åŗ“čæē§» + ## åˆ›å»ŗę¶ˆč“¹č€… *consumer* ę¶ˆč“¹č€…éœ€č¦é€ščæ‡äø€ē³»åˆ—é…ē½®é€‰é”¹åˆ›å»ŗļ¼ŒåŸŗē”€é…ē½®é”¹å¦‚äø‹č”Øę‰€ē¤ŗļ¼š @@ -295,7 +299,7 @@ CREATE TOPIC topic_name AS DATABASE db_name; | `td.connect.user` | string | ē”Øęˆ·å | | | `td.connect.pass` | string | 密码 | | | `td.connect.port` | integer | ęœåŠ”ē«Æēš„ē«Æå£å· | | -| `group.id` | string | ę¶ˆč“¹ē»„ IDļ¼ŒåŒäø€ę¶ˆč“¹ē»„å…±äŗ«ę¶ˆč“¹čæ›åŗ¦ | **必唫锹**ć€‚ęœ€å¤§é•æåŗ¦ļ¼š192怂 | +| `group.id` | string | ę¶ˆč“¹ē»„ IDļ¼ŒåŒäø€ę¶ˆč“¹ē»„å…±äŗ«ę¶ˆč“¹čæ›åŗ¦ |
**必唫锹**ć€‚ęœ€å¤§é•æåŗ¦ļ¼š192怂
ęÆäøŖtopicęœ€å¤šåÆå»ŗē«‹100äøŖ consumer group | | `client.id` | string | 客户端 ID | ęœ€å¤§é•æåŗ¦ļ¼š192怂 | | `auto.offset.reset` | enum | ę¶ˆč“¹ē»„č®¢é˜…ēš„åˆå§‹ä½ē½® |
`earliest`: default;ä»Žå¤“å¼€å§‹č®¢é˜…;
`latest`: ä»…ä»Žęœ€ę–°ę•°ę®å¼€å§‹č®¢é˜…;
`none`: ę²”ęœ‰ęäŗ¤ēš„ offset ę— ę³•č®¢é˜… | | `enable.auto.commit` | boolean | ę˜Æå¦åÆē”Øę¶ˆč“¹ä½ē‚¹č‡ŖåŠØęäŗ¤ļ¼Œtrue: č‡ŖåŠØęäŗ¤ļ¼Œå®¢ęˆ·ē«Æåŗ”ē”Øę— éœ€commitļ¼›falseļ¼šå®¢ęˆ·ē«Æåŗ”ē”Øéœ€č¦č‡Ŗč”Œcommit | é»˜č®¤å€¼äøŗ true | diff --git a/docs/zh/07-develop/09-udf.md b/docs/zh/07-develop/09-udf.md index ae11273a39..ff46437687 100644 --- a/docs/zh/07-develop/09-udf.md +++ b/docs/zh/07-develop/09-udf.md @@ -17,7 +17,7 @@ TDengine ę”ÆęŒé€ščæ‡ C/Python čÆ­čØ€čæ›č”Œ UDF å®šä¹‰ć€‚ęŽ„äø‹ę„ē»“åˆē¤ŗä¾‹ - čšåˆå‡½ę•°éœ€č¦å®žēŽ°čšåˆęŽ„å£å‡½ę•° aggfn_start , aggfn , aggfn_finish怂 - å¦‚ęžœéœ€č¦åˆå§‹åŒ–ļ¼Œå®žēŽ° udf_initļ¼›å¦‚ęžœéœ€č¦ęø…ē†å·„ä½œļ¼Œå®žēŽ°udf_destroy怂 -ęŽ„å£å‡½ę•°ēš„åē§°ę˜Æ UDF åē§°ļ¼Œęˆ–č€…ę˜Æ UDF åē§°å’Œē‰¹å®šåŽē¼€ļ¼ˆ_start, _finish, _init, _destroy)ēš„čæžęŽ„ć€‚åˆ—č”Øäø­ēš„scalarfn,aggfn, udféœ€č¦ę›æę¢ęˆudfå‡½ę•°åć€‚ +ęŽ„å£å‡½ę•°ēš„åē§°ę˜Æ UDF åē§°ļ¼Œęˆ–č€…ę˜Æ UDF åē§°å’Œē‰¹å®šåŽē¼€ļ¼ˆ`_start`, `_finish`, `_init`, `_destroy`)ēš„čæžęŽ„ć€‚åˆ—č”Øäø­ēš„scalarfn,aggfn, udféœ€č¦ę›æę¢ęˆudfå‡½ę•°åć€‚ ### 用 C čÆ­čØ€å®žēŽ°ę ‡é‡å‡½ę•° ę ‡é‡å‡½ę•°å®žēŽ°ęØ”ęæå¦‚äø‹ diff --git a/docs/zh/08-connector/14-java.mdx b/docs/zh/08-connector/14-java.mdx index 27b732b883..c7da2bd4f5 100644 --- a/docs/zh/08-connector/14-java.mdx +++ b/docs/zh/08-connector/14-java.mdx @@ -36,14 +36,15 @@ REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Java ēš„å¹³å°ć€‚ | taos-jdbcdriver ē‰ˆęœ¬ | äø»č¦å˜åŒ– | TDengine ē‰ˆęœ¬ | | :------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------: | +| 3.2.3 | äæ®å¤ ResultSet åœØäø€äŗ›ęƒ…å†µę•°ę®č§£ęžå¤±č“„ | - | | 3.2.2 | ę–°å¢žåŠŸčƒ½ļ¼šę•°ę®č®¢é˜…ę”ÆęŒ seek åŠŸčƒ½ć€‚ | 3.0.5.0 åŠę›“é«˜ē‰ˆęœ¬ | | 3.2.1 | ę–°å¢žåŠŸčƒ½ļ¼šWebSocket čæžęŽ„ę”ÆęŒ schemaless äøŽ prepareStatement å†™å…„ć€‚å˜ę›“ļ¼šconsumer poll čæ”å›žē»“ęžœé›†äøŗ ConsumerRecordļ¼ŒåÆé€ščæ‡ value() čŽ·å–ęŒ‡å®šē»“ęžœé›†ę•°ę®ć€‚ | 3.0.3.0 åŠę›“é«˜ē‰ˆęœ¬ | | 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 | 3.0.0.0 åŠę›“é«˜ē‰ˆęœ¬ | -| 2.0.42 | 修在 WebSocket čæžęŽ„äø­ wasNull ęŽ„å£čæ”å›žå€¼ | - | -| 2.0.41 | 修正 REST čæžęŽ„äø­ē”Øęˆ·åå’ŒåÆ†ē č½¬ē ę–¹å¼ | - | +| 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 ę”ÆęŒ | - | @@ -287,9 +288,9 @@ url äø­ēš„é…ē½®å‚ę•°å¦‚äø‹ļ¼š - batchfetch: trueļ¼šåœØę‰§č”ŒęŸ„čÆ¢ę—¶ę‰¹é‡ę‹‰å–ē»“ęžœé›†ļ¼›falseļ¼šé€č”Œę‹‰å–ē»“ęžœé›†ć€‚é»˜č®¤å€¼äøŗļ¼šfalseć€‚é€č”Œę‹‰å–ē»“ęžœé›†ä½æē”Ø HTTP ę–¹å¼čæ›č”Œę•°ę®ä¼ č¾“ć€‚JDBC REST čæžęŽ„ę”ÆęŒę‰¹é‡ę‹‰å–ę•°ę®åŠŸčƒ½ć€‚taos-jdbcdriver äøŽ TDengine ä¹‹é—“é€ščæ‡ WebSocket čæžęŽ„čæ›č”Œę•°ę®ä¼ č¾“ć€‚ē›øč¾ƒäŗŽ HTTP,WebSocket åÆä»„ä½æ JDBC REST čæžęŽ„ę”ÆęŒå¤§ę•°ę®é‡ęŸ„čÆ¢ļ¼Œå¹¶ęå‡ęŸ„čÆ¢ę€§čƒ½ć€‚ - charset: å½“å¼€åÆę‰¹é‡ę‹‰å–ę•°ę®ę—¶ļ¼ŒęŒ‡å®šč§£ęžå­—ē¬¦äø²ę•°ę®ēš„å­—ē¬¦é›†ć€‚ - batchErrorIgnore:trueļ¼šåœØę‰§č”Œ Statement ēš„ executeBatch ę—¶ļ¼Œå¦‚ęžœäø­é—“ęœ‰äø€ę” SQL ę‰§č”Œå¤±č“„ļ¼Œē»§ē»­ę‰§č”Œäø‹é¢ēš„ SQL 了。falseļ¼šäøå†ę‰§č”Œå¤±č“„ SQL åŽēš„ä»»ä½•čÆ­å„ć€‚é»˜č®¤å€¼äøŗļ¼šfalse怂 -- httpConnectTimeout: čæžęŽ„č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ ms, é»˜č®¤å€¼äøŗ 5000怂 -- httpSocketTimeout: socket č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ msļ¼Œé»˜č®¤å€¼äøŗ 5000ć€‚ä»…åœØ batchfetch 设置为 false ę—¶ē”Ÿę•ˆć€‚ -- messageWaitTimeout: ę¶ˆęÆč¶…ę—¶ę—¶é—“, 单位 ms, é»˜č®¤å€¼äøŗ 3000怂 ä»…åœØ batchfetch 设置为 true ę—¶ē”Ÿę•ˆć€‚ +- httpConnectTimeout: čæžęŽ„č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ ms, é»˜č®¤å€¼äøŗ 60000怂 +- httpSocketTimeout: socket č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ msļ¼Œé»˜č®¤å€¼äøŗ 60000ć€‚ä»…åœØ batchfetch 设置为 false ę—¶ē”Ÿę•ˆć€‚ +- messageWaitTimeout: ę¶ˆęÆč¶…ę—¶ę—¶é—“, 单位 ms, é»˜č®¤å€¼äøŗ 60000怂 ä»…åœØ batchfetch 设置为 true ę—¶ē”Ÿę•ˆć€‚ - useSSL: čæžęŽ„äø­ę˜Æå¦ä½æē”Ø SSL怂 - httpPoolSize: REST å¹¶å‘čÆ·ę±‚å¤§å°ļ¼Œé»˜č®¤ 20怂 @@ -355,9 +356,9 @@ properties äø­ēš„é…ē½®å‚ę•°å¦‚äø‹ļ¼š - TSDBDriver.PROPERTY_KEY_CHARSETļ¼šå®¢ęˆ·ē«Æä½æē”Øēš„å­—ē¬¦é›†ļ¼Œé»˜č®¤å€¼äøŗē³»ē»Ÿå­—ē¬¦é›†ć€‚ - TSDBDriver.PROPERTY_KEY_LOCALEļ¼šä»…åœØä½æē”Ø JDBC åŽŸē”ŸčæžęŽ„ę—¶ē”Ÿę•ˆć€‚ å®¢ęˆ·ē«ÆčÆ­čØ€ēŽÆå¢ƒļ¼Œé»˜č®¤å€¼ē³»ē»Ÿå½“å‰ locale怂 - TSDBDriver.PROPERTY_KEY_TIME_ZONEļ¼šä»…åœØä½æē”Ø JDBC åŽŸē”ŸčæžęŽ„ę—¶ē”Ÿę•ˆć€‚ å®¢ęˆ·ē«Æä½æē”Øēš„ę—¶åŒŗļ¼Œé»˜č®¤å€¼äøŗē³»ē»Ÿå½“å‰ę—¶åŒŗć€‚ -- TSDBDriver.HTTP_CONNECT_TIMEOUT: čæžęŽ„č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ ms, é»˜č®¤å€¼äøŗ 5000ć€‚ä»…åœØ REST čæžęŽ„ę—¶ē”Ÿę•ˆć€‚ -- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ msļ¼Œé»˜č®¤å€¼äøŗ 5000ć€‚ä»…åœØ REST čæžęŽ„äø” batchfetch 设置为 false ę—¶ē”Ÿę•ˆć€‚ -- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: ę¶ˆęÆč¶…ę—¶ę—¶é—“, 单位 ms, é»˜č®¤å€¼äøŗ 3000怂 ä»…åœØ REST čæžęŽ„äø” batchfetch 设置为 true ę—¶ē”Ÿę•ˆć€‚ +- TSDBDriver.HTTP_CONNECT_TIMEOUT: čæžęŽ„č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ ms, é»˜č®¤å€¼äøŗ 60000ć€‚ä»…åœØ REST čæžęŽ„ę—¶ē”Ÿę•ˆć€‚ +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket č¶…ę—¶ę—¶é—“ļ¼Œå•ä½ msļ¼Œé»˜č®¤å€¼äøŗ 60000ć€‚ä»…åœØ REST čæžęŽ„äø” batchfetch 设置为 false ę—¶ē”Ÿę•ˆć€‚ +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: ę¶ˆęÆč¶…ę—¶ę—¶é—“, 单位 ms, é»˜č®¤å€¼äøŗ 60000怂 ä»…åœØ REST čæžęŽ„äø” batchfetch 设置为 true ę—¶ē”Ÿę•ˆć€‚ - TSDBDriver.PROPERTY_KEY_USE_SSL: čæžęŽ„äø­ę˜Æå¦ä½æē”Ø SSLć€‚ä»…åœØ REST čæžęŽ„ę—¶ē”Ÿę•ˆć€‚ - TSDBDriver.HTTP_POOL_SIZE: REST å¹¶å‘čÆ·ę±‚å¤§å°ļ¼Œé»˜č®¤ 20怂 此外对 JDBC åŽŸē”ŸčæžęŽ„ļ¼Œé€ščæ‡ęŒ‡å®š URL 和 Properties čæ˜åÆä»„ęŒ‡å®šå…¶ä»–å‚ę•°ļ¼ŒęÆ”å¦‚ę—„åæ—ēŗ§åˆ«ć€SQL é•æåŗ¦ē­‰ć€‚ę›“å¤ščÆ¦ē»†é…ē½®čÆ·å‚č€ƒ[å®¢ęˆ·ē«Æé…ē½®](/reference/config/#ä»…å®¢ęˆ·ē«Æé€‚ē”Ø)怂 diff --git a/docs/zh/08-connector/20-go.mdx b/docs/zh/08-connector/20-go.mdx index d431be35cb..90ef4d83ca 100644 --- a/docs/zh/08-connector/20-go.mdx +++ b/docs/zh/08-connector/20-go.mdx @@ -32,24 +32,44 @@ REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Go ēš„å¹³å°ć€‚ čÆ·å‚č€ƒ[ē‰ˆęœ¬ę”ÆęŒåˆ—č”Ø](https://github.com/taosdata/driver-go#remind) -## ę”ÆęŒēš„åŠŸčƒ½ē‰¹ę€§ +## 处理异常 -### åŽŸē”ŸčæžęŽ„ +å¦‚ęžœę˜Æ TDengine é”™čÆÆåÆä»„é€ščæ‡ä»„äø‹ę–¹å¼čŽ·å–é”™čÆÆē å’Œé”™čÆÆäæ”ęÆć€‚ -ā€œåŽŸē”ŸčæžęŽ„ā€ęŒ‡čæžęŽ„å™Øé€ščæ‡ TDengine 客户端驱动(taoscļ¼‰ē›“ęŽ„äøŽ TDengine čæč”Œå®žä¾‹å»ŗē«‹ēš„čæžęŽ„ć€‚ę”ÆęŒēš„åŠŸčƒ½ē‰¹ę€§ęœ‰ļ¼š +```go +// import "github.com/taosdata/driver-go/v3/errors" + if err != nil { + tError, is := err.(*errors.TaosError) + if is { + fmt.Println("errorCode:", int(tError.Code)) + fmt.Println("errorMessage:", tError.ErrStr) + } else { + fmt.Println(err.Error()) + } + } +``` -* ę™®é€šęŸ„čÆ¢ -* čæžē»­ęŸ„čÆ¢ -* č®¢é˜… -* schemaless ęŽ„å£ -* å‚ę•°ē»‘å®šęŽ„å£ +## TDengine DataType 和 Go DataType -### REST čæžęŽ„ +| TDengine DataType | Go Type | +|-------------------|-----------| +| TIMESTAMP | time.Time | +| TINYINT | int8 | +| SMALLINT | int16 | +| INT | int32 | +| BIGINT | int64 | +| TINYINT UNSIGNED | uint8 | +| SMALLINT UNSIGNED | uint16 | +| INT UNSIGNED | uint32 | +| BIGINT UNSIGNED | uint64 | +| FLOAT | float32 | +| DOUBLE | float64 | +| BOOL | bool | +| BINARY | string | +| NCHAR | string | +| JSON | []byte | -"REST čæžęŽ„"ęŒ‡čæžęŽ„å™Øé€ščæ‡ taosAdapter ē»„ä»¶ęä¾›ēš„ REST API äøŽ TDengine čæč”Œå®žä¾‹å»ŗē«‹ēš„čæžęŽ„ć€‚ę”ÆęŒēš„åŠŸčƒ½ē‰¹ę€§ęœ‰ļ¼š - -* ę™®é€šęŸ„čÆ¢ -* čæžē»­ęŸ„čÆ¢ +**ę³Øę„**:JSON ē±»åž‹ä»…åœØ tag äø­ę”ÆęŒć€‚ ## 安装歄骤 @@ -63,32 +83,28 @@ REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Go ēš„å¹³å°ć€‚ * ```go env``` * ```gcc -v``` -### 使用 go get 安装 - -`go get -u github.com/taosdata/driver-go/v3@latest` - -### 使用 go mod 箔理 +### å®‰č£…čæžęŽ„å™Ø 1. 使用 `go mod` å‘½ä»¤åˆå§‹åŒ–é”¹ē›®ļ¼š - ```text - go mod init taos-demo - ``` + ```text + go mod init taos-demo + ``` 2. 引兄 taosSql : - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v3/taosSql" - ) - ``` + ```go + import ( + "database/sql" + _ "github.com/taosdata/driver-go/v3/taosSql" + ) + ``` 3. 使用 `go mod tidy` ę›“ę–°ä¾čµ–åŒ…ļ¼š - ```text - go mod tidy - ``` + ```text + go mod tidy + ``` 4. 使用 `go run taos-demo` čæč”ŒēØ‹åŗęˆ–ä½æē”Ø `go build` å‘½ä»¤ē¼–čÆ‘å‡ŗäŗŒčæ›åˆ¶ę–‡ä»¶ć€‚ @@ -99,8 +115,6 @@ REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Go ēš„å¹³å°ć€‚ ## å»ŗē«‹čæžęŽ„ -### ę•°ę®ęŗåē§°ļ¼ˆDSN) - ę•°ę®ęŗåē§°å…·ęœ‰é€šē”Øę ¼å¼ļ¼Œä¾‹å¦‚ [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php)ļ¼Œä½†ę²”ęœ‰ē±»åž‹å‰ē¼€ļ¼ˆę–¹ę‹¬å·č”Øē¤ŗåÆé€‰ļ¼‰ļ¼š ``` text @@ -113,9 +127,7 @@ REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Go ēš„å¹³å°ć€‚ username:password@protocol(address)/dbname?param=value ``` -### ä½æē”ØčæžęŽ„å™Øčæ›č”ŒčæžęŽ„ - - + _taosSql_ é€ščæ‡ cgo å®žēŽ°äŗ† Go ēš„ `database/sql/driver` ęŽ„å£ć€‚åŖéœ€č¦å¼•å…„é©±åŠØå°±åÆä»„ä½æē”Ø [`database/sql`](https://golang.org/pkg/database/sql/) ēš„ęŽ„å£ć€‚ @@ -213,42 +225,165 @@ func main() { +### ęŒ‡å®š URL 和 Properties čŽ·å–čæžęŽ„ + +Go čæžęŽ„å™Øäøę”ÆęŒę­¤åŠŸčƒ½ + +### é…ē½®å‚ę•°ēš„ä¼˜å…ˆēŗ§ + +Go čæžęŽ„å™Øäøę”ÆęŒę­¤åŠŸčƒ½ + ## 使用示例 -### å†™å…„ę•°ę® +### åˆ›å»ŗę•°ę®åŗ“å’Œč”Ø -#### SQL 写兄 +```go +var taosDSN = "root:taosdata@tcp(localhost:6030)/" +taos, err := sql.Open("taosSql", taosDSN) +if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) +} +defer taos.Close() +_, err := taos.Exec("CREATE DATABASE power") +if err != nil { + log.Fatalln("failed to create database, err:", err) +} +_, err = taos.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)") +if err != nil { + log.Fatalln("failed to create stable, err:", err) +} +``` + +### ę’å…„ę•°ę® -#### InfluxDB č”Œåč®®å†™å…„ - - - -#### OpenTSDB Telnet č”Œåč®®å†™å…„ - - - -#### OpenTSDB JSON č”Œåč®®å†™å…„ - - - ### ęŸ„čÆ¢ę•°ę® -### ę›“å¤šē¤ŗä¾‹ēØ‹åŗ +### ę‰§č”Œåø¦ęœ‰ reqId ēš„ SQL -* [ē¤ŗä¾‹ēØ‹åŗ](https://github.com/taosdata/driver-go/tree/3.0/examples) -* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)怂 +ę­¤ reqId åÆē”ØäŗŽčÆ·ę±‚é“¾č·Æčæ½čøŖć€‚ -## ä½æē”Øé™åˆ¶ +```go +db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") +if err != nil { + panic(err) +} +defer db.Close() +ctx := context.WithValue(context.Background(), common.ReqIDKey, common.GetReqID()) +_, err = db.ExecContext(ctx, "create database if not exists example_taos_sql") +if err != nil { + panic(err) +} +``` -ē”±äŗŽ REST ęŽ„å£ę— ēŠ¶ę€ę‰€ä»„ `use db` čÆ­ę³•äøä¼šē”Ÿę•ˆļ¼Œéœ€č¦å°† db åē§°ę”¾åˆ° SQL čÆ­å„äø­ļ¼Œå¦‚ļ¼š`create table if not exists tb1 (ts timestamp, a int)`改为`create table if not exists test.tb1 (ts timestamp, a int)`å¦åˆ™å°†ęŠ„é”™`[0x217] Database not specified or available`怂 +### é€ščæ‡å‚ę•°ē»‘å®šå†™å…„ę•°ę® -ä¹ŸåÆä»„å°† db åē§°ę”¾åˆ° DSN äø­ļ¼Œå°† `root:taosdata@http(localhost:6041)/` 改为 `root:taosdata@http(localhost:6041)/test`ć€‚å½“ęŒ‡å®šēš„ db äøå­˜åœØę—¶ę‰§č”Œ `create database` čÆ­å„äøä¼šęŠ„é”™ļ¼Œč€Œę‰§č”Œé’ˆåÆ¹čÆ„ db ēš„å…¶ä»–ęŸ„čÆ¢ęˆ–å†™å…„ę“ä½œä¼šęŠ„é”™ć€‚ + + -å®Œę•“ē¤ŗä¾‹å¦‚äø‹ļ¼š +```go +package main + +import ( + "time" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" +) + +func main() { + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_stmt") + if err != nil { + panic(err) + } + _, err = db.Exec("create table if not exists example_stmt.tb1(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")") + if err != nil { + panic(err) + } + stmt := db.InsertStmt() + err = stmt.Prepare("insert into example_stmt.tb1 values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + if err != nil { + panic(err) + } + now := time.Now() + params := make([]*param.Param, 14) + params[0] = param.NewParam(2). + AddTimestamp(now, common.PrecisionMilliSecond). + AddTimestamp(now.Add(time.Second), common.PrecisionMilliSecond) + params[1] = param.NewParam(2).AddBool(true).AddNull() + params[2] = param.NewParam(2).AddTinyint(2).AddNull() + params[3] = param.NewParam(2).AddSmallint(3).AddNull() + params[4] = param.NewParam(2).AddInt(4).AddNull() + params[5] = param.NewParam(2).AddBigint(5).AddNull() + params[6] = param.NewParam(2).AddUTinyint(6).AddNull() + params[7] = param.NewParam(2).AddUSmallint(7).AddNull() + params[8] = param.NewParam(2).AddUInt(8).AddNull() + params[9] = param.NewParam(2).AddUBigint(9).AddNull() + params[10] = param.NewParam(2).AddFloat(10).AddNull() + params[11] = param.NewParam(2).AddDouble(11).AddNull() + params[12] = param.NewParam(2).AddBinary([]byte("binary")).AddNull() + params[13] = param.NewParam(2).AddNchar("nchar").AddNull() + + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(6). + AddNchar(5) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Execute() + if err != nil { + panic(err) + } + err = stmt.Close() + if err != nil { + panic(err) + } + // select * from example_stmt.tb1 +} +``` + + + ```go package main @@ -258,288 +393,733 @@ import ( "fmt" "time" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/stmt" ) func main() { - var taosDSN = "root:taosdata@http(localhost:6041)/test" - taos, err := sql.Open("taosRestful", taosDSN) + db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/") if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } - defer taos.Close() - taos.Exec("create database if not exists test") - taos.Exec("create table if not exists tb1 (ts timestamp, a int)") - _, err = taos.Exec("insert into tb1 values(now, 0)(now+1s,1)(now+2s,2)(now+3s,3)") - if err != nil { - fmt.Println("failed to insert, err:", err) - return - } - rows, err := taos.Query("select * from tb1") - if err != nil { - fmt.Println("failed to select from table, err:", err) - return + panic(err) } + defer db.Close() + prepareEnv(db) - defer rows.Close() - for rows.Next() { - var r struct { - ts time.Time - a int - } - err := rows.Scan(&r.ts, &r.a) + config := stmt.NewConfig("ws://127.0.0.1:6041/rest/stmt", 0) + config.SetConnectUser("root") + config.SetConnectPass("taosdata") + config.SetConnectDB("example_ws_stmt") + config.SetMessageTimeout(common.DefaultMessageTimeout) + config.SetWriteWait(common.DefaultWriteWait) + config.SetErrorHandler(func(connector *stmt.Connector, err error) { + panic(err) + }) + config.SetCloseHandler(func() { + fmt.Println("stmt connector closed") + }) + + connector, err := stmt.NewConnector(config) + if err != nil { + panic(err) + } + now := time.Now() + { + stmt, err := connector.Init() if err != nil { - fmt.Println("scan error:\n", err) - return + panic(err) } - fmt.Println(r.ts, r.a) + err = stmt.Prepare("insert into ? using all_json tags(?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + if err != nil { + panic(err) + } + err = stmt.SetTableName("tb1") + if err != nil { + panic(err) + } + err = stmt.SetTags(param.NewParam(1).AddJson([]byte(`{"tb":1}`)), param.NewColumnType(1).AddJson(0)) + if err != nil { + panic(err) + } + params := []*param.Param{ + param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0), + param.NewParam(3).AddBool(true).AddNull().AddBool(true), + param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1), + param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1), + param.NewParam(3).AddInt(1).AddNull().AddInt(1), + param.NewParam(3).AddBigint(1).AddNull().AddBigint(1), + param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1), + param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1), + param.NewParam(3).AddUInt(1).AddNull().AddUInt(1), + param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1), + param.NewParam(3).AddFloat(1).AddNull().AddFloat(1), + param.NewParam(3).AddDouble(1).AddNull().AddDouble(1), + param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")), + param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"), + } + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Exec() + if err != nil { + panic(err) + } + affected := stmt.GetAffectedRows() + fmt.Println("all_json affected rows:", affected) + err = stmt.Close() + if err != nil { + panic(err) + } + } + { + stmt, err := connector.Init() + if err != nil { + panic(err) + } + err = stmt.Prepare("insert into ? using all_all tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + err = stmt.SetTableName("tb1") + if err != nil { + panic(err) + } + + err = stmt.SetTableName("tb2") + if err != nil { + panic(err) + } + err = stmt.SetTags( + param.NewParam(14). + AddTimestamp(now, 0). + AddBool(true). + AddTinyint(2). + AddSmallint(2). + AddInt(2). + AddBigint(2). + AddUTinyint(2). + AddUSmallint(2). + AddUInt(2). + AddUBigint(2). + AddFloat(2). + AddDouble(2). + AddBinary([]byte("tb2")). + AddNchar("tb2"), + param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0), + ) + if err != nil { + panic(err) + } + params := []*param.Param{ + param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0), + param.NewParam(3).AddBool(true).AddNull().AddBool(true), + param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1), + param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1), + param.NewParam(3).AddInt(1).AddNull().AddInt(1), + param.NewParam(3).AddBigint(1).AddNull().AddBigint(1), + param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1), + param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1), + param.NewParam(3).AddUInt(1).AddNull().AddUInt(1), + param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1), + param.NewParam(3).AddFloat(1).AddNull().AddFloat(1), + param.NewParam(3).AddDouble(1).AddNull().AddDouble(1), + param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")), + param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"), + } + paramTypes := param.NewColumnType(14). + AddTimestamp(). + AddBool(). + AddTinyint(). + AddSmallint(). + AddInt(). + AddBigint(). + AddUTinyint(). + AddUSmallint(). + AddUInt(). + AddUBigint(). + AddFloat(). + AddDouble(). + AddBinary(0). + AddNchar(0) + err = stmt.BindParam(params, paramTypes) + if err != nil { + panic(err) + } + err = stmt.AddBatch() + if err != nil { + panic(err) + } + err = stmt.Exec() + if err != nil { + panic(err) + } + affected := stmt.GetAffectedRows() + fmt.Println("all_all affected rows:", affected) + err = stmt.Close() + if err != nil { + panic(err) + } + + } +} + +func prepareEnv(db *sql.DB) { + steps := []string{ + "create database example_ws_stmt", + "create table example_ws_stmt.all_json(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")" + + "tags(t json)", + "create table example_ws_stmt.all_all(" + + "ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")" + + "tags(" + + "tts timestamp," + + "tc1 bool," + + "tc2 tinyint," + + "tc3 smallint," + + "tc4 int," + + "tc5 bigint," + + "tc6 tinyint unsigned," + + "tc7 smallint unsigned," + + "tc8 int unsigned," + + "tc9 bigint unsigned," + + "tc10 float," + + "tc11 double," + + "tc12 binary(20)," + + "tc13 nchar(20))", + } + for _, step := range steps { + _, err := db.Exec(step) + if err != nil { + panic(err) + } + } +} + +``` + + + + +### ę— ęØ”å¼å†™å…„ + + + + +```go +import ( + "fmt" + + "github.com/taosdata/driver-go/v3/af" +) + +func main() { + conn, err := af.Open("localhost", "root", "taosdata", "", 6030) + if err != nil { + fmt.Println("fail to connect, err:", err) + } + defer conn.Close() + _, err = conn.Exec("create database if not exists example") + if err != nil { + panic(err) + } + _, err = conn.Exec("use example") + if err != nil { + panic(err) + } + influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000" + err = conn.InfluxDBInsertLines([]string{influxdbData}, "ns") + if err != nil { + panic(err) + } + telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0" + err = conn.OpenTSDBInsertTelnetLines([]string{telnetData}) + if err != nil { + panic(err) + } + jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + err = conn.OpenTSDBInsertJsonPayload(jsonData) + if err != nil { + panic(err) + } +} +``` + + + + +```go +import ( + "database/sql" + "log" + "time" + + "github.com/taosdata/driver-go/v3/common" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/schemaless" +) + +func main() { + db, err := sql.Open("taosWS", "root:taosdata@ws(localhost:6041)/") + if err != nil { + log.Fatal(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists schemaless_ws") + if err != nil { + log.Fatal(err) + } + s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041/rest/schemaless", 1, + schemaless.SetDb("schemaless_ws"), + schemaless.SetReadTimeout(10*time.Second), + schemaless.SetWriteTimeout(10*time.Second), + schemaless.SetUser("root"), + schemaless.SetPassword("taosdata"), + schemaless.SetErrorHandler(func(err error) { + log.Fatal(err) + }), + )) + if err != nil { + panic(err) + } + influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000" + telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0" + jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + err = s.Insert(influxdbData, schemaless.InfluxDBLineProtocol, "ns", 0, common.GetReqID()) + if err != nil { + panic(err) + } + err = s.Insert(telnetData, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + err = s.Insert(jsonData, schemaless.OpenTSDBJsonFormatProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) } } ``` + + + +### ę‰§č”Œåø¦ęœ‰ reqId ēš„ę— ęØ”å¼å†™å…„ + +```go +func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error +``` + +åÆä»„é€ščæ‡ `common.GetReqID()` čŽ·å–å”Æäø€ id怂 + +### ę•°ę®č®¢é˜… + +TDengine Go čæžęŽ„å™Øę”ÆęŒč®¢é˜…åŠŸčƒ½ļ¼Œåŗ”ē”Ø API å¦‚äø‹ļ¼š + +#### åˆ›å»ŗ Topic + +```go + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq") + if err != nil { + panic(err) + } +``` + +#### åˆ›å»ŗ Consumer + +```go + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "group.id": "test", + "auto.offset.reset": "earliest", + "td.connect.ip": "127.0.0.1", + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "td.connect.port": "6030", + "client.id": "test_tmq_client", + "enable.auto.commit": "false", + "msg.with.table.name": "true", + }) + if err != nil { + panic(err) + } +``` + +#### č®¢é˜…ę¶ˆč“¹ę•°ę® + +```go + err = consumer.Subscribe("example_tmq_topic", nil) + if err != nil { + panic(err) + } + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } +``` + +#### ęŒ‡å®šč®¢é˜… Offset + +```go + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } +``` + +#### å…³é—­č®¢é˜… + +```go + err = consumer.Close() + if err != nil { + panic(err) + } +``` + +#### å®Œę•“ē¤ŗä¾‹ + + + + +```go +package main + +import ( + "fmt" + "os" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/af/tmq" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" +) + +func main() { + db, err := af.Open("", "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + _, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq") + if err != nil { + panic(err) + } + if err != nil { + panic(err) + } + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "group.id": "test", + "auto.offset.reset": "earliest", + "td.connect.ip": "127.0.0.1", + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "td.connect.port": "6030", + "client.id": "test_tmq_client", + "enable.auto.commit": "false", + "msg.with.table.name": "true", + }) + if err != nil { + panic(err) + } + err = consumer.Subscribe("example_tmq_topic", nil) + if err != nil { + panic(err) + } + _, err = db.Exec("create table example_tmq.t1 (ts timestamp,v int)") + if err != nil { + panic(err) + } + _, err = db.Exec("insert into example_tmq.t1 values(now,1)") + if err != nil { + panic(err) + } + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + + partitions, err = consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + } + + err = consumer.Close() + if err != nil { + panic(err) + } +} +``` + + + + +```go +package main + +import ( + "database/sql" + "fmt" + + "github.com/taosdata/driver-go/v3/common" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/tmq" +) + +func main() { + db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/") + if err != nil { + panic(err) + } + defer db.Close() + prepareEnv(db) + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "ws.url": "ws://127.0.0.1:6041/rest/tmq", + "ws.message.channelLen": uint(0), + "ws.message.timeout": common.DefaultMessageTimeout, + "ws.message.writeWait": common.DefaultWriteWait, + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "group.id": "example", + "client.id": "example_consumer", + "auto.offset.reset": "earliest", + }) + if err != nil { + panic(err) + } + err = consumer.Subscribe("example_ws_tmq_topic", nil) + if err != nil { + panic(err) + } + go func() { + _, err := db.Exec("create table example_ws_tmq.t_all(ts timestamp," + + "c1 bool," + + "c2 tinyint," + + "c3 smallint," + + "c4 int," + + "c5 bigint," + + "c6 tinyint unsigned," + + "c7 smallint unsigned," + + "c8 int unsigned," + + "c9 bigint unsigned," + + "c10 float," + + "c11 double," + + "c12 binary(20)," + + "c13 nchar(20)" + + ")") + if err != nil { + panic(err) + } + _, err = db.Exec("insert into example_ws_tmq.t_all values(now,true,2,3,4,5,6,7,8,9,10.123,11.123,'binary','nchar')") + if err != nil { + panic(err) + } + }() + for i := 0; i < 5; i++ { + ev := consumer.Poll(500) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + fmt.Printf("get message:%v\n", e) + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + consumer.Commit() + } + } + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + + partitions, err = consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + } + + err = consumer.Close() + if err != nil { + panic(err) + } +} + +func prepareEnv(db *sql.DB) { + _, err := db.Exec("create database example_ws_tmq WAL_RETENTION_PERIOD 86400") + if err != nil { + panic(err) + } + _, err = db.Exec("create topic example_ws_tmq_topic as database example_ws_tmq") + if err != nil { + panic(err) + } +} +``` + + + + +### ę›“å¤šē¤ŗä¾‹ēØ‹åŗ + +* [ē¤ŗä¾‹ēØ‹åŗ](https://github.com/taosdata/driver-go/tree/3.0/examples) +* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)怂 + ## åøøč§é—®é¢˜ 1. database/sql äø­ stmtļ¼ˆå‚ę•°ē»‘å®šļ¼‰ē›øå…³ęŽ„å£å“©ęŗƒ - REST äøę”ÆęŒå‚ę•°ē»‘å®šē›øå…³ęŽ„å£ļ¼Œå»ŗč®®ä½æē”Ø`db.Exec`和`db.Query`怂 + REST äøę”ÆęŒå‚ę•°ē»‘å®šē›øå…³ęŽ„å£ļ¼Œå»ŗč®®ä½æē”Ø`db.Exec`和`db.Query`怂 2. 使用 `use db` čÆ­å„åŽę‰§č”Œå…¶ä»–čÆ­å„ęŠ„é”™ `[0x217] Database not specified or available` - 在 REST ęŽ„å£äø­ SQL čÆ­å„ēš„ę‰§č”Œę— äøŠäø‹ę–‡å…³č”ļ¼Œä½æē”Ø `use db` čÆ­å„äøä¼šē”Ÿę•ˆļ¼Œč§£å†³åŠžę³•č§äøŠę–¹ä½æē”Øé™åˆ¶ē« čŠ‚ć€‚ + 在 REST ęŽ„å£äø­ SQL čÆ­å„ēš„ę‰§č”Œę— äøŠäø‹ę–‡å…³č”ļ¼Œä½æē”Ø `use db` čÆ­å„äøä¼šē”Ÿę•ˆļ¼Œč§£å†³åŠžę³•č§äøŠę–¹ä½æē”Øé™åˆ¶ē« čŠ‚ć€‚ 3. 使用 taosSql äøęŠ„é”™ä½æē”Ø taosRestful ꊄ错 `[0x217] Database not specified or available` - å› äøŗ REST ęŽ„å£ę— ēŠ¶ę€ļ¼Œä½æē”Ø `use db` čÆ­å„äøä¼šē”Ÿę•ˆļ¼Œč§£å†³åŠžę³•č§äøŠę–¹ä½æē”Øé™åˆ¶ē« čŠ‚ć€‚ + å› äøŗ REST ęŽ„å£ę— ēŠ¶ę€ļ¼Œä½æē”Ø `use db` čÆ­å„äøä¼šē”Ÿę•ˆļ¼Œč§£å†³åŠžę³•č§äøŠę–¹ä½æē”Øé™åˆ¶ē« čŠ‚ć€‚ 4. `readBufferSize` å‚ę•°č°ƒå¤§åŽę— ę˜Žę˜¾ę•ˆęžœ - `readBufferSize` č°ƒå¤§åŽä¼šå‡å°‘čŽ·å–ē»“ęžœę—¶ `syscall` ēš„č°ƒē”Øć€‚å¦‚ęžœęŸ„čÆ¢ē»“ęžœēš„ę•°ę®é‡äøå¤§ļ¼Œäæ®ę”¹čÆ„å‚ę•°äøä¼šåø¦ę„ę˜Žę˜¾ęå‡ļ¼Œå¦‚ęžœčÆ„å‚ę•°äæ®ę”¹čæ‡å¤§ļ¼Œē“¶é¢ˆä¼šåœØč§£ęž JSON ę•°ę®ć€‚å¦‚ęžœéœ€č¦ä¼˜åŒ–ęŸ„čÆ¢é€Ÿåŗ¦ļ¼Œéœ€č¦ę ¹ę®å®žé™…ęƒ…å†µč°ƒę•“čÆ„å€¼ę„č¾¾åˆ°ęŸ„čÆ¢ę•ˆęžœęœ€ä¼˜ć€‚ + `readBufferSize` č°ƒå¤§åŽä¼šå‡å°‘čŽ·å–ē»“ęžœę—¶ `syscall` ēš„č°ƒē”Øć€‚å¦‚ęžœęŸ„čÆ¢ē»“ęžœēš„ę•°ę®é‡äøå¤§ļ¼Œäæ®ę”¹čÆ„å‚ę•°äøä¼šåø¦ę„ę˜Žę˜¾ęå‡ļ¼Œå¦‚ęžœčÆ„å‚ę•°äæ®ę”¹čæ‡å¤§ļ¼Œē“¶é¢ˆä¼šåœØč§£ęž JSON ę•°ę®ć€‚å¦‚ęžœéœ€č¦ä¼˜åŒ–ęŸ„čÆ¢é€Ÿåŗ¦ļ¼Œéœ€č¦ę ¹ę®å®žé™…ęƒ…å†µč°ƒę•“čÆ„å€¼ę„č¾¾åˆ°ęŸ„čÆ¢ę•ˆęžœęœ€ä¼˜ć€‚ 5. `disableCompression` å‚ę•°č®¾ē½®äøŗ `false` ę—¶ęŸ„čÆ¢ę•ˆēŽ‡é™ä½Ž - 当 `disableCompression` å‚ę•°č®¾ē½®äøŗ `false` ę—¶ęŸ„čÆ¢ē»“ęžœä¼šä½æē”Ø `gzip` åŽ‹ē¼©åŽä¼ č¾“ļ¼Œę‹æåˆ°ę•°ę®åŽč¦å…ˆčæ›č”Œ `gzip` č§£åŽ‹ć€‚ + 当 `disableCompression` å‚ę•°č®¾ē½®äøŗ `false` ę—¶ęŸ„čÆ¢ē»“ęžœä¼šä½æē”Ø `gzip` åŽ‹ē¼©åŽä¼ č¾“ļ¼Œę‹æåˆ°ę•°ę®åŽč¦å…ˆčæ›č”Œ `gzip` č§£åŽ‹ć€‚ 6. `go get` å‘½ä»¤ę— ę³•čŽ·å–åŒ…ļ¼Œęˆ–č€…čŽ·å–åŒ…č¶…ę—¶ 设置 Go 代理 `go env -w GOPROXY=https://goproxy.cn,direct`怂 -## 常用 API - -### database/sql API - -* `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` - - 评 API ē”Øę„ę‰“å¼€ DBļ¼Œčæ”å›žäø€äøŖē±»åž‹äøŗ \*DB ēš„åÆ¹č±”ć€‚ - -:::info -评 API ęˆåŠŸåˆ›å»ŗēš„ę—¶å€™ļ¼Œå¹¶ę²”ęœ‰åšęƒé™ē­‰ę£€ęŸ„ļ¼ŒåŖęœ‰åœØēœŸę­£ę‰§č”Œ Query ꈖ者 Exec ēš„ę—¶å€™ę‰čƒ½ēœŸę­£ēš„åŽ»åˆ›å»ŗčæžęŽ„ļ¼Œå¹¶åŒę—¶ę£€ęŸ„ user/password/host/port ę˜Æäøę˜Æåˆę³•ć€‚ -::: - -* `func (db *DB) Exec(query string, args ...interface{}) (Result, error)` - - `sql.Open` å†…ē½®ēš„ę–¹ę³•ļ¼Œē”Øę„ę‰§č”ŒéžęŸ„čÆ¢ē›øå…³ SQL怂 - -* `func (db *DB) Query(query string, args ...interface{}) (*Rows, error)` - - `sql.Open` å†…ē½®ēš„ę–¹ę³•ļ¼Œē”Øę„ę‰§č”ŒęŸ„čÆ¢čÆ­å„ć€‚ - -### 高级功能(af)API - -`af` åŒ…å°č£…äŗ†čæžęŽ„ē®”ē†ć€č®¢é˜…ć€schemalessć€å‚ę•°ē»‘å®šē­‰ TDengine é«˜ēŗ§åŠŸčƒ½ć€‚ - -#### čæžęŽ„ē®”ē† - -* `af.Open(host, user, pass, db string, port int) (*Connector, error)` - - 评 API é€ščæ‡ cgo åˆ›å»ŗäøŽ taosd ēš„čæžęŽ„ć€‚ - -* `func (conn *Connector) Close() error` - - å…³é—­äøŽ taosd ēš„čæžęŽ„ć€‚ - -#### č®¢é˜… - -* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)` - - åˆ›å»ŗę¶ˆč“¹č€…ć€‚ - -* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `rebalanceCb` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - č®¢é˜…å•äøŖäø»é¢˜ć€‚ - -* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `rebalanceCb` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - č®¢é˜…äø»é¢˜ć€‚ - -* `func (c *Consumer) Poll(timeoutMs int) tmq.Event` - - č½®čÆ¢ę¶ˆęÆć€‚ - -* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `tmq.TopicPartition` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - ęäŗ¤ę¶ˆęÆć€‚ - -* `func (c *Consumer) Assignment() (partitions []tmq.TopicPartition, err error)` - - čŽ·å–ę¶ˆč“¹čæ›åŗ¦ć€‚(éœ€č¦ TDengine >= 3.0.5.0, driver-go >= v3.5.0) - -* `func (c *Consumer) Seek(partition tmq.TopicPartition, ignoredTimeoutMs int) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `ignoredTimeoutMs` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - ęŒ‰ē…§ęŒ‡å®šēš„čæ›åŗ¦ę¶ˆč“¹ć€‚(éœ€č¦ TDengine >= 3.0.5.0, driver-go >= v3.5.0) - -* `func (c *Consumer) Close() error` - - å…³é—­čæžęŽ„ć€‚ - -#### schemaless - -* `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` - - 写兄 InfluxDB č”Œåč®®ć€‚ - -* `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` - - 写兄 OpenTDSB telnet åč®®ę•°ę®ć€‚ - -* `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` - - 写兄 OpenTSDB JSON åč®®ę•°ę®ć€‚ - -#### å‚ę•°ē»‘å®š - -* `func (conn *Connector) StmtExecute(sql string, params *param.Param) (res driver.Result, err error)` - - å‚ę•°ē»‘å®šå•č”Œę’å…„ć€‚ - -* `func (conn *Connector) InsertStmt() *insertstmt.InsertStmt` - - åˆå§‹åŒ–å‚ę•°ć€‚ - -* `func (stmt *InsertStmt) Prepare(sql string) error` - - å‚ę•°ē»‘å®šé¢„å¤„ē† SQL čÆ­å„ć€‚ - -* `func (stmt *InsertStmt) SetTableName(name string) error` - - å‚ę•°ē»‘å®šč®¾ē½®č”Øåć€‚ - -* `func (stmt *InsertStmt) SetSubTableName(name string) error` - - å‚ę•°ē»‘å®šč®¾ē½®å­č”Øåć€‚ - -* `func (stmt *InsertStmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` - - å‚ę•°ē»‘å®šå¤šč”Œę•°ę®ć€‚ - -* `func (stmt *InsertStmt) AddBatch() error` - - ę·»åŠ åˆ°å‚ę•°ē»‘å®šę‰¹å¤„ē†ć€‚ - -* `func (stmt *InsertStmt) Execute() error` - - ę‰§č”Œå‚ę•°ē»‘å®šć€‚ - -* `func (stmt *InsertStmt) GetAffectedRows() int` - - čŽ·å–å‚ę•°ē»‘å®šę’å…„å—å½±å“č”Œę•°ć€‚ - -* `func (stmt *InsertStmt) Close() error` - - ē»“ęŸå‚ę•°ē»‘å®šć€‚ - -### é€ščæ‡ WebSocket č®¢é˜… - -* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)` - - åˆ›å»ŗę¶ˆč“¹č€…ć€‚ - -* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `rebalanceCb` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - č®¢é˜…å•äøŖäø»é¢˜ć€‚ - -* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `rebalanceCb` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - č®¢é˜…äø»é¢˜ć€‚ - -* `func (c *Consumer) Poll(timeoutMs int) tmq.Event` - - č½®čÆ¢ę¶ˆęÆć€‚ - -* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `tmq.TopicPartition` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - ęäŗ¤ę¶ˆęÆć€‚ - -* `func (c *Consumer) Assignment() (partitions []tmq.TopicPartition, err error)` - - čŽ·å–ę¶ˆč“¹čæ›åŗ¦ć€‚(éœ€č¦ TDengine >= 3.0.5.0, driver-go >= v3.5.0) - -* `func (c *Consumer) Seek(partition tmq.TopicPartition, ignoredTimeoutMs int) error` -ę³Øę„ļ¼šå‡ŗäŗŽå…¼å®¹ē›®ēš„äæē•™ `ignoredTimeoutMs` å‚ę•°ļ¼Œå½“å‰ęœŖä½æē”Ø - - ęŒ‰ē…§ęŒ‡å®šēš„čæ›åŗ¦ę¶ˆč“¹ć€‚(éœ€č¦ TDengine >= 3.0.5.0, driver-go >= v3.5.0) - -* `func (c *Consumer) Close() error` - - å…³é—­čæžęŽ„ć€‚ - -å®Œę•“č®¢é˜…ē¤ŗä¾‹å‚č§ [GitHub 示例文件](https://github.com/taosdata/driver-go/blob/main/examples/tmqoverws/main.go) - -### é€ščæ‡ WebSocket čæ›č”Œå‚ę•°ē»‘å®š - -* `func NewConnector(config *Config) (*Connector, error)` - - åˆ›å»ŗčæžęŽ„ć€‚ - -* `func (c *Connector) Init() (*Stmt, error)` - - åˆå§‹åŒ–å‚ę•°ć€‚ - -* `func (c *Connector) Close() error` - - å…³é—­čæžęŽ„ć€‚ - -* `func (s *Stmt) Prepare(sql string) error` - - å‚ę•°ē»‘å®šé¢„å¤„ē† SQL čÆ­å„ć€‚ - -* `func (s *Stmt) SetTableName(name string) error` - - å‚ę•°ē»‘å®šč®¾ē½®č”Øåć€‚ - -* `func (s *Stmt) SetTags(tags *param.Param, bindType *param.ColumnType) error` - - å‚ę•°ē»‘å®šč®¾ē½®ę ‡ē­¾ć€‚ - -* `func (s *Stmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` - - å‚ę•°ē»‘å®šå¤šč”Œę•°ę®ć€‚ - -* `func (s *Stmt) AddBatch() error` - - ę·»åŠ åˆ°å‚ę•°ē»‘å®šę‰¹å¤„ē†ć€‚ - -* `func (s *Stmt) Exec() error` - - ę‰§č”Œå‚ę•°ē»‘å®šć€‚ - -* `func (s *Stmt) GetAffectedRows() int` - - čŽ·å–å‚ę•°ē»‘å®šę’å…„å—å½±å“č”Œę•°ć€‚ - -* `func (s *Stmt) Close() error` - - ē»“ęŸå‚ę•°ē»‘å®šć€‚ - -å®Œę•“å‚ę•°ē»‘å®šē¤ŗä¾‹å‚č§ [GitHub 示例文件](https://github.com/taosdata/driver-go/blob/main/examples/stmtoverws/main.go) - ## API å‚č€ƒ å…ØéƒØ API 见 [driver-go 文攣](https://pkg.go.dev/github.com/taosdata/driver-go/v3) diff --git a/docs/zh/08-connector/26-rust.mdx b/docs/zh/08-connector/26-rust.mdx index c23228c8cf..79a6badfea 100644 --- a/docs/zh/08-connector/26-rust.mdx +++ b/docs/zh/08-connector/26-rust.mdx @@ -30,21 +30,57 @@ Websocket čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Rust ēš„å¹³å°ć€‚ | Rust čæžęŽ„å™Øē‰ˆęœ¬ | TDengine ē‰ˆęœ¬ | 主要功能 | | :----------------: | :--------------: | :--------------------------------------------------: | -| v0.8.10 | 3.0.5.0 or later | ę¶ˆęÆč®¢é˜…ļ¼ščŽ·å–ę¶ˆč“¹čæ›åŗ¦åŠęŒ‰ē…§ęŒ‡å®ščæ›åŗ¦å¼€å§‹ę¶ˆč“¹ć€‚ | +| v0.8.12 | 3.0.5.0 or later | ę¶ˆęÆč®¢é˜…ļ¼ščŽ·å–ę¶ˆč“¹čæ›åŗ¦åŠęŒ‰ē…§ęŒ‡å®ščæ›åŗ¦å¼€å§‹ę¶ˆč“¹ć€‚ | | v0.8.0 | 3.0.4.0 | ę”ÆęŒę— ęØ”å¼å†™å…„ć€‚ | | v0.7.6 | 3.0.3.0 | ę”ÆęŒåœØčÆ·ę±‚äø­ä½æē”Ø req_id怂 | | v0.6.0 | 3.0.0.0 | åŸŗē”€åŠŸčƒ½ć€‚ | Rust čæžęŽ„å™Øä»ē„¶åœØåæ«é€Ÿå¼€å‘äø­ļ¼Œ1.0 ä¹‹å‰ę— ę³•äæčÆå…¶å‘åŽå…¼å®¹ć€‚å»ŗč®®ä½æē”Ø 3.0 ē‰ˆęœ¬ä»„äøŠēš„ TDengineļ¼Œä»„éæå…å·²ēŸ„é—®é¢˜ć€‚ -## 安装 +## 处理错误 + +åœØęŠ„é”™åŽļ¼ŒåÆä»„čŽ·å–åˆ°é”™čÆÆēš„å…·ä½“äæ”ęÆļ¼š + +```rust +match conn.exec(sql) { + Ok(_) => { + Ok(()) + } + Err(e) => { + eprintln!("ERROR: {:?}", e); + Err(e) + } +} +``` + +## TDengine DataType 和 Rust DataType + +TDengine ē›®å‰ę”ÆęŒę—¶é—“ęˆ³ć€ę•°å­—ć€å­—ē¬¦ć€åøƒå°”ē±»åž‹ļ¼ŒäøŽ Rust åÆ¹åŗ”ē±»åž‹č½¬ę¢å¦‚äø‹ļ¼š + +| TDengine DataType | Rust DataType | +| ----------------- | ----------------- | +| TIMESTAMP | Timestamp | +| INT | i32 | +| BIGINT | i64 | +| FLOAT | f32 | +| DOUBLE | f64 | +| SMALLINT | i16 | +| TINYINT | i8 | +| BOOL | bool | +| BINARY | Vec | +| NCHAR | String | +| JSON | serde_json::Value | + +**ę³Øę„**:JSON ē±»åž‹ä»…åœØ tag äø­ę”ÆęŒć€‚ + +## 安装歄骤 ### å®‰č£…å‰å‡†å¤‡ * 安装 Rust 开发巄具链 * å¦‚ęžœä½æē”ØåŽŸē”ŸčæžęŽ„ļ¼ŒčÆ·å®‰č£… TDengine å®¢ęˆ·ē«Æé©±åŠØļ¼Œå…·ä½“ę­„éŖ¤čÆ·å‚č€ƒ[å®‰č£…å®¢ęˆ·ē«Æé©±åŠØ](../#å®‰č£…å®¢ęˆ·ē«Æé©±åŠØ) -### 添加 taos ä¾čµ– +### å®‰č£…čæžęŽ„å™Ø ę ¹ę®é€‰ę‹©ēš„čæžęŽ„ę–¹å¼ļ¼ŒęŒ‰ē…§å¦‚äø‹čÆ“ę˜ŽåœØ [Rust](https://rust-lang.org) é”¹ē›®äø­ę·»åŠ  [taos][taos] ä¾čµ–ļ¼š @@ -151,7 +187,8 @@ let builder = TaosBuilder::from_dsn("taos://localhost:6030")?; let conn1 = builder.build(); // use websocket protocol. -let conn2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?; +let builder2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?; +let conn2 = builder2.build(); ``` å»ŗē«‹čæžęŽ„åŽļ¼Œę‚ØåÆä»„čæ›č”Œē›øå…³ę•°ę®åŗ“ę“ä½œļ¼š @@ -233,41 +270,191 @@ async fn demo(taos: &Taos, db: &str) -> Result<(), Error> { ## 使用示例 -### å†™å…„ę•°ę® +### åˆ›å»ŗę•°ę®åŗ“å’Œč”Ø -#### SQL 写兄 +```rust +use taos::*; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let dsn = "taos://localhost:6030"; + let builder = TaosBuilder::from_dsn(dsn)?; + + let taos = builder.build()?; + + let db = "query"; + + // create database + taos.exec_many([ + format!("DROP DATABASE IF EXISTS `{db}`"), + format!("CREATE DATABASE `{db}`"), + format!("USE `{db}`"), + ]) + .await?; + + // create table + taos.exec_many([ + // create super table + "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ + TAGS (`groupid` INT, `location` BINARY(16))", + // create child table + "CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')", + ]).await?; +} +``` + +> **ę³Øę„**ļ¼šå¦‚ęžœäøä½æē”Ø `use db` ęŒ‡å®šę•°ę®åŗ“ļ¼Œåˆ™åŽē»­åÆ¹č”Øēš„ę“ä½œéƒ½éœ€č¦å¢žåŠ ę•°ę®åŗ“åē§°ä½œäøŗå‰ē¼€ļ¼Œå¦‚ db.tb怂 + +### ę’å…„ę•°ę® -#### STMT 写兄 - - - -#### Schemaless 写兄 - - - ### ęŸ„čÆ¢ę•°ę® -## API å‚č€ƒ +### ę‰§č”Œåø¦ęœ‰ req_id ēš„ SQL -### čæžęŽ„ęž„é€ å™Ø - -é€ščæ‡ DSN ę„ęž„å»ŗäø€äøŖčæžęŽ„å™Øęž„é€ å™Øć€‚ +ę­¤ req_id åÆē”ØäŗŽčÆ·ę±‚é“¾č·Æčæ½čøŖć€‚ ```rust -let cfg = TaosBuilder::default().build()?; +let rs = taos.query_with_req_id("select * from stable where tag1 is null", 1)?; ``` -使用 `builder` åÆ¹č±”åˆ›å»ŗå¤šäøŖčæžęŽ„ļ¼š +### é€ščæ‡å‚ę•°ē»‘å®šå†™å…„ę•°ę® + +TDengine ēš„ Rust čæžęŽ„å™Øå®žēŽ°äŗ†å‚ę•°ē»‘å®šę–¹å¼åÆ¹ę•°ę®å†™å…„ļ¼ˆINSERTļ¼‰åœŗę™Æēš„ę”ÆęŒć€‚é‡‡ē”Øčæ™ē§ę–¹å¼å†™å…„ę•°ę®ę—¶ļ¼Œčƒ½éæå… SQL čÆ­ę³•č§£ęžēš„čµ„ęŗę¶ˆč€—ļ¼Œä»Žč€ŒåœØå¾ˆå¤šęƒ…å†µäø‹ę˜¾č‘—ęå‡å†™å…„ę€§čƒ½ć€‚ + +å‚ę•°ē»‘å®šęŽ„å£čÆ¦č§[APIå‚č€ƒ](#stmt-api) + + + +### ę— ęØ”å¼å†™å…„ + +TDengine ę”ÆęŒę— ęØ”å¼å†™å…„åŠŸčƒ½ć€‚ę— ęØ”å¼å†™å…„å…¼å®¹ InfluxDB ēš„ č”Œåč®®ļ¼ˆLine Protocol)、OpenTSDB ēš„ telnet č”Œåč®®å’Œ OpenTSDB ēš„ JSON ę ¼å¼åč®®ć€‚čÆ¦ęƒ…čÆ·å‚č§[ę— ęØ”å¼å†™å…„](../../reference/schemaless/)怂 + + + +### ę‰§č”Œåø¦ęœ‰ req_id ēš„ę— ęØ”å¼å†™å…„ + +ę­¤ req_id åÆē”ØäŗŽčÆ·ę±‚é“¾č·Æčæ½čøŖć€‚ ```rust -let conn: Taos = cfg.build(); +let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .data(data) + .req_id(100u64) + .build()?; + +client.put(&sml_data)? ``` -### čæžęŽ„ę±  +### ę•°ę®č®¢é˜… + +TDengine é€ščæ‡ę¶ˆęÆé˜Ÿåˆ— [TMQ](../../../taos-sql/tmq/) åÆåŠØäø€äøŖč®¢é˜…ć€‚ + +#### åˆ›å»ŗ Topic + +```rust +taos.exec_many([ + // create topic for subscription + format!("CREATE TOPIC tmq_meters with META AS DATABASE {db}") +]) +.await?; +``` + +#### åˆ›å»ŗ Consumer + +从 DSN å¼€å§‹ļ¼Œęž„å»ŗäø€äøŖ TMQ čæžęŽ„å™Øć€‚ + +```rust +let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; +``` + +åˆ›å»ŗę¶ˆč“¹č€…ļ¼š + +```rust +let mut consumer = tmq.build()?; +``` + +#### č®¢é˜…ę¶ˆč“¹ę•°ę® + +ę¶ˆč“¹č€…åÆč®¢é˜…äø€äøŖęˆ–å¤šäøŖ `TOPIC`怂 + +```rust +consumer.subscribe(["tmq_meters"]).await?; +``` + +TMQ ę¶ˆęÆé˜Ÿåˆ—ę˜Æäø€äøŖ [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) ē±»åž‹ļ¼ŒåÆä»„ä½æē”Øē›øåŗ” API åÆ¹ęÆäøŖę¶ˆęÆčæ›č”Œę¶ˆč“¹ļ¼Œå¹¶é€ščæ‡ `.commit` čæ›č”Œå·²ę¶ˆč“¹ę ‡č®°ć€‚ + +```rust +{ + let mut stream = consumer.stream(); + + while let Some((offset, message)) = stream.try_next().await? { + // get information from offset + + // the topic + let topic = offset.topic(); + // the vgroup id, like partition id in kafka. + let vgroup_id = offset.vgroup_id(); + println!("* in vgroup id {vgroup_id} of topic {topic}\n"); + + if let Some(data) = message.into_data() { + while let Some(block) = data.fetch_raw_block().await? { + // one block for one table, get table name if needed + let name = block.table_name(); + let records: Vec = block.deserialize().try_collect()?; + println!( + "** table: {}, got {} records: {:#?}\n", + name.unwrap(), + records.len(), + records + ); + } + } + consumer.commit(offset).await?; + } +} +``` + +čŽ·å–ę¶ˆč“¹čæ›åŗ¦ļ¼š + +ē‰ˆęœ¬č¦ę±‚ connector-rust >= v0.8.8, TDengine >= 3.0.5.0 + +```rust +let assignments = consumer.assignments().await.unwrap(); +``` + +#### ęŒ‡å®šč®¢é˜… Offset + +ęŒ‰ē…§ęŒ‡å®šēš„čæ›åŗ¦ę¶ˆč“¹ļ¼š + +ē‰ˆęœ¬č¦ę±‚ connector-rust >= v0.8.8, TDengine >= 3.0.5.0 + +```rust +consumer.offset_seek(topic, vgroup_id, offset).await; +``` + +#### å…³é—­č®¢é˜… + +```rust +consumer.unsubscribe().await; +``` + +åÆ¹äŗŽ TMQ DSN, ęœ‰ä»„äø‹é…ē½®é”¹åÆä»„čæ›č”Œč®¾ē½®ļ¼Œéœ€č¦ę³Øę„ēš„ę˜Æļ¼Œ`group.id` ę˜Æåæ…é”»ēš„ć€‚ + +- `group.id`: åŒäø€äøŖę¶ˆč“¹č€…ē»„ļ¼Œå°†ä»„č‡³å°‘ę¶ˆč“¹äø€ę¬”ēš„ę–¹å¼čæ›č”Œę¶ˆęÆč“Ÿč½½å‡č””ć€‚ +- `client.id`: åÆé€‰ēš„č®¢é˜…å®¢ęˆ·ē«ÆčÆ†åˆ«é”¹ć€‚ +- `auto.offset.reset`: åÆé€‰åˆå§‹åŒ–č®¢é˜…čµ·ē‚¹ļ¼Œ *earliest* äøŗä»Žå¤“å¼€å§‹č®¢é˜…ļ¼Œ *latest* äøŗä»…ä»Žęœ€ę–°ę•°ę®å¼€å§‹č®¢é˜…ļ¼Œé»˜č®¤äøŗä»Žå¤“č®¢é˜…ć€‚ę³Øę„ļ¼Œę­¤é€‰é”¹åœØåŒäø€äøŖ `group.id` äø­ä»…ē”Ÿę•ˆäø€ę¬”ć€‚ +- `enable.auto.commit`: 当设置为 `true` ę—¶ļ¼Œå°†åÆē”Øč‡ŖåŠØę ‡č®°ęØ”å¼ļ¼Œå½“åÆ¹ę•°ę®äø€č‡“ę€§äøę•ę„Ÿę—¶ļ¼ŒåÆä»„åÆē”Øę­¤ę–¹å¼ć€‚ +- `auto.commit.interval.ms`: č‡ŖåŠØę ‡č®°ēš„ę—¶é—“é—“éš”ć€‚ + +#### å®Œę•“ē¤ŗä¾‹ + +å®Œę•“č®¢é˜…ē¤ŗä¾‹å‚č§ [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/subscribe_demo.rs). + +### äøŽčæžęŽ„ę± ä½æē”Ø åœØå¤ę‚åŗ”ē”Øäø­ļ¼Œå»ŗč®®åÆē”ØčæžęŽ„ę± ć€‚[taos] ēš„čæžęŽ„ę± é»˜č®¤ļ¼ˆå¼‚ę­„ęØ”å¼ļ¼‰ä½æē”Ø [deadpool] å®žēŽ°ć€‚ @@ -295,7 +482,17 @@ let pool: Pool = Pool::builder(Manager::from_dsn(self.dsn.clone()). let taos = pool.get()?; ``` -### čæžęŽ„ +### ę›“å¤šē¤ŗä¾‹ēØ‹åŗ + +ē¤ŗä¾‹ēØ‹åŗęŗē ä½äŗŽ `TDengine/examples/rust` äø‹: + +čÆ·å‚č€ƒļ¼š[rust example](https://github.com/taosdata/TDengine/tree/3.0/examples/rust) + +## åøøč§é—®é¢˜ + +čÆ·å‚č€ƒ [FAQ](../../../train-faq/faq) + +## API å‚č€ƒ [Taos][struct.Taos] åÆ¹č±”ęä¾›äŗ†å¤šäøŖę•°ę®åŗ“ę“ä½œēš„ API: @@ -381,9 +578,13 @@ let taos = pool.get()?; - `.create_database(database: &str)`: ę‰§č”Œ `CREATE DATABASE` čÆ­å„ć€‚ - `.use_database(database: &str)`: ę‰§č”Œ `USE` čÆ­å„ć€‚ -é™¤ę­¤ä¹‹å¤–ļ¼ŒčÆ„ē»“ęž„ä¹Ÿę˜Æ [å‚ę•°ē»‘å®š](#å‚ę•°ē»‘å®šęŽ„å£) 和 [č”Œåč®®ęŽ„å£](#č”Œåč®®ęŽ„å£) ēš„å…„å£ļ¼Œä½æē”Øę–¹ę³•čÆ·å‚č€ƒå…·ä½“ēš„ API čÆ“ę˜Žć€‚ +é™¤ę­¤ä¹‹å¤–ļ¼ŒčÆ„ē»“ęž„ä¹Ÿę˜Æå‚ę•°ē»‘å®šå’Œč”Œåč®®ęŽ„å£ēš„å…„å£ļ¼Œä½æē”Øę–¹ę³•čÆ·å‚č€ƒå…·ä½“ēš„ API čÆ“ę˜Žć€‚ -### å‚ę•°ē»‘å®šęŽ„å£ +

+ +å‚ę•°ē»‘å®šęŽ„å£ + +

äøŽ C ęŽ„å£ē±»ä¼¼ļ¼ŒRust ęä¾›å‚ę•°ē»‘å®šęŽ„å£ć€‚é¦–å…ˆļ¼Œé€ščæ‡ [Taos][struct.Taos] åÆ¹č±”åˆ›å»ŗäø€äøŖ SQL čÆ­å„ēš„å‚ę•°ē»‘å®šåÆ¹č±” [Stmt]: @@ -394,7 +595,7 @@ stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)")?; å‚ę•°ē»‘å®šåÆ¹č±”ęä¾›äŗ†äø€ē»„ęŽ„å£ē”ØäŗŽå®žēŽ°å‚ę•°ē»‘å®šļ¼š -#### `.set_tbname(name)` +`.set_tbname(name)` ē”ØäŗŽē»‘å®šč”Øåć€‚ @@ -403,7 +604,7 @@ let mut stmt = taos.stmt("insert into ? values(? ,?)")?; stmt.set_tbname("d0")?; ``` -#### `.set_tags(&[tag])` +`.set_tags(&[tag])` 当 SQL čÆ­å„ä½æē”Øč¶…ēŗ§č”Øę—¶ļ¼Œē”ØäŗŽē»‘å®šå­č”Øč”Øåå’Œę ‡ē­¾å€¼ļ¼š @@ -413,7 +614,7 @@ stmt.set_tbname("d0")?; stmt.set_tags(&[Value::VarChar("ę¶›ę€".to_string())])?; ``` -#### `.bind(&[column])` +`.bind(&[column])` ē”ØäŗŽē»‘å®šå€¼ē±»åž‹ć€‚ä½æē”Ø [ColumnView] ē»“ęž„ä½“ęž„å»ŗéœ€č¦ēš„ē±»åž‹å¹¶ē»‘å®šļ¼š @@ -437,7 +638,7 @@ let params = vec![ let rows = stmt.bind(¶ms)?.add_batch()?.execute()?; ``` -#### `.execute()` +`.execute()` ę‰§č”Œ SQL怂[Stmt] åÆ¹č±”åÆä»„å¤ē”Øļ¼ŒåœØę‰§č”ŒåŽåÆä»„é‡ę–°ē»‘å®šå¹¶ę‰§č”Œć€‚ę‰§č”Œå‰čÆ·ē”®äæę‰€ęœ‰ę•°ę®å·²é€ščæ‡ `.add_batch` åŠ å…„åˆ°ę‰§č”Œé˜Ÿåˆ—äø­ć€‚ @@ -452,92 +653,6 @@ stmt.execute()?; äø€äøŖåÆčæč”Œēš„ē¤ŗä¾‹čÆ·č§ [GitHub äøŠēš„ē¤ŗä¾‹](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)怂 -### č®¢é˜… - -TDengine é€ščæ‡ę¶ˆęÆé˜Ÿåˆ— [TMQ](../../../taos-sql/tmq/) åÆåŠØäø€äøŖč®¢é˜…ć€‚ - -从 DSN å¼€å§‹ļ¼Œęž„å»ŗäø€äøŖ TMQ čæžęŽ„å™Øć€‚ - -```rust -let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; -``` - -åˆ›å»ŗę¶ˆč“¹č€…ļ¼š - -```rust -let mut consumer = tmq.build()?; -``` - -ę¶ˆč“¹č€…åÆč®¢é˜…äø€äøŖęˆ–å¤šäøŖ `TOPIC`怂 - -```rust -consumer.subscribe(["tmq_meters"]).await?; -``` - -TMQ ę¶ˆęÆé˜Ÿåˆ—ę˜Æäø€äøŖ [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) ē±»åž‹ļ¼ŒåÆä»„ä½æē”Øē›øåŗ” API åÆ¹ęÆäøŖę¶ˆęÆčæ›č”Œę¶ˆč“¹ļ¼Œå¹¶é€ščæ‡ `.commit` čæ›č”Œå·²ę¶ˆč“¹ę ‡č®°ć€‚ - -```rust -{ - let mut stream = consumer.stream(); - - while let Some((offset, message)) = stream.try_next().await? { - // get information from offset - - // the topic - let topic = offset.topic(); - // the vgroup id, like partition id in kafka. - let vgroup_id = offset.vgroup_id(); - println!("* in vgroup id {vgroup_id} of topic {topic}\n"); - - if let Some(data) = message.into_data() { - while let Some(block) = data.fetch_raw_block().await? { - // one block for one table, get table name if needed - let name = block.table_name(); - let records: Vec = block.deserialize().try_collect()?; - println!( - "** table: {}, got {} records: {:#?}\n", - name.unwrap(), - records.len(), - records - ); - } - } - consumer.commit(offset).await?; - } -} -``` - -čŽ·å–ę¶ˆč“¹čæ›åŗ¦ļ¼š - -ē‰ˆęœ¬č¦ę±‚ connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -let assignments = consumer.assignments().await.unwrap(); -``` - -ęŒ‰ē…§ęŒ‡å®šēš„čæ›åŗ¦ę¶ˆč“¹ļ¼š - -ē‰ˆęœ¬č¦ę±‚ connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -consumer.offset_seek(topic, vgroup_id, offset).await; -``` - -åœę­¢č®¢é˜…ļ¼š - -```rust -consumer.unsubscribe().await; -``` - -åÆ¹äŗŽ TMQ DSN, ęœ‰ä»„äø‹é…ē½®é”¹åÆä»„čæ›č”Œč®¾ē½®ļ¼Œéœ€č¦ę³Øę„ēš„ę˜Æļ¼Œ`group.id` ę˜Æåæ…é”»ēš„ć€‚ - -- `group.id`: åŒäø€äøŖę¶ˆč“¹č€…ē»„ļ¼Œå°†ä»„č‡³å°‘ę¶ˆč“¹äø€ę¬”ēš„ę–¹å¼čæ›č”Œę¶ˆęÆč“Ÿč½½å‡č””ć€‚ -- `client.id`: åÆé€‰ēš„č®¢é˜…å®¢ęˆ·ē«ÆčÆ†åˆ«é”¹ć€‚ -- `auto.offset.reset`: åÆé€‰åˆå§‹åŒ–č®¢é˜…čµ·ē‚¹ļ¼Œ *earliest* äøŗä»Žå¤“å¼€å§‹č®¢é˜…ļ¼Œ *latest* äøŗä»…ä»Žęœ€ę–°ę•°ę®å¼€å§‹č®¢é˜…ļ¼Œé»˜č®¤äøŗä»Žå¤“č®¢é˜…ć€‚ę³Øę„ļ¼Œę­¤é€‰é”¹åœØåŒäø€äøŖ `group.id` äø­ä»…ē”Ÿę•ˆäø€ę¬”ć€‚ -- `enable.auto.commit`: 当设置为 `true` ę—¶ļ¼Œå°†åÆē”Øč‡ŖåŠØę ‡č®°ęØ”å¼ļ¼Œå½“åÆ¹ę•°ę®äø€č‡“ę€§äøę•ę„Ÿę—¶ļ¼ŒåÆä»„åÆē”Øę­¤ę–¹å¼ć€‚ -- `auto.commit.interval.ms`: č‡ŖåŠØę ‡č®°ēš„ę—¶é—“é—“éš”ć€‚ - -å®Œę•“č®¢é˜…ē¤ŗä¾‹å‚č§ [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/subscribe_demo.rs). å…¶ä»–ē›øå…³ē»“ęž„ä½“ API ä½æē”ØčÆ“ę˜ŽčÆ·ē§»ę­„ Rust ę–‡ę”£ę‰˜ē®”ē½‘é”µļ¼šć€‚ diff --git a/docs/zh/08-connector/30-python.mdx b/docs/zh/08-connector/30-python.mdx index 8752dc2145..0b9f2d75a7 100644 --- a/docs/zh/08-connector/30-python.mdx +++ b/docs/zh/08-connector/30-python.mdx @@ -21,10 +21,25 @@ Python čæžęŽ„å™Øēš„ęŗē ę‰˜ē®”åœØ [GitHub](https://github.com/taosdata/taos-con - åŽŸē”ŸčæžęŽ„[ę”ÆęŒēš„å¹³å°](../#ę”ÆęŒēš„å¹³å°)和 TDengine å®¢ęˆ·ē«Æę”ÆęŒēš„å¹³å°äø€č‡“ć€‚ - REST čæžęŽ„ę”ÆęŒę‰€ęœ‰čƒ½čæč”Œ Python ēš„å¹³å°ć€‚ -## ē‰ˆęœ¬é€‰ę‹© +### ę”ÆęŒēš„åŠŸčƒ½ + +- åŽŸē”ŸčæžęŽ„ę”ÆęŒ TDengine ēš„ę‰€ęœ‰ę øåæƒåŠŸčƒ½ļ¼Œ åŒ…ę‹¬ļ¼š čæžęŽ„ē®”ē†ć€ę‰§č”Œ SQLć€å‚ę•°ē»‘å®šć€č®¢é˜…ć€ę— ęØ”å¼å†™å…„ļ¼ˆschemaless)。 +- REST čæžęŽ„ę”ÆęŒēš„åŠŸčƒ½åŒ…ę‹¬ļ¼ščæžęŽ„ē®”ē†ć€ę‰§č”Œ SQL怂 (é€ščæ‡ę‰§č”Œ SQL åÆä»„ļ¼š ē®”ē†ę•°ę®åŗ“ć€ē®”ē†č”Øå’Œč¶…ēŗ§č”Øć€å†™å…„ę•°ę®ć€ęŸ„čÆ¢ę•°ę®ć€åˆ›å»ŗčæžē»­ęŸ„čÆ¢ē­‰)怂 + +## åŽ†å²ē‰ˆęœ¬ ę— č®ŗä½æē”Øä»€ä¹ˆē‰ˆęœ¬ēš„ TDengine éƒ½å»ŗč®®ä½æē”Øęœ€ę–°ē‰ˆęœ¬ēš„ `taospy`怂 +|Python Connector ē‰ˆęœ¬|äø»č¦å˜åŒ–| +|:-------------------:|:----:| +|2.7.9|ę•°ę®č®¢é˜…ę”ÆęŒčŽ·å–ę¶ˆč“¹čæ›åŗ¦å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦| +|2.7.8|ę–°å¢ž `execute_many`| + +|Python Websocket Connector ē‰ˆęœ¬|äø»č¦å˜åŒ–| +|:----------------------------:|:-----:| +|0.2.5|1. ę•°ę®č®¢é˜…ę”ÆęŒčŽ·å–ę¶ˆč“¹čæ›åŗ¦å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦
2. ę”ÆęŒ schemaless
3. ę”ÆęŒ STMT| +|0.2.4|ę•°ę®č®¢é˜…ę–°å¢žå–ę¶ˆč®¢é˜…ę–¹ę³•| + ## 处理异常 Python čæžęŽ„å™ØåÆčƒ½ä¼šäŗ§ē”Ÿ 4 ē§å¼‚åøøļ¼š @@ -55,12 +70,25 @@ Python Connector ēš„ę‰€ęœ‰ę•°ę®åŗ“ę“ä½œå¦‚ęžœå‡ŗēŽ°å¼‚åøøļ¼Œéƒ½ä¼šē›“ęŽ„ęŠ›å‡ŗ {{#include docs/examples/python/handle_exception.py}} ``` -## ę”ÆęŒēš„åŠŸčƒ½ +TDengine DataType 和 Python DataType -- åŽŸē”ŸčæžęŽ„ę”ÆęŒ TDengine ēš„ę‰€ęœ‰ę øåæƒåŠŸčƒ½ļ¼Œ åŒ…ę‹¬ļ¼š čæžęŽ„ē®”ē†ć€ę‰§č”Œ SQLć€å‚ę•°ē»‘å®šć€č®¢é˜…ć€ę— ęØ”å¼å†™å…„ļ¼ˆschemaless)。 -- REST čæžęŽ„ę”ÆęŒēš„åŠŸčƒ½åŒ…ę‹¬ļ¼ščæžęŽ„ē®”ē†ć€ę‰§č”Œ SQL怂 (é€ščæ‡ę‰§č”Œ SQL åÆä»„ļ¼š ē®”ē†ę•°ę®åŗ“ć€ē®”ē†č”Øå’Œč¶…ēŗ§č”Øć€å†™å…„ę•°ę®ć€ęŸ„čÆ¢ę•°ę®ć€åˆ›å»ŗčæžē»­ęŸ„čÆ¢ē­‰)怂 +TDengine ē›®å‰ę”ÆęŒę—¶é—“ęˆ³ć€ę•°å­—ć€å­—ē¬¦ć€åøƒå°”ē±»åž‹ļ¼ŒäøŽ Python åÆ¹åŗ”ē±»åž‹č½¬ę¢å¦‚äø‹ļ¼š -## 安装 +|TDengine DataType|Python DataType| +|:---------------:|:-------------:| +|TIMESTAMP|datetime| +|INT|int| +|BIGINT|int| +|FLOAT|float| +|DOUBLE|int| +|SMALLINT|int| +|TINYINT|int| +|BOOL|bool| +|BINARY|str| +|NCHAR|str| +|JSON|str| + +## 安装歄骤 ### å®‰č£…å‰å‡†å¤‡ @@ -373,7 +401,7 @@ TaosCursor ē±»ä½æē”ØåŽŸē”ŸčæžęŽ„čæ›č”Œå†™å…„ć€ęŸ„čÆ¢ę“ä½œć€‚åœØå®¢ęˆ·ē«Æå¤šēŗæ
-#### Connection ē±»ēš„ä½æē”Ø +##### Connection ē±»ēš„ä½æē”Ø `Connection` ē±»ę—¢åŒ…å«åÆ¹ PEP249 Connection ęŽ„å£ēš„å®žēŽ°(å¦‚ļ¼šcursorę–¹ę³•å’Œ close 方法)ļ¼Œä¹ŸåŒ…å«å¾ˆå¤šę‰©å±•åŠŸčƒ½ļ¼ˆå¦‚ļ¼š execute态 query态schemaless_insert 和 subscribe 方法。 @@ -537,7 +565,7 @@ RestClient ē±»ę˜ÆåÆ¹äŗŽ REST API ēš„ē›“ęŽ„å°č£…ć€‚å®ƒåŖåŒ…å«äø€äøŖ sql() ę–¹ `Consumer` ęä¾›äŗ† Python čæžęŽ„å™Øč®¢é˜… TMQ ę•°ę®ēš„ API怂 -#### åˆ›å»ŗ Consumer +##### åˆ›å»ŗ Consumer åˆ›å»ŗ Consumer 语法为 `consumer = Consumer(configs)`ļ¼Œå‚ę•°å®šä¹‰čÆ·å‚č€ƒ [ę•°ę®č®¢é˜…ę–‡ę”£](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)怂 @@ -547,15 +575,15 @@ from taos.tmq import Consumer consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"}) ``` -#### č®¢é˜… topics +##### č®¢é˜… topics -Comsumer API ēš„ `subscribe` ę–¹ę³•ē”ØäŗŽč®¢é˜… topics,consumer ę”ÆęŒåŒę—¶č®¢é˜…å¤šäøŖ topic怂 +Consumer API ēš„ `subscribe` ę–¹ę³•ē”ØäŗŽč®¢é˜… topics,consumer ę”ÆęŒåŒę—¶č®¢é˜…å¤šäøŖ topic怂 ```python consumer.subscribe(['topic1', 'topic2']) ``` -#### ę¶ˆč“¹ę•°ę® +##### ę¶ˆč“¹ę•°ę® Consumer API ēš„ `poll` ę–¹ę³•ē”ØäŗŽę¶ˆč“¹ę•°ę®ļ¼Œ`poll` ę–¹ę³•ęŽ„ę”¶äø€äøŖ float ē±»åž‹ēš„č¶…ę—¶ę—¶é—“ļ¼Œč¶…ę—¶ę—¶é—“å•ä½äøŗē§’ļ¼ˆsļ¼‰ļ¼Œ`poll` ę–¹ę³•åœØč¶…ę—¶ä¹‹å‰čæ”å›žäø€ę” Message ē±»åž‹ēš„ę•°ę®ęˆ–č¶…ę—¶čæ”å›ž `None`ć€‚ę¶ˆč“¹č€…åæ…é”»é€ščæ‡ Message ēš„ `error()` ę–¹ę³•ę ”éŖŒčæ”å›žę•°ę®ēš„ error 俔息。 @@ -573,7 +601,7 @@ while True: print(block.fetchall()) ``` -#### čŽ·å–ę¶ˆč“¹čæ›åŗ¦ +##### čŽ·å–ę¶ˆč“¹čæ›åŗ¦ Consumer API ēš„ `assignment` ę–¹ę³•ē”ØäŗŽčŽ·å– Consumer č®¢é˜…ēš„ę‰€ęœ‰ topic ēš„ę¶ˆč“¹čæ›åŗ¦ļ¼Œčæ”å›žē»“ęžœē±»åž‹äøŗ TopicPartition åˆ—č”Øć€‚ @@ -581,7 +609,7 @@ Consumer API ēš„ `assignment` ę–¹ę³•ē”ØäŗŽčŽ·å– Consumer č®¢é˜…ēš„ę‰€ęœ‰ topic assignments = consumer.assignment() ``` -#### é‡ē½®ę¶ˆč“¹čæ›åŗ¦ +##### ęŒ‡å®šč®¢é˜… Offset Consumer API ēš„ `seek` ę–¹ę³•ē”ØäŗŽé‡ē½® Consumer ēš„ę¶ˆč“¹čæ›åŗ¦åˆ°ęŒ‡å®šä½ē½®ļ¼Œę–¹ę³•å‚ę•°ē±»åž‹äøŗ TopicPartition怂 @@ -590,7 +618,7 @@ tp = TopicPartition(topic='topic1', partition=0, offset=0) consumer.seek(tp) ``` -#### ē»“ęŸę¶ˆč“¹ +##### å…³é—­č®¢é˜… ę¶ˆč“¹ē»“ęŸåŽļ¼Œåŗ”å½“å–ę¶ˆč®¢é˜…ļ¼Œå¹¶å…³é—­ Consumer怂 @@ -599,13 +627,13 @@ consumer.unsubscribe() consumer.close() ``` -#### tmq č®¢é˜…ē¤ŗä¾‹ä»£ē  +##### å®Œę•“ē¤ŗä¾‹ ```python {{#include docs/examples/python/tmq_example.py}} ``` -#### čŽ·å–å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦ē¤ŗä¾‹ä»£ē  +##### čŽ·å–å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦ē¤ŗä¾‹ä»£ē  ```python {{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}} @@ -619,7 +647,7 @@ consumer.close() taosws `Consumer` API ęä¾›äŗ†åŸŗäŗŽ Websocket č®¢é˜… TMQ ę•°ę®ēš„ API怂 -#### åˆ›å»ŗ Consumer +##### åˆ›å»ŗ Consumer åˆ›å»ŗ Consumer 语法为 `consumer = Consumer(conf=configs)`ļ¼Œä½æē”Øę—¶éœ€č¦ęŒ‡å®š `td.connect.websocket.scheme` å‚ę•°å€¼äøŗ "ws"ļ¼Œå‚ę•°å®šä¹‰čÆ·å‚č€ƒ [ę•°ę®č®¢é˜…ę–‡ę”£](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)怂 @@ -629,15 +657,15 @@ import taosws consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"}) ``` -#### č®¢é˜… topics +##### č®¢é˜… topics -Comsumer API ēš„ `subscribe` ę–¹ę³•ē”ØäŗŽč®¢é˜… topics,consumer ę”ÆęŒåŒę—¶č®¢é˜…å¤šäøŖ topic怂 +Consumer API ēš„ `subscribe` ę–¹ę³•ē”ØäŗŽč®¢é˜… topics,consumer ę”ÆęŒåŒę—¶č®¢é˜…å¤šäøŖ topic怂 ```python consumer.subscribe(['topic1', 'topic2']) ``` -#### ę¶ˆč“¹ę•°ę® +##### ę¶ˆč“¹ę•°ę® Consumer API ēš„ `poll` ę–¹ę³•ē”ØäŗŽę¶ˆč“¹ę•°ę®ļ¼Œ`poll` ę–¹ę³•ęŽ„ę”¶äø€äøŖ float ē±»åž‹ēš„č¶…ę—¶ę—¶é—“ļ¼Œč¶…ę—¶ę—¶é—“å•ä½äøŗē§’ļ¼ˆsļ¼‰ļ¼Œ`poll` ę–¹ę³•åœØč¶…ę—¶ä¹‹å‰čæ”å›žäø€ę” Message ē±»åž‹ēš„ę•°ę®ęˆ–č¶…ę—¶čæ”å›ž `None`ć€‚ę¶ˆč“¹č€…åæ…é”»é€ščæ‡ Message ēš„ `error()` ę–¹ę³•ę ”éŖŒčæ”å›žę•°ę®ēš„ error 俔息。 @@ -654,7 +682,7 @@ while True: print(row) ``` -#### čŽ·å–ę¶ˆč“¹čæ›åŗ¦ +##### čŽ·å–ę¶ˆč“¹čæ›åŗ¦ Consumer API ēš„ `assignment` ę–¹ę³•ē”ØäŗŽčŽ·å– Consumer č®¢é˜…ēš„ę‰€ęœ‰ topic ēš„ę¶ˆč“¹čæ›åŗ¦ļ¼Œčæ”å›žē»“ęžœē±»åž‹äøŗ TopicPartition åˆ—č”Øć€‚ @@ -662,7 +690,7 @@ Consumer API ēš„ `assignment` ę–¹ę³•ē”ØäŗŽčŽ·å– Consumer č®¢é˜…ēš„ę‰€ęœ‰ topic assignments = consumer.assignment() ``` -#### é‡ē½®ę¶ˆč“¹čæ›åŗ¦ +##### é‡ē½®ę¶ˆč“¹čæ›åŗ¦ Consumer API ēš„ `seek` ę–¹ę³•ē”ØäŗŽé‡ē½® Consumer ēš„ę¶ˆč“¹čæ›åŗ¦åˆ°ęŒ‡å®šä½ē½®ć€‚ @@ -670,7 +698,7 @@ Consumer API ēš„ `seek` ę–¹ę³•ē”ØäŗŽé‡ē½® Consumer ēš„ę¶ˆč“¹čæ›åŗ¦åˆ°ęŒ‡å®šä½ consumer.seek(topic='topic1', partition=0, offset=0) ``` -#### ē»“ęŸę¶ˆč“¹ +##### ē»“ęŸę¶ˆč“¹ ę¶ˆč“¹ē»“ęŸåŽļ¼Œåŗ”å½“å–ę¶ˆč®¢é˜…ļ¼Œå¹¶å…³é—­ Consumer怂 @@ -679,7 +707,7 @@ consumer.unsubscribe() consumer.close() ``` -#### tmq č®¢é˜…ē¤ŗä¾‹ä»£ē  +##### tmq č®¢é˜…ē¤ŗä¾‹ä»£ē  ```python {{#include docs/examples/python/tmq_websocket_example.py}} @@ -687,7 +715,7 @@ consumer.close() čæžęŽ„å™Øęä¾›äŗ† `assignment` ęŽ„å£ļ¼Œē”ØäŗŽčŽ·å– topic assignment ēš„åŠŸčƒ½ļ¼ŒåÆä»„ęŸ„čÆ¢č®¢é˜…ēš„ topic ēš„ę¶ˆč“¹čæ›åŗ¦ļ¼Œå¹¶ęä¾› `seek` ęŽ„å£ļ¼Œē”ØäŗŽé‡ē½® topic ēš„ę¶ˆč“¹čæ›åŗ¦ć€‚ -#### čŽ·å–å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦ē¤ŗä¾‹ä»£ē  +##### čŽ·å–å’Œé‡ē½®ę¶ˆč“¹čæ›åŗ¦ē¤ŗä¾‹ä»£ē  ```python {{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}} @@ -703,19 +731,19 @@ consumer.close() -ē®€å•å†™å…„ +##### ē®€å•å†™å…„ ```python {{#include docs/examples/python/schemaless_insert.py}} ``` -åø¦ęœ‰ ttl å‚ę•°ēš„å†™å…„ +##### åø¦ęœ‰ ttl å‚ę•°ēš„å†™å…„ ```python {{#include docs/examples/python/schemaless_insert_ttl.py}} ``` -åø¦ęœ‰ req_id å‚ę•°ēš„å†™å…„ +##### åø¦ęœ‰ req_id å‚ę•°ēš„å†™å…„ ```python {{#include docs/examples/python/schemaless_insert_req_id.py}} @@ -725,19 +753,19 @@ consumer.close() -ē®€å•å†™å…„ +##### ē®€å•å†™å…„ ```python {{#include docs/examples/python/schemaless_insert_raw.py}} ``` -åø¦ęœ‰ ttl å‚ę•°ēš„å†™å…„ +##### åø¦ęœ‰ ttl å‚ę•°ēš„å†™å…„ ```python {{#include docs/examples/python/schemaless_insert_raw_ttl.py}} ``` -åø¦ęœ‰ req_id å‚ę•°ēš„å†™å…„ +##### åø¦ęœ‰ req_id å‚ę•°ēš„å†™å…„ ```python {{#include docs/examples/python/schemaless_insert_raw_req_id.py}} @@ -753,7 +781,7 @@ TDengine ēš„ Python čæžęŽ„å™Øę”ÆęŒå‚ę•°ē»‘å®šé£Žę ¼ēš„ Prepare API ę–¹å¼å†™ -#### åˆ›å»ŗ stmt +##### åˆ›å»ŗ stmt Python čæžęŽ„å™Øēš„ `Connection` ęä¾›äŗ† `statement` ę–¹ę³•ē”ØäŗŽåˆ›å»ŗå‚ę•°ē»‘å®šåÆ¹č±” stmtļ¼ŒčÆ„ę–¹ę³•ęŽ„ę”¶ sql å­—ē¬¦äø²ä½œäøŗå‚ę•°ļ¼Œsql å­—ē¬¦äø²ē›®å‰ä»…ę”ÆęŒē”Ø `?` ę„ä»£č”Øē»‘å®šēš„å‚ę•°ć€‚ @@ -764,7 +792,7 @@ conn = taos.connect() stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") ``` -#### å‚ę•°ē»‘å®š +##### å‚ę•°ē»‘å®š č°ƒē”Ø `new_multi_binds` å‡½ę•°åˆ›å»ŗ params åˆ—č”Øļ¼Œē”ØäŗŽå‚ę•°ē»‘å®šć€‚ @@ -794,7 +822,7 @@ params[15].timestamp([None, None, 1626861392591]) stmt.bind_param_batch(params) ``` -#### ę‰§č”Œ sql +##### ę‰§č”Œ sql č°ƒē”Ø stmt ēš„ `execute` ę–¹ę³•ę‰§č”Œ sql @@ -802,7 +830,7 @@ stmt.bind_param_batch(params) stmt.execute() ``` -#### 关闭 stmt +##### 关闭 stmt ęœ€åŽéœ€č¦å…³é—­ stmt怂 @@ -810,7 +838,7 @@ stmt.execute() stmt.close() ``` -#### 示例代码 +##### 示例代码 ```python {{#include docs/examples/python/stmt_example.py}} @@ -819,7 +847,7 @@ stmt.close() -#### åˆ›å»ŗ stmt +##### åˆ›å»ŗ stmt Python WebSocket čæžęŽ„å™Øēš„ `Connection` ęä¾›äŗ† `statement` ę–¹ę³•ē”ØäŗŽåˆ›å»ŗå‚ę•°ē»‘å®šåÆ¹č±” stmtļ¼ŒčÆ„ę–¹ę³•ęŽ„ę”¶ sql å­—ē¬¦äø²ä½œäøŗå‚ę•°ļ¼Œsql å­—ē¬¦äø²ē›®å‰ä»…ę”ÆęŒē”Ø `?` ę„ä»£č”Øē»‘å®šēš„å‚ę•°ć€‚ @@ -830,7 +858,7 @@ conn = taosws.connect('taosws://localhost:6041/test') stmt = conn.statement() ``` -#### č§£ęž sql +##### č§£ęž sql č°ƒē”Ø stmt ēš„ `prepare` ę–¹ę³•ę„č§£ęž insert čÆ­å„ć€‚ @@ -838,7 +866,7 @@ stmt = conn.statement() stmt.prepare("insert into t1 values (?, ?, ?, ?)") ``` -#### å‚ę•°ē»‘å®š +##### å‚ę•°ē»‘å®š č°ƒē”Ø stmt ēš„ `bind_param` ę–¹ę³•ē»‘å®šå‚ę•°ć€‚ @@ -857,7 +885,7 @@ stmt.bind_param([ stmt.add_batch() ``` -#### ę‰§č”Œ sql +##### ę‰§č”Œ sql č°ƒē”Ø stmt ēš„ `execute` ę–¹ę³•ę‰§č”Œ sql @@ -865,7 +893,7 @@ stmt.add_batch() stmt.execute() ``` -#### 关闭 stmt +##### 关闭 stmt ęœ€åŽéœ€č¦å…³é—­ stmt怂 @@ -873,7 +901,7 @@ stmt.execute() stmt.close() ``` -#### 示例代码 +##### 示例代码 ```python {{#include docs/examples/python/stmt_websocket_example.py}} diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md index 416d41614d..fc0cfbe330 100644 --- a/docs/zh/12-taos-sql/10-function.md +++ b/docs/zh/12-taos-sql/10-function.md @@ -991,18 +991,14 @@ SAMPLE(expr, k) **åŠŸčƒ½čÆ“ę˜Ž**: čŽ·å–ę•°ę®ēš„ k äøŖé‡‡ę ·å€¼ć€‚å‚ę•° k ēš„åˆę³•č¾“å…„čŒƒå›“ę˜Æ 1≤ k ≤ 1000怂 -**čæ”å›žē»“ęžœē±»åž‹**: åŒåŽŸå§‹ę•°ę®ē±»åž‹ļ¼Œ čæ”å›žē»“ęžœäø­åø¦ęœ‰čÆ„č”Œč®°å½•ēš„ę—¶é—“ęˆ³ć€‚ +**čæ”å›žē»“ęžœē±»åž‹**: åŒåŽŸå§‹ę•°ę®ē±»åž‹ć€‚ -**é€‚ē”Øę•°ę®ē±»åž‹**: åœØč¶…ēŗ§č”ØęŸ„čÆ¢äø­ä½æē”Øę—¶ļ¼Œäøčƒ½åŗ”ē”ØåœØę ‡ē­¾ä¹‹äøŠć€‚ +**é€‚ē”Øę•°ę®ē±»åž‹**: å…ØéƒØē±»åž‹å­—ę®µć€‚ **åµŒå„—å­ęŸ„čÆ¢ę”ÆęŒ**: é€‚ē”ØäŗŽå†…å±‚ęŸ„čÆ¢å’Œå¤–å±‚ęŸ„čÆ¢ć€‚ **é€‚ē”ØäŗŽ**ļ¼šč”Øå’Œč¶…ēŗ§č”Øć€‚ -**ä½æē”ØčÆ“ę˜Ž**: - -- äøčƒ½å‚äøŽč”Øč¾¾å¼č®”ē®—ļ¼›čÆ„å‡½ę•°åÆä»„åŗ”ē”ØåœØę™®é€šč”Øå’Œč¶…ēŗ§č”ØäøŠļ¼› - ### TAIL @@ -1047,11 +1043,11 @@ TOP(expr, k) UNIQUE(expr) ``` -**åŠŸčƒ½čÆ“ę˜Ž**ļ¼ščæ”å›žčÆ„åˆ—ēš„ę•°å€¼é¦–ę¬”å‡ŗēŽ°ēš„å€¼ć€‚čÆ„å‡½ę•°åŠŸčƒ½äøŽ distinct ē›øä¼¼ļ¼Œä½†ę˜ÆåÆä»„åŒ¹é…ę ‡ē­¾å’Œę—¶é—“ęˆ³äæ”ęÆć€‚åÆä»„é’ˆåÆ¹é™¤ę—¶é—“åˆ—ä»„å¤–ēš„å­—ę®µčæ›č”ŒęŸ„čÆ¢ļ¼ŒåÆä»„åŒ¹é…ę ‡ē­¾å’Œę—¶é—“ęˆ³ļ¼Œå…¶äø­ēš„ę ‡ē­¾å’Œę—¶é—“ęˆ³ę˜Æē¬¬äø€ę¬”å‡ŗēŽ°ę—¶åˆ»ēš„ę ‡ē­¾å’Œę—¶é—“ęˆ³ć€‚ +**åŠŸčƒ½čÆ“ę˜Ž**ļ¼ščæ”å›žčÆ„åˆ—ę•°ę®é¦–ę¬”å‡ŗēŽ°ēš„å€¼ć€‚čÆ„å‡½ę•°åŠŸčƒ½äøŽ distinct 相似。 **čæ”å›žę•°ę®ē±»åž‹**ļ¼šåŒåŗ”ē”Øēš„å­—ę®µć€‚ -**é€‚ē”Øę•°ę®ē±»åž‹**ļ¼šé€‚åˆäŗŽé™¤ę—¶é—“ē±»åž‹ä»„å¤–ēš„å­—ę®µć€‚ +**é€‚ē”Øę•°ę®ē±»åž‹**ļ¼šå…ØéƒØē±»åž‹å­—ę®µć€‚ **é€‚ē”ØäŗŽ**: č”Øå’Œč¶…ēŗ§č”Øć€‚ diff --git a/docs/zh/12-taos-sql/24-show.md b/docs/zh/12-taos-sql/24-show.md index 12ad665e42..f3397ae82d 100644 --- a/docs/zh/12-taos-sql/24-show.md +++ b/docs/zh/12-taos-sql/24-show.md @@ -36,7 +36,7 @@ SHOW CONNECTIONS; SHOW CONSUMERS; ``` -ę˜¾ē¤ŗå½“å‰ę•°ę®åŗ“äø‹ę‰€ęœ‰ę“»č·ƒēš„ę¶ˆč“¹č€…ēš„äæ”ęÆć€‚ +ę˜¾ē¤ŗå½“å‰ę•°ę®åŗ“äø‹ę‰€ęœ‰ę¶ˆč“¹č€…ēš„äæ”ęÆć€‚ ## SHOW CREATE DATABASE diff --git a/docs/zh/28-releases/01-tdengine.md b/docs/zh/28-releases/01-tdengine.md index ae47388566..557552bc1c 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.6.0 + + + ## 3.0.5.1 diff --git a/include/common/tcommon.h b/include/common/tcommon.h index ea17262abd..bdfb1d32b4 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -54,6 +54,11 @@ typedef struct SSessionKey { uint64_t groupId; } SSessionKey; +typedef struct SVersionRange { + uint64_t minVer; + uint64_t maxVer; +} SVersionRange; + static inline int winKeyCmprImpl(const void* pKey1, const void* pKey2) { SWinKey* pWin1 = (SWinKey*)pKey1; SWinKey* pWin2 = (SWinKey*)pKey2; @@ -131,10 +136,10 @@ static inline int STupleKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, enum { TMQ_MSG_TYPE__DUMMY = 0, - TMQ_MSG_TYPE__POLL_RSP, + TMQ_MSG_TYPE__POLL_DATA_RSP, TMQ_MSG_TYPE__POLL_META_RSP, TMQ_MSG_TYPE__EP_RSP, - TMQ_MSG_TYPE__TAOSX_RSP, + TMQ_MSG_TYPE__POLL_DATA_META_RSP, TMQ_MSG_TYPE__WALINFO_RSP, TMQ_MSG_TYPE__END_RSP, }; diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index 6cb7d88523..c0412d2617 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -177,7 +177,6 @@ static FORCE_INLINE void colDataSetDouble(SColumnInfoData* pColumnInfoData, uint int32_t getJsonValueLen(const char* data); int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull); -int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull); int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, const char* pData); int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, uint32_t numOfRows, bool trimValue); int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int32_t* capacity, @@ -187,6 +186,8 @@ int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* p int32_t blockDataUpdateTsWindow(SSDataBlock* pDataBlock, int32_t tsColumnIndex); int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows); + +int32_t colDataGetRowLength(const SColumnInfoData* pColumnInfoData, int32_t rowIdx); void colDataTrim(SColumnInfoData* pColumnInfoData); size_t blockDataGetNumOfCols(const SSDataBlock* pBlock); @@ -207,7 +208,6 @@ double blockDataGetSerialRowSize(const SSDataBlock* pBlock); size_t blockDataGetSerialMetaSize(uint32_t numOfCols); int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo); -int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullFirst); int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows, bool clearPayload); int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows); @@ -236,11 +236,10 @@ int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColIn SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId); SColumnInfoData* bdGetColumnInfoData(const SSDataBlock* pBlock, int32_t index); +int32_t blockGetEncodeSize(const SSDataBlock* pBlock); int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols); const char* blockDecode(SSDataBlock* pBlock, const char* pData); -void blockDebugShowDataBlock(SSDataBlock* pBlock, const char* flag); -void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag); // for debug char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf); @@ -250,9 +249,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pData char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId); int32_t buildCtbNameByGroupIdImpl(const char* stbName, uint64_t groupId, char* pBuf); -static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) { - return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock); -} +void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList); #ifdef __cplusplus } diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 8aa17e46d1..bc4037c642 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -164,6 +164,8 @@ extern char tsSmlTagName[]; // extern bool tsSmlDataFormat; // extern int32_t tsSmlBatchSize; +extern int32_t tmqMaxTopicNum; + // wal extern int64_t tsWalFsyncDataSizeLimit; @@ -184,6 +186,7 @@ extern int64_t tsStreamBufferSize; extern int64_t tsCheckpointInterval; extern bool tsFilterScalarMode; extern int32_t tsMaxStreamBackendCache; +extern int32_t tsPQSortMemThreshold; // #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index fa092a453c..6e182c1c35 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -2909,6 +2909,12 @@ enum { TMQ_OFFSET__SNAPSHOT_META = 3, }; +enum { + WITH_DATA = 0, + WITH_META = 1, + ONLY_META = 2, +}; + typedef struct { int8_t type; union { diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index e551adc17b..8940d1be96 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -145,7 +145,7 @@ enum { TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DROP_TOPIC, "drop-topic", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_TMQ_SUBSCRIBE, "subscribe", SCMSubscribeReq, SCMSubscribeRsp) TD_DEF_MSG_TYPE(TDMT_MND_TMQ_ASK_EP, "ask-ep", SMqAskEpReq, SMqAskEpRsp) - TD_DEF_MSG_TYPE(TDMT_MND_TMQ_CONSUMER_LOST, "consumer-lost", SMqConsumerLostMsg, NULL) +// TD_DEF_MSG_TYPE(TDMT_MND_TMQ_CONSUMER_LOST, "consumer-lost", SMqConsumerLostMsg, NULL) TD_DEF_MSG_TYPE(TDMT_MND_TMQ_CONSUMER_RECOVER, "consumer-recover", SMqConsumerRecoverMsg, NULL) TD_DEF_MSG_TYPE(TDMT_MND_TMQ_HB, "consumer-hb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DO_REBALANCE, "do-rebalance", SMqDoRebalanceMsg, NULL) @@ -253,7 +253,9 @@ enum { TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_DISPATCH, "stream-task-dispatch", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_UNUSED1, "stream-unused1", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_RETRIEVE, "stream-retrieve", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_STREAM_RECOVER_FINISH, "stream-recover-finish", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY, "stream-scan-history", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY_FINISH, "stream-scan-history-finish", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_STREAM_TRANSFER_STATE, "stream-transfer-state", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECK, "stream-task-check", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECKPOINT, "stream-checkpoint", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_REPORT_CHECKPOINT, "stream-report-checkpoint", NULL, NULL) @@ -298,8 +300,7 @@ enum { TD_NEW_MSG_SEG(TDMT_VND_STREAM_MSG) TD_DEF_MSG_TYPE(TDMT_VND_STREAM_TRIGGER, "vnode-stream-trigger", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_VND_STREAM_RECOVER_NONBLOCKING_STAGE, "vnode-stream-recover1", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE, "vnode-stream-recover2", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_VND_STREAM_SCAN_HISTORY, "vnode-stream-scan-history", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_STREAM_CHECK_POINT_SOURCE, "vnode-stream-checkpoint-source", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_STREAM_MAX_MSG, "vnd-stream-max", NULL, NULL) diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 5410e9af88..6bcea77df6 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -16,105 +16,105 @@ #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_RESTORE 52 -#define TK_NK_IPTOKEN 53 -#define TK_FORCE 54 -#define TK_UNSAFE 55 -#define TK_LOCAL 56 -#define TK_QNODE 57 -#define TK_BNODE 58 -#define TK_SNODE 59 -#define TK_MNODE 60 -#define TK_VNODE 61 -#define TK_DATABASE 62 -#define TK_USE 63 -#define TK_FLUSH 64 -#define TK_TRIM 65 -#define TK_COMPACT 66 -#define TK_IF 67 -#define TK_NOT 68 -#define TK_EXISTS 69 -#define TK_BUFFER 70 -#define TK_CACHEMODEL 71 -#define TK_CACHESIZE 72 -#define TK_COMP 73 -#define TK_DURATION 74 -#define TK_NK_VARIABLE 75 -#define TK_MAXROWS 76 -#define TK_MINROWS 77 -#define TK_KEEP 78 -#define TK_PAGES 79 -#define TK_PAGESIZE 80 -#define TK_TSDB_PAGESIZE 81 -#define TK_PRECISION 82 -#define TK_REPLICA 83 -#define TK_VGROUPS 84 -#define TK_SINGLE_STABLE 85 -#define TK_RETENTIONS 86 -#define TK_SCHEMALESS 87 -#define TK_WAL_LEVEL 88 -#define TK_WAL_FSYNC_PERIOD 89 -#define TK_WAL_RETENTION_PERIOD 90 -#define TK_WAL_RETENTION_SIZE 91 -#define TK_WAL_ROLL_PERIOD 92 -#define TK_WAL_SEGMENT_SIZE 93 -#define TK_STT_TRIGGER 94 -#define TK_TABLE_PREFIX 95 -#define TK_TABLE_SUFFIX 96 -#define TK_NK_COLON 97 -#define TK_MAX_SPEED 98 -#define TK_START 99 +#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_UNSAFE 55 +#define TK_LOCAL 56 +#define TK_QNODE 57 +#define TK_BNODE 58 +#define TK_SNODE 59 +#define TK_MNODE 60 +#define TK_VNODE 61 +#define TK_DATABASE 62 +#define TK_USE 63 +#define TK_FLUSH 64 +#define TK_TRIM 65 +#define TK_COMPACT 66 +#define TK_IF 67 +#define TK_NOT 68 +#define TK_EXISTS 69 +#define TK_BUFFER 70 +#define TK_CACHEMODEL 71 +#define TK_CACHESIZE 72 +#define TK_COMP 73 +#define TK_DURATION 74 +#define TK_NK_VARIABLE 75 +#define TK_MAXROWS 76 +#define TK_MINROWS 77 +#define TK_KEEP 78 +#define TK_PAGES 79 +#define TK_PAGESIZE 80 +#define TK_TSDB_PAGESIZE 81 +#define TK_PRECISION 82 +#define TK_REPLICA 83 +#define TK_VGROUPS 84 +#define TK_SINGLE_STABLE 85 +#define TK_RETENTIONS 86 +#define TK_SCHEMALESS 87 +#define TK_WAL_LEVEL 88 +#define TK_WAL_FSYNC_PERIOD 89 +#define TK_WAL_RETENTION_PERIOD 90 +#define TK_WAL_RETENTION_SIZE 91 +#define TK_WAL_ROLL_PERIOD 92 +#define TK_WAL_SEGMENT_SIZE 93 +#define TK_STT_TRIGGER 94 +#define TK_TABLE_PREFIX 95 +#define TK_TABLE_SUFFIX 96 +#define TK_NK_COLON 97 +#define TK_MAX_SPEED 98 +#define TK_START 99 #define TK_TIMESTAMP 100 #define TK_END 101 #define TK_TABLE 102 @@ -193,165 +193,167 @@ #define TK_INTERVAL 175 #define TK_COUNT 176 #define TK_LAST_ROW 177 -#define TK_TOPIC 178 -#define TK_META 179 -#define TK_CONSUMER 180 -#define TK_GROUP 181 -#define TK_DESC 182 -#define TK_DESCRIBE 183 -#define TK_RESET 184 -#define TK_QUERY 185 -#define TK_CACHE 186 -#define TK_EXPLAIN 187 -#define TK_ANALYZE 188 -#define TK_VERBOSE 189 -#define TK_NK_BOOL 190 -#define TK_RATIO 191 -#define TK_NK_FLOAT 192 -#define TK_OUTPUTTYPE 193 -#define TK_AGGREGATE 194 -#define TK_BUFSIZE 195 -#define TK_LANGUAGE 196 -#define TK_REPLACE 197 -#define TK_STREAM 198 -#define TK_INTO 199 -#define TK_PAUSE 200 -#define TK_RESUME 201 -#define TK_TRIGGER 202 -#define TK_AT_ONCE 203 -#define TK_WINDOW_CLOSE 204 -#define TK_IGNORE 205 -#define TK_EXPIRED 206 -#define TK_FILL_HISTORY 207 -#define TK_UPDATE 208 -#define TK_SUBTABLE 209 -#define TK_UNTREATED 210 -#define TK_KILL 211 -#define TK_CONNECTION 212 -#define TK_TRANSACTION 213 -#define TK_BALANCE 214 -#define TK_VGROUP 215 -#define TK_LEADER 216 -#define TK_MERGE 217 -#define TK_REDISTRIBUTE 218 -#define TK_SPLIT 219 -#define TK_DELETE 220 -#define TK_INSERT 221 -#define TK_NULL 222 -#define TK_NK_QUESTION 223 -#define TK_NK_ARROW 224 -#define TK_ROWTS 225 -#define TK_QSTART 226 -#define TK_QEND 227 -#define TK_QDURATION 228 -#define TK_WSTART 229 -#define TK_WEND 230 -#define TK_WDURATION 231 -#define TK_IROWTS 232 -#define TK_ISFILLED 233 -#define TK_CAST 234 -#define TK_NOW 235 -#define TK_TODAY 236 -#define TK_TIMEZONE 237 -#define TK_CLIENT_VERSION 238 -#define TK_SERVER_VERSION 239 -#define TK_SERVER_STATUS 240 -#define TK_CURRENT_USER 241 -#define TK_CASE 242 -#define TK_WHEN 243 -#define TK_THEN 244 -#define TK_ELSE 245 -#define TK_BETWEEN 246 -#define TK_IS 247 -#define TK_NK_LT 248 -#define TK_NK_GT 249 -#define TK_NK_LE 250 -#define TK_NK_GE 251 -#define TK_NK_NE 252 -#define TK_MATCH 253 -#define TK_NMATCH 254 -#define TK_CONTAINS 255 -#define TK_IN 256 -#define TK_JOIN 257 -#define TK_INNER 258 -#define TK_SELECT 259 -#define TK_DISTINCT 260 -#define TK_WHERE 261 -#define TK_PARTITION 262 -#define TK_BY 263 -#define TK_SESSION 264 -#define TK_STATE_WINDOW 265 -#define TK_EVENT_WINDOW 266 -#define TK_SLIDING 267 -#define TK_FILL 268 -#define TK_VALUE 269 -#define TK_VALUE_F 270 -#define TK_NONE 271 -#define TK_PREV 272 -#define TK_NULL_F 273 -#define TK_LINEAR 274 -#define TK_NEXT 275 -#define TK_HAVING 276 -#define TK_RANGE 277 -#define TK_EVERY 278 -#define TK_ORDER 279 -#define TK_SLIMIT 280 -#define TK_SOFFSET 281 -#define TK_LIMIT 282 -#define TK_OFFSET 283 -#define TK_ASC 284 -#define TK_NULLS 285 -#define TK_ABORT 286 -#define TK_AFTER 287 -#define TK_ATTACH 288 -#define TK_BEFORE 289 -#define TK_BEGIN 290 -#define TK_BITAND 291 -#define TK_BITNOT 292 -#define TK_BITOR 293 -#define TK_BLOCKS 294 -#define TK_CHANGE 295 -#define TK_COMMA 296 -#define TK_CONCAT 297 -#define TK_CONFLICT 298 -#define TK_COPY 299 -#define TK_DEFERRED 300 -#define TK_DELIMITERS 301 -#define TK_DETACH 302 -#define TK_DIVIDE 303 -#define TK_DOT 304 -#define TK_EACH 305 -#define TK_FAIL 306 -#define TK_FILE 307 -#define TK_FOR 308 -#define TK_GLOB 309 -#define TK_ID 310 -#define TK_IMMEDIATE 311 -#define TK_IMPORT 312 -#define TK_INITIALLY 313 -#define TK_INSTEAD 314 -#define TK_ISNULL 315 -#define TK_KEY 316 -#define TK_MODULES 317 -#define TK_NK_BITNOT 318 -#define TK_NK_SEMI 319 -#define TK_NOTNULL 320 -#define TK_OF 321 -#define TK_PLUS 322 -#define TK_PRIVILEGE 323 -#define TK_RAISE 324 -#define TK_RESTRICT 325 -#define TK_ROW 326 -#define TK_SEMI 327 -#define TK_STAR 328 -#define TK_STATEMENT 329 -#define TK_STRICT 330 -#define TK_STRING 331 -#define TK_TIMES 332 -#define TK_VALUES 333 -#define TK_VARIABLE 334 -#define TK_VIEW 335 -#define TK_WAL 336 +#define TK_META 178 +#define TK_ONLY 179 +#define TK_TOPIC 180 +#define TK_CONSUMER 181 +#define TK_GROUP 182 +#define TK_DESC 183 +#define TK_DESCRIBE 184 +#define TK_RESET 185 +#define TK_QUERY 186 +#define TK_CACHE 187 +#define TK_EXPLAIN 188 +#define TK_ANALYZE 189 +#define TK_VERBOSE 190 +#define TK_NK_BOOL 191 +#define TK_RATIO 192 +#define TK_NK_FLOAT 193 +#define TK_OUTPUTTYPE 194 +#define TK_AGGREGATE 195 +#define TK_BUFSIZE 196 +#define TK_LANGUAGE 197 +#define TK_REPLACE 198 +#define TK_STREAM 199 +#define TK_INTO 200 +#define TK_PAUSE 201 +#define TK_RESUME 202 +#define TK_TRIGGER 203 +#define TK_AT_ONCE 204 +#define TK_WINDOW_CLOSE 205 +#define TK_IGNORE 206 +#define TK_EXPIRED 207 +#define TK_FILL_HISTORY 208 +#define TK_UPDATE 209 +#define TK_SUBTABLE 210 +#define TK_UNTREATED 211 +#define TK_KILL 212 +#define TK_CONNECTION 213 +#define TK_TRANSACTION 214 +#define TK_BALANCE 215 +#define TK_VGROUP 216 +#define TK_LEADER 217 +#define TK_MERGE 218 +#define TK_REDISTRIBUTE 219 +#define TK_SPLIT 220 +#define TK_DELETE 221 +#define TK_INSERT 222 +#define TK_NULL 223 +#define TK_NK_QUESTION 224 +#define TK_NK_ARROW 225 +#define TK_ROWTS 226 +#define TK_QSTART 227 +#define TK_QEND 228 +#define TK_QDURATION 229 +#define TK_WSTART 230 +#define TK_WEND 231 +#define TK_WDURATION 232 +#define TK_IROWTS 233 +#define TK_ISFILLED 234 +#define TK_CAST 235 +#define TK_NOW 236 +#define TK_TODAY 237 +#define TK_TIMEZONE 238 +#define TK_CLIENT_VERSION 239 +#define TK_SERVER_VERSION 240 +#define TK_SERVER_STATUS 241 +#define TK_CURRENT_USER 242 +#define TK_CASE 243 +#define TK_WHEN 244 +#define TK_THEN 245 +#define TK_ELSE 246 +#define TK_BETWEEN 247 +#define TK_IS 248 +#define TK_NK_LT 249 +#define TK_NK_GT 250 +#define TK_NK_LE 251 +#define TK_NK_GE 252 +#define TK_NK_NE 253 +#define TK_MATCH 254 +#define TK_NMATCH 255 +#define TK_CONTAINS 256 +#define TK_IN 257 +#define TK_JOIN 258 +#define TK_INNER 259 +#define TK_SELECT 260 +#define TK_DISTINCT 261 +#define TK_WHERE 262 +#define TK_PARTITION 263 +#define TK_BY 264 +#define TK_SESSION 265 +#define TK_STATE_WINDOW 266 +#define TK_EVENT_WINDOW 267 +#define TK_SLIDING 268 +#define TK_FILL 269 +#define TK_VALUE 270 +#define TK_VALUE_F 271 +#define TK_NONE 272 +#define TK_PREV 273 +#define TK_NULL_F 274 +#define TK_LINEAR 275 +#define TK_NEXT 276 +#define TK_HAVING 277 +#define TK_RANGE 278 +#define TK_EVERY 279 +#define TK_ORDER 280 +#define TK_SLIMIT 281 +#define TK_SOFFSET 282 +#define TK_LIMIT 283 +#define TK_OFFSET 284 +#define TK_ASC 285 +#define TK_NULLS 286 +#define TK_ABORT 287 +#define TK_AFTER 288 +#define TK_ATTACH 289 +#define TK_BEFORE 290 +#define TK_BEGIN 291 +#define TK_BITAND 292 +#define TK_BITNOT 293 +#define TK_BITOR 294 +#define TK_BLOCKS 295 +#define TK_CHANGE 296 +#define TK_COMMA 297 +#define TK_CONCAT 298 +#define TK_CONFLICT 299 +#define TK_COPY 300 +#define TK_DEFERRED 301 +#define TK_DELIMITERS 302 +#define TK_DETACH 303 +#define TK_DIVIDE 304 +#define TK_DOT 305 +#define TK_EACH 306 +#define TK_FAIL 307 +#define TK_FILE 308 +#define TK_FOR 309 +#define TK_GLOB 310 +#define TK_ID 311 +#define TK_IMMEDIATE 312 +#define TK_IMPORT 313 +#define TK_INITIALLY 314 +#define TK_INSTEAD 315 +#define TK_ISNULL 316 +#define TK_KEY 317 +#define TK_MODULES 318 +#define TK_NK_BITNOT 319 +#define TK_NK_SEMI 320 +#define TK_NOTNULL 321 +#define TK_OF 322 +#define TK_PLUS 323 +#define TK_PRIVILEGE 324 +#define TK_RAISE 325 +#define TK_RESTRICT 326 +#define TK_ROW 327 +#define TK_SEMI 328 +#define TK_STAR 329 +#define TK_STATEMENT 330 +#define TK_STRICT 331 +#define TK_STRING 332 +#define TK_TIMES 333 +#define TK_VALUES 334 +#define TK_VARIABLE 335 +#define TK_VIEW 336 +#define TK_WAL 337 + diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index 3f53976c67..3bef15f3a7 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -55,6 +55,9 @@ typedef struct { void* pStateBackend; struct SStorageAPI api; + + int8_t fillHistory; + STimeWindow winRange; } SReadHandle; // in queue mode, data streams are seperated by msg @@ -193,14 +196,6 @@ int32_t qDeserializeTaskStatus(qTaskInfo_t tinfo, const char* pInput, int32_t le void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order); void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery); STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key); -/** - * return the scan info, in the form of tuple of two items, including table uid and current timestamp - * @param tinfo - * @param uid - * @param ts - * @return - */ -int32_t qGetStreamScanStatus(qTaskInfo_t tinfo, uint64_t* uid, int64_t* ts); SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo); @@ -220,15 +215,22 @@ void* qExtractReaderFromStreamScanner(void* scanner); int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner); -int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo); -int32_t qStreamSourceRecoverStep1(qTaskInfo_t tinfo, int64_t ver); -int32_t qStreamSourceRecoverStep2(qTaskInfo_t tinfo, int64_t ver); +int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo); +int32_t qStreamSourceScanParamForHistoryScanStep1(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow); +int32_t qStreamSourceScanParamForHistoryScanStep2(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow); int32_t qStreamRecoverFinish(qTaskInfo_t tinfo); -int32_t qStreamRestoreParam(qTaskInfo_t tinfo); +int32_t qRestoreStreamOperatorOption(qTaskInfo_t tinfo); bool qStreamRecoverScanFinished(qTaskInfo_t tinfo); -void qStreamCloseTsdbReader(void* task); +bool qStreamRecoverScanStep1Finished(qTaskInfo_t tinfo); +bool qStreamRecoverScanStep2Finished(qTaskInfo_t tinfo); +int32_t qStreamRecoverSetAllStepFinished(qTaskInfo_t tinfo); void resetTaskInfo(qTaskInfo_t tinfo); +void qResetStreamInfoTimeWindow(qTaskInfo_t tinfo); + +int32_t qStreamOperatorReleaseState(qTaskInfo_t tInfo); +int32_t qStreamOperatorReloadState(qTaskInfo_t tInfo); + #ifdef __cplusplus } #endif diff --git a/include/libs/executor/storageapi.h b/include/libs/executor/storageapi.h index 6031b99cfc..e263c9d236 100644 --- a/include/libs/executor/storageapi.h +++ b/include/libs/executor/storageapi.h @@ -123,8 +123,8 @@ typedef struct SSnapContext { SHashObj* suidInfo; SArray* idList; int32_t index; - bool withMeta; - bool queryMeta; // true-get meta, false-get data + int8_t withMeta; + int8_t queryMeta; // true-get meta, false-get data } SSnapContext; typedef struct { @@ -234,29 +234,6 @@ typedef struct SStoreSnapshotFn { int32_t (*getTableInfoFromSnapshot)(SSnapContext* ctx, void** pBuf, int32_t* contLen, int16_t* type, int64_t* uid); } SStoreSnapshotFn; -/** -void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags); -void metaReaderReleaseLock(SMetaReader *pReader); -void metaReaderClear(SMetaReader *pReader); -int32_t metaReaderGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid); -int32_t metaReaderGetTableEntryByUidCache(SMetaReader *pReader, tb_uid_t uid); -int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList); -const void *metaGetTableTagVal(void *tag, int16_t type, STagVal *tagVal); -int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName); - -int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid); -int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); -bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); -int32_t metaGetCachedTableUidList(SMeta *pMeta, tb_uid_t suid, const uint8_t *key, int32_t keyLen, SArray *pList, - bool *acquired); -int32_t metaUidFilterCachePut(SMeta *pMeta, uint64_t suid, const void *pKey, int32_t keyLen, void *pPayload, - int32_t payloadLen, double selectivityRatio); -tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name); -int32_t metaGetCachedTbGroup(SMeta* pMeta, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList); -int32_t metaPutTbGroupToCache(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t -payloadLen); - */ - typedef struct SStoreMeta { SMTbCursor* (*openTableMetaCursor)(void* pVnode); // metaOpenTbCursor void (*closeTableMetaCursor)(SMTbCursor* pTbCur); // metaCloseTbCursor @@ -403,7 +380,7 @@ typedef struct SStateStore { SStreamStateCur* (*streamStateSessionSeekKeyCurrentNext)(SStreamState* pState, const SSessionKey* key); struct SStreamFileState* (*streamFileStateInit)(int64_t memSize, uint32_t keySize, uint32_t rowSize, - uint32_t selectRowSize, GetTsFun fp, void* pFile, TSKEY delMark); + uint32_t selectRowSize, GetTsFun fp, void* pFile, TSKEY delMark, const char*id); void (*streamFileStateDestroy)(struct SStreamFileState* pFileState); void (*streamFileStateClear)(struct SStreamFileState* pFileState); @@ -415,6 +392,7 @@ typedef struct SStateStore { int32_t (*streamStateCommit)(SStreamState* pState); void (*streamStateDestroy)(SStreamState* pState, bool remove); int32_t (*streamStateDeleteCheckPoint)(SStreamState* pState, TSKEY mark); + void (*streamStateReloadInfo)(SStreamState* pState, TSKEY ts); } SStateStore; typedef struct SStorageAPI { diff --git a/include/libs/function/function.h b/include/libs/function/function.h index c92ce254a8..2e3cd670d7 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -129,30 +129,38 @@ typedef struct SSerializeDataHandle { } SSerializeDataHandle; // incremental state storage -typedef struct STdbState { - void *rocksdb; - void **pHandle; - void *writeOpts; - void *readOpts; - void **cfOpts; - void *dbOpt; - struct SStreamTask *pOwner; - void *param; - void *env; - SListNode *pComparNode; - void *pBackend; - char idstr[64]; - void *compactFactory; - TdThreadRwlock rwLock; - void *db; - void *pStateDb; - void *pFuncStateDb; - void *pFillStateDb; // todo refactor - void *pSessionStateDb; - void *pParNameDb; - void *pParTagDb; - void *txn; +typedef struct SBackendCfWrapper { + void *rocksdb; + void **pHandle; + void *writeOpts; + void *readOpts; + void **cfOpts; + void *dbOpt; + void *param; + void *env; + SListNode *pComparNode; + void *pBackend; + void *compactFactory; + TdThreadRwlock rwLock; + bool remove; + int64_t backendId; + char idstr[64]; +} SBackendCfWrapper; +typedef struct STdbState { + SBackendCfWrapper *pBackendCfWrapper; + int64_t backendCfWrapperId; + char idstr[64]; + + struct SStreamTask *pOwner; + void *db; + void *pStateDb; + void *pFuncStateDb; + void *pFillStateDb; // todo refactor + void *pSessionStateDb; + void *pParNameDb; + void *pParTagDb; + void *txn; } STdbState; typedef struct { diff --git a/include/libs/function/tudf.h b/include/libs/function/tudf.h index b71d50d43c..6b15833917 100644 --- a/include/libs/function/tudf.h +++ b/include/libs/function/tudf.h @@ -111,6 +111,12 @@ int32_t udfStartUdfd(int32_t startDnodeId); */ int32_t udfStopUdfd(); +/** + * get udfd pid + * + */ + int32_t udfGetUdfdPid(int32_t* pUdfdPid); + #ifdef __cplusplus } #endif diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index 3a36601b11..3ac971344b 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -362,7 +362,7 @@ typedef struct SCreateTopicStmt { char subDbName[TSDB_DB_NAME_LEN]; char subSTbName[TSDB_TABLE_NAME_LEN]; bool ignoreExists; - bool withMeta; + int8_t withMeta; SNode* pQuery; SNode* pWhere; } SCreateTopicStmt; diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 453c5d4914..c1481da80c 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -246,6 +246,7 @@ typedef struct SSortLogicNode { SLogicNode node; SNodeList* pSortKeys; bool groupSort; + int64_t maxRows; } SSortLogicNode; typedef struct SPartitionLogicNode { @@ -523,6 +524,7 @@ typedef struct SSortPhysiNode { SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function SNodeList* pSortKeys; // element is SOrderByExprNode, and SOrderByExprNode::pExpr is SColumnNode SNodeList* pTargets; + int64_t maxRows; } SSortPhysiNode; typedef SSortPhysiNode SGroupSortPhysiNode; diff --git a/include/libs/stream/streamState.h b/include/libs/stream/streamState.h index 7f9d20a9dd..7747df8595 100644 --- a/include/libs/stream/streamState.h +++ b/include/libs/stream/streamState.h @@ -138,6 +138,8 @@ int32_t streamStateCurPrev(SStreamState* pState, SStreamStateCur* pCur); int32_t streamStatePutParName(SStreamState* pState, int64_t groupId, const char* tbname); int32_t streamStateGetParName(SStreamState* pState, int64_t groupId, void** pVal); +void streamStateReloadInfo(SStreamState* pState, TSKEY ts); + /***compare func **/ typedef struct SStateChekpoint { diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 4fdee619a1..af776da87c 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -44,10 +44,8 @@ enum { TASK_STATUS__DROPPING, TASK_STATUS__FAIL, TASK_STATUS__STOP, - TASK_STATUS__WAIT_DOWNSTREAM, - TASK_STATUS__RECOVER_PREPARE, - TASK_STATUS__RECOVER1, - TASK_STATUS__RECOVER2, + TASK_STATUS__SCAN_HISTORY, // stream task scan history data by using tsdbread in the stream scanner + TASK_STATUS__HALT, // stream task will handle all data in the input queue, and then paused TASK_STATUS__PAUSE, }; @@ -133,7 +131,6 @@ typedef struct { // ref data block, for delete typedef struct { int8_t type; - int64_t ver; SSDataBlock* pBlock; } SStreamRefDataBlock; @@ -203,13 +200,11 @@ static FORCE_INLINE void streamQueueProcessFail(SStreamQueue* queue) { atomic_store_8(&queue->status, STREAM_QUEUE__FAILED); } -void* streamQueueNextItem(SStreamQueue* queue); +void* streamQueueNextItem(SStreamQueue* pQueue); SStreamDataSubmit* streamDataSubmitNew(SPackedData* pData, int32_t type); void streamDataSubmitDestroy(SStreamDataSubmit* pDataSubmit); -SStreamDataSubmit* streamSubmitBlockClone(SStreamDataSubmit* pSubmit); - typedef struct { char* qmsg; void* pExecutor; // not applicable to encoder and decoder @@ -251,7 +246,7 @@ typedef struct { int8_t reserved; } STaskSinkFetch; -typedef struct { +typedef struct SStreamChildEpInfo { int32_t nodeId; int32_t childId; int32_t taskId; @@ -271,31 +266,55 @@ typedef struct SCheckpointInfo { } SCheckpointInfo; typedef struct SStreamStatus { - int8_t taskStatus; - int8_t schedStatus; - int8_t keepTaskStatus; + int8_t taskStatus; + int8_t downstreamReady; // downstream tasks are all ready now, if this flag is set + int8_t schedStatus; + int8_t keepTaskStatus; + bool transferState; + int8_t timerActive; // timer is active } SStreamStatus; -struct SStreamTask { - SStreamId id; - int32_t totalLevel; - int8_t taskLevel; - int8_t outputType; - int16_t dispatchMsgType; - SStreamStatus status; - int32_t selfChildId; - int32_t nodeId; // vgroup id - SEpSet epSet; - SCheckpointInfo chkInfo; - STaskExec exec; - int8_t fillHistory; // fill history - int64_t ekey; // end ts key - int64_t endVer; // end version +typedef struct SHistDataRange { + SVersionRange range; + STimeWindow window; +} SHistDataRange; - // children info - SArray* childEpInfo; // SArray - int32_t nextCheckId; - SArray* checkpointInfo; // SArray +typedef struct SSTaskBasicInfo { + int32_t nodeId; // vgroup id or snode id + SEpSet epSet; + int32_t selfChildId; + int32_t totalLevel; + int8_t taskLevel; + int8_t fillHistory; // is fill history task or not +} SSTaskBasicInfo; + +typedef struct SDispatchMsgInfo { + void* pData; // current dispatch data + int16_t msgType; // dispatch msg type + int32_t retryCount; // retry send data count + int64_t blockingTs; // output blocking timestamp +} SDispatchMsgInfo; + +typedef struct { + int8_t outputType; + int8_t outputStatus; + SStreamQueue* outputQueue; +} SSTaskOutputInfo; + +struct SStreamTask { + SStreamId id; + SSTaskBasicInfo info; + int8_t outputType; + SDispatchMsgInfo msgInfo; + SStreamStatus status; + SCheckpointInfo chkInfo; + STaskExec exec; + SHistDataRange dataRange; + SStreamId historyTaskId; + SStreamId streamTaskId; + SArray* pUpstreamEpInfoList; // SArray, // children info + int32_t nextCheckId; + SArray* checkpointInfo; // SArray // output union { @@ -314,13 +333,14 @@ struct SStreamTask { // trigger int8_t triggerStatus; int64_t triggerParam; - void* timer; + void* schedTimer; + void* launchTaskTimer; SMsgCb* pMsgCb; // msg handle SStreamState* pState; // state backend // the followings attributes don't be serialized - int32_t recoverTryingDownstream; - int32_t recoverWaitingUpstream; + int32_t notReadyTasks; + int32_t numOfWaitingUpstream; int64_t checkReqId; SArray* checkReqIds; // shuffle int32_t refCnt; @@ -332,22 +352,24 @@ struct SStreamTask { // meta typedef struct SStreamMeta { - char* path; - TDB* db; - TTB* pTaskDb; - TTB* pCheckpointDb; - SHashObj* pTasks; - SArray* pTaskList; // SArray - void* ahandle; - TXN* txn; - FTaskExpand* expandFunc; - int32_t vgId; - SRWLatch lock; - int32_t walScanCounter; - void* streamBackend; - int64_t streamBackendRid; - int64_t checkpointTs; + char* path; + TDB* db; + TTB* pTaskDb; + TTB* pCheckpointDb; + SHashObj* pTasks; + SArray* pTaskList; // SArray + void* ahandle; + TXN* txn; + FTaskExpand* expandFunc; + int32_t vgId; + SRWLatch lock; + int32_t walScanCounter; + void* streamBackend; + int64_t streamBackendRid; + SHashObj* pTaskBackendUnique; + TdThreadMutex backendMutex; + int64_t checkpointTs; SArray* checkpointSaved; SArray* checkpointInUse; int32_t checkpointCap; @@ -436,16 +458,17 @@ typedef struct { SMsgHead msgHead; int64_t streamId; int32_t taskId; -} SStreamRecoverStep1Req, SStreamRecoverStep2Req; + int8_t igUntreated; +} SStreamScanHistoryReq; typedef struct { int64_t streamId; int32_t taskId; int32_t childId; -} SStreamRecoverFinishReq; +} SStreamRecoverFinishReq, SStreamTransferReq; -int32_t tEncodeSStreamRecoverFinishReq(SEncoder* pEncoder, const SStreamRecoverFinishReq* pReq); -int32_t tDecodeSStreamRecoverFinishReq(SDecoder* pDecoder, SStreamRecoverFinishReq* pReq); +int32_t tEncodeStreamRecoverFinishReq(SEncoder* pEncoder, const SStreamRecoverFinishReq* pReq); +int32_t tDecodeStreamRecoverFinishReq(SDecoder* pDecoder, SStreamRecoverFinishReq* pReq); typedef struct { int64_t streamId; @@ -514,11 +537,11 @@ typedef struct { SArray* checkpointVer; // SArray } SStreamRecoverDownstreamRsp; -int32_t tEncodeSStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq* pReq); -int32_t tDecodeSStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq); +int32_t tEncodeStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq* pReq); +int32_t tDecodeStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq); -int32_t tEncodeSStreamTaskCheckRsp(SEncoder* pEncoder, const SStreamTaskCheckRsp* pRsp); -int32_t tDecodeSStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp); +int32_t tEncodeStreamTaskCheckRsp(SEncoder* pEncoder, const SStreamTaskCheckRsp* pRsp); +int32_t tDecodeStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp); int32_t tEncodeSStreamTaskRecoverReq(SEncoder* pEncoder, const SStreamRecoverDownstreamReq* pReq); int32_t tDecodeSStreamTaskRecoverReq(SDecoder* pDecoder, SStreamRecoverDownstreamReq* pReq); @@ -530,9 +553,11 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq); int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq); void tDeleteStreamRetrieveReq(SStreamRetrieveReq* pReq); -void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq); +int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, + int64_t dstTaskId); +void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq); -int32_t streamSetupTrigger(SStreamTask* pTask); +int32_t streamSetupScheduleTrigger(SStreamTask* pTask); int32_t streamProcessRunReq(SStreamTask* pTask); int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pMsg, bool exec); @@ -547,30 +572,44 @@ int32_t streamSchedExec(SStreamTask* pTask); int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock); bool streamTaskShouldStop(const SStreamStatus* pStatus); bool streamTaskShouldPause(const SStreamStatus* pStatus); +bool streamTaskIsIdle(const SStreamTask* pTask); int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz); +char* createStreamTaskIdStr(int64_t streamId, int32_t taskId); + // recover and fill history -int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version); -int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version); +void streamPrepareNdoCheckDownstream(SStreamTask* pTask); +int32_t streamTaskCheckDownstreamTasks(SStreamTask* pTask); +int32_t streamTaskLaunchScanHistory(SStreamTask* pTask); int32_t streamTaskCheckStatus(SStreamTask* pTask); -int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version); +int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp); +int32_t streamCheckHistoryTaskDownstrem(SStreamTask* pTask); +int32_t streamTaskScanHistoryDataComplete(SStreamTask* pTask); +int32_t streamStartRecoverTask(SStreamTask* pTask, int8_t igUntreated); +bool streamTaskRecoverScanStep1Finished(SStreamTask* pTask); +bool streamTaskRecoverScanStep2Finished(SStreamTask* pTask); +int32_t streamTaskRecoverSetAllStepFinished(SStreamTask* pTask); // common -int32_t streamSetParamForRecover(SStreamTask* pTask); -int32_t streamRestoreParam(SStreamTask* pTask); -int32_t streamSetStatusNormal(SStreamTask* pTask); +int32_t streamSetParamForScanHistoryData(SStreamTask* pTask); +int32_t streamRestoreParam(SStreamTask* pTask); +int32_t streamSetStatusNormal(SStreamTask* pTask); +const char* streamGetTaskStatusStr(int32_t status); + // source level -int32_t streamSourceRecoverPrepareStep1(SStreamTask* pTask, int64_t ver); -int32_t streamBuildSourceRecover1Req(SStreamTask* pTask, SStreamRecoverStep1Req* pReq); -int32_t streamSourceRecoverScanStep1(SStreamTask* pTask); -int32_t streamBuildSourceRecover2Req(SStreamTask* pTask, SStreamRecoverStep2Req* pReq); -int32_t streamSourceRecoverScanStep2(SStreamTask* pTask, int64_t ver); -int32_t streamDispatchRecoverFinishReq(SStreamTask* pTask); +int32_t streamSetParamForStreamScannerStep1(SStreamTask* pTask, SVersionRange* pVerRange, STimeWindow* pWindow); +int32_t streamSetParamForStreamScannerStep2(SStreamTask* pTask, SVersionRange* pVerRange, STimeWindow* pWindow); +int32_t streamBuildSourceRecover1Req(SStreamTask* pTask, SStreamScanHistoryReq* pReq, int8_t igUntreated); +int32_t streamSourceScanHistoryData(SStreamTask* pTask); +// int32_t streamSourceRecoverScanStep2(SStreamTask* pTask, int64_t ver); +int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask); + +int32_t streamDispatchTransferStateMsg(SStreamTask* pTask); + // agg level int32_t streamAggRecoverPrepare(SStreamTask* pTask); -// int32_t streamAggChildrenRecoverFinish(SStreamTask* pTask); -int32_t streamProcessRecoverFinishReq(SStreamTask* pTask, int32_t childId); +int32_t streamProcessRecoverFinishReq(SStreamTask* pTask, int32_t taskId, int32_t childId); void streamMetaInit(); void streamMetaCleanup(); @@ -597,6 +636,9 @@ int32_t streamProcessCheckpointSourceReq(SStreamMeta* pMeta, SStreamTask* pTask, int32_t streamProcessCheckpointReq(SStreamMeta* pMeta, SStreamTask* pTask, SStreamCheckpointReq* pReq); int32_t streamProcessCheckpointRsp(SStreamMeta* pMeta, SStreamTask* pTask, SStreamCheckpointRsp* pRsp); +int32_t streamTaskReleaseState(SStreamTask* pTask); +int32_t streamTaskReloadState(SStreamTask* pTask); + #ifdef __cplusplus } #endif diff --git a/include/libs/stream/tstreamFileState.h b/include/libs/stream/tstreamFileState.h index 0dbacf6c9f..b2255013ca 100644 --- a/include/libs/stream/tstreamFileState.h +++ b/include/libs/stream/tstreamFileState.h @@ -28,11 +28,10 @@ extern "C" { #endif typedef struct SStreamFileState SStreamFileState; - typedef SList SStreamSnapshot; SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize, - GetTsFun fp, void* pFile, TSKEY delMark); + GetTsFun fp, void* pFile, TSKEY delMark, const char* id); void streamFileStateDestroy(SStreamFileState* pFileState); void streamFileStateClear(SStreamFileState* pFileState); bool needClearDiskBuff(SStreamFileState* pFileState); @@ -50,6 +49,7 @@ int32_t recoverSnapshot(SStreamFileState* pFileState); int32_t getSnapshotIdList(SStreamFileState* pFileState, SArray* list); int32_t deleteExpiredCheckPoint(SStreamFileState* pFileState, TSKEY mark); int32_t streamFileStateGeSelectRowSize(SStreamFileState* pFileState); +void streamFileStateReloadInfo(SStreamFileState* pFileState, TSKEY ts); #ifdef __cplusplus } diff --git a/include/util/taoserror.h b/include/util/taoserror.h index ce24761df9..772a668f0f 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -66,8 +66,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_RPC_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0018) // #define TSDB_CODE_RPC_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x0019) // #define TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED TAOS_DEF_ERROR_CODE(0, 0x0020) // "Vgroup could not be connected" -#define TSDB_CODE_RPC_SOMENODE_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0021) // -#define TSDB_CODE_RPC_MAX_SESSIONS TAOS_DEF_ERROR_CODE(0, 0x0022) // +#define TSDB_CODE_RPC_SOMENODE_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0021) // +#define TSDB_CODE_RPC_MAX_SESSIONS TAOS_DEF_ERROR_CODE(0, 0x0022) // @@ -277,7 +277,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_INVALID_FUNC_COMMENT TAOS_DEF_ERROR_CODE(0, 0x0378) #define TSDB_CODE_MND_INVALID_FUNC_RETRIEVE TAOS_DEF_ERROR_CODE(0, 0x0379) - + // mnode-db #define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0380) @@ -288,9 +288,9 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_TOO_MANY_DATABASES TAOS_DEF_ERROR_CODE(0, 0x0385) #define TSDB_CODE_MND_DB_IN_DROPPING TAOS_DEF_ERROR_CODE(0, 0x0386) // // #define TSDB_CODE_MND_VGROUP_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0387) // 2.x -#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0388) // +#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0388) // #define TSDB_CODE_MND_INVALID_DB_ACCT TAOS_DEF_ERROR_CODE(0, 0x0389) // internal -#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x038A) // +#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x038A) // #define TSDB_CODE_MND_DB_INDEX_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x038B) #define TSDB_CODE_MND_DB_RETENTION_PERIOD_ZERO TAOS_DEF_ERROR_CODE(0, 0x038C) // #define TSDB_CODE_MND_INVALID_DB_OPTION_DAYS TAOS_DEF_ERROR_CODE(0, 0x0390) // 2.x @@ -516,6 +516,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_QRY_JSON_IN_GROUP_ERROR TAOS_DEF_ERROR_CODE(0, 0x072E) #define TSDB_CODE_QRY_JOB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x072F) #define TSDB_CODE_QRY_QWORKER_QUIT TAOS_DEF_ERROR_CODE(0, 0x0730) +#define TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR TAOS_DEF_ERROR_CODE(0, 0x0731) // grant #define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800) @@ -768,6 +769,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TMQ_CONSUMER_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x4001) #define TSDB_CODE_TMQ_CONSUMER_CLOSED TAOS_DEF_ERROR_CODE(0, 0x4002) #define TSDB_CODE_TMQ_CONSUMER_ERROR TAOS_DEF_ERROR_CODE(0, 0x4003) +#define TSDB_CODE_TMQ_TOPIC_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x4004) +#define TSDB_CODE_TMQ_GROUP_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x4005) // stream #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) @@ -778,7 +781,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TDLITE_IVLD_OPEN_DIR TAOS_DEF_ERROR_CODE(0, 0x5101) // UTIL -#define TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x6000) +#define TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x6000) #ifdef __cplusplus } diff --git a/include/util/tcompare.h b/include/util/tcompare.h index f92e1c3970..2fa736f4df 100644 --- a/include/util/tcompare.h +++ b/include/util/tcompare.h @@ -79,6 +79,7 @@ int32_t compareDoubleVal(const void *pLeft, const void *pRight); int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight); int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight); +int32_t compareLenBinaryVal(const void *pLeft, const void *pRight); int32_t comparestrRegexMatch(const void *pLeft, const void *pRight); int32_t comparestrRegexNMatch(const void *pLeft, const void *pRight); diff --git a/include/util/theap.h b/include/util/theap.h index fb5ff8301a..8ddeeb28a4 100644 --- a/include/util/theap.h +++ b/include/util/theap.h @@ -17,6 +17,7 @@ #define _TD_UTIL_HEAP_H_ #include "os.h" +#include "tarray.h" #ifdef __cplusplus extern "C" { @@ -58,6 +59,48 @@ void heapDequeue(Heap* heap); size_t heapSize(Heap* heap); +typedef bool (*pq_comp_fn)(void* l, void* r, void* param); + +typedef struct PriorityQueueNode { + void* data; +} PriorityQueueNode; + +typedef struct PriorityQueue PriorityQueue; + +PriorityQueue* createPriorityQueue(pq_comp_fn fn, FDelete deleteFn, void* param); + +void taosPQSetFn(PriorityQueue* pq, pq_comp_fn fn); + +void destroyPriorityQueue(PriorityQueue* pq); + +PriorityQueueNode* taosPQTop(PriorityQueue* pq); + +size_t taosPQSize(PriorityQueue* pq); + +void taosPQPush(PriorityQueue* pq, const PriorityQueueNode* node); + +void taosPQPop(PriorityQueue* pq); + +typedef struct BoundedQueue BoundedQueue; + +BoundedQueue* createBoundedQueue(uint32_t maxSize, pq_comp_fn fn, FDelete deleteFn, void* param); + +void taosBQSetFn(BoundedQueue* q, pq_comp_fn fn); + +void destroyBoundedQueue(BoundedQueue* q); + +void taosBQPush(BoundedQueue* q, PriorityQueueNode* n); + +PriorityQueueNode* taosBQTop(BoundedQueue* q); + +size_t taosBQSize(BoundedQueue* q); + +size_t taosBQMaxSize(BoundedQueue* q); + +void taosBQBuildHeap(BoundedQueue* q); + +void taosBQPop(BoundedQueue* q); + #ifdef __cplusplus } #endif diff --git a/packaging/testpackage.sh b/packaging/testpackage.sh index 081383f89b..0622b01f2b 100755 --- a/packaging/testpackage.sh +++ b/packaging/testpackage.sh @@ -152,7 +152,7 @@ function wgetFile { file=$1 versionPath=$2 sourceP=$3 -nasServerIP="192.168.1.131" +nasServerIP="192.168.1.213" packagePath="/nas/TDengine/v${versionPath}/${verMode}" if [ -f ${file} ];then echoColor YD "${file} already exists ,it will delete it and download it again " diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 503120fe85..13dc019feb 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -749,6 +749,9 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns, pReq.suid = pTableMeta->uid; pReq.source = TD_REQ_FROM_TAOX; pSql = (action == SCHEMA_ACTION_ADD_COLUMN) ? "sml_add_column" : "sml_modify_column_size"; + } else{ + uError("SML:0x%" PRIx64 " invalid action:%d", info->id, action); + goto end; } code = buildRequest(info->taos->id, pSql, strlen(pSql), NULL, false, &pRequest, 0); diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 975b304bf4..8ac9550aca 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -939,8 +939,6 @@ int stmtClose(TAOS_STMT* stmt) { stmtCleanSQLInfo(pStmt); taosMemoryFree(stmt); - STMT_DLOG_E("stmt freed"); - return TSDB_CODE_SUCCESS; } diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 8758cec2ec..c13f52a3d8 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -652,7 +652,7 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, int32_t type, tm int32_t j = 0; int32_t numOfVgroups = taosArrayGetSize(pTopic->vgs); for (j = 0; j < numOfVgroups; j++) { - SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j); + SMqClientVg* pVg = (SMqClientVg*)taosArrayGet(pTopic->vgs, j); if (pVg->vgId == vgId) { break; } @@ -666,7 +666,7 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, int32_t type, tm return; } - SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j); + SMqClientVg* pVg = (SMqClientVg*)taosArrayGet(pTopic->vgs, j); if (pVg->offsetInfo.currentOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.currentOffset, &pVg->offsetInfo.committedOffset)) { code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups, type); @@ -742,13 +742,15 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us static void generateTimedTask(int64_t refId, int32_t type) { tmq_t* tmq = taosAcquireRef(tmqMgmt.rsetId, refId); - if (tmq != NULL) { - int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t), DEF_QITEM, 0); - *pTaskType = type; - taosWriteQitem(tmq->delayedTask, pTaskType); - tsem_post(&tmq->rspSem); - taosReleaseRef(tmqMgmt.rsetId, refId); - } + if(tmq == NULL) return; + + int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t), DEF_QITEM, 0); + if(pTaskType == NULL) return; + + *pTaskType = type; + taosWriteQitem(tmq->delayedTask, pTaskType); + tsem_post(&tmq->rspSem); + taosReleaseRef(tmqMgmt.rsetId, refId); } void tmqAssignAskEpTask(void* param, void* tmrId) { @@ -763,19 +765,19 @@ void tmqAssignDelayedCommitTask(void* param, void* tmrId) { taosMemoryFree(param); } -void tmqAssignDelayedReportTask(void* param, void* tmrId) { - int64_t refId = *(int64_t*)param; - tmq_t* tmq = taosAcquireRef(tmqMgmt.rsetId, refId); - if (tmq != NULL) { - int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t), DEF_QITEM, 0); - *pTaskType = TMQ_DELAYED_TASK__REPORT; - taosWriteQitem(tmq->delayedTask, pTaskType); - tsem_post(&tmq->rspSem); - } - - taosReleaseRef(tmqMgmt.rsetId, refId); - taosMemoryFree(param); -} +//void tmqAssignDelayedReportTask(void* param, void* tmrId) { +// int64_t refId = *(int64_t*)param; +// tmq_t* tmq = taosAcquireRef(tmqMgmt.rsetId, refId); +// if (tmq != NULL) { +// int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t), DEF_QITEM, 0); +// *pTaskType = TMQ_DELAYED_TASK__REPORT; +// taosWriteQitem(tmq->delayedTask, pTaskType); +// tsem_post(&tmq->rspSem); +// } +// +// taosReleaseRef(tmqMgmt.rsetId, refId); +// taosMemoryFree(param); +//} int32_t tmqHbCb(void* param, SDataBuf* pMsg, int32_t code) { if (pMsg) { @@ -813,7 +815,7 @@ void tmqSendHbReq(void* param, void* tmrId) { offRows->offset = pVg->offsetInfo.currentOffset; char buf[TSDB_OFFSET_LEN] = {0}; tFormatOffset(buf, TSDB_OFFSET_LEN, &offRows->offset); - tscInfo("report offset: vgId:%d, offset:%s, rows:%"PRId64, offRows->vgId, buf, offRows->rows); + tscInfo("consumer:0x%" PRIx64 ",report offset: vgId:%d, offset:%s, rows:%"PRId64, tmq->consumerId, offRows->vgId, buf, offRows->rows); } } // tmq->needReportOffsetRows = false; @@ -917,7 +919,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) { } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__EP_RSP) { SMqAskEpRspWrapper* pEpRspWrapper = (SMqAskEpRspWrapper*)rspWrapper; tDeleteSMqAskEpRsp(&pEpRspWrapper->msg); - } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RSP) { + } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper; taosMemoryFreeClear(pRsp->pEpset); @@ -930,7 +932,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) { taosMemoryFreeClear(pRsp->pEpset); taosMemoryFree(pRsp->metaRsp.metaRsp); - } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__TAOSX_RSP) { + } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper; taosMemoryFreeClear(pRsp->pEpset); @@ -1405,7 +1407,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { strcpy(pRspWrapper->topicName, pParam->topicName); pMsg->pEpSet = NULL; - if (rspType == TMQ_MSG_TYPE__POLL_RSP) { + if (rspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { SDecoder decoder; tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); tDecodeMqDataRsp(&decoder, &pRspWrapper->dataRsp); @@ -1422,7 +1424,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { tDecodeMqMetaRsp(&decoder, &pRspWrapper->metaRsp); tDecoderClear(&decoder); memcpy(&pRspWrapper->metaRsp, pMsg->pData, sizeof(SMqRspHead)); - } else if (rspType == TMQ_MSG_TYPE__TAOSX_RSP) { + } else if (rspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { SDecoder decoder; tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); tDecodeSTaosxRsp(&decoder, &pRspWrapper->taosxRsp); @@ -1489,7 +1491,8 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic makeTopicVgroupKey(vgKey, pTopic->topicName, pVgEp->vgId); SVgroupSaveInfo* pInfo = taosHashGet(pVgOffsetHashMap, vgKey, strlen(vgKey)); - STqOffsetVal offsetNew = {.type = tmq->resetOffsetCfg}; + STqOffsetVal offsetNew = {0}; + offsetNew.type = tmq->resetOffsetCfg; SMqClientVg clientVg = { .pollCnt = 0, @@ -1881,7 +1884,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { terrno = TSDB_CODE_TQ_NO_COMMITTED_OFFSET; tscError("consumer:0x%" PRIx64 " unexpected rsp from poll, code:%s", tmq->consumerId, tstrerror(terrno)); return NULL; - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RSP) { + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)pRspWrapper; int32_t consumerEpoch = atomic_load_32(&tmq->epoch); @@ -1981,7 +1984,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { pRspWrapper = tmqFreeRspWrapper(pRspWrapper); taosFreeQitem(pollRspWrapper); } - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__TAOSX_RSP) { + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)pRspWrapper; int32_t consumerEpoch = atomic_load_32(&tmq->epoch); @@ -2023,7 +2026,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { void* pRsp = NULL; int64_t numOfRows = 0; if (pollRspWrapper->taosxRsp.createTableNum == 0) { - pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows); + tscError("consumer:0x%" PRIx64" createTableNum should > 0 if rsp type is data_meta", tmq->consumerId); } else { pRsp = tmqBuildTaosxRspFromWrapper(pollRspWrapper, pVg, &numOfRows); } diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 7cd33955c1..5d1854ee2c 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -160,9 +160,9 @@ static const SSysDbTableSchema streamSchema[] = { static const SSysDbTableSchema streamTaskSchema[] = { {.name = "stream_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, - {.name = "task_id", .bytes = 8, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, + {.name = "task_id", .bytes = 32, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "node_type", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, - {.name = "node_id", .bytes = 8, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, + {.name = "node_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, {.name = "level", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "status", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, }; @@ -290,7 +290,7 @@ static const SSysDbTableSchema subscriptionSchema[] = { {.name = "topic_name", .bytes = TSDB_TOPIC_FNAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "consumer_group", .bytes = TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}, - {.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false}, + {.name = "consumer_id", .bytes = 32, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "offset", .bytes = TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "rows", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false}, }; @@ -352,7 +352,7 @@ static const SSysDbTableSchema connectionsSchema[] = { static const SSysDbTableSchema consumerSchema[] = { - {.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false}, + {.name = "consumer_id", .bytes = 32, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "consumer_group", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "client_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, {.name = "status", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false}, diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 5d1288d831..b2f03fa7ba 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -47,6 +47,16 @@ int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRo } } +int32_t colDataGetRowLength(const SColumnInfoData* pColumnInfoData, int32_t rowIdx) { + if (colDataIsNull_s(pColumnInfoData, rowIdx)) return 0; + + if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) return pColumnInfoData->info.bytes; + if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) + return getJsonValueLen(colDataGetData(pColumnInfoData, rowIdx)); + else + return varDataTLen(colDataGetData(pColumnInfoData, rowIdx)); +} + int32_t colDataGetFullLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows) { if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { return pColumnInfoData->varmeta.length + sizeof(int32_t) * numOfRows; @@ -56,10 +66,6 @@ int32_t colDataGetFullLength(const SColumnInfoData* pColumnInfoData, int32_t num } } -void colDataTrim(SColumnInfoData* pColumnInfoData) { - // TODO -} - int32_t getJsonValueLen(const char* data) { int32_t dataLen = 0; if (*data == TSDB_DATA_TYPE_NULL) { @@ -78,10 +84,6 @@ int32_t getJsonValueLen(const char* data) { return dataLen; } -int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull) { - return colDataSetVal(pColumnInfoData, rowIndex, pData, isNull); -} - int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const char* pData, bool isNull) { if (isNull) { // There is a placehold for each NULL value of binary or nchar type. @@ -163,7 +165,7 @@ int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, } -int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) { +static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) { if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { return TSDB_CODE_SUCCESS; } @@ -632,7 +634,7 @@ int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) { } else { memcpy(pStart, pCol->pData, dataSize); pStart += dataSize; - } + } } return 0; @@ -871,41 +873,8 @@ int32_t dataBlockCompar(const void* p1, const void* p2, const void* param) { return 0; } -static int32_t doAssignOneTuple(SColumnInfoData* pDstCols, int32_t numOfRows, const SSDataBlock* pSrcBlock, - int32_t tupleIndex) { - int32_t code = 0; - size_t numOfCols = taosArrayGetSize(pSrcBlock->pDataBlock); - - for (int32_t i = 0; i < numOfCols; ++i) { - SColumnInfoData* pDst = &pDstCols[i]; - SColumnInfoData* pSrc = taosArrayGet(pSrcBlock->pDataBlock, i); - - if (pSrc->hasNull && colDataIsNull(pSrc, pSrcBlock->info.rows, tupleIndex, pSrcBlock->pBlockAgg[i])) { - code = colDataSetVal(pDst, numOfRows, NULL, true); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } else { - char* p = colDataGetData(pSrc, tupleIndex); - code = colDataSetVal(pDst, numOfRows, p, false); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - } - - return TSDB_CODE_SUCCESS; -} - static int32_t blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataBlock, const int32_t* index) { -#if 0 - for (int32_t i = 0; i < pDataBlock->info.rows; ++i) { - int32_t code = doAssignOneTuple(pCols, i, pDataBlock, index[i]); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } -#else + size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock); for (int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData* pDst = &pCols[i]; @@ -930,7 +899,7 @@ static int32_t blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataB } } } -#endif + return TSDB_CODE_SUCCESS; } @@ -1090,114 +1059,6 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) { return TSDB_CODE_SUCCESS; } -#if 0 -typedef struct SHelper { - int32_t index; - union { - char* pData; - int64_t i64; - double d64; - }; -} SHelper; - -SHelper* createTupleIndex_rv(int32_t numOfRows, SArray* pOrderInfo, SSDataBlock* pBlock) { - int32_t sortValLengthPerRow = 0; - int32_t numOfCols = taosArrayGetSize(pOrderInfo); - - for (int32_t i = 0; i < numOfCols; ++i) { - SBlockOrderInfo* pInfo = taosArrayGet(pOrderInfo, i); - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, pInfo->slotId); - pInfo->pColData = pColInfo; - sortValLengthPerRow += pColInfo->info.bytes; - } - - size_t len = sortValLengthPerRow * pBlock->info.rows; - - char* buf = taosMemoryCalloc(1, len); - SHelper* phelper = taosMemoryCalloc(numOfRows, sizeof(SHelper)); - for (int32_t i = 0; i < numOfRows; ++i) { - phelper[i].index = i; - phelper[i].pData = buf + sortValLengthPerRow * i; - } - - int32_t offset = 0; - for (int32_t i = 0; i < numOfCols; ++i) { - SBlockOrderInfo* pInfo = taosArrayGet(pOrderInfo, i); - for (int32_t j = 0; j < numOfRows; ++j) { - phelper[j].i64 = *(int32_t*)pInfo->pColData->pData + pInfo->pColData->info.bytes * j; - // memcpy(phelper[j].pData + offset, pInfo->pColData->pData + pInfo->pColData->info.bytes * j, - // pInfo->pColData->info.bytes); - } - - offset += pInfo->pColData->info.bytes; - } - - taosMemoryFree(buf); - return phelper; -} - -int32_t dataBlockCompar_rv(const void* p1, const void* p2, const void* param) { - const SSDataBlockSortHelper* pHelper = (const SSDataBlockSortHelper*)param; - - SHelper* left = (SHelper*)p1; - SHelper* right = (SHelper*)p2; - - SArray* pInfo = pHelper->orderInfo; - - int32_t offset = 0; - int32_t leftx = *(int32_t*)left->pData; //*(int32_t*)(left->pData + offset); - int32_t rightx = *(int32_t*)right->pData; //*(int32_t*)(right->pData + offset); - - if (leftx == rightx) { - return 0; - } else { - return (leftx < rightx) ? -1 : 1; - } - return 0; -} - -int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullFirst) { - // Allocate the additional buffer. - int64_t p0 = taosGetTimestampUs(); - - SSDataBlockSortHelper helper = {.pDataBlock = pDataBlock, .orderInfo = pOrderInfo}; - - uint32_t rows = pDataBlock->info.rows; - SHelper* index = createTupleIndex_rv(rows, helper.orderInfo, pDataBlock); - if (index == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return terrno; - } - - taosqsort(index, rows, sizeof(SHelper), &helper, dataBlockCompar_rv); - - int64_t p1 = taosGetTimestampUs(); - SColumnInfoData* pCols = createHelpColInfoData(pDataBlock); - if (pCols == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return terrno; - } - - int64_t p2 = taosGetTimestampUs(); - - // int32_t code = blockDataAssign(pCols, pDataBlock, index); - // if (code != TSDB_CODE_SUCCESS) { - // terrno = code; - // return code; - // } - - int64_t p3 = taosGetTimestampUs(); - - copyBackToBlock(pDataBlock, pCols); - int64_t p4 = taosGetTimestampUs(); - - printf("sort:%" PRId64 ", create:%" PRId64 ", assign:%" PRId64 ", copyback:%" PRId64 ", rows:%d\n", p1 - p0, p2 - p1, - p3 - p2, p4 - p3, rows); - // destroyTupleIndex(index); - return 0; -} -#endif - void blockDataCleanup(SSDataBlock* pDataBlock) { blockDataEmpty(pDataBlock); SDataBlockInfo* pInfo = &pDataBlock->info; @@ -1334,8 +1195,7 @@ void blockDataFreeRes(SSDataBlock* pBlock) { colDataDestroy(pColInfoData); } - taosArrayDestroy(pBlock->pDataBlock); - pBlock->pDataBlock = NULL; + pBlock->pDataBlock = taosArrayDestroy(pBlock->pDataBlock); taosMemoryFreeClear(pBlock->pBlockAgg); memset(&pBlock->info, 0, sizeof(SDataBlockInfo)); } @@ -1350,6 +1210,7 @@ void* blockDataDestroy(SSDataBlock* pBlock) { return NULL; } +// todo remove it int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src) { dst->info = src->info; dst->info.rows = 0; @@ -1748,16 +1609,6 @@ static void colDataKeepFirstNRows(SColumnInfoData* pColInfoData, size_t n, size_ if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) { // pColInfoData->varmeta.length = colDataMoveVarData(pColInfoData, 0, n); memset(&pColInfoData->varmeta.offset[n], 0, total - n); - } else { // reset the bitmap value - /*int32_t stopIndex = BitmapLen(n) * 8; - for(int32_t i = n; i < stopIndex; ++i) { - colDataClearNull_f(pColInfoData->nullbitmap, i); - } - - int32_t remain = BitmapLen(total) - BitmapLen(n); - if (remain > 0) { - memset(pColInfoData->nullbitmap+BitmapLen(n), 0, remain); - }*/ } } @@ -1864,32 +1715,6 @@ void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) { return (void*)buf; } -int32_t tEncodeDataBlocks(void** buf, const SArray* blocks) { - int32_t tlen = 0; - int32_t sz = taosArrayGetSize(blocks); - tlen += taosEncodeFixedI32(buf, sz); - - for (int32_t i = 0; i < sz; i++) { - SSDataBlock* pBlock = taosArrayGet(blocks, i); - tlen += tEncodeDataBlock(buf, pBlock); - } - - return tlen; -} - -void* tDecodeDataBlocks(const void* buf, SArray** blocks) { - int32_t sz; - buf = taosDecodeFixedI32(buf, &sz); - - *blocks = taosArrayInit(sz, sizeof(SSDataBlock)); - for (int32_t i = 0; i < sz; i++) { - SSDataBlock pBlock = {0}; - buf = tDecodeDataBlock(buf, &pBlock); - taosArrayPush(*blocks, &pBlock); - } - return (void*)buf; -} - static char* formatTimestamp(char* buf, int64_t val, int precision) { time_t tt; int32_t ms = 0; @@ -1939,101 +1764,6 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) { return buf; } -#if 0 -void blockDebugShowDataBlock(SSDataBlock* pBlock, const char* flag) { - SArray* dataBlocks = taosArrayInit(1, sizeof(SSDataBlock*)); - taosArrayPush(dataBlocks, &pBlock); - blockDebugShowDataBlocks(dataBlocks, flag); - taosArrayDestroy(dataBlocks); -} - -void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag) { - char pBuf[128] = {0}; - int32_t sz = taosArrayGetSize(dataBlocks); - for (int32_t i = 0; i < sz; i++) { - SSDataBlock* pDataBlock = taosArrayGet(dataBlocks, i); - size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock); - - int32_t rows = pDataBlock->info.rows; - printf("%s |block ver %" PRIi64 " |block type %d |child id %d|group id %" PRIu64 "\n", flag, - pDataBlock->info.version, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, - pDataBlock->info.id.groupId); - for (int32_t j = 0; j < rows; j++) { - printf("%s |", flag); - for (int32_t k = 0; k < numOfCols; k++) { - SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k); - void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes); - if (k == 0) { - printf("cols:%d |", (int32_t)numOfCols); - } - if (colDataIsNull(pColInfoData, rows, j, NULL)) { - printf(" %15s |", "NULL"); - continue; - } - - switch (pColInfoData->info.type) { - case TSDB_DATA_TYPE_TIMESTAMP: - formatTimestamp(pBuf, *(uint64_t*)var, TSDB_TIME_PRECISION_MILLI); - printf(" %25s |", pBuf); - break; - case TSDB_DATA_TYPE_BOOL: - printf(" %15" PRIi8 " |", *(int8_t*)var); - break; - case TSDB_DATA_TYPE_TINYINT: - printf(" %15" PRIi8 " |", *(int8_t*)var); - break; - case TSDB_DATA_TYPE_SMALLINT: - printf(" %15" PRIi16 " |", *(int16_t*)var); - break; - case TSDB_DATA_TYPE_INT: - printf(" %15d |", *(int32_t*)var); - break; - case TSDB_DATA_TYPE_UTINYINT: - printf(" %15" PRIu8 " |", *(uint8_t*)var); - break; - case TSDB_DATA_TYPE_USMALLINT: - printf(" %15" PRIu16 " |", *(uint16_t*)var); - break; - case TSDB_DATA_TYPE_UINT: - printf(" %15u |", *(uint32_t*)var); - break; - case TSDB_DATA_TYPE_BIGINT: - printf(" %15" PRId64 " |", *(int64_t*)var); - break; - case TSDB_DATA_TYPE_UBIGINT: - printf(" %15" PRIu64 " |", *(uint64_t*)var); - break; - case TSDB_DATA_TYPE_FLOAT: - printf(" %15f |", *(float*)var); - break; - case TSDB_DATA_TYPE_DOUBLE: - printf(" %15lf |", *(double*)var); - break; - case TSDB_DATA_TYPE_VARCHAR: - case TSDB_DATA_TYPE_GEOMETRY: { - char* pData = colDataGetVarData(pColInfoData, j); - int32_t dataSize = TMIN(sizeof(pBuf) - 1, varDataLen(pData)); - memset(pBuf, 0, dataSize + 1); - strncpy(pBuf, varDataVal(pData), dataSize); - printf(" %15s |", pBuf); - } break; - case TSDB_DATA_TYPE_NCHAR: { - char* pData = colDataGetVarData(pColInfoData, j); - int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData)); - memset(pBuf, 0, dataSize); - (void)taosUcs4ToMbs((TdUcs4*)varDataVal(pData), dataSize, pBuf); - printf(" %15s |", pBuf); - } break; - default: - break; - } - } - printf("\n"); - } - } -} -#endif - // for debug char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) { int32_t size = 2048*1024; @@ -2142,182 +1872,6 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) return dumpBuf; } -/** - * @brief TODO: Assume that the final generated result it less than 3M - * - * @param pReq - * @param pDataBlocks - * @param vgId - * @param suid - * - */ -#if 0 -int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataBlock, STSchema* pTSchema, int32_t vgId, - tb_uid_t suid) { - int32_t bufSize = sizeof(SSubmitReq); - int32_t sz = 1; - for (int32_t i = 0; i < sz; ++i) { - const SDataBlockInfo* pBlkInfo = &pDataBlock->info; - - int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock); - bufSize += pBlkInfo->rows * (TD_ROW_HEAD_LEN + pBlkInfo->rowSize + BitmapLen(colNum)); - bufSize += sizeof(SSubmitBlk); - } - - *pReq = taosMemoryCalloc(1, bufSize); - if (!(*pReq)) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return TSDB_CODE_FAILED; - } - void* pDataBuf = *pReq; - - int32_t msgLen = sizeof(SSubmitReq); - int32_t numOfBlks = 0; - SRowBuilder rb = {0}; - tdSRowInit(&rb, pTSchema->version); - - for (int32_t i = 0; i < sz; ++i) { - int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock); - int32_t rows = pDataBlock->info.rows; - - if (colNum <= 1) { - // invalid if only with TS col - continue; - } - - if (rb.nCols != colNum) { - tdSRowSetTpInfo(&rb, colNum, pTSchema->flen); - } - - SSubmitBlk* pSubmitBlk = POINTER_SHIFT(pDataBuf, msgLen); - pSubmitBlk->suid = suid; - pSubmitBlk->uid = pDataBlock->info.id.groupId; - pSubmitBlk->numOfRows = rows; - pSubmitBlk->sversion = pTSchema->version; - - msgLen += sizeof(SSubmitBlk); - int32_t dataLen = 0; - for (int32_t j = 0; j < rows; ++j) { // iterate by row - tdSRowResetBuf(&rb, POINTER_SHIFT(pDataBuf, msgLen + dataLen)); // set row buf - bool isStartKey = false; - int32_t offset = 0; - for (int32_t k = 0; k < colNum; ++k) { // iterate by column - SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k); - STColumn* pCol = &pTSchema->columns[k]; - void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes); - switch (pColInfoData->info.type) { - case TSDB_DATA_TYPE_TIMESTAMP: - if (!isStartKey) { - isStartKey = true; - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NORM, var, true, - offset, k); - continue; // offset should keep 0 for next column - - } else if (colDataIsNull_s(pColInfoData, j)) { - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NULL, NULL, - false, offset, k); - } else { - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NORM, var, - true, offset, k); - } - break; - case TSDB_DATA_TYPE_NCHAR: - case TSDB_DATA_TYPE_VARCHAR: // TSDB_DATA_TYPE_BINARY - case TSDB_DATA_TYPE_GEOMETRY: { - if (colDataIsNull_s(pColInfoData, j)) { - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, pColInfoData->info.type, TD_VTYPE_NULL, NULL, - false, offset, k); - } else { - void* data = colDataGetData(pColInfoData, j); - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, pColInfoData->info.type, TD_VTYPE_NORM, data, - true, offset, k); - } - break; - } - case TSDB_DATA_TYPE_VARBINARY: - case TSDB_DATA_TYPE_DECIMAL: - case TSDB_DATA_TYPE_BLOB: - case TSDB_DATA_TYPE_JSON: - case TSDB_DATA_TYPE_MEDIUMBLOB: - uError("the column type %" PRIi16 " is defined but not implemented yet", pColInfoData->info.type); - break; - default: - if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) { - if (colDataIsNull_s(pColInfoData, j)) { - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, pCol->type, TD_VTYPE_NULL, NULL, false, - offset, k); - } else if (pCol->type == pColInfoData->info.type) { - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, pCol->type, TD_VTYPE_NORM, var, true, offset, - k); - } else { - char tv[8] = {0}; - if (pColInfoData->info.type == TSDB_DATA_TYPE_FLOAT) { - float v = 0; - GET_TYPED_DATA(v, float, pColInfoData->info.type, var); - SET_TYPED_DATA(&tv, pCol->type, v); - } else if (pColInfoData->info.type == TSDB_DATA_TYPE_DOUBLE) { - double v = 0; - GET_TYPED_DATA(v, double, pColInfoData->info.type, var); - SET_TYPED_DATA(&tv, pCol->type, v); - } else if (IS_SIGNED_NUMERIC_TYPE(pColInfoData->info.type)) { - int64_t v = 0; - GET_TYPED_DATA(v, int64_t, pColInfoData->info.type, var); - SET_TYPED_DATA(&tv, pCol->type, v); - } else { - uint64_t v = 0; - GET_TYPED_DATA(v, uint64_t, pColInfoData->info.type, var); - SET_TYPED_DATA(&tv, pCol->type, v); - } - tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, pCol->type, TD_VTYPE_NORM, tv, true, offset, - k); - } - } else { - uError("the column type %" PRIi16 " is undefined\n", pColInfoData->info.type); - } - break; - } - offset += TYPE_BYTES[pCol->type]; // sum/avg would convert to int64_t/uint64_t/double during aggregation - } - tdSRowEnd(&rb); - dataLen += TD_ROW_LEN(rb.pBuf); -#ifdef TD_DEBUG_PRINT_ROW - tdSRowPrint(rb.pBuf, pTSchema, __func__); -#endif - } - - ++numOfBlks; - - pSubmitBlk->dataLen = dataLen; - msgLen += pSubmitBlk->dataLen; - } - - if (numOfBlks > 0) { - (*pReq)->length = msgLen; - - (*pReq)->header.vgId = htonl(vgId); - (*pReq)->header.contLen = htonl(msgLen); - (*pReq)->length = (*pReq)->header.contLen; - (*pReq)->numOfBlocks = htonl(numOfBlks); - SSubmitBlk* blk = (SSubmitBlk*)((*pReq) + 1); - while (numOfBlks--) { - int32_t dataLen = blk->dataLen; - blk->uid = htobe64(blk->uid); - blk->suid = htobe64(blk->suid); - blk->sversion = htonl(blk->sversion); - blk->dataLen = htonl(blk->dataLen); - blk->schemaLen = htonl(blk->schemaLen); - blk->numOfRows = htonl(blk->numOfRows); - blk = (SSubmitBlk*)(blk->data + dataLen); - } - } else { - // no valid rows - taosMemoryFreeClear(*pReq); - } - - return TSDB_CODE_SUCCESS; -} -#endif - int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDataBlock, const STSchema* pTSchema, int64_t uid, int32_t vgId, tb_uid_t suid) { SSubmitReq2* pReq = *ppReq; @@ -2721,3 +2275,149 @@ const char* blockDecode(SSDataBlock* pBlock, const char* pData) { ASSERT(pStart - pData == dataLen); return pStart; } + +void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList) { +// int32_t totalRows = pBlock->info.rows; + int32_t bmLen = BitmapLen(totalRows); + char* pBitmap = NULL; + int32_t maxRows = 0; + + size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i); + // it is a reserved column for scalar function, and no data in this column yet. + if (pDst->pData == NULL) { + continue; + } + + int32_t numOfRows = 0; + if (IS_VAR_DATA_TYPE(pDst->info.type)) { + int32_t j = 0; + pDst->varmeta.length = 0; + + while (j < totalRows) { + if (pBoolList[j] == 0) { + j += 1; + continue; + } + + if (colDataIsNull_var(pDst, j)) { + colDataSetNull_var(pDst, numOfRows); + } else { + // fix address sanitizer error. p1 may point to memory that will change during realloc of colDataSetVal, first copy it to p2 + char* p1 = colDataGetVarData(pDst, j); + int32_t len = 0; + if (pDst->info.type == TSDB_DATA_TYPE_JSON) { + len = getJsonValueLen(p1); + } else { + len = varDataTLen(p1); + } + char* p2 = taosMemoryMalloc(len); + memcpy(p2, p1, len); + colDataSetVal(pDst, numOfRows, p2, false); + taosMemoryFree(p2); + } + numOfRows += 1; + j += 1; + } + + if (maxRows < numOfRows) { + maxRows = numOfRows; + } + } else { + if (pBitmap == NULL) { + pBitmap = taosMemoryCalloc(1, bmLen); + } + + memcpy(pBitmap, pDst->nullbitmap, bmLen); + memset(pDst->nullbitmap, 0, bmLen); + + int32_t j = 0; + + switch (pDst->info.type) { + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_DOUBLE: + case TSDB_DATA_TYPE_TIMESTAMP: + while (j < totalRows) { + if (pBoolList[j] == 0) { + j += 1; + continue; + } + + if (colDataIsNull_f(pBitmap, j)) { + colDataSetNull_f(pDst->nullbitmap, numOfRows); + } else { + ((int64_t*)pDst->pData)[numOfRows] = ((int64_t*)pDst->pData)[j]; + } + numOfRows += 1; + j += 1; + } + break; + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UINT: + while (j < totalRows) { + if (pBoolList[j] == 0) { + j += 1; + continue; + } + if (colDataIsNull_f(pBitmap, j)) { + colDataSetNull_f(pDst->nullbitmap, numOfRows); + } else { + ((int32_t*)pDst->pData)[numOfRows] = ((int32_t*)pDst->pData)[j]; + } + numOfRows += 1; + j += 1; + } + break; + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_USMALLINT: + while (j < totalRows) { + if (pBoolList[j] == 0) { + j += 1; + continue; + } + if (colDataIsNull_f(pBitmap, j)) { + colDataSetNull_f(pDst->nullbitmap, numOfRows); + } else { + ((int16_t*)pDst->pData)[numOfRows] = ((int16_t*)pDst->pData)[j]; + } + numOfRows += 1; + j += 1; + } + break; + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_UTINYINT: + while (j < totalRows) { + if (pBoolList[j] == 0) { + j += 1; + continue; + } + if (colDataIsNull_f(pBitmap, j)) { + colDataSetNull_f(pDst->nullbitmap, numOfRows); + } else { + ((int8_t*)pDst->pData)[numOfRows] = ((int8_t*)pDst->pData)[j]; + } + numOfRows += 1; + j += 1; + } + break; + } + } + + if (maxRows < numOfRows) { + maxRows = numOfRows; + } + } + + pBlock->info.rows = maxRows; + if (pBitmap != NULL) { + taosMemoryFree(pBitmap); + } +} + +int32_t blockGetEncodeSize(const SSDataBlock* pBlock) { + return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock); +} \ No newline at end of file diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index dc95c5f16f..2964a53e79 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -62,6 +62,7 @@ int32_t tsNumOfQnodeFetchThreads = 1; int32_t tsNumOfSnodeStreamThreads = 4; int32_t tsNumOfSnodeWriteThreads = 1; int32_t tsMaxStreamBackendCache = 128; // M +int32_t tsPQSortMemThreshold = 16; // M // sync raft int32_t tsElectInterval = 25 * 1000; @@ -104,11 +105,13 @@ char tsSmlChildTableName[TSDB_TABLE_NAME_LEN] = ""; // user defined child table // bool tsSmlDataFormat = false; // int32_t tsSmlBatchSize = 10000; +// tmq +int32_t tmqMaxTopicNum = 20; // query int32_t tsQueryPolicy = 1; int32_t tsQueryRspPolicy = 0; int64_t tsQueryMaxConcurrentTables = 200; // unit is TSDB_TABLE_NUM_UNIT -bool tsEnableQueryHb = false; +bool tsEnableQueryHb = true; bool tsEnableScience = false; // on taos-cli show float and doulbe with scientific notation if true bool tsTtlChangeOnWrite = false; // ttl delete time changes on last write if true int32_t tsQuerySmaOptimize = 0; @@ -510,6 +513,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddString(pCfg, "telemetryServer", tsTelemServer, 0) != 0) return -1; if (cfgAddInt32(pCfg, "telemetryPort", tsTelemPort, 1, 65056, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "tmqMaxTopicNum", tmqMaxTopicNum, 1, 10000, 1) != 0) return -1; + if (cfgAddInt32(pCfg, "transPullupInterval", tsTransPullupInterval, 1, 10000, 1) != 0) return -1; if (cfgAddInt32(pCfg, "mqRebalanceInterval", tsMqRebalanceInterval, 1, 10000, 1) != 0) return -1; if (cfgAddInt32(pCfg, "ttlUnit", tsTtlUnit, 1, 86400 * 365, 1) != 0) return -1; @@ -533,6 +538,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "filterScalarMode", tsFilterScalarMode, 0) != 0) return -1; if (cfgAddInt32(pCfg, "maxStreamBackendCache", tsMaxStreamBackendCache, 16, 1024, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "pqSortMemThreshold", tsPQSortMemThreshold, 1, 10240, 0) != 0) return -1; GRANT_CFG_ADD; return 0; @@ -880,6 +886,8 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tstrncpy(tsTelemServer, cfgGetItem(pCfg, "telemetryServer")->str, TSDB_FQDN_LEN); tsTelemPort = (uint16_t)cfgGetItem(pCfg, "telemetryPort")->i32; + tmqMaxTopicNum= cfgGetItem(pCfg, "tmqMaxTopicNum")->i32; + tsTransPullupInterval = cfgGetItem(pCfg, "transPullupInterval")->i32; tsMqRebalanceInterval = cfgGetItem(pCfg, "mqRebalanceInterval")->i32; tsTtlUnit = cfgGetItem(pCfg, "ttlUnit")->i32; @@ -914,6 +922,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsFilterScalarMode = cfgGetItem(pCfg, "filterScalarMode")->bval; tsMaxStreamBackendCache = cfgGetItem(pCfg, "maxStreamBackendCache")->i32; + tsPQSortMemThreshold = cfgGetItem(pCfg, "pqSortMemThreshold")->i32; GRANT_CFG_GET; return 0; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 4e8797b1ec..debb93e8ba 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -6982,8 +6982,11 @@ int32_t tDecodeSVAlterTbReqSetCtime(SDecoder* pDecoder, SVAlterTbReq* pReq, int6 if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeSVAlterTbReqCommon(pDecoder, pReq) < 0) return -1; - *(int64_t *)(pDecoder->data + pDecoder->pos) = ctimeMs; - if (tDecodeI64(pDecoder, &pReq->ctimeMs) < 0) return -1; + pReq->ctimeMs = 0; + if (!tDecodeIsEnd(pDecoder)) { + *(int64_t *)(pDecoder->data + pDecoder->pos) = ctimeMs; + if (tDecodeI64(pDecoder, &pReq->ctimeMs) < 0) return -1; + } tEndDecode(pDecoder); return 0; @@ -7541,8 +7544,11 @@ int32_t tDecodeSBatchDeleteReq(SDecoder *pDecoder, SBatchDeleteReq *pReq) { int32_t tDecodeSBatchDeleteReqSetCtime(SDecoder *pDecoder, SBatchDeleteReq *pReq, int64_t ctimeMs) { if (tDecodeSBatchDeleteReqCommon(pDecoder, pReq)) return -1; - *(int64_t *)(pDecoder->data + pDecoder->pos) = ctimeMs; - if (tDecodeI64(pDecoder, &pReq->ctimeMs) < 0) return -1; + pReq->ctimeMs = 0; + if (!tDecodeIsEnd(pDecoder)) { + *(int64_t *)(pDecoder->data + pDecoder->pos) = ctimeMs; + if (tDecodeI64(pDecoder, &pReq->ctimeMs) < 0) return -1; + } return 0; } diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index d8c43747f7..7a5581efbe 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -969,7 +969,7 @@ void taosFormatUtcTime(char* buf, int32_t bufLen, int64_t t, int32_t precision) default: fractionLen = 0; - ASSERT(false); + return; } if (taosLocalTime(", &ptm, buf) == NULL) { diff --git a/source/dnode/mgmt/mgmt_snode/src/smHandle.c b/source/dnode/mgmt/mgmt_snode/src/smHandle.c index 2387c4e25e..311cbdc43b 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smHandle.c +++ b/source/dnode/mgmt/mgmt_snode/src/smHandle.c @@ -76,6 +76,9 @@ SArray *smGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_PAUSE, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RESUME, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK_RSP, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_CHECK_POINT_SOURCE, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; code = 0; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index bf1e30a9bc..a0b3300a10 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -743,9 +743,10 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_RECOVER_FINISH, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TRANSFER_STATE, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK_RSP, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_PAUSE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RESUME, vmPutMsgToWriteQueue, 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 76e2f93027..247c1729a3 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -92,7 +92,7 @@ static void vmProcessStreamQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { const STraceId *trace = &pMsg->info.traceId; dGTrace("vgId:%d, msg:%p get from vnode-stream queue", pVnode->vgId, pMsg); - int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo); + int32_t code = vnodeProcessStreamMsg(pVnode->pImpl, pMsg, pInfo); if (code != 0) { if (terrno != 0) code = terrno; dGError("vgId:%d, msg:%p failed to process stream msg %s since %s", pVnode->vgId, pMsg, TMSG_INFO(pMsg->msgType), diff --git a/source/dnode/mnode/impl/inc/mndConsumer.h b/source/dnode/mnode/impl/inc/mndConsumer.h index 96401511d2..a3a31cfc5a 100644 --- a/source/dnode/mnode/impl/inc/mndConsumer.h +++ b/source/dnode/mnode/impl/inc/mndConsumer.h @@ -25,14 +25,15 @@ extern "C" { enum { MQ_CONSUMER_STATUS_REBALANCE = 1, // MQ_CONSUMER_STATUS__MODIFY_IN_REB, // this value is not used anymore - MQ_CONSUMER_STATUS__READY, - MQ_CONSUMER_STATUS__LOST, + MQ_CONSUMER_STATUS_READY, + MQ_CONSUMER_STATUS_LOST, // MQ_CONSUMER_STATUS__LOST_IN_REB, // this value is not used anymore - MQ_CONSUMER_STATUS__LOST_REBD, -}; +// MQ_CONSUMER_STATUS__LOST_REBD, +};\ int32_t mndInitConsumer(SMnode *pMnode); void mndCleanupConsumer(SMnode *pMnode); +void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId); SMqConsumerObj *mndAcquireConsumer(SMnode *pMnode, int64_t consumerId); void mndReleaseConsumer(SMnode *pMnode, SMqConsumerObj *pConsumer); diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 91c6a270c8..2d6acecbcc 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -137,12 +137,12 @@ typedef enum { } EDndReason; typedef enum { - CONSUMER_UPDATE__TOUCH = 1, // rebalance req do not need change consume topic - CONSUMER_UPDATE__ADD, - CONSUMER_UPDATE__REMOVE, - CONSUMER_UPDATE__LOST, - CONSUMER_UPDATE__RECOVER, - CONSUMER_UPDATE__REBALANCE, // subscribe req need change consume topic + CONSUMER_UPDATE_REB_MODIFY_NOTOPIC = 1, // topic do not need modified after rebalance + CONSUMER_UPDATE_REB_MODIFY_TOPIC, // topic need modified after rebalance + CONSUMER_UPDATE_REB_MODIFY_REMOVE, // topic need removed after rebalance +// CONSUMER_UPDATE_TIMER_LOST, + CONSUMER_UPDATE_RECOVER, + CONSUMER_UPDATE_SUB_MODIFY, // modify after subscribe req } ECsmUpdateType; typedef struct { @@ -549,7 +549,7 @@ typedef struct { // data for display int32_t pid; SEpSet ep; - int64_t upTime; + int64_t createTime; int64_t subscribeTime; int64_t rebalanceTime; @@ -560,7 +560,7 @@ typedef struct { } SMqConsumerObj; SMqConsumerObj* tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_LEN]); -void tDeleteSMqConsumerObj(SMqConsumerObj* pConsumer); +void tDeleteSMqConsumerObj(SMqConsumerObj* pConsumer, bool delete); int32_t tEncodeSMqConsumerObj(void** buf, const SMqConsumerObj* pConsumer); void* tDecodeSMqConsumerObj(const void* buf, SMqConsumerObj* pConsumer, int8_t sver); @@ -647,6 +647,14 @@ typedef struct { // SMqSubActionLogEntry* pLogEntry; } SMqRebOutputObj; +typedef struct SStreamConf { + int8_t igExpired; + int8_t trigger; + int8_t fillHistory; + int64_t triggerParam; + int64_t watermark; +} SStreamConf; + typedef struct { char name[TSDB_STREAM_FNAME_LEN]; // ctl @@ -660,12 +668,7 @@ typedef struct { // info int64_t uid; int8_t status; - // config - int8_t igExpired; - int8_t trigger; - int8_t fillHistory; - int64_t triggerParam; - int64_t watermark; + SStreamConf conf; // source and target int64_t sourceDbUid; int64_t targetDbUid; @@ -682,7 +685,11 @@ typedef struct { char* sql; char* ast; char* physicalPlan; - SArray* tasks; // SArray> + SArray* tasks; // SArray> + + SArray* pHTasksList; // generate the results for already stored ts data + int64_t hTaskUid; // stream task for history ts data + SSchemaWrapper outputSchema; SSchemaWrapper tagSchema; diff --git a/source/dnode/mnode/impl/inc/mndScheduler.h b/source/dnode/mnode/impl/inc/mndScheduler.h index 23085c53ee..14517a99d3 100644 --- a/source/dnode/mnode/impl/inc/mndScheduler.h +++ b/source/dnode/mnode/impl/inc/mndScheduler.h @@ -30,7 +30,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64_t uid, int8_t triggerType, int64_t watermark, int64_t deleteMark); -int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream); +int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream, int64_t nextWindowSkey); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndSubscribe.h b/source/dnode/mnode/impl/inc/mndSubscribe.h index fad316ea12..ba4328b8fe 100644 --- a/source/dnode/mnode/impl/inc/mndSubscribe.h +++ b/source/dnode/mnode/impl/inc/mndSubscribe.h @@ -25,6 +25,7 @@ extern "C" { int32_t mndInitSubscribe(SMnode *pMnode); void mndCleanupSubscribe(SMnode *pMnode); +int32_t mndGetGroupNumByTopic(SMnode *pMnode, const char *topicName); SMqSubscribeObj *mndAcquireSubscribe(SMnode *pMnode, const char *CGroup, const char *topicName); SMqSubscribeObj *mndAcquireSubscribeByKey(SMnode *pMnode, const char *key); void mndReleaseSubscribe(SMnode *pMnode, SMqSubscribeObj *pSub); diff --git a/source/dnode/mnode/impl/src/mndConsumer.c b/source/dnode/mnode/impl/src/mndConsumer.c index 4dded61ce3..47cc4a1ce7 100644 --- a/source/dnode/mnode/impl/src/mndConsumer.c +++ b/source/dnode/mnode/impl/src/mndConsumer.c @@ -26,6 +26,7 @@ #define MND_CONSUMER_VER_NUMBER 2 #define MND_CONSUMER_RESERVE_SIZE 64 +#define MND_MAX_GROUP_PER_TOPIC 100 #define MND_CONSUMER_LOST_HB_CNT 6 #define MND_CONSUMER_LOST_CLEAR_THRESHOLD 43200 @@ -63,7 +64,7 @@ int32_t mndInitConsumer(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_MND_TMQ_HB, mndProcessMqHbReq); mndSetMsgHandle(pMnode, TDMT_MND_TMQ_ASK_EP, mndProcessAskEpReq); mndSetMsgHandle(pMnode, TDMT_MND_TMQ_TIMER, mndProcessMqTimerMsg); - mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_LOST, mndProcessConsumerLostMsg); +// mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_LOST, mndProcessConsumerLostMsg); mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_RECOVER, mndProcessConsumerRecoverMsg); mndSetMsgHandle(pMnode, TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, mndProcessConsumerClearMsg); @@ -75,6 +76,22 @@ int32_t mndInitConsumer(SMnode *pMnode) { void mndCleanupConsumer(SMnode *pMnode) {} +void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId){ + SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg)); + if (pClearMsg == NULL) { + mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d", consumerId, (int32_t)sizeof(SMqConsumerClearMsg)); + return; + } + + pClearMsg->consumerId = consumerId; + SRpcMsg rpcMsg = { + .msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, .pCont = pClearMsg, .contLen = sizeof(SMqConsumerClearMsg)}; + + mInfo("consumer:0x%" PRIx64 " drop from sdb", consumerId); + tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); + return; +} + bool mndRebTryStart() { int32_t old = atomic_val_compare_exchange_32(&mqRebInExecCnt, 0, 1); mDebug("tq timer, rebalance counter old val:%d", old); @@ -105,50 +122,48 @@ void mndRebCntDec() { } } -static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg) { - SMnode *pMnode = pMsg->info.node; - SMqConsumerLostMsg *pLostMsg = pMsg->pCont; - SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pLostMsg->consumerId); - if (pConsumer == NULL) { - return 0; - } - - mInfo("process consumer lost msg, consumer:0x%" PRIx64 " status:%d(%s)", pLostMsg->consumerId, pConsumer->status, - mndConsumerStatusName(pConsumer->status)); - - if (pConsumer->status != MQ_CONSUMER_STATUS__READY) { - mndReleaseConsumer(pMnode, pConsumer); - return -1; - } - - SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__LOST; - - mndReleaseConsumer(pMnode, pConsumer); - - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "lost-csm"); - if (pTrans == NULL) { - goto FAIL; - } - - if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) { - goto FAIL; - } - - if (mndTransPrepare(pMnode, pTrans) != 0) { - goto FAIL; - } - - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); - mndTransDrop(pTrans); - return 0; -FAIL: - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); - mndTransDrop(pTrans); - return -1; -} +//static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg) { +// SMnode *pMnode = pMsg->info.node; +// SMqConsumerLostMsg *pLostMsg = pMsg->pCont; +// SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pLostMsg->consumerId); +// if (pConsumer == NULL) { +// return 0; +// } +// +// mInfo("process consumer lost msg, consumer:0x%" PRIx64 " status:%d(%s)", pLostMsg->consumerId, pConsumer->status, +// mndConsumerStatusName(pConsumer->status)); +// +// if (pConsumer->status != MQ_CONSUMER_STATUS_READY) { +// mndReleaseConsumer(pMnode, pConsumer); +// return -1; +// } +// +// SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup); +// pConsumerNew->updateType = CONSUMER_UPDATE_TIMER_LOST; +// +// mndReleaseConsumer(pMnode, pConsumer); +// +// STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "lost-csm"); +// if (pTrans == NULL) { +// goto FAIL; +// } +// +// if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) { +// goto FAIL; +// } +// +// if (mndTransPrepare(pMnode, pTrans) != 0) { +// goto FAIL; +// } +// +// tDeleteSMqConsumerObj(pConsumerNew, true); +// mndTransDrop(pTrans); +// return 0; +//FAIL: +// tDeleteSMqConsumerObj(pConsumerNew, true); +// mndTransDrop(pTrans); +// return -1; +//} static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) { SMnode *pMnode = pMsg->info.node; @@ -162,14 +177,14 @@ static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) { mInfo("receive consumer recover msg, consumer:0x%" PRIx64 " status:%d(%s)", pRecoverMsg->consumerId, pConsumer->status, mndConsumerStatusName(pConsumer->status)); - if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) { + if (pConsumer->status != MQ_CONSUMER_STATUS_LOST) { mndReleaseConsumer(pMnode, pConsumer); terrno = TSDB_CODE_MND_CONSUMER_NOT_READY; return -1; } SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__RECOVER; + pConsumerNew->updateType = CONSUMER_UPDATE_RECOVER; mndReleaseConsumer(pMnode, pConsumer); @@ -181,13 +196,13 @@ static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) { if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL; if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL; - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); + mndTransDrop(pTrans); return 0; FAIL: - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); + mndTransDrop(pTrans); return -1; } @@ -206,13 +221,13 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) { mInfo("consumer:0x%" PRIx64 " needs to be cleared, status %s", pClearMsg->consumerId, mndConsumerStatusName(pConsumer->status)); - if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) { - mndReleaseConsumer(pMnode, pConsumer); - return -1; - } +// if (pConsumer->status != MQ_CONSUMER_STATUS_LOST) { +// mndReleaseConsumer(pMnode, pConsumer); +// return -1; +// } SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__LOST; +// pConsumerNew->updateType = CONSUMER_UPDATE_TIMER_LOST; mndReleaseConsumer(pMnode, pConsumer); @@ -223,14 +238,14 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) { if (mndSetConsumerDropLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL; if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL; - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); + mndTransDrop(pTrans); return 0; FAIL: - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); + mndTransDrop(pTrans); return -1; } @@ -297,56 +312,29 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) { int32_t hbStatus = atomic_add_fetch_32(&pConsumer->hbStatus, 1); int32_t status = atomic_load_32(&pConsumer->status); - mDebug("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", uptime:%" PRId64 ", hbstatus:%d", - pConsumer->consumerId, status, mndConsumerStatusName(status), pConsumer->subscribeTime, pConsumer->upTime, + mDebug("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", createTime:%" PRId64 ", hbstatus:%d", + pConsumer->consumerId, status, mndConsumerStatusName(status), pConsumer->subscribeTime, pConsumer->createTime, hbStatus); - if (status == MQ_CONSUMER_STATUS__READY) { - if (hbStatus > MND_CONSUMER_LOST_HB_CNT) { - SMqConsumerLostMsg *pLostMsg = rpcMallocCont(sizeof(SMqConsumerLostMsg)); - if (pLostMsg == NULL) { - mError("consumer:0x%"PRIx64" failed to transfer consumer status to lost due to out of memory. alloc size:%d", - pConsumer->consumerId, (int32_t)sizeof(SMqConsumerLostMsg)); - continue; + if (status == MQ_CONSUMER_STATUS_READY) { + if (taosArrayGetSize(pConsumer->assignedTopics) == 0) { // unsubscribe or close + mndDropConsumerFromSdb(pMnode, pConsumer->consumerId); + } else if (hbStatus > MND_CONSUMER_LOST_HB_CNT) { + taosRLockLatch(&pConsumer->lock); + int32_t topicNum = taosArrayGetSize(pConsumer->currentTopics); + for (int32_t i = 0; i < topicNum; i++) { + char key[TSDB_SUBSCRIBE_KEY_LEN]; + char *removedTopic = taosArrayGetP(pConsumer->currentTopics, i); + mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic); + SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key); + taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId); } - - pLostMsg->consumerId = pConsumer->consumerId; - SRpcMsg rpcMsg = { - .msgType = TDMT_MND_TMQ_CONSUMER_LOST, .pCont = pLostMsg, .contLen = sizeof(SMqConsumerLostMsg)}; - - mDebug("consumer:0x%"PRIx64" hb not received beyond threshold %d, set to lost", pConsumer->consumerId, - MND_CONSUMER_LOST_HB_CNT); - tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); + taosRUnLockLatch(&pConsumer->lock); } - } else if (status == MQ_CONSUMER_STATUS__LOST_REBD) { - // if the client is lost longer than one day, clear it. Otherwise, do nothing about the lost consumers. - if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) { - SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg)); - if (pClearMsg == NULL) { - mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d", - pConsumer->consumerId, (int32_t)sizeof(SMqConsumerClearMsg)); - continue; - } - - pClearMsg->consumerId = pConsumer->consumerId; - SRpcMsg rpcMsg = { - .msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, .pCont = pClearMsg, .contLen = sizeof(SMqConsumerClearMsg)}; - - mDebug("consumer:0x%" PRIx64 " lost beyond threshold %d, clear it", pConsumer->consumerId, - MND_CONSUMER_LOST_CLEAR_THRESHOLD); - tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); + } else if (status == MQ_CONSUMER_STATUS_LOST) { + if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) { // clear consumer if lost a day + mndDropConsumerFromSdb(pMnode, pConsumer->consumerId); } - } else if (status == MQ_CONSUMER_STATUS__LOST) { - taosRLockLatch(&pConsumer->lock); - int32_t topicNum = taosArrayGetSize(pConsumer->currentTopics); - for (int32_t i = 0; i < topicNum; i++) { - char key[TSDB_SUBSCRIBE_KEY_LEN]; - char *removedTopic = taosArrayGetP(pConsumer->currentTopics, i); - mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic); - SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key); - taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId); - } - taosRUnLockLatch(&pConsumer->lock); } else { // MQ_CONSUMER_STATUS_REBALANCE taosRLockLatch(&pConsumer->lock); @@ -413,7 +401,7 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) { int32_t status = atomic_load_32(&pConsumer->status); - if (status == MQ_CONSUMER_STATUS__LOST_REBD) { + if (status == MQ_CONSUMER_STATUS_LOST) { mInfo("try to recover consumer:0x%" PRIx64 "", consumerId); SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg)); @@ -475,7 +463,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) { mError("consumer:0x%" PRIx64 " group:%s not consistent with data in sdb, saved cgroup:%s", consumerId, req.cgroup, pConsumer->cgroup); terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST; - return -1; + goto FAIL; } atomic_store_32(&pConsumer->hbStatus, 0); @@ -483,7 +471,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) { // 1. check consumer status int32_t status = atomic_load_32(&pConsumer->status); - if (status == MQ_CONSUMER_STATUS__LOST_REBD) { + if (status == MQ_CONSUMER_STATUS_LOST) { mInfo("try to recover consumer:0x%" PRIx64, consumerId); SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg)); @@ -497,10 +485,10 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) { tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg); } - if (status != MQ_CONSUMER_STATUS__READY) { + if (status != MQ_CONSUMER_STATUS_READY) { mInfo("consumer:0x%" PRIx64 " not ready, status: %s", consumerId, mndConsumerStatusName(status)); terrno = TSDB_CODE_MND_CONSUMER_NOT_READY; - return -1; + goto FAIL; } int32_t serverEpoch = atomic_load_32(&pConsumer->epoch); @@ -582,7 +570,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) { void *buf = rpcMallocCont(tlen); if (buf == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; + goto FAIL; } SMqRspHead* pHead = buf; @@ -669,6 +657,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) { char *cgroup = subscribe.cgroup; SMqConsumerObj *pExistedConsumer = NULL; SMqConsumerObj *pConsumerNew = NULL; + STrans *pTrans = NULL; int32_t code = -1; SArray *pTopicList = subscribe.topicNames; @@ -676,9 +665,17 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) { taosArrayRemoveDuplicate(pTopicList, taosArrayCompareString, freeItem); int32_t newTopicNum = taosArrayGetSize(pTopicList); + for(int i = 0; i < newTopicNum; i++){ + int32_t gNum = mndGetGroupNumByTopic(pMnode, (const char*)taosArrayGetP(pTopicList, i)); + if(gNum >= MND_MAX_GROUP_PER_TOPIC){ + terrno = TSDB_CODE_TMQ_GROUP_OUT_OF_RANGE; + code = terrno; + goto _over; + } + } // check topic existence - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg, "subscribe"); + pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pMsg, "subscribe"); if (pTrans == NULL) { goto _over; } @@ -701,8 +698,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) { pConsumerNew->autoCommitInterval = subscribe.autoCommitInterval; pConsumerNew->resetOffsetCfg = subscribe.resetOffsetCfg; - // set the update type - pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE; +// pConsumerNew->updateType = CONSUMER_UPDATE_SUB_MODIFY; // use insert logic taosArrayDestroy(pConsumerNew->assignedTopics); pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup); @@ -721,7 +717,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) { " cgroup:%s, current status:%d(%s), subscribe topic num: %d", consumerId, subscribe.cgroup, status, mndConsumerStatusName(status), newTopicNum); - if (status != MQ_CONSUMER_STATUS__READY) { + if (status != MQ_CONSUMER_STATUS_READY) { terrno = TSDB_CODE_MND_CONSUMER_NOT_READY; goto _over; } @@ -732,11 +728,11 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) { } // set the update type - pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE; + pConsumerNew->updateType = CONSUMER_UPDATE_SUB_MODIFY; taosArrayDestroy(pConsumerNew->assignedTopics); pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup); - int32_t oldTopicNum = (pExistedConsumer->currentTopics) ? taosArrayGetSize(pExistedConsumer->currentTopics) : 0; + int32_t oldTopicNum = taosArrayGetSize(pExistedConsumer->currentTopics); int32_t i = 0, j = 0; while (i < oldTopicNum || j < newTopicNum) { @@ -791,10 +787,7 @@ _over: mndReleaseConsumer(pMnode, pExistedConsumer); } - if (pConsumerNew) { - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); - } + tDeleteSMqConsumerObj(pConsumerNew, true); // TODO: replace with destroy subscribe msg taosArrayDestroyP(subscribe.topicNames, (FDelete)taosMemoryFree); @@ -894,17 +887,17 @@ CM_DECODE_OVER: } static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer) { - mDebug("consumer:0x%" PRIx64 " cgroup:%s status:%d(%s) epoch:%d load from sdb, perform insert action", + mInfo("consumer:0x%" PRIx64 " sub insert, cgroup:%s status:%d(%s) epoch:%d", pConsumer->consumerId, pConsumer->cgroup, pConsumer->status, mndConsumerStatusName(pConsumer->status), pConsumer->epoch); - pConsumer->subscribeTime = pConsumer->upTime; + pConsumer->subscribeTime = taosGetTimestampMs(); return 0; } static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer) { - mDebug("consumer:0x%" PRIx64 " perform delete action, status:(%d)%s", pConsumer->consumerId, pConsumer->status, + mInfo("consumer:0x%" PRIx64 " perform delete action, status:(%d)%s", pConsumer->consumerId, pConsumer->status, mndConsumerStatusName(pConsumer->status)); - tDeleteSMqConsumerObj(pConsumer); + tDeleteSMqConsumerObj(pConsumer, false); return 0; } @@ -913,10 +906,9 @@ static void updateConsumerStatus(SMqConsumerObj *pConsumer) { if (taosArrayGetSize(pConsumer->rebNewTopics) == 0 && taosArrayGetSize(pConsumer->rebRemovedTopics) == 0) { if (status == MQ_CONSUMER_STATUS_REBALANCE) { - pConsumer->status = MQ_CONSUMER_STATUS__READY; - } else if (status == MQ_CONSUMER_STATUS__LOST) { - ASSERT(taosArrayGetSize(pConsumer->currentTopics) == 0); - pConsumer->status = MQ_CONSUMER_STATUS__LOST_REBD; + pConsumer->status = MQ_CONSUMER_STATUS_READY; + } else if (status == MQ_CONSUMER_STATUS_READY) { + pConsumer->status = MQ_CONSUMER_STATUS_LOST; } } } @@ -930,7 +922,7 @@ static void removeFromNewTopicList(SMqConsumerObj *pConsumer, const char *pTopic taosArrayRemove(pConsumer->rebNewTopics, i); taosMemoryFree(p); - mDebug("consumer:0x%" PRIx64 " remove new topic:%s in the topic list, remain newTopics:%d", pConsumer->consumerId, + mInfo("consumer:0x%" PRIx64 " remove new topic:%s in the topic list, remain newTopics:%d", pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->rebNewTopics)); break; } @@ -946,7 +938,7 @@ static void removeFromRemoveTopicList(SMqConsumerObj *pConsumer, const char *pTo taosArrayRemove(pConsumer->rebRemovedTopics, i); taosMemoryFree(p); - mDebug("consumer:0x%" PRIx64 " remove topic:%s in the removed topic list, remain removedTopics:%d", + mInfo("consumer:0x%" PRIx64 " remove topic:%s in the removed topic list, remain removedTopics:%d", pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->rebRemovedTopics)); break; } @@ -961,7 +953,7 @@ static void removeFromCurrentTopicList(SMqConsumerObj *pConsumer, const char *pT taosArrayRemove(pConsumer->currentTopics, i); taosMemoryFree(topic); - mDebug("consumer:0x%" PRIx64 " remove topic:%s in the current topic list, remain currentTopics:%d", + mInfo("consumer:0x%" PRIx64 " remove topic:%s in the current topic list, remain currentTopics:%d", pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->currentTopics)); break; } @@ -984,47 +976,46 @@ static bool existInCurrentTopicList(const SMqConsumerObj* pConsumer, const char* } static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) { - mDebug("consumer:0x%" PRIx64 " perform update action, update type:%d, subscribe-time:%" PRId64 ", uptime:%" PRId64, - pOldConsumer->consumerId, pNewConsumer->updateType, pOldConsumer->subscribeTime, pOldConsumer->upTime); + mInfo("consumer:0x%" PRIx64 " perform update action, update type:%d, subscribe-time:%" PRId64 ", createTime:%" PRId64, + pOldConsumer->consumerId, pNewConsumer->updateType, pOldConsumer->subscribeTime, pOldConsumer->createTime); taosWLockLatch(&pOldConsumer->lock); - if (pNewConsumer->updateType == CONSUMER_UPDATE__REBALANCE) { + if (pNewConsumer->updateType == CONSUMER_UPDATE_SUB_MODIFY) { TSWAP(pOldConsumer->rebNewTopics, pNewConsumer->rebNewTopics); TSWAP(pOldConsumer->rebRemovedTopics, pNewConsumer->rebRemovedTopics); TSWAP(pOldConsumer->assignedTopics, pNewConsumer->assignedTopics); - pOldConsumer->subscribeTime = pNewConsumer->upTime; + pOldConsumer->subscribeTime = taosGetTimestampMs(); pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE; - } else if (pNewConsumer->updateType == CONSUMER_UPDATE__LOST) { - int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics); - for (int32_t i = 0; i < sz; i++) { - char *topic = taosStrdup(taosArrayGetP(pOldConsumer->currentTopics, i)); - taosArrayPush(pOldConsumer->rebRemovedTopics, &topic); - } - - pOldConsumer->rebalanceTime = pNewConsumer->upTime; - - int32_t prevStatus = pOldConsumer->status; - pOldConsumer->status = MQ_CONSUMER_STATUS__LOST; - mDebug("consumer:0x%" PRIx64 " state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d", - pOldConsumer->consumerId, mndConsumerStatusName(prevStatus), mndConsumerStatusName(pOldConsumer->status), - pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics)); - } else if (pNewConsumer->updateType == CONSUMER_UPDATE__RECOVER) { + mInfo("consumer:0x%" PRIx64 " sub update, modify existed consumer",pOldConsumer->consumerId); +// } else if (pNewConsumer->updateType == CONSUMER_UPDATE_TIMER_LOST) { +// int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics); +// for (int32_t i = 0; i < sz; i++) { +// char *topic = taosStrdup(taosArrayGetP(pOldConsumer->currentTopics, i)); +// taosArrayPush(pOldConsumer->rebRemovedTopics, &topic); +// } +// +// int32_t prevStatus = pOldConsumer->status; +// pOldConsumer->status = MQ_CONSUMER_STATUS_LOST; +// mInfo("consumer:0x%" PRIx64 " timer update, timer lost. state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d", +// pOldConsumer->consumerId, mndConsumerStatusName(prevStatus), mndConsumerStatusName(pOldConsumer->status), +// pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics)); + } else if (pNewConsumer->updateType == CONSUMER_UPDATE_RECOVER) { int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics); for (int32_t i = 0; i < sz; i++) { char *topic = taosStrdup(taosArrayGetP(pOldConsumer->assignedTopics, i)); taosArrayPush(pOldConsumer->rebNewTopics, &topic); } - pOldConsumer->rebalanceTime = pNewConsumer->upTime; pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE; - } else if (pNewConsumer->updateType == CONSUMER_UPDATE__TOUCH) { + mInfo("consumer:0x%" PRIx64 " timer update, timer recover",pOldConsumer->consumerId); + } else if (pNewConsumer->updateType == CONSUMER_UPDATE_REB_MODIFY_NOTOPIC) { atomic_add_fetch_32(&pOldConsumer->epoch, 1); - pOldConsumer->rebalanceTime = pNewConsumer->upTime; - - } else if (pNewConsumer->updateType == CONSUMER_UPDATE__ADD) { + pOldConsumer->rebalanceTime = taosGetTimestampMs(); + mInfo("consumer:0x%" PRIx64 " reb update, only rebalance time", pOldConsumer->consumerId); + } else if (pNewConsumer->updateType == CONSUMER_UPDATE_REB_MODIFY_TOPIC) { char *pNewTopic = taosStrdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0)); // check if exist in current topic @@ -1033,6 +1024,7 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, // add to current topic bool existing = existInCurrentTopicList(pOldConsumer, pNewTopic); if (existing) { + mError("consumer:0x%" PRIx64 "new topic:%s should not in currentTopics", pOldConsumer->consumerId, pNewTopic); taosMemoryFree(pNewTopic); } else { // added into current topic list taosArrayPush(pOldConsumer->currentTopics, &pNewTopic); @@ -1044,17 +1036,17 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, updateConsumerStatus(pOldConsumer); // the re-balance is triggered when the new consumer is launched. - pOldConsumer->rebalanceTime = pNewConsumer->upTime; + pOldConsumer->rebalanceTime = taosGetTimestampMs(); atomic_add_fetch_32(&pOldConsumer->epoch, 1); - mDebug("consumer:0x%" PRIx64 " state (%d)%s -> (%d)%s, new epoch:%d, reb-time:%" PRId64 + mInfo("consumer:0x%" PRIx64 " reb update add, state (%d)%s -> (%d)%s, new epoch:%d, reb-time:%" PRId64 ", current topics:%d, newTopics:%d, removeTopics:%d", pOldConsumer->consumerId, status, mndConsumerStatusName(status), pOldConsumer->status, mndConsumerStatusName(pOldConsumer->status), pOldConsumer->epoch, pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->currentTopics), (int)taosArrayGetSize(pOldConsumer->rebNewTopics), (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics)); - } else if (pNewConsumer->updateType == CONSUMER_UPDATE__REMOVE) { + } else if (pNewConsumer->updateType == CONSUMER_UPDATE_REB_MODIFY_REMOVE) { char *removedTopic = taosArrayGetP(pNewConsumer->rebRemovedTopics, 0); // remove from removed topic @@ -1067,10 +1059,10 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, int32_t status = pOldConsumer->status; updateConsumerStatus(pOldConsumer); - pOldConsumer->rebalanceTime = pNewConsumer->upTime; + pOldConsumer->rebalanceTime = taosGetTimestampMs(); atomic_add_fetch_32(&pOldConsumer->epoch, 1); - mDebug("consumer:0x%" PRIx64 " state (%d)%s -> (%d)%s, new epoch:%d, reb-time:%" PRId64 + mInfo("consumer:0x%" PRIx64 " reb update remove, state (%d)%s -> (%d)%s, new epoch:%d, reb-time:%" PRId64 ", current topics:%d, newTopics:%d, removeTopics:%d", pOldConsumer->consumerId, status, mndConsumerStatusName(status), pOldConsumer->status, mndConsumerStatusName(pOldConsumer->status), pOldConsumer->epoch, pOldConsumer->rebalanceTime, @@ -1133,8 +1125,12 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock * int32_t cols = 0; // consumer id + char consumerIdHex[32] = {0}; + sprintf(varDataVal(consumerIdHex), "0x%"PRIx64, pConsumer->consumerId); + varDataSetLen(consumerIdHex, strlen(varDataVal(consumerIdHex))); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumer->consumerId, false); + colDataSetVal(pColInfo, numOfRows, (const char *)consumerIdHex, false); // consumer group char cgroup[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0}; @@ -1175,7 +1171,7 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock * // up time pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumer->upTime, false); + colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumer->createTime, false); // subscribe time pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); @@ -1190,7 +1186,7 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock * tFormatOffset(buf, TSDB_OFFSET_LEN, &pVal); char parasStr[64 + TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE] = {0}; - sprintf(varDataVal(parasStr), "tbname:%d,commit:%d,interval:%d,reset:%s", pConsumer->withTbName, pConsumer->autoCommit, pConsumer->autoCommitInterval, buf); + sprintf(varDataVal(parasStr), "tbname:%d,commit:%d,interval:%dms,reset:%s", pConsumer->withTbName, pConsumer->autoCommit, pConsumer->autoCommitInterval, buf); varDataSetLen(parasStr, strlen(varDataVal(parasStr))); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); @@ -1216,10 +1212,9 @@ static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter) { static const char *mndConsumerStatusName(int status) { switch (status) { - case MQ_CONSUMER_STATUS__READY: + case MQ_CONSUMER_STATUS_READY: return "ready"; - case MQ_CONSUMER_STATUS__LOST: - case MQ_CONSUMER_STATUS__LOST_REBD: + case MQ_CONSUMER_STATUS_LOST: return "lost"; case MQ_CONSUMER_STATUS_REBALANCE: return "rebalancing"; diff --git a/source/dnode/mnode/impl/src/mndDef.c b/source/dnode/mnode/impl/src/mndDef.c index 50ff9a7d23..8f14bb7cf8 100644 --- a/source/dnode/mnode/impl/src/mndDef.c +++ b/source/dnode/mnode/impl/src/mndDef.c @@ -30,11 +30,11 @@ int32_t tEncodeSStreamObj(SEncoder *pEncoder, const SStreamObj *pObj) { if (tEncodeI64(pEncoder, pObj->uid) < 0) return -1; if (tEncodeI8(pEncoder, pObj->status) < 0) return -1; - if (tEncodeI8(pEncoder, pObj->igExpired) < 0) return -1; - if (tEncodeI8(pEncoder, pObj->trigger) < 0) return -1; - if (tEncodeI8(pEncoder, pObj->fillHistory) < 0) return -1; - if (tEncodeI64(pEncoder, pObj->triggerParam) < 0) return -1; - if (tEncodeI64(pEncoder, pObj->watermark) < 0) return -1; + if (tEncodeI8(pEncoder, pObj->conf.igExpired) < 0) return -1; + if (tEncodeI8(pEncoder, pObj->conf.trigger) < 0) return -1; + if (tEncodeI8(pEncoder, pObj->conf.fillHistory) < 0) return -1; + if (tEncodeI64(pEncoder, pObj->conf.triggerParam) < 0) return -1; + if (tEncodeI64(pEncoder, pObj->conf.watermark) < 0) return -1; if (tEncodeI64(pEncoder, pObj->sourceDbUid) < 0) return -1; if (tEncodeI64(pEncoder, pObj->targetDbUid) < 0) return -1; @@ -100,11 +100,11 @@ int32_t tDecodeSStreamObj(SDecoder *pDecoder, SStreamObj *pObj, int32_t sver) { if (tDecodeI64(pDecoder, &pObj->uid) < 0) return -1; if (tDecodeI8(pDecoder, &pObj->status) < 0) return -1; - if (tDecodeI8(pDecoder, &pObj->igExpired) < 0) return -1; - if (tDecodeI8(pDecoder, &pObj->trigger) < 0) return -1; - if (tDecodeI8(pDecoder, &pObj->fillHistory) < 0) return -1; - if (tDecodeI64(pDecoder, &pObj->triggerParam) < 0) return -1; - if (tDecodeI64(pDecoder, &pObj->watermark) < 0) return -1; + if (tDecodeI8(pDecoder, &pObj->conf.igExpired) < 0) return -1; + if (tDecodeI8(pDecoder, &pObj->conf.trigger) < 0) return -1; + if (tDecodeI8(pDecoder, &pObj->conf.fillHistory) < 0) return -1; + if (tDecodeI64(pDecoder, &pObj->conf.triggerParam) < 0) return -1; + if (tDecodeI64(pDecoder, &pObj->conf.watermark) < 0) return -1; if (tDecodeI64(pDecoder, &pObj->sourceDbUid) < 0) return -1; if (tDecodeI64(pDecoder, &pObj->targetDbUid) < 0) return -1; @@ -160,18 +160,10 @@ int32_t tDecodeSStreamObj(SDecoder *pDecoder, SStreamObj *pObj, int32_t sver) { return 0; } -void tFreeStreamObj(SStreamObj *pStream) { - taosMemoryFree(pStream->sql); - taosMemoryFree(pStream->ast); - taosMemoryFree(pStream->physicalPlan); - - if (pStream->outputSchema.nCols) { - taosMemoryFree(pStream->outputSchema.pSchema); - } - - int32_t sz = taosArrayGetSize(pStream->tasks); - for (int32_t i = 0; i < sz; i++) { - SArray *pLevel = taosArrayGetP(pStream->tasks, i); +static void* freeStreamTasks(SArray* pTaskLevel) { + int32_t numOfLevel = taosArrayGetSize(pTaskLevel); + for (int32_t i = 0; i < numOfLevel; i++) { + SArray *pLevel = taosArrayGetP(pTaskLevel, i); int32_t taskSz = taosArrayGetSize(pLevel); for (int32_t j = 0; j < taskSz; j++) { SStreamTask *pTask = taosArrayGetP(pLevel, j); @@ -181,7 +173,20 @@ void tFreeStreamObj(SStreamObj *pStream) { taosArrayDestroy(pLevel); } - taosArrayDestroy(pStream->tasks); + return taosArrayDestroy(pTaskLevel); +} + +void tFreeStreamObj(SStreamObj *pStream) { + taosMemoryFree(pStream->sql); + taosMemoryFree(pStream->ast); + taosMemoryFree(pStream->physicalPlan); + + if (pStream->outputSchema.nCols || pStream->outputSchema.pSchema) { + taosMemoryFree(pStream->outputSchema.pSchema); + } + + pStream->tasks = freeStreamTasks(pStream->tasks); + pStream->pHTasksList = freeStreamTasks(pStream->pHTasksList); // tagSchema.pSchema if (pStream->tagSchema.nCols > 0) { @@ -224,7 +229,7 @@ void *tDecodeSMqVgEp(const void *buf, SMqVgEp *pVgEp, int8_t sver) { return (void *)buf; } -SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_LEN]) { +SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char* cgroup) { SMqConsumerObj *pConsumer = taosMemoryCalloc(1, sizeof(SMqConsumerObj)); if (pConsumer == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -255,16 +260,20 @@ SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_L return NULL; } - pConsumer->upTime = taosGetTimestampMs(); + pConsumer->createTime = taosGetTimestampMs(); return pConsumer; } -void tDeleteSMqConsumerObj(SMqConsumerObj *pConsumer) { +void tDeleteSMqConsumerObj(SMqConsumerObj *pConsumer, bool delete) { + if(pConsumer == NULL) return; taosArrayDestroyP(pConsumer->currentTopics, (FDelete)taosMemoryFree); taosArrayDestroyP(pConsumer->rebNewTopics, (FDelete)taosMemoryFree); taosArrayDestroyP(pConsumer->rebRemovedTopics, (FDelete)taosMemoryFree); taosArrayDestroyP(pConsumer->assignedTopics, (FDelete)taosMemoryFree); + if(delete){ + taosMemoryFree(pConsumer); + } } int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) { @@ -279,7 +288,7 @@ int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) { tlen += taosEncodeFixedI32(buf, pConsumer->pid); tlen += taosEncodeSEpSet(buf, &pConsumer->ep); - tlen += taosEncodeFixedI64(buf, pConsumer->upTime); + tlen += taosEncodeFixedI64(buf, pConsumer->createTime); tlen += taosEncodeFixedI64(buf, pConsumer->subscribeTime); tlen += taosEncodeFixedI64(buf, pConsumer->rebalanceTime); @@ -349,7 +358,7 @@ void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer, int8_t s buf = taosDecodeFixedI32(buf, &pConsumer->pid); buf = taosDecodeSEpSet(buf, &pConsumer->ep); - buf = taosDecodeFixedI64(buf, &pConsumer->upTime); + buf = taosDecodeFixedI64(buf, &pConsumer->createTime); buf = taosDecodeFixedI64(buf, &pConsumer->subscribeTime); buf = taosDecodeFixedI64(buf, &pConsumer->rebalanceTime); diff --git a/source/dnode/mnode/impl/src/mndDump.c b/source/dnode/mnode/impl/src/mndDump.c index d57053bb5b..62b5cb00e6 100644 --- a/source/dnode/mnode/impl/src/mndDump.c +++ b/source/dnode/mnode/impl/src/mndDump.c @@ -367,10 +367,10 @@ void dumpStream(SSdb *pSdb, SJson *json) { tjsonAddStringToObject(item, "smaId", i642str(pObj->smaId)); tjsonAddStringToObject(item, "uid", i642str(pObj->uid)); tjsonAddStringToObject(item, "status", i642str(pObj->status)); - tjsonAddStringToObject(item, "igExpired", i642str(pObj->igExpired)); - tjsonAddStringToObject(item, "trigger", i642str(pObj->trigger)); - tjsonAddStringToObject(item, "triggerParam", i642str(pObj->triggerParam)); - tjsonAddStringToObject(item, "watermark", i642str(pObj->watermark)); + tjsonAddStringToObject(item, "igExpired", i642str(pObj->conf.igExpired)); + tjsonAddStringToObject(item, "trigger", i642str(pObj->conf.trigger)); + tjsonAddStringToObject(item, "triggerParam", i642str(pObj->conf.triggerParam)); + tjsonAddStringToObject(item, "watermark", i642str(pObj->conf.watermark)); tjsonAddStringToObject(item, "sourceDbUid", i642str(pObj->sourceDbUid)); tjsonAddStringToObject(item, "targetDbUid", i642str(pObj->targetDbUid)); tjsonAddStringToObject(item, "sourceDb", mndGetDbStr(pObj->sourceDb)); diff --git a/source/dnode/mnode/impl/src/mndIndex.c b/source/dnode/mnode/impl/src/mndIndex.c index 2d2637b8ce..b4de51204f 100644 --- a/source/dnode/mnode/impl/src/mndIndex.c +++ b/source/dnode/mnode/impl/src/mndIndex.c @@ -542,32 +542,32 @@ int32_t mndRetrieveTagIdx(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, i STR_TO_VARSTR(n3, (char *)tNameGetTableName(&stbName)); SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)n1, false); + colDataSetVal(pColInfo, numOfRows, (const char *)n1, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)n2, false); + colDataSetVal(pColInfo, numOfRows, (const char *)n2, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)n3, false); + colDataSetVal(pColInfo, numOfRows, (const char *)n3, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)&invalid, false); + colDataSetVal(pColInfo, numOfRows, (const char *)&invalid, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)&pIdx->createdTime, false); + colDataSetVal(pColInfo, numOfRows, (const char *)&pIdx->createdTime, false); char col[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; STR_TO_VARSTR(col, (char *)pIdx->colName); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)col, false); + colDataSetVal(pColInfo, numOfRows, (const char *)col, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); char tag[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; STR_TO_VARSTR(tag, (char *)"tag_index"); - colDataAppend(pColInfo, numOfRows, (const char *)tag, false); + colDataSetVal(pColInfo, numOfRows, (const char *)tag, false); numOfRows++; sdbRelease(pSdb, pIdx); diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 5482f36940..3c2335a6ee 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -233,7 +233,6 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { } code = -1; - taosIp2String(pReq->info.conn.clientIp, ip); if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT) != 0) { mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, terrstr()); @@ -271,6 +270,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { } } +_CONNECT: pConn = mndCreateConn(pMnode, pReq->info.conn.user, connReq.connType, pReq->info.conn.clientIp, pReq->info.conn.clientPort, connReq.pid, connReq.app, connReq.startTime); if (pConn == NULL) { @@ -842,7 +842,7 @@ static int32_t packQueriesIntoBlock(SShowObj* pShow, SConnObj* pConn, SSDataBloc } varDataLen(subStatus) = strlen(&subStatus[VARSTR_HEADER_SIZE]); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, curRowIndex, subStatus, false); + colDataSetVal(pColInfo, curRowIndex, subStatus, (varDataLen(subStatus) == 0) ? true : false); char sql[TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE] = {0}; STR_TO_VARSTR(sql, pQuery->sql); diff --git a/source/dnode/mnode/impl/src/mndScheduler.c b/source/dnode/mnode/impl/src/mndScheduler.c index 9a611fe46a..33905bad86 100644 --- a/source/dnode/mnode/impl/src/mndScheduler.c +++ b/source/dnode/mnode/impl/src/mndScheduler.c @@ -22,10 +22,12 @@ #include "tname.h" #include "tuuid.h" +#define SINK_NODE_LEVEL (0) extern bool tsDeployOnSnode; -static int32_t mndAddSinkTaskToStream(SStreamObj* pStream, SMnode* pMnode, int32_t vgId, SVgObj* pVgroup); -static void setFixedDownstreamEpInfo(SStreamTask* pDstTask, const SStreamTask* pTask); +static int32_t mndAddSinkTaskToStream(SStreamObj* pStream, SArray* pTaskList, SMnode* pMnode, int32_t vgId, + SVgObj* pVgroup, int32_t fillHistory); +static void setFixedDownstreamEpInfo(SStreamTask* pDstTask, const SStreamTask* pTask); int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64_t uid, int8_t triggerType, int64_t watermark, int64_t deleteMark) { @@ -100,18 +102,16 @@ int32_t mndSetSinkTaskInfo(SStreamObj* pStream, SStreamTask* pTask) { return 0; } -#define SINK_NODE_LEVEL (0) - -int32_t mndAddDispatcherForInnerTask(SMnode* pMnode, SStreamObj* pStream, SStreamTask* pTask) { +int32_t mndAddDispatcherForInternalTask(SMnode* pMnode, SStreamObj* pStream, SArray* pSinkNodeList, + SStreamTask* pTask) { bool isShuffle = false; if (pStream->fixedSinkVgId == 0) { SDbObj* pDb = mndAcquireDb(pMnode, pStream->targetDb); if (pDb != NULL && pDb->cfg.numOfVgroups > 1) { - isShuffle = true; pTask->outputType = TASK_OUTPUT__SHUFFLE_DISPATCH; - pTask->dispatchMsgType = TDMT_STREAM_TASK_DISPATCH; + pTask->msgInfo.msgType = TDMT_STREAM_TASK_DISPATCH; if (mndExtractDbInfo(pMnode, pDb, &pTask->shuffleDispatcher.dbInfo, NULL) < 0) { return -1; } @@ -120,7 +120,6 @@ int32_t mndAddDispatcherForInnerTask(SMnode* pMnode, SStreamObj* pStream, SStrea sdbRelease(pMnode->pSdb, pDb); } - SArray* pSinkNodeList = taosArrayGetP(pStream->tasks, SINK_NODE_LEVEL); int32_t numOfSinkNodes = taosArrayGetSize(pSinkNodeList); if (isShuffle) { @@ -133,7 +132,7 @@ int32_t mndAddDispatcherForInnerTask(SMnode* pMnode, SStreamObj* pStream, SStrea for (int32_t j = 0; j < numOfSinkNodes; j++) { SStreamTask* pSinkTask = taosArrayGetP(pSinkNodeList, j); - if (pSinkTask->nodeId == pVgInfo->vgId) { + if (pSinkTask->info.nodeId == pVgInfo->vgId) { pVgInfo->taskId = pSinkTask->id.taskId; break; } @@ -150,11 +149,11 @@ int32_t mndAddDispatcherForInnerTask(SMnode* pMnode, SStreamObj* pStream, SStrea int32_t mndAssignStreamTaskToVgroup(SMnode* pMnode, SStreamTask* pTask, SSubplan* plan, const SVgObj* pVgroup) { int32_t msgLen; - pTask->nodeId = pVgroup->vgId; - pTask->epSet = mndGetVgroupEpset(pMnode, pVgroup); + pTask->info.nodeId = pVgroup->vgId; + pTask->info.epSet = mndGetVgroupEpset(pMnode, pVgroup); - plan->execNode.nodeId = pTask->nodeId; - plan->execNode.epSet = pTask->epSet; + plan->execNode.nodeId = pTask->info.nodeId; + plan->execNode.epSet = pTask->info.epSet; if (qSubPlanToString(plan, &pTask->exec.qmsg, &msgLen) < 0) { terrno = TSDB_CODE_QRY_INVALID_INPUT; return -1; @@ -171,14 +170,15 @@ SSnodeObj* mndSchedFetchOneSnode(SMnode* pMnode) { return pObj; } -int32_t mndAssignTaskToSnode(SMnode* pMnode, SStreamTask* pTask, SSubplan* plan, const SSnodeObj* pSnode) { +int32_t mndAssignStreamTaskToSnode(SMnode* pMnode, SStreamTask* pTask, SSubplan* plan, const SSnodeObj* pSnode) { int32_t msgLen; - pTask->nodeId = SNODE_HANDLE; - pTask->epSet = mndAcquireEpFromSnode(pMnode, pSnode); + pTask->info.nodeId = SNODE_HANDLE; + pTask->info.epSet = mndAcquireEpFromSnode(pMnode, pSnode); plan->execNode.nodeId = SNODE_HANDLE; - plan->execNode.epSet = pTask->epSet; + plan->execNode.epSet = pTask->info.epSet; + mDebug("s-task:0x%x set the agg task to snode:%d", pTask->id.taskId, SNODE_HANDLE); if (qSubPlanToString(plan, &pTask->exec.qmsg, &msgLen) < 0) { terrno = TSDB_CODE_QRY_INVALID_INPUT; @@ -187,6 +187,7 @@ int32_t mndAssignTaskToSnode(SMnode* pMnode, SStreamTask* pTask, SSubplan* plan, return 0; } +// todo random choose a node to do compute SVgObj* mndSchedFetchOneVg(SMnode* pMnode, int64_t dbUid) { void* pIter = NULL; SVgObj* pVgroup = NULL; @@ -203,9 +204,9 @@ SVgObj* mndSchedFetchOneVg(SMnode* pMnode, int64_t dbUid) { } // create sink node for each vgroup. -int32_t mndAddShuffleSinkTasksToStream(SMnode* pMnode, SStreamObj* pStream) { - SSdb* pSdb = pMnode->pSdb; - void* pIter = NULL; +int32_t mndAddShuffleSinkTasksToStream(SMnode* pMnode, SArray* pTaskList, SStreamObj* pStream, int32_t fillHistory) { + SSdb* pSdb = pMnode->pSdb; + void* pIter = NULL; while (1) { SVgObj* pVgroup = NULL; @@ -219,43 +220,45 @@ int32_t mndAddShuffleSinkTasksToStream(SMnode* pMnode, SStreamObj* pStream) { continue; } - mndAddSinkTaskToStream(pStream, pMnode, pVgroup->vgId, pVgroup); + mndAddSinkTaskToStream(pStream, pTaskList, pMnode, pVgroup->vgId, pVgroup, fillHistory); sdbRelease(pSdb, pVgroup); } return 0; } -int32_t mndAddSinkTaskToStream(SStreamObj* pStream, SMnode* pMnode, int32_t vgId, SVgObj* pVgroup) { - SArray* pTaskList = taosArrayGetP(pStream->tasks, SINK_NODE_LEVEL); - - SStreamTask* pTask = tNewStreamTask(pStream->uid, TASK_LEVEL__SINK, pStream->fillHistory, 0, pTaskList); +int32_t mndAddSinkTaskToStream(SStreamObj* pStream, SArray* pTaskList, SMnode* pMnode, int32_t vgId, SVgObj* pVgroup, + int32_t fillHistory) { + SStreamTask* pTask = tNewStreamTask(pStream->uid, TASK_LEVEL__SINK, fillHistory, 0, pTaskList); if (pTask == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pTask->nodeId = vgId; - pTask->epSet = mndGetVgroupEpset(pMnode, pVgroup); + pTask->info.nodeId = vgId; + pTask->info.epSet = mndGetVgroupEpset(pMnode, pVgroup); mndSetSinkTaskInfo(pStream, pTask); return 0; } -static int32_t mndScheduleFillHistoryStreamTask(SMnode* pMnode, SStreamObj* pStream) { - return 0; -} - -static int32_t addSourceStreamTask(SMnode* pMnode, SVgObj* pVgroup, SArray* pTaskList, SStreamObj* pStream, - SSubplan* plan, uint64_t uid, int8_t taskLevel, int8_t fillHistory, - bool hasExtraSink) { - SStreamTask* pTask = tNewStreamTask(uid, taskLevel, fillHistory, pStream->triggerParam, pTaskList); +static int32_t addSourceStreamTask(SMnode* pMnode, SVgObj* pVgroup, SArray* pTaskList, SArray* pSinkTaskList, + SStreamObj* pStream, SSubplan* plan, uint64_t uid, int8_t fillHistory, + bool hasExtraSink, int64_t firstWindowSkey) { + SStreamTask* pTask = tNewStreamTask(uid, TASK_LEVEL__SOURCE, fillHistory, pStream->conf.triggerParam, pTaskList); if (pTask == NULL) { return terrno; } + // todo set the correct ts, which should be last key of queried table. + STimeWindow* pWindow = &pTask->dataRange.window; + + pWindow->skey = INT64_MIN; + pWindow->ekey = firstWindowSkey - 1; + mDebug("add source task 0x%x window:%" PRId64 " - %" PRId64, pTask->id.taskId, pWindow->skey, pWindow->ekey); + // sink or dispatch if (hasExtraSink) { - mndAddDispatcherForInnerTask(pMnode, pStream, pTask); + mndAddDispatcherForInternalTask(pMnode, pStream, pSinkTaskList, pTask); } else { mndSetSinkTaskInfo(pStream, pTask); } @@ -274,9 +277,9 @@ static SStreamChildEpInfo* createStreamTaskEpInfo(SStreamTask* pTask) { return NULL; } - pEpInfo->childId = pTask->selfChildId; - pEpInfo->epSet = pTask->epSet; - pEpInfo->nodeId = pTask->nodeId; + pEpInfo->childId = pTask->info.selfChildId; + pEpInfo->epSet = pTask->info.epSet; + pEpInfo->nodeId = pTask->info.nodeId; pEpInfo->taskId = pTask->id.taskId; return pEpInfo; @@ -285,38 +288,307 @@ static SStreamChildEpInfo* createStreamTaskEpInfo(SStreamTask* pTask) { void setFixedDownstreamEpInfo(SStreamTask* pDstTask, const SStreamTask* pTask) { STaskDispatcherFixedEp* pDispatcher = &pDstTask->fixedEpDispatcher; pDispatcher->taskId = pTask->id.taskId; - pDispatcher->nodeId = pTask->nodeId; - pDispatcher->epSet = pTask->epSet; + pDispatcher->nodeId = pTask->info.nodeId; + pDispatcher->epSet = pTask->info.epSet; pDstTask->outputType = TASK_OUTPUT__FIXED_DISPATCH; - pDstTask->dispatchMsgType = TDMT_STREAM_TASK_DISPATCH; + pDstTask->msgInfo.msgType = TDMT_STREAM_TASK_DISPATCH; } -int32_t appendToUpstream(SStreamTask* pTask, SStreamTask* pUpstream) { +int32_t setEpToDownstreamTask(SStreamTask* pTask, SStreamTask* pDownstream) { SStreamChildEpInfo* pEpInfo = createStreamTaskEpInfo(pTask); if (pEpInfo == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } - if(pUpstream->childEpInfo == NULL) { - pUpstream->childEpInfo = taosArrayInit(4, POINTER_BYTES); + if (pDownstream->pUpstreamEpInfoList == NULL) { + pDownstream->pUpstreamEpInfoList = taosArrayInit(4, POINTER_BYTES); } - - taosArrayPush(pUpstream->childEpInfo, &pEpInfo); + + taosArrayPush(pDownstream->pUpstreamEpInfoList, &pEpInfo); return TSDB_CODE_SUCCESS; } -int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) { - SSdb* pSdb = pMnode->pSdb; +static SArray* addNewTaskList(SArray* pTasksList) { + SArray* pTaskList = taosArrayInit(0, POINTER_BYTES); + taosArrayPush(pTasksList, &pTaskList); + return pTaskList; +} - SQueryPlan* pPlan = qStringToQueryPlan(pStream->physicalPlan); - if (pPlan == NULL) { +// set the history task id +static void setHTasksId(SArray* pTaskList, const SArray* pHTaskList) { + for (int32_t i = 0; i < taosArrayGetSize(pTaskList); ++i) { + SStreamTask** pStreamTask = taosArrayGet(pTaskList, i); + SStreamTask** pHTask = taosArrayGet(pHTaskList, i); + + (*pStreamTask)->historyTaskId.taskId = (*pHTask)->id.taskId; + (*pStreamTask)->historyTaskId.streamId = (*pHTask)->id.streamId; + + (*pHTask)->streamTaskId.taskId = (*pStreamTask)->id.taskId; + (*pHTask)->streamTaskId.streamId = (*pStreamTask)->id.streamId; + + mDebug("s-task:0x%x related history task:0x%x, level:%d", (*pStreamTask)->id.taskId, (*pHTask)->id.taskId, + (*pHTask)->info.taskLevel); + } +} + +static int32_t addSourceTasksForOneLevelStream(SMnode* pMnode, const SQueryPlan* pPlan, SStreamObj* pStream, + bool hasExtraSink, int64_t nextWindowSkey) { + // create exec stream task, since only one level, the exec task is also the source task + SArray* pTaskList = addNewTaskList(pStream->tasks); + SSdb* pSdb = pMnode->pSdb; + + SArray* pHTaskList = NULL; + if (pStream->conf.fillHistory) { + pHTaskList = addNewTaskList(pStream->pHTasksList); + } + + SNodeListNode* inner = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 0); + if (LIST_LENGTH(inner->pNodeList) != 1) { terrno = TSDB_CODE_QRY_INVALID_INPUT; return -1; } - int32_t planTotLevel = LIST_LENGTH(pPlan->pSubplans); - pStream->tasks = taosArrayInit(planTotLevel, POINTER_BYTES); + SSubplan* plan = (SSubplan*)nodesListGetNode(inner->pNodeList, 0); + if (plan->subplanType != SUBPLAN_TYPE_SCAN) { + terrno = TSDB_CODE_QRY_INVALID_INPUT; + return -1; + } + + void* pIter = NULL; + while (1) { + SVgObj* pVgroup; + pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup); + if (pIter == NULL) { + break; + } + + if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) { + sdbRelease(pSdb, pVgroup); + continue; + } + + // new stream task + SArray** pSinkTaskList = taosArrayGet(pStream->tasks, SINK_NODE_LEVEL); + int32_t code = addSourceStreamTask(pMnode, pVgroup, pTaskList, *pSinkTaskList, pStream, plan, pStream->uid, 0, + hasExtraSink, nextWindowSkey); + if (code != TSDB_CODE_SUCCESS) { + sdbRelease(pSdb, pVgroup); + return -1; + } + + if (pStream->conf.fillHistory) { + SArray** pHSinkTaskList = taosArrayGet(pStream->pHTasksList, SINK_NODE_LEVEL); + code = addSourceStreamTask(pMnode, pVgroup, pHTaskList, *pHSinkTaskList, pStream, plan, pStream->hTaskUid, + 1, hasExtraSink, nextWindowSkey); + } + + sdbRelease(pSdb, pVgroup); + if (code != TSDB_CODE_SUCCESS) { + return -1; + } + } + + if (pStream->conf.fillHistory) { + setHTasksId(pTaskList, pHTaskList); + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t doAddSourceTask(SArray* pTaskList, int8_t fillHistory, int64_t uid, SStreamTask* pDownstreamTask, + SMnode* pMnode, SSubplan* pPlan, SVgObj* pVgroup, int64_t nextWindowSkey) { + SStreamTask* pTask = tNewStreamTask(uid, TASK_LEVEL__SOURCE, fillHistory, 0, pTaskList); + if (pTask == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + // todo set the correct ts, which should be last key of queried table. + STimeWindow* pWindow = &pTask->dataRange.window; + pWindow->skey = INT64_MIN; + pWindow->ekey = nextWindowSkey - 1; + + mDebug("s-task:0x%x level:%d set time window:%" PRId64 " - %" PRId64, pTask->id.taskId, pTask->info.taskLevel, + pWindow->skey, pWindow->ekey); + + // all the source tasks dispatch result to a single agg node. + setFixedDownstreamEpInfo(pTask, pDownstreamTask); + if (mndAssignStreamTaskToVgroup(pMnode, pTask, pPlan, pVgroup) < 0) { + return -1; + } + + return setEpToDownstreamTask(pTask, pDownstreamTask); +} + +static int32_t doAddAggTask(uint64_t uid, SArray* pTaskList, SArray* pSinkNodeList, SMnode* pMnode, SStreamObj* pStream, + int32_t fillHistory, SStreamTask** pAggTask) { + *pAggTask = tNewStreamTask(uid, TASK_LEVEL__AGG, fillHistory, pStream->conf.triggerParam, pTaskList); + if (*pAggTask == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + // dispatch + if (mndAddDispatcherForInternalTask(pMnode, pStream, pSinkNodeList, *pAggTask) < 0) { + return -1; + } + + return 0; +} + +static int32_t addAggTask(SStreamObj* pStream, SMnode* pMnode, SQueryPlan* pPlan, SStreamTask** pAggTask, + SStreamTask** pHAggTask) { + SArray* pAggTaskList = addNewTaskList(pStream->tasks); + SSdb* pSdb = pMnode->pSdb; + + SNodeListNode* pInnerNode = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 0); + SSubplan* plan = (SSubplan*)nodesListGetNode(pInnerNode->pNodeList, 0); + if (plan->subplanType != SUBPLAN_TYPE_MERGE) { + terrno = TSDB_CODE_QRY_INVALID_INPUT; + return -1; + } + + *pAggTask = NULL; + SArray* pSinkNodeList = taosArrayGetP(pStream->tasks, SINK_NODE_LEVEL); + + int32_t code = doAddAggTask(pStream->uid, pAggTaskList, pSinkNodeList, pMnode, pStream, 0, pAggTask); + if (code != TSDB_CODE_SUCCESS) { + return -1; + } + + SVgObj* pVgroup = NULL; + SSnodeObj* pSnode = NULL; + + if (tsDeployOnSnode) { + pSnode = mndSchedFetchOneSnode(pMnode); + if (pSnode == NULL) { + pVgroup = mndSchedFetchOneVg(pMnode, pStream->sourceDbUid); + } + } else { + pVgroup = mndSchedFetchOneVg(pMnode, pStream->sourceDbUid); + } + + if (pSnode != NULL) { + code = mndAssignStreamTaskToSnode(pMnode, *pAggTask, plan, pSnode); + } else { + code = mndAssignStreamTaskToVgroup(pMnode, *pAggTask, plan, pVgroup); + } + + if (pStream->conf.fillHistory) { + SArray* pHAggTaskList = addNewTaskList(pStream->pHTasksList); + SArray* pHSinkNodeList = taosArrayGetP(pStream->pHTasksList, SINK_NODE_LEVEL); + + *pHAggTask = NULL; + code = doAddAggTask(pStream->hTaskUid, pHAggTaskList, pHSinkNodeList, pMnode, pStream, pStream->conf.fillHistory, + pHAggTask); + if (code != TSDB_CODE_SUCCESS) { + if (pSnode != NULL) { + sdbRelease(pSdb, pSnode); + } else { + sdbRelease(pSdb, pVgroup); + } + return code; + } + + if (pSnode != NULL) { + code = mndAssignStreamTaskToSnode(pMnode, *pHAggTask, plan, pSnode); + } else { + code = mndAssignStreamTaskToVgroup(pMnode, *pHAggTask, plan, pVgroup); + } + + setHTasksId(pAggTaskList, pHAggTaskList); + } + + if (pSnode != NULL) { + sdbRelease(pSdb, pSnode); + } else { + sdbRelease(pSdb, pVgroup); + } + + return code; +} + +static int32_t addSourceTasksForMultiLevelStream(SMnode* pMnode, SQueryPlan* pPlan, SStreamObj* pStream, + SStreamTask* pDownstreamTask, SStreamTask* pHDownstreamTask, int64_t nextWindowSkey) { + SArray* pSourceTaskList = addNewTaskList(pStream->tasks); + + SArray* pHSourceTaskList = NULL; + if (pStream->conf.fillHistory) { + pHSourceTaskList = addNewTaskList(pStream->pHTasksList); + } + + SSdb* pSdb = pMnode->pSdb; + SNodeListNode* inner = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 1); + SSubplan* plan = (SSubplan*)nodesListGetNode(inner->pNodeList, 0); + if (plan->subplanType != SUBPLAN_TYPE_SCAN) { + terrno = TSDB_CODE_QRY_INVALID_INPUT; + return -1; + } + + void* pIter = NULL; + while (1) { + SVgObj* pVgroup; + pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup); + if (pIter == NULL) { + break; + } + + if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) { + sdbRelease(pSdb, pVgroup); + continue; + } + + int32_t code = + doAddSourceTask(pSourceTaskList, 0, pStream->uid, pDownstreamTask, pMnode, plan, pVgroup, nextWindowSkey); + if (code != TSDB_CODE_SUCCESS) { + sdbRelease(pSdb, pVgroup); + terrno = code; + return -1; + } + + if (pStream->conf.fillHistory) { + code = doAddSourceTask(pHSourceTaskList, 1, pStream->hTaskUid, pHDownstreamTask, pMnode, plan, pVgroup, + nextWindowSkey); + if (code != TSDB_CODE_SUCCESS) { + sdbRelease(pSdb, pVgroup); + return code; + } + } + + sdbRelease(pSdb, pVgroup); + } + + if (pStream->conf.fillHistory) { + setHTasksId(pSourceTaskList, pHSourceTaskList); + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t addSinkTasks(SArray* pTasksList, SMnode* pMnode, SStreamObj* pStream, SArray** pCreatedTaskList, + int32_t fillHistory) { + SArray* pSinkTaskList = addNewTaskList(pTasksList); + if (pStream->fixedSinkVgId == 0) { + if (mndAddShuffleSinkTasksToStream(pMnode, pSinkTaskList, pStream, fillHistory) < 0) { + // TODO free + return -1; + } + } else { + if (mndAddSinkTaskToStream(pStream, pSinkTaskList, pMnode, pStream->fixedSinkVgId, &pStream->fixedSinkVg, + fillHistory) < 0) { + // TODO free + return -1; + } + } + + *pCreatedTaskList = pSinkTaskList; + return TSDB_CODE_SUCCESS; +} + +static int32_t doScheduleStream(SStreamObj* pStream, SMnode* pMnode, SQueryPlan* pPlan, int64_t nextWindowSkey) { + SSdb* pSdb = pMnode->pSdb; + int32_t numOfPlanLevel = LIST_LENGTH(pPlan->pSubplans); bool hasExtraSink = false; bool externalTargetDB = strcmp(pStream->sourceDb, pStream->targetDb) != 0; @@ -329,178 +601,64 @@ int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) { bool multiTarget = (pDbObj->cfg.numOfVgroups > 1); sdbRelease(pSdb, pDbObj); - if (planTotLevel == 2 || externalTargetDB || multiTarget || pStream->fixedSinkVgId) { - SArray* taskOneLevel = taosArrayInit(0, POINTER_BYTES); - taosArrayPush(pStream->tasks, &taskOneLevel); + pStream->tasks = taosArrayInit(numOfPlanLevel + 1, POINTER_BYTES); + pStream->pHTasksList = taosArrayInit(numOfPlanLevel + 1, POINTER_BYTES); + if (numOfPlanLevel == 2 || externalTargetDB || multiTarget || pStream->fixedSinkVgId) { // add extra sink hasExtraSink = true; - if (pStream->fixedSinkVgId == 0) { - if (mndAddShuffleSinkTasksToStream(pMnode, pStream) < 0) { - // TODO free - return -1; - } - } else { - if (mndAddSinkTaskToStream(pStream, pMnode, pStream->fixedSinkVgId, &pStream->fixedSinkVg) < 0) { - // TODO free - return -1; + + SArray* pSinkTaskList = NULL; + int32_t code = addSinkTasks(pStream->tasks, pMnode, pStream, &pSinkTaskList, 0); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + // check for fill history + if (pStream->conf.fillHistory) { + SArray* pHSinkTaskList = NULL; + code = addSinkTasks(pStream->pHTasksList, pMnode, pStream, &pHSinkTaskList, 1); + if (code != TSDB_CODE_SUCCESS) { + return code; } + + setHTasksId(pSinkTaskList, pHSinkTaskList); } } - pStream->totalLevel = planTotLevel + hasExtraSink; + pStream->totalLevel = numOfPlanLevel + hasExtraSink; - if (planTotLevel > 1) { - SStreamTask* pInnerTask; - // inner level - { - SArray* taskInnerLevel = taosArrayInit(0, POINTER_BYTES); - taosArrayPush(pStream->tasks, &taskInnerLevel); + if (numOfPlanLevel > 1) { + SStreamTask* pAggTask = NULL; + SStreamTask* pHAggTask = NULL; - SNodeListNode* inner = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 0); - SSubplan* plan = (SSubplan*)nodesListGetNode(inner->pNodeList, 0); - if (plan->subplanType != SUBPLAN_TYPE_MERGE) { - terrno = TSDB_CODE_QRY_INVALID_INPUT; - return -1; - } - - pInnerTask = tNewStreamTask(pStream->uid, TASK_LEVEL__AGG, pStream->fillHistory, pStream->triggerParam, taskInnerLevel); - if (pInnerTask == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - qDestroyQueryPlan(pPlan); - return -1; - } - - // dispatch - if (mndAddDispatcherForInnerTask(pMnode, pStream, pInnerTask) < 0) { - qDestroyQueryPlan(pPlan); - return -1; - } - - if (tsDeployOnSnode) { - SSnodeObj* pSnode = mndSchedFetchOneSnode(pMnode); - if (pSnode == NULL) { - SVgObj* pVgroup = mndSchedFetchOneVg(pMnode, pStream->sourceDbUid); - if (mndAssignStreamTaskToVgroup(pMnode, pInnerTask, plan, pVgroup) < 0) { - sdbRelease(pSdb, pVgroup); - qDestroyQueryPlan(pPlan); - return -1; - } - sdbRelease(pSdb, pVgroup); - } else { - if (mndAssignTaskToSnode(pMnode, pInnerTask, plan, pSnode) < 0) { - sdbRelease(pSdb, pSnode); - qDestroyQueryPlan(pPlan); - return -1; - } - } - } else { - SVgObj* pVgroup = mndSchedFetchOneVg(pMnode, pStream->sourceDbUid); - if (mndAssignStreamTaskToVgroup(pMnode, pInnerTask, plan, pVgroup) < 0) { - sdbRelease(pSdb, pVgroup); - qDestroyQueryPlan(pPlan); - return -1; - } - - sdbRelease(pSdb, pVgroup); - } + int32_t code = addAggTask(pStream, pMnode, pPlan, &pAggTask, &pHAggTask); + if (code != TSDB_CODE_SUCCESS) { + return code; } // source level - SArray* taskSourceLevel = taosArrayInit(0, POINTER_BYTES); - taosArrayPush(pStream->tasks, &taskSourceLevel); - - SNodeListNode* inner = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 1); - SSubplan* plan = (SSubplan*)nodesListGetNode(inner->pNodeList, 0); - if (plan->subplanType != SUBPLAN_TYPE_SCAN) { - terrno = TSDB_CODE_QRY_INVALID_INPUT; - return -1; - } - - void* pIter = NULL; - while (1) { - SVgObj* pVgroup; - pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup); - if (pIter == NULL) { - break; - } - - if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) { - sdbRelease(pSdb, pVgroup); - continue; - } - - SStreamTask* pTask = tNewStreamTask(pStream->uid, TASK_LEVEL__SOURCE, pStream->fillHistory, 0, taskSourceLevel); - if (pTask == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - sdbRelease(pSdb, pVgroup); - qDestroyQueryPlan(pPlan); - return -1; - } - - // all the source tasks dispatch result to a single agg node. - setFixedDownstreamEpInfo(pTask, pInnerTask); - - if (mndAssignStreamTaskToVgroup(pMnode, pTask, plan, pVgroup) < 0) { - sdbRelease(pSdb, pVgroup); - qDestroyQueryPlan(pPlan); - return -1; - } - - int32_t code = appendToUpstream(pTask, pInnerTask); - sdbRelease(pSdb, pVgroup); - - if (code != TSDB_CODE_SUCCESS) { - terrno = code; - qDestroyQueryPlan(pPlan); - return -1; - } - } - } else if (planTotLevel == 1) { - // create exec stream task, since only one level, the exec task is also the source task - SArray* pTaskList = taosArrayInit(0, POINTER_BYTES); - taosArrayPush(pStream->tasks, &pTaskList); - - SNodeListNode* inner = (SNodeListNode*)nodesListGetNode(pPlan->pSubplans, 0); - if (LIST_LENGTH(inner->pNodeList) != 1) { - terrno = TSDB_CODE_QRY_INVALID_INPUT; - return -1; - } - - SSubplan* plan = (SSubplan*)nodesListGetNode(inner->pNodeList, 0); - if (plan->subplanType != SUBPLAN_TYPE_SCAN) { - terrno = TSDB_CODE_QRY_INVALID_INPUT; - return -1; - } - - void* pIter = NULL; - while (1) { - SVgObj* pVgroup; - pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup); - if (pIter == NULL) { - break; - } - - if (!mndVgroupInDb(pVgroup, pStream->sourceDbUid)) { - sdbRelease(pSdb, pVgroup); - continue; - } - - // new stream task - int32_t code = addSourceStreamTask(pMnode, pVgroup, pTaskList, pStream, plan, pStream->uid, TASK_LEVEL__SOURCE, pStream->fillHistory, hasExtraSink); - sdbRelease(pSdb, pVgroup); - - if (code != TSDB_CODE_SUCCESS) { - qDestroyQueryPlan(pPlan); - return -1; - } - } + return addSourceTasksForMultiLevelStream(pMnode, pPlan, pStream, pAggTask, pHAggTask, nextWindowSkey); + } else if (numOfPlanLevel == 1) { + return addSourceTasksForOneLevelStream(pMnode, pPlan, pStream, hasExtraSink, nextWindowSkey); } - qDestroyQueryPlan(pPlan); return 0; } +int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream, int64_t nextWindowSkey) { + SQueryPlan* pPlan = qStringToQueryPlan(pStream->physicalPlan); + if (pPlan == NULL) { + terrno = TSDB_CODE_QRY_INVALID_INPUT; + return -1; + } + + int32_t code = doScheduleStream(pStream, pMnode, pPlan, nextWindowSkey); + qDestroyQueryPlan(pPlan); + + return code; +} + int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscribeObj* pSub) { SSdb* pSdb = pMnode->pSdb; SVgObj* pVgroup = NULL; @@ -513,8 +671,8 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib terrno = TSDB_CODE_QRY_INVALID_INPUT; return -1; } - }else if(pTopic->subType == TOPIC_SUB_TYPE__TABLE && pTopic->ast != NULL){ - SNode *pAst = NULL; + } else if (pTopic->subType == TOPIC_SUB_TYPE__TABLE && pTopic->ast != NULL) { + SNode* pAst = NULL; if (nodesStringToNode(pTopic->ast, &pAst) != 0) { mError("topic:%s, failed to create since %s", pTopic->name, terrstr()); return -1; @@ -529,7 +687,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib nodesDestroyNode(pAst); } - if(pPlan){ + if (pPlan) { int32_t levelNum = LIST_LENGTH(pPlan->pSubplans); if (levelNum != 1) { qDestroyQueryPlan(pPlan); diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index c337d85b68..68b697ca67 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -555,20 +555,20 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea streamObj.version = 1; streamObj.sql = taosStrdup(pCreate->sql); streamObj.smaId = smaObj.uid; - streamObj.watermark = pCreate->watermark; + streamObj.conf.watermark = pCreate->watermark; streamObj.deleteMark = pCreate->deleteMark; - streamObj.fillHistory = STREAM_FILL_HISTORY_ON; - streamObj.trigger = STREAM_TRIGGER_WINDOW_CLOSE; - streamObj.triggerParam = pCreate->maxDelay; + streamObj.conf.fillHistory = STREAM_FILL_HISTORY_ON; + streamObj.conf.trigger = STREAM_TRIGGER_WINDOW_CLOSE; + streamObj.conf.triggerParam = pCreate->maxDelay; streamObj.ast = taosStrdup(smaObj.ast); // check the maxDelay - if (streamObj.triggerParam < TSDB_MIN_ROLLUP_MAX_DELAY) { + if (streamObj.conf.triggerParam < TSDB_MIN_ROLLUP_MAX_DELAY) { int64_t msInterval = convertTimeFromPrecisionToUnit(pCreate->interval, pDb->cfg.precision, TIME_UNIT_MILLISECOND); - streamObj.triggerParam = msInterval > TSDB_MIN_ROLLUP_MAX_DELAY ? msInterval : TSDB_MIN_ROLLUP_MAX_DELAY; + streamObj.conf.triggerParam = msInterval > TSDB_MIN_ROLLUP_MAX_DELAY ? msInterval : TSDB_MIN_ROLLUP_MAX_DELAY; } - if (streamObj.triggerParam > TSDB_MAX_ROLLUP_MAX_DELAY) { - streamObj.triggerParam = TSDB_MAX_ROLLUP_MAX_DELAY; + if (streamObj.conf.triggerParam > TSDB_MAX_ROLLUP_MAX_DELAY) { + streamObj.conf.triggerParam = TSDB_MAX_ROLLUP_MAX_DELAY; } if (mndAllocSmaVgroup(pMnode, pDb, &streamObj.fixedSinkVg) != 0) { @@ -597,8 +597,8 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea .pAstRoot = pAst, .topicQuery = false, .streamQuery = true, - .triggerType = streamObj.trigger, - .watermark = streamObj.watermark, + .triggerType = streamObj.conf.trigger, + .watermark = streamObj.conf.watermark, .deleteMark = streamObj.deleteMark, }; @@ -633,7 +633,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea if (mndSetCreateSmaVgroupCommitLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER; if (mndSetUpdateSmaStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER; if (mndSetCreateSmaVgroupRedoActions(pMnode, pTrans, pDb, &streamObj.fixedSinkVg, &smaObj) != 0) goto _OVER; - if (mndScheduleStream(pMnode, &streamObj) != 0) goto _OVER; + if (mndScheduleStream(pMnode, &streamObj, 1685959190000) != 0) goto _OVER; if (mndPersistStream(pMnode, pTrans, &streamObj) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; @@ -1278,13 +1278,13 @@ static int32_t mndRetrieveSma(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc STR_TO_VARSTR(col, (char *)""); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataAppend(pColInfo, numOfRows, (const char *)col, false); + colDataSetVal(pColInfo, numOfRows, (const char *)col, false); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); char tag[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; STR_TO_VARSTR(tag, (char *)"sma_index"); - colDataAppend(pColInfo, numOfRows, (const char *)tag, false); + colDataSetVal(pColInfo, numOfRows, (const char *)tag, false); numOfRows++; sdbRelease(pSdb, pSma); diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index 181c06205a..b1afb6ae4d 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -244,7 +244,7 @@ static void mndShowStreamStatus(char *dst, SStreamObj *pStream) { } static void mndShowStreamTrigger(char *dst, SStreamObj *pStream) { - int8_t trigger = pStream->trigger; + int8_t trigger = pStream->conf.trigger; if (trigger == STREAM_TRIGGER_AT_ONCE) { strcpy(dst, "at once"); } else if (trigger == STREAM_TRIGGER_WINDOW_CLOSE) { @@ -304,13 +304,18 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, pObj->smaId = 0; pObj->uid = mndGenerateUid(pObj->name, strlen(pObj->name)); + + char p[TSDB_STREAM_FNAME_LEN + 32] = {0}; + snprintf(p, tListLen(p), "%s_%s", pObj->name, "fillhistory"); + + pObj->hTaskUid = mndGenerateUid(pObj->name, strlen(pObj->name)); pObj->status = 0; - pObj->igExpired = pCreate->igExpired; - pObj->trigger = pCreate->triggerType; - pObj->triggerParam = pCreate->maxDelay; - pObj->watermark = pCreate->watermark; - pObj->fillHistory = pCreate->fillHistory; + pObj->conf.igExpired = pCreate->igExpired; + pObj->conf.trigger = pCreate->triggerType; + pObj->conf.triggerParam = pCreate->maxDelay; + pObj->conf.watermark = pCreate->watermark; + pObj->conf.fillHistory = pCreate->fillHistory; pObj->deleteMark = pCreate->deleteMark; pObj->igCheckUpdate = pCreate->igUpdate; @@ -392,9 +397,9 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, .pAstRoot = pAst, .topicQuery = false, .streamQuery = true, - .triggerType = pObj->trigger == STREAM_TRIGGER_MAX_DELAY ? STREAM_TRIGGER_WINDOW_CLOSE : pObj->trigger, - .watermark = pObj->watermark, - .igExpired = pObj->igExpired, + .triggerType = pObj->conf.trigger == STREAM_TRIGGER_MAX_DELAY ? STREAM_TRIGGER_WINDOW_CLOSE : pObj->conf.trigger, + .watermark = pObj->conf.watermark, + .igExpired = pObj->conf.igExpired, .deleteMark = pObj->deleteMark, .igCheckUpdate = pObj->igCheckUpdate, }; @@ -433,30 +438,37 @@ int32_t mndPersistTaskDeployReq(STrans *pTrans, const SStreamTask *pTask) { SEncoder encoder; tEncoderInit(&encoder, NULL, 0); tEncodeStreamTask(&encoder, pTask); + int32_t size = encoder.pos; int32_t tlen = sizeof(SMsgHead) + size; tEncoderClear(&encoder); + void *buf = taosMemoryCalloc(1, tlen); if (buf == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - ((SMsgHead *)buf)->vgId = htonl(pTask->nodeId); + + ((SMsgHead *)buf)->vgId = htonl(pTask->info.nodeId); + void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); tEncoderInit(&encoder, abuf, size); + tEncodeStreamTask(&encoder, pTask); tEncoderClear(&encoder); STransAction action = {0}; action.mTraceId = pTrans->mTraceId; - memcpy(&action.epSet, &pTask->epSet, sizeof(SEpSet)); + memcpy(&action.epSet, &pTask->info.epSet, sizeof(SEpSet)); action.pCont = buf; action.contLen = tlen; action.msgType = TDMT_STREAM_TASK_DEPLOY; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(buf); return -1; } + return 0; } @@ -464,14 +476,33 @@ int32_t mndPersistStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStrea int32_t level = taosArrayGetSize(pStream->tasks); for (int32_t i = 0; i < level; i++) { SArray *pLevel = taosArrayGetP(pStream->tasks, i); - int32_t sz = taosArrayGetSize(pLevel); - for (int32_t j = 0; j < sz; j++) { + + int32_t numOfTasks = taosArrayGetSize(pLevel); + for (int32_t j = 0; j < numOfTasks; j++) { SStreamTask *pTask = taosArrayGetP(pLevel, j); if (mndPersistTaskDeployReq(pTrans, pTask) < 0) { return -1; } } } + + // persistent stream task for already stored ts data + if (pStream->conf.fillHistory) { + level = taosArrayGetSize(pStream->pHTasksList); + + for (int32_t i = 0; i < level; i++) { + SArray *pLevel = taosArrayGetP(pStream->pHTasksList, i); + + int32_t numOfTasks = taosArrayGetSize(pLevel); + for (int32_t j = 0; j < numOfTasks; j++) { + SStreamTask *pTask = taosArrayGetP(pLevel, j); + if (mndPersistTaskDeployReq(pTrans, pTask) < 0) { + return -1; + } + } + } + } + return 0; } @@ -479,11 +510,13 @@ int32_t mndPersistStream(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream) { if (mndPersistStreamTasks(pMnode, pTrans, pStream) < 0) { return -1; } + SSdbRaw *pCommitRaw = mndStreamActionEncode(pStream); if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); return -1; } + (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); return 0; } @@ -495,6 +528,7 @@ int32_t mndPersistDropStreamLog(SMnode *pMnode, STrans *pTrans, SStreamObj *pStr mndTransDrop(pTrans); return -1; } + (void)sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); return 0; } @@ -608,16 +642,17 @@ _OVER: static int32_t mndPersistTaskDropReq(STrans *pTrans, SStreamTask *pTask) { // vnode - /*if (pTask->nodeId > 0) {*/ + /*if (pTask->info.nodeId > 0) {*/ SVDropStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVDropStreamTaskReq)); if (pReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pReq->head.vgId = htonl(pTask->nodeId); + + pReq->head.vgId = htonl(pTask->info.nodeId); pReq->taskId = pTask->id.taskId; STransAction action = {0}; - memcpy(&action.epSet, &pTask->epSet, sizeof(SEpSet)); + memcpy(&action.epSet, &pTask->info.epSet, sizeof(SEpSet)); action.pCont = pReq; action.contLen = sizeof(SVDropStreamTaskReq); action.msgType = TDMT_STREAM_TASK_DROP; @@ -737,6 +772,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr()); goto _OVER; } + mInfo("trans:%d, used to create stream:%s", pTrans->id, createStreamReq.name); mndTransSetDbName(pTrans, createStreamReq.sourceDB, streamObj.targetDb); @@ -753,7 +789,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { } // schedule stream task for stream obj - if (mndScheduleStream(pMnode, &streamObj) < 0) { + if (mndScheduleStream(pMnode, &streamObj, createStreamReq.lastTs) < 0) { mError("stream:%s, failed to schedule since %s", createStreamReq.name, terrstr()); mndTransDrop(pTrans); goto _OVER; @@ -865,7 +901,7 @@ static int32_t mndBuildStreamCheckpointSourceReq(void **pBuf, int32_t *pLen, con SMStreamDoCheckpointMsg *pMsg) { SStreamCheckpointSourceReq req = {0}; req.checkpointId = pMsg->checkpointId; - req.nodeId = pTask->nodeId; + req.nodeId = pTask->info.nodeId; req.expireTime = -1; req.streamId = pTask->id.streamId; req.taskId = pTask->id.taskId; @@ -894,7 +930,7 @@ static int32_t mndBuildStreamCheckpointSourceReq(void **pBuf, int32_t *pLen, con SMsgHead *pMsgHead = (SMsgHead *)buf; pMsgHead->contLen = htonl(tlen); - pMsgHead->vgId = htonl(pTask->nodeId); + pMsgHead->vgId = htonl(pTask->info.nodeId); tEncoderClear(&encoder); @@ -966,12 +1002,12 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre for (int32_t i = 0; i < totLevel; i++) { SArray *pLevel = taosArrayGetP(pStream->tasks, i); SStreamTask *pTask = taosArrayGetP(pLevel, 0); - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { int32_t sz = taosArrayGetSize(pLevel); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pLevel, j); - /*A(pTask->nodeId > 0);*/ - SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->nodeId); + /*A(pTask->info.nodeId > 0);*/ + SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId); if (pVgObj == NULL) { taosRUnLockLatch(&pStream->lock); mndTransDrop(pTrans); @@ -1067,8 +1103,6 @@ static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) { static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; SStreamObj *pStream = NULL; - /*SDbObj *pDb = NULL;*/ - /*SUserObj *pUser = NULL;*/ SMDropStreamReq dropReq = {0}; if (tDeserializeSMDropStreamReq(pReq->pCont, pReq->contLen, &dropReq) < 0) { @@ -1259,7 +1293,7 @@ static int32_t mndRetrieveStream(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB } pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, numOfRows, (const char *)&pStream->watermark, false); + colDataSetVal(pColInfo, numOfRows, (const char *)&pStream->conf.watermark, false); char trigger[20 + VARSTR_HEADER_SIZE] = {0}; char trigger2[20] = {0}; @@ -1289,12 +1323,16 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock while (numOfRows < rowsCapacity) { pShow->pIter = sdbFetch(pSdb, SDB_STREAM, pShow->pIter, (void **)&pStream); - if (pShow->pIter == NULL) break; + if (pShow->pIter == NULL) { + break; + } // lock taosRLockLatch(&pStream->lock); + // count task num int32_t sz = taosArrayGetSize(pStream->tasks); + int32_t count = 0; for (int32_t i = 0; i < sz; i++) { SArray *pLevel = taosArrayGetP(pStream->tasks, i); @@ -1304,10 +1342,12 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock if (numOfRows + count > rowsCapacity) { blockDataEnsureCapacity(pBlock, numOfRows + count); } + // add row for each task for (int32_t i = 0; i < sz; i++) { SArray *pLevel = taosArrayGetP(pStream->tasks, i); int32_t levelCnt = taosArrayGetSize(pLevel); + for (int32_t j = 0; j < levelCnt; j++) { SStreamTask *pTask = taosArrayGetP(pLevel, j); @@ -1317,18 +1357,25 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock // stream name char streamName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0}; STR_WITH_MAXSIZE_TO_VARSTR(streamName, mndGetDbStr(pStream->name), sizeof(streamName)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)streamName, false); // task id pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, numOfRows, (const char *)&pTask->id.taskId, false); + + char idstr[128] = {0}; + int32_t len = tintToHex(pTask->id.taskId, &idstr[4]); + idstr[2] = '0'; + idstr[3] = 'x'; + varDataSetLen(idstr, len + 2); + colDataSetVal(pColInfo, numOfRows, idstr, false); // node type char nodeType[20 + VARSTR_HEADER_SIZE] = {0}; varDataSetLen(nodeType, 5); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - if (pTask->nodeId > 0) { + if (pTask->info.nodeId > 0) { memcpy(varDataVal(nodeType), "vnode", 5); } else { memcpy(varDataVal(nodeType), "snode", 5); @@ -1337,30 +1384,50 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock // node id pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - int64_t nodeId = TMAX(pTask->nodeId, 0); + int64_t nodeId = TMAX(pTask->info.nodeId, 0); colDataSetVal(pColInfo, numOfRows, (const char *)&nodeId, false); // level char level[20 + VARSTR_HEADER_SIZE] = {0}; - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { memcpy(varDataVal(level), "source", 6); varDataSetLen(level, 6); - } else if (pTask->taskLevel == TASK_LEVEL__AGG) { + } else if (pTask->info.taskLevel == TASK_LEVEL__AGG) { memcpy(varDataVal(level), "agg", 3); varDataSetLen(level, 3); - } else if (pTask->taskLevel == TASK_LEVEL__SINK) { + } else if (pTask->info.taskLevel == TASK_LEVEL__SINK) { memcpy(varDataVal(level), "sink", 4); varDataSetLen(level, 4); - } else if (pTask->taskLevel == TASK_LEVEL__SINK) { } + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)&level, false); // status char status[20 + VARSTR_HEADER_SIZE] = {0}; - char status2[20] = {0}; - strcpy(status, "normal"); - STR_WITH_MAXSIZE_TO_VARSTR(status, status2, sizeof(status)); + int8_t taskStatus = atomic_load_8(&pTask->status.taskStatus); + if (taskStatus == TASK_STATUS__NORMAL) { + memcpy(varDataVal(status), "normal", 6); + varDataSetLen(status, 6); + } else if (taskStatus == TASK_STATUS__DROPPING) { + memcpy(varDataVal(status), "dropping", 8); + varDataSetLen(status, 8); + } else if (taskStatus == TASK_STATUS__FAIL) { + memcpy(varDataVal(status), "fail", 4); + varDataSetLen(status, 4); + } else if (taskStatus == TASK_STATUS__STOP) { + memcpy(varDataVal(status), "stop", 4); + varDataSetLen(status, 4); + } else if (taskStatus == TASK_STATUS__SCAN_HISTORY) { + memcpy(varDataVal(status), "history", 7); + varDataSetLen(status, 7); + } else if (taskStatus == TASK_STATUS__HALT) { + memcpy(varDataVal(status), "halt", 4); + varDataSetLen(status, 4); + } else if (taskStatus == TASK_STATUS__PAUSE) { + memcpy(varDataVal(status), "pause", 5); + varDataSetLen(status, 5); + } pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, numOfRows, (const char *)&status, false); @@ -1389,10 +1456,10 @@ static int32_t mndPauseStreamTask(STrans *pTrans, SStreamTask *pTask) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pReq->head.vgId = htonl(pTask->nodeId); + pReq->head.vgId = htonl(pTask->info.nodeId); pReq->taskId = pTask->id.taskId; STransAction action = {0}; - memcpy(&action.epSet, &pTask->epSet, sizeof(SEpSet)); + memcpy(&action.epSet, &pTask->info.epSet, sizeof(SEpSet)); action.pCont = pReq; action.contLen = sizeof(SVPauseStreamTaskReq); action.msgType = TDMT_STREAM_TASK_PAUSE; @@ -1403,21 +1470,36 @@ static int32_t mndPauseStreamTask(STrans *pTrans, SStreamTask *pTask) { return 0; } -int32_t mndPauseAllStreamTasks(STrans *pTrans, SStreamObj *pStream) { - int32_t size = taosArrayGetSize(pStream->tasks); +int32_t mndPauseAllStreamTaskImpl(STrans *pTrans, SArray* tasks) { + int32_t size = taosArrayGetSize(tasks); for (int32_t i = 0; i < size; i++) { - SArray *pTasks = taosArrayGetP(pStream->tasks, i); + SArray *pTasks = taosArrayGetP(tasks, i); int32_t sz = taosArrayGetSize(pTasks); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pTasks, j); - if (pTask->taskLevel != TASK_LEVEL__SINK && mndPauseStreamTask(pTrans, pTask) < 0) { + if (pTask->info.taskLevel != TASK_LEVEL__SINK && mndPauseStreamTask(pTrans, pTask) < 0) { return -1; } + + if (atomic_load_8(&pTask->status.taskStatus) != TASK_STATUS__PAUSE) { + atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus); + atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__PAUSE); + } } } return 0; } +int32_t mndPauseAllStreamTasks(STrans *pTrans, SStreamObj *pStream) { + int32_t code = mndPauseAllStreamTaskImpl(pTrans, pStream->tasks); + if (code != 0) { + return code; + } + // pStream->pHTasksList is null + // code = mndPauseAllStreamTaskImpl(pTrans, pStream->pHTasksList); + return code; +} + static int32_t mndPersistStreamLog(STrans *pTrans, const SStreamObj *pStream, int8_t status) { SStreamObj streamObj = {0}; memcpy(streamObj.name, pStream->name, TSDB_STREAM_FNAME_LEN); @@ -1457,6 +1539,10 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) { } } + if (pStream->status == STREAM_STATUS__PAUSE) { + return 0; + } + if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pStream->targetDb) != 0) { sdbRelease(pMnode->pSdb, pStream); return -1; @@ -1511,11 +1597,11 @@ static int32_t mndResumeStreamTask(STrans *pTrans, SStreamTask *pTask, int8_t ig terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pReq->head.vgId = htonl(pTask->nodeId); + pReq->head.vgId = htonl(pTask->info.nodeId); pReq->taskId = pTask->id.taskId; pReq->igUntreated = igUntreated; STransAction action = {0}; - memcpy(&action.epSet, &pTask->epSet, sizeof(SEpSet)); + memcpy(&action.epSet, &pTask->info.epSet, sizeof(SEpSet)); action.pCont = pReq; action.contLen = sizeof(SVResumeStreamTaskReq); action.msgType = TDMT_STREAM_TASK_RESUME; @@ -1533,11 +1619,16 @@ int32_t mndResumeAllStreamTasks(STrans *pTrans, SStreamObj *pStream, int8_t igUn int32_t sz = taosArrayGetSize(pTasks); for (int32_t j = 0; j < sz; j++) { SStreamTask *pTask = taosArrayGetP(pTasks, j); - if (pTask->taskLevel != TASK_LEVEL__SINK && mndResumeStreamTask(pTrans, pTask, igUntreated) < 0) { + if (pTask->info.taskLevel != TASK_LEVEL__SINK && mndResumeStreamTask(pTrans, pTask, igUntreated) < 0) { return -1; } + + if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__PAUSE) { + atomic_store_8(&pTask->status.taskStatus, pTask->status.keepTaskStatus); + } } } + // pStream->pHTasksList is null return 0; } @@ -1564,6 +1655,10 @@ static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) { } } + if (pStream->status != STREAM_STATUS__PAUSE) { + return 0; + } + if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pStream->targetDb) != 0) { sdbRelease(pMnode->pSdb, pStream); return -1; diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c index 61691a30d5..7ecd994b5a 100644 --- a/source/dnode/mnode/impl/src/mndSubscribe.c +++ b/source/dnode/mnode/impl/src/mndSubscribe.c @@ -160,10 +160,10 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, SMqSubscribeObj static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub, const SMqRebOutputVg *pRebVg, SSubplan* pPlan) { -// if (pRebVg->oldConsumerId == pRebVg->newConsumerId) { -// terrno = TSDB_CODE_MND_INVALID_SUB_OPTION; -// return -1; -// } + if (pRebVg->oldConsumerId == pRebVg->newConsumerId) { + terrno = TSDB_CODE_MND_INVALID_SUB_OPTION; + return -1; + } void *buf; int32_t tlen; @@ -175,7 +175,7 @@ static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, SMqSubsc SVgObj *pVgObj = mndAcquireVgroup(pMnode, vgId); if (pVgObj == NULL) { taosMemoryFree(buf); - terrno = TSDB_CODE_OUT_OF_MEMORY; + terrno = TSDB_CODE_MND_VGROUP_NOT_EXIST; return -1; } @@ -296,17 +296,17 @@ static void addUnassignedVgroups(SMqRebOutputObj *pOutput, SHashObj *pHash) { } } -static void putNoTransferToOutput(SMqRebOutputObj *pOutput, SMqConsumerEp *pConsumerEp){ - for(int i = 0; i < taosArrayGetSize(pConsumerEp->vgs); i++){ - SMqVgEp *pVgEp = (SMqVgEp *)taosArrayGetP(pConsumerEp->vgs, i); - SMqRebOutputVg outputVg = { - .oldConsumerId = pConsumerEp->consumerId, - .newConsumerId = pConsumerEp->consumerId, - .pVgEp = pVgEp, - }; - taosArrayPush(pOutput->rebVgs, &outputVg); - } -} +//static void putNoTransferToOutput(SMqRebOutputObj *pOutput, SMqConsumerEp *pConsumerEp){ +// for(int i = 0; i < taosArrayGetSize(pConsumerEp->vgs); i++){ +// SMqVgEp *pVgEp = (SMqVgEp *)taosArrayGetP(pConsumerEp->vgs, i); +// SMqRebOutputVg outputVg = { +// .oldConsumerId = pConsumerEp->consumerId, +// .newConsumerId = pConsumerEp->consumerId, +// .pVgEp = pVgEp, +// }; +// taosArrayPush(pOutput->rebVgs, &outputVg); +// } +//} static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, int32_t minVgCnt, int32_t imbConsumerNum) { @@ -357,7 +357,7 @@ static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHas } } } - putNoTransferToOutput(pOutput, pConsumerEp); +// putNoTransferToOutput(pOutput, pConsumerEp); } } @@ -468,40 +468,51 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR } } - if(taosHashGetSize(pOutput->pSub->consumerHash) == 0) { // if all consumer is removed +// if(taosHashGetSize(pOutput->pSub->consumerHash) == 0) { // if all consumer is removed SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pInput->pRebInfo->key); // put all offset rows if (pSub) { taosRLockLatch(&pSub->lock); - bool init = false; if (pOutput->pSub->offsetRows == NULL) { pOutput->pSub->offsetRows = taosArrayInit(4, sizeof(OffsetRows)); - init = true; } pIter = NULL; while (1) { pIter = taosHashIterate(pSub->consumerHash, pIter); if (pIter == NULL) break; SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)pIter; - if (init) { - taosArrayAddAll(pOutput->pSub->offsetRows, pConsumerEp->offsetRows); -// mDebug("pSub->offsetRows is init"); - } else { - for (int j = 0; j < taosArrayGetSize(pConsumerEp->offsetRows); j++) { - OffsetRows *d1 = taosArrayGet(pConsumerEp->offsetRows, j); - for (int i = 0; i < taosArrayGetSize(pOutput->pSub->offsetRows); i++) { - OffsetRows *d2 = taosArrayGet(pOutput->pSub->offsetRows, i); - if (d1->vgId == d2->vgId) { - d2->rows += d1->rows; - d2->offset = d1->offset; -// mDebug("pSub->offsetRows add vgId:%d, after:%"PRId64", before:%"PRId64, d2->vgId, d2->rows, d1->rows); - } + SMqConsumerEp *pConsumerEpNew = taosHashGet(pOutput->pSub->consumerHash, &pConsumerEp->consumerId, sizeof(int64_t)); + + for (int j = 0; j < taosArrayGetSize(pConsumerEp->offsetRows); j++) { + OffsetRows *d1 = taosArrayGet(pConsumerEp->offsetRows, j); + bool jump = false; + for (int i = 0; pConsumerEpNew && i < taosArrayGetSize(pConsumerEpNew->vgs); i++){ + SMqVgEp *pVgEp = taosArrayGetP(pConsumerEpNew->vgs, i); + if(pVgEp->vgId == d1->vgId){ + jump = true; + mInfo("pSub->offsetRows jump, because consumer id:%"PRIx64 " and vgId:%d not change", pConsumerEp->consumerId, pVgEp->vgId); + break; } } + if(jump) continue; + bool find = false; + for (int i = 0; i < taosArrayGetSize(pOutput->pSub->offsetRows); i++) { + OffsetRows *d2 = taosArrayGet(pOutput->pSub->offsetRows, i); + if (d1->vgId == d2->vgId) { + d2->rows += d1->rows; + d2->offset = d1->offset; + find = true; + mInfo("pSub->offsetRows add vgId:%d, after:%"PRId64", before:%"PRId64, d2->vgId, d2->rows, d1->rows); + break; + } + } + if(!find){ + taosArrayPush(pOutput->pSub->offsetRows, d1); + } } } taosRUnLockLatch(&pSub->lock); mndReleaseSubscribe(pMnode, pSub); - } +// } } // 8. generate logs @@ -576,50 +587,44 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu return -1; } + char topic[TSDB_TOPIC_FNAME_LEN] = {0}; + char cgroup[TSDB_CGROUP_LEN] = {0}; + mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true); + // 3. commit log: consumer to update status and epoch // 3.1 set touched consumer int32_t consumerNum = taosArrayGetSize(pOutput->modifyConsumers); for (int32_t i = 0; i < consumerNum; i++) { int64_t consumerId = *(int64_t *)taosArrayGet(pOutput->modifyConsumers, i); - SMqConsumerObj *pConsumerOld = mndAcquireConsumer(pMnode, consumerId); - SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumerOld->consumerId, pConsumerOld->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__TOUCH; - mndReleaseConsumer(pMnode, pConsumerOld); + SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup); + pConsumerNew->updateType = CONSUMER_UPDATE_REB_MODIFY_NOTOPIC; if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) { - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); mndTransDrop(pTrans); return -1; } - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); } // 3.2 set new consumer consumerNum = taosArrayGetSize(pOutput->newConsumers); for (int32_t i = 0; i < consumerNum; i++) { int64_t consumerId = *(int64_t *)taosArrayGet(pOutput->newConsumers, i); + SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup); + pConsumerNew->updateType = CONSUMER_UPDATE_REB_MODIFY_TOPIC; - SMqConsumerObj *pConsumerOld = mndAcquireConsumer(pMnode, consumerId); - SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumerOld->consumerId, pConsumerOld->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__ADD; - char *topic = taosMemoryCalloc(1, TSDB_TOPIC_FNAME_LEN); - char cgroup[TSDB_CGROUP_LEN]; - mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true); - taosArrayPush(pConsumerNew->rebNewTopics, &topic); - mndReleaseConsumer(pMnode, pConsumerOld); + char* topicTmp = taosStrdup(topic); + taosArrayPush(pConsumerNew->rebNewTopics, &topicTmp); if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) { - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); mndTransDrop(pTrans); return -1; } - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); } // 3.3 set removed consumer @@ -627,24 +632,19 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu for (int32_t i = 0; i < consumerNum; i++) { int64_t consumerId = *(int64_t *)taosArrayGet(pOutput->removedConsumers, i); - SMqConsumerObj *pConsumerOld = mndAcquireConsumer(pMnode, consumerId); - SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumerOld->consumerId, pConsumerOld->cgroup); - pConsumerNew->updateType = CONSUMER_UPDATE__REMOVE; - char *topic = taosMemoryCalloc(1, TSDB_TOPIC_FNAME_LEN); - char cgroup[TSDB_CGROUP_LEN]; - mndSplitSubscribeKey(pOutput->pSub->key, topic, cgroup, true); - taosArrayPush(pConsumerNew->rebRemovedTopics, &topic); - mndReleaseConsumer(pMnode, pConsumerOld); + SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup); + pConsumerNew->updateType = CONSUMER_UPDATE_REB_MODIFY_REMOVE; + + char* topicTmp = taosStrdup(topic); + taosArrayPush(pConsumerNew->rebRemovedTopics, &topicTmp); if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) { - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); mndTransDrop(pTrans); return -1; } - tDeleteSMqConsumerObj(pConsumerNew); - taosMemoryFree(pConsumerNew); + tDeleteSMqConsumerObj(pConsumerNew, true); } // 4. TODO commit log: modification log @@ -771,8 +771,10 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) { } static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) { - SMnode *pMnode = pMsg->info.node; - SMDropCgroupReq dropReq = {0}; + SMnode *pMnode = pMsg->info.node; + SMDropCgroupReq dropReq = {0}; + STrans *pTrans = NULL; + int32_t code = TSDB_CODE_ACTION_IN_PROGRESS; if (tDeserializeSMDropCgroupReq(pMsg->pCont, pMsg->contLen, &dropReq) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -791,38 +793,54 @@ static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg) { } } + taosWLockLatch(&pSub->lock); if (taosHashGetSize(pSub->consumerHash) != 0) { terrno = TSDB_CODE_MND_CGROUP_USED; mError("cgroup:%s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr()); - mndReleaseSubscribe(pMnode, pSub); - return -1; + code = -1; + goto end; } - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "drop-cgroup"); + void *pIter = NULL; + SMqConsumerObj *pConsumer; + while (1) { + pIter = sdbFetch(pMnode->pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer); + if (pIter == NULL) { + break; + } + + if (strcmp(dropReq.cgroup, pConsumer->cgroup) == 0) { + mndDropConsumerFromSdb(pMnode, pConsumer->consumerId); + } + sdbRelease(pMnode->pSdb, pConsumer); + } + + pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "drop-cgroup"); if (pTrans == NULL) { mError("cgroup: %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr()); - mndReleaseSubscribe(pMnode, pSub); - mndTransDrop(pTrans); - return -1; + code = -1; + goto end; } mInfo("trans:%d, used to drop cgroup:%s on topic %s", pTrans->id, dropReq.cgroup, dropReq.topic); if (mndSetDropSubCommitLogs(pMnode, pTrans, pSub) < 0) { mError("cgroup %s on topic:%s, failed to drop since %s", dropReq.cgroup, dropReq.topic, terrstr()); - mndReleaseSubscribe(pMnode, pSub); - mndTransDrop(pTrans); - return -1; + code = -1; + goto end; } if (mndTransPrepare(pMnode, pTrans) < 0) { - mndReleaseSubscribe(pMnode, pSub); - mndTransDrop(pTrans); - return -1; + code = -1; + goto end; } - mndReleaseSubscribe(pMnode, pSub); - return TSDB_CODE_ACTION_IN_PROGRESS; +end: + taosWUnLockLatch(&pSub->lock); + mndReleaseSubscribe(pMnode, pSub); + mndTransDrop(pTrans); + + return code; } void mndCleanupSubscribe(SMnode *pMnode) {} @@ -989,6 +1007,32 @@ SMqSubscribeObj *mndAcquireSubscribeByKey(SMnode *pMnode, const char *key) { return pSub; } +int32_t mndGetGroupNumByTopic(SMnode *pMnode, const char *topicName) { + int32_t num = 0; + SSdb *pSdb = pMnode->pSdb; + + void *pIter = NULL; + SMqSubscribeObj *pSub = NULL; + while (1) { + pIter = sdbFetch(pSdb, SDB_SUBSCRIBE, pIter, (void **)&pSub); + if (pIter == NULL) break; + + + char topic[TSDB_TOPIC_FNAME_LEN]; + char cgroup[TSDB_CGROUP_LEN]; + mndSplitSubscribeKey(pSub->key, topic, cgroup, true); + if (strcmp(topic, topicName) != 0) { + sdbRelease(pSdb, pSub); + continue; + } + + num++; + sdbRelease(pSdb, pSub); + } + + return num; +} + void mndReleaseSubscribe(SMnode *pMnode, SMqSubscribeObj *pSub) { SSdb *pSdb = pMnode->pSdb; sdbRelease(pSdb, pSub); @@ -1114,9 +1158,13 @@ static int32_t buildResult(SSDataBlock *pBlock, int32_t* numOfRows, int64_t cons colDataSetVal(pColInfo, *numOfRows, (const char *)&pVgEp->vgId, false); // consumer id + char consumerIdHex[32] = {0}; + sprintf(varDataVal(consumerIdHex), "0x%"PRIx64, consumerId); + varDataSetLen(consumerIdHex, strlen(varDataVal(consumerIdHex))); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - colDataSetVal(pColInfo, *numOfRows, (const char *)&consumerId, consumerId == -1); - + colDataSetVal(pColInfo, *numOfRows, (const char *)consumerIdHex, consumerId == -1); + mDebug("mnd show subscriptions: topic %s, consumer:0x%" PRIx64 " cgroup %s vgid %d", varDataVal(topic), consumerId, varDataVal(cgroup), pVgEp->vgId); diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c index 4bbe531bf8..485823edf3 100644 --- a/source/dnode/mnode/impl/src/mndTopic.c +++ b/source/dnode/mnode/impl/src/mndTopic.c @@ -569,6 +569,11 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) { SMqTopicObj *pTopic = NULL; SDbObj *pDb = NULL; SCMCreateTopicReq createTopicReq = {0}; + if (sdbGetSize(pMnode->pSdb, SDB_TOPIC) >= tmqMaxTopicNum){ + terrno = TSDB_CODE_TMQ_TOPIC_OUT_OF_RANGE; + mError("topic num out of range"); + return code; + } if (tDeserializeSCMCreateTopicReq(pReq->pCont, pReq->contLen, &createTopicReq) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -681,7 +686,11 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) { break; } - if (pConsumer->status == MQ_CONSUMER_STATUS__LOST_REBD) continue; + if (pConsumer->status == MQ_CONSUMER_STATUS_LOST){ + mndDropConsumerFromSdb(pMnode, pConsumer->consumerId); + mndReleaseConsumer(pMnode, pConsumer); + continue; + } int32_t sz = taosArrayGetSize(pConsumer->assignedTopics); for (int32_t i = 0; i < sz; i++) { diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index a82e49f397..444d066afe 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -875,7 +875,7 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p // if (pDb == NULL || pDb->compactStartTime <= 0) { // colDataSetNULL(pColInfo, numOfRows); // } else { - // colDataAppend(pColInfo, numOfRows, (const char *)&pDb->compactStartTime, false); + // colDataSetVal(pColInfo, numOfRows, (const char *)&pDb->compactStartTime, false); // } numOfRows++; diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 3f0165b7a0..f1384b24bf 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -52,23 +52,21 @@ void sndEnqueueStreamDispatch(SSnode *pSnode, SRpcMsg *pMsg) { FAIL: if (pMsg->info.handle == NULL) return; - SRpcMsg rsp = { - .code = code, - .info = pMsg->info, - }; + SRpcMsg rsp = { .code = code, .info = pMsg->info}; tmsgSendRsp(&rsp); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t ver) { - ASSERT(pTask->taskLevel == TASK_LEVEL__AGG && taosArrayGetSize(pTask->childEpInfo) != 0); + ASSERT(pTask->info.taskLevel == TASK_LEVEL__AGG && taosArrayGetSize(pTask->pUpstreamEpInfoList) != 0); pTask->refCnt = 1; - pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; + pTask->id.idStr = createStreamTaskIdStr(pTask->id.streamId, pTask->id.taskId); - pTask->inputQueue = streamQueueOpen(0); - pTask->outputQueue = streamQueueOpen(0); + pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; + pTask->inputQueue = streamQueueOpen(512 << 10); + pTask->outputQueue = streamQueueOpen(512 << 10); if (pTask->inputQueue == NULL || pTask->outputQueue == NULL) { return -1; @@ -85,14 +83,18 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t ver) { return -1; } - int32_t numOfChildEp = taosArrayGetSize(pTask->childEpInfo); - SReadHandle handle = {.vnode = NULL, .numOfVgroups = numOfChildEp, .pStateBackend = pTask->pState}; + int32_t numOfChildEp = taosArrayGetSize(pTask->pUpstreamEpInfoList); + SReadHandle handle = { .vnode = NULL, .numOfVgroups = numOfChildEp, .pStateBackend = pTask->pState, .fillHistory = pTask->info.fillHistory }; initStreamStateAPI(&handle.api); pTask->exec.pExecutor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle, 0); ASSERT(pTask->exec.pExecutor); - streamSetupTrigger(pTask); + streamSetupScheduleTrigger(pTask); + + qDebug("snode:%d expand stream task on snode, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", SNODE_HANDLE, + pTask->id.idStr, pTask->chkInfo.version, pTask->info.selfChildId, pTask->info.taskLevel); + return 0; } @@ -149,9 +151,10 @@ int32_t sndProcessTaskDeployReq(SSnode *pSnode, char *msg, int32_t msgLen) { taosMemoryFree(pTask); return -1; } + tDecoderClear(&decoder); - ASSERT(pTask->taskLevel == TASK_LEVEL__AGG); + ASSERT(pTask->info.taskLevel == TASK_LEVEL__AGG); // 2.save task taosWLockLatch(&pSnode->pMeta->lock); @@ -161,19 +164,20 @@ int32_t sndProcessTaskDeployReq(SSnode *pSnode, char *msg, int32_t msgLen) { return -1; } + int32_t numOfTasks = streamMetaGetNumOfTasks(pSnode->pMeta); taosWUnLockLatch(&pSnode->pMeta->lock); - // 3.go through recover steps to fill history - if (pTask->fillHistory) { - streamSetParamForRecover(pTask); - streamAggRecoverPrepare(pTask); - } + streamPrepareNdoCheckDownstream(pTask); + qDebug("snode:%d s-task:%s is deployed on snode and add into meta, status:%s, numOfTasks:%d", SNODE_HANDLE, pTask->id.idStr, + streamGetTaskStatusStr(pTask->status.taskStatus), numOfTasks); return 0; } int32_t sndProcessTaskDropReq(SSnode *pSnode, char *msg, int32_t msgLen) { SVDropStreamTaskReq *pReq = (SVDropStreamTaskReq *)msg; + qDebug("snode:%d receive msg to drop stream task:0x%x", pSnode->pMeta->vgId, pReq->taskId); + streamMetaRemoveTask(pSnode->pMeta, pReq->taskId); return 0; } @@ -255,13 +259,15 @@ int32_t sndProcessTaskRetrieveRsp(SSnode *pSnode, SRpcMsg *pMsg) { } int32_t sndProcessWriteMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg *pRsp) { - void *pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); - int32_t len = pMsg->contLen - sizeof(SMsgHead); switch (pMsg->msgType) { - case TDMT_STREAM_TASK_DEPLOY: + case TDMT_STREAM_TASK_DEPLOY: { + void *pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); + int32_t len = pMsg->contLen - sizeof(SMsgHead); return sndProcessTaskDeployReq(pSnode, pReq, len); + } + case TDMT_STREAM_TASK_DROP: - return sndProcessTaskDropReq(pSnode, pReq, len); + return sndProcessTaskDropReq(pSnode, pMsg->pCont, pMsg->contLen); default: ASSERT(0); } @@ -277,7 +283,7 @@ int32_t sndProcessTaskRecoverFinishReq(SSnode *pSnode, SRpcMsg *pMsg) { SDecoder decoder; tDecoderInit(&decoder, msg, msgLen); - tDecodeSStreamRecoverFinishReq(&decoder, &req); + tDecodeStreamRecoverFinishReq(&decoder, &req); tDecoderClear(&decoder); // find task @@ -286,7 +292,7 @@ int32_t sndProcessTaskRecoverFinishReq(SSnode *pSnode, SRpcMsg *pMsg) { return -1; } // do process request - if (streamProcessRecoverFinishReq(pTask, req.childId) < 0) { + if (streamProcessRecoverFinishReq(pTask, req.taskId, req.childId) < 0) { streamMetaReleaseTask(pSnode->pMeta, pTask); return -1; } @@ -300,6 +306,102 @@ int32_t sndProcessTaskRecoverFinishRsp(SSnode *pSnode, SRpcMsg *pMsg) { return 0; } +int32_t sndProcessStreamTaskCheckReq(SSnode *pSnode, SRpcMsg *pMsg) { + char *msgStr = pMsg->pCont; + char *msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead)); + int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); + + SStreamTaskCheckReq req; + SDecoder decoder; + + tDecoderInit(&decoder, (uint8_t *)msgBody, msgLen); + tDecodeStreamTaskCheckReq(&decoder, &req); + tDecoderClear(&decoder); + + int32_t taskId = req.downstreamTaskId; + + SStreamTaskCheckRsp rsp = { + .reqId = req.reqId, + .streamId = req.streamId, + .childId = req.childId, + .downstreamNodeId = req.downstreamNodeId, + .downstreamTaskId = req.downstreamTaskId, + .upstreamNodeId = req.upstreamNodeId, + .upstreamTaskId = req.upstreamTaskId, + }; + + SStreamTask *pTask = streamMetaAcquireTask(pSnode->pMeta, taskId); + + if (pTask != NULL) { + rsp.status = streamTaskCheckStatus(pTask); + streamMetaReleaseTask(pSnode->pMeta, pTask); + + qDebug("s-task:%s recv task check req(reqId:0x%" PRIx64 ") task:0x%x (vgId:%d), status:%s, rsp status %d", + pTask->id.idStr, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId, + streamGetTaskStatusStr(pTask->status.taskStatus), rsp.status); + } else { + rsp.status = 0; + qDebug("tq recv task check(taskId:0x%x not built yet) req(reqId:0x%" PRIx64 + ") from task:0x%x (vgId:%d), rsp status %d", + taskId, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.status); + } + + SEncoder encoder; + int32_t code; + int32_t len; + + tEncodeSize(tEncodeStreamTaskCheckRsp, &rsp, len, code); + if (code < 0) { + qError("vgId:%d failed to encode task check rsp, task:0x%x", pSnode->pMeta->vgId, taskId); + return -1; + } + + void *buf = rpcMallocCont(sizeof(SMsgHead) + len); + ((SMsgHead *)buf)->vgId = htonl(req.upstreamNodeId); + + void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); + tEncoderInit(&encoder, (uint8_t *)abuf, len); + tEncodeStreamTaskCheckRsp(&encoder, &rsp); + tEncoderClear(&encoder); + + SRpcMsg rspMsg = {.code = 0, .pCont = buf, .contLen = sizeof(SMsgHead) + len, .info = pMsg->info}; + + tmsgSendRsp(&rspMsg); + return 0; +} + +int32_t sndProcessStreamTaskCheckRsp(SSnode* pSnode, SRpcMsg* pMsg) { + char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); + int32_t len = pMsg->contLen - sizeof(SMsgHead); + + int32_t code; + SStreamTaskCheckRsp rsp; + + SDecoder decoder; + tDecoderInit(&decoder, (uint8_t*)pReq, len); + code = tDecodeStreamTaskCheckRsp(&decoder, &rsp); + + if (code < 0) { + tDecoderClear(&decoder); + return -1; + } + + tDecoderClear(&decoder); + qDebug("tq task:0x%x (vgId:%d) recv check rsp(reqId:0x%" PRIx64 ") from 0x%x (vgId:%d) status %d", + rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.status); + + SStreamTask* pTask = streamMetaAcquireTask(pSnode->pMeta, rsp.upstreamTaskId); + if (pTask == NULL) { + qError("tq failed to locate the stream task:0x%x (vgId:%d), it may have been destroyed", rsp.upstreamTaskId, + pSnode->pMeta->vgId); + return -1; + } + + code = streamProcessCheckRsp(pTask, &rsp); + streamMetaReleaseTask(pSnode->pMeta, pTask); + return code; +} + int32_t sndProcessStreamMsg(SSnode *pSnode, SRpcMsg *pMsg) { switch (pMsg->msgType) { case TDMT_STREAM_TASK_RUN: @@ -312,10 +414,14 @@ int32_t sndProcessStreamMsg(SSnode *pSnode, SRpcMsg *pMsg) { return sndProcessTaskRetrieveReq(pSnode, pMsg); case TDMT_STREAM_RETRIEVE_RSP: return sndProcessTaskRetrieveRsp(pSnode, pMsg); - case TDMT_STREAM_RECOVER_FINISH: + case TDMT_STREAM_SCAN_HISTORY_FINISH: return sndProcessTaskRecoverFinishReq(pSnode, pMsg); - case TDMT_STREAM_RECOVER_FINISH_RSP: + case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP: return sndProcessTaskRecoverFinishRsp(pSnode, pMsg); + case TDMT_STREAM_TASK_CHECK: + return sndProcessStreamTaskCheckReq(pSnode, pMsg); + case TDMT_STREAM_TASK_CHECK_RSP: + return sndProcessStreamTaskCheckRsp(pSnode, pMsg); default: ASSERT(0); } diff --git a/source/dnode/snode/src/snodeInitApi.c b/source/dnode/snode/src/snodeInitApi.c index f5e9245252..c046505630 100644 --- a/source/dnode/snode/src/snodeInitApi.c +++ b/source/dnode/snode/src/snodeInitApi.c @@ -101,6 +101,7 @@ void initStateStoreAPI(SStateStore* pStore) { pStore->streamStateCommit = streamStateCommit; pStore->streamStateDestroy= streamStateDestroy; pStore->streamStateDeleteCheckPoint = streamStateDeleteCheckPoint; + pStore->streamStateReloadInfo = streamStateReloadInfo; } void initFunctionStateStore(SFunctionStateStore* pStore) { diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index e84211c765..5fb30a0028 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -96,6 +96,7 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp int32_t vnodeProcessSyncMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg); int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo); +int32_t vnodeProcessStreamMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo); void vnodeProposeWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs); void vnodeApplyWriteMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs); void vnodeProposeCommitOnNeed(SVnode *pVnode, bool atExit); @@ -126,8 +127,6 @@ int32_t metaGetCachedTbGroup(void *pVnode, tb_uid_t suid, const uint8_t *pKey, int32_t metaPutTbGroupToCache(void* pVnode, uint64_t suid, const void *pKey, int32_t keyLen, void *pPayload, int32_t payloadLen); -int64_t metaGetTbNum(SMeta *pMeta); - int32_t metaGetStbStats(void *pVnode, int64_t uid, int64_t *numOfTables); // tsdb @@ -235,7 +234,7 @@ int32_t vnodeSnapWriterOpen(SVnode *pVnode, int64_t sver, int64_t ever, SVSnapWr int32_t vnodeSnapWriterClose(SVSnapWriter *pWriter, int8_t rollback, SSnapshot *pSnapshot); int32_t vnodeSnapWrite(SVSnapWriter *pWriter, uint8_t *pData, uint32_t nData); -int32_t buildSnapContext(SVnode *pVnode, int64_t snapVersion, int64_t suid, int8_t subType, bool withMeta, +int32_t buildSnapContext(SVnode *pVnode, int64_t snapVersion, int64_t suid, int8_t subType, int8_t withMeta, SSnapContext **ctxRet); int32_t getTableInfoFromSnapshot(SSnapContext *ctx, void **pBuf, int32_t *contLen, int16_t *type, int64_t *uid); SMetaTableInfo getMetaTableInfoFromSnapshot(SSnapContext *ctx); diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 033e4fc5b8..a966fa2245 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -45,27 +45,10 @@ extern "C" { typedef struct STqOffsetStore STqOffsetStore; // tqPush - -// typedef struct { -// // msg info -// int64_t consumerId; -// int64_t reqOffset; -// int64_t processedVer; -// int32_t epoch; -// // rpc info -// int64_t reqId; -// SRpcHandleInfo rpcInfo; -// tmr_h timerId; -// int8_t tmrStopped; -// // exec -// int8_t inputStatus; -// int8_t execStatus; -// SStreamQueue inputQ; -// SRWLatch lock; -// } STqPushHandle; +#define EXTRACT_DATA_FROM_WAL_ID (-1) +#define STREAM_TASK_STATUS_CHECK_ID (-2) // tqExec - typedef struct { char* qmsg; // SubPlanToString } STqExecCol; @@ -187,10 +170,10 @@ int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname); // tqStream int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver); int32_t tqStreamTasksScanWal(STQ* pTq); +int32_t tqStreamTasksStatusCheck(STQ* pTq); // tq util int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, SStreamRefDataBlock** pRefBlock); -char* createStreamTaskIdStr(int64_t streamId, int32_t taskId); int32_t tqAddInputBlockNLaunchTask(SStreamTask* pTask, SStreamQueueItem* pQueueItem); 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, diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index d7694ebfd5..71af169752 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -64,7 +64,6 @@ typedef struct STsdbReadSnap STsdbReadSnap; typedef struct SBlockInfo SBlockInfo; typedef struct SSmaInfo SSmaInfo; typedef struct SBlockCol SBlockCol; -typedef struct SVersionRange SVersionRange; typedef struct SLDataIter SLDataIter; typedef struct SDiskCol SDiskCol; typedef struct SDiskData SDiskData; @@ -383,11 +382,6 @@ struct TSDBKEY { TSKEY ts; }; -struct SVersionRange { - uint64_t minVer; - uint64_t maxVer; -}; - typedef struct SMemSkipListNode SMemSkipListNode; struct SMemSkipListNode { int8_t level; diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index 42d2be04c9..d7404db7c0 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -179,7 +179,8 @@ SArray* metaGetSmaTbUids(SMeta* pMeta); void* metaGetIdx(SMeta* pMeta); void* metaGetIvtIdx(SMeta* pMeta); -void metaReaderInit(SMetaReader* pReader, SMeta* pMeta, int32_t flags); +int64_t metaGetTbNum(SMeta *pMeta); +void metaReaderDoInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags); int32_t metaCreateTSma(SMeta* pMeta, int64_t version, SSmaCfg* pCfg); int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid); @@ -219,6 +220,7 @@ int tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg); int tqUnregisterPushHandle(STQ* pTq, void* pHandle); int tqStartStreamTasks(STQ* pTq); // restore all stream tasks after vnode launching completed. int32_t tqProcessStreamCheckPointReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen); +int32_t tqCheckStreamStatus(STQ* pTq); int tqCommit(STQ*); int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd); @@ -240,14 +242,14 @@ int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLe int32_t tqProcessTaskPauseReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessTaskResumeReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg); -int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t version, char* msg, int32_t msgLen); +int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t version, SRpcMsg* pMsg); int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec); int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg); -int32_t tqProcessTaskRecover1Req(STQ* pTq, SRpcMsg* pMsg); -int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t version, char* msg, int32_t msgLen); +int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg); +int32_t tqProcessTaskTransferStateReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen); int32_t tqProcessTaskRecoverFinishReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRecoverFinishRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqCheckLogInWal(STQ* pTq, int64_t version); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 0e380ea0b2..c26bb45c2b 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -17,13 +17,13 @@ #include "osMemory.h" #include "tencode.h" -void _metaReaderInit(SMetaReader *pReader, void *pVnode, int32_t flags, SStoreMeta *pAPI) { - SMeta *pMeta = ((SVnode *)pVnode)->pMeta; - metaReaderInit(pReader, pMeta, flags); +void _metaReaderInit(SMetaReader* pReader, void* pVnode, int32_t flags, SStoreMeta* pAPI) { + SMeta* pMeta = ((SVnode*)pVnode)->pMeta; + metaReaderDoInit(pReader, pMeta, flags); pReader->pAPI = pAPI; } -void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) { +void metaReaderDoInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) { memset(pReader, 0, sizeof(*pReader)); pReader->pMeta = pMeta; pReader->flags = flags; @@ -143,7 +143,7 @@ tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) { int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) { int code = 0; SMetaReader mr = {0}; - metaReaderInit(&mr, ((SVnode *)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); code = metaReaderGetTableEntryByUid(&mr, uid); if (code < 0) { metaReaderClear(&mr); @@ -159,7 +159,7 @@ int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) { int metaGetTableSzNameByUid(void *meta, uint64_t uid, char *tbName) { int code = 0; SMetaReader mr = {0}; - metaReaderInit(&mr, (SMeta *)meta, 0); + metaReaderDoInit(&mr, (SMeta *)meta, 0); code = metaReaderGetTableEntryByUid(&mr, uid); if (code < 0) { metaReaderClear(&mr); @@ -174,7 +174,7 @@ int metaGetTableSzNameByUid(void *meta, uint64_t uid, char *tbName) { int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) { int code = 0; SMetaReader mr = {0}; - metaReaderInit(&mr, ((SVnode *)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, 0); SMetaReader *pReader = &mr; @@ -195,7 +195,7 @@ int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) { int metaGetTableTypeByName(void *pVnode, char *tbName, ETableType *tbType) { int code = 0; SMetaReader mr = {0}; - metaReaderInit(&mr, ((SVnode *)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); code = metaGetTableEntryByName(&mr, tbName); if (code == 0) *tbType = mr.me.type; @@ -215,7 +215,7 @@ int metaReadNext(SMetaReader *pReader) { int metaGetTableTtlByUid(void *meta, uint64_t uid, int64_t *ttlDays) { int code = -1; SMetaReader mr = {0}; - metaReaderInit(&mr, (SMeta *)meta, 0); + metaReaderDoInit(&mr, (SMeta *)meta, 0); code = metaReaderGetTableEntryByUid(&mr, uid); if (code < 0) { goto _exit; @@ -244,9 +244,7 @@ SMTbCursor *metaOpenTbCursor(void *pVnode) { return NULL; } - SVnode *pVnodeObj = pVnode; - // metaReaderInit(&pTbCur->mr, pVnodeObj->pMeta, 0); - + SVnode* pVnodeObj = pVnode; // tdbTbcMoveToFirst((TBC *)pTbCur->pDbc); pTbCur->pMeta = pVnodeObj->pMeta; pTbCur->paused = 1; @@ -277,7 +275,7 @@ void metaPauseTbCursor(SMTbCursor *pTbCur) { } void metaResumeTbCursor(SMTbCursor *pTbCur, int8_t first) { if (pTbCur->paused) { - metaReaderInit(&pTbCur->mr, pTbCur->pMeta, 0); + metaReaderDoInit(&pTbCur->mr, pTbCur->pMeta, 0); tdbTbcOpen(((SMeta *)pTbCur->pMeta)->pUidIdx, (TBC **)&pTbCur->pDbc, NULL); @@ -784,7 +782,7 @@ STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) { } SMetaReader mr = {0}; - metaReaderInit(&mr, pMeta, 0); + metaReaderDoInit(&mr, pMeta, 0); int64_t smaId; int smaIdx = 0; STSma *pTSma = NULL; @@ -839,7 +837,7 @@ _err: STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) { STSma *pTSma = NULL; SMetaReader mr = {0}; - metaReaderInit(&mr, pMeta, 0); + metaReaderDoInit(&mr, pMeta, 0); if (metaReaderGetTableEntryByUid(&mr, indexUid) < 0) { metaWarn("vgId:%d, failed to get table entry for smaId:%" PRIi64, TD_VID(pMeta->pVnode), indexUid); metaReaderClear(&mr); diff --git a/source/dnode/vnode/src/meta/metaSma.c b/source/dnode/vnode/src/meta/metaSma.c index a49848f442..91704f5c7a 100644 --- a/source/dnode/vnode/src/meta/metaSma.c +++ b/source/dnode/vnode/src/meta/metaSma.c @@ -37,7 +37,7 @@ int32_t metaCreateTSma(SMeta *pMeta, int64_t version, SSmaCfg *pCfg) { // validate req // save smaIndex - metaReaderInit(&mr, pMeta, 0); + metaReaderDoInit(&mr, pMeta, 0); if (metaReaderGetTableEntryByUidCache(&mr, pCfg->indexUid) == 0) { #if 1 terrno = TSDB_CODE_TSMA_ALREADY_EXIST; diff --git a/source/dnode/vnode/src/meta/metaSnapshot.c b/source/dnode/vnode/src/meta/metaSnapshot.c index f4e930e509..18190ac533 100644 --- a/source/dnode/vnode/src/meta/metaSnapshot.c +++ b/source/dnode/vnode/src/meta/metaSnapshot.c @@ -260,7 +260,7 @@ static void saveSuperTableInfoForChildTable(SMetaEntry* me, SHashObj* suidInfo) taosHashPut(suidInfo, &me->uid, sizeof(tb_uid_t), &dataTmp, sizeof(STableInfoForChildTable)); } -int32_t buildSnapContext(SVnode* pVnode, int64_t snapVersion, int64_t suid, int8_t subType, bool withMeta, +int32_t buildSnapContext(SVnode* pVnode, int64_t snapVersion, int64_t suid, int8_t subType, int8_t withMeta, SSnapContext** ctxRet) { SSnapContext* ctx = taosMemoryCalloc(1, sizeof(SSnapContext)); if (ctx == NULL) return -1; @@ -476,7 +476,7 @@ int32_t getTableInfoFromSnapshot(SSnapContext* ctx, void** pBuf, int32_t* contLe if (ctx->index >= taosArrayGetSize(ctx->idList)) { metaDebug("tmqsnap get meta end"); ctx->index = 0; - ctx->queryMeta = false; // change to get data + ctx->queryMeta = 0; // change to get data return 0; } diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 424eac13b0..cb4b3231f6 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -709,7 +709,7 @@ int metaCreateTable(SMeta *pMeta, int64_t ver, SVCreateTbReq *pReq, STableMetaRs } // validate req - metaReaderInit(&mr, pMeta, 0); + metaReaderDoInit(&mr, pMeta, 0); if (metaGetTableEntryByName(&mr, pReq->name) == 0) { if (pReq->type == TSDB_CHILD_TABLE && pReq->ctb.suid != mr.me.ctbEntry.suid) { terrno = TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE; @@ -1980,6 +1980,11 @@ static int metaUpdateTtl(SMeta *pMeta, const SMetaEntry *pME) { int metaUpdateChangeTime(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeMs) { if (!tsTtlChangeOnWrite) return 0; + if (changeTimeMs <= 0) { + metaWarn("Skip to change ttl deletetion time on write, uid: %" PRId64, uid); + return TSDB_CODE_VERSION_NOT_COMPATIBLE; + } + STtlUpdCtimeCtx ctx = {.uid = uid, .changeTimeMs = changeTimeMs}; return ttlMgrUpdateChangeTime(pMeta->pTtlMgr, &ctx); diff --git a/source/dnode/vnode/src/meta/metaTtl.c b/source/dnode/vnode/src/meta/metaTtl.c index c283472c24..af4827a9c7 100644 --- a/source/dnode/vnode/src/meta/metaTtl.c +++ b/source/dnode/vnode/src/meta/metaTtl.c @@ -358,7 +358,8 @@ int ttlMgrFlush(STtlManger *pTtlMgr, TXN *pTxn) { STtlCacheEntry *cacheEntry = taosHashGet(pTtlMgr->pTtlCache, pUid, sizeof(*pUid)); if (cacheEntry == NULL) { - metaError("ttlMgr flush failed to get ttl cache since %s", tstrerror(terrno)); + metaError("ttlMgr flush failed to get ttl cache since %s, uid: %" PRId64 ", type: %d", tstrerror(terrno), *pUid, + pEntry->type); goto _out; } diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index 39aa5c3043..d393f4b6bc 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -896,7 +896,7 @@ static int32_t tdRSmaInfoClone(SSma *pSma, SRSmaInfo *pInfo) { return TSDB_CODE_SUCCESS; } - metaReaderInit(&mr, SMA_META(pSma), 0); + metaReaderDoInit(&mr, SMA_META(pSma), 0); smaDebug("vgId:%d, rsma clone qTaskInfo for suid:%" PRIi64, SMA_VID(pSma), pInfo->suid); if (metaReaderGetTableEntryByUidCache(&mr, pInfo->suid) < 0) { code = terrno; @@ -1116,7 +1116,7 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) { } int64_t nRsmaTables = 0; - metaReaderInit(&mr, SMA_META(pSma), 0); + metaReaderDoInit(&mr, SMA_META(pSma), 0); if (!(uidStore.tbUids = taosArrayInit(1024, sizeof(tb_uid_t)))) { code = TSDB_CODE_OUT_OF_MEMORY; TSDB_CHECK_CODE(code, lino, _exit); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 4798af799a..bee25bf802 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -18,8 +18,6 @@ // 0: not init // 1: already inited // 2: wait to be inited or cleaup -#define WAL_READ_TASKS_ID (-1) - static int32_t tqInitialize(STQ* pTq); static FORCE_INLINE bool tqIsHandleExec(STqHandle* pHandle) { return TMQ_HANDLE_STATUS_EXEC == pHandle->status; } @@ -158,6 +156,29 @@ void tqClose(STQ* pTq) { taosMemoryFree(pTq); } +static bool hasStreamTaskInTimer(SStreamMeta* pMeta) { + bool inTimer = false; + + taosWLockLatch(&pMeta->lock); + + void* pIter = NULL; + while(1) { + pIter = taosHashIterate(pMeta->pTasks, pIter); + if (pIter == NULL) { + break; + } + + SStreamTask* pTask = *(SStreamTask**)pIter; + if (pTask->status.timerActive == 1) { + inTimer = true; + } + } + + taosWUnLockLatch(&pMeta->lock); + + return inTimer; +} + void tqNotifyClose(STQ* pTq) { if (pTq != NULL) { taosWLockLatch(&pTq->pStreamMeta->lock); @@ -170,77 +191,90 @@ void tqNotifyClose(STQ* pTq) { } SStreamTask* pTask = *(SStreamTask**)pIter; - tqDebug("vgId:%d s-task:%s set dropping flag", pTq->pStreamMeta->vgId, pTask->id.idStr); + tqDebug("vgId:%d s-task:%s set closing flag", pTq->pStreamMeta->vgId, pTask->id.idStr); pTask->status.taskStatus = TASK_STATUS__STOP; int64_t st = taosGetTimestampMs(); qKillTask(pTask->exec.pExecutor, TSDB_CODE_SUCCESS); + int64_t el = taosGetTimestampMs() - st; tqDebug("vgId:%d s-task:%s is closed in %" PRId64 " ms", pTq->pStreamMeta->vgId, pTask->id.idStr, el); } taosWUnLockLatch(&pTq->pStreamMeta->lock); + + tqDebug("vgId:%d start to check all tasks", pTq->pStreamMeta->vgId); + + int64_t st = taosGetTimestampMs(); + + while(hasStreamTaskInTimer(pTq->pStreamMeta)) { + tqDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pTq->pStreamMeta->vgId); + taosMsleep(100); + } + + int64_t el = taosGetTimestampMs() - st; + tqDebug("vgId:%d all stream tasks are not in timer, continue close, elapsed time:%"PRId64" ms", pTq->pStreamMeta->vgId, el); } } -static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, - int64_t consumerId, int32_t type) { - int32_t len = 0; - int32_t code = 0; - - if (type == TMQ_MSG_TYPE__POLL_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*)buf)->mqMsgType = type; - ((SMqRspHead*)buf)->epoch = epoch; - ((SMqRspHead*)buf)->consumerId = consumerId; - - void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); - - SEncoder encoder = {0}; - tEncoderInit(&encoder, abuf, len); - - if (type == TMQ_MSG_TYPE__POLL_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; -} +//static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, +// int64_t consumerId, int32_t type) { +// int32_t len = 0; +// int32_t code = 0; +// +// if (type == TMQ_MSG_TYPE__POLL_DATA_RSP) { +// tEncodeSize(tEncodeMqDataRsp, pRsp, len, code); +// } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_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*)buf)->mqMsgType = type; +// ((SMqRspHead*)buf)->epoch = epoch; +// ((SMqRspHead*)buf)->consumerId = consumerId; +// +// void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); +// +// SEncoder encoder = {0}; +// tEncoderInit(&encoder, abuf, len); +// +// if (type == TMQ_MSG_TYPE__POLL_DATA_RSP) { +// tEncodeMqDataRsp(&encoder, pRsp); +// } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { +// tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp); +// } +// +// tEncoderClear(&encoder); +// +// SRpcMsg rsp = { +// .info = *pRpcHandleInfo, +// .pCont = buf, +// .contLen = tlen, +// .code = 0, +// }; +// +// tmsgSendRsp(&rsp); +// return 0; +//} 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; + dataRsp.head.mqMsgType = TMQ_MSG_TYPE__POLL_DATA_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, + tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_DATA_RSP, sver, ever); char buf1[TSDB_OFFSET_LEN] = {0}; @@ -771,19 +805,32 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL; pTask->pMsgCb = &pTq->pVnode->msgCb; pTask->pMeta = pTq->pStreamMeta; + pTask->chkInfo.version = ver; pTask->chkInfo.currentVer = ver; - // expand executor - pTask->status.taskStatus = (pTask->fillHistory) ? TASK_STATUS__WAIT_DOWNSTREAM : TASK_STATUS__NORMAL; + pTask->dataRange.range.maxVer = ver; + pTask->dataRange.range.minVer = ver; - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { - pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1); + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { + SStreamTask* pSateTask = pTask; + SStreamTask task = {0}; + if (pTask->info.fillHistory) { + task.id = pTask->streamTaskId; + task.pMeta = pTask->pMeta; + pSateTask = &task; + } + + pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pSateTask, false, -1, -1); if (pTask->pState == NULL) { return -1; } - SReadHandle handle = {.vnode = pTq->pVnode, .initTqReader = 1, .pStateBackend = pTask->pState}; + SReadHandle handle = {.vnode = pTq->pVnode, + .initTqReader = 1, + .pStateBackend = pTask->pState, + .fillHistory = pTask->info.fillHistory, + .winRange = pTask->dataRange.window}; initStorageAPI(&handle.api); pTask->exec.pExecutor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle, vgId); @@ -792,14 +839,25 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { } 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); + } else if (pTask->info.taskLevel == TASK_LEVEL__AGG) { + SStreamTask* pSateTask = pTask; + SStreamTask task = {0}; + if (pTask->info.fillHistory) { + task.id = pTask->streamTaskId; + task.pMeta = pTask->pMeta; + pSateTask = &task; + } + pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pSateTask, false, -1, -1); if (pTask->pState == NULL) { return -1; } - int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTask->childEpInfo); - SReadHandle handle = {.vnode = NULL, .numOfVgroups = numOfVgroups, .pStateBackend = pTask->pState}; + int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTask->pUpstreamEpInfoList); + SReadHandle handle = {.vnode = NULL, + .numOfVgroups = numOfVgroups, + .pStateBackend = pTask->pState, + .fillHistory = pTask->info.fillHistory, + .winRange = pTask->dataRange.window}; initStorageAPI(&handle.api); pTask->exec.pExecutor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle, vgId); @@ -834,15 +892,17 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { tSimpleHashSetFreeFp(pTask->tbSink.pTblInfo, freePtr); } - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { SWalFilterCond cond = {.deleteMsg = 1}; // delete msg also extract from wal files pTask->exec.pWalReader = walOpenReader(pTq->pVnode->pWal, &cond); } - streamSetupTrigger(pTask); + streamSetupScheduleTrigger(pTask); - tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, - pTask->id.idStr, pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel); + tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 + " child id:%d, level:%d, scan-history:%d, trigger:%" PRId64 " ms", + vgId, pTask->id.idStr, pTask->chkInfo.version, pTask->info.selfChildId, pTask->info.taskLevel, + pTask->info.fillHistory, pTask->triggerParam); // next valid version will add one pTask->chkInfo.version += 1; @@ -858,10 +918,11 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) { SDecoder decoder; tDecoderInit(&decoder, (uint8_t*)msgBody, msgLen); - tDecodeSStreamTaskCheckReq(&decoder, &req); + tDecodeStreamTaskCheckReq(&decoder, &req); tDecoderClear(&decoder); - int32_t taskId = req.downstreamTaskId; + int32_t taskId = req.downstreamTaskId; + SStreamTaskCheckRsp rsp = { .reqId = req.reqId, .streamId = req.streamId, @@ -878,23 +939,20 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) { rsp.status = streamTaskCheckStatus(pTask); streamMetaReleaseTask(pTq->pStreamMeta, pTask); - tqDebug("s-task:%s recv task check req(reqId:0x%" PRIx64 - ") %d at node %d task status:%d, check req from task %d at node %d, rsp status %d", - pTask->id.idStr, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, pTask->status.taskStatus, - rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.status); + tqDebug("s-task:%s recv task check req(reqId:0x%" PRIx64 ") task:0x%x (vgId:%d), status:%s, rsp status %d", + pTask->id.idStr, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId, + streamGetTaskStatusStr(pTask->status.taskStatus), rsp.status); } else { rsp.status = 0; - tqDebug("tq recv task check(taskId:0x%x not built yet) req(reqId:0x%" PRIx64 - ") %d at node %d, check req from task:0x%x at node %d, rsp status %d", - taskId, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.upstreamTaskId, rsp.upstreamNodeId, - rsp.status); + tqDebug("tq recv task check(taskId:0x%x not built yet) req(reqId:0x%" PRIx64 ") from task:0x%x (vgId:%d), rsp status %d", + taskId, rsp.reqId, rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.status); } SEncoder encoder; int32_t code; int32_t len; - tEncodeSize(tEncodeSStreamTaskCheckRsp, &rsp, len, code); + tEncodeSize(tEncodeStreamTaskCheckRsp, &rsp, len, code); if (code < 0) { tqError("vgId:%d failed to encode task check rsp, task:0x%x", pTq->pStreamMeta->vgId, taskId); return -1; @@ -905,7 +963,7 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) { void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); tEncoderInit(&encoder, (uint8_t*)abuf, len); - tEncodeSStreamTaskCheckRsp(&encoder, &rsp); + tEncodeStreamTaskCheckRsp(&encoder, &rsp); tEncoderClear(&encoder); SRpcMsg rspMsg = {.code = 0, .pCont = buf, .contLen = sizeof(SMsgHead) + len, .info = pMsg->info}; @@ -914,13 +972,16 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) { return 0; } -int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { +int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t sversion, SRpcMsg* pMsg) { + char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); + int32_t len = pMsg->contLen - sizeof(SMsgHead); + int32_t code; SStreamTaskCheckRsp rsp; SDecoder decoder; - tDecoderInit(&decoder, (uint8_t*)msg, msgLen); - code = tDecodeSStreamTaskCheckRsp(&decoder, &rsp); + tDecoderInit(&decoder, (uint8_t*)pReq, len); + code = tDecodeStreamTaskCheckRsp(&decoder, &rsp); if (code < 0) { tDecoderClear(&decoder); @@ -928,17 +989,18 @@ int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t sversion, char* msg, int32 } tDecoderClear(&decoder); - tqDebug("tq recv task check rsp(reqId:0x%" PRIx64 ") %d at node %d check req from task:0x%x at node %d, status %d", - rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.status); + tqDebug("tq task:0x%x (vgId:%d) recv check rsp(reqId:0x%" PRIx64 ") from 0x%x (vgId:%d) status %d", + rsp.upstreamTaskId, rsp.upstreamNodeId, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.status); SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, rsp.upstreamTaskId); if (pTask == NULL) { - tqError("tq failed to locate the stream task:0x%x vgId:%d, it may have been destroyed", rsp.upstreamTaskId, + tqError("tq failed to locate the stream task:0x%x (vgId:%d), it may have been destroyed", rsp.upstreamTaskId, pTq->pStreamMeta->vgId); + terrno = TSDB_CODE_STREAM_TASK_NOT_EXIST; return -1; } - code = streamProcessTaskCheckRsp(pTask, &rsp, sversion); + code = streamProcessCheckRsp(pTask, &rsp); streamMetaReleaseTask(pTq->pStreamMeta, pTask); return code; } @@ -971,105 +1033,232 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms tDecoderClear(&decoder); + SStreamMeta* pStreamMeta = pTq->pStreamMeta; + // 2.save task, use the newest commit version as the initial start version of stream task. - taosWLockLatch(&pTq->pStreamMeta->lock); - code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask); - int32_t numOfTasks = streamMetaGetNumOfTasks(pTq->pStreamMeta); + taosWLockLatch(&pStreamMeta->lock); + code = streamMetaAddDeployedTask(pStreamMeta, sversion, pTask); + + int32_t numOfTasks = streamMetaGetNumOfTasks(pStreamMeta); if (code < 0) { tqError("vgId:%d failed to add s-task:%s, total:%d", vgId, pTask->id.idStr, numOfTasks); - taosWUnLockLatch(&pTq->pStreamMeta->lock); + taosWUnLockLatch(&pStreamMeta->lock); return -1; } - taosWUnLockLatch(&pTq->pStreamMeta->lock); + taosWUnLockLatch(&pStreamMeta->lock); - // 3.go through recover steps to fill history - if (pTask->fillHistory) { - streamTaskCheckDownstream(pTask, sversion); - } + // 3. It's an fill history task, do nothing. wait for the main task to start it + streamPrepareNdoCheckDownstream(pTask); + + tqDebug("vgId:%d s-task:%s is deployed and add into meta, status:%s, numOfTasks:%d", vgId, pTask->id.idStr, + streamGetTaskStatusStr(pTask->status.taskStatus), numOfTasks); - tqDebug("vgId:%d s-task:%s is deployed and add meta from mnd, status:%d, total:%d", vgId, pTask->id.idStr, - pTask->status.taskStatus, numOfTasks); return 0; } -int32_t tqProcessTaskRecover1Req(STQ* pTq, SRpcMsg* pMsg) { - int32_t code; +int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { + int32_t code = TSDB_CODE_SUCCESS; char* msg = pMsg->pCont; - int32_t msgLen = pMsg->contLen; - SStreamRecoverStep1Req* pReq = (SStreamRecoverStep1Req*)msg; - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId); + SStreamMeta* pMeta = pTq->pStreamMeta; + SStreamScanHistoryReq* pReq = (SStreamScanHistoryReq*)msg; + + SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->taskId); if (pTask == NULL) { + tqError("vgId:%d failed to acquire stream task:0x%x during stream recover, task may have been destroyed", + pMeta->vgId, pReq->taskId); return -1; } // check param int64_t fillVer1 = pTask->chkInfo.version; if (fillVer1 <= 0) { - streamMetaReleaseTask(pTq->pStreamMeta, pTask); + streamMetaReleaseTask(pMeta, pTask); return -1; } // do recovery step 1 - tqDebug("s-task:%s start non-blocking recover stage(step 1) scan", pTask->id.idStr); + const char* pId = pTask->id.idStr; + tqDebug("s-task:%s start history data scan stage(step 1), status:%s", pId, + streamGetTaskStatusStr(pTask->status.taskStatus)); + int64_t st = taosGetTimestampMs(); + int8_t schedStatus = atomic_val_compare_exchange_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE, + TASK_SCHED_STATUS__WAITING); + if (schedStatus != TASK_SCHED_STATUS__INACTIVE) { + ASSERT(0); + return 0; + } - streamSourceRecoverScanStep1(pTask); - if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING) { - tqDebug("s-task:%s is dropped, abort recover in step1", pTask->id.idStr); + if (!pReq->igUntreated && !streamTaskRecoverScanStep1Finished(pTask)) { + streamSourceScanHistoryData(pTask); + } - streamMetaReleaseTask(pTq->pStreamMeta, pTask); + if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING || streamTaskShouldPause(&pTask->status)) { + tqDebug("s-task:%s is dropped or paused, abort recover in step1", pId); + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + streamMetaReleaseTask(pMeta, pTask); return 0; } double el = (taosGetTimestampMs() - st) / 1000.0; - tqDebug("s-task:%s non-blocking recover stage(step 1) ended, elapsed time:%.2fs", pTask->id.idStr, el); + tqDebug("s-task:%s history data scan stage(step 1) ended, elapsed time:%.2fs", pId, el); - // build msg to launch next step - SStreamRecoverStep2Req req; - code = streamBuildSourceRecover2Req(pTask, &req); - if (code < 0) { - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return -1; + if (pTask->info.fillHistory) { + SVersionRange* pRange = NULL; + SStreamTask* pStreamTask = NULL; + + if (!pReq->igUntreated && !streamTaskRecoverScanStep1Finished(pTask)) { + // 1. stop the related stream task, get the current scan wal version of stream task, ver. + pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.taskId); + if (pStreamTask == NULL) { + // todo handle error + } + + ASSERT(pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE); + + // wait for the stream task get ready for scan history data + while (((pStreamTask->status.downstreamReady == 0) && (pStreamTask->status.taskStatus != TASK_STATUS__STOP)) || + pStreamTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY) { + tqDebug( + "s-task:%s level:%d related stream task:%s not ready for halt, wait for it continue and recheck in 100ms", + pTask->id.idStr, pTask->info.taskLevel, pStreamTask->id.idStr); + taosMsleep(100); + } + + // now we can stop the stream task execution + pStreamTask->status.taskStatus = TASK_STATUS__HALT; + tqDebug("s-task:%s level:%d status is set to halt by history scan task:%s", pStreamTask->id.idStr, + pStreamTask->info.taskLevel, pId); + + // if it's an source task, extract the last version in wal. + pRange = &pTask->dataRange.range; + int64_t latestVer = walReaderGetCurrentVer(pStreamTask->exec.pWalReader); + ASSERT(latestVer >= pRange->maxVer); + + int64_t nextStartVer = pRange->maxVer + 1; + if (nextStartVer > latestVer - 1) { + // no input data yet. no need to execute the secondardy scan while stream task halt + streamTaskRecoverSetAllStepFinished(pTask); + tqDebug("s-task:%s no need to perform secondary scan-history-data(step 2), since no data ingest during secondary scan", pId); + } else { + // 2. do secondary scan of the history data, the time window remain, and the version range is updated to + // [pTask->dataRange.range.maxVer, ver1] + pRange->minVer = nextStartVer; + pRange->maxVer = latestVer - 1; + } + } + + if (!streamTaskRecoverScanStep1Finished(pTask)) { + tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 + " do secondary scan-history-data after halt the related stream task:%s", + pId, pTask->info.taskLevel, pRange->minVer, pRange->maxVer, pStreamTask->id.idStr); + ASSERT(pTask->status.schedStatus == TASK_SCHED_STATUS__WAITING); + + st = taosGetTimestampMs(); + streamSetParamForStreamScannerStep2(pTask, pRange, &pTask->dataRange.window); + } + + if (!streamTaskRecoverScanStep2Finished(pTask)) { + streamSourceScanHistoryData(pTask); + if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING || streamTaskShouldPause(&pTask->status)) { + tqDebug("s-task:%s is dropped or paused, abort recover in step1", pId); + streamMetaReleaseTask(pMeta, pTask); + return 0; + } + + streamTaskRecoverSetAllStepFinished(pTask); + } + + el = (taosGetTimestampMs() - st) / 1000.0; + tqDebug("s-task:%s history data scan stage(step 2) ended, elapsed time:%.2fs", pId, el); + + // 3. notify the downstream tasks to transfer executor state after handle all history blocks. + if (!pTask->status.transferState) { + code = streamDispatchTransferStateMsg(pTask); + if (code != TSDB_CODE_SUCCESS) { + // todo handle error + } + + pTask->status.transferState = true; + } + + // 4. 1) transfer the ownership of executor state, 2) update the scan data range for source task. + // 5. resume the related stream task. + streamTryExec(pTask); + + pTask->status.taskStatus = TASK_STATUS__DROPPING; + tqDebug("s-task:%s scan-history-task set status to be dropping", pId); + + streamMetaSaveTask(pMeta, pTask); + streamMetaSaveTask(pMeta, pStreamTask); + + streamMetaReleaseTask(pMeta, pTask); + streamMetaReleaseTask(pMeta, pStreamTask); + + taosWLockLatch(&pMeta->lock); + if (streamMetaCommit(pTask->pMeta) < 0) { + // persist to disk + } + taosWUnLockLatch(&pMeta->lock); + } else { + // todo update the chkInfo version for current task. + // this task has an associated history stream task, so we need to scan wal from the end version of + // history scan. The current version of chkInfo.current is not updated during the history scan + STimeWindow* pWindow = &pTask->dataRange.window; + + if (pTask->historyTaskId.taskId == 0) { + *pWindow = (STimeWindow){INT64_MIN, INT64_MAX}; + tqDebug("s-task:%s no associated task, reset the time window:%" PRId64 " - %" PRId64, pId, pWindow->skey, + pWindow->ekey); + } else { + tqDebug("s-task:%s history data scan completed, now start to scan data from wal, start ver:%" PRId64 + ", window:%" PRId64 " - %" PRId64, + pId, pTask->chkInfo.currentVer, pWindow->skey, pWindow->ekey); + } + + code = streamTaskScanHistoryDataComplete(pTask); + streamMetaReleaseTask(pMeta, pTask); + + // let's start the stream task by extracting data from wal + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { + tqStartStreamTasks(pTq); + } + + return code; } - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING) { - return 0; - } - - // serialize msg - int32_t len = sizeof(SStreamRecoverStep1Req); - - void* serializedReq = rpcMallocCont(len); - if (serializedReq == NULL) { - tqError("s-task:%s failed to prepare the step2 stage, out of memory", pTask->id.idStr); - return -1; - } - - memcpy(serializedReq, &req, len); - - // dispatch msg - tqDebug("s-task:%s start recover block stage", pTask->id.idStr); - - SRpcMsg rpcMsg = { - .code = 0, .contLen = len, .msgType = TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE, .pCont = serializedReq}; - tmsgPutToQueue(&pTq->pVnode->msgCb, WRITE_QUEUE, &rpcMsg); return 0; } -int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { - int32_t code = 0; +// notify the downstream tasks to transfer executor state after handle all history blocks. +int32_t tqProcessTaskTransferStateReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { + SStreamTransferReq req; - SStreamRecoverStep2Req* pReq = (SStreamRecoverStep2Req*)msg; + SDecoder decoder; + tDecoderInit(&decoder, (uint8_t*)msg, msgLen); + int32_t code = tDecodeStreamRecoverFinishReq(&decoder, &req); + tDecoderClear(&decoder); - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId); + SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.taskId); if (pTask == NULL) { + tqError("failed to find task:0x%x, it may have been dropped already", req.taskId); return -1; } - // do recovery step 2 + // transfer the ownership of executor state + streamTaskReleaseState(pTask); + tqDebug("s-task:%s receive state transfer req", pTask->id.idStr); + + SStreamTask* pStreamTask = streamMetaAcquireTask(pTq->pStreamMeta, pTask->streamTaskId.taskId); + streamTaskReloadState(pStreamTask); + + ASSERT(pTask->streamTaskId.taskId != 0); + pTask->status.transferState = true; // persistent data? + +#if 0 + // do check if current task handle all data in the input queue int64_t st = taosGetTimestampMs(); tqDebug("s-task:%s start step2 recover, ts:%" PRId64, pTask->id.idStr, st); @@ -1108,16 +1297,19 @@ int32_t tqProcessTaskRecover2Req(STQ* pTq, int64_t sversion, char* msg, int32_t tqDebug("s-task:%s step2 recover finished, el:%.2fs", pTask->id.idStr, el); // dispatch recover finish req to all related downstream task - code = streamDispatchRecoverFinishReq(pTask); + code = streamDispatchScanHistoryFinishMsg(pTask); if (code < 0) { streamMetaReleaseTask(pTq->pStreamMeta, pTask); return -1; } - atomic_store_8(&pTask->fillHistory, 0); + atomic_store_8(&pTask->info.fillHistory, 0); streamMetaSaveTask(pTq->pStreamMeta, pTask); +#endif + streamSchedExec(pTask); streamMetaReleaseTask(pTq->pStreamMeta, pTask); + return 0; } @@ -1130,7 +1322,7 @@ int32_t tqProcessTaskRecoverFinishReq(STQ* pTq, SRpcMsg* pMsg) { SDecoder decoder; tDecoderInit(&decoder, (uint8_t*)msg, msgLen); - tDecodeSStreamRecoverFinishReq(&decoder, &req); + tDecodeStreamRecoverFinishReq(&decoder, &req); tDecoderClear(&decoder); // find task @@ -1139,7 +1331,7 @@ int32_t tqProcessTaskRecoverFinishReq(STQ* pTq, SRpcMsg* pMsg) { return -1; } // do process request - if (streamProcessRecoverFinishReq(pTask, req.childId) < 0) { + if (streamProcessRecoverFinishReq(pTask, req.taskId, req.childId) < 0) { streamMetaReleaseTask(pTq->pStreamMeta, pTask); return -1; } @@ -1212,22 +1404,31 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) { int32_t taskId = pReq->taskId; int32_t vgId = TD_VID(pTq->pVnode); - if (taskId == WAL_READ_TASKS_ID) { // all tasks are extracted submit data from the wal + if (taskId == STREAM_TASK_STATUS_CHECK_ID) { + tqStreamTasksStatusCheck(pTq); + return 0; + } + + if (taskId == EXTRACT_DATA_FROM_WAL_ID) { // all tasks are extracted submit data from the wal tqStreamTasksScanWal(pTq); return 0; } SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId); if (pTask != NULL) { - if (pTask->status.taskStatus == TASK_STATUS__NORMAL) { - tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId, pTask->id.idStr, + // even in halt status, the data in inputQ must be processed + int8_t status = pTask->status.taskStatus; + if (status == TASK_STATUS__NORMAL || status == TASK_STATUS__HALT) { + tqDebug("vgId:%d s-task:%s start to process block from inputQ, last chk point:%" PRId64, vgId, pTask->id.idStr, pTask->chkInfo.version); streamProcessRunReq(pTask); } else { - if (streamTaskShouldPause(&pTask->status)) { +// if (streamTaskShouldPause(&pTask->status)) { atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - } - tqDebug("vgId:%d s-task:%s ignore run req since not in ready state", vgId, pTask->id.idStr); +// } + + tqDebug("vgId:%d s-task:%s ignore run req since not in ready state, status:%s, sched-status:%d", vgId, + pTask->id.idStr, streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus); } streamMetaReleaseTask(pTq->pStreamMeta, pTask); @@ -1286,65 +1487,100 @@ int32_t tqProcessTaskDropReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgL return 0; } +int32_t tqProcessTaskPauseImpl(SStreamMeta* pStreamMeta, SStreamTask* pTask) { + if (pTask) { + if (!streamTaskShouldPause(&pTask->status)) { + tqDebug("vgId:%d s-task:%s set pause flag", pStreamMeta->vgId, pTask->id.idStr); + atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus); + atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__PAUSE); + } + streamMetaReleaseTask(pStreamMeta, pTask); + } else { + return -1; + } + return 0; +} + int32_t tqProcessTaskPauseReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)msg; SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId); + int32_t code = tqProcessTaskPauseImpl(pTq->pStreamMeta, pTask); + if (code != 0) { + return code; + } + SStreamTask* pHistoryTask = streamMetaAcquireTask(pTq->pStreamMeta, pTask->historyTaskId.taskId); + if (pHistoryTask) { + code = tqProcessTaskPauseImpl(pTq->pStreamMeta, pHistoryTask); + } + return code; +} + +int32_t tqProcessTaskResumeImpl(STQ* pTq, SStreamTask* pTask, int64_t sversion, int8_t igUntreated) { + int32_t vgId = pTq->pStreamMeta->vgId; if (pTask) { - tqDebug("vgId:%d s-task:%s set pause flag", pTq->pStreamMeta->vgId, pTask->id.idStr); - atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus); - atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__PAUSE); + if (streamTaskShouldPause(&pTask->status)) { + atomic_store_8(&pTask->status.taskStatus, pTask->status.keepTaskStatus); + + // no lock needs to secure the access of the version + if (igUntreated && pTask->info.taskLevel == TASK_LEVEL__SOURCE && !pTask->info.fillHistory) { + // discard all the data when the stream task is suspended. + walReaderSetSkipToVersion(pTask->exec.pWalReader, sversion); + tqDebug("vgId:%d s-task:%s resume to exec, prev paused version:%" PRId64 ", start from vnode ver:%" PRId64 + ", schedStatus:%d", + vgId, pTask->id.idStr, pTask->chkInfo.currentVer, sversion, pTask->status.schedStatus); + } else { // from the previous paused version and go on + tqDebug("vgId:%d s-task:%s resume to exec, from paused ver:%" PRId64 ", vnode ver:%" PRId64 ", schedStatus:%d", + vgId, pTask->id.idStr, pTask->chkInfo.currentVer, sversion, pTask->status.schedStatus); + } + + if (pTask->info.fillHistory && pTask->info.taskLevel == TASK_LEVEL__SOURCE) { + streamStartRecoverTask(pTask, igUntreated); + } else if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && taosQueueItemSize(pTask->inputQueue->queue) == 0) { + tqStartStreamTasks(pTq); + } else { + streamSchedExec(pTask); + } + } streamMetaReleaseTask(pTq->pStreamMeta, pTask); + } else { + return -1; } return 0; } int32_t tqProcessTaskResumeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) { SVResumeStreamTaskReq* pReq = (SVResumeStreamTaskReq*)msg; - - int32_t vgId = pTq->pStreamMeta->vgId; SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, pReq->taskId); - if (pTask) { - atomic_store_8(&pTask->status.taskStatus, pTask->status.keepTaskStatus); - - // no lock needs to secure the access of the version - if (pReq->igUntreated && pTask->taskLevel == TASK_LEVEL__SOURCE) { - // discard all the data when the stream task is suspended. - walReaderSetSkipToVersion(pTask->exec.pWalReader, sversion); - tqDebug("vgId:%d s-task:%s resume to exec, prev paused version:%" PRId64 ", start from vnode ver:%" PRId64 - ", schedStatus:%d", - vgId, pTask->id.idStr, pTask->chkInfo.currentVer, sversion, pTask->status.schedStatus); - } else { // from the previous paused version and go on - tqDebug("vgId:%d s-task:%s resume to exec, from paused ver:%" PRId64 ", vnode ver:%" PRId64 ", schedStatus:%d", - vgId, pTask->id.idStr, pTask->chkInfo.currentVer, sversion, pTask->status.schedStatus); - } - - if (pTask->taskLevel == TASK_LEVEL__SOURCE && taosQueueItemSize(pTask->inputQueue->queue) == 0) { - tqStartStreamTasks(pTq); - } else { - streamSchedExec(pTask); - } - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - } else { - tqError("vgId:%d failed to find the s-task:0x%x for resume stream task", vgId, pReq->taskId); + int32_t code = tqProcessTaskResumeImpl(pTq, pTask, sversion, pReq->igUntreated); + if (code != 0) { + return code; } - return 0; + SStreamTask* pHistoryTask = streamMetaAcquireTask(pTq->pStreamMeta, pTask->historyTaskId.taskId); + if (pHistoryTask) { + code = tqProcessTaskResumeImpl(pTq, pHistoryTask, sversion, pReq->igUntreated); + } + return code; } int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg) { - char* msgStr = pMsg->pCont; - char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead)); - int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); + char* msgStr = pMsg->pCont; + char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead)); + int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); + SDecoder decoder; + SStreamRetrieveReq req; - SDecoder decoder; tDecoderInit(&decoder, (uint8_t*)msgBody, msgLen); tDecodeStreamRetrieveReq(&decoder, &req); tDecoderClear(&decoder); + int32_t taskId = req.dstTaskId; SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId); + if (pTask) { SRpcMsg rsp = {.info = pMsg->info, .code = 0}; streamProcessRetrieveReq(pTask, &req, &rsp); + streamMetaReleaseTask(pTq->pStreamMeta, pTask); tDeleteStreamRetrieveReq(&req); return 0; @@ -1425,46 +1661,6 @@ FAIL: int32_t tqCheckLogInWal(STQ* pTq, int64_t sversion) { return sversion <= pTq->walLogLastVer; } -int32_t tqStartStreamTasks(STQ* pTq) { - int32_t vgId = TD_VID(pTq->pVnode); - SStreamMeta* pMeta = pTq->pStreamMeta; - - taosWLockLatch(&pMeta->lock); - - int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList); - if (numOfTasks == 0) { - tqInfo("vgId:%d no stream tasks exist", vgId); - taosWUnLockLatch(&pMeta->lock); - return 0; - } - - pMeta->walScanCounter += 1; - - if (pMeta->walScanCounter > 1) { - tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter); - taosWUnLockLatch(&pMeta->lock); - return 0; - } - - SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq)); - if (pRunReq == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - tqError("vgId:%d failed to create msg to start wal scanning to launch stream tasks, code:%s", vgId, terrstr()); - taosWUnLockLatch(&pMeta->lock); - return -1; - } - - tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d", vgId, numOfTasks); - pRunReq->head.vgId = vgId; - pRunReq->streamId = 0; - pRunReq->taskId = WAL_READ_TASKS_ID; - - SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)}; - tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg); - taosWUnLockLatch(&pMeta->lock); - - return 0; -} int32_t tqProcessStreamCheckPointReq(STQ* pTq, int64_t sversion, char* pMsg, int32_t msgLen) { int32_t vgId = TD_VID(pTq->pVnode); SStreamMeta* pMeta = pTq->pStreamMeta; diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 77a966715e..ba983b1833 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -114,7 +114,7 @@ bool isValValidForTable(STqHandle* pHandle, SWalCont* pHead) { } SMetaReader mr = {0}; - metaReaderInit(&mr, pHandle->execHandle.pTqReader->pVnodeMeta, 0); + metaReaderDoInit(&mr, pHandle->execHandle.pTqReader->pVnodeMeta, 0); if (metaGetTableEntryByName(&mr, req.tbName) < 0) { metaReaderClear(&mr); @@ -216,9 +216,9 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea code = 0; goto END; } else { - if (pHandle->fetchMeta) { + if (pHandle->fetchMeta != WITH_DATA) { SWalCont* pHead = &((*ppCkHead)->head); - if (IS_META_MSG(pHead->msgType)) { + if (IS_META_MSG(pHead->msgType) && !(pHead->msgType == TDMT_VND_DELETE && pHandle->fetchMeta == ONLY_META)) { code = walFetchBody(pHandle->pWalReader, ppCkHead); if (code < 0) { *fetchOffset = offset; @@ -388,7 +388,7 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id) { int32_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData); while (pReader->nextBlk < numOfBlocks) { - tqDebug("tq reader next data block %d/%d, len:%d %" PRId64 " %d", pReader->nextBlk, + tqTrace("tq reader next data block %d/%d, len:%d %" PRId64 " %d", pReader->nextBlk, numOfBlocks, pReader->msg.msgLen, pReader->msg.ver, pReader->nextBlk); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk); @@ -403,7 +403,7 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id) { void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t)); if (ret != NULL) { - tqDebug("tq reader return submit block, uid:%" PRId64 ", ver:%" PRId64, pSubmitTbData->uid, pReader->msg.ver); + tqTrace("tq reader return submit block, uid:%" PRId64 ", ver:%" PRId64, pSubmitTbData->uid, pReader->msg.ver); SSDataBlock* pRes = NULL; int32_t code = tqRetrieveDataBlock(pReader, &pRes, NULL); @@ -412,11 +412,11 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id) { } } else { pReader->nextBlk += 1; - tqDebug("tq reader discard submit block, uid:%" PRId64 ", continue", pSubmitTbData->uid); + tqTrace("tq reader discard submit block, uid:%" PRId64 ", continue", pSubmitTbData->uid); } } - qDebug("stream scan return empty, all %d submit blocks consumed, %s", numOfBlocks, id); + qTrace("stream scan return empty, all %d submit blocks consumed, %s", numOfBlocks, id); tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE); pReader->msg.msgStr = NULL; @@ -604,7 +604,7 @@ static int32_t doSetVal(SColumnInfoData* pColumnInfoData, int32_t rowIndex, SCol } int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char* id) { - tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk); + tqTrace("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk++); SSDataBlock* pBlock = pReader->pResBlock; @@ -1109,7 +1109,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { } SStreamTask* pTask = *(SStreamTask**)pIter; - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { int32_t code = qUpdateTableListForStreamScanner(pTask->exec.pExecutor, tbUidList, isAdd); if (code != 0) { tqError("vgId:%d, s-task:%s update qualified table error for stream task", vgId, pTask->id.idStr); diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index fe80f48691..5db3e735cc 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -16,6 +16,7 @@ #include "tq.h" static int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle); +static int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId); // this function should be executed by stream threads. // extract submit block from WAL, and add them into the input queue for the sources tasks. @@ -57,7 +58,111 @@ int32_t tqStreamTasksScanWal(STQ* pTq) { return 0; } -static int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { +int32_t tqStreamTasksStatusCheck(STQ* pTq) { + int32_t vgId = TD_VID(pTq->pVnode); + SStreamMeta* pMeta = pTq->pStreamMeta; + + int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList); + tqDebug("vgId:%d start to check all (%d) stream tasks downstream status", vgId, numOfTasks); + if (numOfTasks == 0) { + return TSDB_CODE_SUCCESS; + } + + SArray* pTaskList = NULL; + taosWLockLatch(&pMeta->lock); + pTaskList = taosArrayDup(pMeta->pTaskList, NULL); + taosWUnLockLatch(&pMeta->lock); + + for (int32_t i = 0; i < numOfTasks; ++i) { + int32_t* pTaskId = taosArrayGet(pTaskList, i); + SStreamTask* pTask = streamMetaAcquireTask(pMeta, *pTaskId); + if (pTask == NULL) { + continue; + } + + streamTaskCheckDownstreamTasks(pTask); + streamMetaReleaseTask(pMeta, pTask); + } + taosArrayDestroy(pTaskList); + + return 0; +} + +int32_t tqCheckStreamStatus(STQ* pTq) { + int32_t vgId = TD_VID(pTq->pVnode); + SStreamMeta* pMeta = pTq->pStreamMeta; + + taosWLockLatch(&pMeta->lock); + + int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList); + if (numOfTasks == 0) { + tqInfo("vgId:%d no stream tasks exist", vgId); + taosWUnLockLatch(&pMeta->lock); + return 0; + } + + SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq)); + if (pRunReq == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + tqError("vgId:%d failed to create msg to start wal scanning to launch stream tasks, code:%s", vgId, terrstr()); + taosWUnLockLatch(&pMeta->lock); + return -1; + } + + tqDebug("vgId:%d check for stream tasks status, numOfTasks:%d", vgId, numOfTasks); + pRunReq->head.vgId = vgId; + pRunReq->streamId = 0; + pRunReq->taskId = STREAM_TASK_STATUS_CHECK_ID; + + SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)}; + tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg); + taosWUnLockLatch(&pMeta->lock); + + return 0; +} + +int32_t tqStartStreamTasks(STQ* pTq) { + int32_t vgId = TD_VID(pTq->pVnode); + SStreamMeta* pMeta = pTq->pStreamMeta; + + taosWLockLatch(&pMeta->lock); + + int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList); + if (numOfTasks == 0) { + tqInfo("vgId:%d no stream tasks exist", vgId); + taosWUnLockLatch(&pMeta->lock); + return 0; + } + + pMeta->walScanCounter += 1; + + if (pMeta->walScanCounter > 1) { + tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter); + taosWUnLockLatch(&pMeta->lock); + return 0; + } + + SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq)); + if (pRunReq == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + tqError("vgId:%d failed to create msg to start wal scanning to launch stream tasks, code:%s", vgId, terrstr()); + taosWUnLockLatch(&pMeta->lock); + return -1; + } + + tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d", vgId, numOfTasks); + pRunReq->head.vgId = vgId; + pRunReq->streamId = 0; + pRunReq->taskId = EXTRACT_DATA_FROM_WAL_ID; + + SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)}; + tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg); + taosWUnLockLatch(&pMeta->lock); + + return 0; +} + +int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { // seek the stored version and extract data from WAL int64_t firstVer = walReaderGetValidFirstVer(pTask->exec.pWalReader); if (pTask->chkInfo.currentVer < firstVer) { @@ -102,7 +207,7 @@ static int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { *pScanIdle = true; - bool noNewDataInWal = true; + bool noDataInWal = true; int32_t vgId = pStreamMeta->vgId; int32_t numOfTasks = taosArrayGetSize(pStreamMeta->pTaskList); @@ -129,15 +234,13 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { } int32_t status = pTask->status.taskStatus; - if (pTask->taskLevel != TASK_LEVEL__SOURCE) { -// tqTrace("s-task:%s level:%d not source task, no need to start", pTask->id.idStr, pTask->taskLevel); + if (pTask->info.taskLevel != TASK_LEVEL__SOURCE) { streamMetaReleaseTask(pStreamMeta, pTask); continue; } - if (streamTaskShouldStop(&pTask->status) || status == TASK_STATUS__RECOVER_PREPARE || - status == TASK_STATUS__WAIT_DOWNSTREAM || streamTaskShouldPause(&pTask->status)) { - tqDebug("s-task:%s not ready for new submit block from wal, status:%d", pTask->id.idStr, status); + if (status != TASK_STATUS__NORMAL) { + tqDebug("s-task:%s not ready for new submit block from wal, status:%s", pTask->id.idStr, streamGetTaskStatusStr(status)); streamMetaReleaseTask(pStreamMeta, pTask); continue; } @@ -157,39 +260,47 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } + int32_t numOfItemsInQ = taosQueueItemSize(pTask->inputQueue->queue); + // append the data for the stream SStreamQueueItem* pItem = NULL; code = extractMsgFromWal(pTask->exec.pWalReader, (void**) &pItem, pTask->id.idStr); - if (code != TSDB_CODE_SUCCESS) { // failed, continue + + if ((code != TSDB_CODE_SUCCESS || pItem == NULL) && (numOfItemsInQ == 0)) { // failed, continue streamMetaReleaseTask(pStreamMeta, pTask); continue; } - // delete ignore - if (pItem == NULL) { - streamMetaReleaseTask(pStreamMeta, pTask); - continue; + if (pItem != NULL) { + noDataInWal = false; + code = tAppendDataToInputQueue(pTask, pItem); + if (code == TSDB_CODE_SUCCESS) { + pTask->chkInfo.currentVer = walReaderGetCurrentVer(pTask->exec.pWalReader); + tqDebug("s-task:%s set the ver:%" PRId64 " from WALReader after extract block from WAL", pTask->id.idStr, + pTask->chkInfo.currentVer); + } else { + tqError("s-task:%s append input queue failed, too many in inputQ, ver:%" PRId64, pTask->id.idStr, + pTask->chkInfo.currentVer); + } } - noNewDataInWal = false; - - code = tqAddInputBlockNLaunchTask(pTask, pItem); - if (code == TSDB_CODE_SUCCESS) { - pTask->chkInfo.currentVer = walReaderGetCurrentVer(pTask->exec.pWalReader); - tqDebug("s-task:%s set the ver:%" PRId64 " from WALReader after extract block from WAL", pTask->id.idStr, - pTask->chkInfo.currentVer); - } else { - tqError("s-task:%s append input queue failed, ver:%" PRId64, pTask->id.idStr, pTask->chkInfo.currentVer); + if ((code == TSDB_CODE_SUCCESS) || (numOfItemsInQ > 0)) { + code = streamSchedExec(pTask); + if (code != TSDB_CODE_SUCCESS) { + streamMetaReleaseTask(pStreamMeta, pTask); + return -1; + } } streamMetaReleaseTask(pStreamMeta, pTask); } // all wal are checked, and no new data available in wal. - if (noNewDataInWal) { + if (noDataInWal) { *pScanIdle = true; } taosArrayDestroy(pTaskList); return 0; } + diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 1ff78c586f..cbe3ffee9e 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -48,7 +48,7 @@ static int32_t tqAddBlockSchemaToRsp(const STqExecHandle* pExec, STaosxRsp* pRsp static int32_t tqAddTbNameToRsp(const STQ* pTq, int64_t uid, STaosxRsp* pRsp, int32_t n) { SMetaReader mr = {0}; - metaReaderInit(&mr, pTq->pVnode->pMeta, 0); + metaReaderDoInit(&mr, pTq->pVnode->pMeta, 0); // TODO add reference to gurantee success if (metaReaderGetTableEntryByUidCache(&mr, uid) < 0) { @@ -215,19 +215,15 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR taosArrayClear(pSchemas); SSubmitTbData* pSubmitTbDataRet = NULL; if (tqRetrieveTaosxBlock(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) { - if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue; + if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) goto loop_table; } if (pRsp->withTbName) { int64_t uid = pExec->pTqReader->lastBlkUid; if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) { - taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); - taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); - pBlocks = taosArrayInit(0, sizeof(SSDataBlock)); - pSchemas = taosArrayInit(0, sizeof(void*)); - continue; + goto loop_table; } } - if (pHandle->fetchMeta && pSubmitTbDataRet->pCreateTbReq != NULL) { + if (pHandle->fetchMeta != WITH_DATA && pSubmitTbDataRet->pCreateTbReq != NULL) { if (pRsp->createTableNum == 0) { pRsp->createTableLen = taosArrayInit(0, sizeof(int32_t)); pRsp->createTableReq = taosArrayInit(0, sizeof(void*)); @@ -237,7 +233,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR uint32_t len = 0; tEncodeSize(tEncodeSVCreateTbReq, pSubmitTbDataRet->pCreateTbReq, len, code); if (TSDB_CODE_SUCCESS != code) { - continue; + goto loop_table; } void* createReq = taosMemoryCalloc(1, len); SEncoder encoder = {0}; @@ -246,7 +242,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR if (code < 0) { tEncoderClear(&encoder); taosMemoryFree(createReq); - continue; + goto loop_table; } taosArrayPush(pRsp->createTableLen, &len); @@ -255,6 +251,9 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR tEncoderClear(&encoder); } + if (pHandle->fetchMeta == ONLY_META && pSubmitTbDataRet->pCreateTbReq == NULL){ + goto loop_table; + } for (int32_t i = 0; i < taosArrayGetSize(pBlocks); i++) { SSDataBlock* pBlock = taosArrayGet(pBlocks, i); tqAddBlockDataToRsp(pBlock, (SMqDataRsp*)pRsp, taosArrayGetSize(pBlock->pDataBlock), @@ -265,6 +264,12 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR taosArrayPush(pRsp->blockSchema, &pSW); pRsp->blockNum++; } + continue; + loop_table: + taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); + taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); + pBlocks = taosArrayInit(0, sizeof(SSDataBlock)); + pSchemas = taosArrayInit(0, sizeof(void*)); } } else if (pExec->subType == TOPIC_SUB_TYPE__DB) { STqReader* pReader = pExec->pTqReader; @@ -274,19 +279,15 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR taosArrayClear(pSchemas); SSubmitTbData* pSubmitTbDataRet = NULL; if (tqRetrieveTaosxBlock(pReader, pBlocks, pSchemas, &pSubmitTbDataRet) < 0) { - if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) continue; + if (terrno == TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND) goto loop_db; } if (pRsp->withTbName) { int64_t uid = pExec->pTqReader->lastBlkUid; if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) { - taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); - taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); - pBlocks = taosArrayInit(0, sizeof(SSDataBlock)); - pSchemas = taosArrayInit(0, sizeof(void*)); - continue; + goto loop_db; } } - if (pHandle->fetchMeta && pSubmitTbDataRet->pCreateTbReq != NULL) { + if (pHandle->fetchMeta != WITH_DATA && pSubmitTbDataRet->pCreateTbReq != NULL) { if (pRsp->createTableNum == 0) { pRsp->createTableLen = taosArrayInit(0, sizeof(int32_t)); pRsp->createTableReq = taosArrayInit(0, sizeof(void*)); @@ -296,7 +297,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR uint32_t len = 0; tEncodeSize(tEncodeSVCreateTbReq, pSubmitTbDataRet->pCreateTbReq, len, code); if (TSDB_CODE_SUCCESS != code) { - continue; + goto loop_db; } void* createReq = taosMemoryCalloc(1, len); SEncoder encoder = {0}; @@ -305,7 +306,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR if (code < 0) { tEncoderClear(&encoder); taosMemoryFree(createReq); - continue; + goto loop_db; } taosArrayPush(pRsp->createTableLen, &len); @@ -314,6 +315,9 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR tEncoderClear(&encoder); } + if (pHandle->fetchMeta == ONLY_META && pSubmitTbDataRet->pCreateTbReq == NULL){ + goto loop_db; + } for (int32_t i = 0; i < taosArrayGetSize(pBlocks); i++) { SSDataBlock* pBlock = taosArrayGet(pBlocks, i); tqAddBlockDataToRsp(pBlock, (SMqDataRsp*)pRsp, taosArrayGetSize(pBlock->pDataBlock), @@ -324,6 +328,12 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR taosArrayPush(pRsp->blockSchema, &pSW); pRsp->blockNum++; } + continue; + loop_db: + taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); + taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); + pBlocks = taosArrayInit(0, sizeof(SSDataBlock)); + pSchemas = taosArrayInit(0, sizeof(void*)); } } taosArrayDestroy(pBlocks); diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index 9349c6eb0d..b22650d249 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -309,7 +309,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d tbData.uid = pTableSinkInfo->uid; } else { SMetaReader mr = {0}; - metaReaderInit(&mr, pVnode->pMeta, 0); + metaReaderDoInit(&mr, pVnode->pMeta, 0); if (metaGetTableEntryByName(&mr, ctbName) < 0) { metaReaderClear(&mr); taosMemoryFree(pTableSinkInfo); @@ -335,6 +335,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d tagArray = taosArrayInit(1, sizeof(STagVal)); if (!tagArray) { tdDestroySVCreateTbReq(pCreateTbReq); + taosMemoryFreeClear(pCreateTbReq); goto _end; } STagVal tagVal = { @@ -350,6 +351,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d tagArray = taosArrayDestroy(tagArray); if (pTag == NULL) { tdDestroySVCreateTbReq(pCreateTbReq); + taosMemoryFreeClear(pCreateTbReq); terrno = TSDB_CODE_OUT_OF_MEMORY; goto _end; } @@ -410,7 +412,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d if (k == 0) { SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex); void* colData = colDataGetData(pColData, j); - tqDebug("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); + tqTrace("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); } if (IS_SET_NULL(pCol)) { SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index a301d82c30..c61d42d44e 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -20,12 +20,6 @@ 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 "-0x%x", streamId, taskId); - return taosStrdup(buf); -} - int32_t tqAddInputBlockNLaunchTask(SStreamTask* pTask, SStreamQueueItem* pQueueItem) { int32_t code = tAppendDataToInputQueue(pTask, pQueueItem); if (code < 0) { @@ -123,28 +117,17 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand } } else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) { walRefLastVer(pTq->pVnode->pWal, pHandle->pRef); - if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) { - SMqDataRsp dataRsp = {0}; - tqInitDataRsp(&dataRsp, pRequest); + SMqDataRsp dataRsp = {0}; + tqInitDataRsp(&dataRsp, pRequest); - tqOffsetResetToLog(&dataRsp.rspOffset, pHandle->pRef->refVer); - 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(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId); - tDeleteMqDataRsp(&dataRsp); + tqOffsetResetToLog(&dataRsp.rspOffset, pHandle->pRef->refVer); + 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(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); + tDeleteMqDataRsp(&dataRsp); - *pBlockReturned = true; - return code; - } else { - STaosxRsp taosxRsp = {0}; - tqInitTaosxRsp(&taosxRsp, pRequest); - tqOffsetResetToLog(&taosxRsp.rspOffset, pHandle->pRef->refVer); - int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); - tDeleteSTaosxRsp(&taosxRsp); - - *pBlockReturned = true; - return code; - } + *pBlockReturned = true; + return code; } else if (reqOffset.type == TMQ_OFFSET__RESET_NONE) { tqError("tmq poll: subkey:%s, no offset committed for consumer:0x%" PRIx64 " in vg %d, subkey %s, reset none failed", @@ -187,7 +170,7 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, } } - code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); end : { char buf[TSDB_OFFSET_LEN] = {0}; @@ -230,7 +213,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, pRequest->consumerId, pHandle->subKey, vgId, taosxRsp.blockNum, taosxRsp.rspOffset.type, taosxRsp.rspOffset.uid, taosxRsp.rspOffset.ts); if (taosxRsp.blockNum > 0) { - code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } else { *offset = taosxRsp.rspOffset; @@ -260,7 +243,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead, pRequest->reqId) < 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } @@ -272,7 +255,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (pHead->msgType != TDMT_VND_SUBMIT) { if (totalRows > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer - 1); - code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } @@ -301,7 +284,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (totalRows >= 4096 || taosxRsp.createTableNum > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); - code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); goto end; } else { fetchVer++; @@ -396,9 +379,9 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* int32_t len = 0; int32_t code = 0; - if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { tEncodeSize(tEncodeMqDataRsp, pRsp, len, code); - } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { + } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { tEncodeSize(tEncodeSTaosxRsp, (STaosxRsp*)pRsp, len, code); } @@ -420,9 +403,9 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* SEncoder encoder = {0}; tEncoderInit(&encoder, abuf, len); - if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { tEncodeMqDataRsp(&encoder, pRsp); - } else if (type == TMQ_MSG_TYPE__TAOSX_RSP) { + } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp); } diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 31b13b8411..cde0e6f1b7 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -1610,7 +1610,7 @@ static tb_uid_t getTableSuidByUid(tb_uid_t uid, STsdb *pTsdb) { tb_uid_t suid = 0; SMetaReader mr = {0}; - metaReaderInit(&mr, pTsdb->pVnode->pMeta, 0); + metaReaderDoInit(&mr, pTsdb->pVnode->pMeta, 0); if (metaReaderGetTableEntryByUidCache(&mr, uid) < 0) { metaReaderClear(&mr); // table not esist return 0; diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c index b440d51883..6376f375ea 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c @@ -562,7 +562,8 @@ static int32_t tsdbCommitFileDataStart(SCommitter *pCommitter) { code = terrno; TSDB_CHECK_CODE(code, lino, _exit); } - tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, did); + code = tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, did); + TSDB_CHECK_CODE(code, lino, _exit); wSet.diskId = did; wSet.nSttF = 1; } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 84dcde06ac..165448fb7b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -248,7 +248,7 @@ static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdb STbData* piMemTbData); static STsdb* getTsdbByRetentions(SVnode* pVnode, TSKEY winSKey, SRetention* retentions, const char* idstr, int8_t* pLevel); -static SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_t level); +static SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, const char* id); static bool hasDataInLastBlock(SLastBlockReader* pLastBlockReader); static int32_t doBuildDataBlock(STsdbReader* pReader); static TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader); @@ -775,7 +775,7 @@ static int32_t tsdbReaderCreate(SVnode* pVnode, SQueryTableDataCond* pCond, void pReader->order = pCond->order; pReader->idStr = (idstr != NULL) ? taosStrdup(idstr) : NULL; - pReader->verRange = getQueryVerRange(pVnode, pCond, level); + pReader->verRange = getQueryVerRange(pVnode, pCond, idstr); pReader->type = pCond->type; pReader->window = updateQueryTimeWindow(pReader->pTsdb, &pCond->twindows); pReader->blockInfoBuf.numPerBucket = 1000; // 1000 tables per bucket @@ -3721,7 +3721,7 @@ static STsdb* getTsdbByRetentions(SVnode* pVnode, TSKEY winSKey, SRetention* ret return VND_TSDB(pVnode); } -SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_t level) { +SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, const char* id) { int64_t startVer = (pCond->startVersion == -1) ? 0 : pCond->startVersion; int64_t endVer = 0; @@ -3732,6 +3732,9 @@ SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_ endVer = (pCond->endVersion > pVnode->state.applied) ? pVnode->state.applied : pCond->endVersion; } + tsdbDebug("queried verRange:%"PRId64"-%"PRId64", revised query verRange:%"PRId64"-%"PRId64", %s", pCond->startVersion, + pCond->endVersion, startVer, endVer, id); + return (SVersionRange){.minVer = startVer, .maxVer = endVer}; } @@ -5452,7 +5455,7 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) { int32_t tsdbGetTableSchema(void* pVnode, int64_t uid, STSchema** pSchema, int64_t* suid) { SMetaReader mr = {0}; - metaReaderInit(&mr, ((SVnode*)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); int32_t code = metaReaderGetTableEntryByUidCache(&mr, uid); if (code != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; @@ -5584,57 +5587,3 @@ void tsdbReaderSetId(STsdbReader* pReader, const char* idstr) { void tsdbReaderSetCloseFlag(STsdbReader* pReader) { pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED; } -/*-------------todo:refactor the implementation of those APIs in this file to seperate the API into two files------*/ -// opt perf, do NOT create so many readers -int64_t tsdbGetLastTimestamp(SVnode* pVnode, void* pTableList, int32_t numOfTables, const char* pIdStr) { - SQueryTableDataCond cond = {.type = TIMEWINDOW_RANGE_CONTAINED, .numOfCols = 1, .order = TSDB_ORDER_DESC, - .startVersion = -1, .endVersion = -1}; - cond.twindows.skey = INT64_MIN; - cond.twindows.ekey = INT64_MAX; - - cond.colList = taosMemoryCalloc(1, sizeof(SColumnInfo)); - cond.pSlotList = taosMemoryMalloc(sizeof(int32_t) * cond.numOfCols); - if (cond.colList == NULL || cond.pSlotList == NULL) { - // todo - } - - cond.colList[0].colId = 1; - cond.colList[0].slotId = 0; - cond.colList[0].type = TSDB_DATA_TYPE_TIMESTAMP; - - cond.pSlotList[0] = 0; - - STableKeyInfo* pTableKeyInfo = pTableList; - STsdbReader* pReader = NULL; - SSDataBlock* pBlock = createDataBlock(); - - SColumnInfoData data = {0}; - data.info = (SColumnInfo) {.type = TSDB_DATA_TYPE_TIMESTAMP, .colId = 1, .bytes = TSDB_KEYSIZE}; - blockDataAppendColInfo(pBlock, &data); - - int64_t key = INT64_MIN; - - for(int32_t i = 0; i < numOfTables; ++i) { - int32_t code = tsdbReaderOpen(pVnode, &cond, &pTableKeyInfo[i], 1, pBlock, (void**)&pReader, pIdStr, false, NULL); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - bool hasData = false; - code = tsdbNextDataBlock(pReader, &hasData); - if (!hasData || code != TSDB_CODE_SUCCESS) { - continue; - } - - SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, 0); - int64_t k = *(int64_t*)pCol->pData; - - if (key < k) { - key = k; - } - - tsdbReaderClose(pReader); - } - - return 0; -} diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index b5ca716701..df2aebe45b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -891,8 +891,10 @@ static int32_t tsdbSnapWriteFileDataStart(STsdbSnapWriter* pWriter, int32_t fid) if (pSet) { diskId = pSet->diskId; } else { - tfsAllocDisk(pTsdb->pVnode->pTfs, 0 /*TODO*/, &diskId); - tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, diskId); + code = tfsAllocDisk(pTsdb->pVnode->pTfs, 0 /*TODO*/, &diskId); + TSDB_CHECK_CODE(code, lino, _exit); + code = tfsMkdirRecurAt(pTsdb->pVnode->pTfs, pTsdb->path, diskId); + TSDB_CHECK_CODE(code, lino, _exit); } SDFileSet wSet = {.diskId = diskId, .fid = fid, diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c index 556ec33526..84671197d8 100644 --- a/source/dnode/vnode/src/tsdb/tsdbUtil.c +++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c @@ -528,25 +528,25 @@ void tsdbFidKeyRange(int32_t fid, int32_t minutes, int8_t precision, TSKEY *minK *maxKey = *minKey + tsTickPerMin[precision] * minutes - 1; } -int32_t tsdbFidLevel(int32_t fid, STsdbKeepCfg *pKeepCfg, int64_t now) { +int32_t tsdbFidLevel(int32_t fid, STsdbKeepCfg *pKeepCfg, int64_t nowSec) { int32_t aFid[3]; TSKEY key; if (pKeepCfg->precision == TSDB_TIME_PRECISION_MILLI) { - now = now * 1000; + nowSec = nowSec * 1000; } else if (pKeepCfg->precision == TSDB_TIME_PRECISION_MICRO) { - now = now * 1000000l; + nowSec = nowSec * 1000000l; } else if (pKeepCfg->precision == TSDB_TIME_PRECISION_NANO) { - now = now * 1000000000l; + nowSec = nowSec * 1000000000l; } else { ASSERT(0); } - key = now - pKeepCfg->keep0 * tsTickPerMin[pKeepCfg->precision]; + key = nowSec - pKeepCfg->keep0 * tsTickPerMin[pKeepCfg->precision]; aFid[0] = tsdbKeyFid(key, pKeepCfg->days, pKeepCfg->precision); - key = now - pKeepCfg->keep1 * tsTickPerMin[pKeepCfg->precision]; + key = nowSec - pKeepCfg->keep1 * tsTickPerMin[pKeepCfg->precision]; aFid[1] = tsdbKeyFid(key, pKeepCfg->days, pKeepCfg->precision); - key = now - pKeepCfg->keep2 * tsTickPerMin[pKeepCfg->precision]; + key = nowSec - pKeepCfg->keep2 * tsTickPerMin[pKeepCfg->precision]; aFid[2] = tsdbKeyFid(key, pKeepCfg->days, pKeepCfg->precision); if (fid >= aFid[0]) { @@ -640,7 +640,7 @@ SColVal *tsdbRowIterNext(STSDBRowIter *pIter) { int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema) { int32_t code = 0; TSDBKEY key = TSDBROW_KEY(pRow); - SColVal * pColVal = &(SColVal){0}; + SColVal *pColVal = &(SColVal){0}; STColumn *pTColumn; int32_t iCol, jCol = 1; @@ -764,7 +764,7 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema) } } -int32_t tsdbRowMergerInit(SRowMerger* pMerger, STSchema *pSchema) { +int32_t tsdbRowMergerInit(SRowMerger *pMerger, STSchema *pSchema) { pMerger->pTSchema = pSchema; pMerger->pArray = taosArrayInit(pSchema->numOfCols, sizeof(SColVal)); if (pMerger->pArray == NULL) { @@ -774,7 +774,7 @@ int32_t tsdbRowMergerInit(SRowMerger* pMerger, STSchema *pSchema) { } } -void tsdbRowMergerClear(SRowMerger* pMerger) { +void tsdbRowMergerClear(SRowMerger *pMerger) { for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) { SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol); if (IS_VAR_DATA_TYPE(pTColVal->type)) { @@ -785,7 +785,7 @@ void tsdbRowMergerClear(SRowMerger* pMerger) { taosArrayClear(pMerger->pArray); } -void tsdbRowMergerCleanup(SRowMerger* pMerger) { +void tsdbRowMergerCleanup(SRowMerger *pMerger) { int32_t numOfCols = taosArrayGetSize(pMerger->pArray); for (int32_t iCol = 1; iCol < numOfCols; iCol++) { SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol); @@ -1041,8 +1041,6 @@ int32_t tsdbBuildDeleteSkyline2(SArray *aDelData, int32_t sidx, int32_t eidx, SA // SBlockData ====================================================== int32_t tBlockDataCreate(SBlockData *pBlockData) { - int32_t code = 0; - pBlockData->suid = 0; pBlockData->uid = 0; pBlockData->nRow = 0; @@ -1051,7 +1049,7 @@ int32_t tBlockDataCreate(SBlockData *pBlockData) { pBlockData->aTSKEY = NULL; pBlockData->nColData = 0; pBlockData->aColData = NULL; - return code; + return 0; } void tBlockDataDestroy(SBlockData *pBlockData) { @@ -1107,8 +1105,8 @@ int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema, int32_t iColumn = 1; STColumn *pTColumn = &pTSchema->columns[iColumn]; for (int32_t iCid = 0; iCid < nCid; iCid++) { - - // aCid array (from taos client catalog) contains columns that does not exist in the pTSchema. the pTSchema is newer + // aCid array (from taos client catalog) contains columns that does not exist in the pTSchema. the pTSchema is + // newer if (pTColumn == NULL) { continue; } @@ -1239,7 +1237,7 @@ int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTS _exit: return code; } -static int32_t tBlockDataUpdateRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema) { +int32_t tBlockDataUpdateRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema) { int32_t code = 0; // version diff --git a/source/dnode/vnode/src/vnd/vnodeInitApi.c b/source/dnode/vnode/src/vnd/vnodeInitApi.c index d2db6368a2..28a88561af 100644 --- a/source/dnode/vnode/src/vnd/vnodeInitApi.c +++ b/source/dnode/vnode/src/vnd/vnodeInitApi.c @@ -203,6 +203,7 @@ void initStateStoreAPI(SStateStore* pStore) { pStore->streamStateCommit = streamStateCommit; pStore->streamStateDestroy = streamStateDestroy; pStore->streamStateDeleteCheckPoint = streamStateDeleteCheckPoint; + pStore->streamStateReloadInfo = streamStateReloadInfo; } void initMetaReaderAPI(SStoreMetaReader* pMetaReader) { diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c index 583df15533..64546bb4a1 100644 --- a/source/dnode/vnode/src/vnd/vnodeOpen.c +++ b/source/dnode/vnode/src/vnd/vnodeOpen.c @@ -144,6 +144,7 @@ int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t sr char tsdbFilePrefix[TSDB_FILENAME_LEN] = {0}; snprintf(tsdbPath, TSDB_FILENAME_LEN, "%s%stsdb", srcPath, TD_DIRSEP); snprintf(tsdbFilePrefix, TSDB_FILENAME_LEN, "tsdb%sv", TD_DIRSEP); + int32_t prefixLen = strlen(tsdbFilePrefix); STfsDir *tsdbDir = tfsOpendir(pTfs, tsdbPath); if (tsdbDir == NULL) return 0; @@ -157,11 +158,11 @@ int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t sr char *tsdbFilePrefixPos = strstr(oldRname, tsdbFilePrefix); if (tsdbFilePrefixPos == NULL) continue; - int32_t tsdbFileVgId = atoi(tsdbFilePrefixPos + 6); + int32_t tsdbFileVgId = atoi(tsdbFilePrefixPos + prefixLen); if (tsdbFileVgId == srcVgId) { - char *tsdbFileSurfixPos = tsdbFilePrefixPos + 6 + vnodeVgroupIdLen(srcVgId); + char *tsdbFileSurfixPos = tsdbFilePrefixPos + prefixLen + vnodeVgroupIdLen(srcVgId); - tsdbFilePrefixPos[6] = 0; + tsdbFilePrefixPos[prefixLen] = 0; snprintf(newRname, TSDB_FILENAME_LEN, "%s%d%s", oldRname, dstVgId, tsdbFileSurfixPos); vInfo("vgId:%d, rename file from %s to %s", dstVgId, tsdbFile->rname, newRname); diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 022fc4c951..c122a98a12 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -62,7 +62,7 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { } // query meta - metaReaderInit(&mer1, pVnode->pMeta, 0); + metaReaderDoInit(&mer1, pVnode->pMeta, 0); if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) { code = terrno; @@ -79,7 +79,7 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { schemaTag = mer1.me.stbEntry.schemaTag; metaRsp.suid = mer1.me.uid; } else if (mer1.me.type == TSDB_CHILD_TABLE) { - metaReaderInit(&mer2, pVnode->pMeta, META_READER_NOLOCK); + metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK); if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit; strcpy(metaRsp.stbName, mer2.me.name); @@ -175,7 +175,7 @@ int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { } // query meta - metaReaderInit(&mer1, pVnode->pMeta, 0); + metaReaderDoInit(&mer1, pVnode->pMeta, 0); if (metaGetTableEntryByName(&mer1, cfgReq.tbName) < 0) { code = terrno; @@ -188,7 +188,7 @@ int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { code = TSDB_CODE_VND_HASH_MISMATCH; goto _exit; } else if (mer1.me.type == TSDB_CHILD_TABLE) { - metaReaderInit(&mer2, pVnode->pMeta, 0); + metaReaderDoInit(&mer2, pVnode->pMeta, 0); if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit; strcpy(cfgRsp.stbName, mer2.me.name); diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 14642d74f3..c08ae12299 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -234,8 +234,10 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int } } - *(int64_t *)(pCoder->data + pCoder->pos) = ctimeMs; - pCoder->pos += sizeof(int64_t); + if (!tDecodeIsEnd(pCoder)) { + *(int64_t *)(pCoder->data + pCoder->pos) = ctimeMs; + pCoder->pos += sizeof(int64_t); + } tEndDecode(pCoder); @@ -400,10 +402,6 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t ver, SRpcMsg if (!syncUtilUserCommit(pMsg->msgType)) goto _exit; - if (pMsg->msgType == TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE || pMsg->msgType == TDMT_STREAM_TASK_CHECK_RSP) { - if (tqCheckLogInWal(pVnode->pTq, ver)) return 0; - } - // skip header pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); len = pMsg->contLen - sizeof(SMsgHead); @@ -499,16 +497,6 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t ver, SRpcMsg goto _err; } } break; - case TDMT_VND_STREAM_RECOVER_BLOCKING_STAGE: { - if (tqProcessTaskRecover2Req(pVnode->pTq, ver, pMsg->pCont, pMsg->contLen) < 0) { - goto _err; - } - } break; - case TDMT_STREAM_TASK_CHECK_RSP: { - if (tqProcessStreamTaskCheckRsp(pVnode->pTq, ver, pReq, len) < 0) { - goto _err; - } - } break; case TDMT_VND_STREAM_CHECK_POINT_SOURCE: { if (tqProcessStreamCheckPointReq(pVnode->pTq, ver, pReq, len) < 0) goto _err; @@ -646,26 +634,49 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { // return tqProcessPollReq(pVnode->pTq, pMsg); case TDMT_VND_TMQ_VG_WALINFO: return tqProcessVgWalInfoReq(pVnode->pTq, pMsg); + default: + vError("unknown msg type:%d in fetch queue", pMsg->msgType); + return TSDB_CODE_APP_ERROR; + } +} + +int32_t vnodeProcessStreamMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { + vTrace("vgId:%d, msg:%p in fetch queue is processing", pVnode->config.vgId, pMsg); + if ((pMsg->msgType == TDMT_SCH_FETCH || pMsg->msgType == TDMT_VND_TABLE_META || pMsg->msgType == TDMT_VND_TABLE_CFG || + pMsg->msgType == TDMT_VND_BATCH_META) && + !syncIsReadyForRead(pVnode->sync)) { + vnodeRedirectRpcMsg(pVnode, pMsg, terrno); + return 0; + } + + switch (pMsg->msgType) { case TDMT_STREAM_TASK_RUN: return tqProcessTaskRunReq(pVnode->pTq, pMsg); case TDMT_STREAM_TASK_DISPATCH: return tqProcessTaskDispatchReq(pVnode->pTq, pMsg, true); - case TDMT_STREAM_TASK_CHECK: - return tqProcessStreamTaskCheckReq(pVnode->pTq, pMsg); case TDMT_STREAM_TASK_DISPATCH_RSP: return tqProcessTaskDispatchRsp(pVnode->pTq, pMsg); + case TDMT_STREAM_TASK_CHECK: + return tqProcessStreamTaskCheckReq(pVnode->pTq, pMsg); + case TDMT_STREAM_TASK_CHECK_RSP: + return tqProcessStreamTaskCheckRsp(pVnode->pTq, 0, pMsg); case TDMT_STREAM_RETRIEVE: return tqProcessTaskRetrieveReq(pVnode->pTq, pMsg); case TDMT_STREAM_RETRIEVE_RSP: return tqProcessTaskRetrieveRsp(pVnode->pTq, pMsg); - case TDMT_VND_STREAM_RECOVER_NONBLOCKING_STAGE: - return tqProcessTaskRecover1Req(pVnode->pTq, pMsg); - case TDMT_STREAM_RECOVER_FINISH: + case TDMT_VND_STREAM_SCAN_HISTORY: + return tqProcessTaskScanHistory(pVnode->pTq, pMsg); + case TDMT_STREAM_TRANSFER_STATE: { + char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); + int32_t len = pMsg->contLen - sizeof(SMsgHead); + return tqProcessTaskTransferStateReq(pVnode->pTq, 0, pReq, len); + } + case TDMT_STREAM_SCAN_HISTORY_FINISH: return tqProcessTaskRecoverFinishReq(pVnode->pTq, pMsg); - case TDMT_STREAM_RECOVER_FINISH_RSP: + case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP: return tqProcessTaskRecoverFinishRsp(pVnode->pTq, pMsg); default: - vError("unknown msg type:%d in fetch queue", pMsg->msgType); + vError("unknown msg type:%d in stream queue", pMsg->msgType); return TSDB_CODE_APP_ERROR; } } @@ -1700,7 +1711,7 @@ static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t ver, void *pRe tDecodeSBatchDeleteReq(&decoder, &deleteReq); SMetaReader mr = {0}; - metaReaderInit(&mr, pVnode->pMeta, META_READER_NOLOCK); + metaReaderDoInit(&mr, pVnode->pMeta, META_READER_NOLOCK); int32_t sz = taosArrayGetSize(deleteReq.deleteReqs); for (int32_t i = 0; i < sz; i++) { diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index a250d7a59b..b95c604f54 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -556,7 +556,7 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) vInfo("vgId:%d, not launch stream tasks, since stream tasks are disabled", pVnode->config.vgId); } else { vInfo("vgId:%d start to launch stream tasks", pVnode->config.vgId); - tqStartStreamTasks(pVnode->pTq); + tqCheckStreamStatus(pVnode->pTq); } } diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index f59653700b..dad20c915c 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -392,7 +392,7 @@ static int32_t setAliveResultIntoDataBlock(int64_t* pConnId, SSDataBlock* pBlock int32_t status = 0; int32_t code = getAliveStatusFromApi(pConnId, dbName, &status); if (code == TSDB_CODE_SUCCESS) { - colDataAppend(pCol1, 0, (const char*)&status, false); + colDataSetVal(pCol1, 0, (const char*)&status, false); } return code; } diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 30911c6061..33c9d845b9 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -75,10 +75,11 @@ typedef struct SResultRowInfo { } SResultRowInfo; typedef struct SColMatchItem { - int32_t colId; - int32_t srcSlotId; - int32_t dstSlotId; - bool needOutput; + int32_t colId; + int32_t srcSlotId; + int32_t dstSlotId; + bool needOutput; + SDataType dataType; } SColMatchItem; typedef struct SColMatchInfo { diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index 5d663df50e..0ba9aae133 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -285,6 +285,8 @@ typedef struct SStreamAggSupporter { int16_t stateKeyType; SDiskbasedBuf* pResultBuf; SStateStore stateStore; + STimeWindow winRange; + SStorageAPI* pSessionAPI; } SStreamAggSupporter; typedef struct SWindowSupporter { @@ -503,6 +505,8 @@ typedef struct SStreamSessionAggOperatorInfo { SArray* pUpdated; SSHashObj* pStUpdated; int64_t dataVersion; + SArray* historyWins; + bool isHistoryOp; } SStreamSessionAggOperatorInfo; typedef struct SStreamStateAggOperatorInfo { @@ -522,6 +526,8 @@ typedef struct SStreamStateAggOperatorInfo { SArray* pUpdated; SSHashObj* pSeUpdated; int64_t dataVersion; + bool isHistoryOp; + SArray* historyWins; } SStreamStateAggOperatorInfo; typedef struct SStreamPartitionOperatorInfo { @@ -678,6 +684,8 @@ void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExpr void doClearBufferedBlocks(SStreamScanInfo* pInfo); uint64_t calcGroupId(char* pData, int32_t len); +void streamOpReleaseState(struct SOperatorInfo* pOperator); +void streamOpReloadState(struct SOperatorInfo* pOperator); #ifdef __cplusplus } diff --git a/source/libs/executor/inc/operator.h b/source/libs/executor/inc/operator.h index 1d2685b8c6..e6c3405d7f 100644 --- a/source/libs/executor/inc/operator.h +++ b/source/libs/executor/inc/operator.h @@ -35,6 +35,7 @@ typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* pOptr); typedef void (*__optr_close_fn_t)(void* param); typedef int32_t (*__optr_explain_fn_t)(struct SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len); typedef int32_t (*__optr_reqBuf_fn_t)(struct SOperatorInfo* pOptr); +typedef void (*__optr_state_fn_t)(struct SOperatorInfo* pOptr); typedef struct SOperatorFpSet { __optr_open_fn_t _openFn; // DO NOT invoke this function directly @@ -45,6 +46,8 @@ typedef struct SOperatorFpSet { __optr_encode_fn_t encodeResultRow; __optr_decode_fn_t decodeResultRow; __optr_explain_fn_t getExplainFn; + __optr_state_fn_t releaseStreamStateFn; + __optr_state_fn_t reloadStreamStateFn; } SOperatorFpSet; enum { @@ -126,13 +129,13 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle); -SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild); +SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle); SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle); SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo); @@ -143,6 +146,7 @@ SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNo SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_reqBuf_fn_t reqBufFn, __optr_explain_fn_t explain); +void setOperatorStreamStateFn(SOperatorInfo* pOperator, __optr_state_fn_t relaseFn, __optr_state_fn_t reloadFn); int32_t optrDummyOpenFn(SOperatorInfo* pOperator); int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num); void setOperatorCompleted(SOperatorInfo* pOperator); diff --git a/source/libs/executor/inc/querytask.h b/source/libs/executor/inc/querytask.h index 6497bd90b4..cdf37bcc6b 100644 --- a/source/libs/executor/inc/querytask.h +++ b/source/libs/executor/inc/querytask.h @@ -62,10 +62,12 @@ typedef struct { SSchemaWrapper* schema; char tbName[TSDB_TABLE_NAME_LEN]; // this is the current scan table: todo refactor int8_t recoverStep; + bool recoverStep1Finished; + bool recoverStep2Finished; int8_t recoverScanFinished; SQueryTableDataCond tableCond; - int64_t fillHistoryVer1; - int64_t fillHistoryVer2; + SVersionRange fillHistoryVer; + STimeWindow fillHistoryWindow; SStreamState* pState; int64_t dataVersion; int64_t checkPointId; diff --git a/source/libs/executor/inc/tsort.h b/source/libs/executor/inc/tsort.h index 78c56c0405..7a0d236a37 100644 --- a/source/libs/executor/inc/tsort.h +++ b/source/libs/executor/inc/tsort.h @@ -64,10 +64,14 @@ typedef int32_t (*_sort_merge_compar_fn_t)(const void* p1, const void* p2, void* /** * * @param type + * @param maxRows keep maxRows at most + * @param maxTupleLength max len of one tuple, for check if heap sort is applicable + * @param sortBufSize sort memory buf size, for check if heap sort is applicable * @return */ SSortHandle* tsortCreateSortHandle(SArray* pOrderInfo, int32_t type, int32_t pageSize, int32_t numOfPages, - SSDataBlock* pBlock, const char* idstr); + SSDataBlock* pBlock, const char* idstr, uint64_t maxRows, uint32_t maxTupleLength, + uint32_t sortBufSize); /** * diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 0928029557..cfea233a1c 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1305,6 +1305,7 @@ int32_t extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod c.colId = pColNode->colId; c.srcSlotId = pColNode->slotId; c.dstSlotId = pNode->slotId; + c.dataType = pColNode->node.resType; taosArrayPush(pList, &c); } } diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 76958d086f..b9dd8b048b 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -92,6 +92,7 @@ static int32_t doSetStreamOpOpen(SOperatorInfo* pOperator, char* id) { qError("join not supported for stream block scan, %s" PRIx64, id); return TSDB_CODE_APP_ERROR; } + pOperator->status = OP_NOT_OPENED; return doSetStreamOpOpen(pOperator->pDownstream[0], id); } @@ -115,6 +116,16 @@ void resetTaskInfo(qTaskInfo_t tinfo) { clearStreamBlock(pTaskInfo->pRoot); } +void qResetStreamInfoTimeWindow(qTaskInfo_t tinfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*) tinfo; + if (pTaskInfo == NULL) { + return; + } + + qDebug("%s set fill history start key:%"PRId64, GET_TASKID(pTaskInfo), INT64_MIN); + pTaskInfo->streamInfo.fillHistoryWindow.skey = INT64_MIN; +} + 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) { @@ -131,10 +142,9 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu return doSetStreamBlock(pOperator->pDownstream[0], input, numOfBlocks, type, id); } else { pOperator->status = OP_NOT_OPENED; - SStreamScanInfo* pInfo = pOperator->info; - qDebug("s-task:%s in this batch, all %d blocks need to be processed and dump results", id, (int32_t)numOfBlocks); + qDebug("s-task:%s in this batch, %d blocks need to be processed", id, (int32_t)numOfBlocks); ASSERT(pInfo->validBlockIndex == 0 && taosArrayGetSize(pInfo->pBlockLists) == 0); if (type == STREAM_INPUT__MERGED_SUBMIT) { @@ -265,6 +275,7 @@ qTaskInfo_t qCreateQueueExecTaskInfo(void* msg, SReadHandle* pReaderHandle, int3 terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } + pTaskInfo->pRoot = createRawScanOperatorInfo(pReaderHandle, pTaskInfo); if (NULL == pTaskInfo->pRoot) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -314,8 +325,8 @@ qTaskInfo_t qCreateStreamExecTaskInfo(void* msg, SReadHandle* readers, int32_t v return NULL; } - struct SSubplan* pPlan = NULL; - int32_t code = qStringToSubplan(msg, &pPlan); + SSubplan* pPlan = NULL; + int32_t code = qStringToSubplan(msg, &pPlan); if (code != TSDB_CODE_SUCCESS) { terrno = code; return NULL; @@ -869,19 +880,41 @@ int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner) { } } -int32_t qStreamSourceRecoverStep1(qTaskInfo_t tinfo, int64_t ver) { +int32_t qStreamSourceScanParamForHistoryScanStep1(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM); - pTaskInfo->streamInfo.fillHistoryVer1 = ver; - pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__PREPARE1; + + SStreamTaskInfo* pStreamInfo = &pTaskInfo->streamInfo; + + pStreamInfo->fillHistoryVer = *pVerRange; + pStreamInfo->fillHistoryWindow = *pWindow; + pStreamInfo->recoverStep = STREAM_RECOVER_STEP__PREPARE1; + pStreamInfo->recoverStep1Finished = false; + pStreamInfo->recoverStep2Finished = false; + + qDebug("%s step 1. set param for stream scanner for scan history data, verRange:%" PRId64 " - %" PRId64 ", window:%" PRId64 + " - %" PRId64, + GET_TASKID(pTaskInfo), pStreamInfo->fillHistoryVer.minVer, pStreamInfo->fillHistoryVer.maxVer, pWindow->skey, + pWindow->ekey); return 0; } -int32_t qStreamSourceRecoverStep2(qTaskInfo_t tinfo, int64_t ver) { +int32_t qStreamSourceScanParamForHistoryScanStep2(qTaskInfo_t tinfo, SVersionRange *pVerRange, STimeWindow* pWindow) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM); - pTaskInfo->streamInfo.fillHistoryVer2 = ver; - pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__PREPARE2; + + SStreamTaskInfo* pStreamInfo = &pTaskInfo->streamInfo; + + pStreamInfo->fillHistoryVer = *pVerRange; + pStreamInfo->fillHistoryWindow = *pWindow; + pStreamInfo->recoverStep = STREAM_RECOVER_STEP__PREPARE2; + pStreamInfo->recoverStep1Finished = true; + pStreamInfo->recoverStep2Finished = false; + + qDebug("%s step 2. set param for stream scanner for scan history data, verRange:%" PRId64 " - %" PRId64 ", window:%" PRId64 + " - %" PRId64, + GET_TASKID(pTaskInfo), pStreamInfo->fillHistoryVer.minVer, pStreamInfo->fillHistoryVer.maxVer, pWindow->skey, + pWindow->ekey); return 0; } @@ -892,55 +925,58 @@ int32_t qStreamRecoverFinish(qTaskInfo_t tinfo) { return 0; } -int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo) { +int32_t qSetStreamOperatorOptionForScanHistory(qTaskInfo_t tinfo) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; SOperatorInfo* pOperator = pTaskInfo->pRoot; while (1) { - if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL || - pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL || - pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { + int32_t type = pOperator->operatorType; + if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL || type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL || + type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { SStreamIntervalOperatorInfo* pInfo = pOperator->info; - ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE || - pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); - ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0); + STimeWindowAggSupp* pSup = &pInfo->twAggSup; - qInfo("save stream param for interval: %d, %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark); + ASSERT(pSup->calTrigger == STREAM_TRIGGER_AT_ONCE || pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); + ASSERT(pSup->calTriggerSaved == 0 && pSup->deleteMarkSaved == 0); - pInfo->twAggSup.calTriggerSaved = pInfo->twAggSup.calTrigger; - pInfo->twAggSup.deleteMarkSaved = pInfo->twAggSup.deleteMark; - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - pInfo->twAggSup.deleteMark = INT64_MAX; + qInfo("save stream param for interval: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark); + + pSup->calTriggerSaved = pSup->calTrigger; + pSup->deleteMarkSaved = pSup->deleteMark; + pSup->calTrigger = STREAM_TRIGGER_AT_ONCE; + pSup->deleteMark = INT64_MAX; pInfo->ignoreExpiredDataSaved = pInfo->ignoreExpiredData; pInfo->ignoreExpiredData = false; - } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION || - pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION || - pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { + } else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION || + type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION || + type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE || - pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); + STimeWindowAggSupp* pSup = &pInfo->twAggSup; - ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0); - qInfo("save stream param for session: %d, %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark); + ASSERT(pSup->calTrigger == STREAM_TRIGGER_AT_ONCE || pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); + ASSERT(pSup->calTriggerSaved == 0 && pSup->deleteMarkSaved == 0); - pInfo->twAggSup.calTriggerSaved = pInfo->twAggSup.calTrigger; - pInfo->twAggSup.deleteMarkSaved = pInfo->twAggSup.deleteMark; - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - pInfo->twAggSup.deleteMark = INT64_MAX; + qInfo("save stream param for session: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark); + + pSup->calTriggerSaved = pSup->calTrigger; + pSup->deleteMarkSaved = pSup->deleteMark; + pSup->calTrigger = STREAM_TRIGGER_AT_ONCE; + pSup->deleteMark = INT64_MAX; pInfo->ignoreExpiredDataSaved = pInfo->ignoreExpiredData; pInfo->ignoreExpiredData = false; - } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE) { + } else if (type == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE) { SStreamStateAggOperatorInfo* pInfo = pOperator->info; - ASSERT(pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE || - pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); - ASSERT(pInfo->twAggSup.calTriggerSaved == 0 && pInfo->twAggSup.deleteMarkSaved == 0); + STimeWindowAggSupp* pSup = &pInfo->twAggSup; - qInfo("save stream param for state: %d, %" PRId64, pInfo->twAggSup.calTrigger, pInfo->twAggSup.deleteMark); + ASSERT(pSup->calTrigger == STREAM_TRIGGER_AT_ONCE || pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE); + ASSERT(pSup->calTriggerSaved == 0 && pSup->deleteMarkSaved == 0); - pInfo->twAggSup.calTriggerSaved = pInfo->twAggSup.calTrigger; - pInfo->twAggSup.deleteMarkSaved = pInfo->twAggSup.deleteMark; - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - pInfo->twAggSup.deleteMark = INT64_MAX; + qInfo("save stream param for state: %d, %" PRId64, pSup->calTrigger, pSup->deleteMark); + + pSup->calTriggerSaved = pSup->calTrigger; + pSup->deleteMarkSaved = pSup->deleteMark; + pSup->calTrigger = STREAM_TRIGGER_AT_ONCE; + pSup->deleteMark = INT64_MAX; pInfo->ignoreExpiredDataSaved = pInfo->ignoreExpiredData; pInfo->ignoreExpiredData = false; } @@ -961,7 +997,7 @@ int32_t qStreamSetParamForRecover(qTaskInfo_t tinfo) { return 0; } -int32_t qStreamRestoreParam(qTaskInfo_t tinfo) { +int32_t qRestoreStreamOperatorOption(qTaskInfo_t tinfo) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; SOperatorInfo* pOperator = pTaskInfo->pRoot; @@ -1009,6 +1045,26 @@ bool qStreamRecoverScanFinished(qTaskInfo_t tinfo) { return pTaskInfo->streamInfo.recoverScanFinished; } +bool qStreamRecoverScanStep1Finished(qTaskInfo_t tinfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; + return pTaskInfo->streamInfo.recoverStep1Finished; +} + +bool qStreamRecoverScanStep2Finished(qTaskInfo_t tinfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; + return pTaskInfo->streamInfo.recoverStep2Finished; +} + +int32_t qStreamRecoverSetAllStepFinished(qTaskInfo_t tinfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; + pTaskInfo->streamInfo.recoverStep1Finished = true; + pTaskInfo->streamInfo.recoverStep2Finished = true; + + // reset the time window + pTaskInfo->streamInfo.fillHistoryWindow.skey = INT64_MIN; + return 0; +} + void* qExtractReaderFromStreamScanner(void* scanner) { SStreamScanInfo* pInfo = scanner; return (void*)pInfo->tqReader; @@ -1078,6 +1134,16 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT SOperatorInfo* pOperator = pTaskInfo->pRoot; const char* id = GET_TASKID(pTaskInfo); + if(subType == TOPIC_SUB_TYPE__COLUMN && pOffset->type == TMQ_OFFSET__LOG){ + pOperator = extractOperatorInTree(pOperator, QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN, id); + if (pOperator == NULL) { + return -1; + } + SStreamScanInfo* pInfo = pOperator->info; + SStoreTqReader* pReaderAPI = &pTaskInfo->storageAPI.tqReaderFn; + SWalReader* pWalReader = pReaderAPI->tqReaderGetWalReader(pInfo->tqReader); + walReaderVerifyOffset(pWalReader, pOffset); + } // if pOffset equal to current offset, means continue consume if (tOffsetEqual(pOffset, &pTaskInfo->streamInfo.currentOffset)) { return 0; @@ -1314,4 +1380,16 @@ SArray* getTableListInfo(const SExecTaskInfo* pTaskInfo) { SOperatorInfo* pOperator = pTaskInfo->pRoot; extractTableList(pArray, pOperator); return pArray; -} \ No newline at end of file +} + +int32_t qStreamOperatorReleaseState(qTaskInfo_t tInfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*) tInfo; + pTaskInfo->pRoot->fpSet.releaseStreamStateFn(pTaskInfo->pRoot); + return 0; +} + +int32_t qStreamOperatorReloadState(qTaskInfo_t tInfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*) tInfo; + pTaskInfo->pRoot->fpSet.reloadStreamStateFn(pTaskInfo->pRoot); + return 0; +} diff --git a/source/libs/executor/src/executorInt.c b/source/libs/executor/src/executorInt.c index 42b8a9d31c..eb55ab5e08 100644 --- a/source/libs/executor/src/executorInt.c +++ b/source/libs/executor/src/executorInt.c @@ -540,140 +540,12 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SColumnInfoD } int8_t* pIndicator = (int8_t*)p->pData; - int32_t totalRows = pBlock->info.rows; - if (status == FILTER_RESULT_ALL_QUALIFIED) { // here nothing needs to be done } else if (status == FILTER_RESULT_NONE_QUALIFIED) { pBlock->info.rows = 0; } else { - int32_t bmLen = BitmapLen(totalRows); - char* pBitmap = NULL; - int32_t maxRows = 0; - - size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); - for (int32_t i = 0; i < numOfCols; ++i) { - SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i); - // it is a reserved column for scalar function, and no data in this column yet. - if (pDst->pData == NULL) { - continue; - } - - int32_t numOfRows = 0; - if (IS_VAR_DATA_TYPE(pDst->info.type)) { - int32_t j = 0; - - while (j < totalRows) { - if (pIndicator[j] == 0) { - j += 1; - continue; - } - - if (colDataIsNull_var(pDst, j)) { - colDataSetNull_var(pDst, numOfRows); - } else { - char* p1 = colDataGetVarData(pDst, j); - colDataReassignVal(pDst, numOfRows, j, p1); - } - numOfRows += 1; - j += 1; - } - - if (maxRows < numOfRows) { - maxRows = numOfRows; - } - } else { - if (pBitmap == NULL) { - pBitmap = taosMemoryCalloc(1, bmLen); - } - - memcpy(pBitmap, pDst->nullbitmap, bmLen); - memset(pDst->nullbitmap, 0, bmLen); - - int32_t j = 0; - - switch (pDst->info.type) { - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_UBIGINT: - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_TIMESTAMP: - while (j < totalRows) { - if (pIndicator[j] == 0) { - j += 1; - continue; - } - - if (colDataIsNull_f(pBitmap, j)) { - colDataSetNull_f(pDst->nullbitmap, numOfRows); - } else { - ((int64_t*)pDst->pData)[numOfRows] = ((int64_t*)pDst->pData)[j]; - } - numOfRows += 1; - j += 1; - } - break; - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_UINT: - while (j < totalRows) { - if (pIndicator[j] == 0) { - j += 1; - continue; - } - if (colDataIsNull_f(pBitmap, j)) { - colDataSetNull_f(pDst->nullbitmap, numOfRows); - } else { - ((int32_t*)pDst->pData)[numOfRows] = ((int32_t*)pDst->pData)[j]; - } - numOfRows += 1; - j += 1; - } - break; - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_USMALLINT: - while (j < totalRows) { - if (pIndicator[j] == 0) { - j += 1; - continue; - } - if (colDataIsNull_f(pBitmap, j)) { - colDataSetNull_f(pDst->nullbitmap, numOfRows); - } else { - ((int16_t*)pDst->pData)[numOfRows] = ((int16_t*)pDst->pData)[j]; - } - numOfRows += 1; - j += 1; - } - break; - case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_UTINYINT: - while (j < totalRows) { - if (pIndicator[j] == 0) { - j += 1; - continue; - } - if (colDataIsNull_f(pBitmap, j)) { - colDataSetNull_f(pDst->nullbitmap, numOfRows); - } else { - ((int8_t*)pDst->pData)[numOfRows] = ((int8_t*)pDst->pData)[j]; - } - numOfRows += 1; - j += 1; - } - break; - } - } - - if (maxRows < numOfRows) { - maxRows = numOfRows; - } - } - - pBlock->info.rows = maxRows; - if (pBitmap != NULL) { - taosMemoryFree(pBitmap); - } + trimDataBlock(pBlock, pBlock->info.rows, (bool*) pIndicator); } } @@ -1105,9 +977,11 @@ int32_t buildSessionResultDataBlock(SOperatorInfo* pOperator, void* pState, SSDa int32_t size = 0; void* pVal = NULL; int32_t code = pAPI->stateStore.streamStateSessionGet(pState, pKey, &pVal, &size); - ASSERT(code == 0); + // ASSERT(code == 0); if (code == -1) { - // coverity scan + // for history + qWarn("===stream===not found session result key:%" PRId64 ", ekey:%" PRId64 ", groupId:%" PRIu64, pKey->win.skey, + pKey->win.ekey, pKey->groupId); pGroupResInfo->index += 1; continue; } @@ -1177,40 +1051,16 @@ int32_t buildSessionResultDataBlock(SOperatorInfo* pOperator, void* pState, SSDa return TSDB_CODE_SUCCESS; } -void qStreamCloseTsdbReader(void* task) { - if (task == NULL) { - return; - } - - SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)task; - SOperatorInfo* pOp = pTaskInfo->pRoot; - - qDebug("stream close tsdb reader, reset status uid:%" PRId64 " ts:%" PRId64, pTaskInfo->streamInfo.currentOffset.uid, - pTaskInfo->streamInfo.currentOffset.ts); - - // todo refactor, other thread may already use this read to extract data. - pTaskInfo->streamInfo.currentOffset = (STqOffsetVal){0}; - while (pOp->numOfDownstream == 1 && pOp->pDownstream[0]) { - SOperatorInfo* pDownstreamOp = pOp->pDownstream[0]; - if (pDownstreamOp->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { - SStreamScanInfo* pInfo = pDownstreamOp->info; - if (pInfo->pTableScanOp) { - STableScanInfo* pTSInfo = pInfo->pTableScanOp->info; - - setOperatorCompleted(pInfo->pTableScanOp); - while (pTaskInfo->owner != 0) { - taosMsleep(100); - qDebug("wait for the reader stopping"); - } - - pTaskInfo->storageAPI.tsdReader.tsdReaderClose(pTSInfo->base.dataReader); - pTSInfo->base.dataReader = NULL; - - // restore the status, todo refactor. - pInfo->pTableScanOp->status = OP_OPENED; - pTaskInfo->status = TASK_NOT_COMPLETED; - return; - } - } +void streamOpReleaseState(SOperatorInfo* pOperator) { + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); } } + +void streamOpReloadState(SOperatorInfo* pOperator) { + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c index 92152924f9..7798ded61b 100644 --- a/source/libs/executor/src/filloperator.c +++ b/source/libs/executor/src/filloperator.c @@ -1562,6 +1562,7 @@ SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFi pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamFill, NULL, destroyStreamFillOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamOpReleaseState, streamOpReloadState); code = appendDownstream(pOperator, &downstream, 1); if (code != TSDB_CODE_SUCCESS) { diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 57c22d56d3..9228c923a6 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -1036,7 +1036,7 @@ void appendCreateTableRow(void* pState, SExprSupp* pTableSup, SExprSupp* pTagSup } void* pGpIdCol = taosArrayGet(pDestBlock->pDataBlock, UD_GROUPID_COLUMN_INDEX); - colDataAppend(pGpIdCol, pDestBlock->info.rows, (const char*)&groupId, false); + colDataSetVal(pGpIdCol, pDestBlock->info.rows, (const char*)&groupId, false); pDestBlock->info.rows++; blockDataDestroy(pTmpBlock); } else { @@ -1324,6 +1324,7 @@ SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStr pOperator->exprSupp.pExprInfo = pExprInfo; pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamHashPartition, NULL, destroyStreamPartitionOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamOpReleaseState, streamOpReloadState); initParDownStream(downstream, &pInfo->partitionSup, &pInfo->scalarSup); code = appendDownstream(pOperator, &downstream, 1); diff --git a/source/libs/executor/src/operator.c b/source/libs/executor/src/operator.c index 730252c7ee..2db5ea2f1e 100644 --- a/source/libs/executor/src/operator.c +++ b/source/libs/executor/src/operator.c @@ -38,11 +38,18 @@ SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, .closeFn = closeFn, .reqBufFn = reqBufFn, .getExplainFn = explain, + .releaseStreamStateFn = NULL, + .reloadStreamStateFn = NULL, }; return fpSet; } +void setOperatorStreamStateFn(SOperatorInfo* pOperator, __optr_state_fn_t relaseFn, __optr_state_fn_t reloadFn) { + pOperator->fpSet.releaseStreamStateFn = relaseFn; + pOperator->fpSet.reloadStreamStateFn = reloadFn; +} + int32_t optrDummyOpenFn(SOperatorInfo* pOperator) { OPTR_SET_OPENED(pOperator); pOperator->cost.openCost = 0; @@ -485,13 +492,13 @@ SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SR SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; pOptr = createSessionAggOperatorInfo(ops[0], pSessionNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION == type) { - pOptr = createStreamSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo); + pOptr = createStreamSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION == type) { int32_t children = 0; - pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children); + pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children, pHandle); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION == type) { int32_t children = pHandle->numOfVgroups; - pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children); + pOptr = createStreamFinalSessionAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, children, pHandle); } else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) { pOptr = createPartitionOperatorInfo(ops[0], (SPartitionPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION == type) { @@ -500,7 +507,7 @@ SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SR SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode; pOptr = createStatewindowOperatorInfo(ops[0], pStateNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE == type) { - pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo); + pOptr = createStreamStateAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle); } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN == type) { pOptr = createMergeJoinOperatorInfo(ops, size, (SSortMergeJoinPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) { diff --git a/source/libs/executor/src/projectoperator.c b/source/libs/executor/src/projectoperator.c index cd450c5bb7..412a4bfbc0 100644 --- a/source/libs/executor/src/projectoperator.c +++ b/source/libs/executor/src/projectoperator.c @@ -73,6 +73,20 @@ static void destroyIndefinitOperatorInfo(void* param) { taosMemoryFreeClear(param); } +void streamOperatorReleaseState(SOperatorInfo* pOperator) { + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void streamOperatorReloadState(SOperatorInfo* pOperator) { + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode, SExecTaskInfo* pTaskInfo) { int32_t code = TSDB_CODE_SUCCESS; @@ -136,6 +150,7 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhys pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doProjectOperation, NULL, destroyProjectOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamOperatorReleaseState, streamOperatorReloadState); code = appendDownstream(pOperator, &downstream, 1); if (code != TSDB_CODE_SUCCESS) { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 008a3697fc..74210ee06e 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -44,6 +44,7 @@ int32_t scanDebug = 0; #define SET_REVERSE_SCAN_FLAG(_info) ((_info)->scanFlag = REVERSE_SCAN) #define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC)) #define STREAM_SCAN_OP_NAME "StreamScanOperator" +#define STREAM_SCAN_OP_STATE_NAME "StreamScanFillHistoryState" typedef struct STableMergeScanExecInfo { SFileBlockLoadRecorder blockRecorder; @@ -489,12 +490,12 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int } int32_t code = 0; + bool freeReader = false; // backup the rows int32_t backupRows = pBlock->info.rows; pBlock->info.rows = rows; - bool freeReader = false; STableCachedVal val = {0}; SMetaReader mr = {0}; @@ -1558,13 +1559,13 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows); - pInfo->pRes->info.rows = pBlock->info.rows; - pInfo->pRes->info.id.uid = pBlock->info.id.uid; - pInfo->pRes->info.type = STREAM_NORMAL; - pInfo->pRes->info.version = pBlock->info.version; + pBlockInfo->rows = pBlock->info.rows; + pBlockInfo->id.uid = pBlock->info.id.uid; + pBlockInfo->type = STREAM_NORMAL; + pBlockInfo->version = pBlock->info.version; STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; - pInfo->pRes->info.id.groupId = getTableGroupId(pTableScanInfo->base.pTableListInfo, pBlock->info.id.uid); + pBlockInfo->id.groupId = getTableGroupId(pTableScanInfo->base.pTableListInfo, pBlock->info.id.uid); // todo extract method for (int32_t i = 0; i < taosArrayGetSize(pInfo->matchInfo.pList); ++i) { @@ -1594,7 +1595,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), &pTableScanInfo->base.metaCache); + pBlockInfo->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); @@ -1611,7 +1612,6 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock pInfo->pRes->info.dataLoad = 1; blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex); -// blockDataFreeRes((SSDataBlock*)pBlock); calBlockTbName(pInfo, pInfo->pRes); return 0; @@ -1769,7 +1769,7 @@ void streamScanOperatorDecode(void* pBuff, int32_t len, SStreamScanInfo* pInfo) return; } - void* pUpInfo = pInfo->stateStore.updateInfoInit(0, TSDB_TIME_PRECISION_MILLI, 0); + void* pUpInfo = taosMemoryCalloc(1, sizeof(SUpdateInfo)); int32_t code = pInfo->stateStore.updateInfoDeserialize(pBuff, len, pUpInfo); if (code == TSDB_CODE_SUCCESS) { pInfo->pUpdateInfo = pUpInfo; @@ -1783,25 +1783,28 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { SStorageAPI* pAPI = &pTaskInfo->storageAPI; SStreamScanInfo* pInfo = pOperator->info; + SStreamTaskInfo* pStreamInfo = &pTaskInfo->streamInfo; - qDebug("stream scan started, %s", GET_TASKID(pTaskInfo)); + qDebug("stream scan started, %s", id); - if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE1 || - pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE2) { + if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__PREPARE1 || pStreamInfo->recoverStep == STREAM_RECOVER_STEP__PREPARE2) { STableScanInfo* pTSInfo = pInfo->pTableScanOp->info; - memcpy(&pTSInfo->base.cond, &pTaskInfo->streamInfo.tableCond, sizeof(SQueryTableDataCond)); - if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__PREPARE1) { - pTSInfo->base.cond.startVersion = 0; - pTSInfo->base.cond.endVersion = pTaskInfo->streamInfo.fillHistoryVer1; - qDebug("stream recover step1, verRange:%" PRId64 " - %" PRId64, pTSInfo->base.cond.startVersion, - pTSInfo->base.cond.endVersion); - pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__SCAN1; + memcpy(&pTSInfo->base.cond, &pStreamInfo->tableCond, sizeof(SQueryTableDataCond)); + + if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__PREPARE1) { + pTSInfo->base.cond.startVersion = pStreamInfo->fillHistoryVer.minVer; + pTSInfo->base.cond.endVersion = pStreamInfo->fillHistoryVer.maxVer; + + pTSInfo->base.cond.twindows = pStreamInfo->fillHistoryWindow; + qDebug("stream recover step1, verRange:%" PRId64 "-%" PRId64 " window:%"PRId64"-%"PRId64", %s", pTSInfo->base.cond.startVersion, + pTSInfo->base.cond.endVersion, pTSInfo->base.cond.twindows.skey, pTSInfo->base.cond.twindows.ekey, id); + pStreamInfo->recoverStep = STREAM_RECOVER_STEP__SCAN1; } else { - pTSInfo->base.cond.startVersion = pTaskInfo->streamInfo.fillHistoryVer1 + 1; - pTSInfo->base.cond.endVersion = pTaskInfo->streamInfo.fillHistoryVer2; - qDebug("stream recover step2, verRange:%" PRId64 " - %" PRId64, pTSInfo->base.cond.startVersion, - pTSInfo->base.cond.endVersion); - pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__SCAN2; + pTSInfo->base.cond.startVersion = pStreamInfo->fillHistoryVer.minVer; + pTSInfo->base.cond.endVersion = pStreamInfo->fillHistoryVer.maxVer; + qDebug("stream recover step2, verRange:%" PRId64 " - %" PRId64", %s", pTSInfo->base.cond.startVersion, + pTSInfo->base.cond.endVersion, id); + pStreamInfo->recoverStep = STREAM_RECOVER_STEP__SCAN2; } pAPI->tsdReader.tsdReaderClose(pTSInfo->base.dataReader); @@ -1811,11 +1814,11 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { pTSInfo->scanTimes = 0; pTSInfo->currentGroupId = -1; - pTaskInfo->streamInfo.recoverScanFinished = false; + pStreamInfo->recoverScanFinished = false; } - if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN1 || - pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN2) { + if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__SCAN1 || + pStreamInfo->recoverStep == STREAM_RECOVER_STEP__SCAN2) { if (pInfo->blockRecoverContiCnt > 100) { pInfo->blockRecoverTotCnt += pInfo->blockRecoverContiCnt; pInfo->blockRecoverContiCnt = 0; @@ -1866,11 +1869,11 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { pInfo->blockRecoverContiCnt++; calBlockTbName(pInfo, pInfo->pRecoverRes); if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) { - if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN1) { + if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__SCAN1) { TSKEY maxTs = pAPI->stateStore.updateInfoFillBlockData(pInfo->pUpdateInfo, pInfo->pRecoverRes, pInfo->primaryTsIndex); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); } else { - pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pTaskInfo->streamInfo.fillHistoryVer2); + pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pStreamInfo->fillHistoryVer.maxVer); doCheckUpdate(pInfo, pInfo->pRecoverRes->info.window.ekey, pInfo->pRecoverRes); } } @@ -1884,7 +1887,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { printDataBlock(pInfo->pRecoverRes, "scan recover"); return pInfo->pRecoverRes; } - pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__NONE; + pStreamInfo->recoverStep = STREAM_RECOVER_STEP__NONE; STableScanInfo* pTSInfo = pInfo->pTableScanOp->info; pAPI->tsdReader.tsdReaderClose(pTSInfo->base.dataReader); @@ -1893,7 +1896,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { pTSInfo->base.cond.startVersion = -1; pTSInfo->base.cond.endVersion = -1; - pTaskInfo->streamInfo.recoverScanFinished = true; + pStreamInfo->recoverScanFinished = true; return NULL; } @@ -1912,7 +1915,7 @@ FETCH_NEXT_BLOCK: SPackedData* pPacked = taosArrayGet(pInfo->pBlockLists, current); SSDataBlock* pBlock = pPacked->pDataBlock; if (pBlock->info.parTbName[0]) { - pAPI->stateStore.streamStatePutParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, pBlock->info.parTbName); + pAPI->stateStore.streamStatePutParName(pStreamInfo->pState, pBlock->info.id.groupId, pBlock->info.parTbName); } // TODO move into scan @@ -2092,11 +2095,39 @@ FETCH_NEXT_BLOCK: doCheckUpdate(pInfo, pBlockInfo->window.ekey, pBlock); doFilter(pBlock, pOperator->exprSupp.pFilterInfo, NULL); + + { // do additional time window filter + STimeWindow* pWindow = &pStreamInfo->fillHistoryWindow; + + if (pWindow->skey != INT64_MIN) { + qDebug("%s filter for additional history window, skey:%"PRId64, id, pWindow->skey); + + bool* p = taosMemoryCalloc(pBlock->info.rows, sizeof(bool)); + bool hasUnqualified = false; + + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex); + for(int32_t i = 0; i < pBlock->info.rows; ++i) { + int64_t* ts = (int64_t*) colDataGetData(pCol, i); + p[i] = (*ts >= pWindow->skey); + + if (!p[i]) { + hasUnqualified = true; + } + } + + if (hasUnqualified) { + trimDataBlock(pBlock, pBlock->info.rows, p); + } + + taosMemoryFree(p); + } + } + pBlock->info.dataLoad = 1; blockDataUpdateTsWindow(pBlock, pInfo->primaryTsIndex); - qDebug("%" PRId64 " rows in datablock, update res:%" PRId64 " %s", pBlockInfo->rows, - pInfo->pUpdateDataRes->info.rows, id); + qDebug("%s %" PRId64 " rows in datablock, update res:%" PRId64, id, pBlockInfo->rows, + pInfo->pUpdateDataRes->info.rows); if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) { break; } @@ -2154,7 +2185,7 @@ static SSDataBlock* doRawScan(SOperatorInfo* pOperator) { qDebug("tmqsnap doRawScan called"); if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_DATA) { bool hasNext = false; - if (pInfo->dataReader) { + if (pInfo->dataReader && pInfo->sContext->withMeta != ONLY_META) { code = pAPI->tsdReader.tsdNextDataBlock(pInfo->dataReader, &hasNext); if (code) { pAPI->tsdReader.tsdReaderReleaseDataBlock(pInfo->dataReader); @@ -2180,7 +2211,7 @@ static SSDataBlock* doRawScan(SOperatorInfo* pOperator) { SMetaTableInfo mtInfo = pAPI->snapshotFn.getMetaTableInfoFromSnapshot(pInfo->sContext); STqOffsetVal offset = {0}; - if (mtInfo.uid == 0) { // read snapshot done, change to get data from wal + if (mtInfo.uid == 0 || pInfo->sContext->withMeta == ONLY_META) { // read snapshot done, change to get data from wal qDebug("tmqsnap read snapshot done, change to get data from wal"); tqOffsetResetToLog(&offset, pInfo->sContext->snapVersion); } else { @@ -2294,6 +2325,57 @@ static void destroyStreamScanOperatorInfo(void* param) { taosMemoryFree(pStreamScan); } +void streamScanReleaseState(SOperatorInfo* pOperator) { + SStreamScanInfo* pInfo = pOperator->info; + if (!pInfo->pState) { + return; + } + if (!pInfo->pUpdateInfo) { + return; + } + int32_t len = pInfo->stateStore.updateInfoSerialize(NULL, 0, pInfo->pUpdateInfo); + void* pBuff = taosMemoryCalloc(1, len); + pInfo->stateStore.updateInfoSerialize(pBuff, len, pInfo->pUpdateInfo); + pInfo->stateStore.streamStateSaveInfo(pInfo->pState, STREAM_SCAN_OP_STATE_NAME, strlen(STREAM_SCAN_OP_STATE_NAME), pBuff, len); + taosMemoryFree(pBuff); +} + +void streamScanReloadState(SOperatorInfo* pOperator) { + SStreamScanInfo* pInfo = pOperator->info; + if (!pInfo->pState) { + return; + } + void* pBuff = NULL; + int32_t len = 0; + pInfo->stateStore.streamStateGetInfo(pInfo->pState, STREAM_SCAN_OP_STATE_NAME, strlen(STREAM_SCAN_OP_STATE_NAME), &pBuff, &len); + SUpdateInfo* pUpInfo = taosMemoryCalloc(1, sizeof(SUpdateInfo)); + int32_t code = pInfo->stateStore.updateInfoDeserialize(pBuff, len, pUpInfo); + taosMemoryFree(pBuff); + if (code == TSDB_CODE_SUCCESS && pInfo->pUpdateInfo) { + if (pInfo->pUpdateInfo->minTS < 0) { + pInfo->stateStore.updateInfoDestroy(pInfo->pUpdateInfo); + pInfo->pUpdateInfo = pUpInfo; + } else { + pInfo->pUpdateInfo->minTS = TMAX(pInfo->pUpdateInfo->minTS, pUpInfo->minTS); + pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pUpInfo->maxDataVersion); + SHashObj* curMap = pInfo->pUpdateInfo->pMap; + void *pIte = taosHashIterate(curMap, NULL); + while (pIte != NULL) { + size_t keySize = 0; + int64_t* pUid = taosHashGetKey(pIte, &keySize); + taosHashPut(pUpInfo->pMap, pUid, sizeof(int64_t), pIte, sizeof(TSKEY)); + pIte = taosHashIterate(curMap, pIte); + } + taosHashCleanup(curMap); + pInfo->pUpdateInfo->pMap = pUpInfo->pMap; + pUpInfo->pMap = NULL; + pInfo->stateStore.updateInfoDestroy(pUpInfo); + } + } else { + pInfo->stateStore.updateInfoDestroy(pUpInfo); + } +} + SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SNode* pTagCond, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo) { SArray* pColIds = NULL; @@ -2374,6 +2456,10 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys if (pHandle->vnode) { SOperatorInfo* pTableScanOp = createTableScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo); + if (pTableScanOp == NULL) { + qError("createTableScanOperatorInfo error, errorcode: %d", pTaskInfo->code); + goto _error; + } STableScanInfo* pTSInfo = (STableScanInfo*)pTableScanOp->info; if (pHandle->version > 0) { pTSInfo->base.cond.endVersion = pHandle->version; @@ -2471,6 +2557,7 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys __optr_fn_t nextFn = (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) ? doStreamScan : doQueueScan; pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, nextFn, NULL, destroyStreamScanOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamScanReleaseState, streamScanReloadState); return pOperator; @@ -2801,7 +2888,7 @@ int32_t startGroupTableMergeScan(SOperatorInfo* pOperator) { pInfo->sortBufSize = pInfo->bufPageSize * (kWay + 1); int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize; pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage, - pInfo->pSortInputBlock, pTaskInfo->id.str); + pInfo->pSortInputBlock, pTaskInfo->id.str, 0, 0, 0); tsortSetFetchRawDataFp(pInfo->pSortHandle, getTableDataBlockImpl, NULL, NULL); diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index 585c2e8c54..20fb588a02 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -29,6 +29,8 @@ typedef struct SSortOperatorInfo { int64_t startTs; // sort start time uint64_t sortElapsed; // sort elapsed time, time to flush to disk not included. SLimitInfo limitInfo; + uint64_t maxTupleLength; + int64_t maxRows; } SSortOperatorInfo; static SSDataBlock* doSort(SOperatorInfo* pOperator); @@ -36,6 +38,7 @@ static int32_t doOpenSortOperator(SOperatorInfo* pOperator); static int32_t getExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len); static void destroySortOperatorInfo(void* param); +static int32_t calcSortOperMaxTupleLength(SSortOperatorInfo* pSortOperInfo, SNodeList* pSortKeys); // todo add limit/offset impl SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortNode, SExecTaskInfo* pTaskInfo) { @@ -51,6 +54,8 @@ SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* int32_t numOfCols = 0; pOperator->exprSupp.pExprInfo = createExprInfo(pSortNode->pExprs, NULL, &numOfCols); pOperator->exprSupp.numOfExprs = numOfCols; + calcSortOperMaxTupleLength(pInfo, pSortNode->pSortKeys); + pInfo->maxRows = pSortNode->maxRows; int32_t numOfOutputCols = 0; int32_t code = @@ -193,9 +198,9 @@ int32_t doOpenSortOperator(SOperatorInfo* pOperator) { } pInfo->startTs = taosGetTimestampUs(); - // pInfo->binfo.pRes is not equalled to the input datablock. - pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, -1, -1, NULL, pTaskInfo->id.str); + pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, -1, -1, NULL, pTaskInfo->id.str, + pInfo->maxRows, pInfo->maxTupleLength, tsPQSortMemThreshold * 1024 * 1024); tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, applyScalarFunction, pOperator); @@ -286,6 +291,20 @@ int32_t getExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* return TSDB_CODE_SUCCESS; } +static int32_t calcSortOperMaxTupleLength(SSortOperatorInfo* pSortOperInfo, SNodeList* pSortKeys) { + SColMatchInfo* pColItem = &pSortOperInfo->matchInfo; + size_t size = taosArrayGetSize(pColItem->pList); + for (size_t i = 0; i < size; ++i) { + pSortOperInfo->maxTupleLength += ((SColMatchItem*)taosArrayGet(pColItem->pList, i))->dataType.bytes; + } + size = LIST_LENGTH(pSortKeys); + for (size_t i = 0; i < size; ++i) { + SOrderByExprNode* pOrderExprNode = (SOrderByExprNode*)nodesListGetNode(pSortKeys, i); + pSortOperInfo->maxTupleLength += ((SColumnNode*)pOrderExprNode->pExpr)->node.resType.bytes; + } + return TSDB_CODE_SUCCESS; +} + //===================================================================================== // Group Sort Operator typedef enum EChildOperatorStatus { CHILD_OP_NEW_GROUP, CHILD_OP_SAME_GROUP, CHILD_OP_FINISHED } EChildOperatorStatus; @@ -384,7 +403,7 @@ int32_t beginSortGroup(SOperatorInfo* pOperator) { // pInfo->binfo.pRes is not equalled to the input datablock. pInfo->pCurrSortHandle = - tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, -1, -1, NULL, pTaskInfo->id.str); + tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, -1, -1, NULL, pTaskInfo->id.str, 0, 0, 0); tsortSetFetchRawDataFp(pInfo->pCurrSortHandle, fetchNextGroupSortDataBlock, applyScalarFunction, pOperator); @@ -582,7 +601,7 @@ int32_t openMultiwayMergeOperator(SOperatorInfo* pOperator) { int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize; pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage, - pInfo->pInputBlock, pTaskInfo->id.str); + pInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0); tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL); tsortSetCompareGroupId(pInfo->pSortHandle, pInfo->groupSort); diff --git a/source/libs/executor/src/sysscanoperator.c b/source/libs/executor/src/sysscanoperator.c index 70fe42595e..a1f83dda2f 100644 --- a/source/libs/executor/src/sysscanoperator.c +++ b/source/libs/executor/src/sysscanoperator.c @@ -966,20 +966,20 @@ static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, // table name pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0); - colDataAppend(pColInfoData, numOfRows, tName, false); + colDataSetVal(pColInfoData, numOfRows, tName, false); // database name pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1); - colDataAppend(pColInfoData, numOfRows, dbname, false); + colDataSetVal(pColInfoData, numOfRows, dbname, false); pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2); - colDataAppend(pColInfoData, numOfRows, tableType, false); + colDataSetVal(pColInfoData, numOfRows, tableType, false); // col name char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0}; STR_TO_VARSTR(colName, schemaRow->pSchema[i].name); pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3); - colDataAppend(pColInfoData, numOfRows, colName, false); + colDataSetVal(pColInfoData, numOfRows, colName, false); // col type int8_t colType = schemaRow->pSchema[i].type; @@ -994,10 +994,10 @@ static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, (int32_t)((schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } varDataSetLen(colTypeStr, colTypeLen); - colDataAppend(pColInfoData, numOfRows, (char*)colTypeStr, false); + colDataSetVal(pColInfoData, numOfRows, (char*)colTypeStr, false); pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5); - colDataAppend(pColInfoData, numOfRows, (const char*)&schemaRow->pSchema[i].bytes, false); + colDataSetVal(pColInfoData, numOfRows, (const char*)&schemaRow->pSchema[i].bytes, false); for (int32_t j = 6; j <= 8; ++j) { pColInfoData = taosArrayGet(dataBlock->pDataBlock, j); diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index 022440b2ad..7c009c942a 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -272,7 +272,7 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp continue; } else if (isIsfilledPseudoColumn(pExprInfo)) { bool isFilled = true; - colDataAppend(pDst, pResBlock->info.rows, (char*)&isFilled, false); + colDataSetVal(pDst, pResBlock->info.rows, (char*)&isFilled, false); continue; } else if (!isInterpFunc(pExprInfo)) { if (isGroupKeyFunc(pExprInfo)) { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 78d1e97554..c4111ded92 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -28,6 +28,9 @@ #define IS_FINAL_OP(op) ((op)->isFinal) #define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); +#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" +#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" +#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" typedef struct SStateWindowInfo { SResultWindowInfo winInfo; @@ -2726,6 +2729,38 @@ int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { return size; } +void streamIntervalReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t resSize = sizeof(TSKEY); + pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); + } + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + pAPI->stateStore.streamStateCommit(pInfo->pState); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void streamIntervalReloadState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, + strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); + TSKEY ts = *(TSKEY*)pBuf; + taosMemoryFree(pBuf); + pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild) { SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; @@ -2823,7 +2858,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pInfo->pUpdatedMap = NULL; int32_t funResSize= getMaxFunResSize(&pOperator->exprSupp, numOfCols); pInfo->pState->pFileState = pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, - compareTs, pInfo->pState, pInfo->twAggSup.deleteMark); + compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); pInfo->dataVersion = 0; pInfo->statestore = pTaskInfo->storageAPI.stateStore; pInfo->recvGetAll = false; @@ -2835,6 +2870,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pOperator->fpSet = createOperatorFpSet(NULL, doStreamFinalIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { initIntervalDownStream(downstream, pPhyNode->type, pInfo); } @@ -2873,12 +2909,14 @@ void destroyStreamSessionAggOperatorInfo(void* param) { } taosArrayDestroy(pInfo->pChildren); } + colDataDestroy(&pInfo->twAggSup.timeWindowData); blockDataDestroy(pInfo->pDelRes); blockDataDestroy(pInfo->pWinBlock); blockDataDestroy(pInfo->pUpdateRes); tSimpleHashCleanup(pInfo->pStDeleted); + taosArrayDestroy(pInfo->historyWins); taosMemoryFreeClear(param); } @@ -2928,7 +2966,7 @@ void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uin } int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, - SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore) { + SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, SReadHandle* pHandle, SStorageAPI* pApi) { pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); pSup->gap = gap; @@ -2970,6 +3008,16 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, pCtx[i].saveHandle.pBuf = pSup->pResultBuf; } + if (pHandle) { + pSup->winRange = pHandle->winRange; + // temporary + if (pSup->winRange.ekey <= 0) { + pSup->winRange.ekey = INT64_MAX; + } + } + + pSup->pSessionAPI = pApi; + return TSDB_CODE_SUCCESS; } @@ -2997,6 +3045,13 @@ void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endT bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; } +bool inWinRange(STimeWindow* range, STimeWindow* cur) { + if (cur->skey >= range->skey && cur->ekey <= range->ekey) { + return true; + } + return false; +} + void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, SResultWindowInfo* pCurWin) { pCurWin->sessionWin.groupId = groupId; @@ -3005,6 +3060,12 @@ void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endT int32_t size = pAggSup->resultRowSize; int32_t code = pAggSup->stateStore.streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, pAggSup->gap, &pCurWin->pOutputBuf, &size); + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->pOutputBuf, &pAggSup->pSessionAPI->stateStore); + pCurWin->pOutputBuf = taosMemoryMalloc(size); + } + if (code == TSDB_CODE_SUCCESS) { pCurWin->isOutput = true; } else { @@ -3151,7 +3212,8 @@ static void compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pC while (1) { SResultWindowInfo winInfo = {0}; SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo); - if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap)) { + if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap) || + !inWinRange(&pAggSup->winRange, &winInfo.sessionWin.win)) { taosMemoryFree(winInfo.pOutputBuf); pAPI->stateStore.streamStateFreeCur(pCur); break; @@ -3375,8 +3437,12 @@ static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SS SResultWindowInfo childWin = {0}; childWin.sessionWin = *pWinKey; int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin); - if (code == TSDB_CODE_SUCCESS && pWinKey->win.skey <= childWin.sessionWin.win.skey && - childWin.sessionWin.win.ekey <= pWinKey->win.ekey) { + + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &childWin.sessionWin.win)) { + continue; + } + + if (code == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { if (num == 0) { setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin); code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); @@ -3475,6 +3541,29 @@ void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* // clear the existed group id pBlock->info.id.groupId = 0; buildSessionResultDataBlock(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); + if (pBlock->info.rows == 0) { + cleanupGroupResInfo(pGroupResInfo); + } +} +void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { + int32_t size = taosArrayGetSize(pAllWins); + if (size == 0) { + return; + } + + SSessionKey* pSeKey = taosArrayGet(pAllWins, size - 1); + taosArrayPush(pMaxWins, pSeKey); + if (pSeKey->groupId == 0) { + return; + } + uint64_t preGpId = pSeKey->groupId; + for (int32_t i = size - 2; i >= 0; i--) { + pSeKey = taosArrayGet(pAllWins, i); + if (preGpId != pSeKey->groupId) { + taosArrayPush(pMaxWins, pSeKey); + preGpId = pSeKey->groupId; + } + } } static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { @@ -3554,7 +3643,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { // if chIndex + 1 - size > 0, add new child for (int32_t i = 0; i < chIndex + 1 - size; i++) { SOperatorInfo* pChildOp = - createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0); + createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL); if (!pChildOp) { T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); } @@ -3576,6 +3665,9 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); tSimpleHashCleanup(pInfo->pStUpdated); pInfo->pStUpdated = NULL; + if(pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); pInfo->pUpdated = NULL; blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); @@ -3602,8 +3694,51 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { return NULL; } +void streamSessionReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void resetWinRange(STimeWindow* winRange) { + winRange->skey = INT16_MIN; + winRange->skey = INT16_MAX; +} + +void streamSessionReloadState(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SResultWindowInfo winInfo = {0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + for (int32_t i = 0; i < num; i++) { + SResultWindowInfo winInfo = {0}; + setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); + compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted); + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo) { + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; int32_t numOfCols = 0; int32_t code = TSDB_CODE_OUT_OF_MEMORY; @@ -3634,7 +3769,7 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh } code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, - pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore); + pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -3666,11 +3801,19 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh pInfo->pUpdated = NULL; pInfo->pStUpdated = NULL; pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } setOperatorInfo(pOperator, "StreamSessionWindowAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); if (downstream) { initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); @@ -3778,7 +3921,6 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); tSimpleHashCleanup(pInfo->pStUpdated); pInfo->pStUpdated = NULL; - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); pInfo->pUpdated = NULL; blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); @@ -3809,9 +3951,9 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { } SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild) { + SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle) { int32_t code = TSDB_CODE_OUT_OF_MEMORY; - SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo); + SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); if (pOperator == NULL) { goto _error; } @@ -3828,14 +3970,14 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); } - + setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->operatorType = pPhyNode->type; if (numOfChild > 0) { pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); for (int32_t i = 0; i < numOfChild; i++) { - SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0); + SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0, NULL); if (pChildOp == NULL) { goto _error; } @@ -3876,6 +4018,7 @@ void destroyStreamStateOperatorInfo(void* param) { } colDataDestroy(&pInfo->twAggSup.timeWindowData); blockDataDestroy(pInfo->pDelRes); + taosArrayDestroy(pInfo->historyWins); tSimpleHashCleanup(pInfo->pSeDeleted); taosMemoryFreeClear(param); } @@ -3892,6 +4035,9 @@ bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) { } bool compareStateKey(void* data, void* key) { + if (!data || !key) { + return true; + } SStateKeys* stateKey = (SStateKeys*)key; stateKey->pData = (char*)key + sizeof(SStateKeys); return compareVal(data, stateKey); @@ -3913,9 +4059,15 @@ void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); pCurWin->pStateKey->isNull = false; + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); + pCurWin->winInfo.pOutputBuf = taosMemoryMalloc(size); + } + if (code == TSDB_CODE_SUCCESS) { pCurWin->winInfo.isOutput = true; - } else { + } else if (pKeyData) { if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) { varDataCopy(pCurWin->pStateKey->pData, pKeyData); } else { @@ -4113,6 +4265,10 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { tSimpleHashCleanup(pInfo->pSeUpdated); pInfo->pSeUpdated = NULL; + if(pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); pInfo->pUpdated = NULL; blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); @@ -4138,8 +4294,73 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { return NULL; } +void streamStateReleaseState(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, resSize); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, + SSHashObj* pStUpdated, SSHashObj* pStDeleted) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + SResultRow* pWinResult = NULL; + initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); + + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, true); + compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); + if (pNextWin->isOutput && pStDeleted) { + saveDeleteRes(pStDeleted, pNextWin->sessionWin); + } + removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); + doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin); + taosMemoryFree(pNextWin->pOutputBuf); + saveSessionOutputBuf(pAggSup, pCurWin); +} + +void streamStateReloadState(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + for (int32_t i = 0; i < num; i++) { + SStateWindowInfo curInfo = {0}; + SStateWindowInfo nextInfo = {0}; + setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); + if (compareStateKey(curInfo.pStateKey,nextInfo.pStateKey)) { + compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pStUpdated, pInfo->pStDeleted); + } + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo) { + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { SStreamStateWinodwPhysiNode* pStateNode = (SStreamStateWinodwPhysiNode*)pPhyNode; int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pStateNode->pStateKey)->pExpr; @@ -4183,7 +4404,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes; int16_t type = pColNode->node.resType.type; code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize, - type, &pTaskInfo->storageAPI.stateStore); + type, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -4199,11 +4420,19 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->pUpdated = NULL; pInfo->pSeUpdated = NULL; pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamStateAgg, NULL, destroyStreamStateOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamStateReleaseState, streamStateReloadState); initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); code = appendDownstream(pOperator, &downstream, 1); if (code != TSDB_CODE_SUCCESS) { @@ -5021,13 +5250,16 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->pUpdated = NULL; pInfo->pUpdatedMap = NULL; int32_t funResSize= getMaxFunResSize(pSup, numOfCols); - pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, - compareTs, pInfo->pState, pInfo->twAggSup.deleteMark); + + pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( + tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, + pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); setOperatorInfo(pOperator, "StreamIntervalOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, true, OP_NOT_OPENED, pInfo, pTaskInfo); pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); pInfo->statestore = pTaskInfo->storageAPI.stateStore; pInfo->recvGetAll = false; diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 58b3428b5b..c0be5f99c1 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -19,6 +19,7 @@ #include "tcompare.h" #include "tdatablock.h" #include "tdef.h" +#include "theap.h" #include "tlosertree.h" #include "tpagedbuf.h" #include "tsort.h" @@ -41,6 +42,12 @@ struct SSortHandle { int64_t startTs; uint64_t totalElapsed; + uint64_t maxRows; + uint32_t maxTupleLength; + uint32_t sortBufSize; + BoundedQueue* pBoundedQueue; + uint32_t tmpRowIdx; + int32_t sourceId; SSDataBlock* pDataBlock; SMsortComparParam cmpParam; @@ -61,6 +68,47 @@ struct SSortHandle { static int32_t msortComparFn(const void* pLeft, const void* pRight, void* param); +// | offset[0] | offset[1] |....| nullbitmap | data |...| +static void* createTuple(uint32_t columnNum, uint32_t tupleLen) { + uint32_t totalLen = sizeof(uint32_t) * columnNum + BitmapLen(columnNum) + tupleLen; + return taosMemoryCalloc(1, totalLen); +} +static void destoryTuple(void* t) { taosMemoryFree(t); } + +#define tupleOffset(tuple, colIdx) ((uint32_t*)(tuple + sizeof(uint32_t) * colIdx)) +#define tupleSetOffset(tuple, colIdx, offset) (*tupleOffset(tuple, colIdx) = offset) +#define tupleSetNull(tuple, colIdx, colNum) colDataSetNull_f((char*)tuple + sizeof(uint32_t) * colNum, colIdx) +#define tupleColIsNull(tuple, colIdx, colNum) colDataIsNull_f((char*)tuple + sizeof(uint32_t) * colNum, colIdx) +#define tupleGetDataStartOffset(colNum) (sizeof(uint32_t) * colNum + BitmapLen(colNum)) +#define tupleSetData(tuple, offset, data, length) memcpy(tuple + offset, data, length) + +/** + * @param t the tuple pointer addr, if realloced, *t is changed to the new addr + * @param offset copy data into pTuple start from offset + * @param colIndex the columnIndex, for setting null bitmap + * @return the next offset to add field + * */ +static inline size_t tupleAddField(char** t, uint32_t colNum, uint32_t offset, uint32_t colIdx, void* data, size_t length, + bool isNull, uint32_t tupleLen) { + tupleSetOffset(*t, colIdx, offset); + if (isNull) { + tupleSetNull(*t, colIdx, colNum); + } else { + if (offset + length > tupleLen + tupleGetDataStartOffset(colNum)) { + *t = taosMemoryRealloc(*t, offset + length); + } + tupleSetData(*t, offset, data, length); + } + return offset + length; +} + +static void* tupleGetField(char* t, uint32_t colIdx, uint32_t colNum) { + if (tupleColIsNull(t, colIdx, colNum)) return NULL; + return t + *tupleOffset(t, colIdx); +} + +static int32_t colDataComparFn(const void* pLeft, const void* pRight, void* param); + SSDataBlock* tsortGetSortedDataBlock(const SSortHandle* pSortHandle) { return createOneDataBlock(pSortHandle->pDataBlock, false); } @@ -71,7 +119,8 @@ SSDataBlock* tsortGetSortedDataBlock(const SSortHandle* pSortHandle) { * @return */ SSortHandle* tsortCreateSortHandle(SArray* pSortInfo, int32_t type, int32_t pageSize, int32_t numOfPages, - SSDataBlock* pBlock, const char* idstr) { + SSDataBlock* pBlock, const char* idstr, uint64_t maxRows, uint32_t maxTupleLength, + uint32_t sortBufSize) { SSortHandle* pSortHandle = taosMemoryCalloc(1, sizeof(SSortHandle)); pSortHandle->type = type; @@ -80,6 +129,13 @@ SSortHandle* tsortCreateSortHandle(SArray* pSortInfo, int32_t type, int32_t page pSortHandle->pSortInfo = pSortInfo; pSortHandle->loops = 0; + pSortHandle->maxTupleLength = maxTupleLength; + if (maxRows < 0) + pSortHandle->sortBufSize = 0; + else + pSortHandle->sortBufSize = sortBufSize; + pSortHandle->maxRows = maxRows; + if (pBlock != NULL) { pSortHandle->pDataBlock = createOneDataBlock(pBlock, false); } @@ -150,7 +206,6 @@ void tsortDestroySortHandle(SSortHandle* pSortHandle) { if (pSortHandle == NULL) { return; } - tsortClose(pSortHandle); if (pSortHandle->pMergeTree != NULL) { tMergeTreeDestroy(&pSortHandle->pMergeTree); @@ -159,6 +214,7 @@ void tsortDestroySortHandle(SSortHandle* pSortHandle) { destroyDiskbasedBuf(pSortHandle->pBuf); taosMemoryFreeClear(pSortHandle->idStr); blockDataDestroy(pSortHandle->pDataBlock); + if (pSortHandle->pBoundedQueue) destroyBoundedQueue(pSortHandle->pBoundedQueue); int64_t fetchUs = 0, fetchNum = 0; tsortClearOrderdSource(pSortHandle->pOrderedSource, &fetchUs, &fetchNum); @@ -769,17 +825,7 @@ static int32_t createInitialSources(SSortHandle* pHandle) { return code; } -int32_t tsortOpen(SSortHandle* pHandle) { - if (pHandle->opened) { - return 0; - } - - if (pHandle->fetchfp == NULL || pHandle->comparFn == NULL) { - return -1; - } - - pHandle->opened = true; - +static bool tsortOpenForBufMergeSort(SSortHandle* pHandle) { int32_t code = createInitialSources(pHandle); if (code != TSDB_CODE_SUCCESS) { return code; @@ -840,7 +886,7 @@ int32_t tsortSetCompareGroupId(SSortHandle* pHandle, bool compareGroupId) { return TSDB_CODE_SUCCESS; } -STupleHandle* tsortNextTuple(SSortHandle* pHandle) { +static STupleHandle* tsortBufMergeSortNextTuple(SSortHandle* pHandle) { if (tsortIsClosed(pHandle)) { return NULL; } @@ -890,6 +936,168 @@ STupleHandle* tsortNextTuple(SSortHandle* pHandle) { return &pHandle->tupleHandle; } +static bool tsortIsPQSortApplicable(SSortHandle* pHandle) { + if (pHandle->type != SORT_SINGLESOURCE_SORT) return false; + uint64_t maxRowsFitInMemory = pHandle->sortBufSize / (pHandle->maxTupleLength + sizeof(char*)); + return maxRowsFitInMemory > pHandle->maxRows; +} + +static bool tsortPQCompFn(void* a, void* b, void* param) { + SSortHandle* pHandle = param; + int32_t res = pHandle->comparFn(a, b, param); + if (res < 0) return 1; + return 0; +} + +static bool tsortPQComFnReverse(void*a, void* b, void* param) { + SSortHandle* pHandle = param; + int32_t res = pHandle->comparFn(a, b, param); + if (res > 0) return 1; + return 0; +} + +static int32_t colDataComparFn(const void* pLeft, const void* pRight, void* param) { + char* pLTuple = (char*)pLeft; + char* pRTuple = (char*)pRight; + SSortHandle* pHandle = (SSortHandle*)param; + SArray* orderInfo = (SArray*)pHandle->pSortInfo; + uint32_t colNum = blockDataGetNumOfCols(pHandle->pDataBlock); + for (int32_t i = 0; i < orderInfo->size; ++i) { + SBlockOrderInfo* pOrder = TARRAY_GET_ELEM(orderInfo, i); + void *lData = tupleGetField(pLTuple, pOrder->slotId, colNum); + void *rData = tupleGetField(pRTuple, pOrder->slotId, colNum); + if (!lData && !rData) continue; + if (!lData) return pOrder->nullFirst ? -1 : 1; + if (!rData) return pOrder->nullFirst ? 1 : -1; + + int type = ((SColumnInfoData*)taosArrayGet(pHandle->pDataBlock->pDataBlock, pOrder->slotId))->info.type; + __compar_fn_t fn = getKeyComparFunc(type, pOrder->order); + + int ret = fn(lData, rData); + if (ret == 0) { + continue; + } else { + return ret; + } + } + return 0; +} + +static int32_t tsortOpenForPQSort(SSortHandle* pHandle) { + pHandle->pBoundedQueue = createBoundedQueue(pHandle->maxRows, tsortPQCompFn, destoryTuple, pHandle); + if (NULL == pHandle->pBoundedQueue) return TSDB_CODE_OUT_OF_MEMORY; + tsortSetComparFp(pHandle, colDataComparFn); + + SSortSource** pSource = taosArrayGet(pHandle->pOrderedSource, 0); + SSortSource* source = *pSource; + + pHandle->pDataBlock = NULL; + uint32_t tupleLen = 0; + PriorityQueueNode pqNode; + while (1) { + // fetch data + SSDataBlock* pBlock = pHandle->fetchfp(source->param); + if (NULL == pBlock) break; + + if (pHandle->beforeFp != NULL) { + pHandle->beforeFp(pBlock, pHandle->param); + } + if (pHandle->pDataBlock == NULL) { + pHandle->pDataBlock = createOneDataBlock(pBlock, false); + } + if (pHandle->pDataBlock == NULL) return TSDB_CODE_OUT_OF_MEMORY; + + size_t colNum = blockDataGetNumOfCols(pBlock); + + if (tupleLen == 0) { + for (size_t colIdx = 0; colIdx < colNum; ++colIdx) { + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, colIdx); + tupleLen += pCol->info.bytes; + if (IS_VAR_DATA_TYPE(pCol->info.type)) { + tupleLen += sizeof(VarDataLenT); + } + } + } + size_t colLen = 0; + for (size_t rowIdx = 0; rowIdx < pBlock->info.rows; ++rowIdx) { + void* pTuple = createTuple(colNum, tupleLen); + if (pTuple == NULL) return TSDB_CODE_OUT_OF_MEMORY; + + uint32_t offset = tupleGetDataStartOffset(colNum); + for (size_t colIdx = 0; colIdx < colNum; ++colIdx) { + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, colIdx); + if (colDataIsNull_s(pCol, rowIdx)) { + offset = tupleAddField((char**)&pTuple, colNum, offset, colIdx, 0, 0, true, tupleLen); + } else { + colLen = colDataGetRowLength(pCol, rowIdx); + offset = tupleAddField((char**)&pTuple, colNum, offset, colIdx, colDataGetData(pCol, rowIdx), colLen, false, + tupleLen); + } + } + pqNode.data = pTuple; + taosBQPush(pHandle->pBoundedQueue, &pqNode); + } + } + return TSDB_CODE_SUCCESS; +} + +static STupleHandle* tsortPQSortNextTuple(SSortHandle* pHandle) { + blockDataCleanup(pHandle->pDataBlock); + blockDataEnsureCapacity(pHandle->pDataBlock, 1); + // abondan the top tuple if queue size bigger than max size + if (taosBQSize(pHandle->pBoundedQueue) == taosBQMaxSize(pHandle->pBoundedQueue) + 1) { + taosBQPop(pHandle->pBoundedQueue); + } + if (pHandle->tmpRowIdx == 0) { + // sort the results + taosBQSetFn(pHandle->pBoundedQueue, tsortPQComFnReverse); + taosBQBuildHeap(pHandle->pBoundedQueue); + } + if (taosBQSize(pHandle->pBoundedQueue) > 0) { + uint32_t colNum = blockDataGetNumOfCols(pHandle->pDataBlock); + PriorityQueueNode* node = taosBQTop(pHandle->pBoundedQueue); + char* pTuple = (char*)node->data; + + for (uint32_t i = 0; i < colNum; ++i) { + void* pData = tupleGetField(pTuple, i, colNum); + if (!pData) { + colDataSetNULL(bdGetColumnInfoData(pHandle->pDataBlock, i), 0); + } else { + colDataSetVal(bdGetColumnInfoData(pHandle->pDataBlock, i), 0, pData, false); + } + } + pHandle->pDataBlock->info.rows++; + pHandle->tmpRowIdx++; + taosBQPop(pHandle->pBoundedQueue); + } + if (pHandle->pDataBlock->info.rows == 0) return NULL; + pHandle->tupleHandle.pBlock = pHandle->pDataBlock; + return &pHandle->tupleHandle; +} + +int32_t tsortOpen(SSortHandle* pHandle) { + if (pHandle->opened) { + return 0; + } + + if (pHandle->fetchfp == NULL || pHandle->comparFn == NULL) { + return -1; + } + + pHandle->opened = true; + if (tsortIsPQSortApplicable(pHandle)) + return tsortOpenForPQSort(pHandle); + else + return tsortOpenForBufMergeSort(pHandle); +} + +STupleHandle* tsortNextTuple(SSortHandle* pHandle) { + if (pHandle->pBoundedQueue) + return tsortPQSortNextTuple(pHandle); + else + return tsortBufMergeSortNextTuple(pHandle); +} + bool tsortIsNullVal(STupleHandle* pVHandle, int32_t colIndex) { SColumnInfoData* pColInfoSrc = taosArrayGet(pVHandle->pBlock->pDataBlock, colIndex); return colDataIsNull_s(pColInfoSrc, pVHandle->rowIndex); diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 4365cd8b95..21b36d69ec 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -1712,7 +1712,7 @@ int32_t percentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); varDataSetLen(buf, len); - colDataAppend(pCol, pBlock->info.rows, buf, false); + colDataSetVal(pCol, pBlock->info.rows, buf, false); tMemBucketDestroy(pMemBucket); return pResInfo->numOfRes; @@ -2415,6 +2415,10 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) { } static int32_t firstLastTransferInfoImpl(SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) { + if (!pInput->hasResult) { + return TSDB_CODE_FAILED; + } + if (pOutput->hasResult) { if (isFirst) { if (pInput->ts > pOutput->ts) { diff --git a/source/libs/function/src/thistogram.c b/source/libs/function/src/thistogram.c index e7d631f638..b56691f35d 100644 --- a/source/libs/function/src/thistogram.c +++ b/source/libs/function/src/thistogram.c @@ -474,8 +474,8 @@ double* tHistogramUniform(SHistogramInfo* pHisto, double* ratio, int32_t num) { } ASSERTS(total <= numOfElem && total + pHisto->elems[j + 1].num > numOfElem, - "tHistogramUniform Error, total:%d, numOfElem:%d, elems[%d].num:%d", - total, numOfElem, j + 1, pHisto->elems[j + 1].num); + "tHistogramUniform Error, total:%ld, numOfElem:%ld, elems[%d].num:%ld", + total, (int64_t)numOfElem, j + 1, pHisto->elems[j + 1].num); double delta = numOfElem - total; if (fabs(delta) < FLT_EPSILON) { diff --git a/source/libs/function/src/tpercentile.c b/source/libs/function/src/tpercentile.c index 3ec802a7ce..8101b342a4 100644 --- a/source/libs/function/src/tpercentile.c +++ b/source/libs/function/src/tpercentile.c @@ -39,6 +39,7 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx) if (p != NULL) { pIdList = *(SArray **)p; } else { + taosMemoryFree(buffer); return NULL; } @@ -48,6 +49,7 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx) SFilePage *pg = getBufPage(pMemBucket->pBuffer, *pageId); if (pg == NULL) { + taosMemoryFree(buffer); return NULL; } diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 31a7dfdbc5..5b9f44c812 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -255,6 +255,18 @@ int32_t udfStopUdfd() { return 0; } +int32_t udfGetUdfdPid(int32_t* pUdfdPid) { + SUdfdData *pData = &udfdGlobal; + if (pData->spawnErr) { + return pData->spawnErr; + } + uv_pid_t pid = uv_process_get_pid(&pData->process); + if (pUdfdPid) { + *pUdfdPid = (int32_t)pid; + } + return TSDB_CODE_SUCCESS; +} + //============================================================================================== /* Copyright (c) 2013, Ben Noordhuis * The QUEUE is copied from queue.h under libuv diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c index 3b827a2f99..93259924d5 100644 --- a/source/libs/function/src/udfd.c +++ b/source/libs/function/src/udfd.c @@ -965,40 +965,6 @@ int32_t udfdFillUdfInfoFromMNode(void *clientRpc, char *udfName, SUdf *udf) { return code; } -int32_t udfdConnectToMnode() { - SConnectReq connReq = {0}; - connReq.connType = CONN_TYPE__UDFD; - tstrncpy(connReq.app, "udfd", sizeof(connReq.app)); - tstrncpy(connReq.user, TSDB_DEFAULT_USER, sizeof(connReq.user)); - char pass[TSDB_PASSWORD_LEN + 1] = {0}; - taosEncryptPass_c((uint8_t *)(TSDB_DEFAULT_PASS), strlen(TSDB_DEFAULT_PASS), pass); - tstrncpy(connReq.passwd, pass, sizeof(connReq.passwd)); - connReq.pid = taosGetPId(); - connReq.startTime = taosGetTimestampMs(); - strcpy(connReq.sVer, version); - - int32_t contLen = tSerializeSConnectReq(NULL, 0, &connReq); - void *pReq = rpcMallocCont(contLen); - tSerializeSConnectReq(pReq, contLen, &connReq); - - SUdfdRpcSendRecvInfo *msgInfo = taosMemoryCalloc(1, sizeof(SUdfdRpcSendRecvInfo)); - msgInfo->rpcType = UDFD_RPC_MNODE_CONNECT; - uv_sem_init(&msgInfo->resultSem, 0); - - SRpcMsg rpcMsg = {0}; - rpcMsg.msgType = TDMT_MND_CONNECT; - rpcMsg.pCont = pReq; - rpcMsg.contLen = contLen; - rpcMsg.info.ahandle = msgInfo; - rpcSendRequest(global.clientRpc, &global.mgmtEp.epSet, &rpcMsg, NULL); - - uv_sem_wait(&msgInfo->resultSem); - int32_t code = msgInfo->code; - uv_sem_destroy(&msgInfo->resultSem); - taosMemoryFree(msgInfo); - return code; -} - static bool udfdRpcRfp(int32_t code, tmsg_t msgType) { if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_RPC_BROKEN_LINK || code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED || code == TSDB_CODE_SYN_RESTORING || @@ -1378,23 +1344,6 @@ static int32_t udfdRun() { return 0; } -void udfdConnectMnodeThreadFunc(void *args) { - int32_t retryMnodeTimes = 0; - int32_t code = 0; - while (retryMnodeTimes++ <= TSDB_MAX_REPLICA) { - uv_sleep(100 * (1 << retryMnodeTimes)); - code = udfdConnectToMnode(); - if (code == 0) { - break; - } - fnError("udfd can not connect to mnode, code: %s. retry", tstrerror(code)); - } - - if (code != 0) { - fnError("udfd can not connect to mnode"); - } -} - int32_t udfdInitResidentFuncs() { if (strlen(tsUdfdResFuncs) == 0) { return TSDB_CODE_SUCCESS; @@ -1497,9 +1446,6 @@ int main(int argc, char *argv[]) { udfdInitResidentFuncs(); - uv_thread_t mnodeConnectThread; - uv_thread_create(&mnodeConnectThread, udfdConnectMnodeThreadFunc, NULL); - udfdRun(); removeListeningPipe(); diff --git a/source/libs/geometry/src/geomFunc.c b/source/libs/geometry/src/geomFunc.c index 0e2bac584d..3588bf8b7d 100644 --- a/source/libs/geometry/src/geomFunc.c +++ b/source/libs/geometry/src/geomFunc.c @@ -145,7 +145,7 @@ int32_t executeMakePointFunc(SColumnInfoData *pInputData[], int32_t iLeft, int32 goto _exit; } - colDataAppend(pOutputData, TMAX(iLeft, iRight), output, (output == NULL)); + colDataSetVal(pOutputData, TMAX(iLeft, iRight), output, (output == NULL)); _exit: if (output) { @@ -165,7 +165,7 @@ int32_t executeGeomFromTextFunc(SColumnInfoData *pInputData, int32_t i, SColumnI goto _exit; } - colDataAppend(pOutputData, i, output, (output == NULL)); + colDataSetVal(pOutputData, i, output, (output == NULL)); _exit: if (output) { @@ -185,7 +185,7 @@ int32_t executeAsTextFunc(SColumnInfoData *pInputData, int32_t i, SColumnInfoDat goto _exit; } - colDataAppend(pOutputData, i, output, (output == NULL)); + colDataSetVal(pOutputData, i, output, (output == NULL)); _exit: if (output) { @@ -213,7 +213,7 @@ int32_t executeRelationFunc(const GEOSGeometry *geom1, const GEOSPreparedGeometr } } - colDataAppend(pOutputData, i, &res, (res==-1)); + colDataSetVal(pOutputData, i, &res, (res==-1)); return code; } diff --git a/source/libs/geometry/src/geosWrapper.c b/source/libs/geometry/src/geosWrapper.c index dd83083ec9..993178e2b0 100644 --- a/source/libs/geometry/src/geosWrapper.c +++ b/source/libs/geometry/src/geosWrapper.c @@ -173,6 +173,7 @@ int32_t initCtxAsText() { if (geosCtx->WKTWriter) { GEOSWKTWriter_setRoundingPrecision_r(geosCtx->handle, geosCtx->WKTWriter, 6); + GEOSWKTWriter_setTrim_r(geosCtx->handle, geosCtx->WKTWriter, 0); } else { return code; } diff --git a/source/libs/geometry/test/geomFuncTestUtil.cpp b/source/libs/geometry/test/geomFuncTestUtil.cpp index cb59ea098f..0918781499 100644 --- a/source/libs/geometry/test/geomFuncTestUtil.cpp +++ b/source/libs/geometry/test/geomFuncTestUtil.cpp @@ -84,7 +84,7 @@ void setScalarParam(SScalarParam *sclParam, int32_t type, void *valueArray, TDRo } else { const char *val = (const char *)valueArray + (i * bytes); - colDataAppend(sclParam->columnData, i, val, false); + colDataSetVal(sclParam->columnData, i, val, false); } } } diff --git a/source/libs/index/src/indexFilter.c b/source/libs/index/src/indexFilter.c index 2c12c84081..bfdcd2b030 100644 --- a/source/libs/index/src/indexFilter.c +++ b/source/libs/index/src/indexFilter.c @@ -639,6 +639,10 @@ static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFP ret = indexJsonSearch(arg->ivtIdx, mtm, output->result); indexMultiTermQueryDestroy(mtm); } else { + if (left->colValType == TSDB_DATA_TYPE_GEOMETRY || right->colValType == TSDB_DATA_TYPE_GEOMETRY) { + return TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR; + } + bool reverse = false, equal = false; FilterFunc filterFunc = sifGetFilterFunc(qtype, &reverse, &equal); diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 6e4dde4ec1..8305daa45e 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -502,6 +502,7 @@ static int32_t logicSortCopy(const SSortLogicNode* pSrc, SSortLogicNode* pDst) { COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); CLONE_NODE_LIST_FIELD(pSortKeys); COPY_SCALAR_FIELD(groupSort); + COPY_SCALAR_FIELD(maxRows); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 0b449c5bfe..99790e0a93 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -2100,6 +2100,7 @@ static int32_t jsonToPhysiMergeNode(const SJson* pJson, void* pObj) { static const char* jkSortPhysiPlanExprs = "Exprs"; static const char* jkSortPhysiPlanSortKeys = "SortKeys"; static const char* jkSortPhysiPlanTargets = "Targets"; +static const char* jkSortPhysiPlanMaxRows = "MaxRows"; static int32_t physiSortNodeToJson(const void* pObj, SJson* pJson) { const SSortPhysiNode* pNode = (const SSortPhysiNode*)pObj; @@ -2114,6 +2115,9 @@ static int32_t physiSortNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = nodeListToJson(pJson, jkSortPhysiPlanTargets, pNode->pTargets); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkSortPhysiPlanMaxRows, pNode->maxRows); + } return code; } @@ -2131,6 +2135,9 @@ static int32_t jsonToPhysiSortNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkSortPhysiPlanTargets, &pNode->pTargets); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBigIntValue(pJson, jkSortPhysiPlanMaxRows, &pNode->maxRows); + } return code; } diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 1ca37defa4..e79a520615 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -2594,7 +2594,7 @@ static int32_t msgToPhysiMergeNode(STlvDecoder* pDecoder, void* pObj) { return code; } -enum { PHY_SORT_CODE_BASE_NODE = 1, PHY_SORT_CODE_EXPR, PHY_SORT_CODE_SORT_KEYS, PHY_SORT_CODE_TARGETS }; +enum { PHY_SORT_CODE_BASE_NODE = 1, PHY_SORT_CODE_EXPR, PHY_SORT_CODE_SORT_KEYS, PHY_SORT_CODE_TARGETS, PHY_SORT_CODE_MAX_ROWS }; static int32_t physiSortNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { const SSortPhysiNode* pNode = (const SSortPhysiNode*)pObj; @@ -2609,6 +2609,9 @@ static int32_t physiSortNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeObj(pEncoder, PHY_SORT_CODE_TARGETS, nodeListToMsg, pNode->pTargets); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeI64(pEncoder, PHY_SORT_CODE_MAX_ROWS, pNode->maxRows); + } return code; } @@ -2632,6 +2635,9 @@ static int32_t msgToPhysiSortNode(STlvDecoder* pDecoder, void* pObj) { case PHY_SORT_CODE_TARGETS: code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets); break; + case PHY_SORT_CODE_MAX_ROWS: + code = tlvDecodeI64(pTlv, &pNode->maxRows); + break; default: break; } diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index ff394467f6..78422bf746 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -206,9 +206,9 @@ SNode* createDropComponentNodeStmt(SAstCreateContext* pCxt, ENodeType type, cons 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); + int8_t withMeta); SNode* createCreateTopicStmtUseTable(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pRealTable, - bool withMeta, SNode* pWhere); + int8_t withMeta, SNode* pWhere); SNode* createDropTopicStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SToken* pTopicName); SNode* createDropCGroupStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SToken* pCGroupId, SToken* pTopicName); SNode* createAlterLocalStmt(SAstCreateContext* pCxt, const SToken* pConfig, const SToken* pValue); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 518dd95f23..548cf83b33 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -538,14 +538,18 @@ sma_stream_opt(A) ::= sma_stream_opt(B) MAX_DELAY duration_literal(C). sma_stream_opt(A) ::= sma_stream_opt(B) DELETE_MARK duration_literal(C). { ((SStreamOptions*)B)->pDeleteMark = releaseRawExprNode(pCxt, C); A = B; } /************************************************ create/drop topic ***************************************************/ +%type with_meta { int32_t } +%destructor with_meta { } +with_meta(A) ::= AS. { A = 0; } +with_meta(A) ::= WITH META AS. { A = 1; } +with_meta(A) ::= ONLY META AS. { A = 2; } + cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) AS query_or_subquery(C). { pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, A, &B, C); } -cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) AS DATABASE db_name(C). { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, A, &B, &C, false); } -cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) - WITH META AS DATABASE db_name(C). { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, A, &B, &C, true); } -cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) - AS STABLE full_table_name(C) where_clause_opt(D). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, false, D); } -cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) - WITH META AS STABLE full_table_name(C) where_clause_opt(D). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, true, D); } +cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) with_meta(D) + DATABASE db_name(C). { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, A, &B, &C, D); } +cmd ::= CREATE TOPIC not_exists_opt(A) topic_name(B) with_meta(E) + STABLE full_table_name(C) where_clause_opt(D). { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, A, &B, C, E, D); } + cmd ::= DROP TOPIC exists_opt(A) topic_name(B). { pCxt->pRootNode = createDropTopicStmt(pCxt, A, &B); } cmd ::= DROP CONSUMER GROUP exists_opt(A) cgroup_name(B) ON topic_name(C). { pCxt->pRootNode = createDropCGroupStmt(pCxt, A, &B, &C); } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index e08153c341..f85218c50a 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1715,7 +1715,7 @@ SNode* createCreateTopicStmtUseQuery(SAstCreateContext* pCxt, bool ignoreExists, } SNode* createCreateTopicStmtUseDb(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SToken* pSubDbName, - bool withMeta) { + int8_t withMeta) { CHECK_PARSER_STATUS(pCxt); if (!checkTopicName(pCxt, pTopicName) || !checkDbName(pCxt, pSubDbName, true)) { return NULL; @@ -1730,7 +1730,7 @@ SNode* createCreateTopicStmtUseDb(SAstCreateContext* pCxt, bool ignoreExists, ST } SNode* createCreateTopicStmtUseTable(SAstCreateContext* pCxt, bool ignoreExists, SToken* pTopicName, SNode* pRealTable, - bool withMeta, SNode* pWhere) { + int8_t withMeta, SNode* pWhere) { CHECK_PARSER_STATUS(pCxt); if (!checkTopicName(pCxt, pTopicName)) { return NULL; diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index f9b4e54318..8d35674949 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -331,6 +331,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, int64_t iv; uint64_t uv; char* endptr = NULL; + int32_t code = TSDB_CODE_SUCCESS; if (isNullValue(pSchema->type, pToken)) { if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) { @@ -467,8 +468,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, break; } - case TSDB_DATA_TYPE_BINARY: - case TSDB_DATA_TYPE_GEOMETRY: { + case TSDB_DATA_TYPE_BINARY: { // Too long values will raise the invalid sql error message if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) { return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name); @@ -478,6 +478,30 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, break; } + case TSDB_DATA_TYPE_GEOMETRY: { + unsigned char* output = NULL; + size_t size = 0; + + code = parseGeometry(pToken, &output, &size); + if (code != TSDB_CODE_SUCCESS) { + code = buildSyntaxErrMsg(pMsgBuf, getThreadLocalGeosCtx()->errMsg, pToken->z); + } else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) { + // Too long values will raise the invalid sql error message + code = generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name); + } else { + val->pData = taosMemoryMalloc(size); + if (NULL == val->pData) { + code = TSDB_CODE_OUT_OF_MEMORY; + } else { + memcpy(val->pData, output, size); + val->nData = size; + } + } + + geosFreeBuffer(output); + break; + } + case TSDB_DATA_TYPE_NCHAR: { int32_t output = 0; void* p = taosMemoryCalloc(1, pSchema->bytes - VARSTR_HEADER_SIZE); @@ -508,7 +532,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, } } - return TSDB_CODE_SUCCESS; + return code; } // input pStmt->pSql: [(tag1_name, ...)] TAGS (tag1_value, ...) ... @@ -1382,7 +1406,7 @@ static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql, code = buildSyntaxErrMsg(&pCxt->msg, getThreadLocalGeosCtx()->errMsg, pToken->z); } // Too long values will raise the invalid sql error message - else if (size > pSchema->bytes) { + else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) { code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name); } else { diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index 3af2d440c9..ca7ac1a0b6 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -140,6 +140,7 @@ static SKeyword keywordTable[] = { {"MAX_SPEED", TK_MAX_SPEED}, {"MERGE", TK_MERGE}, {"META", TK_META}, + {"ONLY", TK_ONLY}, {"MINROWS", TK_MINROWS}, {"MINUS", TK_MINUS}, {"MNODE", TK_MNODE}, diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 3f05e3269a..caefbe91a5 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -1,3 +1,5 @@ +/* This file is automatically generated by Lemon from input grammar +** source file "sql.y". */ /* ** 2000-05-29 ** @@ -22,10 +24,7 @@ ** The following is the concatenation of all %include directives from the ** input grammar file: */ -#include -#include /************ Begin %include sections from the grammar ************************/ - #include #include #include @@ -42,11 +41,348 @@ #define YYSTACKDEPTH 0 /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_OR +#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_UNSAFE 55 +#define TK_LOCAL 56 +#define TK_QNODE 57 +#define TK_BNODE 58 +#define TK_SNODE 59 +#define TK_MNODE 60 +#define TK_VNODE 61 +#define TK_DATABASE 62 +#define TK_USE 63 +#define TK_FLUSH 64 +#define TK_TRIM 65 +#define TK_COMPACT 66 +#define TK_IF 67 +#define TK_NOT 68 +#define TK_EXISTS 69 +#define TK_BUFFER 70 +#define TK_CACHEMODEL 71 +#define TK_CACHESIZE 72 +#define TK_COMP 73 +#define TK_DURATION 74 +#define TK_NK_VARIABLE 75 +#define TK_MAXROWS 76 +#define TK_MINROWS 77 +#define TK_KEEP 78 +#define TK_PAGES 79 +#define TK_PAGESIZE 80 +#define TK_TSDB_PAGESIZE 81 +#define TK_PRECISION 82 +#define TK_REPLICA 83 +#define TK_VGROUPS 84 +#define TK_SINGLE_STABLE 85 +#define TK_RETENTIONS 86 +#define TK_SCHEMALESS 87 +#define TK_WAL_LEVEL 88 +#define TK_WAL_FSYNC_PERIOD 89 +#define TK_WAL_RETENTION_PERIOD 90 +#define TK_WAL_RETENTION_SIZE 91 +#define TK_WAL_ROLL_PERIOD 92 +#define TK_WAL_SEGMENT_SIZE 93 +#define TK_STT_TRIGGER 94 +#define TK_TABLE_PREFIX 95 +#define TK_TABLE_SUFFIX 96 +#define TK_NK_COLON 97 +#define TK_MAX_SPEED 98 +#define TK_START 99 +#define TK_TIMESTAMP 100 +#define TK_END 101 +#define TK_TABLE 102 +#define TK_NK_LP 103 +#define TK_NK_RP 104 +#define TK_STABLE 105 +#define TK_ADD 106 +#define TK_COLUMN 107 +#define TK_MODIFY 108 +#define TK_RENAME 109 +#define TK_TAG 110 +#define TK_SET 111 +#define TK_NK_EQ 112 +#define TK_USING 113 +#define TK_TAGS 114 +#define TK_BOOL 115 +#define TK_TINYINT 116 +#define TK_SMALLINT 117 +#define TK_INT 118 +#define TK_INTEGER 119 +#define TK_BIGINT 120 +#define TK_FLOAT 121 +#define TK_DOUBLE 122 +#define TK_BINARY 123 +#define TK_NCHAR 124 +#define TK_UNSIGNED 125 +#define TK_JSON 126 +#define TK_VARCHAR 127 +#define TK_MEDIUMBLOB 128 +#define TK_BLOB 129 +#define TK_VARBINARY 130 +#define TK_GEOMETRY 131 +#define TK_DECIMAL 132 +#define TK_COMMENT 133 +#define TK_MAX_DELAY 134 +#define TK_WATERMARK 135 +#define TK_ROLLUP 136 +#define TK_TTL 137 +#define TK_SMA 138 +#define TK_DELETE_MARK 139 +#define TK_FIRST 140 +#define TK_LAST 141 +#define TK_SHOW 142 +#define TK_PRIVILEGES 143 +#define TK_DATABASES 144 +#define TK_TABLES 145 +#define TK_STABLES 146 +#define TK_MNODES 147 +#define TK_QNODES 148 +#define TK_FUNCTIONS 149 +#define TK_INDEXES 150 +#define TK_ACCOUNTS 151 +#define TK_APPS 152 +#define TK_CONNECTIONS 153 +#define TK_LICENCES 154 +#define TK_GRANTS 155 +#define TK_QUERIES 156 +#define TK_SCORES 157 +#define TK_TOPICS 158 +#define TK_VARIABLES 159 +#define TK_CLUSTER 160 +#define TK_BNODES 161 +#define TK_SNODES 162 +#define TK_TRANSACTIONS 163 +#define TK_DISTRIBUTED 164 +#define TK_CONSUMERS 165 +#define TK_SUBSCRIPTIONS 166 +#define TK_VNODES 167 +#define TK_ALIVE 168 +#define TK_LIKE 169 +#define TK_TBNAME 170 +#define TK_QTAGS 171 +#define TK_AS 172 +#define TK_INDEX 173 +#define TK_FUNCTION 174 +#define TK_INTERVAL 175 +#define TK_COUNT 176 +#define TK_LAST_ROW 177 +#define TK_META 178 +#define TK_ONLY 179 +#define TK_TOPIC 180 +#define TK_CONSUMER 181 +#define TK_GROUP 182 +#define TK_DESC 183 +#define TK_DESCRIBE 184 +#define TK_RESET 185 +#define TK_QUERY 186 +#define TK_CACHE 187 +#define TK_EXPLAIN 188 +#define TK_ANALYZE 189 +#define TK_VERBOSE 190 +#define TK_NK_BOOL 191 +#define TK_RATIO 192 +#define TK_NK_FLOAT 193 +#define TK_OUTPUTTYPE 194 +#define TK_AGGREGATE 195 +#define TK_BUFSIZE 196 +#define TK_LANGUAGE 197 +#define TK_REPLACE 198 +#define TK_STREAM 199 +#define TK_INTO 200 +#define TK_PAUSE 201 +#define TK_RESUME 202 +#define TK_TRIGGER 203 +#define TK_AT_ONCE 204 +#define TK_WINDOW_CLOSE 205 +#define TK_IGNORE 206 +#define TK_EXPIRED 207 +#define TK_FILL_HISTORY 208 +#define TK_UPDATE 209 +#define TK_SUBTABLE 210 +#define TK_UNTREATED 211 +#define TK_KILL 212 +#define TK_CONNECTION 213 +#define TK_TRANSACTION 214 +#define TK_BALANCE 215 +#define TK_VGROUP 216 +#define TK_LEADER 217 +#define TK_MERGE 218 +#define TK_REDISTRIBUTE 219 +#define TK_SPLIT 220 +#define TK_DELETE 221 +#define TK_INSERT 222 +#define TK_NULL 223 +#define TK_NK_QUESTION 224 +#define TK_NK_ARROW 225 +#define TK_ROWTS 226 +#define TK_QSTART 227 +#define TK_QEND 228 +#define TK_QDURATION 229 +#define TK_WSTART 230 +#define TK_WEND 231 +#define TK_WDURATION 232 +#define TK_IROWTS 233 +#define TK_ISFILLED 234 +#define TK_CAST 235 +#define TK_NOW 236 +#define TK_TODAY 237 +#define TK_TIMEZONE 238 +#define TK_CLIENT_VERSION 239 +#define TK_SERVER_VERSION 240 +#define TK_SERVER_STATUS 241 +#define TK_CURRENT_USER 242 +#define TK_CASE 243 +#define TK_WHEN 244 +#define TK_THEN 245 +#define TK_ELSE 246 +#define TK_BETWEEN 247 +#define TK_IS 248 +#define TK_NK_LT 249 +#define TK_NK_GT 250 +#define TK_NK_LE 251 +#define TK_NK_GE 252 +#define TK_NK_NE 253 +#define TK_MATCH 254 +#define TK_NMATCH 255 +#define TK_CONTAINS 256 +#define TK_IN 257 +#define TK_JOIN 258 +#define TK_INNER 259 +#define TK_SELECT 260 +#define TK_DISTINCT 261 +#define TK_WHERE 262 +#define TK_PARTITION 263 +#define TK_BY 264 +#define TK_SESSION 265 +#define TK_STATE_WINDOW 266 +#define TK_EVENT_WINDOW 267 +#define TK_SLIDING 268 +#define TK_FILL 269 +#define TK_VALUE 270 +#define TK_VALUE_F 271 +#define TK_NONE 272 +#define TK_PREV 273 +#define TK_NULL_F 274 +#define TK_LINEAR 275 +#define TK_NEXT 276 +#define TK_HAVING 277 +#define TK_RANGE 278 +#define TK_EVERY 279 +#define TK_ORDER 280 +#define TK_SLIMIT 281 +#define TK_SOFFSET 282 +#define TK_LIMIT 283 +#define TK_OFFSET 284 +#define TK_ASC 285 +#define TK_NULLS 286 +#define TK_ABORT 287 +#define TK_AFTER 288 +#define TK_ATTACH 289 +#define TK_BEFORE 290 +#define TK_BEGIN 291 +#define TK_BITAND 292 +#define TK_BITNOT 293 +#define TK_BITOR 294 +#define TK_BLOCKS 295 +#define TK_CHANGE 296 +#define TK_COMMA 297 +#define TK_CONCAT 298 +#define TK_CONFLICT 299 +#define TK_COPY 300 +#define TK_DEFERRED 301 +#define TK_DELIMITERS 302 +#define TK_DETACH 303 +#define TK_DIVIDE 304 +#define TK_DOT 305 +#define TK_EACH 306 +#define TK_FAIL 307 +#define TK_FILE 308 +#define TK_FOR 309 +#define TK_GLOB 310 +#define TK_ID 311 +#define TK_IMMEDIATE 312 +#define TK_IMPORT 313 +#define TK_INITIALLY 314 +#define TK_INSTEAD 315 +#define TK_ISNULL 316 +#define TK_KEY 317 +#define TK_MODULES 318 +#define TK_NK_BITNOT 319 +#define TK_NK_SEMI 320 +#define TK_NOTNULL 321 +#define TK_OF 322 +#define TK_PLUS 323 +#define TK_PRIVILEGE 324 +#define TK_RAISE 325 +#define TK_RESTRICT 326 +#define TK_ROW 327 +#define TK_SEMI 328 +#define TK_STAR 329 +#define TK_STATEMENT 330 +#define TK_STRICT 331 +#define TK_STRING 332 +#define TK_TIMES 333 +#define TK_VALUES 334 +#define TK_VARIABLE 335 +#define TK_VIEW 336 +#define TK_WAL 337 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -104,27 +440,27 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 485 +#define YYNOCODE 487 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SToken typedef union { int yyinit; ParseTOKENTYPE yy0; - EOrder yy48; - EOperatorType yy70; - int8_t yy73; - int32_t yy120; - SNodeList* yy174; - EFillMode yy204; - SNode* yy242; - STokenPair yy257; - int64_t yy349; - EJoinType yy482; - SAlterOption yy535; - SToken yy669; - ENullOrder yy687; - bool yy777; - SDataType yy794; + EJoinType yy140; + SDataType yy310; + STokenPair yy347; + EOperatorType yy354; + SAlterOption yy365; + SToken yy371; + ENullOrder yy399; + int32_t yy416; + SNode* yy452; + int8_t yy475; + bool yy667; + EOrder yy690; + int64_t yy729; + SNodeList* yy812; + EFillMode yy844; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -140,18 +476,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 794 -#define YYNRULE 596 -#define YYNRULE_WITH_ACTION 596 -#define YYNTOKEN 337 -#define YY_MAX_SHIFT 793 -#define YY_MIN_SHIFTREDUCE 1172 +#define YYNSTATE 791 +#define YYNRULE 597 +#define YYNRULE_WITH_ACTION 597 +#define YYNTOKEN 338 +#define YY_MAX_SHIFT 790 +#define YY_MIN_SHIFTREDUCE 1171 #define YY_MAX_SHIFTREDUCE 1767 #define YY_ERROR_ACTION 1768 #define YY_ACCEPT_ACTION 1769 #define YY_NO_ACTION 1770 #define YY_MIN_REDUCE 1771 -#define YY_MAX_REDUCE 2366 +#define YY_MAX_REDUCE 2367 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -218,713 +554,738 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2730) +#define YY_ACTTAB_COUNT (2858) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 2177, 2067, 170, 218, 1783, 670, 447, 531, 665, 1814, - /* 10 */ 662, 446, 48, 46, 1694, 1937, 2065, 671, 647, 1794, - /* 20 */ 401, 2337, 1543, 41, 40, 410, 409, 47, 45, 44, - /* 30 */ 43, 42, 686, 1624, 2237, 1541, 646, 188, 2195, 41, - /* 40 */ 40, 2338, 648, 47, 45, 44, 43, 42, 1550, 2138, - /* 50 */ 2145, 1571, 700, 622, 1568, 622, 2337, 543, 2337, 2060, - /* 60 */ 2177, 181, 1619, 47, 45, 44, 43, 42, 19, 2145, - /* 70 */ 701, 2343, 188, 2343, 188, 1549, 2338, 648, 2338, 648, - /* 80 */ 220, 368, 2050, 360, 531, 2176, 1814, 2212, 107, 184, - /* 90 */ 110, 2178, 704, 2180, 2181, 699, 622, 694, 2195, 2337, - /* 100 */ 790, 1988, 185, 15, 2265, 143, 87, 641, 397, 2261, - /* 110 */ 2145, 1793, 700, 1940, 2343, 188, 48, 46, 2067, 2338, - /* 120 */ 648, 190, 2155, 370, 401, 2342, 1543, 1653, 2337, 2291, - /* 130 */ 394, 683, 1943, 2064, 671, 2195, 1939, 1624, 205, 1541, - /* 140 */ 1626, 1627, 453, 1318, 2341, 2176, 2159, 2212, 2338, 2340, - /* 150 */ 110, 2178, 704, 2180, 2181, 699, 1317, 694, 1569, 404, - /* 160 */ 145, 2145, 152, 2236, 2265, 181, 1619, 164, 397, 2261, - /* 170 */ 1599, 1609, 19, 2001, 382, 1950, 1625, 1628, 84, 1549, - /* 180 */ 381, 83, 1999, 2161, 1654, 1772, 2051, 347, 1999, 640, - /* 190 */ 1544, 123, 1542, 694, 122, 121, 120, 119, 118, 117, - /* 200 */ 116, 115, 114, 263, 790, 1553, 123, 15, 2177, 122, - /* 210 */ 121, 120, 119, 118, 117, 116, 115, 114, 701, 669, - /* 220 */ 1816, 500, 1547, 1548, 1771, 1598, 1601, 1602, 1603, 1604, - /* 230 */ 1605, 1606, 1607, 1608, 696, 692, 1617, 1618, 1620, 1621, - /* 240 */ 1622, 1623, 2, 642, 1626, 1627, 2195, 1792, 132, 131, - /* 250 */ 130, 129, 128, 127, 126, 125, 124, 670, 2145, 62, - /* 260 */ 700, 37, 399, 1648, 1649, 1650, 1651, 1652, 1656, 1657, - /* 270 */ 1658, 1659, 38, 305, 1599, 1609, 1568, 287, 1398, 1399, - /* 280 */ 1625, 1628, 1205, 683, 41, 40, 684, 1948, 47, 45, - /* 290 */ 44, 43, 42, 2176, 1544, 2212, 1542, 2145, 110, 2178, - /* 300 */ 704, 2180, 2181, 699, 528, 694, 133, 529, 1807, 668, - /* 310 */ 2357, 2060, 2265, 568, 1568, 2177, 397, 2261, 62, 1567, - /* 320 */ 93, 1207, 533, 1210, 1211, 662, 1547, 1548, 530, 1598, - /* 330 */ 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 696, 692, - /* 340 */ 1617, 1618, 1620, 1621, 1622, 1623, 2, 12, 48, 46, - /* 350 */ 12, 637, 10, 2195, 395, 683, 401, 406, 1543, 1363, - /* 360 */ 1994, 1996, 167, 373, 545, 2145, 51, 700, 670, 1624, - /* 370 */ 1950, 1541, 684, 1948, 1354, 729, 728, 727, 1358, 726, - /* 380 */ 1360, 1361, 725, 722, 2131, 1369, 719, 1371, 1372, 716, - /* 390 */ 713, 710, 133, 2177, 8, 2280, 659, 142, 1619, 573, - /* 400 */ 2176, 1791, 2212, 698, 19, 110, 2178, 704, 2180, 2181, - /* 410 */ 699, 1549, 694, 2342, 1230, 191, 1229, 185, 1925, 2265, - /* 420 */ 679, 2277, 2060, 397, 2261, 250, 1600, 659, 142, 138, - /* 430 */ 1570, 2195, 374, 423, 372, 371, 790, 570, 51, 15, - /* 440 */ 643, 638, 631, 2145, 2292, 700, 1570, 1231, 586, 585, - /* 450 */ 584, 2145, 48, 46, 1629, 576, 139, 580, 1764, 572, - /* 460 */ 401, 579, 1543, 571, 1453, 1454, 578, 583, 376, 375, - /* 470 */ 609, 1722, 577, 1624, 191, 1541, 1626, 1627, 2176, 2280, - /* 480 */ 2212, 1995, 1996, 341, 2178, 704, 2180, 2181, 699, 697, - /* 490 */ 694, 685, 2230, 536, 1514, 1515, 529, 1807, 2177, 187, - /* 500 */ 2273, 2274, 1619, 140, 2278, 2276, 1599, 1609, 701, 1230, - /* 510 */ 2312, 1229, 1625, 1628, 1757, 1549, 659, 142, 634, 633, - /* 520 */ 1720, 1721, 1723, 1724, 1725, 491, 1544, 739, 1542, 661, - /* 530 */ 186, 2273, 2274, 525, 140, 2278, 2195, 14, 13, 1568, - /* 540 */ 790, 523, 1231, 49, 519, 515, 659, 142, 2145, 1790, - /* 550 */ 700, 737, 157, 156, 734, 733, 732, 154, 1547, 1548, - /* 560 */ 1763, 1598, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, - /* 570 */ 696, 692, 1617, 1618, 1620, 1621, 1622, 1623, 2, 574, - /* 580 */ 1626, 1627, 285, 2176, 2341, 2212, 209, 208, 110, 2178, - /* 590 */ 704, 2180, 2181, 699, 191, 694, 12, 2001, 285, 2145, - /* 600 */ 2357, 1305, 2265, 101, 391, 2177, 397, 2261, 2110, 490, - /* 610 */ 1599, 1609, 1999, 1687, 600, 701, 1625, 1628, 1924, 283, - /* 620 */ 2273, 658, 62, 134, 657, 66, 2337, 598, 1941, 596, - /* 630 */ 1544, 435, 1542, 737, 157, 156, 734, 733, 732, 154, - /* 640 */ 1667, 646, 188, 2195, 684, 1948, 2338, 648, 1769, 189, - /* 650 */ 2273, 2274, 1549, 140, 2278, 2145, 251, 700, 437, 433, - /* 660 */ 2031, 2139, 1547, 1548, 193, 1598, 1601, 1602, 1603, 1604, - /* 670 */ 1605, 1606, 1607, 1608, 696, 692, 1617, 1618, 1620, 1621, - /* 680 */ 1622, 1623, 2, 48, 46, 739, 169, 1233, 1234, 52, - /* 690 */ 2176, 401, 2212, 1543, 1889, 110, 2178, 704, 2180, 2181, - /* 700 */ 699, 575, 694, 2001, 1624, 2155, 1541, 2240, 622, 2265, - /* 710 */ 396, 2337, 234, 397, 2261, 44, 43, 42, 1999, 2164, - /* 720 */ 416, 1322, 1543, 1303, 62, 415, 2343, 188, 174, 2159, - /* 730 */ 2177, 2338, 648, 1619, 1321, 1541, 562, 558, 554, 550, - /* 740 */ 701, 233, 688, 1789, 2237, 2155, 1549, 41, 40, 1307, - /* 750 */ 34, 47, 45, 44, 43, 42, 41, 40, 1264, 2163, - /* 760 */ 47, 45, 44, 43, 42, 1926, 2161, 622, 2195, 2159, - /* 770 */ 2337, 790, 684, 1948, 49, 1549, 694, 730, 191, 1788, - /* 780 */ 2145, 88, 700, 30, 231, 2343, 188, 48, 46, 1309, - /* 790 */ 2338, 648, 681, 2145, 2177, 401, 1571, 1543, 1265, 502, - /* 800 */ 790, 1787, 564, 563, 701, 749, 2161, 398, 1624, 150, - /* 810 */ 1541, 1626, 1627, 684, 1948, 2176, 694, 2212, 1569, 471, - /* 820 */ 111, 2178, 704, 2180, 2181, 699, 1933, 694, 470, 2145, - /* 830 */ 566, 565, 2195, 57, 2265, 684, 1948, 1619, 2264, 2261, - /* 840 */ 1571, 1599, 1609, 1734, 2145, 191, 700, 1625, 1628, 2046, - /* 850 */ 1549, 2145, 230, 224, 572, 451, 1935, 229, 571, 541, - /* 860 */ 650, 1544, 144, 1542, 249, 2236, 41, 40, 248, 1786, - /* 870 */ 47, 45, 44, 43, 42, 790, 1698, 222, 15, 2176, - /* 880 */ 191, 2212, 1568, 2046, 171, 2178, 704, 2180, 2181, 699, - /* 890 */ 1544, 694, 1542, 1547, 1548, 201, 1598, 1601, 1602, 1603, - /* 900 */ 1604, 1605, 1606, 1607, 1608, 696, 692, 1617, 1618, 1620, - /* 910 */ 1621, 1622, 1623, 2, 1931, 1626, 1627, 582, 581, 2145, - /* 920 */ 684, 1948, 1547, 1548, 623, 2302, 1952, 2001, 90, 203, - /* 930 */ 2280, 355, 2046, 404, 380, 351, 602, 1566, 1470, 1471, - /* 940 */ 452, 167, 2000, 2177, 484, 1599, 1609, 498, 202, 1950, - /* 950 */ 497, 1625, 1628, 701, 256, 629, 2275, 684, 1948, 684, - /* 960 */ 1948, 2342, 1733, 1213, 2337, 1544, 467, 1542, 499, 1567, - /* 970 */ 1785, 684, 1948, 469, 1469, 1472, 36, 461, 207, 476, - /* 980 */ 2341, 2195, 41, 40, 2338, 2339, 47, 45, 44, 43, - /* 990 */ 42, 477, 262, 2145, 695, 700, 731, 1547, 1548, 1992, - /* 1000 */ 1598, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 696, - /* 1010 */ 692, 1617, 1618, 1620, 1621, 1622, 1623, 2, 1847, 369, - /* 1020 */ 2145, 167, 684, 1948, 684, 1948, 684, 1948, 2176, 1951, - /* 1030 */ 2212, 457, 1600, 110, 2178, 704, 2180, 2181, 699, 54, - /* 1040 */ 694, 3, 544, 259, 1945, 2357, 252, 2265, 1890, 41, - /* 1050 */ 40, 397, 2261, 47, 45, 44, 43, 42, 296, 297, - /* 1060 */ 2128, 495, 2305, 295, 489, 488, 487, 486, 483, 482, - /* 1070 */ 481, 480, 479, 475, 474, 473, 472, 350, 464, 463, - /* 1080 */ 462, 607, 459, 458, 367, 1691, 1782, 1634, 767, 766, - /* 1090 */ 765, 764, 413, 1568, 763, 762, 146, 757, 756, 755, - /* 1100 */ 754, 753, 752, 751, 159, 747, 746, 745, 412, 411, - /* 1110 */ 742, 741, 740, 177, 176, 168, 1850, 454, 41, 40, - /* 1120 */ 326, 1655, 47, 45, 44, 43, 42, 87, 622, 2177, - /* 1130 */ 455, 2337, 1784, 2001, 323, 73, 2145, 155, 72, 701, - /* 1140 */ 405, 2330, 1781, 761, 759, 1710, 2343, 188, 1999, 348, - /* 1150 */ 280, 2338, 648, 1944, 684, 1948, 62, 635, 684, 1948, - /* 1160 */ 216, 510, 508, 505, 137, 2177, 1923, 2195, 1780, 691, - /* 1170 */ 2001, 684, 1948, 735, 260, 701, 1992, 366, 286, 2145, - /* 1180 */ 1888, 700, 684, 1948, 1779, 1999, 586, 585, 584, 684, - /* 1190 */ 1948, 667, 2145, 576, 139, 580, 1778, 56, 35, 579, - /* 1200 */ 62, 651, 300, 2195, 578, 583, 376, 375, 1660, 682, - /* 1210 */ 577, 274, 1210, 1211, 2176, 2145, 2212, 700, 2145, 110, - /* 1220 */ 2178, 704, 2180, 2181, 699, 1777, 694, 654, 1776, 684, - /* 1230 */ 1948, 2357, 1887, 2265, 2145, 2177, 414, 397, 2261, 109, - /* 1240 */ 1775, 1774, 445, 1600, 444, 701, 2145, 2284, 647, 306, - /* 1250 */ 2176, 2337, 2212, 2285, 1687, 172, 2178, 704, 2180, 2181, - /* 1260 */ 699, 407, 694, 684, 1948, 736, 646, 188, 1992, 167, - /* 1270 */ 2196, 2338, 648, 2195, 443, 2145, 430, 1950, 2145, 81, - /* 1280 */ 80, 450, 166, 408, 200, 2145, 2177, 700, 261, 319, - /* 1290 */ 2145, 2145, 1978, 604, 2055, 603, 701, 442, 440, 737, - /* 1300 */ 157, 156, 734, 733, 732, 154, 649, 2358, 349, 2177, - /* 1310 */ 750, 431, 191, 1910, 429, 425, 421, 418, 443, 701, - /* 1320 */ 2176, 2299, 2212, 1645, 2195, 110, 2178, 704, 2180, 2181, - /* 1330 */ 699, 91, 694, 148, 74, 135, 2145, 2357, 700, 2265, - /* 1340 */ 1834, 1690, 1825, 397, 2261, 410, 409, 2195, 239, 241, - /* 1350 */ 243, 237, 240, 242, 245, 1557, 191, 244, 621, 2145, - /* 1360 */ 2177, 700, 587, 155, 589, 1823, 1624, 155, 1550, 50, - /* 1370 */ 701, 2176, 50, 2212, 267, 155, 335, 2178, 704, 2180, - /* 1380 */ 2181, 699, 50, 694, 82, 41, 40, 592, 293, 47, - /* 1390 */ 45, 44, 43, 42, 2176, 1619, 2212, 1552, 2195, 110, - /* 1400 */ 2178, 704, 2180, 2181, 699, 71, 694, 153, 1549, 1551, - /* 1410 */ 2145, 2357, 700, 2265, 1766, 1767, 155, 397, 2261, 644, - /* 1420 */ 2177, 14, 13, 1509, 64, 50, 50, 1512, 708, 1719, - /* 1430 */ 701, 153, 1718, 690, 269, 666, 2166, 155, 652, 743, - /* 1440 */ 136, 744, 1467, 153, 1817, 2176, 106, 2212, 298, 2177, - /* 1450 */ 110, 2178, 704, 2180, 2181, 699, 103, 694, 2195, 701, - /* 1460 */ 1808, 1283, 2238, 1281, 2265, 676, 655, 302, 397, 2261, - /* 1470 */ 2145, 1813, 700, 1989, 2295, 660, 1348, 282, 279, 1, - /* 1480 */ 9, 417, 55, 422, 1661, 1610, 318, 2195, 1376, 364, - /* 1490 */ 1574, 1380, 2168, 438, 785, 439, 195, 1387, 196, 2145, - /* 1500 */ 1385, 700, 441, 158, 198, 2176, 1490, 2212, 313, 206, - /* 1510 */ 110, 2178, 704, 2180, 2181, 699, 456, 694, 1571, 460, - /* 1520 */ 2056, 493, 687, 1558, 2265, 1553, 465, 1566, 397, 2261, - /* 1530 */ 478, 2048, 485, 492, 2176, 504, 2212, 494, 503, 111, - /* 1540 */ 2178, 704, 2180, 2181, 699, 501, 694, 591, 210, 211, - /* 1550 */ 506, 507, 213, 2265, 1555, 1561, 1563, 689, 2261, 509, - /* 1560 */ 511, 1572, 601, 526, 4, 2177, 1554, 537, 692, 1617, - /* 1570 */ 1618, 1620, 1621, 1622, 1623, 701, 247, 527, 534, 535, - /* 1580 */ 221, 1569, 538, 1573, 1575, 223, 539, 540, 226, 542, - /* 1590 */ 228, 2177, 594, 546, 567, 85, 569, 86, 232, 588, - /* 1600 */ 354, 701, 1938, 2195, 112, 246, 236, 1934, 608, 606, - /* 1610 */ 151, 89, 238, 2119, 314, 2145, 253, 700, 612, 613, - /* 1620 */ 611, 255, 257, 160, 161, 2177, 1936, 1932, 162, 2195, - /* 1630 */ 1497, 163, 617, 619, 636, 701, 2311, 674, 2287, 2310, - /* 1640 */ 7, 2145, 645, 700, 2116, 70, 2115, 273, 69, 616, - /* 1650 */ 702, 175, 2212, 626, 627, 111, 2178, 704, 2180, 2181, - /* 1660 */ 699, 632, 694, 2195, 2296, 2306, 386, 265, 639, 2265, - /* 1670 */ 275, 618, 268, 359, 2261, 2145, 2176, 700, 2212, 625, - /* 1680 */ 276, 111, 2178, 704, 2180, 2181, 699, 2177, 694, 624, - /* 1690 */ 278, 387, 2360, 656, 653, 2265, 1687, 701, 141, 1570, - /* 1700 */ 2262, 2281, 663, 664, 390, 288, 96, 2061, 1576, 677, - /* 1710 */ 2176, 2177, 2212, 315, 672, 171, 2178, 704, 2180, 2181, - /* 1720 */ 699, 701, 694, 678, 673, 2195, 2075, 2074, 61, 2073, - /* 1730 */ 384, 277, 316, 317, 98, 2177, 281, 2145, 1949, 700, - /* 1740 */ 2246, 393, 100, 102, 786, 701, 2336, 1993, 309, 2195, - /* 1750 */ 706, 1911, 320, 787, 385, 789, 2303, 329, 53, 324, - /* 1760 */ 2137, 2145, 356, 700, 357, 322, 344, 2136, 2135, 343, - /* 1770 */ 333, 78, 2176, 2195, 2212, 419, 1534, 342, 2178, 704, - /* 1780 */ 2180, 2181, 699, 2132, 694, 2145, 420, 700, 1535, 194, - /* 1790 */ 424, 2130, 426, 427, 428, 2129, 2176, 365, 2212, 2177, - /* 1800 */ 2127, 342, 2178, 704, 2180, 2181, 699, 432, 694, 701, - /* 1810 */ 2126, 434, 2125, 436, 1525, 2106, 197, 2105, 199, 1493, - /* 1820 */ 2176, 79, 2212, 1492, 2087, 172, 2178, 704, 2180, 2181, - /* 1830 */ 699, 2086, 694, 2085, 448, 449, 2084, 2195, 2083, 1444, - /* 1840 */ 2039, 2038, 392, 2036, 147, 2035, 2034, 2037, 2033, 2145, - /* 1850 */ 2032, 700, 2030, 2029, 2028, 204, 466, 2027, 468, 2041, - /* 1860 */ 2026, 2025, 2024, 2177, 149, 2011, 2010, 2009, 2040, 2008, - /* 1870 */ 2007, 1446, 2006, 698, 2023, 2022, 2021, 2359, 2020, 2019, - /* 1880 */ 2018, 2017, 2016, 2015, 2176, 2177, 2212, 2014, 2013, 342, - /* 1890 */ 2178, 704, 2180, 2181, 699, 701, 694, 2012, 2005, 2004, - /* 1900 */ 2003, 2195, 496, 2002, 352, 1853, 1319, 1852, 1323, 2177, - /* 1910 */ 63, 353, 1315, 2145, 1851, 700, 1849, 212, 1846, 701, - /* 1920 */ 214, 1845, 513, 2195, 512, 1838, 516, 1827, 400, 514, - /* 1930 */ 520, 524, 518, 215, 1803, 2145, 1212, 700, 1802, 2104, - /* 1940 */ 522, 517, 2094, 521, 217, 76, 2082, 2195, 2176, 219, - /* 1950 */ 2212, 2165, 402, 341, 2178, 704, 2180, 2181, 699, 2145, - /* 1960 */ 694, 700, 2231, 610, 182, 77, 183, 225, 227, 2081, - /* 1970 */ 2176, 532, 2212, 2059, 1927, 342, 2178, 704, 2180, 2181, - /* 1980 */ 699, 793, 694, 1848, 1257, 1844, 547, 549, 1842, 548, - /* 1990 */ 551, 553, 552, 1840, 2176, 312, 2212, 2177, 555, 342, - /* 2000 */ 2178, 704, 2180, 2181, 699, 556, 694, 701, 1837, 557, - /* 2010 */ 559, 180, 1392, 560, 1822, 561, 2177, 1820, 1821, 783, - /* 2020 */ 779, 775, 771, 1819, 310, 1391, 701, 2177, 1799, 1929, - /* 2030 */ 1928, 758, 1306, 235, 1304, 2195, 1302, 701, 760, 1301, - /* 2040 */ 1300, 1299, 1298, 1293, 1295, 1294, 1292, 2145, 1835, 700, - /* 2050 */ 1826, 590, 1824, 377, 2195, 378, 379, 593, 1798, 595, - /* 2060 */ 1797, 597, 1796, 599, 108, 2195, 2145, 303, 700, 113, - /* 2070 */ 1519, 1521, 1518, 2103, 1499, 1523, 1501, 2145, 2093, 700, - /* 2080 */ 58, 29, 605, 67, 2212, 614, 258, 337, 2178, 704, - /* 2090 */ 2180, 2181, 699, 2080, 694, 2177, 2078, 2342, 17, 20, - /* 2100 */ 680, 2176, 1736, 2212, 165, 701, 327, 2178, 704, 2180, - /* 2110 */ 2181, 699, 2176, 694, 2212, 2177, 615, 325, 2178, 704, - /* 2120 */ 2180, 2181, 699, 31, 694, 701, 2177, 1503, 620, 383, - /* 2130 */ 264, 5, 6, 2195, 21, 290, 701, 65, 272, 628, - /* 2140 */ 289, 630, 22, 271, 266, 2145, 2177, 700, 1717, 173, - /* 2150 */ 270, 2166, 33, 2195, 32, 24, 701, 1709, 1751, 92, - /* 2160 */ 254, 1756, 1750, 1757, 2195, 2145, 388, 700, 1755, 1684, - /* 2170 */ 1754, 389, 1683, 284, 59, 178, 2145, 2079, 700, 2077, - /* 2180 */ 2176, 60, 2212, 2076, 2195, 328, 2178, 704, 2180, 2181, - /* 2190 */ 699, 2058, 694, 95, 23, 18, 2145, 291, 700, 292, - /* 2200 */ 2176, 1715, 2212, 94, 2177, 334, 2178, 704, 2180, 2181, - /* 2210 */ 699, 2176, 694, 2212, 701, 25, 338, 2178, 704, 2180, - /* 2220 */ 2181, 699, 294, 694, 299, 2177, 2057, 68, 97, 103, - /* 2230 */ 26, 2176, 99, 2212, 301, 701, 330, 2178, 704, 2180, - /* 2240 */ 2181, 699, 2195, 694, 675, 304, 1636, 1635, 13, 1559, - /* 2250 */ 2177, 2215, 179, 1614, 2145, 693, 700, 11, 192, 1612, - /* 2260 */ 701, 39, 16, 2195, 1611, 1646, 27, 1591, 1583, 703, - /* 2270 */ 28, 705, 1377, 707, 403, 2145, 2177, 700, 709, 711, - /* 2280 */ 1374, 712, 714, 717, 1373, 715, 701, 718, 2195, 2176, - /* 2290 */ 720, 2212, 1370, 721, 339, 2178, 704, 2180, 2181, 699, - /* 2300 */ 2145, 694, 700, 1364, 1362, 723, 1368, 724, 307, 1386, - /* 2310 */ 2176, 104, 2212, 105, 2195, 331, 2178, 704, 2180, 2181, - /* 2320 */ 699, 1367, 694, 75, 1382, 1255, 2145, 1366, 700, 738, - /* 2330 */ 1287, 1365, 1286, 1285, 1284, 2176, 2177, 2212, 1282, 1280, - /* 2340 */ 340, 2178, 704, 2180, 2181, 699, 701, 694, 1279, 1278, - /* 2350 */ 1313, 748, 2177, 308, 1276, 1275, 1274, 1273, 1272, 1271, - /* 2360 */ 1270, 2176, 701, 2212, 1310, 2177, 332, 2178, 704, 2180, - /* 2370 */ 2181, 699, 1308, 694, 2195, 701, 1267, 1266, 1263, 1262, - /* 2380 */ 1261, 1260, 1843, 768, 770, 769, 2145, 1841, 700, 772, - /* 2390 */ 2195, 774, 1839, 1836, 776, 778, 773, 780, 777, 781, - /* 2400 */ 782, 1818, 2145, 2195, 700, 784, 1202, 1795, 311, 788, - /* 2410 */ 1770, 1545, 321, 1770, 792, 2145, 791, 700, 1770, 1770, - /* 2420 */ 1770, 2176, 1770, 2212, 1770, 2177, 345, 2178, 704, 2180, - /* 2430 */ 2181, 699, 1770, 694, 1770, 701, 1770, 2176, 1770, 2212, - /* 2440 */ 1770, 2177, 346, 2178, 704, 2180, 2181, 699, 1770, 694, - /* 2450 */ 2176, 701, 2212, 1770, 2177, 2189, 2178, 704, 2180, 2181, - /* 2460 */ 699, 1770, 694, 2195, 701, 1770, 1770, 1770, 1770, 1770, - /* 2470 */ 1770, 1770, 1770, 1770, 1770, 2145, 1770, 700, 1770, 2195, - /* 2480 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, - /* 2490 */ 1770, 2145, 2195, 700, 1770, 1770, 1770, 1770, 1770, 1770, - /* 2500 */ 1770, 1770, 1770, 1770, 2145, 1770, 700, 1770, 1770, 1770, - /* 2510 */ 2176, 1770, 2212, 1770, 1770, 2188, 2178, 704, 2180, 2181, - /* 2520 */ 699, 1770, 694, 1770, 1770, 1770, 2176, 2177, 2212, 1770, - /* 2530 */ 1770, 2187, 2178, 704, 2180, 2181, 699, 701, 694, 2176, - /* 2540 */ 1770, 2212, 1770, 2177, 361, 2178, 704, 2180, 2181, 699, - /* 2550 */ 1770, 694, 1770, 701, 2177, 1770, 1770, 1770, 1770, 1770, - /* 2560 */ 1770, 1770, 1770, 1770, 701, 2195, 1770, 1770, 1770, 1770, - /* 2570 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 2145, 1770, 700, - /* 2580 */ 1770, 2195, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, - /* 2590 */ 1770, 1770, 2195, 2145, 1770, 700, 1770, 1770, 1770, 1770, - /* 2600 */ 1770, 1770, 1770, 1770, 2145, 1770, 700, 1770, 1770, 1770, - /* 2610 */ 1770, 1770, 2176, 1770, 2212, 1770, 2177, 362, 2178, 704, - /* 2620 */ 2180, 2181, 699, 1770, 694, 1770, 701, 1770, 2176, 1770, - /* 2630 */ 2212, 1770, 2177, 358, 2178, 704, 2180, 2181, 699, 2176, - /* 2640 */ 694, 2212, 701, 1770, 363, 2178, 704, 2180, 2181, 699, - /* 2650 */ 1770, 694, 1770, 1770, 2195, 1770, 1770, 1770, 1770, 1770, - /* 2660 */ 1770, 1770, 1770, 1770, 1770, 1770, 2145, 1770, 700, 1770, - /* 2670 */ 2195, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, - /* 2680 */ 1770, 1770, 2145, 1770, 700, 1770, 1770, 1770, 1770, 1770, - /* 2690 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, - /* 2700 */ 1770, 702, 1770, 2212, 1770, 1770, 337, 2178, 704, 2180, - /* 2710 */ 2181, 699, 1770, 694, 1770, 1770, 1770, 2176, 1770, 2212, - /* 2720 */ 1770, 1770, 336, 2178, 704, 2180, 2181, 699, 1770, 694, + /* 0 */ 2111, 2178, 2156, 2067, 218, 681, 1948, 2139, 528, 1937, + /* 10 */ 1814, 661, 48, 46, 1694, 391, 2164, 1204, 2064, 668, + /* 20 */ 398, 2343, 1543, 41, 40, 132, 2160, 47, 45, 44, + /* 30 */ 43, 42, 565, 1624, 450, 1541, 2156, 530, 1570, 2196, + /* 40 */ 41, 40, 1769, 527, 47, 45, 44, 43, 42, 251, + /* 50 */ 1939, 2146, 1933, 697, 621, 522, 1206, 2338, 1209, 1210, + /* 60 */ 2160, 181, 1619, 520, 2162, 395, 516, 512, 19, 1229, + /* 70 */ 66, 1228, 2344, 188, 691, 1549, 30, 2339, 647, 345, + /* 80 */ 680, 366, 2050, 358, 137, 681, 1948, 2177, 1568, 2213, + /* 90 */ 658, 141, 109, 2179, 701, 2181, 2182, 696, 2162, 691, + /* 100 */ 787, 168, 1230, 15, 185, 132, 2266, 100, 691, 1889, + /* 110 */ 394, 2262, 570, 488, 2067, 413, 48, 46, 681, 1948, + /* 120 */ 412, 680, 1757, 190, 398, 261, 1543, 1653, 1362, 2065, + /* 130 */ 668, 2292, 1941, 1568, 38, 303, 1734, 1624, 193, 1541, + /* 140 */ 1626, 1627, 1794, 1353, 726, 725, 724, 1357, 723, 1359, + /* 150 */ 1360, 722, 719, 1793, 1368, 716, 1370, 1371, 713, 710, + /* 160 */ 707, 184, 621, 51, 646, 2338, 1619, 2338, 91, 62, + /* 170 */ 1599, 1609, 19, 1988, 209, 208, 1625, 1628, 2129, 1549, + /* 180 */ 2344, 188, 645, 188, 1654, 2339, 647, 2339, 647, 2281, + /* 190 */ 285, 1544, 2146, 1542, 283, 2274, 657, 487, 133, 656, + /* 200 */ 169, 2338, 1783, 2146, 787, 41, 40, 15, 2178, 47, + /* 210 */ 45, 44, 43, 42, 62, 2278, 645, 188, 698, 1306, + /* 220 */ 432, 2339, 647, 1547, 1548, 1771, 1598, 1601, 1602, 1603, + /* 230 */ 1604, 1605, 1606, 1607, 1608, 693, 689, 1617, 1618, 1620, + /* 240 */ 1621, 1622, 1623, 2, 1626, 1627, 2196, 434, 430, 131, + /* 250 */ 130, 129, 128, 127, 126, 125, 124, 123, 2146, 1308, + /* 260 */ 697, 1772, 37, 396, 1648, 1649, 1650, 1651, 1652, 1656, + /* 270 */ 1657, 1658, 1659, 525, 1599, 1609, 526, 1807, 666, 1568, + /* 280 */ 1625, 1628, 122, 1452, 1453, 121, 120, 119, 118, 117, + /* 290 */ 116, 115, 114, 113, 2177, 1544, 2213, 1542, 636, 109, + /* 300 */ 2179, 701, 2181, 2182, 696, 2046, 691, 2031, 392, 144, + /* 310 */ 1568, 151, 2237, 2266, 1569, 2178, 166, 394, 2262, 1229, + /* 320 */ 191, 1228, 658, 141, 1950, 661, 191, 1547, 1548, 1691, + /* 330 */ 1598, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 693, + /* 340 */ 689, 1617, 1618, 1620, 1621, 1622, 1623, 2, 12, 48, + /* 350 */ 46, 201, 1230, 2196, 2001, 407, 406, 398, 542, 1543, + /* 360 */ 2343, 364, 62, 2338, 181, 2146, 1570, 697, 2046, 1999, + /* 370 */ 1624, 191, 1541, 583, 582, 581, 681, 1948, 1550, 2342, + /* 380 */ 573, 138, 577, 2339, 2341, 2051, 576, 640, 642, 637, + /* 390 */ 630, 575, 580, 374, 373, 427, 56, 574, 2046, 1619, + /* 400 */ 249, 2177, 620, 2213, 248, 19, 109, 2179, 701, 2181, + /* 410 */ 2182, 696, 1549, 691, 203, 2196, 294, 295, 185, 533, + /* 420 */ 2266, 293, 526, 1807, 394, 2262, 187, 2274, 2275, 2178, + /* 430 */ 139, 2279, 1212, 646, 1397, 1398, 2338, 787, 1567, 698, + /* 440 */ 15, 1816, 41, 40, 207, 2293, 47, 45, 44, 43, + /* 450 */ 42, 645, 188, 48, 46, 1629, 2339, 647, 220, 2178, + /* 460 */ 1600, 398, 528, 1543, 1814, 90, 468, 2196, 353, 698, + /* 470 */ 639, 378, 166, 599, 1624, 467, 1541, 1626, 1627, 2146, + /* 480 */ 1951, 697, 2343, 122, 641, 2338, 121, 120, 119, 118, + /* 490 */ 117, 116, 115, 114, 113, 2001, 62, 2196, 1792, 658, + /* 500 */ 141, 2342, 379, 1619, 1571, 2339, 2340, 1599, 1609, 2146, + /* 510 */ 1999, 697, 106, 1625, 1628, 2177, 1549, 2213, 285, 191, + /* 520 */ 109, 2179, 701, 2181, 2182, 696, 60, 691, 1544, 142, + /* 530 */ 1542, 569, 2358, 618, 2266, 568, 1553, 1940, 394, 2262, + /* 540 */ 1698, 787, 681, 1948, 49, 2177, 1568, 2213, 2146, 2178, + /* 550 */ 170, 2179, 701, 2181, 2182, 696, 12, 691, 10, 698, + /* 560 */ 1547, 1548, 448, 1598, 1601, 1602, 1603, 1604, 1605, 1606, + /* 570 */ 1607, 1608, 693, 689, 1617, 1618, 1620, 1621, 1622, 1623, + /* 580 */ 2, 1626, 1627, 442, 1317, 441, 1690, 2196, 41, 40, + /* 590 */ 622, 2303, 47, 45, 44, 43, 42, 1316, 1791, 2146, + /* 600 */ 1571, 697, 660, 186, 2274, 2275, 165, 139, 2279, 680, + /* 610 */ 1790, 1599, 1609, 681, 1948, 440, 403, 1625, 1628, 1994, + /* 620 */ 1996, 41, 40, 401, 1924, 47, 45, 44, 43, 42, + /* 630 */ 52, 163, 1544, 449, 1542, 2177, 667, 2213, 380, 1950, + /* 640 */ 109, 2179, 701, 2181, 2182, 696, 1999, 691, 2146, 2167, + /* 650 */ 444, 2178, 2241, 191, 2266, 443, 202, 2140, 394, 2262, + /* 660 */ 2146, 698, 497, 2300, 1547, 1548, 736, 1598, 1601, 1602, + /* 670 */ 1603, 1604, 1605, 1606, 1607, 1608, 693, 689, 1617, 1618, + /* 680 */ 1620, 1621, 1622, 1623, 2, 48, 46, 1925, 540, 2196, + /* 690 */ 2060, 736, 51, 398, 1567, 1543, 1600, 621, 658, 141, + /* 700 */ 2338, 2146, 2001, 697, 621, 2169, 1624, 2338, 1541, 388, + /* 710 */ 47, 45, 44, 43, 42, 2344, 188, 1999, 681, 1948, + /* 720 */ 2339, 647, 2344, 188, 44, 43, 42, 2339, 647, 14, + /* 730 */ 13, 1722, 606, 681, 1948, 1619, 12, 2177, 458, 2213, + /* 740 */ 588, 667, 109, 2179, 701, 2181, 2182, 696, 1549, 691, + /* 750 */ 681, 1948, 263, 473, 2358, 598, 2266, 1850, 41, 40, + /* 760 */ 394, 2262, 47, 45, 44, 43, 42, 2178, 1789, 247, + /* 770 */ 474, 1995, 1996, 787, 681, 1948, 49, 695, 633, 632, + /* 780 */ 1720, 1721, 1723, 1724, 1725, 591, 250, 191, 1549, 48, + /* 790 */ 46, 1923, 585, 665, 541, 2060, 1764, 398, 246, 1543, + /* 800 */ 2001, 1569, 189, 2274, 2275, 2196, 139, 2279, 1232, 1233, + /* 810 */ 1624, 2281, 1541, 1626, 1627, 2000, 87, 2146, 2146, 697, + /* 820 */ 734, 156, 155, 731, 730, 729, 153, 583, 582, 581, + /* 830 */ 561, 560, 1667, 368, 573, 138, 577, 2277, 70, 1619, + /* 840 */ 576, 69, 1943, 1599, 1609, 575, 580, 374, 373, 1625, + /* 850 */ 1628, 574, 1549, 2177, 1733, 2213, 1514, 1515, 339, 2179, + /* 860 */ 701, 2181, 2182, 696, 1544, 691, 1542, 2232, 41, 40, + /* 870 */ 1788, 1935, 47, 45, 44, 43, 42, 787, 563, 562, + /* 880 */ 15, 2178, 734, 156, 155, 731, 730, 729, 153, 1787, + /* 890 */ 604, 698, 205, 2313, 1786, 746, 1547, 1548, 1763, 1598, + /* 900 */ 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 693, 689, + /* 910 */ 1617, 1618, 1620, 1621, 1622, 1623, 2, 1626, 1627, 2196, + /* 920 */ 2146, 1469, 1470, 597, 734, 156, 155, 731, 730, 729, + /* 930 */ 153, 2146, 84, 697, 2001, 83, 595, 621, 593, 2146, + /* 940 */ 2338, 393, 681, 1948, 2146, 681, 1948, 1599, 1609, 1999, + /* 950 */ 1931, 681, 1948, 1625, 1628, 2344, 188, 1468, 1471, 1952, + /* 960 */ 2339, 647, 1945, 143, 1710, 252, 2237, 2177, 1544, 2213, + /* 970 */ 1542, 260, 109, 2179, 701, 2181, 2182, 696, 9, 691, + /* 980 */ 579, 578, 34, 1785, 2358, 1321, 2266, 667, 41, 40, + /* 990 */ 394, 2262, 47, 45, 44, 43, 42, 1782, 1320, 2342, + /* 1000 */ 1547, 1548, 1847, 1598, 1601, 1602, 1603, 1604, 1605, 1606, + /* 1010 */ 1607, 1608, 693, 689, 1617, 1618, 1620, 1621, 1622, 1623, + /* 1020 */ 2, 1634, 349, 167, 1566, 681, 1948, 1568, 324, 681, + /* 1030 */ 1948, 481, 728, 2146, 495, 1992, 571, 494, 2156, 676, + /* 1040 */ 401, 2060, 321, 73, 2001, 664, 72, 2146, 166, 298, + /* 1050 */ 1571, 402, 2165, 464, 662, 496, 1950, 346, 1304, 1999, + /* 1060 */ 466, 1781, 2160, 499, 1780, 758, 756, 1779, 216, 507, + /* 1070 */ 505, 502, 764, 763, 762, 761, 410, 572, 760, 759, + /* 1080 */ 145, 754, 753, 752, 751, 750, 749, 748, 158, 744, + /* 1090 */ 743, 742, 409, 408, 739, 738, 737, 176, 175, 1302, + /* 1100 */ 2162, 621, 681, 1948, 2338, 404, 367, 234, 62, 371, + /* 1110 */ 691, 2146, 2281, 166, 2146, 681, 1948, 2146, 454, 2344, + /* 1120 */ 188, 1950, 678, 173, 2339, 647, 681, 1948, 650, 681, + /* 1130 */ 1948, 559, 555, 551, 547, 679, 233, 1778, 2276, 683, + /* 1140 */ 1655, 2238, 87, 2132, 1777, 1776, 304, 108, 492, 405, + /* 1150 */ 154, 486, 485, 484, 483, 480, 479, 478, 477, 476, + /* 1160 */ 472, 471, 470, 469, 348, 461, 460, 459, 1944, 456, + /* 1170 */ 455, 365, 685, 54, 2238, 3, 88, 1600, 372, 231, + /* 1180 */ 370, 369, 147, 567, 134, 1775, 1774, 2146, 81, 80, + /* 1190 */ 447, 2178, 420, 200, 2146, 2146, 732, 733, 1687, 1992, + /* 1200 */ 1992, 698, 262, 628, 653, 569, 439, 437, 317, 568, + /* 1210 */ 55, 1978, 747, 1209, 1210, 1910, 74, 347, 35, 1926, + /* 1220 */ 428, 1552, 2178, 426, 422, 418, 415, 440, 1660, 2196, + /* 1230 */ 2286, 1687, 698, 451, 2331, 2146, 2146, 239, 154, 241, + /* 1240 */ 237, 2146, 240, 697, 688, 154, 452, 230, 224, 1834, + /* 1250 */ 1766, 1767, 2178, 243, 229, 538, 242, 1551, 245, 1825, + /* 1260 */ 2196, 244, 698, 149, 2285, 191, 82, 601, 50, 600, + /* 1270 */ 50, 584, 2146, 222, 697, 1823, 649, 2177, 105, 2213, + /* 1280 */ 727, 586, 109, 2179, 701, 2181, 2182, 696, 102, 691, + /* 1290 */ 2196, 267, 14, 13, 2358, 1263, 2266, 589, 1509, 154, + /* 1300 */ 394, 2262, 2146, 256, 697, 1512, 1817, 50, 2177, 692, + /* 1310 */ 2213, 740, 741, 109, 2179, 701, 2181, 2182, 696, 1890, + /* 1320 */ 691, 291, 71, 259, 1543, 2358, 152, 2266, 1719, 154, + /* 1330 */ 1718, 394, 2262, 1282, 1280, 1264, 64, 1541, 2177, 1784, + /* 1340 */ 2213, 2306, 2178, 109, 2179, 701, 2181, 2182, 696, 50, + /* 1350 */ 691, 269, 698, 407, 406, 2358, 782, 2266, 36, 663, + /* 1360 */ 280, 394, 2262, 1557, 41, 40, 651, 1466, 47, 45, + /* 1370 */ 44, 43, 42, 2178, 1624, 634, 1550, 1549, 136, 1555, + /* 1380 */ 2196, 296, 673, 698, 274, 1888, 300, 1887, 2197, 1347, + /* 1390 */ 411, 381, 2146, 50, 697, 705, 1661, 152, 154, 1645, + /* 1400 */ 2055, 1808, 787, 1619, 1813, 1989, 659, 2296, 282, 1610, + /* 1410 */ 2178, 2196, 135, 152, 279, 1554, 1549, 1, 5, 419, + /* 1420 */ 698, 362, 414, 2146, 1574, 697, 435, 196, 2177, 436, + /* 1430 */ 2213, 1490, 438, 109, 2179, 701, 2181, 2182, 696, 195, + /* 1440 */ 691, 687, 198, 311, 654, 2239, 453, 2266, 2196, 206, + /* 1450 */ 1571, 394, 2262, 316, 457, 1375, 2056, 1379, 1386, 2177, + /* 1460 */ 2146, 2213, 697, 490, 109, 2179, 701, 2181, 2182, 696, + /* 1470 */ 1566, 691, 1384, 157, 462, 475, 684, 2048, 2266, 482, + /* 1480 */ 500, 489, 394, 2262, 491, 501, 498, 211, 210, 503, + /* 1490 */ 504, 213, 506, 1544, 508, 1542, 2177, 1572, 2213, 2178, + /* 1500 */ 523, 110, 2179, 701, 2181, 2182, 696, 4, 691, 698, + /* 1510 */ 524, 532, 531, 534, 221, 2266, 1569, 535, 223, 2265, + /* 1520 */ 2262, 1573, 536, 1575, 537, 1547, 1548, 564, 543, 539, + /* 1530 */ 226, 228, 1558, 85, 1553, 111, 352, 2196, 86, 232, + /* 1540 */ 566, 1938, 603, 2120, 236, 2117, 1934, 89, 2178, 2146, + /* 1550 */ 1497, 697, 238, 605, 609, 312, 150, 253, 698, 610, + /* 1560 */ 159, 160, 1936, 608, 1561, 1563, 1932, 161, 162, 255, + /* 1570 */ 257, 614, 635, 616, 2178, 2312, 671, 689, 1617, 1618, + /* 1580 */ 1620, 1621, 1622, 1623, 695, 2177, 2196, 2213, 2116, 613, + /* 1590 */ 110, 2179, 701, 2181, 2182, 696, 2297, 691, 2146, 2307, + /* 1600 */ 697, 625, 615, 631, 2266, 265, 384, 638, 686, 2262, + /* 1610 */ 268, 8, 2196, 644, 2311, 2288, 174, 273, 626, 385, + /* 1620 */ 624, 623, 2361, 655, 2146, 2178, 697, 140, 652, 1570, + /* 1630 */ 278, 1687, 178, 1576, 699, 698, 2213, 2282, 2178, 110, + /* 1640 */ 2179, 701, 2181, 2182, 696, 286, 691, 95, 698, 2061, + /* 1650 */ 313, 1949, 669, 2266, 314, 670, 276, 357, 2262, 2075, + /* 1660 */ 2177, 2074, 2213, 2196, 2073, 339, 2179, 701, 2181, 2182, + /* 1670 */ 696, 694, 691, 682, 2231, 2146, 2196, 697, 390, 674, + /* 1680 */ 275, 277, 2337, 97, 281, 315, 675, 2178, 2146, 61, + /* 1690 */ 697, 101, 99, 1911, 703, 2247, 783, 698, 1993, 322, + /* 1700 */ 318, 307, 354, 784, 2178, 786, 320, 2138, 53, 327, + /* 1710 */ 341, 2177, 78, 2213, 698, 2137, 171, 2179, 701, 2181, + /* 1720 */ 2182, 696, 355, 691, 2177, 2196, 2213, 2136, 2133, 110, + /* 1730 */ 2179, 701, 2181, 2182, 696, 342, 691, 2146, 331, 697, + /* 1740 */ 416, 417, 2196, 2266, 1534, 1535, 194, 382, 2263, 421, + /* 1750 */ 2131, 423, 424, 2178, 2146, 425, 697, 2130, 363, 2128, + /* 1760 */ 429, 2127, 431, 698, 2126, 433, 1525, 648, 2359, 2107, + /* 1770 */ 197, 2106, 199, 2177, 79, 2213, 1493, 2178, 170, 2179, + /* 1780 */ 701, 2181, 2182, 696, 1492, 691, 2088, 698, 2087, 2086, + /* 1790 */ 2177, 2196, 2213, 445, 446, 340, 2179, 701, 2181, 2182, + /* 1800 */ 696, 2085, 691, 2146, 2178, 697, 2084, 1443, 2039, 2038, + /* 1810 */ 2036, 2035, 146, 2034, 698, 2196, 2037, 2033, 2032, 2304, + /* 1820 */ 383, 2030, 2029, 2028, 2178, 204, 463, 2146, 2027, 697, + /* 1830 */ 465, 2041, 2026, 2025, 698, 2024, 2023, 2022, 2021, 2177, + /* 1840 */ 148, 2213, 2196, 2020, 333, 2179, 701, 2181, 2182, 696, + /* 1850 */ 2019, 691, 2018, 2017, 2146, 2016, 697, 2015, 2014, 2013, + /* 1860 */ 2012, 2011, 2196, 2177, 2010, 2213, 2009, 389, 340, 2179, + /* 1870 */ 701, 2181, 2182, 696, 2146, 691, 697, 493, 1445, 2006, + /* 1880 */ 2005, 2004, 2003, 2002, 1318, 1322, 1853, 643, 2040, 2008, + /* 1890 */ 2177, 2178, 2213, 2007, 350, 171, 2179, 701, 2181, 2182, + /* 1900 */ 696, 698, 691, 212, 1314, 1852, 214, 1851, 1849, 215, + /* 1910 */ 2177, 1846, 2213, 351, 511, 340, 2179, 701, 2181, 2182, + /* 1920 */ 696, 2178, 691, 510, 1845, 509, 513, 514, 1838, 2196, + /* 1930 */ 517, 698, 1827, 515, 397, 519, 518, 1803, 521, 217, + /* 1940 */ 76, 2146, 182, 697, 1211, 1802, 2166, 2360, 2105, 219, + /* 1950 */ 2095, 183, 77, 529, 2083, 225, 227, 2082, 2059, 2196, + /* 1960 */ 1927, 1256, 1848, 1844, 399, 546, 544, 545, 1842, 548, + /* 1970 */ 549, 2146, 550, 697, 552, 554, 553, 2177, 1840, 2213, + /* 1980 */ 2178, 1837, 340, 2179, 701, 2181, 2182, 696, 607, 691, + /* 1990 */ 698, 556, 557, 1822, 558, 1820, 1821, 1819, 1799, 1929, + /* 2000 */ 1391, 1390, 1928, 755, 1305, 1303, 790, 2177, 1301, 2213, + /* 2010 */ 235, 1300, 340, 2179, 701, 2181, 2182, 696, 2196, 691, + /* 2020 */ 310, 1299, 63, 1298, 757, 1297, 1294, 1293, 1292, 1291, + /* 2030 */ 2146, 1835, 697, 375, 1826, 376, 180, 1824, 377, 590, + /* 2040 */ 1798, 1797, 1796, 592, 780, 776, 772, 768, 596, 308, + /* 2050 */ 594, 587, 112, 2178, 1519, 1521, 1518, 1523, 2104, 1499, + /* 2060 */ 1501, 2094, 164, 698, 29, 1503, 602, 67, 2213, 611, + /* 2070 */ 2081, 335, 2179, 701, 2181, 2182, 696, 2080, 691, 20, + /* 2080 */ 31, 2343, 629, 17, 2178, 264, 57, 612, 1736, 107, + /* 2090 */ 617, 2196, 301, 258, 698, 1478, 6, 1477, 619, 7, + /* 2100 */ 21, 22, 627, 2146, 271, 697, 272, 266, 33, 1717, + /* 2110 */ 2167, 65, 172, 270, 1751, 32, 24, 1750, 1709, 2178, + /* 2120 */ 92, 386, 2196, 1755, 1754, 677, 1756, 1757, 387, 698, + /* 2130 */ 284, 1684, 1683, 2079, 2146, 23, 697, 18, 59, 2177, + /* 2140 */ 2058, 2213, 58, 177, 325, 2179, 701, 2181, 2182, 696, + /* 2150 */ 94, 691, 93, 289, 290, 25, 2178, 2196, 2057, 1715, + /* 2160 */ 288, 96, 302, 26, 13, 292, 698, 287, 297, 2146, + /* 2170 */ 2177, 697, 2213, 1559, 68, 323, 2179, 701, 2181, 2182, + /* 2180 */ 696, 2178, 691, 98, 2216, 1636, 254, 102, 1635, 11, + /* 2190 */ 1646, 698, 179, 672, 2196, 1614, 1612, 192, 299, 1611, + /* 2200 */ 690, 39, 16, 27, 28, 2177, 2146, 2213, 697, 1583, + /* 2210 */ 326, 2179, 701, 2181, 2182, 696, 1591, 691, 2178, 2196, + /* 2220 */ 1376, 702, 704, 400, 706, 708, 711, 709, 698, 1373, + /* 2230 */ 1372, 2146, 712, 697, 1369, 714, 1363, 715, 717, 718, + /* 2240 */ 720, 1361, 2177, 2178, 2213, 721, 103, 332, 2179, 701, + /* 2250 */ 2181, 2182, 696, 698, 691, 700, 2196, 305, 104, 1385, + /* 2260 */ 1367, 1381, 75, 1366, 1365, 1254, 1364, 2177, 2146, 2213, + /* 2270 */ 697, 1286, 336, 2179, 701, 2181, 2182, 696, 735, 691, + /* 2280 */ 1285, 2196, 1284, 1283, 1281, 1279, 1278, 1277, 1272, 1312, + /* 2290 */ 745, 1275, 1274, 2146, 1273, 697, 1271, 306, 1270, 1269, + /* 2300 */ 1309, 1260, 1307, 1266, 2177, 1265, 2213, 1262, 1261, 328, + /* 2310 */ 2179, 701, 2181, 2182, 696, 2178, 691, 1259, 1843, 765, + /* 2320 */ 766, 1841, 767, 769, 770, 698, 771, 1839, 773, 2177, + /* 2330 */ 2178, 2213, 1836, 777, 337, 2179, 701, 2181, 2182, 696, + /* 2340 */ 698, 691, 775, 774, 778, 779, 1818, 781, 2178, 1201, + /* 2350 */ 1795, 309, 1545, 2196, 785, 789, 319, 788, 698, 1770, + /* 2360 */ 1770, 1770, 1770, 1770, 1770, 2146, 1770, 697, 2196, 1770, + /* 2370 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2380 */ 2146, 1770, 697, 1770, 1770, 1770, 2196, 1770, 1770, 1770, + /* 2390 */ 1770, 1770, 1770, 1770, 1770, 2178, 1770, 1770, 2146, 1770, + /* 2400 */ 697, 2177, 1770, 2213, 1770, 698, 329, 2179, 701, 2181, + /* 2410 */ 2182, 696, 1770, 691, 1770, 1770, 2177, 2178, 2213, 1770, + /* 2420 */ 1770, 338, 2179, 701, 2181, 2182, 696, 698, 691, 1770, + /* 2430 */ 1770, 1770, 1770, 2196, 2177, 1770, 2213, 1770, 1770, 330, + /* 2440 */ 2179, 701, 2181, 2182, 696, 2146, 691, 697, 1770, 1770, + /* 2450 */ 1770, 1770, 1770, 1770, 1770, 2196, 1770, 1770, 1770, 1770, + /* 2460 */ 1770, 1770, 1770, 1770, 2178, 1770, 1770, 2146, 1770, 697, + /* 2470 */ 1770, 1770, 1770, 1770, 698, 1770, 1770, 1770, 1770, 1770, + /* 2480 */ 1770, 2177, 1770, 2213, 1770, 1770, 343, 2179, 701, 2181, + /* 2490 */ 2182, 696, 1770, 691, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2500 */ 1770, 1770, 2196, 2177, 1770, 2213, 1770, 1770, 344, 2179, + /* 2510 */ 701, 2181, 2182, 696, 2146, 691, 697, 1770, 1770, 1770, + /* 2520 */ 1770, 1770, 1770, 2178, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2530 */ 1770, 1770, 1770, 698, 1770, 1770, 2178, 1770, 1770, 1770, + /* 2540 */ 1770, 1770, 1770, 1770, 1770, 1770, 698, 1770, 1770, 1770, + /* 2550 */ 2177, 1770, 2213, 2178, 1770, 2190, 2179, 701, 2181, 2182, + /* 2560 */ 696, 2196, 691, 698, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2570 */ 1770, 1770, 1770, 2146, 2196, 697, 1770, 1770, 1770, 1770, + /* 2580 */ 1770, 1770, 1770, 1770, 1770, 2178, 2146, 1770, 697, 1770, + /* 2590 */ 1770, 2196, 1770, 1770, 1770, 698, 1770, 1770, 1770, 1770, + /* 2600 */ 1770, 1770, 1770, 2146, 1770, 697, 1770, 1770, 1770, 2177, + /* 2610 */ 1770, 2213, 1770, 1770, 2189, 2179, 701, 2181, 2182, 696, + /* 2620 */ 1770, 691, 2177, 2196, 2213, 1770, 1770, 2188, 2179, 701, + /* 2630 */ 2181, 2182, 696, 1770, 691, 2146, 1770, 697, 1770, 2177, + /* 2640 */ 1770, 2213, 1770, 1770, 359, 2179, 701, 2181, 2182, 696, + /* 2650 */ 1770, 691, 2178, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2660 */ 1770, 1770, 698, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2670 */ 1770, 2177, 2178, 2213, 1770, 1770, 360, 2179, 701, 2181, + /* 2680 */ 2182, 696, 698, 691, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2690 */ 2196, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2700 */ 1770, 1770, 2146, 1770, 697, 1770, 1770, 1770, 1770, 1770, + /* 2710 */ 2196, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2720 */ 1770, 1770, 2146, 1770, 697, 1770, 1770, 1770, 1770, 1770, + /* 2730 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 2177, 1770, + /* 2740 */ 2213, 1770, 2178, 356, 2179, 701, 2181, 2182, 696, 1770, + /* 2750 */ 691, 1770, 698, 1770, 1770, 1770, 1770, 1770, 2177, 2178, + /* 2760 */ 2213, 1770, 1770, 361, 2179, 701, 2181, 2182, 696, 698, + /* 2770 */ 691, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2780 */ 2196, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2790 */ 1770, 1770, 2146, 1770, 697, 1770, 1770, 2196, 1770, 1770, + /* 2800 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 2146, + /* 2810 */ 1770, 697, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, + /* 2820 */ 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770, 699, 1770, + /* 2830 */ 2213, 1770, 1770, 335, 2179, 701, 2181, 2182, 696, 1770, + /* 2840 */ 691, 1770, 1770, 1770, 1770, 2177, 1770, 2213, 1770, 1770, + /* 2850 */ 334, 2179, 701, 2181, 2182, 696, 1770, 691, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 340, 392, 339, 345, 341, 349, 409, 349, 409, 351, - /* 10 */ 350, 414, 12, 13, 14, 379, 407, 408, 456, 340, - /* 20 */ 20, 459, 22, 8, 9, 12, 13, 12, 13, 14, - /* 30 */ 15, 16, 441, 33, 443, 35, 474, 475, 378, 8, - /* 40 */ 9, 479, 480, 12, 13, 14, 15, 16, 35, 409, - /* 50 */ 390, 20, 392, 456, 20, 456, 459, 401, 459, 403, - /* 60 */ 340, 378, 62, 12, 13, 14, 15, 16, 68, 390, - /* 70 */ 350, 474, 475, 474, 475, 75, 479, 480, 479, 480, - /* 80 */ 345, 398, 399, 68, 349, 425, 351, 427, 356, 377, - /* 90 */ 430, 431, 432, 433, 434, 435, 456, 437, 378, 459, - /* 100 */ 100, 389, 442, 103, 444, 373, 358, 350, 448, 449, - /* 110 */ 390, 340, 392, 381, 474, 475, 12, 13, 392, 479, - /* 120 */ 480, 461, 366, 375, 20, 456, 22, 112, 459, 469, - /* 130 */ 404, 20, 384, 407, 408, 378, 380, 33, 62, 35, - /* 140 */ 140, 141, 349, 22, 475, 425, 390, 427, 479, 480, - /* 150 */ 430, 431, 432, 433, 434, 435, 35, 437, 20, 370, - /* 160 */ 440, 390, 442, 443, 444, 378, 62, 378, 448, 449, - /* 170 */ 170, 171, 68, 378, 385, 386, 176, 177, 102, 75, - /* 180 */ 385, 105, 393, 427, 169, 0, 399, 394, 393, 432, - /* 190 */ 190, 21, 192, 437, 24, 25, 26, 27, 28, 29, - /* 200 */ 30, 31, 32, 172, 100, 192, 21, 103, 340, 24, - /* 210 */ 25, 26, 27, 28, 29, 30, 31, 32, 350, 20, - /* 220 */ 352, 100, 222, 223, 0, 225, 226, 227, 228, 229, + /* 0 */ 375, 341, 367, 393, 346, 350, 351, 411, 350, 380, + /* 10 */ 352, 351, 12, 13, 14, 405, 381, 4, 408, 409, + /* 20 */ 20, 3, 22, 8, 9, 370, 391, 12, 13, 14, + /* 30 */ 15, 16, 377, 33, 350, 35, 367, 14, 20, 379, + /* 40 */ 8, 9, 338, 20, 12, 13, 14, 15, 16, 424, + /* 50 */ 381, 391, 380, 393, 458, 49, 43, 461, 45, 46, + /* 60 */ 391, 379, 62, 57, 429, 430, 60, 61, 68, 20, + /* 70 */ 4, 22, 476, 477, 439, 75, 44, 481, 482, 395, + /* 80 */ 20, 399, 400, 68, 35, 350, 351, 427, 20, 429, + /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 429, 439, + /* 100 */ 100, 360, 53, 103, 444, 370, 446, 357, 439, 368, + /* 110 */ 450, 451, 377, 84, 393, 411, 12, 13, 350, 351, + /* 120 */ 416, 20, 104, 463, 20, 62, 22, 112, 100, 408, + /* 130 */ 409, 471, 382, 20, 447, 448, 104, 33, 370, 35, + /* 140 */ 140, 141, 341, 115, 116, 117, 118, 119, 120, 121, + /* 150 */ 122, 123, 124, 341, 126, 127, 128, 129, 130, 131, + /* 160 */ 132, 378, 458, 103, 458, 461, 62, 461, 105, 103, + /* 170 */ 170, 171, 68, 390, 145, 146, 176, 177, 0, 75, + /* 180 */ 476, 477, 476, 477, 169, 481, 482, 481, 482, 431, + /* 190 */ 172, 191, 391, 193, 454, 455, 456, 168, 458, 459, + /* 200 */ 340, 461, 342, 391, 100, 8, 9, 103, 341, 12, + /* 210 */ 13, 14, 15, 16, 103, 457, 476, 477, 351, 35, + /* 220 */ 186, 481, 482, 223, 224, 0, 226, 227, 228, 229, /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 240 */ 240, 241, 242, 20, 140, 141, 378, 340, 24, 25, - /* 250 */ 26, 27, 28, 29, 30, 31, 32, 349, 390, 103, - /* 260 */ 392, 246, 247, 248, 249, 250, 251, 252, 253, 254, - /* 270 */ 255, 256, 445, 446, 170, 171, 20, 62, 140, 141, - /* 280 */ 176, 177, 4, 20, 8, 9, 349, 350, 12, 13, - /* 290 */ 14, 15, 16, 425, 190, 427, 192, 390, 430, 431, - /* 300 */ 432, 433, 434, 435, 344, 437, 369, 347, 348, 401, - /* 310 */ 442, 403, 444, 376, 20, 340, 448, 449, 103, 20, - /* 320 */ 105, 43, 14, 45, 46, 350, 222, 223, 20, 225, + /* 240 */ 240, 241, 242, 243, 140, 141, 379, 213, 214, 24, + /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 75, + /* 260 */ 393, 0, 247, 248, 249, 250, 251, 252, 253, 254, + /* 270 */ 255, 256, 257, 345, 170, 171, 348, 349, 20, 20, + /* 280 */ 176, 177, 21, 170, 171, 24, 25, 26, 27, 28, + /* 290 */ 29, 30, 31, 32, 427, 191, 429, 193, 175, 432, + /* 300 */ 433, 434, 435, 436, 437, 351, 439, 0, 371, 442, + /* 310 */ 20, 444, 445, 446, 20, 341, 379, 450, 451, 20, + /* 320 */ 260, 22, 350, 351, 387, 351, 260, 223, 224, 4, /* 330 */ 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - /* 340 */ 236, 237, 238, 239, 240, 241, 242, 243, 12, 13, - /* 350 */ 243, 175, 245, 378, 370, 20, 20, 388, 22, 100, - /* 360 */ 391, 392, 378, 37, 67, 390, 103, 392, 349, 33, - /* 370 */ 386, 35, 349, 350, 115, 116, 117, 118, 119, 120, - /* 380 */ 121, 122, 123, 124, 0, 126, 127, 128, 129, 130, - /* 390 */ 131, 132, 369, 340, 39, 429, 349, 350, 62, 376, - /* 400 */ 425, 340, 427, 350, 68, 430, 431, 432, 433, 434, - /* 410 */ 435, 75, 437, 3, 20, 259, 22, 442, 0, 444, - /* 420 */ 401, 455, 403, 448, 449, 134, 170, 349, 350, 35, - /* 430 */ 20, 378, 106, 49, 108, 109, 100, 111, 103, 103, - /* 440 */ 264, 265, 266, 390, 469, 392, 20, 53, 70, 71, - /* 450 */ 72, 390, 12, 13, 14, 77, 78, 79, 182, 133, - /* 460 */ 20, 83, 22, 137, 170, 171, 88, 89, 90, 91, - /* 470 */ 114, 222, 94, 33, 259, 35, 140, 141, 425, 429, - /* 480 */ 427, 391, 392, 430, 431, 432, 433, 434, 435, 436, - /* 490 */ 437, 438, 439, 344, 203, 204, 347, 348, 340, 452, - /* 500 */ 453, 454, 62, 456, 457, 455, 170, 171, 350, 20, - /* 510 */ 352, 22, 176, 177, 104, 75, 349, 350, 269, 270, - /* 520 */ 271, 272, 273, 274, 275, 84, 190, 67, 192, 451, - /* 530 */ 452, 453, 454, 49, 456, 457, 378, 1, 2, 20, - /* 540 */ 100, 57, 53, 103, 60, 61, 349, 350, 390, 340, - /* 550 */ 392, 133, 134, 135, 136, 137, 138, 139, 222, 223, - /* 560 */ 284, 225, 226, 227, 228, 229, 230, 231, 232, 233, - /* 570 */ 234, 235, 236, 237, 238, 239, 240, 241, 242, 13, - /* 580 */ 140, 141, 172, 425, 3, 427, 145, 146, 430, 431, - /* 590 */ 432, 433, 434, 435, 259, 437, 243, 378, 172, 390, - /* 600 */ 442, 35, 444, 356, 385, 340, 448, 449, 374, 168, - /* 610 */ 170, 171, 393, 258, 21, 350, 176, 177, 0, 452, - /* 620 */ 453, 454, 103, 456, 457, 4, 459, 34, 381, 36, - /* 630 */ 190, 185, 192, 133, 134, 135, 136, 137, 138, 139, - /* 640 */ 104, 474, 475, 378, 349, 350, 479, 480, 337, 452, - /* 650 */ 453, 454, 75, 456, 457, 390, 422, 392, 212, 213, - /* 660 */ 0, 409, 222, 223, 369, 225, 226, 227, 228, 229, - /* 670 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 680 */ 240, 241, 242, 12, 13, 67, 359, 54, 55, 103, - /* 690 */ 425, 20, 427, 22, 367, 430, 431, 432, 433, 434, - /* 700 */ 435, 13, 437, 378, 33, 366, 35, 442, 456, 444, - /* 710 */ 385, 459, 33, 448, 449, 14, 15, 16, 393, 380, - /* 720 */ 409, 22, 22, 35, 103, 414, 474, 475, 49, 390, - /* 730 */ 340, 479, 480, 62, 35, 35, 57, 58, 59, 60, - /* 740 */ 350, 62, 441, 340, 443, 366, 75, 8, 9, 35, - /* 750 */ 2, 12, 13, 14, 15, 16, 8, 9, 35, 380, - /* 760 */ 12, 13, 14, 15, 16, 0, 427, 456, 378, 390, - /* 770 */ 459, 100, 349, 350, 103, 75, 437, 114, 259, 340, - /* 780 */ 390, 102, 392, 44, 105, 474, 475, 12, 13, 75, - /* 790 */ 479, 480, 369, 390, 340, 20, 20, 22, 75, 100, - /* 800 */ 100, 340, 354, 355, 350, 75, 427, 428, 33, 44, - /* 810 */ 35, 140, 141, 349, 350, 425, 437, 427, 20, 159, - /* 820 */ 430, 431, 432, 433, 434, 435, 379, 437, 168, 390, - /* 830 */ 354, 355, 378, 369, 444, 349, 350, 62, 448, 449, - /* 840 */ 20, 170, 171, 104, 390, 259, 392, 176, 177, 350, - /* 850 */ 75, 390, 173, 174, 133, 369, 379, 178, 137, 180, - /* 860 */ 279, 190, 440, 192, 135, 443, 8, 9, 139, 340, - /* 870 */ 12, 13, 14, 15, 16, 100, 14, 198, 103, 425, - /* 880 */ 259, 427, 20, 350, 430, 431, 432, 433, 434, 435, - /* 890 */ 190, 437, 192, 222, 223, 396, 225, 226, 227, 228, - /* 900 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - /* 910 */ 239, 240, 241, 242, 379, 140, 141, 363, 364, 390, - /* 920 */ 349, 350, 222, 223, 470, 471, 379, 378, 199, 396, - /* 930 */ 429, 202, 350, 370, 205, 18, 207, 20, 140, 141, - /* 940 */ 369, 378, 393, 340, 27, 170, 171, 30, 172, 386, - /* 950 */ 33, 176, 177, 350, 379, 352, 455, 349, 350, 349, - /* 960 */ 350, 456, 104, 14, 459, 190, 49, 192, 51, 20, - /* 970 */ 340, 349, 350, 56, 176, 177, 2, 369, 396, 369, - /* 980 */ 475, 378, 8, 9, 479, 480, 12, 13, 14, 15, - /* 990 */ 16, 369, 172, 390, 379, 392, 387, 222, 223, 390, - /* 1000 */ 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - /* 1010 */ 235, 236, 237, 238, 239, 240, 241, 242, 0, 102, - /* 1020 */ 390, 378, 349, 350, 349, 350, 349, 350, 425, 386, - /* 1030 */ 427, 114, 170, 430, 431, 432, 433, 434, 435, 42, - /* 1040 */ 437, 44, 369, 415, 369, 442, 369, 444, 367, 8, - /* 1050 */ 9, 448, 449, 12, 13, 14, 15, 16, 134, 135, - /* 1060 */ 0, 144, 400, 139, 147, 148, 149, 150, 151, 152, - /* 1070 */ 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - /* 1080 */ 163, 409, 165, 166, 167, 4, 340, 14, 70, 71, - /* 1090 */ 72, 73, 74, 20, 76, 77, 78, 79, 80, 81, - /* 1100 */ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - /* 1110 */ 92, 93, 94, 95, 96, 18, 0, 22, 8, 9, - /* 1120 */ 23, 169, 12, 13, 14, 15, 16, 358, 456, 340, - /* 1130 */ 35, 459, 341, 378, 37, 38, 390, 44, 41, 350, - /* 1140 */ 385, 352, 340, 363, 364, 104, 474, 475, 393, 52, - /* 1150 */ 483, 479, 480, 384, 349, 350, 103, 472, 349, 350, - /* 1160 */ 63, 64, 65, 66, 353, 340, 0, 378, 340, 68, - /* 1170 */ 378, 349, 350, 387, 369, 350, 390, 385, 369, 390, - /* 1180 */ 366, 392, 349, 350, 340, 393, 70, 71, 72, 349, - /* 1190 */ 350, 369, 390, 77, 78, 79, 340, 104, 246, 83, - /* 1200 */ 103, 44, 369, 378, 88, 89, 90, 91, 256, 369, - /* 1210 */ 94, 466, 45, 46, 425, 390, 427, 392, 390, 430, - /* 1220 */ 431, 432, 433, 434, 435, 340, 437, 44, 340, 349, - /* 1230 */ 350, 442, 366, 444, 390, 340, 353, 448, 449, 142, - /* 1240 */ 340, 340, 189, 170, 191, 350, 390, 352, 456, 369, - /* 1250 */ 425, 459, 427, 257, 258, 430, 431, 432, 433, 434, - /* 1260 */ 435, 370, 437, 349, 350, 387, 474, 475, 390, 378, - /* 1270 */ 378, 479, 480, 378, 221, 390, 216, 386, 390, 182, - /* 1280 */ 183, 184, 172, 369, 187, 390, 340, 392, 62, 371, - /* 1290 */ 390, 390, 374, 206, 400, 208, 350, 200, 201, 133, - /* 1300 */ 134, 135, 136, 137, 138, 139, 481, 482, 211, 340, - /* 1310 */ 365, 214, 259, 368, 217, 218, 219, 220, 221, 350, - /* 1320 */ 425, 352, 427, 222, 378, 430, 431, 432, 433, 434, - /* 1330 */ 435, 105, 437, 42, 114, 44, 390, 442, 392, 444, - /* 1340 */ 0, 260, 0, 448, 449, 12, 13, 378, 107, 107, - /* 1350 */ 107, 110, 110, 110, 107, 22, 259, 110, 48, 390, - /* 1360 */ 340, 392, 22, 44, 22, 0, 33, 44, 35, 44, - /* 1370 */ 350, 425, 44, 427, 44, 44, 430, 431, 432, 433, - /* 1380 */ 434, 435, 44, 437, 164, 8, 9, 22, 44, 12, - /* 1390 */ 13, 14, 15, 16, 425, 62, 427, 35, 378, 430, - /* 1400 */ 431, 432, 433, 434, 435, 44, 437, 44, 75, 35, - /* 1410 */ 390, 442, 392, 444, 140, 141, 44, 448, 449, 473, - /* 1420 */ 340, 1, 2, 104, 44, 44, 44, 104, 44, 104, - /* 1430 */ 350, 44, 104, 100, 104, 104, 47, 44, 281, 13, - /* 1440 */ 44, 13, 104, 44, 0, 425, 103, 427, 104, 340, - /* 1450 */ 430, 431, 432, 433, 434, 435, 113, 437, 378, 350, - /* 1460 */ 348, 35, 442, 35, 444, 104, 283, 104, 448, 449, - /* 1470 */ 390, 350, 392, 389, 400, 458, 104, 476, 450, 460, - /* 1480 */ 261, 410, 172, 49, 104, 104, 104, 378, 104, 426, - /* 1490 */ 20, 104, 103, 205, 50, 419, 424, 104, 358, 390, - /* 1500 */ 104, 392, 419, 104, 358, 425, 188, 427, 412, 42, - /* 1510 */ 430, 431, 432, 433, 434, 435, 397, 437, 20, 397, - /* 1520 */ 400, 169, 442, 190, 444, 192, 395, 20, 448, 449, - /* 1530 */ 349, 349, 397, 395, 425, 362, 427, 395, 101, 430, - /* 1540 */ 431, 432, 433, 434, 435, 99, 437, 4, 361, 349, - /* 1550 */ 98, 360, 349, 444, 192, 222, 223, 448, 449, 349, - /* 1560 */ 349, 20, 19, 342, 48, 340, 192, 419, 235, 236, - /* 1570 */ 237, 238, 239, 240, 241, 350, 33, 346, 342, 346, - /* 1580 */ 358, 20, 392, 20, 20, 358, 351, 411, 358, 351, - /* 1590 */ 358, 340, 49, 349, 342, 358, 378, 358, 358, 56, - /* 1600 */ 342, 350, 378, 378, 349, 62, 378, 378, 423, 209, - /* 1610 */ 421, 103, 378, 390, 419, 390, 356, 392, 196, 418, - /* 1620 */ 195, 417, 356, 378, 378, 340, 378, 378, 378, 378, - /* 1630 */ 194, 378, 416, 349, 268, 350, 465, 267, 468, 465, - /* 1640 */ 276, 390, 181, 392, 390, 102, 390, 467, 105, 392, - /* 1650 */ 425, 465, 427, 390, 278, 430, 431, 432, 433, 434, - /* 1660 */ 435, 390, 437, 378, 400, 400, 390, 405, 390, 444, - /* 1670 */ 464, 410, 405, 448, 449, 390, 425, 392, 427, 277, - /* 1680 */ 463, 430, 431, 432, 433, 434, 435, 340, 437, 262, - /* 1690 */ 410, 285, 484, 282, 280, 444, 258, 350, 350, 20, - /* 1700 */ 449, 429, 410, 349, 351, 356, 356, 403, 20, 174, - /* 1710 */ 425, 340, 427, 405, 390, 430, 431, 432, 433, 434, - /* 1720 */ 435, 350, 437, 402, 390, 378, 390, 390, 103, 390, - /* 1730 */ 383, 462, 405, 374, 356, 340, 477, 390, 350, 392, - /* 1740 */ 447, 390, 356, 103, 36, 350, 478, 390, 356, 378, - /* 1750 */ 382, 368, 349, 343, 383, 342, 471, 372, 413, 338, - /* 1760 */ 0, 390, 406, 392, 406, 357, 420, 0, 0, 372, - /* 1770 */ 372, 42, 425, 378, 427, 35, 35, 430, 431, 432, - /* 1780 */ 433, 434, 435, 0, 437, 390, 215, 392, 35, 35, - /* 1790 */ 215, 0, 35, 35, 215, 0, 425, 215, 427, 340, - /* 1800 */ 0, 430, 431, 432, 433, 434, 435, 35, 437, 350, - /* 1810 */ 0, 22, 0, 35, 210, 0, 198, 0, 198, 192, - /* 1820 */ 425, 199, 427, 190, 0, 430, 431, 432, 433, 434, - /* 1830 */ 435, 0, 437, 0, 186, 185, 0, 378, 0, 47, - /* 1840 */ 0, 0, 383, 0, 42, 0, 0, 0, 0, 390, - /* 1850 */ 0, 392, 0, 0, 0, 159, 35, 0, 159, 0, - /* 1860 */ 0, 0, 0, 340, 42, 0, 0, 0, 0, 0, - /* 1870 */ 0, 22, 0, 350, 0, 0, 0, 482, 0, 0, - /* 1880 */ 0, 0, 0, 0, 425, 340, 427, 0, 0, 430, - /* 1890 */ 431, 432, 433, 434, 435, 350, 437, 0, 0, 0, - /* 1900 */ 0, 378, 143, 0, 48, 0, 22, 0, 22, 340, - /* 1910 */ 112, 48, 35, 390, 0, 392, 0, 62, 0, 350, - /* 1920 */ 62, 0, 49, 378, 35, 0, 35, 0, 383, 39, - /* 1930 */ 35, 35, 39, 62, 0, 390, 14, 392, 0, 0, - /* 1940 */ 39, 49, 0, 49, 42, 39, 0, 378, 425, 40, - /* 1950 */ 427, 47, 383, 430, 431, 432, 433, 434, 435, 390, - /* 1960 */ 437, 392, 439, 1, 44, 39, 47, 39, 181, 0, - /* 1970 */ 425, 47, 427, 0, 0, 430, 431, 432, 433, 434, - /* 1980 */ 435, 19, 437, 0, 69, 0, 35, 39, 0, 49, - /* 1990 */ 35, 39, 49, 0, 425, 33, 427, 340, 35, 430, - /* 2000 */ 431, 432, 433, 434, 435, 49, 437, 350, 0, 39, - /* 2010 */ 35, 49, 35, 49, 0, 39, 340, 0, 0, 57, - /* 2020 */ 58, 59, 60, 0, 62, 22, 350, 340, 0, 0, - /* 2030 */ 0, 44, 35, 110, 35, 378, 35, 350, 44, 35, - /* 2040 */ 35, 35, 35, 22, 35, 35, 35, 390, 0, 392, - /* 2050 */ 0, 51, 0, 22, 378, 22, 22, 35, 0, 35, - /* 2060 */ 0, 35, 0, 22, 102, 378, 390, 105, 392, 20, - /* 2070 */ 35, 35, 35, 0, 35, 104, 22, 390, 0, 392, - /* 2080 */ 172, 103, 425, 103, 427, 22, 174, 430, 431, 432, - /* 2090 */ 433, 434, 435, 0, 437, 340, 0, 3, 263, 44, - /* 2100 */ 138, 425, 104, 427, 193, 350, 430, 431, 432, 433, - /* 2110 */ 434, 435, 425, 437, 427, 340, 172, 430, 431, 432, - /* 2120 */ 433, 434, 435, 103, 437, 350, 340, 197, 179, 172, - /* 2130 */ 103, 48, 48, 378, 44, 173, 350, 3, 47, 101, - /* 2140 */ 178, 99, 44, 44, 104, 390, 340, 392, 104, 103, - /* 2150 */ 103, 47, 44, 378, 103, 44, 350, 104, 35, 103, - /* 2160 */ 198, 104, 35, 104, 378, 390, 35, 392, 35, 104, - /* 2170 */ 35, 35, 104, 47, 257, 47, 390, 0, 392, 0, - /* 2180 */ 425, 44, 427, 0, 378, 430, 431, 432, 433, 434, - /* 2190 */ 435, 0, 437, 39, 263, 263, 390, 47, 392, 104, - /* 2200 */ 425, 104, 427, 103, 340, 430, 431, 432, 433, 434, - /* 2210 */ 435, 425, 437, 427, 350, 103, 430, 431, 432, 433, - /* 2220 */ 434, 435, 103, 437, 103, 340, 0, 103, 39, 113, - /* 2230 */ 44, 425, 103, 427, 173, 350, 430, 431, 432, 433, - /* 2240 */ 434, 435, 378, 437, 175, 47, 101, 101, 2, 22, - /* 2250 */ 340, 103, 47, 104, 390, 103, 392, 244, 47, 104, - /* 2260 */ 350, 103, 103, 378, 104, 222, 103, 22, 104, 224, - /* 2270 */ 103, 114, 104, 35, 35, 390, 340, 392, 103, 35, - /* 2280 */ 104, 103, 35, 35, 104, 103, 350, 103, 378, 425, - /* 2290 */ 35, 427, 104, 103, 430, 431, 432, 433, 434, 435, - /* 2300 */ 390, 437, 392, 104, 104, 35, 125, 103, 44, 35, - /* 2310 */ 425, 103, 427, 103, 378, 430, 431, 432, 433, 434, - /* 2320 */ 435, 125, 437, 103, 22, 69, 390, 125, 392, 68, - /* 2330 */ 35, 125, 35, 35, 35, 425, 340, 427, 35, 35, - /* 2340 */ 430, 431, 432, 433, 434, 435, 350, 437, 35, 35, - /* 2350 */ 75, 97, 340, 44, 35, 35, 35, 22, 35, 35, - /* 2360 */ 35, 425, 350, 427, 75, 340, 430, 431, 432, 433, - /* 2370 */ 434, 435, 35, 437, 378, 350, 35, 35, 35, 35, - /* 2380 */ 22, 35, 0, 35, 39, 49, 390, 0, 392, 35, - /* 2390 */ 378, 39, 0, 0, 35, 39, 49, 35, 49, 49, - /* 2400 */ 39, 0, 390, 378, 392, 35, 35, 0, 22, 21, - /* 2410 */ 485, 22, 22, 485, 20, 390, 21, 392, 485, 485, - /* 2420 */ 485, 425, 485, 427, 485, 340, 430, 431, 432, 433, - /* 2430 */ 434, 435, 485, 437, 485, 350, 485, 425, 485, 427, - /* 2440 */ 485, 340, 430, 431, 432, 433, 434, 435, 485, 437, - /* 2450 */ 425, 350, 427, 485, 340, 430, 431, 432, 433, 434, - /* 2460 */ 435, 485, 437, 378, 350, 485, 485, 485, 485, 485, - /* 2470 */ 485, 485, 485, 485, 485, 390, 485, 392, 485, 378, - /* 2480 */ 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2490 */ 485, 390, 378, 392, 485, 485, 485, 485, 485, 485, - /* 2500 */ 485, 485, 485, 485, 390, 485, 392, 485, 485, 485, - /* 2510 */ 425, 485, 427, 485, 485, 430, 431, 432, 433, 434, - /* 2520 */ 435, 485, 437, 485, 485, 485, 425, 340, 427, 485, - /* 2530 */ 485, 430, 431, 432, 433, 434, 435, 350, 437, 425, - /* 2540 */ 485, 427, 485, 340, 430, 431, 432, 433, 434, 435, - /* 2550 */ 485, 437, 485, 350, 340, 485, 485, 485, 485, 485, - /* 2560 */ 485, 485, 485, 485, 350, 378, 485, 485, 485, 485, - /* 2570 */ 485, 485, 485, 485, 485, 485, 485, 390, 485, 392, - /* 2580 */ 485, 378, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2590 */ 485, 485, 378, 390, 485, 392, 485, 485, 485, 485, - /* 2600 */ 485, 485, 485, 485, 390, 485, 392, 485, 485, 485, - /* 2610 */ 485, 485, 425, 485, 427, 485, 340, 430, 431, 432, - /* 2620 */ 433, 434, 435, 485, 437, 485, 350, 485, 425, 485, - /* 2630 */ 427, 485, 340, 430, 431, 432, 433, 434, 435, 425, - /* 2640 */ 437, 427, 350, 485, 430, 431, 432, 433, 434, 435, - /* 2650 */ 485, 437, 485, 485, 378, 485, 485, 485, 485, 485, - /* 2660 */ 485, 485, 485, 485, 485, 485, 390, 485, 392, 485, - /* 2670 */ 378, 485, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2680 */ 485, 485, 390, 485, 392, 485, 485, 485, 485, 485, - /* 2690 */ 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2700 */ 485, 425, 485, 427, 485, 485, 430, 431, 432, 433, - /* 2710 */ 434, 435, 485, 437, 485, 485, 485, 425, 485, 427, - /* 2720 */ 485, 485, 430, 431, 432, 433, 434, 435, 485, 437, - /* 2730 */ 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2740 */ 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, - /* 2750 */ 485, 485, 485, 485, 337, 337, 337, 337, 337, 337, - /* 2760 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2770 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2780 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2790 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2800 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2810 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2820 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2830 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2840 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2850 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2860 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2870 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2880 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2890 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2900 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2910 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2920 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2930 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2940 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2950 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2960 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2970 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2980 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 2990 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3000 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3010 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3020 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3030 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3040 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3050 */ 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, - /* 3060 */ 337, 337, 337, 337, 337, 337, 337, + /* 340 */ 236, 237, 238, 239, 240, 241, 242, 243, 244, 12, + /* 350 */ 13, 397, 53, 379, 379, 12, 13, 20, 67, 22, + /* 360 */ 458, 386, 103, 461, 379, 391, 20, 393, 351, 394, + /* 370 */ 33, 260, 35, 70, 71, 72, 350, 351, 35, 477, + /* 380 */ 77, 78, 79, 481, 482, 400, 83, 351, 265, 266, + /* 390 */ 267, 88, 89, 90, 91, 217, 370, 94, 351, 62, + /* 400 */ 135, 427, 48, 429, 139, 68, 432, 433, 434, 435, + /* 410 */ 436, 437, 75, 439, 397, 379, 134, 135, 444, 345, + /* 420 */ 446, 139, 348, 349, 450, 451, 454, 455, 456, 341, + /* 430 */ 458, 459, 14, 458, 140, 141, 461, 100, 20, 351, + /* 440 */ 103, 353, 8, 9, 397, 471, 12, 13, 14, 15, + /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 346, 341, + /* 460 */ 170, 20, 350, 22, 352, 200, 159, 379, 203, 351, + /* 470 */ 434, 206, 379, 208, 33, 168, 35, 140, 141, 391, + /* 480 */ 387, 393, 458, 21, 20, 461, 24, 25, 26, 27, + /* 490 */ 28, 29, 30, 31, 32, 379, 103, 379, 341, 350, + /* 500 */ 351, 477, 386, 62, 20, 481, 482, 170, 171, 391, + /* 510 */ 394, 393, 357, 176, 177, 427, 75, 429, 172, 260, + /* 520 */ 432, 433, 434, 435, 436, 437, 172, 439, 191, 374, + /* 530 */ 193, 133, 444, 179, 446, 137, 193, 382, 450, 451, + /* 540 */ 14, 100, 350, 351, 103, 427, 20, 429, 391, 341, + /* 550 */ 432, 433, 434, 435, 436, 437, 244, 439, 246, 351, + /* 560 */ 223, 224, 370, 226, 227, 228, 229, 230, 231, 232, + /* 570 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + /* 580 */ 243, 140, 141, 190, 22, 192, 261, 379, 8, 9, + /* 590 */ 472, 473, 12, 13, 14, 15, 16, 35, 341, 391, + /* 600 */ 20, 393, 453, 454, 455, 456, 172, 458, 459, 20, + /* 610 */ 341, 170, 171, 350, 351, 222, 389, 176, 177, 392, + /* 620 */ 393, 8, 9, 371, 0, 12, 13, 14, 15, 16, + /* 630 */ 103, 379, 191, 370, 193, 427, 350, 429, 386, 387, + /* 640 */ 432, 433, 434, 435, 436, 437, 394, 439, 391, 47, + /* 650 */ 411, 341, 444, 260, 446, 416, 172, 411, 450, 451, + /* 660 */ 391, 351, 100, 353, 223, 224, 67, 226, 227, 228, + /* 670 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + /* 680 */ 239, 240, 241, 242, 243, 12, 13, 0, 402, 379, + /* 690 */ 404, 67, 103, 20, 20, 22, 170, 458, 350, 351, + /* 700 */ 461, 391, 379, 393, 458, 103, 33, 461, 35, 386, + /* 710 */ 12, 13, 14, 15, 16, 476, 477, 394, 350, 351, + /* 720 */ 481, 482, 476, 477, 14, 15, 16, 481, 482, 1, + /* 730 */ 2, 223, 114, 350, 351, 62, 244, 427, 370, 429, + /* 740 */ 4, 350, 432, 433, 434, 435, 436, 437, 75, 439, + /* 750 */ 350, 351, 172, 370, 444, 19, 446, 0, 8, 9, + /* 760 */ 450, 451, 12, 13, 14, 15, 16, 341, 341, 33, + /* 770 */ 370, 392, 393, 100, 350, 351, 103, 351, 270, 271, + /* 780 */ 272, 273, 274, 275, 276, 49, 134, 260, 75, 12, + /* 790 */ 13, 0, 56, 402, 370, 404, 183, 20, 62, 22, + /* 800 */ 379, 20, 454, 455, 456, 379, 458, 459, 54, 55, + /* 810 */ 33, 431, 35, 140, 141, 394, 359, 391, 391, 393, + /* 820 */ 133, 134, 135, 136, 137, 138, 139, 70, 71, 72, + /* 830 */ 355, 356, 104, 376, 77, 78, 79, 457, 102, 62, + /* 840 */ 83, 105, 385, 170, 171, 88, 89, 90, 91, 176, + /* 850 */ 177, 94, 75, 427, 104, 429, 204, 205, 432, 433, + /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 8, 9, + /* 870 */ 341, 380, 12, 13, 14, 15, 16, 100, 355, 356, + /* 880 */ 103, 341, 133, 134, 135, 136, 137, 138, 139, 341, + /* 890 */ 411, 351, 62, 353, 341, 75, 223, 224, 285, 226, + /* 900 */ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 379, + /* 920 */ 391, 140, 141, 21, 133, 134, 135, 136, 137, 138, + /* 930 */ 139, 391, 102, 393, 379, 105, 34, 458, 36, 391, + /* 940 */ 461, 386, 350, 351, 391, 350, 351, 170, 171, 394, + /* 950 */ 380, 350, 351, 176, 177, 476, 477, 176, 177, 380, + /* 960 */ 481, 482, 370, 442, 104, 370, 445, 427, 191, 429, + /* 970 */ 193, 370, 432, 433, 434, 435, 436, 437, 39, 439, + /* 980 */ 364, 365, 2, 341, 444, 22, 446, 350, 8, 9, + /* 990 */ 450, 451, 12, 13, 14, 15, 16, 341, 35, 3, + /* 1000 */ 223, 224, 0, 226, 227, 228, 229, 230, 231, 232, + /* 1010 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + /* 1020 */ 243, 14, 18, 18, 20, 350, 351, 20, 23, 350, + /* 1030 */ 351, 27, 388, 391, 30, 391, 13, 33, 367, 402, + /* 1040 */ 371, 404, 37, 38, 379, 370, 41, 391, 379, 370, + /* 1050 */ 20, 386, 381, 49, 411, 51, 387, 52, 35, 394, + /* 1060 */ 56, 341, 391, 100, 341, 364, 365, 341, 63, 64, + /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 13, 76, 77, + /* 1080 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 35, + /* 1100 */ 429, 458, 350, 351, 461, 371, 102, 33, 103, 37, + /* 1110 */ 439, 391, 431, 379, 391, 350, 351, 391, 114, 476, + /* 1120 */ 477, 387, 370, 49, 481, 482, 350, 351, 44, 350, + /* 1130 */ 351, 57, 58, 59, 60, 370, 62, 341, 457, 443, + /* 1140 */ 169, 445, 359, 0, 341, 341, 370, 142, 144, 370, + /* 1150 */ 44, 147, 148, 149, 150, 151, 152, 153, 154, 155, + /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 385, 165, + /* 1170 */ 166, 167, 443, 42, 445, 44, 102, 170, 106, 105, + /* 1180 */ 108, 109, 42, 111, 44, 341, 341, 391, 183, 184, + /* 1190 */ 185, 341, 49, 188, 391, 391, 388, 388, 259, 391, + /* 1200 */ 391, 351, 172, 353, 44, 133, 201, 202, 372, 137, + /* 1210 */ 104, 375, 366, 45, 46, 369, 114, 212, 247, 0, + /* 1220 */ 215, 35, 341, 218, 219, 220, 221, 222, 257, 379, + /* 1230 */ 258, 259, 351, 22, 353, 391, 391, 107, 44, 107, + /* 1240 */ 110, 391, 110, 393, 68, 44, 35, 173, 174, 0, + /* 1250 */ 140, 141, 341, 107, 180, 181, 110, 35, 107, 0, + /* 1260 */ 379, 110, 351, 44, 353, 260, 164, 207, 44, 209, + /* 1270 */ 44, 22, 391, 199, 393, 0, 280, 427, 103, 429, + /* 1280 */ 114, 22, 432, 433, 434, 435, 436, 437, 113, 439, + /* 1290 */ 379, 44, 1, 2, 444, 35, 446, 22, 104, 44, + /* 1300 */ 450, 451, 391, 380, 393, 104, 0, 44, 427, 380, + /* 1310 */ 429, 13, 13, 432, 433, 434, 435, 436, 437, 368, + /* 1320 */ 439, 44, 44, 417, 22, 444, 44, 446, 104, 44, + /* 1330 */ 104, 450, 451, 35, 35, 75, 44, 35, 427, 342, + /* 1340 */ 429, 401, 341, 432, 433, 434, 435, 436, 437, 44, + /* 1350 */ 439, 104, 351, 12, 13, 444, 50, 446, 2, 104, + /* 1360 */ 485, 450, 451, 22, 8, 9, 282, 104, 12, 13, + /* 1370 */ 14, 15, 16, 341, 33, 474, 35, 75, 354, 193, + /* 1380 */ 379, 104, 104, 351, 468, 367, 104, 367, 379, 104, + /* 1390 */ 354, 410, 391, 44, 393, 44, 104, 44, 44, 223, + /* 1400 */ 401, 349, 100, 62, 351, 390, 460, 401, 478, 104, + /* 1410 */ 341, 379, 44, 44, 452, 193, 75, 462, 262, 49, + /* 1420 */ 351, 428, 412, 391, 20, 393, 206, 359, 427, 421, + /* 1430 */ 429, 189, 421, 432, 433, 434, 435, 436, 437, 426, + /* 1440 */ 439, 100, 359, 414, 284, 444, 398, 446, 379, 42, + /* 1450 */ 20, 450, 451, 104, 398, 104, 401, 104, 104, 427, + /* 1460 */ 391, 429, 393, 169, 432, 433, 434, 435, 436, 437, + /* 1470 */ 20, 439, 104, 104, 396, 350, 444, 350, 446, 398, + /* 1480 */ 101, 396, 450, 451, 396, 363, 99, 350, 362, 98, + /* 1490 */ 361, 350, 350, 191, 350, 193, 427, 20, 429, 341, + /* 1500 */ 343, 432, 433, 434, 435, 436, 437, 48, 439, 351, + /* 1510 */ 347, 347, 343, 421, 359, 446, 20, 393, 359, 450, + /* 1520 */ 451, 20, 352, 20, 413, 223, 224, 343, 350, 352, + /* 1530 */ 359, 359, 191, 359, 193, 350, 343, 379, 359, 359, + /* 1540 */ 379, 379, 210, 391, 379, 391, 379, 103, 341, 391, + /* 1550 */ 195, 393, 379, 425, 197, 421, 423, 357, 351, 420, + /* 1560 */ 379, 379, 379, 196, 223, 224, 379, 379, 379, 419, + /* 1570 */ 357, 418, 269, 350, 341, 467, 268, 236, 237, 238, + /* 1580 */ 239, 240, 241, 242, 351, 427, 379, 429, 391, 393, + /* 1590 */ 432, 433, 434, 435, 436, 437, 401, 439, 391, 401, + /* 1600 */ 393, 391, 412, 391, 446, 406, 391, 391, 450, 451, + /* 1610 */ 406, 277, 379, 182, 467, 470, 467, 469, 279, 286, + /* 1620 */ 278, 263, 486, 283, 391, 341, 393, 351, 281, 20, + /* 1630 */ 412, 259, 352, 20, 427, 351, 429, 431, 341, 432, + /* 1640 */ 433, 434, 435, 436, 437, 357, 439, 357, 351, 404, + /* 1650 */ 406, 351, 391, 446, 406, 391, 465, 450, 451, 391, + /* 1660 */ 427, 391, 429, 379, 391, 432, 433, 434, 435, 436, + /* 1670 */ 437, 438, 439, 440, 441, 391, 379, 393, 391, 174, + /* 1680 */ 466, 464, 480, 357, 479, 375, 403, 341, 391, 103, + /* 1690 */ 393, 103, 357, 369, 383, 449, 36, 351, 391, 339, + /* 1700 */ 350, 357, 407, 344, 341, 343, 358, 0, 415, 373, + /* 1710 */ 373, 427, 42, 429, 351, 0, 432, 433, 434, 435, + /* 1720 */ 436, 437, 407, 439, 427, 379, 429, 0, 0, 432, + /* 1730 */ 433, 434, 435, 436, 437, 422, 439, 391, 373, 393, + /* 1740 */ 35, 216, 379, 446, 35, 35, 35, 384, 451, 216, + /* 1750 */ 0, 35, 35, 341, 391, 216, 393, 0, 216, 0, + /* 1760 */ 35, 0, 22, 351, 0, 35, 211, 483, 484, 0, + /* 1770 */ 199, 0, 199, 427, 200, 429, 193, 341, 432, 433, + /* 1780 */ 434, 435, 436, 437, 191, 439, 0, 351, 0, 0, + /* 1790 */ 427, 379, 429, 187, 186, 432, 433, 434, 435, 436, + /* 1800 */ 437, 0, 439, 391, 341, 393, 0, 47, 0, 0, + /* 1810 */ 0, 0, 42, 0, 351, 379, 0, 0, 0, 473, + /* 1820 */ 384, 0, 0, 0, 341, 159, 35, 391, 0, 393, + /* 1830 */ 159, 0, 0, 0, 351, 0, 0, 0, 0, 427, + /* 1840 */ 42, 429, 379, 0, 432, 433, 434, 435, 436, 437, + /* 1850 */ 0, 439, 0, 0, 391, 0, 393, 0, 0, 0, + /* 1860 */ 0, 0, 379, 427, 0, 429, 0, 384, 432, 433, + /* 1870 */ 434, 435, 436, 437, 391, 439, 393, 143, 22, 0, + /* 1880 */ 0, 0, 0, 0, 22, 22, 0, 475, 0, 0, + /* 1890 */ 427, 341, 429, 0, 48, 432, 433, 434, 435, 436, + /* 1900 */ 437, 351, 439, 62, 35, 0, 62, 0, 0, 62, + /* 1910 */ 427, 0, 429, 48, 39, 432, 433, 434, 435, 436, + /* 1920 */ 437, 341, 439, 49, 0, 35, 35, 49, 0, 379, + /* 1930 */ 35, 351, 0, 39, 384, 39, 49, 0, 35, 42, + /* 1940 */ 39, 391, 44, 393, 14, 0, 47, 484, 0, 40, + /* 1950 */ 0, 47, 39, 47, 0, 39, 182, 0, 0, 379, + /* 1960 */ 0, 69, 0, 0, 384, 39, 35, 49, 0, 35, + /* 1970 */ 49, 391, 39, 393, 35, 39, 49, 427, 0, 429, + /* 1980 */ 341, 0, 432, 433, 434, 435, 436, 437, 1, 439, + /* 1990 */ 351, 35, 49, 0, 39, 0, 0, 0, 0, 0, + /* 2000 */ 35, 22, 0, 44, 35, 35, 19, 427, 35, 429, + /* 2010 */ 110, 35, 432, 433, 434, 435, 436, 437, 379, 439, + /* 2020 */ 33, 35, 112, 35, 44, 35, 35, 35, 22, 35, + /* 2030 */ 391, 0, 393, 22, 0, 22, 49, 0, 22, 35, + /* 2040 */ 0, 0, 0, 35, 57, 58, 59, 60, 22, 62, + /* 2050 */ 35, 51, 20, 341, 35, 35, 35, 104, 0, 35, + /* 2060 */ 22, 0, 194, 351, 103, 198, 427, 103, 429, 22, + /* 2070 */ 0, 432, 433, 434, 435, 436, 437, 0, 439, 44, + /* 2080 */ 103, 3, 99, 264, 341, 103, 172, 172, 104, 102, + /* 2090 */ 178, 379, 105, 174, 351, 172, 48, 172, 178, 48, + /* 2100 */ 44, 44, 101, 391, 44, 393, 47, 104, 44, 104, + /* 2110 */ 47, 3, 103, 103, 35, 103, 44, 35, 104, 341, + /* 2120 */ 103, 35, 379, 35, 35, 138, 104, 104, 35, 351, + /* 2130 */ 47, 104, 104, 0, 391, 264, 393, 264, 44, 427, + /* 2140 */ 0, 429, 258, 47, 432, 433, 434, 435, 436, 437, + /* 2150 */ 39, 439, 103, 47, 104, 103, 341, 379, 0, 104, + /* 2160 */ 173, 39, 47, 44, 2, 103, 351, 180, 103, 391, + /* 2170 */ 427, 393, 429, 22, 103, 432, 433, 434, 435, 436, + /* 2180 */ 437, 341, 439, 103, 103, 101, 199, 113, 101, 245, + /* 2190 */ 223, 351, 47, 175, 379, 104, 104, 47, 173, 104, + /* 2200 */ 103, 103, 103, 103, 103, 427, 391, 429, 393, 104, + /* 2210 */ 432, 433, 434, 435, 436, 437, 22, 439, 341, 379, + /* 2220 */ 104, 114, 35, 35, 103, 35, 35, 103, 351, 104, + /* 2230 */ 104, 391, 103, 393, 104, 35, 104, 103, 35, 103, + /* 2240 */ 35, 104, 427, 341, 429, 103, 103, 432, 433, 434, + /* 2250 */ 435, 436, 437, 351, 439, 225, 379, 44, 103, 35, + /* 2260 */ 125, 22, 103, 125, 125, 69, 125, 427, 391, 429, + /* 2270 */ 393, 35, 432, 433, 434, 435, 436, 437, 68, 439, + /* 2280 */ 35, 379, 35, 35, 35, 35, 35, 35, 22, 75, + /* 2290 */ 97, 35, 35, 391, 35, 393, 35, 44, 35, 35, + /* 2300 */ 75, 22, 35, 35, 427, 35, 429, 35, 35, 432, + /* 2310 */ 433, 434, 435, 436, 437, 341, 439, 35, 0, 35, + /* 2320 */ 49, 0, 39, 35, 49, 351, 39, 0, 35, 427, + /* 2330 */ 341, 429, 0, 35, 432, 433, 434, 435, 436, 437, + /* 2340 */ 351, 439, 39, 49, 49, 39, 0, 35, 341, 35, + /* 2350 */ 0, 22, 22, 379, 21, 20, 22, 21, 351, 487, + /* 2360 */ 487, 487, 487, 487, 487, 391, 487, 393, 379, 487, + /* 2370 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2380 */ 391, 487, 393, 487, 487, 487, 379, 487, 487, 487, + /* 2390 */ 487, 487, 487, 487, 487, 341, 487, 487, 391, 487, + /* 2400 */ 393, 427, 487, 429, 487, 351, 432, 433, 434, 435, + /* 2410 */ 436, 437, 487, 439, 487, 487, 427, 341, 429, 487, + /* 2420 */ 487, 432, 433, 434, 435, 436, 437, 351, 439, 487, + /* 2430 */ 487, 487, 487, 379, 427, 487, 429, 487, 487, 432, + /* 2440 */ 433, 434, 435, 436, 437, 391, 439, 393, 487, 487, + /* 2450 */ 487, 487, 487, 487, 487, 379, 487, 487, 487, 487, + /* 2460 */ 487, 487, 487, 487, 341, 487, 487, 391, 487, 393, + /* 2470 */ 487, 487, 487, 487, 351, 487, 487, 487, 487, 487, + /* 2480 */ 487, 427, 487, 429, 487, 487, 432, 433, 434, 435, + /* 2490 */ 436, 437, 487, 439, 487, 487, 487, 487, 487, 487, + /* 2500 */ 487, 487, 379, 427, 487, 429, 487, 487, 432, 433, + /* 2510 */ 434, 435, 436, 437, 391, 439, 393, 487, 487, 487, + /* 2520 */ 487, 487, 487, 341, 487, 487, 487, 487, 487, 487, + /* 2530 */ 487, 487, 487, 351, 487, 487, 341, 487, 487, 487, + /* 2540 */ 487, 487, 487, 487, 487, 487, 351, 487, 487, 487, + /* 2550 */ 427, 487, 429, 341, 487, 432, 433, 434, 435, 436, + /* 2560 */ 437, 379, 439, 351, 487, 487, 487, 487, 487, 487, + /* 2570 */ 487, 487, 487, 391, 379, 393, 487, 487, 487, 487, + /* 2580 */ 487, 487, 487, 487, 487, 341, 391, 487, 393, 487, + /* 2590 */ 487, 379, 487, 487, 487, 351, 487, 487, 487, 487, + /* 2600 */ 487, 487, 487, 391, 487, 393, 487, 487, 487, 427, + /* 2610 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, + /* 2620 */ 487, 439, 427, 379, 429, 487, 487, 432, 433, 434, + /* 2630 */ 435, 436, 437, 487, 439, 391, 487, 393, 487, 427, + /* 2640 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, + /* 2650 */ 487, 439, 341, 487, 487, 487, 487, 487, 487, 487, + /* 2660 */ 487, 487, 351, 487, 487, 487, 487, 487, 487, 487, + /* 2670 */ 487, 427, 341, 429, 487, 487, 432, 433, 434, 435, + /* 2680 */ 436, 437, 351, 439, 487, 487, 487, 487, 487, 487, + /* 2690 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2700 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, + /* 2710 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2720 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, + /* 2730 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, + /* 2740 */ 429, 487, 341, 432, 433, 434, 435, 436, 437, 487, + /* 2750 */ 439, 487, 351, 487, 487, 487, 487, 487, 427, 341, + /* 2760 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 351, + /* 2770 */ 439, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2780 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2790 */ 487, 487, 391, 487, 393, 487, 487, 379, 487, 487, + /* 2800 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 391, + /* 2810 */ 487, 393, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2820 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, + /* 2830 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, + /* 2840 */ 439, 487, 487, 487, 487, 427, 487, 429, 487, 487, + /* 2850 */ 432, 433, 434, 435, 436, 437, 487, 439, 338, 338, + /* 2860 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2870 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2880 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2890 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2900 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2910 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2920 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2930 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2940 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2950 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2960 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2970 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2980 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 2990 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3000 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3010 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3020 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3030 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3040 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3050 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3060 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3070 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3080 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3090 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3100 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3110 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3120 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3130 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3140 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3150 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3160 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3170 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3180 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3190 */ 338, 338, 338, 338, 338, 338, }; -#define YY_SHIFT_COUNT (793) +#define YY_SHIFT_COUNT (790) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2407) +#define YY_SHIFT_MAX (2350) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1097, 0, 104, 0, 336, 336, 336, 336, 336, 336, - /* 10 */ 336, 336, 336, 336, 336, 336, 440, 671, 671, 775, - /* 20 */ 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, - /* 30 */ 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, - /* 40 */ 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, - /* 50 */ 671, 335, 519, 1053, 263, 215, 156, 586, 156, 263, - /* 60 */ 263, 1333, 156, 1333, 1333, 621, 156, 34, 798, 111, - /* 70 */ 111, 798, 278, 278, 294, 138, 308, 308, 111, 111, - /* 80 */ 111, 111, 111, 111, 111, 199, 111, 111, 297, 34, - /* 90 */ 111, 111, 223, 111, 34, 111, 199, 111, 199, 34, - /* 100 */ 111, 111, 34, 111, 34, 34, 34, 111, 460, 917, - /* 110 */ 15, 15, 378, 170, 700, 700, 700, 700, 700, 700, - /* 120 */ 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, - /* 130 */ 700, 700, 700, 326, 410, 294, 138, 633, 633, 714, - /* 140 */ 426, 426, 426, 618, 107, 107, 714, 299, 299, 299, - /* 150 */ 297, 356, 353, 34, 577, 34, 577, 577, 663, 730, - /* 160 */ 259, 259, 259, 259, 259, 259, 259, 259, 1962, 1116, - /* 170 */ 185, 31, 276, 249, 394, 176, 13, 13, 862, 1073, - /* 180 */ 489, 776, 1167, 949, 721, 820, 996, 355, 581, 996, - /* 190 */ 997, 1081, 256, 1219, 1434, 1470, 1288, 297, 1470, 297, - /* 200 */ 1318, 1467, 1498, 1467, 1352, 1507, 1507, 1467, 1352, 1352, - /* 210 */ 1437, 1446, 1507, 1452, 1507, 1507, 1507, 1541, 1516, 1541, - /* 220 */ 1516, 1470, 297, 1561, 297, 1563, 1564, 297, 1563, 297, - /* 230 */ 297, 297, 1507, 297, 1541, 34, 34, 34, 34, 34, - /* 240 */ 34, 34, 34, 34, 34, 34, 1507, 1541, 577, 577, - /* 250 */ 577, 1400, 1508, 1470, 460, 1422, 1425, 1561, 460, 1436, - /* 260 */ 1219, 1507, 1498, 1498, 577, 1366, 1370, 577, 1366, 1370, - /* 270 */ 577, 577, 34, 1364, 1461, 1366, 1376, 1402, 1427, 1219, - /* 280 */ 1406, 1411, 1414, 1438, 299, 1679, 1219, 1507, 1563, 460, - /* 290 */ 460, 1688, 1370, 577, 577, 577, 577, 577, 1370, 577, - /* 300 */ 1535, 460, 663, 460, 299, 1625, 1640, 577, 730, 1507, - /* 310 */ 460, 1708, 1541, 2730, 2730, 2730, 2730, 2730, 2730, 2730, - /* 320 */ 2730, 2730, 1018, 679, 224, 739, 1543, 858, 1041, 418, - /* 330 */ 748, 974, 1110, 1166, 1377, 1377, 1377, 1377, 1377, 1377, - /* 340 */ 1377, 1377, 1377, 500, 729, 51, 51, 441, 484, 446, - /* 350 */ 660, 76, 121, 699, 593, 291, 924, 924, 701, 536, - /* 360 */ 952, 701, 701, 701, 384, 1060, 1093, 1095, 1291, 1220, - /* 370 */ 765, 1241, 1242, 1243, 1247, 566, 688, 1340, 1342, 1365, - /* 380 */ 1087, 1319, 1323, 1226, 1325, 1328, 1330, 1274, 1157, 1183, - /* 390 */ 1310, 1331, 1338, 1344, 1361, 1363, 1372, 1420, 1380, 1101, - /* 400 */ 1381, 1389, 1382, 1384, 1387, 1393, 1396, 1399, 1343, 1362, - /* 410 */ 1374, 1426, 1428, 723, 1444, 1760, 1767, 1768, 1729, 1783, - /* 420 */ 1740, 1571, 1741, 1753, 1754, 1575, 1791, 1757, 1758, 1579, - /* 430 */ 1795, 1582, 1800, 1772, 1810, 1789, 1812, 1778, 1604, 1815, - /* 440 */ 1618, 1817, 1620, 1622, 1627, 1633, 1824, 1831, 1833, 1648, - /* 450 */ 1650, 1836, 1838, 1792, 1840, 1841, 1843, 1802, 1845, 1846, - /* 460 */ 1847, 1848, 1850, 1852, 1853, 1854, 1696, 1821, 1857, 1699, - /* 470 */ 1859, 1860, 1861, 1862, 1874, 1875, 1876, 1878, 1879, 1880, - /* 480 */ 1881, 1882, 1883, 1887, 1888, 1897, 1822, 1865, 1866, 1867, - /* 490 */ 1868, 1869, 1870, 1849, 1872, 1898, 1899, 1759, 1900, 1903, - /* 500 */ 1884, 1856, 1886, 1863, 1905, 1855, 1877, 1907, 1858, 1914, - /* 510 */ 1871, 1916, 1918, 1889, 1873, 1890, 1921, 1891, 1892, 1893, - /* 520 */ 1925, 1895, 1894, 1901, 1927, 1896, 1934, 1902, 1906, 1920, - /* 530 */ 1904, 1919, 1922, 1924, 1938, 1909, 1926, 1939, 1942, 1946, - /* 540 */ 1928, 1787, 1969, 1973, 1974, 1915, 1983, 1985, 1951, 1940, - /* 550 */ 1948, 1988, 1955, 1943, 1952, 1993, 1963, 1956, 1970, 2008, - /* 560 */ 1975, 1964, 1976, 2014, 2017, 2018, 2023, 2028, 2029, 1798, - /* 570 */ 1923, 1977, 2003, 2030, 1997, 1999, 2001, 2004, 2005, 2006, - /* 580 */ 2007, 1987, 1994, 2009, 2010, 2021, 2011, 2048, 2031, 2050, - /* 590 */ 2033, 2000, 2052, 2034, 2022, 2058, 2024, 2060, 2026, 2062, - /* 600 */ 2041, 2049, 2035, 2036, 2037, 1971, 1978, 2073, 1908, 1980, - /* 610 */ 1930, 2039, 2054, 2078, 1911, 2063, 1944, 1912, 2093, 2096, - /* 620 */ 1957, 1949, 2094, 2055, 1835, 2020, 1998, 2027, 2083, 2038, - /* 630 */ 2084, 2042, 2040, 2090, 2098, 2044, 2046, 2047, 2051, 2053, - /* 640 */ 2099, 2091, 2104, 2056, 2108, 1931, 2057, 2059, 2134, 2111, - /* 650 */ 1932, 2123, 2127, 2131, 2133, 2135, 2136, 2065, 2068, 2126, - /* 660 */ 1917, 2137, 2128, 2177, 2179, 2183, 2191, 2100, 2154, 1904, - /* 670 */ 2150, 2112, 2095, 2097, 2119, 2121, 2069, 2124, 2226, 2189, - /* 680 */ 2061, 2129, 2116, 1904, 2198, 2186, 2145, 2013, 2146, 2246, - /* 690 */ 2227, 2043, 2148, 2149, 2152, 2155, 2158, 2160, 2205, 2159, - /* 700 */ 2163, 2211, 2164, 2245, 2045, 2167, 2157, 2168, 2238, 2239, - /* 710 */ 2175, 2176, 2244, 2178, 2180, 2247, 2182, 2188, 2248, 2184, - /* 720 */ 2199, 2255, 2190, 2200, 2270, 2204, 2181, 2196, 2202, 2206, - /* 730 */ 2208, 2264, 2210, 2274, 2220, 2264, 2264, 2302, 2256, 2261, - /* 740 */ 2295, 2297, 2298, 2299, 2303, 2304, 2313, 2314, 2275, 2254, - /* 750 */ 2309, 2319, 2320, 2321, 2335, 2323, 2324, 2325, 2289, 1987, - /* 760 */ 2337, 1994, 2341, 2342, 2343, 2344, 2358, 2346, 2382, 2348, - /* 770 */ 2336, 2345, 2387, 2354, 2347, 2352, 2392, 2359, 2349, 2356, - /* 780 */ 2393, 2362, 2350, 2361, 2401, 2370, 2371, 2407, 2386, 2388, - /* 790 */ 2389, 2390, 2395, 2394, + /* 0 */ 1005, 0, 104, 0, 337, 337, 337, 337, 337, 337, + /* 10 */ 337, 337, 337, 337, 337, 337, 441, 673, 673, 777, + /* 20 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + /* 30 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + /* 40 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + /* 50 */ 673, 60, 259, 393, 589, 111, 527, 111, 589, 589, + /* 60 */ 111, 1341, 111, 1341, 1341, 66, 111, 68, 781, 101, + /* 70 */ 101, 781, 13, 13, 113, 294, 23, 23, 101, 101, + /* 80 */ 101, 101, 101, 101, 101, 258, 101, 101, 291, 68, + /* 90 */ 101, 101, 464, 68, 101, 258, 101, 258, 68, 101, + /* 100 */ 101, 68, 101, 68, 68, 68, 101, 599, 1004, 15, + /* 110 */ 15, 303, 462, 1302, 1302, 1302, 1302, 1302, 1302, 1302, + /* 120 */ 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, + /* 130 */ 1302, 1302, 1072, 18, 113, 294, 754, 754, 184, 346, + /* 140 */ 346, 346, 624, 312, 312, 184, 674, 674, 674, 291, + /* 150 */ 618, 492, 68, 713, 68, 713, 713, 1166, 820, 28, + /* 160 */ 28, 28, 28, 28, 28, 28, 28, 1987, 757, 261, + /* 170 */ 580, 613, 508, 49, 123, 343, 343, 526, 354, 1007, + /* 180 */ 299, 484, 1168, 418, 398, 1030, 972, 939, 996, 972, + /* 190 */ 1131, 325, 290, 1156, 1370, 1404, 1220, 291, 1404, 291, + /* 200 */ 1242, 1407, 1430, 1407, 1294, 1450, 1450, 1407, 1294, 1294, + /* 210 */ 1379, 1387, 1450, 1391, 1450, 1450, 1450, 1477, 1459, 1477, + /* 220 */ 1459, 1404, 291, 1496, 291, 1501, 1503, 291, 1501, 291, + /* 230 */ 291, 291, 1450, 291, 1477, 68, 68, 68, 68, 68, + /* 240 */ 68, 68, 68, 68, 68, 68, 1450, 1477, 713, 713, + /* 250 */ 713, 1332, 1444, 1404, 599, 1357, 1367, 1496, 599, 1355, + /* 260 */ 1156, 1450, 1430, 1430, 713, 1303, 1308, 713, 1303, 1308, + /* 270 */ 713, 713, 68, 1334, 1431, 1303, 1339, 1342, 1358, 1156, + /* 280 */ 1333, 1340, 1347, 1372, 674, 1609, 1501, 599, 599, 1613, + /* 290 */ 1308, 713, 713, 713, 713, 713, 1308, 713, 1505, 599, + /* 300 */ 1166, 599, 674, 1586, 1588, 713, 820, 1450, 599, 1660, + /* 310 */ 1477, 2858, 2858, 2858, 2858, 2858, 2858, 2858, 2858, 2858, + /* 320 */ 1002, 1074, 225, 32, 736, 750, 860, 687, 980, 1356, + /* 330 */ 434, 791, 197, 197, 197, 197, 197, 197, 197, 197, + /* 340 */ 197, 749, 265, 698, 698, 29, 6, 34, 307, 830, + /* 350 */ 562, 963, 902, 652, 282, 282, 710, 728, 971, 710, + /* 360 */ 710, 710, 1143, 178, 1106, 1211, 1140, 1102, 1219, 1130, + /* 370 */ 1132, 1146, 1151, 1023, 1064, 1249, 1259, 1275, 1060, 1194, + /* 380 */ 1201, 63, 1224, 1226, 1247, 1110, 1084, 1160, 1255, 1263, + /* 390 */ 1277, 1278, 1282, 1285, 1291, 1292, 1176, 1305, 602, 1349, + /* 400 */ 1351, 1353, 1354, 1368, 1369, 1175, 1186, 1222, 1298, 1299, + /* 410 */ 1260, 1306, 1707, 1715, 1727, 1670, 1728, 1705, 1525, 1709, + /* 420 */ 1710, 1711, 1533, 1750, 1716, 1717, 1539, 1757, 1542, 1759, + /* 430 */ 1725, 1761, 1740, 1764, 1730, 1555, 1769, 1571, 1771, 1573, + /* 440 */ 1574, 1583, 1593, 1786, 1788, 1789, 1606, 1608, 1801, 1806, + /* 450 */ 1760, 1808, 1809, 1810, 1770, 1811, 1813, 1816, 1817, 1818, + /* 460 */ 1821, 1822, 1823, 1666, 1791, 1828, 1671, 1831, 1832, 1833, + /* 470 */ 1835, 1836, 1837, 1838, 1843, 1850, 1852, 1853, 1855, 1857, + /* 480 */ 1858, 1859, 1860, 1798, 1861, 1864, 1866, 1888, 1889, 1893, + /* 490 */ 1856, 1879, 1880, 1881, 1734, 1882, 1883, 1862, 1846, 1863, + /* 500 */ 1865, 1886, 1841, 1869, 1905, 1844, 1907, 1847, 1908, 1911, + /* 510 */ 1890, 1874, 1875, 1924, 1891, 1878, 1894, 1928, 1895, 1887, + /* 520 */ 1896, 1932, 1903, 1937, 1897, 1901, 1898, 1899, 1904, 1930, + /* 530 */ 1906, 1945, 1909, 1913, 1948, 1950, 1954, 1916, 1774, 1957, + /* 540 */ 1958, 1960, 1892, 1962, 1963, 1931, 1918, 1926, 1968, 1934, + /* 550 */ 1921, 1933, 1978, 1939, 1927, 1936, 1981, 1956, 1943, 1955, + /* 560 */ 1993, 1995, 1996, 1997, 1998, 1999, 1910, 1900, 1965, 1979, + /* 570 */ 2002, 1969, 1970, 1973, 1976, 1986, 1988, 1990, 1959, 1980, + /* 580 */ 1991, 1992, 2006, 1994, 2031, 2011, 2034, 2013, 2000, 2037, + /* 590 */ 2016, 2004, 2040, 2008, 2041, 2015, 2042, 2026, 2032, 2019, + /* 600 */ 2020, 2021, 1953, 1961, 2058, 1914, 1964, 1867, 2024, 2038, + /* 610 */ 2061, 1868, 2047, 1915, 1919, 2070, 2077, 1923, 1912, 1925, + /* 620 */ 1920, 2078, 2035, 1819, 1977, 1984, 1982, 2048, 2001, 2051, + /* 630 */ 1983, 2003, 2056, 2057, 2005, 2009, 2010, 2012, 2014, 2060, + /* 640 */ 2059, 2063, 2017, 2064, 1871, 2022, 2023, 2108, 2072, 1873, + /* 650 */ 2079, 2082, 2086, 2088, 2089, 2093, 2027, 2028, 2083, 1884, + /* 660 */ 2094, 2096, 2133, 2140, 2049, 2111, 1899, 2106, 2052, 2050, + /* 670 */ 2055, 2062, 2065, 2018, 2071, 2158, 2122, 2025, 2080, 2074, + /* 680 */ 1899, 2115, 2119, 2084, 1944, 2087, 2162, 2151, 1967, 2081, + /* 690 */ 2091, 2097, 2092, 2098, 2095, 2145, 2099, 2100, 2150, 2105, + /* 700 */ 2194, 2030, 2101, 2107, 2116, 2187, 2188, 2121, 2125, 2190, + /* 710 */ 2124, 2126, 2191, 2129, 2130, 2200, 2134, 2132, 2203, 2136, + /* 720 */ 2137, 2205, 2142, 2135, 2138, 2139, 2141, 2143, 2213, 2155, + /* 730 */ 2224, 2159, 2213, 2213, 2239, 2196, 2210, 2236, 2245, 2247, + /* 740 */ 2248, 2249, 2250, 2251, 2252, 2214, 2193, 2253, 2256, 2257, + /* 750 */ 2259, 2266, 2261, 2263, 2264, 2225, 1959, 2267, 1980, 2268, + /* 760 */ 2270, 2272, 2273, 2279, 2282, 2318, 2284, 2271, 2283, 2321, + /* 770 */ 2288, 2275, 2287, 2327, 2293, 2294, 2303, 2332, 2298, 2295, + /* 780 */ 2306, 2346, 2312, 2314, 2350, 2329, 2333, 2330, 2334, 2336, + /* 790 */ 2335, }; -#define YY_REDUCE_COUNT (321) -#define YY_REDUCE_MIN (-438) -#define YY_REDUCE_MAX (2292) +#define YY_REDUCE_COUNT (319) +#define YY_REDUCE_MIN (-404) +#define YY_REDUCE_MAX (2418) static const short yy_reduce_ofst[] = { - /* 0 */ 311, -340, -280, -25, -132, 158, 603, 789, 895, 969, - /* 10 */ 265, 1020, 1080, 390, 1109, 1225, 53, 454, 825, 1251, - /* 20 */ 1285, 1347, 1371, 946, 1395, 1459, 1523, 1545, 1569, 1657, - /* 30 */ 1676, 1687, 1755, 1775, 1786, 1806, 1864, 1885, 1910, 1936, - /* 40 */ 1996, 2012, 2025, 2085, 2101, 2114, 2187, 2203, 2214, 2276, - /* 50 */ 2292, 167, 792, -403, 78, -401, -360, 252, 672, 47, - /* 60 */ 197, 379, -438, -244, 339, -331, 505, -211, -274, -63, - /* 70 */ 23, -391, -40, 149, -317, -31, -342, -265, 295, 464, - /* 80 */ 486, 571, 608, 610, 622, -344, 673, 675, -252, -205, - /* 90 */ 677, 805, -243, 809, 219, 822, -92, 833, 19, -16, - /* 100 */ 423, 840, 325, 880, 563, 755, 891, 914, -268, -207, - /* 110 */ -173, -173, 327, -337, -321, -229, -93, 61, 209, 403, - /* 120 */ 439, 461, 529, 630, 746, 802, 828, 844, 856, 885, - /* 130 */ 888, 900, 901, -288, -34, -213, 90, 448, 476, 554, - /* 140 */ -34, 50, 501, 247, -409, 301, 780, 499, 533, 582, - /* 150 */ 769, 234, 422, 643, 609, 549, 786, 878, 918, 945, - /* 160 */ -364, 447, 477, 535, 547, 575, 615, 547, 628, 681, - /* 170 */ 791, 662, 667, 685, 811, 745, 814, 866, 892, 892, - /* 180 */ 883, 894, 1112, 1121, 1084, 1074, 1017, 1017, 1001, 1017, - /* 190 */ 1028, 1019, 892, 1071, 1063, 1076, 1072, 1140, 1083, 1146, - /* 200 */ 1096, 1119, 1120, 1122, 1131, 1181, 1182, 1135, 1138, 1142, - /* 210 */ 1173, 1187, 1200, 1191, 1203, 1210, 1211, 1221, 1231, 1236, - /* 220 */ 1233, 1148, 1222, 1190, 1227, 1235, 1176, 1230, 1238, 1232, - /* 230 */ 1237, 1239, 1244, 1240, 1252, 1218, 1224, 1228, 1229, 1234, - /* 240 */ 1245, 1246, 1248, 1249, 1250, 1253, 1255, 1258, 1223, 1254, - /* 250 */ 1256, 1185, 1189, 1195, 1260, 1201, 1204, 1257, 1266, 1216, - /* 260 */ 1261, 1284, 1264, 1265, 1263, 1171, 1262, 1271, 1174, 1267, - /* 270 */ 1276, 1278, 892, 1170, 1180, 1186, 1206, 1217, 1269, 1280, - /* 280 */ 1208, 1268, 1259, 1017, 1348, 1272, 1292, 1354, 1353, 1349, - /* 290 */ 1350, 1304, 1308, 1324, 1334, 1336, 1337, 1339, 1327, 1351, - /* 300 */ 1321, 1378, 1359, 1386, 1388, 1293, 1368, 1357, 1383, 1403, - /* 310 */ 1392, 1410, 1413, 1345, 1346, 1356, 1358, 1385, 1397, 1398, - /* 320 */ 1408, 1421, + /* 0 */ -296, -340, -133, -26, 88, 310, 540, 850, 881, 911, + /* 10 */ 208, 1001, 1032, 1069, 1158, 1207, 1233, 118, 1284, 1297, + /* 20 */ 1346, 1363, 1436, 1412, 1463, 1483, 426, 1550, 1580, 1639, + /* 30 */ 1712, 1743, 1778, 1815, 1840, 1877, 1902, 1974, 1989, 2007, + /* 40 */ 2054, 2076, 2123, 2182, 2195, 2212, 2244, 2311, 2331, 2401, + /* 50 */ 2418, -260, -25, 239, 149, -404, 246, 479, -28, 348, + /* 60 */ 643, -365, -294, -331, 671, -98, 24, 252, -390, -345, + /* 70 */ -265, -279, -72, 74, -318, 227, -342, 112, -232, 26, + /* 80 */ 192, 263, 368, 383, 400, 286, 424, 592, 457, 116, + /* 90 */ 595, 601, 36, 323, 675, 391, 679, 637, -63, 752, + /* 100 */ 765, 555, 776, 669, 665, 734, 779, 155, -316, -313, + /* 110 */ -313, -259, -140, -199, -188, 157, 257, 269, 427, 529, + /* 120 */ 548, 553, 642, 656, 720, 723, 726, 796, 803, 804, + /* 130 */ 844, 845, -217, -242, -15, 379, 475, 523, 616, -242, + /* 140 */ 380, 681, -250, 696, 729, 701, -46, 17, 47, 783, + /* 150 */ -375, 521, 93, 644, 421, 808, 809, 836, 846, -371, + /* 160 */ -328, 491, 570, 579, 923, 929, 579, 906, 951, 997, + /* 170 */ 940, 875, 901, 1024, 916, 1018, 1020, 1009, 981, 1009, + /* 180 */ 1036, 999, 1052, 1053, 1015, 1006, 946, 946, 930, 946, + /* 190 */ 962, 955, 1009, 1010, 993, 1008, 1013, 1068, 1011, 1083, + /* 200 */ 1029, 1048, 1055, 1056, 1078, 1125, 1127, 1081, 1085, 1088, + /* 210 */ 1122, 1126, 1137, 1129, 1141, 1142, 1144, 1157, 1163, 1169, + /* 220 */ 1164, 1092, 1155, 1124, 1159, 1170, 1111, 1171, 1177, 1172, + /* 230 */ 1174, 1179, 1178, 1180, 1184, 1161, 1162, 1165, 1167, 1173, + /* 240 */ 1181, 1182, 1183, 1187, 1188, 1189, 1185, 1193, 1152, 1154, + /* 250 */ 1197, 1128, 1133, 1134, 1200, 1139, 1150, 1196, 1213, 1153, + /* 260 */ 1190, 1223, 1195, 1198, 1210, 1108, 1199, 1212, 1147, 1204, + /* 270 */ 1215, 1216, 1009, 1145, 1148, 1149, 1214, 1191, 1217, 1218, + /* 280 */ 1136, 1202, 1205, 946, 1276, 1206, 1280, 1288, 1290, 1245, + /* 290 */ 1244, 1261, 1264, 1268, 1270, 1273, 1248, 1287, 1283, 1326, + /* 300 */ 1310, 1335, 1300, 1246, 1311, 1307, 1324, 1350, 1344, 1359, + /* 310 */ 1362, 1293, 1313, 1295, 1315, 1336, 1337, 1365, 1348, 1360, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, @@ -933,41 +1294,41 @@ static const YYACTIONTYPE yy_default[] = { /* 30 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 40 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 50 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 60 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 60 */ 2076, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 70 */ 1768, 1768, 1768, 1768, 2049, 1768, 1768, 1768, 1768, 1768, /* 80 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1857, 1768, /* 90 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 100 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1855, 2042, - /* 110 */ 2267, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 100 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1855, 2042, 2268, + /* 110 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 120 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 130 */ 1768, 1768, 1768, 1768, 2279, 1768, 1768, 1831, 1831, 1768, - /* 140 */ 2279, 2279, 2279, 1855, 2239, 2239, 1768, 1768, 1768, 1768, - /* 150 */ 1857, 2109, 1768, 1768, 1768, 1768, 1768, 1768, 1977, 1768, - /* 160 */ 1768, 1768, 1768, 1768, 2001, 1768, 1768, 1768, 2101, 1768, - /* 170 */ 1768, 2304, 2361, 1768, 1768, 2307, 1768, 1768, 1768, 1768, - /* 180 */ 1768, 2054, 1768, 1768, 1930, 2294, 2271, 2285, 2345, 2272, - /* 190 */ 2269, 2288, 1768, 2298, 1768, 1768, 2123, 1857, 1768, 1857, - /* 200 */ 2088, 2047, 1768, 2047, 2044, 1768, 1768, 2047, 2044, 2044, + /* 130 */ 1768, 1768, 1768, 2280, 1768, 1768, 1831, 1831, 1768, 2280, + /* 140 */ 2280, 2280, 1855, 2240, 2240, 1768, 1768, 1768, 1768, 1857, + /* 150 */ 2110, 1768, 1768, 1768, 1768, 1768, 1768, 1977, 1768, 1768, + /* 160 */ 1768, 1768, 1768, 2001, 1768, 1768, 1768, 2102, 1768, 1768, + /* 170 */ 2305, 2362, 1768, 1768, 2308, 1768, 1768, 1768, 1768, 1768, + /* 180 */ 1768, 2054, 1768, 1768, 1930, 2295, 2272, 2286, 2346, 2273, + /* 190 */ 2270, 2289, 1768, 2299, 1768, 1768, 2124, 1857, 1768, 1857, + /* 200 */ 2089, 2047, 1768, 2047, 2044, 1768, 1768, 2047, 2044, 2044, /* 210 */ 1919, 1915, 1768, 1913, 1768, 1768, 1768, 1768, 1815, 1768, /* 220 */ 1815, 1768, 1857, 1768, 1857, 1768, 1768, 1857, 1768, 1857, /* 230 */ 1857, 1857, 1768, 1857, 1768, 1768, 1768, 1768, 1768, 1768, /* 240 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 250 */ 1768, 2121, 2107, 1768, 1855, 2099, 2097, 1768, 1855, 2095, - /* 260 */ 2298, 1768, 1768, 1768, 1768, 2315, 2313, 1768, 2315, 2313, - /* 270 */ 1768, 1768, 1768, 2329, 2325, 2315, 2334, 2331, 2300, 2298, - /* 280 */ 2364, 2351, 2347, 2285, 1768, 1768, 2298, 1768, 1768, 1855, - /* 290 */ 1855, 1768, 2313, 1768, 1768, 1768, 1768, 1768, 2313, 1768, - /* 300 */ 1768, 1855, 1768, 1855, 1768, 1768, 1946, 1768, 1768, 1768, - /* 310 */ 1855, 1800, 1768, 2090, 2112, 2072, 2072, 1980, 1980, 1980, - /* 320 */ 1858, 1773, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 330 */ 1768, 1768, 1768, 1768, 2328, 2327, 2194, 1768, 2243, 2242, - /* 340 */ 2241, 2232, 2193, 1942, 1768, 2192, 2191, 1768, 1768, 1768, - /* 350 */ 1768, 1768, 1768, 1768, 1768, 1768, 2063, 2062, 2185, 1768, - /* 360 */ 1768, 2186, 2184, 2183, 1768, 1768, 1768, 1768, 1768, 1768, + /* 250 */ 1768, 2122, 2108, 1768, 1855, 2100, 2098, 1768, 1855, 2096, + /* 260 */ 2299, 1768, 1768, 1768, 1768, 2316, 2314, 1768, 2316, 2314, + /* 270 */ 1768, 1768, 1768, 2330, 2326, 2316, 2335, 2332, 2301, 2299, + /* 280 */ 2365, 2352, 2348, 2286, 1768, 1768, 1768, 1855, 1855, 1768, + /* 290 */ 2314, 1768, 1768, 1768, 1768, 1768, 2314, 1768, 1768, 1855, + /* 300 */ 1768, 1855, 1768, 1768, 1946, 1768, 1768, 1768, 1855, 1800, + /* 310 */ 1768, 2091, 2113, 2072, 2072, 1980, 1980, 1980, 1858, 1773, + /* 320 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 330 */ 1768, 1768, 2329, 2328, 2195, 1768, 2244, 2243, 2242, 2233, + /* 340 */ 2194, 1942, 1768, 2193, 2192, 1768, 1768, 1768, 1768, 1768, + /* 350 */ 1768, 1768, 1768, 1768, 2063, 2062, 2186, 1768, 1768, 2187, + /* 360 */ 2185, 2184, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 370 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 380 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 2348, 2352, - /* 390 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 2268, 1768, 1768, - /* 400 */ 1768, 2167, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 380 */ 1768, 1768, 1768, 1768, 1768, 1768, 2349, 2353, 1768, 1768, + /* 390 */ 1768, 1768, 1768, 1768, 2269, 1768, 1768, 1768, 2168, 1768, + /* 400 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 410 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 420 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 430 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, @@ -979,34 +1340,34 @@ static const YYACTIONTYPE yy_default[] = { /* 490 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 500 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 510 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 520 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1805, - /* 530 */ 2172, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 520 */ 1768, 1768, 1768, 1768, 1768, 1768, 1805, 2173, 1768, 1768, + /* 530 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 540 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 550 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 560 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 570 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 580 */ 1768, 1896, 1895, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 570 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1896, 1895, + /* 580 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 590 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 600 */ 1768, 1768, 1768, 1768, 1768, 2176, 1768, 1768, 1768, 1768, + /* 600 */ 1768, 1768, 2177, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 610 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 620 */ 1768, 1768, 2344, 2301, 1768, 1768, 1768, 1768, 1768, 1768, + /* 620 */ 1768, 2345, 2302, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 630 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 640 */ 1768, 1768, 2167, 1768, 2326, 1768, 1768, 2342, 1768, 2346, - /* 650 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 2278, 2274, 1768, - /* 660 */ 1768, 2270, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 2175, + /* 640 */ 1768, 2168, 1768, 2327, 1768, 1768, 2343, 1768, 2347, 1768, + /* 650 */ 1768, 1768, 1768, 1768, 1768, 1768, 2279, 2275, 1768, 1768, + /* 660 */ 2271, 1768, 1768, 1768, 1768, 1768, 2176, 1768, 1768, 1768, /* 670 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 680 */ 1768, 1768, 1768, 2166, 1768, 2229, 1768, 1768, 1768, 2263, - /* 690 */ 1768, 1768, 2214, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 700 */ 1768, 1768, 2176, 1768, 2179, 1768, 1768, 1768, 1768, 1768, - /* 710 */ 1974, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 720 */ 1768, 1768, 1768, 1768, 1768, 1768, 1958, 1956, 1955, 1954, - /* 730 */ 1768, 1987, 1768, 1768, 1768, 1983, 1982, 1768, 1768, 1768, - /* 740 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 750 */ 1876, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1868, - /* 760 */ 1768, 1867, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 680 */ 2167, 1768, 2230, 1768, 1768, 1768, 2264, 1768, 1768, 2215, + /* 690 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 2177, + /* 700 */ 1768, 2180, 1768, 1768, 1768, 1768, 1768, 1974, 1768, 1768, + /* 710 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, + /* 720 */ 1768, 1768, 1768, 1958, 1956, 1955, 1954, 1768, 1987, 1768, + /* 730 */ 1768, 1768, 1983, 1982, 1768, 1768, 1768, 1768, 1768, 1768, + /* 740 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1876, 1768, 1768, + /* 750 */ 1768, 1768, 1768, 1768, 1768, 1768, 1868, 1768, 1867, 1768, + /* 760 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 770 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, /* 780 */ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - /* 790 */ 1768, 1768, 1768, 1768, + /* 790 */ 1768, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1127,7 +1488,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* MAX_SPEED => nothing */ 0, /* START => nothing */ 0, /* TIMESTAMP => nothing */ - 286, /* END => ABORT */ + 287, /* END => ABORT */ 0, /* TABLE => nothing */ 0, /* NK_LP => nothing */ 0, /* NK_RP => nothing */ @@ -1204,8 +1565,9 @@ static const YYCODETYPE yyFallback[] = { 0, /* INTERVAL => nothing */ 0, /* COUNT => nothing */ 0, /* LAST_ROW => nothing */ - 0, /* TOPIC => nothing */ 0, /* META => nothing */ + 0, /* ONLY => nothing */ + 0, /* TOPIC => nothing */ 0, /* CONSUMER => nothing */ 0, /* GROUP => nothing */ 0, /* DESC => nothing */ @@ -1313,56 +1675,56 @@ static const YYCODETYPE yyFallback[] = { 0, /* ASC => nothing */ 0, /* NULLS => nothing */ 0, /* ABORT => nothing */ - 286, /* AFTER => ABORT */ - 286, /* ATTACH => ABORT */ - 286, /* BEFORE => ABORT */ - 286, /* BEGIN => ABORT */ - 286, /* BITAND => ABORT */ - 286, /* BITNOT => ABORT */ - 286, /* BITOR => ABORT */ - 286, /* BLOCKS => ABORT */ - 286, /* CHANGE => ABORT */ - 286, /* COMMA => ABORT */ - 286, /* CONCAT => ABORT */ - 286, /* CONFLICT => ABORT */ - 286, /* COPY => ABORT */ - 286, /* DEFERRED => ABORT */ - 286, /* DELIMITERS => ABORT */ - 286, /* DETACH => ABORT */ - 286, /* DIVIDE => ABORT */ - 286, /* DOT => ABORT */ - 286, /* EACH => ABORT */ - 286, /* FAIL => ABORT */ - 286, /* FILE => ABORT */ - 286, /* FOR => ABORT */ - 286, /* GLOB => ABORT */ - 286, /* ID => ABORT */ - 286, /* IMMEDIATE => ABORT */ - 286, /* IMPORT => ABORT */ - 286, /* INITIALLY => ABORT */ - 286, /* INSTEAD => ABORT */ - 286, /* ISNULL => ABORT */ - 286, /* KEY => ABORT */ - 286, /* MODULES => ABORT */ - 286, /* NK_BITNOT => ABORT */ - 286, /* NK_SEMI => ABORT */ - 286, /* NOTNULL => ABORT */ - 286, /* OF => ABORT */ - 286, /* PLUS => ABORT */ - 286, /* PRIVILEGE => ABORT */ - 286, /* RAISE => ABORT */ - 286, /* RESTRICT => ABORT */ - 286, /* ROW => ABORT */ - 286, /* SEMI => ABORT */ - 286, /* STAR => ABORT */ - 286, /* STATEMENT => ABORT */ - 286, /* STRICT => ABORT */ - 286, /* STRING => ABORT */ - 286, /* TIMES => ABORT */ - 286, /* VALUES => ABORT */ - 286, /* VARIABLE => ABORT */ - 286, /* VIEW => ABORT */ - 286, /* WAL => ABORT */ + 287, /* AFTER => ABORT */ + 287, /* ATTACH => ABORT */ + 287, /* BEFORE => ABORT */ + 287, /* BEGIN => ABORT */ + 287, /* BITAND => ABORT */ + 287, /* BITNOT => ABORT */ + 287, /* BITOR => ABORT */ + 287, /* BLOCKS => ABORT */ + 287, /* CHANGE => ABORT */ + 287, /* COMMA => ABORT */ + 287, /* CONCAT => ABORT */ + 287, /* CONFLICT => ABORT */ + 287, /* COPY => ABORT */ + 287, /* DEFERRED => ABORT */ + 287, /* DELIMITERS => ABORT */ + 287, /* DETACH => ABORT */ + 287, /* DIVIDE => ABORT */ + 287, /* DOT => ABORT */ + 287, /* EACH => ABORT */ + 287, /* FAIL => ABORT */ + 287, /* FILE => ABORT */ + 287, /* FOR => ABORT */ + 287, /* GLOB => ABORT */ + 287, /* ID => ABORT */ + 287, /* IMMEDIATE => ABORT */ + 287, /* IMPORT => ABORT */ + 287, /* INITIALLY => ABORT */ + 287, /* INSTEAD => ABORT */ + 287, /* ISNULL => ABORT */ + 287, /* KEY => ABORT */ + 287, /* MODULES => ABORT */ + 287, /* NK_BITNOT => ABORT */ + 287, /* NK_SEMI => ABORT */ + 287, /* NOTNULL => ABORT */ + 287, /* OF => ABORT */ + 287, /* PLUS => ABORT */ + 287, /* PRIVILEGE => ABORT */ + 287, /* RAISE => ABORT */ + 287, /* RESTRICT => ABORT */ + 287, /* ROW => ABORT */ + 287, /* SEMI => ABORT */ + 287, /* STAR => ABORT */ + 287, /* STATEMENT => ABORT */ + 287, /* STRICT => ABORT */ + 287, /* STRING => ABORT */ + 287, /* TIMES => ABORT */ + 287, /* VALUES => ABORT */ + 287, /* VARIABLE => ABORT */ + 287, /* VIEW => ABORT */ + 287, /* WAL => ABORT */ }; #endif /* YYFALLBACK */ @@ -1416,6 +1778,7 @@ typedef struct yyParser yyParser; #ifndef NDEBUG #include +#include static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -1628,313 +1991,315 @@ static const char *const yyTokenName[] = { /* 175 */ "INTERVAL", /* 176 */ "COUNT", /* 177 */ "LAST_ROW", - /* 178 */ "TOPIC", - /* 179 */ "META", - /* 180 */ "CONSUMER", - /* 181 */ "GROUP", - /* 182 */ "DESC", - /* 183 */ "DESCRIBE", - /* 184 */ "RESET", - /* 185 */ "QUERY", - /* 186 */ "CACHE", - /* 187 */ "EXPLAIN", - /* 188 */ "ANALYZE", - /* 189 */ "VERBOSE", - /* 190 */ "NK_BOOL", - /* 191 */ "RATIO", - /* 192 */ "NK_FLOAT", - /* 193 */ "OUTPUTTYPE", - /* 194 */ "AGGREGATE", - /* 195 */ "BUFSIZE", - /* 196 */ "LANGUAGE", - /* 197 */ "REPLACE", - /* 198 */ "STREAM", - /* 199 */ "INTO", - /* 200 */ "PAUSE", - /* 201 */ "RESUME", - /* 202 */ "TRIGGER", - /* 203 */ "AT_ONCE", - /* 204 */ "WINDOW_CLOSE", - /* 205 */ "IGNORE", - /* 206 */ "EXPIRED", - /* 207 */ "FILL_HISTORY", - /* 208 */ "UPDATE", - /* 209 */ "SUBTABLE", - /* 210 */ "UNTREATED", - /* 211 */ "KILL", - /* 212 */ "CONNECTION", - /* 213 */ "TRANSACTION", - /* 214 */ "BALANCE", - /* 215 */ "VGROUP", - /* 216 */ "LEADER", - /* 217 */ "MERGE", - /* 218 */ "REDISTRIBUTE", - /* 219 */ "SPLIT", - /* 220 */ "DELETE", - /* 221 */ "INSERT", - /* 222 */ "NULL", - /* 223 */ "NK_QUESTION", - /* 224 */ "NK_ARROW", - /* 225 */ "ROWTS", - /* 226 */ "QSTART", - /* 227 */ "QEND", - /* 228 */ "QDURATION", - /* 229 */ "WSTART", - /* 230 */ "WEND", - /* 231 */ "WDURATION", - /* 232 */ "IROWTS", - /* 233 */ "ISFILLED", - /* 234 */ "CAST", - /* 235 */ "NOW", - /* 236 */ "TODAY", - /* 237 */ "TIMEZONE", - /* 238 */ "CLIENT_VERSION", - /* 239 */ "SERVER_VERSION", - /* 240 */ "SERVER_STATUS", - /* 241 */ "CURRENT_USER", - /* 242 */ "CASE", - /* 243 */ "WHEN", - /* 244 */ "THEN", - /* 245 */ "ELSE", - /* 246 */ "BETWEEN", - /* 247 */ "IS", - /* 248 */ "NK_LT", - /* 249 */ "NK_GT", - /* 250 */ "NK_LE", - /* 251 */ "NK_GE", - /* 252 */ "NK_NE", - /* 253 */ "MATCH", - /* 254 */ "NMATCH", - /* 255 */ "CONTAINS", - /* 256 */ "IN", - /* 257 */ "JOIN", - /* 258 */ "INNER", - /* 259 */ "SELECT", - /* 260 */ "DISTINCT", - /* 261 */ "WHERE", - /* 262 */ "PARTITION", - /* 263 */ "BY", - /* 264 */ "SESSION", - /* 265 */ "STATE_WINDOW", - /* 266 */ "EVENT_WINDOW", - /* 267 */ "SLIDING", - /* 268 */ "FILL", - /* 269 */ "VALUE", - /* 270 */ "VALUE_F", - /* 271 */ "NONE", - /* 272 */ "PREV", - /* 273 */ "NULL_F", - /* 274 */ "LINEAR", - /* 275 */ "NEXT", - /* 276 */ "HAVING", - /* 277 */ "RANGE", - /* 278 */ "EVERY", - /* 279 */ "ORDER", - /* 280 */ "SLIMIT", - /* 281 */ "SOFFSET", - /* 282 */ "LIMIT", - /* 283 */ "OFFSET", - /* 284 */ "ASC", - /* 285 */ "NULLS", - /* 286 */ "ABORT", - /* 287 */ "AFTER", - /* 288 */ "ATTACH", - /* 289 */ "BEFORE", - /* 290 */ "BEGIN", - /* 291 */ "BITAND", - /* 292 */ "BITNOT", - /* 293 */ "BITOR", - /* 294 */ "BLOCKS", - /* 295 */ "CHANGE", - /* 296 */ "COMMA", - /* 297 */ "CONCAT", - /* 298 */ "CONFLICT", - /* 299 */ "COPY", - /* 300 */ "DEFERRED", - /* 301 */ "DELIMITERS", - /* 302 */ "DETACH", - /* 303 */ "DIVIDE", - /* 304 */ "DOT", - /* 305 */ "EACH", - /* 306 */ "FAIL", - /* 307 */ "FILE", - /* 308 */ "FOR", - /* 309 */ "GLOB", - /* 310 */ "ID", - /* 311 */ "IMMEDIATE", - /* 312 */ "IMPORT", - /* 313 */ "INITIALLY", - /* 314 */ "INSTEAD", - /* 315 */ "ISNULL", - /* 316 */ "KEY", - /* 317 */ "MODULES", - /* 318 */ "NK_BITNOT", - /* 319 */ "NK_SEMI", - /* 320 */ "NOTNULL", - /* 321 */ "OF", - /* 322 */ "PLUS", - /* 323 */ "PRIVILEGE", - /* 324 */ "RAISE", - /* 325 */ "RESTRICT", - /* 326 */ "ROW", - /* 327 */ "SEMI", - /* 328 */ "STAR", - /* 329 */ "STATEMENT", - /* 330 */ "STRICT", - /* 331 */ "STRING", - /* 332 */ "TIMES", - /* 333 */ "VALUES", - /* 334 */ "VARIABLE", - /* 335 */ "VIEW", - /* 336 */ "WAL", - /* 337 */ "cmd", - /* 338 */ "account_options", - /* 339 */ "alter_account_options", - /* 340 */ "literal", - /* 341 */ "alter_account_option", - /* 342 */ "user_name", - /* 343 */ "sysinfo_opt", - /* 344 */ "privileges", - /* 345 */ "priv_level", - /* 346 */ "with_opt", - /* 347 */ "priv_type_list", - /* 348 */ "priv_type", - /* 349 */ "db_name", - /* 350 */ "table_name", - /* 351 */ "topic_name", - /* 352 */ "search_condition", - /* 353 */ "dnode_endpoint", - /* 354 */ "force_opt", - /* 355 */ "unsafe_opt", - /* 356 */ "not_exists_opt", - /* 357 */ "db_options", - /* 358 */ "exists_opt", - /* 359 */ "alter_db_options", - /* 360 */ "speed_opt", - /* 361 */ "start_opt", - /* 362 */ "end_opt", - /* 363 */ "integer_list", - /* 364 */ "variable_list", - /* 365 */ "retention_list", - /* 366 */ "signed", - /* 367 */ "alter_db_option", - /* 368 */ "retention", - /* 369 */ "full_table_name", - /* 370 */ "column_def_list", - /* 371 */ "tags_def_opt", - /* 372 */ "table_options", - /* 373 */ "multi_create_clause", - /* 374 */ "tags_def", - /* 375 */ "multi_drop_clause", - /* 376 */ "alter_table_clause", - /* 377 */ "alter_table_options", - /* 378 */ "column_name", - /* 379 */ "type_name", - /* 380 */ "signed_literal", - /* 381 */ "create_subtable_clause", - /* 382 */ "specific_cols_opt", - /* 383 */ "expression_list", - /* 384 */ "drop_table_clause", - /* 385 */ "col_name_list", - /* 386 */ "column_def", - /* 387 */ "duration_list", - /* 388 */ "rollup_func_list", - /* 389 */ "alter_table_option", - /* 390 */ "duration_literal", - /* 391 */ "rollup_func_name", - /* 392 */ "function_name", - /* 393 */ "col_name", - /* 394 */ "db_name_cond_opt", - /* 395 */ "like_pattern_opt", - /* 396 */ "table_name_cond", - /* 397 */ "from_db_opt", - /* 398 */ "tag_list_opt", - /* 399 */ "tag_item", - /* 400 */ "column_alias", - /* 401 */ "full_index_name", - /* 402 */ "index_options", - /* 403 */ "index_name", - /* 404 */ "func_list", - /* 405 */ "sliding_opt", - /* 406 */ "sma_stream_opt", - /* 407 */ "func", - /* 408 */ "sma_func_name", - /* 409 */ "query_or_subquery", - /* 410 */ "where_clause_opt", - /* 411 */ "cgroup_name", - /* 412 */ "analyze_opt", - /* 413 */ "explain_options", - /* 414 */ "insert_query", - /* 415 */ "or_replace_opt", - /* 416 */ "agg_func_opt", - /* 417 */ "bufsize_opt", - /* 418 */ "language_opt", - /* 419 */ "stream_name", - /* 420 */ "stream_options", - /* 421 */ "col_list_opt", - /* 422 */ "tag_def_or_ref_opt", - /* 423 */ "subtable_opt", - /* 424 */ "ignore_opt", - /* 425 */ "expression", - /* 426 */ "dnode_list", - /* 427 */ "literal_func", - /* 428 */ "literal_list", - /* 429 */ "table_alias", - /* 430 */ "expr_or_subquery", - /* 431 */ "pseudo_column", - /* 432 */ "column_reference", - /* 433 */ "function_expression", - /* 434 */ "case_when_expression", - /* 435 */ "star_func", - /* 436 */ "star_func_para_list", - /* 437 */ "noarg_func", - /* 438 */ "other_para_list", - /* 439 */ "star_func_para", - /* 440 */ "when_then_list", - /* 441 */ "case_when_else_opt", - /* 442 */ "common_expression", - /* 443 */ "when_then_expr", - /* 444 */ "predicate", - /* 445 */ "compare_op", - /* 446 */ "in_op", - /* 447 */ "in_predicate_value", - /* 448 */ "boolean_value_expression", - /* 449 */ "boolean_primary", - /* 450 */ "from_clause_opt", - /* 451 */ "table_reference_list", - /* 452 */ "table_reference", - /* 453 */ "table_primary", - /* 454 */ "joined_table", - /* 455 */ "alias_opt", - /* 456 */ "subquery", - /* 457 */ "parenthesized_joined_table", - /* 458 */ "join_type", - /* 459 */ "query_specification", - /* 460 */ "set_quantifier_opt", - /* 461 */ "select_list", - /* 462 */ "partition_by_clause_opt", - /* 463 */ "range_opt", - /* 464 */ "every_opt", - /* 465 */ "fill_opt", - /* 466 */ "twindow_clause_opt", - /* 467 */ "group_by_clause_opt", - /* 468 */ "having_clause_opt", - /* 469 */ "select_item", - /* 470 */ "partition_list", - /* 471 */ "partition_item", - /* 472 */ "fill_mode", - /* 473 */ "group_by_list", - /* 474 */ "query_expression", - /* 475 */ "query_simple", - /* 476 */ "order_by_clause_opt", - /* 477 */ "slimit_clause_opt", - /* 478 */ "limit_clause_opt", - /* 479 */ "union_query_expression", - /* 480 */ "query_simple_or_subquery", - /* 481 */ "sort_specification_list", - /* 482 */ "sort_specification", - /* 483 */ "ordering_specification_opt", - /* 484 */ "null_ordering_opt", + /* 178 */ "META", + /* 179 */ "ONLY", + /* 180 */ "TOPIC", + /* 181 */ "CONSUMER", + /* 182 */ "GROUP", + /* 183 */ "DESC", + /* 184 */ "DESCRIBE", + /* 185 */ "RESET", + /* 186 */ "QUERY", + /* 187 */ "CACHE", + /* 188 */ "EXPLAIN", + /* 189 */ "ANALYZE", + /* 190 */ "VERBOSE", + /* 191 */ "NK_BOOL", + /* 192 */ "RATIO", + /* 193 */ "NK_FLOAT", + /* 194 */ "OUTPUTTYPE", + /* 195 */ "AGGREGATE", + /* 196 */ "BUFSIZE", + /* 197 */ "LANGUAGE", + /* 198 */ "REPLACE", + /* 199 */ "STREAM", + /* 200 */ "INTO", + /* 201 */ "PAUSE", + /* 202 */ "RESUME", + /* 203 */ "TRIGGER", + /* 204 */ "AT_ONCE", + /* 205 */ "WINDOW_CLOSE", + /* 206 */ "IGNORE", + /* 207 */ "EXPIRED", + /* 208 */ "FILL_HISTORY", + /* 209 */ "UPDATE", + /* 210 */ "SUBTABLE", + /* 211 */ "UNTREATED", + /* 212 */ "KILL", + /* 213 */ "CONNECTION", + /* 214 */ "TRANSACTION", + /* 215 */ "BALANCE", + /* 216 */ "VGROUP", + /* 217 */ "LEADER", + /* 218 */ "MERGE", + /* 219 */ "REDISTRIBUTE", + /* 220 */ "SPLIT", + /* 221 */ "DELETE", + /* 222 */ "INSERT", + /* 223 */ "NULL", + /* 224 */ "NK_QUESTION", + /* 225 */ "NK_ARROW", + /* 226 */ "ROWTS", + /* 227 */ "QSTART", + /* 228 */ "QEND", + /* 229 */ "QDURATION", + /* 230 */ "WSTART", + /* 231 */ "WEND", + /* 232 */ "WDURATION", + /* 233 */ "IROWTS", + /* 234 */ "ISFILLED", + /* 235 */ "CAST", + /* 236 */ "NOW", + /* 237 */ "TODAY", + /* 238 */ "TIMEZONE", + /* 239 */ "CLIENT_VERSION", + /* 240 */ "SERVER_VERSION", + /* 241 */ "SERVER_STATUS", + /* 242 */ "CURRENT_USER", + /* 243 */ "CASE", + /* 244 */ "WHEN", + /* 245 */ "THEN", + /* 246 */ "ELSE", + /* 247 */ "BETWEEN", + /* 248 */ "IS", + /* 249 */ "NK_LT", + /* 250 */ "NK_GT", + /* 251 */ "NK_LE", + /* 252 */ "NK_GE", + /* 253 */ "NK_NE", + /* 254 */ "MATCH", + /* 255 */ "NMATCH", + /* 256 */ "CONTAINS", + /* 257 */ "IN", + /* 258 */ "JOIN", + /* 259 */ "INNER", + /* 260 */ "SELECT", + /* 261 */ "DISTINCT", + /* 262 */ "WHERE", + /* 263 */ "PARTITION", + /* 264 */ "BY", + /* 265 */ "SESSION", + /* 266 */ "STATE_WINDOW", + /* 267 */ "EVENT_WINDOW", + /* 268 */ "SLIDING", + /* 269 */ "FILL", + /* 270 */ "VALUE", + /* 271 */ "VALUE_F", + /* 272 */ "NONE", + /* 273 */ "PREV", + /* 274 */ "NULL_F", + /* 275 */ "LINEAR", + /* 276 */ "NEXT", + /* 277 */ "HAVING", + /* 278 */ "RANGE", + /* 279 */ "EVERY", + /* 280 */ "ORDER", + /* 281 */ "SLIMIT", + /* 282 */ "SOFFSET", + /* 283 */ "LIMIT", + /* 284 */ "OFFSET", + /* 285 */ "ASC", + /* 286 */ "NULLS", + /* 287 */ "ABORT", + /* 288 */ "AFTER", + /* 289 */ "ATTACH", + /* 290 */ "BEFORE", + /* 291 */ "BEGIN", + /* 292 */ "BITAND", + /* 293 */ "BITNOT", + /* 294 */ "BITOR", + /* 295 */ "BLOCKS", + /* 296 */ "CHANGE", + /* 297 */ "COMMA", + /* 298 */ "CONCAT", + /* 299 */ "CONFLICT", + /* 300 */ "COPY", + /* 301 */ "DEFERRED", + /* 302 */ "DELIMITERS", + /* 303 */ "DETACH", + /* 304 */ "DIVIDE", + /* 305 */ "DOT", + /* 306 */ "EACH", + /* 307 */ "FAIL", + /* 308 */ "FILE", + /* 309 */ "FOR", + /* 310 */ "GLOB", + /* 311 */ "ID", + /* 312 */ "IMMEDIATE", + /* 313 */ "IMPORT", + /* 314 */ "INITIALLY", + /* 315 */ "INSTEAD", + /* 316 */ "ISNULL", + /* 317 */ "KEY", + /* 318 */ "MODULES", + /* 319 */ "NK_BITNOT", + /* 320 */ "NK_SEMI", + /* 321 */ "NOTNULL", + /* 322 */ "OF", + /* 323 */ "PLUS", + /* 324 */ "PRIVILEGE", + /* 325 */ "RAISE", + /* 326 */ "RESTRICT", + /* 327 */ "ROW", + /* 328 */ "SEMI", + /* 329 */ "STAR", + /* 330 */ "STATEMENT", + /* 331 */ "STRICT", + /* 332 */ "STRING", + /* 333 */ "TIMES", + /* 334 */ "VALUES", + /* 335 */ "VARIABLE", + /* 336 */ "VIEW", + /* 337 */ "WAL", + /* 338 */ "cmd", + /* 339 */ "account_options", + /* 340 */ "alter_account_options", + /* 341 */ "literal", + /* 342 */ "alter_account_option", + /* 343 */ "user_name", + /* 344 */ "sysinfo_opt", + /* 345 */ "privileges", + /* 346 */ "priv_level", + /* 347 */ "with_opt", + /* 348 */ "priv_type_list", + /* 349 */ "priv_type", + /* 350 */ "db_name", + /* 351 */ "table_name", + /* 352 */ "topic_name", + /* 353 */ "search_condition", + /* 354 */ "dnode_endpoint", + /* 355 */ "force_opt", + /* 356 */ "unsafe_opt", + /* 357 */ "not_exists_opt", + /* 358 */ "db_options", + /* 359 */ "exists_opt", + /* 360 */ "alter_db_options", + /* 361 */ "speed_opt", + /* 362 */ "start_opt", + /* 363 */ "end_opt", + /* 364 */ "integer_list", + /* 365 */ "variable_list", + /* 366 */ "retention_list", + /* 367 */ "signed", + /* 368 */ "alter_db_option", + /* 369 */ "retention", + /* 370 */ "full_table_name", + /* 371 */ "column_def_list", + /* 372 */ "tags_def_opt", + /* 373 */ "table_options", + /* 374 */ "multi_create_clause", + /* 375 */ "tags_def", + /* 376 */ "multi_drop_clause", + /* 377 */ "alter_table_clause", + /* 378 */ "alter_table_options", + /* 379 */ "column_name", + /* 380 */ "type_name", + /* 381 */ "signed_literal", + /* 382 */ "create_subtable_clause", + /* 383 */ "specific_cols_opt", + /* 384 */ "expression_list", + /* 385 */ "drop_table_clause", + /* 386 */ "col_name_list", + /* 387 */ "column_def", + /* 388 */ "duration_list", + /* 389 */ "rollup_func_list", + /* 390 */ "alter_table_option", + /* 391 */ "duration_literal", + /* 392 */ "rollup_func_name", + /* 393 */ "function_name", + /* 394 */ "col_name", + /* 395 */ "db_name_cond_opt", + /* 396 */ "like_pattern_opt", + /* 397 */ "table_name_cond", + /* 398 */ "from_db_opt", + /* 399 */ "tag_list_opt", + /* 400 */ "tag_item", + /* 401 */ "column_alias", + /* 402 */ "full_index_name", + /* 403 */ "index_options", + /* 404 */ "index_name", + /* 405 */ "func_list", + /* 406 */ "sliding_opt", + /* 407 */ "sma_stream_opt", + /* 408 */ "func", + /* 409 */ "sma_func_name", + /* 410 */ "with_meta", + /* 411 */ "query_or_subquery", + /* 412 */ "where_clause_opt", + /* 413 */ "cgroup_name", + /* 414 */ "analyze_opt", + /* 415 */ "explain_options", + /* 416 */ "insert_query", + /* 417 */ "or_replace_opt", + /* 418 */ "agg_func_opt", + /* 419 */ "bufsize_opt", + /* 420 */ "language_opt", + /* 421 */ "stream_name", + /* 422 */ "stream_options", + /* 423 */ "col_list_opt", + /* 424 */ "tag_def_or_ref_opt", + /* 425 */ "subtable_opt", + /* 426 */ "ignore_opt", + /* 427 */ "expression", + /* 428 */ "dnode_list", + /* 429 */ "literal_func", + /* 430 */ "literal_list", + /* 431 */ "table_alias", + /* 432 */ "expr_or_subquery", + /* 433 */ "pseudo_column", + /* 434 */ "column_reference", + /* 435 */ "function_expression", + /* 436 */ "case_when_expression", + /* 437 */ "star_func", + /* 438 */ "star_func_para_list", + /* 439 */ "noarg_func", + /* 440 */ "other_para_list", + /* 441 */ "star_func_para", + /* 442 */ "when_then_list", + /* 443 */ "case_when_else_opt", + /* 444 */ "common_expression", + /* 445 */ "when_then_expr", + /* 446 */ "predicate", + /* 447 */ "compare_op", + /* 448 */ "in_op", + /* 449 */ "in_predicate_value", + /* 450 */ "boolean_value_expression", + /* 451 */ "boolean_primary", + /* 452 */ "from_clause_opt", + /* 453 */ "table_reference_list", + /* 454 */ "table_reference", + /* 455 */ "table_primary", + /* 456 */ "joined_table", + /* 457 */ "alias_opt", + /* 458 */ "subquery", + /* 459 */ "parenthesized_joined_table", + /* 460 */ "join_type", + /* 461 */ "query_specification", + /* 462 */ "set_quantifier_opt", + /* 463 */ "select_list", + /* 464 */ "partition_by_clause_opt", + /* 465 */ "range_opt", + /* 466 */ "every_opt", + /* 467 */ "fill_opt", + /* 468 */ "twindow_clause_opt", + /* 469 */ "group_by_clause_opt", + /* 470 */ "having_clause_opt", + /* 471 */ "select_item", + /* 472 */ "partition_list", + /* 473 */ "partition_item", + /* 474 */ "fill_mode", + /* 475 */ "group_by_list", + /* 476 */ "query_expression", + /* 477 */ "query_simple", + /* 478 */ "order_by_clause_opt", + /* 479 */ "slimit_clause_opt", + /* 480 */ "limit_clause_opt", + /* 481 */ "union_query_expression", + /* 482 */ "query_simple_or_subquery", + /* 483 */ "sort_specification_list", + /* 484 */ "sort_specification", + /* 485 */ "ordering_specification_opt", + /* 486 */ "null_ordering_opt", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -2247,297 +2612,298 @@ static const char *const yyRuleName[] = { /* 302 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", /* 303 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", /* 304 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", - /* 305 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", - /* 306 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name", - /* 307 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name", - /* 308 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name where_clause_opt", - /* 309 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name where_clause_opt", - /* 310 */ "cmd ::= DROP TOPIC exists_opt topic_name", - /* 311 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", - /* 312 */ "cmd ::= DESC full_table_name", - /* 313 */ "cmd ::= DESCRIBE full_table_name", - /* 314 */ "cmd ::= RESET QUERY CACHE", - /* 315 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", - /* 316 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", - /* 317 */ "analyze_opt ::=", - /* 318 */ "analyze_opt ::= ANALYZE", - /* 319 */ "explain_options ::=", - /* 320 */ "explain_options ::= explain_options VERBOSE NK_BOOL", - /* 321 */ "explain_options ::= explain_options RATIO NK_FLOAT", - /* 322 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", - /* 323 */ "cmd ::= DROP FUNCTION exists_opt function_name", - /* 324 */ "agg_func_opt ::=", - /* 325 */ "agg_func_opt ::= AGGREGATE", - /* 326 */ "bufsize_opt ::=", - /* 327 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", - /* 328 */ "language_opt ::=", - /* 329 */ "language_opt ::= LANGUAGE NK_STRING", - /* 330 */ "or_replace_opt ::=", - /* 331 */ "or_replace_opt ::= OR REPLACE", - /* 332 */ "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", - /* 333 */ "cmd ::= DROP STREAM exists_opt stream_name", - /* 334 */ "cmd ::= PAUSE STREAM exists_opt stream_name", - /* 335 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", - /* 336 */ "col_list_opt ::=", - /* 337 */ "col_list_opt ::= NK_LP col_name_list NK_RP", - /* 338 */ "tag_def_or_ref_opt ::=", - /* 339 */ "tag_def_or_ref_opt ::= tags_def", - /* 340 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", - /* 341 */ "stream_options ::=", - /* 342 */ "stream_options ::= stream_options TRIGGER AT_ONCE", - /* 343 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", - /* 344 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", - /* 345 */ "stream_options ::= stream_options WATERMARK duration_literal", - /* 346 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", - /* 347 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", - /* 348 */ "stream_options ::= stream_options DELETE_MARK duration_literal", - /* 349 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", - /* 350 */ "subtable_opt ::=", - /* 351 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", - /* 352 */ "ignore_opt ::=", - /* 353 */ "ignore_opt ::= IGNORE UNTREATED", - /* 354 */ "cmd ::= KILL CONNECTION NK_INTEGER", - /* 355 */ "cmd ::= KILL QUERY NK_STRING", - /* 356 */ "cmd ::= KILL TRANSACTION NK_INTEGER", - /* 357 */ "cmd ::= BALANCE VGROUP", - /* 358 */ "cmd ::= BALANCE VGROUP LEADER", - /* 359 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", - /* 360 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", - /* 361 */ "cmd ::= SPLIT VGROUP NK_INTEGER", - /* 362 */ "dnode_list ::= DNODE NK_INTEGER", - /* 363 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", - /* 364 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", - /* 365 */ "cmd ::= query_or_subquery", - /* 366 */ "cmd ::= insert_query", - /* 367 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", - /* 368 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", - /* 369 */ "literal ::= NK_INTEGER", - /* 370 */ "literal ::= NK_FLOAT", - /* 371 */ "literal ::= NK_STRING", - /* 372 */ "literal ::= NK_BOOL", - /* 373 */ "literal ::= TIMESTAMP NK_STRING", - /* 374 */ "literal ::= duration_literal", - /* 375 */ "literal ::= NULL", - /* 376 */ "literal ::= NK_QUESTION", - /* 377 */ "duration_literal ::= NK_VARIABLE", - /* 378 */ "signed ::= NK_INTEGER", - /* 379 */ "signed ::= NK_PLUS NK_INTEGER", - /* 380 */ "signed ::= NK_MINUS NK_INTEGER", - /* 381 */ "signed ::= NK_FLOAT", - /* 382 */ "signed ::= NK_PLUS NK_FLOAT", - /* 383 */ "signed ::= NK_MINUS NK_FLOAT", - /* 384 */ "signed_literal ::= signed", - /* 385 */ "signed_literal ::= NK_STRING", - /* 386 */ "signed_literal ::= NK_BOOL", - /* 387 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 388 */ "signed_literal ::= duration_literal", - /* 389 */ "signed_literal ::= NULL", - /* 390 */ "signed_literal ::= literal_func", - /* 391 */ "signed_literal ::= NK_QUESTION", - /* 392 */ "literal_list ::= signed_literal", - /* 393 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 394 */ "db_name ::= NK_ID", - /* 395 */ "table_name ::= NK_ID", - /* 396 */ "column_name ::= NK_ID", - /* 397 */ "function_name ::= NK_ID", - /* 398 */ "table_alias ::= NK_ID", - /* 399 */ "column_alias ::= NK_ID", - /* 400 */ "user_name ::= NK_ID", - /* 401 */ "topic_name ::= NK_ID", - /* 402 */ "stream_name ::= NK_ID", - /* 403 */ "cgroup_name ::= NK_ID", - /* 404 */ "index_name ::= NK_ID", - /* 405 */ "expr_or_subquery ::= expression", - /* 406 */ "expression ::= literal", - /* 407 */ "expression ::= pseudo_column", - /* 408 */ "expression ::= column_reference", - /* 409 */ "expression ::= function_expression", - /* 410 */ "expression ::= case_when_expression", - /* 411 */ "expression ::= NK_LP expression NK_RP", - /* 412 */ "expression ::= NK_PLUS expr_or_subquery", - /* 413 */ "expression ::= NK_MINUS expr_or_subquery", - /* 414 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", - /* 415 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", - /* 416 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", - /* 417 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", - /* 418 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", - /* 419 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 420 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", - /* 421 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", - /* 422 */ "expression_list ::= expr_or_subquery", - /* 423 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", - /* 424 */ "column_reference ::= column_name", - /* 425 */ "column_reference ::= table_name NK_DOT column_name", - /* 426 */ "pseudo_column ::= ROWTS", - /* 427 */ "pseudo_column ::= TBNAME", - /* 428 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 429 */ "pseudo_column ::= QSTART", - /* 430 */ "pseudo_column ::= QEND", - /* 431 */ "pseudo_column ::= QDURATION", - /* 432 */ "pseudo_column ::= WSTART", - /* 433 */ "pseudo_column ::= WEND", - /* 434 */ "pseudo_column ::= WDURATION", - /* 435 */ "pseudo_column ::= IROWTS", - /* 436 */ "pseudo_column ::= ISFILLED", - /* 437 */ "pseudo_column ::= QTAGS", - /* 438 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 439 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 440 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", - /* 441 */ "function_expression ::= literal_func", - /* 442 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 443 */ "literal_func ::= NOW", - /* 444 */ "noarg_func ::= NOW", - /* 445 */ "noarg_func ::= TODAY", - /* 446 */ "noarg_func ::= TIMEZONE", - /* 447 */ "noarg_func ::= DATABASE", - /* 448 */ "noarg_func ::= CLIENT_VERSION", - /* 449 */ "noarg_func ::= SERVER_VERSION", - /* 450 */ "noarg_func ::= SERVER_STATUS", - /* 451 */ "noarg_func ::= CURRENT_USER", - /* 452 */ "noarg_func ::= USER", - /* 453 */ "star_func ::= COUNT", - /* 454 */ "star_func ::= FIRST", - /* 455 */ "star_func ::= LAST", - /* 456 */ "star_func ::= LAST_ROW", - /* 457 */ "star_func_para_list ::= NK_STAR", - /* 458 */ "star_func_para_list ::= other_para_list", - /* 459 */ "other_para_list ::= star_func_para", - /* 460 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 461 */ "star_func_para ::= expr_or_subquery", - /* 462 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 463 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", - /* 464 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", - /* 465 */ "when_then_list ::= when_then_expr", - /* 466 */ "when_then_list ::= when_then_list when_then_expr", - /* 467 */ "when_then_expr ::= WHEN common_expression THEN common_expression", - /* 468 */ "case_when_else_opt ::=", - /* 469 */ "case_when_else_opt ::= ELSE common_expression", - /* 470 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", - /* 471 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", - /* 472 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", - /* 473 */ "predicate ::= expr_or_subquery IS NULL", - /* 474 */ "predicate ::= expr_or_subquery IS NOT NULL", - /* 475 */ "predicate ::= expr_or_subquery in_op in_predicate_value", - /* 476 */ "compare_op ::= NK_LT", - /* 477 */ "compare_op ::= NK_GT", - /* 478 */ "compare_op ::= NK_LE", - /* 479 */ "compare_op ::= NK_GE", - /* 480 */ "compare_op ::= NK_NE", - /* 481 */ "compare_op ::= NK_EQ", - /* 482 */ "compare_op ::= LIKE", - /* 483 */ "compare_op ::= NOT LIKE", - /* 484 */ "compare_op ::= MATCH", - /* 485 */ "compare_op ::= NMATCH", - /* 486 */ "compare_op ::= CONTAINS", - /* 487 */ "in_op ::= IN", - /* 488 */ "in_op ::= NOT IN", - /* 489 */ "in_predicate_value ::= NK_LP literal_list NK_RP", - /* 490 */ "boolean_value_expression ::= boolean_primary", - /* 491 */ "boolean_value_expression ::= NOT boolean_primary", - /* 492 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 493 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 494 */ "boolean_primary ::= predicate", - /* 495 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 496 */ "common_expression ::= expr_or_subquery", - /* 497 */ "common_expression ::= boolean_value_expression", - /* 498 */ "from_clause_opt ::=", - /* 499 */ "from_clause_opt ::= FROM table_reference_list", - /* 500 */ "table_reference_list ::= table_reference", - /* 501 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 502 */ "table_reference ::= table_primary", - /* 503 */ "table_reference ::= joined_table", - /* 504 */ "table_primary ::= table_name alias_opt", - /* 505 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 506 */ "table_primary ::= subquery alias_opt", - /* 507 */ "table_primary ::= parenthesized_joined_table", - /* 508 */ "alias_opt ::=", - /* 509 */ "alias_opt ::= table_alias", - /* 510 */ "alias_opt ::= AS table_alias", - /* 511 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 512 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 513 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 514 */ "join_type ::=", - /* 515 */ "join_type ::= INNER", - /* 516 */ "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", - /* 517 */ "set_quantifier_opt ::=", - /* 518 */ "set_quantifier_opt ::= DISTINCT", - /* 519 */ "set_quantifier_opt ::= ALL", - /* 520 */ "select_list ::= select_item", - /* 521 */ "select_list ::= select_list NK_COMMA select_item", - /* 522 */ "select_item ::= NK_STAR", - /* 523 */ "select_item ::= common_expression", - /* 524 */ "select_item ::= common_expression column_alias", - /* 525 */ "select_item ::= common_expression AS column_alias", - /* 526 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 527 */ "where_clause_opt ::=", - /* 528 */ "where_clause_opt ::= WHERE search_condition", - /* 529 */ "partition_by_clause_opt ::=", - /* 530 */ "partition_by_clause_opt ::= PARTITION BY partition_list", - /* 531 */ "partition_list ::= partition_item", - /* 532 */ "partition_list ::= partition_list NK_COMMA partition_item", - /* 533 */ "partition_item ::= expr_or_subquery", - /* 534 */ "partition_item ::= expr_or_subquery column_alias", - /* 535 */ "partition_item ::= expr_or_subquery AS column_alias", - /* 536 */ "twindow_clause_opt ::=", - /* 537 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 538 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", - /* 539 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 540 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 541 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", - /* 542 */ "sliding_opt ::=", - /* 543 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 544 */ "fill_opt ::=", - /* 545 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 546 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", - /* 547 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", - /* 548 */ "fill_mode ::= NONE", - /* 549 */ "fill_mode ::= PREV", - /* 550 */ "fill_mode ::= NULL", - /* 551 */ "fill_mode ::= NULL_F", - /* 552 */ "fill_mode ::= LINEAR", - /* 553 */ "fill_mode ::= NEXT", - /* 554 */ "group_by_clause_opt ::=", - /* 555 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 556 */ "group_by_list ::= expr_or_subquery", - /* 557 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", - /* 558 */ "having_clause_opt ::=", - /* 559 */ "having_clause_opt ::= HAVING search_condition", - /* 560 */ "range_opt ::=", - /* 561 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", - /* 562 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", - /* 563 */ "every_opt ::=", - /* 564 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 565 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 566 */ "query_simple ::= query_specification", - /* 567 */ "query_simple ::= union_query_expression", - /* 568 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", - /* 569 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", - /* 570 */ "query_simple_or_subquery ::= query_simple", - /* 571 */ "query_simple_or_subquery ::= subquery", - /* 572 */ "query_or_subquery ::= query_expression", - /* 573 */ "query_or_subquery ::= subquery", - /* 574 */ "order_by_clause_opt ::=", - /* 575 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 576 */ "slimit_clause_opt ::=", - /* 577 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 578 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 579 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 580 */ "limit_clause_opt ::=", - /* 581 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 582 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 583 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 584 */ "subquery ::= NK_LP query_expression NK_RP", - /* 585 */ "subquery ::= NK_LP subquery NK_RP", - /* 586 */ "search_condition ::= common_expression", - /* 587 */ "sort_specification_list ::= sort_specification", - /* 588 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 589 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", - /* 590 */ "ordering_specification_opt ::=", - /* 591 */ "ordering_specification_opt ::= ASC", - /* 592 */ "ordering_specification_opt ::= DESC", - /* 593 */ "null_ordering_opt ::=", - /* 594 */ "null_ordering_opt ::= NULLS FIRST", - /* 595 */ "null_ordering_opt ::= NULLS LAST", + /* 305 */ "with_meta ::= AS", + /* 306 */ "with_meta ::= WITH META AS", + /* 307 */ "with_meta ::= ONLY META AS", + /* 308 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", + /* 309 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name", + /* 310 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt", + /* 311 */ "cmd ::= DROP TOPIC exists_opt topic_name", + /* 312 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", + /* 313 */ "cmd ::= DESC full_table_name", + /* 314 */ "cmd ::= DESCRIBE full_table_name", + /* 315 */ "cmd ::= RESET QUERY CACHE", + /* 316 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", + /* 317 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", + /* 318 */ "analyze_opt ::=", + /* 319 */ "analyze_opt ::= ANALYZE", + /* 320 */ "explain_options ::=", + /* 321 */ "explain_options ::= explain_options VERBOSE NK_BOOL", + /* 322 */ "explain_options ::= explain_options RATIO NK_FLOAT", + /* 323 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", + /* 324 */ "cmd ::= DROP FUNCTION exists_opt function_name", + /* 325 */ "agg_func_opt ::=", + /* 326 */ "agg_func_opt ::= AGGREGATE", + /* 327 */ "bufsize_opt ::=", + /* 328 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", + /* 329 */ "language_opt ::=", + /* 330 */ "language_opt ::= LANGUAGE NK_STRING", + /* 331 */ "or_replace_opt ::=", + /* 332 */ "or_replace_opt ::= OR REPLACE", + /* 333 */ "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", + /* 334 */ "cmd ::= DROP STREAM exists_opt stream_name", + /* 335 */ "cmd ::= PAUSE STREAM exists_opt stream_name", + /* 336 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", + /* 337 */ "col_list_opt ::=", + /* 338 */ "col_list_opt ::= NK_LP col_name_list NK_RP", + /* 339 */ "tag_def_or_ref_opt ::=", + /* 340 */ "tag_def_or_ref_opt ::= tags_def", + /* 341 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", + /* 342 */ "stream_options ::=", + /* 343 */ "stream_options ::= stream_options TRIGGER AT_ONCE", + /* 344 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", + /* 345 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", + /* 346 */ "stream_options ::= stream_options WATERMARK duration_literal", + /* 347 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", + /* 348 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", + /* 349 */ "stream_options ::= stream_options DELETE_MARK duration_literal", + /* 350 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", + /* 351 */ "subtable_opt ::=", + /* 352 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", + /* 353 */ "ignore_opt ::=", + /* 354 */ "ignore_opt ::= IGNORE UNTREATED", + /* 355 */ "cmd ::= KILL CONNECTION NK_INTEGER", + /* 356 */ "cmd ::= KILL QUERY NK_STRING", + /* 357 */ "cmd ::= KILL TRANSACTION NK_INTEGER", + /* 358 */ "cmd ::= BALANCE VGROUP", + /* 359 */ "cmd ::= BALANCE VGROUP LEADER", + /* 360 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", + /* 361 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", + /* 362 */ "cmd ::= SPLIT VGROUP NK_INTEGER", + /* 363 */ "dnode_list ::= DNODE NK_INTEGER", + /* 364 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", + /* 365 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", + /* 366 */ "cmd ::= query_or_subquery", + /* 367 */ "cmd ::= insert_query", + /* 368 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", + /* 369 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", + /* 370 */ "literal ::= NK_INTEGER", + /* 371 */ "literal ::= NK_FLOAT", + /* 372 */ "literal ::= NK_STRING", + /* 373 */ "literal ::= NK_BOOL", + /* 374 */ "literal ::= TIMESTAMP NK_STRING", + /* 375 */ "literal ::= duration_literal", + /* 376 */ "literal ::= NULL", + /* 377 */ "literal ::= NK_QUESTION", + /* 378 */ "duration_literal ::= NK_VARIABLE", + /* 379 */ "signed ::= NK_INTEGER", + /* 380 */ "signed ::= NK_PLUS NK_INTEGER", + /* 381 */ "signed ::= NK_MINUS NK_INTEGER", + /* 382 */ "signed ::= NK_FLOAT", + /* 383 */ "signed ::= NK_PLUS NK_FLOAT", + /* 384 */ "signed ::= NK_MINUS NK_FLOAT", + /* 385 */ "signed_literal ::= signed", + /* 386 */ "signed_literal ::= NK_STRING", + /* 387 */ "signed_literal ::= NK_BOOL", + /* 388 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 389 */ "signed_literal ::= duration_literal", + /* 390 */ "signed_literal ::= NULL", + /* 391 */ "signed_literal ::= literal_func", + /* 392 */ "signed_literal ::= NK_QUESTION", + /* 393 */ "literal_list ::= signed_literal", + /* 394 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 395 */ "db_name ::= NK_ID", + /* 396 */ "table_name ::= NK_ID", + /* 397 */ "column_name ::= NK_ID", + /* 398 */ "function_name ::= NK_ID", + /* 399 */ "table_alias ::= NK_ID", + /* 400 */ "column_alias ::= NK_ID", + /* 401 */ "user_name ::= NK_ID", + /* 402 */ "topic_name ::= NK_ID", + /* 403 */ "stream_name ::= NK_ID", + /* 404 */ "cgroup_name ::= NK_ID", + /* 405 */ "index_name ::= NK_ID", + /* 406 */ "expr_or_subquery ::= expression", + /* 407 */ "expression ::= literal", + /* 408 */ "expression ::= pseudo_column", + /* 409 */ "expression ::= column_reference", + /* 410 */ "expression ::= function_expression", + /* 411 */ "expression ::= case_when_expression", + /* 412 */ "expression ::= NK_LP expression NK_RP", + /* 413 */ "expression ::= NK_PLUS expr_or_subquery", + /* 414 */ "expression ::= NK_MINUS expr_or_subquery", + /* 415 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", + /* 416 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", + /* 417 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", + /* 418 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", + /* 419 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", + /* 420 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 421 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", + /* 422 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", + /* 423 */ "expression_list ::= expr_or_subquery", + /* 424 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", + /* 425 */ "column_reference ::= column_name", + /* 426 */ "column_reference ::= table_name NK_DOT column_name", + /* 427 */ "pseudo_column ::= ROWTS", + /* 428 */ "pseudo_column ::= TBNAME", + /* 429 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 430 */ "pseudo_column ::= QSTART", + /* 431 */ "pseudo_column ::= QEND", + /* 432 */ "pseudo_column ::= QDURATION", + /* 433 */ "pseudo_column ::= WSTART", + /* 434 */ "pseudo_column ::= WEND", + /* 435 */ "pseudo_column ::= WDURATION", + /* 436 */ "pseudo_column ::= IROWTS", + /* 437 */ "pseudo_column ::= ISFILLED", + /* 438 */ "pseudo_column ::= QTAGS", + /* 439 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 440 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 441 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", + /* 442 */ "function_expression ::= literal_func", + /* 443 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 444 */ "literal_func ::= NOW", + /* 445 */ "noarg_func ::= NOW", + /* 446 */ "noarg_func ::= TODAY", + /* 447 */ "noarg_func ::= TIMEZONE", + /* 448 */ "noarg_func ::= DATABASE", + /* 449 */ "noarg_func ::= CLIENT_VERSION", + /* 450 */ "noarg_func ::= SERVER_VERSION", + /* 451 */ "noarg_func ::= SERVER_STATUS", + /* 452 */ "noarg_func ::= CURRENT_USER", + /* 453 */ "noarg_func ::= USER", + /* 454 */ "star_func ::= COUNT", + /* 455 */ "star_func ::= FIRST", + /* 456 */ "star_func ::= LAST", + /* 457 */ "star_func ::= LAST_ROW", + /* 458 */ "star_func_para_list ::= NK_STAR", + /* 459 */ "star_func_para_list ::= other_para_list", + /* 460 */ "other_para_list ::= star_func_para", + /* 461 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 462 */ "star_func_para ::= expr_or_subquery", + /* 463 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 464 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", + /* 465 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", + /* 466 */ "when_then_list ::= when_then_expr", + /* 467 */ "when_then_list ::= when_then_list when_then_expr", + /* 468 */ "when_then_expr ::= WHEN common_expression THEN common_expression", + /* 469 */ "case_when_else_opt ::=", + /* 470 */ "case_when_else_opt ::= ELSE common_expression", + /* 471 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", + /* 472 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", + /* 473 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", + /* 474 */ "predicate ::= expr_or_subquery IS NULL", + /* 475 */ "predicate ::= expr_or_subquery IS NOT NULL", + /* 476 */ "predicate ::= expr_or_subquery in_op in_predicate_value", + /* 477 */ "compare_op ::= NK_LT", + /* 478 */ "compare_op ::= NK_GT", + /* 479 */ "compare_op ::= NK_LE", + /* 480 */ "compare_op ::= NK_GE", + /* 481 */ "compare_op ::= NK_NE", + /* 482 */ "compare_op ::= NK_EQ", + /* 483 */ "compare_op ::= LIKE", + /* 484 */ "compare_op ::= NOT LIKE", + /* 485 */ "compare_op ::= MATCH", + /* 486 */ "compare_op ::= NMATCH", + /* 487 */ "compare_op ::= CONTAINS", + /* 488 */ "in_op ::= IN", + /* 489 */ "in_op ::= NOT IN", + /* 490 */ "in_predicate_value ::= NK_LP literal_list NK_RP", + /* 491 */ "boolean_value_expression ::= boolean_primary", + /* 492 */ "boolean_value_expression ::= NOT boolean_primary", + /* 493 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 494 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 495 */ "boolean_primary ::= predicate", + /* 496 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 497 */ "common_expression ::= expr_or_subquery", + /* 498 */ "common_expression ::= boolean_value_expression", + /* 499 */ "from_clause_opt ::=", + /* 500 */ "from_clause_opt ::= FROM table_reference_list", + /* 501 */ "table_reference_list ::= table_reference", + /* 502 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 503 */ "table_reference ::= table_primary", + /* 504 */ "table_reference ::= joined_table", + /* 505 */ "table_primary ::= table_name alias_opt", + /* 506 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 507 */ "table_primary ::= subquery alias_opt", + /* 508 */ "table_primary ::= parenthesized_joined_table", + /* 509 */ "alias_opt ::=", + /* 510 */ "alias_opt ::= table_alias", + /* 511 */ "alias_opt ::= AS table_alias", + /* 512 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 513 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 514 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 515 */ "join_type ::=", + /* 516 */ "join_type ::= INNER", + /* 517 */ "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", + /* 518 */ "set_quantifier_opt ::=", + /* 519 */ "set_quantifier_opt ::= DISTINCT", + /* 520 */ "set_quantifier_opt ::= ALL", + /* 521 */ "select_list ::= select_item", + /* 522 */ "select_list ::= select_list NK_COMMA select_item", + /* 523 */ "select_item ::= NK_STAR", + /* 524 */ "select_item ::= common_expression", + /* 525 */ "select_item ::= common_expression column_alias", + /* 526 */ "select_item ::= common_expression AS column_alias", + /* 527 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 528 */ "where_clause_opt ::=", + /* 529 */ "where_clause_opt ::= WHERE search_condition", + /* 530 */ "partition_by_clause_opt ::=", + /* 531 */ "partition_by_clause_opt ::= PARTITION BY partition_list", + /* 532 */ "partition_list ::= partition_item", + /* 533 */ "partition_list ::= partition_list NK_COMMA partition_item", + /* 534 */ "partition_item ::= expr_or_subquery", + /* 535 */ "partition_item ::= expr_or_subquery column_alias", + /* 536 */ "partition_item ::= expr_or_subquery AS column_alias", + /* 537 */ "twindow_clause_opt ::=", + /* 538 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 539 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", + /* 540 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 541 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 542 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", + /* 543 */ "sliding_opt ::=", + /* 544 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 545 */ "fill_opt ::=", + /* 546 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 547 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", + /* 548 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", + /* 549 */ "fill_mode ::= NONE", + /* 550 */ "fill_mode ::= PREV", + /* 551 */ "fill_mode ::= NULL", + /* 552 */ "fill_mode ::= NULL_F", + /* 553 */ "fill_mode ::= LINEAR", + /* 554 */ "fill_mode ::= NEXT", + /* 555 */ "group_by_clause_opt ::=", + /* 556 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 557 */ "group_by_list ::= expr_or_subquery", + /* 558 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", + /* 559 */ "having_clause_opt ::=", + /* 560 */ "having_clause_opt ::= HAVING search_condition", + /* 561 */ "range_opt ::=", + /* 562 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", + /* 563 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", + /* 564 */ "every_opt ::=", + /* 565 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 566 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 567 */ "query_simple ::= query_specification", + /* 568 */ "query_simple ::= union_query_expression", + /* 569 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", + /* 570 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", + /* 571 */ "query_simple_or_subquery ::= query_simple", + /* 572 */ "query_simple_or_subquery ::= subquery", + /* 573 */ "query_or_subquery ::= query_expression", + /* 574 */ "query_or_subquery ::= subquery", + /* 575 */ "order_by_clause_opt ::=", + /* 576 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 577 */ "slimit_clause_opt ::=", + /* 578 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 579 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 580 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 581 */ "limit_clause_opt ::=", + /* 582 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 583 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 584 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 585 */ "subquery ::= NK_LP query_expression NK_RP", + /* 586 */ "subquery ::= NK_LP subquery NK_RP", + /* 587 */ "search_condition ::= common_expression", + /* 588 */ "sort_specification_list ::= sort_specification", + /* 589 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 590 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", + /* 591 */ "ordering_specification_opt ::=", + /* 592 */ "ordering_specification_opt ::= ASC", + /* 593 */ "ordering_specification_opt ::= DESC", + /* 594 */ "null_ordering_opt ::=", + /* 595 */ "null_ordering_opt ::= NULLS FIRST", + /* 596 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -2664,210 +3030,211 @@ static void yy_destructor( */ /********* Begin destructor definitions ***************************************/ /* Default NON-TERMINAL Destructor */ - case 337: /* cmd */ - case 340: /* literal */ - case 346: /* with_opt */ - case 352: /* search_condition */ - case 357: /* db_options */ - case 359: /* alter_db_options */ - case 361: /* start_opt */ - case 362: /* end_opt */ - case 366: /* signed */ - case 368: /* retention */ - case 369: /* full_table_name */ - case 372: /* table_options */ - case 376: /* alter_table_clause */ - case 377: /* alter_table_options */ - case 380: /* signed_literal */ - case 381: /* create_subtable_clause */ - case 384: /* drop_table_clause */ - case 386: /* column_def */ - case 390: /* duration_literal */ - case 391: /* rollup_func_name */ - case 393: /* col_name */ - case 394: /* db_name_cond_opt */ - case 395: /* like_pattern_opt */ - case 396: /* table_name_cond */ - case 397: /* from_db_opt */ - case 399: /* tag_item */ - case 401: /* full_index_name */ - case 402: /* index_options */ - case 405: /* sliding_opt */ - case 406: /* sma_stream_opt */ - case 407: /* func */ - case 409: /* query_or_subquery */ - case 410: /* where_clause_opt */ - case 413: /* explain_options */ - case 414: /* insert_query */ - case 420: /* stream_options */ - case 423: /* subtable_opt */ - case 425: /* expression */ - case 427: /* literal_func */ - case 430: /* expr_or_subquery */ - case 431: /* pseudo_column */ - case 432: /* column_reference */ - case 433: /* function_expression */ - case 434: /* case_when_expression */ - case 439: /* star_func_para */ - case 441: /* case_when_else_opt */ - case 442: /* common_expression */ - case 443: /* when_then_expr */ - case 444: /* predicate */ - case 447: /* in_predicate_value */ - case 448: /* boolean_value_expression */ - case 449: /* boolean_primary */ - case 450: /* from_clause_opt */ - case 451: /* table_reference_list */ - case 452: /* table_reference */ - case 453: /* table_primary */ - case 454: /* joined_table */ - case 456: /* subquery */ - case 457: /* parenthesized_joined_table */ - case 459: /* query_specification */ - case 463: /* range_opt */ - case 464: /* every_opt */ - case 465: /* fill_opt */ - case 466: /* twindow_clause_opt */ - case 468: /* having_clause_opt */ - case 469: /* select_item */ - case 471: /* partition_item */ - case 474: /* query_expression */ - case 475: /* query_simple */ - case 477: /* slimit_clause_opt */ - case 478: /* limit_clause_opt */ - case 479: /* union_query_expression */ - case 480: /* query_simple_or_subquery */ - case 482: /* sort_specification */ + case 338: /* cmd */ + case 341: /* literal */ + case 347: /* with_opt */ + case 353: /* search_condition */ + case 358: /* db_options */ + case 360: /* alter_db_options */ + case 362: /* start_opt */ + case 363: /* end_opt */ + case 367: /* signed */ + case 369: /* retention */ + case 370: /* full_table_name */ + case 373: /* table_options */ + case 377: /* alter_table_clause */ + case 378: /* alter_table_options */ + case 381: /* signed_literal */ + case 382: /* create_subtable_clause */ + case 385: /* drop_table_clause */ + case 387: /* column_def */ + case 391: /* duration_literal */ + case 392: /* rollup_func_name */ + case 394: /* col_name */ + case 395: /* db_name_cond_opt */ + case 396: /* like_pattern_opt */ + case 397: /* table_name_cond */ + case 398: /* from_db_opt */ + case 400: /* tag_item */ + case 402: /* full_index_name */ + case 403: /* index_options */ + case 406: /* sliding_opt */ + case 407: /* sma_stream_opt */ + case 408: /* func */ + case 411: /* query_or_subquery */ + case 412: /* where_clause_opt */ + case 415: /* explain_options */ + case 416: /* insert_query */ + case 422: /* stream_options */ + case 425: /* subtable_opt */ + case 427: /* expression */ + case 429: /* literal_func */ + case 432: /* expr_or_subquery */ + case 433: /* pseudo_column */ + case 434: /* column_reference */ + case 435: /* function_expression */ + case 436: /* case_when_expression */ + case 441: /* star_func_para */ + case 443: /* case_when_else_opt */ + case 444: /* common_expression */ + case 445: /* when_then_expr */ + case 446: /* predicate */ + case 449: /* in_predicate_value */ + case 450: /* boolean_value_expression */ + case 451: /* boolean_primary */ + case 452: /* from_clause_opt */ + case 453: /* table_reference_list */ + case 454: /* table_reference */ + case 455: /* table_primary */ + case 456: /* joined_table */ + case 458: /* subquery */ + case 459: /* parenthesized_joined_table */ + case 461: /* query_specification */ + case 465: /* range_opt */ + case 466: /* every_opt */ + case 467: /* fill_opt */ + case 468: /* twindow_clause_opt */ + case 470: /* having_clause_opt */ + case 471: /* select_item */ + case 473: /* partition_item */ + case 476: /* query_expression */ + case 477: /* query_simple */ + case 479: /* slimit_clause_opt */ + case 480: /* limit_clause_opt */ + case 481: /* union_query_expression */ + case 482: /* query_simple_or_subquery */ + case 484: /* sort_specification */ { - nodesDestroyNode((yypminor->yy242)); + nodesDestroyNode((yypminor->yy452)); } break; - case 338: /* account_options */ - case 339: /* alter_account_options */ - case 341: /* alter_account_option */ - case 360: /* speed_opt */ - case 417: /* bufsize_opt */ + case 339: /* account_options */ + case 340: /* alter_account_options */ + case 342: /* alter_account_option */ + case 361: /* speed_opt */ + case 410: /* with_meta */ + case 419: /* bufsize_opt */ { } break; - case 342: /* user_name */ - case 349: /* db_name */ - case 350: /* table_name */ - case 351: /* topic_name */ - case 353: /* dnode_endpoint */ - case 378: /* column_name */ - case 392: /* function_name */ - case 400: /* column_alias */ - case 403: /* index_name */ - case 408: /* sma_func_name */ - case 411: /* cgroup_name */ - case 418: /* language_opt */ - case 419: /* stream_name */ - case 429: /* table_alias */ - case 435: /* star_func */ - case 437: /* noarg_func */ - case 455: /* alias_opt */ + case 343: /* user_name */ + case 350: /* db_name */ + case 351: /* table_name */ + case 352: /* topic_name */ + case 354: /* dnode_endpoint */ + case 379: /* column_name */ + case 393: /* function_name */ + case 401: /* column_alias */ + case 404: /* index_name */ + case 409: /* sma_func_name */ + case 413: /* cgroup_name */ + case 420: /* language_opt */ + case 421: /* stream_name */ + case 431: /* table_alias */ + case 437: /* star_func */ + case 439: /* noarg_func */ + case 457: /* alias_opt */ { } break; - case 343: /* sysinfo_opt */ + case 344: /* sysinfo_opt */ { } break; - case 344: /* privileges */ - case 347: /* priv_type_list */ - case 348: /* priv_type */ + case 345: /* privileges */ + case 348: /* priv_type_list */ + case 349: /* priv_type */ { } break; - case 345: /* priv_level */ + case 346: /* priv_level */ { } break; - case 354: /* force_opt */ - case 355: /* unsafe_opt */ - case 356: /* not_exists_opt */ - case 358: /* exists_opt */ - case 412: /* analyze_opt */ - case 415: /* or_replace_opt */ - case 416: /* agg_func_opt */ - case 424: /* ignore_opt */ - case 460: /* set_quantifier_opt */ + case 355: /* force_opt */ + case 356: /* unsafe_opt */ + case 357: /* not_exists_opt */ + case 359: /* exists_opt */ + case 414: /* analyze_opt */ + case 417: /* or_replace_opt */ + case 418: /* agg_func_opt */ + case 426: /* ignore_opt */ + case 462: /* set_quantifier_opt */ { } break; - case 363: /* integer_list */ - case 364: /* variable_list */ - case 365: /* retention_list */ - case 370: /* column_def_list */ - case 371: /* tags_def_opt */ - case 373: /* multi_create_clause */ - case 374: /* tags_def */ - case 375: /* multi_drop_clause */ - case 382: /* specific_cols_opt */ - case 383: /* expression_list */ - case 385: /* col_name_list */ - case 387: /* duration_list */ - case 388: /* rollup_func_list */ - case 398: /* tag_list_opt */ - case 404: /* func_list */ - case 421: /* col_list_opt */ - case 422: /* tag_def_or_ref_opt */ - case 426: /* dnode_list */ - case 428: /* literal_list */ - case 436: /* star_func_para_list */ - case 438: /* other_para_list */ - case 440: /* when_then_list */ - case 461: /* select_list */ - case 462: /* partition_by_clause_opt */ - case 467: /* group_by_clause_opt */ - case 470: /* partition_list */ - case 473: /* group_by_list */ - case 476: /* order_by_clause_opt */ - case 481: /* sort_specification_list */ + case 364: /* integer_list */ + case 365: /* variable_list */ + case 366: /* retention_list */ + case 371: /* column_def_list */ + case 372: /* tags_def_opt */ + case 374: /* multi_create_clause */ + case 375: /* tags_def */ + case 376: /* multi_drop_clause */ + case 383: /* specific_cols_opt */ + case 384: /* expression_list */ + case 386: /* col_name_list */ + case 388: /* duration_list */ + case 389: /* rollup_func_list */ + case 399: /* tag_list_opt */ + case 405: /* func_list */ + case 423: /* col_list_opt */ + case 424: /* tag_def_or_ref_opt */ + case 428: /* dnode_list */ + case 430: /* literal_list */ + case 438: /* star_func_para_list */ + case 440: /* other_para_list */ + case 442: /* when_then_list */ + case 463: /* select_list */ + case 464: /* partition_by_clause_opt */ + case 469: /* group_by_clause_opt */ + case 472: /* partition_list */ + case 475: /* group_by_list */ + case 478: /* order_by_clause_opt */ + case 483: /* sort_specification_list */ { - nodesDestroyList((yypminor->yy174)); + nodesDestroyList((yypminor->yy812)); } break; - case 367: /* alter_db_option */ - case 389: /* alter_table_option */ + case 368: /* alter_db_option */ + case 390: /* alter_table_option */ { } break; - case 379: /* type_name */ + case 380: /* type_name */ { } break; - case 445: /* compare_op */ - case 446: /* in_op */ + case 447: /* compare_op */ + case 448: /* in_op */ { } break; - case 458: /* join_type */ + case 460: /* join_type */ { } break; - case 472: /* fill_mode */ + case 474: /* fill_mode */ { } break; - case 483: /* ordering_specification_opt */ + case 485: /* ordering_specification_opt */ { } break; - case 484: /* null_ordering_opt */ + case 486: /* null_ordering_opt */ { } @@ -3036,7 +3403,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); return yy_action[i]; } }while(1); @@ -3158,602 +3525,603 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 337, /* (0) cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ - 337, /* (1) cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ - 338, /* (2) account_options ::= */ - 338, /* (3) account_options ::= account_options PPS literal */ - 338, /* (4) account_options ::= account_options TSERIES literal */ - 338, /* (5) account_options ::= account_options STORAGE literal */ - 338, /* (6) account_options ::= account_options STREAMS literal */ - 338, /* (7) account_options ::= account_options QTIME literal */ - 338, /* (8) account_options ::= account_options DBS literal */ - 338, /* (9) account_options ::= account_options USERS literal */ - 338, /* (10) account_options ::= account_options CONNS literal */ - 338, /* (11) account_options ::= account_options STATE literal */ - 339, /* (12) alter_account_options ::= alter_account_option */ - 339, /* (13) alter_account_options ::= alter_account_options alter_account_option */ - 341, /* (14) alter_account_option ::= PASS literal */ - 341, /* (15) alter_account_option ::= PPS literal */ - 341, /* (16) alter_account_option ::= TSERIES literal */ - 341, /* (17) alter_account_option ::= STORAGE literal */ - 341, /* (18) alter_account_option ::= STREAMS literal */ - 341, /* (19) alter_account_option ::= QTIME literal */ - 341, /* (20) alter_account_option ::= DBS literal */ - 341, /* (21) alter_account_option ::= USERS literal */ - 341, /* (22) alter_account_option ::= CONNS literal */ - 341, /* (23) alter_account_option ::= STATE literal */ - 337, /* (24) cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ - 337, /* (25) cmd ::= ALTER USER user_name PASS NK_STRING */ - 337, /* (26) cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ - 337, /* (27) cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ - 337, /* (28) cmd ::= DROP USER user_name */ - 343, /* (29) sysinfo_opt ::= */ - 343, /* (30) sysinfo_opt ::= SYSINFO NK_INTEGER */ - 337, /* (31) cmd ::= GRANT privileges ON priv_level with_opt TO user_name */ - 337, /* (32) cmd ::= REVOKE privileges ON priv_level with_opt FROM user_name */ - 344, /* (33) privileges ::= ALL */ - 344, /* (34) privileges ::= priv_type_list */ - 344, /* (35) privileges ::= SUBSCRIBE */ - 347, /* (36) priv_type_list ::= priv_type */ - 347, /* (37) priv_type_list ::= priv_type_list NK_COMMA priv_type */ - 348, /* (38) priv_type ::= READ */ - 348, /* (39) priv_type ::= WRITE */ - 345, /* (40) priv_level ::= NK_STAR NK_DOT NK_STAR */ - 345, /* (41) priv_level ::= db_name NK_DOT NK_STAR */ - 345, /* (42) priv_level ::= db_name NK_DOT table_name */ - 345, /* (43) priv_level ::= topic_name */ - 346, /* (44) with_opt ::= */ - 346, /* (45) with_opt ::= WITH search_condition */ - 337, /* (46) cmd ::= CREATE DNODE dnode_endpoint */ - 337, /* (47) cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ - 337, /* (48) cmd ::= DROP DNODE NK_INTEGER force_opt */ - 337, /* (49) cmd ::= DROP DNODE dnode_endpoint force_opt */ - 337, /* (50) cmd ::= DROP DNODE NK_INTEGER unsafe_opt */ - 337, /* (51) cmd ::= DROP DNODE dnode_endpoint unsafe_opt */ - 337, /* (52) cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ - 337, /* (53) cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ - 337, /* (54) cmd ::= ALTER ALL DNODES NK_STRING */ - 337, /* (55) cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ - 337, /* (56) cmd ::= RESTORE DNODE NK_INTEGER */ - 353, /* (57) dnode_endpoint ::= NK_STRING */ - 353, /* (58) dnode_endpoint ::= NK_ID */ - 353, /* (59) dnode_endpoint ::= NK_IPTOKEN */ - 354, /* (60) force_opt ::= */ - 354, /* (61) force_opt ::= FORCE */ - 355, /* (62) unsafe_opt ::= UNSAFE */ - 337, /* (63) cmd ::= ALTER LOCAL NK_STRING */ - 337, /* (64) cmd ::= ALTER LOCAL NK_STRING NK_STRING */ - 337, /* (65) cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ - 337, /* (66) cmd ::= DROP QNODE ON DNODE NK_INTEGER */ - 337, /* (67) cmd ::= RESTORE QNODE ON DNODE NK_INTEGER */ - 337, /* (68) cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ - 337, /* (69) cmd ::= DROP BNODE ON DNODE NK_INTEGER */ - 337, /* (70) cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ - 337, /* (71) cmd ::= DROP SNODE ON DNODE NK_INTEGER */ - 337, /* (72) cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ - 337, /* (73) cmd ::= DROP MNODE ON DNODE NK_INTEGER */ - 337, /* (74) cmd ::= RESTORE MNODE ON DNODE NK_INTEGER */ - 337, /* (75) cmd ::= RESTORE VNODE ON DNODE NK_INTEGER */ - 337, /* (76) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ - 337, /* (77) cmd ::= DROP DATABASE exists_opt db_name */ - 337, /* (78) cmd ::= USE db_name */ - 337, /* (79) cmd ::= ALTER DATABASE db_name alter_db_options */ - 337, /* (80) cmd ::= FLUSH DATABASE db_name */ - 337, /* (81) cmd ::= TRIM DATABASE db_name speed_opt */ - 337, /* (82) cmd ::= COMPACT DATABASE db_name start_opt end_opt */ - 356, /* (83) not_exists_opt ::= IF NOT EXISTS */ - 356, /* (84) not_exists_opt ::= */ - 358, /* (85) exists_opt ::= IF EXISTS */ - 358, /* (86) exists_opt ::= */ - 357, /* (87) db_options ::= */ - 357, /* (88) db_options ::= db_options BUFFER NK_INTEGER */ - 357, /* (89) db_options ::= db_options CACHEMODEL NK_STRING */ - 357, /* (90) db_options ::= db_options CACHESIZE NK_INTEGER */ - 357, /* (91) db_options ::= db_options COMP NK_INTEGER */ - 357, /* (92) db_options ::= db_options DURATION NK_INTEGER */ - 357, /* (93) db_options ::= db_options DURATION NK_VARIABLE */ - 357, /* (94) db_options ::= db_options MAXROWS NK_INTEGER */ - 357, /* (95) db_options ::= db_options MINROWS NK_INTEGER */ - 357, /* (96) db_options ::= db_options KEEP integer_list */ - 357, /* (97) db_options ::= db_options KEEP variable_list */ - 357, /* (98) db_options ::= db_options PAGES NK_INTEGER */ - 357, /* (99) db_options ::= db_options PAGESIZE NK_INTEGER */ - 357, /* (100) db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ - 357, /* (101) db_options ::= db_options PRECISION NK_STRING */ - 357, /* (102) db_options ::= db_options REPLICA NK_INTEGER */ - 357, /* (103) db_options ::= db_options VGROUPS NK_INTEGER */ - 357, /* (104) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ - 357, /* (105) db_options ::= db_options RETENTIONS retention_list */ - 357, /* (106) db_options ::= db_options SCHEMALESS NK_INTEGER */ - 357, /* (107) db_options ::= db_options WAL_LEVEL NK_INTEGER */ - 357, /* (108) db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ - 357, /* (109) db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ - 357, /* (110) db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ - 357, /* (111) db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ - 357, /* (112) db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ - 357, /* (113) db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ - 357, /* (114) db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ - 357, /* (115) db_options ::= db_options STT_TRIGGER NK_INTEGER */ - 357, /* (116) db_options ::= db_options TABLE_PREFIX signed */ - 357, /* (117) db_options ::= db_options TABLE_SUFFIX signed */ - 359, /* (118) alter_db_options ::= alter_db_option */ - 359, /* (119) alter_db_options ::= alter_db_options alter_db_option */ - 367, /* (120) alter_db_option ::= BUFFER NK_INTEGER */ - 367, /* (121) alter_db_option ::= CACHEMODEL NK_STRING */ - 367, /* (122) alter_db_option ::= CACHESIZE NK_INTEGER */ - 367, /* (123) alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ - 367, /* (124) alter_db_option ::= KEEP integer_list */ - 367, /* (125) alter_db_option ::= KEEP variable_list */ - 367, /* (126) alter_db_option ::= PAGES NK_INTEGER */ - 367, /* (127) alter_db_option ::= REPLICA NK_INTEGER */ - 367, /* (128) alter_db_option ::= WAL_LEVEL NK_INTEGER */ - 367, /* (129) alter_db_option ::= STT_TRIGGER NK_INTEGER */ - 367, /* (130) alter_db_option ::= MINROWS NK_INTEGER */ - 367, /* (131) alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ - 367, /* (132) alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ - 367, /* (133) alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ - 367, /* (134) alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ - 363, /* (135) integer_list ::= NK_INTEGER */ - 363, /* (136) integer_list ::= integer_list NK_COMMA NK_INTEGER */ - 364, /* (137) variable_list ::= NK_VARIABLE */ - 364, /* (138) variable_list ::= variable_list NK_COMMA NK_VARIABLE */ - 365, /* (139) retention_list ::= retention */ - 365, /* (140) retention_list ::= retention_list NK_COMMA retention */ - 368, /* (141) retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ - 360, /* (142) speed_opt ::= */ - 360, /* (143) speed_opt ::= MAX_SPEED NK_INTEGER */ - 361, /* (144) start_opt ::= */ - 361, /* (145) start_opt ::= START WITH NK_INTEGER */ - 361, /* (146) start_opt ::= START WITH NK_STRING */ - 361, /* (147) start_opt ::= START WITH TIMESTAMP NK_STRING */ - 362, /* (148) end_opt ::= */ - 362, /* (149) end_opt ::= END WITH NK_INTEGER */ - 362, /* (150) end_opt ::= END WITH NK_STRING */ - 362, /* (151) end_opt ::= END WITH TIMESTAMP NK_STRING */ - 337, /* (152) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ - 337, /* (153) cmd ::= CREATE TABLE multi_create_clause */ - 337, /* (154) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ - 337, /* (155) cmd ::= DROP TABLE multi_drop_clause */ - 337, /* (156) cmd ::= DROP STABLE exists_opt full_table_name */ - 337, /* (157) cmd ::= ALTER TABLE alter_table_clause */ - 337, /* (158) cmd ::= ALTER STABLE alter_table_clause */ - 376, /* (159) alter_table_clause ::= full_table_name alter_table_options */ - 376, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ - 376, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - 376, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ - 376, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - 376, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ - 376, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ - 376, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ - 376, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ - 376, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ - 373, /* (169) multi_create_clause ::= create_subtable_clause */ - 373, /* (170) multi_create_clause ::= multi_create_clause create_subtable_clause */ - 381, /* (171) 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 */ - 375, /* (172) multi_drop_clause ::= drop_table_clause */ - 375, /* (173) multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ - 384, /* (174) drop_table_clause ::= exists_opt full_table_name */ - 382, /* (175) specific_cols_opt ::= */ - 382, /* (176) specific_cols_opt ::= NK_LP col_name_list NK_RP */ - 369, /* (177) full_table_name ::= table_name */ - 369, /* (178) full_table_name ::= db_name NK_DOT table_name */ - 370, /* (179) column_def_list ::= column_def */ - 370, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ - 386, /* (181) column_def ::= column_name type_name */ - 379, /* (182) type_name ::= BOOL */ - 379, /* (183) type_name ::= TINYINT */ - 379, /* (184) type_name ::= SMALLINT */ - 379, /* (185) type_name ::= INT */ - 379, /* (186) type_name ::= INTEGER */ - 379, /* (187) type_name ::= BIGINT */ - 379, /* (188) type_name ::= FLOAT */ - 379, /* (189) type_name ::= DOUBLE */ - 379, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - 379, /* (191) type_name ::= TIMESTAMP */ - 379, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - 379, /* (193) type_name ::= TINYINT UNSIGNED */ - 379, /* (194) type_name ::= SMALLINT UNSIGNED */ - 379, /* (195) type_name ::= INT UNSIGNED */ - 379, /* (196) type_name ::= BIGINT UNSIGNED */ - 379, /* (197) type_name ::= JSON */ - 379, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - 379, /* (199) type_name ::= MEDIUMBLOB */ - 379, /* (200) type_name ::= BLOB */ - 379, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - 379, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - 379, /* (203) type_name ::= DECIMAL */ - 379, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - 379, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - 371, /* (206) tags_def_opt ::= */ - 371, /* (207) tags_def_opt ::= tags_def */ - 374, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - 372, /* (209) table_options ::= */ - 372, /* (210) table_options ::= table_options COMMENT NK_STRING */ - 372, /* (211) table_options ::= table_options MAX_DELAY duration_list */ - 372, /* (212) table_options ::= table_options WATERMARK duration_list */ - 372, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - 372, /* (214) table_options ::= table_options TTL NK_INTEGER */ - 372, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - 372, /* (216) table_options ::= table_options DELETE_MARK duration_list */ - 377, /* (217) alter_table_options ::= alter_table_option */ - 377, /* (218) alter_table_options ::= alter_table_options alter_table_option */ - 389, /* (219) alter_table_option ::= COMMENT NK_STRING */ - 389, /* (220) alter_table_option ::= TTL NK_INTEGER */ - 387, /* (221) duration_list ::= duration_literal */ - 387, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ - 388, /* (223) rollup_func_list ::= rollup_func_name */ - 388, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - 391, /* (225) rollup_func_name ::= function_name */ - 391, /* (226) rollup_func_name ::= FIRST */ - 391, /* (227) rollup_func_name ::= LAST */ - 385, /* (228) col_name_list ::= col_name */ - 385, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ - 393, /* (230) col_name ::= column_name */ - 337, /* (231) cmd ::= SHOW DNODES */ - 337, /* (232) cmd ::= SHOW USERS */ - 337, /* (233) cmd ::= SHOW USER PRIVILEGES */ - 337, /* (234) cmd ::= SHOW DATABASES */ - 337, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - 337, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - 337, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ - 337, /* (238) cmd ::= SHOW MNODES */ - 337, /* (239) cmd ::= SHOW QNODES */ - 337, /* (240) cmd ::= SHOW FUNCTIONS */ - 337, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - 337, /* (242) cmd ::= SHOW STREAMS */ - 337, /* (243) cmd ::= SHOW ACCOUNTS */ - 337, /* (244) cmd ::= SHOW APPS */ - 337, /* (245) cmd ::= SHOW CONNECTIONS */ - 337, /* (246) cmd ::= SHOW LICENCES */ - 337, /* (247) cmd ::= SHOW GRANTS */ - 337, /* (248) cmd ::= SHOW CREATE DATABASE db_name */ - 337, /* (249) cmd ::= SHOW CREATE TABLE full_table_name */ - 337, /* (250) cmd ::= SHOW CREATE STABLE full_table_name */ - 337, /* (251) cmd ::= SHOW QUERIES */ - 337, /* (252) cmd ::= SHOW SCORES */ - 337, /* (253) cmd ::= SHOW TOPICS */ - 337, /* (254) cmd ::= SHOW VARIABLES */ - 337, /* (255) cmd ::= SHOW CLUSTER VARIABLES */ - 337, /* (256) cmd ::= SHOW LOCAL VARIABLES */ - 337, /* (257) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ - 337, /* (258) cmd ::= SHOW BNODES */ - 337, /* (259) cmd ::= SHOW SNODES */ - 337, /* (260) cmd ::= SHOW CLUSTER */ - 337, /* (261) cmd ::= SHOW TRANSACTIONS */ - 337, /* (262) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - 337, /* (263) cmd ::= SHOW CONSUMERS */ - 337, /* (264) cmd ::= SHOW SUBSCRIPTIONS */ - 337, /* (265) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ - 337, /* (266) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ - 337, /* (267) cmd ::= SHOW VNODES NK_INTEGER */ - 337, /* (268) cmd ::= SHOW VNODES NK_STRING */ - 337, /* (269) cmd ::= SHOW db_name_cond_opt ALIVE */ - 337, /* (270) cmd ::= SHOW CLUSTER ALIVE */ - 394, /* (271) db_name_cond_opt ::= */ - 394, /* (272) db_name_cond_opt ::= db_name NK_DOT */ - 395, /* (273) like_pattern_opt ::= */ - 395, /* (274) like_pattern_opt ::= LIKE NK_STRING */ - 396, /* (275) table_name_cond ::= table_name */ - 397, /* (276) from_db_opt ::= */ - 397, /* (277) from_db_opt ::= FROM db_name */ - 398, /* (278) tag_list_opt ::= */ - 398, /* (279) tag_list_opt ::= tag_item */ - 398, /* (280) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ - 399, /* (281) tag_item ::= TBNAME */ - 399, /* (282) tag_item ::= QTAGS */ - 399, /* (283) tag_item ::= column_name */ - 399, /* (284) tag_item ::= column_name column_alias */ - 399, /* (285) tag_item ::= column_name AS column_alias */ - 337, /* (286) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ - 337, /* (287) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ - 337, /* (288) cmd ::= DROP INDEX exists_opt full_index_name */ - 401, /* (289) full_index_name ::= index_name */ - 401, /* (290) full_index_name ::= db_name NK_DOT index_name */ - 402, /* (291) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - 402, /* (292) 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 */ - 404, /* (293) func_list ::= func */ - 404, /* (294) func_list ::= func_list NK_COMMA func */ - 407, /* (295) func ::= sma_func_name NK_LP expression_list NK_RP */ - 408, /* (296) sma_func_name ::= function_name */ - 408, /* (297) sma_func_name ::= COUNT */ - 408, /* (298) sma_func_name ::= FIRST */ - 408, /* (299) sma_func_name ::= LAST */ - 408, /* (300) sma_func_name ::= LAST_ROW */ - 406, /* (301) sma_stream_opt ::= */ - 406, /* (302) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ - 406, /* (303) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ - 406, /* (304) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - 337, /* (305) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - 337, /* (306) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ - 337, /* (307) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ - 337, /* (308) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name where_clause_opt */ - 337, /* (309) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name where_clause_opt */ - 337, /* (310) cmd ::= DROP TOPIC exists_opt topic_name */ - 337, /* (311) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - 337, /* (312) cmd ::= DESC full_table_name */ - 337, /* (313) cmd ::= DESCRIBE full_table_name */ - 337, /* (314) cmd ::= RESET QUERY CACHE */ - 337, /* (315) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - 337, /* (316) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 412, /* (317) analyze_opt ::= */ - 412, /* (318) analyze_opt ::= ANALYZE */ - 413, /* (319) explain_options ::= */ - 413, /* (320) explain_options ::= explain_options VERBOSE NK_BOOL */ - 413, /* (321) explain_options ::= explain_options RATIO NK_FLOAT */ - 337, /* (322) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - 337, /* (323) cmd ::= DROP FUNCTION exists_opt function_name */ - 416, /* (324) agg_func_opt ::= */ - 416, /* (325) agg_func_opt ::= AGGREGATE */ - 417, /* (326) bufsize_opt ::= */ - 417, /* (327) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 418, /* (328) language_opt ::= */ - 418, /* (329) language_opt ::= LANGUAGE NK_STRING */ - 415, /* (330) or_replace_opt ::= */ - 415, /* (331) or_replace_opt ::= OR REPLACE */ - 337, /* (332) 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 */ - 337, /* (333) cmd ::= DROP STREAM exists_opt stream_name */ - 337, /* (334) cmd ::= PAUSE STREAM exists_opt stream_name */ - 337, /* (335) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 421, /* (336) col_list_opt ::= */ - 421, /* (337) col_list_opt ::= NK_LP col_name_list NK_RP */ - 422, /* (338) tag_def_or_ref_opt ::= */ - 422, /* (339) tag_def_or_ref_opt ::= tags_def */ - 422, /* (340) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 420, /* (341) stream_options ::= */ - 420, /* (342) stream_options ::= stream_options TRIGGER AT_ONCE */ - 420, /* (343) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - 420, /* (344) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - 420, /* (345) stream_options ::= stream_options WATERMARK duration_literal */ - 420, /* (346) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - 420, /* (347) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - 420, /* (348) stream_options ::= stream_options DELETE_MARK duration_literal */ - 420, /* (349) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 423, /* (350) subtable_opt ::= */ - 423, /* (351) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 424, /* (352) ignore_opt ::= */ - 424, /* (353) ignore_opt ::= IGNORE UNTREATED */ - 337, /* (354) cmd ::= KILL CONNECTION NK_INTEGER */ - 337, /* (355) cmd ::= KILL QUERY NK_STRING */ - 337, /* (356) cmd ::= KILL TRANSACTION NK_INTEGER */ - 337, /* (357) cmd ::= BALANCE VGROUP */ - 337, /* (358) cmd ::= BALANCE VGROUP LEADER */ - 337, /* (359) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - 337, /* (360) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - 337, /* (361) cmd ::= SPLIT VGROUP NK_INTEGER */ - 426, /* (362) dnode_list ::= DNODE NK_INTEGER */ - 426, /* (363) dnode_list ::= dnode_list DNODE NK_INTEGER */ - 337, /* (364) cmd ::= DELETE FROM full_table_name where_clause_opt */ - 337, /* (365) cmd ::= query_or_subquery */ - 337, /* (366) cmd ::= insert_query */ - 414, /* (367) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - 414, /* (368) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - 340, /* (369) literal ::= NK_INTEGER */ - 340, /* (370) literal ::= NK_FLOAT */ - 340, /* (371) literal ::= NK_STRING */ - 340, /* (372) literal ::= NK_BOOL */ - 340, /* (373) literal ::= TIMESTAMP NK_STRING */ - 340, /* (374) literal ::= duration_literal */ - 340, /* (375) literal ::= NULL */ - 340, /* (376) literal ::= NK_QUESTION */ - 390, /* (377) duration_literal ::= NK_VARIABLE */ - 366, /* (378) signed ::= NK_INTEGER */ - 366, /* (379) signed ::= NK_PLUS NK_INTEGER */ - 366, /* (380) signed ::= NK_MINUS NK_INTEGER */ - 366, /* (381) signed ::= NK_FLOAT */ - 366, /* (382) signed ::= NK_PLUS NK_FLOAT */ - 366, /* (383) signed ::= NK_MINUS NK_FLOAT */ - 380, /* (384) signed_literal ::= signed */ - 380, /* (385) signed_literal ::= NK_STRING */ - 380, /* (386) signed_literal ::= NK_BOOL */ - 380, /* (387) signed_literal ::= TIMESTAMP NK_STRING */ - 380, /* (388) signed_literal ::= duration_literal */ - 380, /* (389) signed_literal ::= NULL */ - 380, /* (390) signed_literal ::= literal_func */ - 380, /* (391) signed_literal ::= NK_QUESTION */ - 428, /* (392) literal_list ::= signed_literal */ - 428, /* (393) literal_list ::= literal_list NK_COMMA signed_literal */ - 349, /* (394) db_name ::= NK_ID */ - 350, /* (395) table_name ::= NK_ID */ - 378, /* (396) column_name ::= NK_ID */ - 392, /* (397) function_name ::= NK_ID */ - 429, /* (398) table_alias ::= NK_ID */ - 400, /* (399) column_alias ::= NK_ID */ - 342, /* (400) user_name ::= NK_ID */ - 351, /* (401) topic_name ::= NK_ID */ - 419, /* (402) stream_name ::= NK_ID */ - 411, /* (403) cgroup_name ::= NK_ID */ - 403, /* (404) index_name ::= NK_ID */ - 430, /* (405) expr_or_subquery ::= expression */ - 425, /* (406) expression ::= literal */ - 425, /* (407) expression ::= pseudo_column */ - 425, /* (408) expression ::= column_reference */ - 425, /* (409) expression ::= function_expression */ - 425, /* (410) expression ::= case_when_expression */ - 425, /* (411) expression ::= NK_LP expression NK_RP */ - 425, /* (412) expression ::= NK_PLUS expr_or_subquery */ - 425, /* (413) expression ::= NK_MINUS expr_or_subquery */ - 425, /* (414) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - 425, /* (415) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - 425, /* (416) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - 425, /* (417) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - 425, /* (418) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - 425, /* (419) expression ::= column_reference NK_ARROW NK_STRING */ - 425, /* (420) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - 425, /* (421) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - 383, /* (422) expression_list ::= expr_or_subquery */ - 383, /* (423) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - 432, /* (424) column_reference ::= column_name */ - 432, /* (425) column_reference ::= table_name NK_DOT column_name */ - 431, /* (426) pseudo_column ::= ROWTS */ - 431, /* (427) pseudo_column ::= TBNAME */ - 431, /* (428) pseudo_column ::= table_name NK_DOT TBNAME */ - 431, /* (429) pseudo_column ::= QSTART */ - 431, /* (430) pseudo_column ::= QEND */ - 431, /* (431) pseudo_column ::= QDURATION */ - 431, /* (432) pseudo_column ::= WSTART */ - 431, /* (433) pseudo_column ::= WEND */ - 431, /* (434) pseudo_column ::= WDURATION */ - 431, /* (435) pseudo_column ::= IROWTS */ - 431, /* (436) pseudo_column ::= ISFILLED */ - 431, /* (437) pseudo_column ::= QTAGS */ - 433, /* (438) function_expression ::= function_name NK_LP expression_list NK_RP */ - 433, /* (439) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - 433, /* (440) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - 433, /* (441) function_expression ::= literal_func */ - 427, /* (442) literal_func ::= noarg_func NK_LP NK_RP */ - 427, /* (443) literal_func ::= NOW */ - 437, /* (444) noarg_func ::= NOW */ - 437, /* (445) noarg_func ::= TODAY */ - 437, /* (446) noarg_func ::= TIMEZONE */ - 437, /* (447) noarg_func ::= DATABASE */ - 437, /* (448) noarg_func ::= CLIENT_VERSION */ - 437, /* (449) noarg_func ::= SERVER_VERSION */ - 437, /* (450) noarg_func ::= SERVER_STATUS */ - 437, /* (451) noarg_func ::= CURRENT_USER */ - 437, /* (452) noarg_func ::= USER */ - 435, /* (453) star_func ::= COUNT */ - 435, /* (454) star_func ::= FIRST */ - 435, /* (455) star_func ::= LAST */ - 435, /* (456) star_func ::= LAST_ROW */ - 436, /* (457) star_func_para_list ::= NK_STAR */ - 436, /* (458) star_func_para_list ::= other_para_list */ - 438, /* (459) other_para_list ::= star_func_para */ - 438, /* (460) other_para_list ::= other_para_list NK_COMMA star_func_para */ - 439, /* (461) star_func_para ::= expr_or_subquery */ - 439, /* (462) star_func_para ::= table_name NK_DOT NK_STAR */ - 434, /* (463) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - 434, /* (464) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - 440, /* (465) when_then_list ::= when_then_expr */ - 440, /* (466) when_then_list ::= when_then_list when_then_expr */ - 443, /* (467) when_then_expr ::= WHEN common_expression THEN common_expression */ - 441, /* (468) case_when_else_opt ::= */ - 441, /* (469) case_when_else_opt ::= ELSE common_expression */ - 444, /* (470) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - 444, /* (471) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - 444, /* (472) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - 444, /* (473) predicate ::= expr_or_subquery IS NULL */ - 444, /* (474) predicate ::= expr_or_subquery IS NOT NULL */ - 444, /* (475) predicate ::= expr_or_subquery in_op in_predicate_value */ - 445, /* (476) compare_op ::= NK_LT */ - 445, /* (477) compare_op ::= NK_GT */ - 445, /* (478) compare_op ::= NK_LE */ - 445, /* (479) compare_op ::= NK_GE */ - 445, /* (480) compare_op ::= NK_NE */ - 445, /* (481) compare_op ::= NK_EQ */ - 445, /* (482) compare_op ::= LIKE */ - 445, /* (483) compare_op ::= NOT LIKE */ - 445, /* (484) compare_op ::= MATCH */ - 445, /* (485) compare_op ::= NMATCH */ - 445, /* (486) compare_op ::= CONTAINS */ - 446, /* (487) in_op ::= IN */ - 446, /* (488) in_op ::= NOT IN */ - 447, /* (489) in_predicate_value ::= NK_LP literal_list NK_RP */ - 448, /* (490) boolean_value_expression ::= boolean_primary */ - 448, /* (491) boolean_value_expression ::= NOT boolean_primary */ - 448, /* (492) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - 448, /* (493) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - 449, /* (494) boolean_primary ::= predicate */ - 449, /* (495) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - 442, /* (496) common_expression ::= expr_or_subquery */ - 442, /* (497) common_expression ::= boolean_value_expression */ - 450, /* (498) from_clause_opt ::= */ - 450, /* (499) from_clause_opt ::= FROM table_reference_list */ - 451, /* (500) table_reference_list ::= table_reference */ - 451, /* (501) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - 452, /* (502) table_reference ::= table_primary */ - 452, /* (503) table_reference ::= joined_table */ - 453, /* (504) table_primary ::= table_name alias_opt */ - 453, /* (505) table_primary ::= db_name NK_DOT table_name alias_opt */ - 453, /* (506) table_primary ::= subquery alias_opt */ - 453, /* (507) table_primary ::= parenthesized_joined_table */ - 455, /* (508) alias_opt ::= */ - 455, /* (509) alias_opt ::= table_alias */ - 455, /* (510) alias_opt ::= AS table_alias */ - 457, /* (511) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - 457, /* (512) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - 454, /* (513) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 458, /* (514) join_type ::= */ - 458, /* (515) join_type ::= INNER */ - 459, /* (516) 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 */ - 460, /* (517) set_quantifier_opt ::= */ - 460, /* (518) set_quantifier_opt ::= DISTINCT */ - 460, /* (519) set_quantifier_opt ::= ALL */ - 461, /* (520) select_list ::= select_item */ - 461, /* (521) select_list ::= select_list NK_COMMA select_item */ - 469, /* (522) select_item ::= NK_STAR */ - 469, /* (523) select_item ::= common_expression */ - 469, /* (524) select_item ::= common_expression column_alias */ - 469, /* (525) select_item ::= common_expression AS column_alias */ - 469, /* (526) select_item ::= table_name NK_DOT NK_STAR */ - 410, /* (527) where_clause_opt ::= */ - 410, /* (528) where_clause_opt ::= WHERE search_condition */ - 462, /* (529) partition_by_clause_opt ::= */ - 462, /* (530) partition_by_clause_opt ::= PARTITION BY partition_list */ - 470, /* (531) partition_list ::= partition_item */ - 470, /* (532) partition_list ::= partition_list NK_COMMA partition_item */ - 471, /* (533) partition_item ::= expr_or_subquery */ - 471, /* (534) partition_item ::= expr_or_subquery column_alias */ - 471, /* (535) partition_item ::= expr_or_subquery AS column_alias */ - 466, /* (536) twindow_clause_opt ::= */ - 466, /* (537) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - 466, /* (538) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - 466, /* (539) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - 466, /* (540) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - 466, /* (541) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 405, /* (542) sliding_opt ::= */ - 405, /* (543) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 465, /* (544) fill_opt ::= */ - 465, /* (545) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - 465, /* (546) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - 465, /* (547) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - 472, /* (548) fill_mode ::= NONE */ - 472, /* (549) fill_mode ::= PREV */ - 472, /* (550) fill_mode ::= NULL */ - 472, /* (551) fill_mode ::= NULL_F */ - 472, /* (552) fill_mode ::= LINEAR */ - 472, /* (553) fill_mode ::= NEXT */ - 467, /* (554) group_by_clause_opt ::= */ - 467, /* (555) group_by_clause_opt ::= GROUP BY group_by_list */ - 473, /* (556) group_by_list ::= expr_or_subquery */ - 473, /* (557) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 468, /* (558) having_clause_opt ::= */ - 468, /* (559) having_clause_opt ::= HAVING search_condition */ - 463, /* (560) range_opt ::= */ - 463, /* (561) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - 463, /* (562) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 464, /* (563) every_opt ::= */ - 464, /* (564) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - 474, /* (565) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - 475, /* (566) query_simple ::= query_specification */ - 475, /* (567) query_simple ::= union_query_expression */ - 479, /* (568) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - 479, /* (569) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - 480, /* (570) query_simple_or_subquery ::= query_simple */ - 480, /* (571) query_simple_or_subquery ::= subquery */ - 409, /* (572) query_or_subquery ::= query_expression */ - 409, /* (573) query_or_subquery ::= subquery */ - 476, /* (574) order_by_clause_opt ::= */ - 476, /* (575) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 477, /* (576) slimit_clause_opt ::= */ - 477, /* (577) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - 477, /* (578) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - 477, /* (579) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 478, /* (580) limit_clause_opt ::= */ - 478, /* (581) limit_clause_opt ::= LIMIT NK_INTEGER */ - 478, /* (582) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - 478, /* (583) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 456, /* (584) subquery ::= NK_LP query_expression NK_RP */ - 456, /* (585) subquery ::= NK_LP subquery NK_RP */ - 352, /* (586) search_condition ::= common_expression */ - 481, /* (587) sort_specification_list ::= sort_specification */ - 481, /* (588) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - 482, /* (589) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 483, /* (590) ordering_specification_opt ::= */ - 483, /* (591) ordering_specification_opt ::= ASC */ - 483, /* (592) ordering_specification_opt ::= DESC */ - 484, /* (593) null_ordering_opt ::= */ - 484, /* (594) null_ordering_opt ::= NULLS FIRST */ - 484, /* (595) null_ordering_opt ::= NULLS LAST */ + 338, /* (0) cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ + 338, /* (1) cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ + 339, /* (2) account_options ::= */ + 339, /* (3) account_options ::= account_options PPS literal */ + 339, /* (4) account_options ::= account_options TSERIES literal */ + 339, /* (5) account_options ::= account_options STORAGE literal */ + 339, /* (6) account_options ::= account_options STREAMS literal */ + 339, /* (7) account_options ::= account_options QTIME literal */ + 339, /* (8) account_options ::= account_options DBS literal */ + 339, /* (9) account_options ::= account_options USERS literal */ + 339, /* (10) account_options ::= account_options CONNS literal */ + 339, /* (11) account_options ::= account_options STATE literal */ + 340, /* (12) alter_account_options ::= alter_account_option */ + 340, /* (13) alter_account_options ::= alter_account_options alter_account_option */ + 342, /* (14) alter_account_option ::= PASS literal */ + 342, /* (15) alter_account_option ::= PPS literal */ + 342, /* (16) alter_account_option ::= TSERIES literal */ + 342, /* (17) alter_account_option ::= STORAGE literal */ + 342, /* (18) alter_account_option ::= STREAMS literal */ + 342, /* (19) alter_account_option ::= QTIME literal */ + 342, /* (20) alter_account_option ::= DBS literal */ + 342, /* (21) alter_account_option ::= USERS literal */ + 342, /* (22) alter_account_option ::= CONNS literal */ + 342, /* (23) alter_account_option ::= STATE literal */ + 338, /* (24) cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ + 338, /* (25) cmd ::= ALTER USER user_name PASS NK_STRING */ + 338, /* (26) cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ + 338, /* (27) cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ + 338, /* (28) cmd ::= DROP USER user_name */ + 344, /* (29) sysinfo_opt ::= */ + 344, /* (30) sysinfo_opt ::= SYSINFO NK_INTEGER */ + 338, /* (31) cmd ::= GRANT privileges ON priv_level with_opt TO user_name */ + 338, /* (32) cmd ::= REVOKE privileges ON priv_level with_opt FROM user_name */ + 345, /* (33) privileges ::= ALL */ + 345, /* (34) privileges ::= priv_type_list */ + 345, /* (35) privileges ::= SUBSCRIBE */ + 348, /* (36) priv_type_list ::= priv_type */ + 348, /* (37) priv_type_list ::= priv_type_list NK_COMMA priv_type */ + 349, /* (38) priv_type ::= READ */ + 349, /* (39) priv_type ::= WRITE */ + 346, /* (40) priv_level ::= NK_STAR NK_DOT NK_STAR */ + 346, /* (41) priv_level ::= db_name NK_DOT NK_STAR */ + 346, /* (42) priv_level ::= db_name NK_DOT table_name */ + 346, /* (43) priv_level ::= topic_name */ + 347, /* (44) with_opt ::= */ + 347, /* (45) with_opt ::= WITH search_condition */ + 338, /* (46) cmd ::= CREATE DNODE dnode_endpoint */ + 338, /* (47) cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ + 338, /* (48) cmd ::= DROP DNODE NK_INTEGER force_opt */ + 338, /* (49) cmd ::= DROP DNODE dnode_endpoint force_opt */ + 338, /* (50) cmd ::= DROP DNODE NK_INTEGER unsafe_opt */ + 338, /* (51) cmd ::= DROP DNODE dnode_endpoint unsafe_opt */ + 338, /* (52) cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ + 338, /* (53) cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ + 338, /* (54) cmd ::= ALTER ALL DNODES NK_STRING */ + 338, /* (55) cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ + 338, /* (56) cmd ::= RESTORE DNODE NK_INTEGER */ + 354, /* (57) dnode_endpoint ::= NK_STRING */ + 354, /* (58) dnode_endpoint ::= NK_ID */ + 354, /* (59) dnode_endpoint ::= NK_IPTOKEN */ + 355, /* (60) force_opt ::= */ + 355, /* (61) force_opt ::= FORCE */ + 356, /* (62) unsafe_opt ::= UNSAFE */ + 338, /* (63) cmd ::= ALTER LOCAL NK_STRING */ + 338, /* (64) cmd ::= ALTER LOCAL NK_STRING NK_STRING */ + 338, /* (65) cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ + 338, /* (66) cmd ::= DROP QNODE ON DNODE NK_INTEGER */ + 338, /* (67) cmd ::= RESTORE QNODE ON DNODE NK_INTEGER */ + 338, /* (68) cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ + 338, /* (69) cmd ::= DROP BNODE ON DNODE NK_INTEGER */ + 338, /* (70) cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ + 338, /* (71) cmd ::= DROP SNODE ON DNODE NK_INTEGER */ + 338, /* (72) cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ + 338, /* (73) cmd ::= DROP MNODE ON DNODE NK_INTEGER */ + 338, /* (74) cmd ::= RESTORE MNODE ON DNODE NK_INTEGER */ + 338, /* (75) cmd ::= RESTORE VNODE ON DNODE NK_INTEGER */ + 338, /* (76) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ + 338, /* (77) cmd ::= DROP DATABASE exists_opt db_name */ + 338, /* (78) cmd ::= USE db_name */ + 338, /* (79) cmd ::= ALTER DATABASE db_name alter_db_options */ + 338, /* (80) cmd ::= FLUSH DATABASE db_name */ + 338, /* (81) cmd ::= TRIM DATABASE db_name speed_opt */ + 338, /* (82) cmd ::= COMPACT DATABASE db_name start_opt end_opt */ + 357, /* (83) not_exists_opt ::= IF NOT EXISTS */ + 357, /* (84) not_exists_opt ::= */ + 359, /* (85) exists_opt ::= IF EXISTS */ + 359, /* (86) exists_opt ::= */ + 358, /* (87) db_options ::= */ + 358, /* (88) db_options ::= db_options BUFFER NK_INTEGER */ + 358, /* (89) db_options ::= db_options CACHEMODEL NK_STRING */ + 358, /* (90) db_options ::= db_options CACHESIZE NK_INTEGER */ + 358, /* (91) db_options ::= db_options COMP NK_INTEGER */ + 358, /* (92) db_options ::= db_options DURATION NK_INTEGER */ + 358, /* (93) db_options ::= db_options DURATION NK_VARIABLE */ + 358, /* (94) db_options ::= db_options MAXROWS NK_INTEGER */ + 358, /* (95) db_options ::= db_options MINROWS NK_INTEGER */ + 358, /* (96) db_options ::= db_options KEEP integer_list */ + 358, /* (97) db_options ::= db_options KEEP variable_list */ + 358, /* (98) db_options ::= db_options PAGES NK_INTEGER */ + 358, /* (99) db_options ::= db_options PAGESIZE NK_INTEGER */ + 358, /* (100) db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ + 358, /* (101) db_options ::= db_options PRECISION NK_STRING */ + 358, /* (102) db_options ::= db_options REPLICA NK_INTEGER */ + 358, /* (103) db_options ::= db_options VGROUPS NK_INTEGER */ + 358, /* (104) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ + 358, /* (105) db_options ::= db_options RETENTIONS retention_list */ + 358, /* (106) db_options ::= db_options SCHEMALESS NK_INTEGER */ + 358, /* (107) db_options ::= db_options WAL_LEVEL NK_INTEGER */ + 358, /* (108) db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ + 358, /* (109) db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ + 358, /* (110) db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ + 358, /* (111) db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ + 358, /* (112) db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ + 358, /* (113) db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ + 358, /* (114) db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ + 358, /* (115) db_options ::= db_options STT_TRIGGER NK_INTEGER */ + 358, /* (116) db_options ::= db_options TABLE_PREFIX signed */ + 358, /* (117) db_options ::= db_options TABLE_SUFFIX signed */ + 360, /* (118) alter_db_options ::= alter_db_option */ + 360, /* (119) alter_db_options ::= alter_db_options alter_db_option */ + 368, /* (120) alter_db_option ::= BUFFER NK_INTEGER */ + 368, /* (121) alter_db_option ::= CACHEMODEL NK_STRING */ + 368, /* (122) alter_db_option ::= CACHESIZE NK_INTEGER */ + 368, /* (123) alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ + 368, /* (124) alter_db_option ::= KEEP integer_list */ + 368, /* (125) alter_db_option ::= KEEP variable_list */ + 368, /* (126) alter_db_option ::= PAGES NK_INTEGER */ + 368, /* (127) alter_db_option ::= REPLICA NK_INTEGER */ + 368, /* (128) alter_db_option ::= WAL_LEVEL NK_INTEGER */ + 368, /* (129) alter_db_option ::= STT_TRIGGER NK_INTEGER */ + 368, /* (130) alter_db_option ::= MINROWS NK_INTEGER */ + 368, /* (131) alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ + 368, /* (132) alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ + 368, /* (133) alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ + 368, /* (134) alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ + 364, /* (135) integer_list ::= NK_INTEGER */ + 364, /* (136) integer_list ::= integer_list NK_COMMA NK_INTEGER */ + 365, /* (137) variable_list ::= NK_VARIABLE */ + 365, /* (138) variable_list ::= variable_list NK_COMMA NK_VARIABLE */ + 366, /* (139) retention_list ::= retention */ + 366, /* (140) retention_list ::= retention_list NK_COMMA retention */ + 369, /* (141) retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ + 361, /* (142) speed_opt ::= */ + 361, /* (143) speed_opt ::= MAX_SPEED NK_INTEGER */ + 362, /* (144) start_opt ::= */ + 362, /* (145) start_opt ::= START WITH NK_INTEGER */ + 362, /* (146) start_opt ::= START WITH NK_STRING */ + 362, /* (147) start_opt ::= START WITH TIMESTAMP NK_STRING */ + 363, /* (148) end_opt ::= */ + 363, /* (149) end_opt ::= END WITH NK_INTEGER */ + 363, /* (150) end_opt ::= END WITH NK_STRING */ + 363, /* (151) end_opt ::= END WITH TIMESTAMP NK_STRING */ + 338, /* (152) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ + 338, /* (153) cmd ::= CREATE TABLE multi_create_clause */ + 338, /* (154) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ + 338, /* (155) cmd ::= DROP TABLE multi_drop_clause */ + 338, /* (156) cmd ::= DROP STABLE exists_opt full_table_name */ + 338, /* (157) cmd ::= ALTER TABLE alter_table_clause */ + 338, /* (158) cmd ::= ALTER STABLE alter_table_clause */ + 377, /* (159) alter_table_clause ::= full_table_name alter_table_options */ + 377, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + 377, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ + 377, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + 377, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ + 377, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + 377, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ + 377, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + 377, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ + 377, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ + 374, /* (169) multi_create_clause ::= create_subtable_clause */ + 374, /* (170) multi_create_clause ::= multi_create_clause create_subtable_clause */ + 382, /* (171) 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 */ + 376, /* (172) multi_drop_clause ::= drop_table_clause */ + 376, /* (173) multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ + 385, /* (174) drop_table_clause ::= exists_opt full_table_name */ + 383, /* (175) specific_cols_opt ::= */ + 383, /* (176) specific_cols_opt ::= NK_LP col_name_list NK_RP */ + 370, /* (177) full_table_name ::= table_name */ + 370, /* (178) full_table_name ::= db_name NK_DOT table_name */ + 371, /* (179) column_def_list ::= column_def */ + 371, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ + 387, /* (181) column_def ::= column_name type_name */ + 380, /* (182) type_name ::= BOOL */ + 380, /* (183) type_name ::= TINYINT */ + 380, /* (184) type_name ::= SMALLINT */ + 380, /* (185) type_name ::= INT */ + 380, /* (186) type_name ::= INTEGER */ + 380, /* (187) type_name ::= BIGINT */ + 380, /* (188) type_name ::= FLOAT */ + 380, /* (189) type_name ::= DOUBLE */ + 380, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + 380, /* (191) type_name ::= TIMESTAMP */ + 380, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + 380, /* (193) type_name ::= TINYINT UNSIGNED */ + 380, /* (194) type_name ::= SMALLINT UNSIGNED */ + 380, /* (195) type_name ::= INT UNSIGNED */ + 380, /* (196) type_name ::= BIGINT UNSIGNED */ + 380, /* (197) type_name ::= JSON */ + 380, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + 380, /* (199) type_name ::= MEDIUMBLOB */ + 380, /* (200) type_name ::= BLOB */ + 380, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + 380, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + 380, /* (203) type_name ::= DECIMAL */ + 380, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + 380, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 372, /* (206) tags_def_opt ::= */ + 372, /* (207) tags_def_opt ::= tags_def */ + 375, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + 373, /* (209) table_options ::= */ + 373, /* (210) table_options ::= table_options COMMENT NK_STRING */ + 373, /* (211) table_options ::= table_options MAX_DELAY duration_list */ + 373, /* (212) table_options ::= table_options WATERMARK duration_list */ + 373, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + 373, /* (214) table_options ::= table_options TTL NK_INTEGER */ + 373, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + 373, /* (216) table_options ::= table_options DELETE_MARK duration_list */ + 378, /* (217) alter_table_options ::= alter_table_option */ + 378, /* (218) alter_table_options ::= alter_table_options alter_table_option */ + 390, /* (219) alter_table_option ::= COMMENT NK_STRING */ + 390, /* (220) alter_table_option ::= TTL NK_INTEGER */ + 388, /* (221) duration_list ::= duration_literal */ + 388, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ + 389, /* (223) rollup_func_list ::= rollup_func_name */ + 389, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + 392, /* (225) rollup_func_name ::= function_name */ + 392, /* (226) rollup_func_name ::= FIRST */ + 392, /* (227) rollup_func_name ::= LAST */ + 386, /* (228) col_name_list ::= col_name */ + 386, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ + 394, /* (230) col_name ::= column_name */ + 338, /* (231) cmd ::= SHOW DNODES */ + 338, /* (232) cmd ::= SHOW USERS */ + 338, /* (233) cmd ::= SHOW USER PRIVILEGES */ + 338, /* (234) cmd ::= SHOW DATABASES */ + 338, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + 338, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + 338, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ + 338, /* (238) cmd ::= SHOW MNODES */ + 338, /* (239) cmd ::= SHOW QNODES */ + 338, /* (240) cmd ::= SHOW FUNCTIONS */ + 338, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + 338, /* (242) cmd ::= SHOW STREAMS */ + 338, /* (243) cmd ::= SHOW ACCOUNTS */ + 338, /* (244) cmd ::= SHOW APPS */ + 338, /* (245) cmd ::= SHOW CONNECTIONS */ + 338, /* (246) cmd ::= SHOW LICENCES */ + 338, /* (247) cmd ::= SHOW GRANTS */ + 338, /* (248) cmd ::= SHOW CREATE DATABASE db_name */ + 338, /* (249) cmd ::= SHOW CREATE TABLE full_table_name */ + 338, /* (250) cmd ::= SHOW CREATE STABLE full_table_name */ + 338, /* (251) cmd ::= SHOW QUERIES */ + 338, /* (252) cmd ::= SHOW SCORES */ + 338, /* (253) cmd ::= SHOW TOPICS */ + 338, /* (254) cmd ::= SHOW VARIABLES */ + 338, /* (255) cmd ::= SHOW CLUSTER VARIABLES */ + 338, /* (256) cmd ::= SHOW LOCAL VARIABLES */ + 338, /* (257) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + 338, /* (258) cmd ::= SHOW BNODES */ + 338, /* (259) cmd ::= SHOW SNODES */ + 338, /* (260) cmd ::= SHOW CLUSTER */ + 338, /* (261) cmd ::= SHOW TRANSACTIONS */ + 338, /* (262) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + 338, /* (263) cmd ::= SHOW CONSUMERS */ + 338, /* (264) cmd ::= SHOW SUBSCRIPTIONS */ + 338, /* (265) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + 338, /* (266) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + 338, /* (267) cmd ::= SHOW VNODES NK_INTEGER */ + 338, /* (268) cmd ::= SHOW VNODES NK_STRING */ + 338, /* (269) cmd ::= SHOW db_name_cond_opt ALIVE */ + 338, /* (270) cmd ::= SHOW CLUSTER ALIVE */ + 395, /* (271) db_name_cond_opt ::= */ + 395, /* (272) db_name_cond_opt ::= db_name NK_DOT */ + 396, /* (273) like_pattern_opt ::= */ + 396, /* (274) like_pattern_opt ::= LIKE NK_STRING */ + 397, /* (275) table_name_cond ::= table_name */ + 398, /* (276) from_db_opt ::= */ + 398, /* (277) from_db_opt ::= FROM db_name */ + 399, /* (278) tag_list_opt ::= */ + 399, /* (279) tag_list_opt ::= tag_item */ + 399, /* (280) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ + 400, /* (281) tag_item ::= TBNAME */ + 400, /* (282) tag_item ::= QTAGS */ + 400, /* (283) tag_item ::= column_name */ + 400, /* (284) tag_item ::= column_name column_alias */ + 400, /* (285) tag_item ::= column_name AS column_alias */ + 338, /* (286) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + 338, /* (287) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + 338, /* (288) cmd ::= DROP INDEX exists_opt full_index_name */ + 402, /* (289) full_index_name ::= index_name */ + 402, /* (290) full_index_name ::= db_name NK_DOT index_name */ + 403, /* (291) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + 403, /* (292) 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 */ + 405, /* (293) func_list ::= func */ + 405, /* (294) func_list ::= func_list NK_COMMA func */ + 408, /* (295) func ::= sma_func_name NK_LP expression_list NK_RP */ + 409, /* (296) sma_func_name ::= function_name */ + 409, /* (297) sma_func_name ::= COUNT */ + 409, /* (298) sma_func_name ::= FIRST */ + 409, /* (299) sma_func_name ::= LAST */ + 409, /* (300) sma_func_name ::= LAST_ROW */ + 407, /* (301) sma_stream_opt ::= */ + 407, /* (302) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + 407, /* (303) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + 407, /* (304) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + 410, /* (305) with_meta ::= AS */ + 410, /* (306) with_meta ::= WITH META AS */ + 410, /* (307) with_meta ::= ONLY META AS */ + 338, /* (308) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + 338, /* (309) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + 338, /* (310) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + 338, /* (311) cmd ::= DROP TOPIC exists_opt topic_name */ + 338, /* (312) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + 338, /* (313) cmd ::= DESC full_table_name */ + 338, /* (314) cmd ::= DESCRIBE full_table_name */ + 338, /* (315) cmd ::= RESET QUERY CACHE */ + 338, /* (316) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + 338, /* (317) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 414, /* (318) analyze_opt ::= */ + 414, /* (319) analyze_opt ::= ANALYZE */ + 415, /* (320) explain_options ::= */ + 415, /* (321) explain_options ::= explain_options VERBOSE NK_BOOL */ + 415, /* (322) explain_options ::= explain_options RATIO NK_FLOAT */ + 338, /* (323) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + 338, /* (324) cmd ::= DROP FUNCTION exists_opt function_name */ + 418, /* (325) agg_func_opt ::= */ + 418, /* (326) agg_func_opt ::= AGGREGATE */ + 419, /* (327) bufsize_opt ::= */ + 419, /* (328) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 420, /* (329) language_opt ::= */ + 420, /* (330) language_opt ::= LANGUAGE NK_STRING */ + 417, /* (331) or_replace_opt ::= */ + 417, /* (332) or_replace_opt ::= OR REPLACE */ + 338, /* (333) 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 */ + 338, /* (334) cmd ::= DROP STREAM exists_opt stream_name */ + 338, /* (335) cmd ::= PAUSE STREAM exists_opt stream_name */ + 338, /* (336) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 423, /* (337) col_list_opt ::= */ + 423, /* (338) col_list_opt ::= NK_LP col_name_list NK_RP */ + 424, /* (339) tag_def_or_ref_opt ::= */ + 424, /* (340) tag_def_or_ref_opt ::= tags_def */ + 424, /* (341) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 422, /* (342) stream_options ::= */ + 422, /* (343) stream_options ::= stream_options TRIGGER AT_ONCE */ + 422, /* (344) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + 422, /* (345) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + 422, /* (346) stream_options ::= stream_options WATERMARK duration_literal */ + 422, /* (347) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + 422, /* (348) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + 422, /* (349) stream_options ::= stream_options DELETE_MARK duration_literal */ + 422, /* (350) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 425, /* (351) subtable_opt ::= */ + 425, /* (352) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 426, /* (353) ignore_opt ::= */ + 426, /* (354) ignore_opt ::= IGNORE UNTREATED */ + 338, /* (355) cmd ::= KILL CONNECTION NK_INTEGER */ + 338, /* (356) cmd ::= KILL QUERY NK_STRING */ + 338, /* (357) cmd ::= KILL TRANSACTION NK_INTEGER */ + 338, /* (358) cmd ::= BALANCE VGROUP */ + 338, /* (359) cmd ::= BALANCE VGROUP LEADER */ + 338, /* (360) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + 338, /* (361) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + 338, /* (362) cmd ::= SPLIT VGROUP NK_INTEGER */ + 428, /* (363) dnode_list ::= DNODE NK_INTEGER */ + 428, /* (364) dnode_list ::= dnode_list DNODE NK_INTEGER */ + 338, /* (365) cmd ::= DELETE FROM full_table_name where_clause_opt */ + 338, /* (366) cmd ::= query_or_subquery */ + 338, /* (367) cmd ::= insert_query */ + 416, /* (368) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + 416, /* (369) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + 341, /* (370) literal ::= NK_INTEGER */ + 341, /* (371) literal ::= NK_FLOAT */ + 341, /* (372) literal ::= NK_STRING */ + 341, /* (373) literal ::= NK_BOOL */ + 341, /* (374) literal ::= TIMESTAMP NK_STRING */ + 341, /* (375) literal ::= duration_literal */ + 341, /* (376) literal ::= NULL */ + 341, /* (377) literal ::= NK_QUESTION */ + 391, /* (378) duration_literal ::= NK_VARIABLE */ + 367, /* (379) signed ::= NK_INTEGER */ + 367, /* (380) signed ::= NK_PLUS NK_INTEGER */ + 367, /* (381) signed ::= NK_MINUS NK_INTEGER */ + 367, /* (382) signed ::= NK_FLOAT */ + 367, /* (383) signed ::= NK_PLUS NK_FLOAT */ + 367, /* (384) signed ::= NK_MINUS NK_FLOAT */ + 381, /* (385) signed_literal ::= signed */ + 381, /* (386) signed_literal ::= NK_STRING */ + 381, /* (387) signed_literal ::= NK_BOOL */ + 381, /* (388) signed_literal ::= TIMESTAMP NK_STRING */ + 381, /* (389) signed_literal ::= duration_literal */ + 381, /* (390) signed_literal ::= NULL */ + 381, /* (391) signed_literal ::= literal_func */ + 381, /* (392) signed_literal ::= NK_QUESTION */ + 430, /* (393) literal_list ::= signed_literal */ + 430, /* (394) literal_list ::= literal_list NK_COMMA signed_literal */ + 350, /* (395) db_name ::= NK_ID */ + 351, /* (396) table_name ::= NK_ID */ + 379, /* (397) column_name ::= NK_ID */ + 393, /* (398) function_name ::= NK_ID */ + 431, /* (399) table_alias ::= NK_ID */ + 401, /* (400) column_alias ::= NK_ID */ + 343, /* (401) user_name ::= NK_ID */ + 352, /* (402) topic_name ::= NK_ID */ + 421, /* (403) stream_name ::= NK_ID */ + 413, /* (404) cgroup_name ::= NK_ID */ + 404, /* (405) index_name ::= NK_ID */ + 432, /* (406) expr_or_subquery ::= expression */ + 427, /* (407) expression ::= literal */ + 427, /* (408) expression ::= pseudo_column */ + 427, /* (409) expression ::= column_reference */ + 427, /* (410) expression ::= function_expression */ + 427, /* (411) expression ::= case_when_expression */ + 427, /* (412) expression ::= NK_LP expression NK_RP */ + 427, /* (413) expression ::= NK_PLUS expr_or_subquery */ + 427, /* (414) expression ::= NK_MINUS expr_or_subquery */ + 427, /* (415) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + 427, /* (416) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + 427, /* (417) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + 427, /* (418) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + 427, /* (419) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + 427, /* (420) expression ::= column_reference NK_ARROW NK_STRING */ + 427, /* (421) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + 427, /* (422) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + 384, /* (423) expression_list ::= expr_or_subquery */ + 384, /* (424) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + 434, /* (425) column_reference ::= column_name */ + 434, /* (426) column_reference ::= table_name NK_DOT column_name */ + 433, /* (427) pseudo_column ::= ROWTS */ + 433, /* (428) pseudo_column ::= TBNAME */ + 433, /* (429) pseudo_column ::= table_name NK_DOT TBNAME */ + 433, /* (430) pseudo_column ::= QSTART */ + 433, /* (431) pseudo_column ::= QEND */ + 433, /* (432) pseudo_column ::= QDURATION */ + 433, /* (433) pseudo_column ::= WSTART */ + 433, /* (434) pseudo_column ::= WEND */ + 433, /* (435) pseudo_column ::= WDURATION */ + 433, /* (436) pseudo_column ::= IROWTS */ + 433, /* (437) pseudo_column ::= ISFILLED */ + 433, /* (438) pseudo_column ::= QTAGS */ + 435, /* (439) function_expression ::= function_name NK_LP expression_list NK_RP */ + 435, /* (440) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + 435, /* (441) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + 435, /* (442) function_expression ::= literal_func */ + 429, /* (443) literal_func ::= noarg_func NK_LP NK_RP */ + 429, /* (444) literal_func ::= NOW */ + 439, /* (445) noarg_func ::= NOW */ + 439, /* (446) noarg_func ::= TODAY */ + 439, /* (447) noarg_func ::= TIMEZONE */ + 439, /* (448) noarg_func ::= DATABASE */ + 439, /* (449) noarg_func ::= CLIENT_VERSION */ + 439, /* (450) noarg_func ::= SERVER_VERSION */ + 439, /* (451) noarg_func ::= SERVER_STATUS */ + 439, /* (452) noarg_func ::= CURRENT_USER */ + 439, /* (453) noarg_func ::= USER */ + 437, /* (454) star_func ::= COUNT */ + 437, /* (455) star_func ::= FIRST */ + 437, /* (456) star_func ::= LAST */ + 437, /* (457) star_func ::= LAST_ROW */ + 438, /* (458) star_func_para_list ::= NK_STAR */ + 438, /* (459) star_func_para_list ::= other_para_list */ + 440, /* (460) other_para_list ::= star_func_para */ + 440, /* (461) other_para_list ::= other_para_list NK_COMMA star_func_para */ + 441, /* (462) star_func_para ::= expr_or_subquery */ + 441, /* (463) star_func_para ::= table_name NK_DOT NK_STAR */ + 436, /* (464) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + 436, /* (465) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + 442, /* (466) when_then_list ::= when_then_expr */ + 442, /* (467) when_then_list ::= when_then_list when_then_expr */ + 445, /* (468) when_then_expr ::= WHEN common_expression THEN common_expression */ + 443, /* (469) case_when_else_opt ::= */ + 443, /* (470) case_when_else_opt ::= ELSE common_expression */ + 446, /* (471) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + 446, /* (472) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (473) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (474) predicate ::= expr_or_subquery IS NULL */ + 446, /* (475) predicate ::= expr_or_subquery IS NOT NULL */ + 446, /* (476) predicate ::= expr_or_subquery in_op in_predicate_value */ + 447, /* (477) compare_op ::= NK_LT */ + 447, /* (478) compare_op ::= NK_GT */ + 447, /* (479) compare_op ::= NK_LE */ + 447, /* (480) compare_op ::= NK_GE */ + 447, /* (481) compare_op ::= NK_NE */ + 447, /* (482) compare_op ::= NK_EQ */ + 447, /* (483) compare_op ::= LIKE */ + 447, /* (484) compare_op ::= NOT LIKE */ + 447, /* (485) compare_op ::= MATCH */ + 447, /* (486) compare_op ::= NMATCH */ + 447, /* (487) compare_op ::= CONTAINS */ + 448, /* (488) in_op ::= IN */ + 448, /* (489) in_op ::= NOT IN */ + 449, /* (490) in_predicate_value ::= NK_LP literal_list NK_RP */ + 450, /* (491) boolean_value_expression ::= boolean_primary */ + 450, /* (492) boolean_value_expression ::= NOT boolean_primary */ + 450, /* (493) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + 450, /* (494) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + 451, /* (495) boolean_primary ::= predicate */ + 451, /* (496) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + 444, /* (497) common_expression ::= expr_or_subquery */ + 444, /* (498) common_expression ::= boolean_value_expression */ + 452, /* (499) from_clause_opt ::= */ + 452, /* (500) from_clause_opt ::= FROM table_reference_list */ + 453, /* (501) table_reference_list ::= table_reference */ + 453, /* (502) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + 454, /* (503) table_reference ::= table_primary */ + 454, /* (504) table_reference ::= joined_table */ + 455, /* (505) table_primary ::= table_name alias_opt */ + 455, /* (506) table_primary ::= db_name NK_DOT table_name alias_opt */ + 455, /* (507) table_primary ::= subquery alias_opt */ + 455, /* (508) table_primary ::= parenthesized_joined_table */ + 457, /* (509) alias_opt ::= */ + 457, /* (510) alias_opt ::= table_alias */ + 457, /* (511) alias_opt ::= AS table_alias */ + 459, /* (512) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + 459, /* (513) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + 456, /* (514) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 460, /* (515) join_type ::= */ + 460, /* (516) join_type ::= INNER */ + 461, /* (517) 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 */ + 462, /* (518) set_quantifier_opt ::= */ + 462, /* (519) set_quantifier_opt ::= DISTINCT */ + 462, /* (520) set_quantifier_opt ::= ALL */ + 463, /* (521) select_list ::= select_item */ + 463, /* (522) select_list ::= select_list NK_COMMA select_item */ + 471, /* (523) select_item ::= NK_STAR */ + 471, /* (524) select_item ::= common_expression */ + 471, /* (525) select_item ::= common_expression column_alias */ + 471, /* (526) select_item ::= common_expression AS column_alias */ + 471, /* (527) select_item ::= table_name NK_DOT NK_STAR */ + 412, /* (528) where_clause_opt ::= */ + 412, /* (529) where_clause_opt ::= WHERE search_condition */ + 464, /* (530) partition_by_clause_opt ::= */ + 464, /* (531) partition_by_clause_opt ::= PARTITION BY partition_list */ + 472, /* (532) partition_list ::= partition_item */ + 472, /* (533) partition_list ::= partition_list NK_COMMA partition_item */ + 473, /* (534) partition_item ::= expr_or_subquery */ + 473, /* (535) partition_item ::= expr_or_subquery column_alias */ + 473, /* (536) partition_item ::= expr_or_subquery AS column_alias */ + 468, /* (537) twindow_clause_opt ::= */ + 468, /* (538) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + 468, /* (539) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + 468, /* (540) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (541) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (542) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 406, /* (543) sliding_opt ::= */ + 406, /* (544) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 467, /* (545) fill_opt ::= */ + 467, /* (546) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + 467, /* (547) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + 467, /* (548) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + 474, /* (549) fill_mode ::= NONE */ + 474, /* (550) fill_mode ::= PREV */ + 474, /* (551) fill_mode ::= NULL */ + 474, /* (552) fill_mode ::= NULL_F */ + 474, /* (553) fill_mode ::= LINEAR */ + 474, /* (554) fill_mode ::= NEXT */ + 469, /* (555) group_by_clause_opt ::= */ + 469, /* (556) group_by_clause_opt ::= GROUP BY group_by_list */ + 475, /* (557) group_by_list ::= expr_or_subquery */ + 475, /* (558) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 470, /* (559) having_clause_opt ::= */ + 470, /* (560) having_clause_opt ::= HAVING search_condition */ + 465, /* (561) range_opt ::= */ + 465, /* (562) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + 465, /* (563) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 466, /* (564) every_opt ::= */ + 466, /* (565) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + 476, /* (566) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + 477, /* (567) query_simple ::= query_specification */ + 477, /* (568) query_simple ::= union_query_expression */ + 481, /* (569) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + 481, /* (570) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + 482, /* (571) query_simple_or_subquery ::= query_simple */ + 482, /* (572) query_simple_or_subquery ::= subquery */ + 411, /* (573) query_or_subquery ::= query_expression */ + 411, /* (574) query_or_subquery ::= subquery */ + 478, /* (575) order_by_clause_opt ::= */ + 478, /* (576) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 479, /* (577) slimit_clause_opt ::= */ + 479, /* (578) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + 479, /* (579) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + 479, /* (580) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 480, /* (581) limit_clause_opt ::= */ + 480, /* (582) limit_clause_opt ::= LIMIT NK_INTEGER */ + 480, /* (583) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + 480, /* (584) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 458, /* (585) subquery ::= NK_LP query_expression NK_RP */ + 458, /* (586) subquery ::= NK_LP subquery NK_RP */ + 353, /* (587) search_condition ::= common_expression */ + 483, /* (588) sort_specification_list ::= sort_specification */ + 483, /* (589) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + 484, /* (590) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 485, /* (591) ordering_specification_opt ::= */ + 485, /* (592) ordering_specification_opt ::= ASC */ + 485, /* (593) ordering_specification_opt ::= DESC */ + 486, /* (594) null_ordering_opt ::= */ + 486, /* (595) null_ordering_opt ::= NULLS FIRST */ + 486, /* (596) null_ordering_opt ::= NULLS LAST */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -4064,297 +4432,298 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (302) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ -3, /* (303) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ -3, /* (304) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - -6, /* (305) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - -7, /* (306) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ - -9, /* (307) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ - -8, /* (308) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name where_clause_opt */ - -10, /* (309) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name where_clause_opt */ - -4, /* (310) cmd ::= DROP TOPIC exists_opt topic_name */ - -7, /* (311) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - -2, /* (312) cmd ::= DESC full_table_name */ - -2, /* (313) cmd ::= DESCRIBE full_table_name */ - -3, /* (314) cmd ::= RESET QUERY CACHE */ - -4, /* (315) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - -4, /* (316) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 0, /* (317) analyze_opt ::= */ - -1, /* (318) analyze_opt ::= ANALYZE */ - 0, /* (319) explain_options ::= */ - -3, /* (320) explain_options ::= explain_options VERBOSE NK_BOOL */ - -3, /* (321) explain_options ::= explain_options RATIO NK_FLOAT */ - -12, /* (322) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - -4, /* (323) cmd ::= DROP FUNCTION exists_opt function_name */ - 0, /* (324) agg_func_opt ::= */ - -1, /* (325) agg_func_opt ::= AGGREGATE */ - 0, /* (326) bufsize_opt ::= */ - -2, /* (327) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 0, /* (328) language_opt ::= */ - -2, /* (329) language_opt ::= LANGUAGE NK_STRING */ - 0, /* (330) or_replace_opt ::= */ - -2, /* (331) or_replace_opt ::= OR REPLACE */ - -12, /* (332) 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 */ - -4, /* (333) cmd ::= DROP STREAM exists_opt stream_name */ - -4, /* (334) cmd ::= PAUSE STREAM exists_opt stream_name */ - -5, /* (335) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 0, /* (336) col_list_opt ::= */ - -3, /* (337) col_list_opt ::= NK_LP col_name_list NK_RP */ - 0, /* (338) tag_def_or_ref_opt ::= */ - -1, /* (339) tag_def_or_ref_opt ::= tags_def */ - -4, /* (340) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 0, /* (341) stream_options ::= */ - -3, /* (342) stream_options ::= stream_options TRIGGER AT_ONCE */ - -3, /* (343) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - -4, /* (344) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - -3, /* (345) stream_options ::= stream_options WATERMARK duration_literal */ - -4, /* (346) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - -3, /* (347) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - -3, /* (348) stream_options ::= stream_options DELETE_MARK duration_literal */ - -4, /* (349) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 0, /* (350) subtable_opt ::= */ - -4, /* (351) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 0, /* (352) ignore_opt ::= */ - -2, /* (353) ignore_opt ::= IGNORE UNTREATED */ - -3, /* (354) cmd ::= KILL CONNECTION NK_INTEGER */ - -3, /* (355) cmd ::= KILL QUERY NK_STRING */ - -3, /* (356) cmd ::= KILL TRANSACTION NK_INTEGER */ - -2, /* (357) cmd ::= BALANCE VGROUP */ - -3, /* (358) cmd ::= BALANCE VGROUP LEADER */ - -4, /* (359) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - -4, /* (360) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - -3, /* (361) cmd ::= SPLIT VGROUP NK_INTEGER */ - -2, /* (362) dnode_list ::= DNODE NK_INTEGER */ - -3, /* (363) dnode_list ::= dnode_list DNODE NK_INTEGER */ - -4, /* (364) cmd ::= DELETE FROM full_table_name where_clause_opt */ - -1, /* (365) cmd ::= query_or_subquery */ - -1, /* (366) cmd ::= insert_query */ - -7, /* (367) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - -4, /* (368) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - -1, /* (369) literal ::= NK_INTEGER */ - -1, /* (370) literal ::= NK_FLOAT */ - -1, /* (371) literal ::= NK_STRING */ - -1, /* (372) literal ::= NK_BOOL */ - -2, /* (373) literal ::= TIMESTAMP NK_STRING */ - -1, /* (374) literal ::= duration_literal */ - -1, /* (375) literal ::= NULL */ - -1, /* (376) literal ::= NK_QUESTION */ - -1, /* (377) duration_literal ::= NK_VARIABLE */ - -1, /* (378) signed ::= NK_INTEGER */ - -2, /* (379) signed ::= NK_PLUS NK_INTEGER */ - -2, /* (380) signed ::= NK_MINUS NK_INTEGER */ - -1, /* (381) signed ::= NK_FLOAT */ - -2, /* (382) signed ::= NK_PLUS NK_FLOAT */ - -2, /* (383) signed ::= NK_MINUS NK_FLOAT */ - -1, /* (384) signed_literal ::= signed */ - -1, /* (385) signed_literal ::= NK_STRING */ - -1, /* (386) signed_literal ::= NK_BOOL */ - -2, /* (387) signed_literal ::= TIMESTAMP NK_STRING */ - -1, /* (388) signed_literal ::= duration_literal */ - -1, /* (389) signed_literal ::= NULL */ - -1, /* (390) signed_literal ::= literal_func */ - -1, /* (391) signed_literal ::= NK_QUESTION */ - -1, /* (392) literal_list ::= signed_literal */ - -3, /* (393) literal_list ::= literal_list NK_COMMA signed_literal */ - -1, /* (394) db_name ::= NK_ID */ - -1, /* (395) table_name ::= NK_ID */ - -1, /* (396) column_name ::= NK_ID */ - -1, /* (397) function_name ::= NK_ID */ - -1, /* (398) table_alias ::= NK_ID */ - -1, /* (399) column_alias ::= NK_ID */ - -1, /* (400) user_name ::= NK_ID */ - -1, /* (401) topic_name ::= NK_ID */ - -1, /* (402) stream_name ::= NK_ID */ - -1, /* (403) cgroup_name ::= NK_ID */ - -1, /* (404) index_name ::= NK_ID */ - -1, /* (405) expr_or_subquery ::= expression */ - -1, /* (406) expression ::= literal */ - -1, /* (407) expression ::= pseudo_column */ - -1, /* (408) expression ::= column_reference */ - -1, /* (409) expression ::= function_expression */ - -1, /* (410) expression ::= case_when_expression */ - -3, /* (411) expression ::= NK_LP expression NK_RP */ - -2, /* (412) expression ::= NK_PLUS expr_or_subquery */ - -2, /* (413) expression ::= NK_MINUS expr_or_subquery */ - -3, /* (414) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - -3, /* (415) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - -3, /* (416) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - -3, /* (417) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - -3, /* (418) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - -3, /* (419) expression ::= column_reference NK_ARROW NK_STRING */ - -3, /* (420) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - -3, /* (421) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - -1, /* (422) expression_list ::= expr_or_subquery */ - -3, /* (423) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - -1, /* (424) column_reference ::= column_name */ - -3, /* (425) column_reference ::= table_name NK_DOT column_name */ - -1, /* (426) pseudo_column ::= ROWTS */ - -1, /* (427) pseudo_column ::= TBNAME */ - -3, /* (428) pseudo_column ::= table_name NK_DOT TBNAME */ - -1, /* (429) pseudo_column ::= QSTART */ - -1, /* (430) pseudo_column ::= QEND */ - -1, /* (431) pseudo_column ::= QDURATION */ - -1, /* (432) pseudo_column ::= WSTART */ - -1, /* (433) pseudo_column ::= WEND */ - -1, /* (434) pseudo_column ::= WDURATION */ - -1, /* (435) pseudo_column ::= IROWTS */ - -1, /* (436) pseudo_column ::= ISFILLED */ - -1, /* (437) pseudo_column ::= QTAGS */ - -4, /* (438) function_expression ::= function_name NK_LP expression_list NK_RP */ - -4, /* (439) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - -6, /* (440) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - -1, /* (441) function_expression ::= literal_func */ - -3, /* (442) literal_func ::= noarg_func NK_LP NK_RP */ - -1, /* (443) literal_func ::= NOW */ - -1, /* (444) noarg_func ::= NOW */ - -1, /* (445) noarg_func ::= TODAY */ - -1, /* (446) noarg_func ::= TIMEZONE */ - -1, /* (447) noarg_func ::= DATABASE */ - -1, /* (448) noarg_func ::= CLIENT_VERSION */ - -1, /* (449) noarg_func ::= SERVER_VERSION */ - -1, /* (450) noarg_func ::= SERVER_STATUS */ - -1, /* (451) noarg_func ::= CURRENT_USER */ - -1, /* (452) noarg_func ::= USER */ - -1, /* (453) star_func ::= COUNT */ - -1, /* (454) star_func ::= FIRST */ - -1, /* (455) star_func ::= LAST */ - -1, /* (456) star_func ::= LAST_ROW */ - -1, /* (457) star_func_para_list ::= NK_STAR */ - -1, /* (458) star_func_para_list ::= other_para_list */ - -1, /* (459) other_para_list ::= star_func_para */ - -3, /* (460) other_para_list ::= other_para_list NK_COMMA star_func_para */ - -1, /* (461) star_func_para ::= expr_or_subquery */ - -3, /* (462) star_func_para ::= table_name NK_DOT NK_STAR */ - -4, /* (463) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - -5, /* (464) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - -1, /* (465) when_then_list ::= when_then_expr */ - -2, /* (466) when_then_list ::= when_then_list when_then_expr */ - -4, /* (467) when_then_expr ::= WHEN common_expression THEN common_expression */ - 0, /* (468) case_when_else_opt ::= */ - -2, /* (469) case_when_else_opt ::= ELSE common_expression */ - -3, /* (470) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - -5, /* (471) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - -6, /* (472) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - -3, /* (473) predicate ::= expr_or_subquery IS NULL */ - -4, /* (474) predicate ::= expr_or_subquery IS NOT NULL */ - -3, /* (475) predicate ::= expr_or_subquery in_op in_predicate_value */ - -1, /* (476) compare_op ::= NK_LT */ - -1, /* (477) compare_op ::= NK_GT */ - -1, /* (478) compare_op ::= NK_LE */ - -1, /* (479) compare_op ::= NK_GE */ - -1, /* (480) compare_op ::= NK_NE */ - -1, /* (481) compare_op ::= NK_EQ */ - -1, /* (482) compare_op ::= LIKE */ - -2, /* (483) compare_op ::= NOT LIKE */ - -1, /* (484) compare_op ::= MATCH */ - -1, /* (485) compare_op ::= NMATCH */ - -1, /* (486) compare_op ::= CONTAINS */ - -1, /* (487) in_op ::= IN */ - -2, /* (488) in_op ::= NOT IN */ - -3, /* (489) in_predicate_value ::= NK_LP literal_list NK_RP */ - -1, /* (490) boolean_value_expression ::= boolean_primary */ - -2, /* (491) boolean_value_expression ::= NOT boolean_primary */ - -3, /* (492) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - -3, /* (493) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - -1, /* (494) boolean_primary ::= predicate */ - -3, /* (495) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - -1, /* (496) common_expression ::= expr_or_subquery */ - -1, /* (497) common_expression ::= boolean_value_expression */ - 0, /* (498) from_clause_opt ::= */ - -2, /* (499) from_clause_opt ::= FROM table_reference_list */ - -1, /* (500) table_reference_list ::= table_reference */ - -3, /* (501) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - -1, /* (502) table_reference ::= table_primary */ - -1, /* (503) table_reference ::= joined_table */ - -2, /* (504) table_primary ::= table_name alias_opt */ - -4, /* (505) table_primary ::= db_name NK_DOT table_name alias_opt */ - -2, /* (506) table_primary ::= subquery alias_opt */ - -1, /* (507) table_primary ::= parenthesized_joined_table */ - 0, /* (508) alias_opt ::= */ - -1, /* (509) alias_opt ::= table_alias */ - -2, /* (510) alias_opt ::= AS table_alias */ - -3, /* (511) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - -3, /* (512) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - -6, /* (513) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 0, /* (514) join_type ::= */ - -1, /* (515) join_type ::= INNER */ - -12, /* (516) 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 */ - 0, /* (517) set_quantifier_opt ::= */ - -1, /* (518) set_quantifier_opt ::= DISTINCT */ - -1, /* (519) set_quantifier_opt ::= ALL */ - -1, /* (520) select_list ::= select_item */ - -3, /* (521) select_list ::= select_list NK_COMMA select_item */ - -1, /* (522) select_item ::= NK_STAR */ - -1, /* (523) select_item ::= common_expression */ - -2, /* (524) select_item ::= common_expression column_alias */ - -3, /* (525) select_item ::= common_expression AS column_alias */ - -3, /* (526) select_item ::= table_name NK_DOT NK_STAR */ - 0, /* (527) where_clause_opt ::= */ - -2, /* (528) where_clause_opt ::= WHERE search_condition */ - 0, /* (529) partition_by_clause_opt ::= */ - -3, /* (530) partition_by_clause_opt ::= PARTITION BY partition_list */ - -1, /* (531) partition_list ::= partition_item */ - -3, /* (532) partition_list ::= partition_list NK_COMMA partition_item */ - -1, /* (533) partition_item ::= expr_or_subquery */ - -2, /* (534) partition_item ::= expr_or_subquery column_alias */ - -3, /* (535) partition_item ::= expr_or_subquery AS column_alias */ - 0, /* (536) twindow_clause_opt ::= */ - -6, /* (537) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - -4, /* (538) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - -6, /* (539) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - -8, /* (540) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - -7, /* (541) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 0, /* (542) sliding_opt ::= */ - -4, /* (543) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 0, /* (544) fill_opt ::= */ - -4, /* (545) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - -6, /* (546) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - -6, /* (547) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - -1, /* (548) fill_mode ::= NONE */ - -1, /* (549) fill_mode ::= PREV */ - -1, /* (550) fill_mode ::= NULL */ - -1, /* (551) fill_mode ::= NULL_F */ - -1, /* (552) fill_mode ::= LINEAR */ - -1, /* (553) fill_mode ::= NEXT */ - 0, /* (554) group_by_clause_opt ::= */ - -3, /* (555) group_by_clause_opt ::= GROUP BY group_by_list */ - -1, /* (556) group_by_list ::= expr_or_subquery */ - -3, /* (557) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 0, /* (558) having_clause_opt ::= */ - -2, /* (559) having_clause_opt ::= HAVING search_condition */ - 0, /* (560) range_opt ::= */ - -6, /* (561) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - -4, /* (562) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 0, /* (563) every_opt ::= */ - -4, /* (564) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - -4, /* (565) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - -1, /* (566) query_simple ::= query_specification */ - -1, /* (567) query_simple ::= union_query_expression */ - -4, /* (568) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - -3, /* (569) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - -1, /* (570) query_simple_or_subquery ::= query_simple */ - -1, /* (571) query_simple_or_subquery ::= subquery */ - -1, /* (572) query_or_subquery ::= query_expression */ - -1, /* (573) query_or_subquery ::= subquery */ - 0, /* (574) order_by_clause_opt ::= */ - -3, /* (575) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 0, /* (576) slimit_clause_opt ::= */ - -2, /* (577) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - -4, /* (578) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - -4, /* (579) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 0, /* (580) limit_clause_opt ::= */ - -2, /* (581) limit_clause_opt ::= LIMIT NK_INTEGER */ - -4, /* (582) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - -4, /* (583) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - -3, /* (584) subquery ::= NK_LP query_expression NK_RP */ - -3, /* (585) subquery ::= NK_LP subquery NK_RP */ - -1, /* (586) search_condition ::= common_expression */ - -1, /* (587) sort_specification_list ::= sort_specification */ - -3, /* (588) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - -3, /* (589) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 0, /* (590) ordering_specification_opt ::= */ - -1, /* (591) ordering_specification_opt ::= ASC */ - -1, /* (592) ordering_specification_opt ::= DESC */ - 0, /* (593) null_ordering_opt ::= */ - -2, /* (594) null_ordering_opt ::= NULLS FIRST */ - -2, /* (595) null_ordering_opt ::= NULLS LAST */ + -1, /* (305) with_meta ::= AS */ + -3, /* (306) with_meta ::= WITH META AS */ + -3, /* (307) with_meta ::= ONLY META AS */ + -6, /* (308) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + -7, /* (309) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + -8, /* (310) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + -4, /* (311) cmd ::= DROP TOPIC exists_opt topic_name */ + -7, /* (312) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + -2, /* (313) cmd ::= DESC full_table_name */ + -2, /* (314) cmd ::= DESCRIBE full_table_name */ + -3, /* (315) cmd ::= RESET QUERY CACHE */ + -4, /* (316) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + -4, /* (317) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 0, /* (318) analyze_opt ::= */ + -1, /* (319) analyze_opt ::= ANALYZE */ + 0, /* (320) explain_options ::= */ + -3, /* (321) explain_options ::= explain_options VERBOSE NK_BOOL */ + -3, /* (322) explain_options ::= explain_options RATIO NK_FLOAT */ + -12, /* (323) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + -4, /* (324) cmd ::= DROP FUNCTION exists_opt function_name */ + 0, /* (325) agg_func_opt ::= */ + -1, /* (326) agg_func_opt ::= AGGREGATE */ + 0, /* (327) bufsize_opt ::= */ + -2, /* (328) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 0, /* (329) language_opt ::= */ + -2, /* (330) language_opt ::= LANGUAGE NK_STRING */ + 0, /* (331) or_replace_opt ::= */ + -2, /* (332) or_replace_opt ::= OR REPLACE */ + -12, /* (333) 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 */ + -4, /* (334) cmd ::= DROP STREAM exists_opt stream_name */ + -4, /* (335) cmd ::= PAUSE STREAM exists_opt stream_name */ + -5, /* (336) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 0, /* (337) col_list_opt ::= */ + -3, /* (338) col_list_opt ::= NK_LP col_name_list NK_RP */ + 0, /* (339) tag_def_or_ref_opt ::= */ + -1, /* (340) tag_def_or_ref_opt ::= tags_def */ + -4, /* (341) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 0, /* (342) stream_options ::= */ + -3, /* (343) stream_options ::= stream_options TRIGGER AT_ONCE */ + -3, /* (344) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + -4, /* (345) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + -3, /* (346) stream_options ::= stream_options WATERMARK duration_literal */ + -4, /* (347) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + -3, /* (348) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + -3, /* (349) stream_options ::= stream_options DELETE_MARK duration_literal */ + -4, /* (350) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 0, /* (351) subtable_opt ::= */ + -4, /* (352) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 0, /* (353) ignore_opt ::= */ + -2, /* (354) ignore_opt ::= IGNORE UNTREATED */ + -3, /* (355) cmd ::= KILL CONNECTION NK_INTEGER */ + -3, /* (356) cmd ::= KILL QUERY NK_STRING */ + -3, /* (357) cmd ::= KILL TRANSACTION NK_INTEGER */ + -2, /* (358) cmd ::= BALANCE VGROUP */ + -3, /* (359) cmd ::= BALANCE VGROUP LEADER */ + -4, /* (360) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + -4, /* (361) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + -3, /* (362) cmd ::= SPLIT VGROUP NK_INTEGER */ + -2, /* (363) dnode_list ::= DNODE NK_INTEGER */ + -3, /* (364) dnode_list ::= dnode_list DNODE NK_INTEGER */ + -4, /* (365) cmd ::= DELETE FROM full_table_name where_clause_opt */ + -1, /* (366) cmd ::= query_or_subquery */ + -1, /* (367) cmd ::= insert_query */ + -7, /* (368) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + -4, /* (369) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + -1, /* (370) literal ::= NK_INTEGER */ + -1, /* (371) literal ::= NK_FLOAT */ + -1, /* (372) literal ::= NK_STRING */ + -1, /* (373) literal ::= NK_BOOL */ + -2, /* (374) literal ::= TIMESTAMP NK_STRING */ + -1, /* (375) literal ::= duration_literal */ + -1, /* (376) literal ::= NULL */ + -1, /* (377) literal ::= NK_QUESTION */ + -1, /* (378) duration_literal ::= NK_VARIABLE */ + -1, /* (379) signed ::= NK_INTEGER */ + -2, /* (380) signed ::= NK_PLUS NK_INTEGER */ + -2, /* (381) signed ::= NK_MINUS NK_INTEGER */ + -1, /* (382) signed ::= NK_FLOAT */ + -2, /* (383) signed ::= NK_PLUS NK_FLOAT */ + -2, /* (384) signed ::= NK_MINUS NK_FLOAT */ + -1, /* (385) signed_literal ::= signed */ + -1, /* (386) signed_literal ::= NK_STRING */ + -1, /* (387) signed_literal ::= NK_BOOL */ + -2, /* (388) signed_literal ::= TIMESTAMP NK_STRING */ + -1, /* (389) signed_literal ::= duration_literal */ + -1, /* (390) signed_literal ::= NULL */ + -1, /* (391) signed_literal ::= literal_func */ + -1, /* (392) signed_literal ::= NK_QUESTION */ + -1, /* (393) literal_list ::= signed_literal */ + -3, /* (394) literal_list ::= literal_list NK_COMMA signed_literal */ + -1, /* (395) db_name ::= NK_ID */ + -1, /* (396) table_name ::= NK_ID */ + -1, /* (397) column_name ::= NK_ID */ + -1, /* (398) function_name ::= NK_ID */ + -1, /* (399) table_alias ::= NK_ID */ + -1, /* (400) column_alias ::= NK_ID */ + -1, /* (401) user_name ::= NK_ID */ + -1, /* (402) topic_name ::= NK_ID */ + -1, /* (403) stream_name ::= NK_ID */ + -1, /* (404) cgroup_name ::= NK_ID */ + -1, /* (405) index_name ::= NK_ID */ + -1, /* (406) expr_or_subquery ::= expression */ + -1, /* (407) expression ::= literal */ + -1, /* (408) expression ::= pseudo_column */ + -1, /* (409) expression ::= column_reference */ + -1, /* (410) expression ::= function_expression */ + -1, /* (411) expression ::= case_when_expression */ + -3, /* (412) expression ::= NK_LP expression NK_RP */ + -2, /* (413) expression ::= NK_PLUS expr_or_subquery */ + -2, /* (414) expression ::= NK_MINUS expr_or_subquery */ + -3, /* (415) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + -3, /* (416) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + -3, /* (417) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + -3, /* (418) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + -3, /* (419) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + -3, /* (420) expression ::= column_reference NK_ARROW NK_STRING */ + -3, /* (421) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + -3, /* (422) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + -1, /* (423) expression_list ::= expr_or_subquery */ + -3, /* (424) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + -1, /* (425) column_reference ::= column_name */ + -3, /* (426) column_reference ::= table_name NK_DOT column_name */ + -1, /* (427) pseudo_column ::= ROWTS */ + -1, /* (428) pseudo_column ::= TBNAME */ + -3, /* (429) pseudo_column ::= table_name NK_DOT TBNAME */ + -1, /* (430) pseudo_column ::= QSTART */ + -1, /* (431) pseudo_column ::= QEND */ + -1, /* (432) pseudo_column ::= QDURATION */ + -1, /* (433) pseudo_column ::= WSTART */ + -1, /* (434) pseudo_column ::= WEND */ + -1, /* (435) pseudo_column ::= WDURATION */ + -1, /* (436) pseudo_column ::= IROWTS */ + -1, /* (437) pseudo_column ::= ISFILLED */ + -1, /* (438) pseudo_column ::= QTAGS */ + -4, /* (439) function_expression ::= function_name NK_LP expression_list NK_RP */ + -4, /* (440) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + -6, /* (441) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + -1, /* (442) function_expression ::= literal_func */ + -3, /* (443) literal_func ::= noarg_func NK_LP NK_RP */ + -1, /* (444) literal_func ::= NOW */ + -1, /* (445) noarg_func ::= NOW */ + -1, /* (446) noarg_func ::= TODAY */ + -1, /* (447) noarg_func ::= TIMEZONE */ + -1, /* (448) noarg_func ::= DATABASE */ + -1, /* (449) noarg_func ::= CLIENT_VERSION */ + -1, /* (450) noarg_func ::= SERVER_VERSION */ + -1, /* (451) noarg_func ::= SERVER_STATUS */ + -1, /* (452) noarg_func ::= CURRENT_USER */ + -1, /* (453) noarg_func ::= USER */ + -1, /* (454) star_func ::= COUNT */ + -1, /* (455) star_func ::= FIRST */ + -1, /* (456) star_func ::= LAST */ + -1, /* (457) star_func ::= LAST_ROW */ + -1, /* (458) star_func_para_list ::= NK_STAR */ + -1, /* (459) star_func_para_list ::= other_para_list */ + -1, /* (460) other_para_list ::= star_func_para */ + -3, /* (461) other_para_list ::= other_para_list NK_COMMA star_func_para */ + -1, /* (462) star_func_para ::= expr_or_subquery */ + -3, /* (463) star_func_para ::= table_name NK_DOT NK_STAR */ + -4, /* (464) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + -5, /* (465) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + -1, /* (466) when_then_list ::= when_then_expr */ + -2, /* (467) when_then_list ::= when_then_list when_then_expr */ + -4, /* (468) when_then_expr ::= WHEN common_expression THEN common_expression */ + 0, /* (469) case_when_else_opt ::= */ + -2, /* (470) case_when_else_opt ::= ELSE common_expression */ + -3, /* (471) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + -5, /* (472) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + -6, /* (473) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + -3, /* (474) predicate ::= expr_or_subquery IS NULL */ + -4, /* (475) predicate ::= expr_or_subquery IS NOT NULL */ + -3, /* (476) predicate ::= expr_or_subquery in_op in_predicate_value */ + -1, /* (477) compare_op ::= NK_LT */ + -1, /* (478) compare_op ::= NK_GT */ + -1, /* (479) compare_op ::= NK_LE */ + -1, /* (480) compare_op ::= NK_GE */ + -1, /* (481) compare_op ::= NK_NE */ + -1, /* (482) compare_op ::= NK_EQ */ + -1, /* (483) compare_op ::= LIKE */ + -2, /* (484) compare_op ::= NOT LIKE */ + -1, /* (485) compare_op ::= MATCH */ + -1, /* (486) compare_op ::= NMATCH */ + -1, /* (487) compare_op ::= CONTAINS */ + -1, /* (488) in_op ::= IN */ + -2, /* (489) in_op ::= NOT IN */ + -3, /* (490) in_predicate_value ::= NK_LP literal_list NK_RP */ + -1, /* (491) boolean_value_expression ::= boolean_primary */ + -2, /* (492) boolean_value_expression ::= NOT boolean_primary */ + -3, /* (493) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + -3, /* (494) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + -1, /* (495) boolean_primary ::= predicate */ + -3, /* (496) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + -1, /* (497) common_expression ::= expr_or_subquery */ + -1, /* (498) common_expression ::= boolean_value_expression */ + 0, /* (499) from_clause_opt ::= */ + -2, /* (500) from_clause_opt ::= FROM table_reference_list */ + -1, /* (501) table_reference_list ::= table_reference */ + -3, /* (502) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + -1, /* (503) table_reference ::= table_primary */ + -1, /* (504) table_reference ::= joined_table */ + -2, /* (505) table_primary ::= table_name alias_opt */ + -4, /* (506) table_primary ::= db_name NK_DOT table_name alias_opt */ + -2, /* (507) table_primary ::= subquery alias_opt */ + -1, /* (508) table_primary ::= parenthesized_joined_table */ + 0, /* (509) alias_opt ::= */ + -1, /* (510) alias_opt ::= table_alias */ + -2, /* (511) alias_opt ::= AS table_alias */ + -3, /* (512) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + -3, /* (513) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + -6, /* (514) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 0, /* (515) join_type ::= */ + -1, /* (516) join_type ::= INNER */ + -12, /* (517) 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 */ + 0, /* (518) set_quantifier_opt ::= */ + -1, /* (519) set_quantifier_opt ::= DISTINCT */ + -1, /* (520) set_quantifier_opt ::= ALL */ + -1, /* (521) select_list ::= select_item */ + -3, /* (522) select_list ::= select_list NK_COMMA select_item */ + -1, /* (523) select_item ::= NK_STAR */ + -1, /* (524) select_item ::= common_expression */ + -2, /* (525) select_item ::= common_expression column_alias */ + -3, /* (526) select_item ::= common_expression AS column_alias */ + -3, /* (527) select_item ::= table_name NK_DOT NK_STAR */ + 0, /* (528) where_clause_opt ::= */ + -2, /* (529) where_clause_opt ::= WHERE search_condition */ + 0, /* (530) partition_by_clause_opt ::= */ + -3, /* (531) partition_by_clause_opt ::= PARTITION BY partition_list */ + -1, /* (532) partition_list ::= partition_item */ + -3, /* (533) partition_list ::= partition_list NK_COMMA partition_item */ + -1, /* (534) partition_item ::= expr_or_subquery */ + -2, /* (535) partition_item ::= expr_or_subquery column_alias */ + -3, /* (536) partition_item ::= expr_or_subquery AS column_alias */ + 0, /* (537) twindow_clause_opt ::= */ + -6, /* (538) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + -4, /* (539) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + -6, /* (540) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + -8, /* (541) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + -7, /* (542) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 0, /* (543) sliding_opt ::= */ + -4, /* (544) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 0, /* (545) fill_opt ::= */ + -4, /* (546) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + -6, /* (547) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + -6, /* (548) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + -1, /* (549) fill_mode ::= NONE */ + -1, /* (550) fill_mode ::= PREV */ + -1, /* (551) fill_mode ::= NULL */ + -1, /* (552) fill_mode ::= NULL_F */ + -1, /* (553) fill_mode ::= LINEAR */ + -1, /* (554) fill_mode ::= NEXT */ + 0, /* (555) group_by_clause_opt ::= */ + -3, /* (556) group_by_clause_opt ::= GROUP BY group_by_list */ + -1, /* (557) group_by_list ::= expr_or_subquery */ + -3, /* (558) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 0, /* (559) having_clause_opt ::= */ + -2, /* (560) having_clause_opt ::= HAVING search_condition */ + 0, /* (561) range_opt ::= */ + -6, /* (562) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + -4, /* (563) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 0, /* (564) every_opt ::= */ + -4, /* (565) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + -4, /* (566) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + -1, /* (567) query_simple ::= query_specification */ + -1, /* (568) query_simple ::= union_query_expression */ + -4, /* (569) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + -3, /* (570) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + -1, /* (571) query_simple_or_subquery ::= query_simple */ + -1, /* (572) query_simple_or_subquery ::= subquery */ + -1, /* (573) query_or_subquery ::= query_expression */ + -1, /* (574) query_or_subquery ::= subquery */ + 0, /* (575) order_by_clause_opt ::= */ + -3, /* (576) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 0, /* (577) slimit_clause_opt ::= */ + -2, /* (578) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + -4, /* (579) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + -4, /* (580) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 0, /* (581) limit_clause_opt ::= */ + -2, /* (582) limit_clause_opt ::= LIMIT NK_INTEGER */ + -4, /* (583) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + -4, /* (584) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + -3, /* (585) subquery ::= NK_LP query_expression NK_RP */ + -3, /* (586) subquery ::= NK_LP subquery NK_RP */ + -1, /* (587) search_condition ::= common_expression */ + -1, /* (588) sort_specification_list ::= sort_specification */ + -3, /* (589) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + -3, /* (590) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 0, /* (591) ordering_specification_opt ::= */ + -1, /* (592) ordering_specification_opt ::= ASC */ + -1, /* (593) ordering_specification_opt ::= DESC */ + 0, /* (594) null_ordering_opt ::= */ + -2, /* (595) null_ordering_opt ::= NULLS FIRST */ + -2, /* (596) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -4384,54 +4753,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -4446,11 +4767,11 @@ static YYACTIONTYPE yy_reduce( YYMINORTYPE yylhsminor; case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,338,&yymsp[0].minor); + yy_destructor(yypParser,339,&yymsp[0].minor); break; case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,339,&yymsp[0].minor); + yy_destructor(yypParser,340,&yymsp[0].minor); break; case 2: /* account_options ::= */ { } @@ -4464,20 +4785,20 @@ static YYACTIONTYPE yy_reduce( case 9: /* account_options ::= account_options USERS literal */ yytestcase(yyruleno==9); case 10: /* account_options ::= account_options CONNS literal */ yytestcase(yyruleno==10); case 11: /* account_options ::= account_options STATE literal */ yytestcase(yyruleno==11); -{ yy_destructor(yypParser,338,&yymsp[-2].minor); +{ yy_destructor(yypParser,339,&yymsp[-2].minor); { } - yy_destructor(yypParser,340,&yymsp[0].minor); + yy_destructor(yypParser,341,&yymsp[0].minor); } break; case 12: /* alter_account_options ::= alter_account_option */ -{ yy_destructor(yypParser,341,&yymsp[0].minor); +{ yy_destructor(yypParser,342,&yymsp[0].minor); { } } break; case 13: /* alter_account_options ::= alter_account_options alter_account_option */ -{ yy_destructor(yypParser,339,&yymsp[-1].minor); +{ yy_destructor(yypParser,340,&yymsp[-1].minor); { } - yy_destructor(yypParser,341,&yymsp[0].minor); + yy_destructor(yypParser,342,&yymsp[0].minor); } break; case 14: /* alter_account_option ::= PASS literal */ @@ -4491,113 +4812,113 @@ static YYACTIONTYPE yy_reduce( case 22: /* alter_account_option ::= CONNS literal */ yytestcase(yyruleno==22); case 23: /* alter_account_option ::= STATE literal */ yytestcase(yyruleno==23); { } - yy_destructor(yypParser,340,&yymsp[0].minor); + yy_destructor(yypParser,341,&yymsp[0].minor); break; case 24: /* cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ -{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy669, &yymsp[-1].minor.yy0, yymsp[0].minor.yy73); } +{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy371, &yymsp[-1].minor.yy0, yymsp[0].minor.yy475); } break; case 25: /* cmd ::= ALTER USER user_name PASS NK_STRING */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy669, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } break; case 26: /* cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy669, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } break; case 27: /* cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy669, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } break; case 28: /* cmd ::= DROP USER user_name */ -{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy669); } +{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy371); } break; case 29: /* sysinfo_opt ::= */ -{ yymsp[1].minor.yy73 = 1; } +{ yymsp[1].minor.yy475 = 1; } break; case 30: /* sysinfo_opt ::= SYSINFO NK_INTEGER */ -{ yymsp[-1].minor.yy73 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy475 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } break; case 31: /* cmd ::= GRANT privileges ON priv_level with_opt TO user_name */ -{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-5].minor.yy349, &yymsp[-3].minor.yy257, &yymsp[0].minor.yy669, yymsp[-2].minor.yy242); } +{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-5].minor.yy729, &yymsp[-3].minor.yy347, &yymsp[0].minor.yy371, yymsp[-2].minor.yy452); } break; case 32: /* cmd ::= REVOKE privileges ON priv_level with_opt FROM user_name */ -{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-5].minor.yy349, &yymsp[-3].minor.yy257, &yymsp[0].minor.yy669, yymsp[-2].minor.yy242); } +{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-5].minor.yy729, &yymsp[-3].minor.yy347, &yymsp[0].minor.yy371, yymsp[-2].minor.yy452); } break; case 33: /* privileges ::= ALL */ -{ yymsp[0].minor.yy349 = PRIVILEGE_TYPE_ALL; } +{ yymsp[0].minor.yy729 = PRIVILEGE_TYPE_ALL; } break; case 34: /* privileges ::= priv_type_list */ case 36: /* priv_type_list ::= priv_type */ yytestcase(yyruleno==36); -{ yylhsminor.yy349 = yymsp[0].minor.yy349; } - yymsp[0].minor.yy349 = yylhsminor.yy349; +{ yylhsminor.yy729 = yymsp[0].minor.yy729; } + yymsp[0].minor.yy729 = yylhsminor.yy729; break; case 35: /* privileges ::= SUBSCRIBE */ -{ yymsp[0].minor.yy349 = PRIVILEGE_TYPE_SUBSCRIBE; } +{ yymsp[0].minor.yy729 = PRIVILEGE_TYPE_SUBSCRIBE; } break; case 37: /* priv_type_list ::= priv_type_list NK_COMMA priv_type */ -{ yylhsminor.yy349 = yymsp[-2].minor.yy349 | yymsp[0].minor.yy349; } - yymsp[-2].minor.yy349 = yylhsminor.yy349; +{ yylhsminor.yy729 = yymsp[-2].minor.yy729 | yymsp[0].minor.yy729; } + yymsp[-2].minor.yy729 = yylhsminor.yy729; break; case 38: /* priv_type ::= READ */ -{ yymsp[0].minor.yy349 = PRIVILEGE_TYPE_READ; } +{ yymsp[0].minor.yy729 = PRIVILEGE_TYPE_READ; } break; case 39: /* priv_type ::= WRITE */ -{ yymsp[0].minor.yy349 = PRIVILEGE_TYPE_WRITE; } +{ yymsp[0].minor.yy729 = PRIVILEGE_TYPE_WRITE; } break; case 40: /* priv_level ::= NK_STAR NK_DOT NK_STAR */ -{ yylhsminor.yy257.first = yymsp[-2].minor.yy0; yylhsminor.yy257.second = yymsp[0].minor.yy0; } - yymsp[-2].minor.yy257 = yylhsminor.yy257; +{ yylhsminor.yy347.first = yymsp[-2].minor.yy0; yylhsminor.yy347.second = yymsp[0].minor.yy0; } + yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 41: /* priv_level ::= db_name NK_DOT NK_STAR */ -{ yylhsminor.yy257.first = yymsp[-2].minor.yy669; yylhsminor.yy257.second = yymsp[0].minor.yy0; } - yymsp[-2].minor.yy257 = yylhsminor.yy257; +{ yylhsminor.yy347.first = yymsp[-2].minor.yy371; yylhsminor.yy347.second = yymsp[0].minor.yy0; } + yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 42: /* priv_level ::= db_name NK_DOT table_name */ -{ yylhsminor.yy257.first = yymsp[-2].minor.yy669; yylhsminor.yy257.second = yymsp[0].minor.yy669; } - yymsp[-2].minor.yy257 = yylhsminor.yy257; +{ yylhsminor.yy347.first = yymsp[-2].minor.yy371; yylhsminor.yy347.second = yymsp[0].minor.yy371; } + yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 43: /* priv_level ::= topic_name */ -{ yylhsminor.yy257.first = yymsp[0].minor.yy669; yylhsminor.yy257.second = nil_token; } - yymsp[0].minor.yy257 = yylhsminor.yy257; +{ yylhsminor.yy347.first = yymsp[0].minor.yy371; yylhsminor.yy347.second = nil_token; } + yymsp[0].minor.yy347 = yylhsminor.yy347; break; case 44: /* with_opt ::= */ case 144: /* start_opt ::= */ yytestcase(yyruleno==144); case 148: /* end_opt ::= */ yytestcase(yyruleno==148); case 273: /* like_pattern_opt ::= */ yytestcase(yyruleno==273); - case 350: /* subtable_opt ::= */ yytestcase(yyruleno==350); - case 468: /* case_when_else_opt ::= */ yytestcase(yyruleno==468); - case 498: /* from_clause_opt ::= */ yytestcase(yyruleno==498); - case 527: /* where_clause_opt ::= */ yytestcase(yyruleno==527); - case 536: /* twindow_clause_opt ::= */ yytestcase(yyruleno==536); - case 542: /* sliding_opt ::= */ yytestcase(yyruleno==542); - case 544: /* fill_opt ::= */ yytestcase(yyruleno==544); - case 558: /* having_clause_opt ::= */ yytestcase(yyruleno==558); - case 560: /* range_opt ::= */ yytestcase(yyruleno==560); - case 563: /* every_opt ::= */ yytestcase(yyruleno==563); - case 576: /* slimit_clause_opt ::= */ yytestcase(yyruleno==576); - case 580: /* limit_clause_opt ::= */ yytestcase(yyruleno==580); -{ yymsp[1].minor.yy242 = NULL; } + case 351: /* subtable_opt ::= */ yytestcase(yyruleno==351); + case 469: /* case_when_else_opt ::= */ yytestcase(yyruleno==469); + case 499: /* from_clause_opt ::= */ yytestcase(yyruleno==499); + case 528: /* where_clause_opt ::= */ yytestcase(yyruleno==528); + case 537: /* twindow_clause_opt ::= */ yytestcase(yyruleno==537); + case 543: /* sliding_opt ::= */ yytestcase(yyruleno==543); + case 545: /* fill_opt ::= */ yytestcase(yyruleno==545); + case 559: /* having_clause_opt ::= */ yytestcase(yyruleno==559); + case 561: /* range_opt ::= */ yytestcase(yyruleno==561); + case 564: /* every_opt ::= */ yytestcase(yyruleno==564); + case 577: /* slimit_clause_opt ::= */ yytestcase(yyruleno==577); + case 581: /* limit_clause_opt ::= */ yytestcase(yyruleno==581); +{ yymsp[1].minor.yy452 = NULL; } break; case 45: /* with_opt ::= WITH search_condition */ - case 499: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==499); - case 528: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==528); - case 559: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==559); -{ yymsp[-1].minor.yy242 = yymsp[0].minor.yy242; } + case 500: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==500); + case 529: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==529); + case 560: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==560); +{ yymsp[-1].minor.yy452 = yymsp[0].minor.yy452; } break; case 46: /* cmd ::= CREATE DNODE dnode_endpoint */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy669, NULL); } +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy371, NULL); } break; case 47: /* cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0); } break; case 48: /* cmd ::= DROP DNODE NK_INTEGER force_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy777, false); } +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy667, false); } break; case 49: /* cmd ::= DROP DNODE dnode_endpoint force_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy669, yymsp[0].minor.yy777, false); } +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy667, false); } break; case 50: /* cmd ::= DROP DNODE NK_INTEGER unsafe_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, false, yymsp[0].minor.yy777); } +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, false, yymsp[0].minor.yy667); } break; case 51: /* cmd ::= DROP DNODE dnode_endpoint unsafe_opt */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy669, false, yymsp[0].minor.yy777); } +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy371, false, yymsp[0].minor.yy667); } break; case 52: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, NULL); } @@ -4621,49 +4942,49 @@ static YYACTIONTYPE yy_reduce( case 298: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==298); case 299: /* sma_func_name ::= LAST */ yytestcase(yyruleno==299); case 300: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==300); - case 394: /* db_name ::= NK_ID */ yytestcase(yyruleno==394); - case 395: /* table_name ::= NK_ID */ yytestcase(yyruleno==395); - case 396: /* column_name ::= NK_ID */ yytestcase(yyruleno==396); - case 397: /* function_name ::= NK_ID */ yytestcase(yyruleno==397); - case 398: /* table_alias ::= NK_ID */ yytestcase(yyruleno==398); - case 399: /* column_alias ::= NK_ID */ yytestcase(yyruleno==399); - case 400: /* user_name ::= NK_ID */ yytestcase(yyruleno==400); - case 401: /* topic_name ::= NK_ID */ yytestcase(yyruleno==401); - case 402: /* stream_name ::= NK_ID */ yytestcase(yyruleno==402); - case 403: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==403); - case 404: /* index_name ::= NK_ID */ yytestcase(yyruleno==404); - case 444: /* noarg_func ::= NOW */ yytestcase(yyruleno==444); - case 445: /* noarg_func ::= TODAY */ yytestcase(yyruleno==445); - case 446: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==446); - case 447: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==447); - case 448: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==448); - case 449: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==449); - case 450: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==450); - case 451: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==451); - case 452: /* noarg_func ::= USER */ yytestcase(yyruleno==452); - case 453: /* star_func ::= COUNT */ yytestcase(yyruleno==453); - case 454: /* star_func ::= FIRST */ yytestcase(yyruleno==454); - case 455: /* star_func ::= LAST */ yytestcase(yyruleno==455); - case 456: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==456); -{ yylhsminor.yy669 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy669 = yylhsminor.yy669; + case 395: /* db_name ::= NK_ID */ yytestcase(yyruleno==395); + case 396: /* table_name ::= NK_ID */ yytestcase(yyruleno==396); + case 397: /* column_name ::= NK_ID */ yytestcase(yyruleno==397); + case 398: /* function_name ::= NK_ID */ yytestcase(yyruleno==398); + case 399: /* table_alias ::= NK_ID */ yytestcase(yyruleno==399); + case 400: /* column_alias ::= NK_ID */ yytestcase(yyruleno==400); + case 401: /* user_name ::= NK_ID */ yytestcase(yyruleno==401); + case 402: /* topic_name ::= NK_ID */ yytestcase(yyruleno==402); + case 403: /* stream_name ::= NK_ID */ yytestcase(yyruleno==403); + case 404: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==404); + case 405: /* index_name ::= NK_ID */ yytestcase(yyruleno==405); + case 445: /* noarg_func ::= NOW */ yytestcase(yyruleno==445); + case 446: /* noarg_func ::= TODAY */ yytestcase(yyruleno==446); + case 447: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==447); + case 448: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==448); + case 449: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==449); + case 450: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==450); + case 451: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==451); + case 452: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==452); + case 453: /* noarg_func ::= USER */ yytestcase(yyruleno==453); + case 454: /* star_func ::= COUNT */ yytestcase(yyruleno==454); + case 455: /* star_func ::= FIRST */ yytestcase(yyruleno==455); + case 456: /* star_func ::= LAST */ yytestcase(yyruleno==456); + case 457: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==457); +{ yylhsminor.yy371 = yymsp[0].minor.yy0; } + yymsp[0].minor.yy371 = yylhsminor.yy371; break; case 60: /* force_opt ::= */ case 84: /* not_exists_opt ::= */ yytestcase(yyruleno==84); case 86: /* exists_opt ::= */ yytestcase(yyruleno==86); - case 317: /* analyze_opt ::= */ yytestcase(yyruleno==317); - case 324: /* agg_func_opt ::= */ yytestcase(yyruleno==324); - case 330: /* or_replace_opt ::= */ yytestcase(yyruleno==330); - case 352: /* ignore_opt ::= */ yytestcase(yyruleno==352); - case 517: /* set_quantifier_opt ::= */ yytestcase(yyruleno==517); -{ yymsp[1].minor.yy777 = false; } + case 318: /* analyze_opt ::= */ yytestcase(yyruleno==318); + case 325: /* agg_func_opt ::= */ yytestcase(yyruleno==325); + case 331: /* or_replace_opt ::= */ yytestcase(yyruleno==331); + case 353: /* ignore_opt ::= */ yytestcase(yyruleno==353); + case 518: /* set_quantifier_opt ::= */ yytestcase(yyruleno==518); +{ yymsp[1].minor.yy667 = false; } break; case 61: /* force_opt ::= FORCE */ case 62: /* unsafe_opt ::= UNSAFE */ yytestcase(yyruleno==62); - case 318: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==318); - case 325: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==325); - case 518: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==518); -{ yymsp[0].minor.yy777 = true; } + case 319: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==319); + case 326: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==326); + case 519: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==519); +{ yymsp[0].minor.yy667 = true; } break; case 63: /* cmd ::= ALTER LOCAL NK_STRING */ { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[0].minor.yy0, NULL); } @@ -4705,234 +5026,234 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_VNODE_STMT, &yymsp[0].minor.yy0); } break; case 76: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ -{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy777, &yymsp[-1].minor.yy669, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy667, &yymsp[-1].minor.yy371, yymsp[0].minor.yy452); } break; case 77: /* cmd ::= DROP DATABASE exists_opt db_name */ -{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } +{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; case 78: /* cmd ::= USE db_name */ -{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy669); } +{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } break; case 79: /* cmd ::= ALTER DATABASE db_name alter_db_options */ -{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy669, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy452); } break; case 80: /* cmd ::= FLUSH DATABASE db_name */ -{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy669); } +{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } break; case 81: /* cmd ::= TRIM DATABASE db_name speed_opt */ -{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[-1].minor.yy669, yymsp[0].minor.yy120); } +{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy416); } break; case 82: /* cmd ::= COMPACT DATABASE db_name start_opt end_opt */ -{ pCxt->pRootNode = createCompactStmt(pCxt, &yymsp[-2].minor.yy669, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createCompactStmt(pCxt, &yymsp[-2].minor.yy371, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; case 83: /* not_exists_opt ::= IF NOT EXISTS */ -{ yymsp[-2].minor.yy777 = true; } +{ yymsp[-2].minor.yy667 = true; } break; case 85: /* exists_opt ::= IF EXISTS */ - case 331: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==331); - case 353: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==353); -{ yymsp[-1].minor.yy777 = true; } + case 332: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==332); + case 354: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==354); +{ yymsp[-1].minor.yy667 = true; } break; case 87: /* db_options ::= */ -{ yymsp[1].minor.yy242 = createDefaultDatabaseOptions(pCxt); } +{ yymsp[1].minor.yy452 = createDefaultDatabaseOptions(pCxt); } break; case 88: /* db_options ::= db_options BUFFER NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 89: /* db_options ::= db_options CACHEMODEL NK_STRING */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_CACHEMODEL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_CACHEMODEL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 90: /* db_options ::= db_options CACHESIZE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_CACHESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_CACHESIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 91: /* db_options ::= db_options COMP NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_COMP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_COMP, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 92: /* db_options ::= db_options DURATION NK_INTEGER */ case 93: /* db_options ::= db_options DURATION NK_VARIABLE */ yytestcase(yyruleno==93); -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 94: /* db_options ::= db_options MAXROWS NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 95: /* db_options ::= db_options MINROWS NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 96: /* db_options ::= db_options KEEP integer_list */ case 97: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==97); -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_KEEP, yymsp[0].minor.yy174); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_KEEP, yymsp[0].minor.yy812); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 98: /* db_options ::= db_options PAGES NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 99: /* db_options ::= db_options PAGESIZE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 100: /* db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_TSDB_PAGESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TSDB_PAGESIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 101: /* db_options ::= db_options PRECISION NK_STRING */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 102: /* db_options ::= db_options REPLICA NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 103: /* db_options ::= db_options VGROUPS NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 104: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 105: /* db_options ::= db_options RETENTIONS retention_list */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_RETENTIONS, yymsp[0].minor.yy174); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_RETENTIONS, yymsp[0].minor.yy812); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 106: /* db_options ::= db_options SCHEMALESS NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 107: /* db_options ::= db_options WAL_LEVEL NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_WAL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 108: /* db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 109: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_WAL_RETENTION_PERIOD, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_RETENTION_PERIOD, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 110: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-3].minor.yy242, DB_OPTION_WAL_RETENTION_PERIOD, &t); + yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-3].minor.yy452, DB_OPTION_WAL_RETENTION_PERIOD, &t); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 111: /* db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_WAL_RETENTION_SIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_RETENTION_SIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 112: /* db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-3].minor.yy242, DB_OPTION_WAL_RETENTION_SIZE, &t); + yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-3].minor.yy452, DB_OPTION_WAL_RETENTION_SIZE, &t); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 113: /* db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_WAL_ROLL_PERIOD, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_ROLL_PERIOD, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 114: /* db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_WAL_SEGMENT_SIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_SEGMENT_SIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 115: /* db_options ::= db_options STT_TRIGGER NK_INTEGER */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 116: /* db_options ::= db_options TABLE_PREFIX signed */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy242); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy452); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 117: /* db_options ::= db_options TABLE_SUFFIX signed */ -{ yylhsminor.yy242 = setDatabaseOption(pCxt, yymsp[-2].minor.yy242, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy242); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy452); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 118: /* alter_db_options ::= alter_db_option */ -{ yylhsminor.yy242 = createAlterDatabaseOptions(pCxt); yylhsminor.yy242 = setAlterDatabaseOption(pCxt, yylhsminor.yy242, &yymsp[0].minor.yy535); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterDatabaseOptions(pCxt); yylhsminor.yy452 = setAlterDatabaseOption(pCxt, yylhsminor.yy452, &yymsp[0].minor.yy365); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 119: /* alter_db_options ::= alter_db_options alter_db_option */ -{ yylhsminor.yy242 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy242, &yymsp[0].minor.yy535); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy452, &yymsp[0].minor.yy365); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 120: /* alter_db_option ::= BUFFER NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 121: /* alter_db_option ::= CACHEMODEL NK_STRING */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_CACHEMODEL; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_CACHEMODEL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 122: /* alter_db_option ::= CACHESIZE NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_CACHESIZE; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_CACHESIZE; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 123: /* alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 124: /* alter_db_option ::= KEEP integer_list */ case 125: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==125); -{ yymsp[-1].minor.yy535.type = DB_OPTION_KEEP; yymsp[-1].minor.yy535.pList = yymsp[0].minor.yy174; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_KEEP; yymsp[-1].minor.yy365.pList = yymsp[0].minor.yy812; } break; case 126: /* alter_db_option ::= PAGES NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_PAGES; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_PAGES; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 127: /* alter_db_option ::= REPLICA NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 128: /* alter_db_option ::= WAL_LEVEL NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_WAL; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_WAL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 129: /* alter_db_option ::= STT_TRIGGER NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_STT_TRIGGER; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_STT_TRIGGER; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 130: /* alter_db_option ::= MINROWS NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_MINROWS; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_MINROWS; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 131: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 132: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yymsp[-2].minor.yy535.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-2].minor.yy535.val = t; + yymsp[-2].minor.yy365.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-2].minor.yy365.val = t; } break; case 133: /* alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 134: /* alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yymsp[-2].minor.yy535.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-2].minor.yy535.val = t; + yymsp[-2].minor.yy365.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-2].minor.yy365.val = t; } break; case 135: /* integer_list ::= NK_INTEGER */ -{ yylhsminor.yy174 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy174 = yylhsminor.yy174; +{ yylhsminor.yy812 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 136: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ - case 363: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==363); -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-2].minor.yy174, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy174 = yylhsminor.yy174; + case 364: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==364); +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 137: /* variable_list ::= NK_VARIABLE */ -{ yylhsminor.yy174 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy174 = yylhsminor.yy174; +{ yylhsminor.yy812 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 138: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */ -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-2].minor.yy174, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy174 = yylhsminor.yy174; +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 139: /* retention_list ::= retention */ case 169: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==169); @@ -4942,14 +5263,14 @@ static YYACTIONTYPE yy_reduce( case 228: /* col_name_list ::= col_name */ yytestcase(yyruleno==228); case 279: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==279); case 293: /* func_list ::= func */ yytestcase(yyruleno==293); - case 392: /* literal_list ::= signed_literal */ yytestcase(yyruleno==392); - case 459: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==459); - case 465: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==465); - case 520: /* select_list ::= select_item */ yytestcase(yyruleno==520); - case 531: /* partition_list ::= partition_item */ yytestcase(yyruleno==531); - case 587: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==587); -{ yylhsminor.yy174 = createNodeList(pCxt, yymsp[0].minor.yy242); } - yymsp[0].minor.yy174 = yylhsminor.yy174; + case 393: /* literal_list ::= signed_literal */ yytestcase(yyruleno==393); + case 460: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==460); + case 466: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==466); + case 521: /* select_list ::= select_item */ yytestcase(yyruleno==521); + case 532: /* partition_list ::= partition_item */ yytestcase(yyruleno==532); + case 588: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==588); +{ yylhsminor.yy812 = createNodeList(pCxt, yymsp[0].minor.yy452); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 140: /* retention_list ::= retention_list NK_COMMA retention */ case 173: /* multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ yytestcase(yyruleno==173); @@ -4958,287 +5279,287 @@ static YYACTIONTYPE yy_reduce( case 229: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==229); case 280: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==280); case 294: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==294); - case 393: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==393); - case 460: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==460); - case 521: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==521); - case 532: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==532); - case 588: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==588); -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-2].minor.yy174, yymsp[0].minor.yy242); } - yymsp[-2].minor.yy174 = yylhsminor.yy174; + case 394: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==394); + case 461: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==461); + case 522: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==522); + case 533: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==533); + case 589: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==589); +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } + yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 141: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ -{ yylhsminor.yy242 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 142: /* speed_opt ::= */ - case 326: /* bufsize_opt ::= */ yytestcase(yyruleno==326); -{ yymsp[1].minor.yy120 = 0; } + case 327: /* bufsize_opt ::= */ yytestcase(yyruleno==327); +{ yymsp[1].minor.yy416 = 0; } break; case 143: /* speed_opt ::= MAX_SPEED NK_INTEGER */ - case 327: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==327); -{ yymsp[-1].minor.yy120 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } + case 328: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==328); +{ yymsp[-1].minor.yy416 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } break; case 145: /* start_opt ::= START WITH NK_INTEGER */ case 149: /* end_opt ::= END WITH NK_INTEGER */ yytestcase(yyruleno==149); -{ yymsp[-2].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } +{ yymsp[-2].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } break; case 146: /* start_opt ::= START WITH NK_STRING */ case 150: /* end_opt ::= END WITH NK_STRING */ yytestcase(yyruleno==150); -{ yymsp[-2].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } +{ yymsp[-2].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; case 147: /* start_opt ::= START WITH TIMESTAMP NK_STRING */ case 151: /* end_opt ::= END WITH TIMESTAMP NK_STRING */ yytestcase(yyruleno==151); -{ yymsp[-3].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } +{ yymsp[-3].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; case 152: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ case 154: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==154); -{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy777, yymsp[-5].minor.yy242, yymsp[-3].minor.yy174, yymsp[-1].minor.yy174, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy667, yymsp[-5].minor.yy452, yymsp[-3].minor.yy812, yymsp[-1].minor.yy812, yymsp[0].minor.yy452); } break; case 153: /* cmd ::= CREATE TABLE multi_create_clause */ -{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy174); } +{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy812); } break; case 155: /* cmd ::= DROP TABLE multi_drop_clause */ -{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy174); } +{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy812); } break; case 156: /* cmd ::= DROP STABLE exists_opt full_table_name */ -{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy777, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } break; case 157: /* cmd ::= ALTER TABLE alter_table_clause */ - case 365: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==365); - case 366: /* cmd ::= insert_query */ yytestcase(yyruleno==366); -{ pCxt->pRootNode = yymsp[0].minor.yy242; } + case 366: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==366); + case 367: /* cmd ::= insert_query */ yytestcase(yyruleno==367); +{ pCxt->pRootNode = yymsp[0].minor.yy452; } break; case 158: /* cmd ::= ALTER STABLE alter_table_clause */ -{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy242); } +{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy452); } break; case 159: /* alter_table_clause ::= full_table_name alter_table_options */ -{ yylhsminor.yy242 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 160: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ -{ yylhsminor.yy242 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy669, yymsp[0].minor.yy794); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 161: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ -{ yylhsminor.yy242 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy242, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy669); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy371); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 162: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ -{ yylhsminor.yy242 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy669, yymsp[0].minor.yy794); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 163: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ -{ yylhsminor.yy242 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy669, &yymsp[0].minor.yy669); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 164: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ -{ yylhsminor.yy242 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy669, yymsp[0].minor.yy794); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 165: /* alter_table_clause ::= full_table_name DROP TAG column_name */ -{ yylhsminor.yy242 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy242, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy669); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy371); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 166: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ -{ yylhsminor.yy242 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy669, yymsp[0].minor.yy794); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 167: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ -{ yylhsminor.yy242 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy242, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy669, &yymsp[0].minor.yy669); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 168: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ -{ yylhsminor.yy242 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy242, &yymsp[-2].minor.yy669, yymsp[0].minor.yy242); } - yymsp[-5].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy452, &yymsp[-2].minor.yy371, yymsp[0].minor.yy452); } + yymsp[-5].minor.yy452 = yylhsminor.yy452; break; case 170: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ - case 466: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==466); -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-1].minor.yy174, yymsp[0].minor.yy242); } - yymsp[-1].minor.yy174 = yylhsminor.yy174; + case 467: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==467); +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-1].minor.yy812, yymsp[0].minor.yy452); } + yymsp[-1].minor.yy812 = yylhsminor.yy812; break; case 171: /* 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.yy242 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy777, yymsp[-8].minor.yy242, yymsp[-6].minor.yy242, yymsp[-5].minor.yy174, yymsp[-2].minor.yy174, yymsp[0].minor.yy242); } - yymsp[-9].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy667, yymsp[-8].minor.yy452, yymsp[-6].minor.yy452, yymsp[-5].minor.yy812, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } + yymsp[-9].minor.yy452 = yylhsminor.yy452; break; case 174: /* drop_table_clause ::= exists_opt full_table_name */ -{ yylhsminor.yy242 = createDropTableClause(pCxt, yymsp[-1].minor.yy777, yymsp[0].minor.yy242); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createDropTableClause(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 175: /* specific_cols_opt ::= */ case 206: /* tags_def_opt ::= */ yytestcase(yyruleno==206); case 278: /* tag_list_opt ::= */ yytestcase(yyruleno==278); - case 336: /* col_list_opt ::= */ yytestcase(yyruleno==336); - case 338: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==338); - case 529: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==529); - case 554: /* group_by_clause_opt ::= */ yytestcase(yyruleno==554); - case 574: /* order_by_clause_opt ::= */ yytestcase(yyruleno==574); -{ yymsp[1].minor.yy174 = NULL; } + case 337: /* col_list_opt ::= */ yytestcase(yyruleno==337); + case 339: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==339); + case 530: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==530); + case 555: /* group_by_clause_opt ::= */ yytestcase(yyruleno==555); + case 575: /* order_by_clause_opt ::= */ yytestcase(yyruleno==575); +{ yymsp[1].minor.yy812 = NULL; } break; case 176: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ - case 337: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==337); -{ yymsp[-2].minor.yy174 = yymsp[-1].minor.yy174; } + case 338: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==338); +{ yymsp[-2].minor.yy812 = yymsp[-1].minor.yy812; } break; case 177: /* full_table_name ::= table_name */ -{ yylhsminor.yy242 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy669, NULL); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy371, NULL); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 178: /* full_table_name ::= db_name NK_DOT table_name */ -{ yylhsminor.yy242 = createRealTableNode(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy669, NULL); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createRealTableNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371, NULL); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 181: /* column_def ::= column_name type_name */ -{ yylhsminor.yy242 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy669, yymsp[0].minor.yy794, NULL); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310, NULL); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 182: /* type_name ::= BOOL */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_BOOL); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BOOL); } break; case 183: /* type_name ::= TINYINT */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_TINYINT); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TINYINT); } break; case 184: /* type_name ::= SMALLINT */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_SMALLINT); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_SMALLINT); } break; case 185: /* type_name ::= INT */ case 186: /* type_name ::= INTEGER */ yytestcase(yyruleno==186); -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_INT); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_INT); } break; case 187: /* type_name ::= BIGINT */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_BIGINT); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BIGINT); } break; case 188: /* type_name ::= FLOAT */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_FLOAT); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_FLOAT); } break; case 189: /* type_name ::= DOUBLE */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_DOUBLE); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DOUBLE); } break; case 190: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } break; case 191: /* type_name ::= TIMESTAMP */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } break; case 192: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } break; case 193: /* type_name ::= TINYINT UNSIGNED */ -{ yymsp[-1].minor.yy794 = createDataType(TSDB_DATA_TYPE_UTINYINT); } +{ yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UTINYINT); } break; case 194: /* type_name ::= SMALLINT UNSIGNED */ -{ yymsp[-1].minor.yy794 = createDataType(TSDB_DATA_TYPE_USMALLINT); } +{ yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_USMALLINT); } break; case 195: /* type_name ::= INT UNSIGNED */ -{ yymsp[-1].minor.yy794 = createDataType(TSDB_DATA_TYPE_UINT); } +{ yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UINT); } break; case 196: /* type_name ::= BIGINT UNSIGNED */ -{ yymsp[-1].minor.yy794 = createDataType(TSDB_DATA_TYPE_UBIGINT); } +{ yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UBIGINT); } break; case 197: /* type_name ::= JSON */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_JSON); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_JSON); } break; case 198: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } break; case 199: /* type_name ::= MEDIUMBLOB */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } break; case 200: /* type_name ::= BLOB */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_BLOB); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BLOB); } break; case 201: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } break; case 202: /* type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createVarLenDataType(TSDB_DATA_TYPE_GEOMETRY, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_GEOMETRY, &yymsp[-1].minor.yy0); } break; case 203: /* type_name ::= DECIMAL */ -{ yymsp[0].minor.yy794 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 204: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy794 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[-3].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 205: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ -{ yymsp[-5].minor.yy794 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[-5].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 207: /* tags_def_opt ::= tags_def */ - case 339: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==339); - case 458: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==458); -{ yylhsminor.yy174 = yymsp[0].minor.yy174; } - yymsp[0].minor.yy174 = yylhsminor.yy174; + case 340: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==340); + case 459: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==459); +{ yylhsminor.yy812 = yymsp[0].minor.yy812; } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 208: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ - case 340: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==340); -{ yymsp[-3].minor.yy174 = yymsp[-1].minor.yy174; } + case 341: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==341); +{ yymsp[-3].minor.yy812 = yymsp[-1].minor.yy812; } break; case 209: /* table_options ::= */ -{ yymsp[1].minor.yy242 = createDefaultTableOptions(pCxt); } +{ yymsp[1].minor.yy452 = createDefaultTableOptions(pCxt); } break; case 210: /* table_options ::= table_options COMMENT NK_STRING */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-2].minor.yy242, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 211: /* table_options ::= table_options MAX_DELAY duration_list */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-2].minor.yy242, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy174); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy812); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 212: /* table_options ::= table_options WATERMARK duration_list */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-2].minor.yy242, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy174); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy812); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 213: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-4].minor.yy242, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy174); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy812); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 214: /* table_options ::= table_options TTL NK_INTEGER */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-2].minor.yy242, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 215: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-4].minor.yy242, TABLE_OPTION_SMA, yymsp[-1].minor.yy174); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_SMA, yymsp[-1].minor.yy812); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 216: /* table_options ::= table_options DELETE_MARK duration_list */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-2].minor.yy242, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy174); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy812); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 217: /* alter_table_options ::= alter_table_option */ -{ yylhsminor.yy242 = createAlterTableOptions(pCxt); yylhsminor.yy242 = setTableOption(pCxt, yylhsminor.yy242, yymsp[0].minor.yy535.type, &yymsp[0].minor.yy535.val); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createAlterTableOptions(pCxt); yylhsminor.yy452 = setTableOption(pCxt, yylhsminor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 218: /* alter_table_options ::= alter_table_options alter_table_option */ -{ yylhsminor.yy242 = setTableOption(pCxt, yymsp[-1].minor.yy242, yymsp[0].minor.yy535.type, &yymsp[0].minor.yy535.val); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setTableOption(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 219: /* alter_table_option ::= COMMENT NK_STRING */ -{ yymsp[-1].minor.yy535.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 220: /* alter_table_option ::= TTL NK_INTEGER */ -{ yymsp[-1].minor.yy535.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy535.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy365.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } break; case 221: /* duration_list ::= duration_literal */ - case 422: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==422); -{ yylhsminor.yy174 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } - yymsp[0].minor.yy174 = yylhsminor.yy174; + case 423: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==423); +{ yylhsminor.yy812 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 222: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 423: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==423); -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-2].minor.yy174, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } - yymsp[-2].minor.yy174 = yylhsminor.yy174; + case 424: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==424); +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } + yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 225: /* rollup_func_name ::= function_name */ -{ yylhsminor.yy242 = createFunctionNode(pCxt, &yymsp[0].minor.yy669, NULL); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy371, NULL); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 226: /* rollup_func_name ::= FIRST */ case 227: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==227); case 282: /* tag_item ::= QTAGS */ yytestcase(yyruleno==282); -{ yylhsminor.yy242 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 230: /* col_name ::= column_name */ case 283: /* tag_item ::= column_name */ yytestcase(yyruleno==283); -{ yylhsminor.yy242 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy669); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 231: /* cmd ::= SHOW DNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT); } @@ -5253,13 +5574,13 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); } break; case 235: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } break; case 236: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } break; case 237: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy242, NULL, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy452, NULL, OP_TYPE_LIKE); } break; case 238: /* cmd ::= SHOW MNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } @@ -5271,7 +5592,7 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); } break; case 241: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy242, yymsp[-1].minor.yy242, OP_TYPE_EQUAL); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } break; case 242: /* cmd ::= SHOW STREAMS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); } @@ -5290,13 +5611,13 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCES_STMT); } break; case 248: /* cmd ::= SHOW CREATE DATABASE db_name */ -{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy669); } +{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } break; case 249: /* cmd ::= SHOW CREATE TABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy452); } break; case 250: /* cmd ::= SHOW CREATE STABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy452); } break; case 251: /* cmd ::= SHOW QUERIES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } @@ -5315,7 +5636,7 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } break; case 257: /* 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.yy242); } +{ pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-2].minor.yy0), yymsp[0].minor.yy452); } break; case 258: /* cmd ::= SHOW BNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } @@ -5330,7 +5651,7 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } break; case 262: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ -{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy452); } break; case 263: /* cmd ::= SHOW CONSUMERS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); } @@ -5339,10 +5660,10 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); } break; case 265: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy242, yymsp[-1].minor.yy242, OP_TYPE_EQUAL); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } break; case 266: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy242, yymsp[0].minor.yy242, yymsp[-3].minor.yy174); } +{ pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452, yymsp[-3].minor.yy812); } break; case 267: /* cmd ::= SHOW VNODES NK_INTEGER */ { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0), NULL); } @@ -5351,773 +5672,776 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, createValueNode(pCxt, TSDB_DATA_TYPE_VARCHAR, &yymsp[0].minor.yy0)); } break; case 269: /* cmd ::= SHOW db_name_cond_opt ALIVE */ -{ pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy242, QUERY_NODE_SHOW_DB_ALIVE_STMT); } +{ pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy452, QUERY_NODE_SHOW_DB_ALIVE_STMT); } break; case 270: /* cmd ::= SHOW CLUSTER ALIVE */ { pCxt->pRootNode = createShowAliveStmt(pCxt, NULL, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT); } break; case 271: /* db_name_cond_opt ::= */ case 276: /* from_db_opt ::= */ yytestcase(yyruleno==276); -{ yymsp[1].minor.yy242 = createDefaultDatabaseCondValue(pCxt); } +{ yymsp[1].minor.yy452 = createDefaultDatabaseCondValue(pCxt); } break; case 272: /* db_name_cond_opt ::= db_name NK_DOT */ -{ yylhsminor.yy242 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy669); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy371); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 274: /* like_pattern_opt ::= LIKE NK_STRING */ -{ yymsp[-1].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } +{ yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } break; case 275: /* table_name_cond ::= table_name */ -{ yylhsminor.yy242 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy669); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 277: /* from_db_opt ::= FROM db_name */ -{ yymsp[-1].minor.yy242 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy669); } +{ yymsp[-1].minor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } break; case 281: /* tag_item ::= TBNAME */ -{ yylhsminor.yy242 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 284: /* tag_item ::= column_name column_alias */ -{ yylhsminor.yy242 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy669), &yymsp[0].minor.yy669); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy371), &yymsp[0].minor.yy371); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 285: /* tag_item ::= column_name AS column_alias */ -{ yylhsminor.yy242 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy669), &yymsp[0].minor.yy669); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy371), &yymsp[0].minor.yy371); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 286: /* 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.yy777, yymsp[-3].minor.yy242, yymsp[-1].minor.yy242, NULL, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy667, yymsp[-3].minor.yy452, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } break; case 287: /* 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.yy777, yymsp[-5].minor.yy242, yymsp[-3].minor.yy242, yymsp[-1].minor.yy174, NULL); } +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_NORMAL, yymsp[-6].minor.yy667, yymsp[-5].minor.yy452, yymsp[-3].minor.yy452, yymsp[-1].minor.yy812, NULL); } break; case 288: /* cmd ::= DROP INDEX exists_opt full_index_name */ -{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy777, yymsp[0].minor.yy242); } +{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } break; case 289: /* full_index_name ::= index_name */ -{ yylhsminor.yy242 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy669); } - yymsp[0].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy371); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 290: /* full_index_name ::= db_name NK_DOT index_name */ -{ yylhsminor.yy242 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy669); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 291: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ -{ yymsp[-9].minor.yy242 = createIndexOption(pCxt, yymsp[-7].minor.yy174, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), NULL, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } +{ yymsp[-9].minor.yy452 = createIndexOption(pCxt, yymsp[-7].minor.yy812, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; case 292: /* 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.yy242 = createIndexOption(pCxt, yymsp[-9].minor.yy174, releaseRawExprNode(pCxt, yymsp[-5].minor.yy242), releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } +{ yymsp[-11].minor.yy452 = createIndexOption(pCxt, yymsp[-9].minor.yy812, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; case 295: /* func ::= sma_func_name NK_LP expression_list NK_RP */ -{ yylhsminor.yy242 = createFunctionNode(pCxt, &yymsp[-3].minor.yy669, yymsp[-1].minor.yy174); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; +{ yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 296: /* sma_func_name ::= function_name */ - case 509: /* alias_opt ::= table_alias */ yytestcase(yyruleno==509); -{ yylhsminor.yy669 = yymsp[0].minor.yy669; } - yymsp[0].minor.yy669 = yylhsminor.yy669; + case 510: /* alias_opt ::= table_alias */ yytestcase(yyruleno==510); +{ yylhsminor.yy371 = yymsp[0].minor.yy371; } + yymsp[0].minor.yy371 = yylhsminor.yy371; break; case 301: /* sma_stream_opt ::= */ - case 341: /* stream_options ::= */ yytestcase(yyruleno==341); -{ yymsp[1].minor.yy242 = createStreamOptions(pCxt); } + case 342: /* stream_options ::= */ yytestcase(yyruleno==342); +{ yymsp[1].minor.yy452 = createStreamOptions(pCxt); } break; case 302: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy242)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy242); yylhsminor.yy242 = yymsp[-2].minor.yy242; } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ ((SStreamOptions*)yymsp[-2].minor.yy452)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 303: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy242)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy242); yylhsminor.yy242 = yymsp[-2].minor.yy242; } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ ((SStreamOptions*)yymsp[-2].minor.yy452)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 304: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy242)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy242); yylhsminor.yy242 = yymsp[-2].minor.yy242; } - yymsp[-2].minor.yy242 = yylhsminor.yy242; +{ ((SStreamOptions*)yymsp[-2].minor.yy452)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 305: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ -{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy777, &yymsp[-2].minor.yy669, yymsp[0].minor.yy242); } + case 305: /* with_meta ::= AS */ +{ yymsp[0].minor.yy416 = 0; } break; - case 306: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy777, &yymsp[-3].minor.yy669, &yymsp[0].minor.yy669, false); } + case 306: /* with_meta ::= WITH META AS */ +{ yymsp[-2].minor.yy416 = 1; } break; - case 307: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-6].minor.yy777, &yymsp[-5].minor.yy669, &yymsp[0].minor.yy669, true); } + case 307: /* with_meta ::= ONLY META AS */ +{ yymsp[-2].minor.yy416 = 2; } break; - case 308: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name where_clause_opt */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-5].minor.yy777, &yymsp[-4].minor.yy669, yymsp[-1].minor.yy242, false, yymsp[0].minor.yy242); } + case 308: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ +{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, yymsp[0].minor.yy452); } break; - case 309: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name where_clause_opt */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-7].minor.yy777, &yymsp[-6].minor.yy669, yymsp[-1].minor.yy242, true, yymsp[0].minor.yy242); } + case 309: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ +{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy667, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy371, yymsp[-2].minor.yy416); } break; - case 310: /* cmd ::= DROP TOPIC exists_opt topic_name */ -{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } + case 310: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ +{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-5].minor.yy667, &yymsp[-4].minor.yy371, yymsp[-1].minor.yy452, yymsp[-3].minor.yy416, yymsp[0].minor.yy452); } break; - case 311: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ -{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy777, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy669); } + case 311: /* cmd ::= DROP TOPIC exists_opt topic_name */ +{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 312: /* cmd ::= DESC full_table_name */ - case 313: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==313); -{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy242); } + case 312: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ +{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } break; - case 314: /* cmd ::= RESET QUERY CACHE */ + case 313: /* cmd ::= DESC full_table_name */ + case 314: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==314); +{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy452); } + break; + case 315: /* cmd ::= RESET QUERY CACHE */ { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } break; - case 315: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - case 316: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==316); -{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy777, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } + case 316: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + case 317: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==317); +{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 319: /* explain_options ::= */ -{ yymsp[1].minor.yy242 = createDefaultExplainOptions(pCxt); } + case 320: /* explain_options ::= */ +{ yymsp[1].minor.yy452 = createDefaultExplainOptions(pCxt); } break; - case 320: /* explain_options ::= explain_options VERBOSE NK_BOOL */ -{ yylhsminor.yy242 = setExplainVerbose(pCxt, yymsp[-2].minor.yy242, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 321: /* explain_options ::= explain_options VERBOSE NK_BOOL */ +{ yylhsminor.yy452 = setExplainVerbose(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 321: /* explain_options ::= explain_options RATIO NK_FLOAT */ -{ yylhsminor.yy242 = setExplainRatio(pCxt, yymsp[-2].minor.yy242, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 322: /* explain_options ::= explain_options RATIO NK_FLOAT */ +{ yylhsminor.yy452 = setExplainRatio(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 322: /* 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.yy777, yymsp[-9].minor.yy777, &yymsp[-6].minor.yy669, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy794, yymsp[-1].minor.yy120, &yymsp[0].minor.yy669, yymsp[-10].minor.yy777); } + case 323: /* 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.yy667, yymsp[-9].minor.yy667, &yymsp[-6].minor.yy371, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy310, yymsp[-1].minor.yy416, &yymsp[0].minor.yy371, yymsp[-10].minor.yy667); } break; - case 323: /* cmd ::= DROP FUNCTION exists_opt function_name */ -{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } + case 324: /* cmd ::= DROP FUNCTION exists_opt function_name */ +{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 328: /* language_opt ::= */ -{ yymsp[1].minor.yy669 = nil_token; } + case 329: /* language_opt ::= */ +{ yymsp[1].minor.yy371 = nil_token; } break; - case 329: /* language_opt ::= LANGUAGE NK_STRING */ -{ yymsp[-1].minor.yy669 = yymsp[0].minor.yy0; } + case 330: /* language_opt ::= LANGUAGE NK_STRING */ +{ yymsp[-1].minor.yy371 = yymsp[0].minor.yy0; } break; - case 332: /* 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.yy777, &yymsp[-8].minor.yy669, yymsp[-5].minor.yy242, yymsp[-7].minor.yy242, yymsp[-3].minor.yy174, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, yymsp[-4].minor.yy174); } + case 333: /* 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.yy667, &yymsp[-8].minor.yy371, yymsp[-5].minor.yy452, yymsp[-7].minor.yy452, yymsp[-3].minor.yy812, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, yymsp[-4].minor.yy812); } break; - case 333: /* cmd ::= DROP STREAM exists_opt stream_name */ -{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } + case 334: /* cmd ::= DROP STREAM exists_opt stream_name */ +{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 334: /* cmd ::= PAUSE STREAM exists_opt stream_name */ -{ pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } + case 335: /* cmd ::= PAUSE STREAM exists_opt stream_name */ +{ pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 335: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ -{ pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy777, yymsp[-1].minor.yy777, &yymsp[0].minor.yy669); } + case 336: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ +{ pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } break; - case 342: /* stream_options ::= stream_options TRIGGER AT_ONCE */ - case 343: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==343); -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-2].minor.yy242, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 343: /* stream_options ::= stream_options TRIGGER AT_ONCE */ + case 344: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==344); +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 344: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-3].minor.yy242, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 345: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 345: /* stream_options ::= stream_options WATERMARK duration_literal */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-2].minor.yy242, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 346: /* stream_options ::= stream_options WATERMARK duration_literal */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 346: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-3].minor.yy242, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 347: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 347: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-2].minor.yy242, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 348: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 348: /* stream_options ::= stream_options DELETE_MARK duration_literal */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-2].minor.yy242, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 349: /* stream_options ::= stream_options DELETE_MARK duration_literal */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 349: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ -{ yylhsminor.yy242 = setStreamOptions(pCxt, yymsp[-3].minor.yy242, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 350: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ +{ yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 351: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - case 543: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==543); - case 564: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==564); -{ yymsp[-3].minor.yy242 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy242); } + case 352: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + case 544: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==544); + case 565: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==565); +{ yymsp[-3].minor.yy452 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy452); } break; - case 354: /* cmd ::= KILL CONNECTION NK_INTEGER */ + case 355: /* cmd ::= KILL CONNECTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } break; - case 355: /* cmd ::= KILL QUERY NK_STRING */ + case 356: /* cmd ::= KILL QUERY NK_STRING */ { pCxt->pRootNode = createKillQueryStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 356: /* cmd ::= KILL TRANSACTION NK_INTEGER */ + case 357: /* cmd ::= KILL TRANSACTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); } break; - case 357: /* cmd ::= BALANCE VGROUP */ + case 358: /* cmd ::= BALANCE VGROUP */ { pCxt->pRootNode = createBalanceVgroupStmt(pCxt); } break; - case 358: /* cmd ::= BALANCE VGROUP LEADER */ + case 359: /* cmd ::= BALANCE VGROUP LEADER */ { pCxt->pRootNode = createBalanceVgroupLeaderStmt(pCxt); } break; - case 359: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + case 360: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } break; - case 360: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ -{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy174); } + case 361: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ +{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy812); } break; - case 361: /* cmd ::= SPLIT VGROUP NK_INTEGER */ + case 362: /* cmd ::= SPLIT VGROUP NK_INTEGER */ { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 362: /* dnode_list ::= DNODE NK_INTEGER */ -{ yymsp[-1].minor.yy174 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + case 363: /* dnode_list ::= DNODE NK_INTEGER */ +{ yymsp[-1].minor.yy812 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } break; - case 364: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ -{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } + case 365: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ +{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 367: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ -{ yymsp[-6].minor.yy242 = createInsertStmt(pCxt, yymsp[-4].minor.yy242, yymsp[-2].minor.yy174, yymsp[0].minor.yy242); } + case 368: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ +{ yymsp[-6].minor.yy452 = createInsertStmt(pCxt, yymsp[-4].minor.yy452, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } break; - case 368: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ -{ yymsp[-3].minor.yy242 = createInsertStmt(pCxt, yymsp[-1].minor.yy242, NULL, yymsp[0].minor.yy242); } + case 369: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ +{ yymsp[-3].minor.yy452 = createInsertStmt(pCxt, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } break; - case 369: /* literal ::= NK_INTEGER */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 370: /* literal ::= NK_INTEGER */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 370: /* literal ::= NK_FLOAT */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 371: /* literal ::= NK_FLOAT */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 371: /* literal ::= NK_STRING */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 372: /* literal ::= NK_STRING */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 372: /* literal ::= NK_BOOL */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 373: /* literal ::= NK_BOOL */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 373: /* literal ::= TIMESTAMP NK_STRING */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + case 374: /* literal ::= TIMESTAMP NK_STRING */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 374: /* literal ::= duration_literal */ - case 384: /* signed_literal ::= signed */ yytestcase(yyruleno==384); - case 405: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==405); - case 406: /* expression ::= literal */ yytestcase(yyruleno==406); - case 407: /* expression ::= pseudo_column */ yytestcase(yyruleno==407); - case 408: /* expression ::= column_reference */ yytestcase(yyruleno==408); - case 409: /* expression ::= function_expression */ yytestcase(yyruleno==409); - case 410: /* expression ::= case_when_expression */ yytestcase(yyruleno==410); - case 441: /* function_expression ::= literal_func */ yytestcase(yyruleno==441); - case 490: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==490); - case 494: /* boolean_primary ::= predicate */ yytestcase(yyruleno==494); - case 496: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==496); - case 497: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==497); - case 500: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==500); - case 502: /* table_reference ::= table_primary */ yytestcase(yyruleno==502); - case 503: /* table_reference ::= joined_table */ yytestcase(yyruleno==503); - case 507: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==507); - case 566: /* query_simple ::= query_specification */ yytestcase(yyruleno==566); - case 567: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==567); - case 570: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==570); - case 572: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==572); -{ yylhsminor.yy242 = yymsp[0].minor.yy242; } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 375: /* literal ::= duration_literal */ + case 385: /* signed_literal ::= signed */ yytestcase(yyruleno==385); + case 406: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==406); + case 407: /* expression ::= literal */ yytestcase(yyruleno==407); + case 408: /* expression ::= pseudo_column */ yytestcase(yyruleno==408); + case 409: /* expression ::= column_reference */ yytestcase(yyruleno==409); + case 410: /* expression ::= function_expression */ yytestcase(yyruleno==410); + case 411: /* expression ::= case_when_expression */ yytestcase(yyruleno==411); + case 442: /* function_expression ::= literal_func */ yytestcase(yyruleno==442); + case 491: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==491); + case 495: /* boolean_primary ::= predicate */ yytestcase(yyruleno==495); + case 497: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==497); + case 498: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==498); + case 501: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==501); + case 503: /* table_reference ::= table_primary */ yytestcase(yyruleno==503); + case 504: /* table_reference ::= joined_table */ yytestcase(yyruleno==504); + case 508: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==508); + case 567: /* query_simple ::= query_specification */ yytestcase(yyruleno==567); + case 568: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==568); + case 571: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==571); + case 573: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==573); +{ yylhsminor.yy452 = yymsp[0].minor.yy452; } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 375: /* literal ::= NULL */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 376: /* literal ::= NULL */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 376: /* literal ::= NK_QUESTION */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 377: /* literal ::= NK_QUESTION */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 377: /* duration_literal ::= NK_VARIABLE */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 378: /* duration_literal ::= NK_VARIABLE */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 378: /* signed ::= NK_INTEGER */ -{ yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 379: /* signed ::= NK_INTEGER */ +{ yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 379: /* signed ::= NK_PLUS NK_INTEGER */ -{ yymsp[-1].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } + case 380: /* signed ::= NK_PLUS NK_INTEGER */ +{ yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } break; - case 380: /* signed ::= NK_MINUS NK_INTEGER */ + case 381: /* signed ::= NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); + yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 381: /* signed ::= NK_FLOAT */ -{ yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 382: /* signed ::= NK_FLOAT */ +{ yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 382: /* signed ::= NK_PLUS NK_FLOAT */ -{ yymsp[-1].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } + case 383: /* signed ::= NK_PLUS NK_FLOAT */ +{ yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } break; - case 383: /* signed ::= NK_MINUS NK_FLOAT */ + case 384: /* signed ::= NK_MINUS NK_FLOAT */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); + yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 385: /* signed_literal ::= NK_STRING */ -{ yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 386: /* signed_literal ::= NK_STRING */ +{ yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 386: /* signed_literal ::= NK_BOOL */ -{ yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 387: /* signed_literal ::= NK_BOOL */ +{ yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 387: /* signed_literal ::= TIMESTAMP NK_STRING */ -{ yymsp[-1].minor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } + case 388: /* signed_literal ::= TIMESTAMP NK_STRING */ +{ yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; - case 388: /* signed_literal ::= duration_literal */ - case 390: /* signed_literal ::= literal_func */ yytestcase(yyruleno==390); - case 461: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==461); - case 523: /* select_item ::= common_expression */ yytestcase(yyruleno==523); - case 533: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==533); - case 571: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==571); - case 573: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==573); - case 586: /* search_condition ::= common_expression */ yytestcase(yyruleno==586); -{ yylhsminor.yy242 = releaseRawExprNode(pCxt, yymsp[0].minor.yy242); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 389: /* signed_literal ::= duration_literal */ + case 391: /* signed_literal ::= literal_func */ yytestcase(yyruleno==391); + case 462: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==462); + case 524: /* select_item ::= common_expression */ yytestcase(yyruleno==524); + case 534: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==534); + case 572: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==572); + case 574: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==574); + case 587: /* search_condition ::= common_expression */ yytestcase(yyruleno==587); +{ yylhsminor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 389: /* signed_literal ::= NULL */ -{ yylhsminor.yy242 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 390: /* signed_literal ::= NULL */ +{ yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 391: /* signed_literal ::= NK_QUESTION */ -{ yylhsminor.yy242 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 392: /* signed_literal ::= NK_QUESTION */ +{ yylhsminor.yy452 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 411: /* expression ::= NK_LP expression NK_RP */ - case 495: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==495); - case 585: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==585); -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy242)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 412: /* expression ::= NK_LP expression NK_RP */ + case 496: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==496); + case 586: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==586); +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 412: /* expression ::= NK_PLUS expr_or_subquery */ + case 413: /* expression ::= NK_PLUS expr_or_subquery */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 413: /* expression ::= NK_MINUS expr_or_subquery */ + case 414: /* expression ::= NK_MINUS expr_or_subquery */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy242), NULL)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 414: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + case 415: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 415: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + case 416: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 416: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + case 417: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 417: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + case 418: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 418: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ + case 419: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 419: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 420: /* expression ::= column_reference NK_ARROW NK_STRING */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 420: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + case 421: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 421: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + case 422: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 424: /* column_reference ::= column_name */ -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy669, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy669)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 425: /* column_reference ::= column_name */ +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy371, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 425: /* column_reference ::= table_name NK_DOT column_name */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy669, createColumnNode(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy669)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 426: /* column_reference ::= table_name NK_DOT column_name */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371, createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 426: /* pseudo_column ::= ROWTS */ - case 427: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==427); - case 429: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==429); - case 430: /* pseudo_column ::= QEND */ yytestcase(yyruleno==430); - case 431: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==431); - case 432: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==432); - case 433: /* pseudo_column ::= WEND */ yytestcase(yyruleno==433); - case 434: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==434); - case 435: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==435); - case 436: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==436); - case 437: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==437); - case 443: /* literal_func ::= NOW */ yytestcase(yyruleno==443); -{ yylhsminor.yy242 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 427: /* pseudo_column ::= ROWTS */ + case 428: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==428); + case 430: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==430); + case 431: /* pseudo_column ::= QEND */ yytestcase(yyruleno==431); + case 432: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==432); + case 433: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==433); + case 434: /* pseudo_column ::= WEND */ yytestcase(yyruleno==434); + case 435: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==435); + case 436: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==436); + case 437: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==437); + case 438: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==438); + case 444: /* literal_func ::= NOW */ yytestcase(yyruleno==444); +{ yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 428: /* pseudo_column ::= table_name NK_DOT TBNAME */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy669)))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 429: /* pseudo_column ::= table_name NK_DOT TBNAME */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy371)))); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 438: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 439: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==439); -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy669, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy669, yymsp[-1].minor.yy174)); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 439: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 440: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==440); +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812)); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 440: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), yymsp[-1].minor.yy794)); } - yymsp[-5].minor.yy242 = yylhsminor.yy242; + case 441: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy310)); } + yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 442: /* literal_func ::= noarg_func NK_LP NK_RP */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy669, NULL)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 443: /* literal_func ::= noarg_func NK_LP NK_RP */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy371, NULL)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 457: /* star_func_para_list ::= NK_STAR */ -{ yylhsminor.yy174 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy174 = yylhsminor.yy174; + case 458: /* star_func_para_list ::= NK_STAR */ +{ yylhsminor.yy812 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 462: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 526: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==526); -{ yylhsminor.yy242 = createColumnNode(pCxt, &yymsp[-2].minor.yy669, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 463: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 527: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==527); +{ yylhsminor.yy452 = createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 463: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy174, yymsp[-1].minor.yy242)); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 464: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 464: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), yymsp[-2].minor.yy174, yymsp[-1].minor.yy242)); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; + case 465: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 467: /* when_then_expr ::= WHEN common_expression THEN common_expression */ -{ yymsp[-3].minor.yy242 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242)); } + case 468: /* when_then_expr ::= WHEN common_expression THEN common_expression */ +{ yymsp[-3].minor.yy452 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } break; - case 469: /* case_when_else_opt ::= ELSE common_expression */ -{ yymsp[-1].minor.yy242 = releaseRawExprNode(pCxt, yymsp[0].minor.yy242); } + case 470: /* case_when_else_opt ::= ELSE common_expression */ +{ yymsp[-1].minor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } break; - case 470: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ - case 475: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==475); + case 471: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ + case 476: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==476); { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy70, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy354, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 471: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + case 472: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy242), releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy452), releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-4].minor.yy242 = yylhsminor.yy242; + yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 472: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + case 473: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy242), releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-5].minor.yy242 = yylhsminor.yy242; + yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 473: /* predicate ::= expr_or_subquery IS NULL */ + case 474: /* predicate ::= expr_or_subquery IS NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), NULL)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 474: /* predicate ::= expr_or_subquery IS NOT NULL */ + case 475: /* predicate ::= expr_or_subquery IS NOT NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL)); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 476: /* compare_op ::= NK_LT */ -{ yymsp[0].minor.yy70 = OP_TYPE_LOWER_THAN; } + case 477: /* compare_op ::= NK_LT */ +{ yymsp[0].minor.yy354 = OP_TYPE_LOWER_THAN; } break; - case 477: /* compare_op ::= NK_GT */ -{ yymsp[0].minor.yy70 = OP_TYPE_GREATER_THAN; } + case 478: /* compare_op ::= NK_GT */ +{ yymsp[0].minor.yy354 = OP_TYPE_GREATER_THAN; } break; - case 478: /* compare_op ::= NK_LE */ -{ yymsp[0].minor.yy70 = OP_TYPE_LOWER_EQUAL; } + case 479: /* compare_op ::= NK_LE */ +{ yymsp[0].minor.yy354 = OP_TYPE_LOWER_EQUAL; } break; - case 479: /* compare_op ::= NK_GE */ -{ yymsp[0].minor.yy70 = OP_TYPE_GREATER_EQUAL; } + case 480: /* compare_op ::= NK_GE */ +{ yymsp[0].minor.yy354 = OP_TYPE_GREATER_EQUAL; } break; - case 480: /* compare_op ::= NK_NE */ -{ yymsp[0].minor.yy70 = OP_TYPE_NOT_EQUAL; } + case 481: /* compare_op ::= NK_NE */ +{ yymsp[0].minor.yy354 = OP_TYPE_NOT_EQUAL; } break; - case 481: /* compare_op ::= NK_EQ */ -{ yymsp[0].minor.yy70 = OP_TYPE_EQUAL; } + case 482: /* compare_op ::= NK_EQ */ +{ yymsp[0].minor.yy354 = OP_TYPE_EQUAL; } break; - case 482: /* compare_op ::= LIKE */ -{ yymsp[0].minor.yy70 = OP_TYPE_LIKE; } + case 483: /* compare_op ::= LIKE */ +{ yymsp[0].minor.yy354 = OP_TYPE_LIKE; } break; - case 483: /* compare_op ::= NOT LIKE */ -{ yymsp[-1].minor.yy70 = OP_TYPE_NOT_LIKE; } + case 484: /* compare_op ::= NOT LIKE */ +{ yymsp[-1].minor.yy354 = OP_TYPE_NOT_LIKE; } break; - case 484: /* compare_op ::= MATCH */ -{ yymsp[0].minor.yy70 = OP_TYPE_MATCH; } + case 485: /* compare_op ::= MATCH */ +{ yymsp[0].minor.yy354 = OP_TYPE_MATCH; } break; - case 485: /* compare_op ::= NMATCH */ -{ yymsp[0].minor.yy70 = OP_TYPE_NMATCH; } + case 486: /* compare_op ::= NMATCH */ +{ yymsp[0].minor.yy354 = OP_TYPE_NMATCH; } break; - case 486: /* compare_op ::= CONTAINS */ -{ yymsp[0].minor.yy70 = OP_TYPE_JSON_CONTAINS; } + case 487: /* compare_op ::= CONTAINS */ +{ yymsp[0].minor.yy354 = OP_TYPE_JSON_CONTAINS; } break; - case 487: /* in_op ::= IN */ -{ yymsp[0].minor.yy70 = OP_TYPE_IN; } + case 488: /* in_op ::= IN */ +{ yymsp[0].minor.yy354 = OP_TYPE_IN; } break; - case 488: /* in_op ::= NOT IN */ -{ yymsp[-1].minor.yy70 = OP_TYPE_NOT_IN; } + case 489: /* in_op ::= NOT IN */ +{ yymsp[-1].minor.yy354 = OP_TYPE_NOT_IN; } break; - case 489: /* in_predicate_value ::= NK_LP literal_list NK_RP */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy174)); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 490: /* in_predicate_value ::= NK_LP literal_list NK_RP */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 491: /* boolean_value_expression ::= NOT boolean_primary */ + case 492: /* boolean_value_expression ::= NOT boolean_primary */ { - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy242), NULL)); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 492: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 493: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 493: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 494: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy242); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy242); - yylhsminor.yy242 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); + yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 501: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ -{ yylhsminor.yy242 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, NULL); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 502: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ +{ yylhsminor.yy452 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, NULL); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 504: /* table_primary ::= table_name alias_opt */ -{ yylhsminor.yy242 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy669, &yymsp[0].minor.yy669); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + case 505: /* table_primary ::= table_name alias_opt */ +{ yylhsminor.yy452 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 505: /* table_primary ::= db_name NK_DOT table_name alias_opt */ -{ yylhsminor.yy242 = createRealTableNode(pCxt, &yymsp[-3].minor.yy669, &yymsp[-1].minor.yy669, &yymsp[0].minor.yy669); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 506: /* table_primary ::= db_name NK_DOT table_name alias_opt */ +{ yylhsminor.yy452 = createRealTableNode(pCxt, &yymsp[-3].minor.yy371, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 506: /* table_primary ::= subquery alias_opt */ -{ yylhsminor.yy242 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy242), &yymsp[0].minor.yy669); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + case 507: /* table_primary ::= subquery alias_opt */ +{ yylhsminor.yy452 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 508: /* alias_opt ::= */ -{ yymsp[1].minor.yy669 = nil_token; } + case 509: /* alias_opt ::= */ +{ yymsp[1].minor.yy371 = nil_token; } break; - case 510: /* alias_opt ::= AS table_alias */ -{ yymsp[-1].minor.yy669 = yymsp[0].minor.yy669; } + case 511: /* alias_opt ::= AS table_alias */ +{ yymsp[-1].minor.yy371 = yymsp[0].minor.yy371; } break; - case 511: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 512: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==512); -{ yymsp[-2].minor.yy242 = yymsp[-1].minor.yy242; } + case 512: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 513: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==513); +{ yymsp[-2].minor.yy452 = yymsp[-1].minor.yy452; } break; - case 513: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ -{ yylhsminor.yy242 = createJoinTableNode(pCxt, yymsp[-4].minor.yy482, yymsp[-5].minor.yy242, yymsp[-2].minor.yy242, yymsp[0].minor.yy242); } - yymsp[-5].minor.yy242 = yylhsminor.yy242; + case 514: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ +{ yylhsminor.yy452 = createJoinTableNode(pCxt, yymsp[-4].minor.yy140, yymsp[-5].minor.yy452, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } + yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 514: /* join_type ::= */ -{ yymsp[1].minor.yy482 = JOIN_TYPE_INNER; } + case 515: /* join_type ::= */ +{ yymsp[1].minor.yy140 = JOIN_TYPE_INNER; } break; - case 515: /* join_type ::= INNER */ -{ yymsp[0].minor.yy482 = JOIN_TYPE_INNER; } + case 516: /* join_type ::= INNER */ +{ yymsp[0].minor.yy140 = JOIN_TYPE_INNER; } break; - case 516: /* 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 517: /* 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 */ { - yymsp[-11].minor.yy242 = createSelectStmt(pCxt, yymsp[-10].minor.yy777, yymsp[-9].minor.yy174, yymsp[-8].minor.yy242); - yymsp[-11].minor.yy242 = addWhereClause(pCxt, yymsp[-11].minor.yy242, yymsp[-7].minor.yy242); - yymsp[-11].minor.yy242 = addPartitionByClause(pCxt, yymsp[-11].minor.yy242, yymsp[-6].minor.yy174); - yymsp[-11].minor.yy242 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy242, yymsp[-2].minor.yy242); - yymsp[-11].minor.yy242 = addGroupByClause(pCxt, yymsp[-11].minor.yy242, yymsp[-1].minor.yy174); - yymsp[-11].minor.yy242 = addHavingClause(pCxt, yymsp[-11].minor.yy242, yymsp[0].minor.yy242); - yymsp[-11].minor.yy242 = addRangeClause(pCxt, yymsp[-11].minor.yy242, yymsp[-5].minor.yy242); - yymsp[-11].minor.yy242 = addEveryClause(pCxt, yymsp[-11].minor.yy242, yymsp[-4].minor.yy242); - yymsp[-11].minor.yy242 = addFillClause(pCxt, yymsp[-11].minor.yy242, yymsp[-3].minor.yy242); + yymsp[-11].minor.yy452 = createSelectStmt(pCxt, yymsp[-10].minor.yy667, yymsp[-9].minor.yy812, yymsp[-8].minor.yy452); + yymsp[-11].minor.yy452 = addWhereClause(pCxt, yymsp[-11].minor.yy452, yymsp[-7].minor.yy452); + yymsp[-11].minor.yy452 = addPartitionByClause(pCxt, yymsp[-11].minor.yy452, yymsp[-6].minor.yy812); + yymsp[-11].minor.yy452 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy452, yymsp[-2].minor.yy452); + yymsp[-11].minor.yy452 = addGroupByClause(pCxt, yymsp[-11].minor.yy452, yymsp[-1].minor.yy812); + yymsp[-11].minor.yy452 = addHavingClause(pCxt, yymsp[-11].minor.yy452, yymsp[0].minor.yy452); + yymsp[-11].minor.yy452 = addRangeClause(pCxt, yymsp[-11].minor.yy452, yymsp[-5].minor.yy452); + yymsp[-11].minor.yy452 = addEveryClause(pCxt, yymsp[-11].minor.yy452, yymsp[-4].minor.yy452); + yymsp[-11].minor.yy452 = addFillClause(pCxt, yymsp[-11].minor.yy452, yymsp[-3].minor.yy452); } break; - case 519: /* set_quantifier_opt ::= ALL */ -{ yymsp[0].minor.yy777 = false; } + case 520: /* set_quantifier_opt ::= ALL */ +{ yymsp[0].minor.yy667 = false; } break; - case 522: /* select_item ::= NK_STAR */ -{ yylhsminor.yy242 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy242 = yylhsminor.yy242; + case 523: /* select_item ::= NK_STAR */ +{ yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 524: /* select_item ::= common_expression column_alias */ - case 534: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==534); -{ yylhsminor.yy242 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy242), &yymsp[0].minor.yy669); } - yymsp[-1].minor.yy242 = yylhsminor.yy242; + case 525: /* select_item ::= common_expression column_alias */ + case 535: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==535); +{ yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } + yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 525: /* select_item ::= common_expression AS column_alias */ - case 535: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==535); -{ yylhsminor.yy242 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), &yymsp[0].minor.yy669); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 526: /* select_item ::= common_expression AS column_alias */ + case 536: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==536); +{ yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), &yymsp[0].minor.yy371); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 530: /* partition_by_clause_opt ::= PARTITION BY partition_list */ - case 555: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==555); - case 575: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==575); -{ yymsp[-2].minor.yy174 = yymsp[0].minor.yy174; } + case 531: /* partition_by_clause_opt ::= PARTITION BY partition_list */ + case 556: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==556); + case 576: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==576); +{ yymsp[-2].minor.yy812 = yymsp[0].minor.yy812; } break; - case 537: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ -{ yymsp[-5].minor.yy242 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), releaseRawExprNode(pCxt, yymsp[-1].minor.yy242)); } + case 538: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ +{ yymsp[-5].minor.yy452 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 538: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ -{ yymsp[-3].minor.yy242 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy242)); } + case 539: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ +{ yymsp[-3].minor.yy452 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 539: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-5].minor.yy242 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), NULL, yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } + case 540: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-5].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 540: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-7].minor.yy242 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy242), releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), yymsp[-1].minor.yy242, yymsp[0].minor.yy242); } + case 541: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-7].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } break; - case 541: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ -{ yymsp[-6].minor.yy242 = createEventWindowNode(pCxt, yymsp[-3].minor.yy242, yymsp[0].minor.yy242); } + case 542: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ +{ yymsp[-6].minor.yy452 = createEventWindowNode(pCxt, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } break; - case 545: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ -{ yymsp[-3].minor.yy242 = createFillNode(pCxt, yymsp[-1].minor.yy204, NULL); } + case 546: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ +{ yymsp[-3].minor.yy452 = createFillNode(pCxt, yymsp[-1].minor.yy844, NULL); } break; - case 546: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ -{ yymsp[-5].minor.yy242 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy174)); } + case 547: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ +{ yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } break; - case 547: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ -{ yymsp[-5].minor.yy242 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy174)); } + case 548: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ +{ yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } break; - case 548: /* fill_mode ::= NONE */ -{ yymsp[0].minor.yy204 = FILL_MODE_NONE; } + case 549: /* fill_mode ::= NONE */ +{ yymsp[0].minor.yy844 = FILL_MODE_NONE; } break; - case 549: /* fill_mode ::= PREV */ -{ yymsp[0].minor.yy204 = FILL_MODE_PREV; } + case 550: /* fill_mode ::= PREV */ +{ yymsp[0].minor.yy844 = FILL_MODE_PREV; } break; - case 550: /* fill_mode ::= NULL */ -{ yymsp[0].minor.yy204 = FILL_MODE_NULL; } + case 551: /* fill_mode ::= NULL */ +{ yymsp[0].minor.yy844 = FILL_MODE_NULL; } break; - case 551: /* fill_mode ::= NULL_F */ -{ yymsp[0].minor.yy204 = FILL_MODE_NULL_F; } + case 552: /* fill_mode ::= NULL_F */ +{ yymsp[0].minor.yy844 = FILL_MODE_NULL_F; } break; - case 552: /* fill_mode ::= LINEAR */ -{ yymsp[0].minor.yy204 = FILL_MODE_LINEAR; } + case 553: /* fill_mode ::= LINEAR */ +{ yymsp[0].minor.yy844 = FILL_MODE_LINEAR; } break; - case 553: /* fill_mode ::= NEXT */ -{ yymsp[0].minor.yy204 = FILL_MODE_NEXT; } + case 554: /* fill_mode ::= NEXT */ +{ yymsp[0].minor.yy844 = FILL_MODE_NEXT; } break; - case 556: /* group_by_list ::= expr_or_subquery */ -{ yylhsminor.yy174 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); } - yymsp[0].minor.yy174 = yylhsminor.yy174; + case 557: /* group_by_list ::= expr_or_subquery */ +{ yylhsminor.yy812 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } + yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 557: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ -{ yylhsminor.yy174 = addNodeToList(pCxt, yymsp[-2].minor.yy174, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy242))); } - yymsp[-2].minor.yy174 = yylhsminor.yy174; + case 558: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ +{ yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } + yymsp[-2].minor.yy812 = yylhsminor.yy812; break; - case 561: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ -{ yymsp[-5].minor.yy242 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy242), releaseRawExprNode(pCxt, yymsp[-1].minor.yy242)); } + case 562: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ +{ yymsp[-5].minor.yy452 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 562: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ -{ yymsp[-3].minor.yy242 = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy242)); } + case 563: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ +{ yymsp[-3].minor.yy452 = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } break; - case 565: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 566: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ { - yylhsminor.yy242 = addOrderByClause(pCxt, yymsp[-3].minor.yy242, yymsp[-2].minor.yy174); - yylhsminor.yy242 = addSlimitClause(pCxt, yylhsminor.yy242, yymsp[-1].minor.yy242); - yylhsminor.yy242 = addLimitClause(pCxt, yylhsminor.yy242, yymsp[0].minor.yy242); + yylhsminor.yy452 = addOrderByClause(pCxt, yymsp[-3].minor.yy452, yymsp[-2].minor.yy812); + yylhsminor.yy452 = addSlimitClause(pCxt, yylhsminor.yy452, yymsp[-1].minor.yy452); + yylhsminor.yy452 = addLimitClause(pCxt, yylhsminor.yy452, yymsp[0].minor.yy452); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 568: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ -{ yylhsminor.yy242 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy242, yymsp[0].minor.yy242); } - yymsp[-3].minor.yy242 = yylhsminor.yy242; + case 569: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ +{ yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 569: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ -{ yylhsminor.yy242 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy242, yymsp[0].minor.yy242); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 570: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ +{ yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 577: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 581: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==581); -{ yymsp[-1].minor.yy242 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } + case 578: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 582: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==582); +{ yymsp[-1].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } break; - case 578: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 582: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==582); -{ yymsp[-3].minor.yy242 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } + case 579: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 583: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==583); +{ yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 579: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 583: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==583); -{ yymsp[-3].minor.yy242 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } + case 580: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 584: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==584); +{ yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 584: /* subquery ::= NK_LP query_expression NK_RP */ -{ yylhsminor.yy242 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy242); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 585: /* subquery ::= NK_LP query_expression NK_RP */ +{ yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy452); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 589: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ -{ yylhsminor.yy242 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy242), yymsp[-1].minor.yy48, yymsp[0].minor.yy687); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + case 590: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ +{ yylhsminor.yy452 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), yymsp[-1].minor.yy690, yymsp[0].minor.yy399); } + yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 590: /* ordering_specification_opt ::= */ -{ yymsp[1].minor.yy48 = ORDER_ASC; } + case 591: /* ordering_specification_opt ::= */ +{ yymsp[1].minor.yy690 = ORDER_ASC; } break; - case 591: /* ordering_specification_opt ::= ASC */ -{ yymsp[0].minor.yy48 = ORDER_ASC; } + case 592: /* ordering_specification_opt ::= ASC */ +{ yymsp[0].minor.yy690 = ORDER_ASC; } break; - case 592: /* ordering_specification_opt ::= DESC */ -{ yymsp[0].minor.yy48 = ORDER_DESC; } + case 593: /* ordering_specification_opt ::= DESC */ +{ yymsp[0].minor.yy690 = ORDER_DESC; } break; - case 593: /* null_ordering_opt ::= */ -{ yymsp[1].minor.yy687 = NULL_ORDER_DEFAULT; } + case 594: /* null_ordering_opt ::= */ +{ yymsp[1].minor.yy399 = NULL_ORDER_DEFAULT; } break; - case 594: /* null_ordering_opt ::= NULLS FIRST */ -{ yymsp[-1].minor.yy687 = NULL_ORDER_FIRST; } + case 595: /* null_ordering_opt ::= NULLS FIRST */ +{ yymsp[-1].minor.yy399 = NULL_ORDER_FIRST; } break; - case 595: /* null_ordering_opt ::= NULLS LAST */ -{ yymsp[-1].minor.yy687 = NULL_ORDER_LAST; } + case 596: /* null_ordering_opt ::= NULLS LAST */ +{ yymsp[-1].minor.yy399 = NULL_ORDER_LAST; } break; default: break; @@ -6274,12 +6598,56 @@ void Parse( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -6335,14 +6703,13 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= yypParser->yystack - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE - ){ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; yy_pop_parser_stack(yypParser); } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); #ifndef YYNOERRORRECOVERY @@ -6392,7 +6759,7 @@ void Parse( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 713f12e229..4a8d100db3 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -1027,6 +1027,7 @@ static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect return TSDB_CODE_OUT_OF_MEMORY; } + pSort->maxRows = -1; pSort->groupSort = pSelect->groupSort; pSort->node.groupAction = pSort->groupSort ? GROUP_ACTION_KEEP : GROUP_ACTION_CLEAR; pSort->node.requireDataOrder = DATA_ORDER_LEVEL_NONE; @@ -1298,6 +1299,7 @@ static int32_t createSetOpSortLogicNode(SLogicPlanContext* pCxt, SSetOperator* p return TSDB_CODE_OUT_OF_MEMORY; } + pSort->maxRows = -1; TSWAP(pSort->node.pLimit, pSetOperator->pLimit); int32_t code = TSDB_CODE_SUCCESS; diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 2d1a758f33..82d883714d 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -123,7 +123,7 @@ static void optSetParentOrder(SLogicNode* pNode, EOrder order, SLogicNode* pNode pNode->inputTsOrder = order; switch (nodeType(pNode)) { // for those nodes that will change the order, stop propagating - //case QUERY_NODE_LOGIC_PLAN_WINDOW: + // case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_JOIN: case QUERY_NODE_LOGIC_PLAN_AGG: case QUERY_NODE_LOGIC_PLAN_SORT: @@ -769,8 +769,9 @@ static bool pushDownCondOptIsColEqualOnCond(SJoinLogicNode* pJoin, SNode* pCond) } SColumnNode* pLeft = (SColumnNode*)(pOper->pLeft); SColumnNode* pRight = (SColumnNode*)(pOper->pRight); - //TODO: add cast to operator and remove this restriction of optimization - if (pLeft->node.resType.type != pRight->node.resType.type || pLeft->node.resType.bytes != pRight->node.resType.bytes) { + // TODO: add cast to operator and remove this restriction of optimization + if (pLeft->node.resType.type != pRight->node.resType.type || + pLeft->node.resType.bytes != pRight->node.resType.bytes) { return false; } SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets; @@ -2575,7 +2576,7 @@ static void tagScanOptCloneAncestorSlimit(SLogicNode* pTableScanNode) { SLogicNode* pNode = tagScanOptFindAncestorWithSlimit(pTableScanNode); if (NULL != pNode) { - //TODO: only set the slimit now. push down slimit later + // 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; @@ -2629,8 +2630,16 @@ static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubp } static bool pushDownLimitOptShouldBeOptimized(SLogicNode* pNode) { - if (NULL == pNode->pLimit || 1 != LIST_LENGTH(pNode->pChildren) || - QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) { + if (NULL == pNode->pLimit || 1 != LIST_LENGTH(pNode->pChildren)) { + return false; + } + + SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0); + if (QUERY_NODE_LOGIC_PLAN_SORT == nodeType(pChild)) { + SLimitNode* pChildLimit = (SLimitNode*)(pChild->pLimit); + // if we have pushed down, we skip it + if ((*(SSortLogicNode*)pChild).maxRows != -1) return false; + } else if (QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(pChild)) { return false; } return true; @@ -2644,8 +2653,18 @@ static int32_t pushDownLimitOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLog SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0); nodesDestroyNode(pChild->pLimit); - pChild->pLimit = pNode->pLimit; - pNode->pLimit = NULL; + if (QUERY_NODE_LOGIC_PLAN_SORT == nodeType(pChild)) { + SLimitNode* pLimitNode = (SLimitNode*)pNode->pLimit; + int64_t maxRows = -1; + if (pLimitNode->limit != -1) { + maxRows = pLimitNode->limit; + if (pLimitNode->offset != -1) maxRows += pLimitNode->offset; + } + ((SSortLogicNode*)pChild)->maxRows = maxRows; + } else { + pChild->pLimit = pNode->pLimit; + pNode->pLimit = NULL; + } pCxt->optimized = true; return TSDB_CODE_SUCCESS; @@ -2898,7 +2917,7 @@ static SSortLogicNode* sortNonPriKeySatisfied(SLogicNode* pNode) { if (sortPriKeyOptIsPriKeyOrderBy(pSort->pSortKeys)) { return NULL; } - SNode* pSortKeyNode = NULL, *pSortKeyExpr = NULL; + SNode *pSortKeyNode = NULL, *pSortKeyExpr = NULL; FOREACH(pSortKeyNode, pSort->pSortKeys) { pSortKeyExpr = ((SOrderByExprNode*)pSortKeyNode)->pExpr; switch (nodeType(pSortKeyExpr)) { @@ -2931,7 +2950,7 @@ static int32_t sortNonPriKeyOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLog optFindEligibleNode(pLogicSubplan->pNode, sortNonPriKeyShouldOptimize, pNodeList); SNode* pNode = NULL; FOREACH(pNode, pNodeList) { - SSortLogicNode* pSort = (SSortLogicNode*)pNode; + SSortLogicNode* pSort = (SSortLogicNode*)pNode; SOrderByExprNode* pOrderByExpr = (SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0); pSort->node.outputTsOrder = pOrderByExpr->order; optSetParentOrder(pSort->node.pParent, pOrderByExpr->order, NULL); diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index b3d94a5e47..a349e2c0e9 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1374,6 +1374,7 @@ static int32_t createSortPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren if (NULL == pSort) { return TSDB_CODE_OUT_OF_MEMORY; } + pSort->maxRows = pSortLogicNode->maxRows; SNodeList* pPrecalcExprs = NULL; SNodeList* pSortKeys = NULL; diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 246ee13fb0..f352a2bba3 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -1018,6 +1018,7 @@ static int32_t stbSplCreatePartSortNode(SSortLogicNode* pSort, SLogicNode** pOut splSetParent((SLogicNode*)pPartSort); pPartSort->pSortKeys = pSortKeys; pPartSort->groupSort = pSort->groupSort; + pPartSort->maxRows = pSort->maxRows; code = stbSplCreateMergeKeys(pPartSort->pSortKeys, pPartSort->node.pTargets, &pMergeKeys); } diff --git a/source/libs/planner/test/CMakeLists.txt b/source/libs/planner/test/CMakeLists.txt index b9d5c85717..73aca8572a 100644 --- a/source/libs/planner/test/CMakeLists.txt +++ b/source/libs/planner/test/CMakeLists.txt @@ -12,10 +12,17 @@ IF(NOT TD_DARWIN) "${SOURCE_LIST}/../../../parser/test/mockCatalogService.cpp" ) - TARGET_LINK_LIBRARIES( - plannerTest - PUBLIC os util common nodes planner parser catalog transport gtest function qcom - ) + IF (TD_GRANT) + TARGET_LINK_LIBRARIES( + plannerTest + PUBLIC os util common nodes planner parser catalog transport gtest function qcom grant + ) + ELSE () + TARGET_LINK_LIBRARIES( + plannerTest + PUBLIC os util common nodes planner parser catalog transport gtest function qcom + ) + ENDIF() TARGET_INCLUDE_DIRECTORIES( plannerTest diff --git a/source/libs/scalar/CMakeLists.txt b/source/libs/scalar/CMakeLists.txt index 30c68cb512..1fe0f9a18d 100644 --- a/source/libs/scalar/CMakeLists.txt +++ b/source/libs/scalar/CMakeLists.txt @@ -8,13 +8,14 @@ target_include_directories( ) target_link_libraries(scalar - PRIVATE os - PRIVATE util + PRIVATE os + PRIVATE util PRIVATE common PRIVATE nodes PRIVATE function PRIVATE qcom PRIVATE parser + PRIVATE geometry ) if(${BUILD_TEST}) diff --git a/source/libs/scalar/inc/filterInt.h b/source/libs/scalar/inc/filterInt.h index 1ca8ac1d8c..5fb7b0e90c 100644 --- a/source/libs/scalar/inc/filterInt.h +++ b/source/libs/scalar/inc/filterInt.h @@ -271,8 +271,9 @@ struct SFilterInfo { SFilterPCtx pctx; }; -#define FILTER_NO_MERGE_DATA_TYPE(t) \ - ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON) +#define FILTER_NO_MERGE_DATA_TYPE(t) \ + ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON || \ + (t) == TSDB_DATA_TYPE_GEOMETRY) #define FILTER_NO_MERGE_OPTR(o) ((o) == OP_TYPE_IS_NULL || (o) == OP_TYPE_IS_NOT_NULL || (o) == FILTER_DUMMY_EMPTY_OPTR) #define MR_EMPTY_RES(ctx) (ctx->rs == NULL) diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index bbefcc6b3a..b3afbb53c1 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -133,7 +133,7 @@ __compar_fn_t gDataCompare[] = { setChkInBytes2, setChkInBytes4, setChkInBytes8, comparestrRegexMatch, comparestrRegexNMatch, setChkNotInBytes1, setChkNotInBytes2, setChkNotInBytes4, setChkNotInBytes8, compareChkNotInString, comparestrPatternNMatch, comparewcsPatternNMatch, - comparewcsRegexMatch, comparewcsRegexNMatch, + comparewcsRegexMatch, comparewcsRegexNMatch, compareLenBinaryVal }; __compar_fn_t gInt8SignCompare[] = {compareInt8Val, compareInt8Int16, compareInt8Int32, @@ -257,8 +257,7 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_DOUBLE: comparFn = 5; break; - case TSDB_DATA_TYPE_BINARY: - case TSDB_DATA_TYPE_GEOMETRY: { + case TSDB_DATA_TYPE_BINARY: { if (optr == OP_TYPE_MATCH) { comparFn = 19; } else if (optr == OP_TYPE_NMATCH) { @@ -297,6 +296,21 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { break; } + case TSDB_DATA_TYPE_GEOMETRY: { + if (optr == OP_TYPE_EQUAL || optr == OP_TYPE_NOT_EQUAL || optr == OP_TYPE_IS_NULL || + optr == OP_TYPE_IS_NOT_NULL) { + comparFn = 30; + } else if (optr == OP_TYPE_IN) { + comparFn = 8; + } else if (optr == OP_TYPE_NOT_IN) { + comparFn = 25; + } else { + terrno = TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR; + return 0; + } + break; + } + case TSDB_DATA_TYPE_UTINYINT: comparFn = 11; break; @@ -1042,12 +1056,12 @@ static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilte int32_t filterAddFieldFromNode(SFilterInfo *info, SNode *node, SFilterFieldId *fid) { if (node == NULL) { fltDebug("empty node"); - FLT_ERR_RET(TSDB_CODE_APP_ERROR); + goto _return; } if (nodeType(node) != QUERY_NODE_COLUMN && nodeType(node) != QUERY_NODE_VALUE && nodeType(node) != QUERY_NODE_NODE_LIST) { - FLT_ERR_RET(TSDB_CODE_APP_ERROR); + goto _return; } int32_t type; @@ -1063,6 +1077,7 @@ int32_t filterAddFieldFromNode(SFilterInfo *info, SNode *node, SFilterFieldId *f filterAddField(info, v, NULL, type, fid, 0, true, NULL); +_return: return TSDB_CODE_SUCCESS; } @@ -1948,33 +1963,15 @@ int32_t fltInitValFieldData(SFilterInfo *info) { } SDataType *dType = &var->node.resType; - size_t bytes = 0; - - if (type == TSDB_DATA_TYPE_BINARY) { - size_t len = (dType->type == TSDB_DATA_TYPE_BINARY || dType->type == TSDB_DATA_TYPE_NCHAR) ? dType->bytes - : MAX_NUM_STR_SIZE; - bytes = len + 1 + VARSTR_HEADER_SIZE; - - fi->data = taosMemoryCalloc(1, bytes); - } else if (type == TSDB_DATA_TYPE_NCHAR) { - size_t len = (dType->type == TSDB_DATA_TYPE_BINARY || dType->type == TSDB_DATA_TYPE_NCHAR) ? dType->bytes - : MAX_NUM_STR_SIZE; - bytes = (len + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE; - - fi->data = taosMemoryCalloc(1, bytes); - } else { - fi->data = taosMemoryCalloc(1, sizeof(int64_t)); - } - if (dType->type == type) { + size_t bufBytes = TMAX(dType->bytes, sizeof(int64_t)); + fi->data = taosMemoryCalloc(1, bufBytes); assignVal(fi->data, nodesGetValueFromNode(var), dType->bytes, type); } else { SScalarParam out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))}; out.columnData->info.type = type; out.columnData->info.precision = precision; - if (IS_VAR_DATA_TYPE(type)) { - out.columnData->info.bytes = bytes; - } else { + if (!IS_VAR_DATA_TYPE(type)) { out.columnData->info.bytes = tDataTypes[type].bytes; } @@ -1985,7 +1982,13 @@ int32_t fltInitValFieldData(SFilterInfo *info) { return TSDB_CODE_TSC_INVALID_OPERATION; } - memcpy(fi->data, out.columnData->pData, out.columnData->info.bytes); + size_t bufBytes = IS_VAR_DATA_TYPE(type) ? varDataTLen(out.columnData->pData) + : TMAX(out.columnData->info.bytes, sizeof(int64_t)); + fi->data = taosMemoryCalloc(1, bufBytes); + + size_t valBytes = IS_VAR_DATA_TYPE(type) ? varDataTLen(out.columnData->pData) : out.columnData->info.bytes; + memcpy(fi->data, out.columnData->pData, valBytes); + colDataDestroy(out.columnData); taosMemoryFree(out.columnData); } @@ -2751,6 +2754,7 @@ int32_t filterPostProcessRange(SFilterInfo *info) { } int32_t filterGenerateComInfo(SFilterInfo *info) { + terrno = 0; info->cunits = taosMemoryMalloc(info->unitNum * sizeof(*info->cunits)); info->blkUnitRes = taosMemoryMalloc(sizeof(*info->blkUnitRes) * info->unitNum); info->blkUnits = taosMemoryMalloc(sizeof(*info->blkUnits) * (info->unitNum + 1) * info->groupNum); @@ -2758,7 +2762,7 @@ int32_t filterGenerateComInfo(SFilterInfo *info) { for (uint32_t i = 0; i < info->unitNum; ++i) { SFilterUnit *unit = &info->units[i]; - info->cunits[i].func = filterGetCompFuncIdx(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr); + info->cunits[i].func = filterGetCompFuncIdx(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr); // set terrno if err info->cunits[i].rfunc = filterGetRangeCompFuncFromOptrs(unit->compare.optr, unit->compare.optr2); info->cunits[i].optr = FILTER_UNIT_OPTR(unit); info->cunits[i].colData = NULL; @@ -2779,7 +2783,7 @@ int32_t filterGenerateComInfo(SFilterInfo *info) { info->cunits[i].dataType = FILTER_UNIT_DATA_TYPE(unit); } - return TSDB_CODE_SUCCESS; + return terrno; } int32_t filterUpdateComUnits(SFilterInfo *info) { @@ -3336,6 +3340,7 @@ int32_t filterSetExecFunc(SFilterInfo *info) { } int32_t filterPreprocess(SFilterInfo *info) { + int32_t code = TSDB_CODE_SUCCESS; SFilterGroupCtx **gRes = taosMemoryCalloc(info->groupNum, sizeof(SFilterGroupCtx *)); int32_t gResNum = 0; @@ -3361,7 +3366,7 @@ int32_t filterPreprocess(SFilterInfo *info) { filterRewrite(info, gRes, gResNum); - filterGenerateComInfo(info); + FLT_ERR_JRET(filterGenerateComInfo(info)); _return: @@ -3373,7 +3378,7 @@ _return: taosMemoryFreeClear(gRes); - return TSDB_CODE_SUCCESS; + return code; } int32_t fltSetColFieldDataImpl(SFilterInfo *info, void *param, filer_get_col_from_id fp, bool fromColId) { @@ -3741,10 +3746,10 @@ int32_t fltSclBuildRangeFromBlockSma(SFltSclColumnRange *colRange, SColumnDataAg taosArrayPush(points, &startPt); taosArrayPush(points, &endPt); } - SFltSclDatum min; + SFltSclDatum min = {0}; fltSclBuildDatumFromBlockSmaValue(&min, colRange->colNode->node.resType.type, pAgg->min); SFltSclPoint minPt = {.excl = false, .start = true, .val = min}; - SFltSclDatum max; + SFltSclDatum max = {0}; fltSclBuildDatumFromBlockSmaValue(&max, colRange->colNode->node.resType.type, pAgg->max); SFltSclPoint maxPt = {.excl = false, .start = false, .val = max}; taosArrayPush(points, &minPt); @@ -4290,30 +4295,27 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) { return DEAL_RES_ERROR; } + SColumnNode *refNode = (SColumnNode *)node->pLeft; + SExprNode *exprNode = NULL; if (OP_TYPE_IN != node->opType) { - SColumnNode *refNode = (SColumnNode *)node->pLeft; SValueNode *valueNode = (SValueNode *)node->pRight; if (FILTER_GET_FLAG(stat->info->options, FLT_OPTION_TIMESTAMP) && TSDB_DATA_TYPE_UBIGINT == valueNode->node.resType.type && valueNode->datum.u <= INT64_MAX) { valueNode->node.resType.type = TSDB_DATA_TYPE_BIGINT; } - int32_t type = vectorGetConvertType(refNode->node.resType.type, valueNode->node.resType.type); - if (0 != type && type != refNode->node.resType.type) { - stat->scalarMode = true; - return DEAL_RES_CONTINUE; - } + exprNode = &valueNode->node; } else { - SColumnNode *refNode = (SColumnNode *)node->pLeft; SNodeListNode *listNode = (SNodeListNode *)node->pRight; if (LIST_LENGTH(listNode->pNodeList) > 10) { stat->scalarMode = true; return DEAL_RES_CONTINUE; } - int32_t type = vectorGetConvertType(refNode->node.resType.type, listNode->node.resType.type); - if (0 != type && type != refNode->node.resType.type) { - stat->scalarMode = true; - return DEAL_RES_CONTINUE; - } + exprNode = &listNode->node; + } + int32_t type = vectorGetConvertType(refNode->node.resType.type, exprNode->resType.type); + if (0 != type && type != refNode->node.resType.type) { + stat->scalarMode = true; + return DEAL_RES_CONTINUE; } } @@ -4664,7 +4666,7 @@ bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, SColumnInfoData **p, SC code = scalarCalculate(info->sclCtx.node, pList, &output); taosArrayDestroy(pList); - FLT_ERR_RET(code); + FLT_ERR_RET(code); // TODO: current errcode returns as true *p = output.columnData; diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index b41eba293b..35256d0c96 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -26,6 +26,7 @@ #include "tdataformat.h" #include "ttime.h" #include "ttypes.h" +#include "geosWrapper.h" #define LEFT_COL ((pLeftCol->info.type == TSDB_DATA_TYPE_JSON ? (void *)pLeftCol : pLeftCol->pData)) #define RIGHT_COL ((pRightCol->info.type == TSDB_DATA_TYPE_JSON ? (void *)pRightCol : pRightCol->pData)) @@ -378,6 +379,31 @@ static FORCE_INLINE void ncharToVar(char *buf, SScalarParam *pOut, int32_t rowIn taosMemoryFree(t); } +// todo remove this malloc +static FORCE_INLINE void varToGeometry(char *buf, SScalarParam *pOut, int32_t rowIndex, int32_t *overflow) { + //[ToDo] support to parse WKB as well as WKT + unsigned char *t = NULL; + size_t len = 0; + + if (initCtxGeomFromText()) { + sclError("failed to init geometry ctx"); + return; + } + if (doGeomFromText(buf, &t, &len)) { + sclDebug("failed to convert text to geometry"); + return; + } + + char *output = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE); + memcpy(output + VARSTR_HEADER_SIZE, t, len); + varDataSetLen(output, len); + + colDataSetVal(pOut->columnData, rowIndex, output, false); + + taosMemoryFree(output); + geosFreeBuffer(t); +} + // TODO opt performance, tmp is not needed. int32_t vectorConvertFromVarData(SSclVectorConvCtx *pCtx, int32_t *overflow) { bool vton = false; @@ -401,6 +427,8 @@ int32_t vectorConvertFromVarData(SSclVectorConvCtx *pCtx, int32_t *overflow) { vton = true; } else if (TSDB_DATA_TYPE_TIMESTAMP == pCtx->outType) { func = varToTimestamp; + } else if (TSDB_DATA_TYPE_GEOMETRY == pCtx->outType) { + func = varToGeometry; } else { sclError("invalid convert outType:%d, inType:%d", pCtx->outType, pCtx->inType); return TSDB_CODE_APP_ERROR; @@ -881,7 +909,7 @@ int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut, } int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = { - /* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON GEOM VARB DECI BLOB MEDB*/ + /* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/ /*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 7, 11, 12, 13, 14, 0, 7, 0, 0, 0, 0, /*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 7, 3, 4, 5, 7, 0, 7, 0, 0, 0, 0, @@ -890,7 +918,7 @@ int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = { /*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 7, 5, 5, 5, 7, 0, 7, 0, 0, 0, 0, /*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 7, 6, 7, 6, 6, 6, 6, 0, 7, 0, 0, 0, 0, /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 0, 0, 0, - /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, + /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 0, 0, 0, 0, 20, /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, 7, 0, 0, 0, 0, /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, /*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, 7, 0, 0, 0, 0, diff --git a/source/libs/scheduler/inc/schInt.h b/source/libs/scheduler/inc/schInt.h index 7840fe2017..aecf3d5d91 100644 --- a/source/libs/scheduler/inc/schInt.h +++ b/source/libs/scheduler/inc/schInt.h @@ -57,7 +57,7 @@ typedef enum { #define SCHEDULE_DEFAULT_POLICY SCH_LOAD_SEQ #define SCHEDULE_DEFAULT_MAX_NODE_NUM 20 -#define SCH_DEFAULT_TASK_TIMEOUT_USEC 60000000 +#define SCH_DEFAULT_TASK_TIMEOUT_USEC 5000000 #define SCH_MAX_TASK_TIMEOUT_USEC 300000000 #define SCH_DEFAULT_MAX_RETRY_NUM 6 #define SCH_MIN_AYSNC_EXEC_NUM 3 @@ -239,7 +239,7 @@ typedef struct SSchTask { int32_t lastMsgType; // last sent msg type int64_t timeoutUsec; // task timeout useconds before reschedule SQueryNodeAddr succeedAddr; // task executed success node address - int8_t candidateIdx; // current try condidation index + int32_t candidateIdx; // current try condidation index SArray *candidateAddrs; // condidate node addresses, element is SQueryNodeAddr SHashObj *execNodes; // all tried node for current task, element is SSchNodeInfo SSchTaskProfile profile; // task execution profile diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index 78e28bce49..d4ded2dd8b 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -745,7 +745,6 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { return TSDB_CODE_SUCCESS; } - pTask->candidateIdx = 0; pTask->candidateAddrs = taosArrayInit(SCHEDULE_DEFAULT_MAX_NODE_NUM, sizeof(SQueryNodeAddr)); if (NULL == pTask->candidateAddrs) { SCH_TASK_ELOG("taosArrayInit %d condidate addrs failed", SCHEDULE_DEFAULT_MAX_NODE_NUM); @@ -770,6 +769,8 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) { SCH_ERR_RET(schSetAddrsFromNodeList(pJob, pTask)); + pTask->candidateIdx = taosRand() % taosArrayGetSize(pTask->candidateAddrs); + /* for (int32_t i = 0; i < job->dataSrcEps.numOfEps && addNum < SCH_MAX_CANDIDATE_EP_NUM; ++i) { strncpy(epSet->fqdn[epSet->numOfEps], job->dataSrcEps.fqdn[i], sizeof(job->dataSrcEps.fqdn[i])); diff --git a/source/libs/scheduler/test/CMakeLists.txt b/source/libs/scheduler/test/CMakeLists.txt index ce92886221..703bd5932b 100644 --- a/source/libs/scheduler/test/CMakeLists.txt +++ b/source/libs/scheduler/test/CMakeLists.txt @@ -7,10 +7,18 @@ IF(NOT TD_DARWIN) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) ADD_EXECUTABLE(schedulerTest ${SOURCE_LIST}) - TARGET_LINK_LIBRARIES( - schedulerTest - PUBLIC os util common catalog transport gtest qcom taos_static planner scheduler - ) + + IF (TD_GRANT) + TARGET_LINK_LIBRARIES( + schedulerTest + PUBLIC os util common catalog transport gtest qcom taos_static planner scheduler grant + ) + ELSE () + TARGET_LINK_LIBRARIES( + schedulerTest + PUBLIC os util common catalog transport gtest qcom taos_static planner scheduler + ) + ENDIF() TARGET_INCLUDE_DIRECTORIES( schedulerTest diff --git a/source/libs/stream/inc/streamBackendRocksdb.h b/source/libs/stream/inc/streamBackendRocksdb.h index e60ef55902..28b7c10117 100644 --- a/source/libs/stream/inc/streamBackendRocksdb.h +++ b/source/libs/stream/inc/streamBackendRocksdb.h @@ -42,10 +42,11 @@ typedef struct { TdThreadMutex cfMutex; SHashObj* cfInst; int64_t defaultCfInit; -} SBackendHandle; +} SBackendWrapper; void* streamBackendInit(const char* path); void streamBackendCleanup(void* arg); +void streamBackendHandleCleanup(void* arg); int32_t streamBackendDoCheckpoint(void* pMeta, const char* path); SListNode* streamBackendAddCompare(void* backend, void* arg); void streamBackendDelCompare(void* backend, void* arg); diff --git a/source/libs/stream/inc/streamInc.h b/source/libs/stream/inc/streamInc.h index c7ee308b61..eec37d7dbb 100644 --- a/source/libs/stream/inc/streamInc.h +++ b/source/libs/stream/inc/streamInc.h @@ -31,8 +31,9 @@ typedef struct { void* timer; } SStreamGlobalEnv; -static SStreamGlobalEnv streamEnv; +extern SStreamGlobalEnv streamEnv; +void streamRetryDispatchStreamBlock(SStreamTask* pTask, int64_t waitDuration); int32_t streamDispatchStreamBlock(SStreamTask* pTask); SStreamDataBlock* createStreamDataFromDispatchMsg(const SStreamDispatchReq* pReq, int32_t blockType, int32_t srcVg); @@ -41,20 +42,20 @@ SStreamDataBlock* createStreamBlockFromResults(SStreamQueueItem* pItem, SStreamT void destroyStreamDataBlock(SStreamDataBlock* pBlock); int32_t streamRetrieveReqToData(const SStreamRetrieveReq* pReq, SStreamDataBlock* pData); -int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* data); - int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock); int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq); +int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData); int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet); -int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId, - SEpSet* pEpSet); +int32_t streamDoDispatchScanHistoryFinishMsg(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId, + SEpSet* pEpSet); SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* pElem); extern int32_t streamBackendId; +extern int32_t streamBackendCfWrapperId; #ifdef __cplusplus } diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 7457b2197e..691d31e64c 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -16,11 +16,13 @@ #include "streamInc.h" #include "ttimer.h" -#define STREAM_TASK_INPUT_QUEUEU_CAPACITY 20480 -#define STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE (50) +#define STREAM_TASK_INPUT_QUEUE_CAPACITY 20480 +#define STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE (30) #define ONE_MB_F (1048576.0) #define QUEUE_MEM_SIZE_IN_MB(_q) (taosQueueMemorySize(_q) / ONE_MB_F) +SStreamGlobalEnv streamEnv; + int32_t streamInit() { int8_t old; while (1) { @@ -36,6 +38,7 @@ int32_t streamInit() { } atomic_store_8(&streamEnv.inited, 1); } + return 0; } @@ -52,17 +55,30 @@ void streamCleanUp() { } } +char* createStreamTaskIdStr(int64_t streamId, int32_t taskId) { + char buf[128] = {0}; + sprintf(buf, "0x%" PRIx64 "-0x%x", streamId, taskId); + return taosStrdup(buf); +} + void streamSchedByTimer(void* param, void* tmrId) { SStreamTask* pTask = (void*)param; + int8_t status = atomic_load_8(&pTask->triggerStatus); + qDebug("s-task:%s in scheduler timer, trigger status:%d", pTask->id.idStr, status); + if (streamTaskShouldStop(&pTask->status) || streamTaskShouldPause(&pTask->status)) { streamMetaReleaseTask(NULL, pTask); + qDebug("s-task:%s jump out of schedTimer", pTask->id.idStr); return; } - if (atomic_load_8(&pTask->triggerStatus) == TASK_TRIGGER_STATUS__ACTIVE) { + if (status == TASK_TRIGGER_STATUS__ACTIVE) { SStreamTrigger* trigger = taosAllocateQitem(sizeof(SStreamTrigger), DEF_QITEM, 0); - if (trigger == NULL) return; + if (trigger == NULL) { + return; + } + trigger->type = STREAM_INPUT__GET_RES; trigger->pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); if (trigger->pBlock == NULL) { @@ -75,23 +91,27 @@ void streamSchedByTimer(void* param, void* tmrId) { if (tAppendDataToInputQueue(pTask, (SStreamQueueItem*)trigger) < 0) { taosFreeQitem(trigger); - taosTmrReset(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer, &pTask->timer); + taosTmrReset(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer, &pTask->schedTimer); return; } streamSchedExec(pTask); } - taosTmrReset(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer, &pTask->timer); + taosTmrReset(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer, &pTask->schedTimer); } -int32_t streamSetupTrigger(SStreamTask* pTask) { +int32_t streamSetupScheduleTrigger(SStreamTask* pTask) { if (pTask->triggerParam != 0) { int32_t ref = atomic_add_fetch_32(&pTask->refCnt, 1); - ASSERT(ref == 2); - pTask->timer = taosTmrStart(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer); + ASSERT(ref == 2 && pTask->schedTimer == NULL); + + qDebug("s-task:%s setup scheduler trigger, delay:%"PRId64" ms", pTask->id.idStr, pTask->triggerParam); + + pTask->schedTimer = taosTmrStart(streamSchedByTimer, (int32_t)pTask->triggerParam, pTask, streamEnv.timer); pTask->triggerStatus = TASK_TRIGGER_STATUS__INACTIVE; } + return 0; } @@ -104,16 +124,20 @@ int32_t streamSchedExec(SStreamTask* pTask) { if (pRunReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + qError("failed to create msg to aunch s-task:%s, reason out of memory", pTask->id.idStr); return -1; } - pRunReq->head.vgId = pTask->nodeId; + pRunReq->head.vgId = pTask->info.nodeId; pRunReq->streamId = pTask->id.streamId; pRunReq->taskId = pTask->id.taskId; + qDebug("trigger to run s-task:%s", pTask->id.idStr); + SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)}; tmsgPutToQueue(pTask->pMsgCb, STREAM_QUEUE, &msg); - qDebug("trigger to run s-task:%s", pTask->id.idStr); + } else { + qDebug("s-task:%s not launch task since sched status:%d", pTask->id.idStr, pTask->status.schedStatus); } return 0; @@ -143,7 +167,7 @@ int32_t streamTaskEnqueueBlocks(SStreamTask* pTask, const SStreamDispatchReq* pR pDispatchRsp->streamId = htobe64(pReq->streamId); pDispatchRsp->upstreamNodeId = htonl(pReq->upstreamNodeId); pDispatchRsp->upstreamTaskId = htonl(pReq->upstreamTaskId); - pDispatchRsp->downstreamNodeId = htonl(pTask->nodeId); + pDispatchRsp->downstreamNodeId = htonl(pTask->info.nodeId); pDispatchRsp->downstreamTaskId = htonl(pTask->id.taskId); pRsp->pCont = buf; @@ -159,21 +183,18 @@ int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq, // enqueue if (pData != NULL) { - qDebug("s-task:%s (child %d) recv retrieve req from task:0x%x, reqId %" PRId64, pTask->id.idStr, pTask->selfChildId, - pReq->srcTaskId, pReq->reqId); + qDebug("s-task:%s (child %d) recv retrieve req from task:0x%x(vgId:%d), reqId:0x%" PRIx64, pTask->id.idStr, pTask->info.selfChildId, + pReq->srcTaskId, pReq->srcNodeId, pReq->reqId); pData->type = STREAM_INPUT__DATA_RETRIEVE; pData->srcVgId = 0; - // decode - /*pData->blocks = pReq->data;*/ - /*pBlock->sourceVer = pReq->sourceVer;*/ streamRetrieveReqToData(pReq, pData); if (tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pData) == 0) { status = TASK_INPUT_STATUS__NORMAL; } else { status = TASK_INPUT_STATUS__FAILED; } - } else { + } else { // todo handle oom /*streamTaskInputFail(pTask);*/ /*status = TASK_INPUT_STATUS__FAILED;*/ } @@ -188,6 +209,7 @@ int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq, pRsp->pCont = buf; pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamRetrieveRsp); tmsgSendRsp(pRsp); + return status == TASK_INPUT_STATUS__NORMAL ? 0 : -1; } @@ -232,9 +254,26 @@ int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, S return 0; } +// todo record the idle time for dispatch data int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { + if (code != TSDB_CODE_SUCCESS) { + // dispatch message failed: network error, or node not available. + // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set + // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure + // happened too fast. todo handle the shuffle dispatch failure + qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, + pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); + int32_t ret = streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); + if (ret != TSDB_CODE_SUCCESS) { + + } + + return TSDB_CODE_SUCCESS; + } + qDebug("s-task:%s receive dispatch rsp, output status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, code); + // there are other dispatch message not response yet if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp); @@ -243,23 +282,39 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i } } - int8_t old = atomic_exchange_8(&pTask->outputStatus, pRsp->inputStatus); - ASSERT(old == TASK_OUTPUT_STATUS__WAIT); + pTask->msgInfo.retryCount = 0; + ASSERT(pTask->outputStatus == TASK_OUTPUT_STATUS__WAIT); - // the input queue of the (down stream) task that receive the output data is full, so the TASK_INPUT_STATUS_BLOCKED is rsp - // todo we need to send EMPTY PACKAGE to detect if the input queue is available for output of upstream task, every 50 ms. + qDebug("s-task:%s output status is set to:%d", pTask->id.idStr, pTask->outputStatus); + + // the input queue of the (down stream) task that receive the output data is full, + // so the TASK_INPUT_STATUS_BLOCKED is rsp + // todo blocking the output status if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { - // TODO: init recover timer - qError("s-task:%s inputQ of downstream task:0x%x is full, need to block output", pTask->id.idStr, pRsp->downstreamTaskId); + pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time + int32_t waitDuration = 300; // 300 ms + qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", + pTask->id.idStr, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, waitDuration); + streamRetryDispatchStreamBlock(pTask, waitDuration); + } else { // pipeline send data in output queue + // this message has been sent successfully, let's try next one. + destroyStreamDataBlock(pTask->msgInfo.pData); + pTask->msgInfo.pData = NULL; + + if (pTask->msgInfo.blockingTs != 0) { + int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; + qDebug("s-task:%s resume to normal from inputQ blocking, idle time:%"PRId64"ms", pTask->id.idStr, el); + pTask->msgInfo.blockingTs = 0; + } + + // now ready for next data output atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL); - qError("s-task:%s ignore error, and reset task output status:%d", pTask->id.idStr, pTask->outputStatus); - return 0; + // otherwise, continue dispatch the first block to down stream task in pipeline + streamDispatchStreamBlock(pTask); } - // otherwise, continue dispatch the first block to down stream task in pipeline - streamDispatchStreamBlock(pTask); return 0; } @@ -268,25 +323,23 @@ int32_t streamProcessRunReq(SStreamTask* pTask) { return -1; } - /*if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {*/ + /*if (pTask->dispatchType == TASK_OUTPUT__FIXED_DISPATCH || pTask->dispatchType == TASK_OUTPUT__SHUFFLE_DISPATCH) {*/ /*streamDispatchStreamBlock(pTask);*/ /*}*/ return 0; } int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pRsp) { - qDebug("s-task:%s receive retrieve req from node %d taskId:0x%x", pTask->id.idStr, pReq->srcNodeId, pReq->srcTaskId); streamTaskEnqueueRetrieve(pTask, pReq, pRsp); - - ASSERT(pTask->taskLevel != TASK_LEVEL__SINK); + ASSERT(pTask->info.taskLevel != TASK_LEVEL__SINK); streamSchedExec(pTask); return 0; } bool tInputQueueIsFull(const SStreamTask* pTask) { - bool isFull = taosQueueItemSize((pTask->inputQueue->queue)) >= STREAM_TASK_INPUT_QUEUEU_CAPACITY; + bool isFull = taosQueueItemSize((pTask->inputQueue->queue)) >= STREAM_TASK_INPUT_QUEUE_CAPACITY; double size = QUEUE_MEM_SIZE_IN_MB(pTask->inputQueue->queue); - return (isFull || size >= STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE); + return (isFull || size >= STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE); } int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { @@ -296,9 +349,9 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { if (type == STREAM_INPUT__DATA_SUBMIT) { SStreamDataSubmit* px = (SStreamDataSubmit*)pItem; - if ((pTask->taskLevel == TASK_LEVEL__SOURCE) && tInputQueueIsFull(pTask)) { + if ((pTask->info.taskLevel == TASK_LEVEL__SOURCE) && tInputQueueIsFull(pTask)) { qError("s-task:%s input queue is full, capacity(size:%d num:%dMiB), current(blocks:%d, size:%.2fMiB) stop to push data", - pTask->id.idStr, STREAM_TASK_INPUT_QUEUEU_CAPACITY, STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE, total, + pTask->id.idStr, STREAM_TASK_INPUT_QUEUE_CAPACITY, STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE, total, size); streamDataSubmitDestroy(px); taosFreeQitem(pItem); @@ -316,9 +369,9 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { px->submit.msgLen, px->submit.ver, total, size + px->submit.msgLen/1048576.0); } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE || type == STREAM_INPUT__REF_DATA_BLOCK) { - if ((pTask->taskLevel == TASK_LEVEL__SOURCE) && (tInputQueueIsFull(pTask))) { + if ((pTask->info.taskLevel == TASK_LEVEL__SOURCE) && (tInputQueueIsFull(pTask))) { qError("s-task:%s input queue is full, capacity:%d size:%d MiB, current(blocks:%d, size:%.2fMiB) abort", - pTask->id.idStr, STREAM_TASK_INPUT_QUEUEU_CAPACITY, STREAM_TASK_INPUT_QUEUEU_CAPACITY_IN_SIZE, total, + pTask->id.idStr, STREAM_TASK_INPUT_QUEUE_CAPACITY, STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE, total, size); destroyStreamDataBlock((SStreamDataBlock*) pItem); return -1; @@ -347,19 +400,21 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { 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) { - ASSERT(queue->qItem != NULL); - return streamQueueCurItem(queue); +void* streamQueueNextItem(SStreamQueue* pQueue) { + int8_t flag = atomic_exchange_8(&pQueue->status, STREAM_QUEUE__PROCESSING); + + if (flag == STREAM_QUEUE__FAILED) { + ASSERT(pQueue->qItem != NULL); + return streamQueueCurItem(pQueue); } else { - queue->qItem = NULL; - taosGetQitem(queue->qall, &queue->qItem); - if (queue->qItem == NULL) { - taosReadAllQitems(queue->queue, queue->qall); - taosGetQitem(queue->qall, &queue->qItem); + pQueue->qItem = NULL; + taosGetQitem(pQueue->qall, &pQueue->qItem); + if (pQueue->qItem == NULL) { + taosReadAllQitems(pQueue->queue, pQueue->qall); + taosGetQitem(pQueue->qall, &pQueue->qItem); } - return streamQueueCurItem(queue); + + return streamQueueCurItem(pQueue); } } diff --git a/source/libs/stream/src/streamBackendRocksdb.c b/source/libs/stream/src/streamBackendRocksdb.c index 6b4451f678..41b052ec33 100644 --- a/source/libs/stream/src/streamBackendRocksdb.c +++ b/source/libs/stream/src/streamBackendRocksdb.c @@ -72,7 +72,22 @@ typedef int (*BackendCmpFunc)(void* state, const char* aBuf, size_t aLen, const typedef void (*DestroyFunc)(void* state); typedef int32_t (*EncodeValueFunc)(void* value, int32_t vlen, int64_t ttl, char** dest); typedef int32_t (*DecodeValueFunc)(void* value, int32_t vlen, int64_t* ttl, char** dest); +typedef struct { + const char* key; + int32_t len; + int idx; + BackendCmpFunc cmpFunc; + EncodeFunc enFunc; + DecodeFunc deFunc; + ToStringFunc toStrFunc; + CompareName cmpName; + DestroyFunc detroyFunc; + EncodeValueFunc enValueFunc; + DecodeValueFunc deValueFunc; +} SCfInit; + +#define GEN_COLUMN_FAMILY_NAME(name, idstr, SUFFIX) sprintf(name, "%s_%s", idstr, (SUFFIX)); const char* compareDefaultName(void* name); const char* compareStateName(void* name); const char* compareWinKeyName(void* name); @@ -81,11 +96,67 @@ const char* compareFuncKeyName(void* name); const char* compareParKeyName(void* name); const char* comparePartagKeyName(void* name); +int defaultKeyComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int defaultKeyEncode(void* k, char* buf); +int defaultKeyDecode(void* k, char* buf); +int defaultKeyToString(void* k, char* buf); + +int stateKeyDBComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int stateKeyEncode(void* k, char* buf); +int stateKeyDecode(void* k, char* buf); +int stateKeyToString(void* k, char* buf); + +int stateSessionKeyDBComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int stateSessionKeyEncode(void* ses, char* buf); +int stateSessionKeyDecode(void* ses, char* buf); +int stateSessionKeyToString(void* k, char* buf); + +int winKeyDBComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int winKeyEncode(void* k, char* buf); +int winKeyDecode(void* k, char* buf); +int winKeyToString(void* k, char* buf); + +int tupleKeyDBComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int tupleKeyEncode(void* k, char* buf); +int tupleKeyDecode(void* k, char* buf); +int tupleKeyToString(void* k, char* buf); + +int parKeyDBComp(void* state, const char* aBuf, size_t aLen, const char* bBuf, size_t bLen); +int parKeyEncode(void* k, char* buf); +int parKeyDecode(void* k, char* buf); +int parKeyToString(void* k, char* buf); + +int stremaValueEncode(void* k, char* buf); +int streamValueDecode(void* k, char* buf); +int32_t streamValueToString(void* k, char* buf); +int32_t streaValueIsStale(void* k, int64_t ts); +void destroyFunc(void* arg); + +int32_t encodeValueFunc(void* value, int32_t vlen, int64_t ttl, char** dest); +int32_t decodeValueFunc(void* value, int32_t vlen, int64_t* ttl, char** dest); + +SCfInit ginitDict[] = { + {"default", 7, 0, defaultKeyComp, defaultKeyEncode, defaultKeyDecode, defaultKeyToString, compareDefaultName, + destroyFunc, encodeValueFunc, decodeValueFunc}, + {"state", 5, 1, stateKeyDBComp, stateKeyEncode, stateKeyDecode, stateKeyToString, compareStateName, destroyFunc, + encodeValueFunc, decodeValueFunc}, + {"fill", 4, 2, winKeyDBComp, winKeyEncode, winKeyDecode, winKeyToString, compareWinKeyName, destroyFunc, + encodeValueFunc, decodeValueFunc}, + {"sess", 4, 3, stateSessionKeyDBComp, stateSessionKeyEncode, stateSessionKeyDecode, stateSessionKeyToString, + compareSessionKeyName, destroyFunc, encodeValueFunc, decodeValueFunc}, + {"func", 4, 4, tupleKeyDBComp, tupleKeyEncode, tupleKeyDecode, tupleKeyToString, compareFuncKeyName, destroyFunc, + encodeValueFunc, decodeValueFunc}, + {"parname", 7, 5, parKeyDBComp, parKeyEncode, parKeyDecode, parKeyToString, compareParKeyName, destroyFunc, + encodeValueFunc, decodeValueFunc}, + {"partag", 6, 6, parKeyDBComp, parKeyEncode, parKeyDecode, parKeyToString, comparePartagKeyName, destroyFunc, + encodeValueFunc, decodeValueFunc}, +}; + void* streamBackendInit(const char* path) { uint32_t dbMemLimit = nextPow2(tsMaxStreamBackendCache) << 20; qDebug("start to init stream backend at %s", path); - SBackendHandle* pHandle = taosMemoryCalloc(1, sizeof(SBackendHandle)); + SBackendWrapper* pHandle = taosMemoryCalloc(1, sizeof(SBackendWrapper)); pHandle->list = tdListNew(sizeof(SCfComparator)); taosThreadMutexInit(&pHandle->mutex, NULL); taosThreadMutexInit(&pHandle->cfMutex, NULL); @@ -155,8 +226,8 @@ _EXIT: return NULL; } void streamBackendCleanup(void* arg) { - SBackendHandle* pHandle = (SBackendHandle*)arg; - RocksdbCfInst** pIter = (RocksdbCfInst**)taosHashIterate(pHandle->cfInst, NULL); + SBackendWrapper* pHandle = (SBackendWrapper*)arg; + RocksdbCfInst** pIter = (RocksdbCfInst**)taosHashIterate(pHandle->cfInst, NULL); while (pIter != NULL) { RocksdbCfInst* inst = *pIter; destroyRocksdbCfInst(inst); @@ -195,6 +266,68 @@ void streamBackendCleanup(void* arg) { qDebug("destroy stream backend backend:%p", pHandle); return; } +void streamBackendHandleCleanup(void* arg) { + SBackendCfWrapper* wrapper = arg; + bool remove = wrapper->remove; + qDebug("start to do-close backendwrapper %p, %s", wrapper, wrapper->idstr); + if (wrapper->rocksdb == NULL) { + return; + } + + int cfLen = sizeof(ginitDict) / sizeof(ginitDict[0]); + + char* err = NULL; + if (remove) { + for (int i = 0; i < cfLen; i++) { + if (wrapper->pHandle[i] != NULL) + rocksdb_drop_column_family(wrapper->rocksdb, ((rocksdb_column_family_handle_t**)wrapper->pHandle)[i], &err); + if (err != NULL) { + // qError("failed to create cf:%s_%s, reason:%s", wrapper->idstr, ginitDict[i].key, err); + taosMemoryFreeClear(err); + } + } + } else { + rocksdb_flushoptions_t* flushOpt = rocksdb_flushoptions_create(); + for (int i = 0; i < cfLen; i++) { + if (wrapper->pHandle[i] != NULL) rocksdb_flush_cf(wrapper->rocksdb, flushOpt, wrapper->pHandle[i], &err); + if (err != NULL) { + qError("failed to create cf:%s_%s, reason:%s", wrapper->idstr, ginitDict[i].key, err); + taosMemoryFreeClear(err); + } + } + rocksdb_flushoptions_destroy(flushOpt); + } + + for (int i = 0; i < cfLen; i++) { + if (wrapper->pHandle[i] != NULL) { + rocksdb_column_family_handle_destroy(wrapper->pHandle[i]); + } + } + taosMemoryFreeClear(wrapper->pHandle); + for (int i = 0; i < cfLen; i++) { + rocksdb_options_destroy(wrapper->cfOpts[i]); + rocksdb_block_based_options_destroy(((RocksdbCfParam*)wrapper->param)[i].tableOpt); + } + + if (remove) { + streamBackendDelCompare(wrapper->pBackend, wrapper->pComparNode); + } + rocksdb_writeoptions_destroy(wrapper->writeOpts); + wrapper->writeOpts = NULL; + + rocksdb_readoptions_destroy(wrapper->readOpts); + wrapper->readOpts = NULL; + taosMemoryFreeClear(wrapper->cfOpts); + taosMemoryFreeClear(wrapper->param); + + taosThreadRwlockDestroy(&wrapper->rwLock); + wrapper->rocksdb = NULL; + taosReleaseRef(streamBackendId, wrapper->backendId); + + qDebug("end to do-close backendwrapper %p, %s", wrapper, wrapper->idstr); + taosMemoryFree(wrapper); + return; +} int32_t getLatestCheckpoint(void* arg, int64_t* checkpoint) { SStreamMeta* pMeta = arg; @@ -313,16 +446,16 @@ _ERROR: return code; } SListNode* streamBackendAddCompare(void* backend, void* arg) { - SBackendHandle* pHandle = (SBackendHandle*)backend; - SListNode* node = NULL; + SBackendWrapper* pHandle = (SBackendWrapper*)backend; + SListNode* node = NULL; taosThreadMutexLock(&pHandle->mutex); node = tdListAdd(pHandle->list, arg); taosThreadMutexUnlock(&pHandle->mutex); return node; } void streamBackendDelCompare(void* backend, void* arg) { - SBackendHandle* pHandle = (SBackendHandle*)backend; - SListNode* node = NULL; + SBackendWrapper* pHandle = (SBackendWrapper*)backend; + SListNode* node = NULL; taosThreadMutexLock(&pHandle->mutex); node = tdListPopNode(pHandle->list, arg); taosThreadMutexUnlock(&pHandle->mutex); @@ -660,23 +793,6 @@ void destroyFunc(void* arg) { return; } -typedef struct { - const char* key; - int32_t len; - int idx; - BackendCmpFunc cmpFunc; - EncodeFunc enFunc; - DecodeFunc deFunc; - ToStringFunc toStrFunc; - CompareName cmpName; - DestroyFunc detroyFunc; - EncodeValueFunc enValueFunc; - DecodeValueFunc deValueFunc; - -} SCfInit; - -#define GEN_COLUMN_FAMILY_NAME(name, idstr, SUFFIX) sprintf(name, "%s_%s", idstr, (SUFFIX)); - int32_t encodeValueFunc(void* value, int32_t vlen, int64_t ttl, char** dest) { SStreamValue key = {.unixTimestamp = ttl, .len = vlen, .data = (char*)(value)}; int32_t len = 0; @@ -731,22 +847,6 @@ int32_t decodeValueFunc(void* value, int32_t vlen, int64_t* ttl, char** dest) { } return key.len; } -SCfInit ginitDict[] = { - {"default", 7, 0, defaultKeyComp, defaultKeyEncode, defaultKeyDecode, defaultKeyToString, compareDefaultName, - destroyFunc, encodeValueFunc, decodeValueFunc}, - {"state", 5, 1, stateKeyDBComp, stateKeyEncode, stateKeyDecode, stateKeyToString, compareStateName, destroyFunc, - encodeValueFunc, decodeValueFunc}, - {"fill", 4, 2, winKeyDBComp, winKeyEncode, winKeyDecode, winKeyToString, compareWinKeyName, destroyFunc, - encodeValueFunc, decodeValueFunc}, - {"sess", 4, 3, stateSessionKeyDBComp, stateSessionKeyEncode, stateSessionKeyDecode, stateSessionKeyToString, - compareSessionKeyName, destroyFunc, encodeValueFunc, decodeValueFunc}, - {"func", 4, 4, tupleKeyDBComp, tupleKeyEncode, tupleKeyDecode, tupleKeyToString, compareFuncKeyName, destroyFunc, - encodeValueFunc, decodeValueFunc}, - {"parname", 7, 5, parKeyDBComp, parKeyEncode, parKeyDecode, parKeyToString, compareParKeyName, destroyFunc, - encodeValueFunc, decodeValueFunc}, - {"partag", 6, 6, parKeyDBComp, parKeyEncode, parKeyDecode, parKeyToString, comparePartagKeyName, destroyFunc, - encodeValueFunc, decodeValueFunc}, -}; const char* compareDefaultName(void* arg) { (void)arg; @@ -815,11 +915,11 @@ void destroyRocksdbCfInst(RocksdbCfInst* inst) { } int32_t streamStateOpenBackendCf(void* backend, char* name, char** cfs, int32_t nCf) { - SBackendHandle* handle = backend; - char* err = NULL; - int64_t streamId; - int32_t taskId, dummy = 0; - char suffix[64] = {0}; + SBackendWrapper* handle = backend; + char* err = NULL; + int64_t streamId; + int32_t taskId, dummy = 0; + char suffix[64] = {0}; rocksdb_options_t** cfOpts = taosMemoryCalloc(nCf, sizeof(rocksdb_options_t*)); RocksdbCfParam* params = taosMemoryCalloc(nCf, sizeof(RocksdbCfParam*)); @@ -940,28 +1040,31 @@ int32_t streamStateOpenBackendCf(void* backend, char* name, char** cfs, int32_t } int streamStateOpenBackend(void* backend, SStreamState* pState) { qInfo("start to open state %p on backend %p 0x%" PRIx64 "-%d", pState, backend, pState->streamId, pState->taskId); - void* arg = taosAcquireRef(streamBackendId, pState->streamBackendRid); - if (arg == NULL) { - return -1; - } - - SBackendHandle* handle = backend; - - sprintf(pState->pTdbState->idstr, "0x%" PRIx64 "-%d", pState->streamId, pState->taskId); + taosAcquireRef(streamBackendId, pState->streamBackendRid); + SBackendWrapper* handle = backend; + SBackendCfWrapper* pBackendCfWrapper = taosMemoryCalloc(1, sizeof(SBackendCfWrapper)); taosThreadMutexLock(&handle->cfMutex); + RocksdbCfInst** ppInst = taosHashGet(handle->cfInst, pState->pTdbState->idstr, strlen(pState->pTdbState->idstr) + 1); if (ppInst != NULL && *ppInst != NULL) { RocksdbCfInst* inst = *ppInst; - pState->pTdbState->rocksdb = inst->db; - pState->pTdbState->pHandle = (void**)inst->pHandle; - pState->pTdbState->writeOpts = inst->wOpt; - pState->pTdbState->readOpts = inst->rOpt; - pState->pTdbState->cfOpts = (void**)(inst->cfOpt); - pState->pTdbState->dbOpt = handle->dbOpt; - pState->pTdbState->param = inst->param; - pState->pTdbState->pBackend = handle; - pState->pTdbState->pComparNode = inst->pCompareNode; + pBackendCfWrapper->rocksdb = inst->db; + pBackendCfWrapper->pHandle = (void**)inst->pHandle; + pBackendCfWrapper->writeOpts = inst->wOpt; + pBackendCfWrapper->readOpts = inst->rOpt; + pBackendCfWrapper->cfOpts = (void**)(inst->cfOpt); + pBackendCfWrapper->dbOpt = handle->dbOpt; + pBackendCfWrapper->param = inst->param; + pBackendCfWrapper->pBackend = handle; + pBackendCfWrapper->pComparNode = inst->pCompareNode; taosThreadMutexUnlock(&handle->cfMutex); + pBackendCfWrapper->backendId = pState->streamBackendRid; + memcpy(pBackendCfWrapper->idstr, pState->pTdbState->idstr, sizeof(pState->pTdbState->idstr)); + + int64_t id = taosAddRef(streamBackendCfWrapperId, pBackendCfWrapper); + pState->pTdbState->backendCfWrapperId = id; + pState->pTdbState->pBackendCfWrapper = pBackendCfWrapper; + qInfo("succ to open state %p on backendWrapper, %p, %s", pState, pBackendCfWrapper, pBackendCfWrapper->idstr); return 0; } taosThreadMutexUnlock(&handle->cfMutex); @@ -995,27 +1098,33 @@ int streamStateOpenBackend(void* backend, SStreamState* pState) { pCompare[i] = compare; } rocksdb_column_family_handle_t** cfHandle = taosMemoryCalloc(cfLen, sizeof(rocksdb_column_family_handle_t*)); - pState->pTdbState->rocksdb = handle->db; - pState->pTdbState->pHandle = (void**)cfHandle; - pState->pTdbState->writeOpts = rocksdb_writeoptions_create(); - pState->pTdbState->readOpts = rocksdb_readoptions_create(); - pState->pTdbState->cfOpts = (void**)cfOpt; - pState->pTdbState->dbOpt = handle->dbOpt; - pState->pTdbState->param = param; - pState->pTdbState->pBackend = handle; - - taosThreadRwlockInit(&pState->pTdbState->rwLock, NULL); + pBackendCfWrapper->rocksdb = handle->db; + pBackendCfWrapper->pHandle = (void**)cfHandle; + pBackendCfWrapper->writeOpts = rocksdb_writeoptions_create(); + pBackendCfWrapper->readOpts = rocksdb_readoptions_create(); + pBackendCfWrapper->cfOpts = (void**)cfOpt; + pBackendCfWrapper->dbOpt = handle->dbOpt; + pBackendCfWrapper->param = param; + pBackendCfWrapper->pBackend = handle; + pBackendCfWrapper->backendId = pState->streamBackendRid; + taosThreadRwlockInit(&pBackendCfWrapper->rwLock, NULL); SCfComparator compare = {.comp = pCompare, .numOfComp = cfLen}; - pState->pTdbState->pComparNode = streamBackendAddCompare(handle, &compare); - rocksdb_writeoptions_disable_WAL(pState->pTdbState->writeOpts, 1); - qInfo("succ to open state %p on backend, %p, 0x%" PRIx64 "-%d", pState, handle, pState->streamId, pState->taskId); + pBackendCfWrapper->pComparNode = streamBackendAddCompare(handle, &compare); + rocksdb_writeoptions_disable_WAL(pBackendCfWrapper->writeOpts, 1); + memcpy(pBackendCfWrapper->idstr, pState->pTdbState->idstr, sizeof(pState->pTdbState->idstr)); + + int64_t id = taosAddRef(streamBackendCfWrapperId, pBackendCfWrapper); + pState->pTdbState->backendCfWrapperId = id; + pState->pTdbState->pBackendCfWrapper = pBackendCfWrapper; + qInfo("succ to open state %p on backendWrapper %p %s", pState, pBackendCfWrapper, pBackendCfWrapper->idstr); return 0; } void streamStateCloseBackend(SStreamState* pState, bool remove) { - SBackendHandle* pHandle = pState->pTdbState->pBackend; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SBackendWrapper* pHandle = wrapper->pBackend; taosThreadMutexLock(&pHandle->cfMutex); - RocksdbCfInst** ppInst = taosHashGet(pHandle->cfInst, pState->pTdbState->idstr, strlen(pState->pTdbState->idstr) + 1); + RocksdbCfInst** ppInst = taosHashGet(pHandle->cfInst, wrapper->idstr, strlen(pState->pTdbState->idstr) + 1); if (ppInst != NULL && *ppInst != NULL) { RocksdbCfInst* inst = *ppInst; taosMemoryFree(inst); @@ -1024,63 +1133,10 @@ void streamStateCloseBackend(SStreamState* pState, bool remove) { taosThreadMutexUnlock(&pHandle->cfMutex); char* status[] = {"close", "drop"}; - qInfo("start to close %s state %p on backend %p 0x%" PRIx64 "-%d", status[remove == false ? 0 : 1], pState, pHandle, - pState->streamId, pState->taskId); - if (pState->pTdbState->rocksdb == NULL) { - return; - } - - int cfLen = sizeof(ginitDict) / sizeof(ginitDict[0]); - - char* err = NULL; - if (remove) { - for (int i = 0; i < cfLen; i++) { - if (pState->pTdbState->pHandle[i] != NULL) - rocksdb_drop_column_family(pState->pTdbState->rocksdb, - ((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[i], &err); - if (err != NULL) { - qError("failed to create cf:%s_%s, reason:%s", pState->pTdbState->idstr, ginitDict[i].key, err); - taosMemoryFreeClear(err); - } - } - } else { - rocksdb_flushoptions_t* flushOpt = rocksdb_flushoptions_create(); - for (int i = 0; i < cfLen; i++) { - if (pState->pTdbState->pHandle[i] != NULL) - rocksdb_flush_cf(pState->pTdbState->rocksdb, flushOpt, pState->pTdbState->pHandle[i], &err); - if (err != NULL) { - qError("failed to create cf:%s_%s, reason:%s", pState->pTdbState->idstr, ginitDict[i].key, err); - taosMemoryFreeClear(err); - } - } - rocksdb_flushoptions_destroy(flushOpt); - } - - for (int i = 0; i < cfLen; i++) { - if (pState->pTdbState->pHandle[i] != NULL) { - rocksdb_column_family_handle_destroy(pState->pTdbState->pHandle[i]); - } - } - taosMemoryFreeClear(pState->pTdbState->pHandle); - for (int i = 0; i < cfLen; i++) { - rocksdb_options_destroy(pState->pTdbState->cfOpts[i]); - rocksdb_block_based_options_destroy(((RocksdbCfParam*)pState->pTdbState->param)[i].tableOpt); - } - - if (remove) { - streamBackendDelCompare(pState->pTdbState->pBackend, pState->pTdbState->pComparNode); - } - rocksdb_writeoptions_destroy(pState->pTdbState->writeOpts); - pState->pTdbState->writeOpts = NULL; - - rocksdb_readoptions_destroy(pState->pTdbState->readOpts); - pState->pTdbState->readOpts = NULL; - taosMemoryFreeClear(pState->pTdbState->cfOpts); - taosMemoryFreeClear(pState->pTdbState->param); - - taosThreadRwlockDestroy(&pState->pTdbState->rwLock); - pState->pTdbState->rocksdb = NULL; - taosReleaseRef(streamBackendId, pState->streamBackendRid); + qInfo("start to close %s state %p on backendWrapper %p %s", status[remove == false ? 0 : 1], pState, wrapper, + wrapper->idstr); + wrapper->remove |= remove; // update by other pState + taosReleaseRef(streamBackendCfWrapperId, pState->pTdbState->backendCfWrapperId); } void streamStateDestroyCompar(void* arg) { SCfComparator* comp = (SCfComparator*)arg; @@ -1100,26 +1156,26 @@ int streamStateGetCfIdx(SStreamState* pState, const char* funcName) { } } if (pState != NULL && idx != -1) { + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; rocksdb_column_family_handle_t* cf = NULL; - taosThreadRwlockRdlock(&pState->pTdbState->rwLock); - cf = pState->pTdbState->pHandle[idx]; - taosThreadRwlockUnlock(&pState->pTdbState->rwLock); + taosThreadRwlockRdlock(&wrapper->rwLock); + cf = wrapper->pHandle[idx]; + taosThreadRwlockUnlock(&wrapper->rwLock); if (cf == NULL) { char buf[128] = {0}; - GEN_COLUMN_FAMILY_NAME(buf, pState->pTdbState->idstr, ginitDict[idx].key); + GEN_COLUMN_FAMILY_NAME(buf, wrapper->idstr, ginitDict[idx].key); char* err = NULL; - taosThreadRwlockWrlock(&pState->pTdbState->rwLock); - cf = rocksdb_create_column_family(pState->pTdbState->rocksdb, pState->pTdbState->cfOpts[idx], buf, &err); + taosThreadRwlockWrlock(&wrapper->rwLock); + cf = rocksdb_create_column_family(wrapper->rocksdb, wrapper->cfOpts[idx], buf, &err); if (err != NULL) { idx = -1; - qError("failed to to open cf, %p 0x%" PRIx64 "-%d_%s, reason:%s", pState, pState->streamId, pState->taskId, - funcName, err); + qError("failed to to open cf, %p %s_%s, reason:%s", pState, wrapper->idstr, funcName, err); taosMemoryFree(err); } else { - pState->pTdbState->pHandle[idx] = cf; + wrapper->pHandle[idx] = cf; } - taosThreadRwlockUnlock(&pState->pTdbState->rwLock); + taosThreadRwlockUnlock(&wrapper->rwLock); } } @@ -1139,8 +1195,9 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa rocksdb_readoptions_t** readOpt) { int idx = streamStateGetCfIdx(pState, cfName); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; if (snapshot != NULL) { - *snapshot = (rocksdb_snapshot_t*)rocksdb_create_snapshot(pState->pTdbState->rocksdb); + *snapshot = (rocksdb_snapshot_t*)rocksdb_create_snapshot(wrapper->rocksdb); } rocksdb_readoptions_t* rOpt = rocksdb_readoptions_create(); *readOpt = rOpt; @@ -1148,8 +1205,7 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa rocksdb_readoptions_set_snapshot(rOpt, *snapshot); rocksdb_readoptions_set_fill_cache(rOpt, 0); - return rocksdb_create_iterator_cf(pState->pTdbState->rocksdb, rOpt, - ((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[idx]); + return rocksdb_create_iterator_cf(wrapper->rocksdb, rOpt, ((rocksdb_column_family_handle_t**)wrapper->pHandle)[idx]); } #define STREAM_STATE_PUT_ROCKSDB(pState, funcname, key, value, vLen) \ @@ -1163,15 +1219,15 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa code = -1; \ break; \ } \ - char toString[128] = {0}; \ + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; \ + char toString[128] = {0}; \ if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \ int32_t klen = ginitDict[i].enFunc((void*)key, buf); \ - rocksdb_column_family_handle_t* pHandle = \ - ((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[ginitDict[i].idx]; \ - rocksdb_t* db = pState->pTdbState->rocksdb; \ - rocksdb_writeoptions_t* opts = pState->pTdbState->writeOpts; \ - char* ttlV = NULL; \ - int32_t ttlVLen = ginitDict[i].enValueFunc((char*)value, vLen, 0, &ttlV); \ + rocksdb_column_family_handle_t* pHandle = ((rocksdb_column_family_handle_t**)wrapper->pHandle)[ginitDict[i].idx]; \ + rocksdb_t* db = wrapper->rocksdb; \ + rocksdb_writeoptions_t* opts = wrapper->writeOpts; \ + char* ttlV = NULL; \ + int32_t ttlVLen = ginitDict[i].enValueFunc((char*)value, vLen, 0, &ttlV); \ rocksdb_put_cf(db, opts, pHandle, (const char*)buf, klen, (const char*)ttlV, (size_t)ttlVLen, &err); \ if (err != NULL) { \ taosMemoryFree(err); \ @@ -1183,81 +1239,76 @@ rocksdb_iterator_t* streamStateIterCreate(SStreamState* pState, const char* cfNa taosMemoryFree(ttlV); \ } while (0); -#define STREAM_STATE_GET_ROCKSDB(pState, funcname, key, pVal, vLen) \ - do { \ - code = 0; \ - char buf[128] = {0}; \ - char* err = NULL; \ - int i = streamStateGetCfIdx(pState, funcname); \ - if (i < 0) { \ - qWarn("streamState failed to get cf name: %s", funcname); \ - code = -1; \ - break; \ - } \ - char toString[128] = {0}; \ - if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \ - int32_t klen = ginitDict[i].enFunc((void*)key, buf); \ - rocksdb_column_family_handle_t* pHandle = \ - ((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[ginitDict[i].idx]; \ - rocksdb_t* db = pState->pTdbState->rocksdb; \ - rocksdb_readoptions_t* opts = pState->pTdbState->readOpts; \ - size_t len = 0; \ - char* val = rocksdb_get_cf(db, opts, pHandle, (const char*)buf, klen, (size_t*)&len, &err); \ - if (val == NULL || len == 0) { \ - if (err == NULL) { \ - qTrace("streamState str: %s failed to read from %s_%s, err: not exist", toString, pState->pTdbState->idstr, \ - funcname); \ - } else { \ - qError("streamState str: %s failed to read from %s_%s, err: %s", toString, pState->pTdbState->idstr, funcname, \ - err); \ - taosMemoryFreeClear(err); \ - } \ - code = -1; \ - } else { \ - char* p = NULL; \ - int32_t tlen = ginitDict[i].deValueFunc(val, len, NULL, (char**)pVal); \ - if (tlen <= 0) { \ - qError("streamState str: %s failed to read from %s_%s, err: already ttl ", toString, pState->pTdbState->idstr, \ - funcname); \ - code = -1; \ - } else { \ - qTrace("streamState str: %s succ to read from %s_%s, valLen:%d", toString, pState->pTdbState->idstr, funcname, \ - tlen); \ - } \ - taosMemoryFree(val); \ - if (vLen != NULL) *vLen = tlen; \ - } \ - if (code == 0) \ - qDebug("streamState str: %s succ to read from %s_%s", toString, pState->pTdbState->idstr, funcname); \ +#define STREAM_STATE_GET_ROCKSDB(pState, funcname, key, pVal, vLen) \ + do { \ + code = 0; \ + char buf[128] = {0}; \ + char* err = NULL; \ + int i = streamStateGetCfIdx(pState, funcname); \ + if (i < 0) { \ + qWarn("streamState failed to get cf name: %s", funcname); \ + code = -1; \ + break; \ + } \ + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; \ + char toString[128] = {0}; \ + if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \ + int32_t klen = ginitDict[i].enFunc((void*)key, buf); \ + rocksdb_column_family_handle_t* pHandle = ((rocksdb_column_family_handle_t**)wrapper->pHandle)[ginitDict[i].idx]; \ + rocksdb_t* db = wrapper->rocksdb; \ + rocksdb_readoptions_t* opts = wrapper->readOpts; \ + size_t len = 0; \ + char* val = rocksdb_get_cf(db, opts, pHandle, (const char*)buf, klen, (size_t*)&len, &err); \ + if (val == NULL || len == 0) { \ + if (err == NULL) { \ + qTrace("streamState str: %s failed to read from %s_%s, err: not exist", toString, wrapper->idstr, funcname); \ + } else { \ + qError("streamState str: %s failed to read from %s_%s, err: %s", toString, wrapper->idstr, funcname, err); \ + taosMemoryFreeClear(err); \ + } \ + code = -1; \ + } else { \ + char* p = NULL; \ + int32_t tlen = ginitDict[i].deValueFunc(val, len, NULL, (char**)pVal); \ + if (tlen <= 0) { \ + qError("streamState str: %s failed to read from %s_%s, err: already ttl ", toString, wrapper->idstr, \ + funcname); \ + code = -1; \ + } else { \ + qTrace("streamState str: %s succ to read from %s_%s, valLen:%d", toString, wrapper->idstr, funcname, tlen); \ + } \ + taosMemoryFree(val); \ + if (vLen != NULL) *vLen = tlen; \ + } \ + if (code == 0) qDebug("streamState str: %s succ to read from %s_%s", toString, wrapper->idstr, funcname); \ } while (0); -#define STREAM_STATE_DEL_ROCKSDB(pState, funcname, key) \ - do { \ - code = 0; \ - char buf[128] = {0}; \ - char* err = NULL; \ - int i = streamStateGetCfIdx(pState, funcname); \ - if (i < 0) { \ - qWarn("streamState failed to get cf name: %s_%s", pState->pTdbState->idstr, funcname); \ - code = -1; \ - break; \ - } \ - char toString[128] = {0}; \ - if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \ - int32_t klen = ginitDict[i].enFunc((void*)key, buf); \ - rocksdb_column_family_handle_t* pHandle = \ - ((rocksdb_column_family_handle_t**)pState->pTdbState->pHandle)[ginitDict[i].idx]; \ - rocksdb_t* db = pState->pTdbState->rocksdb; \ - rocksdb_writeoptions_t* opts = pState->pTdbState->writeOpts; \ - rocksdb_delete_cf(db, opts, pHandle, (const char*)buf, klen, &err); \ - if (err != NULL) { \ - qError("streamState str: %s failed to del from %s_%s, err: %s", toString, pState->pTdbState->idstr, funcname, \ - err); \ - taosMemoryFree(err); \ - code = -1; \ - } else { \ - qTrace("streamState str: %s succ to del from %s_%s", toString, pState->pTdbState->idstr, funcname); \ - } \ +#define STREAM_STATE_DEL_ROCKSDB(pState, funcname, key) \ + do { \ + code = 0; \ + char buf[128] = {0}; \ + char* err = NULL; \ + int i = streamStateGetCfIdx(pState, funcname); \ + if (i < 0) { \ + qWarn("streamState failed to get cf name: %s_%s", pState->pTdbState->idstr, funcname); \ + code = -1; \ + break; \ + } \ + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; \ + char toString[128] = {0}; \ + if (qDebugFlag & DEBUG_TRACE) ginitDict[i].toStrFunc((void*)key, toString); \ + int32_t klen = ginitDict[i].enFunc((void*)key, buf); \ + rocksdb_column_family_handle_t* pHandle = ((rocksdb_column_family_handle_t**)wrapper->pHandle)[ginitDict[i].idx]; \ + rocksdb_t* db = wrapper->rocksdb; \ + rocksdb_writeoptions_t* opts = wrapper->writeOpts; \ + rocksdb_delete_cf(db, opts, pHandle, (const char*)buf, klen, &err); \ + if (err != NULL) { \ + qError("streamState str: %s failed to del from %s_%s, err: %s", toString, wrapper->idstr, funcname, err); \ + taosMemoryFree(err); \ + code = -1; \ + } else { \ + qTrace("streamState str: %s succ to del from %s_%s", toString, wrapper->idstr, funcname); \ + } \ } while (0); // state cf @@ -1283,18 +1334,19 @@ int32_t streamStateDel_rocksdb(SStreamState* pState, const SWinKey* key) { int32_t streamStateClear_rocksdb(SStreamState* pState) { qDebug("streamStateClear_rocksdb"); - char sKeyStr[128] = {0}; - char eKeyStr[128] = {0}; - SStateKey sKey = {.key = {.ts = 0, .groupId = 0}, .opNum = pState->number}; - SStateKey eKey = {.key = {.ts = INT64_MAX, .groupId = UINT64_MAX}, .opNum = pState->number}; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + char sKeyStr[128] = {0}; + char eKeyStr[128] = {0}; + SStateKey sKey = {.key = {.ts = 0, .groupId = 0}, .opNum = pState->number}; + SStateKey eKey = {.key = {.ts = INT64_MAX, .groupId = UINT64_MAX}, .opNum = pState->number}; int sLen = stateKeyEncode(&sKey, sKeyStr); int eLen = stateKeyEncode(&eKey, eKeyStr); - if (pState->pTdbState->pHandle[1] != NULL) { + if (wrapper->pHandle[1] != NULL) { char* err = NULL; - rocksdb_delete_range_cf(pState->pTdbState->rocksdb, pState->pTdbState->writeOpts, pState->pTdbState->pHandle[1], - sKeyStr, sLen, eKeyStr, eLen, &err); + rocksdb_delete_range_cf(wrapper->rocksdb, wrapper->writeOpts, wrapper->pHandle[1], sKeyStr, sLen, eKeyStr, eLen, + &err); if (err != NULL) { char toStringStart[128] = {0}; char toStringEnd[128] = {0}; @@ -1304,7 +1356,7 @@ int32_t streamStateClear_rocksdb(SStreamState* pState) { qWarn("failed to delete range cf(state) start: %s, end:%s, reason:%s", toStringStart, toStringEnd, err); taosMemoryFree(err); } else { - rocksdb_compact_range_cf(pState->pTdbState->rocksdb, pState->pTdbState->pHandle[1], sKeyStr, sLen, eKeyStr, eLen); + rocksdb_compact_range_cf(wrapper->rocksdb, wrapper->pHandle[1], sKeyStr, sLen, eKeyStr, eLen); } } @@ -1398,8 +1450,9 @@ SStreamStateCur* streamStateSeekKeyNext_rocksdb(SStreamState* pState, const SWin if (pCur == NULL) { return NULL; } + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; pCur->number = pState->number; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "state", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1432,15 +1485,16 @@ SStreamStateCur* streamStateSeekKeyNext_rocksdb(SStreamState* pState, const SWin SStreamStateCur* streamStateSeekToLast_rocksdb(SStreamState* pState, const SWinKey* key) { qDebug("streamStateGetCur_rocksdb"); - int32_t code = 0; + int32_t code = 0; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + const SStateKey maxStateKey = {.key = {.groupId = UINT64_MAX, .ts = INT64_MAX}, .opNum = INT64_MAX}; STREAM_STATE_PUT_ROCKSDB(pState, "state", &maxStateKey, "", 0); - char buf[128] = {0}; - int32_t klen = stateKeyEncode((void*)&maxStateKey, buf); - + char buf[128] = {0}; + int32_t klen = stateKeyEncode((void*)&maxStateKey, buf); SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) return NULL; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "state", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); rocksdb_iter_seek(pCur->iter, buf, (size_t)klen); @@ -1460,10 +1514,11 @@ SStreamStateCur* streamStateSeekToLast_rocksdb(SStreamState* pState, const SWinK SStreamStateCur* streamStateGetCur_rocksdb(SStreamState* pState, const SWinKey* key) { qDebug("streamStateGetCur_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) return NULL; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "state", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1551,12 +1606,14 @@ int32_t streamStateSessionDel_rocksdb(SStreamState* pState, const SSessionKey* k } SStreamStateCur* streamStateSessionSeekKeyCurrentPrev_rocksdb(SStreamState* pState, const SSessionKey* key) { qDebug("streamStateSessionSeekKeyCurrentPrev_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } pCur->number = pState->number; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "sess", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1592,11 +1649,12 @@ SStreamStateCur* streamStateSessionSeekKeyCurrentPrev_rocksdb(SStreamState* pSta } SStreamStateCur* streamStateSessionSeekKeyCurrentNext_rocksdb(SStreamState* pState, SSessionKey* key) { qDebug("streamStateSessionSeekKeyCurrentNext_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "sess", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); pCur->number = pState->number; @@ -1629,11 +1687,12 @@ SStreamStateCur* streamStateSessionSeekKeyCurrentNext_rocksdb(SStreamState* pSta SStreamStateCur* streamStateSessionSeekKeyNext_rocksdb(SStreamState* pState, const SSessionKey* key) { qDebug("streamStateSessionSeekKeyNext_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "sess", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); pCur->number = pState->number; @@ -1722,11 +1781,12 @@ int32_t streamStateFillDel_rocksdb(SStreamState* pState, const SWinKey* key) { SStreamStateCur* streamStateFillGetCur_rocksdb(SStreamState* pState, const SWinKey* key) { qDebug("streamStateFillGetCur_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; if (pCur == NULL) return NULL; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "fill", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1781,12 +1841,13 @@ int32_t streamStateFillGetKVByCur_rocksdb(SStreamStateCur* pCur, SWinKey* pKey, SStreamStateCur* streamStateFillSeekKeyNext_rocksdb(SStreamState* pState, const SWinKey* key) { qDebug("streamStateFillSeekKeyNext_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (!pCur) { return NULL; } - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "fill", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1817,12 +1878,13 @@ SStreamStateCur* streamStateFillSeekKeyNext_rocksdb(SStreamState* pState, const } SStreamStateCur* streamStateFillSeekKeyPrev_rocksdb(SStreamState* pState, const SWinKey* key) { qDebug("streamStateFillSeekKeyPrev_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return NULL; } - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "fill", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -1853,12 +1915,13 @@ SStreamStateCur* streamStateFillSeekKeyPrev_rocksdb(SStreamState* pState, const } int32_t streamStateSessionGetKeyByRange_rocksdb(SStreamState* pState, const SSessionKey* key, SSessionKey* curKey) { qDebug("streamStateSessionGetKeyByRange_rocksdb"); - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); if (pCur == NULL) { return -1; } pCur->number = pState->number; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "sess", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); @@ -2089,6 +2152,7 @@ int32_t streamDefaultIterGet_rocksdb(SStreamState* pState, const void* start, co int code = 0; char* err = NULL; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; rocksdb_snapshot_t* snapshot = NULL; rocksdb_readoptions_t* readopts = NULL; rocksdb_iterator_t* pIter = streamStateIterCreate(pState, "default", &snapshot, &readopts); @@ -2121,15 +2185,16 @@ int32_t streamDefaultIterGet_rocksdb(SStreamState* pState, const void* start, co } rocksdb_iter_next(pIter); } - rocksdb_release_snapshot(pState->pTdbState->rocksdb, snapshot); + rocksdb_release_snapshot(wrapper->rocksdb, snapshot); rocksdb_readoptions_destroy(readopts); rocksdb_iter_destroy(pIter); return code; } void* streamDefaultIterCreate_rocksdb(SStreamState* pState) { - SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; - pCur->db = pState->pTdbState->rocksdb; + pCur->db = wrapper->rocksdb; pCur->iter = streamStateIterCreate(pState, "default", (rocksdb_snapshot_t**)&pCur->snapshot, (rocksdb_readoptions_t**)&pCur->readOpt); return pCur; @@ -2176,7 +2241,8 @@ void streamStateClearBatch(void* pBatch) { rocksdb_writebatch_clear((rocksdb_ void streamStateDestroyBatch(void* pBatch) { rocksdb_writebatch_destroy((rocksdb_writebatch_t*)pBatch); } int32_t streamStatePutBatch(SStreamState* pState, const char* cfName, rocksdb_writebatch_t* pBatch, void* key, void* val, int32_t vlen, int64_t ttl) { - int i = streamStateGetCfIdx(pState, cfName); + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + int i = streamStateGetCfIdx(pState, cfName); if (i < 0) { qError("streamState failed to put to cf name:%s", cfName); @@ -2187,7 +2253,7 @@ int32_t streamStatePutBatch(SStreamState* pState, const char* cfName, rocksdb_wr char* ttlV = NULL; int32_t ttlVLen = ginitDict[i].enValueFunc(val, vlen, ttl, &ttlV); - rocksdb_column_family_handle_t* pCf = pState->pTdbState->pHandle[ginitDict[i].idx]; + rocksdb_column_family_handle_t* pCf = wrapper->pHandle[ginitDict[i].idx]; rocksdb_writebatch_put_cf((rocksdb_writebatch_t*)pBatch, pCf, buf, (size_t)klen, ttlV, (size_t)ttlVLen); taosMemoryFree(ttlV); return 0; @@ -2199,7 +2265,9 @@ int32_t streamStatePutBatchOptimize(SStreamState* pState, int32_t cfIdx, rocksdb char* ttlV = tmpBuf; int32_t ttlVLen = ginitDict[cfIdx].enValueFunc(val, vlen, ttl, &ttlV); - rocksdb_column_family_handle_t* pCf = pState->pTdbState->pHandle[ginitDict[cfIdx].idx]; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + + rocksdb_column_family_handle_t* pCf = wrapper->pHandle[ginitDict[cfIdx].idx]; rocksdb_writebatch_put_cf((rocksdb_writebatch_t*)pBatch, pCf, buf, (size_t)klen, ttlV, (size_t)ttlVLen); if (tmpBuf == NULL) { @@ -2208,8 +2276,9 @@ int32_t streamStatePutBatchOptimize(SStreamState* pState, int32_t cfIdx, rocksdb return 0; } int32_t streamStatePutBatch_rocksdb(SStreamState* pState, void* pBatch) { - char* err = NULL; - rocksdb_write(pState->pTdbState->rocksdb, pState->pTdbState->writeOpts, (rocksdb_writebatch_t*)pBatch, &err); + char* err = NULL; + SBackendCfWrapper* wrapper = pState->pTdbState->pBackendCfWrapper; + rocksdb_write(wrapper->rocksdb, wrapper->writeOpts, (rocksdb_writebatch_t*)pBatch, &err); if (err != NULL) { qError("streamState failed to write batch, err:%s", err); taosMemoryFree(err); diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index 9294e8da06..83976523c7 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -122,7 +122,7 @@ int32_t tDecodeSStreamCheckpointRsp(SDecoder* pDecoder, SStreamCheckpointRsp* pR static int32_t streamAlignCheckpoint(SStreamTask* pTask, int64_t checkpointId, int32_t childId) { if (pTask->checkpointingId == 0) { pTask->checkpointingId = checkpointId; - pTask->checkpointAlignCnt = taosArrayGetSize(pTask->childEpInfo); + pTask->checkpointAlignCnt = taosArrayGetSize(pTask->pUpstreamEpInfoList); } ASSERT(pTask->checkpointingId == checkpointId); @@ -164,7 +164,7 @@ int32_t streamProcessCheckpointReq(SStreamMeta* pMeta, SStreamTask* pTask, SStre int64_t checkpointId = pReq->checkpointId; int32_t childId = pReq->childId; - if (taosArrayGetSize(pTask->childEpInfo) > 0) { + if (taosArrayGetSize(pTask->pUpstreamEpInfoList) > 0) { code = streamAlignCheckpoint(pTask, checkpointId, childId); if (code > 0) { return 0; diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index 7c06e7deb3..37923ca807 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -64,11 +64,11 @@ SStreamDataBlock* createStreamBlockFromResults(SStreamQueueItem* pItem, SStreamT if (pItem->type == STREAM_INPUT__DATA_SUBMIT) { SStreamDataSubmit* pSubmit = (SStreamDataSubmit*)pItem; - pStreamBlocks->childId = pTask->selfChildId; + pStreamBlocks->childId = pTask->info.selfChildId; pStreamBlocks->sourceVer = pSubmit->ver; } else if (pItem->type == STREAM_INPUT__MERGED_SUBMIT) { SStreamMergedSubmit* pMerged = (SStreamMergedSubmit*)pItem; - pStreamBlocks->childId = pTask->selfChildId; + pStreamBlocks->childId = pTask->info.selfChildId; pStreamBlocks->sourceVer = pMerged->ver; } @@ -164,26 +164,6 @@ int32_t streamMergeSubmit(SStreamMergedSubmit* pMerged, SStreamDataSubmit* pSubm return 0; } -static FORCE_INLINE void streamDataSubmitRefInc(SStreamDataSubmit* pDataSubmit) { - atomic_add_fetch_32(pDataSubmit->dataRef, 1); -} - -SStreamDataSubmit* streamSubmitBlockClone(SStreamDataSubmit* pSubmit) { - int32_t len = 0; - if (pSubmit->type == STREAM_INPUT__DATA_SUBMIT) { - len = pSubmit->submit.msgLen; - } - - SStreamDataSubmit* pSubmitClone = taosAllocateQitem(sizeof(SStreamDataSubmit), DEF_QITEM, len); - if (pSubmitClone == NULL) { - return NULL; - } - - streamDataSubmitRefInc(pSubmit); - memcpy(pSubmitClone, pSubmit, sizeof(SStreamDataSubmit)); - return pSubmitClone; -} - SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* pElem) { if (dst->type == STREAM_INPUT__DATA_BLOCK && pElem->type == STREAM_INPUT__DATA_BLOCK) { SStreamDataBlock* pBlock = (SStreamDataBlock*)dst; diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 7af3219f85..d93de7b1e5 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -13,16 +13,19 @@ * along with this program. If not, see . */ +#include "ttimer.h" #include "streamInc.h" -#define MAX_BLOCK_NAME_NUM 1024 +#define MAX_BLOCK_NAME_NUM 1024 +#define DISPATCH_RETRY_INTERVAL_MS 300 +#define MAX_CONTINUE_RETRY_COUNT 5 typedef struct SBlockName { uint32_t hashValue; char parTbName[TSDB_TABLE_NAME_LEN]; } SBlockName; -int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq) { +static int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq) { if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; @@ -44,6 +47,37 @@ int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* p return pEncoder->pos; } +static int32_t streamAddBlockIntoDispatchMsg(const SSDataBlock* pBlock, SStreamDispatchReq* pReq) { + int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock); + void* buf = taosMemoryCalloc(1, dataStrLen); + if (buf == NULL) return -1; + + SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf; + pRetrieve->useconds = 0; + pRetrieve->precision = TSDB_DEFAULT_PRECISION; + pRetrieve->compressed = 0; + pRetrieve->completed = 1; + pRetrieve->streamBlockType = pBlock->info.type; + pRetrieve->numOfRows = htobe64((int64_t)pBlock->info.rows); + pRetrieve->skey = htobe64(pBlock->info.window.skey); + pRetrieve->ekey = htobe64(pBlock->info.window.ekey); + pRetrieve->version = htobe64(pBlock->info.version); + pRetrieve->watermark = htobe64(pBlock->info.watermark); + memcpy(pRetrieve->parTbName, pBlock->info.parTbName, TSDB_TABLE_NAME_LEN); + + int32_t numOfCols = (int32_t)taosArrayGetSize(pBlock->pDataBlock); + pRetrieve->numOfCols = htonl(numOfCols); + + int32_t actualLen = blockEncode(pBlock, pRetrieve->data, numOfCols); + actualLen += sizeof(SRetrieveTableRsp); + ASSERT(actualLen <= dataStrLen); + taosArrayPush(pReq->dataLen, &actualLen); + taosArrayPush(pReq->data, &buf); + + pReq->totalLen += dataStrLen; + return 0; +} + int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; @@ -72,6 +106,27 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { return 0; } +int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, + int64_t dstTaskId) { + pReq->streamId = pTask->id.streamId; + pReq->dataSrcVgId = vgId; + pReq->upstreamTaskId = pTask->id.taskId; + pReq->upstreamChildId = pTask->info.selfChildId; + pReq->upstreamNodeId = pTask->info.nodeId; + pReq->blockNum = numOfBlocks; + pReq->taskId = dstTaskId; + + pReq->data = taosArrayInit(numOfBlocks, POINTER_BYTES); + pReq->dataLen = taosArrayInit(numOfBlocks, sizeof(int32_t)); + if (pReq->data == NULL || pReq->dataLen == NULL) { + taosArrayDestroyP(pReq->data, taosMemoryFree); + taosArrayDestroy(pReq->dataLen); + return TSDB_CODE_OUT_OF_MEMORY; + } + + return TSDB_CODE_SUCCESS; +} + void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq) { taosArrayDestroyP(pReq->data, taosMemoryFree); taosArrayDestroy(pReq->dataLen); @@ -132,17 +187,17 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) SStreamRetrieveReq req = { .streamId = pTask->id.streamId, - .srcNodeId = pTask->nodeId, + .srcNodeId = pTask->info.nodeId, .srcTaskId = pTask->id.taskId, .pRetrieve = pRetrieve, .retrieveLen = dataStrLen, }; - int32_t sz = taosArrayGetSize(pTask->childEpInfo); + int32_t sz = taosArrayGetSize(pTask->pUpstreamEpInfoList); ASSERT(sz > 0); for (int32_t i = 0; i < sz; i++) { req.reqId = tGenIdPI64(); - SStreamChildEpInfo* pEpInfo = taosArrayGetP(pTask->childEpInfo, i); + SStreamChildEpInfo* pEpInfo = taosArrayGetP(pTask->pUpstreamEpInfoList, i); req.dstNodeId = pEpInfo->nodeId; req.dstTaskId = pEpInfo->taskId; int32_t len; @@ -171,8 +226,8 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) } buf = NULL; - qDebug("s-task:%s (child %d) send retrieve req to task %d at node %d, reqId:0x%" PRIx64, pTask->id.idStr, - pTask->selfChildId, pEpInfo->taskId, pEpInfo->nodeId, req.reqId); + qDebug("s-task:%s (child %d) send retrieve req to task:0x%x (vgId:%d), reqId:0x%" PRIx64, pTask->id.idStr, + pTask->info.selfChildId, pEpInfo->taskId, pEpInfo->nodeId, req.reqId); } code = 0; @@ -182,44 +237,13 @@ CLEAR: return code; } -static int32_t streamAddBlockIntoDispatchMsg(const SSDataBlock* pBlock, SStreamDispatchReq* pReq) { - int32_t dataStrLen = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock); - void* buf = taosMemoryCalloc(1, dataStrLen); - if (buf == NULL) return -1; - - SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)buf; - pRetrieve->useconds = 0; - pRetrieve->precision = TSDB_DEFAULT_PRECISION; - pRetrieve->compressed = 0; - pRetrieve->completed = 1; - pRetrieve->streamBlockType = pBlock->info.type; - pRetrieve->numOfRows = htobe64((int64_t)pBlock->info.rows); - pRetrieve->skey = htobe64(pBlock->info.window.skey); - pRetrieve->ekey = htobe64(pBlock->info.window.ekey); - pRetrieve->version = htobe64(pBlock->info.version); - pRetrieve->watermark = htobe64(pBlock->info.watermark); - memcpy(pRetrieve->parTbName, pBlock->info.parTbName, TSDB_TABLE_NAME_LEN); - - int32_t numOfCols = (int32_t)taosArrayGetSize(pBlock->pDataBlock); - pRetrieve->numOfCols = htonl(numOfCols); - - int32_t actualLen = blockEncode(pBlock, pRetrieve->data, numOfCols); - actualLen += sizeof(SRetrieveTableRsp); - ASSERT(actualLen <= dataStrLen); - taosArrayPush(pReq->dataLen, &actualLen); - taosArrayPush(pReq->data, &buf); - - pReq->totalLen += dataStrLen; - return 0; -} - int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet) { void* buf = NULL; int32_t code = -1; SRpcMsg msg = {0}; int32_t tlen; - tEncodeSize(tEncodeSStreamTaskCheckReq, pReq, tlen, code); + tEncodeSize(tEncodeStreamTaskCheckReq, pReq, tlen, code); if (code < 0) { return -1; } @@ -234,7 +258,7 @@ int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pR SEncoder encoder; tEncoderInit(&encoder, abuf, tlen); - if ((code = tEncodeSStreamTaskCheckReq(&encoder, pReq)) < 0) { + if ((code = tEncodeStreamTaskCheckReq(&encoder, pReq)) < 0) { rpcFreeCont(buf); return code; } @@ -245,21 +269,21 @@ int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pR msg.pCont = buf; msg.msgType = TDMT_STREAM_TASK_CHECK; - qDebug("s-task:%s dispatch check msg to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr, - pReq->streamId, pReq->downstreamTaskId, nodeId); + qDebug("s-task:%s (level:%d) dispatch check msg to s-task:%" PRIx64 ":0x%x (vgId:%d)", pTask->id.idStr, + pTask->info.taskLevel, pReq->streamId, pReq->downstreamTaskId, nodeId); tmsgSendReq(pEpSet, &msg); return 0; } -int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId, - SEpSet* pEpSet) { +int32_t streamDoDispatchScanHistoryFinishMsg(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId, + SEpSet* pEpSet) { void* buf = NULL; int32_t code = -1; SRpcMsg msg = {0}; int32_t tlen; - tEncodeSize(tEncodeSStreamRecoverFinishReq, pReq, tlen, code); + tEncodeSize(tEncodeStreamRecoverFinishReq, pReq, tlen, code); if (code < 0) { return -1; } @@ -275,7 +299,7 @@ int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecov SEncoder encoder; tEncoderInit(&encoder, abuf, tlen); - if ((code = tEncodeSStreamRecoverFinishReq(&encoder, pReq)) < 0) { + if ((code = tEncodeStreamRecoverFinishReq(&encoder, pReq)) < 0) { if (buf) { rpcFreeCont(buf); } @@ -286,17 +310,18 @@ int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecov msg.contLen = tlen + sizeof(SMsgHead); msg.pCont = buf; - msg.msgType = TDMT_STREAM_RECOVER_FINISH; + msg.msgType = TDMT_STREAM_SCAN_HISTORY_FINISH; msg.info.noResp = 1; tmsgSendReq(pEpSet, &msg); - qDebug("s-task:%s dispatch recover finish msg to downstream taskId:0x%x node %d: recover finish msg", pTask->id.idStr, - pReq->taskId, vgId); + const char* pStatus = streamGetTaskStatusStr(pTask->status.taskStatus); + qDebug("s-task:%s status:%s dispatch scan-history-data finish msg to taskId:0x%x (vgId:%d)", pTask->id.idStr, pStatus, + pReq->taskId, vgId); return 0; } -int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* pReq, int32_t vgId, SEpSet* pEpSet) { +static int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* pReq, int32_t vgId, SEpSet* pEpSet) { void* buf = NULL; int32_t code = -1; SRpcMsg msg = {0}; @@ -304,7 +329,10 @@ int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* pReq, in // serialize int32_t tlen; tEncodeSize(tEncodeStreamDispatchReq, pReq, tlen, code); - if (code < 0) goto FAIL; + if (code < 0) { + goto FAIL; + } + code = -1; buf = rpcMallocCont(sizeof(SMsgHead) + tlen); if (buf == NULL) { @@ -323,16 +351,16 @@ int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* pReq, in msg.contLen = tlen + sizeof(SMsgHead); msg.pCont = buf; - msg.msgType = pTask->dispatchMsgType; + msg.msgType = pTask->msgInfo.msgType; qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg", pTask->id.idStr, pReq->taskId, vgId); - tmsgSendReq(pEpSet, &msg); - - code = 0; - return 0; + return tmsgSendReq(pEpSet, &msg); FAIL: - if (buf) rpcFreeCont(buf); + if (buf) { + rpcFreeCont(buf); + } + return code; } @@ -365,8 +393,6 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S snprintf(ctbName, TSDB_TABLE_NAME_LEN, "%s.%s", pTask->shuffleDispatcher.dbInfo.db, pDataBlock->info.parTbName); } - SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; - /*uint32_t hashValue = MurmurHash3_32(ctbName, strlen(ctbName));*/ SUseDbRsp* pDbInfo = &pTask->shuffleDispatcher.dbInfo; hashValue = @@ -386,13 +412,16 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S for (j = 0; j < vgSz; j++) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, j); ASSERT(pVgInfo->vgId > 0); + if (hashValue >= pVgInfo->hashBegin && hashValue <= pVgInfo->hashEnd) { if (streamAddBlockIntoDispatchMsg(pDataBlock, &pReqs[j]) < 0) { return -1; } + if (pReqs[j].blockNum == 0) { atomic_add_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); } + pReqs[j].blockNum++; found = true; break; @@ -404,25 +433,17 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { int32_t code = 0; + int32_t numOfBlocks = taosArrayGetSize(pData->blocks); ASSERT(numOfBlocks != 0); if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { - SStreamDispatchReq req = { - .streamId = pTask->id.streamId, - .dataSrcVgId = pData->srcVgId, - .upstreamTaskId = pTask->id.taskId, - .upstreamChildId = pTask->selfChildId, - .upstreamNodeId = pTask->nodeId, - .blockNum = numOfBlocks, - }; + SStreamDispatchReq req = {0}; - req.data = taosArrayInit(numOfBlocks, sizeof(void*)); - req.dataLen = taosArrayInit(numOfBlocks, sizeof(int32_t)); - if (req.data == NULL || req.dataLen == NULL) { - taosArrayDestroyP(req.data, taosMemoryFree); - taosArrayDestroy(req.dataLen); - return TSDB_CODE_OUT_OF_MEMORY; + int32_t downstreamTaskId = pTask->fixedEpDispatcher.taskId; + code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId); + if (code != TSDB_CODE_SUCCESS) { + return code; } for (int32_t i = 0; i < numOfBlocks; i++) { @@ -438,12 +459,9 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat int32_t vgId = pTask->fixedEpDispatcher.nodeId; SEpSet* pEpSet = &pTask->fixedEpDispatcher.epSet; - int32_t downstreamTaskId = pTask->fixedEpDispatcher.taskId; - req.taskId = downstreamTaskId; - - qDebug("s-task:%s (child taskId:%d) fix-dispatch %d block(s) to down stream s-task:0x%x in vgId:%d", pTask->id.idStr, - pTask->selfChildId, numOfBlocks, downstreamTaskId, vgId); + qDebug("s-task:%s (child taskId:%d) fix-dispatch %d block(s) to s-task:0x%x (vgId:%d)", pTask->id.idStr, + pTask->info.selfChildId, numOfBlocks, downstreamTaskId, vgId); code = doSendDispatchMsg(pTask, &req, vgId, pEpSet); taosArrayDestroyP(req.data, taosMemoryFree); @@ -453,8 +471,9 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat int32_t rspCnt = atomic_load_32(&pTask->shuffleDispatcher.waitingRspCnt); ASSERT(rspCnt == 0); - SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; - int32_t vgSz = taosArrayGetSize(vgInfo); + SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; + int32_t vgSz = taosArrayGetSize(vgInfo); + SStreamDispatchReq* pReqs = taosMemoryCalloc(vgSz, sizeof(SStreamDispatchReq)); if (pReqs == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -462,20 +481,11 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat } for (int32_t i = 0; i < vgSz; i++) { - pReqs[i].streamId = pTask->id.streamId; - pReqs[i].dataSrcVgId = pData->srcVgId; - pReqs[i].upstreamTaskId = pTask->id.taskId; - pReqs[i].upstreamChildId = pTask->selfChildId; - pReqs[i].upstreamNodeId = pTask->nodeId; - pReqs[i].blockNum = 0; - pReqs[i].data = taosArrayInit(0, sizeof(void*)); - pReqs[i].dataLen = taosArrayInit(0, sizeof(int32_t)); - if (pReqs[i].data == NULL || pReqs[i].dataLen == NULL) { + SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); + code = tInitStreamDispatchReq(&pReqs[i], pTask, pData->srcVgId, 0, pVgInfo->taskId); + if (code != TSDB_CODE_SUCCESS) { goto FAIL_SHUFFLE_DISPATCH; } - - SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - pReqs[i].taskId = pVgInfo->taskId; } for (int32_t i = 0; i < numOfBlocks; i++) { @@ -483,15 +493,18 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat // TODO: do not use broadcast if (pDataBlock->info.type == STREAM_DELETE_RESULT) { + for (int32_t j = 0; j < vgSz; j++) { if (streamAddBlockIntoDispatchMsg(pDataBlock, &pReqs[j]) < 0) { goto FAIL_SHUFFLE_DISPATCH; } + if (pReqs[j].blockNum == 0) { atomic_add_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); } pReqs[j].blockNum++; } + continue; } @@ -500,16 +513,17 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat } } - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, pTask->selfChildId, + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, pTask->info.selfChildId, numOfBlocks, vgSz); for (int32_t i = 0; i < vgSz; i++) { if (pReqs[i].blockNum > 0) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, pTask->selfChildId, + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, pTask->info.selfChildId, pReqs[i].blockNum, pVgInfo->vgId); - if (doSendDispatchMsg(pTask, &pReqs[i], pVgInfo->vgId, &pVgInfo->epSet) < 0) { + code = doSendDispatchMsg(pTask, &pReqs[i], pVgInfo->vgId, &pVgInfo->epSet); + if (code < 0) { goto FAIL_SHUFFLE_DISPATCH; } } @@ -522,46 +536,87 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat taosArrayDestroyP(pReqs[i].data, taosMemoryFree); taosArrayDestroy(pReqs[i].dataLen); } + taosMemoryFree(pReqs); } + return code; } +static void doRetryDispatchData(void* param, void* tmrId) { + SStreamTask* pTask = param; + ASSERT(pTask->outputStatus == TASK_OUTPUT_STATUS__WAIT); + + int32_t code = streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); + if (code != TSDB_CODE_SUCCESS) { + qDebug("s-task:%s reset the waitRspCnt to be 0 before launch retry dispatch", pTask->id.idStr); + atomic_store_32(&pTask->shuffleDispatcher.waitingRspCnt, 0); + streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); + } +} + +void streamRetryDispatchStreamBlock(SStreamTask* pTask, int64_t waitDuration) { + qError("s-task:%s dispatch data in %"PRId64"ms", pTask->id.idStr, waitDuration); + taosTmrReset(doRetryDispatchData, waitDuration, pTask, streamEnv.timer, &pTask->launchTaskTimer); +} + int32_t streamDispatchStreamBlock(SStreamTask* pTask) { - ASSERT(pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH); + ASSERT((pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH)); + int32_t numOfElems = taosQueueItemSize(pTask->outputQueue->queue); if (numOfElems > 0) { qDebug("s-task:%s try to dispatch intermediate result block to downstream, elem in outputQ:%d", pTask->id.idStr, numOfElems); } + // to make sure only one dispatch is running int8_t old = atomic_val_compare_exchange_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL, TASK_OUTPUT_STATUS__WAIT); if (old != TASK_OUTPUT_STATUS__NORMAL) { - qDebug("s-task:%s task wait for dispatch rsp, not dispatch now, output status:%d", pTask->id.idStr, old); + qDebug("s-task:%s wait for dispatch rsp, not dispatch now, output status:%d", pTask->id.idStr, old); return 0; } + ASSERT(pTask->msgInfo.pData == NULL); qDebug("s-task:%s start to dispatch msg, set output status:%d", pTask->id.idStr, pTask->outputStatus); - SStreamDataBlock* pDispatchedBlock = streamQueueNextItem(pTask->outputQueue); - if (pDispatchedBlock == NULL) { + SStreamDataBlock* pBlock = streamQueueNextItem(pTask->outputQueue); + if (pBlock == NULL) { atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL); - qDebug("s-task:%s stop dispatching since no output in output queue, output status:%d", pTask->id.idStr, - pTask->outputStatus); + qDebug("s-task:%s not dispatch since no elems in outputQ, output status:%d", pTask->id.idStr, pTask->outputStatus); return 0; } - ASSERT(pDispatchedBlock->type == STREAM_INPUT__DATA_BLOCK); + pTask->msgInfo.pData = pBlock; + ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK); - int32_t code = streamDispatchAllBlocks(pTask, pDispatchedBlock); - if (code != TSDB_CODE_SUCCESS) { - streamQueueProcessFail(pTask->outputQueue); - atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL); - qDebug("s-task:%s failed to dispatch msg to downstream, output status:%d", pTask->id.idStr, pTask->outputStatus); + int32_t retryCount = 0; + + while (1) { + int32_t code = streamDispatchAllBlocks(pTask, pBlock); + if (code == TSDB_CODE_SUCCESS) { + break; + } + + qDebug("s-task:%s failed to dispatch msg to downstream, code:%s, output status:%d, retry cnt:%d", pTask->id.idStr, + tstrerror(terrno), pTask->outputStatus, retryCount); + + // todo deal with only partially success dispatch case + atomic_store_32(&pTask->shuffleDispatcher.waitingRspCnt, 0); + if (terrno == TSDB_CODE_APP_IS_STOPPING) { // in case of this error, do not retry anymore + destroyStreamDataBlock(pTask->msgInfo.pData); + pTask->msgInfo.pData = NULL; + return code; + } + + if (++retryCount > MAX_CONTINUE_RETRY_COUNT) { // add to timer to retry + qDebug("s-task:%s failed to dispatch msg to downstream for %d times, code:%s, add timer to retry in %dms", pTask->id.idStr, + retryCount, tstrerror(terrno), DISPATCH_RETRY_INTERVAL_MS); + streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); + break; + } } - // this block can be freed only when it has been pushed to down stream. - destroyStreamDataBlock(pDispatchedBlock); - return code; + // this block can not be deleted until it has been sent to downstream task successfully. + return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 46290c306f..6e1804b08e 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -108,10 +108,11 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i assignOneDataBlock(&block, taosArrayGet(pRetrieveBlock->blocks, 0)); block.info.type = STREAM_PULL_OVER; - block.info.childId = pTask->selfChildId; + block.info.childId = pTask->info.selfChildId; taosArrayPush(pRes, &block); numOfBlocks += 1; - qDebug("s-task:%s(child %d) processed retrieve, reqId:0x%" PRIx64, pTask->id.idStr, pTask->selfChildId, + + qDebug("s-task:%s(child %d) retrieve process completed, reqId:0x%" PRIx64" dump results", pTask->id.idStr, pTask->info.selfChildId, pRetrieveBlock->reqId); } @@ -127,7 +128,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i SSDataBlock block = {0}; assignOneDataBlock(&block, output); - block.info.childId = pTask->selfChildId; + block.info.childId = pTask->info.selfChildId; size += blockDataGetSize(output) + sizeof(SSDataBlock) + sizeof(SColumnInfoData) * blockDataGetNumOfCols(&block); numOfBlocks += 1; @@ -135,7 +136,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i taosArrayPush(pRes, &block); qDebug("s-task:%s (child %d) executed and get %d result blocks, size:%.2fMiB", pTask->id.idStr, - pTask->selfChildId, numOfBlocks, size / 1048576.0); + pTask->info.selfChildId, numOfBlocks, size / 1048576.0); // current output should be dispatched to down stream nodes if (numOfBlocks >= MAX_STREAM_RESULT_DUMP_THRESHOLD) { @@ -164,7 +165,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, SStreamQueueItem* pItem, i int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) { int32_t code = 0; - ASSERT(pTask->taskLevel == TASK_LEVEL__SOURCE); + ASSERT(pTask->info.taskLevel == TASK_LEVEL__SOURCE); void* exec = pTask->exec.pExecutor; qSetStreamOpOpen(exec); @@ -179,7 +180,7 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) { int32_t batchCnt = 0; while (1) { - if (streamTaskShouldStop(&pTask->status) || streamTaskShouldPause(&pTask->status)) { + if (streamTaskShouldStop(&pTask->status)) { taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); return 0; } @@ -189,18 +190,37 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) { if (qExecTask(exec, &output, &ts) < 0) { continue; } + if (output == NULL) { if (qStreamRecoverScanFinished(exec)) { finished = true; } else { qSetStreamOpOpen(exec); + if (streamTaskShouldPause(&pTask->status)) { + SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, 0); + if (qRes == NULL) { + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + qRes->type = STREAM_INPUT__DATA_BLOCK; + qRes->blocks = pRes; + code = streamTaskOutputResultBlock(pTask, qRes); + if (code == TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY) { + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); + taosFreeQitem(qRes); + return code; + } + return 0; + } } break; } SSDataBlock block = {0}; assignOneDataBlock(&block, output); - block.info.childId = pTask->selfChildId; + block.info.childId = pTask->info.selfChildId; taosArrayPush(pRes, &block); batchCnt++; @@ -237,11 +257,6 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) { taosFreeQitem(qRes); return code; } -// -// if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { -// qDebug("s-task:%s scan exec dispatch blocks:%d", pTask->id.idStr, batchCnt); -// streamDispatchStreamBlock(pTask); -// } if (finished) { break; @@ -275,7 +290,7 @@ int32_t streamBatchExec(SStreamTask* pTask, int32_t batchLimit) { return -1; } - if (pTask->taskLevel == TASK_LEVEL__SINK) { + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { ASSERT(((SStreamQueueItem*)pItem)->type == STREAM_INPUT__DATA_BLOCK); streamTaskOutputResultBlock(pTask, (SStreamDataBlock*)pItem); } @@ -317,6 +332,75 @@ int32_t updateCheckPointInfo(SStreamTask* pTask) { return TSDB_CODE_SUCCESS; } +static void waitForTaskIdle(SStreamTask* pTask, SStreamTask* pStreamTask) { + // wait for the stream task to be idle + int64_t st = taosGetTimestampMs(); + + while (!streamTaskIsIdle(pStreamTask)) { + qDebug("s-task:%s level:%d wait for stream task:%s to be idle, check again in 100ms", pTask->id.idStr, + pTask->info.taskLevel, pStreamTask->id.idStr); + taosMsleep(100); + } + + double el = (taosGetTimestampMs() - st) / 1000.0; + if (el > 0) { + qDebug("s-task:%s wait for stream task:%s for %.2fs to handle all data in inputQ", pTask->id.idStr, + pStreamTask->id.idStr, el); + } +} + +static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { + SStreamTask* pStreamTask = streamMetaAcquireTask(pTask->pMeta, pTask->streamTaskId.taskId); + qDebug("s-task:%s scan history task end, update stream task:%s info, transfer exec state", pTask->id.idStr, pStreamTask->id.idStr); + + // todo handle stream task is dropped here + + ASSERT(pStreamTask != NULL && pStreamTask->historyTaskId.taskId == pTask->id.taskId); + STimeWindow* pTimeWindow = &pStreamTask->dataRange.window; + + // here we need to wait for the stream task handle all data in the input queue. + if (pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) { + ASSERT(pStreamTask->status.taskStatus == TASK_STATUS__HALT); + } else { + ASSERT(pStreamTask->status.taskStatus == TASK_STATUS__NORMAL); + pStreamTask->status.taskStatus = TASK_STATUS__HALT; + } + + // wait for the stream task to be idle + waitForTaskIdle(pTask, pStreamTask); + + if (pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) { + // update the scan data range for source task. + qDebug("s-task:%s level:%d stream task window %" PRId64 " - %" PRId64 " update to %" PRId64 " - %" PRId64 + ", status:%s, sched-status:%d", + pStreamTask->id.idStr, TASK_LEVEL__SOURCE, pTimeWindow->skey, pTimeWindow->ekey, INT64_MIN, + pTimeWindow->ekey, streamGetTaskStatusStr(TASK_STATUS__NORMAL), pStreamTask->status.schedStatus); + + // todo transfer state + } else { + // for sink tasks, they are continue to execute, no need to be halt. + // the process should be stopped for a while, during the term of transfer task state. + // OR wait for the inputQ && outputQ of agg tasks are all consumed, and then start the state transfer + qDebug("s-task:%s no need to update time window, for non-source task", pStreamTask->id.idStr); + + // todo transfer state + } + + // expand the query time window for stream scanner + pTimeWindow->skey = INT64_MIN; + qResetStreamInfoTimeWindow(pStreamTask->exec.pExecutor); + + // transfer the ownership of executor state + streamTaskReleaseState(pTask); + streamTaskReloadState(pStreamTask); + + streamSetStatusNormal(pStreamTask); + + streamSchedExec(pStreamTask); + streamMetaReleaseTask(pTask->pMeta, pStreamTask); + return TSDB_CODE_SUCCESS; +} + /** * todo: the batch of blocks should be tuned dynamic, according to the total elapsed time of each batch of blocks, the * appropriate batch of blocks should be handled in 5 to 10 sec. @@ -331,20 +415,23 @@ int32_t streamExecForAll(SStreamTask* pTask) { SStreamQueueItem* pInput = NULL; // merge multiple input data if possible in the input queue. - qDebug("s-task:%s start to extract data block from inputQ", id); + qDebug("s-task:%s start to extract data block from inputQ, status:%s", id, streamGetTaskStatusStr(pTask->status.taskStatus)); while (1) { - if (streamTaskShouldPause(&pTask->status)) { + // downstream task's input queue is blocked, stop immediately + if (streamTaskShouldPause(&pTask->status) || (pTask->outputStatus == TASK_OUTPUT_STATUS__BLOCKED) || + streamTaskShouldStop(&pTask->status)) { if (batchSize > 1) { break; } else { + qDebug("123 %s", pTask->id.idStr); return 0; } } SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); if (qItem == NULL) { - if (pTask->taskLevel == TASK_LEVEL__SOURCE && batchSize < MIN_STREAM_EXEC_BATCH_NUM && times < 5) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && batchSize < MIN_STREAM_EXEC_BATCH_NUM && times < 5) { times++; taosMsleep(10); qDebug("===stream===try again batchSize:%d", batchSize); @@ -358,7 +445,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { if (pInput == NULL) { pInput = qItem; streamQueueProcessSuccess(pTask->inputQueue); - if (pTask->taskLevel == TASK_LEVEL__SINK) { + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { break; } } else { @@ -389,28 +476,20 @@ int32_t streamExecForAll(SStreamTask* pTask) { } if (pInput == NULL) { + if (pTask->info.fillHistory && pTask->status.transferState) { + int32_t code = streamTransferStateToStreamTask(pTask); + } + break; } - if (pTask->taskLevel == TASK_LEVEL__SINK) { + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); qDebug("s-task:%s sink task start to sink %d blocks", id, batchSize); streamTaskOutputResultBlock(pTask, (SStreamDataBlock*)pInput); continue; } - // wait for the task to be ready to go - while (pTask->taskLevel == TASK_LEVEL__SOURCE) { - int8_t status = atomic_load_8(&pTask->status.taskStatus); - if (status != TASK_STATUS__NORMAL && status != TASK_STATUS__PAUSE) { - qError("stream task wait for the end of fill history, s-task:%s, status:%d", id, - atomic_load_8(&pTask->status.taskStatus)); - taosMsleep(100); - } else { - break; - } - } - int64_t st = taosGetTimestampMs(); qDebug("s-task:%s start to process batch of blocks, num:%d", id, batchSize); @@ -423,7 +502,7 @@ int32_t streamExecForAll(SStreamTask* pTask) { const SStreamTrigger* pTrigger = (const SStreamTrigger*)pInput; qSetMultiStreamInput(pExecutor, pTrigger->pBlock, 1, STREAM_INPUT__DATA_BLOCK); } else if (pItem->type == STREAM_INPUT__DATA_SUBMIT) { - ASSERT(pTask->taskLevel == TASK_LEVEL__SOURCE); + ASSERT(pTask->info.taskLevel == TASK_LEVEL__SOURCE); const SStreamDataSubmit* pSubmit = (const SStreamDataSubmit*)pInput; qSetMultiStreamInput(pExecutor, &pSubmit->submit, 1, STREAM_INPUT__DATA_SUBMIT); qDebug("s-task:%s set submit blocks as source block completed, %p %p len:%d ver:%" PRId64, id, pSubmit, @@ -455,14 +534,34 @@ int32_t streamExecForAll(SStreamTask* pTask) { streamTaskExecImpl(pTask, pInput, &resSize, &totalBlocks); double el = (taosGetTimestampMs() - st) / 1000.0; - qDebug("s-task:%s batch of input blocks exec end, elapsed time:%.2fs, result size:%.2fMiB, numOfBlocks:%d", - id, el, resSize / 1048576.0, totalBlocks); + qDebug("s-task:%s batch of (%d)input blocks exec end, elapsed time:%.2fs, result size:%.2fMiB, numOfBlocks:%d", + id, batchSize, el, resSize / 1048576.0, totalBlocks); + streamFreeQitem(pInput); } return 0; } +bool streamTaskIsIdle(const SStreamTask* pTask) { + int32_t numOfItems = taosQueueItemSize(pTask->inputQueue->queue); + if (numOfItems > 0) { + return false; + } + + numOfItems = taosQallItemSize(pTask->inputQueue->qall); + if (numOfItems > 0) { + return false; + } + + // blocked by downstream task + if (pTask->outputStatus == TASK_OUTPUT_STATUS__BLOCKED) { + return false; + } + + return (pTask->status.schedStatus == TASK_SCHED_STATUS__INACTIVE); +} + int32_t streamTryExec(SStreamTask* pTask) { // this function may be executed by multi-threads, so status check is required. int8_t schedStatus = @@ -477,7 +576,8 @@ int32_t streamTryExec(SStreamTask* pTask) { // todo the task should be commit here atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed", pTask->id.idStr); + qDebug("s-task:%s exec completed, status:%s, sched-status:%d", pTask->id.idStr, streamGetTaskStatusStr(pTask->status.taskStatus), + pTask->status.schedStatus); if (!taosQueueEmpty(pTask->inputQueue->queue) && (!streamTaskShouldStop(&pTask->status)) && (!streamTaskShouldPause(&pTask->status))) { @@ -487,3 +587,25 @@ int32_t streamTryExec(SStreamTask* pTask) { return 0; } + +int32_t streamTaskReleaseState(SStreamTask* pTask) { + qDebug("s-task:%s release exec state", pTask->id.idStr); + void* pExecutor = pTask->exec.pExecutor; + if (pExecutor != NULL) { + int32_t code = qStreamOperatorReleaseState(pExecutor); + return code; + } else { + return TSDB_CODE_SUCCESS; + } +} + +int32_t streamTaskReloadState(SStreamTask* pTask) { + qDebug("s-task:%s reload exec state", pTask->id.idStr); + void* pExecutor = pTask->exec.pExecutor; + if (pExecutor != NULL) { + int32_t code = qStreamOperatorReloadState(pExecutor); + return code; + } else { + return TSDB_CODE_SUCCESS; + } +} diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index 09936143e4..dd23cb0f54 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -21,10 +21,18 @@ static TdThreadOnce streamMetaModuleInit = PTHREAD_ONCE_INIT; int32_t streamBackendId = 0; -static void streamMetaEnvInit() { streamBackendId = taosOpenRef(20, streamBackendCleanup); } +int32_t streamBackendCfWrapperId = 0; + +static void streamMetaEnvInit() { + streamBackendId = taosOpenRef(64, streamBackendCleanup); + streamBackendCfWrapperId = taosOpenRef(64, streamBackendHandleCleanup); +} void streamMetaInit() { taosThreadOnce(&streamMetaModuleInit, streamMetaEnvInit); } -void streamMetaCleanup() { taosCloseRef(streamBackendId); } +void streamMetaCleanup() { + taosCloseRef(streamBackendId); + taosCloseRef(streamBackendCfWrapperId); +} SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId) { int32_t code = -1; @@ -93,6 +101,8 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF goto _err; } pMeta->streamBackendRid = taosAddRef(streamBackendId, pMeta->streamBackend); + pMeta->pTaskBackendUnique = + taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); pMeta->checkpointSaved = taosArrayInit(4, sizeof(int64_t)); pMeta->checkpointInUse = taosArrayInit(4, sizeof(int64_t)); pMeta->checkpointCap = 4; @@ -101,6 +111,8 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF taosMemoryFree(streamPath); taosInitRWLatch(&pMeta->lock); + taosThreadMutexInit(&pMeta->backendMutex, NULL); + return pMeta; _err: @@ -131,9 +143,14 @@ void streamMetaClose(SStreamMeta* pMeta) { } SStreamTask* pTask = *(SStreamTask**)pIter; - if (pTask->timer) { - taosTmrStop(pTask->timer); - pTask->timer = NULL; + if (pTask->schedTimer) { + taosTmrStop(pTask->schedTimer); + pTask->schedTimer = NULL; + } + + if (pTask->launchTaskTimer) { + taosTmrStop(pTask->launchTaskTimer); + pTask->launchTaskTimer = NULL; } tFreeStreamTask(pTask); @@ -143,6 +160,8 @@ void streamMetaClose(SStreamMeta* pMeta) { taosRemoveRef(streamBackendId, pMeta->streamBackendRid); pMeta->pTaskList = taosArrayDestroy(pMeta->pTaskList); taosMemoryFree(pMeta->path); + taosThreadMutexDestroy(&pMeta->backendMutex); + taosHashCleanup(pMeta->pTaskBackendUnique); taosArrayDestroy(pMeta->checkpointSaved); taosArrayDestroy(pMeta->checkpointInUse); @@ -274,18 +293,53 @@ void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask) { } void streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) { - taosWLockLatch(&pMeta->lock); + SStreamTask* pTask = NULL; + // pre-delete operation + taosWLockLatch(&pMeta->lock); SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t)); if (ppTask) { - SStreamTask* pTask = *ppTask; + pTask = *ppTask; + atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__DROPPING); + } else { + qDebug("vgId:%d failed to find the task:0x%x, it may be dropped already", pMeta->vgId, taskId); + taosWUnLockLatch(&pMeta->lock); + return; + } + taosWUnLockLatch(&pMeta->lock); + qDebug("s-task:0x%x set task status:%s", taskId, streamGetTaskStatusStr(TASK_STATUS__DROPPING)); + + while(1) { + taosRLockLatch(&pMeta->lock); + ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t)); + + if (ppTask) { + if ((*ppTask)->status.timerActive == 0) { + taosRUnLockLatch(&pMeta->lock); + break; + } + + taosMsleep(10); + qDebug("s-task:%s wait for quit from timer", (*ppTask)->id.idStr); + taosRUnLockLatch(&pMeta->lock); + } else { + taosRUnLockLatch(&pMeta->lock); + break; + } + } + + // let's do delete of stream task + taosWLockLatch(&pMeta->lock); + ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t)); + if (ppTask) { taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t)); tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), pMeta->txn); atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__DROPPING); - int32_t num = taosArrayGetSize(pMeta->pTaskList); + ASSERT(pTask->status.timerActive == 0); + int32_t num = taosArrayGetSize(pMeta->pTaskList); qDebug("s-task:%s set the drop task flag, remain running s-task:%d", pTask->id.idStr, num - 1); for (int32_t i = 0; i < num; ++i) { int32_t* pTaskId = taosArrayGet(pMeta->pTaskList, i); @@ -388,6 +442,7 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) { taosMemoryFree(pTask); continue; } + if (taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, sizeof(void*)) < 0) { tdbFree(pKey); tdbFree(pVal); @@ -396,10 +451,7 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) { return -1; } - if (pTask->fillHistory) { - ASSERT(pTask->status.taskStatus == TASK_STATUS__WAIT_DOWNSTREAM); - streamTaskCheckDownstream(pTask, ver); - } + ASSERT(pTask->status.downstreamReady == 0); } tdbFree(pKey); diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index eb2535782e..9ded58597f 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -14,93 +14,131 @@ */ #include "streamInc.h" +#include "ttimer.h" +#include "wal.h" -int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version) { - qDebug("s-task:%s at node %d launch recover", pTask->id.idStr, pTask->nodeId); +int32_t streamStartRecoverTask(SStreamTask* pTask, int8_t igUntreated) { + SStreamScanHistoryReq req; + streamBuildSourceRecover1Req(pTask, &req, igUntreated); + int32_t len = sizeof(SStreamScanHistoryReq); - if (pTask->taskLevel == TASK_LEVEL__SOURCE) { - atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__RECOVER_PREPARE); - qDebug("s-task:%s set task status:%d and start to recover", pTask->id.idStr, pTask->status.taskStatus); + void* serializedReq = rpcMallocCont(len); + if (serializedReq == NULL) { + return -1; + } - streamSetParamForRecover(pTask); - streamSourceRecoverPrepareStep1(pTask, version); + memcpy(serializedReq, &req, len); - SStreamRecoverStep1Req req; - streamBuildSourceRecover1Req(pTask, &req); - int32_t len = sizeof(SStreamRecoverStep1Req); - - void* serializedReq = rpcMallocCont(len); - if (serializedReq == NULL) { - return -1; - } - - memcpy(serializedReq, &req, len); - - SRpcMsg rpcMsg = { .contLen = len, .pCont = serializedReq, .msgType = TDMT_VND_STREAM_RECOVER_NONBLOCKING_STAGE }; - if (tmsgPutToQueue(pTask->pMsgCb, STREAM_QUEUE, &rpcMsg) < 0) { - /*ASSERT(0);*/ - } - - } else if (pTask->taskLevel == TASK_LEVEL__AGG) { - atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL); - streamSetParamForRecover(pTask); - streamAggRecoverPrepare(pTask); - } else if (pTask->taskLevel == TASK_LEVEL__SINK) { - // sink nodes has no specified operation for fill history - atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL); + SRpcMsg rpcMsg = {.contLen = len, .pCont = serializedReq, .msgType = TDMT_VND_STREAM_SCAN_HISTORY}; + if (tmsgPutToQueue(pTask->pMsgCb, STREAM_QUEUE, &rpcMsg) < 0) { + /*ASSERT(0);*/ } return 0; } -// checkstatus -int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) { - qDebug("s-task:%s in fill history stage, ver:%"PRId64, pTask->id.idStr, version); +const char* streamGetTaskStatusStr(int32_t status) { + switch(status) { + case TASK_STATUS__NORMAL: return "normal"; + case TASK_STATUS__SCAN_HISTORY: return "scan-history"; + case TASK_STATUS__HALT: return "halt"; + case TASK_STATUS__PAUSE: return "paused"; + default:return ""; + } +} + +static int32_t doLaunchScanHistoryTask(SStreamTask* pTask) { + SVersionRange* pRange = &pTask->dataRange.range; + + qDebug("s-task:%s vgId:%d status:%s, start scan-history-data task, verRange:%" PRId64 " - %" PRId64, pTask->id.idStr, + pTask->info.nodeId, streamGetTaskStatusStr(pTask->status.taskStatus), pRange->minVer, pRange->maxVer); + + streamSetParamForScanHistoryData(pTask); + streamSetParamForStreamScannerStep1(pTask, pRange, &pTask->dataRange.window); + + int32_t code = streamStartRecoverTask(pTask, 0); + return code; +} + +int32_t streamTaskLaunchScanHistory(SStreamTask* pTask) { + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { + if (pTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY) { + return doLaunchScanHistoryTask(pTask); + } else { + ASSERT(pTask->status.taskStatus == TASK_STATUS__NORMAL); + qDebug("s-task:%s no need to scan-history-data, status:%s, sched-status:%d, ver:%" PRId64, pTask->id.idStr, + streamGetTaskStatusStr(pTask->status.taskStatus), pTask->status.schedStatus, + walReaderGetCurrentVer(pTask->exec.pWalReader)); + } + } else if (pTask->info.taskLevel == TASK_LEVEL__AGG) { + streamSetStatusNormal(pTask); + streamSetParamForScanHistoryData(pTask); + streamAggRecoverPrepare(pTask); + } else if (pTask->info.taskLevel == TASK_LEVEL__SINK) { + streamSetStatusNormal(pTask); + qDebug("s-task:%s sink task convert to normal immediately", pTask->id.idStr); + } + + return 0; +} + +// check status +int32_t streamTaskCheckDownstreamTasks(SStreamTask* pTask) { + SHistDataRange* pRange = &pTask->dataRange; + STimeWindow* pWindow = &pRange->window; SStreamTaskCheckReq req = { .streamId = pTask->id.streamId, .upstreamTaskId = pTask->id.taskId, - .upstreamNodeId = pTask->nodeId, - .childId = pTask->selfChildId, + .upstreamNodeId = pTask->info.nodeId, + .childId = pTask->info.selfChildId, }; // serialize if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { - req.reqId = tGenIdPI64(); req.downstreamNodeId = pTask->fixedEpDispatcher.nodeId; req.downstreamTaskId = pTask->fixedEpDispatcher.taskId; pTask->checkReqId = req.reqId; - qDebug("s-task:%s at node %d check downstream task:0x%x at node %d", pTask->id.idStr, pTask->nodeId, req.downstreamTaskId, - req.downstreamNodeId); + qDebug("s-task:%s check single downstream task:0x%x(vgId:%d) ver:%" PRId64 "-%" PRId64 " window:%" PRId64 + "-%" PRId64 ", req:0x%" PRIx64, + pTask->id.idStr, req.downstreamTaskId, req.downstreamNodeId, pRange->range.minVer, pRange->range.maxVer, + pWindow->skey, pWindow->ekey, req.reqId); + streamDispatchCheckMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); } else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; int32_t numOfVgs = taosArrayGetSize(vgInfo); - pTask->recoverTryingDownstream = numOfVgs; + pTask->notReadyTasks = numOfVgs; pTask->checkReqIds = taosArrayInit(numOfVgs, sizeof(int64_t)); + qDebug("s-task:%s check %d downstream tasks, ver:%" PRId64 "-%" PRId64 " window:%" PRId64 "-%" PRId64, + pTask->id.idStr, numOfVgs, pRange->range.minVer, pRange->range.maxVer, pWindow->skey, pWindow->ekey); + for (int32_t i = 0; i < numOfVgs; i++) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); req.reqId = tGenIdPI64(); taosArrayPush(pTask->checkReqIds, &req.reqId); req.downstreamNodeId = pVgInfo->vgId; req.downstreamTaskId = pVgInfo->taskId; - qDebug("s-task:%s at node %d check downstream task:0x%x at node %d (shuffle)", pTask->id.idStr, pTask->nodeId, - req.downstreamTaskId, req.downstreamNodeId); + qDebug("s-task:%s (vgId:%d) check downstream task:0x%x (vgId:%d) (shuffle), idx:%d", pTask->id.idStr, pTask->info.nodeId, + req.downstreamTaskId, req.downstreamNodeId, i); streamDispatchCheckMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); } } else { - qDebug("s-task:%s at node %d direct launch recover since no downstream", pTask->id.idStr, pTask->nodeId); - streamTaskLaunchRecover(pTask, version); + pTask->status.downstreamReady = 1; + qDebug("s-task:%s (vgId:%d) no downstream tasks, set downstream checked, try to launch scan-history-data, status:%s", + pTask->id.idStr, pTask->info.nodeId, streamGetTaskStatusStr(pTask->status.taskStatus)); + + streamTaskLaunchScanHistory(pTask); } return 0; } -int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp) { +int32_t streamRecheckDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp) { SStreamTaskCheckReq req = { .reqId = pRsp->reqId, .streamId = pRsp->streamId, @@ -111,7 +149,7 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp .childId = pRsp->childId, }; - qDebug("s-task:%s at node %d check downstream task:0x%x at node %d (recheck)", pTask->id.idStr, pTask->nodeId, + qDebug("s-task:%s (vgId:%d) check downstream task:0x%x (vgId:%d) (recheck)", pTask->id.idStr, pTask->info.nodeId, req.downstreamTaskId, req.downstreamNodeId); if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { @@ -135,11 +173,9 @@ int32_t streamTaskCheckStatus(SStreamTask* pTask) { return atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL? 1:0; } -int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version) { +int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp) { ASSERT(pTask->id.taskId == pRsp->upstreamTaskId); - - qDebug("s-task:%s at node %d recv check rsp from task:0x%x at node %d: status %d", pTask->id.idStr, - pRsp->upstreamNodeId, pRsp->downstreamTaskId, pRsp->downstreamNodeId, pRsp->status); + const char* id = pTask->id.idStr; if (pRsp->status == 1) { if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { @@ -158,146 +194,386 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* return -1; } - int32_t left = atomic_sub_fetch_32(&pTask->recoverTryingDownstream, 1); + int32_t left = atomic_sub_fetch_32(&pTask->notReadyTasks, 1); ASSERT(left >= 0); if (left == 0) { taosArrayDestroy(pTask->checkReqIds); pTask->checkReqIds = NULL; - qDebug("s-task:%s all %d downstream tasks are ready, now enter into recover stage", pTask->id.idStr, numOfReqs); - streamTaskLaunchRecover(pTask, version); + if (pTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY) { + qDebug("s-task:%s all %d downstream tasks are ready, now enter into scan-history-data stage, status:%s", id, numOfReqs, + streamGetTaskStatusStr(pTask->status.taskStatus)); + streamTaskLaunchScanHistory(pTask); + } else { + ASSERT(pTask->status.taskStatus == TASK_STATUS__NORMAL); + qDebug("s-task:%s fixed downstream task is ready, now ready for data from wal, status:%s", id, + streamGetTaskStatusStr(pTask->status.taskStatus)); + } + } else { + int32_t total = taosArrayGetSize(pTask->shuffleDispatcher.dbInfo.pVgroupInfos); + qDebug("s-task:%s (vgId:%d) recv check rsp from task:0x%x (vgId:%d) status:%d, total:%d not ready:%d", id, + pRsp->upstreamNodeId, pRsp->downstreamTaskId, pRsp->downstreamNodeId, pRsp->status, total, left); } } else if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { if (pRsp->reqId != pTask->checkReqId) { return -1; } - streamTaskLaunchRecover(pTask, version); + // set the downstream tasks have been checked flag + ASSERT(pTask->status.downstreamReady == 0); + pTask->status.downstreamReady = 1; + + ASSERT(pTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY || pTask->status.taskStatus == TASK_STATUS__NORMAL); + if (pTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY) { + qDebug("s-task:%s fixed downstream task is ready, now enter into scan-history-data stage, status:%s", id, + streamGetTaskStatusStr(pTask->status.taskStatus)); + streamTaskLaunchScanHistory(pTask); + } else { + qDebug("s-task:%s fixed downstream task is ready, ready for data from inputQ, status:%s", id, + streamGetTaskStatusStr(pTask->status.taskStatus)); + } } else { ASSERT(0); } - } else { // not ready, wait for 100ms and retry - qDebug("s-task:%s downstream taskId:0x%x (vgId:%d) not ready, wait for 100ms and retry", pTask->id.idStr, - pRsp->downstreamTaskId, pRsp->downstreamNodeId); + } else { // not ready, wait for 100ms and retry + qDebug("s-task:%s downstream taskId:0x%x (vgId:%d) not ready, wait for 100ms and retry", id, pRsp->downstreamTaskId, + pRsp->downstreamNodeId); taosMsleep(100); - streamRecheckOneDownstream(pTask, pRsp); + streamRecheckDownstream(pTask, pRsp); } return 0; } // common -int32_t streamSetParamForRecover(SStreamTask* pTask) { - void* exec = pTask->exec.pExecutor; - return qStreamSetParamForRecover(exec); +int32_t streamSetParamForScanHistoryData(SStreamTask* pTask) { + qDebug("s-task:%s set operator option for scan-history-data", pTask->id.idStr); + return qSetStreamOperatorOptionForScanHistory(pTask->exec.pExecutor); } + int32_t streamRestoreParam(SStreamTask* pTask) { - void* exec = pTask->exec.pExecutor; - return qStreamRestoreParam(exec); + qDebug("s-task:%s restore operator param after scan-history-data", pTask->id.idStr); + return qRestoreStreamOperatorOption(pTask->exec.pExecutor); } int32_t streamSetStatusNormal(SStreamTask* pTask) { + qDebug("s-task:%s set task status to be normal, prev:%s", pTask->id.idStr, streamGetTaskStatusStr(pTask->status.taskStatus)); atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL); return 0; } // source -int32_t streamSourceRecoverPrepareStep1(SStreamTask* pTask, int64_t ver) { - void* exec = pTask->exec.pExecutor; - return qStreamSourceRecoverStep1(exec, ver); +int32_t streamSetParamForStreamScannerStep1(SStreamTask* pTask, SVersionRange *pVerRange, STimeWindow* pWindow) { + return qStreamSourceScanParamForHistoryScanStep1(pTask->exec.pExecutor, pVerRange, pWindow); } -int32_t streamBuildSourceRecover1Req(SStreamTask* pTask, SStreamRecoverStep1Req* pReq) { - pReq->msgHead.vgId = pTask->nodeId; +int32_t streamSetParamForStreamScannerStep2(SStreamTask* pTask, SVersionRange *pVerRange, STimeWindow* pWindow) { + return qStreamSourceScanParamForHistoryScanStep2(pTask->exec.pExecutor, pVerRange, pWindow); +} + +int32_t streamBuildSourceRecover1Req(SStreamTask* pTask, SStreamScanHistoryReq* pReq, int8_t igUntreated) { + pReq->msgHead.vgId = pTask->info.nodeId; pReq->streamId = pTask->id.streamId; pReq->taskId = pTask->id.taskId; + pReq->igUntreated = igUntreated; return 0; } -int32_t streamSourceRecoverScanStep1(SStreamTask* pTask) { +int32_t streamSourceScanHistoryData(SStreamTask* pTask) { return streamScanExec(pTask, 100); } -int32_t streamBuildSourceRecover2Req(SStreamTask* pTask, SStreamRecoverStep2Req* pReq) { - pReq->msgHead.vgId = pTask->nodeId; - pReq->streamId = pTask->id.streamId; - pReq->taskId = pTask->id.taskId; - return 0; -} - -int32_t streamSourceRecoverScanStep2(SStreamTask* pTask, int64_t ver) { - void* exec = pTask->exec.pExecutor; - const char* id = pTask->id.idStr; - - int64_t st = taosGetTimestampMs(); - qDebug("s-task:%s recover step2(blocking stage) started", id); - if (qStreamSourceRecoverStep2(exec, ver) < 0) { - } - - int32_t code = streamScanExec(pTask, 100); - - double el = (taosGetTimestampMs() - st) / 1000.0; - qDebug("s-task:%s recover step2(blocking stage) ended, elapsed time:%.2fs", id, el); - - return code; -} - -int32_t streamDispatchRecoverFinishReq(SStreamTask* pTask) { - SStreamRecoverFinishReq req = { .streamId = pTask->id.streamId, .childId = pTask->selfChildId }; +int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask) { + SStreamRecoverFinishReq req = { .streamId = pTask->id.streamId, .childId = pTask->info.selfChildId }; // serialize if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { - qDebug("s-task:%s send recover finish msg to downstream (fix-dispatch) to taskId:%d, status:%d", pTask->id.idStr, - pTask->fixedEpDispatcher.taskId, pTask->status.taskStatus); - req.taskId = pTask->fixedEpDispatcher.taskId; - streamDispatchOneRecoverFinishReq(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); + streamDoDispatchScanHistoryFinishMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); } else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; - int32_t vgSz = taosArrayGetSize(vgInfo); - for (int32_t i = 0; i < vgSz; i++) { + int32_t numOfVgs = taosArrayGetSize(vgInfo); + + qDebug("s-task:%s send scan-history-data complete msg to downstream (shuffle-dispatch) %d tasks, status:%s", pTask->id.idStr, + numOfVgs, streamGetTaskStatusStr(pTask->status.taskStatus)); + for (int32_t i = 0; i < numOfVgs; i++) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); req.taskId = pVgInfo->taskId; - streamDispatchOneRecoverFinishReq(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); + streamDoDispatchScanHistoryFinishMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); } } + + return 0; +} + +static int32_t doDispatchTransferMsg(SStreamTask* pTask, const SStreamTransferReq* pReq, int32_t vgId, SEpSet* pEpSet) { + void* buf = NULL; + int32_t code = -1; + SRpcMsg msg = {0}; + + int32_t tlen; + tEncodeSize(tEncodeStreamRecoverFinishReq, pReq, tlen, code); + if (code < 0) { + return -1; + } + + buf = rpcMallocCont(sizeof(SMsgHead) + tlen); + if (buf == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + ((SMsgHead*)buf)->vgId = htonl(vgId); + void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); + + SEncoder encoder; + tEncoderInit(&encoder, abuf, tlen); + if ((code = tEncodeStreamRecoverFinishReq(&encoder, pReq)) < 0) { + if (buf) { + rpcFreeCont(buf); + } + return code; + } + + tEncoderClear(&encoder); + + msg.contLen = tlen + sizeof(SMsgHead); + msg.pCont = buf; + msg.msgType = TDMT_STREAM_TRANSFER_STATE; + msg.info.noResp = 1; + + tmsgSendReq(pEpSet, &msg); + qDebug("s-task:%s dispatch transfer state msg to taskId:0x%x (vgId:%d)", pTask->id.idStr, pReq->taskId, vgId); + + return 0; +} + +int32_t streamDispatchTransferStateMsg(SStreamTask* pTask) { + SStreamTransferReq req = { .streamId = pTask->id.streamId, .childId = pTask->info.selfChildId }; + + // serialize + if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) { + qDebug("s-task:%s send transfer state msg to downstream (fix-dispatch) to taskId:0x%x, status:%s", pTask->id.idStr, + pTask->fixedEpDispatcher.taskId, streamGetTaskStatusStr(pTask->status.taskStatus)); + + req.taskId = pTask->fixedEpDispatcher.taskId; + doDispatchTransferMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); + } else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) { + SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; + + int32_t numOfVgs = taosArrayGetSize(vgInfo); + for (int32_t i = 0; i < numOfVgs; i++) { + SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); + req.taskId = pVgInfo->taskId; + doDispatchTransferMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); + } + } + return 0; } // agg int32_t streamAggRecoverPrepare(SStreamTask* pTask) { - pTask->recoverWaitingUpstream = taosArrayGetSize(pTask->childEpInfo); - qDebug("s-task:%s wait for %d upstreams", pTask->id.idStr, pTask->recoverWaitingUpstream); + pTask->numOfWaitingUpstream = taosArrayGetSize(pTask->pUpstreamEpInfoList); + qDebug("s-task:%s agg task is ready and wait for %d upstream tasks complete scan-history procedure", pTask->id.idStr, + pTask->numOfWaitingUpstream); return 0; } -int32_t streamAggChildrenRecoverFinish(SStreamTask* pTask) { +int32_t streamAggUpstreamScanHistoryFinish(SStreamTask* pTask) { void* exec = pTask->exec.pExecutor; - if (qStreamRestoreParam(exec) < 0) { + if (qRestoreStreamOperatorOption(exec) < 0) { return -1; } + if (qStreamRecoverFinish(exec) < 0) { return -1; } - streamSetStatusNormal(pTask); + +// streamSetStatusNormal(pTask); return 0; } -int32_t streamProcessRecoverFinishReq(SStreamTask* pTask, int32_t childId) { - if (pTask->taskLevel == TASK_LEVEL__AGG) { - int32_t left = atomic_sub_fetch_32(&pTask->recoverWaitingUpstream, 1); - qDebug("s-task:%s remain unfinished child tasks:%d", pTask->id.idStr, left); +int32_t streamProcessRecoverFinishReq(SStreamTask* pTask, int32_t taskId, int32_t childId) { + if (pTask->info.taskLevel == TASK_LEVEL__AGG) { + int32_t left = atomic_sub_fetch_32(&pTask->numOfWaitingUpstream, 1); ASSERT(left >= 0); + if (left == 0) { - streamAggChildrenRecoverFinish(pTask); + int32_t numOfTasks = taosArrayGetSize(pTask->pUpstreamEpInfoList); + qDebug("s-task:%s all %d upstream tasks finish scan-history data", pTask->id.idStr, numOfTasks); + streamAggUpstreamScanHistoryFinish(pTask); + } else { + qDebug("s-task:%s receive scan-history data finish msg from upstream:0x%x(index:%d), unfinished:%d", + pTask->id.idStr, taskId, childId, left); } + } return 0; } -int32_t tEncodeSStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq* pReq) { +static void doCheckDownstreamStatus(SStreamTask* pTask, SStreamTask* pHTask) { + pHTask->dataRange.range.minVer = 0; + pHTask->dataRange.range.maxVer = pTask->chkInfo.currentVer; + + if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { + qDebug("s-task:%s set the launch condition for fill history s-task:%s, window:%" PRId64 " - %" PRId64 + " ver range:%" PRId64 " - %" PRId64, + pTask->id.idStr, pHTask->id.idStr, pHTask->dataRange.window.skey, pHTask->dataRange.window.ekey, + pHTask->dataRange.range.minVer, pHTask->dataRange.range.maxVer); + } else { + qDebug("s-task:%s no fill history condition for non-source task:%s", pTask->id.idStr, pHTask->id.idStr); + } + + // check if downstream tasks have been ready + streamTaskCheckDownstreamTasks(pHTask); +} + +typedef struct SStreamTaskRetryInfo { + SStreamMeta* pMeta; + int32_t taskId; +} SStreamTaskRetryInfo; + +static void tryLaunchHistoryTask(void* param, void* tmrId) { + SStreamTaskRetryInfo* pInfo = param; + SStreamMeta* pMeta = pInfo->pMeta; + + qDebug("s-task:0x%x in timer to launch related history task", pInfo->taskId); + + taosWLockLatch(&pMeta->lock); + SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &pInfo->taskId, sizeof(int32_t)); + if (ppTask) { + ASSERT((*ppTask)->status.timerActive == 1); + + if (streamTaskShouldStop(&(*ppTask)->status)) { + const char* pStatus = streamGetTaskStatusStr((*ppTask)->status.taskStatus); + qDebug("s-task:%s status:%s quit timer task", (*ppTask)->id.idStr, pStatus); + + (*ppTask)->status.timerActive = 0; + taosWUnLockLatch(&pMeta->lock); + return; + } + } + taosWUnLockLatch(&pMeta->lock); + + SStreamTask* pTask = streamMetaAcquireTask(pMeta, pInfo->taskId); + if (pTask != NULL) { + ASSERT(pTask->status.timerActive == 1); + + // abort the timer if intend to stop task + SStreamTask* pHTask = streamMetaAcquireTask(pMeta, pTask->historyTaskId.taskId); + if (pHTask == NULL && (!streamTaskShouldStop(&pTask->status))) { + const char* pStatus = streamGetTaskStatusStr(pTask->status.taskStatus); + qWarn( + "s-task:%s vgId:%d status:%s failed to launch history task:0x%x, since it may not be built, or have been " + "destroyed, or should stop exec", + pTask->id.idStr, pMeta->vgId, pStatus, pTask->historyTaskId.taskId); + + taosTmrReset(tryLaunchHistoryTask, 100, pInfo, streamEnv.timer, &pTask->launchTaskTimer); + streamMetaReleaseTask(pMeta, pTask); + return; + } + + if (pHTask != NULL) { + doCheckDownstreamStatus(pTask, pHTask); + streamMetaReleaseTask(pMeta, pHTask); + } + + // not in timer anymore + pTask->status.timerActive = 0; + streamMetaReleaseTask(pMeta, pTask); + } else { + qError("s-task:0x%x failed to load task, it may have been destroyed", pInfo->taskId); + } + + taosMemoryFree(pInfo); +} + +// todo fix the bug: 2. race condition +// an fill history task needs to be started. +int32_t streamCheckHistoryTaskDownstrem(SStreamTask* pTask) { + SStreamMeta* pMeta = pTask->pMeta; + int32_t hTaskId = pTask->historyTaskId.taskId; + + // Set the execute conditions, including the query time window and the version range + SStreamTask** pHTask = taosHashGet(pMeta->pTasks, &hTaskId, sizeof(hTaskId)); + if (pHTask == NULL) { + qWarn("s-task:%s vgId:%d failed to launch history task:0x%x, since it is not built yet", pTask->id.idStr, + pMeta->vgId, hTaskId); + + SStreamTaskRetryInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamTaskRetryInfo)); + pInfo->taskId = pTask->id.taskId; + pInfo->pMeta = pTask->pMeta; + + if (pTask->launchTaskTimer == NULL) { + pTask->launchTaskTimer = taosTmrStart(tryLaunchHistoryTask, 100, pInfo, streamEnv.timer); + if (pTask->launchTaskTimer == NULL) { + // todo failed to create timer + } else { + pTask->status.timerActive = 1; // timer is active + qDebug("s-task:%s set timer active flag", pTask->id.idStr); + } + } else { // timer exists + pTask->status.timerActive = 1; + qDebug("s-task:%s set timer active flag, task timer not null", pTask->id.idStr); + taosTmrReset(tryLaunchHistoryTask, 100, pInfo, streamEnv.timer, &pTask->launchTaskTimer); + } + + // try again in 500ms + return TSDB_CODE_SUCCESS; + } + + doCheckDownstreamStatus(pTask, *pHTask); + return TSDB_CODE_SUCCESS; +} + +int32_t streamTaskScanHistoryDataComplete(SStreamTask* pTask) { + SStreamMeta* pMeta = pTask->pMeta; + if (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__DROPPING) { + return 0; + } + + // restore param + int32_t code = streamRestoreParam(pTask); + if (code < 0) { + return -1; + } + + // dispatch recover finish req to all related downstream task + code = streamDispatchScanHistoryFinishMsg(pTask); + if (code < 0) { + return -1; + } + + ASSERT(pTask->status.taskStatus == TASK_STATUS__SCAN_HISTORY); + + // ready to process data from inputQ + streamSetStatusNormal(pTask); + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + + // todo check rsp, commit data + streamMetaSaveTask(pMeta, pTask); + return 0; +} + +bool streamTaskRecoverScanStep1Finished(SStreamTask* pTask) { + void* exec = pTask->exec.pExecutor; + return qStreamRecoverScanStep1Finished(exec); +} + +bool streamTaskRecoverScanStep2Finished(SStreamTask* pTask) { + void* exec = pTask->exec.pExecutor; + return qStreamRecoverScanStep2Finished(exec); +} + +int32_t streamTaskRecoverSetAllStepFinished(SStreamTask* pTask) { + void* exec = pTask->exec.pExecutor; + return qStreamRecoverSetAllStepFinished(exec); +} + +int32_t tEncodeStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq* pReq) { if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pReq->reqId) < 0) return -1; if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; @@ -310,7 +586,7 @@ int32_t tEncodeSStreamTaskCheckReq(SEncoder* pEncoder, const SStreamTaskCheckReq return pEncoder->pos; } -int32_t tDecodeSStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq) { +int32_t tDecodeStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->reqId) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; @@ -323,7 +599,7 @@ int32_t tDecodeSStreamTaskCheckReq(SDecoder* pDecoder, SStreamTaskCheckReq* pReq return 0; } -int32_t tEncodeSStreamTaskCheckRsp(SEncoder* pEncoder, const SStreamTaskCheckRsp* pRsp) { +int32_t tEncodeStreamTaskCheckRsp(SEncoder* pEncoder, const SStreamTaskCheckRsp* pRsp) { if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pRsp->reqId) < 0) return -1; if (tEncodeI64(pEncoder, pRsp->streamId) < 0) return -1; @@ -337,7 +613,7 @@ int32_t tEncodeSStreamTaskCheckRsp(SEncoder* pEncoder, const SStreamTaskCheckRsp return pEncoder->pos; } -int32_t tDecodeSStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp) { +int32_t tDecodeStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pRsp->reqId) < 0) return -1; if (tDecodeI64(pDecoder, &pRsp->streamId) < 0) return -1; @@ -351,7 +627,7 @@ int32_t tDecodeSStreamTaskCheckRsp(SDecoder* pDecoder, SStreamTaskCheckRsp* pRsp return 0; } -int32_t tEncodeSStreamRecoverFinishReq(SEncoder* pEncoder, const SStreamRecoverFinishReq* pReq) { +int32_t tEncodeStreamRecoverFinishReq(SEncoder* pEncoder, const SStreamRecoverFinishReq* pReq) { if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; @@ -359,7 +635,7 @@ int32_t tEncodeSStreamRecoverFinishReq(SEncoder* pEncoder, const SStreamRecoverF tEndEncode(pEncoder); return pEncoder->pos; } -int32_t tDecodeSStreamRecoverFinishReq(SDecoder* pDecoder, SStreamRecoverFinishReq* pReq) { +int32_t tDecodeStreamRecoverFinishReq(SDecoder* pDecoder, SStreamRecoverFinishReq* pReq) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; @@ -367,3 +643,41 @@ int32_t tDecodeSStreamRecoverFinishReq(SDecoder* pDecoder, SStreamRecoverFinishR tEndDecode(pDecoder); return 0; } + +// todo handle race condition, this task may be destroyed +void streamPrepareNdoCheckDownstream(SStreamTask* pTask) { + if (pTask->info.fillHistory) { + qDebug("s-task:%s fill history task, wait for being launched", pTask->id.idStr); + } else { + // calculate the correct start time window, and start the handle the history data for the main task. + if (pTask->historyTaskId.taskId != 0) { + // check downstream tasks for associated scan-history-data tasks + streamCheckHistoryTaskDownstrem(pTask); + + // launch current task + SHistDataRange* pRange = &pTask->dataRange; + int64_t ekey = pRange->window.ekey + 1; + int64_t ver = pRange->range.minVer; + + pRange->window.skey = ekey; + pRange->window.ekey = INT64_MAX; + pRange->range.minVer = 0; + pRange->range.maxVer = ver; + + qDebug("s-task:%s level:%d fill-history task exists, update stream time window:%" PRId64 " - %" PRId64 + ", ver range:%" PRId64 " - %" PRId64, + pTask->id.idStr, pTask->info.taskLevel, pRange->window.skey, pRange->window.ekey, pRange->range.minVer, + pRange->range.maxVer); + } else { + SHistDataRange* pRange = &pTask->dataRange; + qDebug("s-task:%s no associated scan-history task, stream time window:%" PRId64 " - %" PRId64 + ", ver range:%" PRId64 " - %" PRId64, + pTask->id.idStr, pRange->window.skey, pRange->window.ekey, pRange->range.minVer, pRange->range.maxVer); + } + + ASSERT(pTask->status.downstreamReady == 0); + + // check downstream tasks for itself + streamTaskCheckDownstreamTasks(pTask); + } +} diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index d9acbc31d6..9873e7b4c8 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -116,17 +116,33 @@ SStreamState* streamStateOpen(char* path, void* pTask, bool specPath, int32_t sz pState->taskId = pStreamTask->id.taskId; pState->streamId = pStreamTask->id.streamId; + sprintf(pState->pTdbState->idstr, "0x%" PRIx64 "-%d", pState->streamId, pState->taskId); #ifdef USE_ROCKSDB SStreamMeta* pMeta = pStreamTask->pMeta; pState->streamBackendRid = pMeta->streamBackendRid; + // taosWLockLatch(&pMeta->lock); + taosThreadMutexLock(&pMeta->backendMutex); + void* uniqueId = + taosHashGet(pMeta->pTaskBackendUnique, pState->pTdbState->idstr, strlen(pState->pTdbState->idstr) + 1); + if (uniqueId == NULL) { + int code = streamStateOpenBackend(pMeta->streamBackend, pState); + if (code == -1) { + taosReleaseRef(streamBackendId, pState->streamBackendRid); + taosThreadMutexUnlock(&pMeta->backendMutex); + taosMemoryFree(pState); + return NULL; + } + taosHashPut(pMeta->pTaskBackendUnique, pState->pTdbState->idstr, strlen(pState->pTdbState->idstr) + 1, + &pState->pTdbState->backendCfWrapperId, sizeof(pState->pTdbState->backendCfWrapperId)); + } else { + int64_t id = *(int64_t*)uniqueId; + pState->pTdbState->backendCfWrapperId = id; + pState->pTdbState->pBackendCfWrapper = taosAcquireRef(streamBackendCfWrapperId, id); - int code = streamStateOpenBackend(pMeta->streamBackend, pState); - if (code == -1) { - taosReleaseRef(streamBackendId, pMeta->streamBackendRid); - taosMemoryFree(pState); - pState = NULL; + taosAcquireRef(streamBackendId, pState->streamBackendRid); } + taosThreadMutexUnlock(&pMeta->backendMutex); pState->pTdbState->pOwner = pTask; pState->pFileState = NULL; @@ -386,8 +402,8 @@ int32_t streamStateClear(SStreamState* pState) { streamStatePut(pState, &key, NULL, 0); while (1) { SStreamStateCur* pCur = streamStateSeekKeyNext(pState, &key); - SWinKey delKey = {0}; - int32_t code = streamStateGetKVByCur(pCur, &delKey, NULL, 0); + SWinKey delKey = {0}; + int32_t code = streamStateGetKVByCur(pCur, &delKey, NULL, 0); streamStateFreeCur(pCur); if (code == 0) { streamStateDel(pState, &delKey); @@ -499,7 +515,7 @@ int32_t streamStateGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const void** return -1; } const SStateKey* pKTmp = NULL; - int32_t kLen; + int32_t kLen; if (tdbTbcGet(pCur->pCur, (const void**)&pKTmp, &kLen, pVal, pVLen) < 0) { return -1; } @@ -519,7 +535,7 @@ int32_t streamStateFillGetKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const vo return -1; } const SWinKey* pKTmp = NULL; - int32_t kLen; + int32_t kLen; if (tdbTbcGet(pCur->pCur, (const void**)&pKTmp, &kLen, pVal, pVLen) < 0) { return -1; } @@ -536,7 +552,7 @@ int32_t streamStateGetGroupKVByCur(SStreamStateCur* pCur, SWinKey* pKey, const v return -1; } uint64_t groupId = pKey->groupId; - int32_t code = streamStateFillGetKVByCur(pCur, pKey, pVal, pVLen); + int32_t code = streamStateFillGetKVByCur(pCur, pKey, pVal, pVLen); if (code == 0) { if (pKey->groupId == groupId) { return 0; @@ -554,7 +570,7 @@ int32_t streamStateGetFirst(SStreamState* pState, SWinKey* key) { SWinKey tmp = {.ts = 0, .groupId = 0}; streamStatePut(pState, &tmp, NULL, 0); SStreamStateCur* pCur = streamStateSeekKeyNext(pState, &tmp); - int32_t code = streamStateGetKVByCur(pCur, key, NULL, 0); + int32_t code = streamStateGetKVByCur(pCur, key, NULL, 0); streamStateFreeCur(pCur); streamStateDel(pState, &tmp); return code; @@ -594,7 +610,7 @@ SStreamStateCur* streamStateSeekKeyNext(SStreamState* pState, const SWinKey* key } SStateKey sKey = {.key = *key, .opNum = pState->number}; - int32_t c = 0; + int32_t c = 0; if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateKey), &c) < 0) { streamStateFreeCur(pCur); return NULL; @@ -727,9 +743,9 @@ int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVa #else SStreamStateCur* pCur = streamStateSessionSeekKeyCurrentNext(pState, key); - SSessionKey resKey = *key; - void* tmp = NULL; - int32_t code = streamStateSessionGetKVByCur(pCur, &resKey, &tmp, pVLen); + SSessionKey resKey = *key; + void* tmp = NULL; + int32_t code = streamStateSessionGetKVByCur(pCur, &resKey, &tmp, pVLen); if (code == 0) { if (key->win.skey != resKey.win.skey) { code = -1; @@ -746,6 +762,7 @@ int32_t streamStateSessionGet(SStreamState* pState, SSessionKey* key, void** pVa int32_t streamStateSessionDel(SStreamState* pState, const SSessionKey* key) { #ifdef USE_ROCKSDB + qDebug("===stream===delete skey:%" PRId64 ", ekey:%" PRId64 ", groupId:%" PRIu64, key->win.skey,key->win.ekey, key->groupId); return streamStateSessionDel_rocksdb(pState, key); #else SStateSessionKey sKey = {.key = *key, .opNum = pState->number}; @@ -768,7 +785,7 @@ SStreamStateCur* streamStateSessionSeekKeyCurrentPrev(SStreamState* pState, cons } SStateSessionKey sKey = {.key = *key, .opNum = pState->number}; - int32_t c = 0; + int32_t c = 0; if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) { streamStateFreeCur(pCur); return NULL; @@ -799,7 +816,7 @@ SStreamStateCur* streamStateSessionSeekKeyCurrentNext(SStreamState* pState, cons } SStateSessionKey sKey = {.key = *key, .opNum = pState->number}; - int32_t c = 0; + int32_t c = 0; if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) { streamStateFreeCur(pCur); return NULL; @@ -831,7 +848,7 @@ SStreamStateCur* streamStateSessionSeekKeyNext(SStreamState* pState, const SSess } SStateSessionKey sKey = {.key = *key, .opNum = pState->number}; - int32_t c = 0; + int32_t c = 0; if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) { streamStateFreeCur(pCur); return NULL; @@ -855,7 +872,7 @@ int32_t streamStateSessionGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, v return -1; } SStateSessionKey* pKTmp = NULL; - int32_t kLen; + int32_t kLen; if (tdbTbcGet(pCur->pCur, (const void**)&pKTmp, &kLen, (const void**)pVal, pVLen) < 0) { return -1; } @@ -874,13 +891,13 @@ int32_t streamStateSessionClear(SStreamState* pState) { #ifdef USE_ROCKSDB return streamStateSessionClear_rocksdb(pState); #else - SSessionKey key = {.win.skey = 0, .win.ekey = 0, .groupId = 0}; + SSessionKey key = {.win.skey = 0, .win.ekey = 0, .groupId = 0}; SStreamStateCur* pCur = streamStateSessionSeekKeyCurrentNext(pState, &key); while (1) { SSessionKey delKey = {0}; - void* buf = NULL; - int32_t size = 0; - int32_t code = streamStateSessionGetKVByCur(pCur, &delKey, &buf, &size); + void* buf = NULL; + int32_t size = 0; + int32_t code = streamStateSessionGetKVByCur(pCur, &delKey, &buf, &size); if (code == 0 && size > 0) { memset(buf, 0, size); streamStateSessionPut(pState, &delKey, buf, size); @@ -909,14 +926,14 @@ int32_t streamStateSessionGetKeyByRange(SStreamState* pState, const SSessionKey* } SStateSessionKey sKey = {.key = *key, .opNum = pState->number}; - int32_t c = 0; + int32_t c = 0; if (tdbTbcMoveTo(pCur->pCur, &sKey, sizeof(SStateSessionKey), &c) < 0) { streamStateFreeCur(pCur); return -1; } SSessionKey resKey = *key; - int32_t code = streamStateSessionGetKVByCur(pCur, &resKey, NULL, 0); + int32_t code = streamStateSessionGetKVByCur(pCur, &resKey, NULL, 0); if (code == 0 && sessionRangeKeyCmpr(key, &resKey) == 0) { *curKey = resKey; streamStateFreeCur(pCur); @@ -952,19 +969,19 @@ int32_t streamStateSessionAddIfNotExist(SStreamState* pState, SSessionKey* key, return streamStateSessionAddIfNotExist_rocksdb(pState, key, gap, pVal, pVLen); #else // todo refactor - int32_t res = 0; + int32_t res = 0; SSessionKey originKey = *key; SSessionKey searchKey = *key; searchKey.win.skey = key->win.skey - gap; searchKey.win.ekey = key->win.ekey + gap; int32_t valSize = *pVLen; - void* tmp = tdbRealloc(NULL, valSize); + void* tmp = tdbRealloc(NULL, valSize); if (!tmp) { return -1; } SStreamStateCur* pCur = streamStateSessionSeekKeyCurrentPrev(pState, key); - int32_t code = streamStateSessionGetKVByCur(pCur, key, pVal, pVLen); + int32_t code = streamStateSessionGetKVByCur(pCur, key, pVal, pVLen); if (code == 0) { if (sessionRangeKeyCmpr(&searchKey, key) == 0) { memcpy(tmp, *pVal, valSize); @@ -1007,16 +1024,16 @@ int32_t streamStateStateAddIfNotExist(SStreamState* pState, SSessionKey* key, ch #ifdef USE_ROCKSDB return streamStateStateAddIfNotExist_rocksdb(pState, key, pKeyData, keyDataLen, fn, pVal, pVLen); #else - int32_t res = 0; + int32_t res = 0; SSessionKey tmpKey = *key; - int32_t valSize = *pVLen; - void* tmp = tdbRealloc(NULL, valSize); + int32_t valSize = *pVLen; + void* tmp = tdbRealloc(NULL, valSize); if (!tmp) { return -1; } SStreamStateCur* pCur = streamStateSessionSeekKeyCurrentPrev(pState, key); - int32_t code = streamStateSessionGetKVByCur(pCur, key, pVal, pVLen); + int32_t code = streamStateSessionGetKVByCur(pCur, key, pVal, pVLen); if (code == 0) { if (key->win.skey <= tmpKey.win.skey && tmpKey.win.ekey <= key->win.ekey) { memcpy(tmp, *pVal, valSize); @@ -1114,6 +1131,8 @@ int32_t streamStateDeleteCheckPoint(SStreamState* pState, TSKEY mark) { #endif } +void streamStateReloadInfo(SStreamState* pState, TSKEY ts) { streamFileStateReloadInfo(pState->pFileState, ts); } + #if 0 char* streamStateSessionDump(SStreamState* pState) { SStreamStateCur* pCur = taosMemoryCalloc(1, sizeof(SStreamStateCur)); diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c index 5a38fa656b..d0694f72e7 100644 --- a/source/libs/stream/src/streamTask.c +++ b/source/libs/stream/src/streamTask.c @@ -17,9 +17,9 @@ #include "tstream.h" #include "wal.h" -static int32_t mndAddToTaskset(SArray* pArray, SStreamTask* pTask) { +static int32_t addToTaskset(SArray* pArray, SStreamTask* pTask) { int32_t childId = taosArrayGetSize(pArray); - pTask->selfChildId = childId; + pTask->info.selfChildId = childId; taosArrayPush(pArray, &pTask); return 0; } @@ -34,8 +34,8 @@ SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, int8_t fillHisto pTask->id.taskId = tGenIdPI32(); pTask->id.streamId = streamId; - pTask->taskLevel = taskLevel; - pTask->fillHistory = fillHistory; + pTask->info.taskLevel = taskLevel; + pTask->info.fillHistory = fillHistory; pTask->triggerParam = triggerParam; char buf[128] = {0}; @@ -43,10 +43,11 @@ SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, int8_t fillHisto pTask->id.idStr = taosStrdup(buf); pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE; + pTask->status.taskStatus = TASK_STATUS__SCAN_HISTORY; pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL; - mndAddToTaskset(pTaskList, pTask); + addToTaskset(pTaskList, pTask); return pTask; } @@ -72,30 +73,40 @@ int32_t tEncodeStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) { if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pTask->id.streamId) < 0) return -1; if (tEncodeI32(pEncoder, pTask->id.taskId) < 0) return -1; - if (tEncodeI32(pEncoder, pTask->totalLevel) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->taskLevel) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->info.totalLevel) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->info.taskLevel) < 0) return -1; if (tEncodeI8(pEncoder, pTask->outputType) < 0) return -1; - if (tEncodeI16(pEncoder, pTask->dispatchMsgType) < 0) return -1; + if (tEncodeI16(pEncoder, pTask->msgInfo.msgType) < 0) return -1; if (tEncodeI8(pEncoder, pTask->status.taskStatus) < 0) return -1; if (tEncodeI8(pEncoder, pTask->status.schedStatus) < 0) return -1; - if (tEncodeI32(pEncoder, pTask->selfChildId) < 0) return -1; - if (tEncodeI32(pEncoder, pTask->nodeId) < 0) return -1; - if (tEncodeSEpSet(pEncoder, &pTask->epSet) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->info.selfChildId) < 0) return -1; + if (tEncodeI32(pEncoder, pTask->info.nodeId) < 0) return -1; + if (tEncodeSEpSet(pEncoder, &pTask->info.epSet) < 0) return -1; if (tEncodeI64(pEncoder, pTask->chkInfo.id) < 0) return -1; if (tEncodeI64(pEncoder, pTask->chkInfo.version) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->fillHistory) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->info.fillHistory) < 0) return -1; - int32_t epSz = taosArrayGetSize(pTask->childEpInfo); + if (tEncodeI64(pEncoder, pTask->historyTaskId.streamId)) return -1; + if (tEncodeI32(pEncoder, pTask->historyTaskId.taskId)) return -1; + if (tEncodeI64(pEncoder, pTask->streamTaskId.streamId)) return -1; + if (tEncodeI32(pEncoder, pTask->streamTaskId.taskId)) return -1; + + if (tEncodeU64(pEncoder, pTask->dataRange.range.minVer)) return -1; + if (tEncodeU64(pEncoder, pTask->dataRange.range.maxVer)) return -1; + if (tEncodeI64(pEncoder, pTask->dataRange.window.skey)) return -1; + if (tEncodeI64(pEncoder, pTask->dataRange.window.ekey)) return -1; + + int32_t epSz = taosArrayGetSize(pTask->pUpstreamEpInfoList); if (tEncodeI32(pEncoder, epSz) < 0) return -1; for (int32_t i = 0; i < epSz; i++) { - SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->childEpInfo, i); + SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->pUpstreamEpInfoList, i); if (tEncodeStreamEpInfo(pEncoder, pInfo) < 0) return -1; } - if (pTask->taskLevel != TASK_LEVEL__SINK) { + if (pTask->info.taskLevel != TASK_LEVEL__SINK) { if (tEncodeCStr(pEncoder, pTask->exec.qmsg) < 0) return -1; } @@ -125,25 +136,36 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pTask->id.streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pTask->id.taskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pTask->totalLevel) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->taskLevel) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->info.totalLevel) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->info.taskLevel) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->outputType) < 0) return -1; - if (tDecodeI16(pDecoder, &pTask->dispatchMsgType) < 0) return -1; + if (tDecodeI16(pDecoder, &pTask->msgInfo.msgType) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->status.taskStatus) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->status.schedStatus) < 0) return -1; - if (tDecodeI32(pDecoder, &pTask->selfChildId) < 0) return -1; - if (tDecodeI32(pDecoder, &pTask->nodeId) < 0) return -1; - if (tDecodeSEpSet(pDecoder, &pTask->epSet) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->info.selfChildId) < 0) return -1; + if (tDecodeI32(pDecoder, &pTask->info.nodeId) < 0) return -1; + if (tDecodeSEpSet(pDecoder, &pTask->info.epSet) < 0) return -1; if (tDecodeI64(pDecoder, &pTask->chkInfo.id) < 0) return -1; if (tDecodeI64(pDecoder, &pTask->chkInfo.version) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->fillHistory) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->info.fillHistory) < 0) return -1; + + if (tDecodeI64(pDecoder, &pTask->historyTaskId.streamId)) return -1; + if (tDecodeI32(pDecoder, &pTask->historyTaskId.taskId)) return -1; + if (tDecodeI64(pDecoder, &pTask->streamTaskId.streamId)) return -1; + if (tDecodeI32(pDecoder, &pTask->streamTaskId.taskId)) return -1; + + if (tDecodeU64(pDecoder, &pTask->dataRange.range.minVer)) return -1; + if (tDecodeU64(pDecoder, &pTask->dataRange.range.maxVer)) return -1; + if (tDecodeI64(pDecoder, &pTask->dataRange.window.skey)) return -1; + if (tDecodeI64(pDecoder, &pTask->dataRange.window.ekey)) return -1; int32_t epSz; if (tDecodeI32(pDecoder, &epSz) < 0) return -1; - pTask->childEpInfo = taosArrayInit(epSz, sizeof(void*)); + + pTask->pUpstreamEpInfoList = taosArrayInit(epSz, POINTER_BYTES); for (int32_t i = 0; i < epSz; i++) { SStreamChildEpInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamChildEpInfo)); if (pInfo == NULL) return -1; @@ -151,10 +173,10 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) { taosMemoryFreeClear(pInfo); return -1; } - taosArrayPush(pTask->childEpInfo, &pInfo); + taosArrayPush(pTask->pUpstreamEpInfoList, &pInfo); } - if (pTask->taskLevel != TASK_LEVEL__SINK) { + if (pTask->info.taskLevel != TASK_LEVEL__SINK) { if (tDecodeCStrAlloc(pDecoder, &pTask->exec.qmsg) < 0) return -1; } @@ -204,7 +226,7 @@ void tFreeStreamTask(SStreamTask* pTask) { walCloseReader(pTask->exec.pWalReader); } - taosArrayDestroyP(pTask->childEpInfo, taosMemoryFree); + taosArrayDestroyP(pTask->pUpstreamEpInfoList, taosMemoryFree); if (pTask->outputType == TASK_OUTPUT__TABLE) { tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper); taosMemoryFree(pTask->tbSink.pTSchema); diff --git a/source/libs/stream/src/tstreamFileState.c b/source/libs/stream/src/tstreamFileState.c index dc9a1f80bb..dd857141c1 100644 --- a/source/libs/stream/src/tstreamFileState.c +++ b/source/libs/stream/src/tstreamFileState.c @@ -43,12 +43,13 @@ struct SStreamFileState { uint64_t maxRowCount; uint64_t curRowCount; GetTsFun getTs; + char* id; }; typedef SRowBuffPos SRowBuffInfo; SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize, - GetTsFun fp, void* pFile, TSKEY delMark) { + GetTsFun fp, void* pFile, TSKEY delMark, const char* idstr) { if (memSize <= 0) { memSize = DEFAULT_MAX_STREAM_BUFFER_SIZE; } @@ -70,6 +71,7 @@ SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_ if (!pFileState->usedBuffs || !pFileState->freeBuffs || !pFileState->rowBuffMap) { goto _error; } + pFileState->keyLen = keySize; pFileState->rowSize = rowSize; pFileState->selectivityRowSize = selectRowSize; @@ -81,6 +83,8 @@ SStreamFileState* streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_ pFileState->deleteMark = delMark; pFileState->flushMark = INT64_MIN; pFileState->maxTs = INT64_MIN; + pFileState->id = taosStrdup(idstr); + recoverSnapshot(pFileState); return pFileState; @@ -124,6 +128,8 @@ void streamFileStateDestroy(SStreamFileState* pFileState) { if (!pFileState) { return; } + + taosMemoryFree(pFileState->id); tdListFreeP(pFileState->usedBuffs, destroyRowBuffAllPosPtr); tdListFreeP(pFileState->freeBuffs, destroyRowBuff); tSimpleHashCleanup(pFileState->rowBuffMap); @@ -177,7 +183,8 @@ void popUsedBuffs(SStreamFileState* pFileState, SStreamSnapshot* pFlushList, uin i++; } } - qInfo("do stream state flush %d rows to disck. is used: %d", listNEles(pFlushList), used); + + qInfo("stream state flush %d rows to disk. is used:%d", listNEles(pFlushList), used); } int32_t flushRowBuff(SStreamFileState* pFileState) { @@ -185,13 +192,17 @@ int32_t flushRowBuff(SStreamFileState* pFileState) { if (!pFlushList) { return TSDB_CODE_OUT_OF_MEMORY; } + uint64_t num = (uint64_t)(pFileState->curRowCount * FLUSH_RATIO); num = TMAX(num, FLUSH_NUM); popUsedBuffs(pFileState, pFlushList, num, false); + if (isListEmpty(pFlushList)) { popUsedBuffs(pFileState, pFlushList, num, true); } + flushSnapshot(pFileState, pFlushList, false); + SListIter fIter = {0}; tdListInitIter(pFlushList, &fIter, TD_LIST_FORWARD); SListNode* pNode = NULL; @@ -201,6 +212,7 @@ int32_t flushRowBuff(SStreamFileState* pFileState) { tdListAppend(pFileState->freeBuffs, &pPos->pRowBuff); pPos->pRowBuff = NULL; } + tdListFreeP(pFlushList, destroyRowBuffPosPtr); return TSDB_CODE_SUCCESS; } @@ -269,13 +281,13 @@ int32_t getRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, voi TSKEY ts = pFileState->getTs(pKey); if (ts > pFileState->maxTs - pFileState->deleteMark && ts < pFileState->flushMark) { int32_t len = 0; - void* pVal = NULL; - int32_t code = streamStateGet_rocksdb(pFileState->pFileStore, pKey, &pVal, &len); + void* p = NULL; + int32_t code = streamStateGet_rocksdb(pFileState->pFileStore, pKey, &p, &len); qDebug("===stream===get %" PRId64 " from disc, res %d", ts, code); if (code == TSDB_CODE_SUCCESS) { - memcpy(pNewPos->pRowBuff, pVal, len); + memcpy(pNewPos->pRowBuff, p, len); } - taosMemoryFree(pVal); + taosMemoryFree(p); } tSimpleHashPut(pFileState->rowBuffMap, pKey, keyLen, &pNewPos, POINTER_BYTES); @@ -348,7 +360,10 @@ int32_t flushSnapshot(SStreamFileState* pFileState, SStreamSnapshot* pSnapshot, tdListInitIter(pSnapshot, &iter, TD_LIST_FORWARD); const int32_t BATCH_LIMIT = 256; - SListNode* pNode = NULL; + + int64_t st = taosGetTimestampMs(); + int32_t numOfElems = listNEles(pSnapshot); + SListNode* pNode = NULL; int idx = streamStateGetCfIdx(pFileState->pFileStore, "state"); @@ -359,24 +374,31 @@ int32_t flushSnapshot(SStreamFileState* pFileState, SStreamSnapshot* pSnapshot, while ((pNode = tdListNext(&iter)) != NULL && code == TSDB_CODE_SUCCESS) { SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data; ASSERT(pPos->pRowBuff && pFileState->rowSize > 0); + if (streamStateGetBatchSize(batch) >= BATCH_LIMIT) { - code = streamStatePutBatch_rocksdb(pFileState->pFileStore, batch); + streamStatePutBatch_rocksdb(pFileState->pFileStore, batch); streamStateClearBatch(batch); } SStateKey sKey = {.key = *((SWinKey*)pPos->pKey), .opNum = ((SStreamState*)pFileState->pFileStore)->number}; code = streamStatePutBatchOptimize(pFileState->pFileStore, idx, batch, &sKey, pPos->pRowBuff, pFileState->rowSize, 0, buf); + // todo handle failure memset(buf, 0, len); - qDebug("===stream===put %" PRId64 " to disc, res %d", sKey.key.ts, code); +// qDebug("===stream===put %" PRId64 " to disc, res %d", sKey.key.ts, code); } taosMemoryFree(buf); if (streamStateGetBatchSize(batch) > 0) { - code = streamStatePutBatch_rocksdb(pFileState->pFileStore, batch); + streamStatePutBatch_rocksdb(pFileState->pFileStore, batch); } + streamStateClearBatch(batch); + int64_t elapsed = taosGetTimestampMs() - st; + qDebug("%s flush to disk in batch model completed, rows:%d, batch size:%d, elapsed time:%"PRId64"ms", pFileState->id, numOfElems, + BATCH_LIMIT, elapsed); + if (flushState) { const char* taskKey = "streamFileState"; { @@ -385,7 +407,7 @@ int32_t flushSnapshot(SStreamFileState* pFileState, SStreamSnapshot* pSnapshot, int32_t len = 0; sprintf(keyBuf, "%s:%" PRId64 "", taskKey, ((SStreamState*)pFileState->pFileStore)->checkPointId); streamFileStateEncode(&pFileState->flushMark, &valBuf, &len); - code = streamStatePutBatch(pFileState->pFileStore, "default", batch, keyBuf, valBuf, len, 0); + streamStatePutBatch(pFileState->pFileStore, "default", batch, keyBuf, valBuf, len, 0); taosMemoryFree(valBuf); } { @@ -398,8 +420,8 @@ int32_t flushSnapshot(SStreamFileState* pFileState, SStreamSnapshot* pSnapshot, } streamStatePutBatch_rocksdb(pFileState->pFileStore, batch); } - streamStateDestroyBatch(batch); + streamStateDestroyBatch(batch); return code; } @@ -489,7 +511,7 @@ int32_t recoverSnapshot(SStreamFileState* pFileState) { break; } memcpy(pNewPos->pRowBuff, pVal, pVLen); - code = tSimpleHashPut(pFileState->rowBuffMap, pNewPos->pKey, pFileState->rowSize, &pNewPos, POINTER_BYTES); + code = tSimpleHashPut(pFileState->rowBuffMap, pNewPos->pKey, pFileState->keyLen, &pNewPos, POINTER_BYTES); if (code != TSDB_CODE_SUCCESS) { destroyRowBuffPos(pNewPos); break; @@ -502,3 +524,8 @@ int32_t recoverSnapshot(SStreamFileState* pFileState) { } int32_t streamFileStateGeSelectRowSize(SStreamFileState* pFileState) { return pFileState->selectivityRowSize; } + +void streamFileStateReloadInfo(SStreamFileState* pFileState, TSKEY ts) { + pFileState->flushMark = TMAX(pFileState->flushMark, ts); + pFileState->maxTs = TMAX(pFileState->maxTs, ts); +} diff --git a/source/libs/stream/test/tstreamUpdateTest.cpp b/source/libs/stream/test/tstreamUpdateTest.cpp index 18c60aff28..0e84d6b8bd 100644 --- a/source/libs/stream/test/tstreamUpdateTest.cpp +++ b/source/libs/stream/test/tstreamUpdateTest.cpp @@ -158,7 +158,7 @@ TEST(TD_STREAM_UPDATE_TEST, update) { // void *buf = taosMemoryCalloc(1, bufLen); // int32_t resSize = updateInfoSerialize(buf, bufLen, pSU7); - // SUpdateInfo *pSU6 = updateInfoInit(0, TSDB_TIME_PRECISION_MILLI, 0); + // SUpdateInfo *pSU6 = taosMemoryCalloc(1, sizeof(SUpdateInfo)); // int32_t desSize = updateInfoDeserialize(buf, bufLen, pSU6); // GTEST_ASSERT_EQ(desSize, 0); diff --git a/source/libs/tfs/src/tfs.c b/source/libs/tfs/src/tfs.c index bedd14353f..4383c46c17 100644 --- a/source/libs/tfs/src/tfs.c +++ b/source/libs/tfs/src/tfs.c @@ -227,6 +227,9 @@ int32_t tfsMkdirAt(STfs *pTfs, const char *rname, SDiskID diskId) { STfsDisk *pDisk = TFS_DISK_AT(pTfs, diskId); char aname[TMPNAME_LEN]; + if (pDisk == NULL) { + return -1; + } snprintf(aname, TMPNAME_LEN, "%s%s%s", pDisk->path, TD_DIRSEP, rname); if (taosMkDir(aname) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); @@ -315,9 +318,9 @@ int32_t tfsRename(STfs *pTfs, const char *orname, const char *nrname) { char oaname[TMPNAME_LEN] = "\0"; char naname[TMPNAME_LEN] = "\0"; - for (int32_t level = 0; level < pTfs->nlevel; level++) { + for (int32_t level = pTfs->nlevel - 1; level >= 0; level--) { STfsTier *pTier = TFS_TIER_AT(pTfs, level); - for (int32_t id = 0; id < pTier->ndisk; id++) { + for (int32_t id = pTier->ndisk - 1; id >= 0; id--) { STfsDisk *pDisk = pTier->disks[id]; snprintf(oaname, TMPNAME_LEN, "%s%s%s", pDisk->path, TD_DIRSEP, orname); snprintf(naname, TMPNAME_LEN, "%s%s%s", pDisk->path, TD_DIRSEP, nrname); diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index a12f8051ba..1e70ce4a1c 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -47,9 +47,7 @@ static FORCE_INLINE int walBuildTmpMetaName(SWal* pWal, char* buf) { } static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { - int32_t sz = taosArrayGetSize(pWal->fileInfoSet); - terrno = TSDB_CODE_SUCCESS; - + int32_t sz = taosArrayGetSize(pWal->fileInfoSet); SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, fileIdx); char fnameStr[WAL_FILE_LEN]; walBuildLogName(pWal, pFileInfo->firstVer, fnameStr); @@ -74,13 +72,12 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { int64_t capacity = 0; int64_t readSize = 0; char* buf = NULL; - bool firstTrial = pFileInfo->fileSize < fileSize; int64_t offset = TMIN(pFileInfo->fileSize, fileSize); - int64_t offsetForward = offset - stepSize + walCkHeadSz - 1; - int64_t offsetBackward = offset; int64_t retVer = -1; int64_t lastEntryBeginOffset = 0; int64_t lastEntryEndOffset = 0; + int64_t recordLen = 0; + bool forwardStage = false; // check recover size if (2 * tsWalFsyncDataSizeLimit + offset < end) { @@ -91,14 +88,8 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { // search for the valid last WAL entry, e.g. block by block while (1) { - offset = (firstTrial) ? TMIN(fileSize, offsetForward + stepSize - walCkHeadSz + 1) - : TMAX(0, offsetBackward - stepSize + walCkHeadSz - 1); + offset = (lastEntryEndOffset > 0) ? offset : TMAX(0, offset - stepSize + walCkHeadSz - 1); end = TMIN(offset + stepSize, fileSize); - if (firstTrial) { - offsetForward = offset; - } else { - offsetBackward = offset; - } readSize = end - offset; capacity = readSize + sizeof(magic); @@ -129,7 +120,16 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { int64_t pos = 0; SWalCkHead* logContent = NULL; - while ((candidate = tmemmem(haystack, readSize - (haystack - buf), (char*)&magic, sizeof(magic))) != NULL) { + while (true) { + forwardStage = (lastEntryEndOffset > 0 || offset == 0); + terrno = TSDB_CODE_SUCCESS; + if (forwardStage) { + candidate = (readSize - (haystack - buf)) > 0 ? haystack : NULL; + } else { + candidate = tmemmem(haystack, readSize - (haystack - buf), (char*)&magic, sizeof(magic)); + } + + if (candidate == NULL) break; pos = candidate - buf; // validate head @@ -137,13 +137,14 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { if (len < walCkHeadSz) { break; } + logContent = (SWalCkHead*)(buf + pos); if (walValidHeadCksum(logContent) != 0) { terrno = TSDB_CODE_WAL_CHKSUM_MISMATCH; wWarn("vgId:%d, failed to validate checksum of wal entry header. offset:%" PRId64 ", file:%s", pWal->cfg.vgId, offset + pos, fnameStr); haystack = buf + pos + 1; - if (firstTrial) { + if (forwardStage) { break; } else { continue; @@ -151,9 +152,9 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { } // validate body - int64_t size = walCkHeadSz + logContent->head.bodyLen; - if (len < size) { - int64_t extraSize = size - len; + recordLen = walCkHeadSz + logContent->head.bodyLen; + if (len < recordLen) { + int64_t extraSize = recordLen - len; if (capacity < readSize + extraSize + sizeof(magic)) { capacity += extraSize; void* ptr = taosMemoryRealloc(buf, capacity); @@ -184,7 +185,7 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { wWarn("vgId:%d, failed to validate checksum of wal entry body. offset:%" PRId64 ", file:%s", pWal->cfg.vgId, offset + pos, fnameStr); haystack = buf + pos + 1; - if (firstTrial) { + if (forwardStage) { break; } else { continue; @@ -194,21 +195,14 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { // found one retVer = logContent->head.version; lastEntryBeginOffset = offset + pos; - lastEntryEndOffset = offset + pos + sizeof(SWalCkHead) + logContent->head.bodyLen; + lastEntryEndOffset = offset + pos + recordLen; // try next - haystack = buf + pos + 1; + haystack = buf + pos + recordLen; } - if (end == fileSize) firstTrial = false; - if (firstTrial) { - if (terrno == TSDB_CODE_SUCCESS) { - continue; - } else { - firstTrial = false; - } - } - if (retVer >= 0 || offset == 0) break; + offset = (lastEntryEndOffset > 0) ? lastEntryEndOffset : offset; + if (forwardStage && (terrno != TSDB_CODE_SUCCESS || end == fileSize)) break; } if (retVer < 0) { diff --git a/source/util/src/tcompare.c b/source/util/src/tcompare.c index e32ff3da95..843f9c56dc 100644 --- a/source/util/src/tcompare.c +++ b/source/util/src/tcompare.c @@ -225,6 +225,23 @@ int32_t compareLenPrefixedWStrDesc(const void *pLeft, const void *pRight) { return compareLenPrefixedWStr(pRight, pLeft); } +int32_t compareLenBinaryVal(const void *pLeft, const void *pRight) { + int32_t len1 = varDataLen(pLeft); + int32_t len2 = varDataLen(pRight); + + int32_t minLen = TMIN(len1, len2); + int32_t ret = memcmp(varDataVal(pLeft), varDataVal(pRight), minLen); + if (ret == 0) { + if (len1 == len2) { + return 0; + } else { + return len1 > len2 ? 1 : -1; + } + } else { + return ret > 0 ? 1 : -1; + } +} + // string > number > bool > null // ref: https://dev.mysql.com/doc/refman/8.0/en/json.html#json-comparison int32_t compareJsonVal(const void *pLeft, const void *pRight) { diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 0a53ece746..d2b9edf753 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -405,6 +405,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR, "Json not support in t TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_IN_GROUP_ERROR, "Json not support in group/partition by") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JOB_NOT_EXIST, "Job not exist") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitting") +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR, "Geometry not support in this operator") // grant TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired") @@ -629,7 +630,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_INDEX_INVALID_FILE, "Index file is inval TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_MSG, "Invalid message") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_CONSUMER_MISMATCH, "Consumer mismatch") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_CONSUMER_CLOSED, "Consumer closed") -TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_CONSUMER_ERROR, "Consumer error, to see log") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_CONSUMER_ERROR, "Consumer error, to see log") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_TOPIC_OUT_OF_RANGE, "Topic num out of range") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_GROUP_OUT_OF_RANGE, "Group num out of range 100") // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") diff --git a/source/util/src/theap.c b/source/util/src/theap.c index 8c1a1db057..d60606008f 100644 --- a/source/util/src/theap.c +++ b/source/util/src/theap.c @@ -187,3 +187,172 @@ void heapRemove(Heap* heap, HeapNode* node) { } void heapDequeue(Heap* heap) { heapRemove(heap, heap->min); } + + +struct PriorityQueue { + SArray* container; + pq_comp_fn fn; + FDelete deleteFn; + void* param; +}; +PriorityQueue* createPriorityQueue(pq_comp_fn fn, FDelete deleteFn, void* param) { + PriorityQueue* pq = (PriorityQueue*)taosMemoryCalloc(1, sizeof(PriorityQueue)); + pq->container = taosArrayInit(1, sizeof(PriorityQueueNode)); + pq->fn = fn; + pq->deleteFn = deleteFn; + pq->param = param; + return pq; +} + +void taosPQSetFn(PriorityQueue* pq, pq_comp_fn fn) { + pq->fn = fn; +} + +void destroyPriorityQueue(PriorityQueue* pq) { + if (pq->deleteFn) + taosArrayDestroyP(pq->container, pq->deleteFn); + else + taosArrayDestroy(pq->container); + taosMemoryFree(pq); +} + +static size_t pqParent(size_t i) { return (--i) >> 1; /* (i - 1) / 2 */ } +static size_t pqLeft(size_t i) { return (i << 1) | 1; /* i * 2 + 1 */ } +static size_t pqRight(size_t i) { return (++i) << 1; /* (i + 1) * 2 */} +static void pqSwapPQNode(PriorityQueueNode* a, PriorityQueueNode* b) { + void * tmp = a->data; + a->data = b->data; + b->data = tmp; +} + +#define pqContainerGetEle(pq, i) ((PriorityQueueNode*)taosArrayGet((pq)->container, (i))) +#define pqContainerSize(pq) (taosArrayGetSize((pq)->container)) + +size_t taosPQSize(PriorityQueue* pq) { return pqContainerSize(pq); } + +static void pqHeapify(PriorityQueue* pq, size_t from, size_t last) { + size_t largest = from; + do { + from = largest; + size_t l = pqLeft(from); + size_t r = pqRight(from); + if (l < last && pq->fn(pqContainerGetEle(pq, from)->data, pqContainerGetEle(pq, l)->data, pq->param)) { + largest = l; + } + if (r < last && pq->fn(pqContainerGetEle(pq, largest)->data, pqContainerGetEle(pq, r)->data, pq->param)) { + largest = r; + } + if (largest != from) { + pqSwapPQNode(pqContainerGetEle(pq, from), pqContainerGetEle(pq, largest)); + } + } while (largest != from); +} + +static void pqBuildHeap(PriorityQueue* pq) { + if (pqContainerSize(pq) > 1) { + for (size_t i = pqContainerSize(pq) - 1; i > 0; --i) { + pqHeapify(pq, i, pqContainerSize(pq)); + } + pqHeapify(pq, 0, pqContainerSize(pq)); + } +} + +static void pqReverseHeapify(PriorityQueue* pq, size_t i) { + while (i > 0 && !pq->fn(pqContainerGetEle(pq, i)->data, pqContainerGetEle(pq, pqParent(i))->data, pq->param)) { + size_t parentIdx = pqParent(i); + pqSwapPQNode(pqContainerGetEle(pq, i), pqContainerGetEle(pq, parentIdx)); + i = parentIdx; + } +} + +static void pqUpdate(PriorityQueue* pq, size_t i) { + if (i == 0 || pq->fn(pqContainerGetEle(pq, i)->data, pqContainerGetEle(pq, pqParent(i))->data, pq->param)) { + // if value in pos i is smaller than parent, heapify down from i to the end + pqHeapify(pq, i, pqContainerSize(pq)); + } else { + // if value in pos i is big than parent, heapify up from i + pqReverseHeapify(pq, i); + } +} + +static void pqRemove(PriorityQueue* pq, size_t i) { + if (i == pqContainerSize(pq) - 1) { + taosArrayPop(pq->container); + return; + } + + taosArraySet(pq->container, i, taosArrayGet(pq->container, pqContainerSize(pq) - 1)); + taosArrayPop(pq->container); + pqUpdate(pq, i); +} + +PriorityQueueNode* taosPQTop(PriorityQueue* pq) { + return pqContainerGetEle(pq, 0); +} + +void taosPQPush(PriorityQueue* pq, const PriorityQueueNode* node) { + taosArrayPush(pq->container, node); + pqReverseHeapify(pq, pqContainerSize(pq) - 1); +} + +void taosPQPop(PriorityQueue* pq) { + PriorityQueueNode* top = taosPQTop(pq); + if (pq->deleteFn) pq->deleteFn(top->data); + pqRemove(pq, 0); +} + +struct BoundedQueue { + PriorityQueue* queue; + uint32_t maxSize; +}; + +BoundedQueue* createBoundedQueue(uint32_t maxSize, pq_comp_fn fn, FDelete deleteFn, void* param) { + BoundedQueue* q = (BoundedQueue*)taosMemoryCalloc(1, sizeof(BoundedQueue)); + q->queue = createPriorityQueue(fn, deleteFn, param); + taosArrayEnsureCap(q->queue->container, maxSize + 1); + q->maxSize = maxSize; + return q; +} + +void taosBQSetFn(BoundedQueue* q, pq_comp_fn fn) { + taosPQSetFn(q->queue, fn); +} + +void destroyBoundedQueue(BoundedQueue* q) { + if (!q) return; + destroyPriorityQueue(q->queue); + taosMemoryFree(q); +} + +void taosBQPush(BoundedQueue* q, PriorityQueueNode* n) { + if (pqContainerSize(q->queue) == q->maxSize + 1) { + PriorityQueueNode* top = pqContainerGetEle(q->queue, 0); + void *p = top->data; + top->data = n->data; + n->data = p; + if (q->queue->deleteFn) q->queue->deleteFn(n->data); + pqHeapify(q->queue, 0, taosBQSize(q)); + } else { + taosPQPush(q->queue, n); + } +} + +PriorityQueueNode* taosBQTop(BoundedQueue* q) { + return taosPQTop(q->queue); +} + +void taosBQBuildHeap(BoundedQueue *q) { + pqBuildHeap(q->queue); +} + +size_t taosBQMaxSize(BoundedQueue* q) { + return q->maxSize; +} + +size_t taosBQSize(BoundedQueue* q) { + return taosPQSize(q->queue); +} + +void taosBQPop(BoundedQueue* q) { + taosPQPop(q->queue); +} diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 90a7f3fe42..21fed2e1f5 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -33,6 +33,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/subscribeStb3.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/subscribeDb0.py -N 3 -n 3 ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/ins_topics_test.py +,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmqParamsTest.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmqClientConsLog.py @@ -128,6 +129,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TD-19201.py ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TD-21561.py ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3404.py +,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3581.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/balance_vgroups_r1.py -N 6 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/taosShell.py @@ -779,7 +781,7 @@ ,,y,script,./test.sh -f tsim/user/basic.sim ,,y,script,./test.sh -f tsim/user/password.sim ,,y,script,./test.sh -f tsim/user/privilege_db.sim -,,y,script,./test.sh -f tsim/user/privilege_sysinfo.sim +#,,y,script,./test.sh -f tsim/user/privilege_sysinfo.sim ,,y,script,./test.sh -f tsim/user/privilege_topic.sim ,,y,script,./test.sh -f tsim/user/privilege_table.sim ,,y,script,./test.sh -f tsim/db/alter_option.sim diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh index 2d736e1414..206f99ff3d 100755 --- a/tests/parallel_test/run_case.sh +++ b/tests/parallel_test/run_case.sh @@ -76,10 +76,10 @@ ulimit -c unlimited md5sum /usr/lib/libtaos.so.1 md5sum /home/TDinternal/debug/build/lib/libtaos.so -#define taospy 2.7.6 +#define taospy 2.7.10 pip3 list|grep taospy pip3 uninstall taospy -y -pip3 install --default-timeout=120 taospy==2.7.6 +pip3 install --default-timeout=120 taospy==2.7.10 $TIMEOUT_CMD $cmd RET=$? diff --git a/tests/script/sh/deploy.sh b/tests/script/sh/deploy.sh index 7da8da09bf..5b1773e664 100755 --- a/tests/script/sh/deploy.sh +++ b/tests/script/sh/deploy.sh @@ -118,7 +118,7 @@ echo "statusInterval 1" >> $TAOS_CFG echo "dataDir $DATA_DIR" >> $TAOS_CFG echo "logDir $LOG_DIR" >> $TAOS_CFG echo "debugFlag 0" >> $TAOS_CFG -echo "tmrDebugFlag 131" >> $TAOS_CFG +echo "tmrDebugFlag 143" >> $TAOS_CFG echo "uDebugFlag 143" >> $TAOS_CFG echo "rpcDebugFlag 143" >> $TAOS_CFG echo "jniDebugFlag 143" >> $TAOS_CFG diff --git a/tests/script/tsim/parser/limit1_stb.sim b/tests/script/tsim/parser/limit1_stb.sim index 731a218de5..027a4f5c79 100644 --- a/tests/script/tsim/parser/limit1_stb.sim +++ b/tests/script/tsim/parser/limit1_stb.sim @@ -468,7 +468,7 @@ if $data01 != 1 then endi ## supertable aggregation + where + interval + group by order by tag + limit offset -sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9),t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 5 and c1 > 0 and c2 < 9 and c3 > 1 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc limit 2 offset 0 +sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9),t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 5 and c1 > 0 and c2 < 9 and c3 > 1 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc, max(c1) asc limit 2 offset 0 if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/parser/limit_stb.sim b/tests/script/tsim/parser/limit_stb.sim index 6950df9ee1..46bd6260c3 100644 --- a/tests/script/tsim/parser/limit_stb.sim +++ b/tests/script/tsim/parser/limit_stb.sim @@ -508,7 +508,7 @@ endi ### supertable aggregation + where + interval + group by order by tag + limit offset ## TBASE-345 -sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9), t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 5 and c1 > 0 and c2 < 9 and c3 > 1 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc limit 3 offset 0 +sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9), t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 5 and c1 > 0 and c2 < 9 and c3 > 1 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc, max(c1) asc limit 3 offset 0 if $rows != 3 then return -1 endi @@ -554,7 +554,7 @@ if $data09 != 4 then return -1 endi -sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9), t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 8 and c1 > 0 and c2 < 9 and c3 > 4 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc limit 3 offset 0 +sql select _wstart, max(c1), min(c2), avg(c3), sum(c5), spread(c6), first(c7), last(c8), first(c9), t1 from $stb where ts >= $ts0 and ts <= $tsu and t1 > 1 and t1 < 8 and c1 > 0 and c2 < 9 and c3 > 4 and c4 < 7 and c5 > 4 partition by t1 interval(5m) order by t1 desc, max(c1) asc limit 3 offset 0 if $rows != 3 then return -1 endi diff --git a/tests/script/tsim/parser/union.sim b/tests/script/tsim/parser/union.sim index dee5da96e8..f0c534ad11 100644 --- a/tests/script/tsim/parser/union.sim +++ b/tests/script/tsim/parser/union.sim @@ -126,7 +126,6 @@ endi if $data10 != 1 then return -1 endi - sql (select 'ab' as options from union_tb1 limit 1) union all (select 'dd' as options from union_tb0 limit 1) order by options; if $rows != 2 then return -1 diff --git a/tests/script/tsim/query/r/explain_tsorder.result b/tests/script/tsim/query/r/explain_tsorder.result index 6c63a343de..b69a77ada5 100644 --- a/tests/script/tsim/query/r/explain_tsorder.result +++ b/tests/script/tsim/query/r/explain_tsorder.result @@ -2558,3 +2558,243 @@ taos> select a.ts, a.c2, b.c2 from meters as a join (select * from meters order 2022-05-24 00:01:08.000 | 210 | 210 | 2022-05-24 00:01:08.000 | 210 | 210 | +taos> select ts, c2 from meters order by c2; + ts | c2 | +======================================== + 2022-05-21 00:01:08.000 | 11 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-19 00:01:08.000 | 243 | + +taos> select ts, c2 from meters order by c2 limit 4; + ts | c2 | +======================================== + 2022-05-21 00:01:08.000 | 11 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + +taos> select ts, c2 from meters order by c2 limit 2,2; + ts | c2 | +======================================== + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + +taos> select ts, c2 from meters order by ts asc, c2 desc limit 10; + ts | c2 | +======================================== + 2022-05-15 00:01:08.000 | 234 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-19 00:01:08.000 | 243 | + +taos> select ts, c2 from meters order by ts asc, c2 desc limit 5,5; + ts | c2 | +======================================== + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-19 00:01:08.000 | 243 | + +taos> select ts, c2 from d1 order by c2; + ts | c2 | +======================================== + 2022-05-21 00:01:08.000 | 11 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-19 00:01:08.000 | 243 | + +taos> select ts, c2 from d1 order by c2 limit 4; + ts | c2 | +======================================== + 2022-05-21 00:01:08.000 | 11 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-23 00:01:08.000 | 116 | + +taos> select ts, c2 from d1 order by c2 limit 2,2; + ts | c2 | +======================================== + 2022-05-17 00:01:08.000 | 59 | + 2022-05-23 00:01:08.000 | 116 | + +taos> select ts, c2 from d1 order by ts asc, c2 desc limit 10; + ts | c2 | +======================================== + 2022-05-15 00:01:08.000 | 234 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-24 00:01:08.000 | 210 | + +taos> select ts, c2 from d1 order by ts asc, c2 desc limit 5,5; + ts | c2 | +======================================== + 2022-05-20 00:01:08.000 | 120 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-24 00:01:08.000 | 210 | + +taos> select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc; + _wstart | d | avg(c) | +================================================================================ + 2022-05-18 23:00:00.000 | 2022-05-19 00:01:00.000 | 243.000000000 | + 2022-05-15 00:00:00.000 | 2022-05-15 00:01:00.000 | 234.000000000 | + 2022-05-19 04:00:00.000 | 2022-05-19 04:49:00.000 | 218.400000000 | + 2022-05-15 05:00:00.000 | 2022-05-15 06:01:00.000 | 209.500000000 | + 2022-05-18 18:00:00.000 | 2022-05-18 19:13:00.000 | 206.000000000 | + 2022-05-19 09:00:00.000 | 2022-05-19 09:37:00.000 | 193.800000000 | + 2022-05-15 10:00:00.000 | 2022-05-15 12:01:00.000 | 185.000000000 | + 2022-05-19 14:00:00.000 | 2022-05-19 14:25:00.000 | 169.200000000 | + 2022-05-18 13:00:00.000 | 2022-05-18 14:25:00.000 | 169.000000000 | + 2022-05-15 15:00:00.000 | 2022-05-15 18:01:00.000 | 160.500000000 | + 2022-05-19 19:00:00.000 | 2022-05-19 19:13:00.000 | 144.600000000 | + 2022-05-15 20:00:00.000 | 2022-05-16 00:01:00.000 | 136.000000000 | + 2022-05-18 08:00:00.000 | 2022-05-18 09:37:00.000 | 132.000000000 | + 2022-05-16 01:00:00.000 | 2022-05-16 04:49:00.000 | 120.600000000 | + 2022-05-20 00:00:00.000 | 2022-05-20 00:01:00.000 | 120.000000000 | + 2022-05-16 06:00:00.000 | 2022-05-16 09:37:00.000 | 105.200000000 | + 2022-05-18 03:00:00.000 | 2022-05-18 04:49:00.000 | 95.000000000 | + 2022-05-20 05:00:00.000 | 2022-05-20 06:01:00.000 | 92.750000000 | + 2022-05-16 11:00:00.000 | 2022-05-16 14:25:00.000 | 89.800000000 | + 2022-05-16 16:00:00.000 | 2022-05-16 19:13:00.000 | 74.400000000 | + 2022-05-20 10:00:00.000 | 2022-05-20 12:01:00.000 | 65.500000000 | + 2022-05-16 21:00:00.000 | 2022-05-17 00:01:00.000 | 59.000000000 | + 2022-05-17 02:00:00.000 | 2022-05-17 04:49:00.000 | 58.800000000 | + 2022-05-17 07:00:00.000 | 2022-05-17 09:37:00.000 | 58.600000000 | + 2022-05-17 12:00:00.000 | 2022-05-17 14:25:00.000 | 58.400000000 | + 2022-05-17 17:00:00.000 | 2022-05-17 19:13:00.000 | 58.200000000 | + 2022-05-17 22:00:00.000 | 2022-05-18 00:01:00.000 | 58.000000000 | + 2022-05-20 15:00:00.000 | 2022-05-20 18:01:00.000 | 38.250000000 | + 2022-05-20 20:00:00.000 | 2022-05-21 00:01:00.000 | 11.000000000 | + +taos> select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc limit 2; + _wstart | d | avg(c) | +================================================================================ + 2022-05-18 23:00:00.000 | 2022-05-19 00:01:00.000 | 243.000000000 | + 2022-05-15 00:00:00.000 | 2022-05-15 00:01:00.000 | 234.000000000 | + +taos> select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc limit 2,6; + _wstart | d | avg(c) | +================================================================================ + 2022-05-19 04:00:00.000 | 2022-05-19 04:49:00.000 | 218.400000000 | + 2022-05-15 05:00:00.000 | 2022-05-15 06:01:00.000 | 209.500000000 | + 2022-05-18 18:00:00.000 | 2022-05-18 19:13:00.000 | 206.000000000 | + 2022-05-19 09:00:00.000 | 2022-05-19 09:37:00.000 | 193.800000000 | + 2022-05-15 10:00:00.000 | 2022-05-15 12:01:00.000 | 185.000000000 | + 2022-05-19 14:00:00.000 | 2022-05-19 14:25:00.000 | 169.200000000 | + +taos> select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 10; + last(ts) | d | +======================================== + 2022-05-19 00:01:08.000 | 243 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-21 00:01:08.000 | 11 | + +taos> select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 2,8; + last(ts) | d | +======================================== + 2022-05-24 00:01:08.000 | 210 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-21 00:01:08.000 | 11 | + +taos> select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 9,1; + last(ts) | d | +======================================== + 2022-05-21 00:01:08.000 | 11 | + +taos> select last(ts), c2 as d from d1 group by c2 order by c2 asc limit 2,8; + last(ts) | d | +======================================== + 2022-05-17 00:01:08.000 | 59 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-24 00:01:08.000 | 210 | + 2022-05-15 00:01:08.000 | 234 | + 2022-05-19 00:01:08.000 | 243 | + +taos> select last(ts), c2 as d from d1 group by c2 order by c2 asc limit 9,1; + last(ts) | d | +======================================== + 2022-05-19 00:01:08.000 | 243 | + +taos> select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 10; + ts | d | +======================================== + 2022-05-24 00:01:08.000 | 210 | + 2022-05-23 00:01:08.000 | 116 | + 2022-05-22 00:01:08.000 | 196 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-15 00:01:08.000 | 234 | + +taos> select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 2,8; + ts | d | +======================================== + 2022-05-22 00:01:08.000 | 196 | + 2022-05-21 00:01:08.000 | 11 | + 2022-05-20 00:01:08.000 | 120 | + 2022-05-19 00:01:08.000 | 243 | + 2022-05-18 00:01:08.000 | 58 | + 2022-05-17 00:01:08.000 | 59 | + 2022-05-16 00:01:08.000 | 136 | + 2022-05-15 00:01:08.000 | 234 | + +taos> select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 9,1; + ts | d | +======================================== + 2022-05-15 00:01:08.000 | 234 | + diff --git a/tests/script/tsim/query/t/explain_tsorder.sql b/tests/script/tsim/query/t/explain_tsorder.sql index d3264d8895..056ac440fe 100644 --- a/tests/script/tsim/query/t/explain_tsorder.sql +++ b/tests/script/tsim/query/t/explain_tsorder.sql @@ -71,3 +71,30 @@ select a.ts, a.c2, b.c2 from meters as a join meters as b on a.ts = b.ts order b explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts desc\G; explain verbose true select a.ts, a.c2, b.c2 from meters as a join (select ts, c2 from meters order by ts desc) b on a.ts = b.ts order by a.ts asc\G; select a.ts, a.c2, b.c2 from meters as a join (select * from meters order by ts desc) b on a.ts = b.ts order by a.ts asc; + +select ts, c2 from meters order by c2; +select ts, c2 from meters order by c2 limit 4; +select ts, c2 from meters order by c2 limit 2,2; + +select ts, c2 from meters order by ts asc, c2 desc limit 10; +select ts, c2 from meters order by ts asc, c2 desc limit 5,5; + +select ts, c2 from d1 order by c2; +select ts, c2 from d1 order by c2 limit 4; +select ts, c2 from d1 order by c2 limit 2,2; + +select ts, c2 from d1 order by ts asc, c2 desc limit 10; +select ts, c2 from d1 order by ts asc, c2 desc limit 5,5; + +select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc; +select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc limit 2; +select _wstart, first(a) as d, avg(c) from (select _wstart as a, last(ts) as b, avg(c2) as c from meters interval(10s) order by a desc) where a > '2022-05-15 00:01:00.000' and a < '2022-05-21 00:01:08.000' interval(5h) fill(linear) order by avg(c) desc limit 2,6; + +select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 10; +select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 2,8; +select last(ts), c2 as d from d1 group by c2 order by c2 desc limit 9,1; +select last(ts), c2 as d from d1 group by c2 order by c2 asc limit 2,8; +select last(ts), c2 as d from d1 group by c2 order by c2 asc limit 9,1; +select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 10; +select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 2,8; +select last(ts) as ts, c2 as d from d1 group by c2 order by ts desc, c2 asc limit 9,1; diff --git a/tests/script/tsim/query/udf.sim b/tests/script/tsim/query/udf.sim index e539f11531..fbf9d50c25 100644 --- a/tests/script/tsim/query/udf.sim +++ b/tests/script/tsim/query/udf.sim @@ -8,6 +8,9 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c udf -v 1 system sh/exec.sh -n dnode1 -s start sql connect +sql alter user root pass 'taosdata2' +system sh/exec.sh -n dnode1 -s stop +system sh/exec.sh -n dnode1 -s start print ======== step1 udf system sh/compile_udf.sh diff --git a/tests/script/tsim/stream/fillHistoryTransform.sim b/tests/script/tsim/stream/fillHistoryTransform.sim new file mode 100644 index 0000000000..fe58b76b78 --- /dev/null +++ b/tests/script/tsim/stream/fillHistoryTransform.sim @@ -0,0 +1,405 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print =============== create database +sql create database test vgroups 1; +sql select * from information_schema.ins_databases +if $rows != 3 then + return -1 +endi + +print $data00 $data01 $data02 + +sql use test; + +print =====step1 + +sql create table t1(ts timestamp, a int, b int , c int, d double); + +sql insert into t1 values(1648791213000,10,2,3,1.0); + +sql create stream stream0 trigger at_once fill_history 1 IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt as select _wstart, sum(a) from t1 interval(10s); + +$loop_count = 0 +loop00: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop00 +endi + +if $data01 != 10 then + print =====data01=$data01 + goto loop00 +endi + +sql insert into t1 values(1648791213000,1,2,3,1.0); + +$loop_count = 0 +loop0: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop0 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +sql insert into t1 values(1648791213001,2,2,3,1.0); + +$loop_count = 0 +loop1: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop1 +endi + +if $data01 != 3 then + print ======$data01 + goto loop1 +endi + + +sql insert into t1 values(1648791223001,3,2,3,1.0); + +sql insert into t1 values(1648791223002,4,2,3,1.0); + +$loop_count = 0 +loop2: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt; + +if $rows != 2 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop2 +endi + +if $data01 != 3 then + print ======$data01 + goto loop2 +endi + +if $data11 != 7 then + print ======$data01 + goto loop2 +endi + +print =====step1 over + +print =====step2 + +sql create database test1 vgroups 4; + +sql use test1; + +sql create stable st(ts timestamp,a int,b int,c int,d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); + +sql insert into t1 values(1648791213000,10,2,3,1.0); + +sql create stream stream1 trigger at_once fill_history 1 IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt1 as select _wstart, sum(a) from st interval(10s); + +$loop_count = 0 +loop00: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt1; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop00 +endi + +if $data01 != 10 then + print =====data01=$data01 + goto loop00 +endi + +sql insert into t1 values(1648791213000,1,2,3,1.0); + +$loop_count = 0 +loop0: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt1; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop0 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +sql insert into t1 values(1648791213001,2,2,3,1.0); + +$loop_count = 0 +loop1: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt1; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop1 +endi + +if $data01 != 3 then + print ======$data01 + goto loop1 +endi + + +sql insert into t1 values(1648791223001,3,2,3,1.0); + +sql insert into t1 values(1648791223002,4,2,3,1.0); + +$loop_count = 0 +loop2: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt1; + +if $rows != 2 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop2 +endi + +if $data01 != 3 then + print ======$data01 + goto loop2 +endi + +if $data11 != 7 then + print ======$data01 + goto loop2 +endi + +print =====step2 over + +print =====step3 + +sql create database test2 vgroups 4; + +sql use test2; + +sql create stable st(ts timestamp,a int,b int,c int,d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); + +sql insert into t1 values(1648791213000,10,2,3,1.0); + +sql create stream stream2 trigger at_once fill_history 1 IGNORE EXPIRED 0 IGNORE UPDATE 0 into streamt2 as select _wstart, sum(a) from st partition by ta interval(10s); + +$loop_count = 0 +loop00: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt2; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop00 +endi + +if $data01 != 10 then + print =====data01=$data01 + goto loop00 +endi + +sql insert into t1 values(1648791213000,1,2,3,1.0); + +$loop_count = 0 +loop0: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt2; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop0 +endi + +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +sql insert into t1 values(1648791213001,2,2,3,1.0); + +$loop_count = 0 +loop1: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt2; + +if $rows != 1 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop1 +endi + +if $data01 != 3 then + print ======$data01 + goto loop1 +endi + + +sql insert into t1 values(1648791223001,3,2,3,1.0); + +sql insert into t1 values(1648791223002,4,2,3,1.0); + +$loop_count = 0 +loop2: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +sql select * from streamt2; + +if $rows != 2 then + print ======$rows + print data00,data01, data02 + print data10,data11, data12 + print data20,data21, data22 + goto loop2 +endi + +if $data01 != 3 then + print ======$data01 + goto loop2 +endi + +if $data11 != 7 then + print ======$data01 + goto loop2 +endi + +print =====step3 over + +print =====over + + +system sh/stop_dnodes.sh diff --git a/tests/script/tsim/stream/partitionby.sim b/tests/script/tsim/stream/partitionby.sim index df4b60314f..9a660741e7 100644 --- a/tests/script/tsim/stream/partitionby.sim +++ b/tests/script/tsim/stream/partitionby.sim @@ -14,6 +14,7 @@ sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); sql create stream stream_t1 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 into test0.streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); +sleep 500 sql insert into ts1 values(1648791213001,1,12,3,1.0); sql insert into ts2 values(1648791213001,1,12,3,1.0); diff --git a/tests/script/tsim/stream/sliding.sim b/tests/script/tsim/stream/sliding.sim index 05eb7dacba..18893245fa 100644 --- a/tests/script/tsim/stream/sliding.sim +++ b/tests/script/tsim/stream/sliding.sim @@ -575,8 +575,6 @@ endi $loop_count = 0 print step 7 - - sql create database test3 vgroups 6; sql use test3; sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); diff --git a/tests/system-test/0-others/backquote_check.py b/tests/system-test/0-others/backquote_check.py index be8590f913..7c91fd9e8c 100644 --- a/tests/system-test/0-others/backquote_check.py +++ b/tests/system-test/0-others/backquote_check.py @@ -22,7 +22,7 @@ class TDTestCase: def init(self, conn, logSql, replicaVar=1): self.replicaVar = int(replicaVar) tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), True) self.dbname = 'db' self.setsql = TDSetSql() self.stbname = 'stb' diff --git a/tests/system-test/0-others/compatibility.py b/tests/system-test/0-others/compatibility.py index 22e319fdaf..cd71de0c06 100644 --- a/tests/system-test/0-others/compatibility.py +++ b/tests/system-test/0-others/compatibility.py @@ -138,9 +138,9 @@ class TDTestCase: tdLog.printNoPrefix(f"==========step1:prepare and check data in old version-{BASEVERSION}") tdLog.info(f" LD_LIBRARY_PATH=/usr/lib taosBenchmark -t {tableNumbers} -n {recordNumbers1} -y ") os.system(f"LD_LIBRARY_PATH=/usr/lib taosBenchmark -t {tableNumbers} -n {recordNumbers1} -y ") - os.system(f"LD_LIBRARY_PATH=/usr/lib taos -s 'use test;create stream current_stream into current_stream_output_stb as select _wstart as `start`, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s);' ") - os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;create stream power_stream into power_stream_output_stb as select ts, concat_ws(\\".\\", location, tbname) as meter_location, current*voltage*cos(phase) as active_power, current*voltage*sin(phase) as reactive_power from meters partition by tbname;" ') - os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show streams;" ') + # os.system(f"LD_LIBRARY_PATH=/usr/lib taos -s 'use test;create stream current_stream into current_stream_output_stb as select _wstart as `start`, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s);' ") + # os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;create stream power_stream into power_stream_output_stb as select ts, concat_ws(\\".\\", location, tbname) as meter_location, current*voltage*cos(phase) as active_power, current*voltage*sin(phase) as reactive_power from meters partition by tbname;" ') + # os.system('LD_LIBRARY_PATH=/usr/lib taos -s "use test;show streams;" ') os.system(f"sed -i 's/\/etc\/taos/{cPath}/' 0-others/tmqBasic.json ") # os.system("LD_LIBRARY_PATH=/usr/lib taosBenchmark -f 0-others/tmqBasic.json -y ") os.system('LD_LIBRARY_PATH=/usr/lib taos -s "create topic if not exists tmq_test_topic as select current,voltage,phase from test.meters where voltage <= 106 and current <= 5;" ') @@ -224,7 +224,7 @@ class TDTestCase: args = (caller.filename, caller.lineno) tdLog.exit("%s(%d) failed" % args) tdsql.query("show streams;") - tdsql.checkRows(2) + tdsql.checkRows(0) tdsql.query("select *,tbname from d0.almlog where mcid='m0103';") tdsql.checkRows(6) expectList = [0,3003,20031,20032,20033,30031] diff --git a/tests/system-test/1-insert/db_tb_name_check.py b/tests/system-test/1-insert/db_tb_name_check.py index 23bb539620..fa43603e25 100644 --- a/tests/system-test/1-insert/db_tb_name_check.py +++ b/tests/system-test/1-insert/db_tb_name_check.py @@ -44,7 +44,7 @@ class TDTestCase: new_dbname = list(dbname) new_dbname.insert(i,j) dbname_1 = ''.join(new_dbname) - tdSql.execute(f'create database if not exists `{dbname_1}`') + tdSql.execute(f'create database if not exists `{dbname_1}` vgroups 1 replica 1') tdSql.query('select * from information_schema.ins_databases') tdSql.checkEqual(tdSql.queryResult[2][0],str(dbname_1)) tdSql.execute(f'drop database `{dbname_1}`') @@ -56,7 +56,7 @@ class TDTestCase: def tb_name_check(self): dbname = tdCom.getLongName(10) - tdSql.execute(f'create database if not exists `{dbname}`') + tdSql.execute(f'create database if not exists `{dbname}` vgroups 1 replica 1') tdSql.execute(f'use `{dbname}`') tbname = tdCom.getLongName(5) for i in self.special_name: diff --git a/tests/system-test/2-query/limit.py b/tests/system-test/2-query/limit.py index c00e3b7d56..4774602d69 100644 --- a/tests/system-test/2-query/limit.py +++ b/tests/system-test/2-query/limit.py @@ -321,7 +321,7 @@ class TDTestCase: limit = 5 offset = paraDict["rowsPerTbl"] * 2 offset = offset - 2 - sqlStr = f"select max(c1), min(c2), sum(c3), avg(c4), first(c7), last(c8), first(c9) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 partition by t1 interval(5m) fill(value, -1, -2, -3, -4 ,-7 ,'-8', '-9') order by t1 limit %d offset %d"%(limit, offset) + sqlStr = f"select max(c1), min(c2), sum(c3), avg(c4), first(c7), last(c8), first(c9) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 partition by t1 interval(5m) fill(value, -1, -2, -3, -4 ,-7 ,'-8', '-9') order by t1, max(c1) limit %d offset %d"%(limit, offset) # tdLog.info("====sql:%s"%(sqlStr)) tdSql.query(sqlStr) tdSql.checkRows(1) diff --git a/tests/system-test/7-tmq/checkOffsetRowParams.py b/tests/system-test/7-tmq/checkOffsetRowParams.py index 8a24148064..f7e4c61c9c 100644 --- a/tests/system-test/7-tmq/checkOffsetRowParams.py +++ b/tests/system-test/7-tmq/checkOffsetRowParams.py @@ -245,7 +245,7 @@ class TDTestCase: tdSql.query("show consumers") tdSql.checkRows(1) - tdSql.checkData(0, 8, "tbname:1,commit:1,interval:2000,reset:earliest") + tdSql.checkData(0, 8, "tbname:1,commit:1,interval:2000ms,reset:earliest") time.sleep(2) tdLog.info("start insert data") diff --git a/tests/system-test/7-tmq/tmqParamsTest.py b/tests/system-test/7-tmq/tmqParamsTest.py new file mode 100644 index 0000000000..f48eaa84d4 --- /dev/null +++ b/tests/system-test/7-tmq/tmqParamsTest.py @@ -0,0 +1,178 @@ + +import sys +import time +import threading +from taos.tmq import Consumer +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + updatecfgDict = {'debugFlag': 135} + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + self.wal_retention_period1 = 3600 + self.wal_retention_period2 = 1 + self.commit_value_list = ["true", "false"] + self.offset_value_list = ["", "earliest", "latest", "none"] + self.tbname_value_list = ["true", "false"] + self.snapshot_value_list = ["true", "false"] + + # self.commit_value_list = ["true"] + # self.offset_value_list = ["none"] + # self.tbname_value_list = ["true"] + # self.snapshot_value_list = ["true"] + + def tmqParamsTest(self): + paraDict = {'dbName': 'db1', + 'dropFlag': 1, + 'vgroups': 4, + 'stbName': 'stb', + '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': 1, + 'rowsPerTbl': 10000, + 'batchNum': 10, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'auto_commit_interval': "100"} + + + start_group_id = 1 + for snapshot_value in self.snapshot_value_list: + for commit_value in self.commit_value_list: + for offset_value in self.offset_value_list: + for tbname_value in self.tbname_value_list: + topic_name = 'topic1' + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=4,replica=1) + tdLog.info("create stb") + tdCom.create_stable(tdSql, dbname=paraDict["dbName"],stbname=paraDict["stbName"], column_elm_list=paraDict['colSchema'], tag_elm_list=paraDict['tagSchema']) + tdLog.info("create ctb") + tdCom.create_ctable(tdSql, dbname=paraDict["dbName"],stbname=paraDict["stbName"],tag_elm_list=paraDict['tagSchema'],count=paraDict["ctbNum"], default_ctbname_prefix=paraDict['ctbPrefix']) + tdLog.info("insert data") + tmqCom.insert_data(tdSql,paraDict["dbName"],paraDict["ctbPrefix"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"]) + + + tdLog.info("create topics from stb with filter") + queryString = "select ts, log(c1), ceil(pow(c1,3)) from %s.%s where c1 %% 7 == 0" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topic_name, queryString) + tdSql.query(f'select * from information_schema.ins_databases') + db_wal_retention_period_list = list(map(lambda x:x[-8] if x[0] == paraDict['dbName'] else None, tdSql.queryResult)) + for i in range(len(db_wal_retention_period_list)): + if db_wal_retention_period_list[0] is None or db_wal_retention_period_list[-1] is None: + db_wal_retention_period_list.remove(None) + if snapshot_value =="true": + if db_wal_retention_period_list[0] != self.wal_retention_period2: + tdSql.execute(f"alter database {paraDict['dbName']} wal_retention_period {self.wal_retention_period2}") + time.sleep(self.wal_retention_period2+1) + tdSql.execute(f'flush database {paraDict["dbName"]}') + else: + if db_wal_retention_period_list[0] != self.wal_retention_period1: + tdSql.execute(f"alter database {paraDict['dbName']} wal_retention_period {self.wal_retention_period1}") + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expected_res = tdSql.queryRows + group_id = "csm_" + str(start_group_id) + consumer_dict = { + "group.id": group_id, + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "auto.commit.interval.ms": paraDict["auto_commit_interval"], + "enable.auto.commit": commit_value, + "auto.offset.reset": offset_value, + "experimental.snapshot.enable": snapshot_value, + "msg.with.table.name": tbname_value + } + consumer_commit = 1 if consumer_dict["enable.auto.commit"] == "true" else 0 + consumer_tbname = 1 if consumer_dict["msg.with.table.name"] == "true" else 0 + consumer_ret = "earliest" if offset_value == "" else offset_value + expected_parameters=f'tbname:{consumer_tbname},commit:{consumer_commit},interval:{paraDict["auto_commit_interval"]}ms,reset:{consumer_ret}' + if len(offset_value) == 0: + del consumer_dict["auto.offset.reset"] + consumer = Consumer(consumer_dict) + consumer.subscribe([topic_name]) + tdLog.info(f"enable.auto.commit: {commit_value}, auto.offset.reset: {offset_value}, experimental.snapshot.enable: {snapshot_value}, msg.with.table.name: {tbname_value}") + stop_flag = 0 + try: + while True: + res = consumer.poll(1) + tdSql.query('show consumers;') + consumer_info = tdSql.queryResult[0][-1] + if offset_value == "latest": + if not res and stop_flag == 1: + break + else: + if not res: + break + # err = res.error() + # if err is not None: + # raise err + # val = res.value() + # for block in val: + # print(block.fetchall()) + if offset_value == "latest" and stop_flag == 0: + tmqCom.insert_data(tdSql,paraDict["dbName"],paraDict["ctbPrefix"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],int(round(time.time()*1000))) + stop_flag = 1 + finally: + consumer.unsubscribe() + consumer.close() + tdSql.checkEqual(consumer_info, expected_parameters) + start_group_id += 1 + tdSql.query('show subscriptions;') + subscription_info = tdSql.queryResult + if snapshot_value == "true": + if offset_value != "earliest" and offset_value != "": + if offset_value == "latest": + offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace("earliest", "0")), subscription_info)) + tdSql.checkEqual(sum(offset_value_list) > 0, True) + rows_value_list = list(map(lambda x: int(x[-1]), subscription_info)) + tdSql.checkEqual(sum(rows_value_list), expected_res) + elif offset_value == "none": + offset_value_list = list(map(lambda x: x[-2], subscription_info)) + tdSql.checkEqual(offset_value_list, ['none']*len(subscription_info)) + rows_value_list = list(map(lambda x: x[-1], subscription_info)) + tdSql.checkEqual(rows_value_list, [0]*len(subscription_info)) + else: + if offset_value != "none": + offset_value_str = ",".join(list(map(lambda x: x[-2], subscription_info))) + tdSql.checkEqual("tsdb" in offset_value_str, True) + rows_value_list = list(map(lambda x: int(x[-1]), subscription_info)) + tdSql.checkEqual(sum(rows_value_list), expected_res) + else: + offset_value_list = list(map(lambda x: x[-2], subscription_info)) + tdSql.checkEqual(offset_value_list, [None]*len(subscription_info)) + rows_value_list = list(map(lambda x: x[-1], subscription_info)) + tdSql.checkEqual(rows_value_list, [None]*len(subscription_info)) + else: + if offset_value != "none": + offset_value_list = list(map(lambda x: int(x[-2].replace("wal:", "").replace("earliest", "0")), subscription_info)) + tdSql.checkEqual(sum(offset_value_list) > 0, True) + rows_value_list = list(map(lambda x: int(x[-1]), subscription_info)) + tdSql.checkEqual(sum(rows_value_list), expected_res) + else: + offset_value_list = list(map(lambda x: x[-2], subscription_info)) + tdSql.checkEqual(offset_value_list, ['none']*len(subscription_info)) + rows_value_list = list(map(lambda x: x[-1], subscription_info)) + tdSql.checkEqual(rows_value_list, [0]*len(subscription_info)) + tdSql.execute(f"drop topic if exists {topic_name}") + tdSql.execute(f'drop database if exists {paraDict["dbName"]}') + + def run(self): + self.tmqParamsTest() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmq_taosx.py b/tests/system-test/7-tmq/tmq_taosx.py index c3ec4875ce..86c40fdc72 100644 --- a/tests/system-test/7-tmq/tmq_taosx.py +++ b/tests/system-test/7-tmq/tmq_taosx.py @@ -220,6 +220,17 @@ class TDTestCase: return + def checkWal1VgroupOnlyMeta(self): + buildPath = tdCom.getBuildPath() + cfgPath = tdCom.getClientCfgPath() + cmdStr = '%s/build/bin/tmq_taosx_ci -c %s -sv 1 -dv 1 -d -onlymeta'%(buildPath, cfgPath) + tdLog.info(cmdStr) + os.system(cmdStr) + + self.checkJson(cfgPath, "tmq_taosx_tmp") + + return + def checkWal1VgroupTable(self): buildPath = tdCom.getBuildPath() cfgPath = tdCom.getClientCfgPath() @@ -301,6 +312,8 @@ class TDTestCase: def run(self): tdSql.prepare() + self.checkWal1VgroupOnlyMeta() + self.checkWal1Vgroup() self.checkSnapshot1Vgroup() diff --git a/tests/system-test/99-TDcase/TS-3581.py b/tests/system-test/99-TDcase/TS-3581.py new file mode 100644 index 0000000000..18488af0a6 --- /dev/null +++ b/tests/system-test/99-TDcase/TS-3581.py @@ -0,0 +1,79 @@ +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def 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 or "taosd.exe" 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 create_tables(self): + tdSql.execute(f'''CREATE STABLE `dwd_log_master` (`ts` TIMESTAMP, `dim_ip` NCHAR(64)) TAGS (`group_id` BIGINT, `st_hour` NCHAR(2), `org_id` NCHAR(32), + `dev_manufacturer_name` NCHAR(64), `dev_manufacturer_id` INT, `dev_category_name` NCHAR(64), `dev_category_id` INT, `dev_feature_name` NCHAR(64), + `dev_feature_id` INT, `dev_ip` NCHAR(64), `black_list` TINYINT, `white_list` TINYINT)''') + tdSql.execute(f'''CREATE TABLE `dwd_log_master_475021043` USING `dwd_log_master` (`group_id`, `st_hour`, `org_id`, `dev_manufacturer_name`, `dev_manufacturer_id`, + `dev_category_name`, `dev_category_id`, `dev_feature_name`, `dev_feature_id`, `dev_ip`, `black_list`, `white_list`) TAGS + (475021043, "14", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "172.18.22.230", NULL, NULL)''') + + def insert_data(self): + tdLog.debug("start to insert data ............") + + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:30.000','192.168.192.102')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:31.000','172.18.23.249')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:32.000','192.168.200.231')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:33.000','172.18.22.231')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:34.000','192.168.210.231')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:35.000','192.168.192.100')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:36.000','192.168.192.231')") + tdSql.execute(f"INSERT INTO `dwd_log_master_475021043` VALUES ('2023-06-26 14:38:37.000','172.18.23.231')") + + tdLog.debug("insert data ............ [OK]") + + def run(self): + tdSql.prepare() + self.create_tables() + self.insert_data() + tdLog.printNoPrefix("======== test TS-3581") + + for i in range(100): + tdSql.query(f"select first(ts), last(ts), count(*) from dwd_log_master;") + tdSql.checkRows(1) + print(tdSql.queryResult) + tdSql.checkData(0, 0, '2023-06-26 14:38:30.000') + return + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tools/shell/src/shellWebsocket.c b/tools/shell/src/shellWebsocket.c index d8920cb4c3..af7f13c69c 100644 --- a/tools/shell/src/shellWebsocket.c +++ b/tools/shell/src/shellWebsocket.c @@ -17,6 +17,9 @@ #include #include +// save current database name +char curDBName[128] = ""; // TDB_MAX_DBNAME_LEN is 24, put large + int shell_conn_ws_server(bool first) { char cuttedDsn[SHELL_WS_DSN_BUFF] = {0}; int dsnLen = strlen(shell.args.dsn); @@ -59,6 +62,14 @@ int shell_conn_ws_server(bool first) { fprintf(stdout, "successfully connected to cloud service\n"); } fflush(stdout); + + // switch to current database if have + if(curDBName[0] !=0) { + char command[256]; + sprintf(command, "use %s;", curDBName); + shellRunSingleCommandWebsocketImp(command); + } + return 0; } @@ -290,7 +301,46 @@ void shellRunSingleCommandWebsocketImp(char *command) { if (shellRegexMatch(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) { - fprintf(stdout, "Database changed.\r\n\r\n"); + + // copy dbname to curDBName + char *p = command; + bool firstStart = false; + bool firstEnd = false; + int i = 0; + while (*p != 0) { + if (*p != ' ') { + // not blank + if (!firstStart) { + firstStart = true; + } else if (firstEnd) { + if(*p == ';' && *p != '\\') { + break; + } + // database name + curDBName[i++] = *p; + if(i + 4 > sizeof(curDBName)) { + // DBName is too long, reset zero and break + i = 0; + break; + } + } + } else { + // blank + if(firstStart == true && firstEnd == false){ + firstEnd = true; + } + if(firstStart && firstEnd && i > 0){ + // blank after database name + break; + } + } + // move next + p++; + } + // append end + curDBName[i] = 0; + + fprintf(stdout, "Database changed to %s.\r\n\r\n", curDBName); fflush(stdout); ws_free_result(res); return; diff --git a/utils/test/c/tmq_taosx_ci.c b/utils/test/c/tmq_taosx_ci.c index c4becdd381..5d4d73c448 100644 --- a/utils/test/c/tmq_taosx_ci.c +++ b/utils/test/c/tmq_taosx_ci.c @@ -27,6 +27,7 @@ typedef struct { bool snapShot; bool dropTable; bool subTable; + int meta; int srcVgroups; int dstVgroups; char dir[64]; @@ -511,14 +512,18 @@ int32_t create_topic() { taos_free_result(pRes); if (g_conf.subTable) { - pRes = taos_query(pConn, "create topic meters_summary_t1 with meta as stable meters_summary"); + char topic[128] = {0}; + sprintf(topic, "create topic meters_summary_t1 %s as stable meters_summary", g_conf.meta == 0 ? "with meta" : "only meta"); + pRes = taos_query(pConn, topic); if (taos_errno(pRes) != 0) { printf("failed to create topic meters_summary_t1, reason:%s\n", taos_errstr(pRes)); return -1; } taos_free_result(pRes); } else { - pRes = taos_query(pConn, "create topic topic_db with meta as database abc1"); + char topic[128] = {0}; + sprintf(topic, "create topic topic_db %s as database abc1", g_conf.meta == 0 ? "with meta" : "only meta"); + pRes = taos_query(pConn, topic); if (taos_errno(pRes) != 0) { printf("failed to create topic topic_db, reason:%s\n", taos_errstr(pRes)); return -1; @@ -692,95 +697,185 @@ void initLogFile() { } } } else { - if (g_conf.subTable) { - char* result[] = { - "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"meters_summary\",\"columns\":[{\"name\":\"_" - "wstart\",\"type\":9},{\"name\":\"current\",\"type\":6},{\"name\":\"groupid\",\"type\":4},{\"name\":" - "\"location\",\"type\":8,\"length\":16}],\"tags\":[{\"name\":\"group_id\",\"type\":14}]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"t_d2a450ee819dcf7576f0282d9ac22dbc\",\"using\":" - "\"meters_summary\",\"tagNum\":1,\"tags\":[{\"name\":\"group_id\",\"type\":14,\"value\":1.313555008277358e+" - "19}],\"createList\":[]}"}; + if (g_conf.meta) { + if (g_conf.subTable){ - for (int i = 0; i < sizeof(result) / sizeof(result[0]); i++) { - taosFprintfFile(pFile2, result[i]); - taosFprintfFile(pFile2, "\n"); + }else{ + char* result[] = { + "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"tb1\",\"columns\":[{\"name\":\"ts\",\"type\":" + "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":4}],\"tags\":[]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"st1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct0\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":1000},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"ttt\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct1\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":2000}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct2\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":3000}],\"createList\":[]}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":5,\"colName\":\"c4\"," + "\"colType\":5}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":7,\"colName\":\"c3\"," + "\"colType\":8,\"colLength\":64}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":1,\"colName\":\"t2\"," + "\"colType\":8,\"colLength\":64}", + "{\"type\":\"alter\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"alterType\":4,\"colName\":\"t1\"," + "\"colValue\":\"5000\",\"colValueNull\":false}", + "{\"type\":\"drop\",\"tableNameList\":[\"ct3\",\"ct1\"]}", + "{\"type\":\"drop\",\"tableType\":\"super\",\"tableName\":\"st1\"}", + "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":10,\"length\":4}],\"tags\":[]}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":5,\"colName\":\"c3\"," + "\"colType\":5}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":7,\"colName\":\"c2\"," + "\"colType\":10,\"colLength\":8}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":10,\"colName\":\"c3\"," + "\"colNewName\":\"cc3\"}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":9}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":6,\"colName\":\"c1\"}", + "{\"type\":\"drop\",\"tableNameList\":[\"n1\"]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"jt\",\"columns\":[{\"name\":\"ts\",\"type\":9}," + "{\"name\":\"i\",\"type\":4}],\"tags\":[{\"name\":\"t\",\"type\":15}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt1\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[{" + "\"name\":\"t\",\"type\":15,\"value\":\"{\\\"k1\\\":1,\\\"k2\\\":\\\"hello\\\"}\"}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt2\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[]" + ",\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"st1\",\"columns\":[{\"name\":\"ts\",\"type\":9}," + "{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":1}]}", + "{\"type\":\"drop\",\"tableType\":\"super\",\"tableName\":\"st1\"}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"stt\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"sttb\",\"columns\":[{\"name\":\"ts\",\"type\":" + "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt1\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" + "[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt1\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt1\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb1\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt2\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":43},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb2\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":54},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt3\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" + "[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt3\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt3\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb3\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt4\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":433},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb4\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":543},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}"}; + + for (int i = 0; i < sizeof(result) / sizeof(result[0]); i++) { + taosFprintfFile(pFile2, result[i]); + taosFprintfFile(pFile2, "\n"); + } } } else { - char* result[] = { - "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"tb1\",\"columns\":[{\"name\":\"ts\",\"type\":" - "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":4}],\"tags\":[]}", - "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"st1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" - ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," - "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" - "1}]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct0\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" - "{\"name\":\"t1\",\"type\":4,\"value\":1000},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"ttt\\\"\"},{" - "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct1\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" - "{\"name\":\"t1\",\"type\":4,\"value\":2000}],\"createList\":[]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct2\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" - "],\"createList\":[]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" - "{\"name\":\"t1\",\"type\":4,\"value\":3000}],\"createList\":[]}", - "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":5,\"colName\":\"c4\"," - "\"colType\":5}", - "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":7,\"colName\":\"c3\"," - "\"colType\":8,\"colLength\":64}", - "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":1,\"colName\":\"t2\"," - "\"colType\":8,\"colLength\":64}", - "{\"type\":\"alter\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"alterType\":4,\"colName\":\"t1\"," - "\"colValue\":\"5000\",\"colValueNull\":false}", - "{\"type\":\"delete\",\"sql\":\"delete from `ct3` where `ts` >= 1626006833600 and `ts` <= 1626006833605\"}", - "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" - ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":10,\"length\":4}],\"tags\":[]}", - "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":5,\"colName\":\"c3\"," - "\"colType\":5}", - "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":7,\"colName\":\"c2\"," - "\"colType\":10,\"colLength\":8}", - "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":10,\"colName\":\"c3\"," - "\"colNewName\":\"cc3\"}", - "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":9}", - "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":6,\"colName\":\"c1\"}", - "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"jt\",\"columns\":[{\"name\":\"ts\",\"type\":9}," - "{\"name\":\"i\",\"type\":4}],\"tags\":[{\"name\":\"t\",\"type\":15}]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt1\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[{" - "\"name\":\"t\",\"type\":15,\"value\":\"{\\\"k1\\\":1,\\\"k2\\\":\\\"hello\\\"}\"}],\"createList\":[]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt2\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[]" - ",\"createList\":[]}", - "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"stt\",\"columns\":[{\"name\":\"ts\",\"type\":9}" - ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," - "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" - "1}]}", - "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"sttb\",\"columns\":[{\"name\":\"ts\",\"type\":" - "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," - "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" - "1}]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt1\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" - "[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt1\\\"\"},{" - "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt1\",\"using\":\"stt\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"stt1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb1\",\"using\":\"sttb\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"sttb1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt2\",\"using\":\"stt\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":43},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"stt2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb2\",\"using\":\"sttb\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":54},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"sttb2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}", - "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt3\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" - "[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt3\\\"\"},{" - "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt3\",\"using\":\"stt\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"stt3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb3\",\"using\":\"sttb\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"sttb3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt4\",\"using\":\"stt\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":433},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"stt4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb4\",\"using\":\"sttb\"," - "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":543},{\"name\":\"t3\",\"type\":10,\"value\":" - "\"\\\"sttb4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}"}; + if (g_conf.subTable) { + char* result[] = { + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"meters_summary\",\"columns\":[{\"name\":\"_" + "wstart\",\"type\":9},{\"name\":\"current\",\"type\":6},{\"name\":\"groupid\",\"type\":4},{\"name\":" + "\"location\",\"type\":8,\"length\":16}],\"tags\":[{\"name\":\"group_id\",\"type\":14}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"t_d2a450ee819dcf7576f0282d9ac22dbc\",\"using\":" + "\"meters_summary\",\"tagNum\":1,\"tags\":[{\"name\":\"group_id\",\"type\":14,\"value\":1.313555008277358e+" + "19}],\"createList\":[]}"}; - for (int i = 0; i < sizeof(result) / sizeof(result[0]); i++) { - taosFprintfFile(pFile2, result[i]); - taosFprintfFile(pFile2, "\n"); + for (int i = 0; i < sizeof(result) / sizeof(result[0]); i++) { + taosFprintfFile(pFile2, result[i]); + taosFprintfFile(pFile2, "\n"); + } + } + else { + char* result[] = { + "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"tb1\",\"columns\":[{\"name\":\"ts\",\"type\":" + "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":4}],\"tags\":[]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"st1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct0\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":1000},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"ttt\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct1\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":2000}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct2\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"using\":\"st1\",\"tagNum\":3,\"tags\":[" + "{\"name\":\"t1\",\"type\":4,\"value\":3000}],\"createList\":[]}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":5,\"colName\":\"c4\"," + "\"colType\":5}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":7,\"colName\":\"c3\"," + "\"colType\":8,\"colLength\":64}", + "{\"type\":\"alter\",\"tableType\":\"super\",\"tableName\":\"st1\",\"alterType\":1,\"colName\":\"t2\"," + "\"colType\":8,\"colLength\":64}", + "{\"type\":\"alter\",\"tableType\":\"child\",\"tableName\":\"ct3\",\"alterType\":4,\"colName\":\"t1\"," + "\"colValue\":\"5000\",\"colValueNull\":false}", + "{\"type\":\"delete\",\"sql\":\"delete from `ct3` where `ts` >= 1626006833600 and `ts` <= 1626006833605\"}", + "{\"type\":\"create\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":10,\"length\":4}],\"tags\":[]}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":5,\"colName\":\"c3\"," + "\"colType\":5}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":7,\"colName\":\"c2\"," + "\"colType\":10,\"colLength\":8}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":10,\"colName\":\"c3\"," + "\"colNewName\":\"cc3\"}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":9}", + "{\"type\":\"alter\",\"tableType\":\"normal\",\"tableName\":\"n1\",\"alterType\":6,\"colName\":\"c1\"}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"jt\",\"columns\":[{\"name\":\"ts\",\"type\":9}," + "{\"name\":\"i\",\"type\":4}],\"tags\":[{\"name\":\"t\",\"type\":15}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt1\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[{" + "\"name\":\"t\",\"type\":15,\"value\":\"{\\\"k1\\\":1,\\\"k2\\\":\\\"hello\\\"}\"}],\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"jt2\",\"using\":\"jt\",\"tagNum\":1,\"tags\":[]" + ",\"createList\":[]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"stt\",\"columns\":[{\"name\":\"ts\",\"type\":9}" + ",{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"super\",\"tableName\":\"sttb\",\"columns\":[{\"name\":\"ts\",\"type\":" + "9},{\"name\":\"c1\",\"type\":4},{\"name\":\"c2\",\"type\":6},{\"name\":\"c3\",\"type\":8,\"length\":16}]," + "\"tags\":[{\"name\":\"t1\",\"type\":4},{\"name\":\"t3\",\"type\":10,\"length\":8},{\"name\":\"t4\",\"type\":" + "1}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt1\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" + "[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt1\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt1\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":2},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb1\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb1\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt2\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":43},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb2\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":54},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb2\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}", + "{\"type\":\"create\",\"tableType\":\"child\",\"tableName\":\"stt3\",\"using\":\"stt\",\"tagNum\":3,\"tags\":" + "[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":\"\\\"stt3\\\"\"},{" + "\"name\":\"t4\",\"type\":1,\"value\":1}],\"createList\":[{\"tableName\":\"stt3\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":23},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"sttb3\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":4},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb3\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]},{\"tableName\":\"stt4\",\"using\":\"stt\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":433},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"stt4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":0}]},{\"tableName\":\"sttb4\",\"using\":\"sttb\"," + "\"tagNum\":3,\"tags\":[{\"name\":\"t1\",\"type\":4,\"value\":543},{\"name\":\"t3\",\"type\":10,\"value\":" + "\"\\\"sttb4\\\"\"},{\"name\":\"t4\",\"type\":1,\"value\":1}]}]}"}; + + for (int i = 0; i < sizeof(result) / sizeof(result[0]); i++) { + taosFprintfFile(pFile2, result[i]); + taosFprintfFile(pFile2, "\n"); + } } } } @@ -802,6 +897,8 @@ int main(int argc, char* argv[]) { g_conf.dstVgroups = atol(argv[++i]); } else if (strcmp(argv[i], "-t") == 0) { g_conf.subTable = true; + } else if (strcmp(argv[i], "-onlymeta") == 0) { + g_conf.meta = 1; } }