diff --git a/cmake/cmake.platform b/cmake/cmake.platform index acf17e9427..849d31f93e 100644 --- a/cmake/cmake.platform +++ b/cmake/cmake.platform @@ -70,5 +70,46 @@ ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Windows") ENDIF() +IF ("${CPUTYPE}" STREQUAL "") + MESSAGE(STATUS "The current platform " ${CMAKE_SYSTEM_PROCESSOR} " is detected") + + IF (CMAKE_SYSTEM_PROCESSOR MATCHES "(amd64)|(AMD64)") + MESSAGE(STATUS "The current platform is amd64") + SET(PLATFORM_ARCH_STR "amd64") + ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)") + MESSAGE(STATUS "The current platform is x86") + SET(PLATFORM_ARCH_STR "i386") + ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "armv7l") + MESSAGE(STATUS "The current platform is aarch32") + SET(PLATFORM_ARCH_STR "arm") + ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + MESSAGE(STATUS "The current platform is aarch64") + SET(PLATFORM_ARCH_STR "arm64") + ENDIF () +ELSE () + # if generate ARM version: + # cmake -DCPUTYPE=aarch32 .. or cmake -DCPUTYPE=aarch64 + IF (${CPUTYPE} MATCHES "aarch32") + SET(PLATFORM_ARCH_STR "arm") + MESSAGE(STATUS "input cpuType: aarch32") + ELSEIF (${CPUTYPE} MATCHES "aarch64") + SET(PLATFORM_ARCH_STR "arm64") + MESSAGE(STATUS "input cpuType: aarch64") + ELSEIF (${CPUTYPE} MATCHES "mips64") + SET(PLATFORM_ARCH_STR "mips") + MESSAGE(STATUS "input cpuType: mips64") + ELSEIF (${CPUTYPE} MATCHES "x64") + SET(PLATFORM_ARCH_STR "amd64") + MESSAGE(STATUS "input cpuType: x64") + ELSEIF (${CPUTYPE} MATCHES "x86") + SET(PLATFORM_ARCH_STR "i386") + MESSAGE(STATUS "input cpuType: x86") + ELSE () + MESSAGE(STATUS "input cpuType unknown " ${CPUTYPE}) + ENDIF () +ENDIF () + +MESSAGE(STATUS "platform arch:" ${PLATFORM_ARCH_STR}) + MESSAGE("C Compiler ID: ${CMAKE_C_COMPILER_ID}") MESSAGE("CXX Compiler ID: ${CMAKE_CXX_COMPILER_ID}") diff --git a/docs/en/10-cluster/02-cluster-mgmt.md b/docs/en/10-cluster/02-cluster-mgmt.md index 674c92e276..bd3386c411 100644 --- a/docs/en/10-cluster/02-cluster-mgmt.md +++ b/docs/en/10-cluster/02-cluster-mgmt.md @@ -54,14 +54,14 @@ Database changed. taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | compacting | ========================================================================================== - 14 | 38000 | ready | 1 | 1 | master | 0 | - 15 | 38000 | ready | 1 | 1 | master | 0 | - 16 | 38000 | ready | 1 | 1 | master | 0 | - 17 | 38000 | ready | 1 | 1 | master | 0 | - 18 | 37001 | ready | 1 | 1 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | + 14 | 38000 | ready | 1 | 1 | leader | 0 | + 15 | 38000 | ready | 1 | 1 | leader | 0 | + 16 | 38000 | ready | 1 | 1 | leader | 0 | + 17 | 38000 | ready | 1 | 1 | leader | 0 | + 18 | 37001 | ready | 1 | 1 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | Query OK, 8 row(s) in set (0.001154s) ``` @@ -161,14 +161,14 @@ First `show vgroups` is executed to show the vgroup distribution. taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | compacting | ========================================================================================== - 14 | 38000 | ready | 1 | 3 | master | 0 | - 15 | 38000 | ready | 1 | 3 | master | 0 | - 16 | 38000 | ready | 1 | 3 | master | 0 | - 17 | 38000 | ready | 1 | 3 | master | 0 | - 18 | 37001 | ready | 1 | 3 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | + 14 | 38000 | ready | 1 | 3 | leader | 0 | + 15 | 38000 | ready | 1 | 3 | leader | 0 | + 16 | 38000 | ready | 1 | 3 | leader | 0 | + 17 | 38000 | ready | 1 | 3 | leader | 0 | + 18 | 37001 | ready | 1 | 3 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | Query OK, 8 row(s) in set (0.001314s) ``` @@ -191,14 +191,14 @@ Query OK, 0 row(s) in set (0.000575s) taos> show vgroups; vgId | tables | status | onlines | v1_dnode | v1_status | v2_dnode | v2_status | compacting | ================================================================================================================= - 14 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 15 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 16 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 17 | 38000 | ready | 1 | 3 | master | 0 | NULL | 0 | - 18 | 37001 | ready | 2 | 1 | slave | 3 | master | 0 | - 19 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | - 20 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | - 21 | 37000 | ready | 1 | 1 | master | 0 | NULL | 0 | + 14 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 15 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 16 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 17 | 38000 | ready | 1 | 3 | leader | 0 | NULL | 0 | + 18 | 37001 | ready | 2 | 1 | follower | 3 | leader | 0 | + 19 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | + 20 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | + 21 | 37000 | ready | 1 | 1 | leader | 0 | NULL | 0 | Query OK, 8 row(s) in set (0.001242s) ``` @@ -207,7 +207,7 @@ It can be seen from above output that vgId 18 has been moved from dnode 3 to dno :::note - Manual load balancing can only be performed when the automatic load balancing is disabled, i.e. `balance` is set to 0. -- Only a vnode in normal state, i.e. master or slave, can be moved. vnode can't be moved when its in status offline, unsynced or syncing. +- Only a vnode in normal state, i.e. leader or follower, can be moved. vnode can't be moved when its in status offline, unsynced or syncing. - Before moving a vnode, it's necessary to make sure the target dnode has enough resources: CPU, memory and disk. ::: diff --git a/docs/en/10-cluster/03-ha-and-lb.md b/docs/en/10-cluster/03-ha-and-lb.md index bd718eef9f..9780e8f6c6 100644 --- a/docs/en/10-cluster/03-ha-and-lb.md +++ b/docs/en/10-cluster/03-ha-and-lb.md @@ -27,7 +27,7 @@ There may be multiple dnodes in a cluster, but only one mnode can be started in SHOW MNODES; ``` -The end point and role/status (master, slave, unsynced, or offline) of all mnodes can be shown by the above command. When the first dnode is started in a cluster, there must be one mnode in this dnode. Without at least one mnode, the cluster cannot work. If `numOfMNodes` is configured to 2, another mnode will be started when the second dnode is launched. +The end point and role/status (leader, follower, unsynced, or offline) of all mnodes can be shown by the above command. When the first dnode is started in a cluster, there must be one mnode in this dnode. Without at least one mnode, the cluster cannot work. If `numOfMNodes` is configured to 2, another mnode will be started when the second dnode is launched. For the high availability of mnode, `numOfMnodes` needs to be configured to 2 or a higher value. Because the data consistency between mnodes must be guaranteed, the replica confirmation parameter `quorum` is set to 2 automatically if `numOfMNodes` is set to 2 or higher. @@ -58,13 +58,13 @@ When a dnode is offline, it can be detected by the TDengine cluster. There are t - If the dnode has been offline over the threshold configured in `offlineThreshold` in `taos.cfg`, the dnode will be removed from the cluster automatically. A system alert will be generated and automatic load balancing will be triggered if `balance` is set to 1. When the removed dnode is restarted and becomes online, it will not join the cluster automatically. The system administrator has to manually join the dnode to the cluster. :::note -If all the vnodes in a vgroup (or mnodes in mnode group) are in offline or unsynced status, the master node can only be voted on, after all the vnodes or mnodes in the group become online and can exchange status. Following this, the vgroup (or mnode group) is able to provide service. +If all the vnodes in a vgroup (or mnodes in mnode group) are in offline or unsynced status, the leader node can only be voted on, after all the vnodes or mnodes in the group become online and can exchange status. Following this, the vgroup (or mnode group) is able to provide service. ::: ## Arbitrator -The "arbitrator" component is used to address the special case when the number of replicas is set to an even number like 2,4 etc. If half of the vnodes in a vgroup don't work, it is impossible to vote and select a master node. This situation also applies to mnodes if the number of mnodes is set to an even number like 2,4 etc. +The "arbitrator" component is used to address the special case when the number of replicas is set to an even number like 2,4 etc. If half of the vnodes in a vgroup don't work, it is impossible to vote and select a leader node. This situation also applies to mnodes if the number of mnodes is set to an even number like 2,4 etc. To resolve this problem, a new arbitrator component named `tarbitrator`, an abbreviation of TDengine Arbitrator, was introduced. The `tarbitrator` simulates a vnode or mnode but it's only responsible for network communication and doesn't handle any actual data access. As long as more than half of the vnode or mnode, including Arbitrator, are available the vnode group or mnode group can provide data insertion or query services normally. diff --git a/docs/en/14-reference/02-rest-api/02-rest-api.mdx b/docs/en/14-reference/02-rest-api/02-rest-api.mdx index 990af86196..fe18349a6d 100644 --- a/docs/en/14-reference/02-rest-api/02-rest-api.mdx +++ b/docs/en/14-reference/02-rest-api/02-rest-api.mdx @@ -21,7 +21,7 @@ The following example is in an Ubuntu environment and uses the `curl` tool to ve The following example lists all databases on the host h1.taosdata.com. To use it in your environment, replace `h1.taosdata.com` and `6041` (the default port) with the actual running TDengine service FQDN and port number. ```html -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' h1.taosdata.com:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" h1.taosdata.com:6041/rest/sql ``` The following return value results indicate that the verification passed. @@ -106,13 +106,13 @@ The HTTP request's BODY is a complete SQL command, and the data table in the SQL Use `curl` to initiate an HTTP request with a custom authentication method, with the following syntax. ```bash -curl -H 'Authorization: Basic ' -d '' :/rest/sql/[db_name] +curl -L -H "Authorization: Basic " -d "" :/rest/sql/[db_name] ``` Or ```bash -curl -u username:password -d '' :/rest/sql/[db_name] +curl -L -u username:password -d "" :/rest/sql/[db_name] ``` where `TOKEN` is the string after Base64 encoding of `{username}:{password}`, e.g. `root:taosdata` is encoded as `cm9vdDp0YW9zZGF0YQ==`. @@ -192,7 +192,7 @@ Response body: - query all records from table d1001 of database demo ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sql ``` Response body: @@ -218,7 +218,7 @@ Response body: - Create database demo: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "create database demo" 192.168.0.1:6041/rest/sql ``` Response body: @@ -240,7 +240,7 @@ Response body: When the HTTP request URL uses `/rest/sqlt`, the returned result set's timestamp value will be in Unix timestamp format, for example: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sqlt +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sqlt ``` Response body: @@ -268,7 +268,7 @@ Response body: When the HTTP request URL uses `/rest/sqlutc`, the timestamp of the returned result set will be expressed as a UTC format, for example: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6041/rest/sqlutc + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.t1" 192.168.0.1:6041/rest/sqlutc ``` Response body: diff --git a/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json index f651983528..54dc1062d6 100644 --- a/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json +++ b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json @@ -211,7 +211,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode", + "title": "Leader MNode", "transformations": [ { "id": "filterByValue", @@ -221,7 +221,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" @@ -300,7 +300,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode Create Time", + "title": "Leader MNode Create Time", "transformations": [ { "id": "filterByValue", @@ -310,7 +310,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" diff --git a/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json index b4254c428b..1add8522a7 100644 --- a/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json +++ b/docs/en/14-reference/07-tdinsight/assets/tdengine-grafana-7.x.json @@ -153,7 +153,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode", + "title": "Leader MNode", "transformations": [ { "id": "filterByValue", @@ -163,7 +163,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" @@ -246,7 +246,7 @@ ], "timeFrom": null, "timeShift": null, - "title": "Master MNode Create Time", + "title": "Leader MNode Create Time", "transformations": [ { "id": "filterByValue", @@ -256,7 +256,7 @@ "config": { "id": "regex", "options": { - "value": "master" + "value": "leader" } }, "fieldName": "role" diff --git a/docs/en/14-reference/07-tdinsight/index.md b/docs/en/14-reference/07-tdinsight/index.md index cebfafa225..e74c9de7b2 100644 --- a/docs/en/14-reference/07-tdinsight/index.md +++ b/docs/en/14-reference/07-tdinsight/index.md @@ -274,8 +274,8 @@ Details of the metrics are as follows. This section contains the current information and status of the cluster, the alert information is also here (from left to right, top to bottom). - **First EP**: the `firstEp` setting in the current TDengine cluster. -- **Version**: TDengine server version (master mnode). -- **Master Uptime**: The time elapsed since the current Master MNode was elected as Master. +- **Version**: TDengine server version (leader mnode). +- **Leader Uptime**: The time elapsed since the current Leader MNode was elected as Leader. - **Expire Time** - Enterprise version expiration time. - **Used Measuring Points** - The number of measuring points used by the Enterprise Edition. - **Databases** - The number of databases. @@ -333,7 +333,7 @@ Data node resource usage display with repeated multiple rows for the variable `$ 2. **Has MNodes?**: whether the current dnode is a mnode. 3. **CPU Cores**: the number of CPU cores. 4. **VNodes Number**: the number of VNodes in the current dnode. -5. **VNodes Masters**: the number of vnodes in the master role. +5. **VNodes Masters**: the number of vnodes in the leader role. 6. **Current CPU Usage of taosd**: CPU usage rate of taosd processes. 7. **Current Memory Usage of taosd**: memory usage of taosd processes. 8. **Disk Used**: The total disk usage percentage of the taosd data directory. diff --git a/docs/en/14-reference/12-directory.md b/docs/en/14-reference/12-directory.md index 304e3bcb43..d6cffd22e0 100644 --- a/docs/en/14-reference/12-directory.md +++ b/docs/en/14-reference/12-directory.md @@ -26,7 +26,6 @@ All executable files of TDengine are in the _/usr/local/taos/bin_ directory by d - _remove.sh_: script to uninstall TDengine, please execute it carefully, link to the **rmtaos** command in the /usr/bin directory. Will remove the TDengine installation directory `/usr/local/taos`, but will keep `/etc/taos`, `/var/lib/taos`, `/var/log/taos` - _taosadapter_: server-side executable that provides RESTful services and accepts writing requests from a variety of other softwares - _tarbitrator_: provides arbitration for two-node cluster deployments -- _run_taosd_and_taosadapter.sh_: script to start both taosd and taosAdapter - _TDinsight.sh_: script to download TDinsight and install it - _set_core.sh_: script for setting up the system to generate core dump files for easy debugging - _taosd-dump-cfg.gdb_: script to facilitate debugging of taosd's gdb execution. diff --git a/docs/en/21-tdinternal/01-arch.md b/docs/en/21-tdinternal/01-arch.md index 4d8bed4d2d..d7d472eb98 100644 --- a/docs/en/21-tdinternal/01-arch.md +++ b/docs/en/21-tdinternal/01-arch.md @@ -22,9 +22,9 @@ A complete TDengine system runs on one or more physical nodes. Logically, it inc **Virtual node (vnode)**: To better support data sharding, load balancing and prevent data from overheating or skewing, data nodes are virtualized into multiple virtual nodes (vnode, V2, V3, V4, etc. in the figure). Each vnode is a relatively independent work unit, which is the basic unit of time-series data storage and has independent running threads, memory space and persistent storage path. A vnode contains a certain number of tables (data collection points). When a new table is created, the system checks whether a new vnode needs to be created. The number of vnodes that can be created on a data node depends on the capacity of the hardware of the physical node where the data node is located. A vnode belongs to only one DB, but a DB can have multiple vnodes. In addition to the stored time-series data, a vnode also stores the schema and tag values of the included tables. A virtual node is uniquely identified in the system by the EP of the data node and the VGroup ID to which it belongs and is created and managed by the management node. -**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 5) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The master/slave mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the master. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. +**Management node (mnode)**: A virtual logical unit responsible for monitoring and maintaining the running status of all data nodes and load balancing among nodes (M in the figure). At the same time, the management node is also responsible for the storage and management of metadata (including users, databases, tables, static tags, etc.), so it is also called Meta Node. Multiple (up to 5) mnodes can be configured in a TDengine cluster, and they are automatically constructed into a virtual management node group (M0, M1, M2 in the figure). The leader/follower mechanism is adopted for the mnode group and the data synchronization is carried out in a strongly consistent way. Any data update operation can only be executed on the leader. The creation of mnode cluster is completed automatically by the system without manual intervention. There is at most one mnode on each dnode, which is uniquely identified by the EP of the data node to which it belongs. Each dnode automatically obtains the EP of the dnode where all mnodes in the whole cluster are located, through internal messaging interaction. -**Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a master/slave mechanism. Write operations can only be performed on the master vnode, and then replicated to slave vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `“replica”` when creating a DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node groups are created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, it means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. +**Virtual node group (VGroup)**: Vnodes on different data nodes can form a virtual node group to ensure the high availability of the system. The virtual node group is managed in a leader/follower mechanism. Write operations can only be performed on the leader vnode, and then replicated to follower vnodes, thus ensuring that one single replica of data is copied on multiple physical nodes. The number of virtual nodes in a vgroup equals the number of data replicas. If the number of replicas of a DB is N, the system must have at least N data nodes. The number of replicas can be specified by the parameter `“replica”` when creating a DB, and the default is 1. Using the multi-replication feature of TDengine, the same high data reliability can be achieved without the need for expensive storage devices such as disk arrays. Virtual node groups are created and managed by the management node, and the management node assigns a system unique ID, aka VGroup ID. If two virtual nodes have the same vnode group ID, it means that they belong to the same group and the data is backed up to each other. The number of virtual nodes in a virtual node group can be dynamically changed, allowing only one, that is, no data replication. VGroup ID is never changed. Even if a virtual node group is deleted, its ID will not be reused. **TAOSC**: TAOSC is the driver provided by TDengine to applications. It is responsible for dealing with the interaction between application and cluster, and provides the native interface for the C/C++ language. It is also embedded in the JDBC, C #, Python, Go, Node.js language connection libraries. Applications interact with the whole cluster through TAOSC instead of directly connecting to data nodes in the cluster. This module is responsible for obtaining and caching metadata; forwarding requests for insertion, query, etc. to the correct data node; when returning the results to the application, TAOSC also needs to be responsible for the final level of aggregation, sorting, filtering and other operations. For JDBC, C/C++/C#/Python/Go/Node.js interfaces, this module runs on the physical node where the application is located. At the same time, in order to support the fully distributed RESTful interface, TAOSC has a running instance on each dnode of TDengine cluster. @@ -62,13 +62,13 @@ To explain the relationship between vnode, mnode, TAOSC and application and thei 1. Application initiates a request to insert data through JDBC, ODBC, or other APIs. 2. TAOSC checks the cache to see if meta data exists for the table. If it does, it goes straight to Step 4. If not, TAOSC sends a get meta-data request to mnode. 3. Mnode returns the meta-data of the table to TAOSC. Meta-data contains the schema of the table, and also the vgroup information to which the table belongs (the vnode ID and the End Point of the dnode where the table belongs. If the number of replicas is N, there will be N groups of End Points). If TAOSC does not receive a response from the mnode for a long time, and there are multiple mnodes, TAOSC will send a request to the next mnode. -4. TAOSC initiates an insert request to master vnode. +4. TAOSC initiates an insert request to leader vnode. 5. After vnode inserts the data, it gives a reply to TAOSC, indicating that the insertion is successful. If TAOSC doesn't get a response from vnode for a long time, TAOSC will treat this node as offline. In this case, if there are multiple replicas of the inserted database, TAOSC will issue an insert request to the next vnode in vgroup. 6. TAOSC notifies APP that writing is successful. For Step 2 and 3, when TAOSC starts, it does not know the End Point of mnode, so it will directly initiate a request to the configured serving End Point of the cluster. If the dnode that receives the request does not have a mnode configured, it will reply with the mnode EP list, so that TAOSC will re-issue a request to obtain meta-data to the EP of another mnode. -For Step 4 and 5, without caching, TAOSC can't recognize the master in the virtual node group, so assumes that the first vnode is the master and sends a request to it. If this vnode is not the master, it will reply to the actual master as a new target to which TAOSC shall send a request. Once a response of successful insertion is obtained, TAOSC will cache the information of master node. +For Step 4 and 5, without caching, TAOSC can't recognize the leader in the virtual node group, so assumes that the first vnode is the leader and sends a request to it. If this vnode is not the leader, it will reply to the actual leader as a new target to which TAOSC shall send a request. Once a response of successful insertion is obtained, TAOSC will cache the information of leader node. The above describes the process of inserting data. The processes of querying and computing are the same. TAOSC encapsulates and hides all these complicated processes, and it is transparent to applications. @@ -119,65 +119,65 @@ The load balancing process does not require any manual intervention, and it is t ## Data Writing and Replication Process -If a database has N replicas, a virtual node group has N virtual nodes. But only one is the Master and all others are slaves. When the application writes a new record to system, only the Master vnode can accept the writing request. If a slave vnode receives a writing request, the system will notifies TAOSC to redirect. +If a database has N replicas, a virtual node group has N virtual nodes. But only one is the Leader and all others are slaves. When the application writes a new record to system, only the Leader vnode can accept the writing request. If a follower vnode receives a writing request, the system will notifies TAOSC to redirect. -### Master vnode Writing Process +### Leader vnode Writing Process -Master Vnode uses a writing process as follows: +Leader Vnode uses a writing process as follows: -![TDengine Database Master Writing Process](write_master.webp) -
Figure 3: TDengine Master writing process
+![TDengine Database Leader Writing Process](write_master.webp) +
Figure 3: TDengine Leader writing process
-1. Master vnode receives the application data insertion request, verifies, and moves to next step; +1. Leader vnode receives the application data insertion request, verifies, and moves to next step; 2. If the system configuration parameter `“walLevel”` is greater than 0, vnode will write the original request packet into database log file WAL. If walLevel is set to 2 and fsync is set to 0, TDengine will make WAL data written immediately to ensure that even system goes down, all data can be recovered from database log file; -3. If there are multiple replicas, vnode will forward data packet to slave vnodes in the same virtual node group, and the forwarded packet has a version number with data; +3. If there are multiple replicas, vnode will forward data packet to follower vnodes in the same virtual node group, and the forwarded packet has a version number with data; 4. Write into memory and add the record to “skip list”; -5. Master vnode returns a confirmation message to the application, indicating a successful write. +5. Leader vnode returns a confirmation message to the application, indicating a successful write. 6. If any of Step 2, 3 or 4 fails, the error will directly return to the application. -### Slave vnode Writing Process +### Follower vnode Writing Process -For a slave vnode, the write process as follows: +For a follower vnode, the write process as follows: -![TDengine Database Slave Writing Process](write_slave.webp) -
Figure 4: TDengine Slave Writing Process
+![TDengine Database Follower Writing Process](write_slave.webp) +
Figure 4: TDengine Follower Writing Process
-1. Slave vnode receives a data insertion request forwarded by Master vnode; +1. Follower vnode receives a data insertion request forwarded by Leader vnode; 2. If the system configuration parameter `“walLevel”` is greater than 0, vnode will write the original request packet into database log file WAL. If walLevel is set to 2 and fsync is set to 0, TDengine will make WAL data written immediately to ensure that even system goes down, all data can be recovered from database log file; 3. Write into memory and add the record to “skip list”. -Compared with Master vnode, slave vnode has no forwarding or reply confirmation step, means two steps less. But writing into memory and WAL is exactly the same. +Compared with Leader vnode, follower vnode has no forwarding or reply confirmation step, means two steps less. But writing into memory and WAL is exactly the same. ### Remote Disaster Recovery and IDC (Internet Data Center) Migration -As discussed above, TDengine writes using Master and Slave processes. TDengine adopts asynchronous replication for data synchronization. This method can greatly improve write performance, with no obvious impact from network delay. By configuring IDC and rack number for each physical node, it can be ensured that for a virtual node group, virtual nodes are composed of physical nodes from different IDC and different racks, thus implementing remote disaster recovery without other tools. +As discussed above, TDengine writes using Leader and Follower processes. TDengine adopts asynchronous replication for data synchronization. This method can greatly improve write performance, with no obvious impact from network delay. By configuring IDC and rack number for each physical node, it can be ensured that for a virtual node group, virtual nodes are composed of physical nodes from different IDC and different racks, thus implementing remote disaster recovery without other tools. -On the other hand, TDengine supports dynamic modification of the replica number. Once the number of replicas increases, the newly added virtual nodes will immediately enter the data synchronization process. After synchronization is complete, added virtual nodes can provide services. In the synchronization process, master and other synchronized virtual nodes keep serving. With this feature, TDengine can provide IDC migration without service interruption. It is only necessary to add new physical nodes to the existing IDC cluster, and then remove old physical nodes after the data synchronization is completed. +On the other hand, TDengine supports dynamic modification of the replica number. Once the number of replicas increases, the newly added virtual nodes will immediately enter the data synchronization process. After synchronization is complete, added virtual nodes can provide services. In the synchronization process, leader and other synchronized virtual nodes keep serving. With this feature, TDengine can provide IDC migration without service interruption. It is only necessary to add new physical nodes to the existing IDC cluster, and then remove old physical nodes after the data synchronization is completed. However, the asynchronous replication has a very low probability scenario where data may be lost. The specific scenario is as follows: -1. Master vnode has finished its 5-step operations, confirmed the success of writing to APP, and then goes down; -2. Slave vnode receives the write request, then processing fails before writing to the log in Step 2; -3. Slave vnode will become the new master, thus losing one record. +1. Leader vnode has finished its 5-step operations, confirmed the success of writing to APP, and then goes down; +2. Follower vnode receives the write request, then processing fails before writing to the log in Step 2; +3. Follower vnode will become the new leader, thus losing one record. In theory, for asynchronous replication, there is no guarantee to prevent data loss. However, this is an extremely low probability scenario as described above. Note: Remote disaster recovery and no-downtime IDC migration are only supported by Enterprise Edition. **Hint: This function is not available yet** -### Master/slave Selection +### Leader/follower Selection Vnode maintains a version number. When memory data is persisted, the version number will also be persisted. For each data update operation, whether it is time-series data or metadata, this version number will be increased by one. -When a vnode starts, the roles (master, slave) are uncertain, and the data is in an unsynchronized state. It’s necessary to establish TCP connections with other nodes in the virtual node group and exchange status, including version and its own roles. Through the exchange, the system implements a master-selection process. The rules are as follows: +When a vnode starts, the roles (leader, follower) are uncertain, and the data is in an unsynchronized state. It’s necessary to establish TCP connections with other nodes in the virtual node group and exchange status, including version and its own roles. Through the exchange, the system implements a leader-selection process. The rules are as follows: -1. If there’s only one replica, it’s always master -2. When all replicas are online, the one with latest version is master -3. Over half of online nodes are virtual nodes, and some virtual node is slave, it will automatically become master -4. For 2 and 3, if multiple virtual nodes meet the requirement, the first vnode in virtual node group list will be selected as master. +1. If there’s only one replica, it’s always leader +2. When all replicas are online, the one with latest version is leader +3. Over half of online nodes are virtual nodes, and some virtual node is follower, it will automatically become leader +4. For 2 and 3, if multiple virtual nodes meet the requirement, the first vnode in virtual node group list will be selected as leader. ### Synchronous Replication -For scenarios with strong data consistency requirements, asynchronous data replication is not applicable, because there is a small probability of data loss. So, TDengine provides a synchronous replication mechanism for users. When creating a database, in addition to specifying the number of replicas, user also needs to specify a new parameter “quorum”. If quorum is greater than one, it means that every time the Master forwards a message to the replica, it needs to wait for “quorum-1” reply confirms before informing the application that data has been successfully written in slave. If “quorum-1” reply confirms are not received within a certain period of time, the master vnode will return an error to the application. +For scenarios with strong data consistency requirements, asynchronous data replication is not applicable, because there is a small probability of data loss. So, TDengine provides a synchronous replication mechanism for users. When creating a database, in addition to specifying the number of replicas, user also needs to specify a new parameter “quorum”. If quorum is greater than one, it means that every time the Leader forwards a message to the replica, it needs to wait for “quorum-1” reply confirms before informing the application that data has been successfully written in follower. If “quorum-1” reply confirms are not received within a certain period of time, the leader vnode will return an error to the application. With synchronous replication, performance of system will decrease and latency will increase. Because metadata needs strong consistency, the default for data synchronization between mnodes is synchronous replication. diff --git a/docs/en/27-train-faq/03-docker.md b/docs/en/27-train-faq/03-docker.md index afee13c137..0378fffb8b 100644 --- a/docs/en/27-train-faq/03-docker.md +++ b/docs/en/27-train-faq/03-docker.md @@ -109,7 +109,7 @@ taos> It's also able to access the REST interface provided by TDengine in container from the host. ``` -curl -u root:taosdata -d 'show databases' 127.0.0.1:6041/rest/sql +curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql ``` Output is like below: @@ -147,7 +147,7 @@ docker run -d --name tdengine-taosd -p 6030-6042:6030-6042 -p 6030-6042:6030-604 - Verify the REST interface: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' 127.0.0.1:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" 127.0.0.1:6041/rest/sql ``` Below is an example output: diff --git a/docs/zh/14-reference/02-rest-api/02-rest-api.mdx b/docs/zh/14-reference/02-rest-api/02-rest-api.mdx index 43099319b9..a8a92606e4 100644 --- a/docs/zh/14-reference/02-rest-api/02-rest-api.mdx +++ b/docs/zh/14-reference/02-rest-api/02-rest-api.mdx @@ -21,7 +21,7 @@ RESTful 接口不依赖于任何 TDengine 的库,因此客户端不需要安 下面示例是列出所有的数据库,请把 h1.taosdata.com 和 6041(缺省值)替换为实际运行的 TDengine 服务 FQDN 和端口号: ```html -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' h1.taosdata.com:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" h1.taosdata.com:6041/rest/sql ``` 返回值结果如下表示验证通过: @@ -106,13 +106,13 @@ HTTP 请求的 BODY 里就是一个完整的 SQL 语句,SQL 语句中的数据 使用 `curl` 通过自定义身份认证方式来发起一个 HTTP Request,语法如下: ```bash -curl -H 'Authorization: Basic ' -d '' :/rest/sql/[db_name] +curl -L -H "Authorization: Basic " -d "" :/rest/sql/[db_name] ``` 或者 ```bash -curl -u username:password -d '' :/rest/sql/[db_name] +curl -L -u username:password -d "" :/rest/sql/[db_name] ``` 其中,`TOKEN` 为 `{username}:{password}` 经过 Base64 编码之后的字符串,例如 `root:taosdata` 编码后为 `cm9vdDp0YW9zZGF0YQ==` @@ -192,7 +192,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata - 在 demo 库里查询表 d1001 的所有记录: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sql ``` 返回值: @@ -218,7 +218,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata - 创建库 demo: ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6041/rest/sql + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "create database demo" 192.168.0.1:6041/rest/sql ``` 返回值: @@ -240,7 +240,7 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata HTTP 请求 URL 采用 `/rest/sqlt` 时,返回结果集的时间戳将采用 Unix 时间戳格式表示,例如 ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001' 192.168.0.1:6041/rest/sqlt +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sqlt ``` 返回结果: @@ -268,7 +268,7 @@ curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.d1001 HTTP 请求 URL 采用 `/rest/sqlutc` 时,返回结果集的时间戳将采用 UTC 时间字符串表示,例如 ```bash - curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6041/rest/sqlutc + curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.t1" 192.168.0.1:6041/rest/sqlutc ``` 返回值: diff --git a/docs/zh/14-reference/12-directory.md b/docs/zh/14-reference/12-directory.md index f8c8cb4a08..0caf7e03c3 100644 --- a/docs/zh/14-reference/12-directory.md +++ b/docs/zh/14-reference/12-directory.md @@ -26,7 +26,6 @@ TDengine 的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下 - _remove.sh_:卸载 TDengine 的脚本,请谨慎执行,链接到/usr/bin 目录下的**rmtaos**命令。会删除 TDengine 的安装目录/usr/local/taos,但会保留/etc/taos、/var/lib/taos、/var/log/taos - _taosadapter_: 提供 RESTful 服务和接受其他多种软件写入请求的服务端可执行文件 - _tarbitrator_: 提供双节点集群部署的仲裁功能 -- _run_taosd_and_taosadapter.sh_:同时启动 taosd 和 taosAdapter 的脚本 - _TDinsight.sh_:用于下载 TDinsight 并安装的脚本 - _set_core.sh_:用于方便调试设置系统生成 core dump 文件的脚本 - _taosd-dump-cfg.gdb_:用于方便调试 taosd 的 gdb 执行脚本。 diff --git a/docs/zh/27-train-faq/03-docker.md b/docs/zh/27-train-faq/03-docker.md index 7791569b25..72b4603dda 100644 --- a/docs/zh/27-train-faq/03-docker.md +++ b/docs/zh/27-train-faq/03-docker.md @@ -108,7 +108,7 @@ taos> 也可以在宿主机使用 curl 通过 RESTful 端口访问 Docker 容器内的 TDengine server。 ``` -curl -u root:taosdata -d 'show databases' 127.0.0.1:6041/rest/sql +curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql ``` 输出示例如下: @@ -148,7 +148,7 @@ docker run -d --name tdengine-taosd -p 6030-6042:6030-6042 -p 6030-6042:6030-604 使用 curl 命令验证 RESTful 接口可以正常工作: ```bash -curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'show databases;' 127.0.0.1:6041/rest/sql +curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "show databases;" 127.0.0.1:6041/rest/sql ``` 输出示例如下: diff --git a/examples/c/stream_demo.c b/examples/c/stream_demo.c index 5f6e3b2aeb..961eb6c93a 100644 --- a/examples/c/stream_demo.c +++ b/examples/c/stream_demo.c @@ -90,9 +90,10 @@ int32_t create_stream() { /*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/ /*const char* sql = "select sum(k) from tu1 interval(10m)";*/ /*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/ - pRes = taos_query(pConn, - "create stream stream1 trigger window_close into outstb as select _wstartts, sum(k) from st1 " - "interval(10s) "); + pRes = taos_query( + pConn, + "create stream stream1 trigger window_close watermark 10s into outstb as select _wstartts, sum(k) from st1 " + "interval(10s) "); if (taos_errno(pRes) != 0) { printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes)); return -1; diff --git a/include/client/taos.h b/include/client/taos.h index 61538e392a..9d4da221f4 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -187,8 +187,8 @@ DLL_EXPORT TAOS_ROW *taos_result_block(TAOS_RES *res); DLL_EXPORT const char *taos_get_server_info(TAOS *taos); DLL_EXPORT const char *taos_get_client_info(); -DLL_EXPORT const char *taos_errstr(TAOS_RES *tres); -DLL_EXPORT int taos_errno(TAOS_RES *tres); +DLL_EXPORT const char *taos_errstr(TAOS_RES *res); +DLL_EXPORT int taos_errno(TAOS_RES *res); DLL_EXPORT void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param); DLL_EXPORT void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param); @@ -252,6 +252,16 @@ DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_comm /* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */ +enum tmq_res_t { + TMQ_RES_INVALID = -1, + TMQ_RES_DATA = 1, + TMQ_RES_TABLE_META = 2, +}; + +typedef enum tmq_res_t tmq_res_t; + +DLL_EXPORT tmq_res_t tmq_get_res_type(TAOS_RES *res); +DLL_EXPORT int32_t tmq_get_raw_meta(TAOS_RES *res, const void **raw_meta, int32_t *raw_meta_len); DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); diff --git a/include/common/systable.h b/include/common/systable.h index d2c28941c7..faea4dd3f8 100644 --- a/include/common/systable.h +++ b/include/common/systable.h @@ -41,6 +41,7 @@ extern "C" { #define TSDB_INS_TABLE_VGROUPS "vgroups" #define TSDB_INS_TABLE_VNODES "vnodes" #define TSDB_INS_TABLE_CONFIGS "configs" +#define TSDB_INS_TABLE_DNODE_VARIABLES "dnode_variables" #define TSDB_PERFORMANCE_SCHEMA_DB "performance_schema" #define TSDB_PERFS_TABLE_SMAS "smas" diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 371f182d53..35ed5aa997 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -34,6 +34,7 @@ enum { enum { TMQ_MSG_TYPE__DUMMY = 0, TMQ_MSG_TYPE__POLL_RSP, + TMQ_MSG_TYPE__POLL_META_RSP, TMQ_MSG_TYPE__EP_RSP, TMQ_MSG_TYPE__END_RSP, }; @@ -44,6 +45,7 @@ typedef enum EStreamType { STREAM_REPROCESS, STREAM_INVALID, STREAM_GET_ALL, + STREAM_DELETE, } EStreamType; typedef struct { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index a84bc3cd03..50cdff6969 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -168,7 +168,7 @@ typedef struct { int32_t vgId; char* dbFName; char* tbName; -} SBuildTableMetaInput; +} SBuildTableInput; typedef struct { char db[TSDB_DB_FNAME_LEN]; @@ -444,6 +444,7 @@ typedef struct { char* comment; char* pAst1; char* pAst2; + SArray* pFuncs; } SMCreateStbReq; int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq); @@ -662,6 +663,41 @@ int32_t tSerializeSQueryTableRsp(void* buf, int32_t bufLen, SQueryTableRsp* pRsp int32_t tDeserializeSQueryTableRsp(void* buf, int32_t bufLen, SQueryTableRsp* pRsp); +typedef struct { + SMsgHead header; + char dbFName[TSDB_DB_FNAME_LEN]; + char tbName[TSDB_TABLE_NAME_LEN]; +} STableCfgReq; + +typedef struct { + char tbName[TSDB_TABLE_NAME_LEN]; + char stbName[TSDB_TABLE_NAME_LEN]; + char dbFName[TSDB_DB_FNAME_LEN]; + int32_t numOfTags; + int32_t numOfColumns; + int8_t tableType; + int64_t delay1; + int64_t delay2; + int64_t watermark1; + int64_t watermark2; + int32_t ttl; + SArray* pFuncs; + int32_t commentLen; + char* pComment; + SSchema* pSchemas; + int32_t tagsLen; + char* pTags; +} STableCfg; + +typedef STableCfg STableCfgRsp; + +int32_t tSerializeSTableCfgReq(void *buf, int32_t bufLen, STableCfgReq *pReq); +int32_t tDeserializeSTableCfgReq(void *buf, int32_t bufLen, STableCfgReq *pReq); + +int32_t tSerializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp); +int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp); +void tFreeSTableCfgRsp(STableCfgRsp *pRsp); + typedef struct { char db[TSDB_DB_FNAME_LEN]; int32_t numOfVgroups; @@ -1312,7 +1348,7 @@ int32_t tSerializeSSetStandbyReq(void* buf, int32_t bufLen, SSetStandbyReq* pReq int32_t tDeserializeSSetStandbyReq(void* buf, int32_t bufLen, SSetStandbyReq* pReq); typedef struct { - char queryStrId[TSDB_QUERY_ID_LEN]; + char queryStrId[TSDB_QUERY_ID_LEN]; } SKillQueryReq; int32_t tSerializeSKillQueryReq(void* buf, int32_t bufLen, SKillQueryReq* pReq); @@ -1555,6 +1591,7 @@ typedef struct { char name[TSDB_TOPIC_FNAME_LEN]; // accout.topic int8_t igExists; int8_t subType; + int8_t withMeta; char* sql; char subDbName[TSDB_DB_FNAME_LEN]; union { @@ -2277,6 +2314,9 @@ typedef struct { int8_t igNotExists; } SMDropStreamReq; +int32_t tSerializeSMDropStreamReq(void* buf, int32_t bufLen, const SMDropStreamReq* pReq); +int32_t tDeserializeSMDropStreamReq(void* buf, int32_t bufLen, SMDropStreamReq* pReq); + typedef struct { int8_t reserved; } SMDropStreamRsp; @@ -2298,6 +2338,7 @@ typedef struct { int64_t newConsumerId; char subKey[TSDB_SUBSCRIBE_KEY_LEN]; int8_t subType; + int8_t withMeta; char* qmsg; int64_t suid; } SMqRebVgReq; @@ -2310,6 +2351,7 @@ static FORCE_INLINE int32_t tEncodeSMqRebVgReq(void** buf, const SMqRebVgReq* pR tlen += taosEncodeFixedI64(buf, pReq->newConsumerId); tlen += taosEncodeString(buf, pReq->subKey); tlen += taosEncodeFixedI8(buf, pReq->subType); + tlen += taosEncodeFixedI8(buf, pReq->withMeta); if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) { tlen += taosEncodeString(buf, pReq->qmsg); } else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) { @@ -2325,6 +2367,7 @@ static FORCE_INLINE void* tDecodeSMqRebVgReq(const void* buf, SMqRebVgReq* pReq) buf = taosDecodeFixedI64(buf, &pReq->newConsumerId); buf = taosDecodeStringTo(buf, pReq->subKey); buf = taosDecodeFixedI8(buf, &pReq->subType); + buf = taosDecodeFixedI8(buf, &pReq->withMeta); if (pReq->subType == TOPIC_SUB_TYPE__COLUMN) { buf = taosDecodeString(buf, &pReq->qmsg); } else if (pReq->subType == TOPIC_SUB_TYPE__TABLE) { @@ -2669,6 +2712,34 @@ static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) { taosArrayDestroy(pSubTopicEp->vgs); } +typedef struct { + SMqRspHead head; + int64_t reqOffset; + int64_t rspOffset; + int16_t resMsgType; + int32_t metaRspLen; + void* metaRsp; +} SMqMetaRsp; + +static FORCE_INLINE int32_t tEncodeSMqMetaRsp(void** buf, const SMqMetaRsp* pRsp) { + int32_t tlen = 0; + tlen += taosEncodeFixedI64(buf, pRsp->reqOffset); + tlen += taosEncodeFixedI64(buf, pRsp->rspOffset); + tlen += taosEncodeFixedI16(buf, pRsp->resMsgType); + tlen += taosEncodeFixedI32(buf, pRsp->metaRspLen); + tlen += taosEncodeBinary(buf, pRsp->metaRsp, pRsp->metaRspLen); + return tlen; +} + +static FORCE_INLINE void* tDecodeSMqMetaRsp(const void* buf, SMqMetaRsp* pRsp) { + buf = taosDecodeFixedI64(buf, &pRsp->reqOffset); + buf = taosDecodeFixedI64(buf, &pRsp->rspOffset); + buf = taosDecodeFixedI16(buf, &pRsp->resMsgType); + buf = taosDecodeFixedI32(buf, &pRsp->metaRspLen); + buf = taosDecodeBinary(buf, &pRsp->metaRsp, pRsp->metaRspLen); + return (void*)buf; +} + typedef struct { SMqRspHead head; int64_t reqOffset; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index eeac619105..bb5e903d1e 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -131,6 +131,7 @@ enum { TD_DEF_MSG_TYPE(TDMT_MND_DROP_INDEX, "drop-index", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_GET_INDEX, "get-index", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_GET_TABLE_INDEX, "get-table-index", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_MND_TABLE_CFG, "table-cfg", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_CREATE_TOPIC, "create-topic", SMCreateTopicReq, SMCreateTopicRsp) TD_DEF_MSG_TYPE(TDMT_MND_ALTER_TOPIC, "alter-topic", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_MND_DROP_TOPIC, "drop-topic", NULL, NULL) @@ -171,6 +172,7 @@ enum { TD_DEF_MSG_TYPE(TDMT_VND_UPDATE_TAG_VAL, "update-tag-val", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TABLE_META, "vnode-table-meta", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_TABLES_META, "vnode-tables-meta", NULL, NULL) + TD_DEF_MSG_TYPE(TDMT_VND_TABLE_CFG, "vnode-table-cfg", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_CREATE_STB, "vnode-create-stb", SVCreateStbReq, NULL) TD_DEF_MSG_TYPE(TDMT_VND_ALTER_STB, "vnode-alter-stb", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_DROP_STB, "vnode-drop-stb", SVDropStbReq, NULL) @@ -187,7 +189,6 @@ enum { TD_DEF_MSG_TYPE(TDMT_VND_CONSUME, "vnode-consume", SMqPollReq, SMqDataBlkRsp) TD_DEF_MSG_TYPE(TDMT_VND_STREAM_TRIGGER, "vnode-stream-trigger", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_STREAM_DISPATCH_WRITE, "vnode-stream-task-dispatch-write", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_VND_STREAM_TASK_DROP, "vnode-stream-task-drop", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_CREATE_SMA, "vnode-create-sma", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_CANCEL_SMA, "vnode-cancel-sma", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_VND_DROP_SMA, "vnode-drop-sma", NULL, NULL) @@ -204,6 +205,7 @@ enum { //shared by snode and vnode TD_NEW_MSG_SEG(TDMT_STREAM_MSG) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_DEPLOY, "stream-task-deploy", SStreamTaskDeployReq, SStreamTaskDeployRsp) + TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_DROP, "stream-task-drop", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_RUN, "stream-task-run", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_DISPATCH, "stream-task-dispatch", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_RECOVER, "stream-task-recover", NULL, NULL) diff --git a/include/common/tname.h b/include/common/tname.h index 28f97d1028..c691c2f7b2 100644 --- a/include/common/tname.h +++ b/include/common/tname.h @@ -63,6 +63,8 @@ int32_t tNameSetAcctId(SName* dst, int32_t acctId); bool tNameDBNameEqual(SName* left, SName* right); +bool tNameTbNameEqual(SName* left, SName* right); + typedef struct { // input SArray* tags; // element is SSmlKv diff --git a/include/dnode/mnode/mnode.h b/include/dnode/mnode/mnode.h index f1cfa58f62..2509c10601 100644 --- a/include/dnode/mnode/mnode.h +++ b/include/dnode/mnode/mnode.h @@ -95,8 +95,8 @@ int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad); */ int32_t mndProcessRpcMsg(SRpcMsg *pMsg); int32_t mndProcessSyncMsg(SRpcMsg *pMsg); -int32_t mndPreProcessMsg(SRpcMsg *pMsg); -void mndAbortPreprocessMsg(SRpcMsg *pMsg); +int32_t mndPreProcessQueryMsg(SRpcMsg *pMsg); +void mndPostProcessQueryMsg(SRpcMsg *pMsg); /** * @brief Generate machine code diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h index a7ac767883..20f4765190 100644 --- a/include/libs/catalog/catalog.h +++ b/include/libs/catalog/catalog.h @@ -68,7 +68,9 @@ typedef struct SCatalogReq { SArray* pIndex; // element is index name SArray* pUser; // element is SUserAuthInfo SArray* pTableIndex; // element is SNAME + SArray* pTableCfg; // element is SNAME bool qNodeRequired; // valid qnode + bool dNodeRequired; // valid dnode bool forceUpdate; } SCatalogReq; @@ -88,6 +90,8 @@ typedef struct SMetaData { SArray* pIndex; // pRes = SIndexInfo* SArray* pUser; // pRes = bool* SArray* pQnodeList; // pRes = SArray* + SArray* pTableCfg; // pRes = STableCfg* + SArray* pDnodeList; // pRes = SArray* } SMetaData; typedef struct SCatalogCfg { @@ -268,6 +272,8 @@ int32_t catalogAsyncGetAllMeta(SCatalog* pCtg, SRequestConnInfo* pConn, uint64_t int32_t catalogGetQnodeList(SCatalog* pCatalog, SRequestConnInfo* pConn, SArray* pQnodeList); +int32_t catalogGetDnodeList(SCatalog* pCatalog, SRequestConnInfo* pConn, SArray** pDnodeList); + int32_t catalogGetExpiredSTables(SCatalog* pCatalog, SSTableVersion **stables, uint32_t *num); int32_t catalogGetExpiredDBs(SCatalog* pCatalog, SDbVgVersion** dbs, uint32_t* num); @@ -280,6 +286,8 @@ int32_t catalogGetIndexMeta(SCatalog* pCtg, SRequestConnInfo* pConn, const char* int32_t catalogGetTableIndex(SCatalog* pCtg, SRequestConnInfo* pConn, const SName* pTableName, SArray** pRes); +int32_t catalogRefreshGetTableCfg(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableCfg** pCfg); + int32_t catalogUpdateTableIndex(SCatalog* pCtg, STableIndexRsp *pRsp); int32_t catalogGetUdfInfo(SCatalog* pCtg, SRequestConnInfo* pConn, const char* funcName, SFuncInfo* pInfo); diff --git a/include/libs/function/function.h b/include/libs/function/function.h index c5842559f8..a569c8de54 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -67,7 +67,7 @@ typedef struct SResultRowEntryInfo { bool initialized:1; // output buffer has been initialized bool complete:1; // query has completed uint8_t isNullRes:6; // the result is null - uint8_t numOfRes; // num of output result in current buffer + uint16_t numOfRes; // num of output result in current buffer } SResultRowEntryInfo; // determine the real data need to calculated the result diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index cbaff29cb2..1f314d19e7 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -190,6 +190,7 @@ bool fmIsForbidWindowFunc(int32_t funcId); bool fmIsForbidGroupByFunc(int32_t funcId); bool fmIsIntervalInterpoFunc(int32_t funcId); bool fmIsInterpFunc(int32_t funcId); +bool fmIsLastRowFunc(int32_t funcId); int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc); diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index 13a8dbd7e3..10c3f313a2 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -28,6 +28,15 @@ extern "C" { #define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define SHOW_CREATE_DB_RESULT_COLS 2 +#define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE) +#define SHOW_CREATE_DB_RESULT_FIELD2_LEN (TSDB_MAX_BINARY_LEN + VARSTR_HEADER_SIZE) + +#define SHOW_CREATE_TB_RESULT_COLS 2 +#define SHOW_CREATE_TB_RESULT_FIELD1_LEN (TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE) +#define SHOW_CREATE_TB_RESULT_FIELD2_LEN (TSDB_MAX_BINARY_LEN + VARSTR_HEADER_SIZE) + + #define PRIVILEGE_TYPE_MASK(n) (1 << n) #define PRIVILEGE_TYPE_ALL PRIVILEGE_TYPE_MASK(0) @@ -119,14 +128,14 @@ typedef struct SCreateTableStmt { } SCreateTableStmt; typedef struct SCreateSubTableClause { - ENodeType type; - char dbName[TSDB_DB_NAME_LEN]; - char tableName[TSDB_TABLE_NAME_LEN]; - char useDbName[TSDB_DB_NAME_LEN]; - char useTableName[TSDB_TABLE_NAME_LEN]; - bool ignoreExists; - SNodeList* pSpecificTags; - SNodeList* pValsOfTags; + ENodeType type; + char dbName[TSDB_DB_NAME_LEN]; + char tableName[TSDB_TABLE_NAME_LEN]; + char useDbName[TSDB_DB_NAME_LEN]; + char useTableName[TSDB_TABLE_NAME_LEN]; + bool ignoreExists; + SNodeList* pSpecificTags; + SNodeList* pValsOfTags; STableOptions* pOptions; } SCreateSubTableClause; @@ -221,7 +230,7 @@ typedef struct SShowCreateTableStmt { ENodeType type; char dbName[TSDB_DB_NAME_LEN]; char tableName[TSDB_TABLE_NAME_LEN]; - STableMeta* pMeta; + void* pCfg; // STableCfg } SShowCreateTableStmt; typedef struct SShowTableDistributedStmt { @@ -230,6 +239,11 @@ typedef struct SShowTableDistributedStmt { char tableName[TSDB_TABLE_NAME_LEN]; } SShowTableDistributedStmt; +typedef struct SShowDnodeVariablesStmt { + ENodeType type; + SNode* pDnodeId; +} SShowDnodeVariablesStmt; + typedef enum EIndexType { INDEX_TYPE_SMA = 1, INDEX_TYPE_FULLTEXT } EIndexType; typedef struct SIndexOptions { diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 975321cd5b..26a100bb1b 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -59,10 +59,10 @@ extern "C" { for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \ (NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext) -#define DESTORY_LIST(list) \ - do { \ - nodesDestroyList((list)); \ - (list) = NULL; \ +#define NODES_DESTORY_LIST(list) \ + do { \ + nodesDestroyList((list)); \ + (list) = NULL; \ } while (0) #define NODES_CLEAR_LIST(list) \ @@ -180,7 +180,9 @@ typedef enum ENodeType { QUERY_NODE_SHOW_VNODES_STMT, QUERY_NODE_SHOW_APPS_STMT, QUERY_NODE_SHOW_SCORES_STMT, - QUERY_NODE_SHOW_VARIABLE_STMT, + QUERY_NODE_SHOW_VARIABLES_STMT, + QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT, + QUERY_NODE_SHOW_DNODE_VARIABLES_STMT, QUERY_NODE_SHOW_CREATE_DATABASE_STMT, QUERY_NODE_SHOW_CREATE_TABLE_STMT, QUERY_NODE_SHOW_CREATE_STABLE_STMT, @@ -217,6 +219,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN, QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN, QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN, + QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN, QUERY_NODE_PHYSICAL_PLAN_PROJECT, QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN, QUERY_NODE_PHYSICAL_PLAN_HASH_AGG, @@ -225,6 +228,7 @@ typedef enum ENodeType { QUERY_NODE_PHYSICAL_PLAN_SORT, QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL, + QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index b07e8f39d5..cb09bf6a5f 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -40,7 +40,8 @@ typedef enum EScanType { SCAN_TYPE_SYSTEM_TABLE, SCAN_TYPE_STREAM, SCAN_TYPE_TABLE_MERGE, - SCAN_TYPE_BLOCK_INFO + SCAN_TYPE_BLOCK_INFO, + SCAN_TYPE_LAST_ROW } EScanType; typedef struct SScanLogicNode { @@ -260,6 +261,7 @@ typedef struct SScanPhysiNode { typedef SScanPhysiNode STagScanPhysiNode; typedef SScanPhysiNode SBlockDistScanPhysiNode; +typedef SScanPhysiNode SLastRowScanPhysiNode; typedef struct SSystemTableScanPhysiNode { SScanPhysiNode scan; @@ -375,7 +377,8 @@ typedef struct SIntervalPhysiNode { int8_t slidingUnit; } SIntervalPhysiNode; -typedef SIntervalPhysiNode SMergeIntervalPhysiNode; +typedef SIntervalPhysiNode SMergeIntervalPhysiNode; +typedef SIntervalPhysiNode SMergeAlignedIntervalPhysiNode; typedef SIntervalPhysiNode SStreamIntervalPhysiNode; typedef SIntervalPhysiNode SStreamFinalIntervalPhysiNode; typedef SIntervalPhysiNode SStreamSemiIntervalPhysiNode; diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 73e487f073..78013e5457 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -52,7 +52,7 @@ typedef struct SExprNode { SArray* pAssociation; } SExprNode; -typedef enum EColumnType { COLUMN_TYPE_COLUMN = 1, COLUMN_TYPE_TAG } EColumnType; +typedef enum EColumnType { COLUMN_TYPE_COLUMN = 1, COLUMN_TYPE_TAG, COLUMN_TYPE_TBNAME } EColumnType; typedef struct SColumnNode { SExprNode node; // QUERY_NODE_COLUMN @@ -258,6 +258,7 @@ typedef struct SSelectStmt { bool hasUniqueFunc; bool hasTailFunc; bool hasInterpFunc; + bool hasLastRowFunc; } SSelectStmt; typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType; diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index d562d07d77..26f2758033 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -207,6 +207,10 @@ char* jobTaskStatusStr(int32_t status); SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* name); void destroyQueryExecRes(SQueryExecRes* pRes); +int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len); +char* parseTagDatatoJson(void* p); +int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst); +int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst); extern int32_t (*queryBuildMsg[TDMT_MAX])(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallocFp)(int32_t)); extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t msgSize); diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 937ac2b408..ee599e8498 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -30,9 +30,14 @@ extern "C" { typedef struct SStreamTask SStreamTask; enum { - TASK_STATUS__IDLE = 1, - TASK_STATUS__EXECUTING, - TASK_STATUS__CLOSING, + TASK_STATUS__NORMAL = 0, + TASK_STATUS__DROPPING, +}; + +enum { + TASK_EXEC_STATUS__IDLE = 1, + TASK_EXEC_STATUS__EXECUTING, + TASK_EXEC_STATUS__CLOSING, }; enum { @@ -50,16 +55,12 @@ enum { TASK_OUTPUT_STATUS__BLOCKED, }; -enum { - STREAM_CREATED_BY__USER = 1, - STREAM_CREATED_BY__SMA, -}; - enum { STREAM_INPUT__DATA_SUBMIT = 1, STREAM_INPUT__DATA_BLOCK, STREAM_INPUT__TRIGGER, STREAM_INPUT__CHECKPOINT, + STREAM_INPUT__DROP, }; typedef struct { @@ -237,7 +238,9 @@ struct SStreamTask { int64_t streamId; int32_t taskId; int8_t inputType; - int8_t status; + int8_t taskStatus; + + int8_t execStatus; int8_t execType; int8_t sinkType; diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index e963f25616..2cb0c65d35 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -162,7 +162,7 @@ typedef struct SSyncLogStore { SyncIndex (*syncLogEndIndex)(struct SSyncLogStore* pLogStore); bool (*syncLogIsEmpty)(struct SSyncLogStore* pLogStore); int32_t (*syncLogEntryCount)(struct SSyncLogStore* pLogStore); - bool (*syncLogInRange)(struct SSyncLogStore* pLogStore, SyncIndex index); + // bool (*syncLogInRange)(struct SSyncLogStore* pLogStore, SyncIndex index); SyncIndex (*syncLogWriteIndex)(struct SSyncLogStore* pLogStore); SyncIndex (*syncLogLastIndex)(struct SSyncLogStore* pLogStore); diff --git a/include/os/osTime.h b/include/os/osTime.h index 949c15ed0d..965ec61671 100644 --- a/include/os/osTime.h +++ b/include/os/osTime.h @@ -38,7 +38,7 @@ extern "C" { #define MILLISECOND_PER_SECOND (1000i64) #else -#define MILLISECOND_PER_SECOND ((int64_t)1000L) +#define MILLISECOND_PER_SECOND ((int64_t)1000LL) #endif #define MILLISECOND_PER_MINUTE (MILLISECOND_PER_SECOND * 60) @@ -46,9 +46,9 @@ extern "C" { #define MILLISECOND_PER_DAY (MILLISECOND_PER_HOUR * 24) #define MILLISECOND_PER_WEEK (MILLISECOND_PER_DAY * 7) -#define NANOSECOND_PER_USEC (1000L) -#define NANOSECOND_PER_MSEC (1000000L) -#define NANOSECOND_PER_SEC (1000000000L) +#define NANOSECOND_PER_USEC (1000LL) +#define NANOSECOND_PER_MSEC (1000000LL) +#define NANOSECOND_PER_SEC (1000000000LL) #define NANOSECOND_PER_MINUTE (NANOSECOND_PER_SEC * 60) #define NANOSECOND_PER_HOUR (NANOSECOND_PER_MINUTE * 60) #define NANOSECOND_PER_DAY (NANOSECOND_PER_HOUR * 24) @@ -65,21 +65,21 @@ int32_t taosGetTimestampSec(); static FORCE_INLINE int64_t taosGetTimestampMs() { struct timeval systemTime; taosGetTimeOfDay(&systemTime); - return (int64_t)systemTime.tv_sec * 1000L + (int64_t)systemTime.tv_usec / 1000; + return (int64_t)systemTime.tv_sec * 1000LL + (int64_t)systemTime.tv_usec / 1000; } //@return timestamp in microsecond static FORCE_INLINE int64_t taosGetTimestampUs() { struct timeval systemTime; taosGetTimeOfDay(&systemTime); - return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec; + return (int64_t)systemTime.tv_sec * 1000000LL + (int64_t)systemTime.tv_usec; } //@return timestamp in nanosecond static FORCE_INLINE int64_t taosGetTimestampNs() { struct timespec systemTime = {0}; taosClockGetTime(CLOCK_REALTIME, &systemTime); - return (int64_t)systemTime.tv_sec * 1000000000L + (int64_t)systemTime.tv_nsec; + return (int64_t)systemTime.tv_sec * 1000000000LL + (int64_t)systemTime.tv_nsec; } char * taosStrpTime(const char *buf, const char *fmt, struct tm *tm); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index f4d8c2a663..eb68f52a40 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -129,6 +129,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_STMT_CLAUSE_ERROR TAOS_DEF_ERROR_CODE(0, 0X0227) #define TSDB_CODE_TSC_QUERY_KILLED TAOS_DEF_ERROR_CODE(0, 0X0228) #define TSDB_CODE_TSC_NO_EXEC_NODE TAOS_DEF_ERROR_CODE(0, 0X0229) +#define TSDB_CODE_TSC_NOT_STABLE_ERROR TAOS_DEF_ERROR_CODE(0, 0X022a) // mnode-common #define TSDB_CODE_MND_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0300) @@ -419,6 +420,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_SYN_NEW_CONFIG_ERROR TAOS_DEF_ERROR_CODE(0, 0x090F) #define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910) #define TSDB_CODE_SYN_PROPOSE_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0911) +#define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912) #define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF) // tq diff --git a/include/util/tdef.h b/include/util/tdef.h index c5a8b95a08..5304dba741 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -49,12 +49,12 @@ extern const int32_t TYPE_BYTES[16]; #define TSDB_DATA_BOOL_NULL 0x02 #define TSDB_DATA_TINYINT_NULL 0x80 #define TSDB_DATA_SMALLINT_NULL 0x8000 -#define TSDB_DATA_INT_NULL 0x80000000L -#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L +#define TSDB_DATA_INT_NULL 0x80000000LL +#define TSDB_DATA_BIGINT_NULL 0x8000000000000000LL #define TSDB_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL #define TSDB_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN -#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN +#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000LL // an NAN #define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF #define TSDB_DATA_BINARY_NULL 0xFF @@ -108,8 +108,8 @@ extern const int32_t TYPE_BYTES[16]; #define TSDB_INS_USER_STABLES_DBNAME_COLID 2 #define TSDB_TICK_PER_SECOND(precision) \ - ((int64_t)((precision) == TSDB_TIME_PRECISION_MILLI ? 1e3L \ - : ((precision) == TSDB_TIME_PRECISION_MICRO ? 1e6L : 1e9L))) + ((int64_t)((precision) == TSDB_TIME_PRECISION_MILLI ? 1000LL \ + : ((precision) == TSDB_TIME_PRECISION_MICRO ? 1000000LL : 1000000000LL))) #define T_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) #define T_APPEND_MEMBER(dst, ptr, type, member) \ diff --git a/include/util/tpagedbuf.h b/include/util/tpagedbuf.h index af82e29ec5..ef266068cb 100644 --- a/include/util/tpagedbuf.h +++ b/include/util/tpagedbuf.h @@ -28,7 +28,7 @@ typedef struct SArray* SIDList; typedef struct SPageInfo SPageInfo; typedef struct SDiskbasedBuf SDiskbasedBuf; -#define DEFAULT_INTERN_BUF_PAGE_SIZE (1024L) // in bytes +#define DEFAULT_INTERN_BUF_PAGE_SIZE (1024LL) // in bytes typedef struct SFilePage { int32_t num; diff --git a/include/util/types.h b/include/util/types.h index d48995418e..ded9dc37d7 100644 --- a/include/util/types.h +++ b/include/util/types.h @@ -32,7 +32,7 @@ extern "C" { #define GET_UINT64_VAL(x) (*(uint64_t *)(x)) static FORCE_INLINE float taos_align_get_float(const char *pBuf) { -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL static_assert(sizeof(float) == sizeof(uint32_t), "sizeof(float) must equal to sizeof(uint32_t)"); #else assert(sizeof(float) == sizeof(uint32_t)); @@ -43,7 +43,7 @@ static FORCE_INLINE float taos_align_get_float(const char *pBuf) { } static FORCE_INLINE double taos_align_get_double(const char *pBuf) { -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) must equal to sizeof(uint64_t)"); #else assert(sizeof(double) == sizeof(uint64_t)); diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index f07705ff44..d730cc0d8a 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -196,7 +196,6 @@ function install_bin() { ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}rm -f ${bin_link_dir}/tarbitrator || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : ${csudo}rm -f ${bin_link_dir}/TDinsight.sh || : ${csudo}cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo}chmod 0555 ${install_main_dir}/bin/* @@ -211,7 +210,6 @@ function install_bin() { [ -x ${install_main_dir}/bin/TDinsight.sh ] && ${csudo}ln -s ${install_main_dir}/bin/TDinsight.sh ${bin_link_dir}/TDinsight.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : [ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - [ -x ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_${serverName}_and_${adapterName}.sh ${bin_link_dir}/run_${serverName}_and_${adapterName}.sh || : [ -x ${install_main_dir}/bin/tarbitrator ] && ${csudo}ln -s ${install_main_dir}/bin/tarbitrator ${bin_link_dir}/tarbitrator || : if [ "$verMode" == "cluster" ]; then diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh index 31cb5e87b9..6726b3fe2d 100755 --- a/packaging/tools/make_install.sh +++ b/packaging/tools/make_install.sh @@ -176,7 +176,6 @@ function install_bin() { if [ "$osType" != "Darwin" ]; then ${csudo}rm -f ${bin_link_dir}/perfMonitor || : ${csudo}rm -f ${bin_link_dir}/set_core || : - ${csudo}rm -f ${bin_link_dir}/run_taosd_and_taosadapter.sh || : ${csudo}rm -f ${bin_link_dir}/${uninstallScript} || : ${csudo}cp -r ${binary_dir}/build/bin/${clientName} ${install_main_dir}/bin || : @@ -191,7 +190,6 @@ function install_bin() { ${csudo}cp -r ${script_dir}/taosd-dump-cfg.gdb ${install_main_dir}/bin || : ${csudo}cp -r ${script_dir}/remove.sh ${install_main_dir}/bin || : ${csudo}cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin || : - ${csudo}cp -r ${script_dir}/run_taosd_and_taosadapter.sh ${install_main_dir}/bin || : ${csudo}cp -r ${script_dir}/startPre.sh ${install_main_dir}/bin || : ${csudo}chmod 0555 ${install_main_dir}/bin/* @@ -204,7 +202,6 @@ function install_bin() { [ -x ${install_main_dir}/bin/taosdemo ] && ${csudo}ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || : [ -x ${install_main_dir}/bin/perfMonitor ] && ${csudo}ln -s ${install_main_dir}/bin/perfMonitor ${bin_link_dir}/perfMonitor || : [ -x ${install_main_dir}/set_core.sh ] && ${csudo}ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || : - [ -x ${install_main_dir}/run_taosd_and_taosadapter.sh ] && ${csudo}ln -s ${install_main_dir}/bin/run_taosd_and_taosadapter.sh ${bin_link_dir}/run_taosd_and_taosadapter.sh || : [ -x ${install_main_dir}/bin/remove.sh ] && ${csudo}ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/${uninstallScript} || : else diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh index ea8ebba450..d0fbf0c4d7 100755 --- a/packaging/tools/makepkg.sh +++ b/packaging/tools/makepkg.sh @@ -88,7 +88,6 @@ else ${build_dir}/bin/tarbitrator\ ${script_dir}/remove.sh \ ${script_dir}/set_core.sh \ - ${script_dir}/run_taosd_and_taosadapter.sh \ ${script_dir}/startPre.sh \ ${script_dir}/taosd-dump-cfg.gdb" fi @@ -152,7 +151,6 @@ if [ $adapterName != "taosadapter" ]; then sed -i "s/taosadapter/${adapterName}/g" ${install_dir}/cfg/$adapterName.service mv ${install_dir}/bin/taosadapter ${install_dir}/bin/${adapterName} - mv ${install_dir}/bin/run_taosd_and_taosadapter.sh ${install_dir}/bin/run_${serverName}_and_${adapterName}.sh mv ${install_dir}/bin/taosd-dump-cfg.gdb ${install_dir}/bin/${serverName}-dump-cfg.gdb fi diff --git a/packaging/tools/run_taosd_and_taosadapter.sh b/packaging/tools/run_taosd_and_taosadapter.sh deleted file mode 100755 index 9ab9eb484a..0000000000 --- a/packaging/tools/run_taosd_and_taosadapter.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -[[ -x /usr/bin/taosadapter ]] && /usr/bin/taosadapter & -taosd diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index c39b492620..cfe507e505 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -20,9 +20,9 @@ extern "C" { #endif +#include "catalog.h" #include "parser.h" #include "planner.h" -#include "catalog.h" #include "query.h" #include "taos.h" #include "tcommon.h" @@ -51,10 +51,12 @@ extern "C" { enum { RES_TYPE__QUERY = 1, RES_TYPE__TMQ, + RES_TYPE__TMQ_META, }; -#define TD_RES_QUERY(res) (*(int8_t*)res == RES_TYPE__QUERY) -#define TD_RES_TMQ(res) (*(int8_t*)res == RES_TYPE__TMQ) +#define TD_RES_QUERY(res) (*(int8_t*)res == RES_TYPE__QUERY) +#define TD_RES_TMQ(res) (*(int8_t*)res == RES_TYPE__TMQ) +#define TD_RES_TMQ_META(res) (*(int8_t*)res == RES_TYPE__TMQ_META) typedef struct SAppInstInfo SAppInstInfo; @@ -66,9 +68,9 @@ typedef struct { int64_t reportBytes; // not implemented int64_t startTime; // ctl - SRWLatch lock; // lock is used in serialization + SRWLatch lock; // lock is used in serialization SAppInstInfo* pAppInstInfo; - SHashObj* activeInfo; // hash + SHashObj* activeInfo; // hash } SAppHbMgr; typedef int32_t (*FHbRspHandle)(SAppHbMgr* pAppHbMgr, SClientHbRsp* pRsp); @@ -76,13 +78,13 @@ typedef int32_t (*FHbRspHandle)(SAppHbMgr* pAppHbMgr, SClientHbRsp* pRsp); typedef int32_t (*FHbReqHandle)(SClientHbKey* connKey, void* param, SClientHbReq* req); typedef struct { - int8_t inited; - int64_t appId; + int8_t inited; + int64_t appId; // ctl int8_t threadStop; TdThread thread; - TdThreadMutex lock; // used when app init and cleanup - SHashObj *appSummary; + TdThreadMutex lock; // used when app init and cleanup + SHashObj* appSummary; SArray* appHbMgrs; // SArray one for each cluster FHbReqHandle reqHandle[CONN_TYPE__MAX]; FHbRspHandle rspHandle[CONN_TYPE__MAX]; @@ -129,7 +131,7 @@ typedef struct STscObj { int8_t connType; int32_t acctId; uint32_t connId; - TAOS *id; // ref ID returned by taosAddRef + TAOS* id; // ref ID returned by taosAddRef TdThreadMutex mutex; // used to protect the operation on db int32_t numOfReqs; // number of sqlObj bound to this connection SAppInstInfo* pAppInfo; @@ -188,6 +190,14 @@ typedef struct { SReqResultInfo resInfo; } SMqRspObj; +typedef struct { + int8_t resType; + char topic[TSDB_TOPIC_FNAME_LEN]; + char db[TSDB_DB_FNAME_LEN]; + int32_t vgId; + SMqMetaRsp metaRsp; +} SMqMetaRspObj; + typedef struct SRequestObj { int8_t resType; // query or tmq uint64_t requestId; @@ -206,9 +216,9 @@ typedef struct SRequestObj { SRequestSendRecvBody body; bool stableQuery; - bool killed; - uint32_t prevCode; //previous error code: todo refactor, add update flag for catalog - uint32_t retry; + bool killed; + uint32_t prevCode; // previous error code: todo refactor, add update flag for catalog + uint32_t retry; } SRequestObj; typedef struct SSyncQueryParam { @@ -216,15 +226,15 @@ typedef struct SSyncQueryParam { SRequestObj* pRequest; } SSyncQueryParam; -void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4); -void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4); +void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4); +void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4); -void doSetOneRowPtr(SReqResultInfo* pResultInfo); -void setResPrecision(SReqResultInfo* pResInfo, int32_t precision); -int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4, - bool freeAfterUse); -void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols); -void doFreeReqResultInfo(SReqResultInfo* pResInfo); +void doSetOneRowPtr(SReqResultInfo* pResultInfo); +void setResPrecision(SReqResultInfo* pResInfo, int32_t precision); +int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4, + bool freeAfterUse); +void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols); +void doFreeReqResultInfo(SReqResultInfo* pResInfo); SRequestObj* execQuery(STscObj* pTscObj, const char* sql, int sqlLen); static FORCE_INLINE SReqResultInfo* tmqGetCurResInfo(TAOS_RES* res) { @@ -289,7 +299,7 @@ bool persistConnForSpecificMsg(void* parenct, tmsg_t msgType); void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet); STscObj* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db, - uint16_t port, int connType); + uint16_t port, int connType); SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen); @@ -299,7 +309,7 @@ int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArra int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest); -void taos_close_internal(void *taos); +void taos_close_internal(void* taos); // --- heartbeat // global, called by mgmt @@ -320,12 +330,12 @@ void hbMgrInitMqHbRspHandle(); SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res); int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList); -void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData *pResultMeta); +void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultMeta); int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest); int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList); void doAsyncQuery(SRequestObj* pRequest, bool forceUpdateMeta); -int32_t removeMeta(STscObj* pTscObj, SArray* tbList);// todo move to clientImpl.c and become a static function -int32_t handleAlterTbExecRes(void* res, struct SCatalog* pCatalog);// todo move to xxx +int32_t removeMeta(STscObj* pTscObj, SArray* tbList); // todo move to clientImpl.c and become a static function +int32_t handleAlterTbExecRes(void* res, struct SCatalog* pCatalog); // todo move to xxx bool qnodeRequired(SRequestObj* pRequest); #ifdef __cplusplus diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 8920922006..37b8866e25 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -244,10 +244,10 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { } SReqResultInfo* pResultInfo = &pRequest->body.resInfo; + pRequest->code = code; if (pRequest->code != TSDB_CODE_SUCCESS) { pResultInfo->numOfRows = 0; - pRequest->code = code; tscError("0x%" PRIx64 " fetch results failed, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code), pRequest->requestId); } else { @@ -256,7 +256,7 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) { pRequest->requestId); } - pRequest->body.queryFp(pRequest->body.param, pRequest, 0); + pRequest->body.queryFp(pRequest->body.param, pRequest, code); // pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows); } @@ -1444,80 +1444,6 @@ static int32_t doPrepareResPtr(SReqResultInfo* pResInfo) { return TSDB_CODE_SUCCESS; } -static char* parseTagDatatoJson(void* p) { - char* string = NULL; - cJSON* json = cJSON_CreateObject(); - if (json == NULL) { - goto end; - } - - SArray* pTagVals = NULL; - if (tTagToValArray((const STag*)p, &pTagVals) != 0) { - goto end; - } - - int16_t nCols = taosArrayGetSize(pTagVals); - char tagJsonKey[256] = {0}; - for (int j = 0; j < nCols; ++j) { - STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j); - // json key encode by binary - memset(tagJsonKey, 0, sizeof(tagJsonKey)); - memcpy(tagJsonKey, pTagVal->pKey, strlen(pTagVal->pKey)); - // json value - char type = pTagVal->type; - if (type == TSDB_DATA_TYPE_NULL) { - cJSON* value = cJSON_CreateNull(); - if (value == NULL) { - goto end; - } - cJSON_AddItemToObject(json, tagJsonKey, value); - } else if (type == TSDB_DATA_TYPE_NCHAR) { - cJSON* value = NULL; - if (pTagVal->nData > 0) { - char* tagJsonValue = taosMemoryCalloc(pTagVal->nData, 1); - int32_t length = taosUcs4ToMbs((TdUcs4*)pTagVal->pData, pTagVal->nData, tagJsonValue); - if (length < 0) { - tscError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, - pTagVal->pData); - taosMemoryFree(tagJsonValue); - goto end; - } - value = cJSON_CreateString(tagJsonValue); - taosMemoryFree(tagJsonValue); - if (value == NULL) { - goto end; - } - } else if (pTagVal->nData == 0) { - value = cJSON_CreateString(""); - } else { - ASSERT(0); - } - - cJSON_AddItemToObject(json, tagJsonKey, value); - } else if (type == TSDB_DATA_TYPE_DOUBLE) { - double jsonVd = *(double*)(&pTagVal->i64); - cJSON* value = cJSON_CreateNumber(jsonVd); - if (value == NULL) { - goto end; - } - cJSON_AddItemToObject(json, tagJsonKey, value); - } else if (type == TSDB_DATA_TYPE_BOOL) { - char jsonVd = *(char*)(&pTagVal->i64); - cJSON* value = cJSON_CreateBool(jsonVd); - if (value == NULL) { - goto end; - } - cJSON_AddItemToObject(json, tagJsonKey, value); - } else { - ASSERT(0); - } - } - string = cJSON_PrintUnformatted(json); -end: - cJSON_Delete(json); - return string; -} - static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int32_t numOfCols, int32_t* colLength) { for (int32_t i = 0; i < numOfCols; ++i) { int32_t type = pResultInfo->fields[i].type; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index ba7de65931..ab4d14b1cc 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -17,6 +17,7 @@ #include "clientInt.h" #include "clientLog.h" #include "clientStmt.h" +#include "functionMgt.h" #include "os.h" #include "query.h" #include "scheduler.h" @@ -25,7 +26,6 @@ #include "tref.h" #include "trpc.h" #include "version.h" -#include "functionMgt.h" #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 @@ -97,11 +97,11 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha pass = TSDB_DEFAULT_PASS; } - STscObj* pObj = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY); + STscObj *pObj = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY); if (pObj) { return pObj->id; } - + return NULL; } @@ -111,41 +111,40 @@ void taos_close_internal(void *taos) { } STscObj *pTscObj = (STscObj *)taos; - tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", *(int64_t*)pTscObj->id, pTscObj->numOfReqs); + tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", *(int64_t *)pTscObj->id, pTscObj->numOfReqs); - taosRemoveRef(clientConnRefPool, *(int64_t*)pTscObj->id); + taosRemoveRef(clientConnRefPool, *(int64_t *)pTscObj->id); } void taos_close(TAOS *taos) { if (taos == NULL) { return; } - - STscObj* pObj = acquireTscObj(*(int64_t*)taos); + + STscObj *pObj = acquireTscObj(*(int64_t *)taos); if (NULL == pObj) { return; } - + taos_close_internal(pObj); - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); taosMemoryFree(taos); } - -int taos_errno(TAOS_RES *tres) { - if (tres == NULL) { +int taos_errno(TAOS_RES *res) { + if (res == NULL || TD_RES_TMQ_META(res)) { return terrno; } - if (TD_RES_TMQ(tres)) { + if (TD_RES_TMQ(res)) { return 0; } - return ((SRequestObj *)tres)->code; + return ((SRequestObj *)res)->code; } const char *taos_errstr(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return (const char *)tstrerror(terrno); } @@ -179,11 +178,15 @@ void taos_free_result(TAOS_RES *res) { if (pRsp->rsp.withSchema) taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper); pRsp->resInfo.pRspMsg = NULL; doFreeReqResultInfo(&pRsp->resInfo); + } else if (TD_RES_TMQ_META(res)) { + SMqMetaRspObj *pRspObj = (SMqMetaRspObj *)res; + taosMemoryFree(pRspObj->metaRsp.metaRsp); + taosMemoryFree(pRspObj); } } int taos_field_count(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return 0; } @@ -194,7 +197,7 @@ int taos_field_count(TAOS_RES *res) { int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); } TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { - if (taos_num_fields(res) == 0) { + if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res)) { return NULL; } @@ -215,8 +218,8 @@ TAOS_RES *taos_query(TAOS *taos, const char *sql) { terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; } - - STscObj* pTscObj = acquireTscObj(*(int64_t*)taos); + + STscObj *pTscObj = acquireTscObj(*(int64_t *)taos); if (pTscObj == NULL || sql == NULL) { terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; @@ -229,21 +232,21 @@ TAOS_RES *taos_query(TAOS *taos, const char *sql) { taos_query_a(taos, sql, syncQueryFn, param); tsem_wait(¶m->sem); - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); return param->pRequest; #else size_t sqlLen = strlen(sql); if (sqlLen > (size_t)TSDB_MAX_ALLOWED_SQL_LEN) { - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); tscError("sql string exceeds max length:%d", TSDB_MAX_ALLOWED_SQL_LEN); terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT; return NULL; } - TAOS_RES* pRes = execQuery(pTscObj, sql, sqlLen); + TAOS_RES *pRes = execQuery(pTscObj, sql, sqlLen); - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); return pRes; #endif @@ -380,7 +383,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) } int *taos_fetch_lengths(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return NULL; } @@ -389,7 +392,7 @@ int *taos_fetch_lengths(TAOS_RES *res) { } TAOS_ROW *taos_result_block(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { terrno = TSDB_CODE_INVALID_PARA; return NULL; } @@ -438,7 +441,7 @@ const char *taos_data_type(int type) { const char *taos_get_client_info() { return version; } int taos_affected_rows(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ(res)) { + if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res)) { return 0; } @@ -448,7 +451,7 @@ int taos_affected_rows(TAOS_RES *res) { } int taos_result_precision(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return TSDB_TIME_PRECISION_MILLI; } @@ -463,15 +466,15 @@ int taos_result_precision(TAOS_RES *res) { } int taos_select_db(TAOS *taos, const char *db) { - STscObj* pObj = acquireTscObj(*(int64_t*)taos); + STscObj *pObj = acquireTscObj(*(int64_t *)taos); if (pObj == NULL) { - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); terrno = TSDB_CODE_TSC_DISCONNECTED; return TSDB_CODE_TSC_DISCONNECTED; } if (db == NULL || strlen(db) == 0) { - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); terrno = TSDB_CODE_TSC_INVALID_INPUT; return terrno; } @@ -483,19 +486,19 @@ int taos_select_db(TAOS *taos, const char *db) { int32_t code = taos_errno(pRequest); taos_free_result(pRequest); - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); return code; } void taos_stop_query(TAOS_RES *res) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res)) { return; } SRequestObj *pRequest = (SRequestObj *)res; pRequest->killed = true; - - int32_t numOfFields = taos_num_fields(pRequest); + + int32_t numOfFields = taos_num_fields(pRequest); // It is not a query, no need to stop. if (numOfFields == 0) { tscDebug("request %" PRIx64 " no need to be killed since not query", pRequest->requestId); @@ -510,6 +513,9 @@ void taos_stop_query(TAOS_RES *res) { } bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { + if (res == NULL || TD_RES_TMQ_META(res)) { + return true; + } SReqResultInfo *pResultInfo = tscGetCurResInfo(res); if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) { return true; @@ -532,7 +538,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { } int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return 0; } @@ -575,7 +581,7 @@ int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) { } int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return 0; } @@ -615,7 +621,7 @@ int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) { } int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) { - if (res == NULL) { + if (res == NULL || TD_RES_TMQ_META(res)) { return 0; } @@ -636,7 +642,7 @@ int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) { int taos_validate_sql(TAOS *taos, const char *sql) { return true; } void taos_reset_current_db(TAOS *taos) { - STscObj* pTscObj = acquireTscObj(*(int64_t*)taos); + STscObj *pTscObj = acquireTscObj(*(int64_t *)taos); if (pTscObj == NULL) { terrno = TSDB_CODE_TSC_DISCONNECTED; return; @@ -644,17 +650,17 @@ void taos_reset_current_db(TAOS *taos) { resetConnectDB(pTscObj); - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); } const char *taos_get_server_info(TAOS *taos) { - STscObj* pTscObj = acquireTscObj(*(int64_t*)taos); + STscObj *pTscObj = acquireTscObj(*(int64_t *)taos); if (pTscObj == NULL) { terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; } - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); return pTscObj->ver; } @@ -682,7 +688,7 @@ static void destorySqlParseWrapper(SqlParseWrapper *pWrapper) { void retrieveMetaCallback(SMetaData *pResultMeta, void *param, int32_t code) { tscDebug("enter meta callback, code %s", tstrerror(code)); - + SqlParseWrapper *pWrapper = (SqlParseWrapper *)param; SQuery *pQuery = pWrapper->pQuery; SRequestObj *pRequest = pWrapper->pRequest; @@ -723,11 +729,11 @@ void retrieveMetaCallback(SMetaData *pResultMeta, void *param, int32_t code) { } void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) { - STscObj* pTscObj = acquireTscObj(*(int64_t*)taos); + STscObj *pTscObj = acquireTscObj(*(int64_t *)taos); if (pTscObj == NULL || sql == NULL || NULL == fp) { terrno = TSDB_CODE_INVALID_PARA; if (pTscObj) { - releaseTscObj(*(int64_t*)taos); + releaseTscObj(*(int64_t *)taos); } else { terrno = TSDB_CODE_TSC_DISCONNECTED; } @@ -745,7 +751,7 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param } SRequestObj *pRequest = NULL; - int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); + int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest); if (code != TSDB_CODE_SUCCESS) { terrno = code; fp(param, NULL, terrno); @@ -849,8 +855,8 @@ static void fetchCallback(void *pResult, void *param, int32_t code) { SReqResultInfo *pResultInfo = &pRequest->body.resInfo; - tscDebug("0x%" PRIx64 " enter scheduler fetch cb, code:%d - %s, reqId:0x%" PRIx64, - pRequest->self, code, tstrerror(code), pRequest->requestId); + tscDebug("0x%" PRIx64 " enter scheduler fetch cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, + tstrerror(code), pRequest->requestId); pResultInfo->pData = pResult; pResultInfo->numOfRows = 0; @@ -884,6 +890,7 @@ static void fetchCallback(void *pResult, void *param, int32_t code) { void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { ASSERT(res != NULL && fp != NULL); + ASSERT(TD_RES_QUERY(res)); SRequestObj *pRequest = res; pRequest->body.fetchFp = fp; @@ -910,6 +917,7 @@ void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { ASSERT(res != NULL && fp != NULL); + ASSERT(TD_RES_QUERY(res)); SRequestObj *pRequest = res; pRequest->body.resInfo.convertUcs4 = false; @@ -923,6 +931,7 @@ void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { const void *taos_get_raw_block(TAOS_RES *res) { ASSERT(res != NULL); + ASSERT(TD_RES_QUERY(res)); SRequestObj *pRequest = res; return pRequest->body.resInfo.pData; @@ -949,16 +958,16 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { } TAOS_STMT *taos_stmt_init(TAOS *taos) { - STscObj* pObj = acquireTscObj(*(int64_t*)taos); + STscObj *pObj = acquireTscObj(*(int64_t *)taos); if (NULL == pObj) { tscError("invalid parameter for %s", __FUNCTION__); terrno = TSDB_CODE_TSC_DISCONNECTED; return NULL; } - TAOS_STMT* pStmt = stmtInit(pObj); - - releaseTscObj(*(int64_t*)taos); + TAOS_STMT *pStmt = stmtInit(pObj); + + releaseTscObj(*(int64_t *)taos); return pStmt; } diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 6fa4e6bffb..7d2bf019d2 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -2389,17 +2389,19 @@ static int32_t isSchemalessDb(STscObj *taos, SRequestObj *request) { static void smlInsertCallback(void *param, void *res, int32_t code) { SRequestObj *pRequest = (SRequestObj *)res; SSmlHandle *info = (SSmlHandle *)param; + int32_t rows = taos_affected_rows(pRequest); uDebug("SML:0x%" PRIx64 " result. code:%d, msg:%s", info->id, pRequest->code, pRequest->msgBuf); // lock + taosThreadSpinLock(&info->params->lock); + info->params->request->body.resInfo.numOfRows += rows; if (code != TSDB_CODE_SUCCESS) { - taosThreadSpinLock(&info->params->lock); info->params->request->code = code; - taosThreadSpinUnlock(&info->params->lock); } + taosThreadSpinUnlock(&info->params->lock); // unlock - printf("SML:0x%" PRIx64 " insert finished, code: %d, total: %d\n", info->id, code, info->affectedRows); + uDebug("SML:0x%" PRIx64 " insert finished, code: %d, rows: %d, total: %d", info->id, code, rows, info->affectedRows); Params *pParam = info->params; bool isLast = info->isLast; info->cost.endTime = taosGetTimestampUs(); diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 638b4f1ea5..3c349f61a1 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -149,7 +149,10 @@ typedef struct { int32_t epoch; SMqClientVg* vgHandle; SMqClientTopic* topicHandle; - SMqDataBlkRsp msg; + union { + SMqDataBlkRsp dataRsp; + SMqMetaRsp metaRsp; + }; } SMqPollRspWrapper; typedef struct { @@ -401,8 +404,17 @@ int32_t tmqCommitInner2(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_ int32_t code = -1; if (msg != NULL) { - SMqRspObj* pRspObj = (SMqRspObj*)msg; - if (!TD_RES_TMQ(pRspObj)) { + char* topic; + int32_t vgId; + if (TD_RES_TMQ(msg)) { + SMqRspObj* pRspObj = (SMqRspObj*)msg; + topic = pRspObj->topic; + vgId = pRspObj->vgId; + } else if (TD_RES_TMQ_META(msg)) { + SMqMetaRspObj* pMetaRspObj = (SMqMetaRspObj*)msg; + topic = pMetaRspObj->topic; + vgId = pMetaRspObj->vgId; + } else { return TSDB_CODE_TMQ_INVALID_MSG; } @@ -421,10 +433,10 @@ int32_t tmqCommitInner2(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_ for (int32_t i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) { SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i); - if (strcmp(pTopic->topicName, pRspObj->topic) == 0) { + if (strcmp(pTopic->topicName, topic) == 0) { for (int32_t j = 0; j < taosArrayGetSize(pTopic->vgs); j++) { SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j); - if (pVg->vgId == pRspObj->vgId) { + if (pVg->vgId == vgId) { if (pVg->currentOffset < 0 || pVg->committedOffset == pVg->currentOffset) { tscDebug("consumer %ld skip commit for topic %s vg %d, current offset is %ld, committed offset is %ld", tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->currentOffset, pVg->committedOffset); @@ -1131,6 +1143,11 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) { tscWarn("mismatch rsp from vg %d, epoch %d, current epoch %d", vgId, msgEpoch, tmqEpoch); } + // handle meta rsp + int8_t rspType = ((SMqRspHead*)pMsg->pData)->mqMsgType; + if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) { + } + SMqPollRspWrapper* pRspWrapper = taosAllocateQitem(sizeof(SMqPollRspWrapper), DEF_QITEM); if (pRspWrapper == NULL) { taosMemoryFree(pMsg->pData); @@ -1138,17 +1155,23 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) { goto CREATE_MSG_FAIL; } - pRspWrapper->tmqRspType = TMQ_MSG_TYPE__POLL_RSP; + pRspWrapper->tmqRspType = rspType; pRspWrapper->vgHandle = pVg; pRspWrapper->topicHandle = pTopic; - memcpy(&pRspWrapper->msg, pMsg->pData, sizeof(SMqRspHead)); + memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead)); + + if (rspType == TMQ_MSG_TYPE__POLL_RSP) { + tDecodeSMqDataBlkRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &pRspWrapper->dataRsp); + } else { + ASSERT(rspType == TMQ_MSG_TYPE__POLL_META_RSP); + tDecodeSMqMetaRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &pRspWrapper->metaRsp); + } - tDecodeSMqDataBlkRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &pRspWrapper->msg); taosMemoryFree(pMsg->pData); tscDebug("consumer %ld recv poll: vg %d, req offset %ld, rsp offset %ld", tmq->consumerId, pVg->vgId, - pRspWrapper->msg.reqOffset, pRspWrapper->msg.rspOffset); + pRspWrapper->dataRsp.reqOffset, pRspWrapper->dataRsp.rspOffset); taosWriteQitem(tmq->mqueue, pRspWrapper); tsem_post(&tmq->rspSem); @@ -1516,6 +1539,17 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t timeout, SMqClientTopic* return pReq; } +SMqMetaRspObj* tmqBuildMetaRspFromWrapper(SMqPollRspWrapper* pWrapper) { + SMqMetaRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqMetaRspObj)); + pRspObj->resType = RES_TYPE__TMQ; + tstrncpy(pRspObj->topic, pWrapper->topicHandle->topicName, TSDB_TOPIC_FNAME_LEN); + tstrncpy(pRspObj->db, pWrapper->topicHandle->db, TSDB_DB_FNAME_LEN); + pRspObj->vgId = pWrapper->vgHandle->vgId; + + memcpy(&pRspObj->metaRsp, &pWrapper->metaRsp, sizeof(SMqMetaRsp)); + return pRspObj; +} + SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper) { SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj)); pRspObj->resType = RES_TYPE__TMQ; @@ -1523,11 +1557,11 @@ SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper) { tstrncpy(pRspObj->db, pWrapper->topicHandle->db, TSDB_DB_FNAME_LEN); pRspObj->vgId = pWrapper->vgHandle->vgId; pRspObj->resIter = -1; - memcpy(&pRspObj->rsp, &pWrapper->msg, sizeof(SMqDataBlkRsp)); + memcpy(&pRspObj->rsp, &pWrapper->dataRsp, sizeof(SMqDataBlkRsp)); pRspObj->resInfo.totalRows = 0; pRspObj->resInfo.precision = TSDB_TIME_PRECISION_MILLI; - if (!pWrapper->msg.withSchema) { + if (!pWrapper->dataRsp.withSchema) { setResSchemaInfo(&pRspObj->resInfo, pWrapper->topicHandle->schema.pSchema, pWrapper->topicHandle->schema.nCols); } @@ -1643,12 +1677,12 @@ SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)rspWrapper; /*atomic_sub_fetch_32(&tmq->readyRequest, 1);*/ int32_t consumerEpoch = atomic_load_32(&tmq->epoch); - if (pollRspWrapper->msg.head.epoch == consumerEpoch) { + if (pollRspWrapper->dataRsp.head.epoch == consumerEpoch) { SMqClientVg* pVg = pollRspWrapper->vgHandle; /*printf("vg %d offset %ld up to %ld\n", pVg->vgId, pVg->currentOffset, rspMsg->msg.rspOffset);*/ - pVg->currentOffset = pollRspWrapper->msg.rspOffset; + pVg->currentOffset = pollRspWrapper->dataRsp.rspOffset; atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE); - if (pollRspWrapper->msg.blockNum == 0) { + if (pollRspWrapper->dataRsp.blockNum == 0) { taosFreeQitem(pollRspWrapper); rspWrapper = NULL; continue; @@ -1658,8 +1692,25 @@ SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) { taosFreeQitem(pollRspWrapper); return pRsp; } else { - tscDebug("msg discard since epoch mismatch: msg epoch %d, consumer epoch %d\n", pollRspWrapper->msg.head.epoch, - consumerEpoch); + tscDebug("msg discard since epoch mismatch: msg epoch %d, consumer epoch %d\n", + pollRspWrapper->dataRsp.head.epoch, consumerEpoch); + taosFreeQitem(pollRspWrapper); + } + } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { + SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)rspWrapper; + int32_t consumerEpoch = atomic_load_32(&tmq->epoch); + if (pollRspWrapper->dataRsp.head.epoch == consumerEpoch) { + SMqClientVg* pVg = pollRspWrapper->vgHandle; + /*printf("vg %d offset %ld up to %ld\n", pVg->vgId, pVg->currentOffset, rspMsg->msg.rspOffset);*/ + pVg->currentOffset = pollRspWrapper->dataRsp.rspOffset; + atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE); + // build rsp + SMqRspObj* pRsp = tmqBuildRspFromWrapper(pollRspWrapper); + taosFreeQitem(pollRspWrapper); + return pRsp; + } else { + tscDebug("msg discard since epoch mismatch: msg epoch %d, consumer epoch %d\n", + pollRspWrapper->dataRsp.head.epoch, consumerEpoch); taosFreeQitem(pollRspWrapper); } } else { @@ -1747,10 +1798,23 @@ const char* tmq_err2str(int32_t err) { } } +tmq_res_t tmq_get_res_type(TAOS_RES* res) { + if (TD_RES_TMQ(res)) { + return TMQ_RES_DATA; + } else if (TD_RES_TMQ_META(res)) { + return TMQ_RES_TABLE_META; + } else { + return TMQ_RES_INVALID; + } +} + const char* tmq_get_topic_name(TAOS_RES* res) { if (TD_RES_TMQ(res)) { SMqRspObj* pRspObj = (SMqRspObj*)res; return strchr(pRspObj->topic, '.') + 1; + } else if (TD_RES_TMQ_META(res)) { + SMqMetaRspObj* pMetaRspObj = (SMqMetaRspObj*)res; + return strchr(pMetaRspObj->topic, '.') + 1; } else { return NULL; } @@ -1760,6 +1824,9 @@ const char* tmq_get_db_name(TAOS_RES* res) { if (TD_RES_TMQ(res)) { SMqRspObj* pRspObj = (SMqRspObj*)res; return strchr(pRspObj->db, '.') + 1; + } else if (TD_RES_TMQ_META(res)) { + SMqMetaRspObj* pMetaRspObj = (SMqMetaRspObj*)res; + return strchr(pMetaRspObj->db, '.') + 1; } else { return NULL; } @@ -1769,6 +1836,9 @@ int32_t tmq_get_vgroup_id(TAOS_RES* res) { if (TD_RES_TMQ(res)) { SMqRspObj* pRspObj = (SMqRspObj*)res; return pRspObj->vgId; + } else if (TD_RES_TMQ_META(res)) { + SMqMetaRspObj* pMetaRspObj = (SMqMetaRspObj*)res; + return pMetaRspObj->vgId; } else { return -1; } @@ -1786,6 +1856,16 @@ const char* tmq_get_table_name(TAOS_RES* res) { return NULL; } +int32_t tmq_get_raw_meta(TAOS_RES* res, const void** raw_meta, int32_t* raw_meta_len) { + if (TD_RES_TMQ_META(res)) { + SMqMetaRspObj* pMetaRspObj = (SMqMetaRspObj*)res; + *raw_meta = pMetaRspObj->metaRsp.metaRsp; + *raw_meta_len = pMetaRspObj->metaRsp.metaRspLen; + return 0; + } + return -1; +} + void tmq_commit_async(tmq_t* tmq, const TAOS_RES* msg, tmq_commit_cb* cb, void* param) { tmqCommitInner2(tmq, msg, 0, 1, cb, param); } diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index fffb03d9a5..832564e0db 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -1272,10 +1272,10 @@ TEST(testCase, sml_dup_time_Test) { const char *sql[] = { //"test_ms,t0=t c0=f 1626006833641", "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=false,c1=1i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"xcxvwjvf\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000", - "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=T,c1=2i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"fixrzcuq\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000", - "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=3i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"iupzdqub\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000", - "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=4i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"yvvtzzof\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000", - "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=5i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"vbxpilkj\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000" + "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=T,c1=2i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"fixrzcuq\",c8=L\"ncharColValue\",c9=7u64 1626006834639000000", + "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=3i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"iupzdqub\",c8=L\"ncharColValue\",c9=7u64 1626006835639000000", + "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=4i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"yvvtzzof\",c8=L\"ncharColValue\",c9=7u64 1626006836639000000", + "ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=5i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"vbxpilkj\",c8=L\"ncharColValue\",c9=7u64 1626006837639000000" }; pRes = taos_query(taos, "use dup_time"); taos_free_result(pRes); diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index d078d22cdf..a8f8ad00e1 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -127,7 +127,7 @@ int32_t tEncodeSEpSet(SEncoder *pEncoder, const SEpSet *pEp) { if (tEncodeI8(pEncoder, pEp->numOfEps) < 0) return -1; for (int32_t i = 0; i < TSDB_MAX_REPLICA; i++) { if (tEncodeU16(pEncoder, pEp->eps[i].port) < 0) return -1; - if (tEncodeCStr(pEncoder, pEp->eps[i].fqdn) < 0) return -1; + if (tEncodeCStrWithLen(pEncoder, pEp->eps[i].fqdn, TSDB_FQDN_LEN) < 0) return -1; } return 0; } @@ -532,6 +532,14 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq if (pReq->ast2Len > 0) { if (tEncodeBinary(&encoder, pReq->pAst2, pReq->ast2Len) < 0) return -1; } + + int32_t numOfFuncs = taosArrayGetSize(pReq->pFuncs); + if (tEncodeI32(&encoder, numOfFuncs) < 0) return -1; + for (int32_t i = 0; i < numOfFuncs; ++i) { + const char *pFunc = taosArrayGet(pReq->pFuncs, i); + if (tEncodeCStr(&encoder, pFunc) < 0) return -1; + } + tEndEncode(&encoder); int32_t tlen = encoder.pos; @@ -606,6 +614,21 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR if (tDecodeCStrTo(&decoder, pReq->pAst2) < 0) return -1; } + int32_t numOfFuncs = 0; + if (tDecodeI32(&decoder, &numOfFuncs) < 0) return -1; + if (numOfFuncs > 0) { + pReq->pFuncs = taosArrayInit(numOfFuncs, TSDB_FUNC_NAME_LEN); + if (NULL == pReq->pFuncs) return -1; + } + for (int32_t i = 0; i < numOfFuncs; ++i) { + char* pFunc = NULL; + if (tDecodeCStrAlloc(&decoder, &pFunc) < 0) return -1; + if (taosArrayPush(pReq->pFuncs, pFunc) == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + } + tEndDecode(&decoder); tDecoderClear(&decoder); @@ -618,8 +641,7 @@ void tFreeSMCreateStbReq(SMCreateStbReq *pReq) { taosMemoryFreeClear(pReq->comment); taosMemoryFreeClear(pReq->pAst1); taosMemoryFreeClear(pReq->pAst2); - pReq->pColumns = NULL; - pReq->pTags = NULL; + taosArrayDestroy(pReq->pFuncs); } int32_t tSerializeSMDropStbReq(void *buf, int32_t bufLen, SMDropStbReq *pReq) { @@ -1757,6 +1779,165 @@ void tFreeSRetrieveFuncRsp(SRetrieveFuncRsp *pRsp) { taosArrayDestroy(pRsp->pFuncInfos); } +int32_t tSerializeSTableCfgReq(void *buf, int32_t bufLen, STableCfgReq *pReq) { + int32_t headLen = sizeof(SMsgHead); + if (buf != NULL) { + buf = (char *)buf + headLen; + bufLen -= headLen; + } + + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->dbFName) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->tbName) < 0) return -1; + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + + if (buf != NULL) { + SMsgHead *pHead = (SMsgHead *)((char *)buf - headLen); + pHead->vgId = htonl(pReq->header.vgId); + pHead->contLen = htonl(tlen + headLen); + } + + return tlen + headLen; +} + +int32_t tDeserializeSTableCfgReq(void *buf, int32_t bufLen, STableCfgReq *pReq) { + int32_t headLen = sizeof(SMsgHead); + + SMsgHead *pHead = buf; + pHead->vgId = pReq->header.vgId; + pHead->contLen = pReq->header.contLen; + + SDecoder decoder = {0}; + tDecoderInit(&decoder, (char *)buf + headLen, bufLen - headLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->dbFName) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->tbName) < 0) return -1; + + tEndDecode(&decoder); + tDecoderClear(&decoder); + return 0; +} + +int32_t tSerializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pRsp->tbName) < 0) return -1; + if (tEncodeCStr(&encoder, pRsp->stbName) < 0) return -1; + if (tEncodeCStr(&encoder, pRsp->dbFName) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->numOfTags) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->numOfColumns) < 0) return -1; + if (tEncodeI8(&encoder, pRsp->tableType) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->delay1) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->delay2) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->watermark1) < 0) return -1; + if (tEncodeI64(&encoder, pRsp->watermark2) < 0) return -1; + if (tEncodeI32(&encoder, pRsp->ttl) < 0) return -1; + + int32_t numOfFuncs = taosArrayGetSize(pRsp->pFuncs); + if (tEncodeI32(&encoder, numOfFuncs) < 0) return -1; + for (int32_t i = 0; i < numOfFuncs; ++i) { + const char *pFunc = taosArrayGet(pRsp->pFuncs, i); + if (tEncodeCStr(&encoder, pFunc) < 0) return -1; + } + + if (tEncodeI32(&encoder, pRsp->commentLen) < 0) return -1; + if (pRsp->commentLen > 0) { + if (tEncodeCStr(&encoder, pRsp->pComment) < 0) return -1; + } + + for (int32_t i = 0; i < pRsp->numOfColumns + pRsp->numOfTags; ++i) { + SSchema *pSchema = &pRsp->pSchemas[i]; + if (tEncodeSSchema(&encoder, pSchema) < 0) return -1; + } + + if (tEncodeI32(&encoder, pRsp->tagsLen) < 0) return -1; + if (tEncodeBinary(&encoder, pRsp->pTags, pRsp->tagsLen) < 0) return -1; + + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pRsp->tbName) < 0) return -1; + if (tDecodeCStrTo(&decoder, pRsp->stbName) < 0) return -1; + if (tDecodeCStrTo(&decoder, pRsp->dbFName) < 0) return -1; + if (tDecodeI32(&decoder, &pRsp->numOfTags) < 0) return -1; + if (tDecodeI32(&decoder, &pRsp->numOfColumns) < 0) return -1; + if (tDecodeI8(&decoder, &pRsp->tableType) < 0) return -1; + if (tDecodeI64(&decoder, &pRsp->delay1) < 0) return -1; + if (tDecodeI64(&decoder, &pRsp->delay2) < 0) return -1; + if (tDecodeI64(&decoder, &pRsp->watermark1) < 0) return -1; + if (tDecodeI64(&decoder, &pRsp->watermark2) < 0) return -1; + if (tDecodeI32(&decoder, &pRsp->ttl) < 0) return -1; + + int32_t numOfFuncs = 0; + if (tDecodeI32(&decoder, &numOfFuncs) < 0) return -1; + if (numOfFuncs > 0) { + pRsp->pFuncs = taosArrayInit(numOfFuncs, TSDB_FUNC_NAME_LEN); + if (NULL == pRsp->pFuncs) return -1; + } + for (int32_t i = 0; i < numOfFuncs; ++i) { + char pFunc[TSDB_FUNC_NAME_LEN]; + if (tDecodeCStrTo(&decoder, pFunc) < 0) return -1; + if (taosArrayPush(pRsp->pFuncs, pFunc) == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + } + + if (tDecodeI32(&decoder, &pRsp->commentLen) < 0) return -1; + if (pRsp->commentLen > 0) { + if (tDecodeCStrAlloc(&decoder, &pRsp->pComment) < 0) return -1; + } else { + pRsp->pComment = NULL; + } + + int32_t totalCols = pRsp->numOfTags + pRsp->numOfColumns; + pRsp->pSchemas = taosMemoryMalloc(sizeof(SSchema) * totalCols); + if (pRsp->pSchemas == NULL) return -1; + + for (int32_t i = 0; i < totalCols; ++i) { + SSchema *pSchema = &pRsp->pSchemas[i]; + if (tDecodeSSchema(&decoder, pSchema) < 0) return -1; + } + + if (tDecodeI32(&decoder, &pRsp->tagsLen) < 0) return -1; + if (tDecodeBinaryAlloc(&decoder, (void**)&pRsp->pTags, NULL) < 0) return -1; + + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + +void tFreeSTableCfgRsp(STableCfgRsp *pRsp) { + if (NULL == pRsp) { + return; + } + + taosMemoryFreeClear(pRsp->pComment); + taosMemoryFreeClear(pRsp->pSchemas); + taosMemoryFreeClear(pRsp->pTags); + + taosArrayDestroy(pRsp->pFuncs); +} + int32_t tSerializeSCreateDbReq(void *buf, int32_t bufLen, SCreateDbReq *pReq) { SEncoder encoder = {0}; tEncoderInit(&encoder, buf, bufLen); @@ -2956,6 +3137,7 @@ int32_t tSerializeSCMCreateTopicReq(void *buf, int32_t bufLen, const SCMCreateTo if (tEncodeCStr(&encoder, pReq->name) < 0) return -1; if (tEncodeI8(&encoder, pReq->igExists) < 0) return -1; if (tEncodeI8(&encoder, pReq->subType) < 0) return -1; + if (tEncodeI8(&encoder, pReq->withMeta) < 0) return -1; if (tEncodeCStr(&encoder, pReq->subDbName) < 0) return -1; if (TOPIC_SUB_TYPE__DB == pReq->subType) { } else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) { @@ -2985,6 +3167,7 @@ int32_t tDeserializeSCMCreateTopicReq(void *buf, int32_t bufLen, SCMCreateTopicR if (tDecodeCStrTo(&decoder, pReq->name) < 0) return -1; if (tDecodeI8(&decoder, &pReq->igExists) < 0) return -1; if (tDecodeI8(&decoder, &pReq->subType) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->withMeta) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->subDbName) < 0) return -1; if (TOPIC_SUB_TYPE__DB == pReq->subType) { } else if (TOPIC_SUB_TYPE__TABLE == pReq->subType) { @@ -3052,7 +3235,7 @@ int32_t tSerializeSConnectReq(void *buf, int32_t bufLen, SConnectReq *pReq) { if (tEncodeCStr(&encoder, pReq->app) < 0) return -1; if (tEncodeCStr(&encoder, pReq->db) < 0) return -1; if (tEncodeCStr(&encoder, pReq->user) < 0) return -1; - if (tEncodeCStr(&encoder, pReq->passwd) < 0) return -1; + if (tEncodeCStrWithLen(&encoder, pReq->passwd, TSDB_PASSWORD_LEN) < 0) return -1; if (tEncodeI64(&encoder, pReq->startTime) < 0) return -1; tEndEncode(&encoder); @@ -4267,6 +4450,35 @@ int32_t tDeserializeSCMCreateStreamReq(void *buf, int32_t bufLen, SCMCreateStrea return 0; } +int32_t tSerializeSMDropStreamReq(void *buf, int32_t bufLen, const SMDropStreamReq *pReq) { + SEncoder encoder = {0}; + tEncoderInit(&encoder, buf, bufLen); + + if (tStartEncode(&encoder) < 0) return -1; + if (tEncodeCStr(&encoder, pReq->name) < 0) return -1; + if (tEncodeI8(&encoder, pReq->igNotExists) < 0) return -1; + + tEndEncode(&encoder); + + int32_t tlen = encoder.pos; + tEncoderClear(&encoder); + return tlen; +} + +int32_t tDeserializeSMDropStreamReq(void *buf, int32_t bufLen, SMDropStreamReq *pReq) { + SDecoder decoder = {0}; + tDecoderInit(&decoder, buf, bufLen); + + if (tStartDecode(&decoder) < 0) return -1; + if (tDecodeCStrTo(&decoder, pReq->name) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->igNotExists) < 0) return -1; + + tEndDecode(&decoder); + + tDecoderClear(&decoder); + return 0; +} + void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) { taosMemoryFreeClear(pReq->sql); taosMemoryFreeClear(pReq->ast); diff --git a/source/common/src/tname.c b/source/common/src/tname.c index fd05513579..ce454d439d 100644 --- a/source/common/src/tname.c +++ b/source/common/src/tname.c @@ -240,6 +240,15 @@ bool tNameDBNameEqual(SName* left, SName* right) { return (0 == strcmp(left->dbname, right->dbname)); } +bool tNameTbNameEqual(SName* left, SName* right) { + bool equal = tNameDBNameEqual(left, right); + if (equal) { + return (0 == strcmp(left->tname, right->tname)); + } + + return equal; +} + int32_t tNameFromString(SName* dst, const char* str, uint32_t type) { assert(dst != NULL && str != NULL && strlen(str) > 0); @@ -312,8 +321,10 @@ void buildChildTableName(RandTableName* rName) { taosStringBuilderAppendStringLen(&sb, rName->sTableName, rName->sTableNameLen); taosArraySort(rName->tags, compareKv); for (int j = 0; j < taosArrayGetSize(rName->tags); ++j) { + taosStringBuilderAppendChar(&sb, ','); SSmlKv* tagKv = taosArrayGetP(rName->tags, j); taosStringBuilderAppendStringLen(&sb, tagKv->key, tagKv->keyLen); + taosStringBuilderAppendChar(&sb, '='); if (IS_VAR_DATA_TYPE(tagKv->type)) { taosStringBuilderAppendStringLen(&sb, tagKv->value, tagKv->length); } else { @@ -326,9 +337,14 @@ void buildChildTableName(RandTableName* rName) { tMD5Init(&context); tMD5Update(&context, (uint8_t*)keyJoined, (uint32_t)len); tMD5Final(&context); - uint64_t digest1 = *(uint64_t*)(context.digest); - uint64_t digest2 = *(uint64_t*)(context.digest + 8); - snprintf(rName->childTableName, TSDB_TABLE_NAME_LEN, "t_%016" PRIx64 "%016" PRIx64, digest1, digest2); + + char temp[8] = {0}; + rName->childTableName[0] = 't'; + rName->childTableName[1] = '_'; + for(int i = 0; i < 16; i++){ + sprintf(temp, "%02x", context.digest[i]); + strcat(rName->childTableName, temp); + } taosStringBuilderDestroy(&sb); - rName->uid = digest1; + rName->uid = *(uint64_t*)(context.digest); } diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c index 0112feedd2..474e6ab378 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c @@ -73,6 +73,7 @@ int32_t mmProcessGetLoadsReq(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) { } int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { + const STraceId *trace = &pMsg->info.traceId; SDCreateMnodeReq createReq = {0}; if (tDeserializeSDCreateMnodeReq(pMsg->pCont, pMsg->contLen, &createReq) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -81,7 +82,7 @@ int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { if (createReq.replica != 1) { terrno = TSDB_CODE_INVALID_OPTION; - dError("failed to create mnode since %s", terrstr()); + dGError("failed to create mnode since %s", terrstr()); return -1; } @@ -91,7 +92,7 @@ int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { mgmt.path = pInput->path; mgmt.name = pInput->name; if (mmWriteFile(&mgmt, &createReq.replicas[0], deployed) != 0) { - dError("failed to write mnode file since %s", terrstr()); + dGError("failed to write mnode file since %s", terrstr()); return -1; } @@ -99,7 +100,8 @@ int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { } int32_t mmProcessDropReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { - SDDropMnodeReq dropReq = {0}; + const STraceId *trace = &pMsg->info.traceId; + SDDropMnodeReq dropReq = {0}; if (tDeserializeSCreateDropMQSBNodeReq(pMsg->pCont, pMsg->contLen, &dropReq) != 0) { terrno = TSDB_CODE_INVALID_MSG; return -1; @@ -107,7 +109,7 @@ int32_t mmProcessDropReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { if (pInput->pData->dnodeId != 0 && dropReq.dnodeId != pInput->pData->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; - dError("failed to drop mnode since %s", terrstr()); + dGError("failed to drop mnode since %s", terrstr()); return -1; } @@ -117,7 +119,7 @@ int32_t mmProcessDropReq(const SMgmtInputOpt *pInput, SRpcMsg *pMsg) { mgmt.path = pInput->path; mgmt.name = pInput->name; if (mmWriteFile(&mgmt, NULL, deployed) != 0) { - dError("failed to write mnode file since %s", terrstr()); + dGError("failed to write mnode file since %s", terrstr()); return -1; } @@ -180,6 +182,7 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_STB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_STB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_TABLE_META, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_TABLE_CFG, mmPutMsgToReadQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_SMA, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_SMA, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_STREAM, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; @@ -216,7 +219,7 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_VG_DELETE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, mmPutMsgToFetchQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DEPLOY_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TASK_DROP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DROP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_CONFIG_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_REPLICA_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_CONFIRM_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c index 60c42d31f5..7f3f76b4b6 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c @@ -18,7 +18,6 @@ static inline int32_t mmAcquire(SMnodeMgmt *pMgmt) { int32_t code = 0; - taosThreadRwlockRdlock(&pMgmt->lock); if (pMgmt->stopped) { code = -1; @@ -48,7 +47,8 @@ static inline void mmSendRsp(SRpcMsg *pMsg, int32_t code) { static void mmProcessRpcMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) { SMnodeMgmt *pMgmt = pInfo->ahandle; int32_t code = -1; - STraceId * trace = &pMsg->info.traceId; + + const STraceId *trace = &pMsg->info.traceId; dGTrace("msg:%p, get from mnode queue", pMsg); switch (pMsg->msgType) { @@ -68,7 +68,11 @@ static void mmProcessRpcMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) { mmSendRsp(pMsg, code); } - dTrace("msg:%p, is freed, code:0x%x", pMsg, code); + if (code == TSDB_CODE_RPC_REDIRECT) { + mndPostProcessQueryMsg(pMsg); + } + + dGTrace("msg:%p, is freed, code:0x%x", pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } @@ -76,7 +80,9 @@ static void mmProcessRpcMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) { static void mmProcessSyncMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) { SMnodeMgmt *pMgmt = pInfo->ahandle; pMsg->info.node = pMgmt->pMnode; - dTrace("msg:%p, get from mnode-sync queue", pMsg); + + const STraceId *trace = &pMsg->info.traceId; + dGTrace("msg:%p, get from mnode-sync queue", pMsg); SMsgHead *pHead = pMsg->pCont; pHead->contLen = ntohl(pHead->contLen); @@ -84,20 +90,22 @@ static void mmProcessSyncMsg(SQueueInfo *pInfo, SRpcMsg *pMsg) { int32_t code = mndProcessSyncMsg(pMsg); - dTrace("msg:%p, is freed, code:0x%x", pMsg, code); + dGTrace("msg:%p, is freed, code:0x%x", pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } static inline int32_t mmPutMsgToWorker(SMnodeMgmt *pMgmt, SSingleWorker *pWorker, SRpcMsg *pMsg) { + const STraceId *trace = &pMsg->info.traceId; + if (mmAcquire(pMgmt) == 0) { - dTrace("msg:%p, put into %s queue, type:%s", pMsg, pWorker->name, TMSG_INFO(pMsg->msgType)); + dGTrace("msg:%p, put into %s queue, type:%s", pMsg, pWorker->name, TMSG_INFO(pMsg->msgType)); taosWriteQitem(pWorker->queue, pMsg); mmRelease(pMgmt); return 0; } else { - dTrace("msg:%p, failed to put into %s queue since %s, type:%s", pMsg, pWorker->name, terrstr(), - TMSG_INFO(pMsg->msgType)); + dGTrace("msg:%p, failed to put into %s queue since %s, type:%s", pMsg, pWorker->name, terrstr(), + TMSG_INFO(pMsg->msgType)); return -1; } } @@ -116,20 +124,18 @@ int32_t mmPutMsgToReadQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) { int32_t mmPutMsgToQueryQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) { pMsg->info.node = pMgmt->pMnode; - if (mndPreProcessMsg(pMsg) != 0) { - dError("msg:%p, failed to pre-process in mnode since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType)); + if (mndPreProcessQueryMsg(pMsg) != 0) { + const STraceId *trace = &pMsg->info.traceId; + dGError("msg:%p, failed to pre-process in mnode since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType)); return -1; } return mmPutMsgToWorker(pMgmt, &pMgmt->queryWorker, pMsg); } int32_t mmPutMsgToFetchQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) { - pMsg->info.node = pMgmt->pMnode; - return mmPutMsgToWorker(pMgmt, &pMgmt->fetchWorker, pMsg); } - int32_t mmPutMsgToMonitorQueue(SMnodeMgmt *pMgmt, SRpcMsg *pMsg) { return mmPutMsgToWorker(pMgmt, &pMgmt->monitorWorker, pMsg); } diff --git a/source/dnode/mgmt/mgmt_snode/src/smHandle.c b/source/dnode/mgmt/mgmt_snode/src/smHandle.c index 81576e153e..e1ffc3bdb7 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smHandle.c +++ b/source/dnode/mgmt/mgmt_snode/src/smHandle.c @@ -95,7 +95,7 @@ SArray *smGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_MON_SM_INFO, smPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DEPLOY, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TASK_DROP, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DROP, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RUN, smPutNodeMsgToSharedQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH, smPutNodeMsgToSharedQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH_RSP, smPutNodeMsgToSharedQueue, 1) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index c3ed6d781c..d9502ec8f3 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -330,6 +330,7 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_TABLE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_UPDATE_TAG_VAL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TABLE_META, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TABLE_CFG, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_TABLES_META, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_CANCEL_TASK, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; @@ -351,7 +352,7 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_HEARTBEAT, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TASK_DROP, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DROP, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DEPLOY, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RUN, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH, vmPutMsgToFetchQueue, 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 71bbc8ddd4..5e1ef23f1c 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -28,10 +28,10 @@ static inline void vmSendRsp(SRpcMsg *pMsg, int32_t code) { } static void vmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { - SVnodeMgmt *pMgmt = pInfo->ahandle; - int32_t code = -1; + SVnodeMgmt *pMgmt = pInfo->ahandle; + int32_t code = -1; + const STraceId *trace = &pMsg->info.traceId; - STraceId *trace = &pMsg->info.traceId; dGTrace("msg:%p, get from vnode-mgmt queue", pMsg); switch (pMsg->msgType) { case TDMT_MON_VM_INFO: @@ -48,50 +48,52 @@ static void vmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { break; default: terrno = TSDB_CODE_MSG_NOT_PROCESSED; - dError("msg:%p, not processed in vnode-mgmt queue", pMsg); + dGError("msg:%p, not processed in vnode-mgmt queue", pMsg); } if (IsReq(pMsg)) { if (code != 0) { if (terrno != 0) code = terrno; - dError("msg:%p, failed to process since %s", pMsg, terrstr()); + dGError("msg:%p, failed to process since %s", pMsg, terrstr()); } vmSendRsp(pMsg, code); } - dTrace("msg:%p, is freed, code:0x%x", pMsg, code); + dGTrace("msg:%p, is freed, code:0x%x", pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } static void vmProcessQueryQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { - SVnodeObj *pVnode = pInfo->ahandle; + SVnodeObj *pVnode = pInfo->ahandle; + const STraceId *trace = &pMsg->info.traceId; - dTrace("vgId:%d, msg:%p get from vnode-query queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p get from vnode-query queue", pVnode->vgId, pMsg); int32_t code = vnodeProcessQueryMsg(pVnode->pImpl, pMsg); if (code != 0) { if (terrno != 0) code = terrno; - dError("vgId:%d, msg:%p failed to query since %s", pVnode->vgId, pMsg, terrstr()); + dGError("vgId:%d, msg:%p failed to query since %s", pVnode->vgId, pMsg, terrstr()); vmSendRsp(pMsg, code); } - dTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); + dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } static void vmProcessFetchQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { - SVnodeObj *pVnode = pInfo->ahandle; + SVnodeObj *pVnode = pInfo->ahandle; + const STraceId *trace = &pMsg->info.traceId; - dTrace("vgId:%d, msg:%p get from vnode-fetch queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p get from vnode-fetch queue", pVnode->vgId, pMsg); int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo); if (code != 0) { if (terrno != 0) code = terrno; - dError("vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr()); + dGError("vgId:%d, msg:%p failed to fetch since %s", pVnode->vgId, pMsg, terrstr()); vmSendRsp(pMsg, code); } - dTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); + dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } @@ -102,16 +104,17 @@ static void vmProcessSyncQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOf for (int32_t i = 0; i < numOfMsgs; ++i) { if (taosGetQitem(qall, (void **)&pMsg) == 0) continue; - dTrace("vgId:%d, msg:%p get from vnode-sync queue", pVnode->vgId, pMsg); + const STraceId *trace = &pMsg->info.traceId; + dGTrace("vgId:%d, msg:%p get from vnode-sync queue", pVnode->vgId, pMsg); int32_t code = vnodeProcessSyncReq(pVnode->pImpl, pMsg, NULL); if (code != 0) { if (terrno != 0) code = terrno; - dError("vgId:%d, msg:%p failed to sync since %s", pVnode->vgId, pMsg, terrstr()); + dGError("vgId:%d, msg:%p failed to sync since %s", pVnode->vgId, pMsg, terrstr()); vmSendRsp(pMsg, code); } - dTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); + dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } @@ -123,55 +126,57 @@ static void vmProcessMergeQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO for (int32_t i = 0; i < numOfMsgs; ++i) { if (taosGetQitem(qall, (void **)&pMsg) == 0) continue; - dTrace("vgId:%d, msg:%p get from vnode-merge queue", pVnode->vgId, pMsg); + const STraceId *trace = &pMsg->info.traceId; + dGTrace("vgId:%d, msg:%p get from vnode-merge queue", pVnode->vgId, pMsg); int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo); if (code != 0) { if (terrno != 0) code = terrno; - dError("vgId:%d, msg:%p failed to merge since %s", pVnode->vgId, pMsg, terrstr()); + dGError("vgId:%d, msg:%p failed to merge since %s", pVnode->vgId, pMsg, terrstr()); vmSendRsp(pMsg, code); } - dTrace("msg:%p, is freed, code:0x%x", pMsg, code); + dGTrace("msg:%p, is freed, code:0x%x", pMsg, code); rpcFreeCont(pMsg->pCont); taosFreeQitem(pMsg); } } static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtype) { - SMsgHead *pHead = pMsg->pCont; - int32_t code = 0; + const STraceId *trace = &pMsg->info.traceId; + SMsgHead *pHead = pMsg->pCont; + int32_t code = 0; pHead->contLen = ntohl(pHead->contLen); pHead->vgId = ntohl(pHead->vgId); SVnodeObj *pVnode = vmAcquireVnode(pMgmt, pHead->vgId); if (pVnode == NULL) { - dError("vgId:%d, msg:%p failed to put into vnode queue since %s, type:%s", pHead->vgId, pMsg, terrstr(), - TMSG_INFO(pMsg->msgType)); + dGError("vgId:%d, msg:%p failed to put into vnode queue since %s, type:%s", pHead->vgId, pMsg, terrstr(), + TMSG_INFO(pMsg->msgType)); return terrno != 0 ? terrno : -1; } switch (qtype) { case QUERY_QUEUE: vnodePreprocessQueryMsg(pVnode->pImpl, pMsg); - dTrace("vgId:%d, msg:%p put into vnode-query queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p put into vnode-query queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pQueryQ, pMsg); break; case FETCH_QUEUE: - dTrace("vgId:%d, msg:%p put into vnode-fetch queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p put into vnode-fetch queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pFetchQ, pMsg); break; case WRITE_QUEUE: - dTrace("vgId:%d, msg:%p put into vnode-write queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p put into vnode-write queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pWriteQ, pMsg); break; case SYNC_QUEUE: - dTrace("vgId:%d, msg:%p put into vnode-sync queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p put into vnode-sync queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pSyncQ, pMsg); break; case APPLY_QUEUE: - dTrace("vgId:%d, msg:%p put into vnode-apply queue", pVnode->vgId, pMsg); + dGTrace("vgId:%d, msg:%p put into vnode-apply queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pApplyQ, pMsg); break; default: @@ -193,13 +198,15 @@ int32_t vmPutMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsg int32_t vmPutMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsgToQueue(pMgmt, pMsg, FETCH_QUEUE); } int32_t vmPutMsgToMgmtQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { - dTrace("msg:%p, put into vnode-mgmt queue", pMsg); + const STraceId *trace = &pMsg->info.traceId; + dGTrace("msg:%p, put into vnode-mgmt queue", pMsg); taosWriteQitem(pMgmt->mgmtWorker.queue, pMsg); return 0; } int32_t vmPutMsgToMonitorQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { - dTrace("msg:%p, put into vnode-monitor queue", pMsg); + const STraceId *trace = &pMsg->info.traceId; + dGTrace("msg:%p, put into vnode-monitor queue", pMsg); taosWriteQitem(pMgmt->monitorWorker.queue, pMsg); return 0; } diff --git a/source/dnode/mgmt/node_mgmt/src/dmTransport.c b/source/dnode/mgmt/node_mgmt/src/dmTransport.c index 660f512fc5..4761e3dc36 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmTransport.c +++ b/source/dnode/mgmt/node_mgmt/src/dmTransport.c @@ -17,9 +17,44 @@ #include "dmMgmt.h" #include "qworker.h" -static void dmSendRedirectRsp(SRpcMsg *pMsg, const SEpSet *pNewEpSet); -static void dmSendRsp(SRpcMsg *pMsg); -static void dmBuildMnodeRedirectRsp(SDnode *pDnode, SRpcMsg *pMsg); +static inline void dmSendRsp(SRpcMsg *pMsg) { + SMgmtWrapper *pWrapper = pMsg->info.wrapper; + if (InChildProc(pWrapper)) { + dmPutToProcPQueue(&pWrapper->proc, pMsg, DND_FUNC_RSP); + } else { + rpcSendResponse(pMsg); + } +} + +static inline void dmBuildMnodeRedirectRsp(SDnode *pDnode, SRpcMsg *pMsg) { + SEpSet epSet = {0}; + dmGetMnodeEpSetForRedirect(&pDnode->data, pMsg, &epSet); + + const int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet); + pMsg->pCont = rpcMallocCont(contLen); + if (pMsg->pCont == NULL) { + pMsg->code = TSDB_CODE_OUT_OF_MEMORY; + } else { + tSerializeSEpSet(pMsg->pCont, contLen, &epSet); + pMsg->contLen = contLen; + } +} + +static inline void dmSendRedirectRsp(SRpcMsg *pMsg, const SEpSet *pNewEpSet) { + SRpcMsg rsp = {.code = TSDB_CODE_RPC_REDIRECT, .info = pMsg->info}; + int32_t contLen = tSerializeSEpSet(NULL, 0, pNewEpSet); + + rsp.pCont = rpcMallocCont(contLen); + if (rsp.pCont == NULL) { + pMsg->code = TSDB_CODE_OUT_OF_MEMORY; + } else { + tSerializeSEpSet(rsp.pCont, contLen, pNewEpSet); + rsp.contLen = contLen; + } + dmSendRsp(&rsp); + rpcFreeCont(pMsg->pCont); + pMsg->pCont = NULL; +} int32_t dmProcessNodeMsg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) { NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pMsg->msgType)]; @@ -28,31 +63,38 @@ int32_t dmProcessNodeMsg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) { return -1; } - dTrace("msg:%p, will be processed by %s", pMsg, pWrapper->name); + const STraceId *trace = &pMsg->info.traceId; + dGTrace("msg:%p, will be processed by %s", pMsg, pWrapper->name); pMsg->info.wrapper = pWrapper; return (*msgFp)(pWrapper->pMgmt, pMsg); } static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) { - SDnodeTrans * pTrans = &pDnode->trans; + SDnodeTrans *pTrans = &pDnode->trans; int32_t code = -1; - SRpcMsg * pMsg = NULL; + SRpcMsg *pMsg = NULL; SMgmtWrapper *pWrapper = NULL; SDnodeHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(pRpc->msgType)]; - STraceId *trace = &pRpc->info.traceId; + const STraceId *trace = &pRpc->info.traceId; dGTrace("msg:%s is received, handle:%p len:%d code:0x%x app:%p refId:%" PRId64, TMSG_INFO(pRpc->msgType), pRpc->info.handle, pRpc->contLen, pRpc->code, pRpc->info.ahandle, pRpc->info.refId); - if (pRpc->msgType == TDMT_DND_NET_TEST) { - dmProcessNetTestReq(pDnode, pRpc); - return; - } else if (pRpc->msgType == TDMT_MND_SYSTABLE_RETRIEVE_RSP || pRpc->msgType == TDMT_VND_FETCH_RSP) { - qWorkerProcessFetchRsp(NULL, NULL, pRpc, 0); - return; - } else if (pRpc->msgType == TDMT_MND_STATUS_RSP && pEpSet != NULL) { - dmSetMnodeEpSet(&pDnode->data, pEpSet); - } else { + switch (pRpc->msgType) { + case TDMT_DND_NET_TEST: + dmProcessNetTestReq(pDnode, pRpc); + return; + case TDMT_MND_SYSTABLE_RETRIEVE_RSP: + case TDMT_VND_FETCH_RSP: + qWorkerProcessFetchRsp(NULL, NULL, pRpc, 0); + return; + case TDMT_MND_STATUS_RSP: + if (pEpSet != NULL) { + dmSetMnodeEpSet(&pDnode->data, pEpSet); + } + break; + default: + break; } if (pDnode->status != DND_STAT_RUNNING) { @@ -73,39 +115,43 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) { if (pHandle->defaultNtype == NODE_END) { terrno = TSDB_CODE_MSG_NOT_PROCESSED; goto _OVER; - } else { - pWrapper = &pDnode->wrappers[pHandle->defaultNtype]; - if (pHandle->needCheckVgId) { - if (pRpc->contLen > 0) { - SMsgHead *pHead = pRpc->pCont; - int32_t vgId = ntohl(pHead->vgId); - if (vgId == QNODE_HANDLE) { + } + + pWrapper = &pDnode->wrappers[pHandle->defaultNtype]; + if (pHandle->needCheckVgId) { + if (pRpc->contLen > 0) { + const SMsgHead *pHead = pRpc->pCont; + const int32_t vgId = ntohl(pHead->vgId); + switch (vgId) { + case QNODE_HANDLE: pWrapper = &pDnode->wrappers[QNODE]; - } else if (vgId == SNODE_HANDLE) { + break; + case SNODE_HANDLE: pWrapper = &pDnode->wrappers[SNODE]; - } else if (vgId == MNODE_HANDLE) { + break; + case MNODE_HANDLE: pWrapper = &pDnode->wrappers[MNODE]; - } else { - } - } else { - terrno = TSDB_CODE_INVALID_MSG_LEN; - goto _OVER; + break; + default: + break; } + } else { + terrno = TSDB_CODE_INVALID_MSG_LEN; + goto _OVER; } } if (dmMarkWrapper(pWrapper) != 0) { pWrapper = NULL; goto _OVER; - } else { - pRpc->info.wrapper = pWrapper; } + pRpc->info.wrapper = pWrapper; pMsg = taosAllocateQitem(sizeof(SRpcMsg), RPC_QITEM); if (pMsg == NULL) goto _OVER; - memcpy(pMsg, pRpc, sizeof(SRpcMsg)); - dTrace("msg:%p, is created, type:%s handle:%p", pMsg, TMSG_INFO(pRpc->msgType), pMsg->info.handle); + memcpy(pMsg, pRpc, sizeof(SRpcMsg)); + dGTrace("msg:%p, is created, type:%s handle:%p", pMsg, TMSG_INFO(pRpc->msgType), pMsg->info.handle); if (InParentProc(pWrapper)) { code = dmPutToProcCQueue(&pWrapper->proc, pMsg, DND_FUNC_REQ); @@ -115,13 +161,11 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) { _OVER: if (code != 0) { - dTrace("failed to process msg:%p since %s, handle:%p", pMsg, terrstr(), pRpc->info.handle); - if (terrno != 0) code = terrno; + dGTrace("msg:%p, failed to process since %s", pMsg, terrstr()); if (IsReq(pRpc)) { SRpcMsg rsp = {.code = code, .info = pRpc->info}; - if ((code == TSDB_CODE_NODE_NOT_DEPLOYED || code == TSDB_CODE_APP_NOT_READY) && pRpc->msgType > TDMT_MND_MSG && pRpc->msgType < TDMT_VND_MSG) { dmBuildMnodeRedirectRsp(pDnode, &rsp); @@ -135,7 +179,7 @@ _OVER: } if (pMsg != NULL) { - dTrace("msg:%p, is freed", pMsg); + dGTrace("msg:%p, is freed", pMsg); taosFreeQitem(pMsg); } rpcFreeCont(pRpc->pCont); @@ -149,11 +193,11 @@ int32_t dmInitMsgHandle(SDnode *pDnode) { for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; - SArray * pArray = (*pWrapper->func.getHandlesFp)(); + SArray *pArray = (*pWrapper->func.getHandlesFp)(); if (pArray == NULL) return -1; for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) { - SMgmtHandle * pMgmt = taosArrayGet(pArray, i); + SMgmtHandle *pMgmt = taosArrayGet(pArray, i); SDnodeHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(pMgmt->msgType)]; if (pMgmt->needCheckVgId) { pHandle->needCheckVgId = pMgmt->needCheckVgId; @@ -184,45 +228,6 @@ static inline int32_t dmSendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) { } } -static inline void dmSendRsp(SRpcMsg *pMsg) { - SMgmtWrapper *pWrapper = pMsg->info.wrapper; - if (InChildProc(pWrapper)) { - dmPutToProcPQueue(&pWrapper->proc, pMsg, DND_FUNC_RSP); - } else { - rpcSendResponse(pMsg); - } -} - -static void dmBuildMnodeRedirectRsp(SDnode *pDnode, SRpcMsg *pMsg) { - SEpSet epSet = {0}; - dmGetMnodeEpSetForRedirect(&pDnode->data, pMsg, &epSet); - - int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet); - pMsg->pCont = rpcMallocCont(contLen); - if (pMsg->pCont == NULL) { - pMsg->code = TSDB_CODE_OUT_OF_MEMORY; - } else { - tSerializeSEpSet(pMsg->pCont, contLen, &epSet); - pMsg->contLen = contLen; - } -} - -static inline void dmSendRedirectRsp(SRpcMsg *pMsg, const SEpSet *pNewEpSet) { - SRpcMsg rsp = {.code = TSDB_CODE_RPC_REDIRECT, .info = pMsg->info}; - int32_t contLen = tSerializeSEpSet(NULL, 0, pNewEpSet); - - rsp.pCont = rpcMallocCont(contLen); - if (rsp.pCont == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - } else { - tSerializeSEpSet(rsp.pCont, contLen, pNewEpSet); - rsp.contLen = contLen; - } - dmSendRsp(&rsp); - rpcFreeCont(pMsg->pCont); - pMsg->pCont = NULL; -} - static inline void dmRegisterBrokenLinkArg(SRpcMsg *pMsg) { SMgmtWrapper *pWrapper = pMsg->info.wrapper; if (InChildProc(pWrapper)) { diff --git a/source/dnode/mgmt/node_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h index 7897f62f62..01958aa053 100644 --- a/source/dnode/mgmt/node_util/inc/dmUtil.h +++ b/source/dnode/mgmt/node_util/inc/dmUtil.h @@ -40,18 +40,28 @@ #include "wal.h" #include "libs/function/function.h" -// clang-format off #ifdef __cplusplus extern "C" { #endif -#define dFatal(...) { if (dDebugFlag & DEBUG_FATAL) { taosPrintLog("DND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} -#define dError(...) { if (dDebugFlag & DEBUG_ERROR) { taosPrintLog("DND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} -#define dWarn(...) { if (dDebugFlag & DEBUG_WARN) { taosPrintLog("DND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} -#define dInfo(...) { if (dDebugFlag & DEBUG_INFO) { taosPrintLog("DND ", DEBUG_INFO, 255, __VA_ARGS__); }} -#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("DND ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} -#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("DND ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} -#define dGTrace(param, ...) do { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dTrace(param ",GTID: %s", __VA_ARGS__, buf);} while(0) + +// clang-format off + +#define dFatal(...) { if (dDebugFlag & DEBUG_FATAL) { taosPrintLog("DND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} +#define dError(...) { if (dDebugFlag & DEBUG_ERROR) { taosPrintLog("DND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} +#define dWarn(...) { if (dDebugFlag & DEBUG_WARN) { taosPrintLog("DND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} +#define dInfo(...) { if (dDebugFlag & DEBUG_INFO) { taosPrintLog("DND ", DEBUG_INFO, 255, __VA_ARGS__); }} +#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("DND ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} +#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("DND ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} + +#define dGFatal(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dFatal(param ", gtid:%s", __VA_ARGS__, buf);} +#define dGError(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dError(param ", gtid:%s", __VA_ARGS__, buf);} +#define dGWarn(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dWarn (param ", gtid:%s", __VA_ARGS__, buf);} +#define dGInfo(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dInfo (param ", gtid:%s", __VA_ARGS__, buf);} +#define dGDebug(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dDebug(param ", gtid:%s", __VA_ARGS__, buf);} +#define dGTrace(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); dTrace(param ", gtid:%s", __VA_ARGS__, buf);} + +// clang-format on typedef enum { DNODE = 0, @@ -185,4 +195,3 @@ void dmSetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet); #endif #endif /*_TD_DM_INT_H_*/ -// clang-format on diff --git a/source/dnode/mgmt/test/sut/src/sut.cpp b/source/dnode/mgmt/test/sut/src/sut.cpp index 6ef94481ea..21d9351ceb 100644 --- a/source/dnode/mgmt/test/sut/src/sut.cpp +++ b/source/dnode/mgmt/test/sut/src/sut.cpp @@ -102,6 +102,7 @@ int32_t Testbase::SendShowReq(int8_t showType, const char* tb, const char* db) { ASSERT(pRsp->pCont != nullptr); if (pRsp->contLen == 0) return -1; + if (pRsp->code != 0) return -1; showRsp = (SRetrieveMetaTableRsp*)pRsp->pCont; showRsp->handle = htobe64(showRsp->handle); // show Id diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 987b01b96a..0605e3a69e 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -349,6 +349,7 @@ typedef struct { int32_t commentLen; int32_t ast1Len; int32_t ast2Len; + SArray* pFuncs; SSchema* pColumns; SSchema* pTags; char* comment; @@ -420,7 +421,8 @@ typedef struct { int64_t uid; int64_t dbUid; int32_t version; - int8_t subType; // column, db or stable + int8_t subType; // column, db or stable + int8_t withMeta; // TODO SRWLatch lock; int32_t sqlLen; int32_t astLen; @@ -487,6 +489,7 @@ typedef struct { int64_t dbUid; int32_t vgNum; int8_t subType; + int8_t withMeta; int64_t stbUid; SHashObj* consumerHash; // consumerId -> SMqConsumerEp SArray* unassignedVgs; // SArray diff --git a/source/dnode/mnode/impl/inc/mndInfoSchema.h b/source/dnode/mnode/impl/inc/mndInfoSchema.h index 43d934c431..b10d92ee3d 100644 --- a/source/dnode/mnode/impl/inc/mndInfoSchema.h +++ b/source/dnode/mnode/impl/inc/mndInfoSchema.h @@ -25,6 +25,7 @@ extern "C" { int32_t mndInitInfos(SMnode *pMnode); void mndCleanupInfos(SMnode *pMnode); int32_t mndBuildInsTableSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp); +int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index c810a0cbc7..58266724a5 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -34,13 +34,21 @@ extern "C" { #endif // clang-format off -#define mFatal(...) { if (mDebugFlag & DEBUG_FATAL) { taosPrintLog("MND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} -#define mError(...) { if (mDebugFlag & DEBUG_ERROR) { taosPrintLog("MND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} -#define mWarn(...) { if (mDebugFlag & DEBUG_WARN) { taosPrintLog("MND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} -#define mInfo(...) { if (mDebugFlag & DEBUG_INFO) { taosPrintLog("MND ", DEBUG_INFO, 255, __VA_ARGS__); }} -#define mDebug(...) { if (mDebugFlag & DEBUG_DEBUG) { taosPrintLog("MND ", DEBUG_DEBUG, mDebugFlag, __VA_ARGS__); }} -#define mTrace(...) { if (mDebugFlag & DEBUG_TRACE) { taosPrintLog("MND ", DEBUG_TRACE, mDebugFlag, __VA_ARGS__); }} -#define mGTrace(param, ...) do { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mTrace(param ", GTID: %s", __VA_ARGS__, buf);} while(0) + + +#define mFatal(...) { if (mDebugFlag & DEBUG_FATAL) { taosPrintLog("MND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} +#define mError(...) { if (mDebugFlag & DEBUG_ERROR) { taosPrintLog("MND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} +#define mWarn(...) { if (mDebugFlag & DEBUG_WARN) { taosPrintLog("MND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} +#define mInfo(...) { if (mDebugFlag & DEBUG_INFO) { taosPrintLog("MND ", DEBUG_INFO, 255, __VA_ARGS__); }} +#define mDebug(...) { if (mDebugFlag & DEBUG_DEBUG) { taosPrintLog("MND ", DEBUG_DEBUG, mDebugFlag, __VA_ARGS__); }} +#define mTrace(...) { if (mDebugFlag & DEBUG_TRACE) { taosPrintLog("MND ", DEBUG_TRACE, mDebugFlag, __VA_ARGS__); }} + +#define mGFatal(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mFatal(param ", gtid:%s", __VA_ARGS__, buf);} +#define mGError(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mError(param ", gtid:%s", __VA_ARGS__, buf);} +#define mGWarn(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mWarn (param ", gtid:%s", __VA_ARGS__, buf);} +#define mGInfo(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mInfo (param ", gtid:%s", __VA_ARGS__, buf);} +#define mGDebug(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mDebug(param ", gtid:%s", __VA_ARGS__, buf);} +#define mGTrace(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); mTrace(param ", gtid:%s", __VA_ARGS__, buf);} // clang-format on @@ -70,7 +78,7 @@ typedef struct { typedef struct { SCacheObj *connCache; - SCacheObj *appCache; + SCacheObj *appCache; } SProfileMgmt; typedef struct { diff --git a/source/dnode/mnode/impl/inc/mndPerfSchema.h b/source/dnode/mnode/impl/inc/mndPerfSchema.h index 19f60229f9..87b4626e83 100644 --- a/source/dnode/mnode/impl/inc/mndPerfSchema.h +++ b/source/dnode/mnode/impl/inc/mndPerfSchema.h @@ -23,6 +23,7 @@ extern "C" { #endif int32_t mndBuildPerfsTableSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp); +int32_t mndBuildPerfsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp); int32_t mndInitPerfs(SMnode *pMnode); void mndCleanupPerfs(SMnode *pMnode); diff --git a/source/dnode/mnode/impl/inc/mndQnode.h b/source/dnode/mnode/impl/inc/mndQnode.h index 3e38565a4f..17615500c4 100644 --- a/source/dnode/mnode/impl/inc/mndQnode.h +++ b/source/dnode/mnode/impl/inc/mndQnode.h @@ -24,12 +24,12 @@ extern "C" { #define QNODE_LOAD_VALUE(pQnode) (pQnode ? (pQnode->load.numOfQueryInQueue + pQnode->load.numOfFetchInQueue) : 0) -int32_t mndInitQnode(SMnode *pMnode); -void mndCleanupQnode(SMnode *pMnode); - +int32_t mndInitQnode(SMnode *pMnode); +void mndCleanupQnode(SMnode *pMnode); SQnodeObj *mndAcquireQnode(SMnode *pMnode, int32_t qnodeId); -void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj); -int32_t mndCreateQnodeList(SMnode *pMnode, SArray** pList, int32_t limit); +void mndReleaseQnode(SMnode *pMnode, SQnodeObj *pObj); +int32_t mndCreateQnodeList(SMnode *pMnode, SArray **pList, int32_t limit); +int32_t mndSetDropQnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SQnodeObj *pObj); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndSnode.h b/source/dnode/mnode/impl/inc/mndSnode.h index 180f18a6dd..ec7bb02ca7 100644 --- a/source/dnode/mnode/impl/inc/mndSnode.h +++ b/source/dnode/mnode/impl/inc/mndSnode.h @@ -22,9 +22,12 @@ extern "C" { #endif -int32_t mndInitSnode(SMnode *pMnode); -void mndCleanupSnode(SMnode *pMnode); -SEpSet mndAcquireEpFromSnode(SMnode *pMnode, const SSnodeObj *pSnode); +int32_t mndInitSnode(SMnode *pMnode); +void mndCleanupSnode(SMnode *pMnode); +SSnodeObj *mndAcquireSnode(SMnode *pMnode, int32_t qnodeId); +void mndReleaseSnode(SMnode *pMnode, SSnodeObj *pObj); +SEpSet mndAcquireEpFromSnode(SMnode *pMnode, const SSnodeObj *pSnode); +int32_t mndSetDropSnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SSnodeObj *pObj); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndDef.c b/source/dnode/mnode/impl/src/mndDef.c index 20ba71992e..dc7f08ebc2 100644 --- a/source/dnode/mnode/impl/src/mndDef.c +++ b/source/dnode/mnode/impl/src/mndDef.c @@ -381,6 +381,7 @@ SMqSubscribeObj *tCloneSubscribeObj(const SMqSubscribeObj *pSub) { pSubNew->dbUid = pSub->dbUid; pSubNew->stbUid = pSub->stbUid; pSubNew->subType = pSub->subType; + pSubNew->withMeta = pSub->withMeta; pSubNew->vgNum = pSub->vgNum; pSubNew->consumerHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); @@ -414,6 +415,7 @@ int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) { tlen += taosEncodeFixedI64(buf, pSub->dbUid); tlen += taosEncodeFixedI32(buf, pSub->vgNum); tlen += taosEncodeFixedI8(buf, pSub->subType); + tlen += taosEncodeFixedI8(buf, pSub->withMeta); tlen += taosEncodeFixedI64(buf, pSub->stbUid); void *pIter = NULL; @@ -440,6 +442,7 @@ void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub) { buf = taosDecodeFixedI64(buf, &pSub->dbUid); buf = taosDecodeFixedI32(buf, &pSub->vgNum); buf = taosDecodeFixedI8(buf, &pSub->subType); + buf = taosDecodeFixedI8(buf, &pSub->withMeta); buf = taosDecodeFixedI64(buf, &pSub->stbUid); int32_t sz; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 58c3570c36..8d06868955 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -19,6 +19,7 @@ #include "mndMnode.h" #include "mndQnode.h" #include "mndShow.h" +#include "mndSnode.h" #include "mndTrans.h" #include "mndUser.h" #include "mndVgroup.h" @@ -370,7 +371,8 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) { SMnodeObj *pObj = mndAcquireMnode(pMnode, pDnode->id); if (pObj != NULL) { if (pObj->state != statusReq.mload.syncState) { - mInfo("dnode:%d, mnode syncstate from %s to %s", pObj->id, syncStr(pObj->state), syncStr(statusReq.mload.syncState)); + mInfo("dnode:%d, mnode syncstate from %s to %s", pObj->id, syncStr(pObj->state), + syncStr(statusReq.mload.syncState)); pObj->state = statusReq.mload.syncState; pObj->stateStartTime = taosGetTimestampMs(); } @@ -508,7 +510,7 @@ static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) { goto _OVER; } - mDebug("dnode:%s:%d, start to create", createReq.fqdn, createReq.port); + mInfo("dnode:%s:%d, start to create", createReq.fqdn, createReq.port); if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) { terrno = TSDB_CODE_MND_INVALID_DNODE_EP; @@ -538,7 +540,8 @@ _OVER: return code; } -static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, int32_t numOfVnodes) { +static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SMnodeObj *pMObj, SQnodeObj *pQObj, + SSnodeObj *pSObj, int32_t numOfVnodes) { int32_t code = -1; SSdbRaw *pRaw = NULL; STrans *pTrans = NULL; @@ -546,7 +549,7 @@ static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SM pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq); if (pTrans == NULL) goto _OVER; mndTransSetSerial(pTrans); - mDebug("trans:%d, used to drop dnode:%d", pTrans->id, pDnode->id); + mInfo("trans:%d, used to drop dnode:%d", pTrans->id, pDnode->id); pRaw = mndDnodeActionEncode(pDnode); if (pRaw == NULL || mndTransAppendRedolog(pTrans, pRaw) != 0) goto _OVER; @@ -559,11 +562,22 @@ static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SM pRaw = NULL; if (pMObj != NULL) { - mDebug("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id); + mInfo("trans:%d, mnode on dnode:%d will be dropped", pTrans->id, pDnode->id); if (mndSetDropMnodeInfoToTrans(pMnode, pTrans, pMObj) != 0) goto _OVER; } + + if (pQObj != NULL) { + mInfo("trans:%d, qnode on dnode:%d will be dropped", pTrans->id, pDnode->id); + if (mndSetDropQnodeInfoToTrans(pMnode, pTrans, pQObj) != 0) goto _OVER; + } + + if (pSObj != NULL) { + mInfo("trans:%d, snode on dnode:%d will be dropped", pTrans->id, pDnode->id); + if (mndSetDropSnodeInfoToTrans(pMnode, pTrans, pSObj) != 0) goto _OVER; + } + if (numOfVnodes > 0) { - mDebug("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id); + mInfo("trans:%d, %d vnodes on dnode:%d will be dropped", pTrans->id, numOfVnodes, pDnode->id); if (mndSetMoveVgroupsInfoToTrans(pMnode, pTrans, pDnode->id) != 0) goto _OVER; } if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; @@ -581,6 +595,8 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) { int32_t code = -1; SDnodeObj *pDnode = NULL; SMnodeObj *pMObj = NULL; + SQnodeObj *pQObj = NULL; + SSnodeObj *pSObj = NULL; SMDropMnodeReq dropReq = {0}; if (tDeserializeSCreateDropMQSBNodeReq(pReq->pCont, pReq->contLen, &dropReq) != 0) { @@ -588,7 +604,7 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) { goto _OVER; } - mDebug("dnode:%d, start to drop", dropReq.dnodeId); + mInfo("dnode:%d, start to drop", dropReq.dnodeId); if (dropReq.dnodeId <= 0) { terrno = TSDB_CODE_MND_INVALID_DNODE_ID; @@ -601,6 +617,8 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) { goto _OVER; } + pQObj = mndAcquireQnode(pMnode, dropReq.dnodeId); + pSObj = mndAcquireSnode(pMnode, dropReq.dnodeId); pMObj = mndAcquireMnode(pMnode, dropReq.dnodeId); if (pMObj != NULL) { if (sdbGetSize(pMnode->pSdb, SDB_MNODE) <= 1) { @@ -627,7 +645,7 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) { goto _OVER; } - code = mndDropDnode(pMnode, pReq, pDnode, pMObj, numOfVnodes); + code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; _OVER: @@ -637,6 +655,8 @@ _OVER: mndReleaseDnode(pMnode, pDnode); mndReleaseMnode(pMnode, pMObj); + mndReleaseQnode(pMnode, pQObj); + mndReleaseSnode(pMnode, pSObj); return code; } diff --git a/source/dnode/mnode/impl/src/mndInfoSchema.c b/source/dnode/mnode/impl/src/mndInfoSchema.c index c9bccaf1d0..45fefaf870 100644 --- a/source/dnode/mnode/impl/src/mndInfoSchema.c +++ b/source/dnode/mnode/impl/src/mndInfoSchema.c @@ -90,6 +90,38 @@ int32_t mndBuildInsTableSchema(SMnode *pMnode, const char *dbFName, const char * return 0; } +int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) { + if (NULL == pMnode->infosMeta) { + terrno = TSDB_CODE_MND_NOT_READY; + return -1; + } + + STableMetaRsp *pMeta = taosHashGet(pMnode->infosMeta, tbName, strlen(tbName)); + if (NULL == pMeta) { + mError("invalid information schema table name:%s", tbName); + terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + return -1; + } + + strcpy(pRsp->tbName, pMeta->tbName); + strcpy(pRsp->stbName, pMeta->stbName); + strcpy(pRsp->dbFName, pMeta->dbFName); + pRsp->numOfTags = pMeta->numOfTags; + pRsp->numOfColumns = pMeta->numOfColumns; + pRsp->tableType = pMeta->tableType; + + pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema)); + if (pRsp->pSchemas == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + pRsp->pSchemas = NULL; + return -1; + } + + memcpy(pRsp->pSchemas, pMeta->pSchemas, pMeta->numOfColumns * sizeof(SSchema)); + return 0; +} + + int32_t mndInitInfos(SMnode *pMnode) { pMnode->infosMeta = taosHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK); if (pMnode->infosMeta == NULL) { diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index b50781e8a5..675a3aa03f 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -59,22 +59,28 @@ static void *mndBuildTimerMsg(int32_t *pContLen) { static void mndPullupTrans(SMnode *pMnode) { int32_t contLen = 0; void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS_TIMER, .pCont = pReq, .contLen = contLen}; - tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); + if (pReq != NULL) { + SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS_TIMER, .pCont = pReq, .contLen = contLen}; + tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); + } } static void mndCalMqRebalance(SMnode *pMnode) { int32_t contLen = 0; void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_MQ_TIMER, .pCont = pReq, .contLen = contLen}; - tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); + if (pReq != NULL) { + SRpcMsg rpcMsg = {.msgType = TDMT_MND_MQ_TIMER, .pCont = pReq, .contLen = contLen}; + tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); + } } static void mndPullupTelem(SMnode *pMnode) { int32_t contLen = 0; void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_TELEM_TIMER, .pCont = pReq, .contLen = contLen}; - tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); + if (pReq != NULL) { + SRpcMsg rpcMsg = {.msgType = TDMT_MND_TELEM_TIMER, .pCont = pReq, .contLen = contLen}; + tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); + } } static void mndPushTtlTime(SMnode *pMnode) { @@ -89,10 +95,11 @@ static void mndPushTtlTime(SMnode *pMnode) { int32_t contLen = sizeof(SMsgHead) + sizeof(int32_t); SMsgHead *pHead = rpcMallocCont(contLen); if (pHead == NULL) { - mError("ttl time malloc err. contLen:%d", contLen); + sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pVgroup); continue; } + pHead->contLen = htonl(contLen); pHead->vgId = htonl(pVgroup->vgId); @@ -100,13 +107,13 @@ static void mndPushTtlTime(SMnode *pMnode) { *(int32_t *)(POINTER_SHIFT(pHead, sizeof(SMsgHead))) = htonl(t); SRpcMsg rpcMsg = {.msgType = TDMT_VND_DROP_TTL_TABLE, .pCont = pHead, .contLen = contLen}; - SEpSet epSet = mndGetVgroupEpset(pMnode, pVgroup); int32_t code = tmsgSendReq(&epSet, &rpcMsg); if (code != 0) { - mError("ttl time seed err. code:%d", code); + mError("failed to send ttl time seed msg, code:0x%x", code); + } else { + mInfo("send ttl time seed msg, time:%d", t); } - mError("ttl time seed succ. time:%d", t); sdbRelease(pSdb, pVgroup); } } @@ -117,11 +124,12 @@ static void *mndThreadFp(void *param) { setThreadName("mnode-timer"); while (1) { - if (lastTime % (864000) == 0) { // sleep 1 day for ttl + lastTime++; + + if (lastTime % (864000) == 0) { // sleep 1 day for ttl mndPushTtlTime(pMnode); } - lastTime++; taosMsleep(100); if (mndGetStop(pMnode)) break; @@ -549,25 +557,25 @@ int32_t mndProcessSyncMsg(SRpcMsg *pMsg) { static int32_t mndCheckMnodeState(SRpcMsg *pMsg) { if (!IsReq(pMsg)) return 0; if (mndAcquireRpcRef(pMsg->info.node) == 0) return 0; + if (pMsg->msgType == TDMT_MND_MQ_TIMER || pMsg->msgType == TDMT_MND_TELEM_TIMER || + pMsg->msgType == TDMT_MND_TRANS_TIMER) { + return -1; + } - if (IsReq(pMsg) && pMsg->msgType != TDMT_MND_MQ_TIMER && pMsg->msgType != TDMT_MND_TELEM_TIMER && - pMsg->msgType != TDMT_MND_TRANS_TIMER) { - mError("msg:%p, failed to check mnode state since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType)); + const STraceId *trace = &pMsg->info.traceId; + mGError("msg:%p, failed to check mnode state since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType)); - mndAbortPreprocessMsg(pMsg); + SEpSet epSet = {0}; + mndGetMnodeEpSet(pMsg->info.node, &epSet); - SEpSet epSet = {0}; - mndGetMnodeEpSet(pMsg->info.node, &epSet); - - int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet); - pMsg->info.rsp = rpcMallocCont(contLen); - if (pMsg->info.rsp != NULL) { - tSerializeSEpSet(pMsg->info.rsp, contLen, &epSet); - pMsg->info.rspLen = contLen; - terrno = TSDB_CODE_RPC_REDIRECT; - } else { - terrno = TSDB_CODE_OUT_OF_MEMORY; - } + int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet); + pMsg->info.rsp = rpcMallocCont(contLen); + if (pMsg->info.rsp != NULL) { + tSerializeSEpSet(pMsg->info.rsp, contLen, &epSet); + pMsg->info.rspLen = contLen; + terrno = TSDB_CODE_RPC_REDIRECT; + } else { + terrno = TSDB_CODE_OUT_OF_MEMORY; } return -1; @@ -577,17 +585,20 @@ static int32_t mndCheckMsgContent(SRpcMsg *pMsg) { if (!IsReq(pMsg)) return 0; if (pMsg->contLen != 0 && pMsg->pCont != NULL) return 0; - mError("msg:%p, failed to check msg, cont:%p contLen:%d, app:%p type:%s", pMsg, pMsg->pCont, pMsg->contLen, + const STraceId *trace = &pMsg->info.traceId; + mGError("msg:%p, failed to check msg, cont:%p contLen:%d, app:%p type:%s", pMsg, pMsg->pCont, pMsg->contLen, pMsg->info.ahandle, TMSG_INFO(pMsg->msgType)); terrno = TSDB_CODE_INVALID_MSG_LEN; return -1; } int32_t mndProcessRpcMsg(SRpcMsg *pMsg) { - SMnode *pMnode = pMsg->info.node; + SMnode *pMnode = pMsg->info.node; + const STraceId *trace = &pMsg->info.traceId; + MndMsgFp fp = pMnode->msgFp[TMSG_INDEX(pMsg->msgType)]; if (fp == NULL) { - mError("msg:%p, failed to get msg handle, app:%p type:%s", pMsg, pMsg->info.ahandle, TMSG_INFO(pMsg->msgType)); + mGError("msg:%p, failed to get msg handle, app:%p type:%s", pMsg, pMsg->info.ahandle, TMSG_INFO(pMsg->msgType)); terrno = TSDB_CODE_MSG_NOT_PROCESSED; return -1; } @@ -595,18 +606,17 @@ int32_t mndProcessRpcMsg(SRpcMsg *pMsg) { if (mndCheckMsgContent(pMsg) != 0) return -1; if (mndCheckMnodeState(pMsg) != 0) return -1; - STraceId *trace = &pMsg->info.traceId; mGTrace("msg:%p, start to process in mnode, app:%p type:%s", pMsg, pMsg->info.ahandle, TMSG_INFO(pMsg->msgType)); int32_t code = (*fp)(pMsg); mndReleaseRpcRef(pMnode); if (code == TSDB_CODE_ACTION_IN_PROGRESS) { - mTrace("msg:%p, won't response immediately since in progress", pMsg); + mGTrace("msg:%p, won't response immediately since in progress", pMsg); } else if (code == 0) { - mTrace("msg:%p, successfully processed", pMsg); + mGTrace("msg:%p, successfully processed", pMsg); } else { - mError("msg:%p, failed to process since %s, app:%p type:%s", pMsg, terrstr(), pMsg->info.ahandle, - TMSG_INFO(pMsg->msgType)); + mGError("msg:%p, failed to process since %s, app:%p type:%s", pMsg, terrstr(), pMsg->info.ahandle, + TMSG_INFO(pMsg->msgType)); } return code; @@ -622,7 +632,6 @@ void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp) { // Note: uid 0 is reserved int64_t mndGenerateUid(char *name, int32_t len) { int32_t hashval = MurmurHash3_32(name, len); - do { int64_t us = taosGetTimestampUs(); int64_t x = (us & 0x000000FFFFFFFFFF) << 24; diff --git a/source/dnode/mnode/impl/src/mndPerfSchema.c b/source/dnode/mnode/impl/src/mndPerfSchema.c index d7b2e3ec24..7056337c8d 100644 --- a/source/dnode/mnode/impl/src/mndPerfSchema.c +++ b/source/dnode/mnode/impl/src/mndPerfSchema.c @@ -92,6 +92,37 @@ int32_t mndBuildPerfsTableSchema(SMnode *pMnode, const char *dbFName, const char return 0; } +int32_t mndBuildPerfsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) { + if (NULL == pMnode->perfsMeta) { + terrno = TSDB_CODE_MND_NOT_READY; + return -1; + } + + STableMetaRsp *pMeta = taosHashGet(pMnode->perfsMeta, tbName, strlen(tbName)); + if (NULL == pMeta) { + mError("invalid performance schema table name:%s", tbName); + terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + return -1; + } + + strcpy(pRsp->tbName, pMeta->tbName); + strcpy(pRsp->stbName, pMeta->stbName); + strcpy(pRsp->dbFName, pMeta->dbFName); + pRsp->numOfTags = pMeta->numOfTags; + pRsp->numOfColumns = pMeta->numOfColumns; + pRsp->tableType = pMeta->tableType; + + pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema)); + if (pRsp->pSchemas == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + pRsp->pSchemas = NULL; + return -1; + } + + memcpy(pRsp->pSchemas, pMeta->pSchemas, pMeta->numOfColumns * sizeof(SSchema)); + return 0; +} + int32_t mndInitPerfs(SMnode *pMnode) { pMnode->perfsMeta = taosHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); if (pMnode->perfsMeta == NULL) { diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index fd80679316..832e328d96 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -122,30 +122,33 @@ static SConnObj *mndCreateConn(SMnode *pMnode, const char *user, int8_t connType int32_t pid, const char *app, int64_t startTime) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; - char connStr[255] = {0}; - int32_t len = snprintf(connStr, sizeof(connStr), "%s%d%d%d%s", user, ip, port, pid, app); + char connStr[255] = {0}; + int32_t len = snprintf(connStr, sizeof(connStr), "%s%d%d%d%s", user, ip, port, pid, app); uint32_t connId = mndGenerateUid(connStr, len); if (startTime == 0) startTime = taosGetTimestampMs(); - SConnObj connObj = {.id = connId, - .connType = connType, - .appStartTimeMs = startTime, - .pid = pid, - .ip = ip, - .port = port, - .killed = 0, - .loginTimeMs = taosGetTimestampMs(), - .lastAccessTimeMs = 0, - .killId = 0, - .numOfQueries = 0, - .pQueries = NULL}; + SConnObj connObj = { + .id = connId, + .connType = connType, + .appStartTimeMs = startTime, + .pid = pid, + .ip = ip, + .port = port, + .killed = 0, + .loginTimeMs = taosGetTimestampMs(), + .lastAccessTimeMs = 0, + .killId = 0, + .numOfQueries = 0, + .pQueries = NULL, + }; connObj.lastAccessTimeMs = connObj.loginTimeMs; tstrncpy(connObj.user, user, TSDB_USER_LEN); tstrncpy(connObj.app, app, TSDB_APP_NAME_LEN); int32_t keepTime = tsShellActivityTimer * 3; - SConnObj *pConn = taosCachePut(pMgmt->connCache, &connId, sizeof(uint32_t), &connObj, sizeof(connObj), keepTime * 1000); + SConnObj *pConn = + taosCachePut(pMgmt->connCache, &connId, sizeof(uint32_t), &connObj, sizeof(connObj), keepTime * 1000); if (pConn == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; mError("conn:%d, failed to put into cache since %s, user:%s", connId, user, terrstr()); @@ -174,7 +177,6 @@ static SConnObj *mndAcquireConn(SMnode *pMnode, uint32_t connId) { } pConn->lastAccessTimeMs = taosGetTimestampMs(); - mTrace("conn:%u, acquired from cache, data:%p", pConn->id, pConn); return pConn; } @@ -207,13 +209,14 @@ static void mndCancelGetNextConn(SMnode *pMnode, void *pIter) { } static int32_t mndProcessConnectReq(SRpcMsg *pReq) { - SMnode *pMnode = pReq->info.node; - SUserObj *pUser = NULL; - SDbObj *pDb = NULL; - SConnObj *pConn = NULL; - int32_t code = -1; - SConnectReq connReq = {0}; - char ip[30] = {0}; + SMnode *pMnode = pReq->info.node; + SUserObj *pUser = NULL; + SDbObj *pDb = NULL; + SConnObj *pConn = NULL; + int32_t code = -1; + SConnectReq connReq = {0}; + char ip[30] = {0}; + const STraceId *trace = &pReq->info.traceId; if (tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq) != 0) { terrno = TSDB_CODE_INVALID_MSG; @@ -224,11 +227,11 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { pUser = mndAcquireUser(pMnode, pReq->info.conn.user); if (pUser == NULL) { - mError("user:%s, failed to login while acquire user since %s", pReq->info.conn.user, terrstr()); + mGError("user:%s, failed to login while acquire user since %s", pReq->info.conn.user, terrstr()); goto CONN_OVER; } if (0 != strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1)) { - mError("user:%s, failed to auth while acquire user, input:%s", pReq->info.conn.user, connReq.passwd); + mGError("user:%s, failed to auth while acquire user, input:%s", pReq->info.conn.user, connReq.passwd); code = TSDB_CODE_RPC_AUTH_FAILURE; goto CONN_OVER; } @@ -239,8 +242,8 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { pDb = mndAcquireDb(pMnode, db); if (pDb == NULL) { terrno = TSDB_CODE_MND_INVALID_DB; - mError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db, - terrstr()); + mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db, + terrstr()); goto CONN_OVER; } } @@ -248,7 +251,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { 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) { - mError("user:%s, failed to login from %s while create connection since %s", pReq->info.conn.user, ip, terrstr()); + mGError("user:%s, failed to login from %s while create connection since %s", pReq->info.conn.user, ip, terrstr()); goto CONN_OVER; } @@ -273,7 +276,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { pReq->info.rspLen = contLen; pReq->info.rsp = pRsp; - mDebug("user:%s, login from %s:%d, conn:%u, app:%s", pReq->info.conn.user, ip, pConn->port, pConn->id, connReq.app); + mGDebug("user:%s, login from %s:%d, conn:%u, app:%s", pReq->info.conn.user, ip, pConn->port, pConn->id, connReq.app); code = 0; @@ -302,7 +305,7 @@ static int32_t mndSaveQueryList(SConnObj *pConn, SQueryHbReqBasic *pBasic) { return TSDB_CODE_SUCCESS; } -static SAppObj *mndCreateApp(SMnode *pMnode, uint32_t clientIp, SAppHbReq* pReq) { +static SAppObj *mndCreateApp(SMnode *pMnode, uint32_t clientIp, SAppHbReq *pReq) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; SAppObj app; @@ -314,22 +317,19 @@ static SAppObj *mndCreateApp(SMnode *pMnode, uint32_t clientIp, SAppHbReq* pReq) memcpy(&app.summary, &pReq->summary, sizeof(pReq->summary)); app.lastAccessTimeMs = taosGetTimestampMs(); - int32_t keepTime = tsShellActivityTimer * 3; + const int32_t keepTime = tsShellActivityTimer * 3; SAppObj *pApp = taosCachePut(pMgmt->appCache, &pReq->appId, sizeof(pReq->appId), &app, sizeof(app), keepTime * 1000); if (pApp == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; mError("failed to app %" PRIx64 " into cache since %s", pReq->appId, terrstr()); return NULL; } - + mTrace("app %" PRIx64 " is put into cache", pReq->appId); return pApp; } -static void mndFreeApp(SAppObj *pApp) { - mTrace("app %" PRIx64 " is destroyed", pApp->appId); -} - +static void mndFreeApp(SAppObj *pApp) { mTrace("app %" PRIx64 " is destroyed", pApp->appId); } static SAppObj *mndAcquireApp(SMnode *pMnode, int64_t appId) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; @@ -356,7 +356,7 @@ static void mndReleaseApp(SMnode *pMnode, SAppObj *pApp) { void *mndGetNextApp(SMnode *pMnode, SCacheIter *pIter) { SAppObj *pApp = NULL; - bool hasNext = taosCacheIterNext(pIter); + bool hasNext = taosCacheIterNext(pIter); if (hasNext) { size_t dataLen = 0; pApp = taosCacheIterGetData(pIter, &dataLen); @@ -439,16 +439,16 @@ static SClientHbRsp *mndMqHbBuildRsp(SMnode *pMnode, SClientHbReq *pReq) { } static int32_t mndUpdateAppInfo(SMnode *pMnode, SClientHbReq *pHbReq, SRpcConnInfo *connInfo) { - SAppHbReq* pReq = &pHbReq->app; - SAppObj *pApp = mndAcquireApp(pMnode, pReq->appId); + SAppHbReq *pReq = &pHbReq->app; + SAppObj *pApp = mndAcquireApp(pMnode, pReq->appId); if (pApp == NULL) { pApp = mndCreateApp(pMnode, connInfo->clientIp, pReq); if (pApp == NULL) { mError("failed to create new app %" PRIx64 " since %s", pReq->appId, terrstr()); return -1; } else { - mDebug("a new app %" PRIx64 "created", pReq->appId); - mndReleaseApp(pMnode, pApp); + mDebug("a new app %" PRIx64 " is created", pReq->appId); + mndReleaseApp(pMnode, pApp); return TSDB_CODE_SUCCESS; } } @@ -464,7 +464,7 @@ static int32_t mndProcessQueryHeartBeat(SMnode *pMnode, SRpcMsg *pMsg, SClientHb SClientHbBatchRsp *pBatchRsp) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; SClientHbRsp hbRsp = {.connKey = pHbReq->connKey, .status = 0, .info = NULL, .query = NULL}; - SRpcConnInfo connInfo = pMsg->info.conn; + SRpcConnInfo connInfo = pMsg->info.conn; mndUpdateAppInfo(pMnode, pHbReq, &connInfo); @@ -637,9 +637,9 @@ static int32_t mndProcessKillQueryReq(SRpcMsg *pReq) { } mInfo("kill query msg is received, queryId:%s", killReq.queryStrId); - int32_t connId = 0; + int32_t connId = 0; uint64_t queryId = 0; - char* p = strchr(killReq.queryStrId, ':'); + char *p = strchr(killReq.queryStrId, ':'); if (NULL == p) { mError("invalid query id %s", killReq.queryStrId); terrno = TSDB_CODE_MND_INVALID_QUERY_ID; @@ -853,12 +853,12 @@ static int32_t mndRetrieveQueries(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p } static int32_t mndRetrieveApps(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { - SMnode *pMnode = pReq->info.node; - SSdb *pSdb = pMnode->pSdb; - int32_t numOfRows = 0; - int32_t cols = 0; - SAppObj *pApp = NULL; - + SMnode *pMnode = pReq->info.node; + SSdb *pSdb = pMnode->pSdb; + int32_t numOfRows = 0; + int32_t cols = 0; + SAppObj *pApp = NULL; + if (pShow->pIter == NULL) { SProfileMgmt *pMgmt = &pMnode->profileMgmt; pShow->pIter = taosCacheCreateIter(pMgmt->appCache); @@ -931,7 +931,6 @@ static int32_t mndRetrieveApps(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo return numOfRows; } - static void mndCancelGetNextQuery(SMnode *pMnode, void *pIter) { if (pIter != NULL) { taosCacheDestroyIter(pIter); diff --git a/source/dnode/mnode/impl/src/mndQnode.c b/source/dnode/mnode/impl/src/mndQnode.c index f5625f32d5..0a6c97e63c 100644 --- a/source/dnode/mnode/impl/src/mndQnode.c +++ b/source/dnode/mnode/impl/src/mndQnode.c @@ -354,6 +354,14 @@ static int32_t mndSetDropQnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SQn return 0; } +int32_t mndSetDropQnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SQnodeObj *pObj) { + if (pObj == NULL) return 0; + if (mndSetDropQnodeRedoLogs(pTrans, pObj) != 0) return -1; + if (mndSetDropQnodeCommitLogs(pTrans, pObj) != 0) return -1; + if (mndSetDropQnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) return -1; + return 0; +} + static int32_t mndDropQnode(SMnode *pMnode, SRpcMsg *pReq, SQnodeObj *pObj) { int32_t code = -1; @@ -361,9 +369,7 @@ static int32_t mndDropQnode(SMnode *pMnode, SRpcMsg *pReq, SQnodeObj *pObj) { if (pTrans == NULL) goto _OVER; mDebug("trans:%d, used to drop qnode:%d", pTrans->id, pObj->id); - if (mndSetDropQnodeRedoLogs(pTrans, pObj) != 0) goto _OVER; - if (mndSetDropQnodeCommitLogs(pTrans, pObj) != 0) goto _OVER; - if (mndSetDropQnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) goto _OVER; + if (mndSetDropQnodeInfoToTrans(pMnode, pTrans, pObj) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; diff --git a/source/dnode/mnode/impl/src/mndQuery.c b/source/dnode/mnode/impl/src/mndQuery.c index f32a3129de..671152f9c6 100644 --- a/source/dnode/mnode/impl/src/mndQuery.c +++ b/source/dnode/mnode/impl/src/mndQuery.c @@ -18,16 +18,14 @@ #include "mndMnode.h" #include "qworker.h" -int32_t mndPreProcessMsg(SRpcMsg *pMsg) { +int32_t mndPreProcessQueryMsg(SRpcMsg *pMsg) { if (TDMT_VND_QUERY != pMsg->msgType) return 0; - SMnode *pMnode = pMsg->info.node; return qWorkerPreprocessQueryMsg(pMnode->pQuery, pMsg); } -void mndAbortPreprocessMsg(SRpcMsg *pMsg) { +void mndPostProcessQueryMsg(SRpcMsg *pMsg) { if (TDMT_VND_QUERY != pMsg->msgType) return; - SMnode *pMnode = pMsg->info.node; qWorkerAbortPreprocessQueryMsg(pMnode->pQuery, pMsg); } diff --git a/source/dnode/mnode/impl/src/mndSnode.c b/source/dnode/mnode/impl/src/mndSnode.c index 12188a3b3a..df1330197a 100644 --- a/source/dnode/mnode/impl/src/mndSnode.c +++ b/source/dnode/mnode/impl/src/mndSnode.c @@ -65,7 +65,7 @@ SEpSet mndAcquireEpFromSnode(SMnode *pMnode, const SSnodeObj *pSnode) { return epSet; } -static SSnodeObj *mndAcquireSnode(SMnode *pMnode, int32_t snodeId) { +SSnodeObj *mndAcquireSnode(SMnode *pMnode, int32_t snodeId) { SSnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_SNODE, &snodeId); if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) { terrno = TSDB_CODE_MND_SNODE_NOT_EXIST; @@ -73,7 +73,7 @@ static SSnodeObj *mndAcquireSnode(SMnode *pMnode, int32_t snodeId) { return pObj; } -static void mndReleaseSnode(SMnode *pMnode, SSnodeObj *pObj) { +void mndReleaseSnode(SMnode *pMnode, SSnodeObj *pObj) { SSdb *pSdb = pMnode->pSdb; sdbRelease(pSdb, pObj); } @@ -361,6 +361,14 @@ static int32_t mndSetDropSnodeRedoActions(STrans *pTrans, SDnodeObj *pDnode, SSn return 0; } +int32_t mndSetDropSnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SSnodeObj *pObj) { + if (pObj == NULL) return 0; + if (mndSetDropSnodeRedoLogs(pTrans, pObj) != 0) return -1; + if (mndSetDropSnodeCommitLogs(pTrans, pObj) != 0) return -1; + if (mndSetDropSnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) return -1; + return 0; +} + static int32_t mndDropSnode(SMnode *pMnode, SRpcMsg *pReq, SSnodeObj *pObj) { int32_t code = -1; @@ -368,10 +376,7 @@ static int32_t mndDropSnode(SMnode *pMnode, SRpcMsg *pReq, SSnodeObj *pObj) { if (pTrans == NULL) goto _OVER; mDebug("trans:%d, used to drop snode:%d", pTrans->id, pObj->id); - - if (mndSetDropSnodeRedoLogs(pTrans, pObj) != 0) goto _OVER; - if (mndSetDropSnodeCommitLogs(pTrans, pObj) != 0) goto _OVER; - if (mndSetDropSnodeRedoActions(pTrans, pObj->pDnode, pObj) != 0) goto _OVER; + if (mndSetDropSnodeInfoToTrans(pMnode, pTrans, pObj) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 3e50ea8262..e04662d22b 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -43,6 +43,7 @@ static int32_t mndProcessDropStbReq(SRpcMsg *pReq); static int32_t mndProcessTableMetaReq(SRpcMsg *pReq); static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); static void mndCancelGetNextStb(SMnode *pMnode, void *pIter); +static int32_t mndProcessTableCfgReq(SRpcMsg *pReq); int32_t mndInitStb(SMnode *pMnode) { SSdbTable table = { @@ -62,6 +63,7 @@ int32_t mndInitStb(SMnode *pMnode) { mndSetMsgHandle(pMnode, TDMT_VND_ALTER_STB_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_VND_DROP_STB_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq); + mndSetMsgHandle(pMnode, TDMT_MND_TABLE_CFG, mndProcessTableCfgReq); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb); mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb); @@ -75,7 +77,7 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) { terrno = TSDB_CODE_OUT_OF_MEMORY; int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + +pStb->commentLen + - pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE; + pStb->ast1Len + pStb->ast2Len + STB_RESERVE_SIZE + taosArrayGetSize(pStb->pFuncs) * TSDB_FUNC_NAME_LEN; SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, STB_VER_NUMBER, size); if (pRaw == NULL) goto _OVER; @@ -100,6 +102,13 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) { SDB_SET_INT32(pRaw, dataPos, pStb->ast1Len, _OVER) SDB_SET_INT32(pRaw, dataPos, pStb->ast2Len, _OVER) + int32_t funcNum = taosArrayGetSize(pStb->pFuncs); + SDB_SET_INT32(pRaw, dataPos, funcNum, _OVER) + for (int32_t i = 0; i < funcNum; ++i) { + char* func = taosArrayGet(pStb->pFuncs, i); + SDB_SET_BINARY(pRaw, dataPos, func, TSDB_FUNC_NAME_LEN, _OVER) + } + for (int32_t i = 0; i < pStb->numOfColumns; ++i) { SSchema *pSchema = &pStb->pColumns[i]; SDB_SET_INT8(pRaw, dataPos, pSchema->type, _OVER) @@ -181,6 +190,20 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) { SDB_GET_INT32(pRaw, dataPos, &pStb->ast1Len, _OVER) SDB_GET_INT32(pRaw, dataPos, &pStb->ast2Len, _OVER) + int32_t funcNum = 0; + SDB_GET_INT32(pRaw, dataPos, &funcNum, _OVER) + if (funcNum > 0) { + pStb->pFuncs = taosArrayInit(funcNum, TSDB_FUNC_NAME_LEN); + if (NULL == pStb->pFuncs) { + goto _OVER; + } + char funcName[TSDB_FUNC_NAME_LEN]; + for (int32_t i = 0; i < funcNum; ++i) { + SDB_GET_BINARY(pRaw, dataPos, funcName, TSDB_FUNC_NAME_LEN, _OVER) + taosArrayPush(pStb->pFuncs, funcName); + } + } + pStb->pColumns = taosMemoryCalloc(pStb->numOfColumns, sizeof(SSchema)); pStb->pTags = taosMemoryCalloc(pStb->numOfTags, sizeof(SSchema)); if (pStb->pColumns == NULL || pStb->pTags == NULL) { @@ -250,6 +273,7 @@ static int32_t mndStbActionDelete(SSdb *pSdb, SStbObj *pStb) { taosMemoryFreeClear(pStb->comment); taosMemoryFreeClear(pStb->pAst1); taosMemoryFreeClear(pStb->pAst2); + taosArrayDestroy(pStb->pFuncs); return 0; } @@ -680,6 +704,9 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat pDst->numOfColumns = pCreate->numOfColumns; pDst->numOfTags = pCreate->numOfTags; pDst->commentLen = pCreate->commentLen; + pDst->pFuncs = pCreate->pFuncs; + pCreate->pFuncs = NULL; + if (pDst->commentLen > 0) { pDst->comment = taosMemoryCalloc(pDst->commentLen + 1, 1); if (pDst->comment == NULL) { @@ -1277,6 +1304,60 @@ static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbNa return 0; } +static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableCfgRsp *pRsp) { + taosRLockLatch(&pStb->lock); + + int32_t totalCols = pStb->numOfColumns + pStb->numOfTags; + pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema)); + if (pRsp->pSchemas == NULL) { + taosRUnLockLatch(&pStb->lock); + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + strcpy(pRsp->dbFName, pStb->db); + strcpy(pRsp->tbName, tbName); + strcpy(pRsp->stbName, tbName); + pRsp->numOfTags = pStb->numOfTags; + pRsp->numOfColumns = pStb->numOfColumns; + pRsp->tableType = TSDB_SUPER_TABLE; + pRsp->delay1 = pStb->maxdelay[0]; + pRsp->delay2 = pStb->maxdelay[1]; + pRsp->watermark1 = pStb->watermark[0]; + pRsp->watermark2 = pStb->watermark[1]; + pRsp->ttl = pStb->ttl; + pRsp->commentLen = pStb->commentLen; + if (pStb->commentLen > 0) { + pRsp->pComment = strdup(pStb->comment); + } + + for (int32_t i = 0; i < pStb->numOfColumns; ++i) { + SSchema *pSchema = &pRsp->pSchemas[i]; + SSchema *pSrcSchema = &pStb->pColumns[i]; + memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN); + pSchema->type = pSrcSchema->type; + pSchema->colId = pSrcSchema->colId; + pSchema->bytes = pSrcSchema->bytes; + } + + for (int32_t i = 0; i < pStb->numOfTags; ++i) { + SSchema *pSchema = &pRsp->pSchemas[i + pStb->numOfColumns]; + SSchema *pSrcSchema = &pStb->pTags[i]; + memcpy(pSchema->name, pSrcSchema->name, TSDB_COL_NAME_LEN); + pSchema->type = pSrcSchema->type; + pSchema->colId = pSrcSchema->colId; + pSchema->bytes = pSrcSchema->bytes; + } + + if (pStb->pFuncs) { + pRsp->pFuncs = taosArrayDup(pStb->pFuncs); + } + + taosRUnLockLatch(&pStb->lock); + return 0; +} + + static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char *tbName, STableMetaRsp *pRsp, int32_t *smaVer) { char tbFName[TSDB_TABLE_FNAME_LEN] = {0}; @@ -1305,6 +1386,32 @@ static int32_t mndBuildStbSchema(SMnode *pMnode, const char *dbFName, const char return code; } +static int32_t mndBuildStbCfg(SMnode *pMnode, const char *dbFName, const char *tbName, STableCfgRsp *pRsp) { + char tbFName[TSDB_TABLE_FNAME_LEN] = {0}; + snprintf(tbFName, sizeof(tbFName), "%s.%s", dbFName, tbName); + + SDbObj *pDb = mndAcquireDb(pMnode, dbFName); + if (pDb == NULL) { + terrno = TSDB_CODE_MND_DB_NOT_SELECTED; + return -1; + } + + SStbObj *pStb = mndAcquireStb(pMnode, tbFName); + if (pStb == NULL) { + mndReleaseDb(pMnode, pDb); + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; + return -1; + } + + int32_t code = mndBuildStbCfgImp(pDb, pStb, tbName, pRsp); + + mndReleaseDb(pMnode, pDb); + mndReleaseStb(pMnode, pStb); + return code; +} + + + static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, const SMAlterStbReq *pAlter, SStbObj *pObj, void **pCont, int32_t *pLen) { int32_t ret; @@ -1664,6 +1771,63 @@ _OVER: return code; } +static int32_t mndProcessTableCfgReq(SRpcMsg *pReq) { + SMnode *pMnode = pReq->info.node; + int32_t code = -1; + STableCfgReq cfgReq = {0}; + STableCfgRsp cfgRsp = {0}; + + if (tDeserializeSTableCfgReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) { + terrno = TSDB_CODE_INVALID_MSG; + goto _OVER; + } + + if (0 == strcmp(cfgReq.dbFName, TSDB_INFORMATION_SCHEMA_DB)) { + mDebug("information_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName); + if (mndBuildInsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) { + goto _OVER; + } + } else if (0 == strcmp(cfgReq.dbFName, TSDB_PERFORMANCE_SCHEMA_DB)) { + mDebug("performance_schema table:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName); + if (mndBuildPerfsTableCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) { + goto _OVER; + } + } else { + mDebug("stb:%s.%s, start to retrieve cfg", cfgReq.dbFName, cfgReq.tbName); + if (mndBuildStbCfg(pMnode, cfgReq.dbFName, cfgReq.tbName, &cfgRsp) != 0) { + goto _OVER; + } + } + + int32_t rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp); + if (rspLen < 0) { + terrno = TSDB_CODE_INVALID_MSG; + goto _OVER; + } + + void *pRsp = rpcMallocCont(rspLen); + if (pRsp == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + tSerializeSTableCfgRsp(pRsp, rspLen, &cfgRsp); + pReq->info.rsp = pRsp; + pReq->info.rspLen = rspLen; + code = 0; + + mTrace("%s.%s, cfg is retrieved", cfgReq.dbFName, cfgReq.tbName); + +_OVER: + if (code != 0) { + mError("stb:%s.%s, failed to retrieve cfg since %s", cfgReq.dbFName, cfgReq.tbName, terrstr()); + } + + tFreeSTableCfgRsp(&cfgRsp); + return code; +} + + int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t numOfStbs, void **ppRsp, int32_t *pRspLen) { SSTbHbRsp hbRsp = {0}; diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index fb92efecf6..7e9069d5fc 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -54,9 +54,10 @@ int32_t mndInitStream(SMnode *pMnode) { }; mndSetMsgHandle(pMnode, TDMT_MND_CREATE_STREAM, mndProcessCreateStreamReq); - mndSetMsgHandle(pMnode, TDMT_STREAM_TASK_DEPLOY_RSP, mndTransProcessRsp); mndSetMsgHandle(pMnode, TDMT_MND_DROP_STREAM, mndProcessDropStreamReq); - mndSetMsgHandle(pMnode, TDMT_MND_DROP_STREAM_RSP, mndTransProcessRsp); + + mndSetMsgHandle(pMnode, TDMT_STREAM_TASK_DEPLOY_RSP, mndTransProcessRsp); + mndSetMsgHandle(pMnode, TDMT_STREAM_TASK_DROP_RSP, mndTransProcessRsp); mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STREAMS, mndRetrieveStream); mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STREAMS, mndCancelGetNextStream); @@ -477,7 +478,7 @@ static int32_t mndPersistTaskDropReq(STrans *pTrans, SStreamTask *pTask) { memcpy(&action.epSet, &pTask->epSet, sizeof(SEpSet)); action.pCont = pReq; action.contLen = sizeof(SVDropStreamTaskReq); - action.msgType = TDMT_VND_STREAM_TASK_DROP; + action.msgType = TDMT_STREAM_TASK_DROP; if (mndTransAppendRedoAction(pTrans, &action) != 0) { taosMemoryFree(pReq); return -1; @@ -670,20 +671,24 @@ _OVER: static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; - int32_t code = -1; SStreamObj *pStream = NULL; /*SDbObj *pDb = NULL;*/ /*SUserObj *pUser = NULL;*/ - SMDropStreamReq dropReq = *(SMDropStreamReq *)pReq->pCont; + SMDropStreamReq dropReq = {0}; + if (tDeserializeSMDropStreamReq(pReq->pCont, pReq->contLen, &dropReq) < 0) { + ASSERT(0); + terrno = TSDB_CODE_INVALID_MSG; + return -1; + } pStream = mndAcquireStream(pMnode, dropReq.name); if (pStream == NULL) { if (dropReq.igNotExists) { mDebug("stream:%s, not exist, ignore not exist is set", dropReq.name); - code = 0; - goto DROP_STREAM_OVER; + sdbRelease(pMnode->pSdb, pStream); + return -1; } else { terrno = TSDB_CODE_MND_STREAM_NOT_EXIST; return -1; @@ -701,14 +706,16 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq); if (pTrans == NULL) { mError("stream:%s, failed to drop since %s", dropReq.name, terrstr()); - return code; + sdbRelease(pMnode->pSdb, pStream); + return -1; } mDebug("trans:%d, used to drop stream:%s", pTrans->id, dropReq.name); // drop all tasks if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) { mError("stream:%s, failed to drop task since %s", dropReq.name, terrstr()); - return code; + sdbRelease(pMnode->pSdb, pStream); + return -1; } // drop stream @@ -717,8 +724,16 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) { return -1; } -DROP_STREAM_OVER: - return code; + if (mndTransPrepare(pMnode, pTrans) != 0) { + mError("trans:%d, failed to prepare drop stream trans since %s", pTrans->id, terrstr()); + sdbRelease(pMnode->pSdb, pStream); + mndTransDrop(pTrans); + return -1; + } + + sdbRelease(pMnode->pSdb, pStream); + + return TSDB_CODE_ACTION_IN_PROGRESS; } int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) { diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c index d2b7a61e83..8dde3e92d8 100644 --- a/source/dnode/mnode/impl/src/mndSubscribe.c +++ b/source/dnode/mnode/impl/src/mndSubscribe.c @@ -96,6 +96,7 @@ static SMqSubscribeObj *mndCreateSub(SMnode *pMnode, const SMqTopicObj *pTopic, pSub->dbUid = pTopic->dbUid; pSub->stbUid = pTopic->stbUid; pSub->subType = pTopic->subType; + pSub->withMeta = pTopic->withMeta; ASSERT(pSub->unassignedVgs->size == 0); ASSERT(taosHashGetSize(pSub->consumerHash) == 0); @@ -120,6 +121,7 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri req.vgId = pRebVg->pVgEp->vgId; req.qmsg = pRebVg->pVgEp->qmsg; req.subType = pSub->subType; + req.withMeta = pSub->withMeta; req.suid = pSub->stbUid; strncpy(req.subKey, pSub->key, TSDB_SUBSCRIBE_KEY_LEN); diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 07f65b2a90..e3358b41df 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -75,12 +75,10 @@ void mndSyncCommitMsg(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbM } int32_t mndSyncGetSnapshot(struct SSyncFSM *pFsm, SSnapshot *pSnapshot, void *pReaderParam, void **ppReader) { - // TODO: - - // atomic operation - // step1. sdbGetCommitInfo - // step2. create ppReader with pReaderParam - + mDebug("start to read snapshot from sdb in atomic way"); + SMnode *pMnode = pFsm->data; + return sdbStartRead(pMnode->pSdb, (SSdbIter **)ppReader, &pSnapshot->lastApplyIndex, &pSnapshot->lastApplyTerm, + &pSnapshot->lastConfigIndex); return 0; } @@ -98,7 +96,7 @@ void mndRestoreFinish(struct SSyncFSM *pFsm) { mndTransPullup(pMnode); mndSetRestore(pMnode, true); } else { - mInfo("mnode sync restore finished, and will set ready after first deploy"); + mInfo("mnode sync restore finished"); } } @@ -106,14 +104,6 @@ void mndReConfig(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SReConfigCbMeta cbM SMnode *pMnode = pFsm->data; SSyncMgmt *pMgmt = &pMnode->syncMgmt; -#if 0 -// send response - SRpcMsg rpcMsg = {.msgType = pMsg->msgType, .contLen = pMsg->contLen, .conn.applyIndex = cbMeta.index}; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - memcpy(rpcMsg.pCont, pMsg->pCont, pMsg->contLen); - syncGetAndDelRespRpc(pMnode->syncMgmt.sync, cbMeta.seqNum, &rpcMsg.info); -#endif - pMgmt->errCode = cbMeta.code; mInfo("trans:-1, sync reconfig is proposed, saved:%d code:0x%x, index:%" PRId64 " term:%" PRId64, pMgmt->transId, cbMeta.code, cbMeta.index, cbMeta.term); @@ -128,13 +118,13 @@ void mndReConfig(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SReConfigCbMeta cbM } int32_t mndSnapshotStartRead(struct SSyncFSM *pFsm, void **ppReader) { - mInfo("start to read snapshot from sdb"); + mDebug("start to read snapshot from sdb"); SMnode *pMnode = pFsm->data; - return sdbStartRead(pMnode->pSdb, (SSdbIter **)ppReader); + return sdbStartRead(pMnode->pSdb, (SSdbIter **)ppReader, NULL, NULL, NULL); } int32_t mndSnapshotStopRead(struct SSyncFSM *pFsm, void *pReader) { - mInfo("stop to read snapshot from sdb"); + mDebug("stop to read snapshot from sdb"); SMnode *pMnode = pFsm->data; return sdbStopRead(pMnode->pSdb, pReader); } diff --git a/source/dnode/mnode/impl/src/mndTopic.c b/source/dnode/mnode/impl/src/mndTopic.c index 9632c04f4c..a650ed29f1 100644 --- a/source/dnode/mnode/impl/src/mndTopic.c +++ b/source/dnode/mnode/impl/src/mndTopic.c @@ -141,6 +141,7 @@ SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic) { SDB_SET_INT64(pRaw, dataPos, pTopic->dbUid, TOPIC_ENCODE_OVER); SDB_SET_INT32(pRaw, dataPos, pTopic->version, TOPIC_ENCODE_OVER); SDB_SET_INT8(pRaw, dataPos, pTopic->subType, TOPIC_ENCODE_OVER); + SDB_SET_INT8(pRaw, dataPos, pTopic->withMeta, TOPIC_ENCODE_OVER); SDB_SET_INT64(pRaw, dataPos, pTopic->stbUid, TOPIC_ENCODE_OVER); SDB_SET_INT32(pRaw, dataPos, pTopic->sqlLen, TOPIC_ENCODE_OVER); @@ -208,6 +209,7 @@ SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw) { SDB_GET_INT64(pRaw, dataPos, &pTopic->dbUid, TOPIC_DECODE_OVER); SDB_GET_INT32(pRaw, dataPos, &pTopic->version, TOPIC_DECODE_OVER); SDB_GET_INT8(pRaw, dataPos, &pTopic->subType, TOPIC_DECODE_OVER); + SDB_GET_INT8(pRaw, dataPos, &pTopic->withMeta, TOPIC_DECODE_OVER); SDB_GET_INT64(pRaw, dataPos, &pTopic->stbUid, TOPIC_DECODE_OVER); SDB_GET_INT32(pRaw, dataPos, &pTopic->sqlLen, TOPIC_DECODE_OVER); @@ -357,6 +359,10 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq * topicObj.sql = strdup(pCreate->sql); topicObj.sqlLen = strlen(pCreate->sql) + 1; topicObj.subType = pCreate->subType; + topicObj.withMeta = pCreate->withMeta; + if (topicObj.withMeta) { + ASSERT(topicObj.subType != TOPIC_SUB_TYPE__COLUMN); + } if (pCreate->subType == TOPIC_SUB_TYPE__COLUMN) { topicObj.ast = strdup(pCreate->ast); diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index de6a44d456..eec108414e 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -432,11 +432,11 @@ static const char *mndTransStr(ETrnStage stage) { } static void mndTransTestStartFunc(SMnode *pMnode, void *param, int32_t paramLen) { - mInfo("test trans start, param:%s, len:%d", (char *)param, paramLen); + mDebug("test trans start, param:%s, len:%d", (char *)param, paramLen); } static void mndTransTestStopFunc(SMnode *pMnode, void *param, int32_t paramLen) { - mInfo("test trans stop, param:%s, len:%d", (char *)param, paramLen); + mDebug("test trans stop, param:%s, len:%d", (char *)param, paramLen); } static TransCbFp mndTransGetCbFp(ETrnFunc ftype) { diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index 94ddbcd409..696e714a8c 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -1017,6 +1017,11 @@ int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, if (mndAddDropVnodeAction(pMnode, pTrans, pDb, &newVg, &del, true) != 0) return -1; if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg) != 0) return -1; + SSdbRaw *pRaw = mndVgroupActionEncode(&newVg); + if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) return -1; + sdbSetRawStatus(pRaw, SDB_STATUS_READY); + pRaw = NULL; + mInfo("vgId:%d, vgroup info after move, replica:%d", newVg.vgId, newVg.replica); for (int32_t i = 0; i < newVg.replica; ++i) { mInfo("vgId:%d, vnode:%d dnode:%d", newVg.vgId, i, newVg.vnodeGid[i].dnodeId); @@ -1025,6 +1030,7 @@ int32_t mndSetMoveVgroupInfoToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, } int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t delDnodeId) { + int32_t code = 0; SArray *pArray = mndBuildDnodesArray(pMnode, delDnodeId); if (pArray == NULL) return -1; @@ -1042,18 +1048,24 @@ int32_t mndSetMoveVgroupsInfoToTrans(SMnode *pMnode, STrans *pTrans, int32_t del } } + code = 0; if (vnIndex != -1) { mInfo("vgId:%d, vnode:%d will be removed from dnode:%d", pVgroup->vgId, vnIndex, delDnodeId); SDbObj *pDb = mndAcquireDb(pMnode, pVgroup->dbName); - mndSetMoveVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, vnIndex, pArray); + code = mndSetMoveVgroupInfoToTrans(pMnode, pTrans, pDb, pVgroup, vnIndex, pArray); mndReleaseDb(pMnode, pDb); } sdbRelease(pMnode->pSdb, pVgroup); + + if (code != 0) { + sdbCancelFetch(pMnode->pSdb, pIter); + break; + } } taosArrayDestroy(pArray); - return 0; + return code; } static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, diff --git a/source/dnode/mnode/impl/test/sdb/sdbTest.cpp b/source/dnode/mnode/impl/test/sdb/sdbTest.cpp index bc118ee26e..87895d3b49 100644 --- a/source/dnode/mnode/impl/test/sdb/sdbTest.cpp +++ b/source/dnode/mnode/impl/test/sdb/sdbTest.cpp @@ -910,7 +910,7 @@ TEST_F(MndTestSdb, 01_Read_Str) { int32_t len = 0; int32_t code = 0; - code = sdbStartRead(pSdb, &pReader); + code = sdbStartRead(pSdb, &pReader, NULL, NULL, NULL); ASSERT_EQ(code, 0); code = sdbStartWrite(pSdb, &pWritter); ASSERT_EQ(code, 0); diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h index 3b1c4000a8..1294f0cff3 100644 --- a/source/dnode/mnode/sdb/inc/sdb.h +++ b/source/dnode/mnode/sdb/inc/sdb.h @@ -388,7 +388,7 @@ SSdbRow *sdbAllocRow(int32_t objSize); void *sdbGetRowObj(SSdbRow *pRow); void sdbFreeRow(SSdb *pSdb, SSdbRow *pRow, bool callFunc); -int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter); +int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config); int32_t sdbStopRead(SSdb *pSdb, SSdbIter *pIter); int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len); diff --git a/source/dnode/mnode/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c index 0f4e1276c1..ff4a9e4ead 100644 --- a/source/dnode/mnode/sdb/src/sdbFile.c +++ b/source/dnode/mnode/sdb/src/sdbFile.c @@ -519,11 +519,11 @@ static void sdbCloseIter(SSdbIter *pIter) { pIter->name = NULL; } - mInfo("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total); + mDebug("sdbiter:%p, is closed, total:%" PRId64, pIter, pIter->total); taosMemoryFree(pIter); } -int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter) { +int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *term, int64_t *config) { SSdbIter *pIter = sdbCreateIter(pSdb); if (pIter == NULL) return -1; @@ -552,7 +552,11 @@ int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter) { } *ppIter = pIter; - mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s", + if (index != NULL) *index = commitIndex; + if (term != NULL) *term = commitTerm; + if (config != NULL) *config = commitConfig; + + mDebug("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s", pIter, commitIndex, commitTerm, commitConfig, pIter->name); return 0; } @@ -579,14 +583,14 @@ int32_t sdbDoRead(SSdb *pSdb, SSdbIter *pIter, void **ppBuf, int32_t *len) { taosMemoryFree(pBuf); return -1; } else if (readlen == 0) { - mInfo("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total); + mDebug("sdbiter:%p, read snapshot to the end, total:%" PRId64, pIter, pIter->total); *ppBuf = NULL; *len = 0; taosMemoryFree(pBuf); return 0; } else { // (readlen <= maxlen) pIter->total += readlen; - mInfo("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total); + mDebug("sdbiter:%p, read:%d bytes from snapshot, total:%" PRId64, pIter, readlen, pIter->total); *ppBuf = pBuf; *len = readlen; return 0; @@ -605,7 +609,7 @@ int32_t sdbStartWrite(SSdb *pSdb, SSdbIter **ppIter) { } *ppIter = pIter; - mInfo("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name); + mDebug("sdbiter:%p, is created to write snapshot, file:%s", pIter, pIter->name); return 0; } @@ -614,7 +618,7 @@ int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply) { if (!isApply) { sdbCloseIter(pIter); - mInfo("sdbiter:%p, not apply to sdb", pIter); + mDebug("sdbiter:%p, not apply to sdb", pIter); return 0; } @@ -637,7 +641,7 @@ int32_t sdbStopWrite(SSdb *pSdb, SSdbIter *pIter, bool isApply) { return -1; } - mInfo("sdbiter:%p, successfully applyed to sdb", pIter); + mDebug("sdbiter:%p, successfully applyed to sdb", pIter); return 0; } @@ -650,6 +654,6 @@ int32_t sdbDoWrite(SSdb *pSdb, SSdbIter *pIter, void *pBuf, int32_t len) { } pIter->total += writelen; - mInfo("sdbiter:%p, write:%d bytes to snapshot, total:%" PRId64, pIter, writelen, pIter->total); + mDebug("sdbiter:%p, write:%d bytes to snapshot, total:%" PRId64, pIter, writelen, pIter->total); return 0; } \ No newline at end of file diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 84a66c680b..c2c4ea3a88 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -92,7 +92,7 @@ static int32_t sndProcessTaskDeployReq(SSnode *pNode, SRpcMsg *pMsg) { } tDecoderClear(&decoder); - pTask->status = TASK_STATUS__IDLE; + pTask->execStatus = TASK_EXEC_STATUS__IDLE; pTask->inputQueue = streamQueueOpen(); pTask->outputQueue = streamQueueOpen(); @@ -205,7 +205,7 @@ int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg) { switch (pMsg->msgType) { case TDMT_STREAM_TASK_DEPLOY: return sndProcessTaskDeployReq(pSnode, pMsg); - case TDMT_VND_STREAM_TASK_DROP: + case TDMT_STREAM_TASK_DROP: return sndProcessTaskDropReq(pSnode, pMsg); default: ASSERT(0); diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 2ee0673ce5..8f6077e996 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -114,6 +114,7 @@ typedef struct { char subKey[TSDB_SUBSCRIBE_KEY_LEN]; int64_t consumerId; int32_t epoch; + int8_t fetchMeta; // reader SWalReadHandle* pWalReader; diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h index 9339402d43..32be479116 100644 --- a/source/dnode/vnode/src/inc/vnd.h +++ b/source/dnode/vnode/src/inc/vnd.h @@ -32,7 +32,14 @@ extern "C" { #define vInfo(...) do { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("VND ", DEBUG_INFO, 255, __VA_ARGS__); }} while(0) #define vDebug(...) do { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", DEBUG_DEBUG, vDebugFlag, __VA_ARGS__); }} while(0) #define vTrace(...) do { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", DEBUG_TRACE, vDebugFlag, __VA_ARGS__); }} while(0) -#define vGTrace(param, ...) do { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vTrace(param " GTID: %s", __VA_ARGS__, buf);} while(0)//#define vDye(...) do + +#define vGTrace(param, ...) do { if (vDebugFlag & DEBUG_TRACE) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vTrace(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define vGFatal(param, ...) do { if (vDebugFlag & DEBUG_FATAL) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vFatal(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define vGError(param, ...) do { if (vDebugFlag & DEBUG_ERROR) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vError(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define vGWarn(param, ...) do { if (vDebugFlag & DEBUG_WARN) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vWarn(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define vGInfo(param, ...) do { if (vDebugFlag & DEBUG_INFO) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vInfo(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define vGDebug(param, ...) do { if (vDebugFlag & DEBUG_DEBUG) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vDebug(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) + // clang-format on // vnodeCfg.c @@ -71,6 +78,7 @@ void vnodeBufPoolReset(SVBufPool* pPool); int32_t vnodeQueryOpen(SVnode* pVnode); void vnodeQueryClose(SVnode* pVnode); int32_t vnodeGetTableMeta(SVnode* pVnode, SRpcMsg* pMsg); +int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg); // vnodeCommit.c int32_t vnodeBegin(SVnode* pVnode); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index ece4b7e2a4..3ce02dc50a 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -85,6 +85,34 @@ void tqClose(STQ* pTq) { } } +int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) { + int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqMetaRsp(NULL, pRsp); + void* buf = rpcMallocCont(tlen); + if (buf == NULL) { + return -1; + } + + ((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_META_RSP; + ((SMqRspHead*)buf)->epoch = pReq->epoch; + ((SMqRspHead*)buf)->consumerId = pReq->consumerId; + + void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead)); + tEncodeSMqMetaRsp(&abuf, pRsp); + + SRpcMsg resp = { + .info = pMsg->info, + .pCont = buf, + .contLen = tlen, + .code = 0, + }; + tmsgSendRsp(&resp); + + tqDebug("vg %d from consumer %ld (epoch %d) send rsp, res msg type %d, reqOffset: %ld, rspOffset: %ld", + TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->resMsgType, pRsp->reqOffset, pRsp->rspOffset); + + return 0; +} + int32_t tqSendPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataBlkRsp* pRsp) { int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, pRsp); void* buf = rpcMallocCont(tlen); @@ -250,8 +278,23 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) { /*ASSERT(0);*/ } } else { - // TODO - ASSERT(0); + ASSERT(pHandle->fetchMeta); + ASSERT(pHead->msgType == TDMT_VND_CREATE_STB || pHead->msgType == TDMT_VND_ALTER_STB || + pHead->msgType == TDMT_VND_DROP_STB || pHead->msgType == TDMT_VND_CREATE_TABLE || + pHead->msgType == TDMT_VND_ALTER_TABLE || pHead->msgType == TDMT_VND_DROP_TABLE || + pHead->msgType == TDMT_VND_DROP_TTL_TABLE); + // return + SMqMetaRsp metaRsp = {0}; + metaRsp.reqOffset = pReq->currentOffset; + metaRsp.rspOffset = fetchOffset; + metaRsp.resMsgType = pHead->msgType; + metaRsp.metaRspLen = pHead->bodyLen; + metaRsp.metaRsp = pHead->body; + if (tqSendMetaPollRsp(pTq, pMsg, pReq, &metaRsp) < 0) { + code = -1; + } + code = 0; + goto OVER; } // TODO batch optimization: @@ -276,7 +319,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) { if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) { code = -1; } - +OVER: // TODO wrap in destroy func taosArrayDestroy(rsp.blockDataLen); taosArrayDestroyP(rsp.blockData, (FDelete)taosMemoryFree); @@ -384,7 +427,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, char* msg, int32_t msgLen) { } tDecoderClear(&decoder); - pTask->status = TASK_STATUS__IDLE; + pTask->execStatus = TASK_EXEC_STATUS__IDLE; pTask->inputQueue = streamQueueOpen(); pTask->outputQueue = streamQueueOpen(); @@ -459,6 +502,9 @@ int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) { pIter = taosHashIterate(pTq->pStreamTasks, pIter); if (pIter == NULL) break; SStreamTask* pTask = *(SStreamTask**)pIter; + if (atomic_load_8(&pTask->taskStatus) == TASK_STATUS__DROPPING) { + continue; + } if (pTask->inputType != STREAM_INPUT__DATA_SUBMIT) continue; if (!failed) { @@ -487,6 +533,9 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRunReq* pReq = pMsg->pCont; int32_t taskId = pReq->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); + if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + return 0; + } streamProcessRunReq(pTask); return 0; } @@ -501,9 +550,12 @@ int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg) { tDecodeStreamDispatchReq(&decoder, &req); int32_t taskId = req.taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - SRpcMsg rsp = { - .info = pMsg->info, - .code = 0, + if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + return 0; + } + SRpcMsg rsp = { + .info = pMsg->info, + .code = 0, }; streamProcessDispatchReq(pTask, &req, &rsp); return 0; @@ -513,6 +565,9 @@ int32_t tqProcessTaskRecoverReq(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRecoverReq* pReq = pMsg->pCont; int32_t taskId = pReq->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); + if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + return 0; + } streamProcessRecoverReq(pTask, pReq, pMsg); return 0; } @@ -521,6 +576,9 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) { SStreamDispatchRsp* pRsp = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); int32_t taskId = pRsp->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); + if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + return 0; + } streamProcessDispatchRsp(pTask, pRsp); return 0; } @@ -529,16 +587,32 @@ int32_t tqProcessTaskRecoverRsp(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRecoverRsp* pRsp = pMsg->pCont; int32_t taskId = pRsp->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); + if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + return 0; + } streamProcessRecoverRsp(pTask, pRsp); return 0; } int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen) { SVDropStreamTaskReq* pReq = (SVDropStreamTaskReq*)msg; + + SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &pReq->taskId, sizeof(int32_t)); + atomic_store_8(&pTask->taskStatus, TASK_STATUS__DROPPING); + // todo + // clear queue + // push drop req into queue + // launch exec to free memory + // remove from hash + return 0; + +#if 0 int32_t code = taosHashRemove(pTq->pStreamTasks, &pReq->taskId, sizeof(int32_t)); + // set status dropping ASSERT(code == 0); if (code == 0) { // sendrsp } return code; +#endif } diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c index 3af8901b2b..2ec627bd5c 100644 --- a/source/dnode/vnode/src/tq/tqPush.c +++ b/source/dnode/vnode/src/tq/tqPush.c @@ -45,9 +45,9 @@ static int32_t tqLoopExecFromQueue(STQ* pTq, STqHandle* pHandle, SStreamDataSubm int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) { SMqDataBlkRsp rsp = {0}; // 1. guard and set status executing - int8_t execStatus = - atomic_val_compare_exchange_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE, TASK_STATUS__EXECUTING); - if (execStatus == TASK_STATUS__IDLE) { + int8_t execStatus = atomic_val_compare_exchange_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE, + TASK_EXEC_STATUS__EXECUTING); + if (execStatus == TASK_EXEC_STATUS__IDLE) { SStreamDataSubmit* pSubmit = NULL; // 2. check processedVer // 2.1. if not missed, get msg from queue @@ -68,18 +68,18 @@ int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) { goto SEND_RSP; } // set exec status closing - atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__CLOSING); + atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__CLOSING); // second run if (tqLoopExecFromQueue(pTq, pHandle, &pSubmit, &rsp) == 0) { goto SEND_RSP; } // set exec status idle - atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE); + atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE); } SEND_RSP: // 4. if get result // 4.1 set exec input status blocked and exec status idle - atomic_store_8(&pHandle->pushHandle.execStatus, TASK_STATUS__IDLE); + atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE); // 4.2 rpc send rsp.rspOffset = pHandle->pushHandle.processedVer; /*if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) {*/ @@ -150,7 +150,7 @@ int32_t tqEnqueueAll(STQ* pTq, SSubmitReq* pReq) { continue; } int8_t execStatus = atomic_load_8(&pHandle->pushHandle.execStatus); - if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) { + if (execStatus == TASK_EXEC_STATUS__IDLE || execStatus == TASK_EXEC_STATUS__CLOSING) { tqSendExecReq(pTq, pHandle); } } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index fa0eb1d458..f281dcd0a9 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -42,6 +42,25 @@ int64_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalHead* code = 0; goto END; } else { + if (pHandle->fetchMeta) { + SWalReadHead* pHead = &((*ppHeadWithCkSum)->head); + if (pHead->msgType == TDMT_VND_CREATE_STB || pHead->msgType == TDMT_VND_ALTER_STB || + pHead->msgType == TDMT_VND_DROP_STB || pHead->msgType == TDMT_VND_CREATE_TABLE || + pHead->msgType == TDMT_VND_ALTER_TABLE || pHead->msgType == TDMT_VND_DROP_TABLE || + pHead->msgType == TDMT_VND_DROP_TTL_TABLE) { + code = walFetchBody(pHandle->pWalReader, ppHeadWithCkSum); + + if (code < 0) { + ASSERT(0); + *fetchOffset = offset; + code = -1; + goto END; + } + *fetchOffset = offset; + code = 0; + goto END; + } + } code = walSkipFetchBody(pHandle->pWalReader, *ppHeadWithCkSum); if (code < 0) { ASSERT(0); diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index 393cb9f749..ef3b205b3e 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -16,7 +16,7 @@ #include "tq.h" SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, bool createTb, int64_t suid, - const char* stbFullName, int32_t vgId) { + const char* stbFullName, int32_t vgId) { SSubmitReq* ret = NULL; SArray* tagArray = taosArrayInit(1, sizeof(STagVal)); if (!tagArray) { @@ -80,11 +80,10 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo ret->length = sizeof(SSubmitReq); ret->numOfBlocks = htonl(sz); - void* submitBlk = POINTER_SHIFT(ret, sizeof(SSubmitReq)); + SSubmitBlk* blkHead = POINTER_SHIFT(ret, sizeof(SSubmitReq)); for (int32_t i = 0; i < sz; i++) { SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i); - SSubmitBlk* blkHead = submitBlk; blkHead->numOfRows = htons(pDataBlock->info.rows); blkHead->sversion = htonl(pTSchema->version); // TODO @@ -93,11 +92,10 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo blkHead->uid = 0; int32_t rows = pDataBlock->info.rows; - /*int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSchema);*/ - /*blkHead->dataLen = htonl(rows * maxLen);*/ - blkHead->dataLen = 0; - void* blockData = POINTER_SHIFT(submitBlk, sizeof(SSubmitBlk)); + int32_t dataLen = 0; + + void* blkSchema = POINTER_SHIFT(blkHead, sizeof(SSubmitBlk)); int32_t schemaLen = 0; if (createTb) { @@ -135,7 +133,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo } SEncoder encoder = {0}; - tEncoderInit(&encoder, blockData, schemaLen); + tEncoderInit(&encoder, blkSchema, schemaLen); code = tEncodeSVCreateTbReq(&encoder, &createTbReq); tEncoderClear(&encoder); tdDestroySVCreateTbReq(&createTbReq); @@ -148,7 +146,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo } blkHead->schemaLen = htonl(schemaLen); - STSRow* rowData = POINTER_SHIFT(blockData, schemaLen); + STSRow* rowData = POINTER_SHIFT(blkSchema, schemaLen); for (int32_t j = 0; j < rows; j++) { SRowBuilder rb = {0}; @@ -168,14 +166,12 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo } int32_t rowLen = TD_ROW_LEN(rowData); rowData = POINTER_SHIFT(rowData, rowLen); - blkHead->dataLen += rowLen; + dataLen += rowLen; } - int32_t dataLen = blkHead->dataLen; blkHead->dataLen = htonl(dataLen); ret->length += sizeof(SSubmitBlk) + schemaLen + dataLen; - blkHead = POINTER_SHIFT(blkHead, schemaLen + dataLen); - /*submitBlk = blkHead;*/ + blkHead = POINTER_SHIFT(blkHead, sizeof(SSubmitBlk) + schemaLen + dataLen); } ret->length = htonl(ret->length); diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 1a623f1978..395301b7aa 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -1063,11 +1063,11 @@ static int32_t getFileIdFromKey(TSKEY key, int32_t daysPerFile, int32_t precisio } int64_t fid = (int64_t)(key / (daysPerFile * tsTickPerMin[precision])); // set the starting fileId - if (fid < 0L && llabs(fid) > INT32_MAX) { // data value overflow for INT32 + if (fid < 0LL && llabs(fid) > INT32_MAX) { // data value overflow for INT32 fid = INT32_MIN; } - if (fid > 0L && fid > INT32_MAX) { + if (fid > 0LL && fid > INT32_MAX) { fid = INT32_MAX; } diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 2333a93ce0..32d183ca0a 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -124,6 +124,115 @@ _exit: return TSDB_CODE_SUCCESS; } +int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg) { + STableCfgReq cfgReq = {0}; + STableCfgRsp cfgRsp = {0}; + SMetaReader mer1 = {0}; + SMetaReader mer2 = {0}; + char tableFName[TSDB_TABLE_FNAME_LEN]; + SRpcMsg rpcMsg; + int32_t code = 0; + int32_t rspLen = 0; + void *pRsp = NULL; + SSchemaWrapper schema = {0}; + SSchemaWrapper schemaTag = {0}; + + // decode req + if (tDeserializeSTableCfgReq(pMsg->pCont, pMsg->contLen, &cfgReq) != 0) { + code = TSDB_CODE_INVALID_MSG; + goto _exit; + } + + strcpy(cfgRsp.tbName, cfgReq.tbName); + memcpy(cfgRsp.dbFName, cfgReq.dbFName, sizeof(cfgRsp.dbFName)); + + sprintf(tableFName, "%s.%s", cfgReq.dbFName, cfgReq.tbName); + code = vnodeValidateTableHash(pVnode, tableFName); + if (code) { + goto _exit; + } + + // query meta + metaReaderInit(&mer1, pVnode->pMeta, 0); + + if (metaGetTableEntryByName(&mer1, cfgReq.tbName) < 0) { + code = terrno; + goto _exit; + } + + cfgRsp.tableType = mer1.me.type; + + if (mer1.me.type == TSDB_SUPER_TABLE) { + code = TSDB_CODE_VND_HASH_MISMATCH; + goto _exit; + } else if (mer1.me.type == TSDB_CHILD_TABLE) { + metaReaderInit(&mer2, pVnode->pMeta, 0); + if (metaGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit; + + strcpy(cfgRsp.stbName, mer2.me.name); + schema = mer2.me.stbEntry.schemaRow; + schemaTag = mer2.me.stbEntry.schemaTag; + cfgRsp.ttl = mer1.me.ctbEntry.ttlDays; + cfgRsp.commentLen = mer1.me.ctbEntry.commentLen; + if (mer1.me.ctbEntry.commentLen > 0) { + cfgRsp.pComment = strdup(mer1.me.ctbEntry.comment); + } + STag *pTag = (STag *)mer1.me.ctbEntry.pTags; + cfgRsp.tagsLen = pTag->len; + cfgRsp.pTags = taosMemoryMalloc(cfgRsp.tagsLen); + memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen); + } else if (mer1.me.type == TSDB_NORMAL_TABLE) { + schema = mer1.me.ntbEntry.schemaRow; + cfgRsp.ttl = mer1.me.ntbEntry.ttlDays; + cfgRsp.commentLen = mer1.me.ntbEntry.commentLen; + if (mer1.me.ntbEntry.commentLen > 0) { + cfgRsp.pComment = strdup(mer1.me.ntbEntry.comment); + } + } else { + ASSERT(0); + } + + cfgRsp.numOfTags = schemaTag.nCols; + cfgRsp.numOfColumns = schema.nCols; + cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags)); + + memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols); + if (schemaTag.nCols) { + memcpy(cfgRsp.pSchemas + schema.nCols, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols); + } + + // encode and send response + rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp); + if (rspLen < 0) { + code = TSDB_CODE_INVALID_MSG; + goto _exit; + } + + pRsp = rpcMallocCont(rspLen); + if (pRsp == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _exit; + } + tSerializeSTableCfgRsp(pRsp, rspLen, &cfgRsp); + +_exit: + rpcMsg.info = pMsg->info; + rpcMsg.pCont = pRsp; + rpcMsg.contLen = rspLen; + rpcMsg.code = code; + + if (code) { + qError("get table %s cfg failed cause of %s", cfgReq.tbName, tstrerror(code)); + } + + tmsgSendRsp(&rpcMsg); + + tFreeSTableCfgRsp(&cfgRsp); + metaReaderClear(&mer2); + metaReaderClear(&mer1); + return TSDB_CODE_SUCCESS; +} + int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) { pLoad->vgId = TD_VID(pVnode); pLoad->syncState = syncGetMyRole(pVnode->sync); @@ -157,4 +266,4 @@ tsdbReaderT tsdbQueryCacheLast(SVnode *pVnode, SQueryTableDataCond *pCond, STabl return tsdbQueryCacheLastT(pVnode->pTsdb, pCond, groupList, qId, pMemRef); #endif return 0; -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index f3595ebfb0..e764aba48e 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -172,7 +172,7 @@ int32_t vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp goto _err; } } break; - case TDMT_VND_STREAM_TASK_DROP: { + case TDMT_STREAM_TASK_DROP: { if (tqProcessTaskDropReq(pVnode->pTq, pMsg->pCont, pMsg->contLen) < 0) { goto _err; } @@ -255,6 +255,8 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) { return qWorkerProcessHbMsg(pVnode, pVnode->pQuery, pMsg, 0); case TDMT_VND_TABLE_META: return vnodeGetTableMeta(pVnode, pMsg); + case TDMT_VND_TABLE_CFG: + return vnodeGetTableCfg(pVnode, pMsg); case TDMT_VND_CONSUME: return tqProcessPollReq(pVnode->pTq, pMsg, pInfo->workerId); case TDMT_STREAM_TASK_RUN: diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index f1c43512ce..32090b774e 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -336,7 +336,7 @@ static void vnodeSyncReconfig(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SReCon SVnode *pVnode = pFsm->data; SRpcMsg rpcMsg = {.msgType = pMsg->msgType, .contLen = pMsg->contLen}; - syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &rpcMsg.info); + syncGetAndDelRespRpc(pVnode->sync, cbMeta.newCfgSeqNum, &rpcMsg.info); rpcMsg.info.conn.applyIndex = cbMeta.index; STraceId *trace = (STraceId *)&pMsg->info.traceId; diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index 7c90c3538c..98a03aa39b 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -71,11 +71,18 @@ typedef enum { CTG_TASK_GET_TB_META, CTG_TASK_GET_TB_HASH, CTG_TASK_GET_TB_INDEX, + CTG_TASK_GET_TB_CFG, CTG_TASK_GET_INDEX, CTG_TASK_GET_UDF, CTG_TASK_GET_USER, } CTG_TASK_TYPE; +typedef enum { + CTG_TASK_LAUNCHED = 1, + CTG_TASK_DONE, +} CTG_TASK_STATUS; + + typedef struct SCtgDebug { bool lockEnable; bool cacheEnable; @@ -102,6 +109,12 @@ typedef struct SCtgTbIndexCtx { SName* pName; } SCtgTbIndexCtx; +typedef struct SCtgTbCfgCtx { + SName* pName; + int32_t tbType; + SVgroupInfo* pVgInfo; +} SCtgTbCfgCtx; + typedef struct SCtgDbVgCtx { char dbFName[TSDB_DB_FNAME_LEN]; } SCtgDbVgCtx; @@ -190,7 +203,9 @@ typedef struct SCtgJob { SArray* pTasks; int32_t taskDone; SMetaData jobRes; - + int32_t taskIdx; + SRWLatch taskLock; + uint64_t queryId; SCatalog* pCtg; SRequestConnInfo conn; @@ -206,6 +221,7 @@ typedef struct SCtgJob { int32_t userNum; int32_t dbInfoNum; int32_t tbIndexNum; + int32_t tbCfgNum; } SCtgJob; typedef struct SCtgMsgCtx { @@ -215,24 +231,44 @@ typedef struct SCtgMsgCtx { char* target; } SCtgMsgCtx; +typedef struct SCtgTask SCtgTask; +typedef int32_t (*ctgSubTaskCbFp)(SCtgTask*); + +typedef struct SCtgSubRes { + CTG_TASK_TYPE type; + int32_t code; + void* res; + ctgSubTaskCbFp fp; +} SCtgSubRes; + typedef struct SCtgTask { - CTG_TASK_TYPE type; - int32_t taskId; - SCtgJob* pJob; - void* taskCtx; - SCtgMsgCtx msgCtx; - int32_t code; - void* res; + CTG_TASK_TYPE type; + int32_t taskId; + SCtgJob* pJob; + void* taskCtx; + SCtgMsgCtx msgCtx; + int32_t code; + void* res; + CTG_TASK_STATUS status; + SRWLatch lock; + SArray* pParents; + SCtgSubRes subRes; } SCtgTask; +typedef int32_t (*ctgInitTaskFp)(SCtgJob*, int32_t, void*); typedef int32_t (*ctgLanchTaskFp)(SCtgTask*); typedef int32_t (*ctgHandleTaskMsgRspFp)(SCtgTask*, int32_t, const SDataBuf *, int32_t); typedef int32_t (*ctgDumpTaskResFp)(SCtgTask*); +typedef int32_t (*ctgCloneTaskResFp)(SCtgTask*, void**); +typedef int32_t (*ctgCompTaskFp)(SCtgTask*, void*, bool*); typedef struct SCtgAsyncFps { - ctgLanchTaskFp launchFp; + ctgInitTaskFp initFp; + ctgLanchTaskFp launchFp; ctgHandleTaskMsgRspFp handleRspFp; - ctgDumpTaskResFp dumpResFp; + ctgDumpTaskResFp dumpResFp; + ctgCompTaskFp compFp; + ctgCloneTaskResFp cloneFp; } SCtgAsyncFps; typedef struct SCtgApiStat { @@ -520,6 +556,8 @@ int32_t ctgDropTbIndexEnqueue(SCatalog* pCtg, SName* pName, bool syncOp); int32_t ctgOpDropTbIndex(SCtgCacheOperation *operation); int32_t ctgOpUpdateTbIndex(SCtgCacheOperation *operation); int32_t ctgOpClearCache(SCtgCacheOperation *operation); +int32_t ctgReadTbTypeFromCache(SCatalog* pCtg, char* dbFName, char *tableName, int32_t *tbType); +int32_t ctgGetTbHashVgroupFromCache(SCatalog *pCtg, const SName *pTableName, SVgroupInfo **pVgroup); @@ -535,10 +573,14 @@ int32_t ctgGetUserDbAuthFromMnode(SCatalog* pCtg, SRequestConnInfo *pConn, const int32_t ctgGetTbMetaFromMnodeImpl(SCatalog* pCtg, SRequestConnInfo *pConn, char *dbFName, char* tbName, STableMetaOutput* out, SCtgTask* pTask); int32_t ctgGetTbMetaFromMnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableMetaOutput* out, SCtgTask* pTask); int32_t ctgGetTbMetaFromVnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* out, SCtgTask* pTask); +int32_t ctgGetTableCfgFromVnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, SVgroupInfo *vgroupInfo, STableCfg **out, SCtgTask* pTask); +int32_t ctgGetTableCfgFromMnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableCfg **out, SCtgTask* pTask); int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint64_t reqId, const SCatalogReq* pReq, catalogCallback fp, void* param, int32_t* taskNum); int32_t ctgLaunchJob(SCtgJob *pJob); int32_t ctgMakeAsyncRes(SCtgJob *pJob); +int32_t ctgLaunchSubTask(SCtgTask *pTask, CTG_TASK_TYPE type, ctgSubTaskCbFp fp, void* param); +int32_t ctgGetTbCfgCb(SCtgTask *pTask); int32_t ctgCloneVgInfo(SDBVgInfo *src, SDBVgInfo **dst); int32_t ctgCloneMetaOutput(STableMetaOutput *output, STableMetaOutput **pOutput); @@ -559,6 +601,7 @@ char * ctgTaskTypeStr(CTG_TASK_TYPE type); int32_t ctgUpdateSendTargetInfo(SMsgSendInfo *pMsgSendInfo, int32_t msgType, SCtgTask* pTask); int32_t ctgCloneTableIndex(SArray* pIndex, SArray** pRes); void ctgFreeSTableIndex(void *info); +void ctgClearSubTaskRes(SCtgSubRes *pRes); extern SCatalogMgmt gCtgMgmt; diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index bb02895569..44730cd3b5 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -22,36 +22,6 @@ SCatalogMgmt gCtgMgmt = {0}; -int32_t ctgRemoveTbMetaFromCache(SCatalog* pCtg, SName* pTableName, bool syncReq) { - int32_t code = 0; - STableMeta* tblMeta = NULL; - SCtgTbMetaCtx tbCtx = {0}; - tbCtx.flag = CTG_FLAG_UNKNOWN_STB; - tbCtx.pName = pTableName; - - CTG_ERR_JRET(ctgReadTbMetaFromCache(pCtg, &tbCtx, &tblMeta)); - - if (NULL == tblMeta) { - ctgDebug("table already not in cache, db:%s, tblName:%s", pTableName->dbname, pTableName->tname); - return TSDB_CODE_SUCCESS; - } - - char dbFName[TSDB_DB_FNAME_LEN]; - tNameGetFullDbName(pTableName, dbFName); - - if (TSDB_SUPER_TABLE == tblMeta->tableType) { - CTG_ERR_JRET(ctgDropStbMetaEnqueue(pCtg, dbFName, tbCtx.tbInfo.dbId, pTableName->tname, tblMeta->suid, syncReq)); - } else { - CTG_ERR_JRET(ctgDropTbMetaEnqueue(pCtg, dbFName, tbCtx.tbInfo.dbId, pTableName->tname, syncReq)); - } - -_return: - - taosMemoryFreeClear(tblMeta); - - CTG_RET(code); -} - int32_t ctgGetDBVgInfo(SCatalog* pCtg, SRequestConnInfo *pConn, const char* dbFName, SCtgDBCache** dbCache, SDBVgInfo **pInfo) { int32_t code = 0; @@ -212,29 +182,6 @@ _return: CTG_RET(code); } -int32_t ctgGetTbMetaFromCache(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta) { - if (CTG_IS_SYS_DBNAME(ctx->pName->dbname)) { - CTG_FLAG_SET_SYS_DB(ctx->flag); - } - - CTG_ERR_RET(ctgReadTbMetaFromCache(pCtg, ctx, pTableMeta)); - - if (*pTableMeta) { - if (CTG_FLAG_MATCH_STB(ctx->flag, (*pTableMeta)->tableType) && - ((!CTG_FLAG_IS_FORCE_UPDATE(ctx->flag)) || (CTG_FLAG_IS_SYS_DB(ctx->flag)))) { - return TSDB_CODE_SUCCESS; - } - - taosMemoryFreeClear(*pTableMeta); - } - - if (CTG_FLAG_IS_UNKNOWN_STB(ctx->flag)) { - CTG_FLAG_SET_STB(ctx->flag, ctx->tbInfo.tbType); - } - - return TSDB_CODE_SUCCESS; -} - int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta) { int32_t code = 0; STableMetaOutput *output = NULL; @@ -381,6 +328,23 @@ _return: return TSDB_CODE_SUCCESS; } +int32_t ctgGetTbType(SCatalog* pCtg, SRequestConnInfo *pConn, SName* pTableName, int32_t *tbType) { + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(pTableName, dbFName); + CTG_ERR_RET(ctgReadTbTypeFromCache(pCtg, dbFName, pTableName->tname, tbType)); + if (*tbType > 0) { + return TSDB_CODE_SUCCESS; + } + + STableMeta* pMeta = NULL; + CTG_ERR_RET(catalogGetTableMeta(pCtg, pConn, pTableName, &pMeta)); + + *tbType = pMeta->tableType; + taosMemoryFree(pMeta); + + return TSDB_CODE_SUCCESS; +} + int32_t ctgGetTbIndex(SCatalog* pCtg, SRequestConnInfo *pConn, SName* pTableName, SArray** pRes) { CTG_ERR_RET(ctgReadTbIndexFromCache(pCtg, pTableName, pRes)); if (*pRes) { @@ -419,6 +383,20 @@ _return: CTG_RET(code); } +int32_t ctgGetTbCfg(SCatalog* pCtg, SRequestConnInfo *pConn, SName* pTableName, STableCfg** pCfg) { + int32_t tbType = 0; + CTG_ERR_RET(ctgGetTbType(pCtg, pConn, pTableName, &tbType)); + + if (TSDB_SUPER_TABLE == tbType) { + CTG_ERR_RET(ctgGetTableCfgFromMnode(pCtg, pConn, pTableName, pCfg, NULL)); + } else { + SVgroupInfo vgroupInfo = {0}; + CTG_ERR_RET(catalogGetTableHashVgroup(pCtg, pConn, pTableName, &vgroupInfo)); + CTG_ERR_RET(ctgGetTableCfgFromVnode(pCtg, pConn, pTableName, &vgroupInfo, pCfg, NULL)); + } + + CTG_RET(TSDB_CODE_SUCCESS); +} int32_t ctgGetTbDistVgInfo(SCatalog* pCtg, SRequestConnInfo *pConn, SName* pTableName, SArray** pVgList) { STableMeta *tbMeta = NULL; @@ -1121,6 +1099,10 @@ _return: CTG_API_LEAVE(TSDB_CODE_SUCCESS); } +int32_t catalogGetDnodeList(SCatalog* pCatalog, SRequestConnInfo* pConn, SArray** pDnodeList) { + return TSDB_CODE_CTG_INVALID_INPUT; +} + int32_t catalogGetExpiredSTables(SCatalog* pCtg, SSTableVersion **stables, uint32_t *num) { CTG_API_ENTER(); @@ -1207,6 +1189,23 @@ _return: CTG_API_LEAVE(code); } +int32_t catalogRefreshGetTableCfg(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableCfg** pCfg) { + CTG_API_ENTER(); + + if (NULL == pCtg || NULL == pConn || NULL == pTableName || NULL == pCfg) { + CTG_API_LEAVE(TSDB_CODE_CTG_INVALID_INPUT); + } + + int32_t code = 0; + CTG_ERR_JRET(catalogRemoveTableMeta(pCtg, (SName*)pTableName)); + + CTG_ERR_JRET(ctgGetTbCfg(pCtg, pConn, (SName*)pTableName, pCfg)); + +_return: + + CTG_API_LEAVE(code); +} + int32_t catalogGetUdfInfo(SCatalog* pCtg, SRequestConnInfo *pConn, const char* funcName, SFuncInfo* pInfo) { CTG_API_ENTER(); diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 6adadf5045..df986fd4d6 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -20,7 +20,8 @@ #include "systable.h" #include "tref.h" -int32_t ctgInitGetTbMetaTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { +int32_t ctgInitGetTbMetaTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + SName *name = (SName*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_TB_META; @@ -44,12 +45,13 @@ int32_t ctgInitGetTbMetaTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, tbName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, tbName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetDbVgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { +int32_t ctgInitGetDbVgTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + char *dbFName = (char*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_DB_VGROUP; @@ -67,12 +69,13 @@ int32_t ctgInitGetDbVgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetDbCfgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { +int32_t ctgInitGetDbCfgTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + char *dbFName = (char*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_DB_CFG; @@ -90,12 +93,13 @@ int32_t ctgInitGetDbCfgTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetDbInfoTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { +int32_t ctgInitGetDbInfoTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + char *dbFName = (char*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_DB_INFO; @@ -113,13 +117,14 @@ int32_t ctgInitGetDbInfoTask(SCtgJob *pJob, int32_t taskIdx, char *dbFName) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, dbFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), dbFName); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetTbHashTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { +int32_t ctgInitGetTbHashTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + SName *name = (SName*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_TB_HASH; @@ -143,12 +148,12 @@ int32_t ctgInitGetTbHashTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, tableName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, tableName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetQnodeTask(SCtgJob *pJob, int32_t taskIdx) { +int32_t ctgInitGetQnodeTask(SCtgJob *pJob, int32_t taskIdx, void* param) { SCtgTask task = {0}; task.type = CTG_TASK_GET_QNODE; @@ -163,7 +168,8 @@ int32_t ctgInitGetQnodeTask(SCtgJob *pJob, int32_t taskIdx) { return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetIndexTask(SCtgJob *pJob, int32_t taskIdx, char *name) { +int32_t ctgInitGetIndexTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + char *name = (char*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_INDEX; @@ -181,12 +187,13 @@ int32_t ctgInitGetIndexTask(SCtgJob *pJob, int32_t taskIdx, char *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, indexFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, indexFName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetUdfTask(SCtgJob *pJob, int32_t taskIdx, char *name) { +int32_t ctgInitGetUdfTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + char *name = (char*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_UDF; @@ -204,12 +211,13 @@ int32_t ctgInitGetUdfTask(SCtgJob *pJob, int32_t taskIdx, char *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, udfName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, udfName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetUserTask(SCtgJob *pJob, int32_t taskIdx, SUserAuthInfo *user) { +int32_t ctgInitGetUserTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + SUserAuthInfo *user = (SUserAuthInfo*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_USER; @@ -227,12 +235,13 @@ int32_t ctgInitGetUserTask(SCtgJob *pJob, int32_t taskIdx, SUserAuthInfo *user) taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, user:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), user->user); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, user:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), user->user); return TSDB_CODE_SUCCESS; } -int32_t ctgInitGetTbIndexTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { +int32_t ctgInitGetTbIndexTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + SName *name = (SName*)param; SCtgTask task = {0}; task.type = CTG_TASK_GET_TB_INDEX; @@ -255,11 +264,41 @@ int32_t ctgInitGetTbIndexTask(SCtgJob *pJob, int32_t taskIdx, SName *name) { taosArrayPush(pJob->pTasks, &task); - qDebug("QID:0x%" PRIx64 " the %d task type %s initialized, tbName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, tbName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); return TSDB_CODE_SUCCESS; } +int32_t ctgInitGetTbCfgTask(SCtgJob *pJob, int32_t taskIdx, void* param) { + SName *name = (SName*)param; + SCtgTask task = {0}; + + task.type = CTG_TASK_GET_TB_CFG; + task.taskId = taskIdx; + task.pJob = pJob; + + task.taskCtx = taosMemoryCalloc(1, sizeof(SCtgTbCfgCtx)); + if (NULL == task.taskCtx) { + CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } + + SCtgTbCfgCtx* ctx = task.taskCtx; + ctx->pName = taosMemoryMalloc(sizeof(*name)); + if (NULL == ctx->pName) { + taosMemoryFree(task.taskCtx); + CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } + + memcpy(ctx->pName, name, sizeof(*name)); + + taosArrayPush(pJob->pTasks, &task); + + qDebug("QID:0x%" PRIx64 " the %dth task type %s initialized, tbName:%s", pJob->queryId, taskIdx, ctgTaskTypeStr(task.type), name->tname); + + return TSDB_CODE_SUCCESS; +} + + int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob *pJob, const SCatalogReq* pReq) { SHashObj* pDb = taosHashInit(taskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); @@ -296,6 +335,13 @@ int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob *pJob, con taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN); } + for (int32_t i = 0; i < pJob->tbCfgNum; ++i) { + SName* name = taosArrayGet(pReq->pTableCfg, i); + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(name, dbFName); + taosHashPut(pDb, dbFName, strlen(dbFName), dbFName, TSDB_DB_FNAME_LEN); + } + char* dbFName = taosHashIterate(pDb, NULL); while (dbFName) { ctgDropDbVgroupEnqueue(pCtg, dbFName, true); @@ -304,39 +350,31 @@ int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob *pJob, con taosHashCleanup(pDb); - int32_t tbNum = pJob->tbMetaNum + pJob->tbHashNum; - if (tbNum > 0) { - if (tbNum > pJob->tbMetaNum && tbNum > pJob->tbHashNum) { - SHashObj* pTb = taosHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); - for (int32_t i = 0; i < pJob->tbMetaNum; ++i) { - SName* name = taosArrayGet(pReq->pTableMeta, i); - taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); - } - - for (int32_t i = 0; i < pJob->tbHashNum; ++i) { - SName* name = taosArrayGet(pReq->pTableHash, i); - taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); - } - - SName* name = taosHashIterate(pTb, NULL); - while (name) { - catalogRemoveTableMeta(pCtg, name); - name = taosHashIterate(pTb, name); - } - - taosHashCleanup(pTb); - } else { - for (int32_t i = 0; i < pJob->tbMetaNum; ++i) { - SName* name = taosArrayGet(pReq->pTableMeta, i); - catalogRemoveTableMeta(pCtg, name); - } - - for (int32_t i = 0; i < pJob->tbHashNum; ++i) { - SName* name = taosArrayGet(pReq->pTableHash, i); - catalogRemoveTableMeta(pCtg, name); - } - } + // REFRESH TABLE META + SHashObj* pTb = taosHashInit(taskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + for (int32_t i = 0; i < pJob->tbMetaNum; ++i) { + SName* name = taosArrayGet(pReq->pTableMeta, i); + taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); } + + for (int32_t i = 0; i < pJob->tbHashNum; ++i) { + SName* name = taosArrayGet(pReq->pTableHash, i); + taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); + } + + for (int32_t i = 0; i < pJob->tbCfgNum; ++i) { + SName* name = taosArrayGet(pReq->pTableCfg, i); + taosHashPut(pTb, name, sizeof(SName), name, sizeof(SName)); + } + + SName* name = taosHashIterate(pTb, NULL); + while (name) { + catalogRemoveTableMeta(pCtg, name); + name = taosHashIterate(pTb, name); + } + + taosHashCleanup(pTb); + for (int32_t i = 0; i < pJob->tbIndexNum; ++i) { SName* name = taosArrayGet(pReq->pTableIndex, i); @@ -346,6 +384,20 @@ int32_t ctgHandleForceUpdate(SCatalog* pCtg, int32_t taskNum, SCtgJob *pJob, con return TSDB_CODE_SUCCESS; } +int32_t ctgInitTask(SCtgJob *pJob, CTG_TASK_TYPE type, void* param, int32_t *taskId) { + int32_t tid = atomic_fetch_add_32(&pJob->taskIdx, 1); + + CTG_LOCK(CTG_WRITE, &pJob->taskLock); + CTG_ERR_RET((*gCtgAsyncFps[type].initFp)(pJob, tid, param)); + CTG_UNLOCK(CTG_WRITE, &pJob->taskLock); + + if (taskId) { + *taskId = tid; + } + + return TSDB_CODE_SUCCESS; +} + int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint64_t reqId, const SCatalogReq* pReq, catalogCallback fp, void* param, int32_t* taskNum) { int32_t code = 0; int32_t tbMetaNum = (int32_t)taosArrayGetSize(pReq->pTableMeta); @@ -358,8 +410,9 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint6 int32_t userNum = (int32_t)taosArrayGetSize(pReq->pUser); int32_t dbInfoNum = (int32_t)taosArrayGetSize(pReq->pDbInfo); int32_t tbIndexNum = (int32_t)taosArrayGetSize(pReq->pTableIndex); + int32_t tbCfgNum = (int32_t)taosArrayGetSize(pReq->pTableCfg); - *taskNum = tbMetaNum + dbVgNum + udfNum + tbHashNum + qnodeNum + dbCfgNum + indexNum + userNum + dbInfoNum + tbIndexNum; + *taskNum = tbMetaNum + dbVgNum + udfNum + tbHashNum + qnodeNum + dbCfgNum + indexNum + userNum + dbInfoNum + tbIndexNum + tbCfgNum; if (*taskNum <= 0) { ctgDebug("Empty input for job, no need to retrieve meta, reqId:0x%" PRIx64, reqId); return TSDB_CODE_SUCCESS; @@ -389,6 +442,7 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint6 pJob->userNum = userNum; pJob->dbInfoNum = dbInfoNum; pJob->tbIndexNum = tbIndexNum; + pJob->tbCfgNum = tbCfgNum; pJob->pTasks = taosArrayInit(*taskNum, sizeof(SCtgTask)); @@ -401,54 +455,58 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint6 CTG_ERR_JRET(ctgHandleForceUpdate(pCtg, *taskNum, pJob, pReq)); } - int32_t taskIdx = 0; for (int32_t i = 0; i < dbVgNum; ++i) { char* dbFName = taosArrayGet(pReq->pDbVgroup, i); - CTG_ERR_JRET(ctgInitGetDbVgTask(pJob, taskIdx++, dbFName)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_DB_VGROUP, dbFName, NULL)); } for (int32_t i = 0; i < dbCfgNum; ++i) { char* dbFName = taosArrayGet(pReq->pDbCfg, i); - CTG_ERR_JRET(ctgInitGetDbCfgTask(pJob, taskIdx++, dbFName)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_DB_CFG, dbFName, NULL)); } for (int32_t i = 0; i < dbInfoNum; ++i) { char* dbFName = taosArrayGet(pReq->pDbInfo, i); - CTG_ERR_JRET(ctgInitGetDbInfoTask(pJob, taskIdx++, dbFName)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_DB_INFO, dbFName, NULL)); } for (int32_t i = 0; i < tbMetaNum; ++i) { SName* name = taosArrayGet(pReq->pTableMeta, i); - CTG_ERR_JRET(ctgInitGetTbMetaTask(pJob, taskIdx++, name)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_META, name, NULL)); } for (int32_t i = 0; i < tbHashNum; ++i) { SName* name = taosArrayGet(pReq->pTableHash, i); - CTG_ERR_JRET(ctgInitGetTbHashTask(pJob, taskIdx++, name)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_HASH, name, NULL)); } for (int32_t i = 0; i < tbIndexNum; ++i) { SName* name = taosArrayGet(pReq->pTableIndex, i); - CTG_ERR_JRET(ctgInitGetTbIndexTask(pJob, taskIdx++, name)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_INDEX, name, NULL)); + } + + for (int32_t i = 0; i < tbCfgNum; ++i) { + SName* name = taosArrayGet(pReq->pTableCfg, i); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_TB_CFG, name, NULL)); } for (int32_t i = 0; i < indexNum; ++i) { char* indexName = taosArrayGet(pReq->pIndex, i); - CTG_ERR_JRET(ctgInitGetIndexTask(pJob, taskIdx++, indexName)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_INDEX, indexName, NULL)); } for (int32_t i = 0; i < udfNum; ++i) { char* udfName = taosArrayGet(pReq->pUdf, i); - CTG_ERR_JRET(ctgInitGetUdfTask(pJob, taskIdx++, udfName)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_UDF, udfName, NULL)); } for (int32_t i = 0; i < userNum; ++i) { SUserAuthInfo* user = taosArrayGet(pReq->pUser, i); - CTG_ERR_JRET(ctgInitGetUserTask(pJob, taskIdx++, user)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_USER, user, NULL)); } if (qnodeNum) { - CTG_ERR_JRET(ctgInitGetQnodeTask(pJob, taskIdx++)); + CTG_ERR_JRET(ctgInitTask(pJob, CTG_TASK_GET_QNODE, NULL, NULL)); } pJob->refId = taosAddRef(gCtgMgmt.jobPool, pJob); @@ -528,6 +586,21 @@ int32_t ctgDumpTbIndexRes(SCtgTask* pTask) { return TSDB_CODE_SUCCESS; } +int32_t ctgDumpTbCfgRes(SCtgTask* pTask) { + SCtgJob* pJob = pTask->pJob; + if (NULL == pJob->jobRes.pTableCfg) { + pJob->jobRes.pTableCfg = taosArrayInit(pJob->tbCfgNum, sizeof(SMetaRes)); + if (NULL == pJob->jobRes.pTableCfg) { + CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } + } + + SMetaRes res = {.code = pTask->code, .pRes = pTask->res}; + taosArrayPush(pJob->jobRes.pTableCfg, &res); + + return TSDB_CODE_SUCCESS; +} + int32_t ctgDumpIndexRes(SCtgTask* pTask) { SCtgJob* pJob = pTask->pJob; if (NULL == pJob->jobRes.pIndex) { @@ -618,13 +691,48 @@ int32_t ctgDumpUserRes(SCtgTask* pTask) { return TSDB_CODE_SUCCESS; } +int32_t ctgInvokeSubCb(SCtgTask *pTask) { + int32_t code = 0; + + CTG_LOCK(CTG_WRITE, &pTask->lock); + + int32_t parentNum = taosArrayGetSize(pTask->pParents); + for (int32_t i = 0; i < parentNum; ++i) { + SCtgTask* pParent = taosArrayGetP(pTask->pParents, i); + + pParent->subRes.code = pTask->code; + if (TSDB_CODE_SUCCESS == pTask->code) { + code = (*gCtgAsyncFps[pTask->type].cloneFp)(pTask, &pParent->subRes.res); + if (code) { + pParent->subRes.code = code; + } + } + + CTG_ERR_JRET(pParent->subRes.fp(pParent)); + } + +_return: + + CTG_UNLOCK(CTG_WRITE, &pTask->lock); + + CTG_RET(code); +} + + int32_t ctgHandleTaskEnd(SCtgTask* pTask, int32_t rspCode) { SCtgJob* pJob = pTask->pJob; int32_t code = 0; + if (CTG_TASK_DONE == pTask->status) { + return TSDB_CODE_SUCCESS; + } + qDebug("QID:0x%" PRIx64 " task %d end with res %s", pJob->queryId, pTask->taskId, tstrerror(rspCode)); pTask->code = rspCode; + pTask->status = CTG_TASK_DONE; + + ctgInvokeSubCb(pTask); int32_t taskDone = atomic_add_fetch_32(&pJob->taskDone, 1); if (taskDone < taosArrayGetSize(pJob->pTasks)) { @@ -636,7 +744,7 @@ int32_t ctgHandleTaskEnd(SCtgTask* pTask, int32_t rspCode) { _return: - qDebug("QID:0x%" PRIx64 " user callback with rsp %s", pJob->queryId, tstrerror(code)); + qDebug("QID:0x%" PRIx64 " ctg call user callback with rsp %s", pJob->queryId, tstrerror(code)); (*pJob->userFp)(&pJob->jobRes, pJob->userParam, code); @@ -802,11 +910,12 @@ int32_t ctgHandleGetDbVgRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf *pM switch (reqType) { case TDMT_MND_USE_DB: { SUseDbOutput* pOut = (SUseDbOutput*)pTask->msgCtx.out; - - CTG_ERR_JRET(ctgGenerateVgList(pCtg, pOut->dbVgroup->vgHash, (SArray**)&pTask->res)); + SDBVgInfo* pDb = NULL; - CTG_ERR_JRET(ctgUpdateVgroupEnqueue(pCtg, ctx->dbFName, pOut->dbId, pOut->dbVgroup, false)); - pOut->dbVgroup = NULL; + CTG_ERR_JRET(ctgGenerateVgList(pCtg, pOut->dbVgroup->vgHash, (SArray**)&pTask->res)); + + CTG_ERR_JRET(cloneDbVgInfo(pOut->dbVgroup, &pDb)); + CTG_ERR_JRET(ctgUpdateVgroupEnqueue(pCtg, ctx->dbFName, pOut->dbId, pDb, false)); break; } @@ -874,6 +983,7 @@ int32_t ctgHandleGetTbIndexRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf CTG_ERR_JRET(ctgUpdateTbIndexEnqueue(pTask->pJob->pCtg, (STableIndex**)&pTask->msgCtx.out, false)); _return: + if (TSDB_CODE_MND_DB_INDEX_NOT_EXIST == code) { code = TSDB_CODE_SUCCESS; } @@ -882,6 +992,18 @@ _return: CTG_RET(code); } +int32_t ctgHandleGetTbCfgRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf *pMsg, int32_t rspCode) { + int32_t code = 0; + CTG_ERR_JRET(ctgProcessRspMsg(&pTask->msgCtx.out, reqType, pMsg->pData, pMsg->len, rspCode, pTask->msgCtx.target)); + + TSWAP(pTask->res, pTask->msgCtx.out); + +_return: + + ctgHandleTaskEnd(pTask, code); + + CTG_RET(code); +} int32_t ctgHandleGetDbCfgRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf *pMsg, int32_t rspCode) { int32_t code = 0; @@ -1138,6 +1260,48 @@ int32_t ctgLaunchGetTbIndexTask(SCtgTask *pTask) { return TSDB_CODE_SUCCESS; } +int32_t ctgLaunchGetTbCfgTask(SCtgTask *pTask) { + int32_t code = 0; + SCatalog* pCtg = pTask->pJob->pCtg; + SRequestConnInfo* pConn = &pTask->pJob->conn; + SCtgTbCfgCtx* pCtx = (SCtgTbCfgCtx*)pTask->taskCtx; + SArray* pRes = NULL; + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(pCtx->pName, dbFName); + + if (pCtx->tbType <= 0) { + CTG_ERR_JRET(ctgReadTbTypeFromCache(pCtg, dbFName, pCtx->pName->tname, &pCtx->tbType)); + if (pCtx->tbType <= 0) { + CTG_ERR_JRET(ctgLaunchSubTask(pTask, CTG_TASK_GET_TB_META, ctgGetTbCfgCb, pCtx->pName)); + return TSDB_CODE_SUCCESS; + } + } + + if (TSDB_SUPER_TABLE == pCtx->tbType) { + CTG_ERR_JRET(ctgGetTableCfgFromMnode(pCtg, pConn, pCtx->pName, NULL, pTask)); + } else { + if (NULL == pCtx->pVgInfo) { + CTG_ERR_JRET(ctgGetTbHashVgroupFromCache(pCtg, pCtx->pName, &pCtx->pVgInfo)); + if (NULL == pCtx->pVgInfo) { + CTG_ERR_JRET(ctgLaunchSubTask(pTask, CTG_TASK_GET_DB_VGROUP, ctgGetTbCfgCb, dbFName)); + return TSDB_CODE_SUCCESS; + } + } + + CTG_ERR_JRET(ctgGetTableCfgFromVnode(pCtg, pConn, pCtx->pName, pCtx->pVgInfo, NULL, pTask)); + } + + return TSDB_CODE_SUCCESS; + +_return: + + if (CTG_TASK_LAUNCHED == pTask->status) { + ctgHandleTaskEnd(pTask, code); + } + + CTG_RET(code); +} + int32_t ctgLaunchGetQnodeTask(SCtgTask *pTask) { SCatalog* pCtg = pTask->pJob->pCtg; @@ -1244,17 +1408,70 @@ int32_t ctgRelaunchGetTbMetaTask(SCtgTask *pTask) { return TSDB_CODE_SUCCESS; } +int32_t ctgGetTbCfgCb(SCtgTask *pTask) { + int32_t code = 0; + + CTG_ERR_JRET(pTask->subRes.code); + + SCtgTbCfgCtx* pCtx = (SCtgTbCfgCtx*)pTask->taskCtx; + if (CTG_TASK_GET_TB_META == pTask->subRes.type) { + pCtx->tbType = ((STableMeta*)pTask->subRes.res)->tableType; + } else if (CTG_TASK_GET_DB_VGROUP == pTask->subRes.type) { + SDBVgInfo* pDb = (SDBVgInfo*)pTask->subRes.res; + + pCtx->pVgInfo = taosMemoryCalloc(1, sizeof(SVgroupInfo)); + CTG_ERR_JRET(ctgGetVgInfoFromHashValue(pTask->pJob->pCtg, pDb, pCtx->pName, pCtx->pVgInfo)); + } + + CTG_RET(ctgLaunchGetTbCfgTask(pTask)); + +_return: + + CTG_RET(ctgHandleTaskEnd(pTask, pTask->subRes.code)); +} + +int32_t ctgCompDbVgTasks(SCtgTask* pTask, void* param, bool* equal) { + SCtgDbVgCtx* ctx = pTask->taskCtx; + + *equal = (0 == strcmp(ctx->dbFName, param)); + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgCompTbMetaTasks(SCtgTask* pTask, void* param, bool* equal) { + SCtgTbMetaCtx* ctx = pTask->taskCtx; + + *equal = tNameTbNameEqual(ctx->pName, (SName*)param); + + return TSDB_CODE_SUCCESS; +} + +int32_t ctgCloneTbMeta(SCtgTask* pTask, void** pRes) { + STableMeta* pMeta = (STableMeta*)pTask->res; + + CTG_RET(cloneTableMeta(pMeta, (STableMeta**)pRes)); +} + +int32_t ctgCloneDbVg(SCtgTask* pTask, void** pRes) { + SUseDbOutput* pOut = (SUseDbOutput*)pTask->msgCtx.out; + + CTG_RET(cloneDbVgInfo(pOut->dbVgroup, (SDBVgInfo**)pRes)); +} + + SCtgAsyncFps gCtgAsyncFps[] = { - {ctgLaunchGetQnodeTask, ctgHandleGetQnodeRsp, ctgDumpQnodeRes}, - {ctgLaunchGetDbVgTask, ctgHandleGetDbVgRsp, ctgDumpDbVgRes}, - {ctgLaunchGetDbCfgTask, ctgHandleGetDbCfgRsp, ctgDumpDbCfgRes}, - {ctgLaunchGetDbInfoTask, ctgHandleGetDbInfoRsp, ctgDumpDbInfoRes}, - {ctgLaunchGetTbMetaTask, ctgHandleGetTbMetaRsp, ctgDumpTbMetaRes}, - {ctgLaunchGetTbHashTask, ctgHandleGetTbHashRsp, ctgDumpTbHashRes}, - {ctgLaunchGetTbIndexTask, ctgHandleGetTbIndexRsp, ctgDumpTbIndexRes}, - {ctgLaunchGetIndexTask, ctgHandleGetIndexRsp, ctgDumpIndexRes}, - {ctgLaunchGetUdfTask, ctgHandleGetUdfRsp, ctgDumpUdfRes}, - {ctgLaunchGetUserTask, ctgHandleGetUserRsp, ctgDumpUserRes}, + {ctgInitGetQnodeTask, ctgLaunchGetQnodeTask, ctgHandleGetQnodeRsp, ctgDumpQnodeRes, NULL, NULL}, + {ctgInitGetDbVgTask, ctgLaunchGetDbVgTask, ctgHandleGetDbVgRsp, ctgDumpDbVgRes, ctgCompDbVgTasks, ctgCloneDbVg}, + {ctgInitGetDbCfgTask, ctgLaunchGetDbCfgTask, ctgHandleGetDbCfgRsp, ctgDumpDbCfgRes, NULL, NULL}, + {ctgInitGetDbInfoTask, ctgLaunchGetDbInfoTask, ctgHandleGetDbInfoRsp, ctgDumpDbInfoRes, NULL, NULL}, + {ctgInitGetTbMetaTask, ctgLaunchGetTbMetaTask, ctgHandleGetTbMetaRsp, ctgDumpTbMetaRes, ctgCompTbMetaTasks, ctgCloneTbMeta}, + {ctgInitGetTbHashTask, ctgLaunchGetTbHashTask, ctgHandleGetTbHashRsp, ctgDumpTbHashRes, NULL, NULL}, + {ctgInitGetTbIndexTask, ctgLaunchGetTbIndexTask, ctgHandleGetTbIndexRsp, ctgDumpTbIndexRes, NULL, NULL}, + {ctgInitGetTbCfgTask, ctgLaunchGetTbCfgTask, ctgHandleGetTbCfgRsp, ctgDumpTbCfgRes, NULL, NULL}, + {ctgInitGetIndexTask, ctgLaunchGetIndexTask, ctgHandleGetIndexRsp, ctgDumpIndexRes, NULL, NULL}, + {ctgInitGetUdfTask, ctgLaunchGetUdfTask, ctgHandleGetUdfRsp, ctgDumpUdfRes, NULL, NULL}, + {ctgInitGetUserTask, ctgLaunchGetUserTask, ctgHandleGetUserRsp, ctgDumpUserRes, NULL, NULL}, }; int32_t ctgMakeAsyncRes(SCtgJob *pJob) { @@ -1269,6 +1486,86 @@ int32_t ctgMakeAsyncRes(SCtgJob *pJob) { return TSDB_CODE_SUCCESS; } +int32_t ctgSearchExistingTask(SCtgJob *pJob, CTG_TASK_TYPE type, void* param, int32_t* taskId) { + bool equal = false; + SCtgTask* pTask = NULL; + int32_t code = 0; + + CTG_LOCK(CTG_READ, &pJob->taskLock); + + int32_t taskNum = taosArrayGetSize(pJob->pTasks); + for (int32_t i = 0; i < taskNum; ++i) { + pTask = taosArrayGet(pJob->pTasks, i); + if (type != pTask->type) { + continue; + } + + CTG_ERR_JRET((*gCtgAsyncFps[type].compFp)(pTask, param, &equal)); + if (equal) { + break; + } + } + +_return: + + CTG_UNLOCK(CTG_READ, &pJob->taskLock); + if (equal) { + *taskId = pTask->taskId; + } + + CTG_RET(code); +} + +int32_t ctgSetSubTaskCb(SCtgTask *pSub, SCtgTask *pTask) { + int32_t code = 0; + + CTG_LOCK(CTG_WRITE, &pSub->lock); + if (CTG_TASK_DONE == pSub->status) { + pTask->subRes.code = pSub->code; + CTG_ERR_JRET((*gCtgAsyncFps[pTask->type].cloneFp)(pSub, &pTask->subRes.res)); + CTG_ERR_JRET(pTask->subRes.fp(pTask)); + } else { + if (NULL == pSub->pParents) { + pSub->pParents = taosArrayInit(4, POINTER_BYTES); + } + + taosArrayPush(pSub->pParents, &pTask); + } + +_return: + + CTG_UNLOCK(CTG_WRITE, &pSub->lock); + + CTG_RET(code); +} + + +int32_t ctgLaunchSubTask(SCtgTask *pTask, CTG_TASK_TYPE type, ctgSubTaskCbFp fp, void* param) { + SCtgJob* pJob = pTask->pJob; + int32_t subTaskId = -1; + bool newTask = false; + + ctgClearSubTaskRes(&pTask->subRes); + pTask->subRes.type = type; + pTask->subRes.fp = fp; + + CTG_ERR_RET(ctgSearchExistingTask(pJob, type, param, &subTaskId)); + if (subTaskId < 0) { + CTG_ERR_RET(ctgInitTask(pJob, type, param, &subTaskId)); + newTask = true; + } + + SCtgTask* pSub = taosArrayGet(pJob->pTasks, subTaskId); + + CTG_ERR_RET(ctgSetSubTaskCb(pSub, pTask)); + + if (newTask) { + CTG_ERR_RET((*gCtgAsyncFps[pSub->type].launchFp)(pSub)); + pSub->status = CTG_TASK_LAUNCHED; + } + + return TSDB_CODE_SUCCESS; +} int32_t ctgLaunchJob(SCtgJob *pJob) { int32_t taskNum = taosArrayGetSize(pJob->pTasks); @@ -1278,6 +1575,7 @@ int32_t ctgLaunchJob(SCtgJob *pJob) { qDebug("QID:0x%" PRIx64 " ctg start to launch task %d", pJob->queryId, pTask->taskId); CTG_ERR_RET((*gCtgAsyncFps[pTask->type].launchFp)(pTask)); + pTask->status = CTG_TASK_LAUNCHED; } return TSDB_CODE_SUCCESS; diff --git a/source/libs/catalog/src/ctgCache.c b/source/libs/catalog/src/ctgCache.c index 1de5ee3d7d..eeb627624b 100644 --- a/source/libs/catalog/src/ctgCache.c +++ b/source/libs/catalog/src/ctgCache.c @@ -326,6 +326,7 @@ _return: int32_t ctgAcquireTbIndexFromCache(SCatalog* pCtg, char *dbFName, char* tbName, SCtgDBCache **pDb, SCtgTbCache** pTb) { SCtgDBCache *dbCache = NULL; + SCtgTbCache* pCache = NULL; ctgAcquireDBCache(pCtg, dbFName, &dbCache); if (NULL == dbCache) { ctgDebug("db %s not in cache", dbFName); @@ -333,7 +334,7 @@ int32_t ctgAcquireTbIndexFromCache(SCatalog* pCtg, char *dbFName, char* tbName, } int32_t sz = 0; - SCtgTbCache* pCache = taosHashAcquire(dbCache->tbCache, tbName, strlen(tbName)); + pCache = taosHashAcquire(dbCache->tbCache, tbName, strlen(tbName)); if (NULL == pCache) { ctgDebug("tb %s not in cache, dbFName:%s", tbName, dbFName); goto _return; @@ -540,10 +541,10 @@ int32_t ctgReadTbVerFromCache(SCatalog *pCtg, SName *pTableName, int32_t *sver, } -int32_t ctgReadTbTypeFromCache(SCatalog* pCtg, char* dbFName, char *tableName, int32_t *tbType) { +int32_t ctgReadTbTypeFromCache(SCatalog* pCtg, char* dbFName, char *tbName, int32_t *tbType) { SCtgDBCache *dbCache = NULL; SCtgTbCache *tbCache = NULL; - CTG_ERR_RET(ctgAcquireTbMetaFromCache(pCtg, dbFName, tableName, &dbCache, &tbCache)); + CTG_ERR_RET(ctgAcquireTbMetaFromCache(pCtg, dbFName, tbName, &dbCache, &tbCache)); if (NULL == tbCache) { ctgReleaseTbMetaToCache(pCtg, dbCache, tbCache); return TSDB_CODE_SUCCESS; @@ -552,7 +553,7 @@ int32_t ctgReadTbTypeFromCache(SCatalog* pCtg, char* dbFName, char *tableName, i *tbType = tbCache->pMeta->tableType; ctgReleaseTbMetaToCache(pCtg, dbCache, tbCache); - ctgDebug("Got tb %s tbType %d from cache, dbFName:%s", tableName, *tbType, dbFName); + ctgDebug("Got tb %s tbType %d from cache, dbFName:%s", tbName, *tbType, dbFName); return TSDB_CODE_SUCCESS; } @@ -1394,7 +1395,7 @@ int32_t ctgWriteTbMetaToCache(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFNam if (orig) { origType = orig->tableType; - if (origType == meta->tableType && orig->uid == meta->uid && orig->sversion >= meta->sversion && orig->tversion >= meta->tversion) { + if (origType == meta->tableType && orig->uid == meta->uid && (origType == TSDB_CHILD_TABLE || (orig->sversion >= meta->sversion && orig->tversion >= meta->tversion))) { taosMemoryFree(meta); ctgDebug("ignore table %s meta update", tbName); return TSDB_CODE_SUCCESS; @@ -2060,4 +2061,92 @@ int32_t ctgStartUpdateThread() { } +int32_t ctgGetTbMetaFromCache(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgTbMetaCtx* ctx, STableMeta** pTableMeta) { + if (CTG_IS_SYS_DBNAME(ctx->pName->dbname)) { + CTG_FLAG_SET_SYS_DB(ctx->flag); + } + + CTG_ERR_RET(ctgReadTbMetaFromCache(pCtg, ctx, pTableMeta)); + + if (*pTableMeta) { + if (CTG_FLAG_MATCH_STB(ctx->flag, (*pTableMeta)->tableType) && + ((!CTG_FLAG_IS_FORCE_UPDATE(ctx->flag)) || (CTG_FLAG_IS_SYS_DB(ctx->flag)))) { + return TSDB_CODE_SUCCESS; + } + + taosMemoryFreeClear(*pTableMeta); + } + + if (CTG_FLAG_IS_UNKNOWN_STB(ctx->flag)) { + CTG_FLAG_SET_STB(ctx->flag, ctx->tbInfo.tbType); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgRemoveTbMetaFromCache(SCatalog* pCtg, SName* pTableName, bool syncReq) { + int32_t code = 0; + STableMeta* tblMeta = NULL; + SCtgTbMetaCtx tbCtx = {0}; + tbCtx.flag = CTG_FLAG_UNKNOWN_STB; + tbCtx.pName = pTableName; + + CTG_ERR_JRET(ctgReadTbMetaFromCache(pCtg, &tbCtx, &tblMeta)); + + if (NULL == tblMeta) { + ctgDebug("table already not in cache, db:%s, tblName:%s", pTableName->dbname, pTableName->tname); + return TSDB_CODE_SUCCESS; + } + + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(pTableName, dbFName); + + if (TSDB_SUPER_TABLE == tblMeta->tableType) { + CTG_ERR_JRET(ctgDropStbMetaEnqueue(pCtg, dbFName, tbCtx.tbInfo.dbId, pTableName->tname, tblMeta->suid, syncReq)); + } else { + CTG_ERR_JRET(ctgDropTbMetaEnqueue(pCtg, dbFName, tbCtx.tbInfo.dbId, pTableName->tname, syncReq)); + } + +_return: + + taosMemoryFreeClear(tblMeta); + + CTG_RET(code); +} + +int32_t ctgGetTbHashVgroupFromCache(SCatalog *pCtg, const SName *pTableName, SVgroupInfo **pVgroup) { + if (CTG_IS_SYS_DBNAME(pTableName->dbname)) { + ctgError("no valid vgInfo for db, dbname:%s", pTableName->dbname); + CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); + } + + SCtgDBCache* dbCache = NULL; + int32_t code = 0; + char dbFName[TSDB_DB_FNAME_LEN] = {0}; + tNameGetFullDbName(pTableName, dbFName); + + CTG_ERR_RET(ctgAcquireVgInfoFromCache(pCtg, dbFName, &dbCache)); + + if (NULL == dbCache) { + *pVgroup = NULL; + return TSDB_CODE_SUCCESS; + } + + *pVgroup = taosMemoryCalloc(1, sizeof(SVgroupInfo)); + CTG_ERR_JRET(ctgGetVgInfoFromHashValue(pCtg, dbCache->vgCache.vgInfo, pTableName, *pVgroup)); + +_return: + + if (dbCache) { + ctgReleaseVgInfoToCache(pCtg, dbCache); + } + + if (code) { + taosMemoryFreeClear(*pVgroup); + } + + CTG_RET(code); +} + diff --git a/source/libs/catalog/src/ctgRemote.c b/source/libs/catalog/src/ctgRemote.c index fa1a262832..81dabffb4e 100644 --- a/source/libs/catalog/src/ctgRemote.c +++ b/source/libs/catalog/src/ctgRemote.c @@ -172,6 +172,39 @@ int32_t ctgProcessRspMsg(void* out, int32_t reqType, char* msg, int32_t msgSize, qDebug("Got table meta from vnode, tbFName:%s", target); break; } + case TDMT_VND_TABLE_CFG: { + if (TSDB_CODE_SUCCESS != rspCode) { + qError("error rsp for table cfg from vnode, code:%s, tbFName:%s", tstrerror(rspCode), target); + CTG_ERR_RET(rspCode); + } + + code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize); + if (code) { + qError("Process vnode tb cfg rsp failed, code:%s, tbFName:%s", tstrerror(code), target); + CTG_ERR_RET(code); + } + + qDebug("Got table cfg from vnode, tbFName:%s", target); + break; + } + case TDMT_MND_TABLE_CFG: { + if (TSDB_CODE_SUCCESS != rspCode) { + qError("error rsp for stb cfg from mnode, error:%s, tbFName:%s", tstrerror(rspCode), target); + CTG_ERR_RET(rspCode); + } + + code = queryProcessMsgRsp[TMSG_INDEX(reqType)](out, msg, msgSize); + if (code) { + qError("Process mnode stb cfg rsp failed, error:%s, tbFName:%s", tstrerror(code), target); + CTG_ERR_RET(code); + } + + qDebug("Got stb cfg from mnode, tbFName:%s", target); + break; + } + default: + qError("invalid req type %s", TMSG_INFO(reqType)); + return TSDB_CODE_APP_ERROR; } return TSDB_CODE_SUCCESS; @@ -550,7 +583,7 @@ int32_t ctgGetUserDbAuthFromMnode(SCatalog* pCtg, SRequestConnInfo *pConn, const int32_t ctgGetTbMetaFromMnodeImpl(SCatalog* pCtg, SRequestConnInfo *pConn, char *dbFName, char* tbName, STableMetaOutput* out, SCtgTask* pTask) { - SBuildTableMetaInput bInput = {.vgId = 0, .dbFName = dbFName, .tbName = tbName}; + SBuildTableInput bInput = {.vgId = 0, .dbFName = dbFName, .tbName = tbName}; char *msg = NULL; SEpSet *pVnodeEpSet = NULL; int32_t msgLen = 0; @@ -606,9 +639,11 @@ int32_t ctgGetTbMetaFromVnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SNa sprintf(tbFName, "%s.%s", dbFName, pTableName->tname); void*(*mallocFp)(int32_t) = pTask ? taosMemoryMalloc : rpcMallocCont; - ctgDebug("try to get table meta from vnode, vgId:%d, tbFName:%s", vgroupInfo->vgId, tbFName); + SEp* pEp = &vgroupInfo->epSet.eps[vgroupInfo->epSet.inUse]; + ctgDebug("try to get table meta from vnode, vgId:%d, ep num:%d, ep %s:%d, tbFName:%s", + vgroupInfo->vgId, vgroupInfo->epSet.numOfEps, pEp->fqdn, pEp->port, tbFName); - SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .dbFName = dbFName, .tbName = (char *)tNameGetTableName(pTableName)}; + SBuildTableInput bInput = {.vgId = vgroupInfo->vgId, .dbFName = dbFName, .tbName = (char *)tNameGetTableName(pTableName)}; char *msg = NULL; int32_t msgLen = 0; @@ -646,4 +681,89 @@ int32_t ctgGetTbMetaFromVnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SNa return TSDB_CODE_SUCCESS; } +int32_t ctgGetTableCfgFromVnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, SVgroupInfo *vgroupInfo, STableCfg **out, SCtgTask* pTask) { + char *msg = NULL; + int32_t msgLen = 0; + int32_t reqType = TDMT_VND_TABLE_CFG; + char tbFName[TSDB_TABLE_FNAME_LEN]; + tNameExtractFullName(pTableName, tbFName); + void*(*mallocFp)(int32_t) = pTask ? taosMemoryMalloc : rpcMallocCont; + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(pTableName, dbFName); + SBuildTableInput bInput = {.vgId = vgroupInfo->vgId, .dbFName = dbFName, .tbName = (char*)pTableName->tname}; + + SEp* pEp = &vgroupInfo->epSet.eps[vgroupInfo->epSet.inUse]; + ctgDebug("try to get table cfg from vnode, vgId:%d, ep num:%d, ep %s:%d, tbFName:%s", + vgroupInfo->vgId, vgroupInfo->epSet.numOfEps, pEp->fqdn, pEp->port, tbFName); + + int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](&bInput, &msg, 0, &msgLen, mallocFp); + if (code) { + ctgError("Build get tb cfg msg failed, code:%s, tbFName:%s", tstrerror(code), tbFName); + CTG_ERR_RET(code); + } + + if (pTask) { + CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, NULL, (char*)tbFName)); + + SRequestConnInfo vConn = {.pTrans = pConn->pTrans, + .requestId = pConn->requestId, + .requestObjRefId = pConn->requestObjRefId, + .mgmtEps = vgroupInfo->epSet}; + CTG_RET(ctgAsyncSendMsg(pCtg, &vConn, pTask, reqType, msg, msgLen)); + } + + SRpcMsg rpcMsg = { + .msgType = reqType, + .pCont = msg, + .contLen = msgLen, + }; + + SRpcMsg rpcRsp = {0}; + rpcSendRecv(pConn->pTrans, &vgroupInfo->epSet, &rpcMsg, &rpcRsp); + + CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)tbFName)); + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgGetTableCfgFromMnode(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableCfg **out, SCtgTask* pTask) { + char *msg = NULL; + int32_t msgLen = 0; + int32_t reqType = TDMT_MND_TABLE_CFG; + char tbFName[TSDB_TABLE_FNAME_LEN]; + tNameExtractFullName(pTableName, tbFName); + void*(*mallocFp)(int32_t) = pTask ? taosMemoryMalloc : rpcMallocCont; + char dbFName[TSDB_DB_FNAME_LEN]; + tNameGetFullDbName(pTableName, dbFName); + SBuildTableInput bInput = {.vgId = 0, .dbFName = dbFName, .tbName = (char*)pTableName->tname}; + + ctgDebug("try to get table cfg from mnode, tbFName:%s", tbFName); + + int32_t code = queryBuildMsg[TMSG_INDEX(reqType)](&bInput, &msg, 0, &msgLen, mallocFp); + if (code) { + ctgError("Build get tb cfg msg failed, code:%s, tbFName:%s", tstrerror(code), tbFName); + CTG_ERR_RET(code); + } + + if (pTask) { + CTG_ERR_RET(ctgUpdateMsgCtx(&pTask->msgCtx, reqType, NULL, (char*)tbFName)); + + CTG_RET(ctgAsyncSendMsg(pCtg, pConn, pTask, reqType, msg, msgLen)); + } + + SRpcMsg rpcMsg = { + .msgType = reqType, + .pCont = msg, + .contLen = msgLen, + }; + + SRpcMsg rpcRsp = {0}; + rpcSendRecv(pConn->pTrans, &pConn->mgmtEps, &rpcMsg, &rpcRsp); + + CTG_ERR_RET(ctgProcessRspMsg(out, reqType, rpcRsp.pCont, rpcRsp.contLen, rpcRsp.code, (char*)tbFName)); + + return TSDB_CODE_SUCCESS; +} + diff --git a/source/libs/catalog/src/ctgUtil.c b/source/libs/catalog/src/ctgUtil.c index 476eb371b0..8635457dfe 100644 --- a/source/libs/catalog/src/ctgUtil.c +++ b/source/libs/catalog/src/ctgUtil.c @@ -33,6 +33,10 @@ char *ctgTaskTypeStr(CTG_TASK_TYPE type) { return "[get table meta]"; case CTG_TASK_GET_TB_HASH: return "[get table hash]"; + case CTG_TASK_GET_TB_INDEX: + return "[get table index]"; + case CTG_TASK_GET_TB_CFG: + return "[get table cfg]"; case CTG_TASK_GET_INDEX: return "[get index]"; case CTG_TASK_GET_UDF: @@ -96,6 +100,9 @@ void ctgFreeSMetaData(SMetaData* pData) { taosArrayDestroy(pData->pQnodeList); pData->pQnodeList = NULL; + + taosArrayDestroy(pData->pTableCfg); + pData->pTableCfg = NULL; } void ctgFreeSCtgUserAuth(SCtgUserAuth *userCache) { @@ -280,6 +287,13 @@ void ctgFreeMsgCtx(SCtgMsgCtx* pCtx) { } break; } + case TDMT_VND_TABLE_CFG: + case TDMT_MND_TABLE_CFG: { + STableCfgRsp* pOut = (STableCfgRsp*)pCtx->out; + tFreeSTableCfgRsp(pOut); + taosMemoryFreeClear(pCtx->out); + break; + } case TDMT_MND_RETRIEVE_FUNC: { SFuncInfo* pOut = (SFuncInfo*)pCtx->out; taosMemoryFree(pOut->pCode); @@ -328,14 +342,151 @@ void ctgResetTbMetaTask(SCtgTask* pTask) { taosMemoryFreeClear(pTask->res); } -void ctgFreeTask(SCtgTask* pTask) { - ctgFreeMsgCtx(&pTask->msgCtx); - +void ctgFreeTaskRes(CTG_TASK_TYPE type, void **pRes) { + switch (type) { + case CTG_TASK_GET_QNODE: { + taosArrayDestroy((SArray*)*pRes); + *pRes = NULL; + break; + } + case CTG_TASK_GET_TB_META: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_DB_VGROUP: { + taosArrayDestroy((SArray*)*pRes); + *pRes = NULL; + break; + } + case CTG_TASK_GET_DB_CFG: { + if (*pRes) { + SDbCfgInfo* pInfo = (SDbCfgInfo*)*pRes; + taosArrayDestroy(pInfo->pRetensions); + taosMemoryFreeClear(*pRes); + } + break; + } + case CTG_TASK_GET_DB_INFO: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_TB_HASH: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_TB_INDEX: { + taosArrayDestroyEx(*pRes, tFreeSTableIndexInfo); + *pRes = NULL; + break; + } + case CTG_TASK_GET_TB_CFG: { + if (*pRes) { + STableCfg* pInfo = (STableCfg*)*pRes; + tFreeSTableCfgRsp(pInfo); + taosMemoryFreeClear(*pRes); + } + break; + } + case CTG_TASK_GET_INDEX: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_UDF: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_USER: { + taosMemoryFreeClear(*pRes); + break; + } + default: + qError("invalid task type %d", type); + break; + } +} + + +void ctgFreeSubTaskRes(CTG_TASK_TYPE type, void **pRes) { + switch (type) { + case CTG_TASK_GET_QNODE: { + taosArrayDestroy((SArray*)*pRes); + *pRes = NULL; + break; + } + case CTG_TASK_GET_TB_META: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_DB_VGROUP: { + if (*pRes) { + SDBVgInfo* pInfo = (SDBVgInfo*)*pRes; + taosHashCleanup(pInfo->vgHash); + taosMemoryFreeClear(*pRes); + } + break; + } + case CTG_TASK_GET_DB_CFG: { + if (*pRes) { + SDbCfgInfo* pInfo = (SDbCfgInfo*)*pRes; + taosArrayDestroy(pInfo->pRetensions); + taosMemoryFreeClear(*pRes); + } + break; + } + case CTG_TASK_GET_DB_INFO: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_TB_HASH: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_TB_INDEX: { + taosArrayDestroyEx(*pRes, tFreeSTableIndexInfo); + *pRes = NULL; + break; + } + case CTG_TASK_GET_TB_CFG: { + if (*pRes) { + STableCfg* pInfo = (STableCfg*)*pRes; + tFreeSTableCfgRsp(pInfo); + taosMemoryFreeClear(*pRes); + } + break; + } + case CTG_TASK_GET_INDEX: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_UDF: { + taosMemoryFreeClear(*pRes); + break; + } + case CTG_TASK_GET_USER: { + taosMemoryFreeClear(*pRes); + break; + } + default: + qError("invalid task type %d", type); + break; + } +} + + +void ctgClearSubTaskRes(SCtgSubRes *pRes) { + pRes->code = 0; + + if (NULL == pRes->res) { + return; + } + + ctgFreeSubTaskRes(pRes->type, &pRes->res); +} + +void ctgFreeTaskCtx(SCtgTask* pTask) { switch (pTask->type) { case CTG_TASK_GET_QNODE: { - taosArrayDestroy((SArray*)pTask->res); taosMemoryFreeClear(pTask->taskCtx); - pTask->res = NULL; break; } case CTG_TASK_GET_TB_META: { @@ -346,56 +497,49 @@ void ctgFreeTask(SCtgTask* pTask) { pTask->msgCtx.lastOut = NULL; } taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } case CTG_TASK_GET_DB_VGROUP: { - taosArrayDestroy((SArray*)pTask->res); taosMemoryFreeClear(pTask->taskCtx); - pTask->res = NULL; break; } case CTG_TASK_GET_DB_CFG: { taosMemoryFreeClear(pTask->taskCtx); - if (pTask->res) { - SDbCfgInfo* pInfo = (SDbCfgInfo*)pTask->res; - taosArrayDestroy(pInfo->pRetensions); - taosMemoryFreeClear(pTask->res); - } break; } case CTG_TASK_GET_DB_INFO: { taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } case CTG_TASK_GET_TB_HASH: { SCtgTbHashCtx* taskCtx = (SCtgTbHashCtx*)pTask->taskCtx; taosMemoryFreeClear(taskCtx->pName); taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } case CTG_TASK_GET_TB_INDEX: { SCtgTbIndexCtx* taskCtx = (SCtgTbIndexCtx*)pTask->taskCtx; taosMemoryFreeClear(taskCtx->pName); taosMemoryFreeClear(pTask->taskCtx); - taosArrayDestroyEx(pTask->res, tFreeSTableIndexInfo); + break; + } + case CTG_TASK_GET_TB_CFG: { + SCtgTbCfgCtx* taskCtx = (SCtgTbCfgCtx*)pTask->taskCtx; + taosMemoryFreeClear(taskCtx->pName); + taosMemoryFreeClear(taskCtx->pVgInfo); + taosMemoryFreeClear(pTask->taskCtx); break; } case CTG_TASK_GET_INDEX: { taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } case CTG_TASK_GET_UDF: { taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } case CTG_TASK_GET_USER: { taosMemoryFreeClear(pTask->taskCtx); - taosMemoryFreeClear(pTask->res); break; } default: @@ -404,6 +548,16 @@ void ctgFreeTask(SCtgTask* pTask) { } } + +void ctgFreeTask(SCtgTask* pTask) { + ctgFreeMsgCtx(&pTask->msgCtx); + ctgFreeTaskRes(pTask->type, &pTask->res); + ctgFreeTaskCtx(pTask); + + taosArrayDestroy(pTask->pParents); + ctgClearSubTaskRes(&pTask->subRes); +} + void ctgFreeTasks(SArray* pArray) { if (NULL == pArray) { return; diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 66dc2bcaaf..91c3628db2 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -16,6 +16,7 @@ #include "command.h" #include "catalog.h" #include "tdatablock.h" +#include "tglobal.h" static int32_t getSchemaBytes(const SSchema* pSchema) { switch (pSchema->type) { @@ -111,14 +112,435 @@ static int32_t execDescribe(SNode* pStmt, SRetrieveTableRsp** pRsp) { static int32_t execResetQueryCache() { return catalogClearCache(); } -static int32_t execShowCreateDatabase(SShowCreateDatabaseStmt* pStmt) { return TSDB_CODE_FAILED; } -static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt) { return TSDB_CODE_FAILED; } +static SSDataBlock* buildCreateDBResultDataBlock() { + SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); + pBlock->info.numOfCols = SHOW_CREATE_DB_RESULT_COLS; + pBlock->info.hasVarCol = true; -static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt) { return TSDB_CODE_FAILED; } + pBlock->pDataBlock = taosArrayInit(pBlock->info.numOfCols, sizeof(SColumnInfoData)); + + SColumnInfoData infoData = {0}; + infoData.info.type = TSDB_DATA_TYPE_VARCHAR; + infoData.info.bytes = SHOW_CREATE_DB_RESULT_FIELD1_LEN; + + taosArrayPush(pBlock->pDataBlock, &infoData); + + infoData.info.type = TSDB_DATA_TYPE_VARCHAR; + infoData.info.bytes = SHOW_CREATE_DB_RESULT_FIELD2_LEN; + taosArrayPush(pBlock->pDataBlock, &infoData); + + return pBlock; +} + +int64_t getValOfDiffPrecision(int8_t unit, int64_t val) { + int64_t v = 0; + switch (unit) { + case 's': + v = val / 1000; + break; + case 'm': + v = val / tsTickPerMin[TSDB_TIME_PRECISION_MILLI]; + break; + case 'h': + v = val / (tsTickPerMin[TSDB_TIME_PRECISION_MILLI] * 60); + break; + case 'd': + v = val / (tsTickPerMin[TSDB_TIME_PRECISION_MILLI] * 24 * 60); + break; + case 'w': + v = val / (tsTickPerMin[TSDB_TIME_PRECISION_MILLI] * 24 * 60 * 7); + break; + default: + break; + } + + return v; +} + +char *buildRetension(SArray *pRetension) { + size_t size = taosArrayGetSize(pRetension); + if (size == 0) { + return NULL; + } + + char *p1 = taosMemoryCalloc(1, 100); + SRetention *p = taosArrayGet(pRetension, 0); + + int32_t len = 0; + + int64_t v1 = getValOfDiffPrecision(p->freqUnit, p->freq); + int64_t v2 = getValOfDiffPrecision(p->keepUnit, p->keep); + len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + + if (size > 1) { + len += sprintf(p1 + len, ","); + p = taosArrayGet(pRetension, 1); + + v1 = getValOfDiffPrecision(p->freqUnit, p->freq); + v2 = getValOfDiffPrecision(p->keepUnit, p->keep); + len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + } + + if (size > 2) { + len += sprintf(p1 + len, ","); + p = taosArrayGet(pRetension, 2); + + v1 = getValOfDiffPrecision(p->freqUnit, p->freq); + v2 = getValOfDiffPrecision(p->keepUnit, p->keep); + len += sprintf(p1 + len, "%" PRId64 "%c:%" PRId64 "%c", v1, p->freqUnit, v2, p->keepUnit); + } + + return p1; +} + + +static void setCreateDBResultIntoDataBlock(SSDataBlock* pBlock, char *dbFName, SDbCfgInfo* pCfg) { + blockDataEnsureCapacity(pBlock, 1); + pBlock->info.rows = 1; + + SColumnInfoData* pCol1 = taosArrayGet(pBlock->pDataBlock, 0); + char buf1[SHOW_CREATE_DB_RESULT_FIELD1_LEN] = {0}; + STR_TO_VARSTR(buf1, dbFName); + colDataAppend(pCol1, 0, buf1, false); + + SColumnInfoData* pCol2 = taosArrayGet(pBlock->pDataBlock, 1); + char buf2[SHOW_CREATE_DB_RESULT_FIELD2_LEN] = {0}; + int32_t len = 0; + char *prec = NULL; + switch (pCfg->precision) { + case TSDB_TIME_PRECISION_MILLI: + prec = TSDB_TIME_PRECISION_MILLI_STR; + break; + case TSDB_TIME_PRECISION_MICRO: + prec = TSDB_TIME_PRECISION_MICRO_STR; + break; + case TSDB_TIME_PRECISION_NANO: + prec = TSDB_TIME_PRECISION_NANO_STR; + break; + default: + prec = "none"; + break; + } + + char *retentions = buildRetension(pCfg->pRetensions); + + len += sprintf(buf2 + VARSTR_HEADER_SIZE, "CREATE DATABASE `%s` BUFFER %d CACHELAST %d COMP %d DURATION %dm " + "FSYNC %d MAXROWS %d MINROWS %d KEEP %dm,%dm,%dm PAGES %d PAGESIZE %d PRECISION '%s' REPLICA %d " + "STRICT %d WAL %d VGROUPS %d SINGLE_STABLE %d", + dbFName, pCfg->buffer, pCfg->cacheLastRow, pCfg->compression, pCfg->daysPerFile, + pCfg->fsyncPeriod, pCfg->maxRows, pCfg->minRows, pCfg->daysToKeep0, pCfg->daysToKeep1, pCfg->daysToKeep2, + pCfg->pages, pCfg->pageSize, prec, pCfg->replications, pCfg->strict, pCfg->walLevel, pCfg->numOfVgroups, + 1 == pCfg->numOfStables); + + if (retentions) { + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, " RETENTIONS %s", retentions); + taosMemoryFree(retentions); + } + + (varDataLen(buf2)) = len; + + colDataAppend(pCol2, 0, buf2, false); +} + + +static int32_t execShowCreateDatabase(SShowCreateDatabaseStmt* pStmt, SRetrieveTableRsp** pRsp) { + SSDataBlock* pBlock = buildCreateDBResultDataBlock(); + setCreateDBResultIntoDataBlock(pBlock, pStmt->dbName, pStmt->pCfg); + + size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock); + *pRsp = taosMemoryCalloc(1, rspSize); + if (NULL == *pRsp) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + (*pRsp)->useconds = 0; + (*pRsp)->completed = 1; + (*pRsp)->precision = 0; + (*pRsp)->compressed = 0; + (*pRsp)->compLen = 0; + (*pRsp)->numOfRows = htonl(1); + (*pRsp)->numOfCols = htonl(SHOW_CREATE_DB_RESULT_COLS); + + int32_t len = 0; + blockCompressEncode(pBlock, (*pRsp)->data, &len, SHOW_CREATE_DB_RESULT_COLS, false); + ASSERT(len == rspSize - sizeof(SRetrieveTableRsp)); + + blockDataDestroy(pBlock); + return TSDB_CODE_SUCCESS; +} + +static SSDataBlock* buildCreateTbResultDataBlock() { + SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); + pBlock->info.numOfCols = SHOW_CREATE_TB_RESULT_COLS; + pBlock->info.hasVarCol = true; + + pBlock->pDataBlock = taosArrayInit(pBlock->info.numOfCols, sizeof(SColumnInfoData)); + + SColumnInfoData infoData = {0}; + infoData.info.type = TSDB_DATA_TYPE_VARCHAR; + infoData.info.bytes = SHOW_CREATE_TB_RESULT_FIELD1_LEN; + + taosArrayPush(pBlock->pDataBlock, &infoData); + + infoData.info.type = TSDB_DATA_TYPE_VARCHAR; + infoData.info.bytes = SHOW_CREATE_TB_RESULT_FIELD2_LEN; + taosArrayPush(pBlock->pDataBlock, &infoData); + + return pBlock; +} + +void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) { + for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { + SSchema* pSchema = pCfg->pSchemas + i; + char type[32]; + sprintf(type, "%s", tDataTypes[pSchema->type].name); + if (TSDB_DATA_TYPE_VARCHAR == pSchema->type) { + sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); + } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { + sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE)); + } + + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + } +} + +void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) { + for (int32_t i = 0; i < pCfg->numOfTags; ++i) { + SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; + char type[32]; + sprintf(type, "%s", tDataTypes[pSchema->type].name); + if (TSDB_DATA_TYPE_VARCHAR == pSchema->type) { + sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); + } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { + sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE)); + } + + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + } +} + + +void appendTagNameFields(char* buf, int32_t* len, STableCfg* pCfg) { + for (int32_t i = 0; i < pCfg->numOfTags; ++i) { + SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s`", ((i > 0) ? ", " : ""), pSchema->name); + } +} + + +int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) { + SArray *pTagVals = NULL; + STag *pTag = (STag*)pCfg->pTags; + + if (pCfg->pTags && pTag->flags & TD_TAG_JSON) { + char *pJson = parseTagDatatoJson(pTag); + if (pJson) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s", pJson); + taosMemoryFree(pJson); + } + + return TSDB_CODE_SUCCESS; + } + + int32_t code = tTagToValArray((const STag *)pCfg->pTags, &pTagVals); + if (code) { + return code; + } + + int16_t valueNum = taosArrayGetSize(pTagVals); + int32_t num = 0; + int32_t j = 0; + for (int32_t i = 0; i < pCfg->numOfTags; ++i) { + SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; + if (i > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ", "); + } + + if (j >= valueNum) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "NULL"); + continue; + } + + STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, j); + if (pSchema->colId > pTagVal->cid) { + qError("tag value and column mismatch, schemaId:%d, valId:%d", pSchema->colId, pTagVal->cid); + taosArrayDestroy(pTagVals); + return TSDB_CODE_APP_ERROR; + } else if (pSchema->colId == pTagVal->cid) { + char type = pTagVal->type; + int32_t tlen = 0; + + if (IS_VAR_DATA_TYPE(type)) { + dataConverToStr(buf + VARSTR_HEADER_SIZE + *len, type, pTagVal->pData, pTagVal->nData, &tlen); + } else { + dataConverToStr(buf + VARSTR_HEADER_SIZE + *len, type, &pTagVal->i64, tDataTypes[type].bytes, &tlen); + } + *len += tlen; + j++; + } else { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "NULL"); + } + + + /* + if (type == TSDB_DATA_TYPE_BINARY) { + if (pTagVal->nData > 0) { + if (num) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ", "); + } + + memcpy(buf + VARSTR_HEADER_SIZE + *len, pTagVal->pData, pTagVal->nData); + *len += pTagVal->nData; + } + } else if (type == TSDB_DATA_TYPE_NCHAR) { + if (pTagVal->nData > 0) { + if (num) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ", "); + } + int32_t tlen = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, buf + VARSTR_HEADER_SIZE + *len); + } + } else if (type == TSDB_DATA_TYPE_DOUBLE) { + double val = *(double *)(&pTagVal->i64); + int len = 0; + term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len); + } else if (type == TSDB_DATA_TYPE_BOOL) { + int val = *(int *)(&pTagVal->i64); + int len = 0; + term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_INT, key, nKey, (const char *)&val, len); + } + */ + } + + taosArrayDestroy(pTagVals); + + return TSDB_CODE_SUCCESS; +} + +void appendTableOptions(char* buf, int32_t* len, STableCfg* pCfg) { + if (pCfg->commentLen > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " COMMENT '%s'", pCfg->pComment); + } else if (0 == pCfg->commentLen) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " COMMENT ''"); + } + + if (pCfg->watermark1 > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " WATERMARK %" PRId64 "a", pCfg->watermark1); + if (pCfg->watermark2 > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ", %" PRId64 "a", pCfg->watermark2); + } + } + + if (pCfg->delay1 > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " MAX_DELAY %" PRId64 "a", pCfg->delay1); + if (pCfg->delay2 > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ", %" PRId64 "a", pCfg->delay2); + } + } + + int32_t funcNum = taosArrayGetSize(pCfg->pFuncs); + if (funcNum > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " ROLLUP("); + for (int32_t i = 0; i < funcNum; ++i) { + char* pFunc = taosArrayGet(pCfg->pFuncs, i); + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s%s", ((i > 0) ? ", " : ""), pFunc); + } + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, ")"); + } + + if (pCfg->ttl > 0) { + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " TTL %d", pCfg->ttl); + } +} + +static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, char *tbName, STableCfg* pCfg) { + int32_t code = 0; + blockDataEnsureCapacity(pBlock, 1); + pBlock->info.rows = 1; + + SColumnInfoData* pCol1 = taosArrayGet(pBlock->pDataBlock, 0); + char buf1[SHOW_CREATE_TB_RESULT_FIELD1_LEN] = {0}; + STR_TO_VARSTR(buf1, tbName); + colDataAppend(pCol1, 0, buf1, false); + + SColumnInfoData* pCol2 = taosArrayGet(pBlock->pDataBlock, 1); + char buf2[SHOW_CREATE_TB_RESULT_FIELD2_LEN] = {0}; + int32_t len = 0; + + if (TSDB_SUPER_TABLE == pCfg->tableType) { + len += sprintf(buf2 + VARSTR_HEADER_SIZE, "CREATE STABLE `%s` (", tbName); + appendColumnFields(buf2, &len, pCfg); + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, ") TAGS ("); + appendTagFields(buf2, &len, pCfg); + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, ")"); + appendTableOptions(buf2, &len, pCfg); + } else if (TSDB_CHILD_TABLE == pCfg->tableType) { + len += sprintf(buf2 + VARSTR_HEADER_SIZE, "CREATE TABLE `%s` USING `%s` (", tbName, pCfg->stbName); + appendTagNameFields(buf2, &len, pCfg); + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, ") TAGS ("); + code = appendTagValues(buf2, &len, pCfg); + if (code) { + return code; + } + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, ")"); + appendTableOptions(buf2, &len, pCfg); + } else { + len += sprintf(buf2 + VARSTR_HEADER_SIZE, "CREATE TABLE `%s` (", tbName); + appendColumnFields(buf2, &len, pCfg); + len += sprintf(buf2 + VARSTR_HEADER_SIZE + len, ")"); + } + + varDataLen(buf2) = len; + + colDataAppend(pCol2, 0, buf2, false); + + return TSDB_CODE_SUCCESS; +} + + +static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) { + SSDataBlock* pBlock = buildCreateTbResultDataBlock(); + int32_t code = setCreateTBResultIntoDataBlock(pBlock, pStmt->tableName, pStmt->pCfg); + if (code) { + return code; + } + + size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock); + *pRsp = taosMemoryCalloc(1, rspSize); + if (NULL == *pRsp) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + (*pRsp)->useconds = 0; + (*pRsp)->completed = 1; + (*pRsp)->precision = 0; + (*pRsp)->compressed = 0; + (*pRsp)->compLen = 0; + (*pRsp)->numOfRows = htonl(1); + (*pRsp)->numOfCols = htonl(SHOW_CREATE_TB_RESULT_COLS); + + int32_t len = 0; + blockCompressEncode(pBlock, (*pRsp)->data, &len, SHOW_CREATE_TB_RESULT_COLS, false); + ASSERT(len == rspSize - sizeof(SRetrieveTableRsp)); + + blockDataDestroy(pBlock); + return TSDB_CODE_SUCCESS; +} + +static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) { + STableCfg* pCfg = (STableCfg*)pStmt->pCfg; + if (TSDB_SUPER_TABLE != pCfg->tableType) { + terrno = TSDB_CODE_TSC_NOT_STABLE_ERROR; + return terrno; + } + + return execShowCreateTable(pStmt, pRsp); +} static int32_t execAlterLocal(SAlterLocalStmt* pStmt) { return TSDB_CODE_FAILED; } +static int32_t execShowLocalVariables() { return TSDB_CODE_FAILED; } + int32_t qExecCommand(SNode* pStmt, SRetrieveTableRsp** pRsp) { switch (nodeType(pStmt)) { case QUERY_NODE_DESCRIBE_STMT: @@ -126,13 +548,15 @@ int32_t qExecCommand(SNode* pStmt, SRetrieveTableRsp** pRsp) { case QUERY_NODE_RESET_QUERY_CACHE_STMT: return execResetQueryCache(); case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: - return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt); + return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp); case QUERY_NODE_SHOW_CREATE_TABLE_STMT: - return execShowCreateTable((SShowCreateTableStmt*)pStmt); + return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp); case QUERY_NODE_SHOW_CREATE_STABLE_STMT: - return execShowCreateSTable((SShowCreateTableStmt*)pStmt); + return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp); case QUERY_NODE_ALTER_LOCAL_STMT: return execAlterLocal((SAlterLocalStmt*)pStmt); + case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT: + return execShowLocalVariables(); default: break; } diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index 091f300428..ef4ac0b639 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -184,8 +184,8 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo pPhysiChildren = indefPhysiNode->node.pChildren; break; } - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: { - SMergeIntervalPhysiNode *intPhysiNode = (SMergeIntervalPhysiNode *)pNode; + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: { + SMergeAlignedIntervalPhysiNode *intPhysiNode = (SMergeAlignedIntervalPhysiNode *)pNode; pPhysiChildren = intPhysiNode->window.node.pChildren; break; } @@ -841,8 +841,8 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i } break; } - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: { - SMergeIntervalPhysiNode *pIntNode = (SMergeIntervalPhysiNode *)pNode; + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: { + SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode; EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk)); EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); if (pResNode->pExecInfo) { diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 5761c0be78..5128148221 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -733,6 +733,10 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprI SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, + SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId, + SExecTaskInfo* pTaskInfo); + SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild); SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, diff --git a/source/libs/executor/inc/tsort.h b/source/libs/executor/inc/tsort.h index 363f379ee4..35bdd4ee55 100644 --- a/source/libs/executor/inc/tsort.h +++ b/source/libs/executor/inc/tsort.h @@ -50,6 +50,7 @@ typedef struct SMsortComparParam { void **pSources; int32_t numOfSources; SArray *orderInfo; // SArray + bool cmpGroupId; } SMsortComparParam; typedef struct SSortHandle SSortHandle; @@ -99,6 +100,11 @@ int32_t tsortSetFetchRawDataFp(SSortHandle* pHandle, _sort_fetch_block_fn_t fetc */ int32_t tsortSetComparFp(SSortHandle* pHandle, _sort_merge_compar_fn_t fp); +/** + * + */ +int32_t tsortSetCompareGroupId(SSortHandle* pHandle, bool compareGroupId); + /** * * @param pHandle diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 72c480a81b..0c6e7fe5f6 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -2755,7 +2755,7 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t goto _error; } - size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; code = doInitAggInfoSup(&pInfo->aggSup, pOperator->exprSupp.pCtx, num, keyBufSize, pTaskInfo->id.str); if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -2777,9 +2777,9 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t pOperator->name = "SortedMerge"; // pOperator->operatorType = OP_SortedMerge; - pOperator->blocking = true; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; pOperator->pTaskInfo = pTaskInfo; pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo, @@ -2834,8 +2834,8 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SAggOperatorInfo* pAggInfo = pOperator->info; - SExprSupp* pSup = &pOperator->exprSupp; - SOperatorInfo* downstream = pOperator->pDownstream[0]; + SExprSupp* pSup = &pOperator->exprSupp; + SOperatorInfo* downstream = pOperator->pDownstream[0]; int64_t st = taosGetTimestampUs(); @@ -3726,9 +3726,9 @@ SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhy SExprInfo* pExprInfo = createExprInfo(pPhyNode->pFuncs, NULL, &numOfExpr); if (pPhyNode->pExprs != NULL) { - int32_t num = 0; + int32_t num = 0; SExprInfo* pSExpr = createExprInfo(pPhyNode->pExprs, NULL, &num); - int32_t code = initExprSupp(&pInfo->scalarSup, pSExpr, num); + int32_t code = initExprSupp(&pInfo->scalarSup, pSExpr, num); if (code != TSDB_CODE_SUCCESS) { goto _error; } @@ -3751,14 +3751,14 @@ SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhy setFunctionResultOutput(pOperator, &pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, numOfExpr); - pInfo->binfo.pRes = pResBlock; - pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pSup->pCtx, numOfExpr); + pInfo->binfo.pRes = pResBlock; + pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pSup->pCtx, numOfExpr); pOperator->name = "IndefinitOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT; - pOperator->blocking = false; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; pOperator->exprSupp.numOfExprs = numOfExpr; pOperator->pTaskInfo = pTaskInfo; @@ -3828,10 +3828,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pOperator->blocking = false; pOperator->status = OP_NOT_OPENED; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL; - pOperator->exprSupp.pExprInfo = pExprInfo; - pOperator->exprSupp.numOfExprs = num; - pOperator->info = pInfo; - pOperator->pTaskInfo = pTaskInfo; + pOperator->exprSupp.pExprInfo = pExprInfo; + pOperator->exprSupp.numOfExprs = num; + pOperator->info = pInfo; + pOperator->pTaskInfo = pTaskInfo; pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo, NULL, NULL, NULL); @@ -4077,7 +4077,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo return createTagScanOperatorInfo(pHandle, pScanPhyNode, pTableListInfo, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN == type) { - SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*) pPhyNode; + SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*)pPhyNode; pTableListInfo->pTableList = taosArrayInit(4, sizeof(STableKeyInfo)); if (pBlockNode->tableType == TSDB_SUPER_TABLE) { @@ -4180,6 +4180,21 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, &as, pTaskInfo, isStream); + } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL == type) { + SMergeAlignedIntervalPhysiNode* pIntervalPhyNode = (SMergeAlignedIntervalPhysiNode*)pPhyNode; + + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &num); + SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc); + + SInterval interval = {.interval = pIntervalPhyNode->interval, + .sliding = pIntervalPhyNode->sliding, + .intervalUnit = pIntervalPhyNode->intervalUnit, + .slidingUnit = pIntervalPhyNode->slidingUnit, + .offset = pIntervalPhyNode->offset, + .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision}; + + int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + pOptr = createMergeAlignedIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL == type) { SMergeIntervalPhysiNode* pIntervalPhyNode = (SMergeIntervalPhysiNode*)pPhyNode; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 8c6797759e..49e821a71a 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -112,12 +112,12 @@ static void getNextTimeWindow(SInterval* pInterval, STimeWindow* tw, int32_t ord int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor); tm.tm_year = mon / 12; tm.tm_mon = mon % 12; - tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pInterval->precision); + tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision); mon = (int)(mon + interval); tm.tm_year = mon / 12; tm.tm_mon = mon % 12; - tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pInterval->precision); + tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision); tw->ekey -= 1; } @@ -906,7 +906,6 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { // NOTE: this operator does never check if current status is done or not SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamBlockScanInfo* pInfo = pOperator->info; - int32_t rows = 0; pTaskInfo->code = pOperator->fpSet._openFn(pOperator); if (pTaskInfo->code != TSDB_CODE_SUCCESS || pOperator->status == OP_EXEC_DONE) { @@ -1027,9 +1026,6 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { pTaskInfo->code = terrno; return NULL; } - - rows = pBlockInfo->rows; - // currently only the tbname pseudo column if (pInfo->numOfPseudoExpr > 0) { addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes); @@ -1037,14 +1033,16 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { doFilter(pInfo->pCondition, pInfo->pRes); blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex); - break; + if (pBlockInfo->rows > 0) { + break; + } } // record the scan action. pInfo->numOfExec++; pOperator->resultInfo.totalRows += pBlockInfo->rows; - if (rows == 0) { + if (pBlockInfo->rows == 0) { pOperator->status = OP_EXEC_DONE; } else if (pInfo->pUpdateInfo) { pInfo->tsArrayIndex = 0; @@ -1060,7 +1058,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { } } - return (rows == 0) ? NULL : pInfo->pRes; + return (pBlockInfo->rows == 0) ? NULL : pInfo->pRes; } } diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index feb81b1708..a69f11f51d 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -22,10 +22,11 @@ static int32_t getExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain static void destroyOrderOperatorInfo(void* param, int32_t numOfOutput); -SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortPhyNode, + SExecTaskInfo* pTaskInfo) { SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL/* || rowSize > 100 * 1024 * 1024*/) { + if (pInfo == NULL || pOperator == NULL /* || rowSize > 100 * 1024 * 1024*/) { goto _error; } @@ -44,16 +45,17 @@ SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* initResultSizeInfo(pOperator, 1024); - pInfo->pSortInfo = createSortInfo(pSortPhyNode->pSortKeys);; - pInfo->pColMatchInfo = pColMatchColInfo; - pOperator->name = "SortOperator"; + pInfo->pSortInfo = createSortInfo(pSortPhyNode->pSortKeys); + ; + pInfo->pColMatchInfo = pColMatchColInfo; + pOperator->name = "SortOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT; - pOperator->blocking = true; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; - pOperator->exprSupp.pExprInfo = pExprInfo; - pOperator->exprSupp.numOfExprs = numOfCols; - pOperator->pTaskInfo = pTaskInfo; + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + pOperator->exprSupp.pExprInfo = pExprInfo; + pOperator->exprSupp.numOfExprs = numOfCols; + pOperator->pTaskInfo = pTaskInfo; // lazy evaluation for the following parameter since the input datablock is not known till now. // pInfo->bufPageSize = rowSize < 1024 ? 1024 * 2 : rowSize * 2; @@ -147,8 +149,8 @@ void applyScalarFunction(SSDataBlock* pBlock, void* param) { SOperatorInfo* pOperator = param; SSortOperatorInfo* pSort = pOperator->info; if (pOperator->exprSupp.pExprInfo != NULL) { - int32_t code = - projectApplyFunctions(pOperator->exprSupp.pExprInfo, pBlock, pBlock, pOperator->exprSupp.pCtx, pOperator->exprSupp.numOfExprs, NULL); + int32_t code = projectApplyFunctions(pOperator->exprSupp.pExprInfo, pBlock, pBlock, pOperator->exprSupp.pCtx, + pOperator->exprSupp.numOfExprs, NULL); if (code != TSDB_CODE_SUCCESS) { longjmp(pOperator->pTaskInfo->env, code); } @@ -166,8 +168,7 @@ 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); tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, applyScalarFunction, pOperator); @@ -233,6 +234,265 @@ int32_t getExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* return TSDB_CODE_SUCCESS; } +//===================================================================================== +// Group Sort Operator +typedef enum EChildOperatorStatus { CHILD_OP_NEW_GROUP, CHILD_OP_SAME_GROUP, CHILD_OP_FINISHED } EChildOperatorStatus; + +typedef struct SGroupSortOperatorInfo { + SOptrBasicInfo binfo; + SArray* pSortInfo; + SArray* pColMatchInfo; + + int64_t startTs; + uint64_t sortElapsed; + bool hasGroupId; + uint64_t currGroupId; + + SSDataBlock* prefetchedSortInput; + SSortHandle* pCurrSortHandle; + EChildOperatorStatus childOpStatus; + + SSortExecInfo sortExecInfo; +} SGroupSortOperatorInfo; + +SSDataBlock* getGroupSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, + SArray* pColMatchInfo, SGroupSortOperatorInfo* pInfo) { + blockDataCleanup(pDataBlock); + + SSDataBlock* p = tsortGetSortedDataBlock(pHandle); + if (p == NULL) { + return NULL; + } + + blockDataEnsureCapacity(p, capacity); + + while (1) { + STupleHandle* pTupleHandle = tsortNextTuple(pHandle); + if (pTupleHandle == NULL) { + break; + } + + appendOneRowToDataBlock(p, pTupleHandle); + if (p->info.rows >= capacity) { + break; + } + } + + if (p->info.rows > 0) { + int32_t numOfCols = taosArrayGetSize(pColMatchInfo); + for (int32_t i = 0; i < numOfCols; ++i) { + SColMatchInfo* pmInfo = taosArrayGet(pColMatchInfo, i); + ASSERT(pmInfo->matchType == COL_MATCH_FROM_SLOT_ID); + + SColumnInfoData* pSrc = taosArrayGet(p->pDataBlock, pmInfo->srcSlotId); + SColumnInfoData* pDst = taosArrayGet(pDataBlock->pDataBlock, pmInfo->targetSlotId); + colDataAssign(pDst, pSrc, p->info.rows); + } + + pDataBlock->info.rows = p->info.rows; + pDataBlock->info.capacity = p->info.rows; + } + + blockDataDestroy(p); + return (pDataBlock->info.rows > 0) ? pDataBlock : NULL; +} + +typedef struct SGroupSortSourceParam { + SOperatorInfo* childOpInfo; + SGroupSortOperatorInfo* grpSortOpInfo; +} SGroupSortSourceParam; + +SSDataBlock* fetchNextGroupSortDataBlock(void* param) { + SGroupSortSourceParam* source = param; + SGroupSortOperatorInfo* grpSortOpInfo = source->grpSortOpInfo; + if (grpSortOpInfo->prefetchedSortInput) { + SSDataBlock* block = grpSortOpInfo->prefetchedSortInput; + grpSortOpInfo->prefetchedSortInput = NULL; + return block; + } else { + SOperatorInfo* childOp = source->childOpInfo; + SSDataBlock* block = childOp->fpSet.getNextFn(childOp); + if (block != NULL) { + if (block->info.groupId == grpSortOpInfo->currGroupId) { + grpSortOpInfo->childOpStatus = CHILD_OP_SAME_GROUP; + return block; + } else { + grpSortOpInfo->childOpStatus = CHILD_OP_NEW_GROUP; + grpSortOpInfo->prefetchedSortInput = block; + return NULL; + } + } else { + grpSortOpInfo->childOpStatus = CHILD_OP_FINISHED; + return NULL; + } + } +} + +int32_t beginSortGroup(SOperatorInfo* pOperator) { + SGroupSortOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + // pInfo->binfo.pRes is not equalled to the input datablock. + pInfo->pCurrSortHandle = + tsortCreateSortHandle(pInfo->pSortInfo, SORT_SINGLESOURCE_SORT, -1, -1, NULL, pTaskInfo->id.str); + + tsortSetFetchRawDataFp(pInfo->pCurrSortHandle, fetchNextGroupSortDataBlock, applyScalarFunction, pOperator); + + SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource)); + SGroupSortSourceParam* param = taosMemoryCalloc(1, sizeof(SGroupSortSourceParam)); + param->childOpInfo = pOperator->pDownstream[0]; + param->grpSortOpInfo = pInfo; + ps->param = param; + tsortAddSource(pInfo->pCurrSortHandle, ps); + + int32_t code = tsortOpen(pInfo->pCurrSortHandle); + taosMemoryFreeClear(ps); + + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, terrno); + } + + return TSDB_CODE_SUCCESS; +} + +int32_t finishSortGroup(SOperatorInfo* pOperator) { + SGroupSortOperatorInfo* pInfo = pOperator->info; + + SSortExecInfo sortExecInfo = tsortGetSortExecInfo(pInfo->pCurrSortHandle); + pInfo->sortExecInfo.sortMethod = sortExecInfo.sortMethod; + pInfo->sortExecInfo.sortBuffer = sortExecInfo.sortBuffer; + pInfo->sortExecInfo.loops += sortExecInfo.loops; + pInfo->sortExecInfo.readBytes += sortExecInfo.readBytes; + pInfo->sortExecInfo.writeBytes += sortExecInfo.writeBytes; + if (pInfo->pCurrSortHandle != NULL) { + tsortDestroySortHandle(pInfo->pCurrSortHandle); + } + pInfo->pCurrSortHandle = NULL; + return TSDB_CODE_SUCCESS; +} + +SSDataBlock* doGroupSort(SOperatorInfo* pOperator) { + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SGroupSortOperatorInfo* pInfo = pOperator->info; + + int32_t code = pOperator->fpSet._openFn(pOperator); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + + if (!pInfo->hasGroupId) { + pInfo->hasGroupId = true; + + pInfo->prefetchedSortInput = pOperator->pDownstream[0]->fpSet.getNextFn(pOperator->pDownstream[0]); + pInfo->currGroupId = pInfo->prefetchedSortInput->info.groupId; + pInfo->childOpStatus = CHILD_OP_NEW_GROUP; + beginSortGroup(pOperator); + } + + SSDataBlock* pBlock = NULL; + while (pInfo->pCurrSortHandle != NULL) { + // beginSortGroup would fetch all child blocks of pInfo->currGroupId; + ASSERT(pInfo->childOpStatus != CHILD_OP_SAME_GROUP); + pBlock = getGroupSortedBlockData(pInfo->pCurrSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, + pInfo->pColMatchInfo, pInfo); + if (pBlock != NULL) { + pBlock->info.groupId = pInfo->currGroupId; + pOperator->resultInfo.totalRows += pBlock->info.rows; + return pBlock; + } else { + if (pInfo->childOpStatus == CHILD_OP_NEW_GROUP) { + finishSortGroup(pOperator); + pInfo->currGroupId = pInfo->prefetchedSortInput->info.groupId; + beginSortGroup(pOperator); + } else if (pInfo->childOpStatus == CHILD_OP_FINISHED) { + finishSortGroup(pOperator); + doSetOperatorCompleted(pOperator); + return NULL; + } + } + } + return NULL; +} + +int32_t getGroupSortExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) { + SGroupSortOperatorInfo* pInfo = (SGroupSortOperatorInfo*)pOptr->info; + *pOptrExplain = &pInfo->sortExecInfo; + *len = sizeof(SSortExecInfo); + return TSDB_CODE_SUCCESS; +} + +// TODO: +SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SSortPhysiNode* pSortPhyNode, + SExecTaskInfo* pTaskInfo) { + SSortOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SSortOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL /* || rowSize > 100 * 1024 * 1024*/) { + goto _error; + } + + SDataBlockDescNode* pDescNode = pSortPhyNode->node.pOutputDataBlockDesc; + + int32_t numOfCols = 0; + SSDataBlock* pResBlock = createResDataBlock(pDescNode); + SExprInfo* pExprInfo = createExprInfo(pSortPhyNode->pExprs, NULL, &numOfCols); + + int32_t numOfOutputCols = 0; + SArray* pColMatchColInfo = + extractColMatchInfo(pSortPhyNode->pTargets, pDescNode, &numOfOutputCols, COL_MATCH_FROM_SLOT_ID); + + pOperator->exprSupp.pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pOperator->exprSupp.rowEntryInfoOffset); + pInfo->binfo.pRes = pResBlock; + + initResultSizeInfo(pOperator, 1024); + + pInfo->pSortInfo = createSortInfo(pSortPhyNode->pSortKeys); + ; + pInfo->pColMatchInfo = pColMatchColInfo; + pOperator->name = "GroupSortOperator"; + // TODO + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT; + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + pOperator->exprSupp.pExprInfo = pExprInfo; + pOperator->exprSupp.numOfExprs = numOfCols; + pOperator->pTaskInfo = pTaskInfo; + + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doGroupSort, NULL, NULL, destroyOrderOperatorInfo, NULL, + NULL, getGroupSortExplainExecInfo); + + int32_t code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY; + taosMemoryFree(pInfo); + taosMemoryFree(pOperator); + return NULL; +} + +void destroyGroupSortOperatorInfo(void* param, int32_t numOfOutput) { + SGroupSortOperatorInfo* pInfo = (SGroupSortOperatorInfo*)param; + pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes); + + taosArrayDestroy(pInfo->pSortInfo); + taosArrayDestroy(pInfo->pColMatchInfo); +} + +// TODO: sort group +// TODO: msortCompare compare group id in multiway merge sort. +// TODO: table merge scan, group first, then for each group, multiple readers + +//===================================================================================== +// Multiway Sort Merge operator typedef struct SMultiwaySortMergeOperatorInfo { SOptrBasicInfo binfo; @@ -260,11 +520,12 @@ int32_t doOpenMultiwaySortMergeOperator(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->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage, + pInfo->pInputBlock, pTaskInfo->id.str); tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL); - + tsortSetCompareGroupId(pInfo->pSortHandle, true); + for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) { SSortSource* ps = taosMemoryCalloc(1, sizeof(SSortSource)); ps->param = pOperator->pDownstream[i]; @@ -287,7 +548,7 @@ int32_t doOpenMultiwaySortMergeOperator(SOperatorInfo* pOperator) { SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo, SOperatorInfo* pOperator) { SMultiwaySortMergeOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; blockDataCleanup(pDataBlock); @@ -388,24 +649,23 @@ SOperatorInfo* createMultiwaySortMergeOperatorInfo(SOperatorInfo** downStreams, goto _error; } - initResultSizeInfo(pOperator, 1024); - pInfo->binfo.pRes = pResBlock; - pInfo->pSortInfo = pSortInfo; + pInfo->binfo.pRes = pResBlock; + pInfo->pSortInfo = pSortInfo; pInfo->pColMatchInfo = pColMatchColInfo; - pInfo->pInputBlock = pInputBlock; - pOperator->name = "MultiwaySortMerge"; + pInfo->pInputBlock = pInputBlock; + pOperator->name = "MultiwaySortMerge"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_MERGE; - pOperator->blocking = false; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; pOperator->pTaskInfo = pTaskInfo; - pInfo->bufPageSize = getProperSortPageSize(rowSize); + pInfo->bufPageSize = getProperSortPageSize(rowSize); // one additional is reserved for merged result. - pInfo->sortBufSize = pInfo->bufPageSize * (numStreams + 1); + pInfo->sortBufSize = pInfo->bufPageSize * (numStreams + 1); pOperator->fpSet = createOperatorFpSet(doOpenMultiwaySortMergeOperator, doMultiwaySortMerge, NULL, NULL, @@ -422,4 +682,4 @@ _error: taosMemoryFree(pInfo); taosMemoryFree(pOperator); return NULL; -} \ No newline at end of file +} diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 2dbdbd7069..510e393615 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -16,8 +16,8 @@ #include "function.h" #include "functionMgt.h" #include "tdatablock.h" -#include "ttime.h" #include "tfill.h" +#include "ttime.h" typedef enum SResultTsInterpType { RESULT_ROW_START_INTERP = 1, @@ -42,7 +42,7 @@ static void doCloseWindow(SResultRowInfo* pResultRowInfo, const SIntervalAggOper // * merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there // * is a previous result generated or not. // */ -//static void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) { +// static void setIntervalQueryRange(STableQueryInfo* pTableQueryInfo, TSKEY key, STimeWindow* pQRange) { // // do nothing //} @@ -314,18 +314,18 @@ static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t o int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor); tm.tm_year = mon / 12; tm.tm_mon = mon % 12; - tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision); + tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision); mon = (int)(mon + interval); tm.tm_year = mon / 12; tm.tm_mon = mon % 12; - tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, precision); + tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision); tw->ekey -= 1; } -void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, - TSKEY curTs, int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) { +void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs, + int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) { SqlFunctionCtx* pCtx = pSup->pCtx; int32_t index = 1; @@ -405,8 +405,8 @@ static void setNotInterpoWindowKey(SqlFunctionCtx* pCtx, int32_t numOfOutput, in } } -static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, int32_t pos, SSDataBlock* pBlock, const TSKEY* tsCols, - STimeWindow* win, SExprSupp* pSup) { +static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, int32_t pos, SSDataBlock* pBlock, + const TSKEY* tsCols, STimeWindow* win, SExprSupp* pSup) { bool ascQuery = (pInfo->order == TSDB_ORDER_ASC); TSKEY curTs = tsCols[pos]; @@ -434,9 +434,9 @@ static bool setTimeWindowInterpolationStartTs(SIntervalAggOperatorInfo* pInfo, i return true; } -static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SExprSupp* pSup, - int32_t endRowIndex, SArray* pDataBlock, const TSKEY* tsCols, - TSKEY blockEkey, STimeWindow* win) { +static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SExprSupp* pSup, int32_t endRowIndex, + SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, + STimeWindow* win) { int32_t order = pInfo->order; TSKEY actualEndKey = tsCols[endRowIndex]; @@ -548,8 +548,8 @@ static void setResultRowInterpo(SResultRow* pResult, SResultTsInterpType type) { } } -static void doWindowBorderInterpolation(SIntervalAggOperatorInfo* pInfo, SSDataBlock* pBlock, SResultRow* pResult, STimeWindow* win, int32_t startPos, - int32_t forwardRows, SExprSupp* pSup) { +static void doWindowBorderInterpolation(SIntervalAggOperatorInfo* pInfo, SSDataBlock* pBlock, SResultRow* pResult, + STimeWindow* win, int32_t startPos, int32_t forwardRows, SExprSupp* pSup) { if (!pInfo->timeWindowInterpo) { return; } @@ -628,7 +628,7 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info; - SExprSupp* pSup = &pOperatorInfo->exprSupp; + SExprSupp* pSup = &pOperatorInfo->exprSupp; int32_t startPos = 0; int32_t numOfOutput = pSup->numOfExprs; @@ -655,9 +655,8 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num } STimeWindow w = pr->win; - int32_t ret = - setTimeWindowOutputBuf(pResultRowInfo, &w, (scanFlag == MAIN_SCAN), &pResult, groupId, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &w, (scanFlag == MAIN_SCAN), &pResult, groupId, pSup->pCtx, + numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -672,8 +671,8 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); setNotInterpoWindowKey(pSup->pCtx, numOfExprs, RESULT_ROW_START_INTERP); - doApplyFunctions(pTaskInfo, pSup->pCtx, &w, &pInfo->twAggSup.timeWindowData, startPos, 0, tsCols, - pBlock->info.rows, numOfExprs, pInfo->order); + doApplyFunctions(pTaskInfo, pSup->pCtx, &w, &pInfo->twAggSup.timeWindowData, startPos, 0, tsCols, pBlock->info.rows, + numOfExprs, pInfo->order); if (isResultRowInterpolated(pResult, RESULT_ROW_END_INTERP)) { closeResultRow(pr); @@ -685,6 +684,7 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num } void printDataBlock(SSDataBlock* pBlock, const char* flag) { + if (pBlock == NULL) return; SArray* blocks = taosArrayInit(1, sizeof(SSDataBlock)); taosArrayPush(blocks, pBlock); blockDebugShowData(blocks, flag); @@ -753,8 +753,7 @@ int64_t getReskey(void* data, int32_t index) { return *(int64_t*)pos->key; } -static int32_t saveResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t groupId, - SArray* pUpdated) { +static int32_t saveResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t groupId, SArray* pUpdated) { int32_t size = taosArrayGetSize(pUpdated); int32_t index = binarySearch(pUpdated, size, ts, TSDB_ORDER_DESC, getReskey); if (index == -1) { @@ -806,7 +805,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info; SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; + SExprSupp* pSup = &pOperatorInfo->exprSupp; int32_t startPos = 0; int32_t numOfOutput = pSup->numOfExprs; @@ -819,9 +818,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul STimeWindow win = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, pInfo->interval.precision, &pInfo->win); - int32_t ret = - setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -843,9 +841,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul doInterpUnclosedTimeWindow(pOperatorInfo, numOfOutput, pResultRowInfo, pBlock, scanFlag, tsCols, &pos); // restore current time window - ret = - setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, + numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -870,8 +867,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul // null data, failed to allocate more memory buffer int32_t code = setTimeWindowOutputBuf(pResultRowInfo, &nextWin, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, - pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, - &pInfo->aggSup, pTaskInfo); + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (code != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -890,8 +886,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul doWindowBorderInterpolation(pInfo, pBlock, pResult, &nextWin, startPos, forwardRows, pSup); updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true); - doApplyFunctions(pTaskInfo, pSup->pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, - tsCols, pBlock->info.rows, numOfOutput, pInfo->order); + doApplyFunctions(pTaskInfo, pSup->pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols, + pBlock->info.rows, numOfOutput, pInfo->order); doCloseWindow(pResultRowInfo, pInfo, pResult); } @@ -1002,7 +998,7 @@ static bool compareVal(const char* v, const SStateKeys* pKey) { static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SColumnInfoData* pStateColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->stateCol.slotId); int64_t gid = pBlock->info.groupId; @@ -1050,9 +1046,8 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI STimeWindow window = pRowSup->win; pRowSup->win.ekey = pRowSup->win.skey; - int32_t ret = - setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx, + numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1076,9 +1071,8 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI SResultRow* pResult = NULL; pRowSup->win.ekey = tsList[pBlock->info.rows - 1]; - int32_t ret = - setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &pRowSup->win, masterScan, &pResult, gid, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &pRowSup->win, masterScan, &pResult, gid, + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1095,8 +1089,8 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) { SStateWindowOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SExprSupp* pSup = &pOperator->exprSupp; SOptrBasicInfo* pBInfo = &pInfo->binfo; @@ -1207,7 +1201,7 @@ static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type } } -void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SExprSupp *pSup, int32_t numOfOutput) { +void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SExprSupp* pSup, int32_t numOfOutput) { SResultRow* pResult = getResultRowByPos(pResultBuf, p1); SqlFunctionCtx* pCtx = pSup->pCtx; for (int32_t i = 0; i < numOfOutput; ++i) { @@ -1223,7 +1217,7 @@ void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SExprS } } -void doClearWindow(SAggSupporter* pAggSup, SExprSupp *pSup, char* pData, int16_t bytes, uint64_t groupId, +void doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData, int16_t bytes, uint64_t groupId, int32_t numOfOutput) { SET_RES_WINDOW_KEY(pAggSup->keyBuf, pData, bytes, groupId); SResultRowPosition* p1 = @@ -1259,9 +1253,9 @@ static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) { void* key = taosHashGetKey(pIte, &keyLen); uint64_t groupId = *(uint64_t*)key; ASSERT(keyLen == GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))); - TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t)); + TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t)); SResultRowPosition* pPos = (SResultRowPosition*)pIte; - int32_t code = saveResult(ts, pPos->pageId, pPos->offset, groupId, resWins); + int32_t code = saveResult(ts, pPos->pageId, pPos->offset, groupId, resWins); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1269,8 +1263,9 @@ static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) { return TSDB_CODE_SUCCESS; } -bool isCloseWindow(STimeWindow *pWin, STimeWindowAggSupp* pSup) { - return pWin->ekey < pSup->maxTs - pSup->waterMark; +bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup) { + ASSERT(pSup->maxTs == INT64_MIN || pSup->maxTs > 0); + return pSup->maxTs != INT64_MIN && pWin->ekey < pSup->maxTs - pSup->waterMark; } static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup, SInterval* pInterval, @@ -1330,7 +1325,8 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { } if (pBlock->info.type == STREAM_REPROCESS) { - doClearWindows(&pInfo->aggSup, &pOperator->exprSupp, &pInfo->interval, 0, pOperator->exprSupp.numOfExprs, pBlock, NULL); + doClearWindows(&pInfo->aggSup, &pOperator->exprSupp, &pInfo->interval, 0, pOperator->exprSupp.numOfExprs, pBlock, + NULL); qDebug("%s clear existed time window results for updates checked", GET_TASKID(pTaskInfo)); continue; } else if (pBlock->info.type == STREAM_GET_ALL) { @@ -1580,7 +1576,7 @@ _error: // todo handle multiple tables cases. static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId); @@ -1617,9 +1613,8 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator STimeWindow window = pRowSup->win; pRowSup->win.ekey = pRowSup->win.skey; - int32_t ret = - setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &window, masterScan, &pResult, gid, pSup->pCtx, + numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1637,9 +1632,8 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator SResultRow* pResult = NULL; pRowSup->win.ekey = tsList[pBlock->info.rows - 1]; - int32_t ret = - setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &pRowSup->win, masterScan, &pResult, gid, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + int32_t ret = setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, &pRowSup->win, masterScan, &pResult, gid, + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR); } @@ -1656,7 +1650,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { SSessionAggOperatorInfo* pInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pInfo->binfo; - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; if (pOperator->status == OP_RES_TO_RETURN) { doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); @@ -1707,8 +1701,8 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { static void doKeepPrevRows(STimeSliceOperatorInfo* pSliceInfo, const SSDataBlock* pBlock, int32_t rowIndex) { int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); - for(int32_t i = 0; i < numOfCols; ++i) { - SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i); // null data should not be kept since it can not be used to perform interpolation if (!colDataIsNull_s(pColInfoData, i)) { @@ -1844,22 +1838,22 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; STimeSliceOperatorInfo* pSliceInfo = pOperator->info; - SSDataBlock* pResBlock = pSliceInfo->pRes; - SExprSupp* pSup = &pOperator->exprSupp; + SSDataBlock* pResBlock = pSliceInfo->pRes; + SExprSupp* pSup = &pOperator->exprSupp; blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity); -// if (pOperator->status == OP_RES_TO_RETURN) { -// // doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes); -// if (pResBlock->info.rows == 0 || !hasDataInGroupInfo(&pSliceInfo->groupResInfo)) { -// doSetOperatorCompleted(pOperator); -// } -// -// return pResBlock; -// } + // if (pOperator->status == OP_RES_TO_RETURN) { + // // doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes); + // if (pResBlock->info.rows == 0 || !hasDataInGroupInfo(&pSliceInfo->groupResInfo)) { + // doSetOperatorCompleted(pOperator); + // } + // + // return pResBlock; + // } - int32_t order = TSDB_ORDER_ASC; - SInterval* pInterval = &pSliceInfo->interval; + int32_t order = TSDB_ORDER_ASC; + SInterval* pInterval = &pSliceInfo->interval; SOperatorInfo* downstream = pOperator->pDownstream[0]; int32_t numOfRows = 0; @@ -1878,14 +1872,14 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, MAIN_SCAN, true); SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSliceInfo->tsCol.slotId); - for(int32_t i = 0; i < pBlock->info.rows; ++i) { - int64_t ts = *(int64_t*) colDataGetData(pTsCol, i); + for (int32_t i = 0; i < pBlock->info.rows; ++i) { + int64_t ts = *(int64_t*)colDataGetData(pTsCol, i); if (ts == pSliceInfo->current) { - for(int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { + for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[j]; - int32_t dstSlot = pExprInfo->base.resSchema.slotId; - int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; + int32_t dstSlot = pExprInfo->base.resSchema.slotId; + int32_t srcSlot = pExprInfo->base.pParam[0].pCol->slotId; SColumnInfoData* pSrc = taosArrayGet(pBlock->pDataBlock, srcSlot); SColumnInfoData* pDst = taosArrayGet(pResBlock->pDataBlock, dstSlot); @@ -1897,7 +1891,8 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { pResBlock->info.rows += 1; doKeepPrevRows(pSliceInfo, pBlock, i); - pSliceInfo->current = taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); + pSliceInfo->current = + taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision); if (pSliceInfo->current > pSliceInfo->win.ekey) { doSetOperatorCompleted(pOperator); break; @@ -1908,7 +1903,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { } } else if (ts < pSliceInfo->current) { if (i < pBlock->info.rows - 1) { - int64_t nextTs = *(int64_t*) colDataGetData(pTsCol, i + 1); + int64_t nextTs = *(int64_t*)colDataGetData(pTsCol, i + 1); if (nextTs > pSliceInfo->current) { while (pSliceInfo->current < nextTs && pSliceInfo->current <= pSliceInfo->win.ekey) { genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pBlock, i, pResBlock); @@ -1956,7 +1951,7 @@ static SSDataBlock* doTimeslice(SOperatorInfo* pOperator) { return pResBlock->info.rows == 0 ? NULL : pResBlock; } -SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode *pPhyNode, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo) { STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pOperator == NULL || pInfo == NULL) { @@ -1964,17 +1959,17 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode } SInterpFuncPhysiNode* pInterpPhyNode = (SInterpFuncPhysiNode*)pPhyNode; - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; - int32_t numOfExprs = 0; + int32_t numOfExprs = 0; SExprInfo* pExprInfo = createExprInfo(pInterpPhyNode->pFuncs, NULL, &numOfExprs); - int32_t code = initExprSupp(pSup, pExprInfo, numOfExprs); + int32_t code = initExprSupp(pSup, pExprInfo, numOfExprs); if (code != TSDB_CODE_SUCCESS) { goto _error; } if (pInterpPhyNode->pExprs != NULL) { - int32_t num = 0; + int32_t num = 0; SExprInfo* pScalarExprInfo = createExprInfo(pInterpPhyNode->pExprs, NULL, &num); code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, num); if (code != TSDB_CODE_SUCCESS) { @@ -1986,21 +1981,21 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode pInfo->fillType = convertFillType(pInterpPhyNode->fillMode); initResultSizeInfo(pOperator, 4096); - pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, (SNodeListNode*)pInterpPhyNode->pFillValues); - pInfo->pRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc); - pInfo->win = pInterpPhyNode->timeRange; + pInfo->pFillColInfo = createFillColInfo(pExprInfo, numOfExprs, (SNodeListNode*)pInterpPhyNode->pFillValues); + pInfo->pRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc); + pInfo->win = pInterpPhyNode->timeRange; pInfo->interval.interval = pInterpPhyNode->interval; - pInfo->current = pInfo->win.skey; + pInfo->current = pInfo->win.skey; - pOperator->name = "TimeSliceOperator"; + pOperator->name = "TimeSliceOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC; - pOperator->blocking = false; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; - pOperator->pTaskInfo = pTaskInfo; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + pOperator->pTaskInfo = pTaskInfo; - pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTimeslice, NULL, NULL, destroyBasicOperatorInfo, - NULL, NULL, NULL); + pOperator->fpSet = + createOperatorFpSet(operatorDummyOpenFn, doTimeslice, NULL, NULL, destroyBasicOperatorInfo, NULL, NULL, NULL); code = appendDownstream(pOperator, &downstream, 1); return pOperator; @@ -2138,22 +2133,24 @@ void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int3 } } -static void rebuildIntervalWindow(SStreamFinalIntervalOperatorInfo* pInfo, SExprSupp* pSup, SArray* pWinArray, int32_t groupId, - int32_t numOfOutput, SExecTaskInfo* pTaskInfo) { +static void rebuildIntervalWindow(SStreamFinalIntervalOperatorInfo* pInfo, SExprSupp* pSup, SArray* pWinArray, + int32_t groupId, int32_t numOfOutput, SExecTaskInfo* pTaskInfo) { int32_t size = taosArrayGetSize(pWinArray); - ASSERT(pInfo->pChildren); + if (!pInfo->pChildren) { + return; + } for (int32_t i = 0; i < size; i++) { STimeWindow* pParentWin = taosArrayGet(pWinArray, i); SResultRow* pCurResult = NULL; - setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, pParentWin, true, &pCurResult, 0, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); + setTimeWindowOutputBuf(&pInfo->binfo.resultRowInfo, pParentWin, true, &pCurResult, 0, pSup->pCtx, numOfOutput, + pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo); int32_t numOfChildren = taosArrayGetSize(pInfo->pChildren); for (int32_t j = 0; j < numOfChildren; j++) { SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, j); SIntervalAggOperatorInfo* pChInfo = pChildOp->info; - SExprSupp* pChildSup = &pChildOp->exprSupp; + SExprSupp* pChildSup = &pChildOp->exprSupp; - SResultRow* pChResult = NULL; + SResultRow* pChResult = NULL; setTimeWindowOutputBuf(&pChInfo->binfo.resultRowInfo, pParentWin, true, &pChResult, 0, pChildSup->pCtx, pChildSup->numOfExprs, pChildSup->rowEntryInfoOffset, &pChInfo->aggSup, pTaskInfo); compactFunctions(pSup->pCtx, pChildSup->pCtx, numOfOutput, pTaskInfo); @@ -2163,8 +2160,8 @@ static void rebuildIntervalWindow(SStreamFinalIntervalOperatorInfo* pInfo, SExpr bool isDeletedWindow(STimeWindow* pWin, uint64_t groupId, SAggSupporter* pSup) { SET_RES_WINDOW_KEY(pSup->keyBuf, &pWin->skey, sizeof(int64_t), groupId); - SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, - pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(sizeof(int64_t))); + SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf, + GET_RES_WINDOW_KEY_LEN(sizeof(int64_t))); return p1 == NULL; } @@ -2197,7 +2194,8 @@ static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBloc isDeletedWindow(&nextWin, tableGroupId, &pInfo->aggSup)) { SArray* pUpWins = taosArrayInit(8, sizeof(STimeWindow)); taosArrayPush(pUpWins, &nextWin); - rebuildIntervalWindow(pInfo, pSup, pUpWins, pInfo->binfo.pRes->info.groupId, pSup->numOfExprs, pOperatorInfo->pTaskInfo); + rebuildIntervalWindow(pInfo, pSup, pUpWins, pInfo->binfo.pRes->info.groupId, pSup->numOfExprs, + pOperatorInfo->pTaskInfo); taosArrayDestroy(pUpWins); } int32_t code = setTimeWindowOutputBuf(pResultRowInfo, &nextWin, true, &pResult, tableGroupId, pSup->pCtx, @@ -2215,8 +2213,8 @@ static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBloc saveResultRow(pResult, tableGroupId, pUpdated); } updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true); - doApplyFunctions(pTaskInfo, pSup->pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, - tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC); + doApplyFunctions(pTaskInfo, pSup->pCtx, &nextWin, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols, + pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC); int32_t prevEndPos = (forwardRows - 1) * step + startPos; ASSERT(pSDataBlock->info.window.skey > 0 && pSDataBlock->info.window.ekey > 0); startPos = getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, pInfo->order); @@ -2256,9 +2254,7 @@ void copyUpdateDataBlock(SSDataBlock* pDest, SSDataBlock* pSource, int32_t tsCol blockDataUpdateTsWindow(pDest, 0); } -static int32_t getChildIndex(SSDataBlock* pBlock) { - return pBlock->info.childId; -} +static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; } static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { SStreamFinalIntervalOperatorInfo* pInfo = pOperator->info; @@ -2303,7 +2299,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { int32_t childIndex = getChildIndex(pBlock); SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); SIntervalAggOperatorInfo* pChildInfo = pChildOp->info; - SExprSupp* pChildSup = &pChildOp->exprSupp; + SExprSupp* pChildSup = &pChildOp->exprSupp; doClearWindows(&pChildInfo->aggSup, pChildSup, &pChildInfo->interval, pChildInfo->primaryTsIndex, pChildSup->numOfExprs, pBlock, NULL); @@ -2338,6 +2334,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { SStreamFinalIntervalOperatorInfo* pChInfo = pChildOp->info; setInputDataBlock(pChildOp, pChildOp->exprSupp.pCtx, pBlock, pChInfo->order, MAIN_SCAN, true); doHashInterval(pChildOp, pBlock, pBlock->info.groupId, NULL); + pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, pBlock->info.window.ekey); } maxTs = TMAX(maxTs, pBlock->info.window.ekey); } @@ -2405,7 +2402,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, initResultRowInfo(&pInfo->binfo.resultRowInfo); pInfo->pChildren = NULL; if (numOfChild > 0) { - pInfo->pChildren = taosArrayInit(numOfChild, sizeof(SOperatorInfo)); + pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); for (int32_t i = 0; i < numOfChild; i++) { SOperatorInfo* pChildOp = createStreamFinalIntervalOperatorInfo(NULL, pPhyNode, pTaskInfo, 0); if (pChildOp) { @@ -2416,9 +2413,6 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, } } // semi interval operator does not catch result - if (!IS_FINAL_OP(pInfo)) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } pInfo->pUpdateRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc); pInfo->pUpdateRes->info.type = STREAM_REPROCESS; blockDataEnsureCapacity(pInfo->pUpdateRes, 128); @@ -2432,6 +2426,10 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, pOperator->name = "StreamSemiIntervalOperator"; } + if (!IS_FINAL_OP(pInfo)) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + pOperator->operatorType = pPhyNode->type; pOperator->blocking = true; pOperator->status = OP_NOT_OPENED; @@ -2461,9 +2459,9 @@ _error: void destroyStreamAggSupporter(SStreamAggSupporter* pSup) { taosMemoryFreeClear(pSup->pKeyBuf); - void **pIte = NULL; + void** pIte = NULL; while ((pIte = taosHashIterate(pSup->pResultRows, pIte)) != NULL) { - SArray *pWins = (SArray *) (*pIte); + SArray* pWins = (SArray*)(*pIte); taosArrayDestroy(pWins); } taosHashCleanup(pSup->pResultRows); @@ -2487,18 +2485,19 @@ void destroyStreamSessionAggOperatorInfo(void* param, int32_t numOfOutput) { } } -int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock) { +int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, + SSDataBlock* pResultBlock) { int32_t code = initExprSupp(pSup, pExprInfo, numOfCols); if (code != TSDB_CODE_SUCCESS) { return code; } initBasicInfo(pBasicInfo, pResultBlock); - + for (int32_t i = 0; i < numOfCols; ++i) { pSup->pCtx[i].pBuf = NULL; } - + ASSERT(numOfCols > 0); increaseTs(pSup->pCtx); return TSDB_CODE_SUCCESS; @@ -2517,18 +2516,20 @@ void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, int pScanInfo->pUpdateInfo = updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, waterMark); } -int32_t initSessionAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx, int32_t numOfOutput) { +int32_t initSessionAggSupporter(SStreamAggSupporter* pSup, const char* pKey, SqlFunctionCtx* pCtx, + int32_t numOfOutput) { return initStreamAggSupporter(pSup, pKey, pCtx, numOfOutput, sizeof(SResultWindowInfo)); } -SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo) { - SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc); - int32_t code = TSDB_CODE_OUT_OF_MEMORY; +SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo) { + SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc); + int32_t code = TSDB_CODE_OUT_OF_MEMORY; SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { goto _error; } @@ -2540,8 +2541,7 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh if (code != TSDB_CODE_SUCCESS) { goto _error; } - - + code = initSessionAggSupporter(&pInfo->streamAggSup, "StreamSessionAggOperatorInfo", pSup->pCtx, numOfCols); if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -2553,10 +2553,8 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh } initDummyFunction(pInfo->pDummyCtx, pSup->pCtx, numOfCols); - pInfo->twAggSup = (STimeWindowAggSupp) { - .waterMark = pSessionNode->window.watermark, - .calTrigger = pSessionNode->window.triggerType, - .maxTs = INT64_MIN}; + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pSessionNode->window.watermark, .calTrigger = pSessionNode->window.triggerType, .maxTs = INT64_MIN}; initResultRowInfo(&pInfo->binfo.resultRowInfo); initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); @@ -2572,6 +2570,7 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh pInfo->pStDeleted = taosHashInit(64, hashFn, true, HASH_NO_LOCK); pInfo->pDelIterator = NULL; pInfo->pDelRes = createOneDataBlock(pResBlock, false); + pInfo->pDelRes->info.type = STREAM_DELETE; blockDataEnsureCapacity(pInfo->pDelRes, 64); pInfo->pChildren = NULL; pInfo->isFinal = false; @@ -2630,19 +2629,19 @@ static SResultWindowInfo* addNewSessionWindow(SArray* pWinInfos, TSKEY ts) { } SArray* getWinInfos(SStreamAggSupporter* pAggSup, uint64_t groupId) { - void** ite = taosHashGet(pAggSup->pResultRows, &groupId, sizeof(uint64_t)); + void** ite = taosHashGet(pAggSup->pResultRows, &groupId, sizeof(uint64_t)); SArray* pWinInfos = NULL; if (ite == NULL) { pWinInfos = taosArrayInit(1024, pAggSup->valueSize); - taosHashPut(pAggSup->pResultRows, &groupId, sizeof(uint64_t), &pWinInfos, sizeof(void *)); + taosHashPut(pAggSup->pResultRows, &groupId, sizeof(uint64_t), &pWinInfos, sizeof(void*)); } else { pWinInfos = *ite; } return pWinInfos; } -SResultWindowInfo* getSessionTimeWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, - TSKEY endTs, uint64_t groupId, int64_t gap, int32_t* pIndex) { +SResultWindowInfo* getSessionTimeWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + int64_t gap, int32_t* pIndex) { SArray* pWinInfos = getWinInfos(pAggSup, groupId); pAggSup->pCurWins = pWinInfos; @@ -2681,10 +2680,10 @@ SResultWindowInfo* getSessionTimeWindow(SStreamAggSupporter* pAggSup, TSKEY star return insertNewSessionWindow(pWinInfos, startTs, index + 1); } -int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, - TSKEY* pEndTs, int32_t rows, int32_t start, int64_t gap, SHashObj* pStDeleted) { +int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, int32_t rows, + int32_t start, int64_t gap, SHashObj* pStDeleted) { for (int32_t i = start; i < rows; ++i) { - if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap)) ) { + if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) { return i - start; } if (pWinInfo->win.skey > pStartTs[i]) { @@ -2740,7 +2739,7 @@ static int32_t doOneWindowAggImpl(int32_t tsColId, SOptrBasicInfo* pBinfo, SStre SColumnInfoData* pTimeWindowData, SSDataBlock* pSDataBlock, SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex, int32_t winRows, int32_t numOutput, SOperatorInfo* pOperator) { - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, tsColId); @@ -2758,14 +2757,14 @@ static int32_t doOneWindowAggImpl(int32_t tsColId, SOptrBasicInfo* pBinfo, SStre static int32_t doOneWindowAgg(SStreamSessionAggOperatorInfo* pInfo, SSDataBlock* pSDataBlock, SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex, int32_t winRows, - int32_t numOutput, SOperatorInfo * pOperator) { + int32_t numOutput, SOperatorInfo* pOperator) { return doOneWindowAggImpl(pInfo->primaryTsIndex, &pInfo->binfo, &pInfo->streamAggSup, &pInfo->twAggSup.timeWindowData, pSDataBlock, pCurWin, pResult, startIndex, winRows, numOutput, pOperator); } static int32_t doOneStateWindowAgg(SStreamStateAggOperatorInfo* pInfo, SSDataBlock* pSDataBlock, SResultWindowInfo* pCurWin, SResultRow** pResult, int32_t startIndex, - int32_t winRows, int32_t numOutput, SOperatorInfo * pOperator) { + int32_t winRows, int32_t numOutput, SOperatorInfo* pOperator) { return doOneWindowAggImpl(pInfo->primaryTsIndex, &pInfo->binfo, &pInfo->streamAggSup, &pInfo->twAggSup.timeWindowData, pSDataBlock, pCurWin, pResult, startIndex, winRows, numOutput, pOperator); } @@ -2786,7 +2785,7 @@ int32_t getNumCompactWindow(SArray* pWinInfos, int32_t startIndex, int64_t gap) void compactTimeWindow(SStreamSessionAggOperatorInfo* pInfo, int32_t startIndex, int32_t num, uint64_t groupId, int32_t numOfOutput, SHashObj* pStUpdated, SHashObj* pStDeleted, SOperatorInfo* pOperator) { - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SResultWindowInfo* pCurWin = taosArrayGet(pInfo->streamAggSup.pCurWins, startIndex); @@ -2817,8 +2816,8 @@ typedef struct SWinRes { uint64_t groupId; } SWinRes; -static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, - SHashObj* pStUpdated, SHashObj* pStDeleted, bool hasEndTs) { +static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SHashObj* pStUpdated, + SHashObj* pStDeleted, bool hasEndTs) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamSessionAggOperatorInfo* pInfo = pOperator->info; bool masterScan = true; @@ -2836,14 +2835,14 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData if (pSDataBlock->pDataBlock != NULL) { SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - startTsCols = (int64_t*) pStartTsCol->pData; + startTsCols = (int64_t*)pStartTsCol->pData; SColumnInfoData* pEndTsCol = NULL; if (hasEndTs) { pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex); } else { pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); } - endTsCols = (int64_t*) pEndTsCol->pData; + endTsCols = (int64_t*)pEndTsCol->pData; } else { return; } @@ -2851,10 +2850,9 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; for (int32_t i = 0; i < pSDataBlock->info.rows;) { int32_t winIndex = 0; - SResultWindowInfo* pCurWin = getSessionTimeWindow(pAggSup, startTsCols[i], - endTsCols[i], groupId, gap, &winIndex); - winRows = updateSessionWindowInfo(pCurWin, startTsCols, endTsCols, - pSDataBlock->info.rows, i, pInfo->gap, pStDeleted); + SResultWindowInfo* pCurWin = getSessionTimeWindow(pAggSup, startTsCols[i], endTsCols[i], groupId, gap, &winIndex); + winRows = + updateSessionWindowInfo(pCurWin, startTsCols, endTsCols, pSDataBlock->info.rows, i, pInfo->gap, pStDeleted); code = doOneWindowAgg(pInfo, pSDataBlock, pCurWin, &pResult, i, winRows, numOfOutput, pOperator); if (code != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -2877,14 +2875,15 @@ static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSData } } -static void doClearSessionWindows(SStreamAggSupporter* pAggSup, SExprSupp* pSup, SSDataBlock* pBlock, - int32_t tsIndex, int32_t numOfOutput, int64_t gap, SArray* result) { +static void doClearSessionWindows(SStreamAggSupporter* pAggSup, SExprSupp* pSup, SSDataBlock* pBlock, int32_t tsIndex, + int32_t numOfOutput, int64_t gap, SArray* result) { SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, tsIndex); TSKEY* tsCols = (TSKEY*)pColDataInfo->pData; int32_t step = 0; for (int32_t i = 0; i < pBlock->info.rows; i += step) { int32_t winIndex = 0; - SResultWindowInfo* pCurWin = getSessionTimeWindow(pAggSup, tsCols[i], INT64_MIN, pBlock->info.groupId, gap, &winIndex); + SResultWindowInfo* pCurWin = + getSessionTimeWindow(pAggSup, tsCols[i], INT64_MIN, pBlock->info.groupId, gap, &winIndex); step = updateSessionWindowInfo(pCurWin, tsCols, NULL, pBlock->info.rows, i, gap, NULL); ASSERT(isInWindow(pCurWin, tsCols[i], gap)); doClearWindowImpl(&pCurWin->pos, pAggSup->pResultBuf, pSup, numOfOutput); @@ -2934,7 +2933,7 @@ void doBuildDeleteDataBlock(SHashObj* pStDeleted, SSDataBlock* pBlock, void** It static void rebuildTimeWindow(SStreamSessionAggOperatorInfo* pInfo, SArray* pWinArray, int32_t groupId, int32_t numOfOutput, SOperatorInfo* pOperator) { - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; int32_t size = taosArrayGetSize(pWinArray); @@ -2953,7 +2952,7 @@ static void rebuildTimeWindow(SStreamSessionAggOperatorInfo* pInfo, SArray* pWin int32_t chWinSize = taosArrayGetSize(pChWins); int32_t index = binarySearch(pChWins, chWinSize, pParentWin->win.skey, TSDB_ORDER_DESC, getSessionWindowEndkey); if (index < 0) { - index = 0; + index = 0; } for (int32_t k = index; k < chWinSize; k++) { SResultWindowInfo* pcw = taosArrayGet(pChWins, k); @@ -2974,15 +2973,14 @@ typedef SResultWindowInfo* (*__get_win_info_)(void*); SResultWindowInfo* getResWinForSession(void* pData) { return (SResultWindowInfo*)pData; } SResultWindowInfo* getResWinForState(void* pData) { return &((SStateWindowInfo*)pData)->winInfo; } -int32_t closeSessionWindow(SHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SArray* pClosed, - __get_win_info_ fn) { +int32_t closeSessionWindow(SHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SArray* pClosed, __get_win_info_ fn) { // Todo(liuyao) save window to tdb - void **pIte = NULL; + void** pIte = NULL; size_t keyLen = 0; while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) { uint64_t* pGroupId = taosHashGetKey(pIte, &keyLen); - SArray *pWins = (SArray *) (*pIte); - int32_t size = taosArrayGetSize(pWins); + SArray* pWins = (SArray*)(*pIte); + int32_t size = taosArrayGetSize(pWins); for (int32_t i = 0; i < size; i++) { void* pWin = taosArrayGet(pWins, i); SResultWindowInfo* pSeWin = fn(pWin); @@ -3003,9 +3001,9 @@ int32_t closeSessionWindow(SHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SArra } int32_t getAllSessionWindow(SHashObj* pHashMap, SArray* pClosed, __get_win_info_ fn) { - void **pIte = NULL; + void** pIte = NULL; while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) { - SArray *pWins = (SArray *) (*pIte); + SArray* pWins = (SArray*)(*pIte); int32_t size = taosArrayGetSize(pWins); for (int32_t i = 0; i < size; i++) { void* pWin = taosArrayGet(pWins, i); @@ -3029,12 +3027,14 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { } else if (pOperator->status == OP_RES_TO_RETURN) { doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { + /*printDataBlock(pInfo->pDelRes, "session del");*/ return pInfo->pDelRes; } doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf); if (pBInfo->pRes->info.rows == 0 || !hasDataInGroupInfo(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); } + /*printDataBlock(pBInfo->pRes, "session insert");*/ return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes; } @@ -3050,7 +3050,8 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { if (pBlock->info.type == STREAM_REPROCESS) { SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo)); - doClearSessionWindows(&pInfo->streamAggSup, &pOperator->exprSupp, pBlock, 0, pOperator->exprSupp.numOfExprs, pInfo->gap, pWins); + doClearSessionWindows(&pInfo->streamAggSup, &pOperator->exprSupp, pBlock, 0, pOperator->exprSupp.numOfExprs, + pInfo->gap, pWins); if (IS_FINAL_OP(pInfo)) { int32_t childIndex = getChildIndex(pBlock); SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); @@ -3074,13 +3075,14 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { int32_t size = taosArrayGetSize(pInfo->pChildren); // 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); + SOperatorInfo* pChildOp = + createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0); if (!pChildOp) { longjmp(pOperator->pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } taosArrayPush(pInfo->pChildren, &pChildOp); } - SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); + SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); setInputDataBlock(pChildOp, pChildOp->exprSupp.pCtx, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); doStreamSessionAggImpl(pChildOp, pBlock, NULL, NULL, true); } @@ -3091,27 +3093,27 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { // restore the value pOperator->status = OP_RES_TO_RETURN; - closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, - getResWinForSession); + closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, getResWinForSession); copyUpdateResult(pStUpdated, pUpdated); taosHashCleanup(pStUpdated); - finalizeUpdatedResult(pSup->numOfExprs, pInfo->streamAggSup.pResultBuf, pUpdated, - pSup->rowEntryInfoOffset); + finalizeUpdatedResult(pSup->numOfExprs, pInfo->streamAggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset); initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); if (pInfo->pDelRes->info.rows > 0) { + /*printDataBlock(pInfo->pDelRes, "session del");*/ return pInfo->pDelRes; } doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf); + /*printDataBlock(pBInfo->pRes, "session insert");*/ return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes; } static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) { - void **pIte = NULL; + void** pIte = NULL; while ((pIte = taosHashIterate(pInfo->streamAggSup.pResultRows, pIte)) != NULL) { - SArray *pWins = (SArray *) (*pIte); + SArray* pWins = (SArray*)(*pIte); int32_t size = taosArrayGetSize(pWins); for (int32_t i = 0; i < size; i++) { SResultWindowInfo* pWin = (SResultWindowInfo*)taosArrayGet(pWins, i); @@ -3137,7 +3139,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { SOptrBasicInfo* pBInfo = &pInfo->binfo; TSKEY maxTs = INT64_MIN; SExprSupp* pSup = &pOperator->exprSupp; - + if (pOperator->status == OP_EXEC_DONE) { return NULL; } else if (pOperator->status == OP_RES_TO_RETURN) { @@ -3219,8 +3221,8 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes; } -SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, - SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild) { +SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, int32_t numOfChild) { int32_t code = TSDB_CODE_OUT_OF_MEMORY; SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo); if (pOperator == NULL) { @@ -3238,15 +3240,14 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream blockDataEnsureCapacity(pInfo->pUpdateRes, 128); pOperator->name = "StreamSessionSemiAggOperator"; pOperator->fpSet = - createOperatorFpSet(operatorDummyOpenFn, doStreamSessionSemiAgg, NULL, NULL, destroyStreamSessionAggOperatorInfo, - aggEncodeResultRow, aggDecodeResultRow, NULL); + createOperatorFpSet(operatorDummyOpenFn, doStreamSessionSemiAgg, NULL, NULL, + destroyStreamSessionAggOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL); } pOperator->operatorType = pPhyNode->type; if (numOfChild > 0) { pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); for (int32_t i = 0; i < numOfChild; i++) { - SOperatorInfo* pChild = - createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0); + SOperatorInfo* pChild = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0); if (pChild == NULL) { goto _error; } @@ -3364,8 +3365,8 @@ SStateWindowInfo* getStateWindowByTs(SStreamAggSupporter* pAggSup, TSKEY ts, uin return NULL; } -SStateWindowInfo* getStateWindow(SStreamAggSupporter* pAggSup, TSKEY ts, - uint64_t groupId, char* pKeyData, SColumn* pCol, int32_t* pIndex) { +SStateWindowInfo* getStateWindow(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData, + SColumn* pCol, int32_t* pIndex) { SArray* pWinInfos = getWinInfos(pAggSup, groupId); pAggSup->pCurWins = pWinInfos; int32_t size = taosArrayGetSize(pWinInfos); @@ -3497,11 +3498,10 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl char* pKeyData = colDataGetData(pKeyColInfo, i); int32_t winIndex = 0; bool allEqual = true; - SStateWindowInfo* pCurWin = - getStateWindow(pAggSup, tsCols[i], pSDataBlock->info.groupId, pKeyData, - &pInfo->stateCol, &winIndex); - winRows = updateStateWindowInfo(pAggSup->pCurWins, winIndex, tsCols, pKeyColInfo, - pSDataBlock->info.rows, i, &allEqual, pInfo->pSeDeleted); + SStateWindowInfo* pCurWin = + getStateWindow(pAggSup, tsCols[i], pSDataBlock->info.groupId, pKeyData, &pInfo->stateCol, &winIndex); + winRows = updateStateWindowInfo(pAggSup->pCurWins, winIndex, tsCols, pKeyColInfo, pSDataBlock->info.rows, i, + &allEqual, pInfo->pSeDeleted); if (!allEqual) { taosArrayPush(pAggSup->pScanWindow, &pCurWin->winInfo.win); taosHashRemove(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition)); @@ -3515,8 +3515,7 @@ static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBl pCurWin->winInfo.isClosed = false; if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { SWinRes value = {.ts = pCurWin->winInfo.win.skey, .groupId = groupId}; - code = taosHashPut(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition), - &value, sizeof(SWinRes)); + code = taosHashPut(pSeUpdated, &pCurWin->winInfo.pos, sizeof(SResultRowPosition), &value, sizeof(SWinRes)); if (code != TSDB_CODE_SUCCESS) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -3530,7 +3529,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { return NULL; } - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SStreamStateAggOperatorInfo* pInfo = pOperator->info; SOptrBasicInfo* pBInfo = &pInfo->binfo; if (pOperator->status == OP_RES_TO_RETURN) { @@ -3572,8 +3571,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { // restore the value pOperator->status = OP_RES_TO_RETURN; - closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, - getResWinForState); + closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pUpdated, getResWinForState); copyUpdateResult(pSeUpdated, pUpdated); taosHashCleanup(pSeUpdated); @@ -3644,6 +3642,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys pInfo->pSeDeleted = taosHashInit(64, hashFn, true, HASH_NO_LOCK); pInfo->pDelIterator = NULL; pInfo->pDelRes = createOneDataBlock(pResBlock, false); + pInfo->pDelRes->info.type = STREAM_DELETE; blockDataEnsureCapacity(pInfo->pDelRes, 64); pInfo->pChildren = NULL; @@ -3672,48 +3671,48 @@ _error: return NULL; } -typedef struct SMergeIntervalAggOperatorInfo { +typedef struct SMergeAlignedIntervalAggOperatorInfo { SIntervalAggOperatorInfo intervalAggOperatorInfo; bool hasGroupId; uint64_t groupId; SSDataBlock* prefetchedBlock; bool inputBlocksFinished; -} SMergeIntervalAggOperatorInfo; +} SMergeAlignedIntervalAggOperatorInfo; -void destroyMergeIntervalOperatorInfo(void* param, int32_t numOfOutput) { - SMergeIntervalAggOperatorInfo* miaInfo = (SMergeIntervalAggOperatorInfo*)param; +void destroyMergeAlignedIntervalOperatorInfo(void* param, int32_t numOfOutput) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = (SMergeAlignedIntervalAggOperatorInfo*)param; destroyIntervalOperatorInfo(&miaInfo->intervalAggOperatorInfo, numOfOutput); } -static int32_t outputMergeIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t tableGroupId, SSDataBlock* pResultBlock, TSKEY wstartTs) { - SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; - SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; - SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; +static int32_t outputMergeAlignedIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t tableGroupId, + SSDataBlock* pResultBlock, TSKEY wstartTs) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; SExprSupp* pSup = &pOperatorInfo->exprSupp; - bool ascScan = (iaInfo->order == TSDB_ORDER_ASC); + bool ascScan = (iaInfo->order == TSDB_ORDER_ASC); SET_RES_WINDOW_KEY(iaInfo->aggSup.keyBuf, &wstartTs, TSDB_KEYSIZE, tableGroupId); SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE)); ASSERT(p1 != NULL); - finalizeResultRowIntoResultDataBlock(iaInfo->aggSup.pResultBuf, p1, pSup->pCtx, pSup->pExprInfo, - pSup->numOfExprs, pSup->rowEntryInfoOffset, pResultBlock, - pTaskInfo); + finalizeResultRowIntoResultDataBlock(iaInfo->aggSup.pResultBuf, p1, pSup->pCtx, pSup->pExprInfo, pSup->numOfExprs, + pSup->rowEntryInfoOffset, pResultBlock, pTaskInfo); taosHashRemove(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE)); return 0; } -static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pBlock, - int32_t scanFlag, SSDataBlock* pResultBlock) { - SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; - SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; +static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, + SSDataBlock* pBlock, int32_t scanFlag, SSDataBlock* pResultBlock) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; + SExprSupp* pSup = &pOperatorInfo->exprSupp; int32_t startPos = 0; int32_t numOfOutput = pSup->numOfExprs; @@ -3724,18 +3723,18 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* STimeWindow win; win.skey = blockStartTs; - win.ekey = taosTimeAdd(win.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit, iaInfo->interval.precision) - 1; + win.ekey = + taosTimeAdd(win.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit, iaInfo->interval.precision) - 1; - //TODO: remove the hash table usage (groupid + winkey => result row position) - int32_t ret = - setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); + // TODO: remove the hash table (groupid + winkey => result row position) + int32_t ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } - TSKEY currTs = blockStartTs; - TSKEY currPos = startPos; + TSKEY currTs = blockStartTs; + TSKEY currPos = startPos; STimeWindow currWin = win; while (1) { ++currPos; @@ -3746,39 +3745,41 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* continue; } else { updateTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &currWin, true); - doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, - currPos - startPos, tsCols, pBlock->info.rows, numOfOutput, iaInfo->order); + doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, currPos - startPos, + tsCols, pBlock->info.rows, numOfOutput, iaInfo->order); - outputMergeIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs); + outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs); currTs = tsCols[currPos]; currWin.skey = currTs; - currWin.ekey = taosTimeAdd(currWin.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit, iaInfo->interval.precision) - 1; + currWin.ekey = taosTimeAdd(currWin.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit, + iaInfo->interval.precision) - + 1; startPos = currPos; - ret = setTimeWindowOutputBuf(pResultRowInfo, &currWin, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pSup->pCtx, - numOfOutput, pSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); + ret = setTimeWindowOutputBuf(pResultRowInfo, &currWin, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, + pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } } } updateTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &currWin, true); - doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, - currPos - startPos, tsCols, pBlock->info.rows, numOfOutput, iaInfo->order); + doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, currPos - startPos, + tsCols, pBlock->info.rows, numOfOutput, iaInfo->order); - outputMergeIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs); + outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs); } -static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { +static SSDataBlock* doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SMergeIntervalAggOperatorInfo* miaInfo = pOperator->info; - SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperator->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; if (pOperator->status == OP_EXEC_DONE) { return NULL; } - SExprSupp* pSup = &pOperator->exprSupp; + SExprSupp* pSup = &pOperator->exprSupp; SSDataBlock* pRes = iaInfo->binfo.pRes; blockDataCleanup(pRes); blockDataEnsureCapacity(pRes, pOperator->resultInfo.capacity); @@ -3793,6 +3794,7 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { } else { pBlock = miaInfo->prefetchedBlock; miaInfo->groupId = pBlock->info.groupId; + miaInfo->prefetchedBlock = NULL; } if (pBlock == NULL) { @@ -3810,6 +3812,276 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { getTableScanInfo(pOperator, &iaInfo->order, &scanFlag); setInputDataBlock(pOperator, pSup->pCtx, pBlock, iaInfo->order, scanFlag, true); + doMergeAlignedIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes); + + if (pRes->info.rows >= pOperator->resultInfo.threshold) { + break; + } + } + + pRes->info.groupId = miaInfo->groupId; + } + + if (pRes->info.rows == 0) { + doSetOperatorCompleted(pOperator); + } + + size_t rows = pRes->info.rows; + pOperator->resultInfo.totalRows += rows; + return (rows == 0) ? NULL : pRes; +} + +SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, + int32_t numOfCols, SSDataBlock* pResBlock, SInterval* pInterval, + int32_t primaryTsSlotId, SExecTaskInfo* pTaskInfo) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = taosMemoryCalloc(1, sizeof(SMergeAlignedIntervalAggOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (miaInfo == NULL || pOperator == NULL) { + goto _error; + } + + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + SExprSupp* pSup = &pOperator->exprSupp; + + iaInfo->win = pTaskInfo->window; + iaInfo->order = TSDB_ORDER_ASC; + iaInfo->interval = *pInterval; + iaInfo->execModel = pTaskInfo->execModel; + iaInfo->primaryTsIndex = primaryTsSlotId; + + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + initResultSizeInfo(pOperator, 4096); + + int32_t code = + initAggInfo(&pOperator->exprSupp, &iaInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str); + initBasicInfo(&iaInfo->binfo, pResBlock); + + initExecTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &iaInfo->win); + + iaInfo->timeWindowInterpo = timeWindowinterpNeeded(pSup->pCtx, numOfCols, iaInfo); + if (iaInfo->timeWindowInterpo) { + iaInfo->binfo.resultRowInfo.openWindow = tdListNew(sizeof(SResultRowPosition)); + } + + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + initResultRowInfo(&iaInfo->binfo.resultRowInfo); + + pOperator->name = "TimeMergeAlignedIntervalAggOperator"; + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->exprSupp.pExprInfo = pExprInfo; + pOperator->pTaskInfo = pTaskInfo; + pOperator->exprSupp.numOfExprs = numOfCols; + pOperator->info = miaInfo; + + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doMergeAlignedIntervalAgg, NULL, NULL, + destroyMergeAlignedIntervalOperatorInfo, NULL, NULL, NULL); + + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + destroyMergeAlignedIntervalOperatorInfo(miaInfo, numOfCols); + taosMemoryFreeClear(miaInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +//===================================================================================================================== +// merge interval operator +typedef struct SMergeIntervalAggOperatorInfo { + SIntervalAggOperatorInfo intervalAggOperatorInfo; + + SHashObj* groupIntervalHash; + bool hasGroupId; + uint64_t groupId; + SSDataBlock* prefetchedBlock; + bool inputBlocksFinished; +} SMergeIntervalAggOperatorInfo; + +void destroyMergeIntervalOperatorInfo(void* param, int32_t numOfOutput) { + SMergeIntervalAggOperatorInfo* miaInfo = (SMergeIntervalAggOperatorInfo*)param; + taosHashCleanup(miaInfo->groupIntervalHash); + destroyIntervalOperatorInfo(&miaInfo->intervalAggOperatorInfo, numOfOutput); +} + +static int32_t outputPrevIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t tableGroupId, SSDataBlock* pResultBlock, + STimeWindow* newWin) { + SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; + bool ascScan = (iaInfo->order == TSDB_ORDER_ASC); + SExprSupp* pExprSup = &pOperatorInfo->exprSupp; + + STimeWindow* prevWin = taosHashGet(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId)); + if (prevWin == NULL) { + taosHashPut(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId), newWin, sizeof(STimeWindow)); + return 0; + } + + if (newWin == NULL || (ascScan && newWin->skey > prevWin->ekey || (!ascScan) && newWin->skey < prevWin->ekey)) { + SET_RES_WINDOW_KEY(iaInfo->aggSup.keyBuf, &prevWin->skey, TSDB_KEYSIZE, tableGroupId); + SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, + GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE)); + ASSERT(p1 != NULL); + + finalizeResultRowIntoResultDataBlock(iaInfo->aggSup.pResultBuf, p1, pExprSup->pCtx, pExprSup->pExprInfo, + pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset, pResultBlock, pTaskInfo); + taosHashRemove(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE)); + if (newWin == NULL) { + taosHashRemove(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId)); + } else { + taosHashPut(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId), newWin, sizeof(STimeWindow)); + } + } + + return 0; +} + +static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pBlock, + int32_t scanFlag, SSDataBlock* pResultBlock) { + SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + + SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; + SExprSupp* pExprSup = &pOperatorInfo->exprSupp; + + int32_t startPos = 0; + int32_t numOfOutput = pExprSup->numOfExprs; + int64_t* tsCols = extractTsCol(pBlock, iaInfo); + uint64_t tableGroupId = pBlock->info.groupId; + bool ascScan = (iaInfo->order == TSDB_ORDER_ASC); + TSKEY blockStartTs = getStartTsKey(&pBlock->info.window, tsCols); + SResultRow* pResult = NULL; + + STimeWindow win = getActiveTimeWindow(iaInfo->aggSup.pResultBuf, pResultRowInfo, blockStartTs, &iaInfo->interval, + iaInfo->interval.precision, &iaInfo->win); + + int32_t ret = + setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pExprSup->pCtx, + numOfOutput, pExprSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); + if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { + longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + TSKEY ekey = ascScan ? win.ekey : win.skey; + int32_t forwardRows = + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->order); + ASSERT(forwardRows > 0); + + // prev time window not interpolation yet. + if (iaInfo->timeWindowInterpo) { + SResultRowPosition pos = addToOpenWindowList(pResultRowInfo, pResult); + doInterpUnclosedTimeWindow(pOperatorInfo, numOfOutput, pResultRowInfo, pBlock, scanFlag, tsCols, &pos); + + // restore current time window + ret = setTimeWindowOutputBuf(pResultRowInfo, &win, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, pExprSup->pCtx, + numOfOutput, pExprSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); + if (ret != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + // window start key interpolation + doWindowBorderInterpolation(iaInfo, pBlock, pResult, &win, startPos, forwardRows, pExprSup); + } + + updateTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &win, true); + doApplyFunctions(pTaskInfo, pExprSup->pCtx, &win, &iaInfo->twAggSup.timeWindowData, startPos, forwardRows, tsCols, + pBlock->info.rows, numOfOutput, iaInfo->order); + doCloseWindow(pResultRowInfo, iaInfo, pResult); + + // output previous interval results after this interval (&win) is closed + outputPrevIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, &win); + + STimeWindow nextWin = win; + while (1) { + int32_t prevEndPos = forwardRows - 1 + startPos; + startPos = getNextQualifiedWindow(&iaInfo->interval, &nextWin, &pBlock->info, tsCols, prevEndPos, iaInfo->order); + if (startPos < 0) { + break; + } + + // null data, failed to allocate more memory buffer + int32_t code = + setTimeWindowOutputBuf(pResultRowInfo, &nextWin, (scanFlag == MAIN_SCAN), &pResult, tableGroupId, + pExprSup->pCtx, numOfOutput, pExprSup->rowEntryInfoOffset, &iaInfo->aggSup, pTaskInfo); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + ekey = ascScan ? nextWin.ekey : nextWin.skey; + forwardRows = + getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, ekey, binarySearchForKey, NULL, iaInfo->order); + + // window start(end) key interpolation + doWindowBorderInterpolation(iaInfo, pBlock, pResult, &nextWin, startPos, forwardRows, pExprSup); + + updateTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &nextWin, true); + doApplyFunctions(pTaskInfo, pExprSup->pCtx, &nextWin, &iaInfo->twAggSup.timeWindowData, startPos, forwardRows, + tsCols, pBlock->info.rows, numOfOutput, iaInfo->order); + doCloseWindow(pResultRowInfo, iaInfo, pResult); + + // output previous interval results after this interval (&nextWin) is closed + outputPrevIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, &nextWin); + } + + if (iaInfo->timeWindowInterpo) { + saveDataBlockLastRow(iaInfo->pPrevValues, pBlock, iaInfo->pInterpCols); + } +} + +static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + SMergeIntervalAggOperatorInfo* miaInfo = pOperator->info; + SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; + SExprSupp* pExpSupp = &pOperator->exprSupp; + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SSDataBlock* pRes = iaInfo->binfo.pRes; + blockDataCleanup(pRes); + blockDataEnsureCapacity(pRes, pOperator->resultInfo.capacity); + + if (!miaInfo->inputBlocksFinished) { + SOperatorInfo* downstream = pOperator->pDownstream[0]; + int32_t scanFlag = MAIN_SCAN; + while (1) { + SSDataBlock* pBlock = NULL; + if (miaInfo->prefetchedBlock == NULL) { + pBlock = downstream->fpSet.getNextFn(downstream); + } else { + pBlock = miaInfo->prefetchedBlock; + miaInfo->groupId = pBlock->info.groupId; + miaInfo->prefetchedBlock = NULL; + } + + if (pBlock == NULL) { + miaInfo->inputBlocksFinished = true; + break; + } + + if (!miaInfo->hasGroupId) { + miaInfo->hasGroupId = true; + miaInfo->groupId = pBlock->info.groupId; + } else if (miaInfo->groupId != pBlock->info.groupId) { + miaInfo->prefetchedBlock = pBlock; + break; + } + + getTableScanInfo(pOperator, &iaInfo->order, &scanFlag); + setInputDataBlock(pOperator, pExpSupp->pCtx, pBlock, iaInfo->order, scanFlag, true); doMergeIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes); if (pRes->info.rows >= pOperator->resultInfo.threshold) { @@ -3818,6 +4090,13 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) { } pRes->info.groupId = miaInfo->groupId; + } else { + void* p = taosHashIterate(miaInfo->groupIntervalHash, NULL); + if (p != NULL) { + size_t len = 0; + uint64_t* pKey = taosHashGetKey(p, &len); + outputPrevIntervalResult(pOperator, *pKey, pRes, NULL); + } } if (pRes->info.rows == 0) { @@ -3839,29 +4118,30 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprI } SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo; - SExprSupp* pSup = &pOperator->exprSupp; - iaInfo->win = pTaskInfo->window; - iaInfo->order = TSDB_ORDER_ASC; - iaInfo->interval = *pInterval; + iaInfo->win = pTaskInfo->window; + iaInfo->order = TSDB_ORDER_ASC; + iaInfo->interval = *pInterval; iaInfo->execModel = pTaskInfo->execModel; + iaInfo->primaryTsIndex = primaryTsSlotId; + SExprSupp* pExprSupp = &pOperator->exprSupp; + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; initResultSizeInfo(pOperator, 4096); - int32_t code = initAggInfo(&pOperator->exprSupp, &iaInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str); + int32_t code = initAggInfo(pExprSupp, &iaInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str); initBasicInfo(&iaInfo->binfo, pResBlock); initExecTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &iaInfo->win); - iaInfo->timeWindowInterpo = timeWindowinterpNeeded(pSup->pCtx, numOfCols, iaInfo); + iaInfo->timeWindowInterpo = timeWindowinterpNeeded(pExprSupp->pCtx, numOfCols, iaInfo); if (iaInfo->timeWindowInterpo) { iaInfo->binfo.resultRowInfo.openWindow = tdListNew(sizeof(SResultRowPosition)); - } - - if (code != TSDB_CODE_SUCCESS) { - goto _error; + if (iaInfo->binfo.resultRowInfo.openWindow == NULL) { + goto _error; + } } initResultRowInfo(&iaInfo->binfo.resultRowInfo); @@ -3891,4 +4171,4 @@ _error: taosMemoryFreeClear(pOperator); pTaskInfo->code = code; return NULL; -} +} \ No newline at end of file diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index caf567884f..50474ff62e 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -86,6 +86,7 @@ SSortHandle* tsortCreateSortHandle(SArray* pSortInfo, int32_t type, int32_t page pSortHandle->pOrderedSource = taosArrayInit(4, POINTER_BYTES); pSortHandle->cmpParam.orderInfo = pSortInfo; + pSortHandle->cmpParam.cmpGroupId = false; tsortSetComparFp(pSortHandle, msortComparFn); @@ -374,9 +375,10 @@ int32_t msortComparFn(const void *pLeft, const void *pRight, void *param) { SSDataBlock* pLeftBlock = pLeftSource->src.pBlock; SSDataBlock* pRightBlock = pRightSource->src.pBlock; - // first sort by block groupId - if (pLeftBlock->info.groupId != pRightBlock->info.groupId) { - return pLeftBlock->info.groupId < pRightBlock->info.groupId ? -1 : 1; + if (pParam->cmpGroupId) { + if (pLeftBlock->info.groupId != pRightBlock->info.groupId) { + return pLeftBlock->info.groupId < pRightBlock->info.groupId ? -1 : 1; + } } for(int32_t i = 0; i < pInfo->size; ++i) { @@ -685,6 +687,11 @@ int32_t tsortSetComparFp(SSortHandle* pHandle, _sort_merge_compar_fn_t fp) { return TSDB_CODE_SUCCESS; } +int32_t tsortSetCompareGroupId(SSortHandle* pHandle, bool compareGroupId) { + pHandle->cmpParam.cmpGroupId = compareGroupId; + return TSDB_CODE_SUCCESS; +} + STupleHandle* tsortNextTuple(SSortHandle* pHandle) { if (pHandle->cmpParam.numOfSources == pHandle->numOfCompletedSources) { return NULL; diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index e691d562c6..4d2f926c12 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -101,6 +101,11 @@ bool getDerivativeFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); bool derivativeFuncSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo); int32_t derivativeFunction(SqlFunctionCtx *pCtx); +bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); +bool irateFuncSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo); +int32_t irateFunction(SqlFunctionCtx *pCtx); +int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); + bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); int32_t firstFunction(SqlFunctionCtx *pCtx); int32_t firstFunctionMerge(SqlFunctionCtx *pCtx); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index cfad00f458..6baf45a5b3 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -978,6 +978,21 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t return TSDB_CODE_SUCCESS; } +static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + if (1 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + + uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; + + if (!IS_NUMERIC_TYPE(colType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + + pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE}; + return TSDB_CODE_SUCCESS; +} + static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { // first(col_list) will be rewritten as first(col) if (1 != LIST_LENGTH(pFunc->pParameterList)) { @@ -1796,6 +1811,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .processFunc = derivativeFunction, .finalizeFunc = functionFinalize }, + { + .name = "irate", + .type = FUNCTION_TYPE_IRATE, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC, + .translateFunc = translateIrate, + .getEnvFunc = getIrateFuncEnv, + .initFunc = irateFuncSetup, + .processFunc = irateFunction, + .finalizeFunc = irateFinalize + }, { .name = "last_row", .type = FUNCTION_TYPE_LAST_ROW, diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 784017fb05..4d869705ad 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -59,6 +59,12 @@ typedef struct STuplePos { int32_t offset; } STuplePos; +typedef struct SMinmaxResInfo { + bool assign; // assign the first value or not + int64_t v; + STuplePos tuplePos; +} SMinmaxResInfo; + typedef struct STopBotResItem { SVariant v; uint64_t uid; // it is a table uid, used to extract tag data during building of the final result for the tag data @@ -148,6 +154,12 @@ typedef struct SElapsedInfo { int64_t timeUnit; } SElapsedInfo; +typedef struct STwaInfo { + double dOutput; + SPoint1 p; + STimeWindow win; +} STwaInfo; + typedef struct SHistoFuncBin { double lower; double upper; @@ -195,13 +207,13 @@ typedef struct SMavgInfo { } SMavgInfo; typedef struct SSampleInfo { - int32_t samples; - int32_t totalPoints; - int32_t numSampled; - uint8_t colType; - int16_t colBytes; - char* data; - int64_t* timestamp; + int32_t samples; + int32_t totalPoints; + int32_t numSampled; + uint8_t colType; + int16_t colBytes; + char* data; + STuplePos* tuplePos; } SSampleInfo; typedef struct STailItem { @@ -234,6 +246,22 @@ typedef struct SUniqueInfo { char pItems[]; } SUniqueInfo; +typedef struct SDerivInfo { + double prevValue; // previous value + TSKEY prevTs; // previous timestamp + bool ignoreNegative; // ignore the negative value + int64_t tsWindow; // time window for derivative + bool valueSet; // the value has been set already +} SDerivInfo; + +typedef struct SRateInfo { + double firstValue; + TSKEY firstKey; + double lastValue; + TSKEY lastKey; + int8_t hasResult; // flag to denote has value +} SRateInfo; + #define SET_VAL(_info, numOfElem, res) \ do { \ if ((numOfElem) <= 0) { \ @@ -927,12 +955,6 @@ EFuncDataRequired statisDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWin return FUNC_DATA_REQUIRED_STATIS_LOAD; } -typedef struct SMinmaxResInfo { - bool assign; // assign the first value or not - int64_t v; - STuplePos tuplePos; -} SMinmaxResInfo; - bool minmaxFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { if (!functionSetup(pCtx, pResultInfo)) { return false; // not initialized since it has been initialized @@ -1846,9 +1868,8 @@ int32_t leastSQRFunction(SqlFunctionCtx* pCtx) { } numOfElem++; LEASTSQR_CAL(param, x, plist, i, pInfo->stepVal); - - break; } + break; } case TSDB_DATA_TYPE_SMALLINT: { int16_t* plist = (int16_t*)pCol->pData; @@ -1873,7 +1894,6 @@ int32_t leastSQRFunction(SqlFunctionCtx* pCtx) { numOfElem++; LEASTSQR_CAL(param, x, plist, i, pInfo->stepVal); } - break; } @@ -4354,7 +4374,7 @@ bool getSampleFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) { SColumnNode* pCol = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0); SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1); int32_t numOfSamples = pVal->datum.i; - pEnv->calcMemSize = sizeof(SSampleInfo) + numOfSamples * (pCol->node.resType.bytes + sizeof(int64_t)); + pEnv->calcMemSize = sizeof(SSampleInfo) + numOfSamples * (pCol->node.resType.bytes + sizeof(STuplePos)); return true; } @@ -4375,25 +4395,30 @@ bool sampleFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) return false; } pInfo->data = (char*)pInfo + sizeof(SSampleInfo); - pInfo->timestamp = (int64_t*)((char*)pInfo + sizeof(SSampleInfo) + pInfo->samples * pInfo->colBytes); + pInfo->tuplePos = (STuplePos*)((char*)pInfo + sizeof(SSampleInfo) + pInfo->samples * pInfo->colBytes); return true; } -static void sampleAssignResult(SSampleInfo* pInfo, char* data, TSKEY ts, int32_t index) { +static void sampleAssignResult(SSampleInfo* pInfo, char* data, int32_t index) { assignVal(pInfo->data + index * pInfo->colBytes, data, pInfo->colBytes, pInfo->colType); - *(pInfo->timestamp + index) = ts; } -static void doReservoirSample(SSampleInfo* pInfo, char* data, TSKEY ts, int32_t index) { +static void doReservoirSample(SqlFunctionCtx* pCtx, SSampleInfo* pInfo, char* data, int32_t index) { pInfo->totalPoints++; if (pInfo->numSampled < pInfo->samples) { - sampleAssignResult(pInfo, data, ts, pInfo->numSampled); + sampleAssignResult(pInfo, data, pInfo->numSampled); + if (pCtx->subsidiaries.num > 0) { + saveTupleData(pCtx, index, pCtx->pSrcBlock, pInfo->tuplePos + pInfo->numSampled * sizeof(STuplePos)); + } pInfo->numSampled++; } else { int32_t j = taosRand() % (pInfo->totalPoints); if (j < pInfo->samples) { - sampleAssignResult(pInfo, data, ts, j); + sampleAssignResult(pInfo, data, j); + if (pCtx->subsidiaries.num > 0) { + copyTupleData(pCtx, index, pCtx->pSrcBlock, pInfo->tuplePos + j * sizeof(STuplePos)); + } } } } @@ -4404,11 +4429,6 @@ int32_t sampleFunction(SqlFunctionCtx* pCtx) { SInputColumnInfoData* pInput = &pCtx->input; - TSKEY* tsList = NULL; - if (pInput->pPTS != NULL) { - tsList = (int64_t*)pInput->pPTS->pData; - } - SColumnInfoData* pInputCol = pInput->pData[0]; for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) { if (colDataIsNull_s(pInputCol, i)) { @@ -4416,7 +4436,7 @@ int32_t sampleFunction(SqlFunctionCtx* pCtx) { } char* data = colDataGetData(pInputCol, i); - doReservoirSample(pInfo, data, /*tsList[i]*/ 0, i); + doReservoirSample(pCtx, pInfo, data, i); } SET_VAL(pResInfo, pInfo->numSampled, pInfo->numSampled); @@ -4435,6 +4455,7 @@ int32_t sampleFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t currentRow = pBlock->info.rows; for (int32_t i = 0; i < pInfo->numSampled; ++i) { colDataAppend(pCol, currentRow + i, pInfo->data + i * pInfo->colBytes, false); + setSelectivityValue(pCtx, pBlock, pInfo->tuplePos + i * sizeof(STuplePos), currentRow + i); } return pInfo->numSampled; @@ -4670,12 +4691,6 @@ int32_t uniqueFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { return pResInfo->numOfRes; } -typedef struct STwaInfo { - double dOutput; - SPoint1 p; - STimeWindow win; -} STwaInfo; - bool getTwaFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) { pEnv->calcMemSize = sizeof(STwaInfo); return true; @@ -5124,14 +5139,6 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { return TSDB_CODE_SUCCESS; } -typedef struct SDerivInfo { - double prevValue; // previous value - TSKEY prevTs; // previous timestamp - bool ignoreNegative; // ignore the negative value - int64_t tsWindow; // time window for derivative - bool valueSet; // the value has been set already -} SDerivInfo; - bool getDerivativeFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) { pEnv->calcMemSize = sizeof(SDerivInfo); return true; @@ -5226,6 +5233,117 @@ int32_t derivativeFunction(SqlFunctionCtx* pCtx) { return numOfElems; } +bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) { + pEnv->calcMemSize = sizeof(SRateInfo); + return true; +} + +bool irateFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) { + if (!functionSetup(pCtx, pResInfo)) { + return false; // not initialized since it has been initialized + } + + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); + + pInfo->firstKey = INT64_MIN; + pInfo->lastKey = INT64_MIN; + pInfo->firstValue = (double)INT64_MIN; + pInfo->lastValue = (double)INT64_MIN; + + pInfo->hasResult = 0; + return true; +} + +int32_t irateFunction(SqlFunctionCtx* pCtx) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SRateInfo* pRateInfo = GET_ROWCELL_INTERBUF(pResInfo); + + SInputColumnInfoData* pInput = &pCtx->input; + SColumnInfoData* pInputCol = pInput->pData[0]; + + SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput; + + TSKEY* tsList = (int64_t*)pInput->pPTS->pData; + + int32_t numOfElems = 0; + int32_t type = pInputCol->info.type; + + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) { + if (colDataIsNull_f(pInputCol->nullbitmap, i)) { + continue; + } + + numOfElems++; + + char* data = colDataGetData(pInputCol, i); + double v = 0; + GET_TYPED_DATA(v, double, type, data); + + if (INT64_MIN == pRateInfo->lastKey) { + pRateInfo->lastValue = v; + pRateInfo->lastKey = tsList[i]; + continue; + } + + if (tsList[i] > pRateInfo->lastKey) { + if ((INT64_MIN == pRateInfo->firstKey) || pRateInfo->lastKey > pRateInfo->firstKey) { + pRateInfo->firstValue = pRateInfo->lastValue; + pRateInfo->firstKey = pRateInfo->lastKey; + } + + pRateInfo->lastValue = v; + pRateInfo->lastKey = tsList[i]; + + continue; + } + + if ((INT64_MIN == pRateInfo->firstKey) || tsList[i] > pRateInfo->firstKey) { + pRateInfo->firstValue = v; + pRateInfo->firstKey = tsList[i]; + } + + } + + SET_VAL(pResInfo, numOfElems, 1); + return TSDB_CODE_SUCCESS; +} + +static double doCalcRate(const SRateInfo* pRateInfo, double tickPerSec) { + if ((INT64_MIN == pRateInfo->lastKey) || (INT64_MIN == pRateInfo->firstKey) || + (pRateInfo->firstKey >= pRateInfo->lastKey)) { + return 0.0; + } + + double diff = 0; + // If the previous value of the last is greater than the last value, only keep the last point instead of the delta + // value between two values. + diff = pRateInfo->lastValue; + if (diff >= pRateInfo->firstValue) { + diff -= pRateInfo->firstValue; + } + + int64_t duration = pRateInfo->lastKey - pRateInfo->firstKey; + if (duration == 0) { + return 0; + } + + return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0; +} + +int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { + int32_t slotId = pCtx->pExpr->base.resSchema.slotId; + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0; + + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); + double result = doCalcRate(pInfo, 1000); + colDataAppend(pCol, pBlock->info.rows, (const char*)&result, pResInfo->isNullRes); + + return pResInfo->numOfRes; +} + int32_t interpFunction(SqlFunctionCtx* pCtx) { #if 0 int32_t fillType = (int32_t) pCtx->param[2].i64; diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 710b01ce59..5fcf5e239c 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -186,6 +186,13 @@ bool fmIsInterpFunc(int32_t funcId) { return FUNCTION_TYPE_INTERP == funcMgtBuiltins[funcId].type; } +bool fmIsLastRowFunc(int32_t funcId) { + if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { + return false; + } + return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type; +} + void fmFuncMgtDestroy() { void* m = gFunMgtService.pFuncNameHashTable; if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) { diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 0ecad278e3..ea2a7567e4 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -467,7 +467,7 @@ int32_t getUdfdPipeName(char* pipeName, int32_t size) { dnodeId[0] = '1'; } #ifdef _WIN32 - snprintf(pipeName, size, "%s%s", UDF_LISTEN_PIPE_NAME_PREFIX, dnodeId); + snprintf(pipeName, size, "%s.%x.%s", UDF_LISTEN_PIPE_NAME_PREFIX,MurmurHash3_32(tsDataDir, strlen(tsDataDir)), dnodeId); #else snprintf(pipeName, size, "%s/%s%s", tsDataDir, UDF_LISTEN_PIPE_NAME_PREFIX, dnodeId); #endif diff --git a/source/libs/index/src/index.c b/source/libs/index/src/index.c index 04d7e04b30..d6d55c6be0 100644 --- a/source/libs/index/src/index.c +++ b/source/libs/index/src/index.c @@ -35,12 +35,12 @@ #define INDEX_DATA_BOOL_NULL 0x02 #define INDEX_DATA_TINYINT_NULL 0x80 #define INDEX_DATA_SMALLINT_NULL 0x8000 -#define INDEX_DATA_INT_NULL 0x80000000L -#define INDEX_DATA_BIGINT_NULL 0x8000000000000000L +#define INDEX_DATA_INT_NULL 0x80000000LL +#define INDEX_DATA_BIGINT_NULL 0x8000000000000000LL #define INDEX_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL #define INDEX_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN -#define INDEX_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN +#define INDEX_DATA_DOUBLE_NULL 0x7FFFFF0000000000LL // an NAN #define INDEX_DATA_NCHAR_NULL 0xFFFFFFFF #define INDEX_DATA_BINARY_NULL 0xFF #define INDEX_DATA_JSON_NULL 0xFFFFFFFF diff --git a/source/libs/index/src/indexComm.c b/source/libs/index/src/indexComm.c index 99b49f97bd..383d47e9c1 100644 --- a/source/libs/index/src/indexComm.c +++ b/source/libs/index/src/indexComm.c @@ -25,12 +25,12 @@ #define INDEX_DATA_BOOL_NULL 0x02 #define INDEX_DATA_TINYINT_NULL 0x80 #define INDEX_DATA_SMALLINT_NULL 0x8000 -#define INDEX_DATA_INT_NULL 0x80000000L -#define INDEX_DATA_BIGINT_NULL 0x8000000000000000L +#define INDEX_DATA_INT_NULL 0x80000000LL +#define INDEX_DATA_BIGINT_NULL 0x8000000000000000LL #define INDEX_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL #define INDEX_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN -#define INDEX_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN +#define INDEX_DATA_DOUBLE_NULL 0x7FFFFF0000000000LL // an NAN #define INDEX_DATA_NCHAR_NULL 0xFFFFFFFF #define INDEX_DATA_BINARY_NULL 0xFF #define INDEX_DATA_JSON_NULL 0xFFFFFFFF diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 5eaca60ea5..0bde0d0581 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -557,6 +557,14 @@ static SNode* physiSessionCopy(const SSessionWinodwPhysiNode* pSrc, SSessionWino return (SNode*)pDst; } +static SNode* physiPartitionCopy(const SPartitionPhysiNode* pSrc, SPartitionPhysiNode* pDst) { + COPY_BASE_OBJECT_FIELD(node, physiNodeCopy); + CLONE_NODE_LIST_FIELD(pExprs); + CLONE_NODE_LIST_FIELD(pPartitionKeys); + CLONE_NODE_LIST_FIELD(pTargets); + return (SNode*)pDst; +} + static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) { COPY_SCALAR_FIELD(dataBlockId); CLONE_NODE_LIST_FIELD(pSlots); @@ -694,7 +702,7 @@ SNode* nodesCloneNode(const SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: return physiSysTableScanCopy((const SSystemTableScanPhysiNode*)pNode, (SSystemTableScanPhysiNode*)pDst); case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: @@ -702,6 +710,8 @@ SNode* nodesCloneNode(const SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION: case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION: return physiSessionCopy((const SSessionWinodwPhysiNode*)pNode, (SSessionWinodwPhysiNode*)pDst); + case QUERY_NODE_PHYSICAL_PLAN_PARTITION: + return physiPartitionCopy((const SPartitionPhysiNode*)pNode, (SPartitionPhysiNode*)pDst); default: break; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index bde5159087..10a933b00b 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -220,6 +220,8 @@ const char* nodesNodeName(ENodeType type) { return "PhysiSystemTableScan"; case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: return "PhysiBlockDistScan"; + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: + return "PhysiLastRowScan"; case QUERY_NODE_PHYSICAL_PLAN_PROJECT: return "PhysiProject"; case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: @@ -234,8 +236,8 @@ const char* nodesNodeName(ENodeType type) { return "PhysiSort"; case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: return "PhysiHashInterval"; - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: - return "PhysiMergeInterval"; + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: + return "PhysiMergeAlignedInterval"; case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: return "PhysiStreamInterval"; case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: @@ -4105,6 +4107,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return logicPlanToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: return physiTagScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: @@ -4125,7 +4128,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_PHYSICAL_PLAN_SORT: return physiSortNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: @@ -4245,6 +4248,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToLogicPlan(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: return jsonToPhysiTagScanNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: @@ -4265,7 +4269,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { case QUERY_NODE_PHYSICAL_PLAN_SORT: return jsonToPhysiSortNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index a48071ef52..dff3821a0a 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -207,9 +207,12 @@ SNode* nodesMakeNode(ENodeType type) { case QUERY_NODE_SHOW_VNODES_STMT: case QUERY_NODE_SHOW_APPS_STMT: case QUERY_NODE_SHOW_SCORES_STMT: - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: + case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT: case QUERY_NODE_SHOW_TRANSACTIONS_STMT: return makeNode(type, sizeof(SShowStmt)); + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: + return makeNode(type, sizeof(SShowDnodeVariablesStmt)); case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: return makeNode(type, sizeof(SShowCreateDatabaseStmt)); case QUERY_NODE_SHOW_CREATE_TABLE_STMT: @@ -270,6 +273,8 @@ SNode* nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SSystemTableScanPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: return makeNode(type, sizeof(SBlockDistScanPhysiNode)); + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: + return makeNode(type, sizeof(SLastRowScanPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_PROJECT: return makeNode(type, sizeof(SProjectPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: @@ -284,8 +289,8 @@ SNode* nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SSortPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: return makeNode(type, sizeof(SIntervalPhysiNode)); - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: - return makeNode(type, sizeof(SMergeIntervalPhysiNode)); + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: + return makeNode(type, sizeof(SMergeAlignedIntervalPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: return makeNode(type, sizeof(SStreamIntervalPhysiNode)); case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: @@ -637,19 +642,22 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_SHOW_VNODES_STMT: case QUERY_NODE_SHOW_APPS_STMT: case QUERY_NODE_SHOW_SCORES_STMT: - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: + case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT: case QUERY_NODE_SHOW_TRANSACTIONS_STMT: { SShowStmt* pStmt = (SShowStmt*)pNode; nodesDestroyNode(pStmt->pDbName); nodesDestroyNode(pStmt->pTbName); break; } + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: // no pointer field + break; case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: taosMemoryFreeClear(((SShowCreateDatabaseStmt*)pNode)->pCfg); break; case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT: - taosMemoryFreeClear(((SShowCreateTableStmt*)pNode)->pMeta); + taosMemoryFreeClear(((SShowCreateTableStmt*)pNode)->pCfg); break; case QUERY_NODE_SHOW_TABLE_DISTRIBUTED_STMT: // no pointer field case QUERY_NODE_KILL_CONNECTION_STMT: // no pointer field @@ -775,6 +783,7 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: destroyScanPhysiNode((SScanPhysiNode*)pNode); break; case QUERY_NODE_PHYSICAL_PLAN_PROJECT: { @@ -819,7 +828,7 @@ void nodesDestroyNode(SNode* pNode) { break; } case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: - case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 64fcccc827..2d9bb49762 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -161,6 +161,7 @@ SNode* createShowStmtWithCond(SAstCreateContext* pCxt, ENodeType type, SNode* pD SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName); SNode* createShowCreateTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable); SNode* createShowTableDistributedStmt(SAstCreateContext* pCxt, SNode* pRealTable); +SNode* createShowDnodeVariablesStmt(SAstCreateContext* pCxt, SNode* pDnodeId); SNode* createCreateUserStmt(SAstCreateContext* pCxt, SToken* pUserName, const SToken* pPassword); SNode* createAlterUserStmt(SAstCreateContext* pCxt, SToken* pUserName, int8_t alterType, const SToken* pVal); SNode* createDropUserStmt(SAstCreateContext* pCxt, SToken* pUserName); diff --git a/source/libs/parser/inc/parUtil.h b/source/libs/parser/inc/parUtil.h index 862e3e2cc0..d06d6ec527 100644 --- a/source/libs/parser/inc/parUtil.h +++ b/source/libs/parser/inc/parUtil.h @@ -47,6 +47,9 @@ typedef struct SParseMetaCache { SHashObj* pUserAuth; // key is SUserAuthInfo serialized string, element is bool indicating whether or not to pass SHashObj* pUdf; // key is funcName, element is SFuncInfo* SHashObj* pTableIndex; // key is tbFName, element is SArray* + SHashObj* pTableCfg; // key is tbFName, element is STableCfg* + SArray* pDnodes; // element is SEpSet + bool dnodeRequired; } SParseMetaCache; int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...); @@ -77,6 +80,8 @@ int32_t reserveUserAuthInCache(int32_t acctId, const char* pUser, const char* pD int32_t reserveUserAuthInCacheExt(const char* pUser, const SName* pName, AUTH_TYPE type, SParseMetaCache* pMetaCache); int32_t reserveUdfInCache(const char* pFunc, SParseMetaCache* pMetaCache); int32_t reserveTableIndexInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache); +int32_t reserveTableCfgInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache); +int32_t reserveDnodeRequiredInCache(SParseMetaCache* pMetaCache); int32_t getTableMetaFromCache(SParseMetaCache* pMetaCache, const SName* pName, STableMeta** pMeta); int32_t getDbVgInfoFromCache(SParseMetaCache* pMetaCache, const char* pDbFName, SArray** pVgInfo); int32_t getTableVgroupFromCache(SParseMetaCache* pMetaCache, const SName* pName, SVgroupInfo* pVgroup); @@ -87,6 +92,8 @@ int32_t getUserAuthFromCache(SParseMetaCache* pMetaCache, const char* pUser, con bool* pPass); int32_t getUdfInfoFromCache(SParseMetaCache* pMetaCache, const char* pFunc, SFuncInfo* pInfo); int32_t getTableIndexFromCache(SParseMetaCache* pMetaCache, const SName* pName, SArray** pIndexes); +int32_t getTableCfgFromCache(SParseMetaCache* pMetaCache, const SName* pName, STableCfg** pOutput); +int32_t getDnodeListFromCache(SParseMetaCache* pMetaCache, SArray** pDnodes); void destoryParseMetaCache(SParseMetaCache* pMetaCache); #ifdef __cplusplus diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 4c808fc609..16a78712ed 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -373,7 +373,9 @@ cmd ::= SHOW CREATE STABLE full_table_name(A). cmd ::= SHOW QUERIES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } cmd ::= SHOW SCORES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SCORES_STMT); } cmd ::= SHOW TOPICS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT); } -cmd ::= SHOW VARIABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLE_STMT); } +cmd ::= SHOW VARIABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLES_STMT); } +cmd ::= SHOW LOCAL VARIABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } +cmd ::= SHOW DNODE NK_INTEGER(A) VARIABLES. { pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &A)); } cmd ::= SHOW BNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } cmd ::= SHOW SNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT); } cmd ::= SHOW CLUSTER. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT); } @@ -755,8 +757,9 @@ boolean_primary(A) ::= NK_LP(C) boolean_value_expression(B) NK_RP(D). common_expression(A) ::= expression(B). { A = B; } common_expression(A) ::= boolean_value_expression(B). { A = B; } -/************************************************ from_clause *********************************************************/ -from_clause(A) ::= FROM table_reference_list(B). { A = B; } +/************************************************ from_clause_opt *********************************************************/ +from_clause_opt(A) ::= . { A = NULL; } +from_clause_opt(A) ::= FROM table_reference_list(B). { A = B; } table_reference_list(A) ::= table_reference(B). { A = B; } table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); } @@ -790,9 +793,9 @@ join_type(A) ::= INNER. /************************************************ query_specification *************************************************/ query_specification(A) ::= - SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E) - partition_by_clause_opt(F) range_opt(J) every_opt(K) fill_opt(L) twindow_clause_opt(G) - group_by_clause_opt(H) having_clause_opt(I). { + SELECT set_quantifier_opt(B) select_list(C) from_clause_opt(D) + where_clause_opt(E) partition_by_clause_opt(F) range_opt(J) every_opt(K) + fill_opt(L) twindow_clause_opt(G) group_by_clause_opt(H) having_clause_opt(I). { A = createSelectStmt(pCxt, B, C, D); A = addWhereClause(pCxt, A, E); A = addPartitionByClause(pCxt, A, F); diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index ccb0d37da6..4fc5cf96e5 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1197,6 +1197,14 @@ SNode* createShowTableDistributedStmt(SAstCreateContext* pCxt, SNode* pRealTable return (SNode*)pStmt; } +SNode* createShowDnodeVariablesStmt(SAstCreateContext* pCxt, SNode* pDnodeId) { + CHECK_PARSER_STATUS(pCxt); + SShowDnodeVariablesStmt* pStmt = (SShowDnodeVariablesStmt*)nodesMakeNode(QUERY_NODE_SHOW_DNODE_VARIABLES_STMT); + CHECK_OUT_OF_MEM(pStmt); + pStmt->pDnodeId = pDnodeId; + return (SNode*)pStmt; +} + SNode* createCreateUserStmt(SAstCreateContext* pCxt, SToken* pUserName, const SToken* pPassword) { CHECK_PARSER_STATUS(pCxt); char password[TSDB_USET_PASSWORD_LEN] = {0}; diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 6058978451..46d2ae8383 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -397,12 +397,28 @@ static int32_t collectMetaKeyFromShowVariables(SCollectMetaKeyCxt* pCxt, SShowSt pCxt->pMetaCache); } +static int32_t collectMetaKeyFromShowDnodeVariables(SCollectMetaKeyCxt* pCxt, SShowDnodeVariablesStmt* pStmt) { + int32_t code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, + TSDB_INS_TABLE_DNODE_VARIABLES, pCxt->pMetaCache); + if (TSDB_CODE_SUCCESS == code) { + code = reserveDnodeRequiredInCache(pCxt->pMetaCache); + } + return code; +} + static int32_t collectMetaKeyFromShowCreateDatabase(SCollectMetaKeyCxt* pCxt, SShowCreateDatabaseStmt* pStmt) { return reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); } static int32_t collectMetaKeyFromShowCreateTable(SCollectMetaKeyCxt* pCxt, SShowCreateTableStmt* pStmt) { - return reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache); + SName name = {.type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId}; + strcpy(name.dbname, pStmt->dbName); + strcpy(name.tname, pStmt->tableName); + int32_t code = catalogRemoveTableMeta(pCxt->pParseCxt->pCatalog, &name); + if (TSDB_CODE_SUCCESS == code) { + code = reserveTableCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache); + } + return code; } static int32_t collectMetaKeyFromShowApps(SCollectMetaKeyCxt* pCxt, SShowStmt* pStmt) { @@ -502,8 +518,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromShowConnections(pCxt, (SShowStmt*)pStmt); case QUERY_NODE_SHOW_QUERIES_STMT: return collectMetaKeyFromShowQueries(pCxt, (SShowStmt*)pStmt); - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: return collectMetaKeyFromShowVariables(pCxt, (SShowStmt*)pStmt); + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: + return collectMetaKeyFromShowDnodeVariables(pCxt, (SShowDnodeVariablesStmt*)pStmt); case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: return collectMetaKeyFromShowCreateDatabase(pCxt, (SShowCreateDatabaseStmt*)pStmt); case QUERY_NODE_SHOW_CREATE_TABLE_STMT: diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 22d7afd642..0dfc79269e 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -227,12 +227,16 @@ static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) { } } } - DESTORY_LIST(pSelect->pGroupByList); + NODES_DESTORY_LIST(pSelect->pGroupByList); } return code; } -static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { +static int32_t calcConstSelectWithoutFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { + return calcConstProjections(pCxt, pSelect, subquery); +} + +static int32_t calcConstSelectFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { int32_t code = calcConstFromTable(pCxt, pSelect->pFromTable); if (TSDB_CODE_SUCCESS == code) { code = calcConstProjections(pCxt, pSelect, subquery); @@ -258,6 +262,14 @@ static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bo return code; } +static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { + if (NULL == pSelect->pFromTable) { + return calcConstSelectWithoutFrom(pCxt, pSelect, subquery); + } else { + return calcConstSelectFrom(pCxt, pSelect, subquery); + } +} + static int32_t calcConstDelete(SCalcConstContext* pCxt, SDeleteStmt* pDelete) { int32_t code = calcConstFromTable(pCxt, pDelete->pFromTable); if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index c8b78fcc8b..5d34250444 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -257,7 +257,7 @@ static int32_t checkAuth(SInsertParseContext* pCxt, char* pDbFname, bool* pPass) if (pBasicCtx->async) { return getUserAuthFromCache(pCxt->pMetaCache, pBasicCtx->pUser, pDbFname, AUTH_TYPE_WRITE, pPass); } - SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, + SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, .requestId = pBasicCtx->requestId, .requestObjRefId = pBasicCtx->requestRid, .mgmtEps = pBasicCtx->mgmtEpSet}; @@ -270,11 +270,11 @@ static int32_t getTableSchema(SInsertParseContext* pCxt, SName* pTbName, bool is if (pBasicCtx->async) { return getTableMetaFromCache(pCxt->pMetaCache, pTbName, pTableMeta); } - SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, + SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, .requestId = pBasicCtx->requestId, .requestObjRefId = pBasicCtx->requestRid, .mgmtEps = pBasicCtx->mgmtEpSet}; - + if (isStb) { return catalogGetSTableMeta(pBasicCtx->pCatalog, &conn, pTbName, pTableMeta); } @@ -286,7 +286,7 @@ static int32_t getTableVgroup(SInsertParseContext* pCxt, SName* pTbName, SVgroup if (pBasicCtx->async) { return getTableVgroupFromCache(pCxt->pMetaCache, pTbName, pVg); } - SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, + SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, .requestId = pBasicCtx->requestId, .requestObjRefId = pBasicCtx->requestRid, .mgmtEps = pBasicCtx->mgmtEpSet}; @@ -322,7 +322,7 @@ static int32_t getDBCfg(SInsertParseContext* pCxt, const char* pDbFName, SDbCfgI if (pBasicCtx->async) { CHECK_CODE(getDbCfgFromCache(pCxt->pMetaCache, pDbFName, pInfo)); } else { - SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, + SRequestConnInfo conn = {.pTrans = pBasicCtx->pTransporter, .requestId = pBasicCtx->requestId, .requestObjRefId = pBasicCtx->requestRid, .mgmtEps = pBasicCtx->mgmtEpSet}; @@ -1081,15 +1081,6 @@ end: return code; } -static int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) { - *pDst = taosMemoryMalloc(TABLE_META_SIZE(pSrc)); - if (NULL == *pDst) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - memcpy(*pDst, pSrc, TABLE_META_SIZE(pSrc)); - return TSDB_CODE_SUCCESS; -} - static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName* pTableName, const char* pName, int32_t len, STableMeta* pMeta) { SVgroupInfo vg; @@ -1315,15 +1306,6 @@ static void destroyInsertParseContext(SInsertParseContext* pCxt) { destroyBlockArrayList(pCxt->pVgDataBlocks); } -static int32_t checkSchemalessDb(SInsertParseContext* pCxt, char* pDbName) { -// SDbCfgInfo pInfo = {0}; -// char fullName[TSDB_TABLE_FNAME_LEN]; -// snprintf(fullName, sizeof(fullName), "%d.%s", pCxt->pComCxt->acctId, pDbName); -// CHECK_CODE(getDBCfg(pCxt, fullName, &pInfo)); -// return pInfo.schemaless ? TSDB_CODE_SML_INVALID_DB_CONF : TSDB_CODE_SUCCESS; - return TSDB_CODE_SUCCESS; -} - // tb_name // [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)] // [(field1_name, ...)] @@ -1377,8 +1359,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { SName name; CHECK_CODE(createSName(&name, &tbnameToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg)); - CHECK_CODE(checkSchemalessDb(pCxt, name.dbname)); - tNameExtractFullName(&name, tbFName); CHECK_CODE(taosHashPut(pCxt->pTableNameHashObj, tbFName, strlen(tbFName), &name, sizeof(SName))); char dbFName[TSDB_DB_FNAME_LEN]; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a60dba3a9a..6c21f71228 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -133,6 +133,30 @@ static int32_t getTableMeta(STranslateContext* pCxt, const char* pDbName, const return getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pDbName, pTableName, &name), pMeta); } +static int32_t getTableCfg(STranslateContext* pCxt, const SName* pName, STableCfg** pCfg) { + SParseContext* pParCxt = pCxt->pParseCxt; + int32_t code = collectUseDatabase(pName, pCxt->pDbs); + if (TSDB_CODE_SUCCESS == code) { + code = collectUseTable(pName, pCxt->pTables); + } + if (TSDB_CODE_SUCCESS == code) { + if (pParCxt->async) { + code = getTableCfgFromCache(pCxt->pMetaCache, pName, pCfg); + } else { + SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter, + .requestId = pParCxt->requestId, + .requestObjRefId = pParCxt->requestRid, + .mgmtEps = pParCxt->mgmtEpSet}; + code = catalogRefreshGetTableCfg(pParCxt->pCatalog, &conn, pName, pCfg); + } + } + if (TSDB_CODE_SUCCESS != code) { + parserError("catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, + pName->tname); + } + return code; +} + static int32_t refreshGetTableMeta(STranslateContext* pCxt, const char* pDbName, const char* pTableName, STableMeta** pMeta) { SParseContext* pParCxt = pCxt->pParseCxt; @@ -305,6 +329,24 @@ static int32_t getTableIndex(STranslateContext* pCxt, const SName* pName, SArray return code; } +static int32_t getDnodeList(STranslateContext* pCxt, SArray** pDnodes) { + SParseContext* pParCxt = pCxt->pParseCxt; + int32_t code = TSDB_CODE_SUCCESS; + if (pParCxt->async) { + code = getDnodeListFromCache(pCxt->pMetaCache, pDnodes); + } else { + SRequestConnInfo conn = {.pTrans = pParCxt->pTransporter, + .requestId = pParCxt->requestId, + .requestObjRefId = pParCxt->requestRid, + .mgmtEps = pParCxt->mgmtEpSet}; + code = catalogGetDnodeList(pParCxt->pCatalog, &conn, pDnodes); + } + if (TSDB_CODE_SUCCESS != code) { + parserError("getDnodeList error, code:%s", tstrerror(code)); + } + return code; +} + static int32_t initTranslateContext(SParseContext* pParseCxt, SParseMetaCache* pMetaCache, STranslateContext* pCxt) { pCxt->pParseCxt = pParseCxt; pCxt->errCode = TSDB_CODE_SUCCESS; @@ -647,6 +689,10 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p } static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) { + if (NULL != pCxt->pCurrSelectStmt && NULL == pCxt->pCurrSelectStmt->pFromTable) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName); + } + // count(*)/first(*)/last(*) and so on if (0 == strcmp((*pCol)->colName, "*")) { return DEAL_RES_CONTINUE; @@ -1158,6 +1204,7 @@ static void setFuncClassification(SSelectStmt* pSelect, SFunctionNode* pFunc) { pSelect->hasUniqueFunc = pSelect->hasUniqueFunc ? true : (FUNCTION_TYPE_UNIQUE == pFunc->funcType); pSelect->hasTailFunc = pSelect->hasTailFunc ? true : (FUNCTION_TYPE_TAIL == pFunc->funcType); pSelect->hasInterpFunc = pSelect->hasInterpFunc ? true : (FUNCTION_TYPE_INTERP == pFunc->funcType); + pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType); } } @@ -1450,12 +1497,27 @@ static int32_t addMnodeToVgroupList(const SEpSet* pEpSet, SArray** pVgroupList) return TSDB_CODE_SUCCESS; } -static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { - if (0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES) && - 0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLE_DISTRIBUTED)) { - return TSDB_CODE_SUCCESS; +static int32_t dnodeToVgroupsInfo(SArray* pDnodes, SVgroupsInfo** pVgsInfo) { + size_t ndnode = taosArrayGetSize(pDnodes); + *pVgsInfo = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * ndnode); + if (NULL == *pVgsInfo) { + return TSDB_CODE_OUT_OF_MEMORY; } + (*pVgsInfo)->numOfVgroups = ndnode; + for (int32_t i = 0; i < ndnode; ++i) { + memcpy(&((*pVgsInfo)->vgroups[i].epSet), taosArrayGet(pDnodes, i), sizeof(SEpSet)); + } + return TSDB_CODE_SUCCESS; +} +static bool sysTableFromVnode(const char* pTable) { + return (0 == strcmp(pTable, TSDB_INS_TABLE_USER_TABLES)) || + (0 == strcmp(pTable, TSDB_INS_TABLE_USER_TABLE_DISTRIBUTED)); +} + +static bool sysTableFromDnode(const char* pTable) { return 0 == strcmp(pTable, TSDB_INS_TABLE_DNODE_VARIABLES); } + +static int32_t setVnodeSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { int32_t code = TSDB_CODE_SUCCESS; SArray* vgroupList = NULL; if ('\0' != pRealTable->qualDbName[0]) { @@ -1478,6 +1540,26 @@ static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRea return code; } +static int32_t setDnodeSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { + SArray* pDnodes = NULL; + int32_t code = getDnodeList(pCxt, &pDnodes); + if (TSDB_CODE_SUCCESS == code) { + code = dnodeToVgroupsInfo(pDnodes, &pRealTable->pVgroupList); + } + taosArrayDestroy(pDnodes); + return code; +} + +static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { + if (sysTableFromVnode(pRealTable->table.tableName)) { + return setVnodeSysTableVgroupList(pCxt, pName, pRealTable); + } else if (sysTableFromDnode(pRealTable->table.tableName)) { + return setDnodeSysTableVgroupList(pCxt, pName, pRealTable); + } else { + return TSDB_CODE_SUCCESS; + } +} + static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { if (pCxt->pParseCxt->topicQuery) { return TSDB_CODE_SUCCESS; @@ -1952,9 +2034,9 @@ static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode* if (TIME_IS_VAR_DURATION(pInterval->unit)) { int64_t f = 1; if (pInterval->unit == 'n') { - f = 30L * MILLISECOND_PER_DAY; + f = 30LL * MILLISECOND_PER_DAY; } else if (pInterval->unit == 'y') { - f = 365L * MILLISECOND_PER_DAY; + f = 365LL * MILLISECOND_PER_DAY; } intervalRange = pInterval->datum.i * f; } else { @@ -2412,7 +2494,13 @@ static int32_t replaceOrderByAlias(STranslateContext* pCxt, SNodeList* pProjecti return pCxt->errCode; } -static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { +static int32_t translateSelectWithoutFrom(STranslateContext* pCxt, SSelectStmt* pSelect) { + pCxt->pCurrSelectStmt = pSelect; + pCxt->currClause = SQL_CLAUSE_SELECT; + return translateExprList(pCxt, pSelect->pProjectionList); +} + +static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->pCurrSelectStmt = pSelect; int32_t code = translateFrom(pCxt, pSelect->pFromTable); if (TSDB_CODE_SUCCESS == code) { @@ -2461,6 +2549,14 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { return code; } +static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { + if (NULL == pSelect->pFromTable) { + return translateSelectWithoutFrom(pCxt, pSelect); + } else { + return translateSelectFrom(pCxt, pSelect); + } +} + static SNode* createSetOperProject(const char* pTableAlias, SNode* pNode) { SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); if (NULL == pCol) { @@ -2613,7 +2709,7 @@ static int64_t getUnitPerMinute(uint8_t precision) { case TSDB_TIME_PRECISION_MILLI: return MILLISECOND_PER_MINUTE; case TSDB_TIME_PRECISION_MICRO: - return MILLISECOND_PER_MINUTE * 1000L; + return MILLISECOND_PER_MINUTE * 1000LL; case TSDB_TIME_PRECISION_NANO: return NANOSECOND_PER_MINUTE; default: @@ -3450,13 +3546,24 @@ static int32_t buildRollupAst(STranslateContext* pCxt, SCreateTableStmt* pStmt, return code; } +static int32_t buildRollupFuncs(SNodeList* pFuncs, SArray** pArray) { + if (NULL == pFuncs) { + return TSDB_CODE_SUCCESS; + } + *pArray = taosArrayInit(LIST_LENGTH(pFuncs), TSDB_FUNC_NAME_LEN); + SNode* pNode; + FOREACH(pNode, pFuncs) { + taosArrayPush(*pArray, ((SFunctionNode*)pNode)->functionName); + } + return TSDB_CODE_SUCCESS; +} + static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStmt, SMCreateStbReq* pReq) { pReq->igExists = pStmt->ignoreExists; pReq->delay1 = pStmt->pOptions->maxDelay1; pReq->delay2 = pStmt->pOptions->maxDelay2; pReq->watermark1 = pStmt->pOptions->watermark1; pReq->watermark2 = pStmt->pOptions->watermark2; - // pReq->ttl = pStmt->pOptions->ttl; columnDefNodeToField(pStmt->pCols, &pReq->pColumns); columnDefNodeToField(pStmt->pTags, &pReq->pTags); pReq->numOfColumns = LIST_LENGTH(pStmt->pCols); @@ -3470,6 +3577,7 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm } else { pReq->commentLen = -1; } + buildRollupFuncs(pStmt->pOptions->pRollupFuncs, &pReq->pFuncs); SName tableName; tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &tableName), pReq->name); @@ -4081,8 +4189,12 @@ static int32_t translateCreateStream(STranslateContext* pCxt, SCreateStreamStmt* } static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) { - // todo - return TSDB_CODE_SUCCESS; + SMDropStreamReq dropReq = {0}; + SName name; + tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->streamName, strlen(pStmt->streamName)); + tNameGetFullDbName(&name, dropReq.name); + dropReq.igNotExists = pStmt->ignoreNotExists; + return buildCmdMsg(pCxt, TDMT_MND_DROP_STREAM, (FSerializeFunc)tSerializeSMDropStreamReq, &dropReq); } static int32_t readFromFile(char* pName, int32_t* len, char** buf) { @@ -4239,7 +4351,10 @@ static int32_t translateShowCreateDatabase(STranslateContext* pCxt, SShowCreateD } static int32_t translateShowCreateTable(STranslateContext* pCxt, SShowCreateTableStmt* pStmt) { - return getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pStmt->pMeta); + SName name; + toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name); + + return getTableCfg(pCxt, &name, (STableCfg**)&pStmt->pCfg); } static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { @@ -4538,7 +4653,8 @@ static const char* getSysDbName(ENodeType type) { case QUERY_NODE_SHOW_SNODES_STMT: case QUERY_NODE_SHOW_LICENCE_STMT: case QUERY_NODE_SHOW_CLUSTER_STMT: - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: return TSDB_INFORMATION_SCHEMA_DB; case QUERY_NODE_SHOW_CONNECTIONS_STMT: case QUERY_NODE_SHOW_QUERIES_STMT: @@ -4595,10 +4711,12 @@ static const char* getSysTableName(ENodeType type) { return TSDB_PERFS_TABLE_TOPICS; case QUERY_NODE_SHOW_TRANSACTIONS_STMT: return TSDB_PERFS_TABLE_TRANS; - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: return TSDB_INS_TABLE_CONFIGS; case QUERY_NODE_SHOW_APPS_STMT: return TSDB_PERFS_TABLE_APPS; + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: + return TSDB_INS_TABLE_DNODE_VARIABLES; default: break; } @@ -4725,6 +4843,21 @@ static int32_t rewriteShow(STranslateContext* pCxt, SQuery* pQuery) { return code; } +static int32_t rewriteShowDnodeVariables(STranslateContext* pCxt, SQuery* pQuery) { + SSelectStmt* pStmt = NULL; + int32_t code = createSelectStmtForShow(nodeType(pQuery->pRoot), &pStmt); + if (TSDB_CODE_SUCCESS == code) { + code = createOperatorNode(OP_TYPE_EQUAL, "dnode_id", ((SShowDnodeVariablesStmt*)pQuery->pRoot)->pDnodeId, + &pStmt->pWhere); + } + if (TSDB_CODE_SUCCESS == code) { + pQuery->showRewrite = true; + nodesDestroyNode(pQuery->pRoot); + pQuery->pRoot = (SNode*)pStmt; + } + return code; +} + static SNode* createBlockDistInfoFunc() { SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); if (NULL == pFunc) { @@ -5720,10 +5853,13 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { case QUERY_NODE_SHOW_CLUSTER_STMT: case QUERY_NODE_SHOW_TOPICS_STMT: case QUERY_NODE_SHOW_TRANSACTIONS_STMT: - case QUERY_NODE_SHOW_VARIABLE_STMT: + case QUERY_NODE_SHOW_VARIABLES_STMT: case QUERY_NODE_SHOW_APPS_STMT: code = rewriteShow(pCxt, pQuery); break; + case QUERY_NODE_SHOW_DNODE_VARIABLES_STMT: + code = rewriteShowDnodeVariables(pCxt, pQuery); + break; case QUERY_NODE_SHOW_TABLE_DISTRIBUTED_STMT: code = rewriteShowTableDist(pCxt, pQuery); break; @@ -5814,6 +5950,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) { break; case QUERY_NODE_RESET_QUERY_CACHE_STMT: case QUERY_NODE_ALTER_LOCAL_STMT: + case QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT: pQuery->execMode = QUERY_EXEC_MODE_LOCAL; break; default: diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index d94b430c45..b474d95b3c 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -561,6 +561,10 @@ int32_t buildCatalogReq(const SParseMetaCache* pMetaCache, SCatalogReq* pCatalog if (TSDB_CODE_SUCCESS == code) { code = buildTableReq(pMetaCache->pTableIndex, &pCatalogReq->pTableIndex); } + if (TSDB_CODE_SUCCESS == code) { + code = buildTableReq(pMetaCache->pTableCfg, &pCatalogReq->pTableCfg); + } + pCatalogReq->dNodeRequired = pMetaCache->dnodeRequired; return code; } @@ -656,6 +660,10 @@ int32_t putMetaDataToCache(const SCatalogReq* pCatalogReq, const SMetaData* pMet if (TSDB_CODE_SUCCESS == code) { code = putTableDataToCache(pCatalogReq->pTableIndex, pMetaData->pTableIndex, &pMetaCache->pTableIndex); } + if (TSDB_CODE_SUCCESS == code) { + code = putTableDataToCache(pCatalogReq->pTableCfg, pMetaData->pTableCfg, &pMetaCache->pTableCfg); + } + pMetaCache->pDnodes = pMetaData->pDnodeList; return code; } @@ -861,6 +869,10 @@ int32_t reserveTableIndexInCache(int32_t acctId, const char* pDb, const char* pT return reserveTableReqInCache(acctId, pDb, pTable, &pMetaCache->pTableIndex); } +int32_t reserveTableCfgInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache) { + return reserveTableReqInCache(acctId, pDb, pTable, &pMetaCache->pTableCfg); +} + int32_t getTableIndexFromCache(SParseMetaCache* pMetaCache, const SName* pName, SArray** pIndexes) { char fullName[TSDB_TABLE_FNAME_LEN]; tNameExtractFullName(pName, fullName); @@ -875,6 +887,54 @@ int32_t getTableIndexFromCache(SParseMetaCache* pMetaCache, const SName* pName, return code; } +STableCfg* tableCfgDup(STableCfg* pCfg) { + STableCfg* pNew = taosMemoryMalloc(sizeof(*pNew)); + + memcpy(pNew, pCfg, sizeof(*pNew)); + if (pNew->pComment) { + pNew->pComment = strdup(pNew->pComment); + } + if (pNew->pFuncs) { + pNew->pFuncs = taosArrayDup(pNew->pFuncs); + } + + int32_t schemaSize = (pCfg->numOfColumns + pCfg->numOfTags) * sizeof(SSchema); + + SSchema* pSchema = taosMemoryMalloc(schemaSize); + memcpy(pSchema, pCfg->pSchemas, schemaSize); + + pNew->pSchemas = pSchema; + + return pNew; +} + +int32_t getTableCfgFromCache(SParseMetaCache* pMetaCache, const SName* pName, STableCfg** pOutput) { + char fullName[TSDB_TABLE_FNAME_LEN]; + tNameExtractFullName(pName, fullName); + STableCfg* pCfg = NULL; + int32_t code = getMetaDataFromHash(fullName, strlen(fullName), pMetaCache->pTableCfg, (void**)&pCfg); + if (TSDB_CODE_SUCCESS == code) { + *pOutput = tableCfgDup(pCfg); + if (NULL == *pOutput) { + code = TSDB_CODE_OUT_OF_MEMORY; + } + } + return code; +} + +int32_t reserveDnodeRequiredInCache(SParseMetaCache* pMetaCache) { + pMetaCache->dnodeRequired = true; + return TSDB_CODE_SUCCESS; +} + +int32_t getDnodeListFromCache(SParseMetaCache* pMetaCache, SArray** pDnodes) { + *pDnodes = taosArrayDup(pMetaCache->pDnodes); + if (NULL == *pDnodes) { + return TSDB_CODE_OUT_OF_MEMORY; + } + return TSDB_CODE_SUCCESS; +} + void destoryParseMetaCache(SParseMetaCache* pMetaCache) { taosHashCleanup(pMetaCache->pTableMeta); taosHashCleanup(pMetaCache->pDbVgroup); @@ -884,4 +944,5 @@ void destoryParseMetaCache(SParseMetaCache* pMetaCache) { taosHashCleanup(pMetaCache->pUserAuth); taosHashCleanup(pMetaCache->pUdf); taosHashCleanup(pMetaCache->pTableIndex); + taosHashCleanup(pMetaCache->pTableCfg); } diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 422661219e..330cf67b22 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -138,17 +138,17 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 636 -#define YYNRULE 464 +#define YYNSTATE 641 +#define YYNRULE 467 #define YYNTOKEN 242 -#define YY_MAX_SHIFT 635 -#define YY_MIN_SHIFTREDUCE 928 -#define YY_MAX_SHIFTREDUCE 1391 -#define YY_ERROR_ACTION 1392 -#define YY_ACCEPT_ACTION 1393 -#define YY_NO_ACTION 1394 -#define YY_MIN_REDUCE 1395 -#define YY_MAX_REDUCE 1858 +#define YY_MAX_SHIFT 640 +#define YY_MIN_SHIFTREDUCE 933 +#define YY_MAX_SHIFTREDUCE 1399 +#define YY_ERROR_ACTION 1400 +#define YY_ACCEPT_ACTION 1401 +#define YY_NO_ACTION 1402 +#define YY_MIN_REDUCE 1403 +#define YY_MAX_REDUCE 1869 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -215,221 +215,228 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2123) +#define YY_ACTTAB_COUNT (2192) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 1688, 1836, 1515, 309, 407, 1688, 408, 1427, 326, 1393, - /* 10 */ 137, 1685, 37, 35, 1483, 1835, 1685, 1701, 412, 1833, - /* 20 */ 318, 551, 1201, 551, 1223, 38, 36, 34, 33, 32, - /* 30 */ 325, 324, 109, 415, 109, 408, 1427, 1681, 1687, 446, - /* 40 */ 1215, 451, 1681, 1687, 1717, 30, 240, 1199, 554, 1526, - /* 50 */ 1784, 1526, 535, 554, 22, 551, 550, 1671, 14, 534, - /* 60 */ 37, 35, 1328, 322, 1207, 1208, 157, 335, 318, 1701, - /* 70 */ 1201, 134, 515, 365, 1781, 38, 36, 34, 33, 32, - /* 80 */ 1528, 1, 1207, 1526, 1730, 67, 550, 85, 1702, 537, - /* 90 */ 1704, 1705, 533, 58, 554, 1199, 1717, 1770, 113, 76, - /* 100 */ 371, 292, 1766, 632, 514, 551, 14, 1521, 1836, 1671, - /* 110 */ 1418, 534, 1207, 1836, 1836, 538, 369, 1270, 1271, 958, - /* 120 */ 1519, 555, 152, 465, 550, 1622, 1833, 154, 152, 2, - /* 130 */ 425, 1833, 1833, 1526, 206, 82, 1730, 290, 473, 86, - /* 140 */ 1702, 537, 1704, 1705, 533, 1362, 554, 40, 118, 1770, - /* 150 */ 1671, 632, 198, 311, 1766, 148, 1518, 962, 963, 1202, - /* 160 */ 58, 1200, 70, 328, 468, 1270, 1271, 232, 56, 462, - /* 170 */ 364, 134, 363, 1226, 197, 490, 1797, 1216, 330, 1211, - /* 180 */ 1528, 1571, 1573, 1205, 1206, 41, 1252, 1253, 1255, 1256, - /* 190 */ 1257, 1258, 1259, 530, 552, 1267, 1268, 1269, 1272, 53, - /* 200 */ 1225, 1219, 52, 1572, 1573, 26, 59, 1202, 1836, 1200, - /* 210 */ 505, 155, 552, 1267, 1268, 38, 36, 34, 33, 32, - /* 220 */ 37, 35, 153, 155, 1417, 1701, 1833, 397, 318, 67, - /* 230 */ 1201, 1205, 1206, 302, 1252, 1253, 1255, 1256, 1257, 1258, - /* 240 */ 1259, 530, 552, 1267, 1268, 1269, 1272, 511, 1717, 460, - /* 250 */ 459, 1522, 1717, 484, 458, 1199, 504, 114, 455, 1659, - /* 260 */ 535, 454, 453, 452, 1671, 1671, 14, 534, 37, 35, - /* 270 */ 1107, 1108, 1207, 166, 165, 117, 318, 155, 1201, 1292, - /* 280 */ 515, 1504, 303, 58, 301, 300, 356, 448, 58, 2, - /* 290 */ 155, 450, 1730, 503, 1836, 85, 1702, 537, 1704, 1705, - /* 300 */ 533, 1297, 554, 1199, 344, 1770, 358, 354, 152, 292, - /* 310 */ 1766, 632, 1833, 449, 115, 38, 36, 34, 33, 32, - /* 320 */ 1207, 1836, 136, 1517, 1407, 1270, 1271, 1502, 513, 149, - /* 330 */ 1777, 1778, 1327, 1782, 1685, 152, 27, 8, 425, 1833, - /* 340 */ 1065, 577, 576, 575, 1069, 574, 1071, 1072, 573, 1074, - /* 350 */ 570, 1396, 1080, 567, 1082, 1083, 564, 561, 81, 632, - /* 360 */ 1681, 1687, 38, 36, 34, 33, 32, 1202, 78, 1200, - /* 370 */ 1352, 554, 99, 1270, 1271, 98, 97, 96, 95, 94, - /* 380 */ 93, 92, 91, 90, 588, 1342, 38, 36, 34, 33, - /* 390 */ 32, 1205, 1206, 517, 1252, 1253, 1255, 1256, 1257, 1258, - /* 400 */ 1259, 530, 552, 1267, 1268, 1269, 1272, 497, 1350, 1351, - /* 410 */ 1353, 1354, 975, 155, 974, 1202, 99, 1200, 155, 98, + /* 0 */ 1698, 1847, 1523, 309, 412, 1698, 413, 1435, 326, 1401, + /* 10 */ 137, 1695, 37, 35, 1491, 1846, 1695, 1711, 417, 1844, + /* 20 */ 318, 556, 1208, 556, 1230, 38, 36, 34, 33, 32, + /* 30 */ 325, 324, 109, 420, 109, 413, 1435, 1691, 1697, 451, + /* 40 */ 1222, 456, 1691, 1697, 1727, 30, 240, 1206, 559, 1534, + /* 50 */ 1795, 1534, 540, 559, 22, 556, 555, 1681, 14, 539, + /* 60 */ 37, 35, 1336, 322, 1214, 1215, 157, 335, 318, 1711, + /* 70 */ 1208, 134, 520, 365, 1792, 38, 36, 34, 33, 32, + /* 80 */ 1536, 1, 1214, 1534, 1740, 67, 555, 85, 1712, 542, + /* 90 */ 1714, 1715, 538, 58, 559, 1206, 1727, 1780, 113, 76, + /* 100 */ 371, 292, 1776, 637, 519, 556, 14, 1529, 1847, 1681, + /* 110 */ 1426, 539, 1214, 1847, 1847, 543, 369, 1277, 1278, 963, + /* 120 */ 1527, 560, 152, 470, 555, 1632, 1844, 154, 152, 2, + /* 130 */ 430, 1844, 1844, 1534, 206, 82, 1740, 290, 478, 86, + /* 140 */ 1712, 542, 1714, 1715, 538, 1370, 559, 40, 118, 1780, + /* 150 */ 1681, 637, 198, 311, 1776, 148, 1526, 967, 968, 1209, + /* 160 */ 58, 1207, 70, 328, 473, 1277, 1278, 232, 56, 467, + /* 170 */ 364, 134, 363, 1233, 197, 495, 1808, 1223, 330, 1218, + /* 180 */ 1536, 1579, 1581, 1212, 1213, 41, 1259, 1260, 1262, 1263, + /* 190 */ 1264, 1265, 1266, 535, 557, 1274, 1275, 1276, 1279, 53, + /* 200 */ 1232, 1226, 52, 1580, 1581, 26, 59, 1209, 1847, 1207, + /* 210 */ 510, 155, 557, 1274, 1275, 38, 36, 34, 33, 32, + /* 220 */ 37, 35, 153, 155, 1425, 1711, 1844, 402, 318, 67, + /* 230 */ 1208, 1212, 1213, 302, 1259, 1260, 1262, 1263, 1264, 1265, + /* 240 */ 1266, 535, 557, 1274, 1275, 1276, 1279, 516, 1727, 465, + /* 250 */ 464, 1530, 1727, 489, 463, 1206, 509, 114, 460, 1669, + /* 260 */ 540, 459, 458, 457, 1681, 1681, 14, 539, 37, 35, + /* 270 */ 1112, 1113, 1214, 166, 165, 117, 318, 155, 1208, 1299, + /* 280 */ 520, 1512, 303, 58, 301, 300, 356, 453, 58, 2, + /* 290 */ 155, 455, 1740, 508, 1847, 85, 1712, 542, 1714, 1715, + /* 300 */ 538, 1304, 559, 1206, 344, 1780, 358, 354, 152, 292, + /* 310 */ 1776, 637, 1844, 454, 115, 38, 36, 34, 33, 32, + /* 320 */ 1214, 1847, 136, 1525, 1415, 1277, 1278, 1510, 518, 149, + /* 330 */ 1788, 1789, 1233, 1793, 1695, 152, 27, 8, 430, 1844, + /* 340 */ 1070, 582, 581, 580, 1074, 579, 1076, 1077, 578, 1079, + /* 350 */ 575, 1404, 1085, 572, 1087, 1088, 569, 566, 81, 637, + /* 360 */ 1691, 1697, 38, 36, 34, 33, 32, 1209, 78, 1207, + /* 370 */ 1360, 559, 99, 1277, 1278, 98, 97, 96, 95, 94, + /* 380 */ 93, 92, 91, 90, 593, 1350, 38, 36, 34, 33, + /* 390 */ 32, 1212, 1213, 522, 1259, 1260, 1262, 1263, 1264, 1265, + /* 400 */ 1266, 535, 557, 1274, 1275, 1276, 1279, 502, 1358, 1359, + /* 410 */ 1361, 1362, 980, 155, 979, 1209, 99, 1207, 155, 98, /* 420 */ 97, 96, 95, 94, 93, 92, 91, 90, 37, 35, - /* 430 */ 1273, 406, 414, 1701, 410, 410, 318, 162, 1201, 1205, - /* 440 */ 1206, 976, 1252, 1253, 1255, 1256, 1257, 1258, 1259, 530, - /* 450 */ 552, 1267, 1268, 1269, 1272, 38, 36, 34, 33, 32, - /* 460 */ 1717, 474, 65, 1199, 1836, 64, 1027, 155, 535, 975, - /* 470 */ 199, 974, 1578, 1671, 1416, 534, 37, 35, 1834, 308, - /* 480 */ 1207, 1454, 1833, 1029, 318, 1784, 1201, 592, 1576, 1498, - /* 490 */ 38, 36, 34, 33, 32, 1415, 444, 9, 976, 500, - /* 500 */ 1730, 1388, 1836, 87, 1702, 537, 1704, 1705, 533, 1780, - /* 510 */ 554, 1199, 200, 1770, 1671, 1226, 152, 1769, 1766, 632, - /* 520 */ 1833, 538, 133, 1578, 147, 1239, 69, 291, 1207, 321, - /* 530 */ 323, 1621, 588, 1270, 1271, 1671, 293, 1565, 1414, 1576, - /* 540 */ 1326, 610, 609, 608, 333, 9, 607, 606, 605, 119, - /* 550 */ 600, 599, 598, 597, 596, 595, 594, 593, 127, 589, - /* 560 */ 1239, 1395, 38, 36, 34, 33, 32, 632, 1290, 506, - /* 570 */ 501, 1183, 1184, 1227, 1335, 1202, 1413, 1200, 1671, 1412, - /* 580 */ 1225, 1270, 1271, 1387, 28, 108, 107, 106, 105, 104, - /* 590 */ 103, 102, 101, 100, 38, 36, 34, 33, 32, 1205, - /* 600 */ 1206, 1411, 1252, 1253, 1255, 1256, 1257, 1258, 1259, 530, - /* 610 */ 552, 1267, 1268, 1269, 1272, 551, 1671, 1578, 134, 1671, - /* 620 */ 1291, 1224, 331, 1202, 329, 1200, 370, 1529, 1278, 1410, - /* 630 */ 134, 457, 456, 1576, 1225, 1207, 37, 35, 1457, 1528, - /* 640 */ 1228, 1671, 1296, 1526, 318, 1503, 1201, 1205, 1206, 527, - /* 650 */ 1252, 1253, 1255, 1256, 1257, 1258, 1259, 530, 552, 1267, - /* 660 */ 1268, 1269, 1272, 11, 10, 34, 33, 32, 1784, 1671, - /* 670 */ 580, 1199, 38, 36, 34, 33, 32, 29, 316, 1285, - /* 680 */ 1286, 1287, 1288, 1289, 1293, 1294, 1295, 584, 1207, 511, - /* 690 */ 1569, 1689, 1779, 604, 602, 1409, 7, 551, 460, 459, - /* 700 */ 586, 231, 1685, 458, 551, 2, 114, 455, 372, 450, - /* 710 */ 454, 453, 452, 1406, 1578, 382, 1225, 117, 293, 125, - /* 720 */ 124, 583, 582, 581, 289, 1526, 1223, 632, 1681, 1687, - /* 730 */ 1577, 449, 1526, 390, 551, 1671, 402, 515, 586, 554, - /* 740 */ 585, 1270, 1271, 1569, 1304, 383, 135, 1254, 1405, 1404, - /* 750 */ 1290, 269, 263, 1671, 403, 1556, 115, 125, 124, 583, - /* 760 */ 582, 581, 1526, 267, 55, 1403, 551, 54, 212, 551, - /* 770 */ 551, 229, 1777, 510, 1282, 509, 551, 424, 1836, 1612, - /* 780 */ 1523, 1648, 522, 1202, 167, 1200, 373, 253, 1671, 1671, - /* 790 */ 164, 591, 154, 519, 1526, 551, 1833, 1526, 1526, 962, - /* 800 */ 963, 1254, 1291, 1511, 1526, 1671, 482, 1205, 1206, 58, - /* 810 */ 1252, 1253, 1255, 1256, 1257, 1258, 1259, 530, 552, 1267, - /* 820 */ 1268, 1269, 1272, 1526, 1296, 1513, 401, 1789, 1323, 396, - /* 830 */ 395, 394, 393, 392, 389, 388, 387, 386, 385, 381, - /* 840 */ 380, 379, 378, 377, 376, 375, 374, 84, 1402, 1509, - /* 850 */ 190, 1701, 1201, 188, 203, 1401, 1400, 1399, 1398, 29, - /* 860 */ 316, 1285, 1286, 1287, 1288, 1289, 1293, 1294, 1295, 1323, - /* 870 */ 603, 192, 194, 196, 191, 193, 195, 1199, 1717, 62, - /* 880 */ 61, 368, 529, 1254, 161, 999, 514, 1501, 1671, 551, - /* 890 */ 362, 1671, 1701, 534, 1207, 1671, 1671, 1671, 1671, 472, - /* 900 */ 548, 288, 1000, 123, 352, 48, 350, 346, 342, 158, - /* 910 */ 337, 359, 470, 216, 11, 10, 1210, 1526, 1730, 1717, - /* 920 */ 1209, 86, 1702, 537, 1704, 1705, 533, 535, 554, 551, - /* 930 */ 1444, 1770, 1671, 632, 534, 311, 1766, 148, 39, 155, - /* 940 */ 549, 1390, 1391, 579, 486, 39, 1349, 1433, 481, 39, - /* 950 */ 1408, 1484, 461, 1439, 218, 1691, 235, 1526, 1798, 1730, - /* 960 */ 551, 1437, 86, 1702, 537, 1704, 1705, 533, 242, 554, - /* 970 */ 1701, 332, 1770, 523, 121, 463, 311, 1766, 1849, 1298, - /* 980 */ 586, 122, 520, 466, 123, 498, 1260, 1804, 1526, 1202, - /* 990 */ 1156, 1200, 1693, 628, 475, 443, 1701, 1717, 223, 125, - /* 1000 */ 124, 583, 582, 581, 1718, 535, 334, 1428, 48, 244, - /* 1010 */ 1671, 559, 534, 1205, 1206, 543, 1800, 122, 123, 110, - /* 1020 */ 122, 1566, 250, 1717, 512, 1058, 3, 234, 237, 239, - /* 1030 */ 1213, 535, 5, 336, 1212, 1223, 1671, 1730, 534, 343, - /* 1040 */ 86, 1702, 537, 1704, 1705, 533, 339, 554, 1701, 262, - /* 1050 */ 1770, 1027, 1086, 298, 311, 1766, 1849, 1701, 1090, 1097, - /* 1060 */ 1095, 126, 299, 1730, 1167, 1827, 86, 1702, 537, 1704, - /* 1070 */ 1705, 533, 259, 554, 384, 1717, 1770, 1614, 163, 399, - /* 1080 */ 311, 1766, 1849, 535, 1717, 391, 398, 400, 1671, 404, - /* 1090 */ 534, 1788, 535, 1229, 405, 413, 1232, 1671, 416, 534, - /* 1100 */ 170, 417, 172, 515, 1231, 418, 1701, 1233, 419, 175, - /* 1110 */ 421, 177, 515, 422, 1230, 1730, 423, 426, 278, 1702, - /* 1120 */ 537, 1704, 1705, 533, 1730, 554, 180, 278, 1702, 537, - /* 1130 */ 1704, 1705, 533, 1717, 554, 66, 183, 445, 447, 1516, - /* 1140 */ 187, 535, 307, 1512, 1836, 89, 1671, 1701, 534, 189, - /* 1150 */ 201, 260, 476, 1836, 128, 129, 1514, 1510, 154, 1653, - /* 1160 */ 130, 131, 1833, 477, 204, 1701, 1652, 152, 483, 207, - /* 1170 */ 1228, 1833, 487, 1730, 1717, 485, 87, 1702, 537, 1704, - /* 1180 */ 1705, 533, 532, 554, 488, 480, 1770, 1671, 210, 534, - /* 1190 */ 526, 1766, 1717, 499, 494, 214, 1811, 496, 541, 1810, - /* 1200 */ 535, 217, 310, 502, 1791, 1671, 6, 534, 1801, 508, - /* 1210 */ 495, 492, 222, 493, 1730, 1323, 1701, 286, 1702, 537, - /* 1220 */ 1704, 1705, 533, 531, 554, 528, 1742, 1227, 116, 227, - /* 1230 */ 42, 524, 1730, 142, 635, 138, 1702, 537, 1704, 1705, - /* 1240 */ 533, 1785, 554, 1717, 312, 226, 224, 521, 258, 18, - /* 1250 */ 1620, 535, 1619, 228, 539, 544, 1671, 1751, 534, 225, - /* 1260 */ 145, 1832, 545, 233, 246, 546, 626, 622, 618, 614, - /* 1270 */ 257, 540, 1527, 320, 248, 261, 75, 1701, 77, 557, - /* 1280 */ 516, 1850, 518, 1730, 525, 1852, 87, 1702, 537, 1704, - /* 1290 */ 1705, 533, 236, 554, 1701, 83, 1770, 1570, 251, 238, - /* 1300 */ 264, 1767, 1499, 631, 1717, 256, 141, 511, 270, 49, - /* 1310 */ 279, 271, 535, 266, 268, 1665, 1664, 1671, 60, 534, - /* 1320 */ 1663, 1717, 338, 1660, 340, 341, 1194, 1195, 159, 535, - /* 1330 */ 491, 547, 345, 1658, 1671, 117, 534, 347, 348, 349, - /* 1340 */ 1657, 351, 1656, 353, 1730, 1701, 355, 287, 1702, 537, - /* 1350 */ 1704, 1705, 533, 1655, 554, 515, 1654, 357, 1638, 489, - /* 1360 */ 360, 1730, 208, 361, 282, 1702, 537, 1704, 1705, 533, - /* 1370 */ 160, 554, 1717, 511, 115, 1170, 1632, 1169, 1631, 366, - /* 1380 */ 535, 1175, 367, 202, 1630, 1671, 1629, 534, 1142, 229, - /* 1390 */ 1777, 510, 1607, 509, 63, 1606, 1836, 1605, 1604, 1701, - /* 1400 */ 1603, 117, 1602, 507, 1601, 1600, 1599, 1598, 1701, 1597, - /* 1410 */ 152, 1596, 1730, 1595, 1833, 138, 1702, 537, 1704, 1705, - /* 1420 */ 533, 1594, 554, 1593, 1592, 1591, 1717, 1590, 1589, 120, - /* 1430 */ 1588, 1587, 1586, 1585, 535, 1717, 1144, 1582, 1581, 1671, - /* 1440 */ 115, 534, 1584, 532, 1583, 1580, 1579, 1456, 1671, 1424, - /* 1450 */ 534, 146, 315, 111, 965, 150, 1777, 1778, 168, 1782, - /* 1460 */ 1423, 1851, 1701, 409, 964, 1646, 1730, 169, 1640, 287, - /* 1470 */ 1702, 537, 1704, 1705, 533, 1730, 554, 511, 286, 1702, - /* 1480 */ 537, 1704, 1705, 533, 1628, 554, 176, 1743, 112, 1717, - /* 1490 */ 1627, 174, 411, 1617, 179, 1505, 1455, 535, 993, 1453, - /* 1500 */ 185, 429, 1671, 427, 534, 117, 428, 1451, 433, 1449, - /* 1510 */ 431, 432, 140, 1701, 437, 317, 435, 436, 442, 438, - /* 1520 */ 434, 430, 184, 1447, 440, 439, 441, 1701, 1436, 1730, - /* 1530 */ 1435, 1422, 287, 1702, 537, 1704, 1705, 533, 1101, 554, - /* 1540 */ 1717, 1507, 47, 186, 115, 1506, 1100, 68, 535, 1026, - /* 1550 */ 182, 1025, 1024, 1671, 1717, 534, 601, 1023, 603, 151, - /* 1560 */ 1777, 1778, 535, 1782, 1445, 1020, 319, 1671, 1019, 534, - /* 1570 */ 304, 1440, 1018, 305, 464, 1438, 306, 1421, 469, 467, - /* 1580 */ 1730, 1420, 1701, 287, 1702, 537, 1704, 1705, 533, 471, - /* 1590 */ 554, 1701, 88, 1645, 1730, 1639, 1177, 272, 1702, 537, - /* 1600 */ 1704, 1705, 533, 1626, 554, 1701, 51, 478, 132, 1717, - /* 1610 */ 181, 1625, 173, 1624, 178, 205, 420, 535, 1717, 1616, - /* 1620 */ 71, 479, 1671, 50, 534, 209, 535, 4, 211, 1364, - /* 1630 */ 39, 1671, 1717, 534, 23, 171, 221, 15, 213, 45, - /* 1640 */ 535, 215, 1348, 139, 219, 1671, 24, 534, 1341, 1730, - /* 1650 */ 220, 1691, 273, 1702, 537, 1704, 1705, 533, 1730, 554, - /* 1660 */ 72, 274, 1702, 537, 1704, 1705, 533, 25, 554, 1320, - /* 1670 */ 44, 230, 1730, 1319, 16, 281, 1702, 537, 1704, 1705, - /* 1680 */ 533, 1701, 554, 43, 143, 17, 1381, 1370, 1376, 1375, - /* 1690 */ 313, 13, 1380, 1379, 314, 10, 1283, 19, 1701, 144, - /* 1700 */ 1262, 31, 1247, 1261, 12, 20, 156, 1701, 1717, 21, - /* 1710 */ 1615, 243, 536, 241, 1346, 245, 535, 73, 247, 542, - /* 1720 */ 74, 1671, 1690, 534, 78, 1717, 249, 252, 1217, 1733, - /* 1730 */ 556, 1264, 553, 535, 1717, 46, 558, 327, 1671, 1087, - /* 1740 */ 534, 560, 535, 1084, 562, 563, 565, 1671, 1730, 534, - /* 1750 */ 1081, 283, 1702, 537, 1704, 1705, 533, 566, 554, 1701, - /* 1760 */ 568, 1075, 571, 569, 1079, 1730, 1073, 572, 275, 1702, - /* 1770 */ 537, 1704, 1705, 533, 1730, 554, 1078, 284, 1702, 537, - /* 1780 */ 1704, 1705, 533, 1701, 554, 1064, 1717, 578, 79, 80, - /* 1790 */ 1077, 1096, 1076, 57, 535, 254, 1092, 991, 587, 1671, - /* 1800 */ 1701, 534, 1015, 1033, 590, 255, 1013, 1012, 1011, 1010, - /* 1810 */ 1717, 1008, 1009, 1007, 1006, 1030, 1028, 1003, 535, 1002, - /* 1820 */ 1001, 1452, 998, 1671, 997, 534, 1730, 1717, 996, 276, - /* 1830 */ 1702, 537, 1704, 1705, 533, 535, 554, 611, 612, 613, - /* 1840 */ 1671, 1450, 534, 615, 616, 617, 1448, 621, 619, 620, - /* 1850 */ 1730, 1701, 1446, 285, 1702, 537, 1704, 1705, 533, 623, - /* 1860 */ 554, 624, 1701, 625, 1434, 627, 1419, 1730, 634, 629, - /* 1870 */ 277, 1702, 537, 1704, 1705, 533, 630, 554, 1717, 1203, - /* 1880 */ 265, 633, 1394, 1394, 1394, 1394, 535, 1394, 1394, 1717, - /* 1890 */ 1394, 1671, 1394, 534, 1394, 1394, 1394, 535, 1394, 1394, - /* 1900 */ 1394, 1394, 1671, 1701, 534, 1394, 1394, 1394, 1394, 1394, - /* 1910 */ 1394, 1394, 1394, 1394, 1701, 1394, 1394, 1394, 1730, 1394, - /* 1920 */ 1394, 1713, 1702, 537, 1704, 1705, 533, 1394, 554, 1730, - /* 1930 */ 1717, 1394, 1712, 1702, 537, 1704, 1705, 533, 535, 554, - /* 1940 */ 1394, 1717, 1394, 1671, 1394, 534, 1394, 1394, 1394, 535, - /* 1950 */ 1394, 1394, 1394, 1394, 1671, 1394, 534, 1394, 1394, 1394, - /* 1960 */ 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1701, 1394, 1394, - /* 1970 */ 1730, 1394, 1394, 1711, 1702, 537, 1704, 1705, 533, 1701, - /* 1980 */ 554, 1730, 1394, 1394, 296, 1702, 537, 1704, 1705, 533, - /* 1990 */ 1394, 554, 1394, 1701, 1717, 1394, 1394, 1394, 1394, 1394, - /* 2000 */ 1394, 1394, 535, 1394, 1394, 1394, 1717, 1671, 1394, 534, - /* 2010 */ 1394, 1394, 1394, 1394, 535, 1394, 1394, 1394, 1394, 1671, - /* 2020 */ 1717, 534, 1394, 1394, 1394, 1394, 1394, 1394, 535, 1394, - /* 2030 */ 1394, 1394, 1394, 1671, 1730, 534, 1394, 295, 1702, 537, - /* 2040 */ 1704, 1705, 533, 1394, 554, 1701, 1730, 1394, 1394, 297, - /* 2050 */ 1702, 537, 1704, 1705, 533, 1394, 554, 1394, 1394, 1394, - /* 2060 */ 1730, 1394, 1394, 294, 1702, 537, 1704, 1705, 533, 1394, - /* 2070 */ 554, 1394, 1717, 1394, 1394, 1394, 1394, 1394, 1394, 1394, - /* 2080 */ 535, 1394, 1394, 1394, 1394, 1671, 1394, 534, 1394, 1394, - /* 2090 */ 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, - /* 2100 */ 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, 1394, - /* 2110 */ 1394, 1394, 1730, 1394, 1394, 280, 1702, 537, 1704, 1705, - /* 2120 */ 533, 1394, 554, + /* 430 */ 1280, 11, 10, 1711, 462, 461, 318, 162, 1208, 1212, + /* 440 */ 1213, 981, 1259, 1260, 1262, 1263, 1264, 1265, 1266, 535, + /* 450 */ 557, 1274, 1275, 1276, 1279, 38, 36, 34, 33, 32, + /* 460 */ 1727, 479, 65, 1206, 1847, 64, 593, 155, 540, 980, + /* 470 */ 147, 979, 1586, 1681, 1231, 539, 37, 35, 1845, 308, + /* 480 */ 1214, 1462, 1844, 1573, 318, 1795, 1208, 1424, 1584, 1214, + /* 490 */ 38, 36, 34, 33, 32, 1423, 449, 9, 981, 1234, + /* 500 */ 1740, 1396, 1847, 87, 1712, 542, 1714, 1715, 538, 1791, + /* 510 */ 559, 1206, 1311, 1780, 199, 134, 152, 1779, 1776, 637, + /* 520 */ 1844, 543, 133, 1586, 1537, 1246, 1343, 1681, 1214, 321, + /* 530 */ 323, 1631, 1232, 1277, 1278, 1681, 293, 609, 607, 1584, + /* 540 */ 1422, 615, 614, 613, 333, 9, 612, 611, 610, 119, + /* 550 */ 605, 604, 603, 602, 601, 600, 599, 598, 127, 594, + /* 560 */ 1246, 1403, 38, 36, 34, 33, 32, 637, 1297, 505, + /* 570 */ 69, 291, 1285, 967, 968, 1209, 1421, 1207, 1232, 1420, + /* 580 */ 1681, 1277, 1278, 1395, 28, 108, 107, 106, 105, 104, + /* 590 */ 103, 102, 101, 100, 38, 36, 34, 33, 32, 1212, + /* 600 */ 1213, 1511, 1259, 1260, 1262, 1263, 1264, 1265, 1266, 535, + /* 610 */ 557, 1274, 1275, 1276, 1279, 556, 1681, 1586, 1586, 1681, + /* 620 */ 1298, 331, 585, 1209, 329, 1207, 370, 231, 1519, 134, + /* 630 */ 34, 33, 32, 1584, 1585, 1419, 37, 35, 1536, 511, + /* 640 */ 506, 200, 1303, 1534, 318, 591, 1208, 1212, 1213, 1418, + /* 650 */ 1259, 1260, 1262, 1263, 1264, 1265, 1266, 535, 557, 1274, + /* 660 */ 1275, 1276, 1279, 556, 125, 124, 588, 587, 586, 411, + /* 670 */ 419, 1206, 415, 415, 372, 1681, 556, 29, 316, 1292, + /* 680 */ 1293, 1294, 1295, 1296, 1300, 1301, 1302, 387, 1214, 1681, + /* 690 */ 185, 1534, 556, 263, 591, 597, 1564, 1506, 1417, 1261, + /* 700 */ 1190, 1191, 140, 388, 1534, 2, 1414, 556, 447, 443, + /* 710 */ 439, 435, 184, 125, 124, 588, 587, 586, 429, 1795, + /* 720 */ 1534, 1699, 1711, 1335, 289, 1232, 1230, 637, 1413, 1701, + /* 730 */ 1412, 455, 1695, 395, 7, 1534, 407, 68, 1681, 556, + /* 740 */ 182, 1277, 1278, 1790, 556, 1261, 1681, 1411, 1410, 1727, + /* 750 */ 1531, 380, 1235, 454, 408, 1658, 382, 540, 1691, 1697, + /* 760 */ 135, 524, 1681, 556, 539, 269, 1703, 1534, 1681, 559, + /* 770 */ 1681, 1622, 1534, 556, 487, 496, 589, 267, 55, 1577, + /* 780 */ 527, 54, 164, 1209, 553, 1207, 373, 1681, 1681, 1740, + /* 790 */ 596, 1534, 287, 1712, 542, 1714, 1715, 538, 167, 559, + /* 800 */ 181, 1534, 173, 1465, 178, 1521, 425, 1212, 1213, 1409, + /* 810 */ 1259, 1260, 1262, 1263, 1264, 1265, 1266, 535, 557, 1274, + /* 820 */ 1275, 1276, 1279, 58, 590, 171, 406, 1577, 1517, 401, + /* 830 */ 400, 399, 398, 397, 394, 393, 392, 391, 390, 386, + /* 840 */ 385, 384, 383, 377, 376, 375, 374, 203, 1032, 1681, + /* 850 */ 38, 36, 34, 33, 32, 556, 556, 1208, 556, 516, + /* 860 */ 1408, 84, 1407, 465, 464, 1034, 554, 253, 463, 332, + /* 870 */ 1406, 114, 460, 1800, 1331, 459, 458, 457, 608, 1452, + /* 880 */ 212, 534, 1206, 1534, 1534, 190, 1534, 117, 188, 486, + /* 890 */ 1711, 1509, 1261, 62, 61, 368, 293, 1217, 161, 1214, + /* 900 */ 1681, 466, 1681, 192, 362, 516, 191, 1331, 194, 196, + /* 910 */ 1681, 193, 195, 1447, 1445, 288, 584, 1727, 352, 359, + /* 920 */ 350, 346, 342, 158, 337, 519, 115, 477, 1297, 1416, + /* 930 */ 1681, 1334, 539, 117, 1216, 468, 471, 123, 637, 1004, + /* 940 */ 475, 150, 1788, 1789, 532, 1793, 235, 11, 10, 48, + /* 950 */ 525, 216, 1492, 155, 448, 503, 1005, 1740, 1711, 480, + /* 960 */ 86, 1712, 542, 1714, 1715, 538, 1441, 559, 1398, 1399, + /* 970 */ 1780, 528, 115, 39, 311, 1776, 148, 223, 491, 39, + /* 980 */ 1298, 1728, 1711, 334, 591, 1727, 39, 151, 1788, 1789, + /* 990 */ 1357, 1793, 218, 540, 1209, 242, 1207, 1809, 1681, 1436, + /* 1000 */ 539, 1574, 1303, 125, 124, 588, 587, 586, 1811, 1727, + /* 1010 */ 121, 1220, 633, 517, 1305, 234, 237, 540, 1212, 1213, + /* 1020 */ 1267, 239, 1681, 1711, 539, 1740, 3, 1163, 272, 1712, + /* 1030 */ 542, 1714, 1715, 538, 122, 559, 244, 29, 316, 1292, + /* 1040 */ 1293, 1294, 1295, 1296, 1300, 1301, 1302, 123, 1219, 1740, + /* 1050 */ 1727, 548, 86, 1712, 542, 1714, 1715, 538, 540, 559, + /* 1060 */ 48, 564, 1780, 1681, 1711, 539, 311, 1776, 1860, 1289, + /* 1070 */ 122, 123, 110, 122, 5, 250, 336, 1815, 1230, 339, + /* 1080 */ 343, 298, 1174, 1032, 299, 259, 389, 163, 1063, 396, + /* 1090 */ 1740, 1727, 1624, 86, 1712, 542, 1714, 1715, 538, 540, + /* 1100 */ 559, 262, 1091, 1780, 1681, 404, 539, 311, 1776, 1860, + /* 1110 */ 403, 1095, 1102, 1100, 126, 405, 409, 1236, 1838, 410, + /* 1120 */ 418, 1239, 421, 170, 172, 1238, 422, 423, 1240, 426, + /* 1130 */ 424, 1740, 175, 177, 86, 1712, 542, 1714, 1715, 538, + /* 1140 */ 1711, 559, 427, 1237, 1780, 428, 180, 450, 311, 1776, + /* 1150 */ 1860, 431, 452, 66, 183, 1524, 187, 1520, 481, 1799, + /* 1160 */ 189, 128, 307, 89, 260, 129, 1522, 1727, 482, 485, + /* 1170 */ 201, 204, 488, 1518, 130, 540, 131, 490, 207, 1235, + /* 1180 */ 1681, 210, 539, 1812, 504, 546, 6, 492, 1663, 1822, + /* 1190 */ 1662, 1821, 513, 1802, 222, 520, 142, 499, 500, 224, + /* 1200 */ 498, 225, 493, 1711, 501, 1331, 310, 1740, 497, 226, + /* 1210 */ 278, 1712, 542, 1714, 1715, 538, 507, 559, 214, 217, + /* 1220 */ 1711, 116, 1234, 42, 1843, 18, 526, 529, 227, 523, + /* 1230 */ 1727, 233, 312, 1863, 544, 545, 1847, 320, 540, 1796, + /* 1240 */ 1630, 549, 246, 1681, 1629, 539, 551, 1727, 261, 550, + /* 1250 */ 154, 77, 1535, 248, 1844, 540, 75, 562, 520, 264, + /* 1260 */ 1681, 228, 539, 1761, 1578, 1507, 256, 49, 636, 266, + /* 1270 */ 1740, 270, 1675, 278, 1712, 542, 1714, 1715, 538, 279, + /* 1280 */ 559, 271, 268, 1711, 141, 236, 1674, 1740, 530, 60, + /* 1290 */ 87, 1712, 542, 1714, 1715, 538, 238, 559, 1673, 1847, + /* 1300 */ 1780, 1711, 338, 1670, 531, 1776, 340, 341, 1201, 1202, + /* 1310 */ 1727, 159, 345, 152, 1668, 347, 348, 1844, 537, 349, + /* 1320 */ 1667, 1666, 351, 1681, 353, 539, 1665, 355, 1727, 1664, + /* 1330 */ 357, 1648, 160, 360, 361, 1177, 540, 1176, 1642, 1641, + /* 1340 */ 366, 1681, 367, 539, 1640, 1639, 1149, 1617, 63, 1616, + /* 1350 */ 1740, 378, 1711, 286, 1712, 542, 1714, 1715, 538, 536, + /* 1360 */ 559, 533, 1752, 1615, 1614, 1613, 1612, 1611, 1740, 379, + /* 1370 */ 640, 138, 1712, 542, 1714, 1715, 538, 381, 559, 1727, + /* 1380 */ 1610, 1609, 1608, 1607, 258, 1606, 1605, 540, 1604, 1603, + /* 1390 */ 1602, 1601, 1681, 516, 539, 1600, 145, 1599, 1598, 1597, + /* 1400 */ 120, 1596, 631, 627, 623, 619, 257, 1595, 1594, 1593, + /* 1410 */ 1592, 1591, 1590, 1711, 1151, 1589, 521, 1861, 1588, 1740, + /* 1420 */ 1587, 117, 87, 1712, 542, 1714, 1715, 538, 1464, 559, + /* 1430 */ 1432, 83, 1780, 168, 251, 146, 970, 1777, 969, 111, + /* 1440 */ 1727, 520, 1431, 169, 414, 1656, 1650, 416, 540, 1638, + /* 1450 */ 112, 174, 1637, 1681, 176, 539, 1627, 1513, 179, 1463, + /* 1460 */ 115, 1461, 434, 998, 433, 1459, 1711, 552, 438, 1457, + /* 1470 */ 432, 1455, 437, 436, 441, 229, 1788, 515, 442, 514, + /* 1480 */ 1740, 440, 1847, 282, 1712, 542, 1714, 1715, 538, 1711, + /* 1490 */ 559, 444, 445, 1727, 1444, 494, 154, 446, 208, 1443, + /* 1500 */ 1844, 540, 1430, 1515, 186, 1106, 1681, 516, 539, 1105, + /* 1510 */ 1514, 1031, 1453, 1030, 1029, 1028, 1727, 1182, 606, 202, + /* 1520 */ 608, 1025, 512, 47, 540, 1024, 304, 1023, 1448, 1681, + /* 1530 */ 305, 539, 469, 1740, 1446, 117, 138, 1712, 542, 1714, + /* 1540 */ 1715, 538, 315, 559, 306, 1711, 1429, 472, 474, 1428, + /* 1550 */ 88, 476, 1655, 1184, 51, 520, 1740, 1649, 483, 287, + /* 1560 */ 1712, 542, 1714, 1715, 538, 1636, 559, 1635, 1634, 1626, + /* 1570 */ 71, 15, 1727, 4, 115, 209, 39, 1372, 23, 213, + /* 1580 */ 537, 205, 1862, 484, 45, 1681, 211, 539, 50, 229, + /* 1590 */ 1788, 515, 139, 514, 220, 215, 1847, 132, 1711, 1356, + /* 1600 */ 219, 24, 221, 1349, 1701, 72, 230, 1711, 143, 1328, + /* 1610 */ 152, 25, 1740, 1327, 1844, 286, 1712, 542, 1714, 1715, + /* 1620 */ 538, 1711, 559, 44, 1753, 1727, 1389, 17, 1384, 1378, + /* 1630 */ 10, 1383, 313, 540, 1727, 1388, 1387, 314, 1681, 19, + /* 1640 */ 539, 1269, 540, 1268, 31, 1290, 144, 1681, 1727, 539, + /* 1650 */ 156, 317, 16, 12, 13, 20, 540, 43, 1254, 21, + /* 1660 */ 319, 1681, 1711, 539, 1625, 1740, 541, 247, 287, 1712, + /* 1670 */ 542, 1714, 1715, 538, 1740, 559, 241, 287, 1712, 542, + /* 1680 */ 1714, 1715, 538, 1711, 559, 1354, 243, 547, 1740, 1727, + /* 1690 */ 245, 273, 1712, 542, 1714, 1715, 538, 540, 559, 73, + /* 1700 */ 74, 78, 1681, 1700, 539, 252, 1743, 1224, 1271, 249, + /* 1710 */ 1727, 1092, 558, 46, 561, 563, 327, 1089, 540, 565, + /* 1720 */ 567, 568, 570, 1681, 1086, 539, 571, 573, 1080, 1740, + /* 1730 */ 574, 576, 274, 1712, 542, 1714, 1715, 538, 1078, 559, + /* 1740 */ 1069, 1711, 1084, 583, 577, 1101, 1083, 79, 1082, 1081, + /* 1750 */ 1740, 80, 1711, 281, 1712, 542, 1714, 1715, 538, 57, + /* 1760 */ 559, 254, 1097, 1711, 996, 592, 1020, 595, 1727, 255, + /* 1770 */ 1038, 1013, 1018, 1017, 1016, 1035, 540, 1015, 1014, 1727, + /* 1780 */ 1012, 1681, 1011, 539, 1033, 1008, 1007, 540, 1006, 1003, + /* 1790 */ 1727, 1002, 1681, 1001, 539, 1460, 617, 616, 540, 618, + /* 1800 */ 1458, 620, 621, 1681, 622, 539, 1456, 624, 1740, 625, + /* 1810 */ 626, 283, 1712, 542, 1714, 1715, 538, 1454, 559, 1740, + /* 1820 */ 629, 628, 275, 1712, 542, 1714, 1715, 538, 1711, 559, + /* 1830 */ 1740, 630, 1442, 284, 1712, 542, 1714, 1715, 538, 632, + /* 1840 */ 559, 1427, 634, 635, 1711, 1210, 265, 638, 639, 1402, + /* 1850 */ 1402, 1402, 1402, 1402, 1402, 1727, 1402, 1402, 1402, 1402, + /* 1860 */ 1402, 1402, 1402, 540, 1402, 1402, 1402, 1402, 1681, 1402, + /* 1870 */ 539, 1727, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 540, + /* 1880 */ 1402, 1402, 1402, 1402, 1681, 1402, 539, 1402, 1402, 1402, + /* 1890 */ 1402, 1402, 1402, 1711, 1402, 1740, 1402, 1402, 276, 1712, + /* 1900 */ 542, 1714, 1715, 538, 1402, 559, 1402, 1711, 1402, 1402, + /* 1910 */ 1402, 1740, 1402, 1402, 285, 1712, 542, 1714, 1715, 538, + /* 1920 */ 1727, 559, 1402, 1402, 1402, 1402, 1402, 1402, 540, 1402, + /* 1930 */ 1402, 1402, 1402, 1681, 1727, 539, 1402, 1402, 1402, 1402, + /* 1940 */ 1402, 1402, 540, 1402, 1402, 1402, 1402, 1681, 1711, 539, + /* 1950 */ 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, + /* 1960 */ 1740, 1402, 1402, 277, 1712, 542, 1714, 1715, 538, 1711, + /* 1970 */ 559, 1402, 1402, 1402, 1740, 1727, 1402, 1723, 1712, 542, + /* 1980 */ 1714, 1715, 538, 540, 559, 1402, 1402, 1402, 1681, 1402, + /* 1990 */ 539, 1402, 1402, 1402, 1402, 1402, 1727, 1402, 1402, 1402, + /* 2000 */ 1402, 1402, 1402, 1402, 540, 1402, 1402, 1402, 1402, 1681, + /* 2010 */ 1402, 539, 1402, 1402, 1402, 1740, 1402, 1402, 1722, 1712, + /* 2020 */ 542, 1714, 1715, 538, 1402, 559, 1402, 1711, 1402, 1402, + /* 2030 */ 1402, 1402, 1402, 1402, 1402, 1402, 1740, 1402, 1711, 1721, + /* 2040 */ 1712, 542, 1714, 1715, 538, 1402, 559, 1402, 1402, 1711, + /* 2050 */ 1402, 1402, 1402, 1402, 1727, 1402, 1402, 1402, 1402, 1402, + /* 2060 */ 1402, 1402, 540, 1402, 1402, 1727, 1402, 1681, 1402, 539, + /* 2070 */ 1402, 1402, 1402, 540, 1402, 1402, 1727, 1402, 1681, 1402, + /* 2080 */ 539, 1402, 1402, 1402, 540, 1402, 1402, 1402, 1402, 1681, + /* 2090 */ 1711, 539, 1402, 1402, 1740, 1402, 1402, 296, 1712, 542, + /* 2100 */ 1714, 1715, 538, 1402, 559, 1740, 1402, 1402, 295, 1712, + /* 2110 */ 542, 1714, 1715, 538, 1711, 559, 1740, 1727, 1402, 297, + /* 2120 */ 1712, 542, 1714, 1715, 538, 540, 559, 1402, 1402, 1402, + /* 2130 */ 1681, 1402, 539, 1402, 1402, 1402, 1402, 1402, 1402, 1402, + /* 2140 */ 1402, 1727, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 540, + /* 2150 */ 1402, 1402, 1402, 1402, 1681, 1402, 539, 1740, 1402, 1402, + /* 2160 */ 294, 1712, 542, 1714, 1715, 538, 1402, 559, 1402, 1402, + /* 2170 */ 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, + /* 2180 */ 1402, 1740, 1402, 1402, 280, 1712, 542, 1714, 1715, 538, + /* 2190 */ 1402, 559, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 274, 341, 273, 277, 248, 274, 250, 251, 277, 242, @@ -465,7 +472,7 @@ static const YYCODETYPE yy_lookahead[] = { /* 300 */ 320, 164, 322, 47, 45, 325, 174, 175, 355, 329, /* 310 */ 330, 103, 359, 115, 319, 12, 13, 14, 15, 16, /* 320 */ 64, 341, 244, 274, 246, 117, 118, 0, 333, 334, - /* 330 */ 335, 336, 4, 338, 285, 355, 199, 81, 57, 359, + /* 330 */ 335, 336, 20, 338, 285, 355, 199, 81, 57, 359, /* 340 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, /* 350 */ 104, 0, 106, 107, 108, 109, 110, 111, 81, 103, /* 360 */ 311, 312, 12, 13, 14, 15, 16, 159, 91, 161, @@ -475,343 +482,352 @@ static const YYCODETYPE yy_lookahead[] = { /* 400 */ 192, 193, 194, 195, 196, 197, 198, 220, 221, 222, /* 410 */ 223, 224, 20, 211, 22, 159, 21, 161, 211, 24, /* 420 */ 25, 26, 27, 28, 29, 30, 31, 32, 12, 13, - /* 430 */ 14, 249, 249, 245, 252, 252, 20, 55, 22, 183, + /* 430 */ 14, 1, 2, 245, 258, 259, 20, 55, 22, 183, /* 440 */ 184, 49, 186, 187, 188, 189, 190, 191, 192, 193, /* 450 */ 194, 195, 196, 197, 198, 12, 13, 14, 15, 16, - /* 460 */ 272, 300, 80, 47, 341, 83, 47, 211, 280, 20, - /* 470 */ 113, 22, 272, 285, 245, 287, 12, 13, 355, 279, - /* 480 */ 64, 0, 359, 64, 20, 313, 22, 260, 288, 262, - /* 490 */ 12, 13, 14, 15, 16, 245, 47, 81, 49, 146, + /* 460 */ 272, 300, 80, 47, 341, 83, 57, 211, 280, 20, + /* 470 */ 271, 22, 272, 285, 20, 287, 12, 13, 355, 279, + /* 480 */ 64, 0, 359, 284, 20, 313, 22, 245, 288, 64, + /* 490 */ 12, 13, 14, 15, 16, 245, 47, 81, 49, 20, /* 500 */ 312, 151, 341, 315, 316, 317, 318, 319, 320, 337, - /* 510 */ 322, 47, 112, 325, 285, 20, 355, 329, 330, 103, - /* 520 */ 359, 287, 148, 272, 271, 82, 169, 170, 64, 295, - /* 530 */ 279, 297, 57, 117, 118, 285, 58, 284, 245, 288, - /* 540 */ 212, 60, 61, 62, 63, 81, 65, 66, 67, 68, + /* 510 */ 322, 47, 82, 325, 113, 272, 355, 329, 330, 103, + /* 520 */ 359, 287, 148, 272, 281, 82, 14, 285, 64, 295, + /* 530 */ 279, 297, 20, 117, 118, 285, 58, 258, 259, 288, + /* 540 */ 245, 60, 61, 62, 63, 81, 65, 66, 67, 68, /* 550 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 560 */ 82, 0, 12, 13, 14, 15, 16, 103, 90, 216, - /* 570 */ 217, 171, 172, 20, 14, 159, 245, 161, 285, 245, - /* 580 */ 20, 117, 118, 233, 2, 24, 25, 26, 27, 28, + /* 560 */ 82, 0, 12, 13, 14, 15, 16, 103, 90, 146, + /* 570 */ 169, 170, 14, 42, 43, 159, 245, 161, 20, 245, + /* 580 */ 285, 117, 118, 233, 2, 24, 25, 26, 27, 28, /* 590 */ 29, 30, 31, 32, 12, 13, 14, 15, 16, 183, - /* 600 */ 184, 245, 186, 187, 188, 189, 190, 191, 192, 193, + /* 600 */ 184, 0, 186, 187, 188, 189, 190, 191, 192, 193, /* 610 */ 194, 195, 196, 197, 198, 252, 285, 272, 272, 285, - /* 620 */ 142, 20, 264, 159, 279, 161, 263, 281, 14, 245, - /* 630 */ 272, 258, 259, 288, 20, 64, 12, 13, 0, 281, - /* 640 */ 20, 285, 164, 280, 20, 0, 22, 183, 184, 58, + /* 620 */ 142, 264, 92, 159, 279, 161, 263, 148, 273, 272, + /* 630 */ 14, 15, 16, 288, 288, 245, 12, 13, 281, 216, + /* 640 */ 217, 112, 164, 280, 20, 93, 22, 183, 184, 245, /* 650 */ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - /* 660 */ 196, 197, 198, 1, 2, 14, 15, 16, 313, 285, - /* 670 */ 92, 47, 12, 13, 14, 15, 16, 199, 200, 201, - /* 680 */ 202, 203, 204, 205, 206, 207, 208, 282, 64, 252, - /* 690 */ 285, 274, 337, 258, 259, 245, 37, 252, 60, 61, - /* 700 */ 93, 148, 285, 65, 252, 81, 68, 69, 263, 93, - /* 710 */ 72, 73, 74, 245, 272, 263, 20, 280, 58, 112, - /* 720 */ 113, 114, 115, 116, 18, 280, 20, 103, 311, 312, - /* 730 */ 288, 115, 280, 27, 252, 285, 30, 300, 93, 322, - /* 740 */ 282, 117, 118, 285, 82, 263, 18, 187, 245, 245, - /* 750 */ 90, 23, 265, 285, 48, 268, 319, 112, 113, 114, - /* 760 */ 115, 116, 280, 35, 36, 245, 252, 39, 148, 252, - /* 770 */ 252, 334, 335, 336, 183, 338, 252, 263, 341, 280, - /* 780 */ 263, 263, 41, 159, 56, 161, 80, 263, 285, 285, - /* 790 */ 291, 64, 355, 41, 280, 252, 359, 280, 280, 42, - /* 800 */ 43, 187, 142, 273, 280, 285, 263, 183, 184, 81, + /* 660 */ 196, 197, 198, 252, 112, 113, 114, 115, 116, 249, + /* 670 */ 249, 47, 252, 252, 263, 285, 252, 199, 200, 201, + /* 680 */ 202, 203, 204, 205, 206, 207, 208, 263, 64, 285, + /* 690 */ 33, 280, 252, 265, 93, 260, 268, 262, 245, 187, + /* 700 */ 171, 172, 45, 263, 280, 81, 245, 252, 51, 52, + /* 710 */ 53, 54, 55, 112, 113, 114, 115, 116, 263, 313, + /* 720 */ 280, 274, 245, 4, 18, 20, 20, 103, 245, 44, + /* 730 */ 245, 93, 285, 27, 37, 280, 30, 80, 285, 252, + /* 740 */ 83, 117, 118, 337, 252, 187, 285, 245, 245, 272, + /* 750 */ 263, 45, 20, 115, 48, 263, 50, 280, 311, 312, + /* 760 */ 18, 41, 285, 252, 287, 23, 81, 280, 285, 322, + /* 770 */ 285, 280, 280, 252, 263, 298, 282, 35, 36, 285, + /* 780 */ 41, 39, 291, 159, 263, 161, 80, 285, 285, 312, + /* 790 */ 64, 280, 315, 316, 317, 318, 319, 320, 56, 322, + /* 800 */ 143, 280, 145, 0, 147, 273, 149, 183, 184, 245, /* 810 */ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - /* 820 */ 196, 197, 198, 280, 164, 273, 120, 209, 210, 123, + /* 820 */ 196, 197, 198, 81, 282, 168, 120, 285, 273, 123, /* 830 */ 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - /* 840 */ 134, 135, 136, 137, 138, 139, 140, 119, 245, 273, - /* 850 */ 85, 245, 22, 88, 273, 245, 245, 245, 245, 199, - /* 860 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 210, - /* 870 */ 41, 85, 85, 85, 88, 88, 88, 47, 272, 151, - /* 880 */ 152, 153, 273, 187, 156, 47, 280, 0, 285, 252, - /* 890 */ 162, 285, 245, 287, 64, 285, 285, 285, 285, 21, - /* 900 */ 263, 173, 64, 41, 176, 41, 178, 179, 180, 181, - /* 910 */ 182, 82, 34, 41, 1, 2, 47, 280, 312, 272, - /* 920 */ 47, 315, 316, 317, 318, 319, 320, 280, 322, 252, - /* 930 */ 0, 325, 285, 103, 287, 329, 330, 331, 41, 211, - /* 940 */ 263, 117, 118, 273, 82, 41, 82, 0, 304, 41, - /* 950 */ 246, 261, 22, 0, 82, 44, 362, 280, 352, 312, - /* 960 */ 252, 0, 315, 316, 317, 318, 319, 320, 41, 322, - /* 970 */ 245, 263, 325, 232, 41, 22, 329, 330, 331, 82, - /* 980 */ 93, 41, 230, 22, 41, 353, 82, 340, 280, 159, - /* 990 */ 82, 161, 81, 46, 308, 253, 245, 272, 348, 112, - /* 1000 */ 113, 114, 115, 116, 272, 280, 253, 251, 41, 82, - /* 1010 */ 285, 41, 287, 183, 184, 82, 314, 41, 41, 41, - /* 1020 */ 41, 284, 82, 272, 339, 82, 342, 356, 356, 356, - /* 1030 */ 161, 280, 213, 310, 161, 20, 285, 312, 287, 45, - /* 1040 */ 315, 316, 317, 318, 319, 320, 252, 322, 245, 82, - /* 1050 */ 325, 47, 82, 309, 329, 330, 331, 245, 82, 82, - /* 1060 */ 82, 82, 258, 312, 157, 340, 315, 316, 317, 318, - /* 1070 */ 319, 320, 302, 322, 252, 272, 325, 252, 40, 142, - /* 1080 */ 329, 330, 331, 280, 272, 292, 290, 290, 285, 252, - /* 1090 */ 287, 340, 280, 20, 247, 247, 20, 285, 306, 287, - /* 1100 */ 256, 287, 256, 300, 20, 299, 245, 20, 301, 256, - /* 1110 */ 299, 256, 300, 280, 20, 312, 293, 252, 315, 316, - /* 1120 */ 317, 318, 319, 320, 312, 322, 256, 315, 316, 317, - /* 1130 */ 318, 319, 320, 272, 322, 256, 256, 247, 272, 272, - /* 1140 */ 272, 280, 247, 272, 341, 252, 285, 245, 287, 272, - /* 1150 */ 254, 306, 167, 341, 272, 272, 272, 272, 355, 285, - /* 1160 */ 272, 272, 359, 305, 254, 245, 285, 355, 252, 254, - /* 1170 */ 20, 359, 280, 312, 272, 299, 315, 316, 317, 318, - /* 1180 */ 319, 320, 280, 322, 293, 287, 325, 285, 254, 287, - /* 1190 */ 329, 330, 272, 219, 285, 296, 347, 285, 218, 347, - /* 1200 */ 280, 296, 285, 285, 350, 285, 225, 287, 314, 150, - /* 1210 */ 227, 214, 349, 226, 312, 210, 245, 315, 316, 317, - /* 1220 */ 318, 319, 320, 321, 322, 323, 324, 20, 280, 310, - /* 1230 */ 40, 231, 312, 347, 19, 315, 316, 317, 318, 319, - /* 1240 */ 320, 313, 322, 272, 234, 344, 346, 229, 33, 81, - /* 1250 */ 296, 280, 296, 332, 285, 145, 285, 328, 287, 345, - /* 1260 */ 45, 358, 294, 357, 280, 293, 51, 52, 53, 54, - /* 1270 */ 55, 285, 280, 285, 254, 268, 254, 245, 81, 276, - /* 1280 */ 360, 361, 358, 312, 358, 363, 315, 316, 317, 318, - /* 1290 */ 319, 320, 357, 322, 245, 80, 325, 285, 83, 357, - /* 1300 */ 252, 330, 262, 247, 272, 254, 307, 252, 266, 303, - /* 1310 */ 266, 266, 280, 255, 243, 0, 0, 285, 40, 287, - /* 1320 */ 0, 272, 72, 0, 47, 177, 47, 47, 47, 280, - /* 1330 */ 298, 116, 177, 0, 285, 280, 287, 47, 47, 177, - /* 1340 */ 0, 177, 0, 47, 312, 245, 22, 315, 316, 317, - /* 1350 */ 318, 319, 320, 0, 322, 300, 0, 47, 0, 144, - /* 1360 */ 164, 312, 147, 163, 315, 316, 317, 318, 319, 320, - /* 1370 */ 81, 322, 272, 252, 319, 161, 0, 159, 0, 155, - /* 1380 */ 280, 166, 154, 168, 0, 285, 0, 287, 44, 334, - /* 1390 */ 335, 336, 0, 338, 141, 0, 341, 0, 0, 245, - /* 1400 */ 0, 280, 0, 354, 0, 0, 0, 0, 245, 0, - /* 1410 */ 355, 0, 312, 0, 359, 315, 316, 317, 318, 319, - /* 1420 */ 320, 0, 322, 0, 0, 0, 272, 0, 0, 40, - /* 1430 */ 0, 0, 0, 0, 280, 272, 22, 0, 0, 285, - /* 1440 */ 319, 287, 0, 280, 0, 0, 0, 0, 285, 0, - /* 1450 */ 287, 41, 298, 37, 14, 334, 335, 336, 40, 338, - /* 1460 */ 0, 361, 245, 44, 14, 0, 312, 38, 0, 315, - /* 1470 */ 316, 317, 318, 319, 320, 312, 322, 252, 315, 316, - /* 1480 */ 317, 318, 319, 320, 0, 322, 150, 324, 37, 272, - /* 1490 */ 0, 37, 44, 0, 37, 0, 0, 280, 59, 0, - /* 1500 */ 33, 37, 285, 47, 287, 280, 45, 0, 37, 0, - /* 1510 */ 47, 45, 45, 245, 37, 298, 47, 45, 51, 52, - /* 1520 */ 53, 54, 55, 0, 45, 47, 37, 245, 0, 312, - /* 1530 */ 0, 0, 315, 316, 317, 318, 319, 320, 47, 322, - /* 1540 */ 272, 0, 90, 88, 319, 0, 22, 80, 280, 47, - /* 1550 */ 83, 47, 47, 285, 272, 287, 41, 47, 41, 334, - /* 1560 */ 335, 336, 280, 338, 0, 47, 298, 285, 47, 287, - /* 1570 */ 22, 0, 47, 22, 48, 0, 22, 0, 22, 47, - /* 1580 */ 312, 0, 245, 315, 316, 317, 318, 319, 320, 22, - /* 1590 */ 322, 245, 20, 0, 312, 0, 47, 315, 316, 317, - /* 1600 */ 318, 319, 320, 0, 322, 245, 148, 22, 165, 272, - /* 1610 */ 143, 0, 145, 0, 147, 145, 149, 280, 272, 0, - /* 1620 */ 81, 148, 285, 148, 287, 37, 280, 41, 143, 82, - /* 1630 */ 41, 285, 272, 287, 81, 168, 44, 215, 81, 41, - /* 1640 */ 280, 82, 82, 81, 81, 285, 81, 287, 82, 312, - /* 1650 */ 41, 44, 315, 316, 317, 318, 319, 320, 312, 322, - /* 1660 */ 81, 315, 316, 317, 318, 319, 320, 41, 322, 82, - /* 1670 */ 41, 44, 312, 82, 215, 315, 316, 317, 318, 319, - /* 1680 */ 320, 245, 322, 209, 44, 41, 82, 82, 47, 47, - /* 1690 */ 47, 215, 47, 47, 47, 2, 183, 41, 245, 44, - /* 1700 */ 82, 81, 22, 82, 81, 81, 44, 245, 272, 81, - /* 1710 */ 0, 81, 185, 82, 82, 81, 280, 81, 37, 146, - /* 1720 */ 81, 285, 44, 287, 91, 272, 143, 44, 22, 81, - /* 1730 */ 92, 82, 81, 280, 272, 81, 47, 47, 285, 82, - /* 1740 */ 287, 81, 280, 82, 47, 81, 47, 285, 312, 287, - /* 1750 */ 82, 315, 316, 317, 318, 319, 320, 81, 322, 245, - /* 1760 */ 47, 82, 47, 81, 105, 312, 82, 81, 315, 316, - /* 1770 */ 317, 318, 319, 320, 312, 322, 105, 315, 316, 317, - /* 1780 */ 318, 319, 320, 245, 322, 22, 272, 93, 81, 81, - /* 1790 */ 105, 47, 105, 81, 280, 41, 22, 59, 58, 285, - /* 1800 */ 245, 287, 47, 64, 79, 41, 47, 47, 47, 47, - /* 1810 */ 272, 22, 47, 47, 47, 64, 47, 47, 280, 47, - /* 1820 */ 47, 0, 47, 285, 47, 287, 312, 272, 47, 315, - /* 1830 */ 316, 317, 318, 319, 320, 280, 322, 47, 45, 37, - /* 1840 */ 285, 0, 287, 47, 45, 37, 0, 37, 47, 45, - /* 1850 */ 312, 245, 0, 315, 316, 317, 318, 319, 320, 47, - /* 1860 */ 322, 45, 245, 37, 0, 47, 0, 312, 20, 22, - /* 1870 */ 315, 316, 317, 318, 319, 320, 21, 322, 272, 22, - /* 1880 */ 22, 21, 364, 364, 364, 364, 280, 364, 364, 272, - /* 1890 */ 364, 285, 364, 287, 364, 364, 364, 280, 364, 364, - /* 1900 */ 364, 364, 285, 245, 287, 364, 364, 364, 364, 364, - /* 1910 */ 364, 364, 364, 364, 245, 364, 364, 364, 312, 364, - /* 1920 */ 364, 315, 316, 317, 318, 319, 320, 364, 322, 312, - /* 1930 */ 272, 364, 315, 316, 317, 318, 319, 320, 280, 322, - /* 1940 */ 364, 272, 364, 285, 364, 287, 364, 364, 364, 280, - /* 1950 */ 364, 364, 364, 364, 285, 364, 287, 364, 364, 364, - /* 1960 */ 364, 364, 364, 364, 364, 364, 364, 245, 364, 364, - /* 1970 */ 312, 364, 364, 315, 316, 317, 318, 319, 320, 245, - /* 1980 */ 322, 312, 364, 364, 315, 316, 317, 318, 319, 320, - /* 1990 */ 364, 322, 364, 245, 272, 364, 364, 364, 364, 364, - /* 2000 */ 364, 364, 280, 364, 364, 364, 272, 285, 364, 287, - /* 2010 */ 364, 364, 364, 364, 280, 364, 364, 364, 364, 285, - /* 2020 */ 272, 287, 364, 364, 364, 364, 364, 364, 280, 364, - /* 2030 */ 364, 364, 364, 285, 312, 287, 364, 315, 316, 317, - /* 2040 */ 318, 319, 320, 364, 322, 245, 312, 364, 364, 315, - /* 2050 */ 316, 317, 318, 319, 320, 364, 322, 364, 364, 364, - /* 2060 */ 312, 364, 364, 315, 316, 317, 318, 319, 320, 364, - /* 2070 */ 322, 364, 272, 364, 364, 364, 364, 364, 364, 364, - /* 2080 */ 280, 364, 364, 364, 364, 285, 364, 287, 364, 364, - /* 2090 */ 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - /* 2100 */ 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - /* 2110 */ 364, 364, 312, 364, 364, 315, 316, 317, 318, 319, - /* 2120 */ 320, 364, 322, 364, + /* 840 */ 134, 135, 136, 137, 138, 139, 140, 273, 47, 285, + /* 850 */ 12, 13, 14, 15, 16, 252, 252, 22, 252, 252, + /* 860 */ 245, 119, 245, 60, 61, 64, 263, 263, 65, 263, + /* 870 */ 245, 68, 69, 209, 210, 72, 73, 74, 41, 0, + /* 880 */ 148, 273, 47, 280, 280, 85, 280, 280, 88, 304, + /* 890 */ 245, 0, 187, 151, 152, 153, 58, 47, 156, 64, + /* 900 */ 285, 22, 285, 85, 162, 252, 88, 210, 85, 85, + /* 910 */ 285, 88, 88, 0, 0, 173, 273, 272, 176, 82, + /* 920 */ 178, 179, 180, 181, 182, 280, 319, 21, 90, 246, + /* 930 */ 285, 212, 287, 280, 47, 22, 22, 41, 103, 47, + /* 940 */ 34, 334, 335, 336, 58, 338, 362, 1, 2, 41, + /* 950 */ 230, 41, 261, 211, 253, 353, 64, 312, 245, 308, + /* 960 */ 315, 316, 317, 318, 319, 320, 0, 322, 117, 118, + /* 970 */ 325, 232, 319, 41, 329, 330, 331, 348, 82, 41, + /* 980 */ 142, 272, 245, 253, 93, 272, 41, 334, 335, 336, + /* 990 */ 82, 338, 82, 280, 159, 41, 161, 352, 285, 251, + /* 1000 */ 287, 284, 164, 112, 113, 114, 115, 116, 314, 272, + /* 1010 */ 41, 161, 46, 339, 82, 356, 356, 280, 183, 184, + /* 1020 */ 82, 356, 285, 245, 287, 312, 342, 82, 315, 316, + /* 1030 */ 317, 318, 319, 320, 41, 322, 82, 199, 200, 201, + /* 1040 */ 202, 203, 204, 205, 206, 207, 208, 41, 161, 312, + /* 1050 */ 272, 82, 315, 316, 317, 318, 319, 320, 280, 322, + /* 1060 */ 41, 41, 325, 285, 245, 287, 329, 330, 331, 183, + /* 1070 */ 41, 41, 41, 41, 213, 82, 310, 340, 20, 252, + /* 1080 */ 45, 309, 157, 47, 258, 302, 252, 40, 82, 292, + /* 1090 */ 312, 272, 252, 315, 316, 317, 318, 319, 320, 280, + /* 1100 */ 322, 82, 82, 325, 285, 142, 287, 329, 330, 331, + /* 1110 */ 290, 82, 82, 82, 82, 290, 252, 20, 340, 247, + /* 1120 */ 247, 20, 306, 256, 256, 20, 287, 299, 20, 299, + /* 1130 */ 301, 312, 256, 256, 315, 316, 317, 318, 319, 320, + /* 1140 */ 245, 322, 280, 20, 325, 293, 256, 247, 329, 330, + /* 1150 */ 331, 252, 272, 256, 256, 272, 272, 272, 167, 340, + /* 1160 */ 272, 272, 247, 252, 306, 272, 272, 272, 305, 287, + /* 1170 */ 254, 254, 252, 272, 272, 280, 272, 299, 254, 20, + /* 1180 */ 285, 254, 287, 314, 219, 218, 225, 280, 285, 347, + /* 1190 */ 285, 347, 150, 350, 349, 300, 347, 285, 227, 346, + /* 1200 */ 226, 345, 293, 245, 285, 210, 285, 312, 214, 344, + /* 1210 */ 315, 316, 317, 318, 319, 320, 285, 322, 296, 296, + /* 1220 */ 245, 280, 20, 40, 358, 81, 229, 231, 310, 358, + /* 1230 */ 272, 357, 234, 363, 285, 285, 341, 285, 280, 313, + /* 1240 */ 296, 145, 280, 285, 296, 287, 293, 272, 268, 294, + /* 1250 */ 355, 81, 280, 254, 359, 280, 254, 276, 300, 252, + /* 1260 */ 285, 332, 287, 328, 285, 262, 254, 303, 247, 255, + /* 1270 */ 312, 266, 0, 315, 316, 317, 318, 319, 320, 266, + /* 1280 */ 322, 266, 243, 245, 307, 357, 0, 312, 358, 40, + /* 1290 */ 315, 316, 317, 318, 319, 320, 357, 322, 0, 341, + /* 1300 */ 325, 245, 72, 0, 329, 330, 47, 177, 47, 47, + /* 1310 */ 272, 47, 177, 355, 0, 47, 47, 359, 280, 177, + /* 1320 */ 0, 0, 177, 285, 47, 287, 0, 22, 272, 0, + /* 1330 */ 47, 0, 81, 164, 163, 161, 280, 159, 0, 0, + /* 1340 */ 155, 285, 154, 287, 0, 0, 44, 0, 141, 0, + /* 1350 */ 312, 136, 245, 315, 316, 317, 318, 319, 320, 321, + /* 1360 */ 322, 323, 324, 0, 0, 0, 0, 0, 312, 47, + /* 1370 */ 19, 315, 316, 317, 318, 319, 320, 136, 322, 272, + /* 1380 */ 0, 0, 0, 0, 33, 0, 0, 280, 0, 0, + /* 1390 */ 0, 0, 285, 252, 287, 0, 45, 0, 0, 0, + /* 1400 */ 40, 0, 51, 52, 53, 54, 55, 0, 0, 0, + /* 1410 */ 0, 0, 0, 245, 22, 0, 360, 361, 0, 312, + /* 1420 */ 0, 280, 315, 316, 317, 318, 319, 320, 0, 322, + /* 1430 */ 0, 80, 325, 40, 83, 41, 14, 330, 14, 37, + /* 1440 */ 272, 300, 0, 38, 44, 0, 0, 44, 280, 0, + /* 1450 */ 37, 37, 0, 285, 150, 287, 0, 0, 37, 0, + /* 1460 */ 319, 0, 37, 59, 45, 0, 245, 116, 37, 0, + /* 1470 */ 47, 0, 45, 47, 45, 334, 335, 336, 37, 338, + /* 1480 */ 312, 47, 341, 315, 316, 317, 318, 319, 320, 245, + /* 1490 */ 322, 47, 45, 272, 0, 144, 355, 37, 147, 0, + /* 1500 */ 359, 280, 0, 0, 88, 47, 285, 252, 287, 22, + /* 1510 */ 0, 47, 0, 47, 47, 47, 272, 166, 41, 168, + /* 1520 */ 41, 47, 354, 90, 280, 47, 22, 47, 0, 285, + /* 1530 */ 22, 287, 48, 312, 0, 280, 315, 316, 317, 318, + /* 1540 */ 319, 320, 298, 322, 22, 245, 0, 47, 22, 0, + /* 1550 */ 20, 22, 0, 47, 148, 300, 312, 0, 22, 315, + /* 1560 */ 316, 317, 318, 319, 320, 0, 322, 0, 0, 0, + /* 1570 */ 81, 215, 272, 41, 319, 37, 41, 82, 81, 81, + /* 1580 */ 280, 145, 361, 148, 41, 285, 143, 287, 148, 334, + /* 1590 */ 335, 336, 81, 338, 41, 82, 341, 165, 245, 82, + /* 1600 */ 81, 81, 44, 82, 44, 81, 44, 245, 44, 82, + /* 1610 */ 355, 41, 312, 82, 359, 315, 316, 317, 318, 319, + /* 1620 */ 320, 245, 322, 41, 324, 272, 82, 41, 47, 82, + /* 1630 */ 2, 47, 47, 280, 272, 47, 47, 47, 285, 41, + /* 1640 */ 287, 82, 280, 82, 81, 183, 44, 285, 272, 287, + /* 1650 */ 44, 298, 215, 81, 215, 81, 280, 209, 22, 81, + /* 1660 */ 298, 285, 245, 287, 0, 312, 185, 37, 315, 316, + /* 1670 */ 317, 318, 319, 320, 312, 322, 82, 315, 316, 317, + /* 1680 */ 318, 319, 320, 245, 322, 82, 81, 146, 312, 272, + /* 1690 */ 81, 315, 316, 317, 318, 319, 320, 280, 322, 81, + /* 1700 */ 81, 91, 285, 44, 287, 44, 81, 22, 82, 143, + /* 1710 */ 272, 82, 81, 81, 92, 47, 47, 82, 280, 81, + /* 1720 */ 47, 81, 47, 285, 82, 287, 81, 47, 82, 312, + /* 1730 */ 81, 47, 315, 316, 317, 318, 319, 320, 82, 322, + /* 1740 */ 22, 245, 105, 93, 81, 47, 105, 81, 105, 105, + /* 1750 */ 312, 81, 245, 315, 316, 317, 318, 319, 320, 81, + /* 1760 */ 322, 41, 22, 245, 59, 58, 47, 79, 272, 41, + /* 1770 */ 64, 22, 47, 47, 47, 64, 280, 47, 47, 272, + /* 1780 */ 47, 285, 47, 287, 47, 47, 47, 280, 47, 47, + /* 1790 */ 272, 47, 285, 47, 287, 0, 45, 47, 280, 37, + /* 1800 */ 0, 47, 45, 285, 37, 287, 0, 47, 312, 45, + /* 1810 */ 37, 315, 316, 317, 318, 319, 320, 0, 322, 312, + /* 1820 */ 45, 47, 315, 316, 317, 318, 319, 320, 245, 322, + /* 1830 */ 312, 37, 0, 315, 316, 317, 318, 319, 320, 47, + /* 1840 */ 322, 0, 22, 21, 245, 22, 22, 21, 20, 364, + /* 1850 */ 364, 364, 364, 364, 364, 272, 364, 364, 364, 364, + /* 1860 */ 364, 364, 364, 280, 364, 364, 364, 364, 285, 364, + /* 1870 */ 287, 272, 364, 364, 364, 364, 364, 364, 364, 280, + /* 1880 */ 364, 364, 364, 364, 285, 364, 287, 364, 364, 364, + /* 1890 */ 364, 364, 364, 245, 364, 312, 364, 364, 315, 316, + /* 1900 */ 317, 318, 319, 320, 364, 322, 364, 245, 364, 364, + /* 1910 */ 364, 312, 364, 364, 315, 316, 317, 318, 319, 320, + /* 1920 */ 272, 322, 364, 364, 364, 364, 364, 364, 280, 364, + /* 1930 */ 364, 364, 364, 285, 272, 287, 364, 364, 364, 364, + /* 1940 */ 364, 364, 280, 364, 364, 364, 364, 285, 245, 287, + /* 1950 */ 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + /* 1960 */ 312, 364, 364, 315, 316, 317, 318, 319, 320, 245, + /* 1970 */ 322, 364, 364, 364, 312, 272, 364, 315, 316, 317, + /* 1980 */ 318, 319, 320, 280, 322, 364, 364, 364, 285, 364, + /* 1990 */ 287, 364, 364, 364, 364, 364, 272, 364, 364, 364, + /* 2000 */ 364, 364, 364, 364, 280, 364, 364, 364, 364, 285, + /* 2010 */ 364, 287, 364, 364, 364, 312, 364, 364, 315, 316, + /* 2020 */ 317, 318, 319, 320, 364, 322, 364, 245, 364, 364, + /* 2030 */ 364, 364, 364, 364, 364, 364, 312, 364, 245, 315, + /* 2040 */ 316, 317, 318, 319, 320, 364, 322, 364, 364, 245, + /* 2050 */ 364, 364, 364, 364, 272, 364, 364, 364, 364, 364, + /* 2060 */ 364, 364, 280, 364, 364, 272, 364, 285, 364, 287, + /* 2070 */ 364, 364, 364, 280, 364, 364, 272, 364, 285, 364, + /* 2080 */ 287, 364, 364, 364, 280, 364, 364, 364, 364, 285, + /* 2090 */ 245, 287, 364, 364, 312, 364, 364, 315, 316, 317, + /* 2100 */ 318, 319, 320, 364, 322, 312, 364, 364, 315, 316, + /* 2110 */ 317, 318, 319, 320, 245, 322, 312, 272, 364, 315, + /* 2120 */ 316, 317, 318, 319, 320, 280, 322, 364, 364, 364, + /* 2130 */ 285, 364, 287, 364, 364, 364, 364, 364, 364, 364, + /* 2140 */ 364, 272, 364, 364, 364, 364, 364, 364, 364, 280, + /* 2150 */ 364, 364, 364, 364, 285, 364, 287, 312, 364, 364, + /* 2160 */ 315, 316, 317, 318, 319, 320, 364, 322, 364, 364, + /* 2170 */ 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + /* 2180 */ 364, 312, 364, 364, 315, 316, 317, 318, 319, 320, + /* 2190 */ 364, 322, }; -#define YY_SHIFT_COUNT (635) +#define YY_SHIFT_COUNT (640) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1866) +#define YY_SHIFT_MAX (1841) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 728, 0, 0, 48, 208, 208, 208, 208, 256, 256, + /* 0 */ 742, 0, 0, 48, 208, 208, 208, 208, 256, 256, /* 10 */ 208, 208, 416, 464, 624, 464, 464, 464, 464, 464, /* 20 */ 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, /* 30 */ 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, /* 40 */ 66, 66, 104, 104, 104, 18, 18, 18, 18, 12, /* 50 */ 79, 207, 36, 36, 115, 115, 202, 153, 207, 207, /* 60 */ 36, 36, 36, 36, 36, 36, 36, 36, 73, 36, - /* 70 */ 36, 180, 190, 495, 180, 36, 36, 180, 36, 180, - /* 80 */ 180, 180, 36, 475, 706, 478, 660, 660, 395, 189, - /* 90 */ 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, - /* 100 */ 830, 830, 830, 830, 830, 830, 830, 830, 830, 198, - /* 110 */ 153, 4, 4, 281, 419, 553, 553, 553, 327, 419, - /* 120 */ 601, 495, 180, 180, 571, 571, 578, 727, 246, 246, - /* 130 */ 246, 246, 246, 246, 246, 1215, 351, 638, 350, 187, - /* 140 */ 449, 357, 353, 560, 614, 392, 757, 616, 620, 618, - /* 150 */ 659, 618, 165, 165, 165, 328, 696, 819, 1015, 994, - /* 160 */ 1004, 907, 1015, 1015, 1038, 937, 937, 1015, 1073, 1073, - /* 170 */ 1076, 73, 495, 73, 1084, 1087, 73, 1084, 73, 601, - /* 180 */ 1094, 73, 73, 1015, 73, 1073, 180, 180, 180, 180, - /* 190 */ 180, 180, 180, 180, 180, 180, 180, 1015, 1073, 571, - /* 200 */ 571, 1076, 475, 985, 495, 475, 1015, 1084, 475, 601, - /* 210 */ 1094, 475, 1150, 571, 974, 980, 571, 974, 980, 571, - /* 220 */ 571, 180, 981, 1059, 974, 983, 987, 997, 819, 1005, - /* 230 */ 601, 1207, 1190, 1000, 1018, 1010, 1000, 1018, 1000, 1018, - /* 240 */ 1168, 980, 571, 571, 980, 571, 1110, 601, 1094, 475, - /* 250 */ 578, 475, 601, 1197, 571, 727, 1015, 475, 1073, 2123, - /* 260 */ 2123, 2123, 2123, 2123, 2123, 2123, 481, 1467, 561, 119, - /* 270 */ 645, 887, 63, 13, 303, 203, 582, 374, 443, 607, + /* 70 */ 36, 180, 190, 312, 180, 36, 36, 180, 36, 180, + /* 80 */ 180, 180, 36, 409, 706, 478, 838, 838, 395, 189, + /* 90 */ 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + /* 100 */ 835, 835, 835, 835, 835, 835, 835, 835, 835, 198, + /* 110 */ 153, 4, 4, 281, 801, 479, 479, 479, 327, 801, + /* 120 */ 454, 312, 180, 180, 425, 425, 530, 726, 246, 246, + /* 130 */ 246, 246, 246, 246, 246, 1351, 351, 803, 350, 187, + /* 140 */ 449, 401, 423, 512, 558, 392, 531, 638, 732, 664, + /* 150 */ 697, 664, 165, 165, 165, 719, 705, 861, 1058, 1035, + /* 160 */ 1036, 925, 1058, 1058, 1047, 963, 963, 1058, 1097, 1097, + /* 170 */ 1101, 73, 312, 73, 1105, 1108, 73, 1105, 73, 454, + /* 180 */ 1123, 73, 73, 1058, 73, 1097, 180, 180, 180, 180, + /* 190 */ 180, 180, 180, 180, 180, 180, 180, 1058, 1097, 425, + /* 200 */ 425, 1101, 409, 991, 312, 409, 1058, 1105, 409, 454, + /* 210 */ 1123, 409, 1159, 425, 965, 967, 425, 965, 967, 425, + /* 220 */ 425, 180, 961, 1042, 965, 971, 974, 994, 861, 995, + /* 230 */ 454, 1202, 1183, 996, 997, 998, 996, 997, 996, 997, + /* 240 */ 1144, 967, 425, 425, 967, 425, 1096, 454, 1123, 409, + /* 250 */ 530, 409, 454, 1170, 425, 726, 1058, 409, 1097, 2192, + /* 260 */ 2192, 2192, 2192, 2192, 2192, 2192, 481, 657, 561, 119, + /* 270 */ 601, 891, 63, 13, 303, 203, 582, 374, 443, 552, /* 280 */ 550, 550, 550, 550, 550, 550, 550, 550, 132, 382, - /* 290 */ 152, 400, 662, 137, 651, 651, 651, 651, 259, 829, - /* 300 */ 765, 786, 787, 788, 930, 953, 961, 878, 862, 864, - /* 310 */ 872, 913, 824, 752, 741, 897, 591, 904, 911, 908, - /* 320 */ 927, 933, 940, 943, 869, 873, 967, 970, 976, 977, - /* 330 */ 978, 979, 277, 838, 947, 1315, 1316, 1278, 1320, 1250, - /* 340 */ 1323, 1277, 1148, 1279, 1280, 1281, 1155, 1333, 1290, 1291, - /* 350 */ 1162, 1340, 1164, 1342, 1296, 1353, 1324, 1356, 1310, 1358, - /* 360 */ 1289, 1196, 1200, 1214, 1218, 1376, 1378, 1224, 1228, 1384, - /* 370 */ 1386, 1344, 1392, 1253, 1395, 1397, 1398, 1400, 1402, 1404, - /* 380 */ 1405, 1406, 1407, 1409, 1411, 1413, 1421, 1423, 1424, 1425, - /* 390 */ 1427, 1428, 1389, 1430, 1431, 1432, 1433, 1442, 1444, 1414, - /* 400 */ 1437, 1438, 1445, 1446, 1447, 1449, 1418, 1416, 1410, 1440, - /* 410 */ 1419, 1450, 1448, 1460, 1429, 1451, 1465, 1468, 1484, 1454, - /* 420 */ 1336, 1490, 1493, 1457, 1495, 1439, 1496, 1499, 1456, 1461, - /* 430 */ 1464, 1507, 1463, 1466, 1471, 1509, 1469, 1472, 1477, 1523, - /* 440 */ 1478, 1479, 1489, 1528, 1530, 1531, 1541, 1452, 1455, 1491, - /* 450 */ 1524, 1545, 1502, 1504, 1505, 1510, 1515, 1517, 1518, 1521, - /* 460 */ 1525, 1564, 1548, 1571, 1551, 1526, 1575, 1554, 1532, 1577, - /* 470 */ 1556, 1581, 1567, 1572, 1593, 1458, 1549, 1595, 1443, 1585, - /* 480 */ 1473, 1470, 1603, 1611, 1613, 1475, 1619, 1539, 1588, 1485, - /* 490 */ 1586, 1589, 1422, 1553, 1547, 1557, 1559, 1598, 1560, 1562, - /* 500 */ 1563, 1565, 1566, 1609, 1592, 1607, 1579, 1626, 1459, 1587, - /* 510 */ 1591, 1627, 1474, 1629, 1640, 1604, 1644, 1476, 1605, 1641, - /* 520 */ 1642, 1643, 1645, 1646, 1647, 1605, 1693, 1513, 1656, 1618, - /* 530 */ 1620, 1621, 1655, 1623, 1624, 1662, 1680, 1527, 1628, 1631, - /* 540 */ 1632, 1630, 1634, 1573, 1636, 1710, 1681, 1583, 1639, 1633, - /* 550 */ 1678, 1683, 1648, 1649, 1651, 1706, 1654, 1638, 1657, 1689, - /* 560 */ 1690, 1660, 1661, 1697, 1664, 1668, 1699, 1676, 1679, 1713, - /* 570 */ 1682, 1684, 1715, 1686, 1659, 1671, 1685, 1687, 1763, 1694, - /* 580 */ 1707, 1708, 1744, 1712, 1754, 1754, 1774, 1738, 1740, 1755, - /* 590 */ 1739, 1725, 1764, 1759, 1760, 1761, 1762, 1765, 1789, 1766, - /* 600 */ 1767, 1751, 1515, 1769, 1517, 1770, 1772, 1773, 1775, 1777, - /* 610 */ 1781, 1821, 1790, 1793, 1802, 1841, 1796, 1799, 1808, 1846, - /* 620 */ 1801, 1804, 1810, 1852, 1812, 1816, 1826, 1864, 1818, 1866, - /* 630 */ 1847, 1855, 1857, 1858, 1860, 1848, + /* 290 */ 152, 529, 430, 137, 616, 616, 616, 616, 259, 837, + /* 300 */ 800, 818, 823, 824, 879, 913, 914, 906, 896, 908, + /* 310 */ 910, 946, 851, 720, 739, 932, 886, 938, 685, 945, + /* 320 */ 954, 969, 993, 1006, 850, 887, 1019, 1020, 1029, 1030, + /* 330 */ 1031, 1032, 277, 892, 966, 1272, 1286, 1249, 1298, 1230, + /* 340 */ 1303, 1259, 1130, 1261, 1262, 1264, 1135, 1314, 1268, 1269, + /* 350 */ 1142, 1320, 1145, 1321, 1277, 1326, 1305, 1329, 1283, 1331, + /* 360 */ 1251, 1169, 1171, 1174, 1178, 1338, 1339, 1185, 1188, 1344, + /* 370 */ 1345, 1302, 1347, 1207, 1349, 1363, 1364, 1365, 1366, 1215, + /* 380 */ 1322, 1367, 1241, 1380, 1381, 1382, 1383, 1385, 1386, 1388, + /* 390 */ 1389, 1390, 1391, 1395, 1397, 1398, 1399, 1360, 1401, 1407, + /* 400 */ 1408, 1409, 1410, 1411, 1392, 1412, 1415, 1418, 1420, 1428, + /* 410 */ 1430, 1393, 1402, 1394, 1422, 1400, 1424, 1403, 1442, 1405, + /* 420 */ 1413, 1445, 1446, 1449, 1414, 1304, 1452, 1456, 1421, 1457, + /* 430 */ 1404, 1459, 1461, 1423, 1419, 1425, 1465, 1426, 1427, 1431, + /* 440 */ 1469, 1434, 1429, 1441, 1471, 1444, 1447, 1460, 1494, 1499, + /* 450 */ 1502, 1503, 1433, 1416, 1458, 1487, 1510, 1464, 1466, 1467, + /* 460 */ 1468, 1477, 1479, 1474, 1478, 1480, 1512, 1504, 1528, 1508, + /* 470 */ 1484, 1534, 1522, 1500, 1546, 1526, 1549, 1529, 1530, 1552, + /* 480 */ 1406, 1506, 1557, 1432, 1536, 1435, 1436, 1565, 1567, 1568, + /* 490 */ 1440, 1569, 1489, 1538, 1443, 1532, 1535, 1356, 1497, 1495, + /* 500 */ 1498, 1513, 1543, 1517, 1511, 1519, 1520, 1521, 1553, 1558, + /* 510 */ 1560, 1524, 1570, 1437, 1527, 1531, 1562, 1448, 1582, 1564, + /* 520 */ 1544, 1586, 1439, 1547, 1581, 1584, 1585, 1588, 1589, 1590, + /* 530 */ 1547, 1628, 1462, 1598, 1559, 1563, 1561, 1602, 1572, 1574, + /* 540 */ 1606, 1636, 1481, 1578, 1594, 1603, 1605, 1609, 1541, 1618, + /* 550 */ 1664, 1630, 1566, 1619, 1610, 1659, 1661, 1625, 1626, 1631, + /* 560 */ 1685, 1632, 1622, 1629, 1668, 1669, 1638, 1635, 1673, 1640, + /* 570 */ 1642, 1675, 1645, 1646, 1680, 1649, 1656, 1684, 1663, 1637, + /* 580 */ 1641, 1643, 1644, 1718, 1650, 1666, 1670, 1698, 1678, 1720, + /* 590 */ 1720, 1740, 1705, 1707, 1719, 1706, 1688, 1728, 1725, 1726, + /* 600 */ 1727, 1730, 1731, 1749, 1733, 1735, 1711, 1477, 1737, 1479, + /* 610 */ 1738, 1739, 1741, 1742, 1744, 1746, 1795, 1750, 1751, 1762, + /* 620 */ 1800, 1754, 1757, 1767, 1806, 1760, 1764, 1773, 1817, 1774, + /* 630 */ 1775, 1794, 1832, 1792, 1841, 1820, 1822, 1823, 1824, 1826, + /* 640 */ 1828, }; #define YY_REDUCE_COUNT (265) #define YY_REDUCE_MIN (-340) -#define YY_REDUCE_MAX (1800) +#define YY_REDUCE_MAX (1869) static const short yy_reduce_ofst[] = { - /* 0 */ -233, -228, -20, -176, 606, 647, 725, 751, 803, 812, - /* 10 */ 188, 861, 902, 920, 971, 1032, 1049, 1100, 1154, 1163, - /* 20 */ 1217, 1268, 1282, 1337, 1346, 1360, 1436, 1453, 1462, 1514, - /* 30 */ 1538, 1555, 1606, 1617, 1658, 1669, 1722, 1734, 1748, 1800, - /* 40 */ 437, 1055, -5, 1121, 1225, -274, -269, 49, 417, -227, + /* 0 */ -233, -228, -20, -176, 645, 737, 778, 819, 895, 958, + /* 10 */ 188, 975, 1038, 1056, 1107, 477, 1168, 1221, 1244, 1300, + /* 20 */ 1353, 1362, 713, 1376, 1417, 1438, 1496, 1507, 1518, 1583, + /* 30 */ 1599, 1648, 1662, 1703, 1724, 1782, 1793, 1804, 1845, 1869, + /* 40 */ 1141, 1255, -5, 607, 653, -274, -269, 49, 447, -227, /* 50 */ -47, 161, -231, -229, -244, -215, -340, -105, -133, 123, - /* 60 */ -197, -147, 363, 445, 452, 482, 514, 517, -171, 518, - /* 70 */ 543, 200, -24, 234, -201, 637, 677, 251, 524, -101, - /* 80 */ 345, 358, 708, -119, -152, -281, -281, -281, 78, -247, - /* 90 */ -135, -21, 229, 250, 293, 331, 334, 356, 384, 450, - /* 100 */ 468, 503, 504, 520, 603, 610, 611, 612, 613, 253, - /* 110 */ -83, 182, 183, -27, 373, -263, 172, 355, -155, 435, - /* 120 */ 499, -172, 346, 442, 405, 458, 487, 227, -271, 530, - /* 130 */ 552, 576, 581, 609, 670, 644, 704, 690, 594, 632, - /* 140 */ 742, 686, 650, 732, 732, 753, 756, 737, 702, 685, - /* 150 */ 685, 685, 671, 672, 673, 684, 732, 723, 794, 744, - /* 160 */ 804, 770, 822, 825, 793, 796, 797, 837, 847, 848, - /* 170 */ 792, 844, 814, 846, 806, 807, 853, 811, 855, 833, - /* 180 */ 823, 870, 879, 865, 880, 890, 866, 867, 868, 871, - /* 190 */ 877, 882, 883, 884, 885, 888, 889, 893, 895, 874, - /* 200 */ 881, 845, 896, 858, 898, 910, 916, 876, 915, 892, - /* 210 */ 891, 934, 894, 909, 849, 899, 912, 852, 905, 917, - /* 220 */ 918, 732, 854, 863, 886, 900, 914, 901, 919, 685, - /* 230 */ 948, 928, 921, 903, 906, 922, 924, 935, 926, 942, - /* 240 */ 929, 954, 969, 986, 956, 988, 968, 984, 972, 1020, - /* 250 */ 1007, 1022, 992, 1003, 1012, 1040, 1048, 1051, 1056, 1006, - /* 260 */ 999, 1042, 1044, 1045, 1058, 1071, + /* 60 */ -197, -147, 363, 411, 424, 440, 455, 487, -171, 492, + /* 70 */ 511, 200, -24, 234, -201, 521, 603, 251, 604, -101, + /* 80 */ 345, 357, 606, -119, -152, -281, -281, -281, 78, -247, + /* 90 */ -135, -21, 242, 250, 295, 331, 334, 390, 404, 453, + /* 100 */ 461, 483, 485, 502, 503, 564, 615, 617, 625, 199, + /* 110 */ -83, 420, 421, -27, 176, -263, 172, 406, -155, 279, + /* 120 */ 491, -172, 243, 346, 494, 542, 428, 435, -271, 355, + /* 130 */ 532, 555, 574, 608, 643, 585, 683, 691, 584, 602, + /* 140 */ 701, 651, 629, 709, 709, 730, 748, 717, 694, 674, + /* 150 */ 674, 674, 659, 660, 665, 684, 709, 766, 827, 772, + /* 160 */ 826, 783, 834, 840, 797, 820, 825, 864, 872, 873, + /* 170 */ 816, 867, 839, 868, 828, 829, 876, 830, 877, 862, + /* 180 */ 852, 890, 897, 899, 898, 900, 880, 883, 884, 885, + /* 190 */ 888, 889, 893, 894, 901, 902, 904, 911, 915, 903, + /* 200 */ 905, 858, 916, 863, 882, 917, 920, 878, 924, 907, + /* 210 */ 909, 927, 869, 912, 842, 922, 919, 844, 923, 921, + /* 220 */ 931, 709, 843, 845, 849, 853, 856, 865, 918, 674, + /* 230 */ 941, 926, 929, 866, 874, 870, 871, 928, 930, 939, + /* 240 */ 935, 944, 949, 950, 948, 952, 955, 962, 953, 999, + /* 250 */ 980, 1002, 972, 981, 979, 1003, 1007, 1012, 1021, 964, + /* 260 */ 977, 1005, 1013, 1015, 1014, 1039, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 10 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 20 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 30 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 40 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 50 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 60 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1461, 1392, - /* 70 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 80 */ 1392, 1392, 1392, 1459, 1608, 1392, 1772, 1392, 1392, 1392, - /* 90 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 100 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 110 */ 1392, 1392, 1392, 1461, 1392, 1783, 1783, 1783, 1459, 1392, - /* 120 */ 1392, 1392, 1392, 1392, 1392, 1392, 1555, 1392, 1392, 1392, - /* 130 */ 1392, 1392, 1392, 1392, 1392, 1641, 1392, 1392, 1853, 1392, - /* 140 */ 1392, 1647, 1807, 1392, 1392, 1392, 1392, 1508, 1799, 1775, - /* 150 */ 1789, 1776, 1838, 1838, 1838, 1792, 1392, 1803, 1392, 1392, - /* 160 */ 1392, 1633, 1392, 1392, 1613, 1610, 1610, 1392, 1392, 1392, - /* 170 */ 1392, 1461, 1392, 1461, 1392, 1392, 1461, 1392, 1461, 1392, - /* 180 */ 1392, 1461, 1461, 1392, 1461, 1392, 1392, 1392, 1392, 1392, - /* 190 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 200 */ 1392, 1392, 1459, 1643, 1392, 1459, 1392, 1392, 1459, 1392, - /* 210 */ 1392, 1459, 1392, 1392, 1814, 1812, 1392, 1814, 1812, 1392, - /* 220 */ 1392, 1392, 1826, 1822, 1814, 1830, 1828, 1805, 1803, 1789, - /* 230 */ 1392, 1392, 1392, 1844, 1840, 1856, 1844, 1840, 1844, 1840, - /* 240 */ 1392, 1812, 1392, 1392, 1812, 1392, 1618, 1392, 1392, 1459, - /* 250 */ 1392, 1459, 1392, 1524, 1392, 1392, 1392, 1459, 1392, 1635, - /* 260 */ 1649, 1558, 1558, 1558, 1462, 1397, 1392, 1392, 1392, 1392, - /* 270 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1520, - /* 280 */ 1716, 1825, 1824, 1748, 1747, 1746, 1744, 1715, 1392, 1392, - /* 290 */ 1392, 1392, 1392, 1392, 1709, 1710, 1708, 1707, 1392, 1392, - /* 300 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 310 */ 1392, 1773, 1392, 1841, 1845, 1392, 1392, 1392, 1692, 1392, - /* 320 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 330 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 340 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 350 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 360 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 370 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 380 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 390 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 400 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1426, 1392, - /* 410 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 420 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 430 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 440 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 450 */ 1392, 1392, 1392, 1392, 1392, 1392, 1489, 1488, 1392, 1392, - /* 460 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 470 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 480 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 490 */ 1796, 1806, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 500 */ 1392, 1392, 1392, 1392, 1392, 1692, 1392, 1823, 1392, 1782, - /* 510 */ 1778, 1392, 1392, 1774, 1392, 1392, 1839, 1392, 1392, 1392, - /* 520 */ 1392, 1392, 1392, 1392, 1392, 1392, 1768, 1392, 1741, 1392, - /* 530 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1703, 1392, 1392, - /* 540 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 550 */ 1691, 1392, 1732, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 560 */ 1392, 1552, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 570 */ 1392, 1392, 1392, 1392, 1537, 1535, 1534, 1533, 1392, 1530, - /* 580 */ 1392, 1392, 1392, 1392, 1561, 1560, 1392, 1392, 1392, 1392, - /* 590 */ 1392, 1392, 1481, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 600 */ 1392, 1392, 1472, 1392, 1471, 1392, 1392, 1392, 1392, 1392, - /* 610 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 620 */ 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, - /* 630 */ 1392, 1392, 1392, 1392, 1392, 1392, + /* 0 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 10 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 20 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 30 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 40 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 50 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 60 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1469, 1400, + /* 70 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 80 */ 1400, 1400, 1400, 1467, 1618, 1400, 1782, 1400, 1400, 1400, + /* 90 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 100 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 110 */ 1400, 1400, 1400, 1469, 1400, 1794, 1794, 1794, 1467, 1400, + /* 120 */ 1400, 1400, 1400, 1400, 1400, 1400, 1563, 1400, 1400, 1400, + /* 130 */ 1400, 1400, 1400, 1400, 1400, 1651, 1400, 1400, 1864, 1400, + /* 140 */ 1400, 1657, 1818, 1400, 1400, 1400, 1400, 1516, 1810, 1786, + /* 150 */ 1800, 1787, 1849, 1849, 1849, 1803, 1400, 1814, 1400, 1400, + /* 160 */ 1400, 1643, 1400, 1400, 1623, 1620, 1620, 1400, 1400, 1400, + /* 170 */ 1400, 1469, 1400, 1469, 1400, 1400, 1469, 1400, 1469, 1400, + /* 180 */ 1400, 1469, 1469, 1400, 1469, 1400, 1400, 1400, 1400, 1400, + /* 190 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 200 */ 1400, 1400, 1467, 1653, 1400, 1467, 1400, 1400, 1467, 1400, + /* 210 */ 1400, 1467, 1400, 1400, 1825, 1823, 1400, 1825, 1823, 1400, + /* 220 */ 1400, 1400, 1837, 1833, 1825, 1841, 1839, 1816, 1814, 1800, + /* 230 */ 1400, 1400, 1784, 1855, 1851, 1867, 1855, 1851, 1855, 1851, + /* 240 */ 1400, 1823, 1400, 1400, 1823, 1400, 1628, 1400, 1400, 1467, + /* 250 */ 1400, 1467, 1400, 1532, 1400, 1400, 1400, 1467, 1400, 1645, + /* 260 */ 1659, 1566, 1566, 1566, 1470, 1405, 1400, 1400, 1400, 1400, + /* 270 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1528, + /* 280 */ 1726, 1836, 1835, 1758, 1757, 1756, 1754, 1725, 1400, 1400, + /* 290 */ 1400, 1400, 1400, 1400, 1719, 1720, 1718, 1717, 1400, 1400, + /* 300 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 310 */ 1400, 1783, 1400, 1852, 1856, 1400, 1400, 1400, 1702, 1400, + /* 320 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 330 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 340 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 350 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 360 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 370 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 380 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 390 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 400 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 410 */ 1400, 1400, 1400, 1434, 1400, 1400, 1400, 1400, 1400, 1400, + /* 420 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 430 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 440 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 450 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 460 */ 1400, 1497, 1496, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 470 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 480 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 490 */ 1400, 1400, 1400, 1400, 1400, 1807, 1817, 1400, 1400, 1400, + /* 500 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 510 */ 1702, 1400, 1834, 1400, 1793, 1789, 1400, 1400, 1785, 1400, + /* 520 */ 1400, 1850, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 530 */ 1400, 1778, 1400, 1751, 1400, 1400, 1400, 1400, 1400, 1400, + /* 540 */ 1400, 1400, 1713, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 550 */ 1400, 1400, 1400, 1400, 1400, 1701, 1400, 1742, 1400, 1400, + /* 560 */ 1400, 1400, 1400, 1400, 1400, 1400, 1560, 1400, 1400, 1400, + /* 570 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1545, + /* 580 */ 1543, 1542, 1541, 1400, 1538, 1400, 1400, 1400, 1400, 1569, + /* 590 */ 1568, 1400, 1400, 1400, 1400, 1400, 1400, 1489, 1400, 1400, + /* 600 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1480, 1400, 1479, + /* 610 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 620 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 630 */ 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, + /* 640 */ 1400, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1492,7 +1508,7 @@ static const char *const yyTokenName[] = { /* 329 */ "boolean_value_expression", /* 330 */ "boolean_primary", /* 331 */ "common_expression", - /* 332 */ "from_clause", + /* 332 */ "from_clause_opt", /* 333 */ "table_reference_list", /* 334 */ "table_reference", /* 335 */ "table_primary", @@ -1739,262 +1755,265 @@ static const char *const yyRuleName[] = { /* 205 */ "cmd ::= SHOW SCORES", /* 206 */ "cmd ::= SHOW TOPICS", /* 207 */ "cmd ::= SHOW VARIABLES", - /* 208 */ "cmd ::= SHOW BNODES", - /* 209 */ "cmd ::= SHOW SNODES", - /* 210 */ "cmd ::= SHOW CLUSTER", - /* 211 */ "cmd ::= SHOW TRANSACTIONS", - /* 212 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", - /* 213 */ "db_name_cond_opt ::=", - /* 214 */ "db_name_cond_opt ::= db_name NK_DOT", - /* 215 */ "like_pattern_opt ::=", - /* 216 */ "like_pattern_opt ::= LIKE NK_STRING", - /* 217 */ "table_name_cond ::= table_name", - /* 218 */ "from_db_opt ::=", - /* 219 */ "from_db_opt ::= FROM db_name", - /* 220 */ "cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options", - /* 221 */ "cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP", - /* 222 */ "cmd ::= DROP INDEX exists_opt index_name ON table_name", - /* 223 */ "index_options ::=", - /* 224 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt", - /* 225 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt", - /* 226 */ "func_list ::= func", - /* 227 */ "func_list ::= func_list NK_COMMA func", - /* 228 */ "func ::= function_name NK_LP expression_list NK_RP", - /* 229 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression", - /* 230 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name", - /* 231 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name", - /* 232 */ "cmd ::= DROP TOPIC exists_opt topic_name", - /* 233 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", - /* 234 */ "cmd ::= DESC full_table_name", - /* 235 */ "cmd ::= DESCRIBE full_table_name", - /* 236 */ "cmd ::= RESET QUERY CACHE", - /* 237 */ "cmd ::= EXPLAIN analyze_opt explain_options query_expression", - /* 238 */ "analyze_opt ::=", - /* 239 */ "analyze_opt ::= ANALYZE", - /* 240 */ "explain_options ::=", - /* 241 */ "explain_options ::= explain_options VERBOSE NK_BOOL", - /* 242 */ "explain_options ::= explain_options RATIO NK_FLOAT", - /* 243 */ "cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP", - /* 244 */ "cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt", - /* 245 */ "cmd ::= DROP FUNCTION exists_opt function_name", - /* 246 */ "agg_func_opt ::=", - /* 247 */ "agg_func_opt ::= AGGREGATE", - /* 248 */ "bufsize_opt ::=", - /* 249 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", - /* 250 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression", - /* 251 */ "cmd ::= DROP STREAM exists_opt stream_name", - /* 252 */ "into_opt ::=", - /* 253 */ "into_opt ::= INTO full_table_name", - /* 254 */ "stream_options ::=", - /* 255 */ "stream_options ::= stream_options TRIGGER AT_ONCE", - /* 256 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", - /* 257 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", - /* 258 */ "stream_options ::= stream_options WATERMARK duration_literal", - /* 259 */ "cmd ::= KILL CONNECTION NK_INTEGER", - /* 260 */ "cmd ::= KILL QUERY NK_STRING", - /* 261 */ "cmd ::= KILL TRANSACTION NK_INTEGER", - /* 262 */ "cmd ::= BALANCE VGROUP", - /* 263 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", - /* 264 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", - /* 265 */ "cmd ::= SPLIT VGROUP NK_INTEGER", - /* 266 */ "dnode_list ::= DNODE NK_INTEGER", - /* 267 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", - /* 268 */ "cmd ::= SYNCDB db_name REPLICA", - /* 269 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", - /* 270 */ "cmd ::= query_expression", - /* 271 */ "literal ::= NK_INTEGER", - /* 272 */ "literal ::= NK_FLOAT", - /* 273 */ "literal ::= NK_STRING", - /* 274 */ "literal ::= NK_BOOL", - /* 275 */ "literal ::= TIMESTAMP NK_STRING", - /* 276 */ "literal ::= duration_literal", - /* 277 */ "literal ::= NULL", - /* 278 */ "literal ::= NK_QUESTION", - /* 279 */ "duration_literal ::= NK_VARIABLE", - /* 280 */ "signed ::= NK_INTEGER", - /* 281 */ "signed ::= NK_PLUS NK_INTEGER", - /* 282 */ "signed ::= NK_MINUS NK_INTEGER", - /* 283 */ "signed ::= NK_FLOAT", - /* 284 */ "signed ::= NK_PLUS NK_FLOAT", - /* 285 */ "signed ::= NK_MINUS NK_FLOAT", - /* 286 */ "signed_literal ::= signed", - /* 287 */ "signed_literal ::= NK_STRING", - /* 288 */ "signed_literal ::= NK_BOOL", - /* 289 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 290 */ "signed_literal ::= duration_literal", - /* 291 */ "signed_literal ::= NULL", - /* 292 */ "signed_literal ::= literal_func", - /* 293 */ "literal_list ::= signed_literal", - /* 294 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 295 */ "db_name ::= NK_ID", - /* 296 */ "table_name ::= NK_ID", - /* 297 */ "column_name ::= NK_ID", - /* 298 */ "function_name ::= NK_ID", - /* 299 */ "table_alias ::= NK_ID", - /* 300 */ "column_alias ::= NK_ID", - /* 301 */ "user_name ::= NK_ID", - /* 302 */ "index_name ::= NK_ID", - /* 303 */ "topic_name ::= NK_ID", - /* 304 */ "stream_name ::= NK_ID", - /* 305 */ "cgroup_name ::= NK_ID", - /* 306 */ "expression ::= literal", - /* 307 */ "expression ::= pseudo_column", - /* 308 */ "expression ::= column_reference", - /* 309 */ "expression ::= function_expression", - /* 310 */ "expression ::= subquery", - /* 311 */ "expression ::= NK_LP expression NK_RP", - /* 312 */ "expression ::= NK_PLUS expression", - /* 313 */ "expression ::= NK_MINUS expression", - /* 314 */ "expression ::= expression NK_PLUS expression", - /* 315 */ "expression ::= expression NK_MINUS expression", - /* 316 */ "expression ::= expression NK_STAR expression", - /* 317 */ "expression ::= expression NK_SLASH expression", - /* 318 */ "expression ::= expression NK_REM expression", - /* 319 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 320 */ "expression_list ::= expression", - /* 321 */ "expression_list ::= expression_list NK_COMMA expression", - /* 322 */ "column_reference ::= column_name", - /* 323 */ "column_reference ::= table_name NK_DOT column_name", - /* 324 */ "pseudo_column ::= ROWTS", - /* 325 */ "pseudo_column ::= TBNAME", - /* 326 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 327 */ "pseudo_column ::= QSTARTTS", - /* 328 */ "pseudo_column ::= QENDTS", - /* 329 */ "pseudo_column ::= WSTARTTS", - /* 330 */ "pseudo_column ::= WENDTS", - /* 331 */ "pseudo_column ::= WDURATION", - /* 332 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 333 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 334 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP", - /* 335 */ "function_expression ::= literal_func", - /* 336 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 337 */ "literal_func ::= NOW", - /* 338 */ "noarg_func ::= NOW", - /* 339 */ "noarg_func ::= TODAY", - /* 340 */ "noarg_func ::= TIMEZONE", - /* 341 */ "star_func ::= COUNT", - /* 342 */ "star_func ::= FIRST", - /* 343 */ "star_func ::= LAST", - /* 344 */ "star_func ::= LAST_ROW", - /* 345 */ "star_func_para_list ::= NK_STAR", - /* 346 */ "star_func_para_list ::= other_para_list", - /* 347 */ "other_para_list ::= star_func_para", - /* 348 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 349 */ "star_func_para ::= expression", - /* 350 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 351 */ "predicate ::= expression compare_op expression", - /* 352 */ "predicate ::= expression BETWEEN expression AND expression", - /* 353 */ "predicate ::= expression NOT BETWEEN expression AND expression", - /* 354 */ "predicate ::= expression IS NULL", - /* 355 */ "predicate ::= expression IS NOT NULL", - /* 356 */ "predicate ::= expression in_op in_predicate_value", - /* 357 */ "compare_op ::= NK_LT", - /* 358 */ "compare_op ::= NK_GT", - /* 359 */ "compare_op ::= NK_LE", - /* 360 */ "compare_op ::= NK_GE", - /* 361 */ "compare_op ::= NK_NE", - /* 362 */ "compare_op ::= NK_EQ", - /* 363 */ "compare_op ::= LIKE", - /* 364 */ "compare_op ::= NOT LIKE", - /* 365 */ "compare_op ::= MATCH", - /* 366 */ "compare_op ::= NMATCH", - /* 367 */ "compare_op ::= CONTAINS", - /* 368 */ "in_op ::= IN", - /* 369 */ "in_op ::= NOT IN", - /* 370 */ "in_predicate_value ::= NK_LP expression_list NK_RP", - /* 371 */ "boolean_value_expression ::= boolean_primary", - /* 372 */ "boolean_value_expression ::= NOT boolean_primary", - /* 373 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 374 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 375 */ "boolean_primary ::= predicate", - /* 376 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 377 */ "common_expression ::= expression", - /* 378 */ "common_expression ::= boolean_value_expression", - /* 379 */ "from_clause ::= FROM table_reference_list", - /* 380 */ "table_reference_list ::= table_reference", - /* 381 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 382 */ "table_reference ::= table_primary", - /* 383 */ "table_reference ::= joined_table", - /* 384 */ "table_primary ::= table_name alias_opt", - /* 385 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 386 */ "table_primary ::= subquery alias_opt", - /* 387 */ "table_primary ::= parenthesized_joined_table", - /* 388 */ "alias_opt ::=", - /* 389 */ "alias_opt ::= table_alias", - /* 390 */ "alias_opt ::= AS table_alias", - /* 391 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 392 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 393 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 394 */ "join_type ::=", - /* 395 */ "join_type ::= INNER", - /* 396 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 397 */ "set_quantifier_opt ::=", - /* 398 */ "set_quantifier_opt ::= DISTINCT", - /* 399 */ "set_quantifier_opt ::= ALL", - /* 400 */ "select_list ::= NK_STAR", - /* 401 */ "select_list ::= select_sublist", - /* 402 */ "select_sublist ::= select_item", - /* 403 */ "select_sublist ::= select_sublist NK_COMMA select_item", - /* 404 */ "select_item ::= common_expression", - /* 405 */ "select_item ::= common_expression column_alias", - /* 406 */ "select_item ::= common_expression AS column_alias", - /* 407 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 408 */ "where_clause_opt ::=", - /* 409 */ "where_clause_opt ::= WHERE search_condition", - /* 410 */ "partition_by_clause_opt ::=", - /* 411 */ "partition_by_clause_opt ::= PARTITION BY expression_list", - /* 412 */ "twindow_clause_opt ::=", - /* 413 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 414 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP", - /* 415 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 416 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 417 */ "sliding_opt ::=", - /* 418 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 419 */ "fill_opt ::=", - /* 420 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 421 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", - /* 422 */ "fill_mode ::= NONE", - /* 423 */ "fill_mode ::= PREV", - /* 424 */ "fill_mode ::= NULL", - /* 425 */ "fill_mode ::= LINEAR", - /* 426 */ "fill_mode ::= NEXT", - /* 427 */ "group_by_clause_opt ::=", - /* 428 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 429 */ "group_by_list ::= expression", - /* 430 */ "group_by_list ::= group_by_list NK_COMMA expression", - /* 431 */ "having_clause_opt ::=", - /* 432 */ "having_clause_opt ::= HAVING search_condition", - /* 433 */ "range_opt ::=", - /* 434 */ "range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP", - /* 435 */ "every_opt ::=", - /* 436 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 437 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 438 */ "query_expression_body ::= query_primary", - /* 439 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", - /* 440 */ "query_expression_body ::= query_expression_body UNION query_expression_body", - /* 441 */ "query_primary ::= query_specification", - /* 442 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP", - /* 443 */ "order_by_clause_opt ::=", - /* 444 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 445 */ "slimit_clause_opt ::=", - /* 446 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 447 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 448 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 449 */ "limit_clause_opt ::=", - /* 450 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 451 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 452 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 453 */ "subquery ::= NK_LP query_expression NK_RP", - /* 454 */ "search_condition ::= common_expression", - /* 455 */ "sort_specification_list ::= sort_specification", - /* 456 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 457 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", - /* 458 */ "ordering_specification_opt ::=", - /* 459 */ "ordering_specification_opt ::= ASC", - /* 460 */ "ordering_specification_opt ::= DESC", - /* 461 */ "null_ordering_opt ::=", - /* 462 */ "null_ordering_opt ::= NULLS FIRST", - /* 463 */ "null_ordering_opt ::= NULLS LAST", + /* 208 */ "cmd ::= SHOW LOCAL VARIABLES", + /* 209 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES", + /* 210 */ "cmd ::= SHOW BNODES", + /* 211 */ "cmd ::= SHOW SNODES", + /* 212 */ "cmd ::= SHOW CLUSTER", + /* 213 */ "cmd ::= SHOW TRANSACTIONS", + /* 214 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", + /* 215 */ "db_name_cond_opt ::=", + /* 216 */ "db_name_cond_opt ::= db_name NK_DOT", + /* 217 */ "like_pattern_opt ::=", + /* 218 */ "like_pattern_opt ::= LIKE NK_STRING", + /* 219 */ "table_name_cond ::= table_name", + /* 220 */ "from_db_opt ::=", + /* 221 */ "from_db_opt ::= FROM db_name", + /* 222 */ "cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options", + /* 223 */ "cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP", + /* 224 */ "cmd ::= DROP INDEX exists_opt index_name ON table_name", + /* 225 */ "index_options ::=", + /* 226 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt", + /* 227 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt", + /* 228 */ "func_list ::= func", + /* 229 */ "func_list ::= func_list NK_COMMA func", + /* 230 */ "func ::= function_name NK_LP expression_list NK_RP", + /* 231 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression", + /* 232 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name", + /* 233 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name", + /* 234 */ "cmd ::= DROP TOPIC exists_opt topic_name", + /* 235 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", + /* 236 */ "cmd ::= DESC full_table_name", + /* 237 */ "cmd ::= DESCRIBE full_table_name", + /* 238 */ "cmd ::= RESET QUERY CACHE", + /* 239 */ "cmd ::= EXPLAIN analyze_opt explain_options query_expression", + /* 240 */ "analyze_opt ::=", + /* 241 */ "analyze_opt ::= ANALYZE", + /* 242 */ "explain_options ::=", + /* 243 */ "explain_options ::= explain_options VERBOSE NK_BOOL", + /* 244 */ "explain_options ::= explain_options RATIO NK_FLOAT", + /* 245 */ "cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP", + /* 246 */ "cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt", + /* 247 */ "cmd ::= DROP FUNCTION exists_opt function_name", + /* 248 */ "agg_func_opt ::=", + /* 249 */ "agg_func_opt ::= AGGREGATE", + /* 250 */ "bufsize_opt ::=", + /* 251 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", + /* 252 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression", + /* 253 */ "cmd ::= DROP STREAM exists_opt stream_name", + /* 254 */ "into_opt ::=", + /* 255 */ "into_opt ::= INTO full_table_name", + /* 256 */ "stream_options ::=", + /* 257 */ "stream_options ::= stream_options TRIGGER AT_ONCE", + /* 258 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", + /* 259 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", + /* 260 */ "stream_options ::= stream_options WATERMARK duration_literal", + /* 261 */ "cmd ::= KILL CONNECTION NK_INTEGER", + /* 262 */ "cmd ::= KILL QUERY NK_STRING", + /* 263 */ "cmd ::= KILL TRANSACTION NK_INTEGER", + /* 264 */ "cmd ::= BALANCE VGROUP", + /* 265 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", + /* 266 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", + /* 267 */ "cmd ::= SPLIT VGROUP NK_INTEGER", + /* 268 */ "dnode_list ::= DNODE NK_INTEGER", + /* 269 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", + /* 270 */ "cmd ::= SYNCDB db_name REPLICA", + /* 271 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", + /* 272 */ "cmd ::= query_expression", + /* 273 */ "literal ::= NK_INTEGER", + /* 274 */ "literal ::= NK_FLOAT", + /* 275 */ "literal ::= NK_STRING", + /* 276 */ "literal ::= NK_BOOL", + /* 277 */ "literal ::= TIMESTAMP NK_STRING", + /* 278 */ "literal ::= duration_literal", + /* 279 */ "literal ::= NULL", + /* 280 */ "literal ::= NK_QUESTION", + /* 281 */ "duration_literal ::= NK_VARIABLE", + /* 282 */ "signed ::= NK_INTEGER", + /* 283 */ "signed ::= NK_PLUS NK_INTEGER", + /* 284 */ "signed ::= NK_MINUS NK_INTEGER", + /* 285 */ "signed ::= NK_FLOAT", + /* 286 */ "signed ::= NK_PLUS NK_FLOAT", + /* 287 */ "signed ::= NK_MINUS NK_FLOAT", + /* 288 */ "signed_literal ::= signed", + /* 289 */ "signed_literal ::= NK_STRING", + /* 290 */ "signed_literal ::= NK_BOOL", + /* 291 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 292 */ "signed_literal ::= duration_literal", + /* 293 */ "signed_literal ::= NULL", + /* 294 */ "signed_literal ::= literal_func", + /* 295 */ "literal_list ::= signed_literal", + /* 296 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 297 */ "db_name ::= NK_ID", + /* 298 */ "table_name ::= NK_ID", + /* 299 */ "column_name ::= NK_ID", + /* 300 */ "function_name ::= NK_ID", + /* 301 */ "table_alias ::= NK_ID", + /* 302 */ "column_alias ::= NK_ID", + /* 303 */ "user_name ::= NK_ID", + /* 304 */ "index_name ::= NK_ID", + /* 305 */ "topic_name ::= NK_ID", + /* 306 */ "stream_name ::= NK_ID", + /* 307 */ "cgroup_name ::= NK_ID", + /* 308 */ "expression ::= literal", + /* 309 */ "expression ::= pseudo_column", + /* 310 */ "expression ::= column_reference", + /* 311 */ "expression ::= function_expression", + /* 312 */ "expression ::= subquery", + /* 313 */ "expression ::= NK_LP expression NK_RP", + /* 314 */ "expression ::= NK_PLUS expression", + /* 315 */ "expression ::= NK_MINUS expression", + /* 316 */ "expression ::= expression NK_PLUS expression", + /* 317 */ "expression ::= expression NK_MINUS expression", + /* 318 */ "expression ::= expression NK_STAR expression", + /* 319 */ "expression ::= expression NK_SLASH expression", + /* 320 */ "expression ::= expression NK_REM expression", + /* 321 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 322 */ "expression_list ::= expression", + /* 323 */ "expression_list ::= expression_list NK_COMMA expression", + /* 324 */ "column_reference ::= column_name", + /* 325 */ "column_reference ::= table_name NK_DOT column_name", + /* 326 */ "pseudo_column ::= ROWTS", + /* 327 */ "pseudo_column ::= TBNAME", + /* 328 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 329 */ "pseudo_column ::= QSTARTTS", + /* 330 */ "pseudo_column ::= QENDTS", + /* 331 */ "pseudo_column ::= WSTARTTS", + /* 332 */ "pseudo_column ::= WENDTS", + /* 333 */ "pseudo_column ::= WDURATION", + /* 334 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 335 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 336 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP", + /* 337 */ "function_expression ::= literal_func", + /* 338 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 339 */ "literal_func ::= NOW", + /* 340 */ "noarg_func ::= NOW", + /* 341 */ "noarg_func ::= TODAY", + /* 342 */ "noarg_func ::= TIMEZONE", + /* 343 */ "star_func ::= COUNT", + /* 344 */ "star_func ::= FIRST", + /* 345 */ "star_func ::= LAST", + /* 346 */ "star_func ::= LAST_ROW", + /* 347 */ "star_func_para_list ::= NK_STAR", + /* 348 */ "star_func_para_list ::= other_para_list", + /* 349 */ "other_para_list ::= star_func_para", + /* 350 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 351 */ "star_func_para ::= expression", + /* 352 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 353 */ "predicate ::= expression compare_op expression", + /* 354 */ "predicate ::= expression BETWEEN expression AND expression", + /* 355 */ "predicate ::= expression NOT BETWEEN expression AND expression", + /* 356 */ "predicate ::= expression IS NULL", + /* 357 */ "predicate ::= expression IS NOT NULL", + /* 358 */ "predicate ::= expression in_op in_predicate_value", + /* 359 */ "compare_op ::= NK_LT", + /* 360 */ "compare_op ::= NK_GT", + /* 361 */ "compare_op ::= NK_LE", + /* 362 */ "compare_op ::= NK_GE", + /* 363 */ "compare_op ::= NK_NE", + /* 364 */ "compare_op ::= NK_EQ", + /* 365 */ "compare_op ::= LIKE", + /* 366 */ "compare_op ::= NOT LIKE", + /* 367 */ "compare_op ::= MATCH", + /* 368 */ "compare_op ::= NMATCH", + /* 369 */ "compare_op ::= CONTAINS", + /* 370 */ "in_op ::= IN", + /* 371 */ "in_op ::= NOT IN", + /* 372 */ "in_predicate_value ::= NK_LP expression_list NK_RP", + /* 373 */ "boolean_value_expression ::= boolean_primary", + /* 374 */ "boolean_value_expression ::= NOT boolean_primary", + /* 375 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 376 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 377 */ "boolean_primary ::= predicate", + /* 378 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 379 */ "common_expression ::= expression", + /* 380 */ "common_expression ::= boolean_value_expression", + /* 381 */ "from_clause_opt ::=", + /* 382 */ "from_clause_opt ::= FROM table_reference_list", + /* 383 */ "table_reference_list ::= table_reference", + /* 384 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 385 */ "table_reference ::= table_primary", + /* 386 */ "table_reference ::= joined_table", + /* 387 */ "table_primary ::= table_name alias_opt", + /* 388 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 389 */ "table_primary ::= subquery alias_opt", + /* 390 */ "table_primary ::= parenthesized_joined_table", + /* 391 */ "alias_opt ::=", + /* 392 */ "alias_opt ::= table_alias", + /* 393 */ "alias_opt ::= AS table_alias", + /* 394 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 395 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 396 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 397 */ "join_type ::=", + /* 398 */ "join_type ::= INNER", + /* 399 */ "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", + /* 400 */ "set_quantifier_opt ::=", + /* 401 */ "set_quantifier_opt ::= DISTINCT", + /* 402 */ "set_quantifier_opt ::= ALL", + /* 403 */ "select_list ::= NK_STAR", + /* 404 */ "select_list ::= select_sublist", + /* 405 */ "select_sublist ::= select_item", + /* 406 */ "select_sublist ::= select_sublist NK_COMMA select_item", + /* 407 */ "select_item ::= common_expression", + /* 408 */ "select_item ::= common_expression column_alias", + /* 409 */ "select_item ::= common_expression AS column_alias", + /* 410 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 411 */ "where_clause_opt ::=", + /* 412 */ "where_clause_opt ::= WHERE search_condition", + /* 413 */ "partition_by_clause_opt ::=", + /* 414 */ "partition_by_clause_opt ::= PARTITION BY expression_list", + /* 415 */ "twindow_clause_opt ::=", + /* 416 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 417 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP", + /* 418 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 419 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 420 */ "sliding_opt ::=", + /* 421 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 422 */ "fill_opt ::=", + /* 423 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 424 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", + /* 425 */ "fill_mode ::= NONE", + /* 426 */ "fill_mode ::= PREV", + /* 427 */ "fill_mode ::= NULL", + /* 428 */ "fill_mode ::= LINEAR", + /* 429 */ "fill_mode ::= NEXT", + /* 430 */ "group_by_clause_opt ::=", + /* 431 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 432 */ "group_by_list ::= expression", + /* 433 */ "group_by_list ::= group_by_list NK_COMMA expression", + /* 434 */ "having_clause_opt ::=", + /* 435 */ "having_clause_opt ::= HAVING search_condition", + /* 436 */ "range_opt ::=", + /* 437 */ "range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP", + /* 438 */ "every_opt ::=", + /* 439 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 440 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 441 */ "query_expression_body ::= query_primary", + /* 442 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", + /* 443 */ "query_expression_body ::= query_expression_body UNION query_expression_body", + /* 444 */ "query_primary ::= query_specification", + /* 445 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP", + /* 446 */ "order_by_clause_opt ::=", + /* 447 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 448 */ "slimit_clause_opt ::=", + /* 449 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 450 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 451 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 452 */ "limit_clause_opt ::=", + /* 453 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 454 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 455 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 456 */ "subquery ::= NK_LP query_expression NK_RP", + /* 457 */ "search_condition ::= common_expression", + /* 458 */ "sort_specification_list ::= sort_specification", + /* 459 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 460 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", + /* 461 */ "ordering_specification_opt ::=", + /* 462 */ "ordering_specification_opt ::= ASC", + /* 463 */ "ordering_specification_opt ::= DESC", + /* 464 */ "null_ordering_opt ::=", + /* 465 */ "null_ordering_opt ::= NULLS FIRST", + /* 466 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -2162,7 +2181,7 @@ static void yy_destructor( case 329: /* boolean_value_expression */ case 330: /* boolean_primary */ case 331: /* common_expression */ - case 332: /* from_clause */ + case 332: /* from_clause_opt */ case 333: /* table_reference_list */ case 334: /* table_reference */ case 335: /* table_primary */ @@ -2797,262 +2816,265 @@ static const struct { { 242, -2 }, /* (205) cmd ::= SHOW SCORES */ { 242, -2 }, /* (206) cmd ::= SHOW TOPICS */ { 242, -2 }, /* (207) cmd ::= SHOW VARIABLES */ - { 242, -2 }, /* (208) cmd ::= SHOW BNODES */ - { 242, -2 }, /* (209) cmd ::= SHOW SNODES */ - { 242, -2 }, /* (210) cmd ::= SHOW CLUSTER */ - { 242, -2 }, /* (211) cmd ::= SHOW TRANSACTIONS */ - { 242, -4 }, /* (212) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - { 289, 0 }, /* (213) db_name_cond_opt ::= */ - { 289, -2 }, /* (214) db_name_cond_opt ::= db_name NK_DOT */ - { 290, 0 }, /* (215) like_pattern_opt ::= */ - { 290, -2 }, /* (216) like_pattern_opt ::= LIKE NK_STRING */ - { 291, -1 }, /* (217) table_name_cond ::= table_name */ - { 292, 0 }, /* (218) from_db_opt ::= */ - { 292, -2 }, /* (219) from_db_opt ::= FROM db_name */ - { 242, -8 }, /* (220) cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ - { 242, -10 }, /* (221) cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */ - { 242, -6 }, /* (222) cmd ::= DROP INDEX exists_opt index_name ON table_name */ - { 294, 0 }, /* (223) index_options ::= */ - { 294, -9 }, /* (224) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ - { 294, -11 }, /* (225) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ - { 295, -1 }, /* (226) func_list ::= func */ - { 295, -3 }, /* (227) func_list ::= func_list NK_COMMA func */ - { 297, -4 }, /* (228) func ::= function_name NK_LP expression_list NK_RP */ - { 242, -6 }, /* (229) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ - { 242, -7 }, /* (230) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ - { 242, -7 }, /* (231) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ - { 242, -4 }, /* (232) cmd ::= DROP TOPIC exists_opt topic_name */ - { 242, -7 }, /* (233) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - { 242, -2 }, /* (234) cmd ::= DESC full_table_name */ - { 242, -2 }, /* (235) cmd ::= DESCRIBE full_table_name */ - { 242, -3 }, /* (236) cmd ::= RESET QUERY CACHE */ - { 242, -4 }, /* (237) cmd ::= EXPLAIN analyze_opt explain_options query_expression */ - { 302, 0 }, /* (238) analyze_opt ::= */ - { 302, -1 }, /* (239) analyze_opt ::= ANALYZE */ - { 303, 0 }, /* (240) explain_options ::= */ - { 303, -3 }, /* (241) explain_options ::= explain_options VERBOSE NK_BOOL */ - { 303, -3 }, /* (242) explain_options ::= explain_options RATIO NK_FLOAT */ - { 242, -6 }, /* (243) cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ - { 242, -10 }, /* (244) cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ - { 242, -4 }, /* (245) cmd ::= DROP FUNCTION exists_opt function_name */ - { 304, 0 }, /* (246) agg_func_opt ::= */ - { 304, -1 }, /* (247) agg_func_opt ::= AGGREGATE */ - { 305, 0 }, /* (248) bufsize_opt ::= */ - { 305, -2 }, /* (249) bufsize_opt ::= BUFSIZE NK_INTEGER */ - { 242, -8 }, /* (250) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ - { 242, -4 }, /* (251) cmd ::= DROP STREAM exists_opt stream_name */ - { 308, 0 }, /* (252) into_opt ::= */ - { 308, -2 }, /* (253) into_opt ::= INTO full_table_name */ - { 307, 0 }, /* (254) stream_options ::= */ - { 307, -3 }, /* (255) stream_options ::= stream_options TRIGGER AT_ONCE */ - { 307, -3 }, /* (256) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - { 307, -4 }, /* (257) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - { 307, -3 }, /* (258) stream_options ::= stream_options WATERMARK duration_literal */ - { 242, -3 }, /* (259) cmd ::= KILL CONNECTION NK_INTEGER */ - { 242, -3 }, /* (260) cmd ::= KILL QUERY NK_STRING */ - { 242, -3 }, /* (261) cmd ::= KILL TRANSACTION NK_INTEGER */ - { 242, -2 }, /* (262) cmd ::= BALANCE VGROUP */ - { 242, -4 }, /* (263) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - { 242, -4 }, /* (264) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - { 242, -3 }, /* (265) cmd ::= SPLIT VGROUP NK_INTEGER */ - { 309, -2 }, /* (266) dnode_list ::= DNODE NK_INTEGER */ - { 309, -3 }, /* (267) dnode_list ::= dnode_list DNODE NK_INTEGER */ - { 242, -3 }, /* (268) cmd ::= SYNCDB db_name REPLICA */ - { 242, -4 }, /* (269) cmd ::= DELETE FROM full_table_name where_clause_opt */ - { 242, -1 }, /* (270) cmd ::= query_expression */ - { 245, -1 }, /* (271) literal ::= NK_INTEGER */ - { 245, -1 }, /* (272) literal ::= NK_FLOAT */ - { 245, -1 }, /* (273) literal ::= NK_STRING */ - { 245, -1 }, /* (274) literal ::= NK_BOOL */ - { 245, -2 }, /* (275) literal ::= TIMESTAMP NK_STRING */ - { 245, -1 }, /* (276) literal ::= duration_literal */ - { 245, -1 }, /* (277) literal ::= NULL */ - { 245, -1 }, /* (278) literal ::= NK_QUESTION */ - { 285, -1 }, /* (279) duration_literal ::= NK_VARIABLE */ - { 311, -1 }, /* (280) signed ::= NK_INTEGER */ - { 311, -2 }, /* (281) signed ::= NK_PLUS NK_INTEGER */ - { 311, -2 }, /* (282) signed ::= NK_MINUS NK_INTEGER */ - { 311, -1 }, /* (283) signed ::= NK_FLOAT */ - { 311, -2 }, /* (284) signed ::= NK_PLUS NK_FLOAT */ - { 311, -2 }, /* (285) signed ::= NK_MINUS NK_FLOAT */ - { 274, -1 }, /* (286) signed_literal ::= signed */ - { 274, -1 }, /* (287) signed_literal ::= NK_STRING */ - { 274, -1 }, /* (288) signed_literal ::= NK_BOOL */ - { 274, -2 }, /* (289) signed_literal ::= TIMESTAMP NK_STRING */ - { 274, -1 }, /* (290) signed_literal ::= duration_literal */ - { 274, -1 }, /* (291) signed_literal ::= NULL */ - { 274, -1 }, /* (292) signed_literal ::= literal_func */ - { 277, -1 }, /* (293) literal_list ::= signed_literal */ - { 277, -3 }, /* (294) literal_list ::= literal_list NK_COMMA signed_literal */ - { 252, -1 }, /* (295) db_name ::= NK_ID */ - { 280, -1 }, /* (296) table_name ::= NK_ID */ - { 272, -1 }, /* (297) column_name ::= NK_ID */ - { 287, -1 }, /* (298) function_name ::= NK_ID */ - { 313, -1 }, /* (299) table_alias ::= NK_ID */ - { 314, -1 }, /* (300) column_alias ::= NK_ID */ - { 247, -1 }, /* (301) user_name ::= NK_ID */ - { 293, -1 }, /* (302) index_name ::= NK_ID */ - { 299, -1 }, /* (303) topic_name ::= NK_ID */ - { 306, -1 }, /* (304) stream_name ::= NK_ID */ - { 301, -1 }, /* (305) cgroup_name ::= NK_ID */ - { 315, -1 }, /* (306) expression ::= literal */ - { 315, -1 }, /* (307) expression ::= pseudo_column */ - { 315, -1 }, /* (308) expression ::= column_reference */ - { 315, -1 }, /* (309) expression ::= function_expression */ - { 315, -1 }, /* (310) expression ::= subquery */ - { 315, -3 }, /* (311) expression ::= NK_LP expression NK_RP */ - { 315, -2 }, /* (312) expression ::= NK_PLUS expression */ - { 315, -2 }, /* (313) expression ::= NK_MINUS expression */ - { 315, -3 }, /* (314) expression ::= expression NK_PLUS expression */ - { 315, -3 }, /* (315) expression ::= expression NK_MINUS expression */ - { 315, -3 }, /* (316) expression ::= expression NK_STAR expression */ - { 315, -3 }, /* (317) expression ::= expression NK_SLASH expression */ - { 315, -3 }, /* (318) expression ::= expression NK_REM expression */ - { 315, -3 }, /* (319) expression ::= column_reference NK_ARROW NK_STRING */ - { 298, -1 }, /* (320) expression_list ::= expression */ - { 298, -3 }, /* (321) expression_list ::= expression_list NK_COMMA expression */ - { 317, -1 }, /* (322) column_reference ::= column_name */ - { 317, -3 }, /* (323) column_reference ::= table_name NK_DOT column_name */ - { 316, -1 }, /* (324) pseudo_column ::= ROWTS */ - { 316, -1 }, /* (325) pseudo_column ::= TBNAME */ - { 316, -3 }, /* (326) pseudo_column ::= table_name NK_DOT TBNAME */ - { 316, -1 }, /* (327) pseudo_column ::= QSTARTTS */ - { 316, -1 }, /* (328) pseudo_column ::= QENDTS */ - { 316, -1 }, /* (329) pseudo_column ::= WSTARTTS */ - { 316, -1 }, /* (330) pseudo_column ::= WENDTS */ - { 316, -1 }, /* (331) pseudo_column ::= WDURATION */ - { 318, -4 }, /* (332) function_expression ::= function_name NK_LP expression_list NK_RP */ - { 318, -4 }, /* (333) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - { 318, -6 }, /* (334) function_expression ::= CAST NK_LP expression AS type_name NK_RP */ - { 318, -1 }, /* (335) function_expression ::= literal_func */ - { 312, -3 }, /* (336) literal_func ::= noarg_func NK_LP NK_RP */ - { 312, -1 }, /* (337) literal_func ::= NOW */ - { 322, -1 }, /* (338) noarg_func ::= NOW */ - { 322, -1 }, /* (339) noarg_func ::= TODAY */ - { 322, -1 }, /* (340) noarg_func ::= TIMEZONE */ - { 320, -1 }, /* (341) star_func ::= COUNT */ - { 320, -1 }, /* (342) star_func ::= FIRST */ - { 320, -1 }, /* (343) star_func ::= LAST */ - { 320, -1 }, /* (344) star_func ::= LAST_ROW */ - { 321, -1 }, /* (345) star_func_para_list ::= NK_STAR */ - { 321, -1 }, /* (346) star_func_para_list ::= other_para_list */ - { 323, -1 }, /* (347) other_para_list ::= star_func_para */ - { 323, -3 }, /* (348) other_para_list ::= other_para_list NK_COMMA star_func_para */ - { 324, -1 }, /* (349) star_func_para ::= expression */ - { 324, -3 }, /* (350) star_func_para ::= table_name NK_DOT NK_STAR */ - { 325, -3 }, /* (351) predicate ::= expression compare_op expression */ - { 325, -5 }, /* (352) predicate ::= expression BETWEEN expression AND expression */ - { 325, -6 }, /* (353) predicate ::= expression NOT BETWEEN expression AND expression */ - { 325, -3 }, /* (354) predicate ::= expression IS NULL */ - { 325, -4 }, /* (355) predicate ::= expression IS NOT NULL */ - { 325, -3 }, /* (356) predicate ::= expression in_op in_predicate_value */ - { 326, -1 }, /* (357) compare_op ::= NK_LT */ - { 326, -1 }, /* (358) compare_op ::= NK_GT */ - { 326, -1 }, /* (359) compare_op ::= NK_LE */ - { 326, -1 }, /* (360) compare_op ::= NK_GE */ - { 326, -1 }, /* (361) compare_op ::= NK_NE */ - { 326, -1 }, /* (362) compare_op ::= NK_EQ */ - { 326, -1 }, /* (363) compare_op ::= LIKE */ - { 326, -2 }, /* (364) compare_op ::= NOT LIKE */ - { 326, -1 }, /* (365) compare_op ::= MATCH */ - { 326, -1 }, /* (366) compare_op ::= NMATCH */ - { 326, -1 }, /* (367) compare_op ::= CONTAINS */ - { 327, -1 }, /* (368) in_op ::= IN */ - { 327, -2 }, /* (369) in_op ::= NOT IN */ - { 328, -3 }, /* (370) in_predicate_value ::= NK_LP expression_list NK_RP */ - { 329, -1 }, /* (371) boolean_value_expression ::= boolean_primary */ - { 329, -2 }, /* (372) boolean_value_expression ::= NOT boolean_primary */ - { 329, -3 }, /* (373) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - { 329, -3 }, /* (374) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - { 330, -1 }, /* (375) boolean_primary ::= predicate */ - { 330, -3 }, /* (376) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - { 331, -1 }, /* (377) common_expression ::= expression */ - { 331, -1 }, /* (378) common_expression ::= boolean_value_expression */ - { 332, -2 }, /* (379) from_clause ::= FROM table_reference_list */ - { 333, -1 }, /* (380) table_reference_list ::= table_reference */ - { 333, -3 }, /* (381) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - { 334, -1 }, /* (382) table_reference ::= table_primary */ - { 334, -1 }, /* (383) table_reference ::= joined_table */ - { 335, -2 }, /* (384) table_primary ::= table_name alias_opt */ - { 335, -4 }, /* (385) table_primary ::= db_name NK_DOT table_name alias_opt */ - { 335, -2 }, /* (386) table_primary ::= subquery alias_opt */ - { 335, -1 }, /* (387) table_primary ::= parenthesized_joined_table */ - { 337, 0 }, /* (388) alias_opt ::= */ - { 337, -1 }, /* (389) alias_opt ::= table_alias */ - { 337, -2 }, /* (390) alias_opt ::= AS table_alias */ - { 338, -3 }, /* (391) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - { 338, -3 }, /* (392) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - { 336, -6 }, /* (393) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - { 339, 0 }, /* (394) join_type ::= */ - { 339, -1 }, /* (395) join_type ::= INNER */ - { 341, -12 }, /* (396) query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - { 342, 0 }, /* (397) set_quantifier_opt ::= */ - { 342, -1 }, /* (398) set_quantifier_opt ::= DISTINCT */ - { 342, -1 }, /* (399) set_quantifier_opt ::= ALL */ - { 343, -1 }, /* (400) select_list ::= NK_STAR */ - { 343, -1 }, /* (401) select_list ::= select_sublist */ - { 351, -1 }, /* (402) select_sublist ::= select_item */ - { 351, -3 }, /* (403) select_sublist ::= select_sublist NK_COMMA select_item */ - { 352, -1 }, /* (404) select_item ::= common_expression */ - { 352, -2 }, /* (405) select_item ::= common_expression column_alias */ - { 352, -3 }, /* (406) select_item ::= common_expression AS column_alias */ - { 352, -3 }, /* (407) select_item ::= table_name NK_DOT NK_STAR */ - { 310, 0 }, /* (408) where_clause_opt ::= */ - { 310, -2 }, /* (409) where_clause_opt ::= WHERE search_condition */ - { 344, 0 }, /* (410) partition_by_clause_opt ::= */ - { 344, -3 }, /* (411) partition_by_clause_opt ::= PARTITION BY expression_list */ - { 348, 0 }, /* (412) twindow_clause_opt ::= */ - { 348, -6 }, /* (413) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - { 348, -4 }, /* (414) twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ - { 348, -6 }, /* (415) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - { 348, -8 }, /* (416) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - { 296, 0 }, /* (417) sliding_opt ::= */ - { 296, -4 }, /* (418) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - { 347, 0 }, /* (419) fill_opt ::= */ - { 347, -4 }, /* (420) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - { 347, -6 }, /* (421) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ - { 353, -1 }, /* (422) fill_mode ::= NONE */ - { 353, -1 }, /* (423) fill_mode ::= PREV */ - { 353, -1 }, /* (424) fill_mode ::= NULL */ - { 353, -1 }, /* (425) fill_mode ::= LINEAR */ - { 353, -1 }, /* (426) fill_mode ::= NEXT */ - { 349, 0 }, /* (427) group_by_clause_opt ::= */ - { 349, -3 }, /* (428) group_by_clause_opt ::= GROUP BY group_by_list */ - { 354, -1 }, /* (429) group_by_list ::= expression */ - { 354, -3 }, /* (430) group_by_list ::= group_by_list NK_COMMA expression */ - { 350, 0 }, /* (431) having_clause_opt ::= */ - { 350, -2 }, /* (432) having_clause_opt ::= HAVING search_condition */ - { 345, 0 }, /* (433) range_opt ::= */ - { 345, -6 }, /* (434) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ - { 346, 0 }, /* (435) every_opt ::= */ - { 346, -4 }, /* (436) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - { 300, -4 }, /* (437) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ - { 355, -1 }, /* (438) query_expression_body ::= query_primary */ - { 355, -4 }, /* (439) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ - { 355, -3 }, /* (440) query_expression_body ::= query_expression_body UNION query_expression_body */ - { 359, -1 }, /* (441) query_primary ::= query_specification */ - { 359, -6 }, /* (442) query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ - { 356, 0 }, /* (443) order_by_clause_opt ::= */ - { 356, -3 }, /* (444) order_by_clause_opt ::= ORDER BY sort_specification_list */ - { 357, 0 }, /* (445) slimit_clause_opt ::= */ - { 357, -2 }, /* (446) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - { 357, -4 }, /* (447) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - { 357, -4 }, /* (448) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 358, 0 }, /* (449) limit_clause_opt ::= */ - { 358, -2 }, /* (450) limit_clause_opt ::= LIMIT NK_INTEGER */ - { 358, -4 }, /* (451) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - { 358, -4 }, /* (452) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 319, -3 }, /* (453) subquery ::= NK_LP query_expression NK_RP */ - { 340, -1 }, /* (454) search_condition ::= common_expression */ - { 360, -1 }, /* (455) sort_specification_list ::= sort_specification */ - { 360, -3 }, /* (456) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - { 361, -3 }, /* (457) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ - { 362, 0 }, /* (458) ordering_specification_opt ::= */ - { 362, -1 }, /* (459) ordering_specification_opt ::= ASC */ - { 362, -1 }, /* (460) ordering_specification_opt ::= DESC */ - { 363, 0 }, /* (461) null_ordering_opt ::= */ - { 363, -2 }, /* (462) null_ordering_opt ::= NULLS FIRST */ - { 363, -2 }, /* (463) null_ordering_opt ::= NULLS LAST */ + { 242, -3 }, /* (208) cmd ::= SHOW LOCAL VARIABLES */ + { 242, -4 }, /* (209) cmd ::= SHOW DNODE NK_INTEGER VARIABLES */ + { 242, -2 }, /* (210) cmd ::= SHOW BNODES */ + { 242, -2 }, /* (211) cmd ::= SHOW SNODES */ + { 242, -2 }, /* (212) cmd ::= SHOW CLUSTER */ + { 242, -2 }, /* (213) cmd ::= SHOW TRANSACTIONS */ + { 242, -4 }, /* (214) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + { 289, 0 }, /* (215) db_name_cond_opt ::= */ + { 289, -2 }, /* (216) db_name_cond_opt ::= db_name NK_DOT */ + { 290, 0 }, /* (217) like_pattern_opt ::= */ + { 290, -2 }, /* (218) like_pattern_opt ::= LIKE NK_STRING */ + { 291, -1 }, /* (219) table_name_cond ::= table_name */ + { 292, 0 }, /* (220) from_db_opt ::= */ + { 292, -2 }, /* (221) from_db_opt ::= FROM db_name */ + { 242, -8 }, /* (222) cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ + { 242, -10 }, /* (223) cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */ + { 242, -6 }, /* (224) cmd ::= DROP INDEX exists_opt index_name ON table_name */ + { 294, 0 }, /* (225) index_options ::= */ + { 294, -9 }, /* (226) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ + { 294, -11 }, /* (227) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ + { 295, -1 }, /* (228) func_list ::= func */ + { 295, -3 }, /* (229) func_list ::= func_list NK_COMMA func */ + { 297, -4 }, /* (230) func ::= function_name NK_LP expression_list NK_RP */ + { 242, -6 }, /* (231) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ + { 242, -7 }, /* (232) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ + { 242, -7 }, /* (233) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ + { 242, -4 }, /* (234) cmd ::= DROP TOPIC exists_opt topic_name */ + { 242, -7 }, /* (235) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + { 242, -2 }, /* (236) cmd ::= DESC full_table_name */ + { 242, -2 }, /* (237) cmd ::= DESCRIBE full_table_name */ + { 242, -3 }, /* (238) cmd ::= RESET QUERY CACHE */ + { 242, -4 }, /* (239) cmd ::= EXPLAIN analyze_opt explain_options query_expression */ + { 302, 0 }, /* (240) analyze_opt ::= */ + { 302, -1 }, /* (241) analyze_opt ::= ANALYZE */ + { 303, 0 }, /* (242) explain_options ::= */ + { 303, -3 }, /* (243) explain_options ::= explain_options VERBOSE NK_BOOL */ + { 303, -3 }, /* (244) explain_options ::= explain_options RATIO NK_FLOAT */ + { 242, -6 }, /* (245) cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ + { 242, -10 }, /* (246) cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ + { 242, -4 }, /* (247) cmd ::= DROP FUNCTION exists_opt function_name */ + { 304, 0 }, /* (248) agg_func_opt ::= */ + { 304, -1 }, /* (249) agg_func_opt ::= AGGREGATE */ + { 305, 0 }, /* (250) bufsize_opt ::= */ + { 305, -2 }, /* (251) bufsize_opt ::= BUFSIZE NK_INTEGER */ + { 242, -8 }, /* (252) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ + { 242, -4 }, /* (253) cmd ::= DROP STREAM exists_opt stream_name */ + { 308, 0 }, /* (254) into_opt ::= */ + { 308, -2 }, /* (255) into_opt ::= INTO full_table_name */ + { 307, 0 }, /* (256) stream_options ::= */ + { 307, -3 }, /* (257) stream_options ::= stream_options TRIGGER AT_ONCE */ + { 307, -3 }, /* (258) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + { 307, -4 }, /* (259) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + { 307, -3 }, /* (260) stream_options ::= stream_options WATERMARK duration_literal */ + { 242, -3 }, /* (261) cmd ::= KILL CONNECTION NK_INTEGER */ + { 242, -3 }, /* (262) cmd ::= KILL QUERY NK_STRING */ + { 242, -3 }, /* (263) cmd ::= KILL TRANSACTION NK_INTEGER */ + { 242, -2 }, /* (264) cmd ::= BALANCE VGROUP */ + { 242, -4 }, /* (265) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + { 242, -4 }, /* (266) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + { 242, -3 }, /* (267) cmd ::= SPLIT VGROUP NK_INTEGER */ + { 309, -2 }, /* (268) dnode_list ::= DNODE NK_INTEGER */ + { 309, -3 }, /* (269) dnode_list ::= dnode_list DNODE NK_INTEGER */ + { 242, -3 }, /* (270) cmd ::= SYNCDB db_name REPLICA */ + { 242, -4 }, /* (271) cmd ::= DELETE FROM full_table_name where_clause_opt */ + { 242, -1 }, /* (272) cmd ::= query_expression */ + { 245, -1 }, /* (273) literal ::= NK_INTEGER */ + { 245, -1 }, /* (274) literal ::= NK_FLOAT */ + { 245, -1 }, /* (275) literal ::= NK_STRING */ + { 245, -1 }, /* (276) literal ::= NK_BOOL */ + { 245, -2 }, /* (277) literal ::= TIMESTAMP NK_STRING */ + { 245, -1 }, /* (278) literal ::= duration_literal */ + { 245, -1 }, /* (279) literal ::= NULL */ + { 245, -1 }, /* (280) literal ::= NK_QUESTION */ + { 285, -1 }, /* (281) duration_literal ::= NK_VARIABLE */ + { 311, -1 }, /* (282) signed ::= NK_INTEGER */ + { 311, -2 }, /* (283) signed ::= NK_PLUS NK_INTEGER */ + { 311, -2 }, /* (284) signed ::= NK_MINUS NK_INTEGER */ + { 311, -1 }, /* (285) signed ::= NK_FLOAT */ + { 311, -2 }, /* (286) signed ::= NK_PLUS NK_FLOAT */ + { 311, -2 }, /* (287) signed ::= NK_MINUS NK_FLOAT */ + { 274, -1 }, /* (288) signed_literal ::= signed */ + { 274, -1 }, /* (289) signed_literal ::= NK_STRING */ + { 274, -1 }, /* (290) signed_literal ::= NK_BOOL */ + { 274, -2 }, /* (291) signed_literal ::= TIMESTAMP NK_STRING */ + { 274, -1 }, /* (292) signed_literal ::= duration_literal */ + { 274, -1 }, /* (293) signed_literal ::= NULL */ + { 274, -1 }, /* (294) signed_literal ::= literal_func */ + { 277, -1 }, /* (295) literal_list ::= signed_literal */ + { 277, -3 }, /* (296) literal_list ::= literal_list NK_COMMA signed_literal */ + { 252, -1 }, /* (297) db_name ::= NK_ID */ + { 280, -1 }, /* (298) table_name ::= NK_ID */ + { 272, -1 }, /* (299) column_name ::= NK_ID */ + { 287, -1 }, /* (300) function_name ::= NK_ID */ + { 313, -1 }, /* (301) table_alias ::= NK_ID */ + { 314, -1 }, /* (302) column_alias ::= NK_ID */ + { 247, -1 }, /* (303) user_name ::= NK_ID */ + { 293, -1 }, /* (304) index_name ::= NK_ID */ + { 299, -1 }, /* (305) topic_name ::= NK_ID */ + { 306, -1 }, /* (306) stream_name ::= NK_ID */ + { 301, -1 }, /* (307) cgroup_name ::= NK_ID */ + { 315, -1 }, /* (308) expression ::= literal */ + { 315, -1 }, /* (309) expression ::= pseudo_column */ + { 315, -1 }, /* (310) expression ::= column_reference */ + { 315, -1 }, /* (311) expression ::= function_expression */ + { 315, -1 }, /* (312) expression ::= subquery */ + { 315, -3 }, /* (313) expression ::= NK_LP expression NK_RP */ + { 315, -2 }, /* (314) expression ::= NK_PLUS expression */ + { 315, -2 }, /* (315) expression ::= NK_MINUS expression */ + { 315, -3 }, /* (316) expression ::= expression NK_PLUS expression */ + { 315, -3 }, /* (317) expression ::= expression NK_MINUS expression */ + { 315, -3 }, /* (318) expression ::= expression NK_STAR expression */ + { 315, -3 }, /* (319) expression ::= expression NK_SLASH expression */ + { 315, -3 }, /* (320) expression ::= expression NK_REM expression */ + { 315, -3 }, /* (321) expression ::= column_reference NK_ARROW NK_STRING */ + { 298, -1 }, /* (322) expression_list ::= expression */ + { 298, -3 }, /* (323) expression_list ::= expression_list NK_COMMA expression */ + { 317, -1 }, /* (324) column_reference ::= column_name */ + { 317, -3 }, /* (325) column_reference ::= table_name NK_DOT column_name */ + { 316, -1 }, /* (326) pseudo_column ::= ROWTS */ + { 316, -1 }, /* (327) pseudo_column ::= TBNAME */ + { 316, -3 }, /* (328) pseudo_column ::= table_name NK_DOT TBNAME */ + { 316, -1 }, /* (329) pseudo_column ::= QSTARTTS */ + { 316, -1 }, /* (330) pseudo_column ::= QENDTS */ + { 316, -1 }, /* (331) pseudo_column ::= WSTARTTS */ + { 316, -1 }, /* (332) pseudo_column ::= WENDTS */ + { 316, -1 }, /* (333) pseudo_column ::= WDURATION */ + { 318, -4 }, /* (334) function_expression ::= function_name NK_LP expression_list NK_RP */ + { 318, -4 }, /* (335) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + { 318, -6 }, /* (336) function_expression ::= CAST NK_LP expression AS type_name NK_RP */ + { 318, -1 }, /* (337) function_expression ::= literal_func */ + { 312, -3 }, /* (338) literal_func ::= noarg_func NK_LP NK_RP */ + { 312, -1 }, /* (339) literal_func ::= NOW */ + { 322, -1 }, /* (340) noarg_func ::= NOW */ + { 322, -1 }, /* (341) noarg_func ::= TODAY */ + { 322, -1 }, /* (342) noarg_func ::= TIMEZONE */ + { 320, -1 }, /* (343) star_func ::= COUNT */ + { 320, -1 }, /* (344) star_func ::= FIRST */ + { 320, -1 }, /* (345) star_func ::= LAST */ + { 320, -1 }, /* (346) star_func ::= LAST_ROW */ + { 321, -1 }, /* (347) star_func_para_list ::= NK_STAR */ + { 321, -1 }, /* (348) star_func_para_list ::= other_para_list */ + { 323, -1 }, /* (349) other_para_list ::= star_func_para */ + { 323, -3 }, /* (350) other_para_list ::= other_para_list NK_COMMA star_func_para */ + { 324, -1 }, /* (351) star_func_para ::= expression */ + { 324, -3 }, /* (352) star_func_para ::= table_name NK_DOT NK_STAR */ + { 325, -3 }, /* (353) predicate ::= expression compare_op expression */ + { 325, -5 }, /* (354) predicate ::= expression BETWEEN expression AND expression */ + { 325, -6 }, /* (355) predicate ::= expression NOT BETWEEN expression AND expression */ + { 325, -3 }, /* (356) predicate ::= expression IS NULL */ + { 325, -4 }, /* (357) predicate ::= expression IS NOT NULL */ + { 325, -3 }, /* (358) predicate ::= expression in_op in_predicate_value */ + { 326, -1 }, /* (359) compare_op ::= NK_LT */ + { 326, -1 }, /* (360) compare_op ::= NK_GT */ + { 326, -1 }, /* (361) compare_op ::= NK_LE */ + { 326, -1 }, /* (362) compare_op ::= NK_GE */ + { 326, -1 }, /* (363) compare_op ::= NK_NE */ + { 326, -1 }, /* (364) compare_op ::= NK_EQ */ + { 326, -1 }, /* (365) compare_op ::= LIKE */ + { 326, -2 }, /* (366) compare_op ::= NOT LIKE */ + { 326, -1 }, /* (367) compare_op ::= MATCH */ + { 326, -1 }, /* (368) compare_op ::= NMATCH */ + { 326, -1 }, /* (369) compare_op ::= CONTAINS */ + { 327, -1 }, /* (370) in_op ::= IN */ + { 327, -2 }, /* (371) in_op ::= NOT IN */ + { 328, -3 }, /* (372) in_predicate_value ::= NK_LP expression_list NK_RP */ + { 329, -1 }, /* (373) boolean_value_expression ::= boolean_primary */ + { 329, -2 }, /* (374) boolean_value_expression ::= NOT boolean_primary */ + { 329, -3 }, /* (375) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + { 329, -3 }, /* (376) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + { 330, -1 }, /* (377) boolean_primary ::= predicate */ + { 330, -3 }, /* (378) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + { 331, -1 }, /* (379) common_expression ::= expression */ + { 331, -1 }, /* (380) common_expression ::= boolean_value_expression */ + { 332, 0 }, /* (381) from_clause_opt ::= */ + { 332, -2 }, /* (382) from_clause_opt ::= FROM table_reference_list */ + { 333, -1 }, /* (383) table_reference_list ::= table_reference */ + { 333, -3 }, /* (384) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + { 334, -1 }, /* (385) table_reference ::= table_primary */ + { 334, -1 }, /* (386) table_reference ::= joined_table */ + { 335, -2 }, /* (387) table_primary ::= table_name alias_opt */ + { 335, -4 }, /* (388) table_primary ::= db_name NK_DOT table_name alias_opt */ + { 335, -2 }, /* (389) table_primary ::= subquery alias_opt */ + { 335, -1 }, /* (390) table_primary ::= parenthesized_joined_table */ + { 337, 0 }, /* (391) alias_opt ::= */ + { 337, -1 }, /* (392) alias_opt ::= table_alias */ + { 337, -2 }, /* (393) alias_opt ::= AS table_alias */ + { 338, -3 }, /* (394) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + { 338, -3 }, /* (395) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + { 336, -6 }, /* (396) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + { 339, 0 }, /* (397) join_type ::= */ + { 339, -1 }, /* (398) join_type ::= INNER */ + { 341, -12 }, /* (399) 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 */ + { 342, 0 }, /* (400) set_quantifier_opt ::= */ + { 342, -1 }, /* (401) set_quantifier_opt ::= DISTINCT */ + { 342, -1 }, /* (402) set_quantifier_opt ::= ALL */ + { 343, -1 }, /* (403) select_list ::= NK_STAR */ + { 343, -1 }, /* (404) select_list ::= select_sublist */ + { 351, -1 }, /* (405) select_sublist ::= select_item */ + { 351, -3 }, /* (406) select_sublist ::= select_sublist NK_COMMA select_item */ + { 352, -1 }, /* (407) select_item ::= common_expression */ + { 352, -2 }, /* (408) select_item ::= common_expression column_alias */ + { 352, -3 }, /* (409) select_item ::= common_expression AS column_alias */ + { 352, -3 }, /* (410) select_item ::= table_name NK_DOT NK_STAR */ + { 310, 0 }, /* (411) where_clause_opt ::= */ + { 310, -2 }, /* (412) where_clause_opt ::= WHERE search_condition */ + { 344, 0 }, /* (413) partition_by_clause_opt ::= */ + { 344, -3 }, /* (414) partition_by_clause_opt ::= PARTITION BY expression_list */ + { 348, 0 }, /* (415) twindow_clause_opt ::= */ + { 348, -6 }, /* (416) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + { 348, -4 }, /* (417) twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ + { 348, -6 }, /* (418) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + { 348, -8 }, /* (419) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + { 296, 0 }, /* (420) sliding_opt ::= */ + { 296, -4 }, /* (421) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + { 347, 0 }, /* (422) fill_opt ::= */ + { 347, -4 }, /* (423) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + { 347, -6 }, /* (424) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ + { 353, -1 }, /* (425) fill_mode ::= NONE */ + { 353, -1 }, /* (426) fill_mode ::= PREV */ + { 353, -1 }, /* (427) fill_mode ::= NULL */ + { 353, -1 }, /* (428) fill_mode ::= LINEAR */ + { 353, -1 }, /* (429) fill_mode ::= NEXT */ + { 349, 0 }, /* (430) group_by_clause_opt ::= */ + { 349, -3 }, /* (431) group_by_clause_opt ::= GROUP BY group_by_list */ + { 354, -1 }, /* (432) group_by_list ::= expression */ + { 354, -3 }, /* (433) group_by_list ::= group_by_list NK_COMMA expression */ + { 350, 0 }, /* (434) having_clause_opt ::= */ + { 350, -2 }, /* (435) having_clause_opt ::= HAVING search_condition */ + { 345, 0 }, /* (436) range_opt ::= */ + { 345, -6 }, /* (437) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ + { 346, 0 }, /* (438) every_opt ::= */ + { 346, -4 }, /* (439) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + { 300, -4 }, /* (440) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + { 355, -1 }, /* (441) query_expression_body ::= query_primary */ + { 355, -4 }, /* (442) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ + { 355, -3 }, /* (443) query_expression_body ::= query_expression_body UNION query_expression_body */ + { 359, -1 }, /* (444) query_primary ::= query_specification */ + { 359, -6 }, /* (445) query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ + { 356, 0 }, /* (446) order_by_clause_opt ::= */ + { 356, -3 }, /* (447) order_by_clause_opt ::= ORDER BY sort_specification_list */ + { 357, 0 }, /* (448) slimit_clause_opt ::= */ + { 357, -2 }, /* (449) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + { 357, -4 }, /* (450) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + { 357, -4 }, /* (451) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 358, 0 }, /* (452) limit_clause_opt ::= */ + { 358, -2 }, /* (453) limit_clause_opt ::= LIMIT NK_INTEGER */ + { 358, -4 }, /* (454) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + { 358, -4 }, /* (455) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 319, -3 }, /* (456) subquery ::= NK_LP query_expression NK_RP */ + { 340, -1 }, /* (457) search_condition ::= common_expression */ + { 360, -1 }, /* (458) sort_specification_list ::= sort_specification */ + { 360, -3 }, /* (459) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + { 361, -3 }, /* (460) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ + { 362, 0 }, /* (461) ordering_specification_opt ::= */ + { 362, -1 }, /* (462) ordering_specification_opt ::= ASC */ + { 362, -1 }, /* (463) ordering_specification_opt ::= DESC */ + { 363, 0 }, /* (464) null_ordering_opt ::= */ + { 363, -2 }, /* (465) null_ordering_opt ::= NULLS FIRST */ + { 363, -2 }, /* (466) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -3259,24 +3281,24 @@ static YYACTIONTYPE yy_reduce( case 46: /* dnode_endpoint ::= NK_STRING */ case 47: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==47); case 48: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==48); - case 295: /* db_name ::= NK_ID */ yytestcase(yyruleno==295); - case 296: /* table_name ::= NK_ID */ yytestcase(yyruleno==296); - case 297: /* column_name ::= NK_ID */ yytestcase(yyruleno==297); - case 298: /* function_name ::= NK_ID */ yytestcase(yyruleno==298); - case 299: /* table_alias ::= NK_ID */ yytestcase(yyruleno==299); - case 300: /* column_alias ::= NK_ID */ yytestcase(yyruleno==300); - case 301: /* user_name ::= NK_ID */ yytestcase(yyruleno==301); - case 302: /* index_name ::= NK_ID */ yytestcase(yyruleno==302); - case 303: /* topic_name ::= NK_ID */ yytestcase(yyruleno==303); - case 304: /* stream_name ::= NK_ID */ yytestcase(yyruleno==304); - case 305: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==305); - case 338: /* noarg_func ::= NOW */ yytestcase(yyruleno==338); - case 339: /* noarg_func ::= TODAY */ yytestcase(yyruleno==339); - case 340: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==340); - case 341: /* star_func ::= COUNT */ yytestcase(yyruleno==341); - case 342: /* star_func ::= FIRST */ yytestcase(yyruleno==342); - case 343: /* star_func ::= LAST */ yytestcase(yyruleno==343); - case 344: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==344); + case 297: /* db_name ::= NK_ID */ yytestcase(yyruleno==297); + case 298: /* table_name ::= NK_ID */ yytestcase(yyruleno==298); + case 299: /* column_name ::= NK_ID */ yytestcase(yyruleno==299); + case 300: /* function_name ::= NK_ID */ yytestcase(yyruleno==300); + case 301: /* table_alias ::= NK_ID */ yytestcase(yyruleno==301); + case 302: /* column_alias ::= NK_ID */ yytestcase(yyruleno==302); + case 303: /* user_name ::= NK_ID */ yytestcase(yyruleno==303); + case 304: /* index_name ::= NK_ID */ yytestcase(yyruleno==304); + case 305: /* topic_name ::= NK_ID */ yytestcase(yyruleno==305); + case 306: /* stream_name ::= NK_ID */ yytestcase(yyruleno==306); + case 307: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==307); + case 340: /* noarg_func ::= NOW */ yytestcase(yyruleno==340); + case 341: /* noarg_func ::= TODAY */ yytestcase(yyruleno==341); + case 342: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==342); + case 343: /* star_func ::= COUNT */ yytestcase(yyruleno==343); + case 344: /* star_func ::= FIRST */ yytestcase(yyruleno==344); + case 345: /* star_func ::= LAST */ yytestcase(yyruleno==345); + case 346: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==346); { yylhsminor.yy57 = yymsp[0].minor.yy0; } yymsp[0].minor.yy57 = yylhsminor.yy57; break; @@ -3327,9 +3349,9 @@ static YYACTIONTYPE yy_reduce( break; case 64: /* not_exists_opt ::= */ case 66: /* exists_opt ::= */ yytestcase(yyruleno==66); - case 238: /* analyze_opt ::= */ yytestcase(yyruleno==238); - case 246: /* agg_func_opt ::= */ yytestcase(yyruleno==246); - case 397: /* set_quantifier_opt ::= */ yytestcase(yyruleno==397); + case 240: /* analyze_opt ::= */ yytestcase(yyruleno==240); + case 248: /* agg_func_opt ::= */ yytestcase(yyruleno==248); + case 400: /* set_quantifier_opt ::= */ yytestcase(yyruleno==400); { yymsp[1].minor.yy481 = false; } break; case 65: /* exists_opt ::= IF EXISTS */ @@ -3450,7 +3472,7 @@ static YYACTIONTYPE yy_reduce( yymsp[0].minor.yy600 = yylhsminor.yy600; break; case 100: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ - case 267: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==267); + case 269: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==269); { yylhsminor.yy600 = addNodeToList(pCxt, yymsp[-2].minor.yy600, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } yymsp[-2].minor.yy600 = yylhsminor.yy600; break; @@ -3468,11 +3490,11 @@ static YYACTIONTYPE yy_reduce( case 133: /* column_def_list ::= column_def */ yytestcase(yyruleno==133); case 176: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==176); case 181: /* col_name_list ::= col_name */ yytestcase(yyruleno==181); - case 226: /* func_list ::= func */ yytestcase(yyruleno==226); - case 293: /* literal_list ::= signed_literal */ yytestcase(yyruleno==293); - case 347: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==347); - case 402: /* select_sublist ::= select_item */ yytestcase(yyruleno==402); - case 455: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==455); + case 228: /* func_list ::= func */ yytestcase(yyruleno==228); + case 295: /* literal_list ::= signed_literal */ yytestcase(yyruleno==295); + case 349: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==349); + case 405: /* select_sublist ::= select_item */ yytestcase(yyruleno==405); + case 458: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==458); { yylhsminor.yy600 = createNodeList(pCxt, yymsp[0].minor.yy392); } yymsp[0].minor.yy600 = yylhsminor.yy600; break; @@ -3480,11 +3502,11 @@ static YYACTIONTYPE yy_reduce( case 134: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==134); case 177: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==177); case 182: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==182); - case 227: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==227); - case 294: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==294); - case 348: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==348); - case 403: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==403); - case 456: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==456); + case 229: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==229); + case 296: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==296); + case 350: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==350); + case 406: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==406); + case 459: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==459); { yylhsminor.yy600 = addNodeToList(pCxt, yymsp[-2].minor.yy600, yymsp[0].minor.yy392); } yymsp[-2].minor.yy600 = yylhsminor.yy600; break; @@ -3507,7 +3529,7 @@ static YYACTIONTYPE yy_reduce( break; case 111: /* cmd ::= ALTER TABLE alter_table_clause */ case 112: /* cmd ::= ALTER STABLE alter_table_clause */ yytestcase(yyruleno==112); - case 270: /* cmd ::= query_expression */ yytestcase(yyruleno==270); + case 272: /* cmd ::= query_expression */ yytestcase(yyruleno==272); { pCxt->pRootNode = yymsp[0].minor.yy392; } break; case 113: /* alter_table_clause ::= full_table_name alter_table_options */ @@ -3565,9 +3587,9 @@ static YYACTIONTYPE yy_reduce( break; case 129: /* specific_tags_opt ::= */ case 160: /* tags_def_opt ::= */ yytestcase(yyruleno==160); - case 410: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==410); - case 427: /* group_by_clause_opt ::= */ yytestcase(yyruleno==427); - case 443: /* order_by_clause_opt ::= */ yytestcase(yyruleno==443); + case 413: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==413); + case 430: /* group_by_clause_opt ::= */ yytestcase(yyruleno==430); + case 446: /* order_by_clause_opt ::= */ yytestcase(yyruleno==446); { yymsp[1].minor.yy600 = NULL; } break; case 130: /* specific_tags_opt ::= NK_LP col_name_list NK_RP */ @@ -3657,8 +3679,8 @@ static YYACTIONTYPE yy_reduce( { yymsp[-5].minor.yy448 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 161: /* tags_def_opt ::= tags_def */ - case 346: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==346); - case 401: /* select_list ::= select_sublist */ yytestcase(yyruleno==401); + case 348: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==348); + case 404: /* select_list ::= select_sublist */ yytestcase(yyruleno==404); { yylhsminor.yy600 = yymsp[0].minor.yy600; } yymsp[0].minor.yy600 = yylhsminor.yy600; break; @@ -3707,12 +3729,12 @@ static YYACTIONTYPE yy_reduce( { yymsp[-1].minor.yy221.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy221.val = yymsp[0].minor.yy0; } break; case 174: /* duration_list ::= duration_literal */ - case 320: /* expression_list ::= expression */ yytestcase(yyruleno==320); + case 322: /* expression_list ::= expression */ yytestcase(yyruleno==322); { yylhsminor.yy600 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy392)); } yymsp[0].minor.yy600 = yylhsminor.yy600; break; case 175: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 321: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==321); + case 323: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==323); { yylhsminor.yy600 = addNodeToList(pCxt, yymsp[-2].minor.yy600, releaseRawExprNode(pCxt, yymsp[0].minor.yy392)); } yymsp[-2].minor.yy600 = yylhsminor.yy600; break; @@ -3797,252 +3819,259 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT); } break; case 207: /* cmd ::= SHOW VARIABLES */ -{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLE_STMT); } +{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLES_STMT); } break; - case 208: /* cmd ::= SHOW BNODES */ + case 208: /* cmd ::= SHOW LOCAL VARIABLES */ +{ pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } + break; + case 209: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES */ +{ pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-1].minor.yy0)); } + break; + case 210: /* cmd ::= SHOW BNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } break; - case 209: /* cmd ::= SHOW SNODES */ + case 211: /* cmd ::= SHOW SNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT); } break; - case 210: /* cmd ::= SHOW CLUSTER */ + case 212: /* cmd ::= SHOW CLUSTER */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT); } break; - case 211: /* cmd ::= SHOW TRANSACTIONS */ + case 213: /* cmd ::= SHOW TRANSACTIONS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } break; - case 212: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + case 214: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ { pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy392); } break; - case 213: /* db_name_cond_opt ::= */ - case 218: /* from_db_opt ::= */ yytestcase(yyruleno==218); + case 215: /* db_name_cond_opt ::= */ + case 220: /* from_db_opt ::= */ yytestcase(yyruleno==220); { yymsp[1].minor.yy392 = createDefaultDatabaseCondValue(pCxt); } break; - case 214: /* db_name_cond_opt ::= db_name NK_DOT */ + case 216: /* db_name_cond_opt ::= db_name NK_DOT */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy57); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 215: /* like_pattern_opt ::= */ - case 223: /* index_options ::= */ yytestcase(yyruleno==223); - case 252: /* into_opt ::= */ yytestcase(yyruleno==252); - case 408: /* where_clause_opt ::= */ yytestcase(yyruleno==408); - case 412: /* twindow_clause_opt ::= */ yytestcase(yyruleno==412); - case 417: /* sliding_opt ::= */ yytestcase(yyruleno==417); - case 419: /* fill_opt ::= */ yytestcase(yyruleno==419); - case 431: /* having_clause_opt ::= */ yytestcase(yyruleno==431); - case 433: /* range_opt ::= */ yytestcase(yyruleno==433); - case 435: /* every_opt ::= */ yytestcase(yyruleno==435); - case 445: /* slimit_clause_opt ::= */ yytestcase(yyruleno==445); - case 449: /* limit_clause_opt ::= */ yytestcase(yyruleno==449); + case 217: /* like_pattern_opt ::= */ + case 225: /* index_options ::= */ yytestcase(yyruleno==225); + case 254: /* into_opt ::= */ yytestcase(yyruleno==254); + case 381: /* from_clause_opt ::= */ yytestcase(yyruleno==381); + case 411: /* where_clause_opt ::= */ yytestcase(yyruleno==411); + case 415: /* twindow_clause_opt ::= */ yytestcase(yyruleno==415); + case 420: /* sliding_opt ::= */ yytestcase(yyruleno==420); + case 422: /* fill_opt ::= */ yytestcase(yyruleno==422); + case 434: /* having_clause_opt ::= */ yytestcase(yyruleno==434); + case 436: /* range_opt ::= */ yytestcase(yyruleno==436); + case 438: /* every_opt ::= */ yytestcase(yyruleno==438); + case 448: /* slimit_clause_opt ::= */ yytestcase(yyruleno==448); + case 452: /* limit_clause_opt ::= */ yytestcase(yyruleno==452); { yymsp[1].minor.yy392 = NULL; } break; - case 216: /* like_pattern_opt ::= LIKE NK_STRING */ + case 218: /* like_pattern_opt ::= LIKE NK_STRING */ { yymsp[-1].minor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } break; - case 217: /* table_name_cond ::= table_name */ + case 219: /* table_name_cond ::= table_name */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy57); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 219: /* from_db_opt ::= FROM db_name */ + case 221: /* from_db_opt ::= FROM db_name */ { yymsp[-1].minor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy57); } break; - case 220: /* cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ + case 222: /* cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy481, &yymsp[-3].minor.yy57, &yymsp[-1].minor.yy57, NULL, yymsp[0].minor.yy392); } break; - case 221: /* cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */ + case 223: /* cmd ::= CREATE FULLTEXT INDEX not_exists_opt index_name ON table_name NK_LP col_name_list NK_RP */ { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, yymsp[-6].minor.yy481, &yymsp[-5].minor.yy57, &yymsp[-3].minor.yy57, yymsp[-1].minor.yy600, NULL); } break; - case 222: /* cmd ::= DROP INDEX exists_opt index_name ON table_name */ + case 224: /* cmd ::= DROP INDEX exists_opt index_name ON table_name */ { pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-3].minor.yy481, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy57); } break; - case 224: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ + case 226: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt */ { yymsp[-8].minor.yy392 = createIndexOption(pCxt, yymsp[-6].minor.yy600, releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), NULL, yymsp[0].minor.yy392); } break; - case 225: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ + case 227: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt */ { yymsp[-10].minor.yy392 = createIndexOption(pCxt, yymsp[-8].minor.yy600, releaseRawExprNode(pCxt, yymsp[-4].minor.yy392), releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), yymsp[0].minor.yy392); } break; - case 228: /* func ::= function_name NK_LP expression_list NK_RP */ + case 230: /* func ::= function_name NK_LP expression_list NK_RP */ { yylhsminor.yy392 = createFunctionNode(pCxt, &yymsp[-3].minor.yy57, yymsp[-1].minor.yy600); } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 229: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ + case 231: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ { pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-3].minor.yy481, &yymsp[-2].minor.yy57, yymsp[0].minor.yy392, NULL, NULL); } break; - case 230: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ + case 232: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ { pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy481, &yymsp[-3].minor.yy57, NULL, &yymsp[0].minor.yy57, NULL); } break; - case 231: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ + case 233: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ { pCxt->pRootNode = createCreateTopicStmt(pCxt, yymsp[-4].minor.yy481, &yymsp[-3].minor.yy57, NULL, NULL, yymsp[0].minor.yy392); } break; - case 232: /* cmd ::= DROP TOPIC exists_opt topic_name */ + case 234: /* cmd ::= DROP TOPIC exists_opt topic_name */ { pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy481, &yymsp[0].minor.yy57); } break; - case 233: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + case 235: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ { pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy481, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy57); } break; - case 234: /* cmd ::= DESC full_table_name */ - case 235: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==235); + case 236: /* cmd ::= DESC full_table_name */ + case 237: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==237); { pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy392); } break; - case 236: /* cmd ::= RESET QUERY CACHE */ + case 238: /* cmd ::= RESET QUERY CACHE */ { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } break; - case 237: /* cmd ::= EXPLAIN analyze_opt explain_options query_expression */ + case 239: /* cmd ::= EXPLAIN analyze_opt explain_options query_expression */ { pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy481, yymsp[-1].minor.yy392, yymsp[0].minor.yy392); } break; - case 239: /* analyze_opt ::= ANALYZE */ - case 247: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==247); - case 398: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==398); + case 241: /* analyze_opt ::= ANALYZE */ + case 249: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==249); + case 401: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==401); { yymsp[0].minor.yy481 = true; } break; - case 240: /* explain_options ::= */ + case 242: /* explain_options ::= */ { yymsp[1].minor.yy392 = createDefaultExplainOptions(pCxt); } break; - case 241: /* explain_options ::= explain_options VERBOSE NK_BOOL */ + case 243: /* explain_options ::= explain_options VERBOSE NK_BOOL */ { yylhsminor.yy392 = setExplainVerbose(pCxt, yymsp[-2].minor.yy392, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 242: /* explain_options ::= explain_options RATIO NK_FLOAT */ + case 244: /* explain_options ::= explain_options RATIO NK_FLOAT */ { yylhsminor.yy392 = setExplainRatio(pCxt, yymsp[-2].minor.yy392, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 243: /* cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ + case 245: /* cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ { pCxt->pRootNode = createCompactStmt(pCxt, yymsp[-1].minor.yy600); } break; - case 244: /* cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ + case 246: /* cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ { pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-6].minor.yy481, yymsp[-8].minor.yy481, &yymsp[-5].minor.yy57, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy448, yymsp[0].minor.yy228); } break; - case 245: /* cmd ::= DROP FUNCTION exists_opt function_name */ + case 247: /* cmd ::= DROP FUNCTION exists_opt function_name */ { pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy481, &yymsp[0].minor.yy57); } break; - case 248: /* bufsize_opt ::= */ + case 250: /* bufsize_opt ::= */ { yymsp[1].minor.yy228 = 0; } break; - case 249: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ + case 251: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ { yymsp[-1].minor.yy228 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } break; - case 250: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ + case 252: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ { pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-5].minor.yy481, &yymsp[-4].minor.yy57, yymsp[-2].minor.yy392, yymsp[-3].minor.yy392, yymsp[0].minor.yy392); } break; - case 251: /* cmd ::= DROP STREAM exists_opt stream_name */ + case 253: /* cmd ::= DROP STREAM exists_opt stream_name */ { pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy481, &yymsp[0].minor.yy57); } break; - case 253: /* into_opt ::= INTO full_table_name */ - case 379: /* from_clause ::= FROM table_reference_list */ yytestcase(yyruleno==379); - case 409: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==409); - case 432: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==432); + case 255: /* into_opt ::= INTO full_table_name */ + case 382: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==382); + case 412: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==412); + case 435: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==435); { yymsp[-1].minor.yy392 = yymsp[0].minor.yy392; } break; - case 254: /* stream_options ::= */ + case 256: /* stream_options ::= */ { yymsp[1].minor.yy392 = createStreamOptions(pCxt); } break; - case 255: /* stream_options ::= stream_options TRIGGER AT_ONCE */ + case 257: /* stream_options ::= stream_options TRIGGER AT_ONCE */ { ((SStreamOptions*)yymsp[-2].minor.yy392)->triggerType = STREAM_TRIGGER_AT_ONCE; yylhsminor.yy392 = yymsp[-2].minor.yy392; } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 256: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + case 258: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ { ((SStreamOptions*)yymsp[-2].minor.yy392)->triggerType = STREAM_TRIGGER_WINDOW_CLOSE; yylhsminor.yy392 = yymsp[-2].minor.yy392; } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 257: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + case 259: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ { ((SStreamOptions*)yymsp[-3].minor.yy392)->triggerType = STREAM_TRIGGER_MAX_DELAY; ((SStreamOptions*)yymsp[-3].minor.yy392)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy392); yylhsminor.yy392 = yymsp[-3].minor.yy392; } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 258: /* stream_options ::= stream_options WATERMARK duration_literal */ + case 260: /* stream_options ::= stream_options WATERMARK duration_literal */ { ((SStreamOptions*)yymsp[-2].minor.yy392)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy392); yylhsminor.yy392 = yymsp[-2].minor.yy392; } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 259: /* cmd ::= KILL CONNECTION NK_INTEGER */ + case 261: /* cmd ::= KILL CONNECTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } break; - case 260: /* cmd ::= KILL QUERY NK_STRING */ + case 262: /* cmd ::= KILL QUERY NK_STRING */ { pCxt->pRootNode = createKillQueryStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 261: /* cmd ::= KILL TRANSACTION NK_INTEGER */ + case 263: /* cmd ::= KILL TRANSACTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); } break; - case 262: /* cmd ::= BALANCE VGROUP */ + case 264: /* cmd ::= BALANCE VGROUP */ { pCxt->pRootNode = createBalanceVgroupStmt(pCxt); } break; - case 263: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + case 265: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } break; - case 264: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + case 266: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ { pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy600); } break; - case 265: /* cmd ::= SPLIT VGROUP NK_INTEGER */ + case 267: /* cmd ::= SPLIT VGROUP NK_INTEGER */ { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } break; - case 266: /* dnode_list ::= DNODE NK_INTEGER */ + case 268: /* dnode_list ::= DNODE NK_INTEGER */ { yymsp[-1].minor.yy600 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } break; - case 268: /* cmd ::= SYNCDB db_name REPLICA */ + case 270: /* cmd ::= SYNCDB db_name REPLICA */ { pCxt->pRootNode = createSyncdbStmt(pCxt, &yymsp[-1].minor.yy57); } break; - case 269: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ + case 271: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ { pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy392, yymsp[0].minor.yy392); } break; - case 271: /* literal ::= NK_INTEGER */ + case 273: /* literal ::= NK_INTEGER */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 272: /* literal ::= NK_FLOAT */ + case 274: /* literal ::= NK_FLOAT */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 273: /* literal ::= NK_STRING */ + case 275: /* literal ::= NK_STRING */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 274: /* literal ::= NK_BOOL */ + case 276: /* literal ::= NK_BOOL */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 275: /* literal ::= TIMESTAMP NK_STRING */ + case 277: /* literal ::= TIMESTAMP NK_STRING */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 276: /* literal ::= duration_literal */ - case 286: /* signed_literal ::= signed */ yytestcase(yyruleno==286); - case 306: /* expression ::= literal */ yytestcase(yyruleno==306); - case 307: /* expression ::= pseudo_column */ yytestcase(yyruleno==307); - case 308: /* expression ::= column_reference */ yytestcase(yyruleno==308); - case 309: /* expression ::= function_expression */ yytestcase(yyruleno==309); - case 310: /* expression ::= subquery */ yytestcase(yyruleno==310); - case 335: /* function_expression ::= literal_func */ yytestcase(yyruleno==335); - case 371: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==371); - case 375: /* boolean_primary ::= predicate */ yytestcase(yyruleno==375); - case 377: /* common_expression ::= expression */ yytestcase(yyruleno==377); - case 378: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==378); - case 380: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==380); - case 382: /* table_reference ::= table_primary */ yytestcase(yyruleno==382); - case 383: /* table_reference ::= joined_table */ yytestcase(yyruleno==383); - case 387: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==387); - case 438: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==438); - case 441: /* query_primary ::= query_specification */ yytestcase(yyruleno==441); + case 278: /* literal ::= duration_literal */ + case 288: /* signed_literal ::= signed */ yytestcase(yyruleno==288); + case 308: /* expression ::= literal */ yytestcase(yyruleno==308); + case 309: /* expression ::= pseudo_column */ yytestcase(yyruleno==309); + case 310: /* expression ::= column_reference */ yytestcase(yyruleno==310); + case 311: /* expression ::= function_expression */ yytestcase(yyruleno==311); + case 312: /* expression ::= subquery */ yytestcase(yyruleno==312); + case 337: /* function_expression ::= literal_func */ yytestcase(yyruleno==337); + case 373: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==373); + case 377: /* boolean_primary ::= predicate */ yytestcase(yyruleno==377); + case 379: /* common_expression ::= expression */ yytestcase(yyruleno==379); + case 380: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==380); + case 383: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==383); + case 385: /* table_reference ::= table_primary */ yytestcase(yyruleno==385); + case 386: /* table_reference ::= joined_table */ yytestcase(yyruleno==386); + case 390: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==390); + case 441: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==441); + case 444: /* query_primary ::= query_specification */ yytestcase(yyruleno==444); { yylhsminor.yy392 = yymsp[0].minor.yy392; } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 277: /* literal ::= NULL */ + case 279: /* literal ::= NULL */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 278: /* literal ::= NK_QUESTION */ + case 280: /* literal ::= NK_QUESTION */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 279: /* duration_literal ::= NK_VARIABLE */ + case 281: /* duration_literal ::= NK_VARIABLE */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 280: /* signed ::= NK_INTEGER */ + case 282: /* signed ::= NK_INTEGER */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 281: /* signed ::= NK_PLUS NK_INTEGER */ + case 283: /* signed ::= NK_PLUS NK_INTEGER */ { yymsp[-1].minor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } break; - case 282: /* signed ::= NK_MINUS NK_INTEGER */ + case 284: /* 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; @@ -4050,14 +4079,14 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 283: /* signed ::= NK_FLOAT */ + case 285: /* signed ::= NK_FLOAT */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 284: /* signed ::= NK_PLUS NK_FLOAT */ + case 286: /* signed ::= NK_PLUS NK_FLOAT */ { yymsp[-1].minor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } break; - case 285: /* signed ::= NK_MINUS NK_FLOAT */ + case 287: /* 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; @@ -4065,49 +4094,49 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 287: /* signed_literal ::= NK_STRING */ + case 289: /* signed_literal ::= NK_STRING */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 288: /* signed_literal ::= NK_BOOL */ + case 290: /* signed_literal ::= NK_BOOL */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 289: /* signed_literal ::= TIMESTAMP NK_STRING */ + case 291: /* signed_literal ::= TIMESTAMP NK_STRING */ { yymsp[-1].minor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; - case 290: /* signed_literal ::= duration_literal */ - case 292: /* signed_literal ::= literal_func */ yytestcase(yyruleno==292); - case 349: /* star_func_para ::= expression */ yytestcase(yyruleno==349); - case 404: /* select_item ::= common_expression */ yytestcase(yyruleno==404); - case 454: /* search_condition ::= common_expression */ yytestcase(yyruleno==454); + case 292: /* signed_literal ::= duration_literal */ + case 294: /* signed_literal ::= literal_func */ yytestcase(yyruleno==294); + case 351: /* star_func_para ::= expression */ yytestcase(yyruleno==351); + case 407: /* select_item ::= common_expression */ yytestcase(yyruleno==407); + case 457: /* search_condition ::= common_expression */ yytestcase(yyruleno==457); { yylhsminor.yy392 = releaseRawExprNode(pCxt, yymsp[0].minor.yy392); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 291: /* signed_literal ::= NULL */ + case 293: /* signed_literal ::= NULL */ { yylhsminor.yy392 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 311: /* expression ::= NK_LP expression NK_RP */ - case 376: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==376); + case 313: /* expression ::= NK_LP expression NK_RP */ + case 378: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==378); { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy392)); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 312: /* expression ::= NK_PLUS expression */ + case 314: /* expression ::= NK_PLUS expression */ { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy392)); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 313: /* expression ::= NK_MINUS expression */ + case 315: /* expression ::= NK_MINUS expression */ { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy392), NULL)); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 314: /* expression ::= expression NK_PLUS expression */ + case 316: /* expression ::= expression NK_PLUS expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4115,7 +4144,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 315: /* expression ::= expression NK_MINUS expression */ + case 317: /* expression ::= expression NK_MINUS expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4123,7 +4152,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 316: /* expression ::= expression NK_STAR expression */ + case 318: /* expression ::= expression NK_STAR expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4131,7 +4160,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 317: /* expression ::= expression NK_SLASH expression */ + case 319: /* expression ::= expression NK_SLASH expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4139,7 +4168,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 318: /* expression ::= expression NK_REM expression */ + case 320: /* expression ::= expression NK_REM expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4147,60 +4176,60 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 319: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 321: /* expression ::= column_reference NK_ARROW NK_STRING */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 322: /* column_reference ::= column_name */ + case 324: /* column_reference ::= column_name */ { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy57, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy57)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 323: /* column_reference ::= table_name NK_DOT column_name */ + case 325: /* column_reference ::= table_name NK_DOT column_name */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy57, createColumnNode(pCxt, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy57)); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 324: /* pseudo_column ::= ROWTS */ - case 325: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==325); - case 327: /* pseudo_column ::= QSTARTTS */ yytestcase(yyruleno==327); - case 328: /* pseudo_column ::= QENDTS */ yytestcase(yyruleno==328); - case 329: /* pseudo_column ::= WSTARTTS */ yytestcase(yyruleno==329); - case 330: /* pseudo_column ::= WENDTS */ yytestcase(yyruleno==330); - case 331: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==331); - case 337: /* literal_func ::= NOW */ yytestcase(yyruleno==337); + case 326: /* pseudo_column ::= ROWTS */ + case 327: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==327); + case 329: /* pseudo_column ::= QSTARTTS */ yytestcase(yyruleno==329); + case 330: /* pseudo_column ::= QENDTS */ yytestcase(yyruleno==330); + case 331: /* pseudo_column ::= WSTARTTS */ yytestcase(yyruleno==331); + case 332: /* pseudo_column ::= WENDTS */ yytestcase(yyruleno==332); + case 333: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==333); + case 339: /* literal_func ::= NOW */ yytestcase(yyruleno==339); { yylhsminor.yy392 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } yymsp[0].minor.yy392 = yylhsminor.yy392; break; - case 326: /* pseudo_column ::= table_name NK_DOT TBNAME */ + case 328: /* pseudo_column ::= table_name NK_DOT TBNAME */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy57)))); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 332: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 333: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==333); + case 334: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 335: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==335); { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy57, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy57, yymsp[-1].minor.yy600)); } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 334: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */ + case 336: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), yymsp[-1].minor.yy448)); } yymsp[-5].minor.yy392 = yylhsminor.yy392; break; - case 336: /* literal_func ::= noarg_func NK_LP NK_RP */ + case 338: /* literal_func ::= noarg_func NK_LP NK_RP */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy57, NULL)); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 345: /* star_func_para_list ::= NK_STAR */ + case 347: /* star_func_para_list ::= NK_STAR */ { yylhsminor.yy600 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } yymsp[0].minor.yy600 = yylhsminor.yy600; break; - case 350: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 407: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==407); + case 352: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 410: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==410); { yylhsminor.yy392 = createColumnNode(pCxt, &yymsp[-2].minor.yy57, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 351: /* predicate ::= expression compare_op expression */ - case 356: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==356); + case 353: /* predicate ::= expression compare_op expression */ + case 358: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==358); { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4208,7 +4237,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 352: /* predicate ::= expression BETWEEN expression AND expression */ + case 354: /* predicate ::= expression BETWEEN expression AND expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4216,7 +4245,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy392 = yylhsminor.yy392; break; - case 353: /* predicate ::= expression NOT BETWEEN expression AND expression */ + case 355: /* predicate ::= expression NOT BETWEEN expression AND expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4224,71 +4253,71 @@ static YYACTIONTYPE yy_reduce( } yymsp[-5].minor.yy392 = yylhsminor.yy392; break; - case 354: /* predicate ::= expression IS NULL */ + case 356: /* predicate ::= expression IS NULL */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), NULL)); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 355: /* predicate ::= expression IS NOT NULL */ + case 357: /* predicate ::= expression IS NOT NULL */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), NULL)); } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 357: /* compare_op ::= NK_LT */ + case 359: /* compare_op ::= NK_LT */ { yymsp[0].minor.yy324 = OP_TYPE_LOWER_THAN; } break; - case 358: /* compare_op ::= NK_GT */ + case 360: /* compare_op ::= NK_GT */ { yymsp[0].minor.yy324 = OP_TYPE_GREATER_THAN; } break; - case 359: /* compare_op ::= NK_LE */ + case 361: /* compare_op ::= NK_LE */ { yymsp[0].minor.yy324 = OP_TYPE_LOWER_EQUAL; } break; - case 360: /* compare_op ::= NK_GE */ + case 362: /* compare_op ::= NK_GE */ { yymsp[0].minor.yy324 = OP_TYPE_GREATER_EQUAL; } break; - case 361: /* compare_op ::= NK_NE */ + case 363: /* compare_op ::= NK_NE */ { yymsp[0].minor.yy324 = OP_TYPE_NOT_EQUAL; } break; - case 362: /* compare_op ::= NK_EQ */ + case 364: /* compare_op ::= NK_EQ */ { yymsp[0].minor.yy324 = OP_TYPE_EQUAL; } break; - case 363: /* compare_op ::= LIKE */ + case 365: /* compare_op ::= LIKE */ { yymsp[0].minor.yy324 = OP_TYPE_LIKE; } break; - case 364: /* compare_op ::= NOT LIKE */ + case 366: /* compare_op ::= NOT LIKE */ { yymsp[-1].minor.yy324 = OP_TYPE_NOT_LIKE; } break; - case 365: /* compare_op ::= MATCH */ + case 367: /* compare_op ::= MATCH */ { yymsp[0].minor.yy324 = OP_TYPE_MATCH; } break; - case 366: /* compare_op ::= NMATCH */ + case 368: /* compare_op ::= NMATCH */ { yymsp[0].minor.yy324 = OP_TYPE_NMATCH; } break; - case 367: /* compare_op ::= CONTAINS */ + case 369: /* compare_op ::= CONTAINS */ { yymsp[0].minor.yy324 = OP_TYPE_JSON_CONTAINS; } break; - case 368: /* in_op ::= IN */ + case 370: /* in_op ::= IN */ { yymsp[0].minor.yy324 = OP_TYPE_IN; } break; - case 369: /* in_op ::= NOT IN */ + case 371: /* in_op ::= NOT IN */ { yymsp[-1].minor.yy324 = OP_TYPE_NOT_IN; } break; - case 370: /* in_predicate_value ::= NK_LP expression_list NK_RP */ + case 372: /* in_predicate_value ::= NK_LP expression_list NK_RP */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy600)); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 372: /* boolean_value_expression ::= NOT boolean_primary */ + case 374: /* boolean_value_expression ::= NOT boolean_primary */ { SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy392), NULL)); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 373: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 375: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4296,7 +4325,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 374: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 376: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy392); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy392); @@ -4304,47 +4333,47 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 381: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ + case 384: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ { yylhsminor.yy392 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy392, yymsp[0].minor.yy392, NULL); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 384: /* table_primary ::= table_name alias_opt */ + case 387: /* table_primary ::= table_name alias_opt */ { yylhsminor.yy392 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy57, &yymsp[0].minor.yy57); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 385: /* table_primary ::= db_name NK_DOT table_name alias_opt */ + case 388: /* table_primary ::= db_name NK_DOT table_name alias_opt */ { yylhsminor.yy392 = createRealTableNode(pCxt, &yymsp[-3].minor.yy57, &yymsp[-1].minor.yy57, &yymsp[0].minor.yy57); } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 386: /* table_primary ::= subquery alias_opt */ + case 389: /* table_primary ::= subquery alias_opt */ { yylhsminor.yy392 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy392), &yymsp[0].minor.yy57); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 388: /* alias_opt ::= */ + case 391: /* alias_opt ::= */ { yymsp[1].minor.yy57 = nil_token; } break; - case 389: /* alias_opt ::= table_alias */ + case 392: /* alias_opt ::= table_alias */ { yylhsminor.yy57 = yymsp[0].minor.yy57; } yymsp[0].minor.yy57 = yylhsminor.yy57; break; - case 390: /* alias_opt ::= AS table_alias */ + case 393: /* alias_opt ::= AS table_alias */ { yymsp[-1].minor.yy57 = yymsp[0].minor.yy57; } break; - case 391: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 392: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==392); + case 394: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 395: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==395); { yymsp[-2].minor.yy392 = yymsp[-1].minor.yy392; } break; - case 393: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + case 396: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ { yylhsminor.yy392 = createJoinTableNode(pCxt, yymsp[-4].minor.yy204, yymsp[-5].minor.yy392, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); } yymsp[-5].minor.yy392 = yylhsminor.yy392; break; - case 394: /* join_type ::= */ + case 397: /* join_type ::= */ { yymsp[1].minor.yy204 = JOIN_TYPE_INNER; } break; - case 395: /* join_type ::= INNER */ + case 398: /* join_type ::= INNER */ { yymsp[0].minor.yy204 = JOIN_TYPE_INNER; } break; - case 396: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 399: /* 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.yy392 = createSelectStmt(pCxt, yymsp[-10].minor.yy481, yymsp[-9].minor.yy600, yymsp[-8].minor.yy392); yymsp[-11].minor.yy392 = addWhereClause(pCxt, yymsp[-11].minor.yy392, yymsp[-7].minor.yy392); @@ -4357,74 +4386,74 @@ static YYACTIONTYPE yy_reduce( yymsp[-11].minor.yy392 = addFillClause(pCxt, yymsp[-11].minor.yy392, yymsp[-3].minor.yy392); } break; - case 399: /* set_quantifier_opt ::= ALL */ + case 402: /* set_quantifier_opt ::= ALL */ { yymsp[0].minor.yy481 = false; } break; - case 400: /* select_list ::= NK_STAR */ + case 403: /* select_list ::= NK_STAR */ { yymsp[0].minor.yy600 = NULL; } break; - case 405: /* select_item ::= common_expression column_alias */ + case 408: /* select_item ::= common_expression column_alias */ { yylhsminor.yy392 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy392), &yymsp[0].minor.yy57); } yymsp[-1].minor.yy392 = yylhsminor.yy392; break; - case 406: /* select_item ::= common_expression AS column_alias */ + case 409: /* select_item ::= common_expression AS column_alias */ { yylhsminor.yy392 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), &yymsp[0].minor.yy57); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 411: /* partition_by_clause_opt ::= PARTITION BY expression_list */ - case 428: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==428); - case 444: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==444); + case 414: /* partition_by_clause_opt ::= PARTITION BY expression_list */ + case 431: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==431); + case 447: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==447); { yymsp[-2].minor.yy600 = yymsp[0].minor.yy600; } break; - case 413: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + case 416: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ { yymsp[-5].minor.yy392 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), releaseRawExprNode(pCxt, yymsp[-1].minor.yy392)); } break; - case 414: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ + case 417: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ { yymsp[-3].minor.yy392 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy392)); } break; - case 415: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + case 418: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ { yymsp[-5].minor.yy392 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), NULL, yymsp[-1].minor.yy392, yymsp[0].minor.yy392); } break; - case 416: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + case 419: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ { yymsp[-7].minor.yy392 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy392), releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), yymsp[-1].minor.yy392, yymsp[0].minor.yy392); } break; - case 418: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - case 436: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==436); + case 421: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + case 439: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==439); { yymsp[-3].minor.yy392 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy392); } break; - case 420: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ + case 423: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ { yymsp[-3].minor.yy392 = createFillNode(pCxt, yymsp[-1].minor.yy270, NULL); } break; - case 421: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ + case 424: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ { yymsp[-5].minor.yy392 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy600)); } break; - case 422: /* fill_mode ::= NONE */ + case 425: /* fill_mode ::= NONE */ { yymsp[0].minor.yy270 = FILL_MODE_NONE; } break; - case 423: /* fill_mode ::= PREV */ + case 426: /* fill_mode ::= PREV */ { yymsp[0].minor.yy270 = FILL_MODE_PREV; } break; - case 424: /* fill_mode ::= NULL */ + case 427: /* fill_mode ::= NULL */ { yymsp[0].minor.yy270 = FILL_MODE_NULL; } break; - case 425: /* fill_mode ::= LINEAR */ + case 428: /* fill_mode ::= LINEAR */ { yymsp[0].minor.yy270 = FILL_MODE_LINEAR; } break; - case 426: /* fill_mode ::= NEXT */ + case 429: /* fill_mode ::= NEXT */ { yymsp[0].minor.yy270 = FILL_MODE_NEXT; } break; - case 429: /* group_by_list ::= expression */ + case 432: /* group_by_list ::= expression */ { yylhsminor.yy600 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy392))); } yymsp[0].minor.yy600 = yylhsminor.yy600; break; - case 430: /* group_by_list ::= group_by_list NK_COMMA expression */ + case 433: /* group_by_list ::= group_by_list NK_COMMA expression */ { yylhsminor.yy600 = addNodeToList(pCxt, yymsp[-2].minor.yy600, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy392))); } yymsp[-2].minor.yy600 = yylhsminor.yy600; break; - case 434: /* range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ + case 437: /* range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ { yymsp[-5].minor.yy392 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy392), releaseRawExprNode(pCxt, yymsp[-1].minor.yy392)); } break; - case 437: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 440: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ { yylhsminor.yy392 = addOrderByClause(pCxt, yymsp[-3].minor.yy392, yymsp[-2].minor.yy600); yylhsminor.yy392 = addSlimitClause(pCxt, yylhsminor.yy392, yymsp[-1].minor.yy392); @@ -4432,56 +4461,56 @@ static YYACTIONTYPE yy_reduce( } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 439: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ + case 442: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ { yylhsminor.yy392 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy392, yymsp[0].minor.yy392); } yymsp[-3].minor.yy392 = yylhsminor.yy392; break; - case 440: /* query_expression_body ::= query_expression_body UNION query_expression_body */ + case 443: /* query_expression_body ::= query_expression_body UNION query_expression_body */ { yylhsminor.yy392 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 442: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ + case 445: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ { yymsp[-5].minor.yy392 = yymsp[-4].minor.yy392; } yy_destructor(yypParser,356,&yymsp[-3].minor); yy_destructor(yypParser,357,&yymsp[-2].minor); yy_destructor(yypParser,358,&yymsp[-1].minor); break; - case 446: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 450: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==450); + case 449: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 453: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==453); { yymsp[-1].minor.yy392 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } break; - case 447: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 451: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==451); + case 450: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 454: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==454); { yymsp[-3].minor.yy392 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 448: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 452: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==452); + case 451: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 455: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==455); { yymsp[-3].minor.yy392 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 453: /* subquery ::= NK_LP query_expression NK_RP */ + case 456: /* subquery ::= NK_LP query_expression NK_RP */ { yylhsminor.yy392 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy392); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 457: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ + case 460: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ { yylhsminor.yy392 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy392), yymsp[-1].minor.yy162, yymsp[0].minor.yy529); } yymsp[-2].minor.yy392 = yylhsminor.yy392; break; - case 458: /* ordering_specification_opt ::= */ + case 461: /* ordering_specification_opt ::= */ { yymsp[1].minor.yy162 = ORDER_ASC; } break; - case 459: /* ordering_specification_opt ::= ASC */ + case 462: /* ordering_specification_opt ::= ASC */ { yymsp[0].minor.yy162 = ORDER_ASC; } break; - case 460: /* ordering_specification_opt ::= DESC */ + case 463: /* ordering_specification_opt ::= DESC */ { yymsp[0].minor.yy162 = ORDER_DESC; } break; - case 461: /* null_ordering_opt ::= */ + case 464: /* null_ordering_opt ::= */ { yymsp[1].minor.yy529 = NULL_ORDER_DEFAULT; } break; - case 462: /* null_ordering_opt ::= NULLS FIRST */ + case 465: /* null_ordering_opt ::= NULLS FIRST */ { yymsp[-1].minor.yy529 = NULL_ORDER_FIRST; } break; - case 463: /* null_ordering_opt ::= NULLS LAST */ + case 466: /* null_ordering_opt ::= NULLS LAST */ { yymsp[-1].minor.yy529 = NULL_ORDER_LAST; } break; default: diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index b0c6181264..8802f91bdf 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -93,6 +93,16 @@ void generateInformationSchema(MockCatalogService* mcs) { .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); builder.done(); } + { + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "configs", TSDB_SYSTEM_TABLE, 1) + .addColumn("name", TSDB_DATA_TYPE_BINARY, TSDB_CONFIG_OPTION_LEN); + builder.done(); + } + { + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "dnode_variables", TSDB_SYSTEM_TABLE, 1) + .addColumn("dnode_id", TSDB_DATA_TYPE_INT); + builder.done(); + } } void generatePerformanceSchema(MockCatalogService* mcs) { @@ -187,6 +197,12 @@ void generateFunctions(MockCatalogService* mcs) { 8); } +void generateDnodes(MockCatalogService* mcs) { + mcs->createDnode(1, "host1", 7030); + mcs->createDnode(2, "host2", 7030); + mcs->createDnode(3, "host3", 7030); +} + } // namespace int32_t __catalogGetHandle(const char* clusterId, struct SCatalog** catalogHandle) { return 0; } @@ -241,6 +257,15 @@ int32_t __catalogGetTableIndex(SCatalog* pCtg, void* pTrans, const SEpSet* pMgmt return g_mockCatalogService->catalogGetTableIndex(pName, pRes); } +int32_t __catalogGetDnodeList(SCatalog* pCatalog, SRequestConnInfo* pConn, SArray** pDnodeList) { + return g_mockCatalogService->catalogGetDnodeList(pDnodeList); +} + +int32_t __catalogRefreshGetTableCfg(SCatalog* pCtg, SRequestConnInfo *pConn, const SName* pTableName, STableCfg** pCfg) { + *pCfg = (STableCfg*)taosMemoryCalloc(1, sizeof(STableCfg)); + return 0; +} + void initMetaDataEnv() { g_mockCatalogService.reset(new MockCatalogService()); @@ -258,6 +283,8 @@ void initMetaDataEnv() { stub.set(catalogRefreshGetTableMeta, __catalogRefreshGetTableMeta); stub.set(catalogRemoveTableMeta, __catalogRemoveTableMeta); stub.set(catalogGetTableIndex, __catalogGetTableIndex); + stub.set(catalogGetDnodeList, __catalogGetDnodeList); + stub.set(catalogRefreshGetTableCfg, __catalogRefreshGetTableCfg); // { // AddrAny any("libcatalog.so"); // std::map result; @@ -307,6 +334,7 @@ void generateMetaData() { generateTestST1(g_mockCatalogService.get()); generateTestST2(g_mockCatalogService.get()); generateFunctions(g_mockCatalogService.get()); + generateDnodes(g_mockCatalogService.get()); g_mockCatalogService->showTables(); } diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 9758da7899..1f7657146b 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -165,6 +165,14 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } + int32_t catalogGetDnodeList(SArray** pDnodes) const { + *pDnodes = taosArrayInit(dnode_.size(), sizeof(SEpSet)); + for (const auto& dnode : dnode_) { + taosArrayPush(*pDnodes, &dnode.second); + } + return TSDB_CODE_SUCCESS; + } + int32_t catalogGetAllMeta(const SCatalogReq* pCatalogReq, SMetaData* pMetaData) const { int32_t code = getAllTableMeta(pCatalogReq->pTableMeta, &pMetaData->pTableMeta); if (TSDB_CODE_SUCCESS == code) { @@ -188,6 +196,12 @@ class MockCatalogServiceImpl { if (TSDB_CODE_SUCCESS == code) { code = getAllTableIndex(pCatalogReq->pTableIndex, &pMetaData->pTableIndex); } + if (TSDB_CODE_SUCCESS == code && pCatalogReq->dNodeRequired) { + code = catalogGetDnodeList(&pMetaData->pDnodeList); + } + if (TSDB_CODE_SUCCESS == code) { + code = getAllTableCfg(pCatalogReq->pTableCfg, &pMetaData->pTableCfg); + } return code; } @@ -303,11 +317,18 @@ class MockCatalogServiceImpl { } } + void createDnode(int32_t dnodeId, const std::string& host, int16_t port) { + SEpSet epSet = {0}; + addEpIntoEpSet(&epSet, host.c_str(), port); + dnode_.insert(std::make_pair(dnodeId, epSet)); + } + private: typedef std::map> TableMetaCache; typedef std::map DbMetaCache; typedef std::map> UdfMetaCache; typedef std::map> IndexMetaCache; + typedef std::map DnodeCache; uint64_t getNextId() { return id_++; } @@ -527,11 +548,26 @@ class MockCatalogServiceImpl { return TSDB_CODE_SUCCESS; } + int32_t getAllTableCfg(SArray* pTableCfgReq, SArray** pTableCfgData) const { + if (NULL != pTableCfgReq) { + int32_t ntables = taosArrayGetSize(pTableCfgReq); + *pTableCfgData = taosArrayInit(ntables, sizeof(SMetaRes)); + for (int32_t i = 0; i < ntables; ++i) { + SMetaRes res = {0}; + res.pRes = taosMemoryCalloc(1, sizeof(STableCfg)); + res.code = TSDB_CODE_SUCCESS; + taosArrayPush(*pTableCfgData, &res); + } + } + return TSDB_CODE_SUCCESS; + } + uint64_t id_; std::unique_ptr builder_; DbMetaCache meta_; UdfMetaCache udf_; IndexMetaCache index_; + DnodeCache dnode_; }; MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) {} @@ -557,6 +593,10 @@ void MockCatalogService::createFunction(const std::string& func, int8_t funcType void MockCatalogService::createSmaIndex(const SMCreateSmaReq* pReq) { impl_->createSmaIndex(pReq); } +void MockCatalogService::createDnode(int32_t dnodeId, const std::string& host, int16_t port) { + impl_->createDnode(dnodeId, host, port); +} + int32_t MockCatalogService::catalogGetTableMeta(const SName* pTableName, STableMeta** pTableMeta) const { return impl_->catalogGetTableMeta(pTableName, pTableMeta); } @@ -581,6 +621,8 @@ int32_t MockCatalogService::catalogGetTableIndex(const SName* pTableName, SArray return impl_->catalogGetTableIndex(pTableName, pIndexes); } +int32_t MockCatalogService::catalogGetDnodeList(SArray** pDnodes) const { return impl_->catalogGetDnodeList(pDnodes); } + int32_t MockCatalogService::catalogGetAllMeta(const SCatalogReq* pCatalogReq, SMetaData* pMetaData) const { return impl_->catalogGetAllMeta(pCatalogReq, pMetaData); } diff --git a/source/libs/parser/test/mockCatalogService.h b/source/libs/parser/test/mockCatalogService.h index 1c98a7d9d5..932424823c 100644 --- a/source/libs/parser/test/mockCatalogService.h +++ b/source/libs/parser/test/mockCatalogService.h @@ -62,6 +62,7 @@ class MockCatalogService { void showTables() const; void createFunction(const std::string& func, int8_t funcType, int8_t outputType, int32_t outputLen, int32_t bufSize); void createSmaIndex(const SMCreateSmaReq* pReq); + void createDnode(int32_t dnodeId, const std::string& host, int16_t port); int32_t catalogGetTableMeta(const SName* pTableName, STableMeta** pTableMeta) const; int32_t catalogGetTableHashVgroup(const SName* pTableName, SVgroupInfo* vgInfo) const; @@ -69,6 +70,7 @@ class MockCatalogService { int32_t catalogGetDBVgInfo(const char* pDbFName, SArray** pVgList) const; int32_t catalogGetUdfInfo(const std::string& funcName, SFuncInfo* pInfo) const; int32_t catalogGetTableIndex(const SName* pTableName, SArray** pIndexes) const; + int32_t catalogGetDnodeList(SArray** pDnodes) const; int32_t catalogGetAllMeta(const SCatalogReq* pCatalogReq, SMetaData* pMetaData) const; private: diff --git a/source/libs/parser/test/parInitialDTest.cpp b/source/libs/parser/test/parInitialDTest.cpp index 4ecbb7b6d8..c2039718d0 100644 --- a/source/libs/parser/test/parInitialDTest.cpp +++ b/source/libs/parser/test/parInitialDTest.cpp @@ -159,7 +159,35 @@ TEST_F(ParserInitialDTest, dropSTable) { run("DROP STABLE st1"); } -// todo DROP stream +TEST_F(ParserInitialDTest, dropStream) { + useDb("root", "test"); + + SMDropStreamReq expect = {0}; + + auto clearDropStreamReq = [&]() { memset(&expect, 0, sizeof(SMDropStreamReq)); }; + + auto setDropStreamReq = [&](const char* pStream, int8_t igNotExists = 0) { + sprintf(expect.name, "0.%s", pStream); + expect.igNotExists = igNotExists; + }; + + setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { + ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_STREAM_STMT); + SMDropStreamReq req = {0}; + ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSMDropStreamReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req)); + + ASSERT_EQ(std::string(req.name), std::string(expect.name)); + ASSERT_EQ(req.igNotExists, expect.igNotExists); + }); + + setDropStreamReq("s1"); + run("DROP STREAM s1"); + clearDropStreamReq(); + + setDropStreamReq("s2", 1); + run("DROP STREAM IF EXISTS s2"); + clearDropStreamReq(); +} TEST_F(ParserInitialDTest, dropTable) { useDb("root", "test"); diff --git a/source/libs/parser/test/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp index 11e09cd83d..e7ab1cb61b 100644 --- a/source/libs/parser/test/parSelectTest.cpp +++ b/source/libs/parser/test/parSelectTest.cpp @@ -388,4 +388,10 @@ TEST_F(ParserSelectTest, informationSchema) { run("SELECT * FROM information_schema.user_databases WHERE name = 'information_schema'"); } +TEST_F(ParserSelectTest, withoutFrom) { + useDb("root", "test"); + + run("SELECT 1"); +} + } // namespace ParserTest diff --git a/source/libs/parser/test/parShowToUse.cpp b/source/libs/parser/test/parShowToUse.cpp index 940b6ea8ac..81a09114e3 100644 --- a/source/libs/parser/test/parShowToUse.cpp +++ b/source/libs/parser/test/parShowToUse.cpp @@ -45,7 +45,7 @@ TEST_F(ParserShowToUseTest, showCreateSTable) { ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_SHOW_CREATE_STABLE_STMT); ASSERT_EQ(pQuery->execMode, QUERY_EXEC_MODE_LOCAL); ASSERT_TRUE(pQuery->haveResultSet); - ASSERT_NE(((SShowCreateTableStmt*)pQuery->pRoot)->pMeta, nullptr); + ASSERT_NE(((SShowCreateTableStmt*)pQuery->pRoot)->pCfg, nullptr); }); run("SHOW CREATE STABLE st1"); @@ -58,7 +58,7 @@ TEST_F(ParserShowToUseTest, showCreateTable) { ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_SHOW_CREATE_TABLE_STMT); ASSERT_EQ(pQuery->execMode, QUERY_EXEC_MODE_LOCAL); ASSERT_TRUE(pQuery->haveResultSet); - ASSERT_NE(((SShowCreateTableStmt*)pQuery->pRoot)->pMeta, nullptr); + ASSERT_NE(((SShowCreateTableStmt*)pQuery->pRoot)->pCfg, nullptr); }); run("SHOW CREATE TABLE t1"); @@ -76,6 +76,12 @@ TEST_F(ParserShowToUseTest, showDnodes) { run("SHOW dnodes"); } +TEST_F(ParserShowToUseTest, showDnodeVariables) { + useDb("root", "test"); + + run("SHOW DNODE 1 VARIABLES"); +} + TEST_F(ParserShowToUseTest, showFunctions) { useDb("root", "test"); @@ -84,6 +90,12 @@ TEST_F(ParserShowToUseTest, showFunctions) { // todo SHOW licence +TEST_F(ParserShowToUseTest, showLocalVariables) { + useDb("root", "test"); + + run("SHOW LOCAL VARIABLES"); +} + TEST_F(ParserShowToUseTest, showIndexes) { useDb("root", "test"); @@ -157,7 +169,11 @@ TEST_F(ParserShowToUseTest, showUsers) { run("SHOW users"); } -// todo SHOW variables +TEST_F(ParserShowToUseTest, showVariables) { + useDb("root", "test"); + + run("SHOW VARIABLES"); +} TEST_F(ParserShowToUseTest, showVgroups) { useDb("root", "test"); diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index c7490faa0c..eafc6ba37a 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -56,8 +56,12 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { pCol->node.resType = pToBeRewrittenExpr->resType; strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName); strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName); - if (QUERY_NODE_FUNCTION == nodeType(pExpr) && FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pExpr)->funcType) { - pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID; + if (QUERY_NODE_FUNCTION == nodeType(pExpr)) { + if (FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pExpr)->funcType) { + pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID; + } else if (FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pExpr)->funcType) { + pCol->colType = COLUMN_TYPE_TBNAME; + } } nodesDestroyNode(*pNode); *pNode = (SNode*)pCol; @@ -292,6 +296,59 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect return code; } +static int32_t createColumnByLastRow(SNodeList* pFuncs, SNodeList** pOutput) { + int32_t code = TSDB_CODE_SUCCESS; + SNodeList* pCols = NULL; + SNode* pFunc = NULL; + FOREACH(pFunc, pFuncs) { + SFunctionNode* pLastRow = (SFunctionNode*)pFunc; + SColumnNode* pCol = (SColumnNode*)nodesListGetNode(pLastRow->pParameterList, 0); + snprintf(pCol->colName, sizeof(pCol->colName), "%s", pLastRow->node.aliasName); + snprintf(pCol->node.aliasName, sizeof(pCol->colName), "%s", pLastRow->node.aliasName); + NODES_CLEAR_LIST(pLastRow->pParameterList); + code = nodesListMakeStrictAppend(&pCols, (SNode*)pCol); + if (TSDB_CODE_SUCCESS != code) { + break; + } + } + if (TSDB_CODE_SUCCESS == code) { + *pOutput = pCols; + } else { + nodesDestroyList(pCols); + } + return code; +} + +static int32_t createLastRowScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable, + SLogicNode** pLogicNode) { + SScanLogicNode* pScan = NULL; + int32_t code = makeScanLogicNode(pCxt, pRealTable, false, (SLogicNode**)&pScan); + + SNodeList* pFuncs = NULL; + if (TSDB_CODE_SUCCESS == code) { + pScan->scanType = SCAN_TYPE_LAST_ROW; + code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsLastRowFunc, &pFuncs); + } + if (TSDB_CODE_SUCCESS == code) { + code = rewriteExprsForSelect(pFuncs, pSelect, SQL_CLAUSE_FROM); + } + if (TSDB_CODE_SUCCESS == code) { + code = createColumnByLastRow(pFuncs, &pScan->pScanCols); + } + if (TSDB_CODE_SUCCESS == code) { + code = createColumnByRewriteExprs(pScan->pScanCols, &pScan->node.pTargets); + } + + if (TSDB_CODE_SUCCESS == code) { + *pLogicNode = (SLogicNode*)pScan; + } else { + nodesDestroyNode((SNode*)pScan); + } + nodesDestroyList(pFuncs); + + return code; +} + static int32_t createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, STempTableNode* pTable, SLogicNode** pLogicNode) { return createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode); @@ -363,7 +420,11 @@ static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pS SLogicNode** pLogicNode) { switch (nodeType(pTable)) { case QUERY_NODE_REAL_TABLE: - return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode); + if (pSelect->hasLastRowFunc) { + return createLastRowScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode); + } else { + return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode); + } case QUERY_NODE_TEMP_TABLE: return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode); case QUERY_NODE_JOIN_TABLE: @@ -840,7 +901,12 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe return code; } -static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { +static int32_t createSelectWithoutFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, + SLogicNode** pLogicNode) { + return createProjectLogicNode(pCxt, pSelect, pLogicNode); +} + +static int32_t createSelectFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { SLogicNode* pRoot = NULL; int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot); if (TSDB_CODE_SUCCESS == code) { @@ -880,6 +946,14 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele return code; } +static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { + if (NULL == pSelect->pFromTable) { + return createSelectWithoutFromLogicNode(pCxt, pSelect, pLogicNode); + } else { + return createSelectFromLogicNode(pCxt, pSelect, pLogicNode); + } +} + static int32_t createSetOpRootLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, FCreateSetOpLogicNode func, SLogicNode** pRoot) { return createRootLogicNode(pCxt, pSetOperator, pSetOperator->precision, (FCreateLogicNode)func, pRoot); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 5ed49f6aae..3155828f32 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -293,16 +293,22 @@ static int32_t cpdCondAppend(SNode** pCond, SNode** pAdditionalCond) { return code; } -static int32_t cpdCalcTimeRange(SScanLogicNode* pScan, SNode** pPrimaryKeyCond, SNode** pOtherCond) { - bool isStrict = false; - int32_t code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict); - if (TSDB_CODE_SUCCESS == code) { - if (isStrict) { - nodesDestroyNode(*pPrimaryKeyCond); - } else { - code = cpdCondAppend(pOtherCond, pPrimaryKeyCond); +static int32_t cpdCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, SNode** pPrimaryKeyCond, + SNode** pOtherCond) { + int32_t code = TSDB_CODE_SUCCESS; + if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) { + code = cpdCondAppend(pOtherCond, pPrimaryKeyCond); + } else { + bool isStrict = false; + code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict); + if (TSDB_CODE_SUCCESS == code) { + if (isStrict) { + nodesDestroyNode(*pPrimaryKeyCond); + } else { + code = cpdCondAppend(pOtherCond, pPrimaryKeyCond); + } + *pPrimaryKeyCond = NULL; } - *pPrimaryKeyCond = NULL; } return code; } @@ -344,7 +350,7 @@ static int32_t cpdOptimizeScanCondition(SOptimizeContext* pCxt, SScanLogicNode* SNode* pOtherCond = NULL; int32_t code = nodesPartitionCond(&pScan->node.pConditions, &pPrimaryKeyCond, &pTagCond, &pOtherCond); if (TSDB_CODE_SUCCESS == code && NULL != pPrimaryKeyCond) { - code = cpdCalcTimeRange(pScan, &pPrimaryKeyCond, &pOtherCond); + code = cpdCalcTimeRange(pCxt, pScan, &pPrimaryKeyCond, &pOtherCond); } if (TSDB_CODE_SUCCESS == code && NULL != pTagCond) { code = cpdApplyTagIndex(pScan, &pTagCond, &pOtherCond); @@ -1042,7 +1048,7 @@ static int32_t smaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) static EDealRes partTagsOptHasColImpl(SNode* pNode, void* pContext) { if (QUERY_NODE_COLUMN == nodeType(pNode)) { - if (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType) { + if (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType) { *(bool*)pContext = true; return DEAL_RES_END; } @@ -1056,49 +1062,102 @@ static bool partTagsOptHasCol(SNodeList* pPartKeys) { return hasCol; } +static bool partTagsIsOptimizableNode(SLogicNode* pNode) { + return ((QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode) || + (QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode) && NULL != ((SAggLogicNode*)pNode)->pGroupKeys && + NULL != ((SAggLogicNode*)pNode)->pAggFuncs)) && + 1 == LIST_LENGTH(pNode->pChildren) && + QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(nodesListGetNode(pNode->pChildren, 0))); +} + +static SNodeList* partTagsGetPartKeys(SLogicNode* pNode) { + if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) { + return ((SPartitionLogicNode*)pNode)->pPartitionKeys; + } else { + return ((SAggLogicNode*)pNode)->pGroupKeys; + } +} + static bool partTagsOptMayBeOptimized(SLogicNode* pNode) { - if (QUERY_NODE_LOGIC_PLAN_PARTITION != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) || - QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) { + if (!partTagsIsOptimizableNode(pNode)) { return false; } - return !partTagsOptHasCol(((SPartitionLogicNode*)pNode)->pPartitionKeys); + return !partTagsOptHasCol(partTagsGetPartKeys(pNode)); +} + +static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) { + if (QUERY_NODE_COLUMN == nodeType(*pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)*pNode)->colType) { + SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); + if (NULL == pFunc) { + *(int32_t*)pContext = TSDB_CODE_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + strcpy(pFunc->functionName, "tbname"); + pFunc->funcType = FUNCTION_TYPE_TBNAME; + nodesDestroyNode(*pNode); + *pNode = (SNode*)pFunc; + return DEAL_RES_IGNORE_CHILD; + } + return DEAL_RES_CONTINUE; +} + +static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) { + int32_t code = TSDB_CODE_SUCCESS; + nodesRewriteExprs(pPartKeys, partTagsOptRebuildTbanmeImpl, &code); + return code; } static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { - SPartitionLogicNode* pPart = - (SPartitionLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized); - if (NULL == pPart) { + SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized); + if (NULL == pNode) { return TSDB_CODE_SUCCESS; } - SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pPart->node.pChildren, 0); - TSWAP(pPart->pPartitionKeys, pScan->pPartTags); - int32_t code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pPart, (SLogicNode*)pScan); + int32_t code = TSDB_CODE_SUCCESS; + SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pNode->pChildren, 0); + if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) { + TSWAP(((SPartitionLogicNode*)pNode)->pPartitionKeys, pScan->pPartTags); + int32_t code = replaceLogicNode(pLogicSubplan, pNode, (SLogicNode*)pScan); + if (TSDB_CODE_SUCCESS == code) { + NODES_CLEAR_LIST(pNode->pChildren); + nodesDestroyNode((SNode*)pNode); + } + } else { + SNode* pGroupKey = NULL; + FOREACH(pGroupKey, ((SAggLogicNode*)pNode)->pGroupKeys) { + code = nodesListMakeStrictAppend( + &pScan->pPartTags, nodesCloneNode(nodesListGetNode(((SGroupingSetNode*)pGroupKey)->pParameterList, 0))); + if (TSDB_CODE_SUCCESS != code) { + break; + } + } + NODES_DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys); + } if (TSDB_CODE_SUCCESS == code) { - NODES_CLEAR_LIST(pPart->node.pChildren); - nodesDestroyNode((SNode*)pPart); + code = partTagsOptRebuildTbanme(pScan->pPartTags); } return code; } static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) { - //TODO: enable this optimization after new mechanising that map projection and targets of project node + // TODO: enable this optimization after new mechanising that map projection and targets of project node if (NULL != pNode->pParent) { return false; } - + if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren)) { return false; } SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode; - if (-1 != pProjectNode->limit || -1 != pProjectNode->slimit || -1 != pProjectNode->offset || -1 != pProjectNode->soffset) { + if (-1 != pProjectNode->limit || -1 != pProjectNode->slimit || -1 != pProjectNode->offset || + -1 != pProjectNode->soffset) { return false; } SHashObj* pProjColNameHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); - SNode* pProjection; + SNode* pProjection; FOREACH(pProjection, pProjectNode->pProjections) { SExprNode* pExprNode = (SExprNode*)pProjection; if (QUERY_NODE_COLUMN != nodeType(pExprNode)) { @@ -1106,7 +1165,7 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) { return false; } - char* projColumnName = ((SColumnNode*)pProjection)->colName; + char* projColumnName = ((SColumnNode*)pProjection)->colName; int32_t* pExist = taosHashGet(pProjColNameHash, projColumnName, strlen(projColumnName)); if (NULL != pExist) { taosHashCleanup(pProjColNameHash); @@ -1121,9 +1180,10 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) { return true; } -static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SProjectLogicNode* pProjectNode) { +static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, + SProjectLogicNode* pProjectNode) { SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProjectNode->node.pChildren, 0); - SNodeList* pNewChildTargets = nodesMakeList(); + SNodeList* pNewChildTargets = nodesMakeList(); SNode* pProjection = NULL; FOREACH(pProjection, pProjectNode->pProjections) { @@ -1137,7 +1197,7 @@ static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* } nodesDestroyList(pChild->pTargets); pChild->pTargets = pNewChildTargets; - + int32_t code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pProjectNode, pChild); if (TSDB_CODE_SUCCESS == code) { NODES_CLEAR_LIST(pProjectNode->node.pChildren); @@ -1148,7 +1208,7 @@ static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* static int32_t eliminateProjOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { SProjectLogicNode* pProjectNode = - (SProjectLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, eliminateProjOptMayBeOptimized); + (SProjectLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, eliminateProjOptMayBeOptimized); if (NULL == pProjectNode) { return TSDB_CODE_SUCCESS; @@ -1163,7 +1223,7 @@ static const SOptimizeRule optimizeRuleSet[] = { {.pName = "ConditionPushDown", .optimizeFunc = cpdOptimize}, {.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize}, {.pName = "SmaIndex", .optimizeFunc = smaOptimize}, - {.pName = "PartitionByTags", .optimizeFunc = partTagsOptimize}, + // {.pName = "PartitionTags", .optimizeFunc = partTagsOptimize}, {.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize} }; // clang-format on diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 55d73f6c93..37765edfc5 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -462,6 +462,8 @@ static ENodeType getScanOperatorType(EScanType scanType) { return QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN; case SCAN_TYPE_BLOCK_INFO: return QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN; + case SCAN_TYPE_LAST_ROW: + return QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN; default: break; } @@ -534,7 +536,11 @@ static int32_t createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* } SQueryNodeLoad node = {.addr = {.nodeId = MNODE_HANDLE, .epSet = pCxt->pPlanCxt->mgmtEpSet}, .load = 0}; taosArrayPush(pCxt->pExecNodeList, &node); - pScan->mgmtEpSet = pCxt->pPlanCxt->mgmtEpSet; + if (0 == strcmp(pScanLogicNode->tableName.tname, TSDB_INS_TABLE_DNODE_VARIABLES)) { + pScan->mgmtEpSet = pScanLogicNode->pVgroupList->vgroups->epSet; + } else { + pScan->mgmtEpSet = pCxt->pPlanCxt->mgmtEpSet; + } tNameGetFullDbName(&pScanLogicNode->tableName, pSubplan->dbFName); return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode); @@ -555,6 +561,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, switch (pScanLogicNode->scanType) { case SCAN_TYPE_TAG: case SCAN_TYPE_BLOCK_INFO: + case SCAN_TYPE_LAST_ROW: return createSimpleScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_TABLE: return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); @@ -728,7 +735,7 @@ static int32_t rewritePrecalcExprs(SPhysiPlanContext* pCxt, SNodeList* pList, SN SRewritePrecalcExprsCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pPrecalcExprs = *pPrecalcExprs}; nodesRewriteExprs(*pRewrittenList, doRewritePrecalcExprs, &cxt); if (0 == LIST_LENGTH(cxt.pPrecalcExprs) || TSDB_CODE_SUCCESS != cxt.errCode) { - DESTORY_LIST(*pPrecalcExprs); + NODES_DESTORY_LIST(*pPrecalcExprs); } return cxt.errCode; } @@ -910,8 +917,16 @@ static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChild pProject->slimit = pProjectLogicNode->slimit; pProject->soffset = pProjectLogicNode->soffset; - int32_t code = setListSlotId(pCxt, ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc->dataBlockId, - -1, pProjectLogicNode->pProjections, &pProject->pProjections); + int32_t code = TSDB_CODE_SUCCESS; + if (0 == LIST_LENGTH(pChildren)) { + pProject->pProjections = nodesCloneList(pProjectLogicNode->pProjections); + if (NULL == pProject->pProjections) { + code = TSDB_CODE_OUT_OF_MEMORY; + } + } else { + code = setListSlotId(pCxt, ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc->dataBlockId, -1, + pProjectLogicNode->pProjections, &pProject->pProjections); + } if (TSDB_CODE_SUCCESS == code) { code = addDataBlockSlotsForProject(pCxt, pProjectLogicNode->stmtName, pProject->pProjections, pProject->node.pOutputDataBlockDesc); @@ -1034,7 +1049,7 @@ static ENodeType getIntervalOperatorType(EWindowAlgorithm windowAlgo) { case INTERVAL_ALGO_HASH: return QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL; case INTERVAL_ALGO_MERGE: - return QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL; + return QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL; case INTERVAL_ALGO_STREAM_FINAL: return QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL; case INTERVAL_ALGO_STREAM_SEMI: diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 390d665760..f0e0e84bd9 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -176,7 +176,7 @@ static bool stbSplNeedSplit(bool streamQuery, SLogicNode* pNode) { return !stbSplHasGatherExecFunc(((SAggLogicNode*)pNode)->pAggFuncs) && stbSplHasMultiTbScan(streamQuery, pNode); case QUERY_NODE_LOGIC_PLAN_WINDOW: { SWindowLogicNode* pWindow = (SWindowLogicNode*)pNode; - if (WINDOW_TYPE_STATE == pWindow->winType || (!streamQuery && WINDOW_TYPE_SESSION == pWindow->winType) ) { + if (WINDOW_TYPE_STATE == pWindow->winType || (!streamQuery && WINDOW_TYPE_SESSION == pWindow->winType)) { return false; } return !stbSplHasGatherExecFunc(pWindow->pFuncs) && stbSplHasMultiTbScan(streamQuery, pNode); @@ -380,6 +380,7 @@ static int32_t stbSplCreateExchangeNode(SSplitContext* pCxt, SLogicNode* pParent SExchangeLogicNode* pExchange = NULL; int32_t code = splCreateExchangeNode(pCxt, pPartChild, &pExchange); if (TSDB_CODE_SUCCESS == code) { + pExchange->node.pParent = pParent; code = nodesListMakeAppend(&pParent->pChildren, (SNode*)pExchange); } return code; @@ -484,7 +485,27 @@ static int32_t stbSplSplitSession(SSplitContext* pCxt, SStableSplitInfo* pInfo) } } -static int32_t stbSplSplitWindowNode(SSplitContext* pCxt, SStableSplitInfo* pInfo) { +static SNodeList* stbSplGetPartKeys(SLogicNode* pNode) { + if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { + return ((SScanLogicNode*)pNode)->pPartTags; + } else { + return NULL; + } +} + +static bool stbSplIsPartTbanme(SNodeList* pPartKeys) { + if (NULL == pPartKeys || 1 != LIST_LENGTH(pPartKeys)) { + return false; + } + SNode* pPartKey = nodesListGetNode(pPartKeys, 0); + return QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPartKey)->funcType; +} + +static bool stbSplIsMultiTableWinodw(SWindowLogicNode* pWindow) { + return stbSplIsPartTbanme(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); +} + +static int32_t stbSplSplitWindowForMergeTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) { switch (((SWindowLogicNode*)pInfo->pSplitNode)->winType) { case WINDOW_TYPE_INTERVAL: return stbSplSplitInterval(pCxt, pInfo); @@ -496,6 +517,34 @@ static int32_t stbSplSplitWindowNode(SSplitContext* pCxt, SStableSplitInfo* pInf return TSDB_CODE_PLAN_INTERNAL_ERROR; } +static int32_t stbSplSplitWindowForMultiTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) { + if (pCxt->pPlanCxt->streamQuery) { + SPLIT_FLAG_SET_MASK(pInfo->pSubplan->splitFlag, SPLIT_FLAG_STABLE_SPLIT); + return TSDB_CODE_SUCCESS; + } + + SExchangeLogicNode* pExchange = NULL; + int32_t code = splCreateExchangeNode(pCxt, pInfo->pSplitNode, &pExchange); + if (TSDB_CODE_SUCCESS == code) { + code = replaceLogicNode(pInfo->pSubplan, pInfo->pSplitNode, (SLogicNode*)pExchange); + } + if (TSDB_CODE_SUCCESS == code) { + code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren, + (SNode*)splCreateScanSubplan(pCxt, pInfo->pSplitNode, SPLIT_FLAG_STABLE_SPLIT)); + } + pInfo->pSubplan->subplanType = SUBPLAN_TYPE_MERGE; + ++(pCxt->groupId); + return code; +} + +static int32_t stbSplSplitWindowNode(SSplitContext* pCxt, SStableSplitInfo* pInfo) { + if (stbSplIsMultiTableWinodw((SWindowLogicNode*)pInfo->pSplitNode)) { + return stbSplSplitWindowForMultiTable(pCxt, pInfo); + } else { + return stbSplSplitWindowForMergeTable(pCxt, pInfo); + } +} + static int32_t stbSplCreatePartAggNode(SAggLogicNode* pMergeAgg, SLogicNode** pOutput) { SNodeList* pFunc = pMergeAgg->pAggFuncs; pMergeAgg->pAggFuncs = NULL; @@ -885,7 +934,7 @@ static int32_t unionSplitSubplan(SSplitContext* pCxt, SLogicSubplan* pUnionSubpl } if (TSDB_CODE_SUCCESS == code) { nodesDestroyList(pSubplanChildren); - DESTORY_LIST(pSplitNode->pChildren); + NODES_DESTORY_LIST(pSplitNode->pChildren); } return code; } diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index f74c7df355..790c418b17 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -83,3 +83,21 @@ TEST_F(PlanBasicTest, interpFunc) { run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)"); } + +TEST_F(PlanBasicTest, lastRowFunc) { + useDb("root", "test"); + + run("SELECT LAST_ROW(c1) FROM t1"); + + run("SELECT LAST_ROW(*) FROM t1"); + + run("SELECT LAST_ROW(c1, c2) FROM t1"); + + run("SELECT LAST_ROW(c1) FROM st1"); +} + +TEST_F(PlanBasicTest, withoutFrom) { + useDb("root", "test"); + + run("SELECT 1"); +} diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp index 6b514ef2c3..1bee43aa49 100644 --- a/source/libs/planner/test/planOptimizeTest.cpp +++ b/source/libs/planner/test/planOptimizeTest.cpp @@ -45,14 +45,21 @@ TEST_F(PlanOptimizeTest, ConditionPushDown) { TEST_F(PlanOptimizeTest, orderByPrimaryKey) { useDb("root", "test"); - run("SELECT * FROM t1 ORDER BY ts"); - run("SELECT * FROM t1 ORDER BY ts DESC"); run("SELECT c1 FROM t1 ORDER BY ts"); + run("SELECT c1 FROM t1 ORDER BY ts DESC"); run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTARTTS DESC"); } +TEST_F(PlanOptimizeTest, PartitionTags) { + useDb("root", "test"); + + run("SELECT c1 FROM st1 PARTITION BY tag1"); + + run("SELECT SUM(c1) FROM st1 GROUP BY tag1"); +} + TEST_F(PlanOptimizeTest, eliminateProjection) { useDb("root", "test"); @@ -60,5 +67,5 @@ TEST_F(PlanOptimizeTest, eliminateProjection) { run("SELECT c1 FROM t1"); run("SELECT * FROM st1"); run("SELECT c1 FROM st1s3"); - //run("select 1-abs(c1) from (select unique(c1) c1 from st1s3) order by 1 nulls first"); + // run("select 1-abs(c1) from (select unique(c1) c1 from st1s3) order by 1 nulls first"); } diff --git a/source/libs/planner/test/planOtherTest.cpp b/source/libs/planner/test/planOtherTest.cpp index 0f2540924c..b8963c29f9 100644 --- a/source/libs/planner/test/planOtherTest.cpp +++ b/source/libs/planner/test/planOtherTest.cpp @@ -37,7 +37,9 @@ TEST_F(PlanOtherTest, createStream) { TEST_F(PlanOtherTest, createStreamUseSTable) { useDb("root", "test"); - run("create stream if not exists s1 as select count(*) from st1 interval(10s)"); + run("CREATE STREAM IF NOT EXISTS s1 as SELECT COUNT(*) FROM st1 INTERVAL(10s)"); + + run("CREATE STREAM IF NOT EXISTS s1 as SELECT COUNT(*) FROM st1 PARTITION BY TBNAME INTERVAL(10s)"); } TEST_F(PlanOtherTest, createSmaIndex) { @@ -74,6 +76,8 @@ TEST_F(PlanOtherTest, show) { run("SHOW TABLE DISTRIBUTED t1"); run("SHOW TABLE DISTRIBUTED st1"); + + run("SHOW DNODE 1 VARIABLES"); } TEST_F(PlanOtherTest, delete) { diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c index 2120d24d26..c807c1c4cd 100644 --- a/source/libs/qcom/src/queryUtil.c +++ b/source/libs/qcom/src/queryUtil.c @@ -19,6 +19,7 @@ #include "tmsg.h" #include "trpc.h" #include "tsched.h" +#include "cJSON.h" #define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS) #define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS) @@ -220,3 +221,209 @@ void destroyQueryExecRes(SQueryExecRes* pRes) { qError("invalid exec result for request type %d", pRes->msgType); } } + +int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len) { + int32_t n = 0; + + switch (type) { + case TSDB_DATA_TYPE_NULL: + n = sprintf(str, "null"); + break; + + case TSDB_DATA_TYPE_BOOL: + n = sprintf(str, (*(int8_t*)buf) ? "true" : "false"); + break; + + case TSDB_DATA_TYPE_TINYINT: + n = sprintf(str, "%d", *(int8_t*)buf); + break; + + case TSDB_DATA_TYPE_SMALLINT: + n = sprintf(str, "%d", *(int16_t*)buf); + break; + + case TSDB_DATA_TYPE_INT: + n = sprintf(str, "%d", *(int32_t*)buf); + break; + + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + n = sprintf(str, "%" PRId64, *(int64_t*)buf); + break; + + case TSDB_DATA_TYPE_FLOAT: + n = sprintf(str, "%e", GET_FLOAT_VAL(buf)); + break; + + case TSDB_DATA_TYPE_DOUBLE: + n = sprintf(str, "%e", GET_DOUBLE_VAL(buf)); + break; + + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + if (bufSize < 0) { +// tscError("invalid buf size"); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + *str = '"'; + memcpy(str + 1, buf, bufSize); + *(str + bufSize + 1) = '"'; + n = bufSize + 2; + break; + + case TSDB_DATA_TYPE_UTINYINT: + n = sprintf(str, "%d", *(uint8_t*)buf); + break; + + case TSDB_DATA_TYPE_USMALLINT: + n = sprintf(str, "%d", *(uint16_t*)buf); + break; + + case TSDB_DATA_TYPE_UINT: + n = sprintf(str, "%u", *(uint32_t*)buf); + break; + + case TSDB_DATA_TYPE_UBIGINT: + n = sprintf(str, "%" PRIu64, *(uint64_t*)buf); + break; + + default: +// tscError("unsupported type:%d", type); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + *len = n; + + return TSDB_CODE_SUCCESS; +} + +char* parseTagDatatoJson(void* p) { + char* string = NULL; + cJSON* json = cJSON_CreateObject(); + if (json == NULL) { + goto end; + } + + SArray* pTagVals = NULL; + if (tTagToValArray((const STag*)p, &pTagVals) != 0) { + goto end; + } + + int16_t nCols = taosArrayGetSize(pTagVals); + char tagJsonKey[256] = {0}; + for (int j = 0; j < nCols; ++j) { + STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, j); + // json key encode by binary + memset(tagJsonKey, 0, sizeof(tagJsonKey)); + memcpy(tagJsonKey, pTagVal->pKey, strlen(pTagVal->pKey)); + // json value + char type = pTagVal->type; + if (type == TSDB_DATA_TYPE_NULL) { + cJSON* value = cJSON_CreateNull(); + if (value == NULL) { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + } else if (type == TSDB_DATA_TYPE_NCHAR) { + cJSON* value = NULL; + if (pTagVal->nData > 0) { + char* tagJsonValue = taosMemoryCalloc(pTagVal->nData, 1); + int32_t length = taosUcs4ToMbs((TdUcs4*)pTagVal->pData, pTagVal->nData, tagJsonValue); + if (length < 0) { + qError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, + pTagVal->pData); + taosMemoryFree(tagJsonValue); + goto end; + } + value = cJSON_CreateString(tagJsonValue); + taosMemoryFree(tagJsonValue); + if (value == NULL) { + goto end; + } + } else if (pTagVal->nData == 0) { + value = cJSON_CreateString(""); + } else { + ASSERT(0); + } + + cJSON_AddItemToObject(json, tagJsonKey, value); + } else if (type == TSDB_DATA_TYPE_DOUBLE) { + double jsonVd = *(double*)(&pTagVal->i64); + cJSON* value = cJSON_CreateNumber(jsonVd); + if (value == NULL) { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + } else if (type == TSDB_DATA_TYPE_BOOL) { + char jsonVd = *(char*)(&pTagVal->i64); + cJSON* value = cJSON_CreateBool(jsonVd); + if (value == NULL) { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + } else { + ASSERT(0); + } + } + string = cJSON_PrintUnformatted(json); +end: + cJSON_Delete(json); + return string; +} + + +int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) { + if (NULL == pSrc) { + *pDst = NULL; + return TSDB_CODE_SUCCESS; + } + + int32_t metaSize = (pSrc->tableInfo.numOfColumns + pSrc->tableInfo.numOfTags) * sizeof(SSchema); + *pDst = taosMemoryMalloc(metaSize); + if (NULL == *pDst) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + memcpy(*pDst, pSrc, metaSize); + return TSDB_CODE_SUCCESS; +} + +int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst) { + if (NULL == pSrc) { + *pDst = NULL; + return TSDB_CODE_SUCCESS; + } + + *pDst = taosMemoryMalloc(sizeof(*pSrc)); + if (NULL == *pDst) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + memcpy(*pDst, pSrc, sizeof(*pSrc)); + if (pSrc->vgHash) { + (*pDst)->vgHash = taosHashInit(taosHashGetSize(pSrc->vgHash), taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); + if (NULL == (*pDst)->vgHash) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SVgroupInfo* vgInfo = NULL; + void *pIter = taosHashIterate(pSrc->vgHash, NULL); + while (pIter) { + vgInfo = pIter; + int32_t* vgId = taosHashGetKey(pIter, NULL); + + if (0 != taosHashPut((*pDst)->vgHash, vgId, sizeof(*vgId), vgInfo, sizeof(*vgInfo))) { + qError("taosHashPut failed, vgId:%d", vgInfo->vgId); + taosHashCancelIterate(pSrc->vgHash, pIter); + taosHashCleanup((*pDst)->vgHash); + taosMemoryFreeClear(*pDst); + return TSDB_CODE_CTG_MEM_ERROR; + } + + pIter = taosHashIterate(pSrc->vgHash, pIter); + } + } + + return TSDB_CODE_SUCCESS; +} + + diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c index b89c220519..e2dfd9682b 100644 --- a/source/libs/qcom/src/querymsg.c +++ b/source/libs/qcom/src/querymsg.c @@ -63,7 +63,7 @@ int32_t queryBuildUseDbOutput(SUseDbOutput *pOut, SUseDbRsp *usedbRsp) { } int32_t queryBuildTableMetaReqMsg(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallcFp)(int32_t)) { - SBuildTableMetaInput *pInput = input; + SBuildTableInput *pInput = input; if (NULL == input || NULL == msg || NULL == msgLen) { return TSDB_CODE_TSC_INVALID_INPUT; } @@ -221,6 +221,27 @@ int32_t queryBuildGetTbIndexMsg(void *input, char **msg, int32_t msgSize, int32_ return TSDB_CODE_SUCCESS; } +int32_t queryBuildGetTbCfgMsg(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallcFp)(int32_t)) { + if (NULL == msg || NULL == msgLen) { + return TSDB_CODE_TSC_INVALID_INPUT; + } + + SBuildTableInput *pInput = input; + STableCfgReq cfgReq = {0}; + cfgReq.header.vgId = pInput->vgId; + strcpy(cfgReq.dbFName, pInput->dbFName); + strcpy(cfgReq.tbName, pInput->tbName); + + int32_t bufLen = tSerializeSTableCfgReq(NULL, 0, &cfgReq); + void *pBuf = (*mallcFp)(bufLen); + tSerializeSTableCfgReq(pBuf, bufLen, &cfgReq); + + *msg = pBuf; + *msgLen = bufLen; + + return TSDB_CODE_SUCCESS; +} + int32_t queryProcessUseDBRsp(void *output, char *msg, int32_t msgSize) { SUseDbOutput *pOut = output; @@ -493,6 +514,21 @@ int32_t queryProcessGetTbIndexRsp(void *output, char *msg, int32_t msgSize) { return TSDB_CODE_SUCCESS; } +int32_t queryProcessGetTbCfgRsp(void *output, char *msg, int32_t msgSize) { + if (NULL == output || NULL == msg || msgSize <= 0) { + return TSDB_CODE_TSC_INVALID_INPUT; + } + + STableCfgRsp *out = taosMemoryCalloc(1, sizeof(STableCfgRsp)); + if (tDeserializeSTableCfgRsp(msg, msgSize, out) != 0) { + qError("tDeserializeSTableCfgRsp failed, msgSize:%d", msgSize); + return TSDB_CODE_INVALID_MSG; + } + + *(STableCfgRsp**)output = out; + + return TSDB_CODE_SUCCESS; +} void initQueryModuleMsgHandle() { queryBuildMsg[TMSG_INDEX(TDMT_VND_TABLE_META)] = queryBuildTableMetaReqMsg; @@ -504,6 +540,8 @@ void initQueryModuleMsgHandle() { queryBuildMsg[TMSG_INDEX(TDMT_MND_RETRIEVE_FUNC)] = queryBuildRetrieveFuncMsg; queryBuildMsg[TMSG_INDEX(TDMT_MND_GET_USER_AUTH)] = queryBuildGetUserAuthMsg; queryBuildMsg[TMSG_INDEX(TDMT_MND_GET_TABLE_INDEX)] = queryBuildGetTbIndexMsg; + queryBuildMsg[TMSG_INDEX(TDMT_VND_TABLE_CFG)] = queryBuildGetTbCfgMsg; + queryBuildMsg[TMSG_INDEX(TDMT_MND_TABLE_CFG)] = queryBuildGetTbCfgMsg; queryProcessMsgRsp[TMSG_INDEX(TDMT_VND_TABLE_META)] = queryProcessTableMetaRsp; queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_TABLE_META)] = queryProcessTableMetaRsp; @@ -514,6 +552,8 @@ void initQueryModuleMsgHandle() { queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_RETRIEVE_FUNC)] = queryProcessRetrieveFuncRsp; queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_GET_USER_AUTH)] = queryProcessGetUserAuthRsp; queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_GET_TABLE_INDEX)] = queryProcessGetTbIndexRsp; + queryProcessMsgRsp[TMSG_INDEX(TDMT_VND_TABLE_CFG)] = queryProcessGetTbCfgRsp; + queryProcessMsgRsp[TMSG_INDEX(TDMT_MND_TABLE_CFG)] = queryProcessGetTbCfgRsp; } #pragma GCC diagnostic pop diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 1c5a12687d..d8419bdbef 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1415,11 +1415,19 @@ int32_t roundFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOut } int32_t lowerFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { +#ifdef WINDOWS + return doCaseConvFunction(pInput, inputNum, pOutput, towlower); +#else return doCaseConvFunction(pInput, inputNum, pOutput, tolower); +#endif } int32_t upperFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { +#ifdef WINDOWS + return doCaseConvFunction(pInput, inputNum, pOutput, towupper); +#else return doCaseConvFunction(pInput, inputNum, pOutput, toupper); +#endif } int32_t ltrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index 38a1ad14b1..18a6e5bf77 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -50,6 +50,10 @@ void streamCleanUp() { void streamTriggerByTimer(void* param, void* tmrId) { SStreamTask* pTask = (void*)param; + if (atomic_load_8(&pTask->taskStatus) == TASK_STATUS__DROPPING) { + return; + } + if (atomic_load_8(&pTask->triggerStatus) == TASK_TRIGGER_STATUS__ACTIVE) { SStreamTrigger* trigger = taosAllocateQitem(sizeof(SStreamTrigger), DEF_QITEM); if (trigger == NULL) return; @@ -82,8 +86,8 @@ int32_t streamSetupTrigger(SStreamTask* pTask) { } int32_t streamLaunchByWrite(SStreamTask* pTask, int32_t vgId) { - int8_t execStatus = atomic_load_8(&pTask->status); - if (execStatus == TASK_STATUS__IDLE || execStatus == TASK_STATUS__CLOSING) { + int8_t execStatus = atomic_load_8(&pTask->execStatus); + if (execStatus == TASK_EXEC_STATUS__IDLE || execStatus == TASK_EXEC_STATUS__CLOSING) { SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq)); if (pRunReq == NULL) return -1; @@ -188,6 +192,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp) { int32_t streamProcessRunReq(SStreamTask* pTask) { streamExec(pTask, pTask->pMsgCb); + if (pTask->dispatchType != TASK_DISPATCH__NONE) { streamDispatch(pTask, pTask->pMsgCb); } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 5a71fccab8..bab86223bf 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -33,6 +33,9 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) ASSERT(pTask->inputType == STREAM_INPUT__DATA_BLOCK); SArray* blocks = pBlock->blocks; qSetMultiStreamInput(exec, blocks->pData, blocks->size, STREAM_DATA_TYPE_SSDATA_BLOCK, false); + } else if (pItem->type == STREAM_INPUT__DROP) { + // TODO exec drop + return 0; } // exec @@ -58,6 +61,10 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { streamTaskExecImpl(pTask, data, pRes); + if (pTask->taskStatus == TASK_STATUS__DROPPING) { + return NULL; + } + if (taosArrayGetSize(pRes) != 0) { SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); if (qRes == NULL) { @@ -75,12 +82,17 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { return NULL; } - if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { - streamDataSubmitRefDec((SStreamDataSubmit*)data); + if (((SStreamQueueItem*)data)->type == STREAM_INPUT__TRIGGER) { + blockDataDestroy(((SStreamTrigger*)data)->pBlock); taosFreeQitem(data); } else { - taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); - taosFreeQitem(data); + if (pTask->inputType == STREAM_INPUT__DATA_SUBMIT) { + streamDataSubmitRefDec((SStreamDataSubmit*)data); + taosFreeQitem(data); + } else { + taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); + taosFreeQitem(data); + } } streamQueueProcessSuccess(pTask->inputQueue); return taosArrayInit(0, sizeof(SSDataBlock)); @@ -94,25 +106,26 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock)); if (pRes == NULL) return -1; while (1) { - int8_t execStatus = atomic_val_compare_exchange_8(&pTask->status, TASK_STATUS__IDLE, TASK_STATUS__EXECUTING); - if (execStatus == TASK_STATUS__IDLE) { + int8_t execStatus = + atomic_val_compare_exchange_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE, TASK_EXEC_STATUS__EXECUTING); + if (execStatus == TASK_EXEC_STATUS__IDLE) { // first run pRes = streamExecForQall(pTask, pRes); if (pRes == NULL) goto FAIL; // set status closing - atomic_store_8(&pTask->status, TASK_STATUS__CLOSING); + atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__CLOSING); // second run, make sure inputQ and qall are cleared pRes = streamExecForQall(pTask, pRes); if (pRes == NULL) goto FAIL; taosArrayDestroy(pRes); - atomic_store_8(&pTask->status, TASK_STATUS__IDLE); + atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); return 0; - } else if (execStatus == TASK_STATUS__CLOSING) { + } else if (execStatus == TASK_EXEC_STATUS__CLOSING) { continue; - } else if (execStatus == TASK_STATUS__EXECUTING) { + } else if (execStatus == TASK_EXEC_STATUS__EXECUTING) { ASSERT(taosArrayGetSize(pRes) == 0); taosArrayDestroy(pRes); return 0; @@ -122,7 +135,7 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { } FAIL: if (pRes) taosArrayDestroy(pRes); - atomic_store_8(&pTask->status, TASK_STATUS__IDLE); + atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); return -1; } diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c index b5a63d937a..6dfaa4cb74 100644 --- a/source/libs/stream/src/streamTask.c +++ b/source/libs/stream/src/streamTask.c @@ -23,7 +23,7 @@ SStreamTask* tNewSStreamTask(int64_t streamId) { } pTask->taskId = tGenIdPI32(); pTask->streamId = streamId; - pTask->status = TASK_STATUS__IDLE; + pTask->execStatus = TASK_EXEC_STATUS__IDLE; pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; pTask->outputStatus = TASK_OUTPUT_STATUS__NORMAL; @@ -35,7 +35,8 @@ int32_t tEncodeSStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) { if (tEncodeI64(pEncoder, pTask->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pTask->taskId) < 0) return -1; if (tEncodeI8(pEncoder, pTask->inputType) < 0) return -1; - if (tEncodeI8(pEncoder, pTask->status) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->taskStatus) < 0) return -1; + if (tEncodeI8(pEncoder, pTask->execStatus) < 0) return -1; if (tEncodeI8(pEncoder, pTask->execType) < 0) return -1; if (tEncodeI8(pEncoder, pTask->sinkType) < 0) return -1; if (tEncodeI8(pEncoder, pTask->dispatchType) < 0) return -1; @@ -83,7 +84,8 @@ int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask) { if (tDecodeI64(pDecoder, &pTask->streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pTask->taskId) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->inputType) < 0) return -1; - if (tDecodeI8(pDecoder, &pTask->status) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->taskStatus) < 0) return -1; + if (tDecodeI8(pDecoder, &pTask->execStatus) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->execType) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->sinkType) < 0) return -1; if (tDecodeI8(pDecoder, &pTask->dispatchType) < 0) return -1; diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h index 63db395425..1bd0671fb5 100644 --- a/source/libs/sync/inc/syncInt.h +++ b/source/libs/sync/inc/syncInt.h @@ -197,6 +197,7 @@ int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, S cJSON* syncNode2Json(const SSyncNode* pSyncNode); char* syncNode2Str(const SSyncNode* pSyncNode); void syncNodeEventLog(const SSyncNode* pSyncNode, char* str); +void syncNodeErrorLog(const SSyncNode* pSyncNode, char* str); char* syncNode2SimpleStr(const SSyncNode* pSyncNode); bool syncNodeInConfig(SSyncNode* pSyncNode, const SSyncCfg* config); void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* newConfig, SyncIndex lastConfigChangeIndex); @@ -253,6 +254,7 @@ void syncNodePrint(SSyncNode* pObj); void syncNodePrint2(char* s, SSyncNode* pObj); void syncNodeLog(SSyncNode* pObj); void syncNodeLog2(char* s, SSyncNode* pObj); +void syncNodeLog3(char* s, SSyncNode* pObj); #ifdef __cplusplus } diff --git a/source/libs/sync/inc/syncRaftCfg.h b/source/libs/sync/inc/syncRaftCfg.h index 7f45276e9f..efe8a65b77 100644 --- a/source/libs/sync/inc/syncRaftCfg.h +++ b/source/libs/sync/inc/syncRaftCfg.h @@ -27,7 +27,7 @@ extern "C" { #include "syncInt.h" #include "taosdef.h" -#define CONFIG_FILE_LEN 1024 +#define CONFIG_FILE_LEN 2048 #define MAX_CONFIG_INDEX_COUNT 512 @@ -49,14 +49,14 @@ int32_t raftCfgClose(SRaftCfg *pRaftCfg); int32_t raftCfgPersist(SRaftCfg *pRaftCfg); int32_t raftCfgAddConfigIndex(SRaftCfg *pRaftCfg, SyncIndex configIndex); -cJSON * syncCfg2Json(SSyncCfg *pSyncCfg); -char * syncCfg2Str(SSyncCfg *pSyncCfg); -char * syncCfg2SimpleStr(SSyncCfg *pSyncCfg); +cJSON *syncCfg2Json(SSyncCfg *pSyncCfg); +char *syncCfg2Str(SSyncCfg *pSyncCfg); +char *syncCfg2SimpleStr(SSyncCfg *pSyncCfg); int32_t syncCfgFromJson(const cJSON *pRoot, SSyncCfg *pSyncCfg); int32_t syncCfgFromStr(const char *s, SSyncCfg *pSyncCfg); -cJSON * raftCfg2Json(SRaftCfg *pRaftCfg); -char * raftCfg2Str(SRaftCfg *pRaftCfg); +cJSON *raftCfg2Json(SRaftCfg *pRaftCfg); +char *raftCfg2Str(SRaftCfg *pRaftCfg); int32_t raftCfgFromJson(const cJSON *pRoot, SRaftCfg *pRaftCfg); int32_t raftCfgFromStr(const char *s, SRaftCfg *pRaftCfg); diff --git a/source/libs/sync/inc/syncSnapshot.h b/source/libs/sync/inc/syncSnapshot.h index 069154fb93..f00dfe6f50 100644 --- a/source/libs/sync/inc/syncSnapshot.h +++ b/source/libs/sync/inc/syncSnapshot.h @@ -39,8 +39,8 @@ typedef struct SSyncSnapshotSender { bool start; int32_t seq; int32_t ack; - void *pReader; - void *pCurrentBlock; + void * pReader; + void * pCurrentBlock; int32_t blockLen; SSnapshot snapshot; SSyncCfg lastConfig; @@ -55,19 +55,19 @@ typedef struct SSyncSnapshotSender { SSyncSnapshotSender *snapshotSenderCreate(SSyncNode *pSyncNode, int32_t replicaIndex); void snapshotSenderDestroy(SSyncSnapshotSender *pSender); bool snapshotSenderIsStart(SSyncSnapshotSender *pSender); -void snapshotSenderStart(SSyncSnapshotSender *pSender); +void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader); void snapshotSenderStop(SSyncSnapshotSender *pSender); int32_t snapshotSend(SSyncSnapshotSender *pSender); int32_t snapshotReSend(SSyncSnapshotSender *pSender); -cJSON *snapshotSender2Json(SSyncSnapshotSender *pSender); -char *snapshotSender2Str(SSyncSnapshotSender *pSender); -char *snapshotSender2SimpleStr(SSyncSnapshotSender *pSender, char *event); +cJSON * snapshotSender2Json(SSyncSnapshotSender *pSender); +char * snapshotSender2Str(SSyncSnapshotSender *pSender); +char * snapshotSender2SimpleStr(SSyncSnapshotSender *pSender, char *event); typedef struct SSyncSnapshotReceiver { bool start; int32_t ack; - void *pWriter; + void * pWriter; SyncTerm term; SyncTerm privateTerm; SSnapshot snapshot; @@ -83,8 +83,8 @@ void snapshotReceiverStart(SSyncSnapshotReceiver *pReceiver, SyncTerm privateT bool snapshotReceiverIsStart(SSyncSnapshotReceiver *pReceiver); void snapshotReceiverStop(SSyncSnapshotReceiver *pReceiver, bool apply); cJSON *snapshotReceiver2Json(SSyncSnapshotReceiver *pReceiver); -char *snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver); -char *snapshotReceiver2SimpleStr(SSyncSnapshotReceiver *pReceiver, char *event); +char * snapshotReceiver2Str(SSyncSnapshotReceiver *pReceiver); +char * snapshotReceiver2SimpleStr(SSyncSnapshotReceiver *pReceiver, char *event); int32_t syncNodeOnSnapshotSendCb(SSyncNode *ths, SyncSnapshotSend *pMsg); int32_t syncNodeOnSnapshotRspCb(SSyncNode *ths, SyncSnapshotRsp *pMsg); diff --git a/source/libs/sync/src/syncAppendEntries.c b/source/libs/sync/src/syncAppendEntries.c index d2726201cc..c51cbc0513 100644 --- a/source/libs/sync/src/syncAppendEntries.c +++ b/source/libs/sync/src/syncAppendEntries.c @@ -99,19 +99,25 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { if (pMsg->term > ths->pRaftStore->currentTerm) { syncNodeUpdateTerm(ths, pMsg->term); } - assert(pMsg->term <= ths->pRaftStore->currentTerm); + ASSERT(pMsg->term <= ths->pRaftStore->currentTerm); // reset elect timer if (pMsg->term == ths->pRaftStore->currentTerm) { ths->leaderCache = pMsg->srcId; syncNodeResetElectTimer(ths); } - assert(pMsg->dataLen >= 0); + ASSERT(pMsg->dataLen >= 0); SyncTerm localPreLogTerm = 0; if (pMsg->prevLogIndex >= SYNC_INDEX_BEGIN && pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) { SSyncRaftEntry* pEntry = ths->pLogStore->getEntry(ths->pLogStore, pMsg->prevLogIndex); - assert(pEntry != NULL); + if (pEntry == NULL) { + char logBuf[128]; + snprintf(logBuf, sizeof(logBuf), "getEntry error, index:%ld, since %s", pMsg->prevLogIndex, terrstr()); + syncNodeErrorLog(ths, logBuf); + return -1; + } + localPreLogTerm = pEntry->term; syncEntryDestory(pEntry); } @@ -160,7 +166,7 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { // accept request if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) { // preIndex = -1, or has preIndex entry in local log - assert(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)); + ASSERT(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)); // has extra entries (> preIndex) in local log bool hasExtraEntries = pMsg->prevLogIndex < ths->pLogStore->getLastIndex(ths->pLogStore); @@ -179,13 +185,21 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { SyncIndex extraIndex = pMsg->prevLogIndex + 1; SSyncRaftEntry* pExtraEntry = ths->pLogStore->getEntry(ths->pLogStore, extraIndex); - assert(pExtraEntry != NULL); + if (pExtraEntry == NULL) { + char logBuf[128]; + snprintf(logBuf, sizeof(logBuf), "getEntry error2, index:%ld, since %s", extraIndex, terrstr()); + syncNodeErrorLog(ths, logBuf); + return -1; + } SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen); - assert(pAppendEntry != NULL); + if (pAppendEntry == NULL) { + syncNodeErrorLog(ths, "syncEntryDeserialize pAppendEntry error"); + return -1; + } // log not match, conflict - assert(extraIndex == pAppendEntry->index); + ASSERT(extraIndex == pAppendEntry->index); if (pExtraEntry->term != pAppendEntry->term) { conflict = true; } @@ -201,7 +215,12 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { for (SyncIndex index = delEnd; index >= delBegin; --index) { if (ths->pFsm->FpRollBackCb != NULL) { SSyncRaftEntry* pRollBackEntry = ths->pLogStore->getEntry(ths->pLogStore, index); - assert(pRollBackEntry != NULL); + if (pRollBackEntry == NULL) { + char logBuf[128]; + snprintf(logBuf, sizeof(logBuf), "getEntry error3, index:%ld, since %s", index, terrstr()); + syncNodeErrorLog(ths, logBuf); + return -1; + } // if (pRollBackEntry->msgType != TDMT_SYNC_NOOP) { if (syncUtilUserRollback(pRollBackEntry->msgType)) { @@ -257,7 +276,10 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { } else if (!hasExtraEntries && hasAppendEntries) { SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen); - assert(pAppendEntry != NULL); + if (pAppendEntry == NULL) { + syncNodeErrorLog(ths, "syncEntryDeserialize pAppendEntry2 error"); + return -1; + } // append new entries ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry); @@ -287,7 +309,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) { // do nothing } else { - assert(0); + syncNodeLog3("", ths); + ASSERT(0); } SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId); diff --git a/source/libs/sync/src/syncAppendEntriesReply.c b/source/libs/sync/src/syncAppendEntriesReply.c index 47fd23baae..f13a3604da 100644 --- a/source/libs/sync/src/syncAppendEntriesReply.c +++ b/source/libs/sync/src/syncAppendEntriesReply.c @@ -67,7 +67,7 @@ int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* p return ret; } - assert(pMsg->term == ths->pRaftStore->currentTerm); + ASSERT(pMsg->term == ths->pRaftStore->currentTerm); if (pMsg->success) { // nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1] @@ -173,21 +173,44 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries // get sender SSyncSnapshotSender* pSender = syncNodeGetSnapshotSender(ths, &(pMsg->srcId)); ASSERT(pSender != NULL); - bool hasSnapshot = syncNodeHasSnapshot(ths); - SSnapshot snapshot; - ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot); - // start sending snapshot first time - // start here, stop by receiver - if (hasSnapshot && nextIndex <= snapshot.lastApplyIndex + 1 && !snapshotSenderIsStart(pSender) && - pMsg->privateTerm < pSender->privateTerm) { - snapshotSenderStart(pSender); + SSnapshot snapshot; + void* pReader = NULL; + ths->pFsm->FpGetSnapshot(ths->pFsm, &snapshot, NULL, &pReader); + if (snapshot.lastApplyIndex >= SYNC_INDEX_BEGIN && nextIndex <= snapshot.lastApplyIndex + 1 && + !snapshotSenderIsStart(pSender) && pMsg->privateTerm < pSender->privateTerm) { + // has snapshot + ASSERT(pReader != NULL); + snapshotSenderStart(pSender, snapshot, pReader); char* eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender start"); syncNodeEventLog(ths, eventLog); taosMemoryFree(eventLog); + + } else { + // no snapshot + if (pReader != NULL) { + ths->pFsm->FpSnapshotStopRead(ths->pFsm, pReader); + } } + /* + bool hasSnapshot = syncNodeHasSnapshot(ths); + SSnapshot snapshot; + ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot); + + // start sending snapshot first time + // start here, stop by receiver + if (hasSnapshot && nextIndex <= snapshot.lastApplyIndex + 1 && !snapshotSenderIsStart(pSender) && + pMsg->privateTerm < pSender->privateTerm) { + snapshotSenderStart(pSender); + + char* eventLog = snapshotSender2SimpleStr(pSender, "snapshot sender start"); + syncNodeEventLog(ths, eventLog); + taosMemoryFree(eventLog); + } + */ + SyncIndex sentryIndex = pSender->snapshot.lastApplyIndex + 1; // update nextIndex to sentryIndex @@ -207,12 +230,6 @@ int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntries syncIndexMgrLog2("recv SyncAppendEntriesReply, after pNextIndex:", ths->pNextIndex); syncIndexMgrLog2("recv SyncAppendEntriesReply, after pMatchIndex:", ths->pMatchIndex); - if (gRaftDetailLog) { - SSnapshot snapshot; - ths->pFsm->FpGetSnapshotInfo(ths->pFsm, &snapshot); - sTrace("recv SyncAppendEntriesReply, after snapshot.lastApplyIndex:%ld, snapshot.lastApplyTerm:%lu", - snapshot.lastApplyIndex, snapshot.lastApplyTerm); - } return ret; } \ No newline at end of file diff --git a/source/libs/sync/src/syncCommit.c b/source/libs/sync/src/syncCommit.c index ec3e1ab2ba..c92edae381 100644 --- a/source/libs/sync/src/syncCommit.c +++ b/source/libs/sync/src/syncCommit.c @@ -75,7 +75,7 @@ void syncMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) { if (agree) { // term SSyncRaftEntry* pEntry = pSyncNode->pLogStore->getEntry(pSyncNode->pLogStore, index); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); // cannot commit, even if quorum agree. need check term! if (pEntry->term == pSyncNode->pRaftStore->currentTerm) { diff --git a/source/libs/sync/src/syncElection.c b/source/libs/sync/src/syncElection.c index fdebbe3990..e0f2b0fed2 100644 --- a/source/libs/sync/src/syncElection.c +++ b/source/libs/sync/src/syncElection.c @@ -32,7 +32,7 @@ // /\ UNCHANGED <> // int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); int32_t ret = 0; for (int i = 0; i < pSyncNode->peersNum; ++i) { @@ -44,7 +44,7 @@ int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) { pMsg->lastLogTerm = pSyncNode->pLogStore->getLastTerm(pSyncNode->pLogStore); ret = syncNodeRequestVote(pSyncNode, &pSyncNode->peersId[i], pMsg); - assert(ret == 0); + ASSERT(ret == 0); syncRequestVoteDestroy(pMsg); } return ret; @@ -75,7 +75,7 @@ int32_t syncNodeElect(SSyncNode* pSyncNode) { if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) { syncNodeFollower2Candidate(pSyncNode); } - assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); // start election raftStoreNextTerm(pSyncNode->pRaftStore); @@ -86,7 +86,7 @@ int32_t syncNodeElect(SSyncNode* pSyncNode) { syncNodeVoteForSelf(pSyncNode); if (voteGrantedMajority(pSyncNode->pVotesGranted)) { // only myself, to leader - assert(!pSyncNode->pVotesGranted->toLeader); + ASSERT(!pSyncNode->pVotesGranted->toLeader); syncNodeCandidate2Leader(pSyncNode); pSyncNode->pVotesGranted->toLeader = true; return ret; @@ -98,7 +98,7 @@ int32_t syncNodeElect(SSyncNode* pSyncNode) { ret = syncNodeRequestVotePeers(pSyncNode); } - assert(ret == 0); + ASSERT(ret == 0); syncNodeResetElectTimer(pSyncNode); return ret; diff --git a/source/libs/sync/src/syncEnv.c b/source/libs/sync/src/syncEnv.c index e67439f8fe..fb0bfb8bef 100644 --- a/source/libs/sync/src/syncEnv.c +++ b/source/libs/sync/src/syncEnv.c @@ -14,7 +14,7 @@ */ #include "syncEnv.h" -// #include +// #include SSyncEnv *gSyncEnv = NULL; @@ -35,11 +35,12 @@ bool syncEnvIsStart() { } int32_t syncEnvStart() { - int32_t ret = 0; - taosSeedRand(taosGetTimestampSec()); + int32_t ret = 0; + uint32_t seed = (uint32_t)(taosGetTimestampNs() & 0x00000000FFFFFFFF); + taosSeedRand(seed); // gSyncEnv = doSyncEnvStart(gSyncEnv); gSyncEnv = doSyncEnvStart(); - assert(gSyncEnv != NULL); + ASSERT(gSyncEnv != NULL); sTrace("sync env start ok"); return ret; } @@ -85,7 +86,7 @@ static void syncEnvTick(void *param, void *tmrId) { static SSyncEnv *doSyncEnvStart() { SSyncEnv *pSyncEnv = (SSyncEnv *)taosMemoryMalloc(sizeof(SSyncEnv)); - assert(pSyncEnv != NULL); + ASSERT(pSyncEnv != NULL); memset(pSyncEnv, 0, sizeof(SSyncEnv)); pSyncEnv->envTickTimerCounter = 0; @@ -102,7 +103,7 @@ static SSyncEnv *doSyncEnvStart() { } static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) { - assert(pSyncEnv == gSyncEnv); + ASSERT(pSyncEnv == gSyncEnv); if (pSyncEnv != NULL) { atomic_store_8(&(pSyncEnv->isStart), 0); taosTmrCleanUp(pSyncEnv->pTimerManager); diff --git a/source/libs/sync/src/syncIO.c b/source/libs/sync/src/syncIO.c index 0b5a9685c0..038c36c417 100644 --- a/source/libs/sync/src/syncIO.c +++ b/source/libs/sync/src/syncIO.c @@ -30,7 +30,7 @@ static int32_t syncIODestroy(SSyncIO *io); static int32_t syncIOStartInternal(SSyncIO *io); static int32_t syncIOStopInternal(SSyncIO *io); -static void * syncIOConsumerFunc(void *param); +static void *syncIOConsumerFunc(void *param); static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet); static int32_t syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey); @@ -47,11 +47,11 @@ static void syncIOTickPing(void *param, void *tmrId); int32_t syncIOStart(char *host, uint16_t port) { int32_t ret = 0; gSyncIO = syncIOCreate(host, port); - assert(gSyncIO != NULL); + ASSERT(gSyncIO != NULL); taosSeedRand(taosGetTimestampSec()); ret = syncIOStartInternal(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); sTrace("syncIOStart ok, gSyncIO:%p", gSyncIO); return ret; @@ -59,16 +59,16 @@ int32_t syncIOStart(char *host, uint16_t port) { int32_t syncIOStop() { int32_t ret = syncIOStopInternal(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); ret = syncIODestroy(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); return ret; } int32_t syncIOSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) { - assert(pEpSet->inUse == 0); - assert(pEpSet->numOfEps == 1); + ASSERT(pEpSet->inUse == 0); + ASSERT(pEpSet->numOfEps == 1); int32_t ret = 0; { @@ -107,25 +107,25 @@ int32_t syncIOEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) { int32_t syncIOQTimerStart() { int32_t ret = syncIOStartQ(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); return ret; } int32_t syncIOQTimerStop() { int32_t ret = syncIOStopQ(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); return ret; } int32_t syncIOPingTimerStart() { int32_t ret = syncIOStartPing(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); return ret; } int32_t syncIOPingTimerStop() { int32_t ret = syncIOStopPing(gSyncIO); - assert(ret == 0); + ASSERT(ret == 0); return ret; } @@ -151,7 +151,7 @@ static SSyncIO *syncIOCreate(char *host, uint16_t port) { static int32_t syncIODestroy(SSyncIO *io) { int32_t ret = 0; int8_t start = atomic_load_8(&io->isStart); - assert(start == 0); + ASSERT(start == 0); if (io->serverRpc != NULL) { rpcClose(io->serverRpc); @@ -242,9 +242,9 @@ static int32_t syncIOStopInternal(SSyncIO *io) { } static void *syncIOConsumerFunc(void *param) { - SSyncIO * io = param; + SSyncIO *io = param; STaosQall *qall; - SRpcMsg * pRpcMsg, rpcMsg; + SRpcMsg *pRpcMsg, rpcMsg; qall = taosAllocateQall(); while (1) { @@ -264,7 +264,7 @@ static void *syncIOConsumerFunc(void *param) { if (pRpcMsg->msgType == TDMT_SYNC_PING) { if (io->FpOnSyncPing != NULL) { SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncPing(io->pSyncNode, pSyncMsg); syncPingDestroy(pSyncMsg); } @@ -272,7 +272,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_PING_REPLY) { if (io->FpOnSyncPingReply != NULL) { SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncPingReply(io->pSyncNode, pSyncMsg); syncPingReplyDestroy(pSyncMsg); } @@ -280,7 +280,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_CLIENT_REQUEST) { if (io->FpOnSyncClientRequest != NULL) { SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncClientRequest(io->pSyncNode, pSyncMsg); syncClientRequestDestroy(pSyncMsg); } @@ -288,7 +288,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE) { if (io->FpOnSyncRequestVote != NULL) { SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncRequestVote(io->pSyncNode, pSyncMsg); syncRequestVoteDestroy(pSyncMsg); } @@ -296,7 +296,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_REQUEST_VOTE_REPLY) { if (io->FpOnSyncRequestVoteReply != NULL) { SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncRequestVoteReply(io->pSyncNode, pSyncMsg); syncRequestVoteReplyDestroy(pSyncMsg); } @@ -304,7 +304,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES) { if (io->FpOnSyncAppendEntries != NULL) { SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncAppendEntries(io->pSyncNode, pSyncMsg); syncAppendEntriesDestroy(pSyncMsg); } @@ -312,7 +312,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_APPEND_ENTRIES_REPLY) { if (io->FpOnSyncAppendEntriesReply != NULL) { SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncAppendEntriesReply(io->pSyncNode, pSyncMsg); syncAppendEntriesReplyDestroy(pSyncMsg); } @@ -320,7 +320,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_TIMEOUT) { if (io->FpOnSyncTimeout != NULL) { SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncTimeout(io->pSyncNode, pSyncMsg); syncTimeoutDestroy(pSyncMsg); } @@ -328,7 +328,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_SNAPSHOT_SEND) { if (io->FpOnSyncSnapshotSend != NULL) { SyncSnapshotSend *pSyncMsg = syncSnapshotSendFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncSnapshotSend(io->pSyncNode, pSyncMsg); syncSnapshotSendDestroy(pSyncMsg); } @@ -336,7 +336,7 @@ static void *syncIOConsumerFunc(void *param) { } else if (pRpcMsg->msgType == TDMT_SYNC_SNAPSHOT_RSP) { if (io->FpOnSyncSnapshotRsp != NULL) { SyncSnapshotRsp *pSyncMsg = syncSnapshotRspFromRpcMsg2(pRpcMsg); - assert(pSyncMsg != NULL); + ASSERT(pSyncMsg != NULL); io->FpOnSyncSnapshotRsp(io->pSyncNode, pSyncMsg); syncSnapshotRspDestroy(pSyncMsg); } diff --git a/source/libs/sync/src/syncIndexMgr.c b/source/libs/sync/src/syncIndexMgr.c index 18cb55b417..5b432aeec4 100644 --- a/source/libs/sync/src/syncIndexMgr.c +++ b/source/libs/sync/src/syncIndexMgr.c @@ -20,7 +20,7 @@ SSyncIndexMgr *syncIndexMgrCreate(SSyncNode *pSyncNode) { SSyncIndexMgr *pSyncIndexMgr = taosMemoryMalloc(sizeof(SSyncIndexMgr)); - assert(pSyncIndexMgr != NULL); + ASSERT(pSyncIndexMgr != NULL); memset(pSyncIndexMgr, 0, sizeof(SSyncIndexMgr)); pSyncIndexMgr->replicas = &(pSyncNode->replicasId); @@ -63,7 +63,12 @@ void syncIndexMgrSetIndex(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaftId, } // maybe config change - assert(0); + // ASSERT(0); + + char host[128]; + uint16_t port; + syncUtilU642Addr(pRaftId->addr, host, sizeof(host), &port); + sError("vgId:%d index mgr set for %s:%d, index:%" PRId64 " error", pSyncIndexMgr->pSyncNode->vgId, host, port, index); } SyncIndex syncIndexMgrGetIndex(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaftId) { @@ -73,7 +78,9 @@ SyncIndex syncIndexMgrGetIndex(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaf return idx; } } - assert(0); + + syncNodeLog3("syncIndexMgrGetIndex", pSyncIndexMgr->pSyncNode); + ASSERT(0); } cJSON *syncIndexMgr2Json(SSyncIndexMgr *pSyncIndexMgr) { @@ -119,7 +126,7 @@ cJSON *syncIndexMgr2Json(SSyncIndexMgr *pSyncIndexMgr) { char *syncIndexMgr2Str(SSyncIndexMgr *pSyncIndexMgr) { cJSON *pJson = syncIndexMgr2Json(pSyncIndexMgr); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } @@ -162,7 +169,11 @@ void syncIndexMgrSetTerm(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaftId, S } // maybe config change - assert(0); + // ASSERT(0); + char host[128]; + uint16_t port; + syncUtilU642Addr(pRaftId->addr, host, sizeof(host), &port); + sError("vgId:%d index mgr set for %s:%d, term:%lu error", pSyncIndexMgr->pSyncNode->vgId, host, port, term); } SyncTerm syncIndexMgrGetTerm(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaftId) { @@ -172,5 +183,5 @@ SyncTerm syncIndexMgrGetTerm(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRaftI return term; } } - assert(0); + ASSERT(0); } \ No newline at end of file diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index 33e7a8241f..da6d869611 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -75,7 +75,7 @@ int32_t syncInit() { void syncCleanUp() { int32_t ret = syncEnvStop(); - assert(ret == 0); + ASSERT(ret == 0); if (tsNodeRefId != -1) { taosCloseRef(tsNodeRefId); @@ -85,7 +85,7 @@ void syncCleanUp() { int64_t syncOpen(const SSyncInfo* pSyncInfo) { SSyncNode* pSyncNode = syncNodeOpen(pSyncInfo); - assert(pSyncNode != NULL); + ASSERT(pSyncNode != NULL); if (gRaftDetailLog) { syncNodeLog2("syncNodeOpen open success", pSyncNode); @@ -156,8 +156,12 @@ int32_t syncSetStandby(int64_t rid) { if (pSyncNode->state != TAOS_SYNC_STATE_FOLLOWER) { taosReleaseRef(tsNodeRefId, pSyncNode->rid); - terrno = TSDB_CODE_SYN_IS_LEADER; - sError("failed to set standby since it is not follower, rid:%" PRId64, rid); + if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) { + terrno = TSDB_CODE_SYN_IS_LEADER; + } else { + terrno = TSDB_CODE_SYN_STANDBY_NOT_READY; + } + sError("failed to set standby since it is not follower, state:%s rid:%" PRId64, syncStr(pSyncNode->state), rid); return -1; } @@ -314,7 +318,7 @@ bool syncCanLeaderTransfer(int64_t rid) { if (pSyncNode == NULL) { return false; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); if (pSyncNode->replicaNum == 1) { taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -351,7 +355,7 @@ ESyncState syncGetMyRole(int64_t rid) { if (pSyncNode == NULL) { return TAOS_SYNC_STATE_ERROR; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); ESyncState state = pSyncNode->state; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -363,7 +367,7 @@ bool syncIsReady(int64_t rid) { if (pSyncNode == NULL) { return false; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); bool b = (pSyncNode->state == TAOS_SYNC_STATE_LEADER) && pSyncNode->restoreFinish; taosReleaseRef(tsNodeRefId, pSyncNode->rid); return b; @@ -374,7 +378,7 @@ bool syncIsRestoreFinish(int64_t rid) { if (pSyncNode == NULL) { return false; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); bool b = pSyncNode->restoreFinish; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -386,7 +390,7 @@ int32_t syncGetSnapshotMeta(int64_t rid, struct SSnapshotMeta* sMeta) { if (pSyncNode == NULL) { return -1; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); sMeta->lastConfigIndex = pSyncNode->pRaftCfg->lastConfigIndex; sTrace("vgId:%d, get snapshot meta, lastConfigIndex:%" PRId64, pSyncNode->vgId, pSyncNode->pRaftCfg->lastConfigIndex); @@ -400,7 +404,7 @@ int32_t syncGetSnapshotMetaByIndex(int64_t rid, SyncIndex snapshotIndex, struct if (pSyncNode == NULL) { return -1; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); ASSERT(pSyncNode->pRaftCfg->configIndexCount >= 1); SyncIndex lastIndex = (pSyncNode->pRaftCfg->configIndexArr)[0]; @@ -444,7 +448,7 @@ SyncTerm syncGetMyTerm(int64_t rid) { if (pSyncNode == NULL) { return TAOS_SYNC_STATE_ERROR; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); SyncTerm term = pSyncNode->pRaftStore->currentTerm; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -456,7 +460,7 @@ SyncGroupId syncGetVgId(int64_t rid) { if (pSyncNode == NULL) { return TAOS_SYNC_STATE_ERROR; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); SyncGroupId vgId = pSyncNode->vgId; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -469,7 +473,7 @@ void syncGetEpSet(int64_t rid, SEpSet* pEpSet) { memset(pEpSet, 0, sizeof(*pEpSet)); return; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); pEpSet->numOfEps = 0; for (int i = 0; i < pSyncNode->pRaftCfg->cfg.replicaNum; ++i) { snprintf(pEpSet->eps[i].fqdn, sizeof(pEpSet->eps[i].fqdn), "%s", (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodeFqdn); @@ -490,7 +494,7 @@ int32_t syncGetRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg) { if (pSyncNode == NULL) { return TAOS_SYNC_STATE_ERROR; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); SRespStub stub; int32_t ret = syncRespMgrGet(pSyncNode->pSyncRespMgr, index, &stub); @@ -507,7 +511,7 @@ int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcHandleInfo* pInfo) if (pSyncNode == NULL) { return TAOS_SYNC_STATE_ERROR; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); SRespStub stub; int32_t ret = syncRespMgrGetAndDel(pSyncNode->pSyncRespMgr, index, &stub); @@ -526,7 +530,7 @@ void syncSetMsgCb(int64_t rid, const SMsgCb* msgcb) { sTrace("syncSetQ get pSyncNode is NULL, rid:%ld", rid); return; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); pSyncNode->msgcb = msgcb; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -538,7 +542,7 @@ char* sync2SimpleStr(int64_t rid) { sTrace("syncSetRpc get pSyncNode is NULL, rid:%ld", rid); return NULL; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); char* s = syncNode2SimpleStr(pSyncNode); taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -550,7 +554,7 @@ void setPingTimerMS(int64_t rid, int32_t pingTimerMS) { if (pSyncNode == NULL) { return; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); pSyncNode->pingBaseLine = pingTimerMS; pSyncNode->pingTimerMS = pingTimerMS; @@ -562,7 +566,7 @@ void setElectTimerMS(int64_t rid, int32_t electTimerMS) { if (pSyncNode == NULL) { return; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); pSyncNode->electBaseLine = electTimerMS; taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -573,7 +577,7 @@ void setHeartbeatTimerMS(int64_t rid, int32_t hbTimerMS) { if (pSyncNode == NULL) { return; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); pSyncNode->hbBaseLine = hbTimerMS; pSyncNode->heartbeatTimerMS = hbTimerMS; @@ -588,7 +592,7 @@ int32_t syncPropose(int64_t rid, const SRpcMsg* pMsg, bool isWeak) { terrno = TSDB_CODE_SYN_INTERNAL_ERROR; return -1; } - assert(rid == pSyncNode->rid); + ASSERT(rid == pSyncNode->rid); ret = syncNodePropose(pSyncNode, pMsg, isWeak); taosReleaseRef(tsNodeRefId, pSyncNode->rid); @@ -658,7 +662,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { SSyncInfo* pSyncInfo = (SSyncInfo*)pOldSyncInfo; SSyncNode* pSyncNode = (SSyncNode*)taosMemoryMalloc(sizeof(SSyncNode)); - assert(pSyncNode != NULL); + ASSERT(pSyncNode != NULL); memset(pSyncNode, 0, sizeof(SSyncNode)); int32_t ret = 0; @@ -678,12 +682,12 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { meta.snapshotEnable = pSyncInfo->snapshotEnable; meta.lastConfigIndex = SYNC_INDEX_INVALID; ret = raftCfgCreateFile((SSyncCfg*)&(pSyncInfo->syncCfg), meta, pSyncNode->configPath); - assert(ret == 0); + ASSERT(ret == 0); } else { // update syncCfg by raft_config.json pSyncNode->pRaftCfg = raftCfgOpen(pSyncNode->configPath); - assert(pSyncNode->pRaftCfg != NULL); + ASSERT(pSyncNode->pRaftCfg != NULL); pSyncInfo->syncCfg = pSyncNode->pRaftCfg->cfg; if (gRaftDetailLog) { @@ -708,7 +712,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { // init raft config pSyncNode->pRaftCfg = raftCfgOpen(pSyncNode->configPath); - assert(pSyncNode->pRaftCfg != NULL); + ASSERT(pSyncNode->pRaftCfg != NULL); // init internal pSyncNode->myNodeInfo = pSyncNode->pRaftCfg->cfg.nodeInfo[pSyncNode->pRaftCfg->cfg.myIndex]; @@ -767,23 +771,23 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { // init TLA+ server vars pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER; pSyncNode->pRaftStore = raftStoreOpen(pSyncNode->raftStorePath); - assert(pSyncNode->pRaftStore != NULL); + ASSERT(pSyncNode->pRaftStore != NULL); // init TLA+ candidate vars pSyncNode->pVotesGranted = voteGrantedCreate(pSyncNode); - assert(pSyncNode->pVotesGranted != NULL); + ASSERT(pSyncNode->pVotesGranted != NULL); pSyncNode->pVotesRespond = votesRespondCreate(pSyncNode); - assert(pSyncNode->pVotesRespond != NULL); + ASSERT(pSyncNode->pVotesRespond != NULL); // init TLA+ leader vars pSyncNode->pNextIndex = syncIndexMgrCreate(pSyncNode); - assert(pSyncNode->pNextIndex != NULL); + ASSERT(pSyncNode->pNextIndex != NULL); pSyncNode->pMatchIndex = syncIndexMgrCreate(pSyncNode); - assert(pSyncNode->pMatchIndex != NULL); + ASSERT(pSyncNode->pMatchIndex != NULL); // init TLA+ log vars pSyncNode->pLogStore = logStoreCreate(pSyncNode); - assert(pSyncNode->pLogStore != NULL); + ASSERT(pSyncNode->pLogStore != NULL); pSyncNode->commitIndex = SYNC_INDEX_INVALID; // timer ms init @@ -841,7 +845,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { // tools pSyncNode->pSyncRespMgr = syncRespMgrCreate(pSyncNode, 0); - assert(pSyncNode->pSyncRespMgr != NULL); + ASSERT(pSyncNode->pSyncRespMgr != NULL); // restore state pSyncNode->restoreFinish = false; @@ -889,7 +893,7 @@ void syncNodeStart(SSyncNode* pSyncNode) { // int32_t ret = 0; // ret = syncNodeStartPingTimer(pSyncNode); - // assert(ret == 0); + // ASSERT(ret == 0); if (gRaftDetailLog) { syncNodeLog2("==state change become leader immediately==", pSyncNode); @@ -911,10 +915,10 @@ void syncNodeClose(SSyncNode* pSyncNode) { syncNodeEventLog(pSyncNode, "sync close"); int32_t ret; - assert(pSyncNode != NULL); + ASSERT(pSyncNode != NULL); ret = raftStoreClose(pSyncNode->pRaftStore); - assert(ret == 0); + ASSERT(ret == 0); syncRespMgrDestroy(pSyncNode->pSyncRespMgr); voteGrantedDestroy(pSyncNode->pVotesGranted); @@ -976,7 +980,7 @@ int32_t syncNodePingSelf(SSyncNode* pSyncNode) { int32_t ret = 0; SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId, pSyncNode->vgId); ret = syncNodePing(pSyncNode, &pMsg->destId, pMsg); - assert(ret == 0); + ASSERT(ret == 0); syncPingDestroy(pMsg); return ret; @@ -988,7 +992,7 @@ int32_t syncNodePingPeers(SSyncNode* pSyncNode) { SRaftId* destId = &(pSyncNode->peersId[i]); SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, destId, pSyncNode->vgId); ret = syncNodePing(pSyncNode, destId, pMsg); - assert(ret == 0); + ASSERT(ret == 0); syncPingDestroy(pMsg); } return ret; @@ -1000,7 +1004,7 @@ int32_t syncNodePingAll(SSyncNode* pSyncNode) { SRaftId* destId = &(pSyncNode->replicasId[i]); SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, destId, pSyncNode->vgId); ret = syncNodePing(pSyncNode, destId, pMsg); - assert(ret == 0); + ASSERT(ret == 0); syncPingDestroy(pMsg); } return ret; @@ -1278,6 +1282,9 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) { // snapshot receivers cJSON* pReceivers = cJSON_CreateArray(); cJSON_AddItemToObject(pRoot, "receiver", snapshotReceiver2Json(pSyncNode->pNewNodeReceiver)); + + // changing + cJSON_AddNumberToObject(pRoot, "changing", pSyncNode->changing); } cJSON* pJson = cJSON_CreateObject(); @@ -1300,31 +1307,90 @@ void syncNodeEventLog(const SSyncNode* pSyncNode, char* str) { pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); } SyncIndex logLastIndex = pSyncNode->pLogStore->syncLogLastIndex(pSyncNode->pLogStore); + SyncIndex logBeginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore); if (userStrLen < 256) { char logBuf[128 + 256]; - snprintf(logBuf, sizeof(logBuf), - "vgId:%d, sync %s %s, term:%lu, commit:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, replica-num:%d, " - "lconfig:%ld, changing:%d", - pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, - pSyncNode->commitIndex, logLastIndex, snapshot.lastApplyIndex, pSyncNode->pRaftCfg->isStandBy, - pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, pSyncNode->changing); + if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) { + snprintf(logBuf, sizeof(logBuf), + "vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, " + "replica-num:%d, " + "lconfig:%ld, changing:%d", + pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, + pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, + pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, + pSyncNode->changing); + } else { + snprintf(logBuf, sizeof(logBuf), "%s", str); + } sDebug("%s", logBuf); } else { int len = 128 + userStrLen; char* s = (char*)taosMemoryMalloc(len); - snprintf(s, len, - "vgId:%d, sync %s %s, term:%lu, commit:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, replica-num:%d, " - "lconfig:%ld, changing:%d", - pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, - pSyncNode->commitIndex, logLastIndex, snapshot.lastApplyIndex, pSyncNode->pRaftCfg->isStandBy, - pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, pSyncNode->changing); + if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) { + snprintf(s, len, + "vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, " + "replica-num:%d, " + "lconfig:%ld, changing:%d", + pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, + pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, + pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, + pSyncNode->changing); + } else { + snprintf(s, len, "%s", str); + } sDebug("%s", s); taosMemoryFree(s); } } +void syncNodeErrorLog(const SSyncNode* pSyncNode, char* str) { + int32_t userStrLen = strlen(str); + + SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0}; + if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { + pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); + } + SyncIndex logLastIndex = pSyncNode->pLogStore->syncLogLastIndex(pSyncNode->pLogStore); + SyncIndex logBeginIndex = pSyncNode->pLogStore->syncLogBeginIndex(pSyncNode->pLogStore); + + if (userStrLen < 256) { + char logBuf[128 + 256]; + if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) { + snprintf(logBuf, sizeof(logBuf), + "vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, " + "replica-num:%d, " + "lconfig:%ld, changing:%d", + pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, + pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, + pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, + pSyncNode->changing); + } else { + snprintf(logBuf, sizeof(logBuf), "%s", str); + } + sError("%s", logBuf); + + } else { + int len = 128 + userStrLen; + char* s = (char*)taosMemoryMalloc(len); + if (pSyncNode != NULL && pSyncNode->pRaftCfg != NULL && pSyncNode->pRaftStore != NULL) { + snprintf(s, len, + "vgId:%d, sync %s %s, term:%lu, commit:%ld, beginlog:%ld, lastlog:%ld, lastsnapshot:%ld, standby:%d, " + "replica-num:%d, " + "lconfig:%ld, changing:%d", + pSyncNode->vgId, syncUtilState2String(pSyncNode->state), str, pSyncNode->pRaftStore->currentTerm, + pSyncNode->commitIndex, logBeginIndex, logLastIndex, snapshot.lastApplyIndex, + pSyncNode->pRaftCfg->isStandBy, pSyncNode->replicaNum, pSyncNode->pRaftCfg->lastConfigIndex, + pSyncNode->changing); + } else { + snprintf(s, len, "%s", str); + } + sError("%s", s); + taosMemoryFree(s); + } +} + char* syncNode2SimpleStr(const SSyncNode* pSyncNode) { int len = 256; char* s = (char*)taosMemoryMalloc(len); @@ -1396,7 +1462,7 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde pSyncNode->pRaftCfg->isStandBy = 1; // set standby } - // persist last config index + // add last config index raftCfgAddConfigIndex(pSyncNode->pRaftCfg, lastConfigChangeIndex); if (IamInNew) { @@ -1690,8 +1756,8 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) { } void syncNodeCandidate2Leader(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); - assert(voteGrantedMajority(pSyncNode->pVotesGranted)); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + ASSERT(voteGrantedMajority(pSyncNode->pVotesGranted)); syncNodeBecomeLeader(pSyncNode, "candidate to leader"); syncNodeLog2("==state change syncNodeCandidate2Leader==", pSyncNode); @@ -1703,21 +1769,21 @@ void syncNodeCandidate2Leader(SSyncNode* pSyncNode) { } void syncNodeFollower2Candidate(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER); pSyncNode->state = TAOS_SYNC_STATE_CANDIDATE; syncNodeLog2("==state change syncNodeFollower2Candidate==", pSyncNode); } void syncNodeLeader2Follower(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_LEADER); syncNodeBecomeFollower(pSyncNode, "leader to follower"); syncNodeLog2("==state change syncNodeLeader2Follower==", pSyncNode); } void syncNodeCandidate2Follower(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE); syncNodeBecomeFollower(pSyncNode, "candidate to follower"); syncNodeLog2("==state change syncNodeCandidate2Follower==", pSyncNode); @@ -1728,8 +1794,8 @@ void syncNodeCandidate2Follower(SSyncNode* pSyncNode) { // just called by syncNodeVoteForSelf // need assert void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) { - assert(term == pSyncNode->pRaftStore->currentTerm); - assert(!raftStoreHasVoted(pSyncNode->pRaftStore)); + ASSERT(term == pSyncNode->pRaftStore->currentTerm); + ASSERT(!raftStoreHasVoted(pSyncNode->pRaftStore)); raftStoreVote(pSyncNode->pRaftStore, pRaftId); } @@ -1752,7 +1818,7 @@ void syncNodeVoteForSelf(SSyncNode* pSyncNode) { // snapshot -------------- bool syncNodeHasSnapshot(SSyncNode* pSyncNode) { bool ret = false; - SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0}; + SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0, .lastConfigIndex = -1}; if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); if (snapshot.lastApplyIndex >= SYNC_INDEX_BEGIN) { @@ -1762,6 +1828,7 @@ bool syncNodeHasSnapshot(SSyncNode* pSyncNode) { return ret; } +#if 0 bool syncNodeIsIndexInSnapshot(SSyncNode* pSyncNode, SyncIndex index) { ASSERT(syncNodeHasSnapshot(pSyncNode)); ASSERT(pSyncNode->pFsm->FpGetSnapshotInfo != NULL); @@ -1772,6 +1839,7 @@ bool syncNodeIsIndexInSnapshot(SSyncNode* pSyncNode, SyncIndex index) { bool b = (index <= snapshot.lastApplyIndex); return b; } +#endif SyncIndex syncNodeGetLastIndex(SSyncNode* pSyncNode) { SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0}; @@ -1788,7 +1856,7 @@ SyncTerm syncNodeGetLastTerm(SSyncNode* pSyncNode) { SyncTerm lastTerm = 0; if (syncNodeHasSnapshot(pSyncNode)) { // has snapshot - SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0}; + SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0, .lastConfigIndex = -1}; if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); } @@ -1822,8 +1890,12 @@ SyncIndex syncNodeSyncStartIndex(SSyncNode* pSyncNode) { SyncIndex syncNodeGetPreIndex(SSyncNode* pSyncNode, SyncIndex index) { ASSERT(index >= SYNC_INDEX_BEGIN); + SyncIndex syncStartIndex = syncNodeSyncStartIndex(pSyncNode); - ASSERT(index <= syncStartIndex); + if (index > syncStartIndex) { + syncNodeLog3("syncNodeGetPreIndex", pSyncNode); + ASSERT(0); + } SyncIndex preIndex = index - 1; return preIndex; @@ -1831,8 +1903,51 @@ SyncIndex syncNodeGetPreIndex(SSyncNode* pSyncNode, SyncIndex index) { SyncTerm syncNodeGetPreTerm(SSyncNode* pSyncNode, SyncIndex index) { ASSERT(index >= SYNC_INDEX_BEGIN); + SyncIndex syncStartIndex = syncNodeSyncStartIndex(pSyncNode); - ASSERT(index <= syncStartIndex); + if (index > syncStartIndex) { + syncNodeLog3("syncNodeGetPreTerm", pSyncNode); + ASSERT(0); + } + + if (index == SYNC_INDEX_BEGIN) { + return 0; + } + + SyncTerm preTerm = 0; + SyncIndex preIndex = index - 1; + SSyncRaftEntry* pPreEntry = NULL; + int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, preIndex, &pPreEntry); + if (code == 0) { + ASSERT(pPreEntry != NULL); + preTerm = pPreEntry->term; + taosMemoryFree(pPreEntry); + return preTerm; + } else { + if (terrno == TSDB_CODE_WAL_LOG_NOT_EXIST) { + SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0, .lastConfigIndex = -1}; + if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { + pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); + if (snapshot.lastApplyIndex == preIndex) { + return snapshot.lastApplyTerm; + } + } + } + } + + ASSERT(0); + return -1; +} + +#if 0 +SyncTerm syncNodeGetPreTerm(SSyncNode* pSyncNode, SyncIndex index) { + ASSERT(index >= SYNC_INDEX_BEGIN); + + SyncIndex syncStartIndex = syncNodeSyncStartIndex(pSyncNode); + if (index > syncStartIndex) { + syncNodeLog3("syncNodeGetPreTerm", pSyncNode); + ASSERT(0); + } if (index == SYNC_INDEX_BEGIN) { return 0; @@ -1841,7 +1956,7 @@ SyncTerm syncNodeGetPreTerm(SSyncNode* pSyncNode, SyncIndex index) { SyncTerm preTerm = 0; if (syncNodeHasSnapshot(pSyncNode)) { // has snapshot - SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0}; + SSnapshot snapshot = {.data = NULL, .lastApplyIndex = -1, .lastApplyTerm = 0, .lastConfigIndex = -1}; if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); } @@ -1888,6 +2003,7 @@ SyncTerm syncNodeGetPreTerm(SSyncNode* pSyncNode, SyncIndex index) { return preTerm; } +#endif // get pre index and term of "index" int32_t syncNodeGetPreIndexTerm(SSyncNode* pSyncNode, SyncIndex index, SyncIndex* pPreIndex, SyncTerm* pPreTerm) { @@ -1925,6 +2041,12 @@ void syncNodeLog2(char* s, SSyncNode* pObj) { } } +void syncNodeLog3(char* s, SSyncNode* pObj) { + char* serialized = syncNode2Str(pObj); + sTraceLong("syncNodeLog3 | len:%lu | %s | %s", strlen(serialized), s, serialized); + taosMemoryFree(serialized); +} + // ------ local funciton --------- // enqueue message ---- static void syncNodeEqPingTimer(void* param, void* tmrId) { @@ -2036,17 +2158,17 @@ static void syncNodeEqHeartbeatTimer(void* param, void* tmrId) { static int32_t syncNodeEqNoop(SSyncNode* ths) { int32_t ret = 0; - assert(ths->state == TAOS_SYNC_STATE_LEADER); + ASSERT(ths->state == TAOS_SYNC_STATE_LEADER); - SyncIndex index = ths->pLogStore->getLastIndex(ths->pLogStore) + 1; + SyncIndex index = ths->pLogStore->syncLogWriteIndex(ths->pLogStore); SyncTerm term = ths->pRaftStore->currentTerm; SSyncRaftEntry* pEntry = syncEntryBuildNoop(term, index, ths->vgId); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); uint32_t entryLen; char* serialized = syncEntrySerialize(pEntry, &entryLen); SyncClientRequest* pSyncMsg = syncClientRequestBuild(entryLen); - assert(pSyncMsg->dataLen == entryLen); + ASSERT(pSyncMsg->dataLen == entryLen); memcpy(pSyncMsg->data, serialized, entryLen); SRpcMsg rpcMsg = {0}; @@ -2066,10 +2188,10 @@ static int32_t syncNodeEqNoop(SSyncNode* ths) { static int32_t syncNodeAppendNoop(SSyncNode* ths) { int32_t ret = 0; - SyncIndex index = ths->pLogStore->getLastIndex(ths->pLogStore) + 1; + SyncIndex index = ths->pLogStore->syncLogWriteIndex(ths->pLogStore); SyncTerm term = ths->pRaftStore->currentTerm; SSyncRaftEntry* pEntry = syncEntryBuildNoop(term, index, ths->vgId); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); if (ths->state == TAOS_SYNC_STATE_LEADER) { // ths->pLogStore->appendEntry(ths->pLogStore, pEntry); @@ -2132,7 +2254,7 @@ int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg) { SyncIndex index = ths->pLogStore->syncLogWriteIndex(ths->pLogStore); SyncTerm term = ths->pRaftStore->currentTerm; SSyncRaftEntry* pEntry = syncEntryBuild2((SyncClientRequest*)pMsg, term, index); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); if (ths->state == TAOS_SYNC_STATE_LEADER) { // ths->pLogStore->appendEntry(ths->pLogStore, pEntry); @@ -2290,7 +2412,7 @@ static int32_t syncNodeConfigChangeFinish(SSyncNode* ths, SRpcMsg* pRpcMsg, SSyn ths->pFsm->FpReConfigCb(ths->pFsm, pRpcMsg, cbMeta); } - // update changing + // clear changing ths->changing = false; char tmpbuf[512]; @@ -2309,6 +2431,9 @@ static int32_t syncNodeConfigChangeFinish(SSyncNode* ths, SRpcMsg* pRpcMsg, SSyn static int32_t syncNodeConfigChange(SSyncNode* ths, SRpcMsg* pRpcMsg, SSyncRaftEntry* pEntry, SyncReconfigFinish* pFinish) { + // set changing + ths->changing = true; + // old config SSyncCfg oldSyncCfg = ths->pRaftCfg->cfg; diff --git a/source/libs/sync/src/syncMessage.c b/source/libs/sync/src/syncMessage.c index 454609009c..119a178893 100644 --- a/source/libs/sync/src/syncMessage.c +++ b/source/libs/sync/src/syncMessage.c @@ -186,18 +186,18 @@ void syncTimeoutDestroy(SyncTimeout* pMsg) { } void syncTimeoutSerialize(const SyncTimeout* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncTimeoutDeserialize(const char* buf, uint32_t len, SyncTimeout* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncTimeoutSerialize2(const SyncTimeout* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncTimeoutSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -208,9 +208,9 @@ char* syncTimeoutSerialize2(const SyncTimeout* pMsg, uint32_t* len) { SyncTimeout* syncTimeoutDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncTimeout* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncTimeoutDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -228,7 +228,7 @@ void syncTimeoutFromRpcMsg(const SRpcMsg* pRpcMsg, SyncTimeout* pMsg) { SyncTimeout* syncTimeoutFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncTimeout* pMsg = syncTimeoutDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -322,19 +322,19 @@ void syncPingDestroy(SyncPing* pMsg) { } void syncPingSerialize(const SyncPing* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncPingDeserialize(const char* buf, uint32_t len, SyncPing* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); - assert(pMsg->bytes == sizeof(SyncPing) + pMsg->dataLen); + ASSERT(len == pMsg->bytes); + ASSERT(pMsg->bytes == sizeof(SyncPing) + pMsg->dataLen); } char* syncPingSerialize2(const SyncPing* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncPingSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -345,9 +345,9 @@ char* syncPingSerialize2(const SyncPing* pMsg, uint32_t* len) { SyncPing* syncPingDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncPing* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncPingDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -406,7 +406,7 @@ SyncPing* syncPingDeserialize3(void* buf, int32_t bufLen) { } pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); pMsg->bytes = bytes; if (tDecodeI32(&decoder, &pMsg->vgId) < 0) { @@ -435,7 +435,7 @@ SyncPing* syncPingDeserialize3(void* buf, int32_t bufLen) { if (tDecodeBinary(&decoder, (uint8_t**)(&data), &len) < 0) { return NULL; } - assert(len = pMsg->dataLen); + ASSERT(len = pMsg->dataLen); memcpy(pMsg->data, data, len); tEndDecode(&decoder); @@ -457,7 +457,7 @@ void syncPingFromRpcMsg(const SRpcMsg* pRpcMsg, SyncPing* pMsg) { SyncPing* syncPingFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncPing* pMsg = syncPingDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -584,19 +584,19 @@ void syncPingReplyDestroy(SyncPingReply* pMsg) { } void syncPingReplySerialize(const SyncPingReply* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncPingReplyDeserialize(const char* buf, uint32_t len, SyncPingReply* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); - assert(pMsg->bytes == sizeof(SyncPing) + pMsg->dataLen); + ASSERT(len == pMsg->bytes); + ASSERT(pMsg->bytes == sizeof(SyncPing) + pMsg->dataLen); } char* syncPingReplySerialize2(const SyncPingReply* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncPingReplySerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -607,9 +607,9 @@ char* syncPingReplySerialize2(const SyncPingReply* pMsg, uint32_t* len) { SyncPingReply* syncPingReplyDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncPingReply* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncPingReplyDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -668,7 +668,7 @@ SyncPingReply* syncPingReplyDeserialize3(void* buf, int32_t bufLen) { } pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); pMsg->bytes = bytes; if (tDecodeI32(&decoder, &pMsg->vgId) < 0) { @@ -697,7 +697,7 @@ SyncPingReply* syncPingReplyDeserialize3(void* buf, int32_t bufLen) { if (tDecodeBinary(&decoder, (uint8_t**)(&data), &len) < 0) { return NULL; } - assert(len = pMsg->dataLen); + ASSERT(len = pMsg->dataLen); memcpy(pMsg->data, data, len); tEndDecode(&decoder); @@ -719,7 +719,7 @@ void syncPingReplyFromRpcMsg(const SRpcMsg* pRpcMsg, SyncPingReply* pMsg) { SyncPingReply* syncPingReplyFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncPingReply* pMsg = syncPingReplyDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -844,18 +844,18 @@ void syncClientRequestDestroy(SyncClientRequest* pMsg) { } void syncClientRequestSerialize(const SyncClientRequest* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncClientRequestDeserialize(const char* buf, uint32_t len, SyncClientRequest* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncClientRequestSerialize2(const SyncClientRequest* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncClientRequestSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -866,9 +866,9 @@ char* syncClientRequestSerialize2(const SyncClientRequest* pMsg, uint32_t* len) SyncClientRequest* syncClientRequestDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncClientRequest* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncClientRequestDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -888,7 +888,7 @@ void syncClientRequestFromRpcMsg(const SRpcMsg* pRpcMsg, SyncClientRequest* pMsg // step 3. RpcMsg => SyncClientRequest, from queue SyncClientRequest* syncClientRequestFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncClientRequest* pMsg = syncClientRequestDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -974,18 +974,18 @@ void syncRequestVoteDestroy(SyncRequestVote* pMsg) { } void syncRequestVoteSerialize(const SyncRequestVote* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncRequestVoteDeserialize(const char* buf, uint32_t len, SyncRequestVote* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncRequestVoteSerialize2(const SyncRequestVote* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncRequestVoteSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -996,9 +996,9 @@ char* syncRequestVoteSerialize2(const SyncRequestVote* pMsg, uint32_t* len) { SyncRequestVote* syncRequestVoteDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncRequestVote* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncRequestVoteDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1016,7 +1016,7 @@ void syncRequestVoteFromRpcMsg(const SRpcMsg* pRpcMsg, SyncRequestVote* pMsg) { SyncRequestVote* syncRequestVoteFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncRequestVote* pMsg = syncRequestVoteDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -1125,18 +1125,18 @@ void syncRequestVoteReplyDestroy(SyncRequestVoteReply* pMsg) { } void syncRequestVoteReplySerialize(const SyncRequestVoteReply* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncRequestVoteReplyDeserialize(const char* buf, uint32_t len, SyncRequestVoteReply* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncRequestVoteReplySerialize2(const SyncRequestVoteReply* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncRequestVoteReplySerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1147,9 +1147,9 @@ char* syncRequestVoteReplySerialize2(const SyncRequestVoteReply* pMsg, uint32_t* SyncRequestVoteReply* syncRequestVoteReplyDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncRequestVoteReply* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncRequestVoteReplyDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1167,7 +1167,7 @@ void syncRequestVoteReplyFromRpcMsg(const SRpcMsg* pRpcMsg, SyncRequestVoteReply SyncRequestVoteReply* syncRequestVoteReplyFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncRequestVoteReply* pMsg = syncRequestVoteReplyDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -1274,19 +1274,19 @@ void syncAppendEntriesDestroy(SyncAppendEntries* pMsg) { } void syncAppendEntriesSerialize(const SyncAppendEntries* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncAppendEntriesDeserialize(const char* buf, uint32_t len, SyncAppendEntries* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); - assert(pMsg->bytes == sizeof(SyncAppendEntries) + pMsg->dataLen); + ASSERT(len == pMsg->bytes); + ASSERT(pMsg->bytes == sizeof(SyncAppendEntries) + pMsg->dataLen); } char* syncAppendEntriesSerialize2(const SyncAppendEntries* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncAppendEntriesSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1297,9 +1297,9 @@ char* syncAppendEntriesSerialize2(const SyncAppendEntries* pMsg, uint32_t* len) SyncAppendEntries* syncAppendEntriesDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncAppendEntries* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncAppendEntriesDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1317,7 +1317,7 @@ void syncAppendEntriesFromRpcMsg(const SRpcMsg* pRpcMsg, SyncAppendEntries* pMsg SyncAppendEntries* syncAppendEntriesFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncAppendEntries* pMsg = syncAppendEntriesDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -1444,18 +1444,18 @@ void syncAppendEntriesReplyDestroy(SyncAppendEntriesReply* pMsg) { } void syncAppendEntriesReplySerialize(const SyncAppendEntriesReply* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncAppendEntriesReplyDeserialize(const char* buf, uint32_t len, SyncAppendEntriesReply* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncAppendEntriesReplySerialize2(const SyncAppendEntriesReply* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncAppendEntriesReplySerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1466,9 +1466,9 @@ char* syncAppendEntriesReplySerialize2(const SyncAppendEntriesReply* pMsg, uint3 SyncAppendEntriesReply* syncAppendEntriesReplyDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncAppendEntriesReply* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncAppendEntriesReplyDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1486,7 +1486,7 @@ void syncAppendEntriesReplyFromRpcMsg(const SRpcMsg* pRpcMsg, SyncAppendEntriesR SyncAppendEntriesReply* syncAppendEntriesReplyFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncAppendEntriesReply* pMsg = syncAppendEntriesReplyDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -1607,18 +1607,18 @@ void syncApplyMsgDestroy(SyncApplyMsg* pMsg) { } void syncApplyMsgSerialize(const SyncApplyMsg* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncApplyMsgDeserialize(const char* buf, uint32_t len, SyncApplyMsg* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncApplyMsgSerialize2(const SyncApplyMsg* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncApplyMsgSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1629,9 +1629,9 @@ char* syncApplyMsgSerialize2(const SyncApplyMsg* pMsg, uint32_t* len) { SyncApplyMsg* syncApplyMsgDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncApplyMsg* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncApplyMsgDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1752,19 +1752,19 @@ void syncSnapshotSendDestroy(SyncSnapshotSend* pMsg) { } void syncSnapshotSendSerialize(const SyncSnapshotSend* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncSnapshotSendDeserialize(const char* buf, uint32_t len, SyncSnapshotSend* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); - assert(pMsg->bytes == sizeof(SyncSnapshotSend) + pMsg->dataLen); + ASSERT(len == pMsg->bytes); + ASSERT(pMsg->bytes == sizeof(SyncSnapshotSend) + pMsg->dataLen); } char* syncSnapshotSendSerialize2(const SyncSnapshotSend* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncSnapshotSendSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1775,9 +1775,9 @@ char* syncSnapshotSendSerialize2(const SyncSnapshotSend* pMsg, uint32_t* len) { SyncSnapshotSend* syncSnapshotSendDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncSnapshotSend* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncSnapshotSendDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1795,7 +1795,7 @@ void syncSnapshotSendFromRpcMsg(const SRpcMsg* pRpcMsg, SyncSnapshotSend* pMsg) SyncSnapshotSend* syncSnapshotSendFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncSnapshotSend* pMsg = syncSnapshotSendDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -1925,18 +1925,18 @@ void syncSnapshotRspDestroy(SyncSnapshotRsp* pMsg) { } void syncSnapshotRspSerialize(const SyncSnapshotRsp* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncSnapshotRspDeserialize(const char* buf, uint32_t len, SyncSnapshotRsp* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncSnapshotRspSerialize2(const SyncSnapshotRsp* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncSnapshotRspSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -1947,9 +1947,9 @@ char* syncSnapshotRspSerialize2(const SyncSnapshotRsp* pMsg, uint32_t* len) { SyncSnapshotRsp* syncSnapshotRspDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncSnapshotRsp* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncSnapshotRspDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -1967,7 +1967,7 @@ void syncSnapshotRspFromRpcMsg(const SRpcMsg* pRpcMsg, SyncSnapshotRsp* pMsg) { SyncSnapshotRsp* syncSnapshotRspFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncSnapshotRsp* pMsg = syncSnapshotRspDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -2085,18 +2085,18 @@ void syncLeaderTransferDestroy(SyncLeaderTransfer* pMsg) { } void syncLeaderTransferSerialize(const SyncLeaderTransfer* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncLeaderTransferDeserialize(const char* buf, uint32_t len, SyncLeaderTransfer* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncLeaderTransferSerialize2(const SyncLeaderTransfer* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncLeaderTransferSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -2107,9 +2107,9 @@ char* syncLeaderTransferSerialize2(const SyncLeaderTransfer* pMsg, uint32_t* len SyncLeaderTransfer* syncLeaderTransferDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncLeaderTransfer* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncLeaderTransferDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -2127,7 +2127,7 @@ void syncLeaderTransferFromRpcMsg(const SRpcMsg* pRpcMsg, SyncLeaderTransfer* pM SyncLeaderTransfer* syncLeaderTransferFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncLeaderTransfer* pMsg = syncLeaderTransferDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } @@ -2247,18 +2247,18 @@ void syncReconfigFinishDestroy(SyncReconfigFinish* pMsg) { } void syncReconfigFinishSerialize(const SyncReconfigFinish* pMsg, char* buf, uint32_t bufLen) { - assert(pMsg->bytes <= bufLen); + ASSERT(pMsg->bytes <= bufLen); memcpy(buf, pMsg, pMsg->bytes); } void syncReconfigFinishDeserialize(const char* buf, uint32_t len, SyncReconfigFinish* pMsg) { memcpy(pMsg, buf, len); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); } char* syncReconfigFinishSerialize2(const SyncReconfigFinish* pMsg, uint32_t* len) { char* buf = taosMemoryMalloc(pMsg->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); syncReconfigFinishSerialize(pMsg, buf, pMsg->bytes); if (len != NULL) { *len = pMsg->bytes; @@ -2269,9 +2269,9 @@ char* syncReconfigFinishSerialize2(const SyncReconfigFinish* pMsg, uint32_t* len SyncReconfigFinish* syncReconfigFinishDeserialize2(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SyncReconfigFinish* pMsg = taosMemoryMalloc(bytes); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); syncReconfigFinishDeserialize(buf, len, pMsg); - assert(len == pMsg->bytes); + ASSERT(len == pMsg->bytes); return pMsg; } @@ -2289,7 +2289,7 @@ void syncReconfigFinishFromRpcMsg(const SRpcMsg* pRpcMsg, SyncReconfigFinish* pM SyncReconfigFinish* syncReconfigFinishFromRpcMsg2(const SRpcMsg* pRpcMsg) { SyncReconfigFinish* pMsg = syncReconfigFinishDeserialize2(pRpcMsg->pCont, pRpcMsg->contLen); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); return pMsg; } diff --git a/source/libs/sync/src/syncRaftCfg.c b/source/libs/sync/src/syncRaftCfg.c index 08c3e0126c..2cc1eb0239 100644 --- a/source/libs/sync/src/syncRaftCfg.c +++ b/source/libs/sync/src/syncRaftCfg.c @@ -24,42 +24,47 @@ SRaftCfg *raftCfgOpen(const char *path) { snprintf(pCfg->path, sizeof(pCfg->path), "%s", path); pCfg->pFile = taosOpenFile(pCfg->path, TD_FILE_READ | TD_FILE_WRITE); - assert(pCfg->pFile != NULL); + ASSERT(pCfg->pFile != NULL); taosLSeekFile(pCfg->pFile, 0, SEEK_SET); char buf[1024] = {0}; int len = taosReadFile(pCfg->pFile, buf, sizeof(buf)); - assert(len > 0); + ASSERT(len > 0); int32_t ret = raftCfgFromStr(buf, pCfg); - assert(ret == 0); + ASSERT(ret == 0); return pCfg; } int32_t raftCfgClose(SRaftCfg *pRaftCfg) { int64_t ret = taosCloseFile(&(pRaftCfg->pFile)); - assert(ret == 0); + ASSERT(ret == 0); taosMemoryFree(pRaftCfg); return 0; } int32_t raftCfgPersist(SRaftCfg *pRaftCfg) { - assert(pRaftCfg != NULL); + ASSERT(pRaftCfg != NULL); char *s = raftCfg2Str(pRaftCfg); taosLSeekFile(pRaftCfg->pFile, 0, SEEK_SET); char buf[CONFIG_FILE_LEN] = {0}; memset(buf, 0, sizeof(buf)); - ASSERT(strlen(s) + 1 <= CONFIG_FILE_LEN); + + if (strlen(s) + 1 > CONFIG_FILE_LEN) { + sError("too long config str:%s", s); + ASSERT(0); + } + snprintf(buf, sizeof(buf), "%s", s); int64_t ret = taosWriteFile(pRaftCfg->pFile, buf, sizeof(buf)); - assert(ret == sizeof(buf)); + ASSERT(ret == sizeof(buf)); // int64_t ret = taosWriteFile(pRaftCfg->pFile, s, strlen(s) + 1); - // assert(ret == strlen(s) + 1); + // ASSERT(ret == strlen(s) + 1); taosMemoryFree(s); taosFsyncFile(pRaftCfg->pFile); @@ -96,14 +101,14 @@ cJSON *syncCfg2Json(SSyncCfg *pSyncCfg) { char *syncCfg2Str(SSyncCfg *pSyncCfg) { cJSON *pJson = syncCfg2Json(pSyncCfg); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } char *syncCfg2SimpleStr(SSyncCfg *pSyncCfg) { int32_t len = 512; - char * s = taosMemoryMalloc(len); + char *s = taosMemoryMalloc(len); memset(s, 0, len); snprintf(s, len, "{replica-num:%d, my-index:%d, ", pSyncCfg->replicaNum, pSyncCfg->myIndex); @@ -130,27 +135,27 @@ int32_t syncCfgFromJson(const cJSON *pRoot, SSyncCfg *pSyncCfg) { const cJSON *pJson = pRoot; cJSON *pReplicaNum = cJSON_GetObjectItem(pJson, "replicaNum"); - assert(cJSON_IsNumber(pReplicaNum)); + ASSERT(cJSON_IsNumber(pReplicaNum)); pSyncCfg->replicaNum = cJSON_GetNumberValue(pReplicaNum); cJSON *pMyIndex = cJSON_GetObjectItem(pJson, "myIndex"); - assert(cJSON_IsNumber(pMyIndex)); + ASSERT(cJSON_IsNumber(pMyIndex)); pSyncCfg->myIndex = cJSON_GetNumberValue(pMyIndex); cJSON *pNodeInfoArr = cJSON_GetObjectItem(pJson, "nodeInfo"); int arraySize = cJSON_GetArraySize(pNodeInfoArr); - assert(arraySize == pSyncCfg->replicaNum); + ASSERT(arraySize == pSyncCfg->replicaNum); for (int i = 0; i < arraySize; ++i) { cJSON *pNodeInfo = cJSON_GetArrayItem(pNodeInfoArr, i); - assert(pNodeInfo != NULL); + ASSERT(pNodeInfo != NULL); cJSON *pNodePort = cJSON_GetObjectItem(pNodeInfo, "nodePort"); - assert(cJSON_IsNumber(pNodePort)); + ASSERT(cJSON_IsNumber(pNodePort)); ((pSyncCfg->nodeInfo)[i]).nodePort = cJSON_GetNumberValue(pNodePort); cJSON *pNodeFqdn = cJSON_GetObjectItem(pNodeInfo, "nodeFqdn"); - assert(cJSON_IsString(pNodeFqdn)); + ASSERT(cJSON_IsString(pNodeFqdn)); snprintf(((pSyncCfg->nodeInfo)[i]).nodeFqdn, sizeof(((pSyncCfg->nodeInfo)[i]).nodeFqdn), "%s", pNodeFqdn->valuestring); } @@ -160,10 +165,10 @@ int32_t syncCfgFromJson(const cJSON *pRoot, SSyncCfg *pSyncCfg) { int32_t syncCfgFromStr(const char *s, SSyncCfg *pSyncCfg) { cJSON *pRoot = cJSON_Parse(s); - assert(pRoot != NULL); + ASSERT(pRoot != NULL); int32_t ret = syncCfgFromJson(pRoot, pSyncCfg); - assert(ret == 0); + ASSERT(ret == 0); cJSON_Delete(pRoot); return 0; @@ -196,16 +201,16 @@ cJSON *raftCfg2Json(SRaftCfg *pRaftCfg) { char *raftCfg2Str(SRaftCfg *pRaftCfg) { cJSON *pJson = raftCfg2Json(pRaftCfg); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } int32_t raftCfgCreateFile(SSyncCfg *pCfg, SRaftCfgMeta meta, const char *path) { - assert(pCfg != NULL); + ASSERT(pCfg != NULL); TdFilePtr pFile = taosOpenFile(path, TD_FILE_CREATE | TD_FILE_WRITE); - assert(pFile != NULL); + ASSERT(pFile != NULL); SRaftCfg raftCfg; raftCfg.cfg = *pCfg; @@ -222,10 +227,10 @@ int32_t raftCfgCreateFile(SSyncCfg *pCfg, SRaftCfgMeta meta, const char *path) { ASSERT(strlen(s) + 1 <= CONFIG_FILE_LEN); snprintf(buf, sizeof(buf), "%s", s); int64_t ret = taosWriteFile(pFile, buf, sizeof(buf)); - assert(ret == sizeof(buf)); + ASSERT(ret == sizeof(buf)); // int64_t ret = taosWriteFile(pFile, s, strlen(s) + 1); - // assert(ret == strlen(s) + 1); + // ASSERT(ret == strlen(s) + 1); taosMemoryFree(s); taosCloseFile(&pFile); @@ -250,19 +255,19 @@ int32_t raftCfgFromJson(const cJSON *pRoot, SRaftCfg *pRaftCfg) { cJSON *pIndexArr = cJSON_GetObjectItem(pJson, "configIndexArr"); int arraySize = cJSON_GetArraySize(pIndexArr); - assert(arraySize == pRaftCfg->configIndexCount); + ASSERT(arraySize == pRaftCfg->configIndexCount); memset(pRaftCfg->configIndexArr, 0, sizeof(pRaftCfg->configIndexArr)); for (int i = 0; i < arraySize; ++i) { cJSON *pIndexObj = cJSON_GetArrayItem(pIndexArr, i); - assert(pIndexObj != NULL); + ASSERT(pIndexObj != NULL); cJSON *pIndex = cJSON_GetObjectItem(pIndexObj, "index"); - assert(cJSON_IsString(pIndex)); + ASSERT(cJSON_IsString(pIndex)); (pRaftCfg->configIndexArr)[i] = atoll(pIndex->valuestring); } - cJSON * pJsonSyncCfg = cJSON_GetObjectItem(pJson, "SSyncCfg"); + cJSON *pJsonSyncCfg = cJSON_GetObjectItem(pJson, "SSyncCfg"); int32_t code = syncCfgFromJson(pJsonSyncCfg, &(pRaftCfg->cfg)); ASSERT(code == 0); @@ -271,10 +276,10 @@ int32_t raftCfgFromJson(const cJSON *pRoot, SRaftCfg *pRaftCfg) { int32_t raftCfgFromStr(const char *s, SRaftCfg *pRaftCfg) { cJSON *pRoot = cJSON_Parse(s); - assert(pRoot != NULL); + ASSERT(pRoot != NULL); int32_t ret = raftCfgFromJson(pRoot, pRaftCfg); - assert(ret == 0); + ASSERT(ret == 0); cJSON_Delete(pRoot); return 0; diff --git a/source/libs/sync/src/syncRaftEntry.c b/source/libs/sync/src/syncRaftEntry.c index 05a2dbaa3f..ff334a76bb 100644 --- a/source/libs/sync/src/syncRaftEntry.c +++ b/source/libs/sync/src/syncRaftEntry.c @@ -19,7 +19,7 @@ SSyncRaftEntry* syncEntryBuild(uint32_t dataLen) { uint32_t bytes = sizeof(SSyncRaftEntry) + dataLen; SSyncRaftEntry* pEntry = taosMemoryMalloc(bytes); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); memset(pEntry, 0, bytes); pEntry->bytes = bytes; pEntry->dataLen = dataLen; @@ -29,14 +29,14 @@ SSyncRaftEntry* syncEntryBuild(uint32_t dataLen) { // step 4. SyncClientRequest => SSyncRaftEntry, add term, index SSyncRaftEntry* syncEntryBuild2(SyncClientRequest* pMsg, SyncTerm term, SyncIndex index) { SSyncRaftEntry* pEntry = syncEntryBuild3(pMsg, term, index); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); return pEntry; } SSyncRaftEntry* syncEntryBuild3(SyncClientRequest* pMsg, SyncTerm term, SyncIndex index) { SSyncRaftEntry* pEntry = syncEntryBuild(pMsg->dataLen); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); pEntry->msgType = pMsg->msgType; pEntry->originalRpcType = pMsg->originalRpcType; @@ -63,7 +63,7 @@ SSyncRaftEntry* syncEntryBuildNoop(SyncTerm term, SyncIndex index, int32_t vgId) memcpy(rpcMsg.pCont, &head, sizeof(head)); SSyncRaftEntry* pEntry = syncEntryBuild(rpcMsg.contLen); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); pEntry->msgType = TDMT_SYNC_CLIENT_REQUEST; pEntry->originalRpcType = TDMT_SYNC_NOOP; @@ -72,7 +72,7 @@ SSyncRaftEntry* syncEntryBuildNoop(SyncTerm term, SyncIndex index, int32_t vgId) pEntry->term = term; pEntry->index = index; - assert(pEntry->dataLen == rpcMsg.contLen); + ASSERT(pEntry->dataLen == rpcMsg.contLen); memcpy(pEntry->data, rpcMsg.pCont, rpcMsg.contLen); rpcFreeCont(rpcMsg.pCont); @@ -88,7 +88,7 @@ void syncEntryDestory(SSyncRaftEntry* pEntry) { // step 5. SSyncRaftEntry => bin, to raft log char* syncEntrySerialize(const SSyncRaftEntry* pEntry, uint32_t* len) { char* buf = taosMemoryMalloc(pEntry->bytes); - assert(buf != NULL); + ASSERT(buf != NULL); memcpy(buf, pEntry, pEntry->bytes); if (len != NULL) { *len = pEntry->bytes; @@ -100,9 +100,9 @@ char* syncEntrySerialize(const SSyncRaftEntry* pEntry, uint32_t* len) { SSyncRaftEntry* syncEntryDeserialize(const char* buf, uint32_t len) { uint32_t bytes = *((uint32_t*)buf); SSyncRaftEntry* pEntry = taosMemoryMalloc(bytes); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); memcpy(pEntry, buf, len); - assert(len == pEntry->bytes); + ASSERT(len == pEntry->bytes); return pEntry; } diff --git a/source/libs/sync/src/syncRaftLog.c b/source/libs/sync/src/syncRaftLog.c index 79d9b329c1..0f6e8a28d9 100644 --- a/source/libs/sync/src/syncRaftLog.c +++ b/source/libs/sync/src/syncRaftLog.c @@ -25,7 +25,7 @@ static SyncIndex raftLogEndIndex(struct SSyncLogStore* pLogStore); static SyncIndex raftLogWriteIndex(struct SSyncLogStore* pLogStore); static bool raftLogIsEmpty(struct SSyncLogStore* pLogStore); static int32_t raftLogEntryCount(struct SSyncLogStore* pLogStore); -static bool raftLogInRange(struct SSyncLogStore* pLogStore, SyncIndex index); + static SyncIndex raftLogLastIndex(struct SSyncLogStore* pLogStore); static SyncTerm raftLogLastTerm(struct SSyncLogStore* pLogStore); static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry); @@ -58,8 +58,6 @@ static int32_t raftLogSetBeginIndex(struct SSyncLogStore* pLogStore, SyncIndex b return 0; } -int32_t raftLogResetBeginIndex(struct SSyncLogStore* pLogStore) { return 0; } - static SyncIndex raftLogBeginIndex(struct SSyncLogStore* pLogStore) { SSyncLogStoreData* pData = pLogStore->data; SWal* pWal = pData->pWal; @@ -81,6 +79,7 @@ static int32_t raftLogEntryCount(struct SSyncLogStore* pLogStore) { return count > 0 ? count : 0; } +#if 0 static bool raftLogInRange(struct SSyncLogStore* pLogStore, SyncIndex index) { SyncIndex beginIndex = raftLogBeginIndex(pLogStore); SyncIndex endIndex = raftLogEndIndex(pLogStore); @@ -90,6 +89,7 @@ static bool raftLogInRange(struct SSyncLogStore* pLogStore, SyncIndex index) { return false; } } +#endif static SyncIndex raftLogLastIndex(struct SSyncLogStore* pLogStore) { SyncIndex lastIndex; @@ -143,7 +143,10 @@ static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntr SWal* pWal = pData->pWal; SyncIndex writeIndex = raftLogWriteIndex(pLogStore); - ASSERT(pEntry->index == writeIndex); + if (pEntry->index != writeIndex) { + sError("raftLogAppendEntry error, pEntry->index:%ld update to writeIndex:%ld", pEntry->index, writeIndex); + pEntry->index = writeIndex; + } int code = 0; SSyncLogMeta syncMeta; @@ -171,6 +174,7 @@ static int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncRaftEntr return code; } +#if 0 static int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncRaftEntry** ppEntry) { SSyncLogStoreData* pData = pLogStore->data; SWal* pWal = pData->pWal; @@ -215,6 +219,49 @@ static int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, return code; } +#endif + +static int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncRaftEntry** ppEntry) { + SSyncLogStoreData* pData = pLogStore->data; + SWal* pWal = pData->pWal; + int32_t code; + + *ppEntry = NULL; + + SWalReadHandle* pWalHandle = walOpenReadHandle(pWal); + if (pWalHandle == NULL) { + return -1; + } + + code = walReadWithHandle(pWalHandle, index); + if (code != 0) { + int32_t err = terrno; + const char* errStr = tstrerror(err); + int32_t linuxErr = errno; + const char* linuxErrMsg = strerror(errno); + sError("raftLogGetEntry error, err:%d %X, msg:%s, linuxErr:%d, linuxErrMsg:%s", err, err, errStr, linuxErr, + linuxErrMsg); + + walCloseReadHandle(pWalHandle); + return code; + } + + *ppEntry = syncEntryBuild(pWalHandle->pHead->head.bodyLen); + ASSERT(*ppEntry != NULL); + (*ppEntry)->msgType = TDMT_SYNC_CLIENT_REQUEST; + (*ppEntry)->originalRpcType = pWalHandle->pHead->head.msgType; + (*ppEntry)->seqNum = pWalHandle->pHead->head.syncMeta.seqNum; + (*ppEntry)->isWeak = pWalHandle->pHead->head.syncMeta.isWeek; + (*ppEntry)->term = pWalHandle->pHead->head.syncMeta.term; + (*ppEntry)->index = index; + ASSERT((*ppEntry)->dataLen == pWalHandle->pHead->head.bodyLen); + memcpy((*ppEntry)->data, pWalHandle->pHead->head.body, pWalHandle->pHead->head.bodyLen); + + // need to hold, do not new every time!! + walCloseReadHandle(pWalHandle); + + return code; +} static int32_t raftLogTruncate(struct SSyncLogStore* pLogStore, SyncIndex fromIndex) { SSyncLogStoreData* pData = pLogStore->data; @@ -245,10 +292,10 @@ static int32_t raftLogGetLastEntry(SSyncLogStore* pLogStore, SSyncRaftEntry** pp //------------------------------- SSyncLogStore* logStoreCreate(SSyncNode* pSyncNode) { SSyncLogStore* pLogStore = taosMemoryMalloc(sizeof(SSyncLogStore)); - assert(pLogStore != NULL); + ASSERT(pLogStore != NULL); pLogStore->data = taosMemoryMalloc(sizeof(SSyncLogStoreData)); - assert(pLogStore->data != NULL); + ASSERT(pLogStore->data != NULL); SSyncLogStoreData* pData = pLogStore->data; pData->pSyncNode = pSyncNode; @@ -277,7 +324,6 @@ SSyncLogStore* logStoreCreate(SSyncNode* pSyncNode) { pLogStore->syncLogEndIndex = raftLogEndIndex; pLogStore->syncLogIsEmpty = raftLogIsEmpty; pLogStore->syncLogEntryCount = raftLogEntryCount; - pLogStore->syncLogInRange = raftLogInRange; pLogStore->syncLogLastIndex = raftLogLastIndex; pLogStore->syncLogLastTerm = raftLogLastTerm; pLogStore->syncLogAppendEntry = raftLogAppendEntry; @@ -285,6 +331,8 @@ SSyncLogStore* logStoreCreate(SSyncNode* pSyncNode) { pLogStore->syncLogTruncate = raftLogTruncate; pLogStore->syncLogWriteIndex = raftLogWriteIndex; + // pLogStore->syncLogInRange = raftLogInRange; + return pLogStore; } @@ -301,7 +349,7 @@ int32_t logStoreAppendEntry(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry) { SWal* pWal = pData->pWal; SyncIndex lastIndex = logStoreLastIndex(pLogStore); - assert(pEntry->index == lastIndex + 1); + ASSERT(pEntry->index == lastIndex + 1); int code = 0; SSyncLogMeta syncMeta; @@ -347,10 +395,10 @@ SSyncRaftEntry* logStoreGetEntry(SSyncLogStore* pLogStore, SyncIndex index) { linuxErrMsg); ASSERT(0); } - // assert(walReadWithHandle(pWalHandle, index) == 0); + // ASSERT(walReadWithHandle(pWalHandle, index) == 0); SSyncRaftEntry* pEntry = syncEntryBuild(pWalHandle->pHead->head.bodyLen); - assert(pEntry != NULL); + ASSERT(pEntry != NULL); pEntry->msgType = TDMT_SYNC_CLIENT_REQUEST; pEntry->originalRpcType = pWalHandle->pHead->head.msgType; @@ -358,7 +406,7 @@ SSyncRaftEntry* logStoreGetEntry(SSyncLogStore* pLogStore, SyncIndex index) { pEntry->isWeak = pWalHandle->pHead->head.syncMeta.isWeek; pEntry->term = pWalHandle->pHead->head.syncMeta.term; pEntry->index = index; - assert(pEntry->dataLen == pWalHandle->pHead->head.bodyLen); + ASSERT(pEntry->dataLen == pWalHandle->pHead->head.bodyLen); memcpy(pEntry->data, pWalHandle->pHead->head.body, pWalHandle->pHead->head.bodyLen); // need to hold, do not new every time!! @@ -373,7 +421,7 @@ SSyncRaftEntry* logStoreGetEntry(SSyncLogStore* pLogStore, SyncIndex index) { int32_t logStoreTruncate(SSyncLogStore* pLogStore, SyncIndex fromIndex) { SSyncLogStoreData* pData = pLogStore->data; SWal* pWal = pData->pWal; - // assert(walRollback(pWal, fromIndex) == 0); + // ASSERT(walRollback(pWal, fromIndex) == 0); int32_t code = walRollback(pWal, fromIndex); if (code != 0) { int32_t err = terrno; @@ -407,7 +455,7 @@ SyncTerm logStoreLastTerm(SSyncLogStore* pLogStore) { int32_t logStoreUpdateCommitIndex(SSyncLogStore* pLogStore, SyncIndex index) { SSyncLogStoreData* pData = pLogStore->data; SWal* pWal = pData->pWal; - // assert(walCommit(pWal, index) == 0); + // ASSERT(walCommit(pWal, index) == 0); int32_t code = walCommit(pWal, index); if (code != 0) { int32_t err = terrno; diff --git a/source/libs/sync/src/syncRaftStore.c b/source/libs/sync/src/syncRaftStore.c index 52e8152926..a1ab95c00f 100644 --- a/source/libs/sync/src/syncRaftStore.c +++ b/source/libs/sync/src/syncRaftStore.c @@ -39,40 +39,40 @@ SRaftStore *raftStoreOpen(const char *path) { if (!raftStoreFileExist(pRaftStore->path)) { ret = raftStoreInit(pRaftStore); - assert(ret == 0); + ASSERT(ret == 0); } pRaftStore->pFile = taosOpenFile(path, TD_FILE_READ | TD_FILE_WRITE); - assert(pRaftStore->pFile != NULL); + ASSERT(pRaftStore->pFile != NULL); int len = taosReadFile(pRaftStore->pFile, storeBuf, RAFT_STORE_BLOCK_SIZE); - assert(len == RAFT_STORE_BLOCK_SIZE); + ASSERT(len == RAFT_STORE_BLOCK_SIZE); ret = raftStoreDeserialize(pRaftStore, storeBuf, len); - assert(ret == 0); + ASSERT(ret == 0); return pRaftStore; } static int32_t raftStoreInit(SRaftStore *pRaftStore) { - assert(pRaftStore != NULL); + ASSERT(pRaftStore != NULL); pRaftStore->pFile = taosOpenFile(pRaftStore->path, TD_FILE_CREATE | TD_FILE_WRITE); - assert(pRaftStore->pFile != NULL); + ASSERT(pRaftStore->pFile != NULL); pRaftStore->currentTerm = 0; pRaftStore->voteFor.addr = 0; pRaftStore->voteFor.vgId = 0; int32_t ret = raftStorePersist(pRaftStore); - assert(ret == 0); + ASSERT(ret == 0); taosCloseFile(&pRaftStore->pFile); return 0; } int32_t raftStoreClose(SRaftStore *pRaftStore) { - assert(pRaftStore != NULL); + ASSERT(pRaftStore != NULL); taosCloseFile(&pRaftStore->pFile); taosMemoryFree(pRaftStore); @@ -81,17 +81,17 @@ int32_t raftStoreClose(SRaftStore *pRaftStore) { } int32_t raftStorePersist(SRaftStore *pRaftStore) { - assert(pRaftStore != NULL); + ASSERT(pRaftStore != NULL); int32_t ret; char storeBuf[RAFT_STORE_BLOCK_SIZE] = {0}; ret = raftStoreSerialize(pRaftStore, storeBuf, sizeof(storeBuf)); - assert(ret == 0); + ASSERT(ret == 0); taosLSeekFile(pRaftStore->pFile, 0, SEEK_SET); ret = taosWriteFile(pRaftStore->pFile, storeBuf, sizeof(storeBuf)); - assert(ret == RAFT_STORE_BLOCK_SIZE); + ASSERT(ret == RAFT_STORE_BLOCK_SIZE); taosFsyncFile(pRaftStore->pFile); return 0; @@ -103,7 +103,7 @@ static bool raftStoreFileExist(char *path) { } int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len) { - assert(pRaftStore != NULL); + ASSERT(pRaftStore != NULL); cJSON *pRoot = cJSON_CreateObject(); @@ -125,7 +125,7 @@ int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len) { char *serialized = cJSON_Print(pRoot); int len2 = strlen(serialized); - assert(len2 < len); + ASSERT(len2 < len); memset(buf, 0, len); snprintf(buf, len, "%s", serialized); taosMemoryFree(serialized); @@ -135,17 +135,17 @@ int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len) { } int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len) { - assert(pRaftStore != NULL); + ASSERT(pRaftStore != NULL); - assert(len > 0 && len <= RAFT_STORE_BLOCK_SIZE); + ASSERT(len > 0 && len <= RAFT_STORE_BLOCK_SIZE); cJSON *pRoot = cJSON_Parse(buf); cJSON *pCurrentTerm = cJSON_GetObjectItem(pRoot, "current_term"); - assert(cJSON_IsString(pCurrentTerm)); + ASSERT(cJSON_IsString(pCurrentTerm)); sscanf(pCurrentTerm->valuestring, "%lu", &(pRaftStore->currentTerm)); cJSON *pVoteForAddr = cJSON_GetObjectItem(pRoot, "vote_for_addr"); - assert(cJSON_IsString(pVoteForAddr)); + ASSERT(cJSON_IsString(pVoteForAddr)); sscanf(pVoteForAddr->valuestring, "%lu", &(pRaftStore->voteFor.addr)); cJSON *pVoteForVgid = cJSON_GetObjectItem(pRoot, "vote_for_vgid"); @@ -161,7 +161,7 @@ bool raftStoreHasVoted(SRaftStore *pRaftStore) { } void raftStoreVote(SRaftStore *pRaftStore, SRaftId *pRaftId) { - assert(!syncUtilEmptyId(pRaftId)); + ASSERT(!syncUtilEmptyId(pRaftId)); pRaftStore->voteFor = *pRaftId; raftStorePersist(pRaftStore); } @@ -216,7 +216,7 @@ cJSON *raftStore2Json(SRaftStore *pRaftStore) { char *raftStore2Str(SRaftStore *pRaftStore) { cJSON *pJson = raftStore2Json(pRaftStore); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } diff --git a/source/libs/sync/src/syncReplication.c b/source/libs/sync/src/syncReplication.c index f044ae5733..d6e6fbe522 100644 --- a/source/libs/sync/src/syncReplication.c +++ b/source/libs/sync/src/syncReplication.c @@ -49,7 +49,7 @@ // /\ UNCHANGED <> // int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) { - assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER); + ASSERT(pSyncNode->state == TAOS_SYNC_STATE_LEADER); syncIndexMgrLog2("==syncNodeAppendEntriesPeers== pNextIndex", pSyncNode->pNextIndex); syncIndexMgrLog2("==syncNodeAppendEntriesPeers== pMatchIndex", pSyncNode->pMatchIndex); @@ -68,7 +68,7 @@ int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) { SyncTerm preLogTerm = 0; if (preLogIndex >= SYNC_INDEX_BEGIN) { SSyncRaftEntry* pPreEntry = pSyncNode->pLogStore->getEntry(pSyncNode->pLogStore, preLogIndex); - assert(pPreEntry != NULL); + ASSERT(pPreEntry != NULL); preLogTerm = pPreEntry->term; syncEntryDestory(pPreEntry); @@ -81,12 +81,12 @@ int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) { SSyncRaftEntry* pEntry = pSyncNode->pLogStore->getEntry(pSyncNode->pLogStore, nextIndex); if (pEntry != NULL) { pMsg = syncAppendEntriesBuild(pEntry->bytes, pSyncNode->vgId); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); // add pEntry into msg uint32_t len; char* serialized = syncEntrySerialize(pEntry, &len); - assert(len == pEntry->bytes); + ASSERT(len == pEntry->bytes); memcpy(pMsg->data, serialized, len); taosMemoryFree(serialized); @@ -95,10 +95,10 @@ int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) { } else { // maybe overflow, send empty record pMsg = syncAppendEntriesBuild(0, pSyncNode->vgId); - assert(pMsg != NULL); + ASSERT(pMsg != NULL); } - assert(pMsg != NULL); + ASSERT(pMsg != NULL); pMsg->srcId = pSyncNode->myRaftId; pMsg->destId = *pDestId; pMsg->term = pSyncNode->pRaftStore->currentTerm; @@ -148,25 +148,32 @@ int32_t syncNodeAppendEntriesPeersSnapshot(SSyncNode* pSyncNode) { SSyncRaftEntry* pEntry; int32_t code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, nextIndex, &pEntry); - ASSERT(code == 0); - if (pEntry != NULL) { + if (code == 0) { + ASSERT(pEntry != NULL); + pMsg = syncAppendEntriesBuild(pEntry->bytes, pSyncNode->vgId); ASSERT(pMsg != NULL); // add pEntry into msg uint32_t len; char* serialized = syncEntrySerialize(pEntry, &len); - assert(len == pEntry->bytes); + ASSERT(len == pEntry->bytes); memcpy(pMsg->data, serialized, len); taosMemoryFree(serialized); syncEntryDestory(pEntry); } else { - // no entry in log - pMsg = syncAppendEntriesBuild(0, pSyncNode->vgId); - ASSERT(pMsg != NULL); + if (terrno == TSDB_CODE_WAL_LOG_NOT_EXIST) { + // no entry in log + pMsg = syncAppendEntriesBuild(0, pSyncNode->vgId); + ASSERT(pMsg != NULL); + + } else { + syncNodeLog3("", pSyncNode); + ASSERT(0); + } } // prepare msg diff --git a/source/libs/sync/src/syncRequestVote.c b/source/libs/sync/src/syncRequestVote.c index 9ed7f00982..def5c321ad 100644 --- a/source/libs/sync/src/syncRequestVote.c +++ b/source/libs/sync/src/syncRequestVote.c @@ -52,7 +52,7 @@ int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) { if (pMsg->term > ths->pRaftStore->currentTerm) { syncNodeUpdateTerm(ths, pMsg->term); } - assert(pMsg->term <= ths->pRaftStore->currentTerm); + ASSERT(pMsg->term <= ths->pRaftStore->currentTerm); bool logOK = (pMsg->lastLogTerm > ths->pLogStore->getLastTerm(ths->pLogStore)) || ((pMsg->lastLogTerm == ths->pLogStore->getLastTerm(ths->pLogStore)) && diff --git a/source/libs/sync/src/syncRequestVoteReply.c b/source/libs/sync/src/syncRequestVoteReply.c index 5d041cefcd..60963d0dd3 100644 --- a/source/libs/sync/src/syncRequestVoteReply.c +++ b/source/libs/sync/src/syncRequestVoteReply.c @@ -50,7 +50,7 @@ int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) return ret; } - // assert(!(pMsg->term > ths->pRaftStore->currentTerm)); + // ASSERT(!(pMsg->term > ths->pRaftStore->currentTerm)); // no need this code, because if I receive reply.term, then I must have sent for that term. // if (pMsg->term > ths->pRaftStore->currentTerm) { // syncNodeUpdateTerm(ths, pMsg->term); @@ -65,7 +65,7 @@ int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) return ret; } - assert(pMsg->term == ths->pRaftStore->currentTerm); + ASSERT(pMsg->term == ths->pRaftStore->currentTerm); // This tallies votes even when the current state is not Candidate, // but they won't be looked at, so it doesn't matter. @@ -115,7 +115,7 @@ int32_t syncNodeOnRequestVoteReplySnapshotCb(SSyncNode* ths, SyncRequestVoteRepl return ret; } - // assert(!(pMsg->term > ths->pRaftStore->currentTerm)); + // ASSERT(!(pMsg->term > ths->pRaftStore->currentTerm)); // no need this code, because if I receive reply.term, then I must have sent for that term. // if (pMsg->term > ths->pRaftStore->currentTerm) { // syncNodeUpdateTerm(ths, pMsg->term); diff --git a/source/libs/sync/src/syncRespMgr.c b/source/libs/sync/src/syncRespMgr.c index 354575d29e..48c1b70a04 100644 --- a/source/libs/sync/src/syncRespMgr.c +++ b/source/libs/sync/src/syncRespMgr.c @@ -22,7 +22,7 @@ SSyncRespMgr *syncRespMgrCreate(void *data, int64_t ttl) { pObj->pRespHash = taosHashInit(sizeof(uint64_t), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); - assert(pObj->pRespHash != NULL); + ASSERT(pObj->pRespHash != NULL); pObj->ttl = ttl; pObj->data = data; pObj->seqNum = 0; diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index c694a0b715..ff3dc56f71 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -67,51 +67,55 @@ void snapshotSenderDestroy(SSyncSnapshotSender *pSender) { bool snapshotSenderIsStart(SSyncSnapshotSender *pSender) { return pSender->start; } // begin send snapshot (current term, seq begin) -void snapshotSenderStart(SSyncSnapshotSender *pSender) { +void snapshotSenderStart(SSyncSnapshotSender *pSender, SSnapshot snapshot, void *pReader) { ASSERT(!snapshotSenderIsStart(pSender)); pSender->seq = SYNC_SNAPSHOT_SEQ_BEGIN; pSender->ack = SYNC_SNAPSHOT_SEQ_INVALID; - // open snapshot reader + // init snapshot and reader ASSERT(pSender->pReader == NULL); - int32_t ret = pSender->pSyncNode->pFsm->FpSnapshotStartRead(pSender->pSyncNode->pFsm, &(pSender->pReader)); - ASSERT(ret == 0); + pSender->pReader = pReader; + pSender->snapshot = snapshot; if (pSender->pCurrentBlock != NULL) { taosMemoryFree(pSender->pCurrentBlock); } - pSender->blockLen = 0; - // get current snapshot info - pSender->pSyncNode->pFsm->FpGetSnapshotInfo(pSender->pSyncNode->pFsm, &(pSender->snapshot)); - - sTrace("snapshotSenderStart lastApplyIndex:%ld, lastApplyTerm:%lu, lastConfigIndex:%ld", - pSender->snapshot.lastApplyIndex, pSender->snapshot.lastApplyTerm, pSender->snapshot.lastConfigIndex); - if (pSender->snapshot.lastConfigIndex != SYNC_INDEX_INVALID) { - /* + int32_t code = 0; SSyncRaftEntry *pEntry = NULL; - int32_t code = pSender->pSyncNode->pLogStore->syncLogGetEntry(pSender->pSyncNode->pLogStore, - pSender->snapshot.lastConfigIndex, &pEntry); - ASSERT(code == 0); - ASSERT(pEntry != NULL); - */ + code = pSender->pSyncNode->pLogStore->syncLogGetEntry(pSender->pSyncNode->pLogStore, + pSender->snapshot.lastConfigIndex, &pEntry); - SSyncRaftEntry *pEntry = - pSender->pSyncNode->pLogStore->getEntry(pSender->pSyncNode->pLogStore, pSender->snapshot.lastConfigIndex); - ASSERT(pEntry != NULL); + bool getLastConfig = false; + if (code == 0) { + ASSERT(pEntry != NULL); - SRpcMsg rpcMsg; - syncEntry2OriginalRpc(pEntry, &rpcMsg); - SSyncCfg lastConfig; - int32_t ret = syncCfgFromStr(rpcMsg.pCont, &lastConfig); - ASSERT(ret == 0); - pSender->lastConfig = lastConfig; + SRpcMsg rpcMsg; + syncEntry2OriginalRpc(pEntry, &rpcMsg); - rpcFreeCont(rpcMsg.pCont); - syncEntryDestory(pEntry); + SSyncCfg lastConfig; + int32_t ret = syncCfgFromStr(rpcMsg.pCont, &lastConfig); + ASSERT(ret == 0); + pSender->lastConfig = lastConfig; + getLastConfig = true; + + rpcFreeCont(rpcMsg.pCont); + syncEntryDestory(pEntry); + } else { + if (pSender->snapshot.lastConfigIndex == pSender->pSyncNode->pRaftCfg->lastConfigIndex) { + sTrace("vgId:%d sync sender get cfg from local", pSender->pSyncNode->vgId); + pSender->lastConfig = pSender->pSyncNode->pRaftCfg->cfg; + getLastConfig = true; + } + } + + if (!getLastConfig) { + syncNodeLog3("", pSender->pSyncNode); + ASSERT(0); + } } else { memset(&(pSender->lastConfig), 0, sizeof(SSyncCfg)); @@ -529,6 +533,10 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) { ASSERT(writeCode == 0); pSyncNode->pFsm->FpSnapshotStopWrite(pSyncNode->pFsm, pReceiver->pWriter, true); + if (pReceiver->snapshot.lastApplyIndex > pReceiver->pSyncNode->commitIndex) { + pReceiver->pSyncNode->commitIndex = pReceiver->snapshot.lastApplyIndex; + } + pSyncNode->pLogStore->syncLogSetBeginIndex(pSyncNode->pLogStore, pMsg->lastIndex + 1); // maybe update lastconfig @@ -548,7 +556,7 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) { pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot); do { - char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver finish"); + char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver finish, apply snapshot"); syncNodeEventLog(pSyncNode, eventLog); taosMemoryFree(eventLog); } while (0); @@ -559,7 +567,7 @@ int32_t syncNodeOnSnapshotSendCb(SSyncNode *pSyncNode, SyncSnapshotSend *pMsg) { needRsp = true; do { - char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver end"); + char *eventLog = snapshotReceiver2SimpleStr(pReceiver, "snapshot receiver stop"); syncNodeEventLog(pSyncNode, eventLog); taosMemoryFree(eventLog); } while (0); diff --git a/source/libs/sync/src/syncUtil.c b/source/libs/sync/src/syncUtil.c index 1d1ff7ae53..5b73d980c4 100644 --- a/source/libs/sync/src/syncUtil.c +++ b/source/libs/sync/src/syncUtil.c @@ -86,7 +86,7 @@ void syncUtilraftId2EpSet(const SRaftId* raftId, SEpSet* pEpSet) { void syncUtilnodeInfo2raftId(const SNodeInfo* pNodeInfo, SyncGroupId vgId, SRaftId* raftId) { uint32_t ipv4 = taosGetIpv4FromFqdn(pNodeInfo->nodeFqdn); - assert(ipv4 != 0xFFFFFFFF); + ASSERT(ipv4 != 0xFFFFFFFF); char ipbuf[128] = {0}; tinet_ntoa(ipbuf, ipv4); raftId->addr = syncUtilAddr2U64(ipbuf, pNodeInfo->nodePort); @@ -124,7 +124,7 @@ void syncUtilbufCopyDeep(const SSyncBuffer* src, SSyncBuffer* dest) { int32_t syncUtilRand(int32_t max) { return taosRand() % max; } int32_t syncUtilElectRandomMS(int32_t min, int32_t max) { - assert(min > 0 && max > 0 && max >= min); + ASSERT(min > 0 && max > 0 && max >= min); return min + syncUtilRand(max - min); } @@ -201,7 +201,7 @@ bool syncUtilCanPrint(char c) { char* syncUtilprintBin(char* ptr, uint32_t len) { char* s = taosMemoryMalloc(len + 1); - assert(s != NULL); + ASSERT(s != NULL); memset(s, 0, len + 1); memcpy(s, ptr, len); @@ -216,7 +216,7 @@ char* syncUtilprintBin(char* ptr, uint32_t len) { char* syncUtilprintBin2(char* ptr, uint32_t len) { uint32_t len2 = len * 4 + 1; char* s = taosMemoryMalloc(len2); - assert(s != NULL); + ASSERT(s != NULL); memset(s, 0, len2); char* p = s; diff --git a/source/libs/sync/src/syncVoteMgr.c b/source/libs/sync/src/syncVoteMgr.c index 528c2f26c8..d6c2cbd34e 100644 --- a/source/libs/sync/src/syncVoteMgr.c +++ b/source/libs/sync/src/syncVoteMgr.c @@ -24,7 +24,7 @@ static void voteGrantedClearVotes(SVotesGranted *pVotesGranted) { SVotesGranted *voteGrantedCreate(SSyncNode *pSyncNode) { SVotesGranted *pVotesGranted = taosMemoryMalloc(sizeof(SVotesGranted)); - assert(pVotesGranted != NULL); + ASSERT(pVotesGranted != NULL); memset(pVotesGranted, 0, sizeof(SVotesGranted)); pVotesGranted->replicas = &(pSyncNode->replicasId); @@ -62,9 +62,9 @@ bool voteGrantedMajority(SVotesGranted *pVotesGranted) { } void voteGrantedVote(SVotesGranted *pVotesGranted, SyncRequestVoteReply *pMsg) { - assert(pMsg->voteGranted == true); - assert(pMsg->term == pVotesGranted->term); - assert(syncUtilSameId(&pVotesGranted->pSyncNode->myRaftId, &pMsg->destId)); + ASSERT(pMsg->voteGranted == true); + ASSERT(pMsg->term == pVotesGranted->term); + ASSERT(syncUtilSameId(&pVotesGranted->pSyncNode->myRaftId, &pMsg->destId)); int j = -1; for (int i = 0; i < pVotesGranted->replicaNum; ++i) { @@ -73,14 +73,14 @@ void voteGrantedVote(SVotesGranted *pVotesGranted, SyncRequestVoteReply *pMsg) { break; } } - assert(j != -1); - assert(j >= 0 && j < pVotesGranted->replicaNum); + ASSERT(j != -1); + ASSERT(j >= 0 && j < pVotesGranted->replicaNum); if (pVotesGranted->isGranted[j] != true) { ++(pVotesGranted->votes); pVotesGranted->isGranted[j] = true; } - assert(pVotesGranted->votes <= pVotesGranted->replicaNum); + ASSERT(pVotesGranted->votes <= pVotesGranted->replicaNum); } void voteGrantedReset(SVotesGranted *pVotesGranted, SyncTerm term) { @@ -127,7 +127,7 @@ cJSON *voteGranted2Json(SVotesGranted *pVotesGranted) { char *voteGranted2Str(SVotesGranted *pVotesGranted) { cJSON *pJson = voteGranted2Json(pVotesGranted); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } @@ -162,7 +162,7 @@ void voteGrantedLog2(char *s, SVotesGranted *pObj) { // SVotesRespond ----------------------------- SVotesRespond *votesRespondCreate(SSyncNode *pSyncNode) { SVotesRespond *pVotesRespond = taosMemoryMalloc(sizeof(SVotesRespond)); - assert(pVotesRespond != NULL); + ASSERT(pVotesRespond != NULL); memset(pVotesRespond, 0, sizeof(SVotesRespond)); pVotesRespond->replicas = &(pSyncNode->replicasId); @@ -198,15 +198,15 @@ bool votesResponded(SVotesRespond *pVotesRespond, const SRaftId *pRaftId) { } void votesRespondAdd(SVotesRespond *pVotesRespond, const SyncRequestVoteReply *pMsg) { - assert(pVotesRespond->term == pMsg->term); + ASSERT(pVotesRespond->term == pMsg->term); for (int i = 0; i < pVotesRespond->replicaNum; ++i) { if (syncUtilSameId(&((*(pVotesRespond->replicas))[i]), &pMsg->srcId)) { - // assert(pVotesRespond->isRespond[i] == false); + // ASSERT(pVotesRespond->isRespond[i] == false); pVotesRespond->isRespond[i] = true; return; } } - assert(0); + ASSERT(0); } void votesRespondReset(SVotesRespond *pVotesRespond, SyncTerm term) { @@ -256,7 +256,7 @@ cJSON *votesRespond2Json(SVotesRespond *pVotesRespond) { char *votesRespond2Str(SVotesRespond *pVotesRespond) { cJSON *pJson = votesRespond2Json(pVotesRespond); - char * serialized = cJSON_Print(pJson); + char *serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } diff --git a/source/libs/sync/test/CMakeLists.txt b/source/libs/sync/test/CMakeLists.txt index 2057aa23a4..27084286da 100644 --- a/source/libs/sync/test/CMakeLists.txt +++ b/source/libs/sync/test/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(syncWriteTest "") add_executable(syncReplicateTest "") add_executable(syncRefTest "") add_executable(syncLogStoreCheck "") +add_executable(syncLogStoreCheck2 "") add_executable(syncRaftCfgTest "") add_executable(syncRespMgrTest "") add_executable(syncSnapshotTest "") @@ -196,6 +197,10 @@ target_sources(syncLogStoreCheck PRIVATE "syncLogStoreCheck.cpp" ) +target_sources(syncLogStoreCheck2 + PRIVATE + "syncLogStoreCheck2.cpp" +) target_sources(syncRaftCfgTest PRIVATE "syncRaftCfgTest.cpp" @@ -442,6 +447,11 @@ target_include_directories(syncLogStoreCheck "${TD_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) +target_include_directories(syncLogStoreCheck2 + PUBLIC + "${TD_SOURCE_DIR}/include/libs/sync" + "${CMAKE_CURRENT_SOURCE_DIR}/../inc" +) target_include_directories(syncRaftCfgTest PUBLIC "${TD_SOURCE_DIR}/include/libs/sync" @@ -668,6 +678,10 @@ target_link_libraries(syncLogStoreCheck sync gtest_main ) +target_link_libraries(syncLogStoreCheck2 + sync + gtest_main +) target_link_libraries(syncRaftCfgTest sync gtest_main diff --git a/source/libs/sync/test/syncLogStoreCheck2.cpp b/source/libs/sync/test/syncLogStoreCheck2.cpp new file mode 100644 index 0000000000..80679bc85c --- /dev/null +++ b/source/libs/sync/test/syncLogStoreCheck2.cpp @@ -0,0 +1,76 @@ +#include +#include +#include "syncEnv.h" +#include "syncIO.h" +#include "syncInt.h" +#include "syncRaftLog.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "wal.h" + +void logTest() { + sTrace("--- sync log test: trace"); + sDebug("--- sync log test: debug"); + sInfo("--- sync log test: info"); + sWarn("--- sync log test: warn"); + sError("--- sync log test: error"); + sFatal("--- sync log test: fatal"); +} + +void init() { + int code = walInit(); + assert(code == 0); +} + +void cleanup() { walCleanUp(); } + +SWal* createWal(char* path, int32_t vgId) { + SWalCfg walCfg; + memset(&walCfg, 0, sizeof(SWalCfg)); + walCfg.vgId = vgId; + walCfg.fsyncPeriod = 1000; + walCfg.retentionPeriod = 1000; + walCfg.rollPeriod = 1000; + walCfg.retentionSize = 1000; + walCfg.segSize = 1000; + walCfg.level = TAOS_WAL_FSYNC; + SWal* pWal = walOpen(path, &walCfg); + assert(pWal != NULL); + return pWal; +} + +SSyncNode* createSyncNode(SWal* pWal) { + SSyncNode* pSyncNode = (SSyncNode*)taosMemoryMalloc(sizeof(SSyncNode)); + memset(pSyncNode, 0, sizeof(SSyncNode)); + pSyncNode->pWal = pWal; + return pSyncNode; +} + +void usage(char* exe) { printf("usage: %s path vgId \n", exe); } + +int main(int argc, char** argv) { + if (argc != 3) { + usage(argv[0]); + exit(-1); + } + char* path = argv[1]; + int32_t vgId = atoi(argv[2]); + + init(); + SWal* pWal = createWal(path, vgId); + assert(pWal != NULL); + SSyncNode* pSyncNode = createSyncNode(pWal); + assert(pSyncNode != NULL); + + SSyncLogStore* pLog = logStoreCreate(pSyncNode); + assert(pLog != NULL); + + logStoreSimplePrint2((char*)"==syncLogStoreCheck2==", pLog); + + walClose(pWal); + logStoreDestory(pLog); + taosMemoryFree(pSyncNode); + + cleanup(); + return 0; +} diff --git a/source/libs/sync/test/syncRaftLogTest2.cpp b/source/libs/sync/test/syncRaftLogTest2.cpp index 32ff441a6f..bd6fa7c2c3 100644 --- a/source/libs/sync/test/syncRaftLogTest2.cpp +++ b/source/libs/sync/test/syncRaftLogTest2.cpp @@ -69,6 +69,7 @@ void test1() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest1 ----- ", pLogStore); if (gAssert) { @@ -88,6 +89,7 @@ void test1() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest1 restart ----- ", pLogStore); if (gAssert) { @@ -110,6 +112,7 @@ void test2() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; pLogStore->syncLogSetBeginIndex(pLogStore, 5); logStoreLog2((char*)"\n\n\ntest2 ----- ", pLogStore); @@ -130,6 +133,7 @@ void test2() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest2 restart ----- ", pLogStore); if (gAssert) { @@ -152,6 +156,7 @@ void test3() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest3 ----- ", pLogStore); if (gAssert) { @@ -198,6 +203,7 @@ void test3() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest3 restart ----- ", pLogStore); if (gAssert) { @@ -220,6 +226,7 @@ void test4() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest4 ----- ", pLogStore); pLogStore->syncLogSetBeginIndex(pLogStore, 5); @@ -257,6 +264,7 @@ void test4() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest4 restart ----- ", pLogStore); if (gAssert) { @@ -279,6 +287,7 @@ void test5() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest5 ----- ", pLogStore); pLogStore->syncLogSetBeginIndex(pLogStore, 5); @@ -329,6 +338,7 @@ void test5() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest5 restart ----- ", pLogStore); if (gAssert) { @@ -351,6 +361,7 @@ void test6() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest6 ----- ", pLogStore); pLogStore->syncLogSetBeginIndex(pLogStore, 5); @@ -401,6 +412,7 @@ void test6() { init(); pLogStore = logStoreCreate(pSyncNode); assert(pLogStore); + pSyncNode->pLogStore = pLogStore; logStoreLog2((char*)"\n\n\ntest6 restart ----- ", pLogStore); if (gAssert) { diff --git a/source/libs/sync/test/syncReconfigFinishTest.cpp b/source/libs/sync/test/syncReconfigFinishTest.cpp index 22e22bb562..2aac38bbd1 100644 --- a/source/libs/sync/test/syncReconfigFinishTest.cpp +++ b/source/libs/sync/test/syncReconfigFinishTest.cpp @@ -14,8 +14,8 @@ void logTest() { sFatal("--- sync log test: fatal"); } -SSyncCfg* createSyncOldCfg() { - SSyncCfg* pCfg = (SSyncCfg*)taosMemoryMalloc(sizeof(SSyncCfg)); +SSyncCfg *createSyncOldCfg() { + SSyncCfg *pCfg = (SSyncCfg *)taosMemoryMalloc(sizeof(SSyncCfg)); memset(pCfg, 0, sizeof(SSyncCfg)); pCfg->replicaNum = 3; @@ -28,8 +28,8 @@ SSyncCfg* createSyncOldCfg() { return pCfg; } -SSyncCfg* createSyncNewCfg() { - SSyncCfg* pCfg = (SSyncCfg*)taosMemoryMalloc(sizeof(SSyncCfg)); +SSyncCfg *createSyncNewCfg() { + SSyncCfg *pCfg = (SSyncCfg *)taosMemoryMalloc(sizeof(SSyncCfg)); memset(pCfg, 0, sizeof(SSyncCfg)); pCfg->replicaNum = 3; @@ -44,9 +44,9 @@ SSyncCfg* createSyncNewCfg() { SyncReconfigFinish *createMsg() { SyncReconfigFinish *pMsg = syncReconfigFinishBuild(1234); - - SSyncCfg* pOld = createSyncOldCfg(); - SSyncCfg* pNew = createSyncNewCfg(); + + SSyncCfg *pOld = createSyncOldCfg(); + SSyncCfg *pNew = createSyncNewCfg(); pMsg->oldCfg = *pOld; pMsg->newCfg = *pNew; @@ -60,18 +60,16 @@ SyncReconfigFinish *createMsg() { return pMsg; } - void test1() { SyncReconfigFinish *pMsg = createMsg(); syncReconfigFinishLog2((char *)"test1:", pMsg); syncReconfigFinishDestroy(pMsg); } - void test2() { SyncReconfigFinish *pMsg = createMsg(); - uint32_t len = pMsg->bytes; - char * serialized = (char *)taosMemoryMalloc(len); + uint32_t len = pMsg->bytes; + char * serialized = (char *)taosMemoryMalloc(len); syncReconfigFinishSerialize(pMsg, serialized, len); SyncReconfigFinish *pMsg2 = syncReconfigFinishBuild(1000); syncReconfigFinishDeserialize(serialized, len, pMsg2); @@ -84,8 +82,8 @@ void test2() { void test3() { SyncReconfigFinish *pMsg = createMsg(); - uint32_t len; - char * serialized = syncReconfigFinishSerialize2(pMsg, &len); + uint32_t len; + char * serialized = syncReconfigFinishSerialize2(pMsg, &len); SyncReconfigFinish *pMsg2 = syncReconfigFinishDeserialize2(serialized, len); syncReconfigFinishLog2((char *)"test3: SyncReconfigFinishSerialize2 -> syncReconfigFinishDeserialize2 ", pMsg2); @@ -96,7 +94,7 @@ void test3() { void test4() { SyncReconfigFinish *pMsg = createMsg(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncReconfigFinish2RpcMsg(pMsg, &rpcMsg); SyncReconfigFinish *pMsg2 = (SyncReconfigFinish *)taosMemoryMalloc(rpcMsg.contLen); syncReconfigFinishFromRpcMsg(&rpcMsg, pMsg2); @@ -109,7 +107,7 @@ void test4() { void test5() { SyncReconfigFinish *pMsg = createMsg(); - SRpcMsg rpcMsg; + SRpcMsg rpcMsg; syncReconfigFinish2RpcMsg(pMsg, &rpcMsg); SyncReconfigFinish *pMsg2 = syncReconfigFinishFromRpcMsg2(&rpcMsg); syncReconfigFinishLog2((char *)"test5: syncReconfigFinish2RpcMsg -> syncReconfigFinishFromRpcMsg2 ", pMsg2); diff --git a/source/libs/tdb/src/db/tdbBtree.c b/source/libs/tdb/src/db/tdbBtree.c index 45e71f6c0d..1c924fa636 100644 --- a/source/libs/tdb/src/db/tdbBtree.c +++ b/source/libs/tdb/src/db/tdbBtree.c @@ -56,14 +56,9 @@ typedef struct { } SIntHdr; #pragma pack(pop) -typedef struct { - u8 flags; - SBTree *pBt; -} SBtreeInitPageArg; - static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2); static int tdbBtreeOpenImpl(SBTree *pBt); -static int tdbBtreeInitPage(SPage *pPage, void *arg, int init); +//static int tdbBtreeInitPage(SPage *pPage, void *arg, int init); static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell, int *szCell, TXN *pTxn, SBTree *pBt); static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt); @@ -348,7 +343,7 @@ static int tdbBtreeOpenImpl(SBTree *pBt) { return 0; } -static int tdbBtreeInitPage(SPage *pPage, void *arg, int init) { +int tdbBtreeInitPage(SPage *pPage, void *arg, int init) { SBTree *pBt; u8 flags; u8 leaf; diff --git a/source/libs/tdb/src/db/tdbPager.c b/source/libs/tdb/src/db/tdbPager.c index a74bb54883..dd3f09d5d2 100644 --- a/source/libs/tdb/src/db/tdbPager.c +++ b/source/libs/tdb/src/db/tdbPager.c @@ -424,4 +424,71 @@ static int tdbPagerWritePageToDB(SPager *pPager, SPage *pPage) { } return 0; -} \ No newline at end of file +} + +int tdbPagerRestore(SPager *pPager, SBTree *pBt) { + int ret = 0; + SPgno journalSize = 0; + u8 *pageBuf = NULL; + + tdb_fd_t jfd = tdbOsOpen(pPager->jFileName, TDB_O_RDWR, 0755); + if (jfd == NULL) { + return 0; + } + + ret = tdbGetFileSize(jfd, pPager->pageSize, &journalSize); + if (ret < 0) { + return -1; + } + + pageBuf = tdbOsCalloc(1, pPager->pageSize); + if (pageBuf == NULL) { + return -1; + } + + TXN txn; + tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, 0); + SBtreeInitPageArg iArg; + iArg.pBt = pBt; + iArg.flags = 0; + + for (int pgIndex = 0; pgIndex < journalSize; ++pgIndex) { + // read pgno & the page from journal + SPgno pgno; + SPage *pPage; + + int ret = tdbOsRead(jfd, &pgno, sizeof(pgno)); + if (ret < 0) { + return -1; + } + + ret = tdbOsRead(jfd, pageBuf, pPager->pageSize); + if (ret < 0) { + return -1; + } + + ret = tdbPagerFetchPage(pPager, &pgno, &pPage, tdbBtreeInitPage, &iArg, &txn); + if (ret < 0) { + return -1; + } + + // write the page to db + ret = tdbPagerWritePageToDB(pPager, pPage); + if (ret < 0) { + return -1; + } + + tdbPCacheRelease(pPager->pCache, pPage, &txn); + } + + tdbOsFSync(pPager->fd); + + tdbTxnClose(&txn); + + tdbOsFree(pageBuf); + + tdbOsClose(jfd); + tdbOsRemove(pPager->jFileName); + + return 0; +} diff --git a/source/libs/tdb/src/db/tdbTable.c b/source/libs/tdb/src/db/tdbTable.c index 1575f9f206..f1bfb4eabc 100644 --- a/source/libs/tdb/src/db/tdbTable.c +++ b/source/libs/tdb/src/db/tdbTable.c @@ -61,6 +61,11 @@ int tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprF return -1; } + ret = tdbPagerRestore(pPager, pTb->pBt); + if (ret < 0) { + return -1; + } + *ppTb = pTb; return 0; } diff --git a/source/libs/tdb/src/db/tdbUtil.c b/source/libs/tdb/src/db/tdbUtil.c index 4acb83c8e4..9021e08ffe 100644 --- a/source/libs/tdb/src/db/tdbUtil.c +++ b/source/libs/tdb/src/db/tdbUtil.c @@ -64,4 +64,4 @@ int tdbGetFileSize(tdb_fd_t fd, int szPage, SPgno *size) { *size = szBytes / szPage; return 0; -} \ No newline at end of file +} diff --git a/source/libs/tdb/src/inc/tdbInt.h b/source/libs/tdb/src/inc/tdbInt.h index 39b5584fab..c914e098f7 100644 --- a/source/libs/tdb/src/inc/tdbInt.h +++ b/source/libs/tdb/src/inc/tdbInt.h @@ -158,6 +158,13 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i int tdbBtreeGet(SBTree *pBt, const void *pKey, int kLen, void **ppVal, int *vLen); int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkLen, void **ppVal, int *vLen); +typedef struct { + u8 flags; + SBTree *pBt; +} SBtreeInitPageArg; + +int tdbBtreeInitPage(SPage *pPage, void *arg, int init); + // SBTC int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn); int tdbBtcClose(SBTC *pBtc); @@ -185,6 +192,7 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initP TXN *pTxn); void tdbPagerReturnPage(SPager *pPager, SPage *pPage, TXN *pTxn); int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno); +int tdbPagerRestore(SPager *pPager, SBTree *pBt); // tdbPCache.c ==================================== #define TDB_PCACHE_PAGE \ diff --git a/source/libs/tdb/src/inc/tdbUtil.h b/source/libs/tdb/src/inc/tdbUtil.h index c518e8efcc..fe97f9c986 100644 --- a/source/libs/tdb/src/inc/tdbUtil.h +++ b/source/libs/tdb/src/inc/tdbUtil.h @@ -20,7 +20,7 @@ extern "C" { #endif -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL #define TDB_STATIC_ASSERT(op, info) static_assert(op, info) #else #define TDB_STATIC_ASSERT(op, info) diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h index 146b127422..327fe50814 100644 --- a/source/libs/transport/inc/transComm.h +++ b/source/libs/transport/inc/transComm.h @@ -183,6 +183,8 @@ typedef enum { ConnNormal, ConnAcquire, ConnRelease, ConnBroken, ConnInPool } Co #define transContLenFromMsg(msgLen) (msgLen - sizeof(STransMsgHead)); #define transIsReq(type) (type & 1U) +#define transLabel(trans) ((STrans*)trans)->label + // int rpcAuthenticateMsg(void* pMsg, int msgLen, void* pAuth, void* pKey); // void rpcBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey); //// int32_t rpcCompressRpcMsg(char* pCont, int32_t contLen); diff --git a/source/libs/transport/inc/transLog.h b/source/libs/transport/inc/transLog.h index 9947ba803f..121939787c 100644 --- a/source/libs/transport/inc/transLog.h +++ b/source/libs/transport/inc/transLog.h @@ -24,16 +24,21 @@ extern "C" { #include "tlog.h" #include "ttrace.h" -#define tFatal(...) do {if (rpcDebugFlag & DEBUG_FATAL){ taosPrintLog("RPC FATAL ", DEBUG_FATAL, rpcDebugFlag, __VA_ARGS__); }} while (0) -#define tError(...)do { if (rpcDebugFlag & DEBUG_ERROR){ taosPrintLog("RPC ERROR ", DEBUG_ERROR, rpcDebugFlag, __VA_ARGS__); } } while(0) -#define tWarn(...) do { if (rpcDebugFlag & DEBUG_WARN) { taosPrintLog("RPC WARN ", DEBUG_WARN, rpcDebugFlag, __VA_ARGS__); }} while(0) -#define tInfo(...) do { if (rpcDebugFlag & DEBUG_INFO) { taosPrintLog("RPC ", DEBUG_INFO, rpcDebugFlag, __VA_ARGS__); }} while(0) -#define tDebug(...) do {if (rpcDebugFlag & DEBUG_DEBUG){ taosPrintLog("RPC ", DEBUG_DEBUG, rpcDebugFlag, __VA_ARGS__); }} while(0) -#define tTrace(...) do {if (rpcDebugFlag & DEBUG_TRACE){ taosPrintLog("RPC ", DEBUG_TRACE, rpcDebugFlag, __VA_ARGS__); }} while(0) -#define tDump(x, y) do {if (rpcDebugFlag & DEBUG_DUMP) { taosDumpData((unsigned char *)x, y); } } while(0) +#define tFatal(...) { if (rpcDebugFlag & DEBUG_FATAL) { taosPrintLog("RPC FATAL ", DEBUG_FATAL, rpcDebugFlag, __VA_ARGS__); }} +#define tError(...) { if (rpcDebugFlag & DEBUG_ERROR ){ taosPrintLog("RPC ERROR ", DEBUG_ERROR, rpcDebugFlag, __VA_ARGS__); }} +#define tWarn(...) { if (rpcDebugFlag & DEBUG_WARN) { taosPrintLog("RPC WARN ", DEBUG_WARN, rpcDebugFlag, __VA_ARGS__); }} +#define tInfo(...) { if (rpcDebugFlag & DEBUG_INFO) { taosPrintLog("RPC ", DEBUG_INFO, rpcDebugFlag, __VA_ARGS__); }} +#define tDebug(...) { if (rpcDebugFlag & DEBUG_DEBUG) { taosPrintLog("RPC ", DEBUG_DEBUG, rpcDebugFlag, __VA_ARGS__); }} +#define tTrace(...) { if (rpcDebugFlag & DEBUG_TRACE) { taosPrintLog("RPC ", DEBUG_TRACE, rpcDebugFlag, __VA_ARGS__); }} +#define tDump(x, y) { if (rpcDebugFlag & DEBUG_DUMP) { taosDumpData((unsigned char *)x, y); } } + +#define tGTrace(param, ...) do { if (rpcDebugFlag & DEBUG_TRACE){char buf[40] = {0}; TRACE_TO_STR(trace, buf); tTrace(param ", gtid:%s", __VA_ARGS__, buf);}} while(0) +#define tGFatal(param, ...) do {if (rpcDebugFlag & DEBUG_FATAL){ char buf[40] = {0}; TRACE_TO_STR(trace, buf); tFatal(param ", gtid:%s", __VA_ARGS__, buf); }} while (0) +#define tGError(param, ...) do { if (rpcDebugFlag & DEBUG_ERROR){ char buf[40] = {0}; TRACE_TO_STR(trace, buf); tError(param ", gtid:%s", __VA_ARGS__, buf);} } while(0) +#define tGWarn(param, ...) do { if (rpcDebugFlag & DEBUG_WARN) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); tWarn(param ", gtid:%s", __VA_ARGS__, buf); }} while(0) +#define tGInfo(param, ...) do { if (rpcDebugFlag & DEBUG_INFO) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); tInfo(param ", gtid:%s", __VA_ARGS__, buf); }} while(0) +#define tGDebug(param,...) do {if (rpcDebugFlag & DEBUG_DEBUG){ char buf[40] = {0}; TRACE_TO_STR(trace, buf); tDebug(param ", gtid:%s", __VA_ARGS__, buf); }} while(0) -//#define tTR(param, ...) do { char buf[40] = {0};TRACE_TO_STR(trace, buf);tTrace("TRID: %s "param, buf, __VA_ARGS__);} while(0) -#define tGTrace(param, ...) do { char buf[40] = {0}; TRACE_TO_STR(trace, buf); tTrace(param ", GTID: %s", __VA_ARGS__, buf);} while(0) // clang-format on #ifdef __cplusplus diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index 912c8b59c2..bf03ea26ba 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -175,6 +175,7 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) { #define CONN_SHOULD_RELEASE(conn, head) \ do { \ if ((head)->release == 1 && (head->msgLen) == sizeof(*head)) { \ + int connStatus = conn->status; \ uint64_t ahandle = head->ahandle; \ CONN_GET_MSGCTX_BY_AHANDLE(conn, ahandle); \ conn->status = ConnRelease; \ @@ -186,7 +187,9 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) { } \ destroyCmsg(pMsg); \ cliReleaseUnfinishedMsg(conn); \ - addConnToPool(((SCliThrdObj*)conn->hostThrd)->pool, conn); \ + if (connStatus != ConnInPool) { \ + addConnToPool(((SCliThrdObj*)conn->hostThrd)->pool, conn); \ + } \ return; \ } \ } while (0) @@ -450,7 +453,7 @@ void* destroyConnPool(void* pool) { while (connList != NULL) { while (!QUEUE_IS_EMPTY(&connList->conn)) { queue* h = QUEUE_HEAD(&connList->conn); - QUEUE_REMOVE(h); + // QUEUE_REMOVE(h); SCliConn* c = QUEUE_DATA(h, SCliConn, conn); cliDestroyConn(c, true); } @@ -476,18 +479,19 @@ static SCliConn* getConnFromPool(void* pool, char* ip, uint32_t port) { if (QUEUE_IS_EMPTY(&plist->conn)) { return NULL; } - queue* h = QUEUE_HEAD(&plist->conn); - QUEUE_REMOVE(h); + queue* h = QUEUE_HEAD(&plist->conn); SCliConn* conn = QUEUE_DATA(h, SCliConn, conn); conn->status = ConnNormal; + QUEUE_REMOVE(&conn->conn); QUEUE_INIT(&conn->conn); + assert(h == &conn->conn); return conn; } static void addConnToPool(void* pool, SCliConn* conn) { SCliThrdObj* thrd = conn->hostThrd; CONN_HANDLE_THREAD_QUIT(thrd); - STrans* pTransInst = ((SCliThrdObj*)conn->hostThrd)->pTransInst; + STrans* pTransInst = thrd->pTransInst; conn->expireTime = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime); transQueueClear(&conn->cliMsgs); transCtxCleanup(&conn->ctx); @@ -500,6 +504,7 @@ static void addConnToPool(void* pool, SCliConn* conn) { SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key)); // list already create before assert(plist != NULL); + QUEUE_INIT(&conn->conn); QUEUE_PUSH(&plist->conn, &conn->conn); assert(!QUEUE_IS_EMPTY(&plist->conn)); } @@ -561,7 +566,6 @@ static SCliConn* cliCreateConn(SCliThrdObj* pThrd) { } static void cliDestroyConn(SCliConn* conn, bool clear) { tTrace("%s conn %p remove from conn pool", CONN_GET_INST_LABEL(conn), conn); - QUEUE_REMOVE(&conn->conn); if (clear) { uv_close((uv_handle_t*)conn->stream, cliDestroy); @@ -778,11 +782,11 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { int ret = transSetConnOption((uv_tcp_t*)conn->stream); if (ret) { - tError("%s conn %p failed to set conn option, errmsg %s", pTransInst->label, conn, uv_err_name(ret)); + tError("%s conn %p failed to set conn option, errmsg %s", transLabel(pTransInst), conn, uv_err_name(ret)); } int fd = taosCreateSocketWithTimeOutOpt(TRANS_CONN_TIMEOUT); if (fd == -1) { - tTrace("%s conn %p failed to create socket", pTransInst->label, conn); + tTrace("%s conn %p failed to create socket", transLabel(pTransInst), conn); cliHandleExcept(conn); return; } @@ -1006,7 +1010,9 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) { tTrace("%s use remote epset, inUse: %d, retry count:%d, limit: %d", pTransInst->label, pEpSet->inUse, pCtx->retryCount + 1, TRANS_RETRY_COUNT_LIMIT); } - addConnToPool(pThrd->pool, pConn); + if (pConn->status != ConnInPool) { + addConnToPool(pThrd->pool, pConn); + } STaskArg* arg = taosMemoryMalloc(sizeof(STaskArg)); arg->param1 = pMsg; @@ -1110,7 +1116,7 @@ void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STra SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[idx]; STraceId* trace = &pReq->info.traceId; - tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", pTransInst->label, thrd->pid, + tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), thrd->pid, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle); ASSERT(transSendAsync(thrd->asyncPool, &(cliMsg->q)) == 0); } @@ -1143,7 +1149,7 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[idx]; STraceId* trace = &pReq->info.traceId; - tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", pTransInst->label, thrd->pid, + tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), thrd->pid, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle); transSendAsync(thrd->asyncPool, &(cliMsg->q)); diff --git a/source/libs/transport/src/transSvr.c b/source/libs/transport/src/transSvr.c index f9558d7252..593a790a21 100644 --- a/source/libs/transport/src/transSvr.c +++ b/source/libs/transport/src/transSvr.c @@ -284,12 +284,12 @@ static void uvHandleReq(SSvrConn* pConn) { if (pConn->status == ConnNormal && pHead->noResp == 0) { transRefSrvHandle(pConn); - tGTrace("conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pConn, TMSG_INFO(transMsg.msgType), - taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), taosInetNtoa(pConn->localAddr.sin_addr), - ntohs(pConn->localAddr.sin_port), transMsg.contLen); - } else { - tGTrace("conn %p %s received from %s:%d, local info: %s:%d, msg size: %d, resp:%d, code: %d", pConn, + tGTrace("%s conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", transLabel(pConn), pConn, TMSG_INFO(transMsg.msgType), taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), + taosInetNtoa(pConn->localAddr.sin_addr), ntohs(pConn->localAddr.sin_port), transMsg.contLen); + } else { + tGTrace("%s conn %p %s received from %s:%d, local info: %s:%d, msg size: %d, resp:%d, code: %d", transLabel(pConn), + pConn, TMSG_INFO(transMsg.msgType), taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), taosInetNtoa(pConn->localAddr.sin_addr), ntohs(pConn->localAddr.sin_port), transMsg.contLen, pHead->noResp, transMsg.code); // no ref here @@ -304,7 +304,8 @@ static void uvHandleReq(SSvrConn* pConn) { transMsg.info.refId = pConn->refId; transMsg.info.traceId = pHead->traceId; - tGTrace("handle %p conn: %p translated to app, refId: %" PRIu64 "", transMsg.info.handle, pConn, pConn->refId); + tGTrace("%s handle %p conn: %p translated to app, refId: %" PRIu64 "", transLabel(pConn), transMsg.info.handle, pConn, + pConn->refId); assert(transMsg.info.handle != NULL); if (pHead->noResp == 1) { @@ -330,12 +331,12 @@ void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { SConnBuffer* pBuf = &conn->readBuf; if (nread > 0) { pBuf->len += nread; - tTrace("conn %p total read: %d, current read: %d", conn, pBuf->len, (int)nread); + tTrace("%s conn %p total read: %d, current read: %d", transLabel(conn->pTransInst), conn, pBuf->len, (int)nread); if (transReadComplete(pBuf)) { - tTrace("conn %p alread read complete packet", conn); + tTrace("%s conn %p alread read complete packet", transLabel(conn->pTransInst), conn); uvHandleReq(conn); } else { - tTrace("conn %p read partial packet, continue to read", conn); + tTrace("%s conn %p read partial packet, continue to read", transLabel(conn->pTransInst), conn); } return; } @@ -343,12 +344,12 @@ void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { return; } - tError("conn %p read error: %s", conn, uv_err_name(nread)); + tError("%s conn %p read error: %s", transLabel(conn->pTransInst), conn, uv_err_name(nread)); if (nread < 0) { conn->broken = true; if (conn->status == ConnAcquire) { if (conn->regArg.init) { - tTrace("conn %p broken, notify server app", conn); + tTrace("%s conn %p broken, notify server app", transLabel(conn->pTransInst), conn); STrans* pTransInst = conn->pTransInst; (*pTransInst->cfp)(pTransInst->parent, &(conn->regArg.msg), NULL); memset(&conn->regArg, 0, sizeof(conn->regArg)); @@ -457,9 +458,9 @@ static void uvPrepareSendData(SSvrMsg* smsg, uv_buf_t* wb) { int32_t len = transMsgLenFromCont(pMsg->contLen); STraceId* trace = &pMsg->info.traceId; - tGTrace("conn %p %s is sent to %s:%d, local info: %s:%d, msglen:%d", pConn, TMSG_INFO(pHead->msgType), - taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), taosInetNtoa(pConn->localAddr.sin_addr), - ntohs(pConn->localAddr.sin_port), len); + tGTrace("%s conn %p %s is sent to %s:%d, local info: %s:%d, msglen:%d", transLabel(pConn->pTransInst), pConn, + TMSG_INFO(pHead->msgType), taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), + taosInetNtoa(pConn->localAddr.sin_addr), ntohs(pConn->localAddr.sin_port), len); pHead->msgLen = htonl(len); wb->base = msg; @@ -737,7 +738,7 @@ static bool addHandleToWorkloop(SWorkThrdObj* pThrd, char* pipeName) { // conn set QUEUE_INIT(&pThrd->conn); - pThrd->asyncPool = transCreateAsyncPool(pThrd->loop, 5, pThrd, uvWorkerAsyncCb); + pThrd->asyncPool = transCreateAsyncPool(pThrd->loop, 1, pThrd, uvWorkerAsyncCb); uv_pipe_connect(&pThrd->connect_req, pThrd->pipe, pipeName, uvOnPipeConnectionCb); // uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb); return true; @@ -801,7 +802,7 @@ static SSvrConn* createConn(void* hThrd) { pConn->refId = exh->refId; transRefSrvHandle(pConn); - tTrace("handle %p, conn %p created, refId: %" PRId64 "", exh, pConn, pConn->refId); + tTrace("%s handle %p, conn %p created, refId: %" PRId64 "", transLabel(pThrd->pTransInst), exh, pConn, pConn->refId); return pConn; } @@ -848,7 +849,7 @@ static void uvDestroyConn(uv_handle_t* handle) { transReleaseExHandle(refMgt, conn->refId); transRemoveExHandle(refMgt, conn->refId); - tDebug("conn %p destroy", conn); + tDebug("%s conn %p destroy", transLabel(thrd->pTransInst), conn); // uv_timer_stop(&conn->pTimer); transQueueDestroy(&conn->srvMsgs); @@ -977,18 +978,18 @@ void uvHandleRelease(SSvrMsg* msg, SWorkThrdObj* thrd) { uvStartSendRespInternal(msg); return; } else if (conn->status == ConnRelease || conn->status == ConnNormal) { - tDebug("conn %p already released, ignore release-msg", conn); + tDebug("%s conn %p already released, ignore release-msg", transLabel(thrd->pTransInst), conn); } destroySmsg(msg); } void uvHandleResp(SSvrMsg* msg, SWorkThrdObj* thrd) { // send msg to client - tDebug("conn %p start to send resp (2/2)", msg->pConn); + tDebug("%s conn %p start to send resp (2/2)", transLabel(thrd->pTransInst), msg->pConn); uvStartSendResp(msg); } void uvHandleRegister(SSvrMsg* msg, SWorkThrdObj* thrd) { SSvrConn* conn = msg->pConn; - tDebug("conn %p register brokenlink callback", conn); + tDebug("%s conn %p register brokenlink callback", transLabel(thrd->pTransInst), conn); if (conn->status == ConnAcquire) { if (!transQueuePush(&conn->srvMsgs, msg)) { return; @@ -1094,7 +1095,7 @@ void transReleaseSrvHandle(void* handle) { m->msg = tmsg; m->type = Release; - tTrace("conn %p start to release", exh->handle); + tTrace("%s conn %p start to release", transLabel(pThrd->pTransInst), exh->handle); transSendAsync(pThrd->asyncPool, &m->q); transReleaseExHandle(refMgt, refId); return; @@ -1152,7 +1153,7 @@ void transRegisterMsg(const STransMsg* msg) { m->msg = tmsg; m->type = Register; - tTrace("conn %p start to register brokenlink callback", exh->handle); + tTrace("%s conn %p start to register brokenlink callback", transLabel(pThrd->pTransInst), exh->handle); transSendAsync(pThrd->asyncPool, &m->q); transReleaseExHandle(refMgt, refId); return; diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index e940191cea..9bed6d230b 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -100,7 +100,6 @@ static int32_t walReadChangeFile(SWalReadHandle *pRead, int64_t fileFirstVer) { TdFilePtr pLogTFile = taosOpenFile(fnameStr, TD_FILE_READ); if (pLogTFile == NULL) { terrno = TAOS_SYSTEM_ERROR(errno); - terrno = TSDB_CODE_WAL_INVALID_VER; wError("cannot open file %s, since %s", fnameStr, terrstr()); return -1; } @@ -259,6 +258,12 @@ int32_t walReadWithHandle_s(SWalReadHandle *pRead, int64_t ver, SWalReadHead **p int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { int64_t code; + + if (pRead->pWal->vers.firstVer == -1) { + terrno = TSDB_CODE_WAL_LOG_NOT_EXIST; + return -1; + } + // TODO: check wal life if (pRead->curVersion != ver) { if (walReadSeekVer(pRead, ver) < 0) { diff --git a/source/util/src/tbuffer.c b/source/util/src/tbuffer.c index 8552ccac2c..d2fac72c77 100644 --- a/source/util/src/tbuffer.c +++ b/source/util/src/tbuffer.c @@ -21,7 +21,7 @@ typedef union Un4B { uint32_t ui; float f; } Un4B; -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL static_assert(sizeof(Un4B) == sizeof(uint32_t), "sizeof(Un4B) must equal to sizeof(uint32_t)"); static_assert(sizeof(Un4B) == sizeof(float), "sizeof(Un4B) must equal to sizeof(float)"); #endif @@ -30,7 +30,7 @@ typedef union Un8B { uint64_t ull; double d; } Un8B; -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL static_assert(sizeof(Un8B) == sizeof(uint64_t), "sizeof(Un8B) must equal to sizeof(uint64_t)"); static_assert(sizeof(Un8B) == sizeof(double), "sizeof(Un8B) must equal to sizeof(double)"); #endif diff --git a/source/util/src/tcompression.c b/source/util/src/tcompression.c index 041aec4054..38613a77e6 100644 --- a/source/util/src/tcompression.c +++ b/source/util/src/tcompression.c @@ -58,7 +58,7 @@ static const int32_t TEST_NUMBER = 1; #define is_bigendian() ((*(char *)&TEST_NUMBER) == 0) -#define SIMPLE8B_MAX_INT64 ((uint64_t)2305843009213693951L) +#define SIMPLE8B_MAX_INT64 ((uint64_t)2305843009213693951LL) #define safeInt64Add(a, b) (((a >= 0) && (b <= INT64_MAX - a)) || ((a < 0) && (b >= INT64_MIN - a))) #define ZIGZAG_ENCODE(T, v) ((u##T)((v) >> (sizeof(T) * 8 - 1))) ^ (((u##T)(v)) << 1) // zigzag encode diff --git a/source/util/src/tencode.c b/source/util/src/tencode.c index 185daf9e45..2267c90783 100644 --- a/source/util/src/tencode.c +++ b/source/util/src/tencode.c @@ -16,7 +16,7 @@ #define _DEFAULT_SOURCE #include "tencode.h" -#if __STDC_VERSION__ >= 201112L +#if __STDC_VERSION__ >= 201112LL static_assert(sizeof(float) == sizeof(uint32_t), "sizeof(float) must equal to sizeof(uint32_t)"); static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) must equal to sizeof(uint64_t)"); #endif diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 6afb240ab9..b89e908df7 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -134,6 +134,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_TBNAME_ERROR, "Stmt table name not s TAOS_DEFINE_ERROR(TSDB_CODE_TSC_STMT_CLAUSE_ERROR, "not supported stmt clause") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_QUERY_KILLED, "Query killed") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_EXEC_NODE, "No available execution node") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NOT_STABLE_ERROR, "Table is not a super table") // mnode-common TAOS_DEFINE_ERROR(TSDB_CODE_MND_APP_ERROR, "Mnode internal error") @@ -426,6 +427,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_IN_NEW_CONFIG, "Sync not in new confi TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEW_CONFIG_ERROR, "Sync new config error") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RECONFIG_NOT_READY, "Sync not ready for reconfig") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready for propose") +TAOS_DEFINE_ERROR(TSDB_CODE_SYN_STANDBY_NOT_READY, "Sync not ready for standby") TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INTERNAL_ERROR, "Sync internal error") // wal diff --git a/source/util/src/thash.c b/source/util/src/thash.c index 98762d8fb0..8275072748 100644 --- a/source/util/src/thash.c +++ b/source/util/src/thash.c @@ -31,12 +31,12 @@ #define GET_HASH_NODE_DATA(_n) ((char *)(_n) + sizeof(SHashNode)) #define GET_HASH_PNODE(_n) ((SHashNode *)((char *)(_n) - sizeof(SHashNode))) -#define FREE_HASH_NODE(_fp, _n) \ - do { \ - if (_fp != NULL) { \ - (_fp)(_n); \ - } \ - taosMemoryFreeClear(_n); \ +#define FREE_HASH_NODE(_fp, _n) \ + do { \ + if (_fp != NULL) { \ + (_fp)(GET_HASH_NODE_DATA(_n)); \ + } \ + taosMemoryFreeClear(_n); \ } while (0); struct SHashNode { @@ -56,7 +56,7 @@ typedef struct SHashEntry { } SHashEntry; struct SHashObj { - SHashEntry ** hashList; + SHashEntry **hashList; size_t capacity; // number of slots int64_t size; // number of elements in hash table _hash_fn_t hashFp; // hash function @@ -65,7 +65,7 @@ struct SHashObj { SRWLatch lock; // read-write spin lock SHashLockTypeE type; // lock type bool enableUpdate; // enable update - SArray * pMemBlock; // memory block allocated for SHashEntry + SArray *pMemBlock; // memory block allocated for SHashEntry _hash_before_fn_t callbackFp; // function invoked before return the value to caller }; @@ -633,7 +633,7 @@ void taosHashTableResize(SHashObj *pHashObj) { } int64_t st = taosGetTimestampUs(); - void * pNewEntryList = taosMemoryRealloc(pHashObj->hashList, sizeof(void *) * newCapacity); + void *pNewEntryList = taosMemoryRealloc(pHashObj->hashList, sizeof(void *) * newCapacity); if (pNewEntryList == NULL) { // uDebug("cache resize failed due to out of memory, capacity remain:%zu", pHashObj->capacity); return; @@ -642,7 +642,7 @@ void taosHashTableResize(SHashObj *pHashObj) { pHashObj->hashList = pNewEntryList; size_t inc = newCapacity - pHashObj->capacity; - void * p = taosMemoryCalloc(inc, sizeof(SHashEntry)); + void *p = taosMemoryCalloc(inc, sizeof(SHashEntry)); for (int32_t i = 0; i < inc; ++i) { pHashObj->hashList[i + pHashObj->capacity] = (void *)((char *)p + i * sizeof(SHashEntry)); @@ -653,9 +653,9 @@ void taosHashTableResize(SHashObj *pHashObj) { pHashObj->capacity = newCapacity; for (int32_t idx = 0; idx < pHashObj->capacity; ++idx) { SHashEntry *pe = pHashObj->hashList[idx]; - SHashNode * pNode; - SHashNode * pNext; - SHashNode * pPrev = NULL; + SHashNode *pNode; + SHashNode *pNext; + SHashNode *pPrev = NULL; if (pe->num == 0) { assert(pe->next == NULL); diff --git a/tests/pytest/util/boundary.py b/tests/pytest/util/boundary.py new file mode 100644 index 0000000000..4cef926f2e --- /dev/null +++ b/tests/pytest/util/boundary.py @@ -0,0 +1,44 @@ +class DataBoundary: + def __init__(self): + self.TINYINT_BOUNDARY = [-128, 127] + self.SMALLINT_BOUNDARY = [-32768, 32767] + self.INT_BOUNDARY = [-2147483648, 2147483647] + self.BIGINT_BOUNDARY = [-9223372036854775808, 9223372036854775807] + self.UTINYINT_BOUNDARY = [0, 255] + self.USMALLINT_BOUNDARY = [0, 65535] + self.UINT_BOUNDARY = [0, 4294967295] + self.UBIGINT_BOUNDARY = [0, 18446744073709551615] + self.FLOAT_BOUNDARY = [-3.40E+38, 3.40E+38] + self.DOUBLE_BOUNDARY = [-1.7e+308, 1.7e+308] + self.BOOL_BOUNDARY = [True, False] + self.BINARY_MAX_LENGTH = 16374 + self.NCHAR_MAX_LENGTH = 4093 + self.DBNAME_MAX_LENGTH = 64 + self.STBNAME_MAX_LENGTH = 192 + self.TBNAME_MAX_LENGTH = 192 + self.CHILD_TBNAME_MAX_LENGTH = 192 + self.TAG_KEY_MAX_LENGTH = 64 + self.COL_KEY_MAX_LENGTH = 64 + self.MAX_TAG_COUNT = 128 + self.MAX_TAG_COL_COUNT = 4096 + self.mnodeShmSize = [6292480, 2147483647] + self.mnodeShmSize_default = 6292480 + self.vnodeShmSize = [6292480, 2147483647] + self.vnodeShmSize_default = 31458304 + self.DB_PARAM_BUFFER_CONFIG = {"create_name": "buffer", "query_name": "buffer", "vnode_json_key": "szBuf", "boundary": [3, 16384], "default": 96} + self.DB_PARAM_CACHELAST_CONFIG = {"create_name": "cachelast", "query_name": "cache_model", "vnode_json_key": "", "boundary": [0, 1, 2, 3], "default": 0} + self.DB_PARAM_COMP_CONFIG = {"create_name": "comp", "query_name": "compression", "vnode_json_key": "", "boundary": [0, 1, 2], "default": 2} + self.DB_PARAM_DURATION_CONFIG = {"create_name": "duration", "query_name": "duration", "vnode_json_key": "daysPerFile", "boundary": [1, 3650, '60m', '5256000m', '1h', '87600h', '1d', '3650d'], "default": "14400m"} + self.DB_PARAM_FSYNC_CONFIG = {"create_name": "fsync", "query_name": "fsync", "vnode_json_key": "", "boundary": [0, 180000], "default": 3000} + self.DB_PARAM_KEEP_CONFIG = {"create_name": "keep", "query_name": "fsync", "vnode_json_key": "", "boundary": [1, 365000,'1440m','525600000m','24h','8760000h','1d','365000d'], "default": "5256000m,5256000m,5256000m"} + self.DB_PARAM_MAXROWS_CONFIG = {"create_name": "maxrows", "query_name": "maxrows", "vnode_json_key": "maxRows", "boundary": [200, 10000], "default": 4096} + self.DB_PARAM_MINROWS_CONFIG = {"create_name": "minrows", "query_name": "minrows", "vnode_json_key": "minRows", "boundary": [10, 1000], "default": 100} + self.DB_PARAM_NTABLES_CONFIG = {"create_name": "ntables", "query_name": "ntables", "vnode_json_key": "", "boundary": 0, "default": 0} + self.DB_PARAM_PAGES_CONFIG = {"create_name": "pages", "query_name": "pages", "vnode_json_key": "szCache", "boundary": [64], "default": 256} + self.DB_PARAM_PAGESIZE_CONFIG = {"create_name": "pagesize", "query_name": "pagesize", "vnode_json_key": "szPage", "boundary": [1, 16384], "default": 4} + self.DB_PARAM_PRECISION_CONFIG = {"create_name": "precision", "query_name": "precision", "vnode_json_key": "", "boundary": ['ms', 'us', 'ns'], "default": "ms"} + self.DB_PARAM_REPLICA_CONFIG = {"create_name": "replica", "query_name": "replica", "vnode_json_key": "", "boundary": [1], "default": 1} + self.DB_PARAM_SINGLE_STABLE_CONFIG = {"create_name": "single_stable", "query_name": "single_stable_model", "vnode_json_key": "", "boundary": [0, 1], "default": 0} + self.DB_PARAM_STRICT_CONFIG = {"create_name": "strict", "query_name": "strict", "vnode_json_key": "", "boundary": {"no_strict": 0, "strict": 1}, "default": "no_strict"} + self.DB_PARAM_VGROUPS_CONFIG = {"create_name": "vgroups", "query_name": "vgroups", "vnode_json_key": "", "boundary": [1, 32], "default": 2} + self.DB_PARAM_WAL_CONFIG = {"create_name": "wal", "query_name": "wal", "vnode_json_key": "", "boundary": [1, 2], "default": 1} \ No newline at end of file diff --git a/tests/pytest/util/common.py b/tests/pytest/util/common.py index e158f8edd2..b43f87be29 100644 --- a/tests/pytest/util/common.py +++ b/tests/pytest/util/common.py @@ -17,7 +17,7 @@ import string import requests import time import socket - +from .boundary import DataBoundary import taos from util.log import * from util.sql import * @@ -25,9 +25,45 @@ from util.cases import * from util.dnodes import * from util.common import * -class TDCom: - def init(self, conn, logSql): - tdSql.init(conn.cursor(), logSql) +class TDCom: + def __init__(self): + self.sml_type = None + self.env_setting = None + self.smlChildTableName_value = None + self.defaultJSONStrType_value = None + self.smlTagNullName_value = None + self.default_varchar_length = 256 + self.default_nchar_length = 256 + self.default_varchar_datatype = "letters" + self.default_nchar_datatype = "letters" + self.default_tagname_prefix = "t" + self.default_colname_prefix = "c" + self.default_stbname_prefix = "stb" + self.default_ctbname_prefix = "ctb" + self.default_tbname_prefix = "tb" + self.default_tag_index_start_num = 1 + self.default_column_index_start_num = 1 + self.default_stbname_index_start_num = 1 + self.default_ctbname_index_start_num = 1 + self.default_tbname_index_start_num = 1 + self.default_tagts_name = "ts" + self.default_colts_name = "ts" + self.dbname = "test" + self.stb_name = "stb" + self.ctb_name = "ctb" + self.tb_name = "tb" + self.need_tagts = False + self.tag_type_str = "" + self.column_type_str = "" + self.columns_str = None + self.ts_value = None + self.tag_value_list = list() + self.column_value_list = list() + self.full_type_list = ["tinyint", "smallint", "int", "bigint", "tinyint unsigned", "smallint unsigned", "int unsigned", "bigint unsigned", "float", "double", "binary", "nchar", "bool"] + self.white_list = ["statsd", "node_exporter", "collectd", "icinga2", "tcollector", "information_schema", "performance_schema"] + self.Boundary = DataBoundary() + # def init(self, conn, logSql): + # # tdSql.init(conn.cursor(), logSql) def preDefine(self): header = {'Authorization': 'Basic cm9vdDp0YW9zZGF0YQ=='} @@ -113,6 +149,59 @@ class TDCom: def dateToTs(self, datetime_input): return int(time.mktime(time.strptime(datetime_input, "%Y-%m-%d %H:%M:%S.%f"))) + def genTs(self, precision="ms", ts="", protype="taosc", ns_tag=None): + """ + protype = "taosc" or "restful" + gen ts and datetime + """ + if precision == "ns": + if ts == "" or ts is None: + ts = time.time_ns() + else: + ts = ts + if ns_tag is None: + dt = ts + else: + dt = datetime.fromtimestamp(ts // 1000000000) + dt = dt.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(int(ts % 1000000000)).zfill(9) + if protype == "restful": + dt = datetime.fromtimestamp(ts // 1000000000) + dt = dt.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(int(ts % 1000000000)).zfill(9) + else: + if ts == "" or ts is None: + ts = time.time() + else: + ts = ts + if precision == "ms" or precision is None: + ts = int(round(ts * 1000)) + dt = datetime.fromtimestamp(ts // 1000) + if protype == "taosc": + dt = dt.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(int(ts % 1000)).zfill(3) + '000' + elif protype == "restful": + dt = dt.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(int(ts % 1000)).zfill(3) + else: + pass + elif precision == "us": + ts = int(round(ts * 1000000)) + dt = datetime.fromtimestamp(ts // 1000000) + dt = dt.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(int(ts % 1000000)).zfill(6) + return ts, dt + + def get_long_name(self, length=10, mode="letters"): + """ + generate long name + mode could be numbers/letters/letters_mixed/mixed + """ + if mode == "numbers": + population = string.digits + elif mode == "letters": + population = string.ascii_letters.lower() + elif mode == "letters_mixed": + population = string.ascii_letters.upper() + string.ascii_letters.lower() + else: + population = string.ascii_letters.lower() + string.digits + return "".join(random.choices(population, k=length)) + def getLongName(self, len, mode = "mixed"): """ generate long name @@ -177,84 +266,92 @@ class TDCom: def close(self): self.cursor.close() - def create_database(self,tsql, dbName='test',dropFlag=1,precision="ms", **kwargs): + ######################################################################################################################################## + # new common API + ######################################################################################################################################## + def create_database(self,tsql, dbName='test',dropFlag=1,**kwargs): if dropFlag == 1: tsql.execute("drop database if exists %s"%(dbName)) ''' vgroups replica precision strict wal fsync comp cachelast single_stable buffer pagesize pages minrows maxrows duration keep retentions ''' - sqlString = f'create database if not exists {dbName} precision "{precision}" vgroups 4' + sqlString = f'create database if not exists {dbName} ' + + dbParams = "" if len(kwargs) > 0: - dbParams = "" for param, value in kwargs.items(): - dbParams += f'{param} {value} ' + if param == "precision": + dbParams += f'{param} "{value}" ' + else: + dbParams += f'{param} {value} ' sqlString += f'{dbParams}' + tdLog.debug("create db sql: %s"%sqlString) tsql.execute(sqlString) tdLog.debug("complete to create database %s"%(dbName)) return - def create_stable(self,tsql, dbName,stbName,columnDict,tagDict): - colSchema = '' - for i in range(columnDict['int']): - colSchema += ', c%d int'%i - tagSchema = '' - for i in range(tagDict['int']): - if i > 0: - tagSchema += ',' - tagSchema += 't%d int'%i + # def create_stable(self,tsql, dbName,stbName,column_elm_list=None, tag_elm_list=None): + # colSchema = '' + # for i in range(columnDict['int']): + # colSchema += ', c%d int'%i + # tagSchema = '' + # for i in range(tagDict['int']): + # if i > 0: + # tagSchema += ',' + # tagSchema += 't%d int'%i - tsql.execute("create table if not exists %s.%s (ts timestamp %s) tags(%s)"%(dbName, stbName, colSchema, tagSchema)) - tdLog.debug("complete to create %s.%s" %(dbName, stbName)) - return + # tsql.execute("create table if not exists %s.%s (ts timestamp %s) tags(%s)"%(dbName, stbName, colSchema, tagSchema)) + # tdLog.debug("complete to create %s.%s" %(dbName, stbName)) + # return - def create_ctables(self,tsql, dbName,stbName,ctbNum,tagDict): - tsql.execute("use %s" %dbName) - tagsValues = '' - for i in range(tagDict['int']): - if i > 0: - tagsValues += ',' - tagsValues += '%d'%i + # def create_ctables(self,tsql, dbName,stbName,ctbNum,tagDict): + # tsql.execute("use %s" %dbName) + # tagsValues = '' + # for i in range(tagDict['int']): + # if i > 0: + # tagsValues += ',' + # tagsValues += '%d'%i - pre_create = "create table" - sql = pre_create - #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) - for i in range(ctbNum): - sql += " %s_%d using %s tags(%s)"%(stbName,i,stbName,tagsValues) - if (i > 0) and (i%100 == 0): - tsql.execute(sql) - sql = pre_create - if sql != pre_create: - tsql.execute(sql) + # pre_create = "create table" + # sql = pre_create + # #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + # for i in range(ctbNum): + # sql += " %s_%d using %s tags(%s)"%(stbName,i,stbName,tagsValues) + # if (i > 0) and (i%100 == 0): + # tsql.execute(sql) + # sql = pre_create + # if sql != pre_create: + # tsql.execute(sql) - tdLog.debug("complete to create %d child tables in %s.%s" %(ctbNum, dbName, stbName)) - return + # tdLog.debug("complete to create %d child tables in %s.%s" %(ctbNum, dbName, stbName)) + # return - def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs=0): - tdLog.debug("start to insert data ............") - tsql.execute("use %s" %dbName) - pre_insert = "insert into " - sql = pre_insert - if startTs == 0: - t = time.time() - startTs = int(round(t * 1000)) - #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) - for i in range(ctbNum): - sql += " %s_%d values "%(stbName,i) - for j in range(rowsPerTbl): - sql += "(%d, %d, %d)"%(startTs + j, j, j) - if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): - tsql.execute(sql) - if j < rowsPerTbl - 1: - sql = "insert into %s_%d values " %(stbName,i) - else: - sql = "insert into " - #end sql - if sql != pre_insert: - #print("insert sql:%s"%sql) - tsql.execute(sql) - tdLog.debug("insert data ............ [OK]") - return + # def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs=0): + # tdLog.debug("start to insert data ............") + # tsql.execute("use %s" %dbName) + # pre_insert = "insert into " + # sql = pre_insert + # if startTs == 0: + # t = time.time() + # startTs = int(round(t * 1000)) + # #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + # for i in range(ctbNum): + # sql += " %s_%d values "%(stbName,i) + # for j in range(rowsPerTbl): + # sql += "(%d, %d, %d)"%(startTs + j, j, j) + # if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + # tsql.execute(sql) + # if j < rowsPerTbl - 1: + # sql = "insert into %s_%d values " %(stbName,i) + # else: + # sql = "insert into " + # #end sql + # if sql != pre_insert: + # #print("insert sql:%s"%sql) + # tsql.execute(sql) + # tdLog.debug("insert data ............ [OK]") + # return def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) @@ -295,4 +392,250 @@ class TDCom: newTdSql.init(cur, False) return newTdSql + ################################################################################################################ + # port from the common.py of new test frame + ################################################################################################################ + def gen_default_tag_str(self): + default_tag_str = "" + for tag_type in self.full_type_list: + if tag_type.lower() not in ["varchar", "binary", "nchar"]: + default_tag_str += f" {self.default_tagname_prefix}{self.default_tag_index_start_num} {tag_type}," + else: + if tag_type.lower() in ["varchar", "binary"]: + default_tag_str += f" {self.default_tagname_prefix}{self.default_tag_index_start_num} {tag_type}({self.default_varchar_length})," + else: + default_tag_str += f" {self.default_tagname_prefix}{self.default_tag_index_start_num} {tag_type}({self.default_nchar_length})," + self.default_tag_index_start_num += 1 + if self.need_tagts: + default_tag_str = self.default_tagts_name + " timestamp," + default_tag_str + return default_tag_str[:-1].lstrip() + + def gen_default_column_str(self): + self.default_column_index_start_num = 1 + default_column_str = "" + for col_type in self.full_type_list: + if col_type.lower() not in ["varchar", "binary", "nchar"]: + default_column_str += f" {self.default_colname_prefix}{self.default_column_index_start_num} {col_type}," + else: + if col_type.lower() in ["varchar", "binary"]: + default_column_str += f" {self.default_colname_prefix}{self.default_column_index_start_num} {col_type}({self.default_varchar_length})," + else: + default_column_str += f" {self.default_colname_prefix}{self.default_column_index_start_num} {col_type}({self.default_nchar_length})," + self.default_column_index_start_num += 1 + default_column_str = self.default_colts_name + " timestamp," + default_column_str + return default_column_str[:-1].lstrip() + + def gen_tag_type_str(self, tagname_prefix, tag_elm_list): + tag_index_start_num = 1 + tag_type_str = "" + if tag_elm_list is None: + tag_type_str = self.gen_default_tag_str() + else: + for tag_elm in tag_elm_list: + if "count" in tag_elm: + total_count = int(tag_elm["count"]) + else: + total_count = 1 + if total_count > 0: + for _ in range(total_count): + tag_type_str += f'{tagname_prefix}{tag_index_start_num} {tag_elm["type"]}, ' + if tag_elm["type"] in ["varchar", "binary", "nchar"]: + tag_type_str = tag_type_str.rstrip()[:-1] + f'({tag_elm["len"]}), ' + tag_index_start_num += 1 + else: + continue + tag_type_str = tag_type_str.rstrip()[:-1] + + return tag_type_str + + def gen_column_type_str(self, colname_prefix, column_elm_list): + column_index_start_num = 1 + column_type_str = "" + if column_elm_list is None: + column_type_str = self.gen_default_column_str() + else: + for column_elm in column_elm_list: + if "count" in column_elm: + total_count = int(column_elm["count"]) + else: + total_count = 1 + if total_count > 0: + for _ in range(total_count): + column_type_str += f'{colname_prefix}{column_index_start_num} {column_elm["type"]}, ' + if column_elm["type"] in ["varchar", "binary", "nchar"]: + column_type_str = column_type_str.rstrip()[:-1] + f'({column_elm["len"]}), ' + column_index_start_num += 1 + else: + continue + column_type_str = self.default_colts_name + " timestamp, " + column_type_str.rstrip()[:-1] + return column_type_str + + def gen_random_type_value(self, type_name, binary_length, binary_type, nchar_length, nchar_type): + if type_name.lower() == "tinyint": + return random.randint(self.Boundary.TINYINT_BOUNDARY[0], self.Boundary.TINYINT_BOUNDARY[1]) + elif type_name.lower() == "smallint": + return random.randint(self.Boundary.SMALLINT_BOUNDARY[0], self.Boundary.SMALLINT_BOUNDARY[1]) + elif type_name.lower() == "int": + return random.randint(self.Boundary.INT_BOUNDARY[0], self.Boundary.INT_BOUNDARY[1]) + elif type_name.lower() == "bigint": + return random.randint(self.Boundary.BIGINT_BOUNDARY[0], self.Boundary.BIGINT_BOUNDARY[1]) + elif type_name.lower() == "tinyint unsigned": + return random.randint(self.Boundary.UTINYINT_BOUNDARY[0], self.Boundary.UTINYINT_BOUNDARY[1]) + elif type_name.lower() == "smallint unsigned": + return random.randint(self.Boundary.USMALLINT_BOUNDARY[0], self.Boundary.USMALLINT_BOUNDARY[1]) + elif type_name.lower() == "int unsigned": + return random.randint(self.Boundary.UINT_BOUNDARY[0], self.Boundary.UINT_BOUNDARY[1]) + elif type_name.lower() == "bigint unsigned": + return random.randint(self.Boundary.UBIGINT_BOUNDARY[0], self.Boundary.UBIGINT_BOUNDARY[1]) + elif type_name.lower() == "float": + return random.uniform(self.Boundary.FLOAT_BOUNDARY[0], self.Boundary.FLOAT_BOUNDARY[1]) + elif type_name.lower() == "double": + return random.uniform(self.Boundary.FLOAT_BOUNDARY[0], self.Boundary.FLOAT_BOUNDARY[1]) + elif type_name.lower() == "binary": + return f'{self.get_long_name(binary_length, binary_type)}' + elif type_name.lower() == "varchar": + return self.get_long_name(binary_length, binary_type) + elif type_name.lower() == "nchar": + return self.get_long_name(nchar_length, nchar_type) + elif type_name.lower() == "bool": + return random.choice(self.Boundary.BOOL_BOUNDARY) + elif type_name.lower() == "timestamp": + return self.genTs()[0] + else: + pass + + def gen_tag_value_list(self, tag_elm_list): + tag_value_list = list() + if tag_elm_list is None: + tag_value_list = list(map(lambda i: self.gen_random_type_value(i, self.default_varchar_length, self.default_varchar_datatype, self.default_nchar_length, self.default_nchar_datatype), self.full_type_list)) + else: + for tag_elm in tag_elm_list: + if "count" in tag_elm: + total_count = int(tag_elm["count"]) + else: + total_count = 1 + if total_count > 0: + for _ in range(total_count): + if tag_elm["type"] in ["varchar", "binary", "nchar"]: + tag_value_list.append(self.gen_random_type_value(tag_elm["type"], tag_elm["len"], self.default_varchar_datatype, tag_elm["len"], self.default_nchar_datatype)) + else: + tag_value_list.append(self.gen_random_type_value(tag_elm["type"], "", "", "", "")) + else: + continue + return tag_value_list + + def gen_column_value_list(self, column_elm_list, ts_value=None): + if ts_value is None: + ts_value = self.genTs()[0] + + column_value_list = list() + if column_elm_list is None: + column_value_list = list(map(lambda i: self.gen_random_type_value(i, self.default_varchar_length, self.default_varchar_datatype, self.default_nchar_length, self.default_nchar_datatype), self.full_type_list)) + else: + for column_elm in column_elm_list: + if "count" in column_elm: + total_count = int(column_elm["count"]) + else: + total_count = 1 + if total_count > 0: + for _ in range(total_count): + if column_elm["type"] in ["varchar", "binary", "nchar"]: + column_value_list.append(self.gen_random_type_value(column_elm["type"], column_elm["len"], self.default_varchar_datatype, column_elm["len"], self.default_nchar_datatype)) + else: + column_value_list.append(self.gen_random_type_value(column_elm["type"], "", "", "", "")) + else: + continue + column_value_list = [self.ts_value] + self.column_value_list + return column_value_list + + def create_stable(self, tsql, dbname=None, stbname="stb", column_elm_list=None, tag_elm_list=None, + count=1, default_stbname_prefix="stb", **kwargs): + colname_prefix = 'c' + tagname_prefix = 't' + stbname_index_start_num = 1 + stb_params = "" + if len(kwargs) > 0: + for param, value in kwargs.items(): + stb_params += f'{param} "{value}" ' + column_type_str = self.gen_column_type_str(colname_prefix, column_elm_list) + tag_type_str = self.gen_tag_type_str(tagname_prefix, tag_elm_list) + + if int(count) <= 1: + create_stable_sql = f'create table {dbname}.{stbname} ({column_type_str}) tags ({tag_type_str}) {stb_params};' + tdLog.info("create stb sql: %s"%create_stable_sql) + tsql.execute(create_stable_sql) + else: + for _ in range(count): + create_stable_sql = f'create table {dbname}.{default_stbname_prefix}{stbname_index_start_num} ({column_type_str}) tags ({tag_type_str}) {stb_params};' + stbname_index_start_num += 1 + tsql.execute(create_stable_sql) + + def create_ctable(self, tsql, dbname=None, stbname=None, tag_elm_list=None, count=1, default_ctbname_prefix="ctb", **kwargs): + ctbname_index_start_num = 0 + ctb_params = "" + if len(kwargs) > 0: + for param, value in kwargs.items(): + ctb_params += f'{param} "{value}" ' + tag_value_list = self.gen_tag_value_list(tag_elm_list) + tag_value_str = "" + # tag_value_str = ", ".join(str(v) for v in self.tag_value_list) + for tag_value in tag_value_list: + if isinstance(tag_value, str): + tag_value_str += f'"{tag_value}", ' + else: + tag_value_str += f'{tag_value}, ' + tag_value_str = tag_value_str.rstrip()[:-1] + + if int(count) <= 1: + create_ctable_sql = f'create table {dbname}.{default_ctbname_prefix}{ctbname_index_start_num} using {dbname}.{stbname} tags ({tag_value_str}) {ctb_params};' + tsql.execute(create_ctable_sql) + else: + for _ in range(count): + create_ctable_sql = f'create table {dbname}.{default_ctbname_prefix}{ctbname_index_start_num} using {dbname}.{stbname} tags ({tag_value_str}) {ctb_params};' + ctbname_index_start_num += 1 + tdLog.info("create ctb sql: %s"%create_ctable_sql) + tsql.execute(create_ctable_sql) + + def create_table(self, tsql, dbname=None, tbname="ntb", column_elm_list=None, count=1, **kwargs): + tbname_index_start_num = 1 + tbname_prefix="ntb" + + tb_params = "" + if len(kwargs) > 0: + for param, value in kwargs.items(): + tb_params += f'{param} "{value}" ' + column_type_str = self.gen_column_type_str(tbname_prefix, column_elm_list) + + if int(count) <= 1: + create_table_sql = f'create table {dbname}.{tbname} ({column_type_str}) {tb_params};' + tsql.execute(create_table_sql) + else: + for _ in range(count): + create_table_sql = f'create table {dbname}.{tbname_prefix}{tbname_index_start_num} ({column_type_str}) {tb_params};' + tbname_index_start_num += 1 + tsql.execute(create_table_sql) + + def insert_rows(self, tsql, dbname=None, tbname=None, column_ele_list=None, start_ts_value=None, count=1): + if start_ts_value is None: + start_ts_value = self.genTs()[0] + + column_value_list = self.gen_column_value_list(column_ele_list, start_ts_value) + # column_value_str = ", ".join(str(v) for v in self.column_value_list) + column_value_str = "" + for column_value in column_value_list: + if isinstance(column_value, str): + column_value_str += f'"{column_value}", ' + else: + column_value_str += f'{column_value}, ' + column_value_str = column_value_str.rstrip()[:-1] + if int(count) <= 1: + insert_sql = f'insert into {self.tb_name} values ({column_value_str});' + tsql.execute(insert_sql) + else: + for num in range(count): + column_value_list = self.gen_column_value_list(column_ele_list, f'{start_ts_value}+{num}s') + column_value_str = ", ".join(str(v) for v in column_value_list) + insert_sql = f'insert into {dbname}.{tbname} values ({column_value_str});' + tsql.execute(insert_sql) + tdCom = TDCom() diff --git a/tests/pytest/util/constant.py b/tests/pytest/util/constant.py new file mode 100644 index 0000000000..e5095c74dc --- /dev/null +++ b/tests/pytest/util/constant.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +# basic data type boundary +TINYINT_MAX = 127 +TINYINT_MIN = -128 + +TINYINT_UN_MAX = 255 +TINYINT_UN_MIN = 0 + +SMALLINT_MAX = 32767 +SMALLINT_MIN = -32768 + +SMALLINT_UN_MAX = 65535 +MALLINT_UN_MIN = 0 + +INT_MAX = 2147483647 +INT_MIN = -2147483648 + +INT_UN_MAX = 4294967295 +INT_UN_MIN = 0 + +BIGINT_MAX = 9223372036854775807 +BIGINT_MIN = -9223372036854775808 + +BIGINT_UN_MAX = 18446744073709551615 +BIGINT_UN_MIN = 0 + +FLOAT_MAX = 3.40E+38 +FLOAT_MIN = -3.40E+38 + +DOUBLE_MAX = 1.7E+308 +DOUBLE_MIN = -1.7E+308 + +# schema boundary +BINARY_LENGTH_MAX = 16374 +NCAHR_LENGTH_MAX_ = 4093 +DBNAME_LENGTH_MAX_ = 64 + +STBNAME_LENGTH_MAX = 192 +STBNAME_LENGTH_MIN = 1 + +TBNAME_LENGTH_MAX = 192 +TBNAME_LENGTH_MIN = 1 + +CHILD_TBNAME_LENGTH_MAX = 192 +CHILD_TBNAME_LENGTH_MIN = 1 + +TAG_NAME_LENGTH_MAX = 64 +TAG_NAME_LENGTH_MIN = 1 + +COL_NAME_LENGTH_MAX = 64 +COL_NAME_LENGTH_MIN = 1 + +TAG_COUNT_MAX = 128 +TAG_COUNT_MIN = 1 + +COL_COUNT_MAX = 4096 +COL_COUNT_MIN = 2 + +TAG_COL_COUNT_MAX = 4096 +TAG_COL_COUNT_MIN = 3 + +MNODE_SHM_SIZE_MAX = 2147483647 +MNODE_SHM_SIZE_MIN = 6292480 +MNODE_SHM_SIZE_DEFAULT = 6292480 + +VNODE_SHM_SIZE_MAX = 2147483647 +VNODE_SHM_SIZE_MIN = 6292480 +VNODE_SHM_SIZE_DEFAULT = 31458304 \ No newline at end of file diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py index b7c6dce018..580fc8ee47 100644 --- a/tests/pytest/util/sql.py +++ b/tests/pytest/util/sql.py @@ -61,7 +61,7 @@ class TDSql: self.cursor.execute(s) s = 'use db' self.cursor.execute(s) - time.sleep(2) + time.sleep(2) def error(self, sql): expectErrNotOccured = True @@ -249,7 +249,7 @@ class TDSql: raise Exception(repr(e)) return self.queryResult - + def executeTimes(self, sql, times): for i in range(times): try: diff --git a/tests/pytest/util/sqlset.py b/tests/pytest/util/sqlset.py new file mode 100644 index 0000000000..939f53154a --- /dev/null +++ b/tests/pytest/util/sqlset.py @@ -0,0 +1,46 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +from util.sql import tdSql + +class TDSetSql: + def init(self, conn, logSql): + tdSql.init(conn.cursor(), logSql) + self.stbname = 'stb' + + def set_create_normaltable_sql(self, ntbname='ntb', + column_dict={'ts':'timestamp','col1':'tinyint','col2':'smallint','col3':'int','col4':'bigint','col5': 'unsigned int','col6': 'unsigned tinyint','col7': 'unsigned smallint', + 'col8': 'unsigned int','col9': 'unsigned bigint','col10': 'float','col11': 'double','col12': 'bool','col13': 'binary(20)','col14': 'nchar(20)'}): + column_sql = '' + for k, v in column_dict.items(): + column_sql += f"{k} {v}," + create_ntb_sql = f'create table {ntbname} ({column_sql[:-1]})' + return create_ntb_sql + + def set_create_stable_sql(self,stbname='stb', + column_dict={'ts':'timestamp','col1':'tinyint','col2':'smallint','col3':'int','col4':'bigint','col5': 'unsigned int','col6': 'unsigned tinyint','col7': 'unsigned smallint', + 'col8': 'unsigned int','col9': 'unsigned bigint','col10': 'float','col11': 'double','col12': 'bool','col13': 'binary(20)','col14': 'nchar(20)'}, + tag_dict={'ts_tag':'timestamp','t1':'tinyint','t2':'smallint','t3':'int','t4':'bigint','t5': 'unsigned int','t6': 'unsigned tinyint','t7': 'unsigned smallint', + 't8': 'unsigned int','t9': 'unsigned bigint','t10': 'float','t11': 'double','t12': 'bool','t13': 'binary(20)','t14': 'nchar(20)'}): + column_sql = '' + tag_sql = '' + for k,v in column_dict.items(): + column_sql += f"{k} {v}," + for k,v in tag_dict.items(): + tag_sql += f"{k} {v}," + create_stb_sql = f'create table {stbname} ({column_sql[:-1]}) tags({tag_sql[:-1]})' + return create_stb_sql + + + + \ No newline at end of file diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c index 7dd7621d0b..0e7030b230 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -353,13 +353,13 @@ void taosMemoryFree(const void *ptr) { static int64_t taosGetTimestampMs() { struct timeval systemTime; taosGetTimeOfDay(&systemTime); - return (int64_t)systemTime.tv_sec * 1000L + (int64_t)systemTime.tv_usec/1000; + return (int64_t)systemTime.tv_sec * 1000LL + (int64_t)systemTime.tv_usec/1000; } static int64_t taosGetTimestampUs() { struct timeval systemTime; taosGetTimeOfDay(&systemTime); - return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec; + return (int64_t)systemTime.tv_sec * 1000000LL + (int64_t)systemTime.tv_usec; } bool colExists(TAOS_MULTI_BIND* pBind, int32_t dataType) { diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 41bbfaa938..1ab6491736 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -23,6 +23,11 @@ # ---- dnode ./test.sh -f tsim/dnode/create_dnode.sim ./test.sh -f tsim/dnode/drop_dnode_has_mnode.sim +./test.sh -f tsim/dnode/drop_dnode_has_qnode_snode.sim +./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica1.sim +#./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica3.sim +#./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim +#./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim # ---- insert ./test.sh -f tsim/insert/basic0.sim @@ -75,12 +80,13 @@ ./test.sh -f tsim/stream/distributeInterval0.sim # ./test.sh -f tsim/stream/distributesession0.sim # ./test.sh -f tsim/stream/session0.sim -# ./test.sh -f tsim/stream/session1.sim +./test.sh -f tsim/stream/session1.sim # ./test.sh -f tsim/stream/state0.sim ./test.sh -f tsim/stream/triggerInterval0.sim # ./test.sh -f tsim/stream/triggerSession0.sim ./test.sh -f tsim/stream/partitionby.sim ./test.sh -f tsim/stream/schedSnode.sim +./test.sh -f tsim/stream/windowClose.sim # ---- transaction diff --git a/tests/script/sh/abs_max.c b/tests/script/sh/abs_max.c index cd8ba0ff15..d623adacf9 100644 --- a/tests/script/sh/abs_max.c +++ b/tests/script/sh/abs_max.c @@ -11,8 +11,8 @@ typedef struct SUdfInit{ } SUdfInit; -#define TSDB_DATA_INT_NULL 0x80000000L -#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L +#define TSDB_DATA_INT_NULL 0x80000000LL +#define TSDB_DATA_BIGINT_NULL 0x8000000000000000LL void abs_max(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBuf, char* tsOutput, int* numOfOutput, short otype, short obytes, SUdfInit* buf) { diff --git a/tests/script/sh/demo.c b/tests/script/sh/demo.c index 23d2174448..2a862c0464 100644 --- a/tests/script/sh/demo.c +++ b/tests/script/sh/demo.c @@ -17,7 +17,7 @@ typedef struct SDemo{ }SDemo; #define FLOAT_NULL 0x7FF00000 // it is an NAN -#define DOUBLE_NULL 0x7FFFFF0000000000L // it is an NAN +#define DOUBLE_NULL 0x7FFFFF0000000000LL // it is an NAN void demo(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBuf, char* tsOutput, diff --git a/tests/script/sh/deploy.bat b/tests/script/sh/deploy.bat index 921f1611fb..f0d8c10b7e 100644 --- a/tests/script/sh/deploy.bat +++ b/tests/script/sh/deploy.bat @@ -59,48 +59,29 @@ for /f "skip=1" %%A in ( 'wmic computersystem get caption' ) do if not defined fqdn set "fqdn=%%A" -echo firstEp %fqdn%:7100 > %TAOS_CFG% +echo firstEp %fqdn%:7100 >> %TAOS_CFG% +echo secondEp %fqdn%:7200 >> %TAOS_CFG% echo fqdn %fqdn% >> %TAOS_CFG% echo serverPort %NODE% >> %TAOS_CFG% +echo supportVnodes 128 >> %TAOS_CFG% echo dataDir %DATA_DIR% >> %TAOS_CFG% echo logDir %LOG_DIR% >> %TAOS_CFG% echo debugFlag 0 >> %TAOS_CFG% -echo mDebugFlag 135 >> %TAOS_CFG% -echo sdbDebugFlag 135 >> %TAOS_CFG% -echo dDebugFlag 135 >> %TAOS_CFG% -echo vDebugFlag 135 >> %TAOS_CFG% -echo tsdbDebugFlag 135 >> %TAOS_CFG% -echo cDebugFlag 135 >> %TAOS_CFG% -echo jnidebugFlag 135 >> %TAOS_CFG% -echo odbcdebugFlag 135 >> %TAOS_CFG% -echo httpDebugFlag 135 >> %TAOS_CFG% -echo monDebugFlag 135 >> %TAOS_CFG% -echo mqttDebugFlag 135 >> %TAOS_CFG% -echo qdebugFlag 135 >> %TAOS_CFG% -echo rpcDebugFlag 135 >> %TAOS_CFG% +echo mDebugFlag 143 >> %TAOS_CFG% +echo dDebugFlag 143 >> %TAOS_CFG% +echo vDebugFlag 143 >> %TAOS_CFG% +echo tqDebugFlag 143 >> %TAOS_CFG% +echo tsdbDebugFlag 143 >> %TAOS_CFG% +echo cDebugFlag 143 >> %TAOS_CFG% +echo jniDebugFlag 143 >> %TAOS_CFG% +echo qDebugFlag 143 >> %TAOS_CFG% +echo rpcDebugFlag 143 >> %TAOS_CFG% echo tmrDebugFlag 131 >> %TAOS_CFG% -echo udebugFlag 135 >> %TAOS_CFG% -echo sdebugFlag 135 >> %TAOS_CFG% -echo wdebugFlag 135 >> %TAOS_CFG% -echo cqdebugFlag 135 >> %TAOS_CFG% -echo monitor 0 >> %TAOS_CFG% -echo monitorInterval 1 >> %TAOS_CFG% -echo http 0 >> %TAOS_CFG% -echo slaveQuery 0 >> %TAOS_CFG% -echo numOfThreadsPerCore 2.0 >> %TAOS_CFG% -echo defaultPass taosdata >> %TAOS_CFG% +echo uDebugFlag 143 >> %TAOS_CFG% +echo sDebugFlag 143 >> %TAOS_CFG% +echo wDebugFlag 143 >> %TAOS_CFG% echo numOfLogLines 20000000 >> %TAOS_CFG% -echo mnodeEqualVnodeNum 0 >> %TAOS_CFG% -echo balanceInterval 1 >> %TAOS_CFG% -echo clog 2 >> %TAOS_CFG% -echo days 10 >> %TAOS_CFG% echo statusInterval 1 >> %TAOS_CFG% -echo maxVgroupsPerDb 4 >> %TAOS_CFG% -echo minTablesPerVnode 4 >> %TAOS_CFG% -echo maxTablesPerVnode 1000 >> %TAOS_CFG% -echo tableIncStepPerVnode 10000 >> %TAOS_CFG% echo asyncLog 0 >> %TAOS_CFG% -echo numOfMnodes 1 >> %TAOS_CFG% echo locale en_US.UTF-8 >> %TAOS_CFG% -echo fsync 0 >> %TAOS_CFG% echo telemetryReporting 0 >> %TAOS_CFG% diff --git a/tests/script/sh/exec.bat b/tests/script/sh/exec.bat index 6651c7aa8f..7a2c58fc66 100644 --- a/tests/script/sh/exec.bat +++ b/tests/script/sh/exec.bat @@ -30,9 +30,28 @@ rem echo CFG_DIR: %CFG_DIR% set TAOS_CFG=%CFG_DIR%taos.cfg rem echo TAOS_CFG: %TAOS_CFG% +set LOG_DIR=%NODE_DIR%log\ +rem echo LOG_DIR: %LOG_DIR% + +set TAOS_LOG=%LOG_DIR%taosdlog.0 +rem echo TAOS_LOG: %TAOS_LOG% + if %EXEC_OPTON% == start ( + rm -rf %TAOS_LOG% echo start %TAOSD% -c %CFG_DIR% start %TAOSD% -c %CFG_DIR% + set /a check_num=0 +:check_online + sleep 1 + set /a check_num=check_num+1 + if "%check_num%" == "11" ( + echo check online out time. + goto :finish + ) + echo check taosd online + tail -n +0 %TAOS_LOG% | grep -q "TDengine initialized successfully" || goto :check_online + echo finish + goto :finish ) if %EXEC_OPTON% == stop ( @@ -44,5 +63,8 @@ if %EXEC_OPTON% == stop ( ) do ( rem echo taskkill /IM %%A taskkill /IM %%A > NUL 2>&1 + goto :finish ) ) + +:finish \ No newline at end of file diff --git a/tests/script/sh/sum_double.c b/tests/script/sh/sum_double.c index 0297920361..d6eea5d291 100644 --- a/tests/script/sh/sum_double.c +++ b/tests/script/sh/sum_double.c @@ -10,7 +10,7 @@ typedef struct SUdfInit{ int const_item; /* 0 if result is independent of arguments */ } SUdfInit; -#define TSDB_DATA_INT_NULL 0x80000000L +#define TSDB_DATA_INT_NULL 0x80000000LL void sum_double(char* data, short itype, short ibytes, int numOfRows, long long* ts, char* dataOutput, char* interBuf, char* tsOutput, diff --git a/tests/script/tsim/db/alter_option.sim b/tests/script/tsim/db/alter_option.sim index fede960a6a..f24e32279d 100644 --- a/tests/script/tsim/db/alter_option.sim +++ b/tests/script/tsim/db/alter_option.sim @@ -43,8 +43,16 @@ print ===> $data20 $data21 $data22 $data23 $data24 $data25 if $data00 != 1 then return -1 endi -if $data01 != localhost:7100 then - return -1 +system_content printf %OS% +if $system_content == Windows_NT then + system_content printf %COMPUTERNAME%:7100 + if $data01 != $system_content then + return -1 + endi +else + if $data01 != localhost:7100 then + return -1 + endi endi if $data04 != ready then goto check_dnode_ready_1 diff --git a/tests/script/tsim/db/create_all_options.sim b/tests/script/tsim/db/create_all_options.sim index efe7ff99cf..3979ef1ec1 100644 --- a/tests/script/tsim/db/create_all_options.sim +++ b/tests/script/tsim/db/create_all_options.sim @@ -43,8 +43,16 @@ print ===> $data20 $data21 $data22 $data23 $data24 $data25 if $data00 != 1 then return -1 endi -if $data01 != localhost:7100 then - return -1 +system_content printf %OS% +if $system_content == Windows_NT then + system_content printf %COMPUTERNAME%:7100 + if $data01 != $system_content then + return -1 + endi +else + if $data01 != localhost:7100 then + return -1 + endi endi if $data04 != ready then goto check_dnode_ready_1 diff --git a/tests/script/tsim/dnode/drop_dnode_has_mnode.sim b/tests/script/tsim/dnode/drop_dnode_has_mnode.sim index 1dbec2c04d..16cd2bb3b0 100644 --- a/tests/script/tsim/dnode/drop_dnode_has_mnode.sim +++ b/tests/script/tsim/dnode/drop_dnode_has_mnode.sim @@ -70,6 +70,7 @@ if $data(2)[2] != follower then endi print =============== step4: drop dnode 2 +sql_error drop dnode 1 sql drop dnode 2 print show dnodes; @@ -83,7 +84,7 @@ if $data00 != 1 then return -1 endi -print show dnodes; +print show mnodes; sql show mnodes print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] diff --git a/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim new file mode 100644 index 0000000000..15ad13b6fa --- /dev/null +++ b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim @@ -0,0 +1,135 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/deploy.sh -n dnode3 -i 3 +system sh/cfg.sh -n dnode1 -c supportVnodes -v 0 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +sql connect + +print =============== step1 create dnode2 +sql create dnode $hostname port 7200 +sql create dnode $hostname port 7300 + +$x = 0 +step1: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi +if $data(3)[4] != offline then + goto step1 +endi + +print =============== step2 create database +sql create database d1 vgroups 4 +sql use d1 +sql create table d1.st (ts timestamp, i int) tags (j int) +sql create table d1.c1 using st tags(1) +sql show d1.tables +if $rows != 1 then + return -1 +endi + +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 4 then + return -1 +endi +if $data(2)[3] != 2 then + return -1 +endi +if $data(3)[3] != 2 then + return -1 +endi +if $data(4)[3] != 2 then + return -1 +endi +if $data(5)[3] != 2 then + return -1 +endi + +print =============== step3: start dnode 3 +system sh/exec.sh -n dnode3 -s start +$x = 0 +step4: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step4 +endi +if $data(2)[4] != ready then + goto step4 +endi +if $data(3)[4] != ready then + goto step4 +endi + +print =============== step3: drop dnode2 +sql drop dnode 2 + +print show dnodes; +sql show dnodes; +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] +if $rows != 2 then + return -1 +endi + +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 4 then + return -1 +endi +if $data(2)[3] != 3 then + return -1 +endi +if $data(3)[3] != 3 then + return -1 +endi +if $data(4)[3] != 3 then + return -1 +endi +if $data(5)[3] != 3 then + return -1 +endi + +print =============== step4: select data +sql show d1.tables +if $rows != 1 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT +system sh/exec.sh -n dnode3 -s stop -x SIGINT diff --git a/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim new file mode 100644 index 0000000000..35a2466297 --- /dev/null +++ b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim @@ -0,0 +1,135 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/deploy.sh -n dnode3 -i 3 +system sh/deploy.sh -n dnode4 -i 4 +system sh/deploy.sh -n dnode5 -i 5 +system sh/cfg.sh -n dnode1 -c supportVnodes -v 0 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +system sh/exec.sh -n dnode3 -s start +system sh/exec.sh -n dnode4 -s start +sql connect + +print =============== step1 create dnode2 dnode3 dnode4 dnode 5 +sql create dnode $hostname port 7200 +sql create dnode $hostname port 7300 +sql create dnode $hostname port 7400 +sql create dnode $hostname port 7500 + +$x = 0 +step1: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi +if $data(3)[4] != ready then + goto step1 +endi +if $data(4)[4] != ready then + goto step1 +endi +if $data(5)[4] != offline then + goto step1 +endi + +print =============== step3 create database +sql create database d1 vgroups 4 replica 3 +sql use d1 +sql create table d1.st (ts timestamp, i int) tags (j int) +sql create table d1.c1 using st tags(1) +sql show d1.tables +if $rows != 1 then + return -1 +endi + +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi +if $data(2)[3] != 2 then + return -1 +endi +if $data(2)[5] != 3 then + return -1 +endi +if $data(2)[7] != 4 then + return -1 +endi + +print =============== step4: drop dnode 2 +system sh/exec.sh -n dnode5 -s start +$x = 0 +step4: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step4 +endi +if $data(2)[4] != ready then + goto step4 +endi +if $data(3)[4] != ready then + goto step4 +endi +if $data(4)[4] != ready then + goto step4 +endi +if $data(5)[4] != ready then + goto step4 +endi + +print =============== step5: drop dnode2 +sql drop dnode 2 + +print show dnodes; +sql show dnodes; +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] +if $rows != 4 then + return -1 +endi + +print show d1.vgroups +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi + + +print =============== step6: select data +sql show d1.tables +if $rows != 1 then + return -1 +endi + +return +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT +system sh/exec.sh -n dnode3 -s stop -x SIGINT diff --git a/tests/script/tsim/dnode/drop_dnode_has_qnode_snode.sim b/tests/script/tsim/dnode/drop_dnode_has_qnode_snode.sim new file mode 100644 index 0000000000..6641ce053c --- /dev/null +++ b/tests/script/tsim/dnode/drop_dnode_has_qnode_snode.sim @@ -0,0 +1,71 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +sql connect + +print =============== step1 create dnode2 +sql create dnode $hostname port 7200 + +$x = 0 +step1: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 2 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi + +print =============== step2: create qnode snode on dnode 2 +sql create qnode on dnode 2 +sql create snode on dnode 2 + +sql show qnodes +if $rows != 1 then + return -1 +endi + +sql show snodes +if $rows != 1 then + return -1 +endi + +print =============== step3: drop dnode 2 +sql drop dnode 2 + +print show dnodes; +sql show dnodes; +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] +if $rows != 1 then + return -1 +endi +if $data00 != 1 then + return -1 +endi + +sql show qnodes +if $rows != 0 then + return -1 +endi + +sql show snodes +if $rows != 0 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT diff --git a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica1.sim b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica1.sim new file mode 100644 index 0000000000..63639877ee --- /dev/null +++ b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica1.sim @@ -0,0 +1,151 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/deploy.sh -n dnode3 -i 3 +system sh/cfg.sh -n dnode1 -c supportVnodes -v 0 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +sql connect + +print =============== step1 create dnode2 +sql create dnode $hostname port 7200 +sql create dnode $hostname port 7300 + +$x = 0 +step1: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi +if $data(3)[4] != offline then + goto step1 +endi + +print =============== step2 drop dnode which not exist +sql_error drop dnode 1 +sql_error drop dnode 4 + +print =============== step3 create database +sql create database d1 vgroups 1 +sql use d1 +sql create table d1.st (ts timestamp, i int) tags (j int) +sql create table d1.c1 using st tags(1) +sql show d1.tables +if $rows != 1 then + return -1 +endi + +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi +if $data(2)[3] != 2 then + return -1 +endi + +print =============== step4: drop dnode 2 +print cant drop since no enough vnodes +sql_error drop dnode 2 + +system sh/exec.sh -n dnode2 -s stop +system sh/exec.sh -n dnode3 -s start +$x = 0 +step4: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step4 +endi +if $data(2)[4] != offline then + goto step4 +endi +if $data(3)[4] != ready then + goto step4 +endi + +# cant drop since offline +sql_error drop dnode 2 + +print =============== step5: start dnode2 +system sh/exec.sh -n dnode2 -s start + +$x = 0 +step5: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step5 +endi +if $data(2)[4] != ready then + goto step5 +endi +if $data(3)[4] != ready then + goto step5 +endi + +print =============== step6: drop dnode2 +sql drop dnode 2 + +print show dnodes; +sql show dnodes; +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] +if $rows != 2 then + return -1 +endi + +print show d1.vgroups +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi +if $data(2)[3] != 3 then + return -1 +endi + +print =============== step7: select data +sql show d1.tables +if $rows != 1 then + return -1 +endi + +return +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT +system sh/exec.sh -n dnode3 -s stop -x SIGINT diff --git a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim new file mode 100644 index 0000000000..91679a7e81 --- /dev/null +++ b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim @@ -0,0 +1,137 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/deploy.sh -n dnode3 -i 3 +system sh/deploy.sh -n dnode4 -i 4 +system sh/deploy.sh -n dnode5 -i 5 +system sh/cfg.sh -n dnode1 -c supportVnodes -v 0 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +system sh/exec.sh -n dnode3 -s start +system sh/exec.sh -n dnode4 -s start +sql connect + +print =============== step1 create dnode2 dnode3 dnode4 dnode 5 +sql create dnode $hostname port 7200 +sql create dnode $hostname port 7300 +sql create dnode $hostname port 7400 +sql create dnode $hostname port 7500 + +$x = 0 +step1: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi +if $data(3)[4] != ready then + goto step1 +endi +if $data(4)[4] != ready then + goto step1 +endi +if $data(5)[4] != offline then + goto step1 +endi + +print =============== step3 create database +sql create database d1 vgroups 1 replica 3 +sql use d1 +sql create table d1.st (ts timestamp, i int) tags (j int) +sql create table d1.c1 using st tags(1) +sql show d1.tables +if $rows != 1 then + return -1 +endi + +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi +if $data(2)[3] != 2 then + return -1 +endi +if $data(2)[5] != 3 then + return -1 +endi +if $data(2)[7] != 4 then + return -1 +endi + +print =============== step4: drop dnode 2 +system sh/exec.sh -n dnode5 -s start +$x = 0 +step4: + $ = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not online! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 3 then + return -1 +endi +if $data(1)[4] != ready then + goto step4 +endi +if $data(2)[4] != ready then + goto step4 +endi +if $data(3)[4] != ready then + goto step4 +endi +if $data(4)[4] != ready then + goto step4 +endi +if $data(5)[4] != ready then + goto step4 +endi + +print =============== step5: drop dnode2 +sql drop dnode 2 + +print show dnodes; +sql show dnodes; +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +print $data[1][0] $data[1][1] $data[1][2] $data[1][3] $data[1][4] +if $rows != 4 then + return -1 +endi + +print show d1.vgroups +sql show d1.vgroups +print $data[0][0] $data[0][1] $data[0][2] $data[0][3] $data[0][4] +if $rows != 1 then + return -1 +endi +#if $data(2)[3] != 3 then +# return -1 +#endi + +print =============== step6: select data +sql show d1.tables +if $rows != 1 then + return -1 +endi + +return +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT +system sh/exec.sh -n dnode3 -s stop -x SIGINT diff --git a/tests/script/tsim/mnode/basic5.sim b/tests/script/tsim/mnode/basic5.sim index fc591aa25d..23f5f6d782 100644 --- a/tests/script/tsim/mnode/basic5.sim +++ b/tests/script/tsim/mnode/basic5.sim @@ -148,7 +148,7 @@ endi print =============== step6: stop mnode1 system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sql_error drop mnode on dnode 1 +# sql_error drop mnode on dnode 1 $x = 0 step61: diff --git a/tests/script/tsim/show/basic.sim b/tests/script/tsim/show/basic.sim index f23d75d78b..94ca2f6550 100644 --- a/tests/script/tsim/show/basic.sim +++ b/tests/script/tsim/show/basic.sim @@ -36,6 +36,7 @@ sql create database db vgroups 3 sql use db sql create table stb (ts timestamp, c int) tags (t int) sql create table t0 using stb tags (0) +sql create table tba (ts timestamp, c1 binary(10), c2 nchar(10)); print =============== run show xxxx sql show dnodes @@ -62,7 +63,7 @@ if $rows != 1 then endi #sql show streams, sql show tables -if $rows != 1 then +if $rows != 2 then return -1 endi #sql show user_table_distributed @@ -98,7 +99,7 @@ if $rows != 1 then endi #sql select * from information_schema.`streams` sql select * from information_schema.user_tables -if $rows != 29 then +if $rows != 30 then return -1 endi #sql select * from information_schema.user_table_distributed @@ -160,7 +161,7 @@ if $rows != 1 then endi #sql show streams, sql show tables -if $rows != 1 then +if $rows != 2 then return -1 endi #sql show user_table_distributed @@ -196,7 +197,7 @@ if $rows != 1 then endi #sql select * from performance_schema.`streams` sql select * from information_schema.user_tables -if $rows != 29 then +if $rows != 30 then return -1 endi #sql select * from information_schema.user_table_distributed @@ -209,5 +210,22 @@ if $rows != 3 then return -1 endi +sql show create stable stb; +if $rows != 1 then + return -1 +endi + +sql show create table t0; +if $rows != 1 then + return -1 +endi + +sql show create table tba; +if $rows != 1 then + return -1 +endi + +sql_error show create stable t0; + system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode2 -s stop -x SIGINT diff --git a/tests/script/tsim/stream/windowClose.sim b/tests/script/tsim/stream/windowClose.sim index 07d7fb794e..695d5749fa 100644 --- a/tests/script/tsim/stream/windowClose.sim +++ b/tests/script/tsim/stream/windowClose.sim @@ -22,7 +22,7 @@ sql create stream stream1 trigger window_close into streamt as select _wstartts sql insert into tu1 values(now, 1); -sleep 300 +sleep 500 sql select * from streamt; if $rows != 0 then print ======$rows diff --git a/tests/script/tsim/trans/create_db.sim b/tests/script/tsim/trans/create_db.sim index f730f2fb67..d4d158ede0 100644 --- a/tests/script/tsim/trans/create_db.sim +++ b/tests/script/tsim/trans/create_db.sim @@ -96,50 +96,53 @@ sql_error create database d1 vgroups 2; print =============== kill dnode2 system sh/exec.sh -n dnode2 -s stop -x SIGINT -print =============== create database -sql show transactions -if $rows != 0 then - return -1 -endi +system_content printf %OS% +if $system_content != Windows_NT then + print =============== create database + sql show transactions + if $rows != 0 then + return -1 + endi -sql_error create database d2 vgroups 2; + sql_error create database d2 vgroups 2; -print =============== show transactions -sql show transactions -if $rows != 1 then - return -1 -endi + print =============== show transactions + sql show transactions + if $rows != 1 then + return -1 + endi -if $data[0][0] != 8 then - return -1 -endi + if $data[0][0] != 8 then + return -1 + endi -if $data[0][2] != redoAction then - return -1 -endi + if $data[0][2] != redoAction then + return -1 + endi -if $data[0][3] != d2 then - return -1 -endi + if $data[0][3] != d2 then + return -1 + endi -sql show databases ; -if $rows != 4 then - return -1 -endi -print d2 ==> $data(d2)[19] -if $data(d2)[19] != creating then - return -1 -endi + sql show databases ; + if $rows != 4 then + return -1 + endi + print d2 ==> $data(d2)[19] + if $data(d2)[19] != creating then + return -1 + endi -sql_error create database d2 vgroups 2; + sql_error create database d2 vgroups 2; -print =============== kill transaction -sql kill transaction 8; -sleep 2000 + print =============== kill transaction + sql kill transaction 8; + sleep 2000 -sql show transactions -if $rows != 0 then - return -1 + sql show transactions + if $rows != 0 then + return -1 + endi endi print =============== start dnode2 @@ -153,25 +156,25 @@ step3: print ====> dnode not ready! return -1 endi -sql show dnodes -print ===> $data00 $data01 $data02 $data03 $data04 $data05 -print ===> $data10 $data11 $data12 $data13 $data14 $data15 -if $rows != 2 then - return -1 -endi -if $data(1)[4] != ready then - goto step3 -endi -if $data(2)[4] != ready then - goto step3 -endi + sql show dnodes + print ===> $data00 $data01 $data02 $data03 $data04 $data05 + print ===> $data10 $data11 $data12 $data13 $data14 $data15 + if $rows != 2 then + return -1 + endi + if $data(1)[4] != ready then + goto step3 + endi + if $data(2)[4] != ready then + goto step3 + endi sql show transactions if $rows != 0 then return -1 endi -sql drop database d2; +sql drop database if exists d2; sql show transactions if $rows != 0 then diff --git a/tests/script/wtest.bat b/tests/script/wtest.bat index 9ed58a90d1..1aa27202c6 100644 --- a/tests/script/wtest.bat +++ b/tests/script/wtest.bat @@ -52,6 +52,7 @@ echo wal 0 >> %TAOS_CFG% echo asyncLog 0 >> %TAOS_CFG% echo locale en_US.UTF-8 >> %TAOS_CFG% echo enableCoreFile 1 >> %TAOS_CFG% +echo charset cp65001 >> %TAOS_CFG% set "FILE_NAME=testSuite.sim" if "%1" == "-f" set "FILE_NAME=%2" diff --git a/tests/system-test/1-insert/create_retentions.py b/tests/system-test/1-insert/create_retentions.py index 313c643822..5a0684e2ee 100644 --- a/tests/system-test/1-insert/create_retentions.py +++ b/tests/system-test/1-insert/create_retentions.py @@ -1,5 +1,7 @@ import datetime +from dataclasses import dataclass +from typing import List from util.log import * from util.sql import * from util.cases import * @@ -28,6 +30,28 @@ CHAR_COL = [ BINARY_COL, NCHAR_COL, ] BOOLEAN_COL = [ BOOL_COL, ] TS_TYPE_COL = [ TS_COL, ] +## insert data args: +TIME_STEP = 10000 +NOW = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + +@dataclass +class DataSet: + ts_data : List[int] = None + int_data : List[int] = None + bint_data : List[int] = None + sint_data : List[int] = None + tint_data : List[int] = None + int_un_data : List[int] = None + bint_un_data : List[int] = None + sint_un_data : List[int] = None + tint_un_data : List[int] = None + float_data : List[float] = None + double_data : List[float] = None + bool_data : List[int] = None + binary_data : List[str] = None + nchar_data : List[str] = None + + class TDTestCase: def init(self, conn, logSql): @@ -37,10 +61,13 @@ class TDTestCase: @property def create_databases_sql_err(self): return [ - "create database if not exists db1 retentions 0s:1d", - "create database if not exists db1 retentions 1s:1y", - "create database if not exists db1 retentions 1s:1n", - "create database if not exists db1 retentions 1s:1n,2s:2d,3s:3d,4s:4d", + "create database db1 retentions 0s:1d", + "create database db3 retentions 1s:0d", + "create database db1 retentions 1s:1y", + "create database db1 retentions 1s:1n", + "create database db2 retentions 1w:1d ;", + "create database db5 retentions 1s:1d,3s:3d,2s:2d", + "create database db1 retentions 1s:1n,2s:2d,3s:3d,4s:4d", ] @property @@ -60,16 +87,41 @@ class TDTestCase: @property def create_stable_sql_err(self): return [ - f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(ceil) delay 1", - f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(count) delay 1", - f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} binary(16)) tags (tag1 int) rollup(avg) delay 1", - f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) tags (tag1 int) rollup(avg) delay 1", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(ceil) watermark 1s maxdelay 1m", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(count) watermark 1min", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay -1s", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark -1m", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) watermark 1m ", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) maxdelay 1m ", + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} binary(16)) tags (tag1 int) rollup(avg) watermark 1s", + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) tags (tag1 int) rollup(avg) maxdelay 1m", + # f"create table ntb_1 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) rollup(avg) watermark 1s maxdelay 1s", + # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) tags (tag1 int) " , + # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) " , + # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) " , + # f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int, {BINARY_COL} nchar(16)) " , + + # watermark, maxdelay: [0, 900000], [ms, s, m, ?] + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay 1u", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark 1b", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark 900001ms", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay 16m", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay 901s", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay 1h", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) maxdelay 0.2h", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark 0.002d", + ] @property def create_stable_sql_current(self): return [ - f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(avg) delay 5", + f"create stable stb1 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(avg)", + f"create stable stb2 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(min) watermark 5s maxdelay 1m", + f"create stable stb3 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(max) watermark 5s maxdelay 1m", + f"create stable stb4 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(sum) watermark 5s maxdelay 1m", + # f"create stable stb5 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(last) watermark 5s maxdelay 1m", + # f"create stable stb6 ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) rollup(first) watermark 5s maxdelay 1m", ] def test_create_stb(self): @@ -79,14 +131,19 @@ class TDTestCase: for cur_sql in self.create_stable_sql_current: tdSql.execute(cur_sql) tdSql.query("show stables") + # assert "rollup" in tdSql.description tdSql.checkRows(len(self.create_stable_sql_current)) + # tdSql.execute("use db") # because db is a noraml database, not a rollup database, should not be able to create a rollup database + # tdSql.error(f"create stable nor_db_rollup_stb ({PRIMARY_COL} timestamp, {INT_COL} int) tags (tag1 int) file_factor 5.0") + + def test_create_databases(self): for err_sql in self.create_databases_sql_err: tdSql.error(err_sql) for cur_sql in self.create_databases_sql_current: tdSql.execute(cur_sql) - tdSql.query("show databases") + # tdSql.query("show databases") for alter_sql in self.alter_database_sql: tdSql.error(alter_sql) @@ -95,9 +152,7 @@ class TDTestCase: self.test_create_stb() def __create_tb(self): - tdSql.prepare() - - tdLog.printNoPrefix("==========step1:create table") + tdLog.printNoPrefix("==========step: create table") create_stb_sql = f'''create table stb1( ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, @@ -120,129 +175,118 @@ class TDTestCase: for i in range(4): tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )') - def __create_data_set(self, rows): - now_time = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) - pos_data = [] - neg_data = [] - spec_data = [] - for i in range(rows): - pos_data.append( - ( - now_time - i * 1000, i, 11111 * i, 111 * i % 32767 , 11 * i % 127, 1.11 * i, 1100.0011 * i, - i % 2, f'binary{i}', f'nchar_测试_{i}', now_time + 1 * i, 11 * i % 127, 111 * i % 32767, i, 11111 * i - ) - ) - neg_data.append( - ( - now_time - i * 7776000000, -i, -11111 * i, -111 * i % 32767, -11 * i % 127, -1.11 * i, -1100.0011 * i, - i % 2, f'binary{i}', f'nchar_测试_{i}', now_time + 1 * i, 11 * i % 127, 111 * i % 32767, i, 11111 * i - ) - ) - - def __insert_data(self, rows): - now_time = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) - for i in range(rows): - tdSql.execute( - f'''insert into ct1 values ( - { now_time - i * 1000 }, {i}, {11111 * i}, {111 * i % 32767 }, {11 * i % 127}, {1.11*i}, {1100.0011*i}, - {i%2}, 'binary{i}', 'nchar_测试_{i}', { now_time + 1 * i }, {11 * i % 127}, {111 * i % 32767}, {i}, {11111 * i} )''' - ) - tdSql.execute( - f'''insert into ct4 values ( - { now_time - i * 7776000000 }, {i}, {11111 * i}, {111 * i % 32767 }, {11 * i % 127}, {1.11*i}, {1100.0011*i}, - {i%2}, 'binary{i}', 'nchar_测试_{i}', { now_time + 1 * i }, {11 * i % 127}, {111 * i % 32767}, {i}, {11111 * i} )''' - ) - tdSql.execute( - f'''insert into ct2 values ( - { now_time - i * 7776000000 }, {-i}, {-11111 * i}, {-111 * i % 32767 }, {-11 * i % 127}, {-1.11*i}, {-1100.0011*i}, - {i%2}, 'binary{i}', 'nchar_测试_{i}', { now_time + 1 * i }, {11 * i % 127}, {111 * i % 32767}, {i}, {11111 * i} )''' - ) - tdSql.execute( - f'''insert into ct1 values - ( { now_time - rows * 5 }, 0, 0, 0, 0, 0, 0, 0, 'binary0', 'nchar_测试_0', { now_time + 8 }, 0, 0, 0, 0) - ( { now_time + 10000 }, { rows }, -99999, -999, -99, -9.99, -99.99, 1, 'binary9', 'nchar_测试_9', { now_time + 9 }, 0, 0, 0, 0 ) - ''' - ) - - tdSql.execute( - f'''insert into ct4 values - ( { now_time - rows * 7776000000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( { now_time - rows * 3888000000 + 10800000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( { now_time + 7776000000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( - { now_time + 5184000000}, {pow(2,31)-pow(2,15)}, {pow(2,63)-pow(2,30)}, 32767, 127, - { 3.3 * pow(10,38) }, { 1.3 * pow(10,308) }, { rows % 2 }, "binary_limit-1", "nchar_测试_limit-1", { now_time - 86400000}, - 254, 65534, {pow(2,32)-pow(2,16)}, {pow(2,64)-pow(2,31)} - ) - ( - { now_time + 2592000000 }, {pow(2,31)-pow(2,16)}, {pow(2,63)-pow(2,31)}, 32766, 126, - { 3.2 * pow(10,38) }, { 1.2 * pow(10,308) }, { (rows-1) % 2 }, "binary_limit-2", "nchar_测试_limit-2", { now_time - 172800000}, - 255, 65535, {pow(2,32)-pow(2,15)}, {pow(2,64)-pow(2,30)} - ) - ''' - ) - - tdSql.execute( - f'''insert into ct2 values - ( { now_time - rows * 7776000000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( { now_time - rows * 3888000000 + 10800000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( { now_time + 7776000000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( - { now_time + 5184000000 }, { -1 * pow(2,31) + pow(2,15) }, { -1 * pow(2,63) + pow(2,30) }, -32766, -126, { -1 * 3.2 * pow(10,38) }, - { -1.2 * pow(10,308) }, { rows % 2 }, "binary_limit-1", "nchar_测试_limit-1", { now_time - 86400000 }, 1, 1, 1, 1 - ) - ( - { now_time + 2592000000 }, { -1 * pow(2,31) + pow(2,16) }, { -1 * pow(2,63) + pow(2,31) }, -32767, -127, { - 3.3 * pow(10,38) }, - { -1.3 * pow(10,308) }, { (rows-1) % 2 }, "binary_limit-2", "nchar_测试_limit-2", { now_time - 172800000 }, 1, 1, 1, 1 - ) - ''' - ) + def __data_set(self, rows): + data_set = DataSet() + # neg_data_set = DataSet() + data_set.ts_data = [] + data_set.int_data = [] + data_set.bint_data = [] + data_set.sint_data = [] + data_set.tint_data = [] + data_set.int_un_data = [] + data_set.bint_un_data = [] + data_set.sint_un_data = [] + data_set.tint_un_data = [] + data_set.float_data = [] + data_set.double_data = [] + data_set.bool_data = [] + data_set.binary_data = [] + data_set.nchar_data = [] for i in range(rows): - insert_data = f'''insert into t1 values - ( { now_time - i * 3600000 }, {i}, {i * 11111}, { i % 32767 }, { i % 127}, { i * 1.11111 }, { i * 1000.1111 }, { i % 2}, - "binary_{i}", "nchar_测试_{i}", { now_time - 1000 * i }, {i % 127}, {i % 32767}, {i}, {i * 11111}) - ''' - tdSql.execute(insert_data) - tdSql.execute( - f'''insert into t1 values - ( { now_time + 10800000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( { now_time - (( rows // 2 ) * 60 + 30) * 60000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) - ( { now_time - rows * 3600000 }, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) - ( - { now_time + 7200000 }, { pow(2,31) - pow(2,15) }, { pow(2,63) - pow(2,30) }, 32767, 127, { 3.3 * pow(10,38) }, - { 1.3 * pow(10,308) }, { rows % 2 }, "binary_limit-1", "nchar_测试_limit-1", { now_time - 86400000 }, - 254, 65534, {pow(2,32)-pow(2,16)}, {pow(2,64)-pow(2,31)} - ) - ( - { now_time + 3600000 } , { pow(2,31) - pow(2,16) }, { pow(2,63) - pow(2,31) }, 32766, 126, { 3.2 * pow(10,38) }, - { 1.2 * pow(10,308) }, { (rows-1) % 2 }, "binary_limit-2", "nchar_测试_limit-2", { now_time - 172800000 }, - 255, 65535, {pow(2,32)-pow(2,15)}, {pow(2,64)-pow(2,30)} - ) + data_set.ts_data.append(NOW + 1 * (rows - i)) + data_set.int_data.append(rows - i) + data_set.bint_data.append(11111 * (rows - i)) + data_set.sint_data.append(111 * (rows - i) % 32767) + data_set.tint_data.append(11 * (rows - i) % 127) + data_set.int_un_data.append(rows - i) + data_set.bint_un_data.append(11111 * (rows - i)) + data_set.sint_un_data.append(111 * (rows - i) % 32767) + data_set.tint_un_data.append(11 * (rows - i) % 127) + data_set.float_data.append(1.11 * (rows - i)) + data_set.double_data.append(1100.0011 * (rows - i)) + data_set.bool_data.append((rows - i) % 2) + data_set.binary_data.append(f'binary{(rows - i)}') + data_set.nchar_data.append(f'nchar_测试_{(rows - i)}') + + # neg_data_set.ts_data.append(-1 * i) + # neg_data_set.int_data.append(-i) + # neg_data_set.bint_data.append(-11111 * i) + # neg_data_set.sint_data.append(-111 * i % 32767) + # neg_data_set.tint_data.append(-11 * i % 127) + # neg_data_set.int_un_data.append(-i) + # neg_data_set.bint_un_data.append(-11111 * i) + # neg_data_set.sint_un_data.append(-111 * i % 32767) + # neg_data_set.tint_un_data.append(-11 * i % 127) + # neg_data_set.float_data.append(-1.11 * i) + # neg_data_set.double_data.append(-1100.0011 * i) + # neg_data_set.binary_data.append(f'binary{i}') + # neg_data_set.nchar_data.append(f'nchar_测试_{i}') + + return data_set + + def __insert_data(self): + data = self.__data_set(rows=self.rows) + + # now_time = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + null_data = '''null, null, null, null, null, null, null, null, null, null, null, null, null, null''' + zero_data = "0, 0, 0, 0, 0, 0, 0, 'binary_0', 'nchar_0', 0, 0, 0, 0, 0" + + for i in range(self.rows): + row_data = f''' + {data.int_data[i]}, {data.bint_data[i]}, {data.sint_data[i]}, {data.tint_data[i]}, {data.float_data[i]}, {data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {data.tint_un_data[i]}, + {data.sint_un_data[i]}, {data.int_un_data[i]}, {data.bint_un_data[i]} ''' - ) + neg_row_data = f''' + {-1 * data.int_data[i]}, {-1 * data.bint_data[i]}, {-1 * data.sint_data[i]}, {-1 * data.tint_data[i]}, {-1 * data.float_data[i]}, {-1 * data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {1 * data.tint_un_data[i]}, + {1 * data.sint_un_data[i]}, {1 * data.int_un_data[i]}, {1 * data.bint_un_data[i]} + ''' + + tdSql.execute( f"insert into ct1 values ( {NOW - i * TIME_STEP}, {row_data} )" ) + tdSql.execute( f"insert into ct2 values ( {NOW - i * int(TIME_STEP * 0.6)}, {neg_row_data} )" ) + tdSql.execute( f"insert into ct4 values ( {NOW - i * int(TIME_STEP * 0.8) }, {row_data} )" ) + tdSql.execute( f"insert into t1 values ( {NOW - i * int(TIME_STEP * 1.2)}, {row_data} )" ) + + tdSql.execute( f"insert into ct2 values ( {NOW + int(TIME_STEP * 0.6)}, {null_data} )" ) + tdSql.execute( f"insert into ct2 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.6)}, {null_data} )" ) + tdSql.execute( f"insert into ct2 values ( {NOW - self.rows * int(TIME_STEP * 0.29) }, {null_data} )" ) + + tdSql.execute( f"insert into ct4 values ( {NOW + int(TIME_STEP * 0.8)}, {null_data} )" ) + tdSql.execute( f"insert into ct4 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.8)}, {null_data} )" ) + tdSql.execute( f"insert into ct4 values ( {NOW - self.rows * int(TIME_STEP * 0.39)}, {null_data} )" ) + + tdSql.execute( f"insert into t1 values ( {NOW + int(TIME_STEP * 1.2)}, {null_data} )" ) + tdSql.execute( f"insert into t1 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 1.2)}, {null_data} )" ) + tdSql.execute( f"insert into t1 values ( {NOW - self.rows * int(TIME_STEP * 0.59)}, {null_data} )" ) def run(self): - tdSql.prepare() - - tdLog.printNoPrefix("==========step1:create table") - self.__create_tb() - - tdLog.printNoPrefix("==========step2:insert data") self.rows = 10 - self.__insert_data(self.rows) - tdLog.printNoPrefix("==========step3:all check") - self.all_test() + + tdLog.printNoPrefix("==========step0:all check") + # self.all_test() + + tdLog.printNoPrefix("==========step1:create table in normal database") + tdSql.prepare() + self.__create_tb() + self.__insert_data() + # return + + tdLog.printNoPrefix("==========step2:create table in rollup database") + tdSql.execute("create database db3 retentions 1s:4m,2s:8m,3s:12m") + tdSql.execute("use db3") + self.__create_tb() + self.__insert_data() + tdSql.execute("drop database if exists db1 ") tdSql.execute("drop database if exists db2 ") tdDnodes.stop(1) tdDnodes.start(1) - tdSql.execute("use db") - tdLog.printNoPrefix("==========step4:after wal, all check again ") self.all_test() diff --git a/tests/system-test/1-insert/time_range_wise.py b/tests/system-test/1-insert/time_range_wise.py new file mode 100644 index 0000000000..5387970d56 --- /dev/null +++ b/tests/system-test/1-insert/time_range_wise.py @@ -0,0 +1,343 @@ +import datetime + +from dataclasses import dataclass +from typing import List, Any, Tuple +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.constant import * + +PRIMARY_COL = "ts" + +INT_COL = "c_int" +BINT_COL = "c_bint" +SINT_COL = "c_sint" +TINT_COL = "c_tint" +FLOAT_COL = "c_float" +DOUBLE_COL = "c_double" +BOOL_COL = "c_bool" +TINT_UN_COL = "c_tint_un" +SINT_UN_COL = "c_sint_un" +BINT_UN_COL = "c_bint_un" +INT_UN_COL = "c_int_un" +BINARY_COL = "c_binary" +NCHAR_COL = "c_nchar" +TS_COL = "c_ts" + + + +NUM_COL = [INT_COL, BINT_COL, SINT_COL, TINT_COL, FLOAT_COL, DOUBLE_COL, ] +CHAR_COL = [BINARY_COL, NCHAR_COL, ] +BOOLEAN_COL = [BOOL_COL, ] +TS_TYPE_COL = [TS_COL, ] + +# insert data args: +TIME_STEP = 10000 +NOW = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + + +@dataclass +class DataSet: + ts_data : List[int] = None + int_data : List[int] = None + bint_data : List[int] = None + sint_data : List[int] = None + tint_data : List[int] = None + int_un_data : List[int] = None + bint_un_data: List[int] = None + sint_un_data: List[int] = None + tint_un_data: List[int] = None + float_data : List[float] = None + double_data : List[float] = None + bool_data : List[int] = None + binary_data : List[str] = None + nchar_data : List[str] = None + + def __post_init__(self): + self.ts_data = [] + self.int_data = [] + self.bint_data = [] + self.sint_data = [] + self.tint_data = [] + self.int_un_data = [] + self.bint_un_data = [] + self.sint_un_data = [] + self.tint_un_data = [] + self.float_data = [] + self.double_data = [] + self.bool_data = [] + self.binary_data = [] + self.nchar_data = [] + + +@dataclass +class SMAschema: + creation : str = "CREATE" + index_name : str = "sma_index_1" + index_flag : str = "SMA INDEX" + operator : str = "ON" + tbname : str = None + watermark : str = None + maxdelay : str = None + func : Tuple[str] = None + interval : Tuple[str] = None + sliding : str = None + other : Any = None + drop : str = "DROP" + drop_flag : str = "INDEX" + + def __post_init__(self): + if isinstance(self.other, dict): + for k,v in self.other.items(): + + if k.lower() == "index_name" and isinstance(v, str) and not self.index_name: + self.index_name = v + del self.other[k] + + if k.lower() == "index_flag" and isinstance(v, str) and not self.index_flag: + self.index_flag = v + del self.other[k] + + if k.lower() == "operator" and isinstance(v, str) and not self.operator: + self.operator = v + del self.other[k] + + if k.lower() == "tbname" and isinstance(v, str) and not self.tbname: + self.tbname = v + del self.other[k] + + if k.lower() == "watermark" and isinstance(v, str) and not self.watermark: + self.watermark = v + del self.other[k] + + if k.lower() == "maxdelay" and isinstance(v, str) and not self.maxdelay: + self.maxdelay = v + del self.other[k] + + if k.lower() == "functions" and isinstance(v, tuple) and not self.func: + self.func = v + del self.other[k] + + if k.lower() == "interval" and isinstance(v, tuple) and not self.interval: + self.interval = v + del self.other[k] + + if k.lower() == "sliding" and isinstance(v, str) and not self.sliding: + self.sliding = v + del self.other[k] + + if k.lower() == "drop_flag" and isinstance(v, str) and not self.drop_flag: + self.drop_flag = v + del self.other[k] + + +class TDTestCase: + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + """ + create sma index : + 1. only create on stable, err_type: [child-table, normal-table] + 2. one taosd, one sma index , err_type: [ + one stb --> multi sma index, + multi stb in one db--> multi sma index, + multi stb in multi db --> multi sma index + ] + 3. arg of (interval/sliding) in query sql is equal to this arg in sma index + 4. client timezone is equal to timezone of sma index + 5. does not take effect unless querySmaOptimize flag is turned on, + """ + def __create_sma_index(self, sma:SMAschema): + sql = f"{sma.creation} {sma.index_flag} {sma.index_name} {sma.operator} {sma.tbname}" + if sma.func: + sql += f" function({', '.join(sma.func)})" + if sma.interval: + sql += f" interval({', '.join(sma.interval)})" + if sma.sliding: + sql += f" sliding({sma.sliding})" + if sma.watermark: + sql += f" watermark {sma.watermark}" + if sma.maxdelay: + sql += f" maxdelay {sma.maxdelay}" + if isinstance(sma.other, dict): + for k,v in sma.other.items(): + if isinstance(v,tuple) or isinstance(v, list): + sql += f" {k} ({' '.join(v)})" + else: + sql += f" {k} {v}" + if isinstance(sma.other, tuple) or isinstance(sma.other, list): + sql += " ".join(sma.other) + if isinstance(sma.other, int) or isinstance(sma.other, float) or isinstance(sma.other, str): + sql += sma.other + + return sql + + def sma_create_check(self, sma:SMAschema): + tdSql.query("show stables") + stb_in_list = False + for row in tdSql.queryResult: + if sma.tbname == row[0]: + stb_in_list = True + break + if not stb_in_list: + tdSql.error(self.__create_sma_index(sma)) + if not sma.creation: + tdSql.error(self.__create_sma_index(sma)) + if not sma.index_flag: + tdSql.error(self.__create_sma_index(sma)) + if not sma.index_name: + tdSql.error(self.__create_sma_index(sma)) + if not sma.operator: + tdSql.error(self.__create_sma_index(sma)) + if not sma.tbname: + tdSql.error(self.__create_sma_index(sma)) + if not sma.func: + tdSql.error(self.__create_sma_index(sma)) + if not sma.interval: + tdSql.error(self.__create_sma_index(sma)) + if not sma.sliding: + tdSql.error(self.__create_sma_index(sma)) + if sma.other: + tdSql.error(self.__create_sma_index(sma)) + + + def all_test(self): + pass + + def __create_tb(self): + tdLog.printNoPrefix("==========step: create table") + create_stb_sql = f'''create table stb1( + ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, + {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, + {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp, + {TINT_UN_COL} tinyint unsigned, {SINT_UN_COL} smallint unsigned, + {INT_UN_COL} int unsigned, {BINT_UN_COL} bigint unsigned + ) tags (tag1 int) + ''' + create_ntb_sql = f'''create table t1( + ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, + {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, + {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp, + {TINT_UN_COL} tinyint unsigned, {SINT_UN_COL} smallint unsigned, + {INT_UN_COL} int unsigned, {BINT_UN_COL} bigint unsigned + ) + ''' + tdSql.execute(create_stb_sql) + tdSql.execute(create_ntb_sql) + + for i in range(4): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )') + + def __data_set(self, rows): + data_set = DataSet() + + for i in range(rows): + data_set.ts_data.append(NOW + 1 * (rows - i)) + data_set.int_data.append(rows - i) + data_set.bint_data.append(11111 * (rows - i)) + data_set.sint_data.append(111 * (rows - i) % 32767) + data_set.tint_data.append(11 * (rows - i) % 127) + data_set.int_un_data.append(rows - i) + data_set.bint_un_data.append(11111 * (rows - i)) + data_set.sint_un_data.append(111 * (rows - i) % 32767) + data_set.tint_un_data.append(11 * (rows - i) % 127) + data_set.float_data.append(1.11 * (rows - i)) + data_set.double_data.append(1100.0011 * (rows - i)) + data_set.bool_data.append((rows - i) % 2) + data_set.binary_data.append(f'binary{(rows - i)}') + data_set.nchar_data.append(f'nchar_测试_{(rows - i)}') + + return data_set + + def __insert_data(self): + data = self.__data_set(rows=self.rows) + + # now_time = int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000) + null_data = '''null, null, null, null, null, null, null, null, null, null, null, null, null, null''' + zero_data = "0, 0, 0, 0, 0, 0, 0, 'binary_0', 'nchar_0', 0, 0, 0, 0, 0" + + for i in range(self.rows): + row_data = f''' + {data.int_data[i]}, {data.bint_data[i]}, {data.sint_data[i]}, {data.tint_data[i]}, {data.float_data[i]}, {data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {data.tint_un_data[i]}, + {data.sint_un_data[i]}, {data.int_un_data[i]}, {data.bint_un_data[i]} + ''' + neg_row_data = f''' + {-1 * data.int_data[i]}, {-1 * data.bint_data[i]}, {-1 * data.sint_data[i]}, {-1 * data.tint_data[i]}, {-1 * data.float_data[i]}, {-1 * data.double_data[i]}, + {data.bool_data[i]}, '{data.binary_data[i]}', '{data.nchar_data[i]}', {data.ts_data[i]}, {1 * data.tint_un_data[i]}, + {1 * data.sint_un_data[i]}, {1 * data.int_un_data[i]}, {1 * data.bint_un_data[i]} + ''' + + tdSql.execute( + f"insert into ct1 values ( {NOW - i * TIME_STEP}, {row_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - i * int(TIME_STEP * 0.6)}, {neg_row_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - i * int(TIME_STEP * 0.8) }, {row_data} )") + tdSql.execute( + f"insert into t1 values ( {NOW - i * int(TIME_STEP * 1.2)}, {row_data} )") + + tdSql.execute( + f"insert into ct2 values ( {NOW + int(TIME_STEP * 0.6)}, {null_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.6)}, {null_data} )") + tdSql.execute( + f"insert into ct2 values ( {NOW - self.rows * int(TIME_STEP * 0.29) }, {null_data} )") + + tdSql.execute( + f"insert into ct4 values ( {NOW + int(TIME_STEP * 0.8)}, {null_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 0.8)}, {null_data} )") + tdSql.execute( + f"insert into ct4 values ( {NOW - self.rows * int(TIME_STEP * 0.39)}, {null_data} )") + + tdSql.execute( + f"insert into t1 values ( {NOW + int(TIME_STEP * 1.2)}, {null_data} )") + tdSql.execute( + f"insert into t1 values ( {NOW - (self.rows + 1) * int(TIME_STEP * 1.2)}, {null_data} )") + tdSql.execute( + f"insert into t1 values ( {NOW - self.rows * int(TIME_STEP * 0.59)}, {null_data} )") + + def run(self): + sma1 = SMAschema(func=("min(c1)","max(c2)")) + sql1 = self.__create_sma_index(sma1) + print("================") + print(sql1) + # a = DataSet() + # return + self.rows = 10 + + tdLog.printNoPrefix("==========step0:all check") + # self.all_test() + + tdLog.printNoPrefix("==========step1:create table in normal database") + tdSql.prepare() + self.__create_tb() + self.__insert_data() + return + + tdLog.printNoPrefix("==========step2:create table in rollup database") + tdSql.execute("create database db3 retentions 1s:4m,2s:8m,3s:12m") + tdSql.execute("use db3") + self.__create_tb() + self.__insert_data() + + tdSql.execute("drop database if exists db1 ") + tdSql.execute("drop database if exists db2 ") + + tdDnodes.stop(1) + tdDnodes.start(1) + + tdLog.printNoPrefix("==========step4:after wal, all check again ") + self.all_test() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/distribute_agg_avg.py b/tests/system-test/2-query/distribute_agg_avg.py new file mode 100644 index 0000000000..647a262558 --- /dev/null +++ b/tests/system-test/2-query/distribute_agg_avg.py @@ -0,0 +1,279 @@ +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np +import random ,os ,sys +import platform + + +class TDTestCase: + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, + "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"fnDebugFlag":143, + "maxTablesPerVnode":2 ,"minTablesPerVnode":2,"tableIncStepPerVnode":2 } + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self.vnode_disbutes = None + self.ts = 1537146000000 + + + def check_avg_functions(self, tbname , col_name): + + avg_sql = f"select avg({col_name}) from {tbname};" + + same_sql = f"select {col_name} from {tbname} where {col_name} is not null " + + tdSql.query(same_sql) + pre_data = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None] + if (platform.system().lower() == 'windows' and pre_data.dtype == 'int32'): + pre_data = np.array(pre_data, dtype = 'int64') + pre_avg = np.sum(pre_data)/len(pre_data) + + tdSql.query(avg_sql) + tdSql.checkData(0,0,pre_avg) + + def prepare_datas_of_distribute(self): + + # prepate datas for 20 tables distributed at different vgroups + tdSql.execute("create database if not exists testdb keep 3650 duration 1000 vgroups 5") + tdSql.execute(" use testdb ") + tdSql.execute( + '''create table stb1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + tags (t0 timestamp, t1 int, t2 bigint, t3 smallint, t4 tinyint, t5 float, t6 double, t7 bool, t8 binary(16),t9 nchar(32)) + ''' + ) + + tdSql.execute( + ''' + create table t1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + ''' + ) + for i in range(20): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + + for i in range(9): + tdSql.execute( + f"insert into ct1 values ( now()-{i*10}s, {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, 'binary{i}', 'nchar{i}', now()+{1*i}a )" + ) + tdSql.execute( + f"insert into ct4 values ( now()-{i*90}d, {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, 'binary{i}', 'nchar{i}', now()+{1*i}a )" + ) + + for i in range(1,21): + if i ==1 or i == 4: + continue + else: + tbname = "ct"+f'{i}' + for j in range(9): + tdSql.execute( + f"insert into {tbname} values ( now()-{(i+j)*10}s, {1*(j+i)}, {11111*(j+i)}, {111*(j+i)}, {11*(j)}, {1.11*(j+i)}, {11.11*(j+i)}, {(j+i)%2}, 'binary{j}', 'nchar{j}', now()+{1*j}a )" + ) + tdSql.execute("insert into ct1 values (now()-45s, 0, 0, 0, 0, 0, 0, 0, 'binary0', 'nchar0', now()+8a )") + tdSql.execute("insert into ct1 values (now()+10s, 9, -99999, -999, -99, -9.99, -99.99, 1, 'binary9', 'nchar9', now()+9a )") + tdSql.execute("insert into ct1 values (now()+15s, 9, -99999, -999, -99, -9.99, NULL, 1, 'binary9', 'nchar9', now()+9a )") + tdSql.execute("insert into ct1 values (now()+20s, 9, -99999, -999, NULL, -9.99, -99.99, 1, 'binary9', 'nchar9', now()+9a )") + + tdSql.execute("insert into ct4 values (now()-810d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct4 values (now()-400d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct4 values (now()+90d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + + tdSql.execute( + f'''insert into t1 values + ( '2020-04-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ( '2020-10-21 01:01:01.000', 1, 11111, 111, 11, 1.11, 11.11, 1, "binary1", "nchar1", now()+1a ) + ( '2020-12-31 01:01:01.000', 2, 22222, 222, 22, 2.22, 22.22, 0, "binary2", "nchar2", now()+2a ) + ( '2021-01-01 01:01:06.000', 3, 33333, 333, 33, 3.33, 33.33, 0, "binary3", "nchar3", now()+3a ) + ( '2021-05-07 01:01:10.000', 4, 44444, 444, 44, 4.44, 44.44, 1, "binary4", "nchar4", now()+4a ) + ( '2021-07-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ( '2021-09-30 01:01:16.000', 5, 55555, 555, 55, 5.55, 55.55, 0, "binary5", "nchar5", now()+5a ) + ( '2022-02-01 01:01:20.000', 6, 66666, 666, 66, 6.66, 66.66, 1, "binary6", "nchar6", now()+6a ) + ( '2022-10-28 01:01:26.000', 7, 00000, 000, 00, 0.00, 00.00, 1, "binary7", "nchar7", "1970-01-01 08:00:00.000" ) + ( '2022-12-01 01:01:30.000', 8, -88888, -888, -88, -8.88, -88.88, 0, "binary8", "nchar8", "1969-01-01 01:00:00.000" ) + ( '2022-12-31 01:01:36.000', 9, -99999999999999999, -999, -99, -9.99, -999999999999999999999.99, 1, "binary9", "nchar9", "1900-01-01 00:00:00.000" ) + ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ''' + ) + + tdLog.info(" prepare data for distributed_aggregate done! ") + + def check_distribute_datas(self): + # get vgroup_ids of all + tdSql.query("show vgroups ") + vgroups = tdSql.queryResult + + vnode_tables={} + + for vgroup_id in vgroups: + vnode_tables[vgroup_id[0]]=[] + + + # check sub_table of per vnode ,make sure sub_table has been distributed + tdSql.query("show tables like 'ct%'") + table_names = tdSql.queryResult + tablenames = [] + for table_name in table_names: + vnode_tables[table_name[6]].append(table_name[0]) + self.vnode_disbutes = vnode_tables + + count = 0 + for k ,v in vnode_tables.items(): + if len(v)>=2: + count+=1 + if count < 2: + tdLog.exit(" the datas of all not satisfy sub_table has been distributed ") + + def check_avg_distribute_diff_vnode(self,col_name): + + vgroup_ids = [] + for k ,v in self.vnode_disbutes.items(): + if len(v)>=2: + vgroup_ids.append(k) + + distribute_tbnames = [] + + for vgroup_id in vgroup_ids: + vnode_tables = self.vnode_disbutes[vgroup_id] + distribute_tbnames.append(random.sample(vnode_tables,1)[0]) + tbname_ins = "" + for tbname in distribute_tbnames: + tbname_ins += "'%s' ,"%tbname + + tbname_filters = tbname_ins[:-1] + + avg_sql = f"select avg({col_name}) from stb1 where tbname in ({tbname_filters});" + + same_sql = f"select {col_name} from stb1 where tbname in ({tbname_filters}) and {col_name} is not null " + + tdSql.query(same_sql) + pre_data = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None] + if (platform.system().lower() == 'windows' and pre_data.dtype == 'int32'): + pre_data = np.array(pre_data, dtype = 'int64') + pre_avg = np.sum(pre_data)/len(pre_data) + + tdSql.query(avg_sql) + tdSql.checkData(0,0,pre_avg) + + def check_avg_status(self): + # check max function work status + + tdSql.query("show tables like 'ct%'") + table_names = tdSql.queryResult + tablenames = [] + for table_name in table_names: + tablenames.append(table_name[0]) + + tdSql.query("desc stb1") + col_names = tdSql.queryResult + + colnames = [] + for col_name in col_names: + if col_name[1] in ["INT" ,"BIGINT" ,"SMALLINT" ,"TINYINT" , "FLOAT" ,"DOUBLE"]: + colnames.append(col_name[0]) + + for tablename in tablenames: + for colname in colnames: + self.check_avg_functions(tablename,colname) + + # check max function for different vnode + + for colname in colnames: + if colname.startswith("c"): + self.check_avg_distribute_diff_vnode(colname) + else: + # self.check_avg_distribute_diff_vnode(colname) # bug for tag + pass + + + def distribute_agg_query(self): + # basic filter + tdSql.query(" select avg(c1) from stb1 ") + tdSql.checkData(0,0,14.086956522) + + tdSql.query(" select avg(a) from (select avg(c1) a from stb1 partition by tbname) ") + tdSql.checkData(0,0,14.292307692) + + tdSql.query(" select avg(c1) from stb1 where t1=1") + tdSql.checkData(0,0,6.000000000) + + tdSql.query("select avg(c1+c2) from stb1 where c1 =1 ") + tdSql.checkData(0,0,11112.000000000) + + tdSql.query("select avg(c1) from stb1 where tbname=\"ct2\"") + tdSql.checkData(0,0,6.000000000) + + tdSql.query("select avg(c1) from stb1 partition by tbname") + tdSql.checkRows(20) + + tdSql.query("select avg(c1) from stb1 where t1> 4 partition by tbname") + tdSql.checkRows(15) + + # union all + tdSql.query("select avg(c1) from stb1 union all select avg(c1) from stb1 ") + tdSql.checkRows(2) + tdSql.checkData(0,0,14.086956522) + + tdSql.query("select avg(a) from (select avg(c1) a from stb1 union all select avg(c1) a from stb1)") + tdSql.checkRows(1) + tdSql.checkData(0,0,14.086956522) + + # join + + tdSql.execute(" create database if not exists db ") + tdSql.execute(" use db ") + tdSql.execute(" create stable st (ts timestamp , c1 int ,c2 float) tags(t1 int) ") + tdSql.execute(" create table tb1 using st tags(1) ") + tdSql.execute(" create table tb2 using st tags(2) ") + + + for i in range(10): + ts = i*10 + self.ts + tdSql.execute(f" insert into tb1 values({ts},{i},{i}.0)") + tdSql.execute(f" insert into tb2 values({ts},{i},{i}.0)") + + tdSql.query("select avg(tb1.c1), avg(tb2.c2) from tb1, tb2 where tb1.ts=tb2.ts") + tdSql.checkRows(1) + tdSql.checkData(0,0,4.500000000) + tdSql.checkData(0,1,4.500000000) + + # group by + tdSql.execute(" use testdb ") + + # partition by tbname or partition by tag + tdSql.query("select avg(c1) from stb1 partition by tbname") + tdSql.checkRows(20) + + # nest query for support max + tdSql.query("select avg(c2+2)+1 from (select avg(c1) c2 from stb1)") + tdSql.checkData(0,0,17.086956522) + tdSql.query("select avg(c1+2) as c2 from (select ts ,c1 ,c2 from stb1)") + tdSql.checkData(0,0,16.086956522) + tdSql.query("select avg(a+2) as c2 from (select ts ,abs(c1) a ,c2 from stb1)") + tdSql.checkData(0,0,16.086956522) + + # mixup with other functions + tdSql.query("select max(c1),count(c1),last(c2,c3),sum(c1+c2),avg(c1) from stb1") + tdSql.checkData(0,0,28) + tdSql.checkData(0,1,184) + tdSql.checkData(0,2,-99999) + tdSql.checkData(0,3,-999) + tdSql.checkData(0,4,28202310.000000000) + tdSql.checkData(0,5,14.086956522) + + def run(self): + + self.prepare_datas_of_distribute() + self.check_distribute_datas() + self.check_avg_status() + self.distribute_agg_query() + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/distribute_agg_max.py b/tests/system-test/2-query/distribute_agg_max.py index ae0ab5aafa..5c9760cbcf 100644 --- a/tests/system-test/2-query/distribute_agg_max.py +++ b/tests/system-test/2-query/distribute_agg_max.py @@ -245,6 +245,27 @@ class TDTestCase: tdSql.query(" select max(c1),c2 from stb1 group by c2 ") tdSql.checkRows(31) + # selective common cols of datas + tdSql.query("select max(c1),c2,c3,c5 from stb1") + tdSql.checkRows(1) + tdSql.checkData(0,0,28) + tdSql.checkData(0,1,311108) + tdSql.checkData(0,2,3108) + tdSql.checkData(0,3,31.08000) + + tdSql.query("select max(c1),t1,c2,t3 from stb1") + tdSql.checkRows(1) + tdSql.checkData(0,0,28) + tdSql.checkData(0,1,19) + tdSql.checkData(0,2,311108) + + tdSql.query("select max(c1),ceil(t1),pow(c2,1)+2,abs(t3) from stb1") + tdSql.checkRows(1) + tdSql.checkData(0,0,28) + tdSql.checkData(0,1,19) + tdSql.checkData(0,2,311110.000000000) + tdSql.checkData(0,3,2109) + # partition by tbname or partition by tag tdSql.query("select max(c1),tbname from stb1 partition by tbname") query_data = tdSql.queryResult diff --git a/tests/system-test/2-query/distribute_agg_min.py b/tests/system-test/2-query/distribute_agg_min.py index 8a458c74df..dd20d88229 100644 --- a/tests/system-test/2-query/distribute_agg_min.py +++ b/tests/system-test/2-query/distribute_agg_min.py @@ -245,6 +245,24 @@ class TDTestCase: tdSql.query(" select min(c1),c2 from stb1 group by c2 ") tdSql.checkRows(31) + # selective common cols of datas + tdSql.query("select min(c1),c2,c3,c5 from stb1") + tdSql.checkRows(1) + tdSql.checkData(0,0,0) + tdSql.checkData(0,1,0) + tdSql.checkData(0,2,0) + tdSql.checkData(0,3,0) + + tdSql.query("select min(c1),t1,c2,t3 from stb1 where c1 >5") + tdSql.checkRows(1) + tdSql.checkData(0,0,6) + tdSql.checkData(0,2,66666) + + tdSql.query("select min(c1),ceil(t1),pow(c2,1)+2,abs(t3) from stb1 where c1>12") + tdSql.checkRows(1) + tdSql.checkData(0,0,13) + tdSql.checkData(0,2,144445.000000000) + # partition by tbname or partition by tag tdSql.query("select min(c1),tbname from stb1 partition by tbname") query_data = tdSql.queryResult diff --git a/tests/system-test/2-query/distribute_agg_stddev.py b/tests/system-test/2-query/distribute_agg_stddev.py new file mode 100644 index 0000000000..5050e6e940 --- /dev/null +++ b/tests/system-test/2-query/distribute_agg_stddev.py @@ -0,0 +1,304 @@ +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np +import random ,os ,sys +import platform +import math + +class TDTestCase: + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, + "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"fnDebugFlag":143, + "maxTablesPerVnode":2 ,"minTablesPerVnode":2,"tableIncStepPerVnode":2 } + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self.vnode_disbutes = None + self.ts = 1537146000000 + + + def check_stddev_functions(self, tbname , col_name): + + stddev_sql = f"select stddev({col_name}) from {tbname};" + + same_sql = f"select {col_name} from {tbname} where {col_name} is not null " + + tdSql.query(same_sql) + pre_data = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None] + if (platform.system().lower() == 'windows' and pre_data.dtype == 'int32'): + pre_data = np.array(pre_data, dtype = 'int64') + pre_avg = np.sum(pre_data)/len(pre_data) + + # Calculate variance + stddev_result = 0 + for num in tdSql.queryResult: + stddev_result += (num-pre_avg)*(num-pre_avg)/len(tdSql.queryResult) + + stddev_result = math.sqrt(stddev_result) + + tdSql.query(stddev_sql) + + if -0.0001 < tdSql.queryResult[0][0]-stddev_result < 0.0001: + tdLog.info(" sql:%s; row:0 col:0 data:%d , expect:%d"%(stddev_sql,tdSql.queryResult[0][0],stddev_result)) + else: + tdLog.exit(" sql:%s; row:0 col:0 data:%d , expect:%d"%(stddev_sql,tdSql.queryResult[0][0],stddev_result)) + + def prepare_datas_of_distribute(self): + + # prepate datas for 20 tables distributed at different vgroups + tdSql.execute("create database if not exists testdb keep 3650 duration 1000 vgroups 5") + tdSql.execute(" use testdb ") + tdSql.execute( + '''create table stb1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + tags (t0 timestamp, t1 int, t2 bigint, t3 smallint, t4 tinyint, t5 float, t6 double, t7 bool, t8 binary(16),t9 nchar(32)) + ''' + ) + + tdSql.execute( + ''' + create table t1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + ''' + ) + for i in range(20): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + + for i in range(9): + tdSql.execute( + f"insert into ct1 values ( now()-{i*10}s, {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, 'binary{i}', 'nchar{i}', now()+{1*i}a )" + ) + tdSql.execute( + f"insert into ct4 values ( now()-{i*90}d, {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, 'binary{i}', 'nchar{i}', now()+{1*i}a )" + ) + + for i in range(1,21): + if i ==1 or i == 4: + continue + else: + tbname = "ct"+f'{i}' + for j in range(9): + tdSql.execute( + f"insert into {tbname} values ( now()-{(i+j)*10}s, {1*(j+i)}, {11111*(j+i)}, {111*(j+i)}, {11*(j)}, {1.11*(j+i)}, {11.11*(j+i)}, {(j+i)%2}, 'binary{j}', 'nchar{j}', now()+{1*j}a )" + ) + tdSql.execute("insert into ct1 values (now()-45s, 0, 0, 0, 0, 0, 0, 0, 'binary0', 'nchar0', now()+8a )") + tdSql.execute("insert into ct1 values (now()+10s, 9, -99999, -999, -99, -9.99, -99.99, 1, 'binary9', 'nchar9', now()+9a )") + tdSql.execute("insert into ct1 values (now()+15s, 9, -99999, -999, -99, -9.99, NULL, 1, 'binary9', 'nchar9', now()+9a )") + tdSql.execute("insert into ct1 values (now()+20s, 9, -99999, -999, NULL, -9.99, -99.99, 1, 'binary9', 'nchar9', now()+9a )") + + tdSql.execute("insert into ct4 values (now()-810d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct4 values (now()-400d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct4 values (now()+90d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + + tdSql.execute( + f'''insert into t1 values + ( '2020-04-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ( '2020-10-21 01:01:01.000', 1, 11111, 111, 11, 1.11, 11.11, 1, "binary1", "nchar1", now()+1a ) + ( '2020-12-31 01:01:01.000', 2, 22222, 222, 22, 2.22, 22.22, 0, "binary2", "nchar2", now()+2a ) + ( '2021-01-01 01:01:06.000', 3, 33333, 333, 33, 3.33, 33.33, 0, "binary3", "nchar3", now()+3a ) + ( '2021-05-07 01:01:10.000', 4, 44444, 444, 44, 4.44, 44.44, 1, "binary4", "nchar4", now()+4a ) + ( '2021-07-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ( '2021-09-30 01:01:16.000', 5, 55555, 555, 55, 5.55, 55.55, 0, "binary5", "nchar5", now()+5a ) + ( '2022-02-01 01:01:20.000', 6, 66666, 666, 66, 6.66, 66.66, 1, "binary6", "nchar6", now()+6a ) + ( '2022-10-28 01:01:26.000', 7, 00000, 000, 00, 0.00, 00.00, 1, "binary7", "nchar7", "1970-01-01 08:00:00.000" ) + ( '2022-12-01 01:01:30.000', 8, -88888, -888, -88, -8.88, -88.88, 0, "binary8", "nchar8", "1969-01-01 01:00:00.000" ) + ( '2022-12-31 01:01:36.000', 9, -99999999999999999, -999, -99, -9.99, -999999999999999999999.99, 1, "binary9", "nchar9", "1900-01-01 00:00:00.000" ) + ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + ''' + ) + + tdLog.info(" prepare data for distributed_aggregate done! ") + + def check_distribute_datas(self): + # get vgroup_ids of all + tdSql.query("show vgroups ") + vgroups = tdSql.queryResult + + vnode_tables={} + + for vgroup_id in vgroups: + vnode_tables[vgroup_id[0]]=[] + + + # check sub_table of per vnode ,make sure sub_table has been distributed + tdSql.query("show tables like 'ct%'") + table_names = tdSql.queryResult + tablenames = [] + for table_name in table_names: + vnode_tables[table_name[6]].append(table_name[0]) + self.vnode_disbutes = vnode_tables + + count = 0 + for k ,v in vnode_tables.items(): + if len(v)>=2: + count+=1 + if count < 2: + tdLog.exit(" the datas of all not satisfy sub_table has been distributed ") + + def check_stddev_distribute_diff_vnode(self,col_name): + + vgroup_ids = [] + for k ,v in self.vnode_disbutes.items(): + if len(v)>=2: + vgroup_ids.append(k) + + distribute_tbnames = [] + + for vgroup_id in vgroup_ids: + vnode_tables = self.vnode_disbutes[vgroup_id] + distribute_tbnames.append(random.sample(vnode_tables,1)[0]) + tbname_ins = "" + for tbname in distribute_tbnames: + tbname_ins += "'%s' ,"%tbname + + tbname_filters = tbname_ins[:-1] + + stddev_sql = f"select stddev({col_name}) from stb1 where tbname in ({tbname_filters});" + + same_sql = f"select {col_name} from stb1 where tbname in ({tbname_filters}) and {col_name} is not null " + + tdSql.query(same_sql) + pre_data = np.array(tdSql.queryResult)[np.array(tdSql.queryResult) != None] + if (platform.system().lower() == 'windows' and pre_data.dtype == 'int32'): + pre_data = np.array(pre_data, dtype = 'int64') + pre_avg = np.sum(pre_data)/len(pre_data) + + # Calculate variance + stddev_result = 0 + for num in tdSql.queryResult: + stddev_result += (num-pre_avg)*(num-pre_avg)/len(tdSql.queryResult) + + stddev_result = math.sqrt(stddev_result) + + tdSql.query(stddev_sql) + tdSql.checkData(0,0,stddev_result) + + + def check_stddev_status(self): + # check max function work status + + tdSql.query("show tables like 'ct%'") + table_names = tdSql.queryResult + tablenames = [] + for table_name in table_names: + tablenames.append(table_name[0]) + + tdSql.query("desc stb1") + col_names = tdSql.queryResult + + colnames = [] + for col_name in col_names: + if col_name[1] in ["INT" ,"BIGINT" ,"SMALLINT" ,"TINYINT" , "FLOAT" ,"DOUBLE"]: + colnames.append(col_name[0]) + + for tablename in tablenames: + for colname in colnames: + if colname.startswith("c"): + self.check_stddev_functions(tablename,colname) + else: + # self.check_stddev_functions(tablename,colname) + pass + + + # check max function for different vnode + + for colname in colnames: + if colname.startswith("c"): + self.check_stddev_distribute_diff_vnode(colname) + else: + # self.check_stddev_distribute_diff_vnode(colname) # bug for tag + pass + + + def distribute_agg_query(self): + # basic filter + tdSql.query(" select stddev(c1) from stb1 ") + tdSql.checkData(0,0,6.694663959) + + tdSql.query(" select stddev(a) from (select stddev(c1) a from stb1 partition by tbname) ") + tdSql.checkData(0,0,0.156797505) + + tdSql.query(" select stddev(c1) from stb1 where t1=1") + tdSql.checkData(0,0,2.581988897) + + tdSql.query("select stddev(c1+c2) from stb1 where c1 =1 ") + tdSql.checkData(0,0,0.000000000) + + tdSql.query("select stddev(c1) from stb1 where tbname=\"ct2\"") + tdSql.checkData(0,0,2.581988897) + + tdSql.query("select stddev(c1) from stb1 partition by tbname") + tdSql.checkRows(20) + + tdSql.query("select stddev(c1) from stb1 where t1> 4 partition by tbname") + tdSql.checkRows(15) + + # union all + tdSql.query("select stddev(c1) from stb1 union all select stddev(c1) from stb1 ") + tdSql.checkRows(2) + tdSql.checkData(0,0,6.694663959) + + tdSql.query("select stddev(a) from (select stddev(c1) a from stb1 union all select stddev(c1) a from stb1)") + tdSql.checkRows(1) + tdSql.checkData(0,0,0.000000000) + + # join + + tdSql.execute(" create database if not exists db ") + tdSql.execute(" use db ") + tdSql.execute(" create stable st (ts timestamp , c1 int ,c2 float) tags(t1 int) ") + tdSql.execute(" create table tb1 using st tags(1) ") + tdSql.execute(" create table tb2 using st tags(2) ") + + + for i in range(10): + ts = i*10 + self.ts + tdSql.execute(f" insert into tb1 values({ts},{i},{i}.0)") + tdSql.execute(f" insert into tb2 values({ts},{i},{i}.0)") + + tdSql.query("select stddev(tb1.c1), stddev(tb2.c2) from tb1, tb2 where tb1.ts=tb2.ts") + tdSql.checkRows(1) + tdSql.checkData(0,0,2.872281323) + tdSql.checkData(0,1,2.872281323) + + # group by + tdSql.execute(" use testdb ") + + # partition by tbname or partition by tag + tdSql.query("select stddev(c1) from stb1 partition by tbname") + tdSql.checkRows(20) + + # nest query for support max + tdSql.query("select stddev(c2+2)+1 from (select stddev(c1) c2 from stb1)") + tdSql.checkData(0,0,1.000000000) + tdSql.query("select stddev(c1+2) as c2 from (select ts ,c1 ,c2 from stb1)") + tdSql.checkData(0,0,6.694663959) + tdSql.query("select stddev(a+2) as c2 from (select ts ,abs(c1) a ,c2 from stb1)") + tdSql.checkData(0,0,6.694663959) + + # mixup with other functions + tdSql.query("select max(c1),count(c1),last(c2,c3),sum(c1+c2),avg(c1),stddev(c1) from stb1") + tdSql.checkData(0,0,28) + tdSql.checkData(0,1,184) + tdSql.checkData(0,2,-99999) + tdSql.checkData(0,3,-999) + tdSql.checkData(0,4,28202310.000000000) + tdSql.checkData(0,5,14.086956522) + tdSql.checkData(0,6,6.694663959) + + def run(self): + + self.prepare_datas_of_distribute() + self.check_distribute_datas() + self.check_stddev_status() + self.distribute_agg_query() + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/join.py b/tests/system-test/2-query/join.py index 140808d387..5ff11c84dd 100644 --- a/tests/system-test/2-query/join.py +++ b/tests/system-test/2-query/join.py @@ -238,7 +238,7 @@ class TDTestCase: ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp - ) tags (t1 int) + ) tags (tag1 int) ''' create_ntb_sql = f'''create table t1( ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, diff --git a/tests/system-test/2-query/json_tag.py b/tests/system-test/2-query/json_tag.py index 957e916e34..052ff923ac 100644 --- a/tests/system-test/2-query/json_tag.py +++ b/tests/system-test/2-query/json_tag.py @@ -518,7 +518,7 @@ class TDTestCase: tdSql.query("select avg(dataint) from jsons1 where jtag is not null") tdSql.checkData(0, 0, 5.3) #tdSql.error("select twa(dataint) from jsons1 where jtag is not null") - tdSql.error("select irate(dataint) from jsons1 where jtag is not null") + tdSql.query("select irate(dataint) from jsons1 where jtag is not null") #tdSql.query("select sum(dataint) from jsons1 where jtag->'tag1' is not null") #tdSql.checkData(0, 0, 49) tdSql.query("select stddev(dataint) from jsons1 where jtag->'tag1'>1") diff --git a/tests/system-test/2-query/sample.py b/tests/system-test/2-query/sample.py index a84d93404a..33ef7e65db 100644 --- a/tests/system-test/2-query/sample.py +++ b/tests/system-test/2-query/sample.py @@ -624,8 +624,7 @@ class TDTestCase: tdLog.info(" sample data is in datas groups ,successed sql is : %s" % sample_query ) else: tdLog.exit(" sample data is not in datas groups ,failed sql is : %s" % sample_query ) - - + def basic_sample_query(self): tdSql.execute(" drop database if exists db ") tdSql.execute(" create database if not exists db duration 300 ") @@ -760,6 +759,14 @@ class TDTestCase: self.check_sample("select sample( c1 ,3 ) from t1 where c1 between 1 and 10" ,"select c1 from t1 where c1 between 1 and 10") + tdSql.query("select sample(c1,2) ,c2,c3 ,c5 from stb1") + tdSql.checkRows(2) + tdSql.checkCols(4) + + self.check_sample("select sample( c1 ,3 ),c2,c3,c4,c5 from t1 where c1 between 1 and 10" ,"select c1,c2,c3,c4,c5 from t1 where c1 between 1 and 10") + self.check_sample("select sample( c1 ,3 ),c2,c3,c4,c5 from stb1 where c1 between 1 and 10" ,"select c1,c2,c3,c4,c5 from stb1 where c1 between 1 and 10") + self.check_sample("select sample( c1 ,3 ),t1 from stb1 where c1 between 1 and 10" ,"select c1,t1 from stb1 where c1 between 1 and 10") + # join tdSql.query("select sample( ct4.c1 , 1 ) from ct1, ct4 where ct4.ts=ct1.ts") @@ -772,8 +779,8 @@ class TDTestCase: self.check_sample("select sample(c1,2) from stb1 partition by tbname" , "select c1 from stb1 partition by tbname") # nest query - # tdSql.query("select sample(c1,2) from (select c1 from t1); ") - # tdSql.checkRows(2) + tdSql.query("select sample(c1,2) from (select c1 from t1); ") + tdSql.checkRows(2) # union all tdSql.query("select sample(c1,2) from t1 union all select sample(c1,3) from t1") diff --git a/tests/system-test/2-query/substr.py b/tests/system-test/2-query/substr.py index e78606826b..79b5ac515b 100644 --- a/tests/system-test/2-query/substr.py +++ b/tests/system-test/2-query/substr.py @@ -23,6 +23,9 @@ CHAR_COL = [ BINARY_COL, NCHAR_COL, ] BOOLEAN_COL = [ BOOL_COL, ] TS_TYPE_COL = [ TS_COL, ] +ERR_POS = 0 +CURRENT_POS = 1 +LENS = 6 class TDTestCase: @@ -76,6 +79,7 @@ class TDTestCase: if pos < 1: tdSql.error(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ") + break tdSql.query(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ") for j in range(tdSql.queryRows): @@ -127,7 +131,7 @@ class TDTestCase: tdLog.printNoPrefix("==========current sql condition check , must return query ok==========") tbname = ["ct1", "ct2", "ct4", "t1", "stb1"] for tb in tbname: - self.__substr_check(tb, 1, 6) + self.__substr_check(tb, CURRENT_POS, LENS) tdLog.printNoPrefix(f"==========current sql condition check in {tb} over==========") def __test_error(self): @@ -137,7 +141,7 @@ class TDTestCase: for tb in tbname: for errsql in self.__substr_err_check(tb): tdSql.error(sql=errsql) - self.__substr_check(tb, 0, 6) + self.__substr_check(tb, ERR_POS, LENS) tdLog.printNoPrefix(f"==========err sql condition check in {tb} over==========") @@ -154,7 +158,7 @@ class TDTestCase: ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, {FLOAT_COL} float, {DOUBLE_COL} double, {BOOL_COL} bool, {BINARY_COL} binary(16), {NCHAR_COL} nchar(32), {TS_COL} timestamp - ) tags (t1 int) + ) tags (tag1 int) ''' create_ntb_sql = f'''create table t1( ts timestamp, {INT_COL} int, {BINT_COL} bigint, {SINT_COL} smallint, {TINT_COL} tinyint, diff --git a/tests/system-test/2-query/sum.py b/tests/system-test/2-query/sum.py index ea0e1f7fae..f6ff4989e7 100644 --- a/tests/system-test/2-query/sum.py +++ b/tests/system-test/2-query/sum.py @@ -73,7 +73,7 @@ class TDTestCase: f"select sum(ceil( {un_num_col} )) from {tbanme} ", ) ) - sqls.extend( f"select sum( {un_num_col} + {un_num_col_2} ) from {tbanme} " for un_num_col_2 in UN_NUM_COL ) + # sqls.extend( f"select sum( {un_num_col} + {un_num_col_2} ) from {tbanme} " for un_num_col_2 in UN_NUM_COL ) sqls.extend( f"select sum( {num_col} + {ts_col} ) from {tbanme} " for num_col in NUM_COL for ts_col in TS_TYPE_COL) sqls.extend( diff --git a/tests/system-test/2-query/top.py b/tests/system-test/2-query/top.py index 83f535856e..86e201ea9a 100644 --- a/tests/system-test/2-query/top.py +++ b/tests/system-test/2-query/top.py @@ -11,103 +11,159 @@ # -*- coding: utf-8 -*- -import random import string from util.common import * from util.log import * from util.cases import * from util.sql import * - +from util.sqlset import * class TDTestCase: def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor()) - + self.setsql = TDSetSql() + self.ntbname = 'ntb' self.rowNum = 10 self.tbnum = 20 self.ts = 1537146000000 self.binary_str = 'taosdata' self.nchar_str = '涛思数据' - def top_check_base(self): - tdSql.prepare() - tdSql.execute('''create table stb(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 tinyint unsigned, col6 smallint unsigned, - col7 int unsigned, col8 bigint unsigned, col9 float, col10 double, col11 bool, col12 binary(20), col13 nchar(20)) tags(loc nchar(20))''') - tdSql.execute("create table stb_1 using stb tags('beijing')") - for i in range(self.rowNum): - tdSql.execute(f"insert into stb_1 values(%d, %d, %d, %d, %d, %d, %d, %d, %d, %f, %f, %d, '{self.binary_str}%d', '{self.nchar_str}%d')" - % (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1)) - column_list = ['col1','col2','col3','col4','col5','col6','col7','col8'] - error_column_list = ['col11','col12','col13'] - error_param_list = [0,101] - for i in column_list: - tdSql.query(f'select top({i},2) from stb_1') - tdSql.checkRows(2) - tdSql.checkEqual(tdSql.queryResult,[(9,),(10,)]) - for j in error_param_list: - tdSql.error(f'select top({i},{j}) from stb_1') - for i in error_column_list: - tdSql.error(f'select top({i},10) from stb_1') - tdSql.query("select ts,top(col1, 2),ts from stb_1 group by tbname") - tdSql.checkRows(2) - tdSql.query('select top(col2,1) from stb_1 interval(1y) order by col2') - tdSql.checkData(0,0,10) - tdSql.error("select * from stb_1 where top(col2,1)=1") - tdSql.execute('drop database db') - def top_check_stb_distribute(self): - # prepare data for vgroup 4 + self.column_dict = { + 'ts' : 'timestamp', + 'col1': 'tinyint', + 'col2': 'smallint', + 'col3': 'int', + 'col4': 'bigint', + 'col5': 'tinyint unsigned', + 'col6': 'smallint unsigned', + 'col7': 'int unsigned', + 'col8': 'bigint unsigned', + 'col9': 'float', + 'col10': 'double', + 'col11': 'bool', + 'col12': 'binary(20)', + 'col13': 'nchar(20)' + } + + self.param_list = [1,100] + + def insert_data(self,column_dict,tbname,row_num): + sql = '' + for k, v in column_dict.items(): + if v.lower() == 'timestamp' or v.lower() == 'tinyint' or v.lower() == 'smallint' or v.lower() == 'int' or v.lower() == 'bigint' or \ + v.lower() == 'tinyint unsigned' or v.lower() == 'smallint unsigned' or v.lower() == 'int unsigned' or v.lower() == 'bigint unsigned' or v.lower() == 'bool': + sql += '%d,' + elif v.lower() == 'float' or v.lower() == 'double': + sql += '%f,' + elif 'binary' in v.lower(): + sql += f'"{self.binary_str}%d",' + elif 'nchar' in v.lower(): + sql += f'"{self.nchar_str}%d",' + insert_sql = f'insert into {tbname} values({sql[:-1]})' + for i in range(row_num): + insert_list = [] + for k, v in column_dict.items(): + if v.lower() in[ 'tinyint' , 'smallint' , 'int', 'bigint' , 'tinyint unsigned' , 'smallint unsigned' , 'int unsigned' , 'bigint unsigned'] or\ + 'binary' in v.lower() or 'nchar' in v.lower(): + insert_list.append(1 + i) + elif v.lower() == 'float' or v.lower() == 'double': + insert_list.append(0.1 + i) + elif v.lower() == 'bool': + insert_list.append(i % 2) + elif v.lower() == 'timestamp': + insert_list.append(self.ts + i) + tdSql.execute(insert_sql%(tuple(insert_list))) + pass + def top_check_data(self,tbname,tb_type): + new_column_dict = {} + for param in self.param_list: + for k,v in self.column_dict.items(): + if v.lower() in ['tinyint','smallint','int','bigint','tinyint unsigned','smallint unsigned','int unsigned','bigint unsigned']: + tdSql.query(f'select top({k},{param}) from {tbname}') + if param >= self.rowNum: + if tb_type in ['normal_table','child_table']: + tdSql.checkRows(self.rowNum) + values_list = [] + for i in range(self.rowNum): + tp = (self.rowNum-i,) + values_list.insert(0,tp) + tdSql.checkEqual(tdSql.queryResult,values_list) + elif tb_type == 'stable': + tdSql.checkRows(param) + elif param < self.rowNum: + if tb_type in ['normal_table','child_table']: + tdSql.checkRows(param) + values_list = [] + for i in range(param): + tp = (self.rowNum-i,) + values_list.insert(0,tp) + tdSql.checkEqual(tdSql.queryResult,values_list) + elif tb_type == 'stable': + tdSql.checkRows(param) + for i in [self.param_list[0]-1,self.param_list[-1]+1]: + tdSql.error(f'select top({k},{i}) from {tbname}') + new_column_dict.update({k:v}) + elif v.lower() == 'bool' or 'binary' in v.lower() or 'nchar' in v.lower(): + tdSql.error(f'select top({k},{param}) from {tbname}') + tdSql.error(f'select * from {tbname} where top({k},{param})=1') + for key in new_column_dict.keys(): + for k in self.column_dict.keys(): + if key == k : + continue + else: + tdSql.query(f'select top({key},2),{k} from {tbname} group by tbname') + if tb_type == 'normal_table' or tb_type == 'child_table': + tdSql.checkRows(2) + else: + tdSql.checkRows(2*self.tbnum) + def top_check_stb(self): dbname = tdCom.getLongName(10, "letters") stbname = tdCom.getLongName(5, "letters") + tag_dict = { + 't0':'int' + } + tag_values = [ + f'1' + ] tdSql.execute(f"create database if not exists {dbname} vgroups 2") tdSql.execute(f'use {dbname}') - # build 20 child tables,every table insert 10 rows - tdSql.execute(f'''create table {stbname}(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 tinyint unsigned, col6 smallint unsigned, - col7 int unsigned, col8 bigint unsigned, col9 float, col10 double, col11 bool, col12 binary(20), col13 nchar(20)) tags(loc nchar(20))''') + tdSql.execute(self.setsql.set_create_stable_sql(stbname,self.column_dict,tag_dict)) + for i in range(self.tbnum): - tdSql.execute(f"create table {stbname}_{i} using {stbname} tags('beijing')") - tdSql.execute(f"insert into {stbname}_{i}(ts) values(%d)" % (self.ts - 1-i)) - column_list = ['col1','col2','col3','col4','col5','col6','col7','col8'] - for i in [f'{stbname}', f'{dbname}.{stbname}']: - for j in column_list: - tdSql.query(f"select top({j},1) from {i}") - tdSql.checkRows(0) + tdSql.execute(f"create table {stbname}_{i} using {stbname} tags({tag_values[0]})") + tdSql.execute(self.insert_data(self.column_dict,f'{stbname}_{i}',self.rowNum)) tdSql.query('show tables') vgroup_list = [] for i in range(len(tdSql.queryResult)): vgroup_list.append(tdSql.queryResult[i][6]) - vgroup_list_set = set(vgroup_list) + vgroup_list_set = set(vgroup_list) for i in vgroup_list_set: vgroups_num = vgroup_list.count(i) - if vgroups_num >=2: + if vgroups_num >= 2: tdLog.info(f'This scene with {vgroups_num} vgroups is ok!') - continue - else: - tdLog.exit(f'This scene does not meet the requirements with {vgroups_num} vgroup!\n') - for i in range(self.rowNum): - for j in range(self.tbnum): - tdSql.execute(f"insert into {stbname}_{j} values(%d, %d, %d, %d, %d, %d, %d, %d, %d, %f, %f, %d, '{self.binary_str}%d', '{self.nchar_str}%d')" - % (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1)) - - error_column_list = ['col11','col12','col13'] - error_param_list = [0,101] - for i in column_list: - tdSql.query(f'select top({i},2) from {stbname}') - tdSql.checkRows(2) - tdSql.checkEqual(tdSql.queryResult,[(10,),(10,)]) - for j in error_param_list: - tdSql.error(f'select top({i},{j}) from {stbname}') - for i in error_column_list: - tdSql.error(f'select top({i},10) from {stbname}') - tdSql.query(f"select ts,top(col1, 2),ts from {stbname} group by tbname") - tdSql.checkRows(2*self.tbnum) - tdSql.query(f'select top(col2,1) from {stbname} interval(1y) order by col2') - tdSql.checkData(0,0,10) - tdSql.error(f"select * from {stbname} where top(col2,1)=1") + else: + tdLog.exit( + 'This scene does not meet the requirements with {vgroups_num} vgroup!\n') + for i in range(self.tbnum): + self.top_check_data(f'{stbname}_{i}','child_table') + self.top_check_data(stbname,'stable') + tdSql.execute(f'drop database {dbname}') + + def top_check_ntb(self): + tdSql.prepare() + tdSql.execute(self.setsql.set_create_normaltable_sql(self.ntbname,self.column_dict)) + self.insert_data(self.column_dict,self.ntbname,self.rowNum) + self.top_check_data(self.ntbname,'normal_table') + tdSql.execute('drop database db') + def run(self): - self.top_check_base() - self.top_check_stb_distribute() + self.top_check_ntb() + self.top_check_stb() + + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/system-test/2-query/twa.py b/tests/system-test/2-query/twa.py new file mode 100644 index 0000000000..b400e503d9 --- /dev/null +++ b/tests/system-test/2-query/twa.py @@ -0,0 +1,150 @@ +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np +import random ,os ,sys +import platform +import math + +class TDTestCase: + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, + "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"fnDebugFlag":143, + "maxTablesPerVnode":2 ,"minTablesPerVnode":2,"tableIncStepPerVnode":2 } + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + self.vnode_disbutes = None + self.ts = 1537146000000 + self.tb_nums = 20 + self.row_nums = 100 + self.time_step = 1000 + + def prepare_datas_of_distribute(self): + + # prepate datas for 20 tables distributed at different vgroups + tdSql.execute("create database if not exists testdb keep 3650 duration 1000 vgroups 5") + tdSql.execute(" use testdb ") + tdSql.execute( + '''create table stb1 + (ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp) + tags (t0 timestamp, t1 int, t2 bigint, t3 smallint, t4 tinyint, t5 float, t6 double, t7 bool, t8 binary(16),t9 nchar(32)) + ''' + ) + + for i in range(self.tb_nums): + tdSql.execute(f'create table ct{i+1} using stb1 tags ( now(), {1*i}, {11111*i}, {111*i}, {11*i}, {1.11*i}, {11.11*i}, {i%2}, "binary{i}", "nchar{i}" )') + ts = self.ts + for j in range(self.row_nums): + ts+=j*self.time_step + tdSql.execute( + f"insert into ct{i+1} values({ts}, 1, 11111, 111, 1, 1.11, 11.11, 2, 'binary{j}', 'nchar{j}', now()+{1*j}a )" + ) + + tdSql.execute("insert into ct1 values (now()-810d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct1 values (now()-400d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + tdSql.execute("insert into ct1 values (now()+90d, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ") + + tdLog.info(" prepare data for distributed_aggregate done! ") + + def twa_support_types(self): + tdSql.query("desc stb1 ") + schema_list = tdSql.queryResult + for col_type in schema_list: + if col_type[1] in ["TINYINT" ,"SMALLINT","BIGINT" ,"INT","FLOAT","DOUBLE"]: + tdSql.query(f" select twa({col_type[0]}) from stb1 partition by tbname ") + else: + tdSql.error(f" select twa({col_type[0]}) from stb1 partition by tbname ") + + + def check_distribute_datas(self): + # get vgroup_ids of all + tdSql.query("show vgroups ") + vgroups = tdSql.queryResult + + vnode_tables={} + + for vgroup_id in vgroups: + vnode_tables[vgroup_id[0]]=[] + + # check sub_table of per vnode ,make sure sub_table has been distributed + tdSql.query("show tables like 'ct%'") + table_names = tdSql.queryResult + tablenames = [] + for table_name in table_names: + vnode_tables[table_name[6]].append(table_name[0]) + self.vnode_disbutes = vnode_tables + + count = 0 + for k ,v in vnode_tables.items(): + if len(v)>=2: + count+=1 + if count < 2: + tdLog.exit(" the datas of all not satisfy sub_table has been distributed ") + + def distribute_twa_query(self): + # basic filter + tdSql.query(" select twa(c1) from ct1 ") + tdSql.checkData(0,0,1.000000000) + + tdSql.query(" select twa(c1) from stb1 partition by tbname ") + tdSql.checkRows(self.tb_nums) + tdSql.checkData(0,0,1.000000000) + + tdSql.query(" select twa(c2) from stb1 group by tbname ") + tdSql.checkRows(self.tb_nums) + tdSql.checkData(0,0,11111.000000000) + + tdSql.query("select twa(c1+c2) from stb1 partition by tbname ") + tdSql.checkData(0,0,11112.000000000) + + tdSql.query("select twa(c1) from stb1 partition by t1") + tdSql.checkRows(self.tb_nums) + tdSql.checkData(0,0,1.000000000) + + # union all + tdSql.query(" select twa(c1) from stb1 partition by tbname union all select twa(c1) from stb1 partition by tbname ") + tdSql.checkRows(40) + tdSql.checkData(0,0,1.000000000) + + # join + + tdSql.execute(" create database if not exists db ") + tdSql.execute(" use db ") + tdSql.execute(" create stable st (ts timestamp , c1 int ,c2 float) tags(t1 int) ") + tdSql.execute(" create table tb1 using st tags(1) ") + tdSql.execute(" create table tb2 using st tags(2) ") + + + for i in range(10): + ts = i*10 + self.ts + tdSql.execute(f" insert into tb1 values({ts},{i},{i}.0)") + tdSql.execute(f" insert into tb2 values({ts},{i},{i}.0)") + + tdSql.query(" select twa(tb1.c1), twa(tb2.c2) from tb1, tb2 where tb1.ts=tb2.ts ") + tdSql.checkRows(1) + tdSql.checkData(0,0,4.500000000) + tdSql.checkData(0,1,4.500000000) + + # group by + tdSql.execute(" use testdb ") + + # mixup with other functions + tdSql.query(" select twa(c1),twa(c2),max(c1),elapsed(ts) from stb1 ") + tdSql.checkData(0,0,1.000000000) + tdSql.checkData(0,1,11111.000000000) + tdSql.checkData(0,2,1) + + def run(self): + self.prepare_datas_of_distribute() + self.check_distribute_datas() + self.twa_support_types() + self.distribute_twa_query() + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/stbFilter.py b/tests/system-test/7-tmq/stbFilter.py new file mode 100644 index 0000000000..542894574b --- /dev/null +++ b/tests/system-test/7-tmq/stbFilter.py @@ -0,0 +1,260 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + #tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def tmqCase1(self): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'db1', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 100, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 10, + 'showMsg': 1, + 'showRow': 1} + + topicNameList = ['topic1', 'topic2', 'topic3'] + expectRowsList = [] + 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 %% 4 == 0" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + queryString = "select ts, log(c1), cos(c1) from %s.%s where c1 > 5000" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[1], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + queryString = "select ts, log(c1), atan(c1) from %s.%s where ts >= %d" %(paraDict['dbName'], paraDict['stbName'], paraDict["startTs"]+9000) + sqlString = "create topic %s as %s" %(topicNameList[2], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + # init consume info, and start tmq_sim, then check consume result + tdLog.info("insert consume info to consume processor") + consumerId = 0 + expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] + topicList = topicNameList[0] + ifcheckdata = 0 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:false, auto.commit.interval.ms:6000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + + if expectRowsList[0] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[0], resultList[0])) + tdLog.exit("0 tmq consume rows error!") + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 1 + topicList = topicNameList[1] + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + if expectRowsList[1] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[1], resultList[0])) + tdLog.exit("1 tmq consume rows error!") + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 2 + topicList = topicNameList[2] + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + # if expectRowsList[2] != resultList[0]: + # tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[2], resultList[0])) + # tdLog.exit("2 tmq consume rows error!") + + time.sleep(10) + for i in range(len(topicNameList)): + tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self): + tdLog.printNoPrefix("======== test case 2: ") + paraDict = {'dbName': 'db2', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':2}, {'type': 'binary', 'len':20, 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbNum': 10, + 'rowsPerTbl': 10000, + 'batchNum': 100, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 10, + 'showMsg': 1, + 'showRow': 1} + + topicNameList = ['topic1', 'topic2', 'topic3'] + expectRowsList = [] + 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") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], ctbNum=paraDict['ctbNum']) + tdLog.info("insert data") + tmqCom.insert_data_1(tdSql,paraDict["dbName"],paraDict["ctbPrefix"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"]) + + tdLog.info("create topics from stb with filter") + # sqlString = "create topic %s as select ts, sin(c1), pow(c2,3) from %s.%s where c2 >= 0" %(topicNameList[0], paraDict['dbName'], paraDict['stbName']) + queryString = "select ts, sin(c1), pow(c2,3) from %s.%s where c2 >= 0" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[0], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + queryString = "select ts, sin(c1), pow(c2,3) from %s.%s where sin(c2) >= 0" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[1], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + queryString = "select ts, sin(c1), floor(pow(c2,3)), c2 from %s.%s where (sin(c2) >= 0) and (floor(pow(c2,3)) %% 9 == 0)" %(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicNameList[2], queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + tdSql.query(queryString) + expectRowsList.append(tdSql.getRows()) + + # start tmq consume processor + tdLog.info("insert consume info to consume processor") + consumerId = 0 + expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] + topicList = topicNameList[0] + ifcheckdata = 0 + ifManualCommit = 1 + keyList = 'group.id:cgrp1, enable.auto.commit:false, auto.commit.interval.ms:6000, auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + + if expectRowsList[0] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[0], resultList[0])) + tdLog.exit("0 tmq consume rows error!") + + # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 1 + topicList = topicNameList[1] + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + if expectRowsList[1] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[1], resultList[0])) + tdLog.exit("1 tmq consume rows error!") + + # # reinit consume info, and start tmq_sim, then check consume result + tmqCom.initConsumerTable() + consumerId = 2 + topicList = topicNameList[2] + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(paraDict['pollDelay'],paraDict["dbName"],paraDict['showMsg'], paraDict['showRow']) + + tdLog.info("wait the consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + if expectRowsList[2] != resultList[0]: + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[2], resultList[0])) + tdLog.exit("2 tmq consume rows error!") + + # time.sleep(10) + # for i in range(len(topicNameList)): + # tdSql.query("drop topic %s"%topicNameList[i]) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def run(self): + tdSql.prepare() + self.tmqCase1() + self.tmqCase2() + + 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/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 68adaa4126..9b23056546 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -42,9 +42,11 @@ class TMQCom: tdSql.query("create database if not exists %s vgroups 1"%(cdbName)) tdSql.query("drop table if exists %s.consumeinfo "%(cdbName)) tdSql.query("drop table if exists %s.consumeresult "%(cdbName)) + tdSql.query("drop table if exists %s.notifyinfo "%(cdbName)) tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int, ifmanualcommit int)"%cdbName) tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + tdSql.query("create table %s.notifyinfo (ts timestamp, cmdid int, consumerid int)"%cdbName) def initConsumerInfoTable(self,cdbName='cdb'): tdLog.info("drop consumeinfo table") @@ -92,13 +94,190 @@ class TMQCom: tdLog.info(shellCmd) os.system(shellCmd) + def getStartConsumeNotifyFromTmqsim(self,cdbName='cdb'): + while 1: + tdSql.query("select * from %s.notifyinfo"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if (tdSql.getRows() == 1) and (tdSql.getData(0, 1) == 0): + break + else: + time.sleep(0.1) + return + + def getStartCommitNotifyFromTmqsim(self,cdbName='cdb'): + while 1: + tdSql.query("select * from %s.notifyinfo"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 2 : + print(tdSql.getData(0, 1), tdSql.getData(1, 1)) + if tdSql.getData(1, 1) == 1: + break + time.sleep(0.1) + return + + def create_database(self,tsql, dbName,dropFlag=1,vgroups=4,replica=1): + if dropFlag == 1: + tsql.execute("drop database if exists %s"%(dbName)) + + tsql.execute("create database if not exists %s vgroups %d replica %d"%(dbName, vgroups, replica)) + tdLog.debug("complete to create database %s"%(dbName)) + return + + def create_stable(self,tsql, dbName,stbName): + tsql.execute("create table if not exists %s.%s (ts timestamp, c1 int, c2 int, c3 binary(16)) tags(t1 int, t2 binary(32))"%(dbName, stbName)) + tdLog.debug("complete to create %s.%s" %(dbName, stbName)) + return + + def create_ctable(self,tsql=None, dbName='dbx',stbName='stb',ctbPrefix='ctb',ctbNum=1): + tsql.execute("use %s" %dbName) + pre_create = "create table" + sql = pre_create + #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + for i in range(ctbNum): + tagValue = 'beijing' + if (i % 2 == 0): + tagValue = 'shanghai' + + sql += " %s%d using %s tags(%d, '%s')"%(ctbPrefix,i,stbName,i+1, tagValue) + if (i > 0) and (i%100 == 0): + tsql.execute(sql) + sql = pre_create + if sql != pre_create: + tsql.execute(sql) + + tdLog.debug("complete to create %d child tables in %s.%s" %(ctbNum, dbName, stbName)) + return + + def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs=None): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + if startTs is None: + t = time.time() + startTs = int(round(t * 1000)) + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s%d values "%(stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s%d values " %(stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def insert_data_1(self,tsql,dbName,ctbPrefix,ctbNum,rowsPerTbl,batchNum,startTs): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + t = time.time() + startTs = int(round(t * 1000)) + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s%d values "%(ctbPrefix,i) + for j in range(rowsPerTbl): + if (j % 2 == 0): + sql += "(%d, %d, %d, 'tmqrow_%d') "%(startTs + j, j, j, j) + else: + sql += "(%d, %d, %d, 'tmqrow_%d') "%(startTs + j, j, -j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s%d values " %(ctbPrefix,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def insert_data_interlaceByMultiTbl(self,tsql,dbName,ctbPrefix,ctbNum,rowsPerTbl,batchNum,startTs=0): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + if startTs == 0: + t = time.time() + startTs = int(round(t * 1000)) + + ctbDict = {} + for i in range(ctbNum): + ctbDict[i] = 0 + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + rowsOfCtb = 0 + while rowsOfCtb < rowsPerTbl: + for i in range(ctbNum): + sql += " %s.%s_%d values "%(dbName,ctbPrefix,i) + for k in range(batchNum): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + ctbDict[i], ctbDict[i], ctbDict[i]) + ctbDict[i] += 1 + if (0 == ctbDict[i]%batchNum) or (ctbDict[i] == rowsPerTbl): + tsql.execute(sql) + sql = "insert into " + break + rowsOfCtb = ctbDict[0] + + tdLog.debug("insert data ............ [OK]") + return + + def insert_data_with_autoCreateTbl(self,tsql,dbName,stbName,ctbPrefix,ctbNum,rowsPerTbl,batchNum,startTs=0): + tdLog.debug("start to insert data wiht auto create child table ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + if startTs == 0: + t = time.time() + startTs = int(round(t * 1000)) + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + rowsOfSql = 0 + for i in range(ctbNum): + sql += " %s.%s_%d using %s.%s tags (%d) values "%(dbName,ctbPrefix,i,dbName,stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + rowsOfSql += 1 + if (j > 0) and ((rowsOfSql == batchNum) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + rowsOfSql = 0 + if j < rowsPerTbl - 1: + sql = "insert into %s.%s_%d using %s.%s tags (%d) values " %(dbName,ctbPrefix,i,dbName,stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + def syncCreateDbStbCtbInsertData(self, tsql, paraDict): - tdCom.create_database(tsql, paraDict["dbName"],paraDict["dropFlag"], paraDict['precision']) - tdCom.create_stable(tsql, paraDict["dbName"],paraDict["stbName"], paraDict["columnDict"], paraDict["tagDict"]) - tdCom.create_ctables(tsql, paraDict["dbName"],paraDict["stbName"],paraDict["ctbNum"],paraDict["tagDict"]) + tdCom.create_database(tsql, paraDict["dbName"],paraDict["dropFlag"]) + tdCom.create_stable(tsql, dbname=paraDict["dbName"],stbname=paraDict["stbName"], column_elm_list=paraDict['colSchema'], tag_elm_list=paraDict['tagSchema']) + tdCom.create_ctable(tsql, dbname=paraDict["dbName"],stbname=paraDict["stbName"],tag_elm_list=paraDict['tagSchema'],count=paraDict["ctbNum"], default_ctbname_prefix=paraDict['ctbPrefix']) if "event" in paraDict and type(paraDict['event']) == type(threading.Event()): paraDict["event"].set() - tdCom.insert_data(tsql,paraDict["dbName"],paraDict["stbName"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"]) + + ctbPrefix = paraDict['ctbPrefix'] + ctbNum = paraDict["ctbNum"] + for i in range(ctbNum): + tbName = '%s%s'%(ctbPrefix,i) + tdCom.insert_rows(tsql,dbname=paraDict["dbName"],tbname=tbName,start_ts_value=paraDict['startTs'],count=paraDict['rowsPerTbl']) return def threadFunction(self, **paraDict): diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index db3f7216ab..0e7c4673ee 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -35,6 +35,7 @@ python3 ./test.py -f 2-query/lower.py python3 ./test.py -f 2-query/join.py python3 ./test.py -f 2-query/join2.py python3 ./test.py -f 2-query/cast.py +python3 ./test.py -f 2-query/substr.py python3 ./test.py -f 2-query/union.py python3 ./test.py -f 2-query/union1.py python3 ./test.py -f 2-query/concat.py @@ -105,12 +106,15 @@ python3 ./test.py -f 2-query/distribute_agg_min.py python3 ./test.py -f 2-query/distribute_agg_sum.py python3 ./test.py -f 2-query/distribute_agg_spread.py python3 ./test.py -f 2-query/distribute_agg_apercentile.py +python3 ./test.py -f 2-query/distribute_agg_avg.py +python3 ./test.py -f 2-query/distribute_agg_stddev.py +python3 ./test.py -f 2-query/twa.py -python3 ./test.py -f 6-cluster/5dnode1mnode.py -python3 ./test.py -f 6-cluster/5dnode2mnode.py +python3 ./test.py -f 6-cluster/5dnode1mnode.py +python3 ./test.py -f 6-cluster/5dnode2mnode.py #python3 ./test.py -f 6-cluster/5dnode3mnodeStop.py #python3 ./test.py -f 6-cluster/5dnode3mnodeDrop.py -# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeStopInsert.py +# BUG python3 ./test.py -f 6-cluster/5dnode3mnodeStopInsert.py python3 ./test.py -f 7-tmq/basic5.py python3 ./test.py -f 7-tmq/subscribeDb.py @@ -127,3 +131,4 @@ python3 ./test.py -f 7-tmq/subscribeStb4.py python3 ./test.py -f 7-tmq/db.py python3 ./test.py -f 7-tmq/tmqError.py python3 ./test.py -f 7-tmq/schema.py +python3 ./test.py -f 7-tmq/stbFilter.py diff --git a/tests/tsim/src/simExe.c b/tests/tsim/src/simExe.c index f97a13d2c5..aaad76bb53 100644 --- a/tests/tsim/src/simExe.c +++ b/tests/tsim/src/simExe.c @@ -39,13 +39,26 @@ void simLogSql(char *sql, bool useSharp) { char *simParseArbitratorName(char *varName) { static char hostName[140]; +#ifdef WINDOWS + taosGetFqdn(hostName); + sprintf(&hostName[strlen(hostName)], ":%d", 8000); +#else sprintf(hostName, "%s:%d", "localhost", 8000); +#endif return hostName; } char *simParseHostName(char *varName) { static char hostName[140]; +#ifdef WINDOWS + hostName[0] = '\"'; + taosGetFqdn(&hostName[1]); + int strEndIndex = strlen(hostName); + hostName[strEndIndex] = '\"'; + hostName[strEndIndex + 1] = '\0'; +#else sprintf(hostName, "%s", "localhost"); +#endif return hostName; } @@ -399,7 +412,8 @@ bool simExecuteSystemCmd(SScript *script, char *option) { sprintf(buf, "cd %s; ", simScriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); #else - sprintf(buf, "%s%s", simScriptDir, option); + sprintf(buf, "%s", simScriptDir); + simVisuallizeOption(script, option, buf + strlen(buf)); simReplaceStr(buf, ".sh", ".bat"); #endif diff --git a/tools/taos-tools b/tools/taos-tools index 28a49b447f..d3c29fb492 160000 --- a/tools/taos-tools +++ b/tools/taos-tools @@ -1 +1 @@ -Subproject commit 28a49b447f71c4f014ebbac858b7215b897d57fd +Subproject commit d3c29fb492514cbaf08cb533976121bff5d94dea diff --git a/tools/taosadapter b/tools/taosadapter index 29926478ed..c1dc11f3ca 160000 --- a/tools/taosadapter +++ b/tools/taosadapter @@ -1 +1 @@ -Subproject commit 29926478edd87533a043f91c1a9ed0e27671e626 +Subproject commit c1dc11f3cae64adf31dbd9a954ef8372d1e8f671