diff --git a/docs/en/10-cluster/02-cluster-mgmt.md b/docs/en/10-cluster/02-cluster-mgmt.md
index 674c92e2766a4eb304079140af19c8efea72d55e..bd3386c41161fc55b4bedcecd6ad3ab5c35be8b6 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 bd718eef9f8dc181628132de831dbca2af59d158..9780e8f6c68904e444d07c6a8c87b095c6b70ead 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/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json b/docs/en/14-reference/07-tdinsight/assets/15146-tdengine-monitor-dashboard.json
index f651983528ca824b4e6b14586aac5a5bfb4ecab8..54dc1062d6440cc0fc7b8c69d9e4c6b53e4cd01e 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 b4254c428b28a0084e54b5e3c509dd2e0ec651b9..1add8522a712aa2cfef6187e577c42d205432b66 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 cebfafa225e6e8de75ff84bb51fa664784177910..e74c9de7b2aa71278a99d45f250e0dcaf86d4704 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/21-tdinternal/01-arch.md b/docs/en/21-tdinternal/01-arch.md
index 4d8bed4d2d6b3a0404e10213aeab599767325cc2..d7d472eb98a22325e850f4f040dccaa34d02bbff 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:
-
-
Figure 3: TDengine Master writing process
+
+ 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:
-
- Figure 4: TDengine Slave Writing Process
+
+ 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/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h
index cbaff29cb2de5ab4e93d39caa1cd89810fbdddde..1f314d19e7da4863f8ec7ab3e2d2f45169b9babb 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/nodes.h b/include/libs/nodes/nodes.h
index 58e2393970089e49b71f3ab616da9f5893e007de..26a100bb1bf3d9ea0d591b52e1fed31e6296a5d8 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) \
@@ -219,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,
@@ -227,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 b07e8f39d5bcae86ebd32208613f98c7e2bff497..cb09bf6a5fbb596a3d7e9ecaffd5ac19c50effd1 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 7a63f87412ef5493d181b27684d70c01b23e78f3..78013e545723293e6e73502d21bd1b291f505604 100644
--- a/include/libs/nodes/querynodes.h
+++ b/include/libs/nodes/querynodes.h
@@ -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/source/common/src/tdatablock.c b/source/common/src/tdatablock.c
index 3c3d3e953dc567f7f9edb83d56d6ff48dca9edf6..5594ee9bcf1cffb1edb7e96c734bc8d877188d46 100644
--- a/source/common/src/tdatablock.c
+++ b/source/common/src/tdatablock.c
@@ -263,6 +263,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, uint32_t numOfRow1, in
pColumnInfoData->varmeta.length = len + oldLen;
} else {
if (finalNumOfRows > *capacity) {
+ ASSERT(finalNumOfRows*pColumnInfoData->info.bytes);
char* tmp = taosMemoryRealloc(pColumnInfoData->pData, finalNumOfRows * pColumnInfoData->info.bytes);
if (tmp == NULL) {
return TSDB_CODE_VND_OUT_OF_MEMORY;
@@ -1126,6 +1127,7 @@ void blockDataCleanup(SSDataBlock* pDataBlock) {
}
int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, size_t existRows, uint32_t numOfRows) {
+ ASSERT(numOfRows);
if (0 == numOfRows || numOfRows <= existRows) {
return TSDB_CODE_SUCCESS;
}
@@ -1178,6 +1180,8 @@ void colInfoDataCleanup(SColumnInfoData* pColumn, uint32_t numOfRows) {
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) {
int32_t code = 0;
+ ASSERT(numOfRows > 0);
+
if (numOfRows == 0) {
return TSDB_CODE_SUCCESS;
}
diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c
index 71bbc8ddd43aaf6583bcf4758ca018fe798108d4..5e1ef23f1c7819d524f99e72485e942a13ee9ecc 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_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h
index f599de384cdc36f04873b0d34d40b18168b136da..01958aa05355e489371679c56f74d73bf2f2db0b 100644
--- a/source/dnode/mgmt/node_util/inc/dmUtil.h
+++ b/source/dnode/mgmt/node_util/inc/dmUtil.h
@@ -44,6 +44,7 @@
extern "C" {
#endif
+
// clang-format off
#define dFatal(...) { if (dDebugFlag & DEBUG_FATAL) { taosPrintLog("DND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }}
diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h
index 958d82a75dc187a89f50efe43789d0eb093ed3f1..58266724a5278d0baafcebd70f9d33423c6cd1cc 100644
--- a/source/dnode/mnode/impl/inc/mndInt.h
+++ b/source/dnode/mnode/impl/inc/mndInt.h
@@ -35,6 +35,7 @@ extern "C" {
// 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__); }}
@@ -77,7 +78,7 @@ typedef struct {
typedef struct {
SCacheObj *connCache;
- SCacheObj *appCache;
+ SCacheObj *appCache;
} SProfileMgmt;
typedef struct {
diff --git a/source/dnode/mnode/impl/inc/mndQnode.h b/source/dnode/mnode/impl/inc/mndQnode.h
index 3e38565a4fe67b93d8ba8b9d30160ce54b13dee5..17615500c47abc2ea0dcad21b5a70ec8a1310892 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 180f18a6ddc68a5cd93987714c3d2b42349a529f..ec7bb02ca7cd86ad5f677fa229f7a575ace6086a 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/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c
index 58c3570c3631ec0ceee76163d4afd50e047245ad..8d068689559c4d4dfa85ab0c1b3cf9b354ef2674 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/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c
index 01e3bdcf13b6bfdf5844002acbc69e4bfdd15157..832e328d962479f739004ae765171ddfeb71aa2d 100644
--- a/source/dnode/mnode/impl/src/mndProfile.c
+++ b/source/dnode/mnode/impl/src/mndProfile.c
@@ -447,7 +447,7 @@ static int32_t mndUpdateAppInfo(SMnode *pMnode, SClientHbReq *pHbReq, SRpcConnIn
mError("failed to create new app %" PRIx64 " since %s", pReq->appId, terrstr());
return -1;
} else {
- mDebug("a new app %" PRIx64 "created", pReq->appId);
+ mDebug("a new app %" PRIx64 " is created", pReq->appId);
mndReleaseApp(pMnode, pApp);
return TSDB_CODE_SUCCESS;
}
diff --git a/source/dnode/mnode/impl/src/mndQnode.c b/source/dnode/mnode/impl/src/mndQnode.c
index f5625f32d5a73af783dc0172ba949cc6d4532462..0a6c97e63c8e9af36bd6d91b4d05445f77a82db3 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/mndSnode.c b/source/dnode/mnode/impl/src/mndSnode.c
index 12188a3b3a08aee7bdae08b202c3563106ee35d1..df1330197a7b98ed85e047fbc7522c87dac5e19f 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/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c
index 8666739dab0d4e45cdcb0f5eabe2d4f3804dd4f3..e3358b41df07b75d3a1624bbd13f08645b1d66d7 100644
--- a/source/dnode/mnode/impl/src/mndSync.c
+++ b/source/dnode/mnode/impl/src/mndSync.c
@@ -75,7 +75,7 @@ void mndSyncCommitMsg(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbM
}
int32_t mndSyncGetSnapshot(struct SSyncFSM *pFsm, SSnapshot *pSnapshot, void *pReaderParam, void **ppReader) {
- mInfo("start to read snapshot from sdb in atomic way");
+ 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);
@@ -96,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");
}
}
@@ -118,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, 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/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c
index de6a44d456c992defcdbae39d97b260b471e43a6..eec108414e352377cefe88c3bc28ee3df6cb552a 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 94ddbcd409c8ef4b1ad6bf8d97bda63edb63ea92..696e714a8cb58abdff44b08e8ea7d76de15ece44 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/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c
index 47c4a4ed0fe982c64ed8358f66e6d9d0ee6e4f8b..ff4a9e4ead5511b3c876522f2103b429f30da4ed 100644
--- a/source/dnode/mnode/sdb/src/sdbFile.c
+++ b/source/dnode/mnode/sdb/src/sdbFile.c
@@ -519,7 +519,7 @@ 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);
}
@@ -556,7 +556,7 @@ int32_t sdbStartRead(SSdb *pSdb, SSdbIter **ppIter, int64_t *index, int64_t *ter
if (term != NULL) *term = commitTerm;
if (config != NULL) *config = commitConfig;
- mInfo("sdbiter:%p, is created to read snapshot, commit index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " file:%s",
+ 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;
}
@@ -583,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;
@@ -609,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;
}
@@ -618,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;
}
@@ -641,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;
}
@@ -654,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/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h
index 7fa188d83abe2706009a087b5fc21023f9bcf0e7..32be479116c30e6e4023baa1bccaafdd1efdf22b 100644
--- a/source/dnode/vnode/src/inc/vnd.h
+++ b/source/dnode/vnode/src/inc/vnd.h
@@ -26,20 +26,19 @@ extern "C" {
#endif
// clang-format off
-
-#define vFatal(...) { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("VND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }}
-#define vError(...) { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("VND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }}
-#define vWarn(...) { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("VND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }}
-#define vInfo(...) { if (vDebugFlag & DEBUG_INFO) { taosPrintLog("VND ", DEBUG_INFO, 255, __VA_ARGS__); }}
-#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", DEBUG_DEBUG, vDebugFlag, __VA_ARGS__); }}
-#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", DEBUG_TRACE, vDebugFlag, __VA_ARGS__); }}
-
-#define vGFatal(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vFatal(param ", gtid:%s", __VA_ARGS__, buf);}
-#define vGError(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vError(param ", gtid:%s", __VA_ARGS__, buf);}
-#define vGWarn(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vWarn (param ", gtid:%s", __VA_ARGS__, buf);}
-#define vGInfo(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vInfo (param ", gtid:%s", __VA_ARGS__, buf);}
-#define vGDebug(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vDebug(param ", gtid:%s", __VA_ARGS__, buf);}
-#define vGTrace(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); vTrace(param ", gtid:%s", __VA_ARGS__, buf);}
+#define vFatal(...) do { if (vDebugFlag & DEBUG_FATAL) { taosPrintLog("VND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} while(0)
+#define vError(...) do { if (vDebugFlag & DEBUG_ERROR) { taosPrintLog("VND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} while(0)
+#define vWarn(...) do { if (vDebugFlag & DEBUG_WARN) { taosPrintLog("VND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} while(0)
+#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 { 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
diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c
index 83059e36460226db271cbc346ca7b6e20b688293..ece66d30fbe19ea06b014636d572eb17214b65b3 100644
--- a/source/dnode/vnode/src/tq/tqSink.c
+++ b/source/dnode/vnode/src/tq/tqSink.c
@@ -92,9 +92,8 @@ 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;
+
+ int32_t dataLen = 0;
void* blkSchema = POINTER_SHIFT(blkHead, sizeof(SSubmitBlk));
@@ -167,9 +166,8 @@ 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;
diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c
index ae0f669d656a458a310339e461ad2e55918ee211..2d55b06f064ca0023c551f8718a44b69d1996f8a 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 2a0f34cd03e02ac13b570907ab26f0f946557133..51281482219ae31fb0766ab45c0d35be68941789 100644
--- a/source/libs/executor/inc/executorimpl.h
+++ b/source/libs/executor/inc/executorimpl.h
@@ -234,6 +234,7 @@ typedef struct SColMatchInfo {
int32_t colId;
int32_t targetSlotId;
bool output;
+ bool reserved;
int32_t matchType; // determinate the source according to col id or slot id
} SColMatchInfo;
@@ -253,7 +254,6 @@ typedef struct STableScanInfo {
SFileBlockLoadRecorder readRecorder;
int64_t numOfRows;
-// int32_t prevGroupId; // previous table group id
SScanInfo scanInfo;
int32_t scanTimes;
SNode* pFilterNode; // filter info, which is push down by optimizer
@@ -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 363f379ee471e9d9d604784f1fcd24880b4ae3e7..35bdd4ee554e4a1af7b040293909000d77f2fcdd 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/executil.c b/source/libs/executor/src/executil.c
index 27096fe7f9cefe3ea4c0ce1f144c127e9f551a7f..566abb14515cd02904183a14aa3b5f34cb6181a8 100644
--- a/source/libs/executor/src/executil.c
+++ b/source/libs/executor/src/executil.c
@@ -300,7 +300,7 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
SColMatchInfo c = {0};
c.output = true;
- c.colId = pColNode->colId;
+ c.colId = pColNode->colId;
c.srcSlotId = pColNode->slotId;
c.matchType = type;
c.targetSlotId = pNode->slotId;
diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c
index 94675ce253a3149551548521f596ba79b98a18ed..097b8b9fb8223483abaee795fc3b5e77312cf2aa 100644
--- a/source/libs/executor/src/executorimpl.c
+++ b/source/libs/executor/src/executorimpl.c
@@ -609,7 +609,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
}
int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
- colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity);
+ ASSERT(pResult->info.capacity > 0);
colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
numOfRows = dest.numOfRows;
@@ -649,7 +649,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
}
int32_t startOffset = createNewColModel ? 0 : pResult->info.rows;
- colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity);
+ ASSERT(pResult->info.capacity > 0);
colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows);
numOfRows = dest.numOfRows;
@@ -1340,9 +1340,9 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowR
}
if (rowRes != NULL) {
+ int32_t totalRows = pBlock->info.rows;
SSDataBlock* px = createOneDataBlock(pBlock, true);
- int32_t totalRows = pBlock->info.rows;
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
SColumnInfoData* pSrc = taosArrayGet(px->pDataBlock, i);
SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i);
@@ -2765,7 +2765,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;
@@ -2787,9 +2787,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,
@@ -2844,8 +2844,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();
@@ -3736,9 +3736,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;
}
@@ -3761,14 +3761,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;
@@ -3838,10 +3838,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);
@@ -4087,7 +4087,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) {
@@ -4190,6 +4190,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 734c6bfbfbd4ded409e0910a55a26b2cdae674e5..39a62410f9fe02730dc3c38fb3ffb618398b6e59 100644
--- a/source/libs/executor/src/scanoperator.c
+++ b/source/libs/executor/src/scanoperator.c
@@ -224,7 +224,7 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca
pBlock->pBlockAgg = taosMemoryCalloc(numOfCols, POINTER_BYTES);
}
- for (int32_t i = 0; i < numOfCols; ++i) {
+ for (int32_t i = 0; i < taosArrayGetSize(pTableScanInfo->pColMatchInfo); ++i) {
SColMatchInfo* pColMatchInfo = taosArrayGet(pTableScanInfo->pColMatchInfo, i);
if (!pColMatchInfo->output) {
continue;
@@ -384,7 +384,14 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
continue;
}
- tsdbRetrieveDataBlockInfo(pTableScanInfo->dataReader, &pBlock->info);
+ blockDataCleanup(pBlock);
+
+ SDataBlockInfo binfo = pBlock->info;
+ tsdbRetrieveDataBlockInfo(pTableScanInfo->dataReader, &binfo);
+
+ binfo.capacity = binfo.rows;
+ blockDataEnsureCapacity(pBlock, binfo.rows);
+ pBlock->info = binfo;
uint32_t status = 0;
int32_t code = loadDataBlock(pOperator, pTableScanInfo, pBlock, &status);
@@ -530,7 +537,6 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
// taosSsleep(20);
SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc;
-
int32_t numOfCols = 0;
SArray* pColList = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c
index 9d13276e6d68d2aaf380d0ac3111c2214c6f0e75..97be4645a8030741644f9c8fc84cc270a0ecad9e 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;
@@ -146,8 +148,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);
}
@@ -165,8 +167,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);
@@ -232,6 +233,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;
@@ -259,11 +519,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];
@@ -286,7 +547,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);
@@ -387,24 +648,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,
@@ -421,4 +681,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 5495b5e9bf4483588e08bf62eca769991302cad7..3ff45d7237cee7c9f7c09cd01a5df8928bdcd6a4 100644
--- a/source/libs/executor/src/timewindowoperator.c
+++ b/source/libs/executor/src/timewindowoperator.c
@@ -684,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);
@@ -1262,7 +1263,7 @@ static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) {
return TSDB_CODE_SUCCESS;
}
-bool isCloseWindow(STimeWindow *pWin, STimeWindowAggSupp* pSup) {
+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;
}
@@ -2402,7 +2403,7 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
initResultRowInfo(&pInfo->binfo.resultRowInfo);
pInfo->pChildren = NULL;
if (numOfChild > 0) {
- pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void *));
+ pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*));
for (int32_t i = 0; i < numOfChild; i++) {
SOperatorInfo* pChildOp = createStreamFinalIntervalOperatorInfo(NULL, pPhyNode, pTaskInfo, 0);
if (pChildOp) {
@@ -3027,12 +3028,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;
}
@@ -3100,9 +3103,11 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
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;
}
@@ -3667,25 +3672,25 @@ _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);
@@ -3702,10 +3707,10 @@ static int32_t outputMergeIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t
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;
@@ -3722,7 +3727,7 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo*
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)
+ // 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) {
@@ -3744,7 +3749,7 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo*
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;
@@ -3763,14 +3768,14 @@ static void doMergeIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo*
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;
}
@@ -3790,6 +3795,7 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
} else {
pBlock = miaInfo->prefetchedBlock;
miaInfo->groupId = pBlock->info.groupId;
+ miaInfo->prefetchedBlock = NULL;
}
if (pBlock == NULL) {
@@ -3807,7 +3813,7 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
getTableScanInfo(pOperator, &iaInfo->order, &scanFlag);
setInputDataBlock(pOperator, pSup->pCtx, pBlock, iaInfo->order, scanFlag, true);
- doMergeIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes);
+ doMergeAlignedIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes);
if (pRes->info.rows >= pOperator->resultInfo.threshold) {
break;
@@ -3826,11 +3832,11 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
return (rows == 0) ? NULL : pRes;
}
-SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
- SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
- SExecTaskInfo* pTaskInfo) {
- SMergeIntervalAggOperatorInfo* miaInfo = taosMemoryCalloc(1, sizeof(SMergeIntervalAggOperatorInfo));
- SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
+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;
}
@@ -3864,6 +3870,283 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprI
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) {
+ break;
+ }
+ }
+
+ 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) {
+ doSetOperatorCompleted(pOperator);
+ }
+
+ size_t rows = pRes->info.rows;
+ pOperator->resultInfo.totalRows += rows;
+ return (rows == 0) ? NULL : pRes;
+}
+
+SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
+ SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
+ SExecTaskInfo* pTaskInfo) {
+ SMergeIntervalAggOperatorInfo* miaInfo = taosMemoryCalloc(1, sizeof(SMergeIntervalAggOperatorInfo));
+ SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
+ if (miaInfo == NULL || pOperator == NULL) {
+ goto _error;
+ }
+
+ SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo;
+
+ 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(pExprSupp, &iaInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str);
+ initBasicInfo(&iaInfo->binfo, pResBlock);
+
+ initExecTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &iaInfo->win);
+
+ iaInfo->timeWindowInterpo = timeWindowinterpNeeded(pExprSupp->pCtx, numOfCols, iaInfo);
+ if (iaInfo->timeWindowInterpo) {
+ iaInfo->binfo.resultRowInfo.openWindow = tdListNew(sizeof(SResultRowPosition));
+ if (iaInfo->binfo.resultRowInfo.openWindow == NULL) {
+ goto _error;
+ }
+ }
+
+ initResultRowInfo(&iaInfo->binfo.resultRowInfo);
+
pOperator->name = "TimeMergeIntervalAggOperator";
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL;
pOperator->blocking = false;
@@ -3889,4 +4172,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 581935514e20fb0b755ca03439f5053d14f70469..1dd72fd83fb080749a58e47aba22e0b461f47e5b 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,6 +375,12 @@ int32_t msortComparFn(const void *pLeft, const void *pRight, void *param) {
SSDataBlock* pLeftBlock = pLeftSource->src.pBlock;
SSDataBlock* pRightBlock = pRightSource->src.pBlock;
+ 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) {
SBlockOrderInfo* pOrder = TARRAY_GET_ELEM(pInfo, i);
SColumnInfoData* pLeftColInfoData = TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pOrder->slotId);
@@ -680,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 e691d562c6b4426015a7a7d10906d6c4b307cb5f..4d2f926c125764c019ab8f2ca797bd3b230a683c 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 cfad00f45898a60dc196edae522c67246d5afb69..6baf45a5b3abb92bc4cd595a24bc67f148cd799d 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 1164b962624c94af6024808e2de6438553d14be1..d7ff03ec594f414cb4449624221e7220c76880eb 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;
@@ -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
@@ -4665,12 +4687,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;
@@ -5119,14 +5135,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;
@@ -5221,6 +5229,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 710b01ce59eb04573ed3ec9befe3046f1876df4e..5fcf5e239cc28d639eb2655d8d121c158d2cdec7 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/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c
index 8290b5628c0a09cff094232546dfdafdf5ce6af4..0bde0d0581324d5a098fb2dc8b8f9906c5944920 100644
--- a/source/libs/nodes/src/nodesCloneFuncs.c
+++ b/source/libs/nodes/src/nodesCloneFuncs.c
@@ -702,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:
diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c
index bde5159087634a2ad06b6b4a1e38ff06f7a32948..10a933b00b074ae266ee632277a1799ad6c2632d 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 9b0241f2f133ff744c048319bd78001ea0bdc649..dff3821a0a070b484c31fefba4d250087a501afe 100644
--- a/source/libs/nodes/src/nodesUtilFuncs.c
+++ b/source/libs/nodes/src/nodesUtilFuncs.c
@@ -273,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:
@@ -287,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:
@@ -781,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: {
@@ -825,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/sql.y b/source/libs/parser/inc/sql.y
index 54c46ecb5dcf06d1f9f3264820e0265580d36504..16a78712edcd1df4741cea1e0be65114520f250e 100644
--- a/source/libs/parser/inc/sql.y
+++ b/source/libs/parser/inc/sql.y
@@ -757,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); }
@@ -792,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/parCalcConst.c b/source/libs/parser/src/parCalcConst.c
index 22d7afd6424a291e397a5a206f822ddadd1e2bc8..0dfc79269e9a47bf7af13521a36c1e0073015f20 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/parTranslater.c b/source/libs/parser/src/parTranslater.c
index 502e35cc4c06741b3c20d25cae2c7086c9ac6745..6c21f712289e083f73ab03bf3c453449120842c2 100644
--- a/source/libs/parser/src/parTranslater.c
+++ b/source/libs/parser/src/parTranslater.c
@@ -689,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;
@@ -1200,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);
}
}
@@ -2489,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) {
@@ -2538,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) {
diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c
index c7651137b1d7f8d5dc219790797394978fada021..330cf67b222d5573fbadd171101502cf25a5e5f9 100644
--- a/source/libs/parser/src/sql.c
+++ b/source/libs/parser/src/sql.c
@@ -139,16 +139,16 @@ typedef union {
#define ParseCTX_STORE
#define YYFALLBACK 1
#define YYNSTATE 641
-#define YYNRULE 466
+#define YYNRULE 467
#define YYNTOKEN 242
#define YY_MAX_SHIFT 640
#define YY_MIN_SHIFTREDUCE 933
-#define YY_MAX_SHIFTREDUCE 1398
-#define YY_ERROR_ACTION 1399
-#define YY_ACCEPT_ACTION 1400
-#define YY_NO_ACTION 1401
-#define YY_MIN_REDUCE 1402
-#define YY_MAX_REDUCE 1867
+#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])))
@@ -217,226 +217,226 @@ typedef union {
*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2192)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 1697, 1845, 1522, 309, 412, 1697, 413, 1434, 326, 1400,
- /* 10 */ 137, 1694, 37, 35, 1490, 1844, 1694, 1710, 417, 1842,
+ /* 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, 1434, 1690, 1696, 451,
- /* 40 */ 1222, 456, 1690, 1696, 1726, 30, 240, 1206, 559, 1533,
- /* 50 */ 1793, 1533, 540, 559, 22, 556, 555, 1680, 14, 539,
- /* 60 */ 37, 35, 1335, 322, 1214, 1215, 157, 335, 318, 1710,
- /* 70 */ 1208, 134, 520, 365, 1790, 38, 36, 34, 33, 32,
- /* 80 */ 1535, 1, 1214, 1533, 1739, 67, 555, 85, 1711, 542,
- /* 90 */ 1713, 1714, 538, 58, 559, 1206, 1726, 1779, 113, 76,
- /* 100 */ 371, 292, 1775, 637, 519, 556, 14, 1528, 1845, 1680,
- /* 110 */ 1425, 539, 1214, 1845, 1845, 543, 369, 1277, 1278, 963,
- /* 120 */ 1526, 560, 152, 470, 555, 1631, 1842, 154, 152, 2,
- /* 130 */ 430, 1842, 1842, 1533, 206, 82, 1739, 290, 478, 86,
- /* 140 */ 1711, 542, 1713, 1714, 538, 1369, 559, 40, 118, 1779,
- /* 150 */ 1680, 637, 198, 311, 1775, 148, 1525, 967, 968, 1209,
+ /* 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, 1806, 1223, 330, 1218,
- /* 180 */ 1535, 1578, 1580, 1212, 1213, 41, 1259, 1260, 1262, 1263,
+ /* 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, 1579, 1580, 26, 59, 1209, 1845, 1207,
+ /* 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, 1424, 1710, 1842, 402, 318, 67,
+ /* 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, 1726, 465,
- /* 250 */ 464, 1529, 1726, 489, 463, 1206, 509, 114, 460, 1668,
- /* 260 */ 540, 459, 458, 457, 1680, 1680, 14, 539, 37, 35,
+ /* 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, 1511, 303, 58, 301, 300, 356, 453, 58, 2,
- /* 290 */ 155, 455, 1739, 508, 1845, 85, 1711, 542, 1713, 1714,
- /* 300 */ 538, 1304, 559, 1206, 344, 1779, 358, 354, 152, 292,
- /* 310 */ 1775, 637, 1842, 454, 115, 38, 36, 34, 33, 32,
- /* 320 */ 1214, 1845, 136, 1524, 1414, 1277, 1278, 1509, 518, 149,
- /* 330 */ 1786, 1787, 1233, 1791, 1694, 152, 27, 8, 430, 1842,
+ /* 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, 1403, 1085, 572, 1087, 1088, 569, 566, 81, 637,
- /* 360 */ 1690, 1696, 38, 36, 34, 33, 32, 1209, 78, 1207,
- /* 370 */ 1359, 559, 99, 1277, 1278, 98, 97, 96, 95, 94,
- /* 380 */ 93, 92, 91, 90, 593, 1349, 38, 36, 34, 33,
+ /* 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, 1357, 1358,
- /* 410 */ 1360, 1361, 980, 155, 979, 1209, 99, 1207, 155, 98,
+ /* 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 */ 1280, 11, 10, 1710, 462, 461, 318, 162, 1208, 1212,
+ /* 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 */ 1726, 479, 65, 1206, 1845, 64, 593, 155, 540, 980,
- /* 470 */ 147, 979, 1585, 1680, 1231, 539, 37, 35, 1843, 308,
- /* 480 */ 1214, 1461, 1842, 1572, 318, 1793, 1208, 1423, 1583, 1214,
- /* 490 */ 38, 36, 34, 33, 32, 1422, 449, 9, 981, 1234,
- /* 500 */ 1739, 1395, 1845, 87, 1711, 542, 1713, 1714, 538, 1789,
- /* 510 */ 559, 1206, 1311, 1779, 199, 134, 152, 1778, 1775, 637,
- /* 520 */ 1842, 543, 133, 1585, 1536, 1246, 1342, 1680, 1214, 321,
- /* 530 */ 323, 1630, 1232, 1277, 1278, 1680, 293, 609, 607, 1583,
- /* 540 */ 1421, 615, 614, 613, 333, 9, 612, 611, 610, 119,
+ /* 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, 1402, 38, 36, 34, 33, 32, 637, 1297, 505,
- /* 570 */ 69, 291, 1285, 967, 968, 1209, 1420, 1207, 1232, 1419,
- /* 580 */ 1680, 1277, 1278, 1394, 28, 108, 107, 106, 105, 104,
+ /* 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, 1510, 1259, 1260, 1262, 1263, 1264, 1265, 1266, 535,
- /* 610 */ 557, 1274, 1275, 1276, 1279, 556, 1680, 1585, 1585, 1680,
- /* 620 */ 1298, 331, 585, 1209, 329, 1207, 370, 231, 1518, 134,
- /* 630 */ 34, 33, 32, 1583, 1584, 1418, 37, 35, 1535, 511,
- /* 640 */ 506, 200, 1303, 1533, 318, 591, 1208, 1212, 1213, 1417,
+ /* 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, 1680, 556, 29, 316, 1292,
- /* 680 */ 1293, 1294, 1295, 1296, 1300, 1301, 1302, 387, 1214, 1680,
- /* 690 */ 185, 1533, 556, 263, 591, 597, 1563, 1505, 1416, 1261,
- /* 700 */ 1190, 1191, 140, 388, 1533, 2, 1413, 556, 447, 443,
- /* 710 */ 439, 435, 184, 125, 124, 588, 587, 586, 429, 1793,
- /* 720 */ 1533, 1698, 1710, 1334, 289, 1232, 1230, 637, 1412, 1700,
- /* 730 */ 1411, 455, 1694, 395, 7, 1533, 407, 68, 1680, 556,
- /* 740 */ 182, 1277, 1278, 1788, 556, 1261, 1680, 1410, 1409, 1726,
- /* 750 */ 1530, 380, 1235, 454, 408, 1657, 382, 540, 1690, 1696,
- /* 760 */ 135, 524, 1680, 556, 539, 269, 1702, 1533, 1680, 559,
- /* 770 */ 1680, 1621, 1533, 556, 487, 496, 589, 267, 55, 1576,
- /* 780 */ 527, 54, 164, 1209, 553, 1207, 373, 1680, 1680, 1739,
- /* 790 */ 596, 1533, 287, 1711, 542, 1713, 1714, 538, 167, 559,
- /* 800 */ 181, 1533, 173, 1464, 178, 1520, 425, 1212, 1213, 1408,
+ /* 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, 1576, 1516, 401,
+ /* 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, 1680,
+ /* 840 */ 385, 384, 383, 377, 376, 375, 374, 203, 1032, 1681,
/* 850 */ 38, 36, 34, 33, 32, 556, 556, 1208, 556, 516,
- /* 860 */ 1407, 84, 1406, 465, 464, 1034, 554, 253, 463, 332,
- /* 870 */ 1405, 114, 460, 1798, 1330, 459, 458, 457, 608, 1451,
- /* 880 */ 212, 534, 1206, 1533, 1533, 190, 1533, 117, 188, 486,
- /* 890 */ 1710, 1508, 1261, 62, 61, 368, 293, 1217, 161, 1214,
- /* 900 */ 1680, 466, 1680, 192, 362, 516, 191, 1330, 194, 196,
- /* 910 */ 1680, 193, 195, 1446, 1444, 288, 584, 1726, 352, 359,
- /* 920 */ 350, 346, 342, 158, 337, 519, 115, 477, 1297, 1415,
- /* 930 */ 1680, 1333, 539, 117, 1216, 468, 471, 123, 637, 1004,
- /* 940 */ 475, 150, 1786, 1787, 532, 1791, 235, 11, 10, 48,
- /* 950 */ 525, 216, 1491, 155, 448, 503, 1005, 1739, 1710, 480,
- /* 960 */ 86, 1711, 542, 1713, 1714, 538, 1440, 559, 1397, 1398,
- /* 970 */ 1779, 528, 115, 39, 311, 1775, 148, 223, 491, 39,
- /* 980 */ 1298, 1727, 1710, 334, 591, 1726, 39, 151, 1786, 1787,
- /* 990 */ 1356, 1791, 218, 540, 1209, 242, 1207, 1807, 1680, 1435,
- /* 1000 */ 539, 1573, 1303, 125, 124, 588, 587, 586, 1809, 1726,
+ /* 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, 1680, 1710, 539, 1739, 3, 1163, 272, 1711,
- /* 1030 */ 542, 1713, 1714, 538, 122, 559, 244, 29, 316, 1292,
- /* 1040 */ 1293, 1294, 1295, 1296, 1300, 1301, 1302, 123, 1219, 1739,
- /* 1050 */ 1726, 548, 86, 1711, 542, 1713, 1714, 538, 540, 559,
- /* 1060 */ 48, 564, 1779, 1680, 1710, 539, 311, 1775, 1858, 1289,
- /* 1070 */ 122, 123, 110, 122, 5, 250, 336, 1813, 1230, 339,
+ /* 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 */ 1739, 1726, 1623, 86, 1711, 542, 1713, 1714, 538, 540,
- /* 1100 */ 559, 262, 1091, 1779, 1680, 404, 539, 311, 1775, 1858,
- /* 1110 */ 403, 1095, 1102, 1100, 126, 405, 409, 1236, 1836, 410,
+ /* 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, 1739, 175, 177, 86, 1711, 542, 1713, 1714, 538,
- /* 1140 */ 1710, 559, 427, 1237, 1779, 428, 180, 450, 311, 1775,
- /* 1150 */ 1858, 431, 452, 66, 183, 1523, 187, 1519, 481, 1797,
- /* 1160 */ 189, 128, 307, 89, 260, 129, 1521, 1726, 482, 485,
- /* 1170 */ 201, 204, 488, 1517, 130, 540, 131, 490, 207, 1235,
- /* 1180 */ 1680, 210, 539, 1810, 504, 546, 6, 492, 1662, 1820,
- /* 1190 */ 1661, 1819, 513, 1800, 222, 520, 142, 499, 500, 224,
- /* 1200 */ 498, 225, 493, 1710, 501, 1330, 310, 1739, 497, 226,
- /* 1210 */ 278, 1711, 542, 1713, 1714, 538, 507, 559, 214, 217,
- /* 1220 */ 1710, 116, 1234, 42, 1841, 18, 526, 529, 227, 523,
- /* 1230 */ 1726, 233, 312, 1861, 544, 545, 1845, 320, 540, 1794,
- /* 1240 */ 1629, 549, 246, 1680, 1628, 539, 551, 1726, 261, 550,
- /* 1250 */ 154, 77, 1534, 248, 1842, 540, 75, 562, 520, 264,
- /* 1260 */ 1680, 228, 539, 1760, 1577, 1506, 256, 49, 636, 266,
- /* 1270 */ 1739, 270, 1674, 278, 1711, 542, 1713, 1714, 538, 279,
- /* 1280 */ 559, 271, 268, 1710, 141, 236, 1673, 1739, 530, 60,
- /* 1290 */ 87, 1711, 542, 1713, 1714, 538, 238, 559, 1672, 1845,
- /* 1300 */ 1779, 1710, 338, 1669, 531, 1775, 340, 341, 1201, 1202,
- /* 1310 */ 1726, 159, 345, 152, 1667, 347, 348, 1842, 537, 349,
- /* 1320 */ 1666, 1665, 351, 1680, 353, 539, 1664, 355, 1726, 1663,
- /* 1330 */ 357, 1647, 160, 360, 361, 1177, 540, 1176, 1641, 1640,
- /* 1340 */ 366, 1680, 367, 539, 1639, 1638, 1149, 1616, 63, 1615,
- /* 1350 */ 1739, 378, 1710, 286, 1711, 542, 1713, 1714, 538, 536,
- /* 1360 */ 559, 533, 1751, 1614, 1613, 1612, 1611, 1610, 1739, 379,
- /* 1370 */ 640, 138, 1711, 542, 1713, 1714, 538, 381, 559, 1726,
- /* 1380 */ 1609, 1608, 1607, 1606, 258, 1605, 1604, 540, 1603, 1602,
- /* 1390 */ 1601, 1600, 1680, 516, 539, 1599, 145, 1598, 1597, 1596,
- /* 1400 */ 120, 1595, 631, 627, 623, 619, 257, 1594, 1593, 1592,
- /* 1410 */ 1591, 1590, 1589, 1710, 1151, 1588, 521, 1859, 1587, 1739,
- /* 1420 */ 1586, 117, 87, 1711, 542, 1713, 1714, 538, 1463, 559,
- /* 1430 */ 1431, 83, 1779, 168, 251, 146, 970, 1776, 969, 111,
- /* 1440 */ 1726, 520, 1430, 169, 414, 1655, 1649, 416, 540, 1637,
- /* 1450 */ 112, 174, 1636, 1680, 176, 539, 1626, 1512, 179, 1462,
- /* 1460 */ 115, 1460, 434, 998, 433, 1458, 1710, 552, 438, 1456,
- /* 1470 */ 432, 1454, 437, 436, 441, 229, 1786, 515, 442, 514,
- /* 1480 */ 1739, 440, 1845, 282, 1711, 542, 1713, 1714, 538, 1710,
- /* 1490 */ 559, 444, 445, 1726, 1443, 494, 154, 446, 208, 1442,
- /* 1500 */ 1842, 540, 1429, 1514, 186, 1106, 1680, 516, 539, 1105,
- /* 1510 */ 1513, 1031, 1452, 1030, 1029, 1028, 1726, 1182, 606, 202,
- /* 1520 */ 608, 1025, 512, 47, 540, 1024, 304, 1023, 1447, 1680,
- /* 1530 */ 305, 539, 469, 1739, 1445, 117, 138, 1711, 542, 1713,
- /* 1540 */ 1714, 538, 315, 559, 306, 1710, 1428, 472, 474, 1427,
- /* 1550 */ 88, 476, 1654, 1184, 51, 520, 1739, 1648, 483, 287,
- /* 1560 */ 1711, 542, 1713, 1714, 538, 1635, 559, 1634, 1633, 1625,
- /* 1570 */ 71, 15, 1726, 4, 115, 209, 39, 1371, 23, 213,
- /* 1580 */ 537, 205, 1860, 484, 45, 1680, 211, 539, 50, 229,
- /* 1590 */ 1786, 515, 139, 514, 220, 215, 1845, 132, 1710, 1355,
- /* 1600 */ 219, 24, 221, 1348, 1700, 72, 230, 1710, 143, 1327,
- /* 1610 */ 152, 25, 1739, 1326, 1842, 286, 1711, 542, 1713, 1714,
- /* 1620 */ 538, 1710, 559, 44, 1752, 1726, 1388, 17, 1383, 1377,
- /* 1630 */ 10, 1382, 313, 540, 1726, 1387, 1386, 314, 1680, 19,
- /* 1640 */ 539, 1269, 540, 1268, 31, 1290, 144, 1680, 1726, 539,
+ /* 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, 1680, 1710, 539, 1624, 1739, 541, 247, 287, 1711,
- /* 1670 */ 542, 1713, 1714, 538, 1739, 559, 241, 287, 1711, 542,
- /* 1680 */ 1713, 1714, 538, 1710, 559, 1353, 243, 547, 1739, 1726,
- /* 1690 */ 245, 273, 1711, 542, 1713, 1714, 538, 540, 559, 73,
- /* 1700 */ 74, 78, 1680, 1699, 539, 252, 1742, 1224, 1271, 249,
- /* 1710 */ 1726, 1092, 558, 46, 561, 563, 327, 1089, 540, 565,
- /* 1720 */ 567, 568, 570, 1680, 1086, 539, 571, 573, 1080, 1739,
- /* 1730 */ 574, 576, 274, 1711, 542, 1713, 1714, 538, 1078, 559,
- /* 1740 */ 1069, 1710, 1084, 583, 577, 1101, 1083, 79, 1082, 1081,
- /* 1750 */ 1739, 80, 1710, 281, 1711, 542, 1713, 1714, 538, 57,
- /* 1760 */ 559, 254, 1097, 1710, 996, 592, 1020, 595, 1726, 255,
- /* 1770 */ 1038, 1013, 1018, 1017, 1016, 1035, 540, 1015, 1014, 1726,
- /* 1780 */ 1012, 1680, 1011, 539, 1033, 1008, 1007, 540, 1006, 1003,
- /* 1790 */ 1726, 1002, 1680, 1001, 539, 1459, 617, 616, 540, 618,
- /* 1800 */ 1457, 620, 621, 1680, 622, 539, 1455, 624, 1739, 625,
- /* 1810 */ 626, 283, 1711, 542, 1713, 1714, 538, 1453, 559, 1739,
- /* 1820 */ 629, 628, 275, 1711, 542, 1713, 1714, 538, 1710, 559,
- /* 1830 */ 1739, 630, 1441, 284, 1711, 542, 1713, 1714, 538, 632,
- /* 1840 */ 559, 1426, 634, 635, 1710, 1210, 265, 638, 639, 1401,
- /* 1850 */ 1401, 1401, 1401, 1401, 1401, 1726, 1401, 1401, 1401, 1401,
- /* 1860 */ 1401, 1401, 1401, 540, 1401, 1401, 1401, 1401, 1680, 1401,
- /* 1870 */ 539, 1726, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 540,
- /* 1880 */ 1401, 1401, 1401, 1401, 1680, 1401, 539, 1401, 1401, 1401,
- /* 1890 */ 1401, 1401, 1401, 1710, 1401, 1739, 1401, 1401, 276, 1711,
- /* 1900 */ 542, 1713, 1714, 538, 1401, 559, 1401, 1710, 1401, 1401,
- /* 1910 */ 1401, 1739, 1401, 1401, 285, 1711, 542, 1713, 1714, 538,
- /* 1920 */ 1726, 559, 1401, 1401, 1401, 1401, 1401, 1401, 540, 1401,
- /* 1930 */ 1401, 1401, 1401, 1680, 1726, 539, 1401, 1401, 1401, 1401,
- /* 1940 */ 1401, 1401, 540, 1401, 1401, 1401, 1401, 1680, 1710, 539,
- /* 1950 */ 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401,
- /* 1960 */ 1739, 1401, 1401, 277, 1711, 542, 1713, 1714, 538, 1710,
- /* 1970 */ 559, 1401, 1401, 1401, 1739, 1726, 1401, 1722, 1711, 542,
- /* 1980 */ 1713, 1714, 538, 540, 559, 1401, 1401, 1401, 1680, 1401,
- /* 1990 */ 539, 1401, 1401, 1401, 1401, 1401, 1726, 1401, 1401, 1401,
- /* 2000 */ 1401, 1401, 1401, 1401, 540, 1401, 1401, 1401, 1401, 1680,
- /* 2010 */ 1401, 539, 1401, 1401, 1401, 1739, 1401, 1401, 1721, 1711,
- /* 2020 */ 542, 1713, 1714, 538, 1401, 559, 1401, 1710, 1401, 1401,
- /* 2030 */ 1401, 1401, 1401, 1401, 1401, 1401, 1739, 1401, 1710, 1720,
- /* 2040 */ 1711, 542, 1713, 1714, 538, 1401, 559, 1401, 1401, 1710,
- /* 2050 */ 1401, 1401, 1401, 1401, 1726, 1401, 1401, 1401, 1401, 1401,
- /* 2060 */ 1401, 1401, 540, 1401, 1401, 1726, 1401, 1680, 1401, 539,
- /* 2070 */ 1401, 1401, 1401, 540, 1401, 1401, 1726, 1401, 1680, 1401,
- /* 2080 */ 539, 1401, 1401, 1401, 540, 1401, 1401, 1401, 1401, 1680,
- /* 2090 */ 1710, 539, 1401, 1401, 1739, 1401, 1401, 296, 1711, 542,
- /* 2100 */ 1713, 1714, 538, 1401, 559, 1739, 1401, 1401, 295, 1711,
- /* 2110 */ 542, 1713, 1714, 538, 1710, 559, 1739, 1726, 1401, 297,
- /* 2120 */ 1711, 542, 1713, 1714, 538, 540, 559, 1401, 1401, 1401,
- /* 2130 */ 1680, 1401, 539, 1401, 1401, 1401, 1401, 1401, 1401, 1401,
- /* 2140 */ 1401, 1726, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 540,
- /* 2150 */ 1401, 1401, 1401, 1401, 1680, 1401, 539, 1739, 1401, 1401,
- /* 2160 */ 294, 1711, 542, 1713, 1714, 538, 1401, 559, 1401, 1401,
- /* 2170 */ 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401, 1401,
- /* 2180 */ 1401, 1739, 1401, 1401, 280, 1711, 542, 1713, 1714, 538,
- /* 2190 */ 1401, 559,
+ /* 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,
@@ -763,71 +763,71 @@ static const short yy_reduce_ofst[] = {
/* 260 */ 977, 1005, 1013, 1015, 1014, 1039,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 10 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 20 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 30 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 40 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 50 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 60 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1468, 1399,
- /* 70 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 80 */ 1399, 1399, 1399, 1466, 1617, 1399, 1781, 1399, 1399, 1399,
- /* 90 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 100 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 110 */ 1399, 1399, 1399, 1468, 1399, 1792, 1792, 1792, 1466, 1399,
- /* 120 */ 1399, 1399, 1399, 1399, 1399, 1399, 1562, 1399, 1399, 1399,
- /* 130 */ 1399, 1399, 1399, 1399, 1399, 1650, 1399, 1399, 1862, 1399,
- /* 140 */ 1399, 1656, 1816, 1399, 1399, 1399, 1399, 1515, 1808, 1784,
- /* 150 */ 1798, 1785, 1847, 1847, 1847, 1801, 1399, 1812, 1399, 1399,
- /* 160 */ 1399, 1642, 1399, 1399, 1622, 1619, 1619, 1399, 1399, 1399,
- /* 170 */ 1399, 1468, 1399, 1468, 1399, 1399, 1468, 1399, 1468, 1399,
- /* 180 */ 1399, 1468, 1468, 1399, 1468, 1399, 1399, 1399, 1399, 1399,
- /* 190 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 200 */ 1399, 1399, 1466, 1652, 1399, 1466, 1399, 1399, 1466, 1399,
- /* 210 */ 1399, 1466, 1399, 1399, 1823, 1821, 1399, 1823, 1821, 1399,
- /* 220 */ 1399, 1399, 1835, 1831, 1823, 1839, 1837, 1814, 1812, 1798,
- /* 230 */ 1399, 1399, 1399, 1853, 1849, 1865, 1853, 1849, 1853, 1849,
- /* 240 */ 1399, 1821, 1399, 1399, 1821, 1399, 1627, 1399, 1399, 1466,
- /* 250 */ 1399, 1466, 1399, 1531, 1399, 1399, 1399, 1466, 1399, 1644,
- /* 260 */ 1658, 1565, 1565, 1565, 1469, 1404, 1399, 1399, 1399, 1399,
- /* 270 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1527,
- /* 280 */ 1725, 1834, 1833, 1757, 1756, 1755, 1753, 1724, 1399, 1399,
- /* 290 */ 1399, 1399, 1399, 1399, 1718, 1719, 1717, 1716, 1399, 1399,
- /* 300 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 310 */ 1399, 1782, 1399, 1850, 1854, 1399, 1399, 1399, 1701, 1399,
- /* 320 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 330 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 340 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 350 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 360 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 370 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 380 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 390 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 400 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 410 */ 1399, 1399, 1399, 1433, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 420 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 430 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 440 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 450 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 460 */ 1399, 1496, 1495, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 470 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 480 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 490 */ 1399, 1399, 1399, 1399, 1399, 1805, 1815, 1399, 1399, 1399,
- /* 500 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 510 */ 1701, 1399, 1832, 1399, 1791, 1787, 1399, 1399, 1783, 1399,
- /* 520 */ 1399, 1848, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 530 */ 1399, 1777, 1399, 1750, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 540 */ 1399, 1399, 1712, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 550 */ 1399, 1399, 1399, 1399, 1399, 1700, 1399, 1741, 1399, 1399,
- /* 560 */ 1399, 1399, 1399, 1399, 1399, 1399, 1559, 1399, 1399, 1399,
- /* 570 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1544,
- /* 580 */ 1542, 1541, 1540, 1399, 1537, 1399, 1399, 1399, 1399, 1568,
- /* 590 */ 1567, 1399, 1399, 1399, 1399, 1399, 1399, 1488, 1399, 1399,
- /* 600 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1479, 1399, 1478,
- /* 610 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 620 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 630 */ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
- /* 640 */ 1399,
+ /* 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 *****************************/
@@ -1508,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",
@@ -1928,91 +1928,92 @@ static const char *const yyRuleName[] = {
/* 378 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP",
/* 379 */ "common_expression ::= expression",
/* 380 */ "common_expression ::= boolean_value_expression",
- /* 381 */ "from_clause ::= FROM table_reference_list",
- /* 382 */ "table_reference_list ::= table_reference",
- /* 383 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference",
- /* 384 */ "table_reference ::= table_primary",
- /* 385 */ "table_reference ::= joined_table",
- /* 386 */ "table_primary ::= table_name alias_opt",
- /* 387 */ "table_primary ::= db_name NK_DOT table_name alias_opt",
- /* 388 */ "table_primary ::= subquery alias_opt",
- /* 389 */ "table_primary ::= parenthesized_joined_table",
- /* 390 */ "alias_opt ::=",
- /* 391 */ "alias_opt ::= table_alias",
- /* 392 */ "alias_opt ::= AS table_alias",
- /* 393 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP",
- /* 394 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP",
- /* 395 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition",
- /* 396 */ "join_type ::=",
- /* 397 */ "join_type ::= INNER",
- /* 398 */ "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",
- /* 399 */ "set_quantifier_opt ::=",
- /* 400 */ "set_quantifier_opt ::= DISTINCT",
- /* 401 */ "set_quantifier_opt ::= ALL",
- /* 402 */ "select_list ::= NK_STAR",
- /* 403 */ "select_list ::= select_sublist",
- /* 404 */ "select_sublist ::= select_item",
- /* 405 */ "select_sublist ::= select_sublist NK_COMMA select_item",
- /* 406 */ "select_item ::= common_expression",
- /* 407 */ "select_item ::= common_expression column_alias",
- /* 408 */ "select_item ::= common_expression AS column_alias",
- /* 409 */ "select_item ::= table_name NK_DOT NK_STAR",
- /* 410 */ "where_clause_opt ::=",
- /* 411 */ "where_clause_opt ::= WHERE search_condition",
- /* 412 */ "partition_by_clause_opt ::=",
- /* 413 */ "partition_by_clause_opt ::= PARTITION BY expression_list",
- /* 414 */ "twindow_clause_opt ::=",
- /* 415 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP",
- /* 416 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP",
- /* 417 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt",
- /* 418 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt",
- /* 419 */ "sliding_opt ::=",
- /* 420 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP",
- /* 421 */ "fill_opt ::=",
- /* 422 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP",
- /* 423 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP",
- /* 424 */ "fill_mode ::= NONE",
- /* 425 */ "fill_mode ::= PREV",
- /* 426 */ "fill_mode ::= NULL",
- /* 427 */ "fill_mode ::= LINEAR",
- /* 428 */ "fill_mode ::= NEXT",
- /* 429 */ "group_by_clause_opt ::=",
- /* 430 */ "group_by_clause_opt ::= GROUP BY group_by_list",
- /* 431 */ "group_by_list ::= expression",
- /* 432 */ "group_by_list ::= group_by_list NK_COMMA expression",
- /* 433 */ "having_clause_opt ::=",
- /* 434 */ "having_clause_opt ::= HAVING search_condition",
- /* 435 */ "range_opt ::=",
- /* 436 */ "range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP",
- /* 437 */ "every_opt ::=",
- /* 438 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP",
- /* 439 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt",
- /* 440 */ "query_expression_body ::= query_primary",
- /* 441 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body",
- /* 442 */ "query_expression_body ::= query_expression_body UNION query_expression_body",
- /* 443 */ "query_primary ::= query_specification",
- /* 444 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP",
- /* 445 */ "order_by_clause_opt ::=",
- /* 446 */ "order_by_clause_opt ::= ORDER BY sort_specification_list",
- /* 447 */ "slimit_clause_opt ::=",
- /* 448 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER",
- /* 449 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER",
- /* 450 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER",
- /* 451 */ "limit_clause_opt ::=",
- /* 452 */ "limit_clause_opt ::= LIMIT NK_INTEGER",
- /* 453 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER",
- /* 454 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER",
- /* 455 */ "subquery ::= NK_LP query_expression NK_RP",
- /* 456 */ "search_condition ::= common_expression",
- /* 457 */ "sort_specification_list ::= sort_specification",
- /* 458 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification",
- /* 459 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt",
- /* 460 */ "ordering_specification_opt ::=",
- /* 461 */ "ordering_specification_opt ::= ASC",
- /* 462 */ "ordering_specification_opt ::= DESC",
- /* 463 */ "null_ordering_opt ::=",
- /* 464 */ "null_ordering_opt ::= NULLS FIRST",
- /* 465 */ "null_ordering_opt ::= NULLS LAST",
+ /* 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 */
@@ -2180,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 */
@@ -2988,91 +2989,92 @@ static const struct {
{ 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, -2 }, /* (381) from_clause ::= FROM table_reference_list */
- { 333, -1 }, /* (382) table_reference_list ::= table_reference */
- { 333, -3 }, /* (383) table_reference_list ::= table_reference_list NK_COMMA table_reference */
- { 334, -1 }, /* (384) table_reference ::= table_primary */
- { 334, -1 }, /* (385) table_reference ::= joined_table */
- { 335, -2 }, /* (386) table_primary ::= table_name alias_opt */
- { 335, -4 }, /* (387) table_primary ::= db_name NK_DOT table_name alias_opt */
- { 335, -2 }, /* (388) table_primary ::= subquery alias_opt */
- { 335, -1 }, /* (389) table_primary ::= parenthesized_joined_table */
- { 337, 0 }, /* (390) alias_opt ::= */
- { 337, -1 }, /* (391) alias_opt ::= table_alias */
- { 337, -2 }, /* (392) alias_opt ::= AS table_alias */
- { 338, -3 }, /* (393) parenthesized_joined_table ::= NK_LP joined_table NK_RP */
- { 338, -3 }, /* (394) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */
- { 336, -6 }, /* (395) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */
- { 339, 0 }, /* (396) join_type ::= */
- { 339, -1 }, /* (397) join_type ::= INNER */
- { 341, -12 }, /* (398) 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 }, /* (399) set_quantifier_opt ::= */
- { 342, -1 }, /* (400) set_quantifier_opt ::= DISTINCT */
- { 342, -1 }, /* (401) set_quantifier_opt ::= ALL */
- { 343, -1 }, /* (402) select_list ::= NK_STAR */
- { 343, -1 }, /* (403) select_list ::= select_sublist */
- { 351, -1 }, /* (404) select_sublist ::= select_item */
- { 351, -3 }, /* (405) select_sublist ::= select_sublist NK_COMMA select_item */
- { 352, -1 }, /* (406) select_item ::= common_expression */
- { 352, -2 }, /* (407) select_item ::= common_expression column_alias */
- { 352, -3 }, /* (408) select_item ::= common_expression AS column_alias */
- { 352, -3 }, /* (409) select_item ::= table_name NK_DOT NK_STAR */
- { 310, 0 }, /* (410) where_clause_opt ::= */
- { 310, -2 }, /* (411) where_clause_opt ::= WHERE search_condition */
- { 344, 0 }, /* (412) partition_by_clause_opt ::= */
- { 344, -3 }, /* (413) partition_by_clause_opt ::= PARTITION BY expression_list */
- { 348, 0 }, /* (414) twindow_clause_opt ::= */
- { 348, -6 }, /* (415) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */
- { 348, -4 }, /* (416) twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */
- { 348, -6 }, /* (417) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */
- { 348, -8 }, /* (418) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */
- { 296, 0 }, /* (419) sliding_opt ::= */
- { 296, -4 }, /* (420) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */
- { 347, 0 }, /* (421) fill_opt ::= */
- { 347, -4 }, /* (422) fill_opt ::= FILL NK_LP fill_mode NK_RP */
- { 347, -6 }, /* (423) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */
- { 353, -1 }, /* (424) fill_mode ::= NONE */
- { 353, -1 }, /* (425) fill_mode ::= PREV */
- { 353, -1 }, /* (426) fill_mode ::= NULL */
- { 353, -1 }, /* (427) fill_mode ::= LINEAR */
- { 353, -1 }, /* (428) fill_mode ::= NEXT */
- { 349, 0 }, /* (429) group_by_clause_opt ::= */
- { 349, -3 }, /* (430) group_by_clause_opt ::= GROUP BY group_by_list */
- { 354, -1 }, /* (431) group_by_list ::= expression */
- { 354, -3 }, /* (432) group_by_list ::= group_by_list NK_COMMA expression */
- { 350, 0 }, /* (433) having_clause_opt ::= */
- { 350, -2 }, /* (434) having_clause_opt ::= HAVING search_condition */
- { 345, 0 }, /* (435) range_opt ::= */
- { 345, -6 }, /* (436) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */
- { 346, 0 }, /* (437) every_opt ::= */
- { 346, -4 }, /* (438) every_opt ::= EVERY NK_LP duration_literal NK_RP */
- { 300, -4 }, /* (439) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */
- { 355, -1 }, /* (440) query_expression_body ::= query_primary */
- { 355, -4 }, /* (441) query_expression_body ::= query_expression_body UNION ALL query_expression_body */
- { 355, -3 }, /* (442) query_expression_body ::= query_expression_body UNION query_expression_body */
- { 359, -1 }, /* (443) query_primary ::= query_specification */
- { 359, -6 }, /* (444) query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */
- { 356, 0 }, /* (445) order_by_clause_opt ::= */
- { 356, -3 }, /* (446) order_by_clause_opt ::= ORDER BY sort_specification_list */
- { 357, 0 }, /* (447) slimit_clause_opt ::= */
- { 357, -2 }, /* (448) slimit_clause_opt ::= SLIMIT NK_INTEGER */
- { 357, -4 }, /* (449) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */
- { 357, -4 }, /* (450) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */
- { 358, 0 }, /* (451) limit_clause_opt ::= */
- { 358, -2 }, /* (452) limit_clause_opt ::= LIMIT NK_INTEGER */
- { 358, -4 }, /* (453) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */
- { 358, -4 }, /* (454) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */
- { 319, -3 }, /* (455) subquery ::= NK_LP query_expression NK_RP */
- { 340, -1 }, /* (456) search_condition ::= common_expression */
- { 360, -1 }, /* (457) sort_specification_list ::= sort_specification */
- { 360, -3 }, /* (458) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */
- { 361, -3 }, /* (459) sort_specification ::= expression ordering_specification_opt null_ordering_opt */
- { 362, 0 }, /* (460) ordering_specification_opt ::= */
- { 362, -1 }, /* (461) ordering_specification_opt ::= ASC */
- { 362, -1 }, /* (462) ordering_specification_opt ::= DESC */
- { 363, 0 }, /* (463) null_ordering_opt ::= */
- { 363, -2 }, /* (464) null_ordering_opt ::= NULLS FIRST */
- { 363, -2 }, /* (465) null_ordering_opt ::= NULLS LAST */
+ { 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 */
@@ -3349,7 +3351,7 @@ static YYACTIONTYPE yy_reduce(
case 66: /* exists_opt ::= */ yytestcase(yyruleno==66);
case 240: /* analyze_opt ::= */ yytestcase(yyruleno==240);
case 248: /* agg_func_opt ::= */ yytestcase(yyruleno==248);
- case 399: /* set_quantifier_opt ::= */ yytestcase(yyruleno==399);
+ case 400: /* set_quantifier_opt ::= */ yytestcase(yyruleno==400);
{ yymsp[1].minor.yy481 = false; }
break;
case 65: /* exists_opt ::= IF EXISTS */
@@ -3491,8 +3493,8 @@ static YYACTIONTYPE yy_reduce(
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 404: /* select_sublist ::= select_item */ yytestcase(yyruleno==404);
- case 457: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==457);
+ 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;
@@ -3503,8 +3505,8 @@ static YYACTIONTYPE yy_reduce(
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 405: /* select_sublist ::= select_sublist NK_COMMA select_item */ yytestcase(yyruleno==405);
- case 458: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==458);
+ 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;
@@ -3585,9 +3587,9 @@ static YYACTIONTYPE yy_reduce(
break;
case 129: /* specific_tags_opt ::= */
case 160: /* tags_def_opt ::= */ yytestcase(yyruleno==160);
- case 412: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==412);
- case 429: /* group_by_clause_opt ::= */ yytestcase(yyruleno==429);
- case 445: /* order_by_clause_opt ::= */ yytestcase(yyruleno==445);
+ 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 */
@@ -3678,7 +3680,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 161: /* tags_def_opt ::= tags_def */
case 348: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==348);
- case 403: /* select_list ::= select_sublist */ yytestcase(yyruleno==403);
+ case 404: /* select_list ::= select_sublist */ yytestcase(yyruleno==404);
{ yylhsminor.yy600 = yymsp[0].minor.yy600; }
yymsp[0].minor.yy600 = yylhsminor.yy600;
break;
@@ -3851,15 +3853,16 @@ static YYACTIONTYPE yy_reduce(
case 217: /* like_pattern_opt ::= */
case 225: /* index_options ::= */ yytestcase(yyruleno==225);
case 254: /* into_opt ::= */ yytestcase(yyruleno==254);
- case 410: /* where_clause_opt ::= */ yytestcase(yyruleno==410);
- case 414: /* twindow_clause_opt ::= */ yytestcase(yyruleno==414);
- case 419: /* sliding_opt ::= */ yytestcase(yyruleno==419);
- case 421: /* fill_opt ::= */ yytestcase(yyruleno==421);
- case 433: /* having_clause_opt ::= */ yytestcase(yyruleno==433);
- case 435: /* range_opt ::= */ yytestcase(yyruleno==435);
- case 437: /* every_opt ::= */ yytestcase(yyruleno==437);
- case 447: /* slimit_clause_opt ::= */ yytestcase(yyruleno==447);
- case 451: /* limit_clause_opt ::= */ yytestcase(yyruleno==451);
+ 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 218: /* like_pattern_opt ::= LIKE NK_STRING */
@@ -3918,7 +3921,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 241: /* analyze_opt ::= ANALYZE */
case 249: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==249);
- case 400: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==400);
+ case 401: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==401);
{ yymsp[0].minor.yy481 = true; }
break;
case 242: /* explain_options ::= */
@@ -3954,9 +3957,9 @@ static YYACTIONTYPE yy_reduce(
{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy481, &yymsp[0].minor.yy57); }
break;
case 255: /* into_opt ::= INTO full_table_name */
- case 381: /* from_clause ::= FROM table_reference_list */ yytestcase(yyruleno==381);
- case 411: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==411);
- case 434: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==434);
+ 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 256: /* stream_options ::= */
@@ -4040,12 +4043,12 @@ static YYACTIONTYPE yy_reduce(
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 382: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==382);
- case 384: /* table_reference ::= table_primary */ yytestcase(yyruleno==384);
- case 385: /* table_reference ::= joined_table */ yytestcase(yyruleno==385);
- case 389: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==389);
- case 440: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==440);
- case 443: /* query_primary ::= query_specification */ yytestcase(yyruleno==443);
+ 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;
@@ -4105,8 +4108,8 @@ static YYACTIONTYPE yy_reduce(
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 406: /* select_item ::= common_expression */ yytestcase(yyruleno==406);
- case 456: /* search_condition ::= common_expression */ yytestcase(yyruleno==456);
+ 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;
@@ -4221,7 +4224,7 @@ static YYACTIONTYPE yy_reduce(
yymsp[0].minor.yy600 = yylhsminor.yy600;
break;
case 352: /* star_func_para ::= table_name NK_DOT NK_STAR */
- case 409: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==409);
+ 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;
@@ -4330,47 +4333,47 @@ static YYACTIONTYPE yy_reduce(
}
yymsp[-2].minor.yy392 = yylhsminor.yy392;
break;
- case 383: /* 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 386: /* 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 387: /* 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 388: /* 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 390: /* alias_opt ::= */
+ case 391: /* alias_opt ::= */
{ yymsp[1].minor.yy57 = nil_token; }
break;
- case 391: /* alias_opt ::= table_alias */
+ case 392: /* alias_opt ::= table_alias */
{ yylhsminor.yy57 = yymsp[0].minor.yy57; }
yymsp[0].minor.yy57 = yylhsminor.yy57;
break;
- case 392: /* alias_opt ::= AS table_alias */
+ case 393: /* alias_opt ::= AS table_alias */
{ yymsp[-1].minor.yy57 = yymsp[0].minor.yy57; }
break;
- case 393: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */
- case 394: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==394);
+ 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 395: /* 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 396: /* join_type ::= */
+ case 397: /* join_type ::= */
{ yymsp[1].minor.yy204 = JOIN_TYPE_INNER; }
break;
- case 397: /* join_type ::= INNER */
+ case 398: /* join_type ::= INNER */
{ yymsp[0].minor.yy204 = JOIN_TYPE_INNER; }
break;
- case 398: /* 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);
@@ -4383,74 +4386,74 @@ static YYACTIONTYPE yy_reduce(
yymsp[-11].minor.yy392 = addFillClause(pCxt, yymsp[-11].minor.yy392, yymsp[-3].minor.yy392);
}
break;
- case 401: /* set_quantifier_opt ::= ALL */
+ case 402: /* set_quantifier_opt ::= ALL */
{ yymsp[0].minor.yy481 = false; }
break;
- case 402: /* select_list ::= NK_STAR */
+ case 403: /* select_list ::= NK_STAR */
{ yymsp[0].minor.yy600 = NULL; }
break;
- case 407: /* 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 408: /* 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 413: /* partition_by_clause_opt ::= PARTITION BY expression_list */
- case 430: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==430);
- case 446: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==446);
+ 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 415: /* 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 416: /* 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 417: /* 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 418: /* 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 420: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */
- case 438: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==438);
+ 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 422: /* 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 423: /* 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 424: /* fill_mode ::= NONE */
+ case 425: /* fill_mode ::= NONE */
{ yymsp[0].minor.yy270 = FILL_MODE_NONE; }
break;
- case 425: /* fill_mode ::= PREV */
+ case 426: /* fill_mode ::= PREV */
{ yymsp[0].minor.yy270 = FILL_MODE_PREV; }
break;
- case 426: /* fill_mode ::= NULL */
+ case 427: /* fill_mode ::= NULL */
{ yymsp[0].minor.yy270 = FILL_MODE_NULL; }
break;
- case 427: /* fill_mode ::= LINEAR */
+ case 428: /* fill_mode ::= LINEAR */
{ yymsp[0].minor.yy270 = FILL_MODE_LINEAR; }
break;
- case 428: /* fill_mode ::= NEXT */
+ case 429: /* fill_mode ::= NEXT */
{ yymsp[0].minor.yy270 = FILL_MODE_NEXT; }
break;
- case 431: /* 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 432: /* 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 436: /* 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 439: /* 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);
@@ -4458,56 +4461,56 @@ static YYACTIONTYPE yy_reduce(
}
yymsp[-3].minor.yy392 = yylhsminor.yy392;
break;
- case 441: /* 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 442: /* 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 444: /* 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 448: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */
- case 452: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==452);
+ 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 449: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */
- case 453: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==453);
+ 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 450: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */
- case 454: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==454);
+ 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 455: /* 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 459: /* 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 460: /* ordering_specification_opt ::= */
+ case 461: /* ordering_specification_opt ::= */
{ yymsp[1].minor.yy162 = ORDER_ASC; }
break;
- case 461: /* ordering_specification_opt ::= ASC */
+ case 462: /* ordering_specification_opt ::= ASC */
{ yymsp[0].minor.yy162 = ORDER_ASC; }
break;
- case 462: /* ordering_specification_opt ::= DESC */
+ case 463: /* ordering_specification_opt ::= DESC */
{ yymsp[0].minor.yy162 = ORDER_DESC; }
break;
- case 463: /* null_ordering_opt ::= */
+ case 464: /* null_ordering_opt ::= */
{ yymsp[1].minor.yy529 = NULL_ORDER_DEFAULT; }
break;
- case 464: /* null_ordering_opt ::= NULLS FIRST */
+ case 465: /* null_ordering_opt ::= NULLS FIRST */
{ yymsp[-1].minor.yy529 = NULL_ORDER_FIRST; }
break;
- case 465: /* 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/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp
index 11e09cd83d89f5ba02df18f5a439786ffe6d83c0..e7ab1cb61b2281ed3cf65dc5d5742e4ff1c80be1 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/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c
index 36d2efc13f67ff1e7f81e4a4ab021a29fbad0fd9..eafc6ba37abf3b3fb58a7468445c055932a261bd 100644
--- a/source/libs/planner/src/planLogicCreater.c
+++ b/source/libs/planner/src/planLogicCreater.c
@@ -296,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);
@@ -367,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:
@@ -844,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) {
@@ -884,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 cd3218cf94615649cb96ba157089fb8533dc78a4..3155828f32e62e654847330aeca68b6a3c18c133 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);
@@ -1126,7 +1132,7 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
break;
}
}
- DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys);
+ NODES_DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys);
}
if (TSDB_CODE_SUCCESS == code) {
code = partTagsOptRebuildTbanme(pScan->pPartTags);
diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c
index ff78370c522fc8f17c885a8248091e5baee64601..37765edfc57a54f8d4e9ac02aff93d2eba3eb610 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;
}
@@ -559,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);
@@ -732,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;
}
@@ -914,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);
@@ -1038,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 29119bf1d2ee59582b87246ab52af1a3f31b1ab2..f0e0e84bd9bf88ece3575bf905c05416f26cf0d9 100644
--- a/source/libs/planner/src/planSpliter.c
+++ b/source/libs/planner/src/planSpliter.c
@@ -934,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 f74c7df355ad74b1db1192caf83c60fca7673f79..790c418b17a307a216d7b21735221ceb811e8710 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/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c
index 3e062d395f63e642fe3b3dcb193b56a7ac38ef79..ff3dc56f715fd69b0adc0615f826d4797cee4688 100644
--- a/source/libs/sync/src/syncSnapshot.c
+++ b/source/libs/sync/src/syncSnapshot.c
@@ -533,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
@@ -552,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);
@@ -563,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/test/syncLogStoreCheck2.cpp b/source/libs/sync/test/syncLogStoreCheck2.cpp
index 431b291ca797847a00556f5aeb6d231f48061dc6..80679bc85c4067fef291dcc583b727f1f3e909c3 100644
--- a/source/libs/sync/test/syncLogStoreCheck2.cpp
+++ b/source/libs/sync/test/syncLogStoreCheck2.cpp
@@ -65,7 +65,7 @@ int main(int argc, char** argv) {
SSyncLogStore* pLog = logStoreCreate(pSyncNode);
assert(pLog != NULL);
- logStorePrint2((char*)"==syncLogStoreCheck==", pLog);
+ logStoreSimplePrint2((char*)"==syncLogStoreCheck2==", pLog);
walClose(pWal);
logStoreDestory(pLog);
diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h
index 146b127422345e2989a2c644e60aa2065b7ac8c5..327fe50814505259baaba21ec8c2a16d40ea3f18 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 81099941c691f8992e3a27385b8b38da754a6b48..121939787cc0e9c35adcc357c376e710f6f156bd 100644
--- a/source/libs/transport/inc/transLog.h
+++ b/source/libs/transport/inc/transLog.h
@@ -32,8 +32,13 @@ extern "C" {
#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 tTR(param, ...) do { char buf[40] = {0};TRACE_TO_STR(trace, buf);tTrace("TRID: %s "param, buf, __VA_ARGS__);} while(0)
-#define tGTrace(param, ...) { char buf[40] = {0}; TRACE_TO_STR(trace, buf); tTrace(param ", gtid:%s", __VA_ARGS__, buf);}
+#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)
+
// clang-format on
#ifdef __cplusplus
diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c
index 912c8b59c211413e4ee49ac5074585d734457278..bf03ea26ba8d05226b23e80e8a40d4816e0105f2 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 f9558d7252ceabfd6514f53665baefa60dd2ef23..593a790a2121f12d30e17ee0adb1b5de9c21ffb7 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 b1129b441cacfe32ed7f76fbe62a0bb8cb575acf..9bed6d230bcd227317075c1894462b1d805d270b 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;
}
diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt
index dbfd05146cf687f50d8b33605df8c66c643597d9..1ab64917367f374af31ac11f8646849834b2d457 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
diff --git a/tests/script/tsim/dnode/drop_dnode_has_mnode.sim b/tests/script/tsim/dnode/drop_dnode_has_mnode.sim
index 1dbec2c04d0db3974a55cf7bccb757dc99f35016..16cd2bb3b0a6eb5537c9461611feefa3c2a51b00 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 0000000000000000000000000000000000000000..15ad13b6fa4208d4cac3eca5ad5427328d09ea6b
--- /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 0000000000000000000000000000000000000000..35a246629789a629b86a75ce7702097c174fd832
--- /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 0000000000000000000000000000000000000000..6641ce053ccbf5bdd10984793acd699050207fcd
--- /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 0000000000000000000000000000000000000000..63639877ee6108f1a6f9a337a4eb3b560b70c479
--- /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 0000000000000000000000000000000000000000..91679a7e812bf66201dbb06223cf715c290e4bc6
--- /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/system-test/2-query/json_tag.py b/tests/system-test/2-query/json_tag.py
index 957e916e344d6bb35288521717d39f40ce39360b..052ff923ac33c933343e6476e8ddbe6acc252df8 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 a84d93404a9f082ffa85c50d1eb8c015309308ec..33ef7e65db0fbb3d40730f9cc012fd5d0d7b9d15 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")