other: merge main.
This commit is contained in:
commit
1b9eca5ce0
|
@ -105,6 +105,12 @@ class Consumer:
|
||||||
def poll(self, timeout: float = 1.0):
|
def poll(self, timeout: float = 1.0):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def assignment(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def poll(self, timeout: float = 1.0):
|
||||||
|
pass
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ window_clause: {
|
||||||
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)]
|
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)]
|
||||||
|
|
||||||
interp_clause:
|
interp_clause:
|
||||||
RANGE(ts_val, ts_val) EVERY(every_val) FILL(fill_mod_and_val)
|
RANGE(ts_val [, ts_val]) EVERY(every_val) FILL(fill_mod_and_val)
|
||||||
|
|
||||||
partition_by_clause:
|
partition_by_clause:
|
||||||
PARTITION BY expr [, expr] ...
|
PARTITION BY expr [, expr] ...
|
||||||
|
|
|
@ -889,9 +889,10 @@ ignore_null_values: {
|
||||||
- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
|
- `INTERP` is used to get the value that matches the specified time slice from a column. If no such value exists an interpolation value will be returned based on `FILL` parameter.
|
||||||
- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
|
- The input data of `INTERP` is the value of the specified column and a `where` clause can be used to filter the original data. If no `where` condition is specified then all original data is the input.
|
||||||
- `INTERP` must be used along with `RANGE`, `EVERY`, `FILL` keywords.
|
- `INTERP` must be used along with `RANGE`, `EVERY`, `FILL` keywords.
|
||||||
- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1 <= timestamp2. timestamp1 is the starting point of the output time range and must be specified. timestamp2 is the ending point of the output time range and must be specified.
|
- The output time range of `INTERP` is specified by `RANGE(timestamp1,timestamp2)` parameter, with timestamp1 <= timestamp2. timestamp1 is the starting point of the output time range. timestamp2 is the ending point of the output time range.
|
||||||
- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY(time_unit)`. Starting from timestamp1, one interpolation is performed for every time interval specified `time_unit` parameter. The parameter `time_unit` must be an integer, with no quotes, with a time unit of: a(millisecond)), s(second), m(minute), h(hour), d(day), or w(week). For example, `EVERY(500a)` will interpolate every 500 milliseconds.
|
- The number of rows in the result set of `INTERP` is determined by the parameter `EVERY(time_unit)`. Starting from timestamp1, one interpolation is performed for every time interval specified `time_unit` parameter. The parameter `time_unit` must be an integer, with no quotes, with a time unit of: a(millisecond)), s(second), m(minute), h(hour), d(day), or w(week). For example, `EVERY(500a)` will interpolate every 500 milliseconds.
|
||||||
- Interpolation is performed based on `FILL` parameter. For more information about FILL clause, see [FILL Clause](../distinguished/#fill-clause).
|
- Interpolation is performed based on `FILL` parameter. For more information about FILL clause, see [FILL Clause](../distinguished/#fill-clause).
|
||||||
|
- When only one timestamp value is specified in `RANGE` clause, `INTERP` is used to generate interpolation at this point in time. In this case, `EVERY` clause can be omitted. For example, SELECT INTERP(col) FROM tb RANGE('2023-01-01 00:00:00') FILL(linear).
|
||||||
- `INTERP` can be applied to supertable by interpolating primary key sorted data of all its childtables. It can also be used with `partition by tbname` when applied to supertable to generate interpolation on each single timeline.
|
- `INTERP` can be applied to supertable by interpolating primary key sorted data of all its childtables. It can also be used with `partition by tbname` when applied to supertable to generate interpolation on each single timeline.
|
||||||
- Pseudocolumn `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.2.0).
|
- Pseudocolumn `_irowts` can be used along with `INTERP` to return the timestamps associated with interpolation points(support after version 3.0.2.0).
|
||||||
- Pseudocolumn `_isfilled` can be used along with `INTERP` to indicate whether the results are original records or data points generated by interpolation algorithm(support after version 3.0.3.0).
|
- Pseudocolumn `_isfilled` can be used along with `INTERP` to indicate whether the results are original records or data points generated by interpolation algorithm(support after version 3.0.3.0).
|
||||||
|
@ -902,7 +903,7 @@ ignore_null_values: {
|
||||||
- We want to downsample every 1 hour and use a linear fill for missing values. Note the order in which the "partition by" clause and the "range", "every" and "fill" parameters are used.
|
- We want to downsample every 1 hour and use a linear fill for missing values. Note the order in which the "partition by" clause and the "range", "every" and "fill" parameters are used.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT _irowts,INTERP(current) FROM test.meters PARTITION BY TBNAME RANGE('2017-07-22 00:00:00','2017-07-24 12:25:00') EVERY(1h) FILL(LINEAR)
|
SELECT _irowts,INTERP(current) FROM test.meters PARTITION BY TBNAME RANGE('2017-07-22 00:00:00','2017-07-24 12:25:00') EVERY(1h) FILL(LINEAR)
|
||||||
```
|
```
|
||||||
|
|
||||||
### LAST
|
### LAST
|
||||||
|
|
|
@ -453,6 +453,170 @@ As the way to connect introduced above but add `req_id` argument.
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### Subscription
|
||||||
|
|
||||||
|
Connector support data subscription. For more information about subscroption, please refer to [Data Subscription](../../../develop/tmq/).
|
||||||
|
|
||||||
|
<Tabs defaultValue="native">
|
||||||
|
<TabItem value="native" label="native connection">
|
||||||
|
|
||||||
|
The `consumer` in the connector contains the subscription api.
|
||||||
|
|
||||||
|
#### Create Consumer
|
||||||
|
|
||||||
|
The syntax for creating a consumer is `consumer = Consumer(configs)`. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/).
|
||||||
|
|
||||||
|
```python
|
||||||
|
from taos.tmq import Consumer
|
||||||
|
|
||||||
|
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Subscribe topics
|
||||||
|
|
||||||
|
The `subscribe` function is used to subscribe to a list of topics.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Consume
|
||||||
|
|
||||||
|
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(1)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
val = res.value()
|
||||||
|
|
||||||
|
for block in val:
|
||||||
|
print(block.fetchall())
|
||||||
|
```
|
||||||
|
|
||||||
|
#### assignment
|
||||||
|
|
||||||
|
The `assignment` function is used to get the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Seek
|
||||||
|
|
||||||
|
The `seek` function is used to reset the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||||
|
consumer.seek(tp)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### After consuming data
|
||||||
|
|
||||||
|
You should unsubscribe to the topics and close the consumer after consuming.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Tmq subscription example
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### assignment and seek example
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem value="websocket" label="WebSocket connection">
|
||||||
|
|
||||||
|
In addition to native connections, the connector also supports subscriptions via websockets.
|
||||||
|
|
||||||
|
#### Create Consumer
|
||||||
|
|
||||||
|
The syntax for creating a consumer is "consumer = consumer = Consumer(conf=configs)". You need to specify that the `td.connect.websocket.scheme` parameter is set to "ws" in the configuration. For more subscription api parameters, please refer to [Data Subscription](../../../develop/tmq/#create-a-consumer).
|
||||||
|
|
||||||
|
```python
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### subscribe topics
|
||||||
|
|
||||||
|
The `subscribe` function is used to subscribe to a list of topics.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Consume
|
||||||
|
|
||||||
|
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(timeout=1.0)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
for block in message:
|
||||||
|
for row in block:
|
||||||
|
print(row)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### assignment
|
||||||
|
|
||||||
|
The `assignment` function is used to get the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Seek
|
||||||
|
|
||||||
|
The `seek` function is used to reset the assignment of the topic.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### After consuming data
|
||||||
|
|
||||||
|
You should unsubscribe to the topics and close the consumer after consuming.
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Subscription example
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Assignment and seek example
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
### Schemaless Insert
|
### Schemaless Insert
|
||||||
|
|
||||||
Connector support schemaless insert.
|
Connector support schemaless insert.
|
||||||
|
@ -507,7 +671,8 @@ Insert with req_id argument
|
||||||
|
|
||||||
| Example program links | Example program content |
|
| Example program links | Example program content |
|
||||||
| ------------------------------------------------------------------------------------------------------------- | ------------------- ---- |
|
| ------------------------------------------------------------------------------------------------------------- | ------------------- ---- |
|
||||||
| [bind_multi.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-multi.py) | parameter binding, bind multiple rows at once |
|
| [bind_multi.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-multi.py) | parameter binding,
|
||||||
|
bind multiple rows at once |
|
||||||
| [bind_row.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-row.py) | bind_row.py
|
| [bind_row.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-row.py) | bind_row.py
|
||||||
| [insert_lines.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/insert-lines.py) | InfluxDB line protocol writing |
|
| [insert_lines.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/insert-lines.py) | InfluxDB line protocol writing |
|
||||||
| [json_tag.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/json-tag.py) | Use JSON type tags |
|
| [json_tag.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/json-tag.py) | Use JSON type tags |
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import taos
|
||||||
|
from taos.tmq import Consumer
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
|
||||||
|
def prepare():
|
||||||
|
conn = taos.connect()
|
||||||
|
conn.execute("drop topic if exists tmq_assignment_demo_topic")
|
||||||
|
conn.execute("drop database if exists tmq_assignment_demo_db")
|
||||||
|
conn.execute("create database if not exists tmq_assignment_demo_db wal_retention_period 3600")
|
||||||
|
conn.select_db("tmq_assignment_demo_db")
|
||||||
|
conn.execute(
|
||||||
|
"create table if not exists tmq_assignment_demo_table (ts timestamp, c1 int, c2 float, c3 binary(10)) tags(t1 int)")
|
||||||
|
conn.execute(
|
||||||
|
"create topic if not exists tmq_assignment_demo_topic as select ts, c1, c2, c3 from tmq_assignment_demo_table")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now-2s, 1, 1.0, 'tmq test')")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now-1s, 2, 2.0, 'tmq test')")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now, 3, 3.0, 'tmq test')")
|
||||||
|
|
||||||
|
|
||||||
|
def taos_get_assignment_and_seek_demo():
|
||||||
|
prepare()
|
||||||
|
consumer = Consumer(
|
||||||
|
{
|
||||||
|
"group.id": "0",
|
||||||
|
# should disable snapshot,
|
||||||
|
# otherwise it will cause invalid params error
|
||||||
|
"experimental.snapshot.enable": "false",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
consumer.subscribe(["tmq_assignment_demo_topic"])
|
||||||
|
|
||||||
|
# get topic assignment
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
for assignment in assignments:
|
||||||
|
print(assignment)
|
||||||
|
|
||||||
|
# poll
|
||||||
|
consumer.poll(1)
|
||||||
|
consumer.poll(1)
|
||||||
|
|
||||||
|
# get topic assignment again
|
||||||
|
after_pool_assignments = consumer.assignment()
|
||||||
|
for assignment in after_pool_assignments:
|
||||||
|
print(assignment)
|
||||||
|
|
||||||
|
# seek to the beginning
|
||||||
|
for assignment in assignments:
|
||||||
|
consumer.seek(assignment)
|
||||||
|
|
||||||
|
# now the assignment should be the same as before poll
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
for assignment in assignments:
|
||||||
|
print(assignment)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
taosws_get_assignment_and_seek_demo()
|
|
@ -0,0 +1,57 @@
|
||||||
|
import taos
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
|
||||||
|
def prepare():
|
||||||
|
conn = taos.connect()
|
||||||
|
conn.execute("drop topic if exists tmq_assignment_demo_topic")
|
||||||
|
conn.execute("drop database if exists tmq_assignment_demo_db")
|
||||||
|
conn.execute("create database if not exists tmq_assignment_demo_db wal_retention_period 3600")
|
||||||
|
conn.select_db("tmq_assignment_demo_db")
|
||||||
|
conn.execute(
|
||||||
|
"create table if not exists tmq_assignment_demo_table (ts timestamp, c1 int, c2 float, c3 binary(10)) tags(t1 int)")
|
||||||
|
conn.execute(
|
||||||
|
"create topic if not exists tmq_assignment_demo_topic as select ts, c1, c2, c3 from tmq_assignment_demo_table")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now-2s, 1, 1.0, 'tmq test')")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now-1s, 2, 2.0, 'tmq test')")
|
||||||
|
conn.execute("insert into d0 using tmq_assignment_demo_table tags (0) values (now, 3, 3.0, 'tmq test')")
|
||||||
|
|
||||||
|
|
||||||
|
def taosws_get_assignment_and_seek_demo():
|
||||||
|
prepare()
|
||||||
|
consumer = taosws.Consumer(conf={
|
||||||
|
"td.connect.websocket.scheme": "ws",
|
||||||
|
# should disable snapshot,
|
||||||
|
# otherwise it will cause invalid params error
|
||||||
|
"experimental.snapshot.enable": "false",
|
||||||
|
"group.id": "0",
|
||||||
|
})
|
||||||
|
consumer.subscribe(["tmq_assignment_demo_topic"])
|
||||||
|
|
||||||
|
# get topic assignment
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
for assignment in assignments:
|
||||||
|
print(assignment.to_string())
|
||||||
|
|
||||||
|
# poll
|
||||||
|
consumer.poll(1)
|
||||||
|
consumer.poll(1)
|
||||||
|
|
||||||
|
# get topic assignment again
|
||||||
|
after_poll_assignments = consumer.assignment()
|
||||||
|
for assignment in after_poll_assignments:
|
||||||
|
print(assignment.to_string())
|
||||||
|
|
||||||
|
# seek to the beginning
|
||||||
|
for assignment in assignments:
|
||||||
|
for a in assignment.assignments():
|
||||||
|
consumer.seek(assignment.topic(), a.vg_id(), a.offset())
|
||||||
|
|
||||||
|
# now the assignment should be the same as before poll
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
for assignment in assignments:
|
||||||
|
print(assignment.to_string())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
taosws_get_assignment_and_seek_demo()
|
|
@ -105,6 +105,12 @@ class Consumer:
|
||||||
def poll(self, timeout: float = 1.0):
|
def poll(self, timeout: float = 1.0):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def assignment(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def seek(self, partition):
|
||||||
|
pass
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -456,27 +456,169 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线
|
||||||
|
|
||||||
### 数据订阅
|
### 数据订阅
|
||||||
|
|
||||||
连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅](../../develop/tmq/)。
|
连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅文档](../../develop/tmq/)。
|
||||||
|
|
||||||
<Tabs defaultValue="native">
|
<Tabs defaultValue="native">
|
||||||
<TabItem value="native" label="原生连接">
|
<TabItem value="native" label="原生连接">
|
||||||
|
|
||||||
`Consumer` 提供了 Python 连接器订阅 TMQ 数据的 API,相关 API 定义请参考 [数据订阅文档](../../develop/tmq/#%E4%B8%BB%E8%A6%81%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C-api)。
|
`Consumer` 提供了 Python 连接器订阅 TMQ 数据的 API。
|
||||||
|
|
||||||
|
#### 创建 Consumer
|
||||||
|
|
||||||
|
创建 Consumer 语法为 `consumer = Consumer(configs)`,参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
||||||
|
|
||||||
|
```python
|
||||||
|
from taos.tmq import Consumer
|
||||||
|
|
||||||
|
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 订阅 topics
|
||||||
|
|
||||||
|
Comsumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 消费数据
|
||||||
|
|
||||||
|
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(1)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
val = res.value()
|
||||||
|
|
||||||
|
for block in val:
|
||||||
|
print(block.fetchall())
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获取消费进度
|
||||||
|
|
||||||
|
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 重置消费进度
|
||||||
|
|
||||||
|
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置,方法参数类型为 TopicPartition。
|
||||||
|
|
||||||
|
```python
|
||||||
|
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||||
|
consumer.seek(tp)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 结束消费
|
||||||
|
|
||||||
|
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### tmq 订阅示例代码
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{{#include docs/examples/python/tmq_example.py}}
|
{{#include docs/examples/python/tmq_example.py}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 获取和重置消费进度示例代码
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
<TabItem value="websocket" label="WebSocket 连接">
|
<TabItem value="websocket" label="WebSocket 连接">
|
||||||
|
|
||||||
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据。
|
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据,使用 websocket 方式订阅 TMQ 数据需要安装 `taos-ws-py`。
|
||||||
|
|
||||||
|
taosws `Consumer` API 提供了基于 Websocket 订阅 TMQ 数据的 API。
|
||||||
|
|
||||||
|
#### 创建 Consumer
|
||||||
|
|
||||||
|
创建 Consumer 语法为 `consumer = Consumer(conf=configs)`,使用时需要指定 `td.connect.websocket.scheme` 参数值为 "ws",参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
||||||
|
|
||||||
|
```python
|
||||||
|
import taosws
|
||||||
|
|
||||||
|
consumer = taosws.(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 订阅 topics
|
||||||
|
|
||||||
|
Comsumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.subscribe(['topic1', 'topic2'])
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 消费数据
|
||||||
|
|
||||||
|
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
||||||
|
|
||||||
|
```python
|
||||||
|
while True:
|
||||||
|
res = consumer.poll(timeout=1.0)
|
||||||
|
if not res:
|
||||||
|
continue
|
||||||
|
err = res.error()
|
||||||
|
if err is not None:
|
||||||
|
raise err
|
||||||
|
for block in message:
|
||||||
|
for row in block:
|
||||||
|
print(row)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获取消费进度
|
||||||
|
|
||||||
|
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||||
|
|
||||||
|
```python
|
||||||
|
assignments = consumer.assignment()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 重置消费进度
|
||||||
|
|
||||||
|
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 结束消费
|
||||||
|
|
||||||
|
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||||
|
|
||||||
|
```python
|
||||||
|
consumer.unsubscribe()
|
||||||
|
consumer.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### tmq 订阅示例代码
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
连接器提供了 `assignment` 接口,用于获取 topic assignment 的功能,可以查询订阅的 topic 的消费进度,并提供 `seek` 接口,用于重置 topic 的消费进度。
|
||||||
|
|
||||||
|
#### 获取和重置消费进度示例代码
|
||||||
|
|
||||||
|
```python
|
||||||
|
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||||
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ window_clause: {
|
||||||
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)]
|
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [FILL(fill_mod_and_val)]
|
||||||
|
|
||||||
interp_clause:
|
interp_clause:
|
||||||
RANGE(ts_val, ts_val) EVERY(every_val) FILL(fill_mod_and_val)
|
RANGE(ts_val [, ts_val]) EVERY(every_val) FILL(fill_mod_and_val)
|
||||||
|
|
||||||
partition_by_clause:
|
partition_by_clause:
|
||||||
PARTITION BY expr [, expr] ...
|
PARTITION BY expr [, expr] ...
|
||||||
|
|
|
@ -890,9 +890,10 @@ ignore_null_values: {
|
||||||
- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
|
- INTERP 用于在指定时间断面获取指定列的记录值,如果该时间断面不存在符合条件的行数据,那么会根据 FILL 参数的设定进行插值。
|
||||||
- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
|
- INTERP 的输入数据为指定列的数据,可以通过条件语句(where 子句)来对原始列数据进行过滤,如果没有指定过滤条件则输入为全部数据。
|
||||||
- INTERP 需要同时与 RANGE,EVERY 和 FILL 关键字一起使用。
|
- INTERP 需要同时与 RANGE,EVERY 和 FILL 关键字一起使用。
|
||||||
- INTERP 的输出时间范围根据 RANGE(timestamp1,timestamp2)字段来指定,需满足 timestamp1 <= timestamp2。其中 timestamp1(必选值)为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2(必选值)为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
- INTERP 的输出时间范围根据 RANGE(timestamp1, timestamp2)字段来指定,需满足 timestamp1 <= timestamp2。其中 timestamp1 为输出时间范围的起始值,即如果 timestamp1 时刻符合插值条件则 timestamp1 为输出的第一条记录,timestamp2 为输出时间范围的结束值,即输出的最后一条记录的 timestamp 不能大于 timestamp2。
|
||||||
- INTERP 根据 EVERY(time_unit) 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(time_unit 值)进行插值,time_unit 可取值时间单位:1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。例如 EVERY(500a) 将对于指定数据每500毫秒间隔进行一次插值.
|
- INTERP 根据 EVERY(time_unit) 字段来确定输出时间范围内的结果条数,即从 timestamp1 开始每隔固定长度的时间(time_unit 值)进行插值,time_unit 可取值时间单位:1a(毫秒),1s(秒),1m(分),1h(小时),1d(天),1w(周)。例如 EVERY(500a) 将对于指定数据每500毫秒间隔进行一次插值.
|
||||||
- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。关于 FILL 子句如何使用请参考 [FILL 子句](../distinguished/#fill-子句)
|
- INTERP 根据 FILL 字段来决定在每个符合输出条件的时刻如何进行插值。关于 FILL 子句如何使用请参考 [FILL 子句](../distinguished/#fill-子句)
|
||||||
|
- INTERP 可以在 RANGE 字段中只指定唯一的时间戳对单个时间点进行插值,在这种情况下,EVERY 字段可以省略。例如:SELECT INTERP(col) FROM tb RANGE('2023-01-01 00:00:00') FILL(linear).
|
||||||
- INTERP 作用于超级表时, 会将该超级表下的所有子表数据按照主键列排序后进行插值计算,也可以搭配 PARTITION BY tbname 使用,将结果强制规约到单个时间线。
|
- INTERP 作用于超级表时, 会将该超级表下的所有子表数据按照主键列排序后进行插值计算,也可以搭配 PARTITION BY tbname 使用,将结果强制规约到单个时间线。
|
||||||
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.2.0版本以后支持)。
|
- INTERP 可以与伪列 _irowts 一起使用,返回插值点所对应的时间戳(3.0.2.0版本以后支持)。
|
||||||
- INTERP 可以与伪列 _isfilled 一起使用,显示返回结果是否为原始记录或插值算法产生的数据(3.0.3.0版本以后支持)。
|
- INTERP 可以与伪列 _isfilled 一起使用,显示返回结果是否为原始记录或插值算法产生的数据(3.0.3.0版本以后支持)。
|
||||||
|
|
|
@ -248,6 +248,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pData
|
||||||
tb_uid_t suid);
|
tb_uid_t suid);
|
||||||
|
|
||||||
char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId);
|
char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId);
|
||||||
|
int32_t buildCtbNameByGroupIdImpl(const char* stbName, uint64_t groupId, char* pBuf);
|
||||||
|
|
||||||
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
||||||
return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock);
|
return blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock)) + blockDataGetSize(pBlock);
|
||||||
|
|
|
@ -1975,6 +1975,7 @@ typedef struct {
|
||||||
SArray* fillNullCols; // array of SColLocation
|
SArray* fillNullCols; // array of SColLocation
|
||||||
int64_t deleteMark;
|
int64_t deleteMark;
|
||||||
int8_t igUpdate;
|
int8_t igUpdate;
|
||||||
|
int64_t lastTs;
|
||||||
} SCMCreateStreamReq;
|
} SCMCreateStreamReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2033,6 +2034,11 @@ typedef struct {
|
||||||
char cgroup[TSDB_CGROUP_LEN];
|
char cgroup[TSDB_CGROUP_LEN];
|
||||||
char clientId[256];
|
char clientId[256];
|
||||||
SArray* topicNames; // SArray<char**>
|
SArray* topicNames; // SArray<char**>
|
||||||
|
|
||||||
|
int8_t withTbName;
|
||||||
|
int8_t autoCommit;
|
||||||
|
int32_t autoCommitInterval;
|
||||||
|
int8_t resetOffsetCfg;
|
||||||
} SCMSubscribeReq;
|
} SCMSubscribeReq;
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tSerializeSCMSubscribeReq(void** buf, const SCMSubscribeReq* pReq) {
|
static FORCE_INLINE int32_t tSerializeSCMSubscribeReq(void** buf, const SCMSubscribeReq* pReq) {
|
||||||
|
@ -2047,6 +2053,12 @@ static FORCE_INLINE int32_t tSerializeSCMSubscribeReq(void** buf, const SCMSubsc
|
||||||
for (int32_t i = 0; i < topicNum; i++) {
|
for (int32_t i = 0; i < topicNum; i++) {
|
||||||
tlen += taosEncodeString(buf, (char*)taosArrayGetP(pReq->topicNames, i));
|
tlen += taosEncodeString(buf, (char*)taosArrayGetP(pReq->topicNames, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlen += taosEncodeFixedI8(buf, pReq->withTbName);
|
||||||
|
tlen += taosEncodeFixedI8(buf, pReq->autoCommit);
|
||||||
|
tlen += taosEncodeFixedI32(buf, pReq->autoCommitInterval);
|
||||||
|
tlen += taosEncodeFixedI8(buf, pReq->resetOffsetCfg);
|
||||||
|
|
||||||
return tlen;
|
return tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2064,6 +2076,11 @@ static FORCE_INLINE void* tDeserializeSCMSubscribeReq(void* buf, SCMSubscribeReq
|
||||||
buf = taosDecodeString(buf, &name);
|
buf = taosDecodeString(buf, &name);
|
||||||
taosArrayPush(pReq->topicNames, &name);
|
taosArrayPush(pReq->topicNames, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = taosDecodeFixedI8(buf, &pReq->withTbName);
|
||||||
|
buf = taosDecodeFixedI8(buf, &pReq->autoCommit);
|
||||||
|
buf = taosDecodeFixedI32(buf, &pReq->autoCommitInterval);
|
||||||
|
buf = taosDecodeFixedI8(buf, &pReq->resetOffsetCfg);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2455,15 +2472,6 @@ typedef struct {
|
||||||
char cgroup[TSDB_CGROUP_LEN];
|
char cgroup[TSDB_CGROUP_LEN];
|
||||||
} SMqAskEpReq;
|
} SMqAskEpReq;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int64_t consumerId;
|
|
||||||
int32_t epoch;
|
|
||||||
} SMqHbReq;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int8_t reserved;
|
|
||||||
} SMqHbRsp;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t key;
|
int32_t key;
|
||||||
int32_t valueLen;
|
int32_t valueLen;
|
||||||
|
@ -2487,6 +2495,7 @@ typedef struct {
|
||||||
int64_t stime; // timestamp precision ms
|
int64_t stime; // timestamp precision ms
|
||||||
int64_t reqRid;
|
int64_t reqRid;
|
||||||
bool stableQuery;
|
bool stableQuery;
|
||||||
|
bool isSubQuery;
|
||||||
char fqdn[TSDB_FQDN_LEN];
|
char fqdn[TSDB_FQDN_LEN];
|
||||||
int32_t subPlanNum;
|
int32_t subPlanNum;
|
||||||
SArray* subDesc; // SArray<SQuerySubDesc>
|
SArray* subDesc; // SArray<SQuerySubDesc>
|
||||||
|
@ -2891,7 +2900,7 @@ int32_t tDecodeSMqCMCommitOffsetReq(SDecoder* decoder, SMqCMCommitOffsetReq* pRe
|
||||||
// tqOffset
|
// tqOffset
|
||||||
enum {
|
enum {
|
||||||
TMQ_OFFSET__RESET_NONE = -3,
|
TMQ_OFFSET__RESET_NONE = -3,
|
||||||
TMQ_OFFSET__RESET_EARLIEAST = -2,
|
TMQ_OFFSET__RESET_EARLIEST = -2,
|
||||||
TMQ_OFFSET__RESET_LATEST = -1,
|
TMQ_OFFSET__RESET_LATEST = -1,
|
||||||
TMQ_OFFSET__LOG = 1,
|
TMQ_OFFSET__LOG = 1,
|
||||||
TMQ_OFFSET__SNAPSHOT_DATA = 2,
|
TMQ_OFFSET__SNAPSHOT_DATA = 2,
|
||||||
|
@ -3354,6 +3363,28 @@ static FORCE_INLINE void tDeleteSMqAskEpRsp(SMqAskEpRsp* pRsp) {
|
||||||
taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteMqSubTopicEp);
|
taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteMqSubTopicEp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t vgId;
|
||||||
|
STqOffsetVal offset;
|
||||||
|
int64_t rows;
|
||||||
|
}OffsetRows;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||||
|
SArray* offsetRows;
|
||||||
|
}TopicOffsetRows;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t consumerId;
|
||||||
|
int32_t epoch;
|
||||||
|
SArray* topics;
|
||||||
|
} SMqHbReq;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int8_t reserved;
|
||||||
|
} SMqHbRsp;
|
||||||
|
|
||||||
|
|
||||||
#define TD_AUTO_CREATE_TABLE 0x1
|
#define TD_AUTO_CREATE_TABLE 0x1
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t suid;
|
int64_t suid;
|
||||||
|
@ -3478,10 +3509,8 @@ int32_t tSerializeSMqAskEpReq(void* buf, int32_t bufLen, SMqAskEpReq* pReq);
|
||||||
int32_t tDeserializeSMqAskEpReq(void* buf, int32_t bufLen, SMqAskEpReq* pReq);
|
int32_t tDeserializeSMqAskEpReq(void* buf, int32_t bufLen, SMqAskEpReq* pReq);
|
||||||
int32_t tSerializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
int32_t tSerializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
||||||
int32_t tDeserializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
int32_t tDeserializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
||||||
int32_t tSerializeSMqAskEpReq(void* buf, int32_t bufLen, SMqAskEpReq* pReq);
|
int32_t tDeatroySMqHbReq(SMqHbReq* pReq);
|
||||||
int32_t tDeserializeSMqAskEpReq(void* buf, int32_t bufLen, SMqAskEpReq* pReq);
|
|
||||||
int32_t tSerializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
|
||||||
int32_t tDeserializeSMqHbReq(void* buf, int32_t bufLen, SMqHbReq* pReq);
|
|
||||||
|
|
||||||
#define SUBMIT_REQ_AUTO_CREATE_TABLE 0x1
|
#define SUBMIT_REQ_AUTO_CREATE_TABLE 0x1
|
||||||
#define SUBMIT_REQ_COLUMN_DATA_FORMAT 0x2
|
#define SUBMIT_REQ_COLUMN_DATA_FORMAT 0x2
|
||||||
|
|
|
@ -150,7 +150,7 @@ enum {
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_HB, "consumer-hb", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_HB, "consumer-hb", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DO_REBALANCE, "do-rebalance", SMqDoRebalanceMsg, NULL)
|
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DO_REBALANCE, "do-rebalance", SMqDoRebalanceMsg, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DROP_CGROUP, "drop-cgroup", SMqDropCGroupReq, SMqDropCGroupRsp)
|
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_DROP_CGROUP, "drop-cgroup", SMqDropCGroupReq, SMqDropCGroupRsp)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_UNUSED2, "unused2", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_MND_CREATE_VG, "create-vg", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_TIMER, "tmq-tmr", SMTimerReq, NULL)
|
TD_DEF_MSG_TYPE(TDMT_MND_TMQ_TIMER, "tmq-tmr", SMTimerReq, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TELEM_TIMER, "telem-tmr", SMTimerReq, SMTimerReq)
|
TD_DEF_MSG_TYPE(TDMT_MND_TELEM_TIMER, "telem-tmr", SMTimerReq, SMTimerReq)
|
||||||
TD_DEF_MSG_TYPE(TDMT_MND_TRANS_TIMER, "trans-tmr", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_MND_TRANS_TIMER, "trans-tmr", NULL, NULL)
|
||||||
|
|
|
@ -87,6 +87,7 @@ typedef struct SCatalogReq {
|
||||||
bool dNodeRequired; // valid dnode
|
bool dNodeRequired; // valid dnode
|
||||||
bool svrVerRequired;
|
bool svrVerRequired;
|
||||||
bool forceUpdate;
|
bool forceUpdate;
|
||||||
|
bool cloned;
|
||||||
} SCatalogReq;
|
} SCatalogReq;
|
||||||
|
|
||||||
typedef struct SMetaRes {
|
typedef struct SMetaRes {
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
#ifndef TDENGINE_STORAGEAPI_H
|
#ifndef TDENGINE_STORAGEAPI_H
|
||||||
#define TDENGINE_STORAGEAPI_H
|
#define TDENGINE_STORAGEAPI_H
|
||||||
|
|
||||||
#include "tsimplehash.h"
|
|
||||||
#include "tscalablebf.h"
|
|
||||||
#include "taosdef.h"
|
|
||||||
#include "tmsg.h"
|
|
||||||
#include "tcommon.h"
|
|
||||||
#include "index.h"
|
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "index.h"
|
||||||
|
#include "taosdef.h"
|
||||||
|
#include "tcommon.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
#include "tscalablebf.h"
|
||||||
|
#include "tsimplehash.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -46,7 +46,7 @@ typedef struct SMetaEntry {
|
||||||
int8_t type;
|
int8_t type;
|
||||||
int8_t flags; // TODO: need refactor?
|
int8_t flags; // TODO: need refactor?
|
||||||
tb_uid_t uid;
|
tb_uid_t uid;
|
||||||
char * name;
|
char* name;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
SSchemaWrapper schemaRow;
|
SSchemaWrapper schemaRow;
|
||||||
|
@ -57,43 +57,45 @@ typedef struct SMetaEntry {
|
||||||
int64_t ctime;
|
int64_t ctime;
|
||||||
int32_t ttlDays;
|
int32_t ttlDays;
|
||||||
int32_t commentLen;
|
int32_t commentLen;
|
||||||
char * comment;
|
char* comment;
|
||||||
tb_uid_t suid;
|
tb_uid_t suid;
|
||||||
uint8_t *pTags;
|
uint8_t* pTags;
|
||||||
} ctbEntry;
|
} ctbEntry;
|
||||||
struct {
|
struct {
|
||||||
int64_t ctime;
|
int64_t ctime;
|
||||||
int32_t ttlDays;
|
int32_t ttlDays;
|
||||||
int32_t commentLen;
|
int32_t commentLen;
|
||||||
char * comment;
|
char* comment;
|
||||||
int32_t ncid; // next column id
|
int32_t ncid; // next column id
|
||||||
SSchemaWrapper schemaRow;
|
SSchemaWrapper schemaRow;
|
||||||
} ntbEntry;
|
} ntbEntry;
|
||||||
struct {
|
struct {
|
||||||
STSma *tsma;
|
STSma* tsma;
|
||||||
} smaEntry;
|
} smaEntry;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t *pBuf;
|
uint8_t* pBuf;
|
||||||
} SMetaEntry;
|
} SMetaEntry;
|
||||||
|
|
||||||
typedef struct SMetaReader {
|
typedef struct SMetaReader {
|
||||||
int32_t flags;
|
int32_t flags;
|
||||||
void * pMeta;
|
void* pMeta;
|
||||||
SDecoder coder;
|
SDecoder coder;
|
||||||
SMetaEntry me;
|
SMetaEntry me;
|
||||||
void * pBuf;
|
void* pBuf;
|
||||||
int32_t szBuf;
|
int32_t szBuf;
|
||||||
struct SStoreMeta* pAPI;
|
struct SStoreMeta* pAPI;
|
||||||
} SMetaReader;
|
} SMetaReader;
|
||||||
|
|
||||||
typedef struct SMTbCursor {
|
typedef struct SMTbCursor {
|
||||||
void * pDbc;
|
void* pMeta;
|
||||||
void * pKey;
|
void* pDbc;
|
||||||
void * pVal;
|
void* pKey;
|
||||||
|
void* pVal;
|
||||||
int32_t kLen;
|
int32_t kLen;
|
||||||
int32_t vLen;
|
int32_t vLen;
|
||||||
SMetaReader mr;
|
SMetaReader mr;
|
||||||
|
int8_t paused;
|
||||||
} SMTbCursor;
|
} SMTbCursor;
|
||||||
|
|
||||||
typedef struct SRowBuffPos {
|
typedef struct SRowBuffPos {
|
||||||
|
@ -107,22 +109,22 @@ typedef struct SRowBuffPos {
|
||||||
typedef struct SMetaTableInfo {
|
typedef struct SMetaTableInfo {
|
||||||
int64_t suid;
|
int64_t suid;
|
||||||
int64_t uid;
|
int64_t uid;
|
||||||
SSchemaWrapper *schema;
|
SSchemaWrapper* schema;
|
||||||
char tbName[TSDB_TABLE_NAME_LEN];
|
char tbName[TSDB_TABLE_NAME_LEN];
|
||||||
} SMetaTableInfo;
|
} SMetaTableInfo;
|
||||||
|
|
||||||
typedef struct SSnapContext {
|
typedef struct SSnapContext {
|
||||||
SMeta * pMeta; // todo remove it
|
SMeta* pMeta; // todo remove it
|
||||||
int64_t snapVersion;
|
int64_t snapVersion;
|
||||||
void * pCur;
|
void* pCur;
|
||||||
int64_t suid;
|
int64_t suid;
|
||||||
int8_t subType;
|
int8_t subType;
|
||||||
SHashObj * idVersion;
|
SHashObj* idVersion;
|
||||||
SHashObj * suidInfo;
|
SHashObj* suidInfo;
|
||||||
SArray * idList;
|
SArray* idList;
|
||||||
int32_t index;
|
int32_t index;
|
||||||
bool withMeta;
|
bool withMeta;
|
||||||
bool queryMeta; // true-get meta, false-get data
|
bool queryMeta; // true-get meta, false-get data
|
||||||
} SSnapContext;
|
} SSnapContext;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -139,10 +141,9 @@ typedef struct {
|
||||||
// int32_t tqReaderSeek(STqReader *pReader, int64_t ver, const char *id);
|
// int32_t tqReaderSeek(STqReader *pReader, int64_t ver, const char *id);
|
||||||
// bool tqNextBlockInWal(STqReader* pReader, const char* idstr);
|
// bool tqNextBlockInWal(STqReader* pReader, const char* idstr);
|
||||||
// bool tqNextBlockImpl(STqReader *pReader, const char* idstr);
|
// bool tqNextBlockImpl(STqReader *pReader, const char* idstr);
|
||||||
// int32_t getTableInfoFromSnapshot(SSnapContext *ctx, void **pBuf, int32_t *contLen, int16_t *type, int64_t *uid);
|
// int32_t getTableInfoFromSnapshot(SSnapContext *ctx, void **pBuf, int32_t *contLen, int16_t *type, int64_t
|
||||||
// SMetaTableInfo getMetaTableInfoFromSnapshot(SSnapContext *ctx);
|
// *uid); SMetaTableInfo getMetaTableInfoFromSnapshot(SSnapContext *ctx); int32_t setForSnapShot(SSnapContext
|
||||||
// int32_t setForSnapShot(SSnapContext *ctx, int64_t uid);
|
// *ctx, int64_t uid); int32_t destroySnapContext(SSnapContext *ctx);
|
||||||
// int32_t destroySnapContext(SSnapContext *ctx);
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
/*-------------------------------------------------new api format---------------------------------------------------*/
|
/*-------------------------------------------------new api format---------------------------------------------------*/
|
||||||
|
@ -219,16 +220,16 @@ typedef struct SStoreTqReader {
|
||||||
bool (*tqReaderIsQueriedTable)();
|
bool (*tqReaderIsQueriedTable)();
|
||||||
bool (*tqReaderCurrentBlockConsumed)();
|
bool (*tqReaderCurrentBlockConsumed)();
|
||||||
|
|
||||||
struct SWalReader *(*tqReaderGetWalReader)(); // todo remove it
|
struct SWalReader* (*tqReaderGetWalReader)(); // todo remove it
|
||||||
int32_t (*tqReaderRetrieveTaosXBlock)(); // todo remove it
|
int32_t (*tqReaderRetrieveTaosXBlock)(); // todo remove it
|
||||||
|
|
||||||
int32_t (*tqReaderSetSubmitMsg)(); // todo remove it
|
int32_t (*tqReaderSetSubmitMsg)(); // todo remove it
|
||||||
bool (*tqReaderNextBlockFilterOut)();
|
bool (*tqReaderNextBlockFilterOut)();
|
||||||
} SStoreTqReader;
|
} SStoreTqReader;
|
||||||
|
|
||||||
typedef struct SStoreSnapshotFn {
|
typedef struct SStoreSnapshotFn {
|
||||||
int32_t (*createSnapshot)(SSnapContext *ctx, int64_t uid);
|
int32_t (*createSnapshot)(SSnapContext* ctx, int64_t uid);
|
||||||
int32_t (*destroySnapshot)(SSnapContext *ctx);
|
int32_t (*destroySnapshot)(SSnapContext* ctx);
|
||||||
SMetaTableInfo (*getMetaTableInfoFromSnapshot)(SSnapContext* ctx);
|
SMetaTableInfo (*getMetaTableInfoFromSnapshot)(SSnapContext* ctx);
|
||||||
int32_t (*getTableInfoFromSnapshot)(SSnapContext* ctx, void** pBuf, int32_t* contLen, int16_t* type, int64_t* uid);
|
int32_t (*getTableInfoFromSnapshot)(SSnapContext* ctx, void** pBuf, int32_t* contLen, int16_t* type, int64_t* uid);
|
||||||
} SStoreSnapshotFn;
|
} SStoreSnapshotFn;
|
||||||
|
@ -252,42 +253,54 @@ int32_t metaUidFilterCachePut(SMeta *pMeta, uint64_t suid, const void *pKey, in
|
||||||
int32_t payloadLen, double selectivityRatio);
|
int32_t payloadLen, double selectivityRatio);
|
||||||
tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name);
|
tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name);
|
||||||
int32_t metaGetCachedTbGroup(SMeta* pMeta, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList);
|
int32_t metaGetCachedTbGroup(SMeta* pMeta, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList);
|
||||||
int32_t metaPutTbGroupToCache(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen);
|
int32_t metaPutTbGroupToCache(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t
|
||||||
|
payloadLen);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct SStoreMeta {
|
typedef struct SStoreMeta {
|
||||||
SMTbCursor *(*openTableMetaCursor)(void *pVnode); // metaOpenTbCursor
|
SMTbCursor* (*openTableMetaCursor)(void* pVnode); // metaOpenTbCursor
|
||||||
void (*closeTableMetaCursor)(SMTbCursor *pTbCur); // metaCloseTbCursor
|
void (*closeTableMetaCursor)(SMTbCursor* pTbCur); // metaCloseTbCursor
|
||||||
int32_t (*cursorNext)(SMTbCursor *pTbCur, ETableType jumpTableType); // metaTbCursorNext
|
void (*pauseTableMetaCursor)(SMTbCursor* pTbCur); // metaPauseTbCursor
|
||||||
int32_t (*cursorPrev)(SMTbCursor *pTbCur, ETableType jumpTableType); // metaTbCursorPrev
|
void (*resumeTableMetaCursor)(SMTbCursor* pTbCur, int8_t first); // metaResumeTbCursor
|
||||||
|
int32_t (*cursorNext)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorNext
|
||||||
|
int32_t (*cursorPrev)(SMTbCursor* pTbCur, ETableType jumpTableType); // metaTbCursorPrev
|
||||||
|
|
||||||
int32_t (*getTableTags)(void *pVnode, uint64_t suid, SArray *uidList);
|
int32_t (*getTableTags)(void* pVnode, uint64_t suid, SArray* uidList);
|
||||||
int32_t (*getTableTagsByUid)(void *pVnode, int64_t suid, SArray *uidList);
|
int32_t (*getTableTagsByUid)(void* pVnode, int64_t suid, SArray* uidList);
|
||||||
const void *(*extractTagVal)(const void *tag, int16_t type, STagVal *tagVal); // todo remove it
|
const void* (*extractTagVal)(const void* tag, int16_t type, STagVal* tagVal); // todo remove it
|
||||||
|
|
||||||
int32_t (*getTableUidByName)(void *pVnode, char *tbName, uint64_t *uid);
|
int32_t (*getTableUidByName)(void* pVnode, char* tbName, uint64_t* uid);
|
||||||
int32_t (*getTableTypeByName)(void *pVnode, char *tbName, ETableType *tbType);
|
int32_t (*getTableTypeByName)(void* pVnode, char* tbName, ETableType* tbType);
|
||||||
int32_t (*getTableNameByUid)(void *pVnode, uint64_t uid, char *tbName);
|
int32_t (*getTableNameByUid)(void* pVnode, uint64_t uid, char* tbName);
|
||||||
bool (*isTableExisted)(void *pVnode, tb_uid_t uid);
|
bool (*isTableExisted)(void* pVnode, tb_uid_t uid);
|
||||||
|
|
||||||
int32_t (*metaGetCachedTbGroup)(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList);
|
int32_t (*metaGetCachedTbGroup)(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList);
|
||||||
int32_t (*metaPutTbGroupToCache)(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen);
|
int32_t (*metaPutTbGroupToCache)(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
|
||||||
|
int32_t payloadLen);
|
||||||
|
|
||||||
int32_t (*getCachedTableList)(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray* pList1, bool* acquireRes);
|
int32_t (*getCachedTableList)(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray* pList1,
|
||||||
int32_t (*putCachedTableList)(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen, double selectivityRatio);
|
bool* acquireRes);
|
||||||
|
int32_t (*putCachedTableList)(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
|
||||||
|
int32_t payloadLen, double selectivityRatio);
|
||||||
|
|
||||||
void *(*storeGetIndexInfo)();
|
void* (*storeGetIndexInfo)();
|
||||||
void *(*getInvertIndex)(void* pVnode);
|
void* (*getInvertIndex)(void* pVnode);
|
||||||
int32_t (*getChildTableList)(void *pVnode, int64_t suid, SArray *list); // support filter and non-filter cases. [vnodeGetCtbIdList & vnodeGetCtbIdListByFilter]
|
int32_t (*getChildTableList)(
|
||||||
int32_t (*storeGetTableList)(void* pVnode, int8_t type, SArray* pList); // vnodeGetStbIdList & vnodeGetAllTableList
|
void* pVnode, int64_t suid,
|
||||||
void *storeGetVersionRange;
|
SArray* list); // support filter and non-filter cases. [vnodeGetCtbIdList & vnodeGetCtbIdListByFilter]
|
||||||
void *storeGetLastTimestamp;
|
int32_t (*storeGetTableList)(void* pVnode, int8_t type, SArray* pList); // vnodeGetStbIdList & vnodeGetAllTableList
|
||||||
|
void* storeGetVersionRange;
|
||||||
|
void* storeGetLastTimestamp;
|
||||||
|
|
||||||
int32_t (*getTableSchema)(void *pVnode, int64_t uid, STSchema **pSchema, int64_t *suid); // tsdbGetTableSchema
|
int32_t (*getTableSchema)(void* pVnode, int64_t uid, STSchema** pSchema, int64_t* suid); // tsdbGetTableSchema
|
||||||
|
|
||||||
// db name, vgId, numOfTables, numOfSTables
|
// db name, vgId, numOfTables, numOfSTables
|
||||||
int32_t (*getNumOfChildTables)(void* pVnode, int64_t uid, int64_t* numOfTables); // int32_t metaGetStbStats(SMeta *pMeta, int64_t uid, SMetaStbStats *pInfo);
|
int32_t (*getNumOfChildTables)(
|
||||||
void (*getBasicInfo)(void *pVnode, const char **dbname, int32_t *vgId, int64_t* numOfTables, int64_t* numOfNormalTables);// vnodeGetInfo(void *pVnode, const char **dbname, int32_t *vgId) & metaGetTbNum(SMeta *pMeta) & metaGetNtbNum(SMeta *pMeta);
|
void* pVnode, int64_t uid,
|
||||||
|
int64_t* numOfTables); // int32_t metaGetStbStats(SMeta *pMeta, int64_t uid, SMetaStbStats *pInfo);
|
||||||
|
void (*getBasicInfo)(void* pVnode, const char** dbname, int32_t* vgId, int64_t* numOfTables,
|
||||||
|
int64_t* numOfNormalTables); // vnodeGetInfo(void *pVnode, const char **dbname, int32_t *vgId) &
|
||||||
|
// metaGetTbNum(SMeta *pMeta) & metaGetNtbNum(SMeta *pMeta);
|
||||||
|
|
||||||
int64_t (*getNumOfRowsInMem)(void* pVnode);
|
int64_t (*getNumOfRowsInMem)(void* pVnode);
|
||||||
/**
|
/**
|
||||||
|
@ -298,24 +311,24 @@ int32_t vnodeGetStbIdList(void *pVnode, int64_t suid, SArray *list);
|
||||||
} SStoreMeta;
|
} SStoreMeta;
|
||||||
|
|
||||||
typedef struct SStoreMetaReader {
|
typedef struct SStoreMetaReader {
|
||||||
void (*initReader)(SMetaReader *pReader, void *pVnode, int32_t flags, SStoreMeta* pAPI);
|
void (*initReader)(SMetaReader* pReader, void* pVnode, int32_t flags, SStoreMeta* pAPI);
|
||||||
void (*clearReader)(SMetaReader *pReader);
|
void (*clearReader)(SMetaReader* pReader);
|
||||||
void (*readerReleaseLock)(SMetaReader *pReader);
|
void (*readerReleaseLock)(SMetaReader* pReader);
|
||||||
int32_t (*getTableEntryByUid)(SMetaReader *pReader, tb_uid_t uid);
|
int32_t (*getTableEntryByUid)(SMetaReader* pReader, tb_uid_t uid);
|
||||||
int32_t (*getTableEntryByName)(SMetaReader *pReader, const char *name);
|
int32_t (*getTableEntryByName)(SMetaReader* pReader, const char* name);
|
||||||
int32_t (*getEntryGetUidCache)(SMetaReader *pReader, tb_uid_t uid);
|
int32_t (*getEntryGetUidCache)(SMetaReader* pReader, tb_uid_t uid);
|
||||||
} SStoreMetaReader;
|
} SStoreMetaReader;
|
||||||
|
|
||||||
typedef struct SUpdateInfo {
|
typedef struct SUpdateInfo {
|
||||||
SArray *pTsBuckets;
|
SArray* pTsBuckets;
|
||||||
uint64_t numBuckets;
|
uint64_t numBuckets;
|
||||||
SArray *pTsSBFs;
|
SArray* pTsSBFs;
|
||||||
uint64_t numSBFs;
|
uint64_t numSBFs;
|
||||||
int64_t interval;
|
int64_t interval;
|
||||||
int64_t watermark;
|
int64_t watermark;
|
||||||
TSKEY minTS;
|
TSKEY minTS;
|
||||||
SScalableBf *pCloseWinSBF;
|
SScalableBf* pCloseWinSBF;
|
||||||
SHashObj *pMap;
|
SHashObj* pMap;
|
||||||
uint64_t maxDataVersion;
|
uint64_t maxDataVersion;
|
||||||
} SUpdateInfo;
|
} SUpdateInfo;
|
||||||
|
|
||||||
|
@ -334,15 +347,15 @@ typedef struct SStateStore {
|
||||||
|
|
||||||
int32_t (*streamStateAddIfNotExist)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
int32_t (*streamStateAddIfNotExist)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||||
int32_t (*streamStateReleaseBuf)(SStreamState* pState, const SWinKey* key, void* pVal);
|
int32_t (*streamStateReleaseBuf)(SStreamState* pState, const SWinKey* key, void* pVal);
|
||||||
void (*streamStateFreeVal)(void* val);
|
void (*streamStateFreeVal)(void* val);
|
||||||
|
|
||||||
int32_t (*streamStatePut)(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
int32_t (*streamStatePut)(SStreamState* pState, const SWinKey* key, const void* value, int32_t vLen);
|
||||||
int32_t (*streamStateGet)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
int32_t (*streamStateGet)(SStreamState* pState, const SWinKey* key, void** pVal, int32_t* pVLen);
|
||||||
bool (*streamStateCheck)(SStreamState* pState, const SWinKey* key);
|
bool (*streamStateCheck)(SStreamState* pState, const SWinKey* key);
|
||||||
int32_t (*streamStateGetByPos)(SStreamState* pState, void* pos, void** pVal);
|
int32_t (*streamStateGetByPos)(SStreamState* pState, void* pos, void** pVal);
|
||||||
int32_t (*streamStateDel)(SStreamState* pState, const SWinKey* key);
|
int32_t (*streamStateDel)(SStreamState* pState, const SWinKey* key);
|
||||||
int32_t (*streamStateClear)(SStreamState* pState);
|
int32_t (*streamStateClear)(SStreamState* pState);
|
||||||
void (*streamStateSetNumber)(SStreamState* pState, int32_t number);
|
void (*streamStateSetNumber)(SStreamState* pState, int32_t number);
|
||||||
int32_t (*streamStateSaveInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void* pVal, int32_t vLen);
|
int32_t (*streamStateSaveInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void* pVal, int32_t vLen);
|
||||||
int32_t (*streamStateGetInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
int32_t (*streamStateGetInfo)(SStreamState* pState, void* pKey, int32_t keyLen, void** pVal, int32_t* pLen);
|
||||||
|
|
||||||
|
@ -353,36 +366,37 @@ typedef struct SStateStore {
|
||||||
int32_t (*streamStateCurNext)(SStreamState* pState, SStreamStateCur* pCur);
|
int32_t (*streamStateCurNext)(SStreamState* pState, SStreamStateCur* pCur);
|
||||||
int32_t (*streamStateCurPrev)(SStreamState* pState, SStreamStateCur* pCur);
|
int32_t (*streamStateCurPrev)(SStreamState* pState, SStreamStateCur* pCur);
|
||||||
|
|
||||||
SStreamStateCur* (*streamStateGetAndCheckCur)(SStreamState* pState, SWinKey* key);
|
SStreamStateCur* (*streamStateGetAndCheckCur)(SStreamState* pState, SWinKey* key);
|
||||||
SStreamStateCur* (*streamStateSeekKeyNext)(SStreamState* pState, const SWinKey* key);
|
SStreamStateCur* (*streamStateSeekKeyNext)(SStreamState* pState, const SWinKey* key);
|
||||||
SStreamStateCur* (*streamStateFillSeekKeyNext)(SStreamState* pState, const SWinKey* key);
|
SStreamStateCur* (*streamStateFillSeekKeyNext)(SStreamState* pState, const SWinKey* key);
|
||||||
SStreamStateCur* (*streamStateFillSeekKeyPrev)(SStreamState* pState, const SWinKey* key);
|
SStreamStateCur* (*streamStateFillSeekKeyPrev)(SStreamState* pState, const SWinKey* key);
|
||||||
void (*streamStateFreeCur)(SStreamStateCur* pCur);
|
void (*streamStateFreeCur)(SStreamStateCur* pCur);
|
||||||
|
|
||||||
int32_t (*streamStateGetGroupKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
int32_t (*streamStateGetGroupKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||||
int32_t (*streamStateGetKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
int32_t (*streamStateGetKVByCur)(SStreamStateCur* pCur, SWinKey* pKey, const void** pVal, int32_t* pVLen);
|
||||||
|
|
||||||
int32_t (*streamStateSessionAddIfNotExist)(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal, int32_t* pVLen);
|
int32_t (*streamStateSessionAddIfNotExist)(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal,
|
||||||
|
int32_t* pVLen);
|
||||||
int32_t (*streamStateSessionPut)(SStreamState* pState, const SSessionKey* key, const void* value, int32_t vLen);
|
int32_t (*streamStateSessionPut)(SStreamState* pState, const SSessionKey* key, const void* value, int32_t vLen);
|
||||||
int32_t (*streamStateSessionGet)(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
|
int32_t (*streamStateSessionGet)(SStreamState* pState, SSessionKey* key, void** pVal, int32_t* pVLen);
|
||||||
int32_t (*streamStateSessionDel)(SStreamState* pState, const SSessionKey* key);
|
int32_t (*streamStateSessionDel)(SStreamState* pState, const SSessionKey* key);
|
||||||
int32_t (*streamStateSessionClear)(SStreamState* pState);
|
int32_t (*streamStateSessionClear)(SStreamState* pState);
|
||||||
int32_t (*streamStateSessionGetKVByCur)(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
int32_t (*streamStateSessionGetKVByCur)(SStreamStateCur* pCur, SSessionKey* pKey, void** pVal, int32_t* pVLen);
|
||||||
int32_t (*streamStateStateAddIfNotExist)(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
int32_t (*streamStateStateAddIfNotExist)(SStreamState* pState, SSessionKey* key, char* pKeyData, int32_t keyDataLen,
|
||||||
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
state_key_cmpr_fn fn, void** pVal, int32_t* pVLen);
|
||||||
int32_t (*streamStateSessionGetKeyByRange)(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
int32_t (*streamStateSessionGetKeyByRange)(SStreamState* pState, const SSessionKey* range, SSessionKey* curKey);
|
||||||
|
|
||||||
SUpdateInfo* (*updateInfoInit)(int64_t interval, int32_t precision, int64_t watermark);
|
SUpdateInfo* (*updateInfoInit)(int64_t interval, int32_t precision, int64_t watermark);
|
||||||
TSKEY (*updateInfoFillBlockData)(SUpdateInfo *pInfo, SSDataBlock *pBlock, int32_t primaryTsCol);
|
TSKEY (*updateInfoFillBlockData)(SUpdateInfo* pInfo, SSDataBlock* pBlock, int32_t primaryTsCol);
|
||||||
bool (*updateInfoIsUpdated)(SUpdateInfo *pInfo, uint64_t tableId, TSKEY ts);
|
bool (*updateInfoIsUpdated)(SUpdateInfo* pInfo, uint64_t tableId, TSKEY ts);
|
||||||
bool (*updateInfoIsTableInserted)(SUpdateInfo *pInfo, int64_t tbUid);
|
bool (*updateInfoIsTableInserted)(SUpdateInfo* pInfo, int64_t tbUid);
|
||||||
void (*updateInfoDestroy)(SUpdateInfo *pInfo);
|
void (*updateInfoDestroy)(SUpdateInfo* pInfo);
|
||||||
|
|
||||||
SUpdateInfo* (*updateInfoInitP)(SInterval *pInterval, int64_t watermark);
|
SUpdateInfo* (*updateInfoInitP)(SInterval* pInterval, int64_t watermark);
|
||||||
void (*updateInfoAddCloseWindowSBF)(SUpdateInfo *pInfo);
|
void (*updateInfoAddCloseWindowSBF)(SUpdateInfo* pInfo);
|
||||||
void (*updateInfoDestoryColseWinSBF)(SUpdateInfo *pInfo);
|
void (*updateInfoDestoryColseWinSBF)(SUpdateInfo* pInfo);
|
||||||
int32_t (*updateInfoSerialize)(void *buf, int32_t bufLen, const SUpdateInfo *pInfo);
|
int32_t (*updateInfoSerialize)(void* buf, int32_t bufLen, const SUpdateInfo* pInfo);
|
||||||
int32_t (*updateInfoDeserialize)(void *buf, int32_t bufLen, SUpdateInfo *pInfo);
|
int32_t (*updateInfoDeserialize)(void* buf, int32_t bufLen, SUpdateInfo* pInfo);
|
||||||
|
|
||||||
SStreamStateCur* (*streamStateSessionSeekKeyNext)(SStreamState* pState, const SSessionKey* key);
|
SStreamStateCur* (*streamStateSessionSeekKeyNext)(SStreamState* pState, const SSessionKey* key);
|
||||||
SStreamStateCur* (*streamStateSessionSeekKeyCurrentPrev)(SStreamState* pState, const SSessionKey* key);
|
SStreamStateCur* (*streamStateSessionSeekKeyCurrentPrev)(SStreamState* pState, const SSessionKey* key);
|
||||||
|
@ -396,11 +410,11 @@ typedef struct SStateStore {
|
||||||
bool (*needClearDiskBuff)(struct SStreamFileState* pFileState);
|
bool (*needClearDiskBuff)(struct SStreamFileState* pFileState);
|
||||||
|
|
||||||
SStreamState* (*streamStateOpen)(char* path, void* pTask, bool specPath, int32_t szPage, int32_t pages);
|
SStreamState* (*streamStateOpen)(char* path, void* pTask, bool specPath, int32_t szPage, int32_t pages);
|
||||||
void (*streamStateClose)(SStreamState* pState, bool remove);
|
void (*streamStateClose)(SStreamState* pState, bool remove);
|
||||||
int32_t (*streamStateBegin)(SStreamState* pState);
|
int32_t (*streamStateBegin)(SStreamState* pState);
|
||||||
int32_t (*streamStateCommit)(SStreamState* pState);
|
int32_t (*streamStateCommit)(SStreamState* pState);
|
||||||
void (*streamStateDestroy)(SStreamState* pState, bool remove);
|
void (*streamStateDestroy)(SStreamState* pState, bool remove);
|
||||||
int32_t (*streamStateDeleteCheckPoint)(SStreamState* pState, TSKEY mark);
|
int32_t (*streamStateDeleteCheckPoint)(SStreamState* pState, TSKEY mark);
|
||||||
} SStateStore;
|
} SStateStore;
|
||||||
|
|
||||||
typedef struct SStorageAPI {
|
typedef struct SStorageAPI {
|
||||||
|
|
|
@ -233,6 +233,7 @@ bool fmIsGroupKeyFunc(int32_t funcId);
|
||||||
bool fmIsBlockDistFunc(int32_t funcId);
|
bool fmIsBlockDistFunc(int32_t funcId);
|
||||||
|
|
||||||
void getLastCacheDataType(SDataType* pType);
|
void getLastCacheDataType(SDataType* pType);
|
||||||
|
SFunctionNode* createFunction(const char* pName, SNodeList* pParameterList);
|
||||||
|
|
||||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
||||||
|
|
||||||
|
|
|
@ -425,16 +425,18 @@ typedef struct SStreamOptions {
|
||||||
} SStreamOptions;
|
} SStreamOptions;
|
||||||
|
|
||||||
typedef struct SCreateStreamStmt {
|
typedef struct SCreateStreamStmt {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
char streamName[TSDB_TABLE_NAME_LEN];
|
char streamName[TSDB_TABLE_NAME_LEN];
|
||||||
char targetDbName[TSDB_DB_NAME_LEN];
|
char targetDbName[TSDB_DB_NAME_LEN];
|
||||||
char targetTabName[TSDB_TABLE_NAME_LEN];
|
char targetTabName[TSDB_TABLE_NAME_LEN];
|
||||||
bool ignoreExists;
|
bool ignoreExists;
|
||||||
SStreamOptions* pOptions;
|
SStreamOptions* pOptions;
|
||||||
SNode* pQuery;
|
SNode* pQuery;
|
||||||
SNodeList* pTags;
|
SNode* pPrevQuery;
|
||||||
SNode* pSubtable;
|
SNodeList* pTags;
|
||||||
SNodeList* pCols;
|
SNode* pSubtable;
|
||||||
|
SNodeList* pCols;
|
||||||
|
SCMCreateStreamReq* pReq;
|
||||||
} SCreateStreamStmt;
|
} SCreateStreamStmt;
|
||||||
|
|
||||||
typedef struct SDropStreamStmt {
|
typedef struct SDropStreamStmt {
|
||||||
|
|
|
@ -328,6 +328,8 @@ void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* p
|
||||||
SNode* nodesListGetNode(SNodeList* pList, int32_t index);
|
SNode* nodesListGetNode(SNodeList* pList, int32_t index);
|
||||||
SListCell* nodesListGetCell(SNodeList* pList, int32_t index);
|
SListCell* nodesListGetCell(SNodeList* pList, int32_t index);
|
||||||
void nodesDestroyList(SNodeList* pList);
|
void nodesDestroyList(SNodeList* pList);
|
||||||
|
bool nodesListMatch(const SNodeList* pList, const SNodeList* pSubList);
|
||||||
|
|
||||||
// Only clear the linked list structure, without releasing the elements inside
|
// Only clear the linked list structure, without releasing the elements inside
|
||||||
void nodesClearList(SNodeList* pList);
|
void nodesClearList(SNodeList* pList);
|
||||||
|
|
||||||
|
@ -346,6 +348,7 @@ void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pCon
|
||||||
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||||
|
|
||||||
bool nodesEqualNode(const SNode* a, const SNode* b);
|
bool nodesEqualNode(const SNode* a, const SNode* b);
|
||||||
|
bool nodesMatchNode(const SNode* pSub, const SNode* pNode);
|
||||||
|
|
||||||
SNode* nodesCloneNode(const SNode* pNode);
|
SNode* nodesCloneNode(const SNode* pNode);
|
||||||
SNodeList* nodesCloneList(const SNodeList* pList);
|
SNodeList* nodesCloneList(const SNodeList* pList);
|
||||||
|
|
|
@ -617,6 +617,7 @@ typedef struct SQueryPlan {
|
||||||
int32_t numOfSubplans;
|
int32_t numOfSubplans;
|
||||||
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
|
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
|
||||||
SExplainInfo explainInfo;
|
SExplainInfo explainInfo;
|
||||||
|
void* pPostPlan;
|
||||||
} SQueryPlan;
|
} SQueryPlan;
|
||||||
|
|
||||||
const char* dataOrderStr(EDataOrderLevel order);
|
const char* dataOrderStr(EDataOrderLevel order);
|
||||||
|
|
|
@ -241,6 +241,12 @@ typedef enum EFillMode {
|
||||||
FILL_MODE_NEXT
|
FILL_MODE_NEXT
|
||||||
} EFillMode;
|
} EFillMode;
|
||||||
|
|
||||||
|
typedef enum ETimeLineMode {
|
||||||
|
TIME_LINE_NONE = 1,
|
||||||
|
TIME_LINE_MULTI,
|
||||||
|
TIME_LINE_GLOBAL,
|
||||||
|
} ETimeLineMode;
|
||||||
|
|
||||||
typedef struct SFillNode {
|
typedef struct SFillNode {
|
||||||
ENodeType type; // QUERY_NODE_FILL
|
ENodeType type; // QUERY_NODE_FILL
|
||||||
EFillMode mode;
|
EFillMode mode;
|
||||||
|
@ -263,50 +269,50 @@ typedef struct SCaseWhenNode {
|
||||||
} SCaseWhenNode;
|
} SCaseWhenNode;
|
||||||
|
|
||||||
typedef struct SSelectStmt {
|
typedef struct SSelectStmt {
|
||||||
ENodeType type; // QUERY_NODE_SELECT_STMT
|
ENodeType type; // QUERY_NODE_SELECT_STMT
|
||||||
bool isDistinct;
|
bool isDistinct;
|
||||||
SNodeList* pProjectionList;
|
SNodeList* pProjectionList;
|
||||||
SNode* pFromTable;
|
SNode* pFromTable;
|
||||||
SNode* pWhere;
|
SNode* pWhere;
|
||||||
SNodeList* pPartitionByList;
|
SNodeList* pPartitionByList;
|
||||||
SNodeList* pTags; // for create stream
|
SNodeList* pTags; // for create stream
|
||||||
SNode* pSubtable; // for create stream
|
SNode* pSubtable; // for create stream
|
||||||
SNode* pWindow;
|
SNode* pWindow;
|
||||||
SNodeList* pGroupByList; // SGroupingSetNode
|
SNodeList* pGroupByList; // SGroupingSetNode
|
||||||
SNode* pHaving;
|
SNode* pHaving;
|
||||||
SNode* pRange;
|
SNode* pRange;
|
||||||
SNode* pEvery;
|
SNode* pEvery;
|
||||||
SNode* pFill;
|
SNode* pFill;
|
||||||
SNodeList* pOrderByList; // SOrderByExprNode
|
SNodeList* pOrderByList; // SOrderByExprNode
|
||||||
SLimitNode* pLimit;
|
SLimitNode* pLimit;
|
||||||
SLimitNode* pSlimit;
|
SLimitNode* pSlimit;
|
||||||
STimeWindow timeRange;
|
STimeWindow timeRange;
|
||||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
int32_t selectFuncNum;
|
int32_t selectFuncNum;
|
||||||
int32_t returnRows; // EFuncReturnRows
|
int32_t returnRows; // EFuncReturnRows
|
||||||
bool isEmptyResult;
|
ETimeLineMode timeLineResMode;
|
||||||
bool isTimeLineResult;
|
bool isEmptyResult;
|
||||||
bool isSubquery;
|
bool isSubquery;
|
||||||
bool hasAggFuncs;
|
bool hasAggFuncs;
|
||||||
bool hasRepeatScanFuncs;
|
bool hasRepeatScanFuncs;
|
||||||
bool hasIndefiniteRowsFunc;
|
bool hasIndefiniteRowsFunc;
|
||||||
bool hasMultiRowsFunc;
|
bool hasMultiRowsFunc;
|
||||||
bool hasSelectFunc;
|
bool hasSelectFunc;
|
||||||
bool hasSelectValFunc;
|
bool hasSelectValFunc;
|
||||||
bool hasOtherVectorFunc;
|
bool hasOtherVectorFunc;
|
||||||
bool hasUniqueFunc;
|
bool hasUniqueFunc;
|
||||||
bool hasTailFunc;
|
bool hasTailFunc;
|
||||||
bool hasInterpFunc;
|
bool hasInterpFunc;
|
||||||
bool hasInterpPseudoColFunc;
|
bool hasInterpPseudoColFunc;
|
||||||
bool hasLastRowFunc;
|
bool hasLastRowFunc;
|
||||||
bool hasLastFunc;
|
bool hasLastFunc;
|
||||||
bool hasTimeLineFunc;
|
bool hasTimeLineFunc;
|
||||||
bool hasUdaf;
|
bool hasUdaf;
|
||||||
bool hasStateKey;
|
bool hasStateKey;
|
||||||
bool onlyHasKeepOrderFunc;
|
bool onlyHasKeepOrderFunc;
|
||||||
bool groupSort;
|
bool groupSort;
|
||||||
bool tagScan;
|
bool tagScan;
|
||||||
} SSelectStmt;
|
} SSelectStmt;
|
||||||
|
|
||||||
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
|
||||||
|
@ -321,6 +327,7 @@ typedef struct SSetOperator {
|
||||||
SNode* pLimit;
|
SNode* pLimit;
|
||||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
|
ETimeLineMode timeLineResMode;
|
||||||
} SSetOperator;
|
} SSetOperator;
|
||||||
|
|
||||||
typedef enum ESqlClause {
|
typedef enum ESqlClause {
|
||||||
|
@ -434,7 +441,9 @@ typedef struct SQuery {
|
||||||
EQueryExecStage execStage;
|
EQueryExecStage execStage;
|
||||||
EQueryExecMode execMode;
|
EQueryExecMode execMode;
|
||||||
bool haveResultSet;
|
bool haveResultSet;
|
||||||
|
SNode* pPrevRoot;
|
||||||
SNode* pRoot;
|
SNode* pRoot;
|
||||||
|
SNode* pPostRoot;
|
||||||
int32_t numOfResCols;
|
int32_t numOfResCols;
|
||||||
SSchema* pResSchema;
|
SSchema* pResSchema;
|
||||||
int8_t precision;
|
int8_t precision;
|
||||||
|
|
|
@ -74,6 +74,7 @@ int32_t qAnalyseSqlSemantic(SParseContext* pCxt, const struct SCatalogReq* pCata
|
||||||
const struct SMetaData* pMetaData, SQuery* pQuery);
|
const struct SMetaData* pMetaData, SQuery* pQuery);
|
||||||
int32_t qContinueParseSql(SParseContext* pCxt, struct SCatalogReq* pCatalogReq, const struct SMetaData* pMetaData,
|
int32_t qContinueParseSql(SParseContext* pCxt, struct SCatalogReq* pCatalogReq, const struct SMetaData* pMetaData,
|
||||||
SQuery* pQuery);
|
SQuery* pQuery);
|
||||||
|
int32_t qContinueParsePostQuery(SParseContext* pCxt, SQuery* pQuery, void** pResRow);
|
||||||
|
|
||||||
void qDestroyParseContext(SParseContext* pCxt);
|
void qDestroyParseContext(SParseContext* pCxt);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
|
||||||
// @groupId id of a group of datasource subplans of this @pSubplan
|
// @groupId id of a group of datasource subplans of this @pSubplan
|
||||||
// @pSource one execution location of this group of datasource subplans
|
// @pSource one execution location of this group of datasource subplans
|
||||||
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource);
|
||||||
|
int32_t qContinuePlanPostQuery(void *pPostPlan);
|
||||||
|
|
||||||
void qClearSubplanExecutionNode(SSubplan* pSubplan);
|
void qClearSubplanExecutionNode(SSubplan* pSubplan);
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,7 @@ struct SStreamTask {
|
||||||
int64_t checkpointingId;
|
int64_t checkpointingId;
|
||||||
int32_t checkpointAlignCnt;
|
int32_t checkpointAlignCnt;
|
||||||
struct SStreamMeta* pMeta;
|
struct SStreamMeta* pMeta;
|
||||||
|
SSHashObj* pNameMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// meta
|
// meta
|
||||||
|
|
|
@ -154,14 +154,14 @@ typedef struct SSnapshotMeta {
|
||||||
typedef struct SSyncFSM {
|
typedef struct SSyncFSM {
|
||||||
void* data;
|
void* data;
|
||||||
|
|
||||||
int32_t (*FpCommitCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, const SFsmCbMeta* pMeta);
|
int32_t (*FpCommitCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
|
||||||
SyncIndex (*FpAppliedIndexCb)(const struct SSyncFSM* pFsm);
|
SyncIndex (*FpAppliedIndexCb)(const struct SSyncFSM* pFsm);
|
||||||
int32_t (*FpPreCommitCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, const SFsmCbMeta* pMeta);
|
int32_t (*FpPreCommitCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
|
||||||
void (*FpRollBackCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, const SFsmCbMeta* pMeta);
|
void (*FpRollBackCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
|
||||||
|
|
||||||
void (*FpRestoreFinishCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
|
void (*FpRestoreFinishCb)(const struct SSyncFSM* pFsm, const SyncIndex commitIdx);
|
||||||
void (*FpReConfigCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, const SReConfigCbMeta* pMeta);
|
void (*FpReConfigCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SReConfigCbMeta* pMeta);
|
||||||
void (*FpLeaderTransferCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, const SFsmCbMeta* pMeta);
|
void (*FpLeaderTransferCb)(const struct SSyncFSM* pFsm, SRpcMsg* pMsg, SFsmCbMeta* pMeta);
|
||||||
bool (*FpApplyQueueEmptyCb)(const struct SSyncFSM* pFsm);
|
bool (*FpApplyQueueEmptyCb)(const struct SSyncFSM* pFsm);
|
||||||
int32_t (*FpApplyQueueItems)(const struct SSyncFSM* pFsm);
|
int32_t (*FpApplyQueueItems)(const struct SSyncFSM* pFsm);
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ int32_t walSkipFetchBody(SWalReader *pRead, const SWalCkHead *pHead);
|
||||||
|
|
||||||
void walRefFirstVer(SWal *, SWalRef *);
|
void walRefFirstVer(SWal *, SWalRef *);
|
||||||
void walRefLastVer(SWal *, SWalRef *);
|
void walRefLastVer(SWal *, SWalRef *);
|
||||||
SWalRef *walRefCommittedVer(SWal *);
|
void walRefCommitVer(SWal *, SWalRef *);
|
||||||
|
|
||||||
SWalRef *walOpenRef(SWal *);
|
SWalRef *walOpenRef(SWal *);
|
||||||
void walCloseRef(SWal *pWal, int64_t refId);
|
void walCloseRef(SWal *pWal, int64_t refId);
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef void *(*__array_item_dup_fn_t)(void *);
|
||||||
|
|
||||||
typedef void (*FDelete)(void *);
|
typedef void (*FDelete)(void *);
|
||||||
typedef int32_t (*FEncode)(void **buf, const void *dst);
|
typedef int32_t (*FEncode)(void **buf, const void *dst);
|
||||||
typedef void *(*FDecode)(const void *buf, void *dst);
|
typedef void *(*FDecode)(const void *buf, void *dst, int8_t sver);
|
||||||
|
|
||||||
#define TD_EQ 0x1
|
#define TD_EQ 0x1
|
||||||
#define TD_GT 0x2
|
#define TD_GT 0x2
|
||||||
|
|
|
@ -345,7 +345,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_MND_TRANS_CLOG_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x03D4)
|
#define TSDB_CODE_MND_TRANS_CLOG_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x03D4)
|
||||||
#define TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL TAOS_DEF_ERROR_CODE(0, 0x03D5)
|
#define TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL TAOS_DEF_ERROR_CODE(0, 0x03D5)
|
||||||
#define TSDB_CODE_MND_LAST_TRANS_NOT_FINISHED TAOS_DEF_ERROR_CODE(0, 0x03D6) //internal
|
#define TSDB_CODE_MND_LAST_TRANS_NOT_FINISHED TAOS_DEF_ERROR_CODE(0, 0x03D6) //internal
|
||||||
#define TSDB_CODE_MND_TRNAS_SYNC_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x03D7)
|
#define TSDB_CODE_MND_TRANS_SYNC_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x03D7)
|
||||||
#define TSDB_CODE_MND_TRANS_UNKNOW_ERROR TAOS_DEF_ERROR_CODE(0, 0x03DF)
|
#define TSDB_CODE_MND_TRANS_UNKNOW_ERROR TAOS_DEF_ERROR_CODE(0, 0x03DF)
|
||||||
|
|
||||||
// mnode-mq
|
// mnode-mq
|
||||||
|
|
|
@ -244,7 +244,7 @@ int32_t taosArraySearchIdx(const SArray* pArray, const void* key, __compar_fn_t
|
||||||
void taosArraySortPWithExt(SArray* pArray, __ext_compar_fn_t fn, const void* param);
|
void taosArraySortPWithExt(SArray* pArray, __ext_compar_fn_t fn, const void* param);
|
||||||
|
|
||||||
int32_t taosEncodeArray(void** buf, const SArray* pArray, FEncode encode);
|
int32_t taosEncodeArray(void** buf, const SArray* pArray, FEncode encode);
|
||||||
void* taosDecodeArray(const void* buf, SArray** pArray, FDecode decode, int32_t dataSz);
|
void* taosDecodeArray(const void* buf, SArray** pArray, FDecode decode, int32_t dataSz, int8_t sver);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ extern "C" {
|
||||||
#define TD_VER_MAX UINT64_MAX // TODO: use the real max version from query handle
|
#define TD_VER_MAX UINT64_MAX // TODO: use the real max version from query handle
|
||||||
|
|
||||||
// Bytes for each type.
|
// Bytes for each type.
|
||||||
extern const int32_t TYPE_BYTES[17];
|
extern const int32_t TYPE_BYTES[21];
|
||||||
|
|
||||||
// TODO: replace and remove code below
|
// TODO: replace and remove code below
|
||||||
#define CHAR_BYTES sizeof(char)
|
#define CHAR_BYTES sizeof(char)
|
||||||
|
@ -195,6 +195,7 @@ typedef enum ELogicConditionType {
|
||||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||||
#define TSDB_TOPIC_NAME_LEN 193 // it is a null-terminated string
|
#define TSDB_TOPIC_NAME_LEN 193 // it is a null-terminated string
|
||||||
#define TSDB_CGROUP_LEN 193 // it is a null-terminated string
|
#define TSDB_CGROUP_LEN 193 // it is a null-terminated string
|
||||||
|
#define TSDB_OFFSET_LEN 64 // it is a null-terminated string
|
||||||
#define TSDB_USER_CGROUP_LEN (TSDB_USER_LEN + TSDB_CGROUP_LEN) // it is a null-terminated string
|
#define TSDB_USER_CGROUP_LEN (TSDB_USER_LEN + TSDB_CGROUP_LEN) // it is a null-terminated string
|
||||||
#define TSDB_STREAM_NAME_LEN 193 // it is a null-terminated string
|
#define TSDB_STREAM_NAME_LEN 193 // it is a null-terminated string
|
||||||
#define TSDB_DB_NAME_LEN 65
|
#define TSDB_DB_NAME_LEN 65
|
||||||
|
|
|
@ -227,6 +227,12 @@ typedef struct {
|
||||||
STaosxRsp rsp;
|
STaosxRsp rsp;
|
||||||
} SMqTaosxRspObj;
|
} SMqTaosxRspObj;
|
||||||
|
|
||||||
|
typedef struct SReqRelInfo {
|
||||||
|
uint64_t userRefId;
|
||||||
|
uint64_t prevRefId;
|
||||||
|
uint64_t nextRefId;
|
||||||
|
} SReqRelInfo;
|
||||||
|
|
||||||
typedef struct SRequestObj {
|
typedef struct SRequestObj {
|
||||||
int8_t resType; // query or tmq
|
int8_t resType; // query or tmq
|
||||||
uint64_t requestId;
|
uint64_t requestId;
|
||||||
|
@ -250,10 +256,14 @@ typedef struct SRequestObj {
|
||||||
bool validateOnly; // todo refactor
|
bool validateOnly; // todo refactor
|
||||||
bool killed;
|
bool killed;
|
||||||
bool inRetry;
|
bool inRetry;
|
||||||
|
bool isSubReq;
|
||||||
uint32_t prevCode; // previous error code: todo refactor, add update flag for catalog
|
uint32_t prevCode; // previous error code: todo refactor, add update flag for catalog
|
||||||
uint32_t retry;
|
uint32_t retry;
|
||||||
int64_t allocatorRefId;
|
int64_t allocatorRefId;
|
||||||
SQuery* pQuery;
|
SQuery* pQuery;
|
||||||
|
void* pPostPlan;
|
||||||
|
SReqRelInfo relation;
|
||||||
|
void* pWrapper;
|
||||||
} SRequestObj;
|
} SRequestObj;
|
||||||
|
|
||||||
typedef struct SSyncQueryParam {
|
typedef struct SSyncQueryParam {
|
||||||
|
@ -279,6 +289,7 @@ TAOS_RES* taosQueryImplWithReqid(TAOS* taos, const char* sql, bool validateOnly,
|
||||||
void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly);
|
void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly);
|
||||||
void taosAsyncQueryImplWithReqid(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly,
|
void taosAsyncQueryImplWithReqid(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly,
|
||||||
int64_t reqid);
|
int64_t reqid);
|
||||||
|
void taosAsyncFetchImpl(SRequestObj *pRequest, __taos_async_fn_t fp, void *param);
|
||||||
|
|
||||||
int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols);
|
int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols);
|
||||||
|
|
||||||
|
@ -368,6 +379,7 @@ typedef struct SSqlCallbackWrapper {
|
||||||
SParseContext* pParseCtx;
|
SParseContext* pParseCtx;
|
||||||
SCatalogReq* pCatalogReq;
|
SCatalogReq* pCatalogReq;
|
||||||
SRequestObj* pRequest;
|
SRequestObj* pRequest;
|
||||||
|
void* pPlanInfo;
|
||||||
} SSqlCallbackWrapper;
|
} SSqlCallbackWrapper;
|
||||||
|
|
||||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res);
|
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res);
|
||||||
|
@ -382,6 +394,12 @@ int32_t handleCreateTbExecRes(void* res, SCatalog* pCatalog);
|
||||||
bool qnodeRequired(SRequestObj* pRequest);
|
bool qnodeRequired(SRequestObj* pRequest);
|
||||||
void continueInsertFromCsv(SSqlCallbackWrapper* pWrapper, SRequestObj* pRequest);
|
void continueInsertFromCsv(SSqlCallbackWrapper* pWrapper, SRequestObj* pRequest);
|
||||||
void destorySqlCallbackWrapper(SSqlCallbackWrapper* pWrapper);
|
void destorySqlCallbackWrapper(SSqlCallbackWrapper* pWrapper);
|
||||||
|
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code);
|
||||||
|
void restartAsyncQuery(SRequestObj *pRequest, int32_t code);
|
||||||
|
int32_t buildPreviousRequest(SRequestObj *pRequest, const char* sql, SRequestObj** pNewRequest);
|
||||||
|
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce);
|
||||||
|
void returnToUser(SRequestObj* pRequest);
|
||||||
|
void stopAllQueries(SRequestObj *pRequest);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,6 +358,49 @@ int32_t releaseRequest(int64_t rid) { return taosReleaseRef(clientReqRefPool, ri
|
||||||
|
|
||||||
int32_t removeRequest(int64_t rid) { return taosRemoveRef(clientReqRefPool, rid); }
|
int32_t removeRequest(int64_t rid) { return taosRemoveRef(clientReqRefPool, rid); }
|
||||||
|
|
||||||
|
|
||||||
|
void destroySubRequests(SRequestObj *pRequest) {
|
||||||
|
int32_t reqIdx = -1;
|
||||||
|
SRequestObj *pReqList[16] = {NULL};
|
||||||
|
uint64_t tmpRefId = 0;
|
||||||
|
|
||||||
|
if (pRequest->relation.userRefId && pRequest->relation.userRefId != pRequest->self) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRequestObj* pTmp = pRequest;
|
||||||
|
while (pTmp->relation.prevRefId) {
|
||||||
|
tmpRefId = pTmp->relation.prevRefId;
|
||||||
|
pTmp = acquireRequest(tmpRefId);
|
||||||
|
if (pTmp) {
|
||||||
|
pReqList[++reqIdx] = pTmp;
|
||||||
|
releaseRequest(tmpRefId);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 ", prev req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pTmp->self,
|
||||||
|
tmpRefId, pTmp->requestId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = reqIdx; i >= 0; i--) {
|
||||||
|
removeRequest(pReqList[i]->self);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpRefId = pRequest->relation.nextRefId;
|
||||||
|
while (tmpRefId) {
|
||||||
|
pTmp = acquireRequest(tmpRefId);
|
||||||
|
if (pTmp) {
|
||||||
|
tmpRefId = pTmp->relation.nextRefId;
|
||||||
|
removeRequest(pTmp->self);
|
||||||
|
releaseRequest(pTmp->self);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 " is not there", tmpRefId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void doDestroyRequest(void *p) {
|
void doDestroyRequest(void *p) {
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
return;
|
return;
|
||||||
|
@ -368,10 +411,14 @@ void doDestroyRequest(void *p) {
|
||||||
uint64_t reqId = pRequest->requestId;
|
uint64_t reqId = pRequest->requestId;
|
||||||
tscTrace("begin to destroy request %" PRIx64 " p:%p", reqId, pRequest);
|
tscTrace("begin to destroy request %" PRIx64 " p:%p", reqId, pRequest);
|
||||||
|
|
||||||
|
destroySubRequests(pRequest);
|
||||||
|
|
||||||
taosHashRemove(pRequest->pTscObj->pRequests, &pRequest->self, sizeof(pRequest->self));
|
taosHashRemove(pRequest->pTscObj->pRequests, &pRequest->self, sizeof(pRequest->self));
|
||||||
|
|
||||||
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
||||||
|
|
||||||
|
destorySqlCallbackWrapper(pRequest->pWrapper);
|
||||||
|
|
||||||
taosMemoryFreeClear(pRequest->msgBuf);
|
taosMemoryFreeClear(pRequest->msgBuf);
|
||||||
taosMemoryFreeClear(pRequest->pDb);
|
taosMemoryFreeClear(pRequest->pDb);
|
||||||
|
|
||||||
|
@ -412,6 +459,63 @@ void destroyRequest(SRequestObj *pRequest) {
|
||||||
removeRequest(pRequest->self);
|
removeRequest(pRequest->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void taosStopQueryImpl(SRequestObj *pRequest) {
|
||||||
|
pRequest->killed = true;
|
||||||
|
|
||||||
|
// It is not a query, no need to stop.
|
||||||
|
if (NULL == pRequest->pQuery || QUERY_EXEC_MODE_SCHEDULE != pRequest->pQuery->execMode) {
|
||||||
|
tscDebug("request 0x%" PRIx64 " no need to be killed since not query", pRequest->requestId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
schedulerFreeJob(&pRequest->body.queryJob, TSDB_CODE_TSC_QUERY_KILLED);
|
||||||
|
tscDebug("request %" PRIx64 " killed", pRequest->requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopAllQueries(SRequestObj *pRequest) {
|
||||||
|
int32_t reqIdx = -1;
|
||||||
|
SRequestObj *pReqList[16] = {NULL};
|
||||||
|
uint64_t tmpRefId = 0;
|
||||||
|
|
||||||
|
if (pRequest->relation.userRefId && pRequest->relation.userRefId != pRequest->self) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRequestObj* pTmp = pRequest;
|
||||||
|
while (pTmp->relation.prevRefId) {
|
||||||
|
tmpRefId = pTmp->relation.prevRefId;
|
||||||
|
pTmp = acquireRequest(tmpRefId);
|
||||||
|
if (pTmp) {
|
||||||
|
pReqList[++reqIdx] = pTmp;
|
||||||
|
releaseRequest(tmpRefId);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 ", prev req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pTmp->self,
|
||||||
|
tmpRefId, pTmp->requestId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = reqIdx; i >= 0; i--) {
|
||||||
|
taosStopQueryImpl(pReqList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosStopQueryImpl(pRequest);
|
||||||
|
|
||||||
|
tmpRefId = pRequest->relation.nextRefId;
|
||||||
|
while (tmpRefId) {
|
||||||
|
pTmp = acquireRequest(tmpRefId);
|
||||||
|
if (pTmp) {
|
||||||
|
tmpRefId = pTmp->relation.nextRefId;
|
||||||
|
taosStopQueryImpl(pTmp);
|
||||||
|
releaseRequest(pTmp->self);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 " is not there", tmpRefId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void crashReportThreadFuncUnexpectedStopped(void) { atomic_store_32(&clientStop, -1); }
|
void crashReportThreadFuncUnexpectedStopped(void) { atomic_store_32(&clientStop, -1); }
|
||||||
|
|
||||||
static void *tscCrashReportThreadFp(void *param) {
|
static void *tscCrashReportThreadFp(void *param) {
|
||||||
|
|
|
@ -464,6 +464,7 @@ int32_t hbBuildQueryDesc(SQueryHbReqBasic *hbBasic, STscObj *pObj) {
|
||||||
desc.useconds = now - pRequest->metric.start;
|
desc.useconds = now - pRequest->metric.start;
|
||||||
desc.reqRid = pRequest->self;
|
desc.reqRid = pRequest->self;
|
||||||
desc.stableQuery = pRequest->stableQuery;
|
desc.stableQuery = pRequest->stableQuery;
|
||||||
|
desc.isSubQuery = pRequest->isSubReq;
|
||||||
taosGetFqdn(desc.fqdn);
|
taosGetFqdn(desc.fqdn);
|
||||||
desc.subPlanNum = pRequest->body.subplanNum;
|
desc.subPlanNum = pRequest->body.subplanNum;
|
||||||
|
|
||||||
|
|
|
@ -237,6 +237,17 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t buildPreviousRequest(SRequestObj *pRequest, const char* sql, SRequestObj** pNewRequest) {
|
||||||
|
int32_t code = buildRequest(pRequest->pTscObj->id, sql, strlen(sql), pRequest, pRequest->validateOnly, pNewRequest, 0);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
pRequest->relation.prevRefId = (*pNewRequest)->self;
|
||||||
|
(*pNewRequest)->relation.nextRefId = pRequest->self;
|
||||||
|
(*pNewRequest)->relation.userRefId = pRequest->self;
|
||||||
|
(*pNewRequest)->isSubReq = true;
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb) {
|
int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb) {
|
||||||
STscObj* pTscObj = pRequest->pTscObj;
|
STscObj* pTscObj = pRequest->pTscObj;
|
||||||
|
|
||||||
|
@ -878,6 +889,81 @@ static bool incompletaFileParsing(SNode* pStmt) {
|
||||||
return QUERY_NODE_VNODE_MODIFY_STMT != nodeType(pStmt) ? false : ((SVnodeModifyOpStmt*)pStmt)->fileProcessing;
|
return QUERY_NODE_VNODE_MODIFY_STMT != nodeType(pStmt) ? false : ((SVnodeModifyOpStmt*)pStmt)->fileProcessing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void continuePostSubQuery(SRequestObj* pRequest, TAOS_ROW row) {
|
||||||
|
SSqlCallbackWrapper* pWrapper = pRequest->pWrapper;
|
||||||
|
int32_t code = nodesAcquireAllocator(pWrapper->pParseCtx->allocatorId);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
int64_t analyseStart = taosGetTimestampUs();
|
||||||
|
code = qContinueParsePostQuery(pWrapper->pParseCtx, pRequest->pQuery, (void**)row);
|
||||||
|
pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = qContinuePlanPostQuery(pRequest->pPostPlan);
|
||||||
|
}
|
||||||
|
nodesReleaseAllocator(pWrapper->pParseCtx->allocatorId);
|
||||||
|
|
||||||
|
handleQueryAnslyseRes(pWrapper, NULL, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void returnToUser(SRequestObj* pRequest) {
|
||||||
|
if (pRequest->relation.userRefId == pRequest->self || 0 == pRequest->relation.userRefId) {
|
||||||
|
// return to client
|
||||||
|
pRequest->body.queryFp(pRequest->body.param, pRequest, pRequest->code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRequestObj* pUserReq = acquireRequest(pRequest->relation.userRefId);
|
||||||
|
if (pUserReq) {
|
||||||
|
pUserReq->code = pRequest->code;
|
||||||
|
// return to client
|
||||||
|
pUserReq->body.queryFp(pUserReq->body.param, pUserReq, pUserReq->code);
|
||||||
|
releaseRequest(pRequest->relation.userRefId);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 ", user ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pRequest->self,
|
||||||
|
pRequest->relation.userRefId, pRequest->requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void postSubQueryFetchCb(void* param, TAOS_RES* res, int32_t rowNum) {
|
||||||
|
SRequestObj* pRequest = (SRequestObj*)res;
|
||||||
|
if (pRequest->code) {
|
||||||
|
returnToUser(pRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_ROW row = NULL;
|
||||||
|
if (rowNum > 0) {
|
||||||
|
row = taos_fetch_row(res); // for single row only now
|
||||||
|
}
|
||||||
|
|
||||||
|
SRequestObj* pNextReq = acquireRequest(pRequest->relation.nextRefId);
|
||||||
|
if (pNextReq) {
|
||||||
|
continuePostSubQuery(pNextReq, row);
|
||||||
|
releaseRequest(pRequest->relation.nextRefId);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 ", next req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pRequest->self,
|
||||||
|
pRequest->relation.nextRefId, pRequest->requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePostSubQuery(SSqlCallbackWrapper* pWrapper) {
|
||||||
|
SRequestObj* pRequest = pWrapper->pRequest;
|
||||||
|
if (TD_RES_QUERY(pRequest)) {
|
||||||
|
taosAsyncFetchImpl(pRequest, postSubQueryFetchCb, pWrapper);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRequestObj* pNextReq = acquireRequest(pRequest->relation.nextRefId);
|
||||||
|
if (pNextReq) {
|
||||||
|
continuePostSubQuery(pNextReq, NULL);
|
||||||
|
releaseRequest(pRequest->relation.nextRefId);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 ", next req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pRequest->self,
|
||||||
|
pRequest->relation.nextRefId, pRequest->requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// todo refacto the error code mgmt
|
// todo refacto the error code mgmt
|
||||||
void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) {
|
void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) {
|
||||||
SSqlCallbackWrapper* pWrapper = param;
|
SSqlCallbackWrapper* pWrapper = param;
|
||||||
|
@ -912,12 +998,7 @@ void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) {
|
||||||
if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code) && pRequest->sqlstr != NULL) {
|
if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code) && pRequest->sqlstr != NULL) {
|
||||||
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%s, tryCount:%d, reqId:0x%" PRIx64, pRequest->self,
|
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%s, tryCount:%d, reqId:0x%" PRIx64, pRequest->self,
|
||||||
tstrerror(code), pRequest->retry, pRequest->requestId);
|
tstrerror(code), pRequest->retry, pRequest->requestId);
|
||||||
pRequest->prevCode = code;
|
restartAsyncQuery(pRequest, code);
|
||||||
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
|
||||||
qDestroyQuery(pRequest->pQuery);
|
|
||||||
pRequest->pQuery = NULL;
|
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
|
||||||
doAsyncQuery(pRequest, true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,10 +1019,15 @@ void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
if (pRequest->relation.nextRefId) {
|
||||||
|
handlePostSubQuery(pWrapper);
|
||||||
|
} else {
|
||||||
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
|
|
||||||
// return to client
|
// return to client
|
||||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res) {
|
SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res) {
|
||||||
|
@ -1049,6 +1135,7 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat
|
||||||
pRequest->requestId);
|
pRequest->requestId);
|
||||||
} else {
|
} else {
|
||||||
pRequest->body.subplanNum = pDag->numOfSubplans;
|
pRequest->body.subplanNum = pDag->numOfSubplans;
|
||||||
|
TSWAP(pRequest->pPostPlan, pDag->pPostPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
pRequest->metric.execStart = taosGetTimestampUs();
|
pRequest->metric.execStart = taosGetTimestampUs();
|
||||||
|
@ -1084,6 +1171,7 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat
|
||||||
tscDebug("0x%" PRIx64 " plan not executed, code:%s 0x%" PRIx64, pRequest->self, tstrerror(code),
|
tscDebug("0x%" PRIx64 " plan not executed, code:%s 0x%" PRIx64, pRequest->self, tstrerror(code),
|
||||||
pRequest->requestId);
|
pRequest->requestId);
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
pRequest->code = terrno;
|
pRequest->code = terrno;
|
||||||
}
|
}
|
||||||
|
@ -1103,6 +1191,7 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultM
|
||||||
pRequest->body.execMode = pQuery->execMode;
|
pRequest->body.execMode = pQuery->execMode;
|
||||||
if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
|
if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery->pRoot && !pRequest->inRetry) {
|
if (pQuery->pRoot && !pRequest->inRetry) {
|
||||||
|
@ -2402,3 +2491,90 @@ TAOS_RES* taosQueryImplWithReqid(TAOS* taos, const char* sql, bool validateOnly,
|
||||||
|
|
||||||
return pRequest;
|
return pRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fetchCallback(void *pResult, void *param, int32_t code) {
|
||||||
|
SRequestObj *pRequest = (SRequestObj *)param;
|
||||||
|
|
||||||
|
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
|
||||||
|
|
||||||
|
tscDebug("0x%" PRIx64 " enter scheduler fetch cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code,
|
||||||
|
tstrerror(code), pRequest->requestId);
|
||||||
|
|
||||||
|
pResultInfo->pData = pResult;
|
||||||
|
pResultInfo->numOfRows = 0;
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pRequest->code = code;
|
||||||
|
taosMemoryFreeClear(pResultInfo->pData);
|
||||||
|
pRequest->body.fetchFp(pRequest->body.param, pRequest, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFreeClear(pResultInfo->pData);
|
||||||
|
pRequest->body.fetchFp(pRequest->body.param, pRequest, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequest->code =
|
||||||
|
setQueryResultFromRsp(pResultInfo, (const SRetrieveTableRsp *)pResultInfo->pData, pResultInfo->convertUcs4, true);
|
||||||
|
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||||
|
pResultInfo->numOfRows = 0;
|
||||||
|
pRequest->code = code;
|
||||||
|
tscError("0x%" PRIx64 " fetch results failed, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code),
|
||||||
|
pRequest->requestId);
|
||||||
|
} else {
|
||||||
|
tscDebug("0x%" PRIx64 " fetch results, numOfRows:%" PRId64 " total Rows:%" PRId64 ", complete:%d, reqId:0x%" PRIx64,
|
||||||
|
pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed,
|
||||||
|
pRequest->requestId);
|
||||||
|
|
||||||
|
STscObj *pTscObj = pRequest->pTscObj;
|
||||||
|
SAppClusterSummary *pActivity = &pTscObj->pAppInfo->summary;
|
||||||
|
atomic_add_fetch_64((int64_t *)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosAsyncFetchImpl(SRequestObj *pRequest, __taos_async_fn_t fp, void *param) {
|
||||||
|
pRequest->body.fetchFp = fp;
|
||||||
|
pRequest->body.param = param;
|
||||||
|
|
||||||
|
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
|
||||||
|
|
||||||
|
// this query has no results or error exists, return directly
|
||||||
|
if (taos_num_fields(pRequest) == 0 || pRequest->code != TSDB_CODE_SUCCESS) {
|
||||||
|
pResultInfo->numOfRows = 0;
|
||||||
|
pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all data has returned to App already, no need to try again
|
||||||
|
if (pResultInfo->completed) {
|
||||||
|
// it is a local executed query, no need to do async fetch
|
||||||
|
if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
|
||||||
|
if (pResultInfo->localResultFetched) {
|
||||||
|
pResultInfo->numOfRows = 0;
|
||||||
|
pResultInfo->current = 0;
|
||||||
|
} else {
|
||||||
|
pResultInfo->localResultFetched = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pResultInfo->numOfRows = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSchedulerReq req = {
|
||||||
|
.syncReq = false,
|
||||||
|
.fetchFp = fetchCallback,
|
||||||
|
.cbParam = pRequest,
|
||||||
|
};
|
||||||
|
|
||||||
|
schedulerFetchRows(pRequest->body.queryJob, &req);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -563,22 +563,13 @@ int taos_select_db(TAOS *taos, const char *db) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void taos_stop_query(TAOS_RES *res) {
|
void taos_stop_query(TAOS_RES *res) {
|
||||||
if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res)) {
|
if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRequestObj *pRequest = (SRequestObj *)res;
|
stopAllQueries((SRequestObj*)res);
|
||||||
pRequest->killed = true;
|
|
||||||
|
|
||||||
// It is not a query, no need to stop.
|
|
||||||
if (NULL == pRequest->pQuery || QUERY_EXEC_MODE_SCHEDULE != pRequest->pQuery->execMode) {
|
|
||||||
tscDebug("request 0x%" PRIx64 " no need to be killed since not query", pRequest->requestId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
schedulerFreeJob(&pRequest->body.queryJob, TSDB_CODE_TSC_QUERY_KILLED);
|
|
||||||
tscDebug("request %" PRIx64 " killed", pRequest->requestId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
||||||
|
@ -774,8 +765,13 @@ static void destoryCatalogReq(SCatalogReq *pCatalogReq) {
|
||||||
taosArrayDestroy(pCatalogReq->pDbVgroup);
|
taosArrayDestroy(pCatalogReq->pDbVgroup);
|
||||||
taosArrayDestroy(pCatalogReq->pDbCfg);
|
taosArrayDestroy(pCatalogReq->pDbCfg);
|
||||||
taosArrayDestroy(pCatalogReq->pDbInfo);
|
taosArrayDestroy(pCatalogReq->pDbInfo);
|
||||||
taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
|
if (pCatalogReq->cloned) {
|
||||||
taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
|
taosArrayDestroy(pCatalogReq->pTableMeta);
|
||||||
|
taosArrayDestroy(pCatalogReq->pTableHash);
|
||||||
|
} else {
|
||||||
|
taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
|
||||||
|
taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
|
||||||
|
}
|
||||||
taosArrayDestroy(pCatalogReq->pUdf);
|
taosArrayDestroy(pCatalogReq->pUdf);
|
||||||
taosArrayDestroy(pCatalogReq->pIndex);
|
taosArrayDestroy(pCatalogReq->pIndex);
|
||||||
taosArrayDestroy(pCatalogReq->pUser);
|
taosArrayDestroy(pCatalogReq->pUser);
|
||||||
|
@ -794,26 +790,108 @@ void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
|
||||||
taosMemoryFree(pWrapper);
|
taosMemoryFree(pWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyCtxInRequest(SRequestObj* pRequest) {
|
||||||
|
schedulerFreeJob(&pRequest->body.queryJob, 0);
|
||||||
|
qDestroyQuery(pRequest->pQuery);
|
||||||
|
pRequest->pQuery = NULL;
|
||||||
|
destorySqlCallbackWrapper(pRequest->pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
|
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
|
||||||
SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
|
SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
|
||||||
SRequestObj *pRequest = pWrapper->pRequest;
|
SRequestObj *pRequest = pWrapper->pRequest;
|
||||||
SQuery *pQuery = pRequest->pQuery;
|
SQuery *pQuery = pRequest->pQuery;
|
||||||
|
|
||||||
int64_t analyseStart = taosGetTimestampUs();
|
|
||||||
pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
|
|
||||||
qDebug("0x%" PRIx64 " start to semantic analysis, reqId:0x%" PRIx64, pRequest->self, pRequest->requestId);
|
qDebug("0x%" PRIx64 " start to semantic analysis, reqId:0x%" PRIx64, pRequest->self, pRequest->requestId);
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
int64_t analyseStart = taosGetTimestampUs();
|
||||||
|
pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
|
code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
|
||||||
|
|
||||||
|
handleQueryAnslyseRes(pWrapper, pResultMeta, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t cloneCatalogReq(SCatalogReq* * ppTarget, SCatalogReq* pSrc) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SCatalogReq* pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
|
||||||
|
if (pTarget == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
|
||||||
|
pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
|
||||||
|
pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
|
||||||
|
pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
|
||||||
|
pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
|
||||||
|
pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
|
||||||
|
pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
|
||||||
|
pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
|
||||||
|
pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
|
||||||
|
pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
|
||||||
|
pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
|
||||||
|
pTarget->qNodeRequired = pSrc->qNodeRequired;
|
||||||
|
pTarget->dNodeRequired = pSrc->dNodeRequired;
|
||||||
|
pTarget->svrVerRequired = pSrc->svrVerRequired;
|
||||||
|
pTarget->forceUpdate = pSrc->forceUpdate;
|
||||||
|
pTarget->cloned = true;
|
||||||
|
|
||||||
|
*ppTarget = pTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode* pRoot) {
|
||||||
|
SRequestObj* pNewRequest = NULL;
|
||||||
|
SSqlCallbackWrapper* pNewWrapper = NULL;
|
||||||
|
int32_t code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
|
||||||
|
if (code) {
|
||||||
|
handleQueryAnslyseRes(pWrapper, pResultMeta, code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNewRequest->pQuery = (SQuery*)nodesMakeNode(QUERY_NODE_QUERY);
|
||||||
|
if (NULL == pNewRequest->pQuery) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
pNewRequest->pQuery->pRoot = pRoot;
|
||||||
|
pRoot = NULL;
|
||||||
|
pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
|
||||||
|
}
|
||||||
|
doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
|
||||||
|
nodesDestroyNode(pRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
|
||||||
|
SRequestObj *pRequest = pWrapper->pRequest;
|
||||||
|
SQuery *pQuery = pRequest->pQuery;
|
||||||
|
|
||||||
|
if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
|
||||||
|
SNode* prevRoot = pQuery->pPrevRoot;
|
||||||
|
pQuery->pPrevRoot = NULL;
|
||||||
|
handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
pRequest->stableQuery = pQuery->stableQuery;
|
pRequest->stableQuery = pQuery->stableQuery;
|
||||||
if (pQuery->pRoot) {
|
if (pQuery->pRoot) {
|
||||||
pRequest->stmtType = pQuery->pRoot->type;
|
pRequest->stmtType = pQuery->pRoot->type;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pRequest->metric.analyseCostUs = taosGetTimestampUs() - analyseStart;
|
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
if (pQuery->haveResultSet) {
|
if (pQuery->haveResultSet) {
|
||||||
setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
|
setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
|
||||||
setResPrecision(&pRequest->body.resInfo, pQuery->precision);
|
setResPrecision(&pRequest->body.resInfo, pQuery->precision);
|
||||||
|
@ -826,14 +904,14 @@ static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t
|
||||||
launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
|
launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
|
||||||
} else {
|
} else {
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
qDestroyQuery(pRequest->pQuery);
|
qDestroyQuery(pRequest->pQuery);
|
||||||
pRequest->pQuery = NULL;
|
pRequest->pQuery = NULL;
|
||||||
|
|
||||||
if (NEED_CLIENT_HANDLE_ERROR(code)) {
|
if (NEED_CLIENT_HANDLE_ERROR(code)) {
|
||||||
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64,
|
tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%" PRIx64,
|
||||||
pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
|
pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
|
||||||
pRequest->prevCode = code;
|
restartAsyncQuery(pRequest, code);
|
||||||
doAsyncQuery(pRequest, true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +919,7 @@ static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t
|
||||||
tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:0x%" PRIx64, pRequest->self,
|
tscError("0x%" PRIx64 " error occurs, code:%s, return to user app, reqId:0x%" PRIx64, pRequest->self,
|
||||||
tstrerror(code), pRequest->requestId);
|
tstrerror(code), pRequest->requestId);
|
||||||
pRequest->code = code;
|
pRequest->code = code;
|
||||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
returnToUser(pRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,6 +982,7 @@ static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t c
|
||||||
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
|
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
|
||||||
tstrerror(code), pWrapper->pRequest->requestId);
|
tstrerror(code), pWrapper->pRequest->requestId);
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
terrno = code;
|
terrno = code;
|
||||||
pRequest->code = code;
|
pRequest->code = code;
|
||||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||||
|
@ -920,6 +999,7 @@ void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest)
|
||||||
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
|
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pWrapper->pRequest->self, code,
|
||||||
tstrerror(code), pWrapper->pRequest->requestId);
|
tstrerror(code), pWrapper->pRequest->requestId);
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
terrno = code;
|
terrno = code;
|
||||||
pRequest->code = code;
|
pRequest->code = code;
|
||||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||||
|
@ -967,27 +1047,16 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
STscObj *pTscObj = pRequest->pTscObj;
|
STscObj *pTscObj = pRequest->pTscObj;
|
||||||
SSqlCallbackWrapper *pWrapper = NULL;
|
SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
if (pWrapper == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
|
} else {
|
||||||
code = pRequest->prevCode;
|
pWrapper->pRequest = pRequest;
|
||||||
terrno = code;
|
pRequest->pWrapper = pWrapper;
|
||||||
pRequest->code = code;
|
*ppWrapper = pWrapper;
|
||||||
tscDebug("call sync query cb with code: %s", tstrerror(code));
|
|
||||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
|
|
||||||
if (pWrapper == NULL) {
|
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
} else {
|
|
||||||
pWrapper->pRequest = pRequest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -999,7 +1068,7 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
|
code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
|
||||||
int64_t syntaxStart = taosGetTimestampUs();
|
int64_t syntaxStart = taosGetTimestampUs();
|
||||||
|
|
||||||
pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
|
pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
|
||||||
|
@ -1014,6 +1083,27 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
|
pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
|
SSqlCallbackWrapper *pWrapper = NULL;
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
|
||||||
|
code = pRequest->prevCode;
|
||||||
|
terrno = code;
|
||||||
|
pRequest->code = code;
|
||||||
|
tscDebug("call sync query cb with code: %s", tstrerror(code));
|
||||||
|
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
|
||||||
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pRequest->stmtType = pRequest->pQuery->pRoot->type;
|
pRequest->stmtType = pRequest->pQuery->pRoot->type;
|
||||||
code = phaseAsyncQuery(pWrapper);
|
code = phaseAsyncQuery(pWrapper);
|
||||||
|
@ -1023,6 +1113,7 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code),
|
tscError("0x%" PRIx64 " error happens, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code, tstrerror(code),
|
||||||
pRequest->requestId);
|
pRequest->requestId);
|
||||||
destorySqlCallbackWrapper(pWrapper);
|
destorySqlCallbackWrapper(pWrapper);
|
||||||
|
pRequest->pWrapper = NULL;
|
||||||
qDestroyQuery(pRequest->pQuery);
|
qDestroyQuery(pRequest->pQuery);
|
||||||
pRequest->pQuery = NULL;
|
pRequest->pQuery = NULL;
|
||||||
|
|
||||||
|
@ -1040,48 +1131,57 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fetchCallback(void *pResult, void *param, int32_t code) {
|
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
|
||||||
SRequestObj *pRequest = (SRequestObj *)param;
|
int32_t reqIdx = 0;
|
||||||
|
SRequestObj *pReqList[16] = {NULL};
|
||||||
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
|
SRequestObj *pUserReq = NULL;
|
||||||
|
pReqList[0] = pRequest;
|
||||||
tscDebug("0x%" PRIx64 " enter scheduler fetch cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code,
|
uint64_t tmpRefId = 0;
|
||||||
tstrerror(code), pRequest->requestId);
|
SRequestObj* pTmp = pRequest;
|
||||||
|
while (pTmp->relation.prevRefId) {
|
||||||
pResultInfo->pData = pResult;
|
tmpRefId = pTmp->relation.prevRefId;
|
||||||
pResultInfo->numOfRows = 0;
|
pTmp = acquireRequest(tmpRefId);
|
||||||
|
if (pTmp) {
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
pReqList[++reqIdx] = pTmp;
|
||||||
pRequest->code = code;
|
releaseRequest(tmpRefId);
|
||||||
taosMemoryFreeClear(pResultInfo->pData);
|
} else {
|
||||||
pRequest->body.fetchFp(pRequest->body.param, pRequest, 0);
|
tscError("0x%" PRIx64 ", prev req ref 0x%" PRIx64 " is not there, reqId:0x%" PRIx64, pTmp->self,
|
||||||
return;
|
tmpRefId, pTmp->requestId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
tmpRefId = pRequest->relation.nextRefId;
|
||||||
taosMemoryFreeClear(pResultInfo->pData);
|
while (tmpRefId) {
|
||||||
pRequest->body.fetchFp(pRequest->body.param, pRequest, 0);
|
pTmp = acquireRequest(tmpRefId);
|
||||||
return;
|
if (pTmp) {
|
||||||
|
tmpRefId = pTmp->relation.nextRefId;
|
||||||
|
removeRequest(pTmp->self);
|
||||||
|
releaseRequest(pTmp->self);
|
||||||
|
} else {
|
||||||
|
tscError("0x%" PRIx64 " is not there", tmpRefId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pRequest->code =
|
for (int32_t i = reqIdx; i >= 0; i--) {
|
||||||
setQueryResultFromRsp(pResultInfo, (const SRetrieveTableRsp *)pResultInfo->pData, pResultInfo->convertUcs4, true);
|
destroyCtxInRequest(pReqList[i]);
|
||||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
if (pReqList[i]->relation.userRefId == pReqList[i]->self || 0 == pReqList[i]->relation.userRefId) {
|
||||||
pResultInfo->numOfRows = 0;
|
pUserReq = pReqList[i];
|
||||||
pRequest->code = code;
|
} else {
|
||||||
tscError("0x%" PRIx64 " fetch results failed, code:%s, reqId:0x%" PRIx64, pRequest->self, tstrerror(code),
|
removeRequest(pReqList[i]->self);
|
||||||
pRequest->requestId);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUserReq) {
|
||||||
|
pUserReq->prevCode = code;
|
||||||
|
memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
|
||||||
} else {
|
} else {
|
||||||
tscDebug("0x%" PRIx64 " fetch results, numOfRows:%" PRId64 " total Rows:%" PRId64 ", complete:%d, reqId:0x%" PRIx64,
|
tscError("user req is missing");
|
||||||
pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed,
|
return;
|
||||||
pRequest->requestId);
|
|
||||||
|
|
||||||
STscObj *pTscObj = pRequest->pTscObj;
|
|
||||||
SAppClusterSummary *pActivity = &pTscObj->pAppInfo->summary;
|
|
||||||
atomic_add_fetch_64((int64_t *)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pRequest->body.fetchFp(pRequest->body.param, pRequest, pResultInfo->numOfRows);
|
doAsyncQuery(pUserReq, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
||||||
|
@ -1095,43 +1195,8 @@ void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SRequestObj *pRequest = res;
|
SRequestObj *pRequest = res;
|
||||||
pRequest->body.fetchFp = fp;
|
|
||||||
pRequest->body.param = param;
|
|
||||||
|
|
||||||
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
|
taosAsyncFetchImpl(pRequest, fp, param);
|
||||||
|
|
||||||
// this query has no results or error exists, return directly
|
|
||||||
if (taos_num_fields(pRequest) == 0 || pRequest->code != TSDB_CODE_SUCCESS) {
|
|
||||||
pResultInfo->numOfRows = 0;
|
|
||||||
pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// all data has returned to App already, no need to try again
|
|
||||||
if (pResultInfo->completed) {
|
|
||||||
// it is a local executed query, no need to do async fetch
|
|
||||||
if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
|
|
||||||
if (pResultInfo->localResultFetched) {
|
|
||||||
pResultInfo->numOfRows = 0;
|
|
||||||
pResultInfo->current = 0;
|
|
||||||
} else {
|
|
||||||
pResultInfo->localResultFetched = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pResultInfo->numOfRows = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSchedulerReq req = {
|
|
||||||
.syncReq = false,
|
|
||||||
.fetchFp = fetchCallback,
|
|
||||||
.cbParam = pRequest,
|
|
||||||
};
|
|
||||||
|
|
||||||
schedulerFetchRows(pRequest->body.queryJob, &req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
|
||||||
|
|
|
@ -77,6 +77,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((code = taosCheckVersionCompatibleFromStr(version, connectRsp.sVer, 3)) != 0) {
|
if ((code = taosCheckVersionCompatibleFromStr(version, connectRsp.sVer, 3)) != 0) {
|
||||||
|
tscError("version not compatible. client version: %s, server version: %s", version, connectRsp.sVer);
|
||||||
setErrno(pRequest, code);
|
setErrno(pRequest, code);
|
||||||
tsem_post(&pRequest->body.rspSem);
|
tsem_post(&pRequest->body.rspSem);
|
||||||
goto End;
|
goto End;
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct tmq_t {
|
||||||
int8_t useSnapshot;
|
int8_t useSnapshot;
|
||||||
int8_t autoCommit;
|
int8_t autoCommit;
|
||||||
int32_t autoCommitInterval;
|
int32_t autoCommitInterval;
|
||||||
int32_t resetOffsetCfg;
|
int8_t resetOffsetCfg;
|
||||||
uint64_t consumerId;
|
uint64_t consumerId;
|
||||||
bool hbBgEnable;
|
bool hbBgEnable;
|
||||||
tmq_commit_cb* commitCb;
|
tmq_commit_cb* commitCb;
|
||||||
|
@ -99,6 +99,7 @@ struct tmq_t {
|
||||||
// poll info
|
// poll info
|
||||||
int64_t pollCnt;
|
int64_t pollCnt;
|
||||||
int64_t totalRows;
|
int64_t totalRows;
|
||||||
|
bool needReportOffsetRows;
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
tmr_h hbLiveTimer;
|
tmr_h hbLiveTimer;
|
||||||
|
@ -264,7 +265,7 @@ tmq_conf_t* tmq_conf_new() {
|
||||||
conf->withTbName = false;
|
conf->withTbName = false;
|
||||||
conf->autoCommit = true;
|
conf->autoCommit = true;
|
||||||
conf->autoCommitInterval = DEFAULT_AUTO_COMMIT_INTERVAL;
|
conf->autoCommitInterval = DEFAULT_AUTO_COMMIT_INTERVAL;
|
||||||
conf->resetOffset = TMQ_OFFSET__RESET_EARLIEAST;
|
conf->resetOffset = TMQ_OFFSET__RESET_EARLIEST;
|
||||||
conf->hbBgEnable = true;
|
conf->hbBgEnable = true;
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
|
@ -318,7 +319,7 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
||||||
conf->resetOffset = TMQ_OFFSET__RESET_NONE;
|
conf->resetOffset = TMQ_OFFSET__RESET_NONE;
|
||||||
return TMQ_CONF_OK;
|
return TMQ_CONF_OK;
|
||||||
} else if (strcasecmp(value, "earliest") == 0) {
|
} else if (strcasecmp(value, "earliest") == 0) {
|
||||||
conf->resetOffset = TMQ_OFFSET__RESET_EARLIEAST;
|
conf->resetOffset = TMQ_OFFSET__RESET_EARLIEST;
|
||||||
return TMQ_CONF_OK;
|
return TMQ_CONF_OK;
|
||||||
} else if (strcasecmp(value, "latest") == 0) {
|
} else if (strcasecmp(value, "latest") == 0) {
|
||||||
conf->resetOffset = TMQ_OFFSET__RESET_LATEST;
|
conf->resetOffset = TMQ_OFFSET__RESET_LATEST;
|
||||||
|
@ -357,7 +358,7 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
||||||
return TMQ_CONF_OK;
|
return TMQ_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(key, "enable.heartbeat.background") == 0) {
|
// if (strcasecmp(key, "enable.heartbeat.background") == 0) {
|
||||||
// if (strcasecmp(value, "true") == 0) {
|
// if (strcasecmp(value, "true") == 0) {
|
||||||
// conf->hbBgEnable = true;
|
// conf->hbBgEnable = true;
|
||||||
// return TMQ_CONF_OK;
|
// return TMQ_CONF_OK;
|
||||||
|
@ -365,10 +366,10 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
||||||
// conf->hbBgEnable = false;
|
// conf->hbBgEnable = false;
|
||||||
// return TMQ_CONF_OK;
|
// return TMQ_CONF_OK;
|
||||||
// } else {
|
// } else {
|
||||||
tscError("the default value of enable.heartbeat.background is true, can not be seted");
|
// tscError("the default value of enable.heartbeat.background is true, can not be seted");
|
||||||
return TMQ_CONF_INVALID;
|
// return TMQ_CONF_INVALID;
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (strcasecmp(key, "td.connect.ip") == 0) {
|
if (strcasecmp(key, "td.connect.ip") == 0) {
|
||||||
conf->ip = taosStrdup(value);
|
conf->ip = taosStrdup(value);
|
||||||
|
@ -422,30 +423,30 @@ char** tmq_list_to_c_array(const tmq_list_t* list) {
|
||||||
return container->pData;
|
return container->pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SMqClientVg* foundClientVg(SArray* pTopicList, const char* pName, int32_t vgId, int32_t* index,
|
//static SMqClientVg* foundClientVg(SArray* pTopicList, const char* pName, int32_t vgId, int32_t* index,
|
||||||
int32_t* numOfVgroups) {
|
// int32_t* numOfVgroups) {
|
||||||
int32_t numOfTopics = taosArrayGetSize(pTopicList);
|
// int32_t numOfTopics = taosArrayGetSize(pTopicList);
|
||||||
*index = -1;
|
// *index = -1;
|
||||||
*numOfVgroups = 0;
|
// *numOfVgroups = 0;
|
||||||
|
//
|
||||||
for (int32_t i = 0; i < numOfTopics; ++i) {
|
// for (int32_t i = 0; i < numOfTopics; ++i) {
|
||||||
SMqClientTopic* pTopic = taosArrayGet(pTopicList, i);
|
// SMqClientTopic* pTopic = taosArrayGet(pTopicList, i);
|
||||||
if (strcmp(pTopic->topicName, pName) != 0) {
|
// if (strcmp(pTopic->topicName, pName) != 0) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
*numOfVgroups = taosArrayGetSize(pTopic->vgs);
|
// *numOfVgroups = taosArrayGetSize(pTopic->vgs);
|
||||||
for (int32_t j = 0; j < (*numOfVgroups); ++j) {
|
// for (int32_t j = 0; j < (*numOfVgroups); ++j) {
|
||||||
SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, j);
|
// SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, j);
|
||||||
if (pClientVg->vgId == vgId) {
|
// if (pClientVg->vgId == vgId) {
|
||||||
*index = j;
|
// *index = j;
|
||||||
return pClientVg;
|
// return pClientVg;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return NULL;
|
// return NULL;
|
||||||
}
|
//}
|
||||||
|
|
||||||
// Two problems do not need to be addressed here
|
// Two problems do not need to be addressed here
|
||||||
// 1. update to of epset. the response of poll request will automatically handle this problem
|
// 1. update to of epset. the response of poll request will automatically handle this problem
|
||||||
|
@ -567,12 +568,12 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN
|
||||||
atomic_add_fetch_32(&pParamSet->totalRspNum, 1);
|
atomic_add_fetch_32(&pParamSet->totalRspNum, 1);
|
||||||
|
|
||||||
SEp* pEp = GET_ACTIVE_EP(&pVg->epSet);
|
SEp* pEp = GET_ACTIVE_EP(&pVg->epSet);
|
||||||
char offsetBuf[80] = {0};
|
char offsetBuf[TSDB_OFFSET_LEN] = {0};
|
||||||
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->offset.val);
|
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->offset.val);
|
||||||
|
|
||||||
char commitBuf[80] = {0};
|
char commitBuf[TSDB_OFFSET_LEN] = {0};
|
||||||
tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->offsetInfo.committedOffset);
|
tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->offsetInfo.committedOffset);
|
||||||
tscDebug("consumer:0x%" PRIx64 " topic:%s on vgId:%d send offset:%s prev:%s, ep:%s:%d, ordinal:%d/%d, req:0x%" PRIx64,
|
tscInfo("consumer:0x%" PRIx64 " topic:%s on vgId:%d send offset:%s prev:%s, ep:%s:%d, ordinal:%d/%d, req:0x%" PRIx64,
|
||||||
tmq->consumerId, pOffset->offset.subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1,
|
tmq->consumerId, pOffset->offset.subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1,
|
||||||
totalVgroups, pMsgSendInfo->requestId);
|
totalVgroups, pMsgSendInfo->requestId);
|
||||||
|
|
||||||
|
@ -796,6 +797,27 @@ void tmqSendHbReq(void* param, void* tmrId) {
|
||||||
SMqHbReq req = {0};
|
SMqHbReq req = {0};
|
||||||
req.consumerId = tmq->consumerId;
|
req.consumerId = tmq->consumerId;
|
||||||
req.epoch = tmq->epoch;
|
req.epoch = tmq->epoch;
|
||||||
|
if(tmq->needReportOffsetRows){
|
||||||
|
req.topics = taosArrayInit(taosArrayGetSize(tmq->clientTopics), sizeof(TopicOffsetRows));
|
||||||
|
for(int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++){
|
||||||
|
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||||
|
int32_t numOfVgroups = taosArrayGetSize(pTopic->vgs);
|
||||||
|
TopicOffsetRows* data = taosArrayReserve(req.topics, 1);
|
||||||
|
strcpy(data->topicName, pTopic->topicName);
|
||||||
|
data->offsetRows = taosArrayInit(numOfVgroups, sizeof(OffsetRows));
|
||||||
|
for(int j = 0; j < numOfVgroups; j++){
|
||||||
|
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||||
|
OffsetRows* offRows = taosArrayReserve(data->offsetRows, 1);
|
||||||
|
offRows->vgId = pVg->vgId;
|
||||||
|
offRows->rows = pVg->numOfRows;
|
||||||
|
offRows->offset = pVg->offsetInfo.committedOffset;
|
||||||
|
char buf[TSDB_OFFSET_LEN] = {0};
|
||||||
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &offRows->offset);
|
||||||
|
tscInfo("report offset: vgId:%d, offset:%s, rows:%"PRId64, offRows->vgId, buf, offRows->rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmq->needReportOffsetRows = false;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tlen = tSerializeSMqHbReq(NULL, 0, &req);
|
int32_t tlen = tSerializeSMqHbReq(NULL, 0, &req);
|
||||||
if (tlen < 0) {
|
if (tlen < 0) {
|
||||||
|
@ -835,13 +857,14 @@ void tmqSendHbReq(void* param, void* tmrId) {
|
||||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
||||||
|
|
||||||
OVER:
|
OVER:
|
||||||
|
tDeatroySMqHbReq(&req);
|
||||||
taosTmrReset(tmqSendHbReq, 1000, param, tmqMgmt.timer, &tmq->hbLiveTimer);
|
taosTmrReset(tmqSendHbReq, 1000, param, tmqMgmt.timer, &tmq->hbLiveTimer);
|
||||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void defaultCommitCbFn(tmq_t* pTmq, int32_t code, void* param) {
|
static void defaultCommitCbFn(tmq_t* pTmq, int32_t code, void* param) {
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
tscDebug("consumer:0x%" PRIx64 ", failed to commit offset, code:%s", pTmq->consumerId, tstrerror(code));
|
tscError("consumer:0x%" PRIx64 ", failed to commit offset, code:%s", pTmq->consumerId, tstrerror(code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,6 +992,14 @@ int32_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tmq_unsubscribe(tmq_t* tmq) {
|
int32_t tmq_unsubscribe(tmq_t* tmq) {
|
||||||
|
if (tmq->autoCommit) {
|
||||||
|
int32_t rsp = tmq_commit_sync(tmq, NULL);
|
||||||
|
if (rsp != 0) {
|
||||||
|
return rsp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taosSsleep(2); // sleep 2s for hb to send offset and rows to server
|
||||||
|
|
||||||
int32_t rsp;
|
int32_t rsp;
|
||||||
int32_t retryCnt = 0;
|
int32_t retryCnt = 0;
|
||||||
tmq_list_t* lst = tmq_list_new();
|
tmq_list_t* lst = tmq_list_new();
|
||||||
|
@ -1063,6 +1094,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
||||||
pTmq->status = TMQ_CONSUMER_STATUS__INIT;
|
pTmq->status = TMQ_CONSUMER_STATUS__INIT;
|
||||||
pTmq->pollCnt = 0;
|
pTmq->pollCnt = 0;
|
||||||
pTmq->epoch = 0;
|
pTmq->epoch = 0;
|
||||||
|
pTmq->needReportOffsetRows = true;
|
||||||
|
|
||||||
// set conf
|
// set conf
|
||||||
strcpy(pTmq->clientId, conf->clientId);
|
strcpy(pTmq->clientId, conf->clientId);
|
||||||
|
@ -1107,7 +1139,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
||||||
pTmq->hbLiveTimer = taosTmrStart(tmqSendHbReq, 1000, pRefId, tmqMgmt.timer);
|
pTmq->hbLiveTimer = taosTmrStart(tmqSendHbReq, 1000, pRefId, tmqMgmt.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[80] = {0};
|
char buf[TSDB_OFFSET_LEN] = {0};
|
||||||
STqOffsetVal offset = {.type = pTmq->resetOffsetCfg};
|
STqOffsetVal offset = {.type = pTmq->resetOffsetCfg};
|
||||||
tFormatOffset(buf, tListLen(buf), &offset);
|
tFormatOffset(buf, tListLen(buf), &offset);
|
||||||
tscInfo("consumer:0x%" PRIx64 " is setup, refId:%" PRId64
|
tscInfo("consumer:0x%" PRIx64 " is setup, refId:%" PRId64
|
||||||
|
@ -1123,7 +1155,7 @@ _failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||||
const int32_t MAX_RETRY_COUNT = 120 * 60; // let's wait for 2 mins at most
|
const int32_t MAX_RETRY_COUNT = 120 * 2; // let's wait for 2 mins at most
|
||||||
const SArray* container = &topic_list->container;
|
const SArray* container = &topic_list->container;
|
||||||
int32_t sz = taosArrayGetSize(container);
|
int32_t sz = taosArrayGetSize(container);
|
||||||
void* buf = NULL;
|
void* buf = NULL;
|
||||||
|
@ -1131,7 +1163,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||||
SCMSubscribeReq req = {0};
|
SCMSubscribeReq req = {0};
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " cgroup:%s, subscribe %d topics", tmq->consumerId, tmq->groupId, sz);
|
tscInfo("consumer:0x%" PRIx64 " cgroup:%s, subscribe %d topics", tmq->consumerId, tmq->groupId, sz);
|
||||||
|
|
||||||
req.consumerId = tmq->consumerId;
|
req.consumerId = tmq->consumerId;
|
||||||
tstrncpy(req.clientId, tmq->clientId, 256);
|
tstrncpy(req.clientId, tmq->clientId, 256);
|
||||||
|
@ -1143,6 +1175,11 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.withTbName = tmq->withTbName;
|
||||||
|
req.autoCommit = tmq->autoCommit;
|
||||||
|
req.autoCommitInterval = tmq->autoCommitInterval;
|
||||||
|
req.resetOffsetCfg = tmq->resetOffsetCfg;
|
||||||
|
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
char* topic = taosArrayGetP(container, i);
|
char* topic = taosArrayGetP(container, i);
|
||||||
|
|
||||||
|
@ -1154,7 +1191,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tNameExtractFullName(&name, topicFName);
|
tNameExtractFullName(&name, topicFName);
|
||||||
tscDebug("consumer:0x%" PRIx64 " subscribe topic:%s", tmq->consumerId, topicFName);
|
tscInfo("consumer:0x%" PRIx64 " subscribe topic:%s", tmq->consumerId, topicFName);
|
||||||
|
|
||||||
taosArrayPush(req.topicNames, &topicFName);
|
taosArrayPush(req.topicNames, &topicFName);
|
||||||
}
|
}
|
||||||
|
@ -1215,7 +1252,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 ", mnd not ready for subscribe, retry:%d in 500ms", tmq->consumerId, retryCnt);
|
tscInfo("consumer:0x%" PRIx64 ", mnd not ready for subscribe, retry:%d in 500ms", tmq->consumerId, retryCnt);
|
||||||
taosMsleep(500);
|
taosMsleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1375,8 +1412,8 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead));
|
memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||||
|
|
||||||
char buf[80];
|
char buf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(buf, 80, &pRspWrapper->dataRsp.rspOffset);
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &pRspWrapper->dataRsp.rspOffset);
|
||||||
tscDebug("consumer:0x%" PRIx64 " recv poll rsp, vgId:%d, req ver:%" PRId64 ", rsp:%s type %d, reqId:0x%" PRIx64,
|
tscDebug("consumer:0x%" PRIx64 " recv poll rsp, vgId:%d, req ver:%" PRId64 ", rsp:%s type %d, reqId:0x%" PRIx64,
|
||||||
tmq->consumerId, vgId, pRspWrapper->dataRsp.reqOffset.version, buf, rspType, requestId);
|
tmq->consumerId, vgId, pRspWrapper->dataRsp.reqOffset.version, buf, rspType, requestId);
|
||||||
} else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
} else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||||
|
@ -1442,7 +1479,7 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
||||||
tstrncpy(pTopic->topicName, pTopicEp->topic, TSDB_TOPIC_FNAME_LEN);
|
tstrncpy(pTopic->topicName, pTopicEp->topic, TSDB_TOPIC_FNAME_LEN);
|
||||||
tstrncpy(pTopic->db, pTopicEp->db, TSDB_DB_FNAME_LEN);
|
tstrncpy(pTopic->db, pTopicEp->db, TSDB_DB_FNAME_LEN);
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
|
tscInfo("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
|
||||||
pTopic->vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
|
pTopic->vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
|
||||||
|
|
||||||
for (int32_t j = 0; j < vgNumGet; j++) {
|
for (int32_t j = 0; j < vgNumGet; j++) {
|
||||||
|
@ -1495,7 +1532,7 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
||||||
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
||||||
|
|
||||||
char vgKey[TSDB_TOPIC_FNAME_LEN + 22];
|
char vgKey[TSDB_TOPIC_FNAME_LEN + 22];
|
||||||
tscDebug("consumer:0x%" PRIx64 " update ep epoch from %d to epoch %d, incoming topics:%d, existed topics:%d",
|
tscInfo("consumer:0x%" PRIx64 " update ep epoch from %d to epoch %d, incoming topics:%d, existed topics:%d",
|
||||||
tmq->consumerId, tmq->epoch, epoch, topicNumGet, topicNumCur);
|
tmq->consumerId, tmq->epoch, epoch, topicNumGet, topicNumCur);
|
||||||
if (epoch <= tmq->epoch) {
|
if (epoch <= tmq->epoch) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1518,14 +1555,14 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
||||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
||||||
if (pTopicCur->vgs) {
|
if (pTopicCur->vgs) {
|
||||||
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
||||||
tscDebug("consumer:0x%" PRIx64 ", current vg num: %d", tmq->consumerId, vgNumCur);
|
tscInfo("consumer:0x%" PRIx64 ", current vg num: %d", tmq->consumerId, vgNumCur);
|
||||||
for (int32_t j = 0; j < vgNumCur; j++) {
|
for (int32_t j = 0; j < vgNumCur; j++) {
|
||||||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
||||||
makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
|
makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
|
||||||
|
|
||||||
char buf[80];
|
char buf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(buf, 80, &pVgCur->offsetInfo.currentOffset);
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &pVgCur->offsetInfo.currentOffset);
|
||||||
tscDebug("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
|
tscInfo("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
|
||||||
vgKey, buf);
|
vgKey, buf);
|
||||||
|
|
||||||
SVgroupSaveInfo info = {.offset = pVgCur->offsetInfo.currentOffset, .numOfRows = pVgCur->numOfRows};
|
SVgroupSaveInfo info = {.offset = pVgCur->offsetInfo.currentOffset, .numOfRows = pVgCur->numOfRows};
|
||||||
|
@ -1555,7 +1592,7 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
||||||
atomic_store_8(&tmq->status, flag);
|
atomic_store_8(&tmq->status, flag);
|
||||||
atomic_store_32(&tmq->epoch, epoch);
|
atomic_store_32(&tmq->epoch, epoch);
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " update topic info completed", tmq->consumerId);
|
tscInfo("consumer:0x%" PRIx64 " update topic info completed", tmq->consumerId);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1591,7 +1628,7 @@ int32_t askEpCallbackFn(void* param, SDataBuf* pMsg, int32_t code) {
|
||||||
SMqRspHead* head = pMsg->pData;
|
SMqRspHead* head = pMsg->pData;
|
||||||
int32_t epoch = atomic_load_32(&tmq->epoch);
|
int32_t epoch = atomic_load_32(&tmq->epoch);
|
||||||
if (head->epoch <= epoch) {
|
if (head->epoch <= epoch) {
|
||||||
tscDebug("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, no need to update local ep",
|
tscInfo("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, no need to update local ep",
|
||||||
tmq->consumerId, head->epoch, epoch);
|
tmq->consumerId, head->epoch, epoch);
|
||||||
|
|
||||||
if (tmq->status == TMQ_CONSUMER_STATUS__RECOVER) {
|
if (tmq->status == TMQ_CONSUMER_STATUS__RECOVER) {
|
||||||
|
@ -1603,7 +1640,7 @@ int32_t askEpCallbackFn(void* param, SDataBuf* pMsg, int32_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tscDebug("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, update local ep", tmq->consumerId,
|
tscInfo("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, update local ep", tmq->consumerId,
|
||||||
head->epoch, epoch);
|
head->epoch, epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,7 +1710,7 @@ SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper, SMqClientVg* pVg,
|
||||||
return pRspObj;
|
return pRspObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMqTaosxRspObj* tmqBuildTaosxRspFromWrapper(SMqPollRspWrapper* pWrapper) {
|
SMqTaosxRspObj* tmqBuildTaosxRspFromWrapper(SMqPollRspWrapper* pWrapper, SMqClientVg* pVg, int64_t* numOfRows) {
|
||||||
SMqTaosxRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqTaosxRspObj));
|
SMqTaosxRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqTaosxRspObj));
|
||||||
pRspObj->resType = RES_TYPE__TMQ_METADATA;
|
pRspObj->resType = RES_TYPE__TMQ_METADATA;
|
||||||
tstrncpy(pRspObj->topic, pWrapper->topicHandle->topicName, TSDB_TOPIC_FNAME_LEN);
|
tstrncpy(pRspObj->topic, pWrapper->topicHandle->topicName, TSDB_TOPIC_FNAME_LEN);
|
||||||
|
@ -1688,6 +1725,13 @@ SMqTaosxRspObj* tmqBuildTaosxRspFromWrapper(SMqPollRspWrapper* pWrapper) {
|
||||||
setResSchemaInfo(&pRspObj->resInfo, pWrapper->topicHandle->schema.pSchema, pWrapper->topicHandle->schema.nCols);
|
setResSchemaInfo(&pRspObj->resInfo, pWrapper->topicHandle->schema.pSchema, pWrapper->topicHandle->schema.nCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract the rows in this data packet
|
||||||
|
for (int32_t i = 0; i < pRspObj->rsp.blockNum; ++i) {
|
||||||
|
SRetrieveTableRsp* pRetrieve = (SRetrieveTableRsp*)taosArrayGetP(pRspObj->rsp.blockData, i);
|
||||||
|
int64_t rows = htobe64(pRetrieve->numOfRows);
|
||||||
|
pVg->numOfRows += rows;
|
||||||
|
(*numOfRows) += rows;
|
||||||
|
}
|
||||||
return pRspObj;
|
return pRspObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1745,7 +1789,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
||||||
sendInfo->msgType = TDMT_VND_TMQ_CONSUME;
|
sendInfo->msgType = TDMT_VND_TMQ_CONSUME;
|
||||||
|
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
char offsetFormatBuf[80];
|
char offsetFormatBuf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.currentOffset);
|
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.currentOffset);
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64, pTmq->consumerId,
|
tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64, pTmq->consumerId,
|
||||||
|
@ -1882,8 +1926,8 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
pVg->offsetInfo.walVerEnd = pDataRsp->head.walever;
|
pVg->offsetInfo.walVerEnd = pDataRsp->head.walever;
|
||||||
pVg->receivedInfoFromVnode = true;
|
pVg->receivedInfoFromVnode = true;
|
||||||
|
|
||||||
char buf[80];
|
char buf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(buf, 80, &pDataRsp->rspOffset);
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &pDataRsp->rspOffset);
|
||||||
if (pDataRsp->blockNum == 0) {
|
if (pDataRsp->blockNum == 0) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " empty block received, vgId:%d, offset:%s, vg total:%" PRId64
|
tscDebug("consumer:0x%" PRIx64 " empty block received, vgId:%d, offset:%s, vg total:%" PRId64
|
||||||
" total:%" PRId64 " reqId:0x%" PRIx64,
|
" total:%" PRId64 " reqId:0x%" PRIx64,
|
||||||
|
@ -1985,13 +2029,13 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
if (pollRspWrapper->taosxRsp.createTableNum == 0) {
|
if (pollRspWrapper->taosxRsp.createTableNum == 0) {
|
||||||
pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
||||||
} else {
|
} else {
|
||||||
pRsp = tmqBuildTaosxRspFromWrapper(pollRspWrapper);
|
pRsp = tmqBuildTaosxRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmq->totalRows += numOfRows;
|
tmq->totalRows += numOfRows;
|
||||||
|
|
||||||
char buf[80];
|
char buf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(buf, 80, &pVg->offsetInfo.currentOffset);
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &pVg->offsetInfo.currentOffset);
|
||||||
tscDebug("consumer:0x%" PRIx64 " process taosx poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
|
tscDebug("consumer:0x%" PRIx64 " process taosx poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
|
||||||
", vg total:%" PRId64 " total:%" PRId64 " reqId:0x%" PRIx64,
|
", vg total:%" PRId64 " total:%" PRId64 " reqId:0x%" PRIx64,
|
||||||
tmq->consumerId, pVg->vgId, buf, pollRspWrapper->dataRsp.blockNum, numOfRows, pVg->numOfRows,
|
tmq->consumerId, pVg->vgId, buf, pollRspWrapper->dataRsp.blockNum, numOfRows, pVg->numOfRows,
|
||||||
|
@ -2024,12 +2068,12 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
||||||
void* rspObj;
|
void* rspObj;
|
||||||
int64_t startTime = taosGetTimestampMs();
|
int64_t startTime = taosGetTimestampMs();
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
|
tscInfo("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
|
||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
// in no topic status, delayed task also need to be processed
|
// in no topic status, delayed task also need to be processed
|
||||||
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
|
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId);
|
tscInfo("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId);
|
||||||
taosMsleep(500); // sleep for a while
|
taosMsleep(500); // sleep for a while
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2041,7 +2085,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " not ready, retry:%d/40 in 500ms", tmq->consumerId, retryCnt);
|
tscInfo("consumer:0x%" PRIx64 " not ready, retry:%d/40 in 500ms", tmq->consumerId, retryCnt);
|
||||||
taosMsleep(500);
|
taosMsleep(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2050,7 +2094,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
||||||
tmqHandleAllDelayedTask(tmq);
|
tmqHandleAllDelayedTask(tmq);
|
||||||
|
|
||||||
if (tmqPollImpl(tmq, timeout) < 0) {
|
if (tmqPollImpl(tmq, timeout) < 0) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " return due to poll error", tmq->consumerId);
|
tscError("consumer:0x%" PRIx64 " return due to poll error", tmq->consumerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
rspObj = tmqHandleAllRsp(tmq, timeout, false);
|
rspObj = tmqHandleAllRsp(tmq, timeout, false);
|
||||||
|
@ -2058,7 +2102,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " return rsp %p", tmq->consumerId, rspObj);
|
tscDebug("consumer:0x%" PRIx64 " return rsp %p", tmq->consumerId, rspObj);
|
||||||
return (TAOS_RES*)rspObj;
|
return (TAOS_RES*)rspObj;
|
||||||
} else if (terrno == TSDB_CODE_TQ_NO_COMMITTED_OFFSET) {
|
} else if (terrno == TSDB_CODE_TQ_NO_COMMITTED_OFFSET) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " return null since no committed offset", tmq->consumerId);
|
tscInfo("consumer:0x%" PRIx64 " return null since no committed offset", tmq->consumerId);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2066,7 +2110,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
||||||
int64_t currentTime = taosGetTimestampMs();
|
int64_t currentTime = taosGetTimestampMs();
|
||||||
int64_t elapsedTime = currentTime - startTime;
|
int64_t elapsedTime = currentTime - startTime;
|
||||||
if (elapsedTime > timeout) {
|
if (elapsedTime > timeout) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
|
tscInfo("consumer:0x%" PRIx64 " (epoch %d) timeout, no rsp, start time %" PRId64 ", current time %" PRId64,
|
||||||
tmq->consumerId, tmq->epoch, startTime, currentTime);
|
tmq->consumerId, tmq->epoch, startTime, currentTime);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2099,7 +2143,7 @@ static void displayConsumeStatistics(const tmq_t* pTmq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tmq_consumer_close(tmq_t* tmq) {
|
int32_t tmq_consumer_close(tmq_t* tmq) {
|
||||||
tscDebug("consumer:0x%" PRIx64 " start to close consumer, status:%d", tmq->consumerId, tmq->status);
|
tscInfo("consumer:0x%" PRIx64 " start to close consumer, status:%d", tmq->consumerId, tmq->status);
|
||||||
displayConsumeStatistics(tmq);
|
displayConsumeStatistics(tmq);
|
||||||
|
|
||||||
if (tmq->status == TMQ_CONSUMER_STATUS__READY) {
|
if (tmq->status == TMQ_CONSUMER_STATUS__READY) {
|
||||||
|
@ -2110,6 +2154,7 @@ int32_t tmq_consumer_close(tmq_t* tmq) {
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
taosSsleep(2); // sleep 2s for hb to send offset and rows to server
|
||||||
|
|
||||||
int32_t retryCnt = 0;
|
int32_t retryCnt = 0;
|
||||||
tmq_list_t* lst = tmq_list_new();
|
tmq_list_t* lst = tmq_list_new();
|
||||||
|
@ -2125,7 +2170,7 @@ int32_t tmq_consumer_close(tmq_t* tmq) {
|
||||||
|
|
||||||
tmq_list_destroy(lst);
|
tmq_list_destroy(lst);
|
||||||
} else {
|
} else {
|
||||||
tscWarn("consumer:0x%" PRIx64 " not in ready state, close it directly", tmq->consumerId);
|
tscInfo("consumer:0x%" PRIx64 " not in ready state, close it directly", tmq->consumerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosRemoveRef(tmqMgmt.rsetId, tmq->refId);
|
taosRemoveRef(tmqMgmt.rsetId, tmq->refId);
|
||||||
|
@ -2388,7 +2433,7 @@ void asyncAskEp(tmq_t* pTmq, __tmq_askep_fn_t askEpFn, void* param) {
|
||||||
sendInfo->msgType = TDMT_MND_TMQ_ASK_EP;
|
sendInfo->msgType = TDMT_MND_TMQ_ASK_EP;
|
||||||
|
|
||||||
SEpSet epSet = getEpSet_s(&pTmq->pTscObj->pAppInfo->mgmtEp);
|
SEpSet epSet = getEpSet_s(&pTmq->pTscObj->pAppInfo->mgmtEp);
|
||||||
tscDebug("consumer:0x%" PRIx64 " ask ep from mnode, reqId:0x%" PRIx64, pTmq->consumerId, sendInfo->requestId);
|
tscInfo("consumer:0x%" PRIx64 " ask ep from mnode, reqId:0x%" PRIx64, pTmq->consumerId, sendInfo->requestId);
|
||||||
|
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
asyncSendMsgToServer(pTmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
||||||
|
@ -2411,6 +2456,7 @@ int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet) {
|
||||||
// if no more waiting rsp
|
// if no more waiting rsp
|
||||||
pParamSet->callbackFn(tmq, pParamSet->code, pParamSet->userParam);
|
pParamSet->callbackFn(tmq, pParamSet->code, pParamSet->userParam);
|
||||||
taosMemoryFree(pParamSet);
|
taosMemoryFree(pParamSet);
|
||||||
|
tmq->needReportOffsetRows = true;
|
||||||
|
|
||||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2608,10 +2654,10 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
|
||||||
sendInfo->msgType = TDMT_VND_TMQ_VG_WALINFO;
|
sendInfo->msgType = TDMT_VND_TMQ_VG_WALINFO;
|
||||||
|
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
char offsetFormatBuf[80];
|
char offsetFormatBuf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pClientVg->offsetInfo.currentOffset);
|
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pClientVg->offsetInfo.currentOffset);
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " %s retrieve wal info vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64,
|
tscInfo("consumer:0x%" PRIx64 " %s retrieve wal info vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64,
|
||||||
tmq->consumerId, pTopic->topicName, pClientVg->vgId, tmq->epoch, offsetFormatBuf, req.reqId);
|
tmq->consumerId, pTopic->topicName, pClientVg->vgId, tmq->epoch, offsetFormatBuf, req.reqId);
|
||||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pClientVg->epSet, &transporterId, sendInfo);
|
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pClientVg->epSet, &transporterId, sendInfo);
|
||||||
}
|
}
|
||||||
|
@ -2645,10 +2691,10 @@ int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_a
|
||||||
|
|
||||||
pOffsetInfo->currentOffset.type = TMQ_OFFSET__LOG;
|
pOffsetInfo->currentOffset.type = TMQ_OFFSET__LOG;
|
||||||
|
|
||||||
char offsetBuf[80] = {0};
|
char offsetBuf[TSDB_OFFSET_LEN] = {0};
|
||||||
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffsetInfo->currentOffset);
|
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffsetInfo->currentOffset);
|
||||||
|
|
||||||
tscDebug("vgId:%d offset is update to:%s", p->vgId, offsetBuf);
|
tscInfo("vgId:%d offset is update to:%s", p->vgId, offsetBuf);
|
||||||
|
|
||||||
pOffsetInfo->walVerBegin = p->begin;
|
pOffsetInfo->walVerBegin = p->begin;
|
||||||
pOffsetInfo->walVerEnd = p->end;
|
pOffsetInfo->walVerEnd = p->end;
|
||||||
|
@ -2727,7 +2773,7 @@ int32_t tmq_offset_seek(tmq_t* tmq, const char* pTopicName, int32_t vgId, int64_
|
||||||
SMqRspObj rspObj = {.resType = RES_TYPE__TMQ, .vgId = pVg->vgId};
|
SMqRspObj rspObj = {.resType = RES_TYPE__TMQ, .vgId = pVg->vgId};
|
||||||
tstrncpy(rspObj.topic, tname, tListLen(rspObj.topic));
|
tstrncpy(rspObj.topic, tname, tListLen(rspObj.topic));
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 " seek to %" PRId64 " on vgId:%d", tmq->consumerId, offset, pVg->vgId);
|
tscInfo("consumer:0x%" PRIx64 " seek to %" PRId64 " on vgId:%d", tmq->consumerId, offset, pVg->vgId);
|
||||||
|
|
||||||
SSyncCommitInfo* pInfo = taosMemoryMalloc(sizeof(SSyncCommitInfo));
|
SSyncCommitInfo* pInfo = taosMemoryMalloc(sizeof(SSyncCommitInfo));
|
||||||
if (pInfo == NULL) {
|
if (pInfo == NULL) {
|
||||||
|
|
|
@ -291,6 +291,8 @@ static const SSysDbTableSchema subscriptionSchema[] = {
|
||||||
{.name = "consumer_group", .bytes = TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
{.name = "consumer_group", .bytes = TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
||||||
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||||
{.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
{.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
||||||
|
{.name = "offset", .bytes = TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
||||||
|
{.name = "rows", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SSysDbTableSchema vnodesSchema[] = {
|
static const SSysDbTableSchema vnodesSchema[] = {
|
||||||
|
@ -359,6 +361,7 @@ static const SSysDbTableSchema consumerSchema[] = {
|
||||||
{.name = "up_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
{.name = "up_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||||
{.name = "subscribe_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
{.name = "subscribe_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||||
{.name = "rebalance_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
{.name = "rebalance_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||||
|
{.name = "parameters", .bytes = 64 + TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SSysDbTableSchema offsetSchema[] = {
|
static const SSysDbTableSchema offsetSchema[] = {
|
||||||
|
@ -381,6 +384,7 @@ static const SSysDbTableSchema querySchema[] = {
|
||||||
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||||
{.name = "exec_usec", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
{.name = "exec_usec", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
|
||||||
{.name = "stable_query", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = false},
|
{.name = "stable_query", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = false},
|
||||||
|
{.name = "sub_query", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = false},
|
||||||
{.name = "sub_num", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
{.name = "sub_num", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||||
{.name = "sub_status", .bytes = TSDB_SHOW_SUBQUERY_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
{.name = "sub_status", .bytes = TSDB_SHOW_SUBQUERY_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||||
{.name = "sql", .bytes = TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
{.name = "sql", .bytes = TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||||
|
|
|
@ -2482,19 +2482,31 @@ _end:
|
||||||
}
|
}
|
||||||
|
|
||||||
char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
||||||
if (stbFullName[0] == 0) {
|
char* pBuf = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
|
||||||
|
if (!pBuf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
int32_t code = buildCtbNameByGroupIdImpl(stbFullName, groupId, pBuf);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosMemoryFree(pBuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t buildCtbNameByGroupIdImpl(const char* stbFullName, uint64_t groupId, char* cname) {
|
||||||
|
if (stbFullName[0] == 0) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
SArray* tags = taosArrayInit(0, sizeof(SSmlKv));
|
SArray* tags = taosArrayInit(0, sizeof(SSmlKv));
|
||||||
if (tags == NULL) {
|
if (tags == NULL) {
|
||||||
return NULL;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* cname = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
|
|
||||||
if (cname == NULL) {
|
if (cname == NULL) {
|
||||||
taosArrayDestroy(tags);
|
taosArrayDestroy(tags);
|
||||||
return NULL;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSmlKv pTag = {.key = "group_id",
|
SSmlKv pTag = {.key = "group_id",
|
||||||
|
@ -2516,9 +2528,9 @@ char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
||||||
taosArrayDestroy(tags);
|
taosArrayDestroy(tags);
|
||||||
|
|
||||||
if ((rname.ctbShortName && rname.ctbShortName[0]) == 0) {
|
if ((rname.ctbShortName && rname.ctbShortName[0]) == 0) {
|
||||||
return NULL;
|
return TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
return rname.ctbShortName;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) {
|
int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) {
|
||||||
|
|
|
@ -493,6 +493,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
||||||
|
|
||||||
if (cfgAddInt64(pCfg, "mndSdbWriteDelta", tsMndSdbWriteDelta, 20, 10000, 0) != 0) return -1;
|
if (cfgAddInt64(pCfg, "mndSdbWriteDelta", tsMndSdbWriteDelta, 20, 10000, 0) != 0) return -1;
|
||||||
if (cfgAddInt64(pCfg, "mndLogRetention", tsMndLogRetention, 500, 10000, 0) != 0) return -1;
|
if (cfgAddInt64(pCfg, "mndLogRetention", tsMndLogRetention, 500, 10000, 0) != 0) return -1;
|
||||||
|
if (cfgAddBool(pCfg, "skipGrant", tsMndSkipGrant, 0) != 0) return -1;
|
||||||
|
|
||||||
if (cfgAddBool(pCfg, "monitor", tsEnableMonitor, 0) != 0) return -1;
|
if (cfgAddBool(pCfg, "monitor", tsEnableMonitor, 0) != 0) return -1;
|
||||||
if (cfgAddInt32(pCfg, "monitorInterval", tsMonitorInterval, 1, 200000, 0) != 0) return -1;
|
if (cfgAddInt32(pCfg, "monitorInterval", tsMonitorInterval, 1, 200000, 0) != 0) return -1;
|
||||||
|
@ -892,6 +893,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
|
||||||
|
|
||||||
tsMndSdbWriteDelta = cfgGetItem(pCfg, "mndSdbWriteDelta")->i64;
|
tsMndSdbWriteDelta = cfgGetItem(pCfg, "mndSdbWriteDelta")->i64;
|
||||||
tsMndLogRetention = cfgGetItem(pCfg, "mndLogRetention")->i64;
|
tsMndLogRetention = cfgGetItem(pCfg, "mndLogRetention")->i64;
|
||||||
|
tsMndSkipGrant = cfgGetItem(pCfg, "skipGrant")->bval;
|
||||||
|
|
||||||
tsStartUdfd = cfgGetItem(pCfg, "udf")->bval;
|
tsStartUdfd = cfgGetItem(pCfg, "udf")->bval;
|
||||||
tstrncpy(tsUdfdResFuncs, cfgGetItem(pCfg, "udfdResFuncs")->str, sizeof(tsUdfdResFuncs));
|
tstrncpy(tsUdfdResFuncs, cfgGetItem(pCfg, "udfdResFuncs")->str, sizeof(tsUdfdResFuncs));
|
||||||
|
|
|
@ -224,6 +224,7 @@ static int32_t tSerializeSClientHbReq(SEncoder *pEncoder, const SClientHbReq *pR
|
||||||
if (tEncodeI64(pEncoder, desc->stime) < 0) return -1;
|
if (tEncodeI64(pEncoder, desc->stime) < 0) return -1;
|
||||||
if (tEncodeI64(pEncoder, desc->reqRid) < 0) return -1;
|
if (tEncodeI64(pEncoder, desc->reqRid) < 0) return -1;
|
||||||
if (tEncodeI8(pEncoder, desc->stableQuery) < 0) return -1;
|
if (tEncodeI8(pEncoder, desc->stableQuery) < 0) return -1;
|
||||||
|
if (tEncodeI8(pEncoder, desc->isSubQuery) < 0) return -1;
|
||||||
if (tEncodeCStr(pEncoder, desc->fqdn) < 0) return -1;
|
if (tEncodeCStr(pEncoder, desc->fqdn) < 0) return -1;
|
||||||
if (tEncodeI32(pEncoder, desc->subPlanNum) < 0) return -1;
|
if (tEncodeI32(pEncoder, desc->subPlanNum) < 0) return -1;
|
||||||
|
|
||||||
|
@ -291,6 +292,7 @@ static int32_t tDeserializeSClientHbReq(SDecoder *pDecoder, SClientHbReq *pReq)
|
||||||
if (tDecodeI64(pDecoder, &desc.stime) < 0) return -1;
|
if (tDecodeI64(pDecoder, &desc.stime) < 0) return -1;
|
||||||
if (tDecodeI64(pDecoder, &desc.reqRid) < 0) return -1;
|
if (tDecodeI64(pDecoder, &desc.reqRid) < 0) return -1;
|
||||||
if (tDecodeI8(pDecoder, (int8_t *)&desc.stableQuery) < 0) return -1;
|
if (tDecodeI8(pDecoder, (int8_t *)&desc.stableQuery) < 0) return -1;
|
||||||
|
if (tDecodeI8(pDecoder, (int8_t *)&desc.isSubQuery) < 0) return -1;
|
||||||
if (tDecodeCStrTo(pDecoder, desc.fqdn) < 0) return -1;
|
if (tDecodeCStrTo(pDecoder, desc.fqdn) < 0) return -1;
|
||||||
if (tDecodeI32(pDecoder, &desc.subPlanNum) < 0) return -1;
|
if (tDecodeI32(pDecoder, &desc.subPlanNum) < 0) return -1;
|
||||||
|
|
||||||
|
@ -5338,6 +5340,15 @@ int32_t tDeserializeSMqAskEpReq(void *buf, int32_t bufLen, SMqAskEpReq *pReq) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tDeatroySMqHbReq(SMqHbReq* pReq){
|
||||||
|
for(int i = 0; i < taosArrayGetSize(pReq->topics); i++){
|
||||||
|
TopicOffsetRows* vgs = taosArrayGet(pReq->topics, i);
|
||||||
|
if(vgs) taosArrayDestroy(vgs->offsetRows);
|
||||||
|
}
|
||||||
|
taosArrayDestroy(pReq->topics);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tSerializeSMqHbReq(void *buf, int32_t bufLen, SMqHbReq *pReq) {
|
int32_t tSerializeSMqHbReq(void *buf, int32_t bufLen, SMqHbReq *pReq) {
|
||||||
SEncoder encoder = {0};
|
SEncoder encoder = {0};
|
||||||
tEncoderInit(&encoder, buf, bufLen);
|
tEncoderInit(&encoder, buf, bufLen);
|
||||||
|
@ -5346,6 +5357,21 @@ int32_t tSerializeSMqHbReq(void *buf, int32_t bufLen, SMqHbReq *pReq) {
|
||||||
if (tEncodeI64(&encoder, pReq->consumerId) < 0) return -1;
|
if (tEncodeI64(&encoder, pReq->consumerId) < 0) return -1;
|
||||||
if (tEncodeI32(&encoder, pReq->epoch) < 0) return -1;
|
if (tEncodeI32(&encoder, pReq->epoch) < 0) return -1;
|
||||||
|
|
||||||
|
int32_t sz = taosArrayGetSize(pReq->topics);
|
||||||
|
if (tEncodeI32(&encoder, sz) < 0) return -1;
|
||||||
|
for (int32_t i = 0; i < sz; ++i) {
|
||||||
|
TopicOffsetRows* vgs = (TopicOffsetRows*)taosArrayGet(pReq->topics, i);
|
||||||
|
if (tEncodeCStr(&encoder, vgs->topicName) < 0) return -1;
|
||||||
|
int32_t szVgs = taosArrayGetSize(vgs->offsetRows);
|
||||||
|
if (tEncodeI32(&encoder, szVgs) < 0) return -1;
|
||||||
|
for (int32_t j = 0; j < szVgs; ++j) {
|
||||||
|
OffsetRows *offRows = taosArrayGet(vgs->offsetRows, j);
|
||||||
|
if (tEncodeI32(&encoder, offRows->vgId) < 0) return -1;
|
||||||
|
if (tEncodeI64(&encoder, offRows->rows) < 0) return -1;
|
||||||
|
if (tEncodeSTqOffsetVal(&encoder, &offRows->offset) < 0) return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tEndEncode(&encoder);
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
int32_t tlen = encoder.pos;
|
int32_t tlen = encoder.pos;
|
||||||
|
@ -5362,7 +5388,28 @@ int32_t tDeserializeSMqHbReq(void *buf, int32_t bufLen, SMqHbReq *pReq) {
|
||||||
|
|
||||||
if (tDecodeI64(&decoder, &pReq->consumerId) < 0) return -1;
|
if (tDecodeI64(&decoder, &pReq->consumerId) < 0) return -1;
|
||||||
if (tDecodeI32(&decoder, &pReq->epoch) < 0) return -1;
|
if (tDecodeI32(&decoder, &pReq->epoch) < 0) return -1;
|
||||||
|
int32_t sz = 0;
|
||||||
|
if (tDecodeI32(&decoder, &sz) < 0) return -1;
|
||||||
|
if(sz > 0){
|
||||||
|
pReq->topics = taosArrayInit(sz, sizeof(TopicOffsetRows));
|
||||||
|
if (NULL == pReq->topics) return -1;
|
||||||
|
for (int32_t i = 0; i < sz; ++i) {
|
||||||
|
TopicOffsetRows* data = taosArrayReserve(pReq->topics, 1);
|
||||||
|
tDecodeCStrTo(&decoder, data->topicName);
|
||||||
|
int32_t szVgs = 0;
|
||||||
|
if (tDecodeI32(&decoder, &szVgs) < 0) return -1;
|
||||||
|
if(szVgs > 0){
|
||||||
|
data->offsetRows = taosArrayInit(szVgs, sizeof(OffsetRows));
|
||||||
|
if (NULL == data->offsetRows) return -1;
|
||||||
|
for (int32_t j= 0; j < szVgs; ++j) {
|
||||||
|
OffsetRows* offRows = taosArrayReserve(data->offsetRows, 1);
|
||||||
|
if (tDecodeI32(&decoder, &offRows->vgId) < 0) return -1;
|
||||||
|
if (tDecodeI64(&decoder, &offRows->rows) < 0) return -1;
|
||||||
|
if (tDecodeSTqOffsetVal(&decoder, &offRows->offset) < 0) return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
tEndDecode(&decoder);
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
|
@ -6122,6 +6169,7 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS
|
||||||
}
|
}
|
||||||
if (tEncodeI64(&encoder, pReq->deleteMark) < 0) return -1;
|
if (tEncodeI64(&encoder, pReq->deleteMark) < 0) return -1;
|
||||||
if (tEncodeI8(&encoder, pReq->igUpdate) < 0) return -1;
|
if (tEncodeI8(&encoder, pReq->igUpdate) < 0) return -1;
|
||||||
|
if (tEncodeI64(&encoder, pReq->lastTs) < 0) return -1;
|
||||||
|
|
||||||
tEndEncode(&encoder);
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
@ -6207,6 +6255,7 @@ int32_t tDeserializeSCMCreateStreamReq(void *buf, int32_t bufLen, SCMCreateStrea
|
||||||
|
|
||||||
if (tDecodeI64(&decoder, &pReq->deleteMark) < 0) return -1;
|
if (tDecodeI64(&decoder, &pReq->deleteMark) < 0) return -1;
|
||||||
if (tDecodeI8(&decoder, &pReq->igUpdate) < 0) return -1;
|
if (tDecodeI8(&decoder, &pReq->igUpdate) < 0) return -1;
|
||||||
|
if (tDecodeI64(&decoder, &pReq->lastTs) < 0) return -1;
|
||||||
|
|
||||||
tEndDecode(&decoder);
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
@ -6273,6 +6322,9 @@ int32_t tDeserializeSMRecoverStreamReq(void *buf, int32_t bufLen, SMRecoverStrea
|
||||||
}
|
}
|
||||||
|
|
||||||
void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) {
|
void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) {
|
||||||
|
if (NULL == pReq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
taosArrayDestroy(pReq->pTags);
|
taosArrayDestroy(pReq->pTags);
|
||||||
taosMemoryFreeClear(pReq->sql);
|
taosMemoryFreeClear(pReq->sql);
|
||||||
taosMemoryFreeClear(pReq->ast);
|
taosMemoryFreeClear(pReq->ast);
|
||||||
|
@ -7086,15 +7138,15 @@ int32_t tDecodeSTqOffsetVal(SDecoder *pDecoder, STqOffsetVal *pOffsetVal) {
|
||||||
|
|
||||||
int32_t tFormatOffset(char *buf, int32_t maxLen, const STqOffsetVal *pVal) {
|
int32_t tFormatOffset(char *buf, int32_t maxLen, const STqOffsetVal *pVal) {
|
||||||
if (pVal->type == TMQ_OFFSET__RESET_NONE) {
|
if (pVal->type == TMQ_OFFSET__RESET_NONE) {
|
||||||
snprintf(buf, maxLen, "offset(reset to none)");
|
snprintf(buf, maxLen, "none");
|
||||||
} else if (pVal->type == TMQ_OFFSET__RESET_EARLIEAST) {
|
} else if (pVal->type == TMQ_OFFSET__RESET_EARLIEST) {
|
||||||
snprintf(buf, maxLen, "offset(reset to earlieast)");
|
snprintf(buf, maxLen, "earliest");
|
||||||
} else if (pVal->type == TMQ_OFFSET__RESET_LATEST) {
|
} else if (pVal->type == TMQ_OFFSET__RESET_LATEST) {
|
||||||
snprintf(buf, maxLen, "offset(reset to latest)");
|
snprintf(buf, maxLen, "latest");
|
||||||
} else if (pVal->type == TMQ_OFFSET__LOG) {
|
} else if (pVal->type == TMQ_OFFSET__LOG) {
|
||||||
snprintf(buf, maxLen, "offset(log) ver:%" PRId64, pVal->version);
|
snprintf(buf, maxLen, "log:%" PRId64, pVal->version);
|
||||||
} else if (pVal->type == TMQ_OFFSET__SNAPSHOT_DATA || pVal->type == TMQ_OFFSET__SNAPSHOT_META) {
|
} else if (pVal->type == TMQ_OFFSET__SNAPSHOT_DATA || pVal->type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
snprintf(buf, maxLen, "offset(snapshot) uid:%" PRId64 " ts:%" PRId64, pVal->uid, pVal->ts);
|
snprintf(buf, maxLen, "snapshot:%" PRId64 "|%" PRId64, pVal->uid, pVal->ts);
|
||||||
} else {
|
} else {
|
||||||
return TSDB_CODE_INVALID_PARA;
|
return TSDB_CODE_INVALID_PARA;
|
||||||
}
|
}
|
||||||
|
@ -7112,7 +7164,7 @@ bool tOffsetEqual(const STqOffsetVal *pLeft, const STqOffsetVal *pRight) {
|
||||||
return pLeft->uid == pRight->uid;
|
return pLeft->uid == pRight->uid;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
/*ASSERT(pLeft->type == TMQ_OFFSET__RESET_NONE || pLeft->type == TMQ_OFFSET__RESET_EARLIEAST ||*/
|
/*ASSERT(pLeft->type == TMQ_OFFSET__RESET_NONE || pLeft->type == TMQ_OFFSET__RESET_EARLIEST ||*/
|
||||||
/*pLeft->type == TMQ_OFFSET__RESET_LATEST);*/
|
/*pLeft->type == TMQ_OFFSET__RESET_LATEST);*/
|
||||||
/*return true;*/
|
/*return true;*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "ttypes.h"
|
#include "ttypes.h"
|
||||||
#include "tcompression.h"
|
#include "tcompression.h"
|
||||||
|
|
||||||
const int32_t TYPE_BYTES[17] = {
|
const int32_t TYPE_BYTES[21] = {
|
||||||
-1, // TSDB_DATA_TYPE_NULL
|
-1, // TSDB_DATA_TYPE_NULL
|
||||||
CHAR_BYTES, // TSDB_DATA_TYPE_BOOL
|
CHAR_BYTES, // TSDB_DATA_TYPE_BOOL
|
||||||
CHAR_BYTES, // TSDB_DATA_TYPE_TINYINT
|
CHAR_BYTES, // TSDB_DATA_TYPE_TINYINT
|
||||||
|
@ -34,6 +34,10 @@ const int32_t TYPE_BYTES[17] = {
|
||||||
INT_BYTES, // TSDB_DATA_TYPE_UINT
|
INT_BYTES, // TSDB_DATA_TYPE_UINT
|
||||||
sizeof(uint64_t), // TSDB_DATA_TYPE_UBIGINT
|
sizeof(uint64_t), // TSDB_DATA_TYPE_UBIGINT
|
||||||
TSDB_MAX_JSON_TAG_LEN, // TSDB_DATA_TYPE_JSON
|
TSDB_MAX_JSON_TAG_LEN, // TSDB_DATA_TYPE_JSON
|
||||||
|
TSDB_MAX_TAGS_LEN, // TSDB_DATA_TYPE_VARBINARY: placeholder, not implemented
|
||||||
|
TSDB_MAX_TAGS_LEN, // TSDB_DATA_TYPE_DECIMAL: placeholder, not implemented
|
||||||
|
TSDB_MAX_TAGS_LEN, // TSDB_DATA_TYPE_BLOB: placeholder, not implemented
|
||||||
|
TSDB_MAX_TAGS_LEN, // TSDB_DATA_TYPE_MEDIUMBLOB: placeholder, not implemented
|
||||||
sizeof(VarDataOffsetT), // TSDB_DATA_TYPE_GEOMETRY
|
sizeof(VarDataOffsetT), // TSDB_DATA_TYPE_GEOMETRY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,6 +61,10 @@ tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX] = {
|
||||||
{TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", 0, UINT32_MAX, tsCompressInt, tsDecompressInt},
|
{TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", 0, UINT32_MAX, tsCompressInt, tsDecompressInt},
|
||||||
{TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", 0, UINT64_MAX, tsCompressBigint, tsDecompressBigint},
|
{TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", 0, UINT64_MAX, tsCompressBigint, tsDecompressBigint},
|
||||||
{TSDB_DATA_TYPE_JSON, 4, TSDB_MAX_JSON_TAG_LEN, "JSON", 0, 0, tsCompressString, tsDecompressString},
|
{TSDB_DATA_TYPE_JSON, 4, TSDB_MAX_JSON_TAG_LEN, "JSON", 0, 0, tsCompressString, tsDecompressString},
|
||||||
|
{TSDB_DATA_TYPE_VARBINARY, 9, 1, "VARBINARY", 0, 0, NULL, NULL}, // placeholder, not implemented
|
||||||
|
{TSDB_DATA_TYPE_DECIMAL, 7, 1, "DECIMAL", 0, 0, NULL, NULL}, // placeholder, not implemented
|
||||||
|
{TSDB_DATA_TYPE_BLOB, 4, 1, "BLOB", 0, 0, NULL, NULL}, // placeholder, not implemented
|
||||||
|
{TSDB_DATA_TYPE_MEDIUMBLOB, 10, 1, "MEDIUMBLOB", 0, 0, NULL, NULL}, // placeholder, not implemented
|
||||||
{TSDB_DATA_TYPE_GEOMETRY, 8, 1, "GEOMETRY", 0, 0, tsCompressString, tsDecompressString},
|
{TSDB_DATA_TYPE_GEOMETRY, 8, 1, "GEOMETRY", 0, 0, tsCompressString, tsDecompressString},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ SArray *mmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_TOPIC, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_TOPIC, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_SUBSCRIBE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_SUBSCRIBE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_ASK_EP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_ASK_EP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_HB, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_HB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_CGROUP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_CGROUP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_CGROUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_TMQ_DROP_CGROUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_TRANS, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_TRANS, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
|
@ -265,6 +265,7 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||||
|
|
||||||
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (pMgmt->pTfs) {
|
if (pMgmt->pTfs) {
|
||||||
if (tfsDirExistAt(pMgmt->pTfs, path, (SDiskID){0})) {
|
if (tfsDirExistAt(pMgmt->pTfs, path, (SDiskID){0})) {
|
||||||
terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST;
|
terrno = TSDB_CODE_VND_DIR_ALREADY_EXIST;
|
||||||
|
@ -278,8 +279,9 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) {
|
if (vnodeCreate(path, &vnodeCfg, pMgmt->pTfs) < 0) {
|
||||||
tFreeSCreateVnodeReq(&req);
|
tFreeSCreateVnodeReq(&req);
|
||||||
dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr());
|
dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr());
|
||||||
code = terrno;
|
code = terrno;
|
||||||
|
|
|
@ -108,7 +108,7 @@ typedef enum {
|
||||||
TRN_STAGE_UNDO_ACTION = 3,
|
TRN_STAGE_UNDO_ACTION = 3,
|
||||||
TRN_STAGE_COMMIT = 4,
|
TRN_STAGE_COMMIT = 4,
|
||||||
TRN_STAGE_COMMIT_ACTION = 5,
|
TRN_STAGE_COMMIT_ACTION = 5,
|
||||||
TRN_STAGE_FINISHED = 6,
|
TRN_STAGE_FINISH = 6,
|
||||||
TRN_STAGE_PRE_FINISH = 7
|
TRN_STAGE_PRE_FINISH = 7
|
||||||
} ETrnStage;
|
} ETrnStage;
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ typedef struct {
|
||||||
void* rpcRsp;
|
void* rpcRsp;
|
||||||
int32_t rpcRspLen;
|
int32_t rpcRspLen;
|
||||||
int32_t redoActionPos;
|
int32_t redoActionPos;
|
||||||
|
SArray* prepareActions;
|
||||||
SArray* redoActions;
|
SArray* redoActions;
|
||||||
SArray* undoActions;
|
SArray* undoActions;
|
||||||
SArray* commitActions;
|
SArray* commitActions;
|
||||||
|
@ -550,33 +551,39 @@ typedef struct {
|
||||||
int64_t upTime;
|
int64_t upTime;
|
||||||
int64_t subscribeTime;
|
int64_t subscribeTime;
|
||||||
int64_t rebalanceTime;
|
int64_t rebalanceTime;
|
||||||
|
|
||||||
|
int8_t withTbName;
|
||||||
|
int8_t autoCommit;
|
||||||
|
int32_t autoCommitInterval;
|
||||||
|
int32_t resetOffsetCfg;
|
||||||
} SMqConsumerObj;
|
} SMqConsumerObj;
|
||||||
|
|
||||||
SMqConsumerObj* tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_LEN]);
|
SMqConsumerObj* tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_LEN]);
|
||||||
void tDeleteSMqConsumerObj(SMqConsumerObj* pConsumer);
|
void tDeleteSMqConsumerObj(SMqConsumerObj* pConsumer);
|
||||||
int32_t tEncodeSMqConsumerObj(void** buf, const SMqConsumerObj* pConsumer);
|
int32_t tEncodeSMqConsumerObj(void** buf, const SMqConsumerObj* pConsumer);
|
||||||
void* tDecodeSMqConsumerObj(const void* buf, SMqConsumerObj* pConsumer);
|
void* tDecodeSMqConsumerObj(const void* buf, SMqConsumerObj* pConsumer, int8_t sver);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
char* qmsg; // SubPlanToString
|
// char* qmsg; // SubPlanToString
|
||||||
SEpSet epSet;
|
SEpSet epSet;
|
||||||
} SMqVgEp;
|
} SMqVgEp;
|
||||||
|
|
||||||
SMqVgEp* tCloneSMqVgEp(const SMqVgEp* pVgEp);
|
SMqVgEp* tCloneSMqVgEp(const SMqVgEp* pVgEp);
|
||||||
void tDeleteSMqVgEp(SMqVgEp* pVgEp);
|
void tDeleteSMqVgEp(SMqVgEp* pVgEp);
|
||||||
int32_t tEncodeSMqVgEp(void** buf, const SMqVgEp* pVgEp);
|
int32_t tEncodeSMqVgEp(void** buf, const SMqVgEp* pVgEp);
|
||||||
void* tDecodeSMqVgEp(const void* buf, SMqVgEp* pVgEp);
|
void* tDecodeSMqVgEp(const void* buf, SMqVgEp* pVgEp, int8_t sver);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t consumerId; // -1 for unassigned
|
int64_t consumerId; // -1 for unassigned
|
||||||
SArray* vgs; // SArray<SMqVgEp*>
|
SArray* vgs; // SArray<SMqVgEp*>
|
||||||
|
SArray* offsetRows; // SArray<OffsetRows*>
|
||||||
} SMqConsumerEp;
|
} SMqConsumerEp;
|
||||||
|
|
||||||
SMqConsumerEp* tCloneSMqConsumerEp(const SMqConsumerEp* pEp);
|
//SMqConsumerEp* tCloneSMqConsumerEp(const SMqConsumerEp* pEp);
|
||||||
void tDeleteSMqConsumerEp(void* pEp);
|
//void tDeleteSMqConsumerEp(void* pEp);
|
||||||
int32_t tEncodeSMqConsumerEp(void** buf, const SMqConsumerEp* pEp);
|
int32_t tEncodeSMqConsumerEp(void** buf, const SMqConsumerEp* pEp);
|
||||||
void* tDecodeSMqConsumerEp(const void* buf, SMqConsumerEp* pEp);
|
void* tDecodeSMqConsumerEp(const void* buf, SMqConsumerEp* pEp, int8_t sver);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||||
|
@ -588,14 +595,16 @@ typedef struct {
|
||||||
int64_t stbUid;
|
int64_t stbUid;
|
||||||
SHashObj* consumerHash; // consumerId -> SMqConsumerEp
|
SHashObj* consumerHash; // consumerId -> SMqConsumerEp
|
||||||
SArray* unassignedVgs; // SArray<SMqVgEp*>
|
SArray* unassignedVgs; // SArray<SMqVgEp*>
|
||||||
|
SArray* offsetRows;
|
||||||
char dbName[TSDB_DB_FNAME_LEN];
|
char dbName[TSDB_DB_FNAME_LEN];
|
||||||
|
char* qmsg; // SubPlanToString
|
||||||
} SMqSubscribeObj;
|
} SMqSubscribeObj;
|
||||||
|
|
||||||
SMqSubscribeObj* tNewSubscribeObj(const char key[TSDB_SUBSCRIBE_KEY_LEN]);
|
SMqSubscribeObj* tNewSubscribeObj(const char key[TSDB_SUBSCRIBE_KEY_LEN]);
|
||||||
SMqSubscribeObj* tCloneSubscribeObj(const SMqSubscribeObj* pSub);
|
SMqSubscribeObj* tCloneSubscribeObj(const SMqSubscribeObj* pSub);
|
||||||
void tDeleteSubscribeObj(SMqSubscribeObj* pSub);
|
void tDeleteSubscribeObj(SMqSubscribeObj* pSub);
|
||||||
int32_t tEncodeSubscribeObj(void** buf, const SMqSubscribeObj* pSub);
|
int32_t tEncodeSubscribeObj(void** buf, const SMqSubscribeObj* pSub);
|
||||||
void* tDecodeSubscribeObj(const void* buf, SMqSubscribeObj* pSub);
|
void* tDecodeSubscribeObj(const void* buf, SMqSubscribeObj* pSub, int8_t sver);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t epoch;
|
int32_t epoch;
|
||||||
|
@ -687,12 +696,12 @@ int32_t tEncodeSStreamObj(SEncoder* pEncoder, const SStreamObj* pObj);
|
||||||
int32_t tDecodeSStreamObj(SDecoder* pDecoder, SStreamObj* pObj, int32_t sver);
|
int32_t tDecodeSStreamObj(SDecoder* pDecoder, SStreamObj* pObj, int32_t sver);
|
||||||
void tFreeStreamObj(SStreamObj* pObj);
|
void tFreeStreamObj(SStreamObj* pObj);
|
||||||
|
|
||||||
typedef struct {
|
//typedef struct {
|
||||||
char streamName[TSDB_STREAM_FNAME_LEN];
|
// char streamName[TSDB_STREAM_FNAME_LEN];
|
||||||
int64_t uid;
|
// int64_t uid;
|
||||||
int64_t streamUid;
|
// int64_t streamUid;
|
||||||
SArray* childInfo; // SArray<SStreamChildEpInfo>
|
// SArray* childInfo; // SArray<SStreamChildEpInfo>
|
||||||
} SStreamCheckpointObj;
|
//} SStreamCheckpointObj;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ int32_t mndTransAppendRedolog(STrans *pTrans, SSdbRaw *pRaw);
|
||||||
int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw);
|
int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw);
|
||||||
int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw);
|
int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw);
|
||||||
int32_t mndTransAppendNullLog(STrans *pTrans);
|
int32_t mndTransAppendNullLog(STrans *pTrans);
|
||||||
|
int32_t mndTransAppendPrepareAction(STrans *pTrans, STransAction *pAction);
|
||||||
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction);
|
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction);
|
||||||
int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction);
|
int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction);
|
||||||
void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen);
|
void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen);
|
||||||
|
@ -78,15 +79,23 @@ void mndTransSetDbName(STrans *pTrans, const char *dbname, const char *stbnam
|
||||||
void mndTransSetSerial(STrans *pTrans);
|
void mndTransSetSerial(STrans *pTrans);
|
||||||
void mndTransSetParallel(STrans *pTrans);
|
void mndTransSetParallel(STrans *pTrans);
|
||||||
void mndTransSetOper(STrans *pTrans, EOperType oper);
|
void mndTransSetOper(STrans *pTrans, EOperType oper);
|
||||||
int32_t mndTrancCheckConflict(SMnode *pMnode, STrans *pTrans);
|
int32_t mndTransCheckConflict(SMnode *pMnode, STrans *pTrans);
|
||||||
|
static int32_t mndTrancCheckConflict(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
return mndTransCheckConflict(pMnode, pTrans);
|
||||||
|
}
|
||||||
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans);
|
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans);
|
||||||
int32_t mndTransProcessRsp(SRpcMsg *pRsp);
|
int32_t mndTransProcessRsp(SRpcMsg *pRsp);
|
||||||
void mndTransPullup(SMnode *pMnode);
|
void mndTransPullup(SMnode *pMnode);
|
||||||
int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans);
|
int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans);
|
||||||
void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader);
|
void mndTransExecute(SMnode *pMnode, STrans *pTrans);
|
||||||
|
void mndTransRefresh(SMnode *pMnode, STrans *pTrans);
|
||||||
int32_t mndSetRpcInfoForDbTrans(SMnode *pMnode, SRpcMsg *pMsg, EOperType oper, const char *dbname);
|
int32_t mndSetRpcInfoForDbTrans(SMnode *pMnode, SRpcMsg *pMsg, EOperType oper, const char *dbname);
|
||||||
|
|
||||||
|
SSdbRaw *mndTransEncode(STrans *pTrans);
|
||||||
|
SSdbRow *mndTransDecode(SSdbRaw *pRaw);
|
||||||
|
void mndTransDropData(STrans *pTrans);
|
||||||
|
|
||||||
|
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,6 +40,8 @@ int32_t mndValidateUserPassInfo(SMnode *pMnode, SUserPassVersion *pUsers, int3
|
||||||
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db);
|
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db);
|
||||||
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic);
|
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic);
|
||||||
|
|
||||||
|
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew);
|
||||||
|
void mndUserFreeObj(SUserObj *pUser);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@ void mndCleanupVgroup(SMnode *pMnode);
|
||||||
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId);
|
SVgObj *mndAcquireVgroup(SMnode *pMnode, int32_t vgId);
|
||||||
void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup);
|
void mndReleaseVgroup(SMnode *pMnode, SVgObj *pVgroup);
|
||||||
SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup);
|
SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup);
|
||||||
|
SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw);
|
||||||
SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup);
|
SEpSet mndGetVgroupEpset(SMnode *pMnode, const SVgObj *pVgroup);
|
||||||
int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId);
|
int32_t mndGetVnodesNum(SMnode *pMnode, int32_t dnodeId);
|
||||||
void mndSortVnodeGid(SVgObj *pVgroup);
|
void mndSortVnodeGid(SVgObj *pVgroup);
|
||||||
|
@ -36,6 +37,7 @@ int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDb, SVgObj *pVgroup);
|
||||||
SArray *mndBuildDnodesArray(SMnode *, int32_t exceptDnodeId);
|
SArray *mndBuildDnodesArray(SMnode *, int32_t exceptDnodeId);
|
||||||
int32_t mndAllocSmaVgroup(SMnode *, SDbObj *pDb, SVgObj *pVgroup);
|
int32_t mndAllocSmaVgroup(SMnode *, SDbObj *pDb, SVgObj *pVgroup);
|
||||||
int32_t mndAllocVgroup(SMnode *, SDbObj *pDb, SVgObj **ppVgroups);
|
int32_t mndAllocVgroup(SMnode *, SDbObj *pDb, SVgObj **ppVgroups);
|
||||||
|
int32_t mndAddPrepareNewVgAction(SMnode *, STrans *pTrans, SVgObj *pVg);
|
||||||
int32_t mndAddCreateVnodeAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid);
|
int32_t mndAddCreateVnodeAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, SVnodeGid *pVgid);
|
||||||
int32_t mndAddAlterVnodeConfirmAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup);
|
int32_t mndAddAlterVnodeConfirmAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup);
|
||||||
int32_t mndAddAlterVnodeAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, tmsg_t msgType);
|
int32_t mndAddAlterVnodeAction(SMnode *, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, tmsg_t msgType);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
|
||||||
#define MND_CONSUMER_VER_NUMBER 1
|
#define MND_CONSUMER_VER_NUMBER 2
|
||||||
#define MND_CONSUMER_RESERVE_SIZE 64
|
#define MND_CONSUMER_RESERVE_SIZE 64
|
||||||
|
|
||||||
#define MND_CONSUMER_LOST_HB_CNT 6
|
#define MND_CONSUMER_LOST_HB_CNT 6
|
||||||
|
@ -391,12 +391,13 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
||||||
|
int32_t code = 0;
|
||||||
SMnode *pMnode = pMsg->info.node;
|
SMnode *pMnode = pMsg->info.node;
|
||||||
SMqHbReq req = {0};
|
SMqHbReq req = {0};
|
||||||
|
|
||||||
if (tDeserializeSMqHbReq(pMsg->pCont, pMsg->contLen, &req) < 0) {
|
if ((code = tDeserializeSMqHbReq(pMsg->pCont, pMsg->contLen, &req)) < 0) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
return -1;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t consumerId = req.consumerId;
|
int64_t consumerId = req.consumerId;
|
||||||
|
@ -404,7 +405,8 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
||||||
if (pConsumer == NULL) {
|
if (pConsumer == NULL) {
|
||||||
mError("consumer:0x%" PRIx64 " not exist", consumerId);
|
mError("consumer:0x%" PRIx64 " not exist", consumerId);
|
||||||
terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST;
|
terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST;
|
||||||
return -1;
|
code = -1;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_store_32(&pConsumer->hbStatus, 0);
|
atomic_store_32(&pConsumer->hbStatus, 0);
|
||||||
|
@ -424,9 +426,28 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
||||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < taosArrayGetSize(req.topics); i++){
|
||||||
|
TopicOffsetRows* data = taosArrayGet(req.topics, i);
|
||||||
|
mDebug("heartbeat report offset rows.%s:%s", pConsumer->cgroup, data->topicName);
|
||||||
|
|
||||||
|
SMqSubscribeObj *pSub = mndAcquireSubscribe(pMnode, pConsumer->cgroup, data->topicName);
|
||||||
|
taosWLockLatch(&pSub->lock);
|
||||||
|
SMqConsumerEp *pConsumerEp = taosHashGet(pSub->consumerHash, &consumerId, sizeof(int64_t));
|
||||||
|
if(pConsumerEp){
|
||||||
|
taosArrayDestroy(pConsumerEp->offsetRows);
|
||||||
|
pConsumerEp->offsetRows = data->offsetRows;
|
||||||
|
data->offsetRows = NULL;
|
||||||
|
}
|
||||||
|
taosWUnLockLatch(&pSub->lock);
|
||||||
|
|
||||||
|
mndReleaseSubscribe(pMnode, pSub);
|
||||||
|
}
|
||||||
|
|
||||||
mndReleaseConsumer(pMnode, pConsumer);
|
mndReleaseConsumer(pMnode, pConsumer);
|
||||||
|
|
||||||
return 0;
|
end:
|
||||||
|
tDeatroySMqHbReq(&req);
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
||||||
|
@ -644,7 +665,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
||||||
SCMSubscribeReq subscribe = {0};
|
SCMSubscribeReq subscribe = {0};
|
||||||
tDeserializeSCMSubscribeReq(msgStr, &subscribe);
|
tDeserializeSCMSubscribeReq(msgStr, &subscribe);
|
||||||
|
|
||||||
uint64_t consumerId = subscribe.consumerId;
|
int64_t consumerId = subscribe.consumerId;
|
||||||
char *cgroup = subscribe.cgroup;
|
char *cgroup = subscribe.cgroup;
|
||||||
SMqConsumerObj *pExistedConsumer = NULL;
|
SMqConsumerObj *pExistedConsumer = NULL;
|
||||||
SMqConsumerObj *pConsumerNew = NULL;
|
SMqConsumerObj *pConsumerNew = NULL;
|
||||||
|
@ -675,6 +696,11 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
||||||
pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup);
|
pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup);
|
||||||
tstrncpy(pConsumerNew->clientId, subscribe.clientId, tListLen(pConsumerNew->clientId));
|
tstrncpy(pConsumerNew->clientId, subscribe.clientId, tListLen(pConsumerNew->clientId));
|
||||||
|
|
||||||
|
pConsumerNew->withTbName = subscribe.withTbName;
|
||||||
|
pConsumerNew->autoCommit = subscribe.autoCommit;
|
||||||
|
pConsumerNew->autoCommitInterval = subscribe.autoCommitInterval;
|
||||||
|
pConsumerNew->resetOffsetCfg = subscribe.resetOffsetCfg;
|
||||||
|
|
||||||
// set the update type
|
// set the update type
|
||||||
pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
|
pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
|
||||||
taosArrayDestroy(pConsumerNew->assignedTopics);
|
taosArrayDestroy(pConsumerNew->assignedTopics);
|
||||||
|
@ -822,7 +848,7 @@ SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw) {
|
||||||
goto CM_DECODE_OVER;
|
goto CM_DECODE_OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sver != MND_CONSUMER_VER_NUMBER) {
|
if (sver < 1 || sver > MND_CONSUMER_VER_NUMBER) {
|
||||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||||
goto CM_DECODE_OVER;
|
goto CM_DECODE_OVER;
|
||||||
}
|
}
|
||||||
|
@ -849,7 +875,7 @@ SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_BINARY(pRaw, dataPos, buf, len, CM_DECODE_OVER);
|
SDB_GET_BINARY(pRaw, dataPos, buf, len, CM_DECODE_OVER);
|
||||||
SDB_GET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE, CM_DECODE_OVER);
|
SDB_GET_RESERVE(pRaw, dataPos, MND_CONSUMER_RESERVE_SIZE, CM_DECODE_OVER);
|
||||||
|
|
||||||
if (tDecodeSMqConsumerObj(buf, pConsumer) == NULL) {
|
if (tDecodeSMqConsumerObj(buf, pConsumer, sver) == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY; // TODO set correct error code
|
terrno = TSDB_CODE_OUT_OF_MEMORY; // TODO set correct error code
|
||||||
goto CM_DECODE_OVER;
|
goto CM_DECODE_OVER;
|
||||||
}
|
}
|
||||||
|
@ -1159,6 +1185,17 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumer->rebalanceTime, pConsumer->rebalanceTime == 0);
|
colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumer->rebalanceTime, pConsumer->rebalanceTime == 0);
|
||||||
|
|
||||||
|
char buf[TSDB_OFFSET_LEN] = {0};
|
||||||
|
STqOffsetVal pVal = {.type = pConsumer->resetOffsetCfg};
|
||||||
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &pVal);
|
||||||
|
|
||||||
|
char parasStr[64 + TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
|
sprintf(varDataVal(parasStr), "tbname:%d,commit:%d,interval:%d,reset:%s", pConsumer->withTbName, pConsumer->autoCommit, pConsumer->autoCommitInterval, buf);
|
||||||
|
varDataSetLen(parasStr, strlen(varDataVal(parasStr)));
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, numOfRows, (const char *)parasStr, false);
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,6 +414,13 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) {
|
||||||
if (pCfg->tsdbPageSize <= 0) pCfg->tsdbPageSize = TSDB_DEFAULT_TSDB_PAGESIZE;
|
if (pCfg->tsdbPageSize <= 0) pCfg->tsdbPageSize = TSDB_DEFAULT_TSDB_PAGESIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetPrepareNewVgActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
||||||
|
for (int32_t v = 0; v < pDb->cfg.numOfVgroups; ++v) {
|
||||||
|
if (mndAddPrepareNewVgAction(pMnode, pTrans, (pVgroups + v)) != 0) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mndSetCreateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
static int32_t mndSetCreateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
||||||
SSdbRaw *pDbRaw = mndDbActionEncode(pDb);
|
SSdbRaw *pDbRaw = mndDbActionEncode(pDb);
|
||||||
if (pDbRaw == NULL) return -1;
|
if (pDbRaw == NULL) return -1;
|
||||||
|
@ -424,7 +431,7 @@ static int32_t mndSetCreateDbRedoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pD
|
||||||
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroups + v);
|
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroups + v);
|
||||||
if (pVgRaw == NULL) return -1;
|
if (pVgRaw == NULL) return -1;
|
||||||
if (mndTransAppendRedolog(pTrans, pVgRaw) != 0) return -1;
|
if (mndTransAppendRedolog(pTrans, pVgRaw) != 0) return -1;
|
||||||
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_CREATING) != 0) return -1;
|
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_UPDATE) != 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -446,7 +453,8 @@ static int32_t mndSetCreateDbUndoLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pD
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndSetCreateDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups) {
|
static int32_t mndSetCreateDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroups,
|
||||||
|
SUserObj *pUserDuped) {
|
||||||
SSdbRaw *pDbRaw = mndDbActionEncode(pDb);
|
SSdbRaw *pDbRaw = mndDbActionEncode(pDb);
|
||||||
if (pDbRaw == NULL) return -1;
|
if (pDbRaw == NULL) return -1;
|
||||||
if (mndTransAppendCommitlog(pTrans, pDbRaw) != 0) return -1;
|
if (mndTransAppendCommitlog(pTrans, pDbRaw) != 0) return -1;
|
||||||
|
@ -459,6 +467,13 @@ static int32_t mndSetCreateDbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj *
|
||||||
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_READY) != 0) return -1;
|
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_READY) != 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pUserDuped) {
|
||||||
|
SSdbRaw *pUserRaw = mndUserActionEncode(pUserDuped);
|
||||||
|
if (pUserRaw == NULL) return -1;
|
||||||
|
if (mndTransAppendCommitlog(pTrans, pUserRaw) != 0) return -1;
|
||||||
|
if (sdbSetRawStatus(pUserRaw, SDB_STATUS_READY) != 0) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,6 +580,15 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add database privileges for user
|
||||||
|
SUserObj newUserObj = {0}, *pNewUserDuped = NULL;
|
||||||
|
if (!pUser->superUser) {
|
||||||
|
if (mndUserDupObj(pUser, &newUserObj) != 0) goto _OVER;
|
||||||
|
taosHashPut(newUserObj.readDbs, dbObj.name, strlen(dbObj.name) + 1, dbObj.name, TSDB_FILENAME_LEN);
|
||||||
|
taosHashPut(newUserObj.writeDbs, dbObj.name, strlen(dbObj.name) + 1, dbObj.name, TSDB_FILENAME_LEN);
|
||||||
|
pNewUserDuped = &newUserObj;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "create-db");
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "create-db");
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
|
@ -572,12 +596,13 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
||||||
mInfo("trans:%d, used to create db:%s", pTrans->id, pCreate->db);
|
mInfo("trans:%d, used to create db:%s", pTrans->id, pCreate->db);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, dbObj.name, NULL);
|
mndTransSetDbName(pTrans, dbObj.name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
mndTransSetOper(pTrans, MND_OPER_CREATE_DB);
|
mndTransSetOper(pTrans, MND_OPER_CREATE_DB);
|
||||||
|
if (mndSetPrepareNewVgActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
||||||
if (mndSetCreateDbRedoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
if (mndSetCreateDbRedoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
||||||
if (mndSetCreateDbUndoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
if (mndSetCreateDbUndoLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
||||||
if (mndSetCreateDbCommitLogs(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
if (mndSetCreateDbCommitLogs(pMnode, pTrans, &dbObj, pVgroups, pNewUserDuped) != 0) goto _OVER;
|
||||||
if (mndSetCreateDbRedoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
if (mndSetCreateDbRedoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
||||||
if (mndSetCreateDbUndoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
if (mndSetCreateDbUndoActions(pMnode, pTrans, &dbObj, pVgroups) != 0) goto _OVER;
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
@ -586,6 +611,7 @@ static int32_t mndCreateDb(SMnode *pMnode, SRpcMsg *pReq, SCreateDbReq *pCreate,
|
||||||
|
|
||||||
_OVER:
|
_OVER:
|
||||||
taosMemoryFree(pVgroups);
|
taosMemoryFree(pVgroups);
|
||||||
|
mndUserFreeObj(&newUserObj);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -814,7 +840,7 @@ static int32_t mndAlterDb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pOld, SDbObj *p
|
||||||
|
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
mndTransSetDbName(pTrans, pOld->name, NULL);
|
mndTransSetDbName(pTrans, pOld->name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndSetAlterDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
|
if (mndSetAlterDbRedoLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
|
||||||
if (mndSetAlterDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
|
if (mndSetAlterDbCommitLogs(pMnode, pTrans, pOld, pNew) != 0) goto _OVER;
|
||||||
|
@ -1111,7 +1137,7 @@ static int32_t mndDropDb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb) {
|
||||||
mInfo("trans:%d start to drop db:%s", pTrans->id, pDb->name);
|
mInfo("trans:%d start to drop db:%s", pTrans->id, pDb->name);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,14 +187,14 @@ SMqVgEp *tCloneSMqVgEp(const SMqVgEp *pVgEp) {
|
||||||
SMqVgEp *pVgEpNew = taosMemoryMalloc(sizeof(SMqVgEp));
|
SMqVgEp *pVgEpNew = taosMemoryMalloc(sizeof(SMqVgEp));
|
||||||
if (pVgEpNew == NULL) return NULL;
|
if (pVgEpNew == NULL) return NULL;
|
||||||
pVgEpNew->vgId = pVgEp->vgId;
|
pVgEpNew->vgId = pVgEp->vgId;
|
||||||
pVgEpNew->qmsg = taosStrdup(pVgEp->qmsg);
|
// pVgEpNew->qmsg = taosStrdup(pVgEp->qmsg);
|
||||||
pVgEpNew->epSet = pVgEp->epSet;
|
pVgEpNew->epSet = pVgEp->epSet;
|
||||||
return pVgEpNew;
|
return pVgEpNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tDeleteSMqVgEp(SMqVgEp *pVgEp) {
|
void tDeleteSMqVgEp(SMqVgEp *pVgEp) {
|
||||||
if (pVgEp) {
|
if (pVgEp) {
|
||||||
taosMemoryFreeClear(pVgEp->qmsg);
|
// taosMemoryFreeClear(pVgEp->qmsg);
|
||||||
taosMemoryFree(pVgEp);
|
taosMemoryFree(pVgEp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,14 +202,18 @@ void tDeleteSMqVgEp(SMqVgEp *pVgEp) {
|
||||||
int32_t tEncodeSMqVgEp(void **buf, const SMqVgEp *pVgEp) {
|
int32_t tEncodeSMqVgEp(void **buf, const SMqVgEp *pVgEp) {
|
||||||
int32_t tlen = 0;
|
int32_t tlen = 0;
|
||||||
tlen += taosEncodeFixedI32(buf, pVgEp->vgId);
|
tlen += taosEncodeFixedI32(buf, pVgEp->vgId);
|
||||||
tlen += taosEncodeString(buf, pVgEp->qmsg);
|
// tlen += taosEncodeString(buf, pVgEp->qmsg);
|
||||||
tlen += taosEncodeSEpSet(buf, &pVgEp->epSet);
|
tlen += taosEncodeSEpSet(buf, &pVgEp->epSet);
|
||||||
return tlen;
|
return tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *tDecodeSMqVgEp(const void *buf, SMqVgEp *pVgEp) {
|
void *tDecodeSMqVgEp(const void *buf, SMqVgEp *pVgEp, int8_t sver) {
|
||||||
buf = taosDecodeFixedI32(buf, &pVgEp->vgId);
|
buf = taosDecodeFixedI32(buf, &pVgEp->vgId);
|
||||||
buf = taosDecodeString(buf, &pVgEp->qmsg);
|
if(sver == 1){
|
||||||
|
uint64_t size = 0;
|
||||||
|
buf = taosDecodeVariantU64(buf, &size);
|
||||||
|
buf = POINTER_SHIFT(buf, size);
|
||||||
|
}
|
||||||
buf = taosDecodeSEpSet(buf, &pVgEp->epSet);
|
buf = taosDecodeSEpSet(buf, &pVgEp->epSet);
|
||||||
return (void *)buf;
|
return (void *)buf;
|
||||||
}
|
}
|
||||||
|
@ -321,10 +325,14 @@ int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) {
|
||||||
tlen += taosEncodeFixedI32(buf, 0);
|
tlen += taosEncodeFixedI32(buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlen += taosEncodeFixedI8(buf, pConsumer->withTbName);
|
||||||
|
tlen += taosEncodeFixedI8(buf, pConsumer->autoCommit);
|
||||||
|
tlen += taosEncodeFixedI32(buf, pConsumer->autoCommitInterval);
|
||||||
|
tlen += taosEncodeFixedI32(buf, pConsumer->resetOffsetCfg);
|
||||||
return tlen;
|
return tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer) {
|
void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer, int8_t sver) {
|
||||||
int32_t sz;
|
int32_t sz;
|
||||||
buf = taosDecodeFixedI64(buf, &pConsumer->consumerId);
|
buf = taosDecodeFixedI64(buf, &pConsumer->consumerId);
|
||||||
buf = taosDecodeStringTo(buf, pConsumer->clientId);
|
buf = taosDecodeStringTo(buf, pConsumer->clientId);
|
||||||
|
@ -375,50 +383,94 @@ void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer) {
|
||||||
taosArrayPush(pConsumer->assignedTopics, &topic);
|
taosArrayPush(pConsumer->assignedTopics, &topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sver > 1){
|
||||||
|
buf = taosDecodeFixedI8(buf, &pConsumer->withTbName);
|
||||||
|
buf = taosDecodeFixedI8(buf, &pConsumer->autoCommit);
|
||||||
|
buf = taosDecodeFixedI32(buf, &pConsumer->autoCommitInterval);
|
||||||
|
buf = taosDecodeFixedI32(buf, &pConsumer->resetOffsetCfg);
|
||||||
|
}
|
||||||
return (void *)buf;
|
return (void *)buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMqConsumerEp *tCloneSMqConsumerEp(const SMqConsumerEp *pConsumerEpOld) {
|
//SMqConsumerEp *tCloneSMqConsumerEp(const SMqConsumerEp *pConsumerEpOld) {
|
||||||
SMqConsumerEp *pConsumerEpNew = taosMemoryMalloc(sizeof(SMqConsumerEp));
|
// SMqConsumerEp *pConsumerEpNew = taosMemoryMalloc(sizeof(SMqConsumerEp));
|
||||||
if (pConsumerEpNew == NULL) return NULL;
|
// if (pConsumerEpNew == NULL) return NULL;
|
||||||
pConsumerEpNew->consumerId = pConsumerEpOld->consumerId;
|
// pConsumerEpNew->consumerId = pConsumerEpOld->consumerId;
|
||||||
pConsumerEpNew->vgs = taosArrayDup(pConsumerEpOld->vgs, (__array_item_dup_fn_t)tCloneSMqVgEp);
|
// pConsumerEpNew->vgs = taosArrayDup(pConsumerEpOld->vgs, NULL);
|
||||||
return pConsumerEpNew;
|
// return pConsumerEpNew;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void tDeleteSMqConsumerEp(void *data) {
|
//void tDeleteSMqConsumerEp(void *data) {
|
||||||
SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)data;
|
// SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)data;
|
||||||
taosArrayDestroyP(pConsumerEp->vgs, (FDelete)tDeleteSMqVgEp);
|
// taosArrayDestroy(pConsumerEp->vgs);
|
||||||
}
|
//}
|
||||||
|
|
||||||
int32_t tEncodeSMqConsumerEp(void **buf, const SMqConsumerEp *pConsumerEp) {
|
int32_t tEncodeSMqConsumerEp(void **buf, const SMqConsumerEp *pConsumerEp) {
|
||||||
int32_t tlen = 0;
|
int32_t tlen = 0;
|
||||||
tlen += taosEncodeFixedI64(buf, pConsumerEp->consumerId);
|
tlen += taosEncodeFixedI64(buf, pConsumerEp->consumerId);
|
||||||
tlen += taosEncodeArray(buf, pConsumerEp->vgs, (FEncode)tEncodeSMqVgEp);
|
tlen += taosEncodeArray(buf, pConsumerEp->vgs, (FEncode)tEncodeSMqVgEp);
|
||||||
#if 0
|
int32_t szVgs = taosArrayGetSize(pConsumerEp->offsetRows);
|
||||||
int32_t sz = taosArrayGetSize(pConsumerEp->vgs);
|
tlen += taosEncodeFixedI32(buf, szVgs);
|
||||||
tlen += taosEncodeFixedI32(buf, sz);
|
for (int32_t j= 0; j < szVgs; ++j) {
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
OffsetRows *offRows = taosArrayGet(pConsumerEp->offsetRows, j);
|
||||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, i);
|
tlen += taosEncodeFixedI32(buf, offRows->vgId);
|
||||||
tlen += tEncodeSMqVgEp(buf, pVgEp);
|
tlen += taosEncodeFixedI64(buf, offRows->rows);
|
||||||
|
tlen += taosEncodeFixedI8(buf, offRows->offset.type);
|
||||||
|
if (offRows->offset.type == TMQ_OFFSET__SNAPSHOT_DATA || offRows->offset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.uid);
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.ts);
|
||||||
|
} else if (offRows->offset.type == TMQ_OFFSET__LOG) {
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.version);
|
||||||
|
} else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
//#if 0
|
||||||
|
// int32_t sz = taosArrayGetSize(pConsumerEp->vgs);
|
||||||
|
// tlen += taosEncodeFixedI32(buf, sz);
|
||||||
|
// for (int32_t i = 0; i < sz; i++) {
|
||||||
|
// SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, i);
|
||||||
|
// tlen += tEncodeSMqVgEp(buf, pVgEp);
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
return tlen;
|
return tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *tDecodeSMqConsumerEp(const void *buf, SMqConsumerEp *pConsumerEp) {
|
void *tDecodeSMqConsumerEp(const void *buf, SMqConsumerEp *pConsumerEp, int8_t sver) {
|
||||||
buf = taosDecodeFixedI64(buf, &pConsumerEp->consumerId);
|
buf = taosDecodeFixedI64(buf, &pConsumerEp->consumerId);
|
||||||
buf = taosDecodeArray(buf, &pConsumerEp->vgs, (FDecode)tDecodeSMqVgEp, sizeof(SMqVgEp));
|
buf = taosDecodeArray(buf, &pConsumerEp->vgs, (FDecode)tDecodeSMqVgEp, sizeof(SMqVgEp), sver);
|
||||||
#if 0
|
if (sver > 1){
|
||||||
int32_t sz;
|
int32_t szVgs = 0;
|
||||||
buf = taosDecodeFixedI32(buf, &sz);
|
buf = taosDecodeFixedI32(buf, &szVgs);
|
||||||
pConsumerEp->vgs = taosArrayInit(sz, sizeof(void *));
|
if(szVgs > 0){
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
pConsumerEp->offsetRows = taosArrayInit(szVgs, sizeof(OffsetRows));
|
||||||
SMqVgEp *pVgEp = taosMemoryMalloc(sizeof(SMqVgEp));
|
if (NULL == pConsumerEp->offsetRows) return NULL;
|
||||||
buf = tDecodeSMqVgEp(buf, pVgEp);
|
for (int32_t j= 0; j < szVgs; ++j) {
|
||||||
taosArrayPush(pConsumerEp->vgs, &pVgEp);
|
OffsetRows* offRows = taosArrayReserve(pConsumerEp->offsetRows, 1);
|
||||||
|
buf = taosDecodeFixedI32(buf, &offRows->vgId);
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->rows);
|
||||||
|
buf = taosDecodeFixedI8(buf, &offRows->offset.type);
|
||||||
|
if (offRows->offset.type == TMQ_OFFSET__SNAPSHOT_DATA || offRows->offset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.uid);
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.ts);
|
||||||
|
} else if (offRows->offset.type == TMQ_OFFSET__LOG) {
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.version);
|
||||||
|
} else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
//#if 0
|
||||||
|
// int32_t sz;
|
||||||
|
// buf = taosDecodeFixedI32(buf, &sz);
|
||||||
|
// pConsumerEp->vgs = taosArrayInit(sz, sizeof(void *));
|
||||||
|
// for (int32_t i = 0; i < sz; i++) {
|
||||||
|
// SMqVgEp *pVgEp = taosMemoryMalloc(sizeof(SMqVgEp));
|
||||||
|
// buf = tDecodeSMqVgEp(buf, pVgEp);
|
||||||
|
// taosArrayPush(pConsumerEp->vgs, &pVgEp);
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
return (void *)buf;
|
return (void *)buf;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +520,9 @@ SMqSubscribeObj *tCloneSubscribeObj(const SMqSubscribeObj *pSub) {
|
||||||
taosHashPut(pSubNew->consumerHash, &newEp.consumerId, sizeof(int64_t), &newEp, sizeof(SMqConsumerEp));
|
taosHashPut(pSubNew->consumerHash, &newEp.consumerId, sizeof(int64_t), &newEp, sizeof(SMqConsumerEp));
|
||||||
}
|
}
|
||||||
pSubNew->unassignedVgs = taosArrayDup(pSub->unassignedVgs, (__array_item_dup_fn_t)tCloneSMqVgEp);
|
pSubNew->unassignedVgs = taosArrayDup(pSub->unassignedVgs, (__array_item_dup_fn_t)tCloneSMqVgEp);
|
||||||
|
pSubNew->offsetRows = taosArrayDup(pSub->offsetRows, NULL);
|
||||||
memcpy(pSubNew->dbName, pSub->dbName, TSDB_DB_FNAME_LEN);
|
memcpy(pSubNew->dbName, pSub->dbName, TSDB_DB_FNAME_LEN);
|
||||||
|
pSubNew->qmsg = taosStrdup(pSub->qmsg);
|
||||||
return pSubNew;
|
return pSubNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,9 +533,12 @@ void tDeleteSubscribeObj(SMqSubscribeObj *pSub) {
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)pIter;
|
SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)pIter;
|
||||||
taosArrayDestroyP(pConsumerEp->vgs, (FDelete)tDeleteSMqVgEp);
|
taosArrayDestroyP(pConsumerEp->vgs, (FDelete)tDeleteSMqVgEp);
|
||||||
|
taosArrayDestroy(pConsumerEp->offsetRows);
|
||||||
}
|
}
|
||||||
taosHashCleanup(pSub->consumerHash);
|
taosHashCleanup(pSub->consumerHash);
|
||||||
taosArrayDestroyP(pSub->unassignedVgs, (FDelete)tDeleteSMqVgEp);
|
taosArrayDestroyP(pSub->unassignedVgs, (FDelete)tDeleteSMqVgEp);
|
||||||
|
taosMemoryFreeClear(pSub->qmsg);
|
||||||
|
taosArrayDestroy(pSub->offsetRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
|
int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
|
||||||
|
@ -508,10 +565,28 @@ int32_t tEncodeSubscribeObj(void **buf, const SMqSubscribeObj *pSub) {
|
||||||
if (cnt != sz) return -1;
|
if (cnt != sz) return -1;
|
||||||
tlen += taosEncodeArray(buf, pSub->unassignedVgs, (FEncode)tEncodeSMqVgEp);
|
tlen += taosEncodeArray(buf, pSub->unassignedVgs, (FEncode)tEncodeSMqVgEp);
|
||||||
tlen += taosEncodeString(buf, pSub->dbName);
|
tlen += taosEncodeString(buf, pSub->dbName);
|
||||||
|
|
||||||
|
int32_t szVgs = taosArrayGetSize(pSub->offsetRows);
|
||||||
|
tlen += taosEncodeFixedI32(buf, szVgs);
|
||||||
|
for (int32_t j= 0; j < szVgs; ++j) {
|
||||||
|
OffsetRows *offRows = taosArrayGet(pSub->offsetRows, j);
|
||||||
|
tlen += taosEncodeFixedI32(buf, offRows->vgId);
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->rows);
|
||||||
|
tlen += taosEncodeFixedI8(buf, offRows->offset.type);
|
||||||
|
if (offRows->offset.type == TMQ_OFFSET__SNAPSHOT_DATA || offRows->offset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.uid);
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.ts);
|
||||||
|
} else if (offRows->offset.type == TMQ_OFFSET__LOG) {
|
||||||
|
tlen += taosEncodeFixedI64(buf, offRows->offset.version);
|
||||||
|
} else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tlen += taosEncodeString(buf, pSub->qmsg);
|
||||||
return tlen;
|
return tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub) {
|
void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub, int8_t sver) {
|
||||||
//
|
//
|
||||||
buf = taosDecodeStringTo(buf, pSub->key);
|
buf = taosDecodeStringTo(buf, pSub->key);
|
||||||
buf = taosDecodeFixedI64(buf, &pSub->dbUid);
|
buf = taosDecodeFixedI64(buf, &pSub->dbUid);
|
||||||
|
@ -526,74 +601,98 @@ void *tDecodeSubscribeObj(const void *buf, SMqSubscribeObj *pSub) {
|
||||||
pSub->consumerHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
pSub->consumerHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
SMqConsumerEp consumerEp = {0};
|
SMqConsumerEp consumerEp = {0};
|
||||||
buf = tDecodeSMqConsumerEp(buf, &consumerEp);
|
buf = tDecodeSMqConsumerEp(buf, &consumerEp, sver);
|
||||||
taosHashPut(pSub->consumerHash, &consumerEp.consumerId, sizeof(int64_t), &consumerEp, sizeof(SMqConsumerEp));
|
taosHashPut(pSub->consumerHash, &consumerEp.consumerId, sizeof(int64_t), &consumerEp, sizeof(SMqConsumerEp));
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = taosDecodeArray(buf, &pSub->unassignedVgs, (FDecode)tDecodeSMqVgEp, sizeof(SMqVgEp));
|
buf = taosDecodeArray(buf, &pSub->unassignedVgs, (FDecode)tDecodeSMqVgEp, sizeof(SMqVgEp), sver);
|
||||||
buf = taosDecodeStringTo(buf, pSub->dbName);
|
buf = taosDecodeStringTo(buf, pSub->dbName);
|
||||||
|
|
||||||
|
if (sver > 1){
|
||||||
|
int32_t szVgs = 0;
|
||||||
|
buf = taosDecodeFixedI32(buf, &szVgs);
|
||||||
|
if(szVgs > 0){
|
||||||
|
pSub->offsetRows = taosArrayInit(szVgs, sizeof(OffsetRows));
|
||||||
|
if (NULL == pSub->offsetRows) return NULL;
|
||||||
|
for (int32_t j= 0; j < szVgs; ++j) {
|
||||||
|
OffsetRows* offRows = taosArrayReserve(pSub->offsetRows, 1);
|
||||||
|
buf = taosDecodeFixedI32(buf, &offRows->vgId);
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->rows);
|
||||||
|
buf = taosDecodeFixedI8(buf, &offRows->offset.type);
|
||||||
|
if (offRows->offset.type == TMQ_OFFSET__SNAPSHOT_DATA || offRows->offset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.uid);
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.ts);
|
||||||
|
} else if (offRows->offset.type == TMQ_OFFSET__LOG) {
|
||||||
|
buf = taosDecodeFixedI64(buf, &offRows->offset.version);
|
||||||
|
} else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf = taosDecodeString(buf, &pSub->qmsg);
|
||||||
|
}
|
||||||
return (void *)buf;
|
return (void *)buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMqSubActionLogEntry *tCloneSMqSubActionLogEntry(SMqSubActionLogEntry *pEntry) {
|
//SMqSubActionLogEntry *tCloneSMqSubActionLogEntry(SMqSubActionLogEntry *pEntry) {
|
||||||
SMqSubActionLogEntry *pEntryNew = taosMemoryMalloc(sizeof(SMqSubActionLogEntry));
|
// SMqSubActionLogEntry *pEntryNew = taosMemoryMalloc(sizeof(SMqSubActionLogEntry));
|
||||||
if (pEntryNew == NULL) return NULL;
|
// if (pEntryNew == NULL) return NULL;
|
||||||
pEntryNew->epoch = pEntry->epoch;
|
// pEntryNew->epoch = pEntry->epoch;
|
||||||
pEntryNew->consumers = taosArrayDup(pEntry->consumers, (__array_item_dup_fn_t)tCloneSMqConsumerEp);
|
// pEntryNew->consumers = taosArrayDup(pEntry->consumers, (__array_item_dup_fn_t)tCloneSMqConsumerEp);
|
||||||
return pEntryNew;
|
// return pEntryNew;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//void tDeleteSMqSubActionLogEntry(SMqSubActionLogEntry *pEntry) {
|
||||||
|
// taosArrayDestroyEx(pEntry->consumers, (FDelete)tDeleteSMqConsumerEp);
|
||||||
|
//}
|
||||||
|
|
||||||
void tDeleteSMqSubActionLogEntry(SMqSubActionLogEntry *pEntry) {
|
//int32_t tEncodeSMqSubActionLogEntry(void **buf, const SMqSubActionLogEntry *pEntry) {
|
||||||
taosArrayDestroyEx(pEntry->consumers, (FDelete)tDeleteSMqConsumerEp);
|
// int32_t tlen = 0;
|
||||||
}
|
// tlen += taosEncodeFixedI32(buf, pEntry->epoch);
|
||||||
|
// tlen += taosEncodeArray(buf, pEntry->consumers, (FEncode)tEncodeSMqSubActionLogEntry);
|
||||||
|
// return tlen;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void *tDecodeSMqSubActionLogEntry(const void *buf, SMqSubActionLogEntry *pEntry) {
|
||||||
|
// buf = taosDecodeFixedI32(buf, &pEntry->epoch);
|
||||||
|
// buf = taosDecodeArray(buf, &pEntry->consumers, (FDecode)tDecodeSMqSubActionLogEntry, sizeof(SMqSubActionLogEntry));
|
||||||
|
// return (void *)buf;
|
||||||
|
//}
|
||||||
|
|
||||||
int32_t tEncodeSMqSubActionLogEntry(void **buf, const SMqSubActionLogEntry *pEntry) {
|
//SMqSubActionLogObj *tCloneSMqSubActionLogObj(SMqSubActionLogObj *pLog) {
|
||||||
int32_t tlen = 0;
|
// SMqSubActionLogObj *pLogNew = taosMemoryMalloc(sizeof(SMqSubActionLogObj));
|
||||||
tlen += taosEncodeFixedI32(buf, pEntry->epoch);
|
// if (pLogNew == NULL) return pLogNew;
|
||||||
tlen += taosEncodeArray(buf, pEntry->consumers, (FEncode)tEncodeSMqSubActionLogEntry);
|
// memcpy(pLogNew->key, pLog->key, TSDB_SUBSCRIBE_KEY_LEN);
|
||||||
return tlen;
|
// pLogNew->logs = taosArrayDup(pLog->logs, (__array_item_dup_fn_t)tCloneSMqConsumerEp);
|
||||||
}
|
// return pLogNew;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void tDeleteSMqSubActionLogObj(SMqSubActionLogObj *pLog) {
|
||||||
|
// taosArrayDestroyEx(pLog->logs, (FDelete)tDeleteSMqConsumerEp);
|
||||||
|
//}
|
||||||
|
|
||||||
void *tDecodeSMqSubActionLogEntry(const void *buf, SMqSubActionLogEntry *pEntry) {
|
//int32_t tEncodeSMqSubActionLogObj(void **buf, const SMqSubActionLogObj *pLog) {
|
||||||
buf = taosDecodeFixedI32(buf, &pEntry->epoch);
|
// int32_t tlen = 0;
|
||||||
buf = taosDecodeArray(buf, &pEntry->consumers, (FDecode)tDecodeSMqSubActionLogEntry, sizeof(SMqSubActionLogEntry));
|
// tlen += taosEncodeString(buf, pLog->key);
|
||||||
return (void *)buf;
|
// tlen += taosEncodeArray(buf, pLog->logs, (FEncode)tEncodeSMqSubActionLogEntry);
|
||||||
}
|
// return tlen;
|
||||||
|
//}
|
||||||
SMqSubActionLogObj *tCloneSMqSubActionLogObj(SMqSubActionLogObj *pLog) {
|
//
|
||||||
SMqSubActionLogObj *pLogNew = taosMemoryMalloc(sizeof(SMqSubActionLogObj));
|
//void *tDecodeSMqSubActionLogObj(const void *buf, SMqSubActionLogObj *pLog) {
|
||||||
if (pLogNew == NULL) return pLogNew;
|
// buf = taosDecodeStringTo(buf, pLog->key);
|
||||||
memcpy(pLogNew->key, pLog->key, TSDB_SUBSCRIBE_KEY_LEN);
|
// buf = taosDecodeArray(buf, &pLog->logs, (FDecode)tDecodeSMqSubActionLogEntry, sizeof(SMqSubActionLogEntry));
|
||||||
pLogNew->logs = taosArrayDup(pLog->logs, (__array_item_dup_fn_t)tCloneSMqConsumerEp);
|
// return (void *)buf;
|
||||||
return pLogNew;
|
//}
|
||||||
}
|
//
|
||||||
|
//int32_t tEncodeSMqOffsetObj(void **buf, const SMqOffsetObj *pOffset) {
|
||||||
void tDeleteSMqSubActionLogObj(SMqSubActionLogObj *pLog) {
|
// int32_t tlen = 0;
|
||||||
taosArrayDestroyEx(pLog->logs, (FDelete)tDeleteSMqConsumerEp);
|
// tlen += taosEncodeString(buf, pOffset->key);
|
||||||
}
|
// tlen += taosEncodeFixedI64(buf, pOffset->offset);
|
||||||
|
// return tlen;
|
||||||
int32_t tEncodeSMqSubActionLogObj(void **buf, const SMqSubActionLogObj *pLog) {
|
//}
|
||||||
int32_t tlen = 0;
|
//
|
||||||
tlen += taosEncodeString(buf, pLog->key);
|
//void *tDecodeSMqOffsetObj(void *buf, SMqOffsetObj *pOffset) {
|
||||||
tlen += taosEncodeArray(buf, pLog->logs, (FEncode)tEncodeSMqSubActionLogEntry);
|
// buf = taosDecodeStringTo(buf, pOffset->key);
|
||||||
return tlen;
|
// buf = taosDecodeFixedI64(buf, &pOffset->offset);
|
||||||
}
|
// return buf;
|
||||||
|
//}
|
||||||
void *tDecodeSMqSubActionLogObj(const void *buf, SMqSubActionLogObj *pLog) {
|
|
||||||
buf = taosDecodeStringTo(buf, pLog->key);
|
|
||||||
buf = taosDecodeArray(buf, &pLog->logs, (FDecode)tDecodeSMqSubActionLogEntry, sizeof(SMqSubActionLogEntry));
|
|
||||||
return (void *)buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tEncodeSMqOffsetObj(void **buf, const SMqOffsetObj *pOffset) {
|
|
||||||
int32_t tlen = 0;
|
|
||||||
tlen += taosEncodeString(buf, pOffset->key);
|
|
||||||
tlen += taosEncodeFixedI64(buf, pOffset->offset);
|
|
||||||
return tlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *tDecodeSMqOffsetObj(void *buf, SMqOffsetObj *pOffset) {
|
|
||||||
buf = taosDecodeStringTo(buf, pOffset->key);
|
|
||||||
buf = taosDecodeFixedI64(buf, &pOffset->offset);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
|
@ -632,7 +632,7 @@ static int32_t mndCreateDnode(SMnode *pMnode, SRpcMsg *pReq, SCreateDnodeReq *pC
|
||||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
|
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_GLOBAL, pReq, "create-dnode");
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
|
mInfo("trans:%d, used to create dnode:%s", pTrans->id, dnodeObj.ep);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
pRaw = mndDnodeActionEncode(&dnodeObj);
|
pRaw = mndDnodeActionEncode(&dnodeObj);
|
||||||
if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
|
if (pRaw == NULL || mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
|
||||||
|
@ -889,7 +889,7 @@ static int32_t mndDropDnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode, SM
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
mInfo("trans:%d, used to drop dnode:%d, force:%d", pTrans->id, pDnode->id, force);
|
mInfo("trans:%d, used to drop dnode:%d, force:%d", pTrans->id, pDnode->id, force);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
pRaw = mndDnodeActionEncode(pDnode);
|
pRaw = mndDnodeActionEncode(pDnode);
|
||||||
if (pRaw == NULL) goto _OVER;
|
if (pRaw == NULL) goto _OVER;
|
||||||
|
|
|
@ -645,7 +645,7 @@ int32_t mndAddIndexImpl(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pSt
|
||||||
|
|
||||||
// mInfo("trans:%d, used to add index to stb:%s", pTrans->id, pStb->name);
|
// mInfo("trans:%d, used to add index to stb:%s", pTrans->id, pStb->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ static int32_t mndDropIdx(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SIdxObj *p
|
||||||
|
|
||||||
mInfo("trans:%d, used to drop idx:%s", pTrans->id, pIdx->name);
|
mInfo("trans:%d, used to drop idx:%s", pTrans->id, pIdx->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
if (mndSetDropIdxRedoLogs(pMnode, pTrans, pIdx) != 0) goto _OVER;
|
if (mndSetDropIdxRedoLogs(pMnode, pTrans, pIdx) != 0) goto _OVER;
|
||||||
|
@ -860,4 +860,4 @@ int32_t mndDropIdxsByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,7 +578,7 @@ static int32_t mndCreateMnode(SMnode *pMnode, SRpcMsg *pReq, SDnodeObj *pDnode,
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
mInfo("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId);
|
mInfo("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
SMnodeObj mnodeObj = {0};
|
SMnodeObj mnodeObj = {0};
|
||||||
mnodeObj.id = pDnode->id;
|
mnodeObj.id = pDnode->id;
|
||||||
|
@ -732,7 +732,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SRpcMsg *pReq, SMnodeObj *pObj) {
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
mInfo("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id);
|
mInfo("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndSetDropMnodeInfoToTrans(pMnode, pTrans, pObj, false) != 0) goto _OVER;
|
if (mndSetDropMnodeInfoToTrans(pMnode, pTrans, pObj, false) != 0) goto _OVER;
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
|
@ -227,6 +227,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((code = taosCheckVersionCompatibleFromStr(connReq.sVer, version, 3)) != 0) {
|
if ((code = taosCheckVersionCompatibleFromStr(connReq.sVer, version, 3)) != 0) {
|
||||||
|
mGError("version not compatible. client version: %s, server version: %s", connReq.sVer, version);
|
||||||
terrno = code;
|
terrno = code;
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +246,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1) != 0) {
|
if (strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1) != 0 && !tsMndSkipGrant) {
|
||||||
mGError("user:%s, failed to login from %s since invalid pass, input:%s", pReq->info.conn.user, ip, connReq.passwd);
|
mGError("user:%s, failed to login from %s since invalid pass, input:%s", pReq->info.conn.user, ip, connReq.passwd);
|
||||||
code = TSDB_CODE_MND_AUTH_FAILURE;
|
code = TSDB_CODE_MND_AUTH_FAILURE;
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
|
@ -834,6 +835,9 @@ static int32_t mndRetrieveQueries(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pQuery->stableQuery, false);
|
colDataSetVal(pColInfo, numOfRows, (const char *)&pQuery->stableQuery, false);
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, numOfRows, (const char *)&pQuery->isSubQuery, false);
|
||||||
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pQuery->subPlanNum, false);
|
colDataSetVal(pColInfo, numOfRows, (const char *)&pQuery->subPlanNum, false);
|
||||||
|
|
||||||
|
|
|
@ -570,25 +570,21 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
||||||
|
|
||||||
mDebug("init subscription %s for topic:%s assign vgId:%d", pSub->key, pTopic->name, pVgEp->vgId);
|
mDebug("init subscription %s for topic:%s assign vgId:%d", pSub->key, pTopic->name, pVgEp->vgId);
|
||||||
|
|
||||||
if (pSubplan) {
|
|
||||||
int32_t msgLen;
|
|
||||||
|
|
||||||
pSubplan->execNode.epSet = pVgEp->epSet;
|
|
||||||
pSubplan->execNode.nodeId = pVgEp->vgId;
|
|
||||||
|
|
||||||
if (qSubPlanToString(pSubplan, &pVgEp->qmsg, &msgLen) < 0) {
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
|
||||||
qDestroyQueryPlan(pPlan);
|
|
||||||
terrno = TSDB_CODE_QRY_INVALID_INPUT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pVgEp->qmsg = taosStrdup("");
|
|
||||||
}
|
|
||||||
|
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSubplan) {
|
||||||
|
int32_t msgLen;
|
||||||
|
|
||||||
|
if (qSubPlanToString(pSubplan, &pSub->qmsg, &msgLen) < 0) {
|
||||||
|
qDestroyQueryPlan(pPlan);
|
||||||
|
terrno = TSDB_CODE_QRY_INVALID_INPUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pSub->qmsg = taosStrdup("");
|
||||||
|
}
|
||||||
|
|
||||||
qDestroyQueryPlan(pPlan);
|
qDestroyQueryPlan(pPlan);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,7 @@ static int32_t mndSetCreateSmaVgroupRedoLogs(SMnode *pMnode, STrans *pTrans, SVg
|
||||||
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
|
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
|
||||||
if (pVgRaw == NULL) return -1;
|
if (pVgRaw == NULL) return -1;
|
||||||
if (mndTransAppendRedolog(pTrans, pVgRaw) != 0) return -1;
|
if (mndTransAppendRedolog(pTrans, pVgRaw) != 0) return -1;
|
||||||
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_CREATING) != 0) return -1;
|
if (sdbSetRawStatus(pVgRaw, SDB_STATUS_UPDATE) != 0) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,11 +622,11 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "create-sma");
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "create-sma");
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
mInfo("trans:%d, used to create sma:%s stream:%s", pTrans->id, pCreate->name, streamObj.name);
|
mInfo("trans:%d, used to create sma:%s stream:%s", pTrans->id, pCreate->name, streamObj.name);
|
||||||
|
if (mndAddPrepareNewVgAction(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
|
||||||
if (mndSetCreateSmaRedoLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
if (mndSetCreateSmaRedoLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
||||||
if (mndSetCreateSmaVgroupRedoLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
|
if (mndSetCreateSmaVgroupRedoLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER;
|
||||||
if (mndSetCreateSmaCommitLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
if (mndSetCreateSmaCommitLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER;
|
||||||
|
@ -845,7 +845,7 @@ static int32_t mndDropSma(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SSmaObj *p
|
||||||
|
|
||||||
mInfo("trans:%d, used to drop sma:%s", pTrans->id, pSma->name);
|
mInfo("trans:%d, used to drop sma:%s", pTrans->id, pSma->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
|
|
||||||
|
|
|
@ -874,7 +874,7 @@ _OVER:
|
||||||
|
|
||||||
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
int32_t mndAddStbToTrans(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) {
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) return -1;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) return -1;
|
||||||
if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
if (mndSetCreateStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
||||||
if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
if (mndSetCreateStbUndoLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
||||||
if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
if (mndSetCreateStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) return -1;
|
||||||
|
@ -1968,7 +1968,7 @@ static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbOb
|
||||||
|
|
||||||
mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
|
mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (needRsp) {
|
if (needRsp) {
|
||||||
void *pCont = NULL;
|
void *pCont = NULL;
|
||||||
|
@ -1998,7 +1998,7 @@ static int32_t mndAlterStbAndUpdateTagIdxImp(SMnode *pMnode, SRpcMsg *pReq, SDbO
|
||||||
mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
|
mInfo("trans:%d, used to alter stb:%s", pTrans->id, pStb->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
|
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (needRsp) {
|
if (needRsp) {
|
||||||
void *pCont = NULL;
|
void *pCont = NULL;
|
||||||
|
@ -2242,7 +2242,7 @@ static int32_t mndDropStb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *p
|
||||||
|
|
||||||
mInfo("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
mInfo("trans:%d, used to drop stb:%s", pTrans->id, pStb->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
if (mndSetDropStbRedoLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
||||||
if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
if (mndSetDropStbCommitLogs(pMnode, pTrans, pStb) != 0) goto _OVER;
|
||||||
|
@ -3304,7 +3304,7 @@ static int32_t mndCheckIndexReq(SCreateTagIndexReq *pReq) {
|
||||||
|
|
||||||
mInfo("trans:%d, used to add index to stb:%s", pTrans->id, pStb->name);
|
mInfo("trans:%d, used to add index to stb:%s", pTrans->id, pStb->name);
|
||||||
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
mndTransSetDbName(pTrans, pDb->name, pStb->name);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
|
if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
|
||||||
if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
|
if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER;
|
||||||
|
|
|
@ -735,7 +735,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
||||||
mInfo("trans:%d, used to create stream:%s", pTrans->id, createStreamReq.name);
|
mInfo("trans:%d, used to create stream:%s", pTrans->id, createStreamReq.name);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, createStreamReq.sourceDB, streamObj.targetDb);
|
mndTransSetDbName(pTrans, createStreamReq.sourceDB, streamObj.targetDb);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
@ -890,7 +890,7 @@ static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) {
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "stream-checkpoint");
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq, "stream-checkpoint");
|
||||||
if (pTrans == NULL) return -1;
|
if (pTrans == NULL) return -1;
|
||||||
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
mndReleaseStream(pMnode, pStream);
|
mndReleaseStream(pMnode, pStream);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1001,7 +1001,7 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
||||||
mInfo("trans:%d, used to drop stream:%s", pTrans->id, dropReq.name);
|
mInfo("trans:%d, used to drop stream:%s", pTrans->id, dropReq.name);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
sdbRelease(pMnode->pSdb, pStream);
|
sdbRelease(pMnode->pSdb, pStream);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1369,7 +1369,7 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) {
|
||||||
mInfo("trans:%d, used to pause stream:%s", pTrans->id, pauseReq.name);
|
mInfo("trans:%d, used to pause stream:%s", pTrans->id, pauseReq.name);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
sdbRelease(pMnode->pSdb, pStream);
|
sdbRelease(pMnode->pSdb, pStream);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1477,7 +1477,7 @@ static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) {
|
||||||
mInfo("trans:%d, used to pause stream:%s", pTrans->id, pauseReq.name);
|
mInfo("trans:%d, used to pause stream:%s", pTrans->id, pauseReq.name);
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
mndTransSetDbName(pTrans, pStream->sourceDb, pStream->targetDb);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
sdbRelease(pMnode->pSdb, pStream);
|
sdbRelease(pMnode->pSdb, pStream);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
|
||||||
#define MND_SUBSCRIBE_VER_NUMBER 1
|
#define MND_SUBSCRIBE_VER_NUMBER 2
|
||||||
#define MND_SUBSCRIBE_RESERVE_SIZE 64
|
#define MND_SUBSCRIBE_RESERVE_SIZE 64
|
||||||
|
|
||||||
#define MND_SUBSCRIBE_REBALANCE_CNT 3
|
#define MND_SUBSCRIBE_REBALANCE_CNT 3
|
||||||
|
@ -99,13 +99,23 @@ static SMqSubscribeObj *mndCreateSubscription(SMnode *pMnode, const SMqTopicObj
|
||||||
return pSub;
|
return pSub;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscribeObj *pSub,
|
static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, SMqSubscribeObj *pSub,
|
||||||
const SMqRebOutputVg *pRebVg) {
|
const SMqRebOutputVg *pRebVg, SSubplan* pPlan) {
|
||||||
SMqRebVgReq req = {0};
|
SMqRebVgReq req = {0};
|
||||||
req.oldConsumerId = pRebVg->oldConsumerId;
|
req.oldConsumerId = pRebVg->oldConsumerId;
|
||||||
req.newConsumerId = pRebVg->newConsumerId;
|
req.newConsumerId = pRebVg->newConsumerId;
|
||||||
req.vgId = pRebVg->pVgEp->vgId;
|
req.vgId = pRebVg->pVgEp->vgId;
|
||||||
req.qmsg = pRebVg->pVgEp->qmsg;
|
if(pPlan){
|
||||||
|
pPlan->execNode.epSet = pRebVg->pVgEp->epSet;
|
||||||
|
pPlan->execNode.nodeId = pRebVg->pVgEp->vgId;
|
||||||
|
int32_t msgLen;
|
||||||
|
if (qSubPlanToString(pPlan, &req.qmsg, &msgLen) < 0) {
|
||||||
|
terrno = TSDB_CODE_QRY_INVALID_INPUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
req.qmsg = taosStrdup("");
|
||||||
|
}
|
||||||
req.subType = pSub->subType;
|
req.subType = pSub->subType;
|
||||||
req.withMeta = pSub->withMeta;
|
req.withMeta = pSub->withMeta;
|
||||||
req.suid = pSub->stbUid;
|
req.suid = pSub->stbUid;
|
||||||
|
@ -115,6 +125,7 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
tEncodeSize(tEncodeSMqRebVgReq, &req, tlen, ret);
|
tEncodeSize(tEncodeSMqRebVgReq, &req, tlen, ret);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
taosMemoryFree(req.qmsg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +133,7 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
||||||
void *buf = taosMemoryMalloc(tlen);
|
void *buf = taosMemoryMalloc(tlen);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
taosMemoryFree(req.qmsg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,17 +147,19 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
||||||
if (tEncodeSMqRebVgReq(&encoder, &req) < 0) {
|
if (tEncodeSMqRebVgReq(&encoder, &req) < 0) {
|
||||||
taosMemoryFreeClear(buf);
|
taosMemoryFreeClear(buf);
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
|
taosMemoryFree(req.qmsg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
*pBuf = buf;
|
*pBuf = buf;
|
||||||
*pLen = tlen;
|
*pLen = tlen;
|
||||||
|
|
||||||
|
taosMemoryFree(req.qmsg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SMqSubscribeObj *pSub,
|
static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub,
|
||||||
const SMqRebOutputVg *pRebVg) {
|
const SMqRebOutputVg *pRebVg, SSubplan* pPlan) {
|
||||||
// if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
|
// if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
|
||||||
// terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
|
// terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
|
||||||
// return -1;
|
// return -1;
|
||||||
|
@ -153,7 +167,7 @@ static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SM
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
int32_t tlen;
|
int32_t tlen;
|
||||||
if (mndBuildSubChangeReq(&buf, &tlen, pSub, pRebVg) < 0) {
|
if (mndBuildSubChangeReq(&buf, &tlen, pSub, pRebVg, pPlan) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +269,7 @@ static void doAddNewConsumers(SMqRebOutputObj *pOutput, const SMqRebInputObj *pI
|
||||||
for (int32_t i = 0; i < numOfNewConsumers; i++) {
|
for (int32_t i = 0; i < numOfNewConsumers; i++) {
|
||||||
int64_t consumerId = *(int64_t *)taosArrayGet(pInput->pRebInfo->newConsumers, i);
|
int64_t consumerId = *(int64_t *)taosArrayGet(pInput->pRebInfo->newConsumers, i);
|
||||||
|
|
||||||
SMqConsumerEp newConsumerEp;
|
SMqConsumerEp newConsumerEp = {0};
|
||||||
newConsumerEp.consumerId = consumerId;
|
newConsumerEp.consumerId = consumerId;
|
||||||
newConsumerEp.vgs = taosArrayInit(0, sizeof(void *));
|
newConsumerEp.vgs = taosArrayInit(0, sizeof(void *));
|
||||||
|
|
||||||
|
@ -449,8 +463,44 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
|
||||||
|
|
||||||
SMqRebOutputVg* pRebOutput = (SMqRebOutputVg *)pRemovedIter;
|
SMqRebOutputVg* pRebOutput = (SMqRebOutputVg *)pRemovedIter;
|
||||||
taosArrayPush(pOutput->rebVgs, pRebOutput);
|
taosArrayPush(pOutput->rebVgs, pRebOutput);
|
||||||
if(taosHashGetSize(pOutput->pSub->consumerHash) == 0){ // if all consumer is removed, put all vg into unassigned
|
if(taosHashGetSize(pOutput->pSub->consumerHash) == 0){ // if all consumer is removed
|
||||||
taosArrayPush(pOutput->pSub->unassignedVgs, &pRebOutput->pVgEp);
|
taosArrayPush(pOutput->pSub->unassignedVgs, &pRebOutput->pVgEp); // put all vg into unassigned
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taosHashGetSize(pOutput->pSub->consumerHash) == 0) { // if all consumer is removed
|
||||||
|
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pInput->pRebInfo->key); // put all offset rows
|
||||||
|
if (pSub) {
|
||||||
|
taosRLockLatch(&pSub->lock);
|
||||||
|
bool init = false;
|
||||||
|
if (pOutput->pSub->offsetRows == NULL) {
|
||||||
|
pOutput->pSub->offsetRows = taosArrayInit(4, sizeof(OffsetRows));
|
||||||
|
init = true;
|
||||||
|
}
|
||||||
|
pIter = NULL;
|
||||||
|
while (1) {
|
||||||
|
pIter = taosHashIterate(pSub->consumerHash, pIter);
|
||||||
|
if (pIter == NULL) break;
|
||||||
|
SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)pIter;
|
||||||
|
if (init) {
|
||||||
|
taosArrayAddAll(pOutput->pSub->offsetRows, pConsumerEp->offsetRows);
|
||||||
|
// mDebug("pSub->offsetRows is init");
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j < taosArrayGetSize(pConsumerEp->offsetRows); j++) {
|
||||||
|
OffsetRows *d1 = taosArrayGet(pConsumerEp->offsetRows, j);
|
||||||
|
for (int i = 0; i < taosArrayGetSize(pOutput->pSub->offsetRows); i++) {
|
||||||
|
OffsetRows *d2 = taosArrayGet(pOutput->pSub->offsetRows, i);
|
||||||
|
if (d1->vgId == d2->vgId) {
|
||||||
|
d2->rows += d1->rows;
|
||||||
|
d2->offset = d1->offset;
|
||||||
|
// mDebug("pSub->offsetRows add vgId:%d, after:%"PRId64", before:%"PRId64, d2->vgId, d2->rows, d1->rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taosRUnLockLatch(&pSub->lock);
|
||||||
|
mndReleaseSubscribe(pMnode, pSub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,14 +533,25 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOutputObj *pOutput) {
|
static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOutputObj *pOutput) {
|
||||||
|
struct SSubplan* pPlan = NULL;
|
||||||
|
if(strcmp(pOutput->pSub->qmsg, "") != 0){
|
||||||
|
int32_t code = qStringToSubplan(pOutput->pSub->qmsg, &pPlan);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pMsg, "tmq-reb");
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pMsg, "tmq-reb");
|
||||||
if (pTrans == NULL) {
|
if (pTrans == NULL) {
|
||||||
|
nodesDestroyNode((SNode*)pPlan);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pOutput->pSub->dbName, NULL);
|
mndTransSetDbName(pTrans, pOutput->pSub->dbName, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
|
nodesDestroyNode((SNode*)pPlan);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,11 +561,13 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
int32_t vgNum = taosArrayGetSize(rebVgs);
|
int32_t vgNum = taosArrayGetSize(rebVgs);
|
||||||
for (int32_t i = 0; i < vgNum; i++) {
|
for (int32_t i = 0; i < vgNum; i++) {
|
||||||
SMqRebOutputVg *pRebVg = taosArrayGet(rebVgs, i);
|
SMqRebOutputVg *pRebVg = taosArrayGet(rebVgs, i);
|
||||||
if (mndPersistSubChangeVgReq(pMnode, pTrans, pOutput->pSub, pRebVg) < 0) {
|
if (mndPersistSubChangeVgReq(pMnode, pTrans, pOutput->pSub, pRebVg, pPlan) < 0) {
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
|
nodesDestroyNode((SNode*)pPlan);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodesDestroyNode((SNode*)pPlan);
|
||||||
|
|
||||||
// 2. redo log: subscribe and vg assignment
|
// 2. redo log: subscribe and vg assignment
|
||||||
// subscribe
|
// subscribe
|
||||||
|
@ -809,7 +872,7 @@ static SSdbRow *mndSubActionDecode(SSdbRaw *pRaw) {
|
||||||
int8_t sver = 0;
|
int8_t sver = 0;
|
||||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto SUB_DECODE_OVER;
|
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto SUB_DECODE_OVER;
|
||||||
|
|
||||||
if (sver != MND_SUBSCRIBE_VER_NUMBER) {
|
if (sver > MND_SUBSCRIBE_VER_NUMBER || sver < 1) {
|
||||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||||
goto SUB_DECODE_OVER;
|
goto SUB_DECODE_OVER;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +891,7 @@ static SSdbRow *mndSubActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_BINARY(pRaw, dataPos, buf, tlen, SUB_DECODE_OVER);
|
SDB_GET_BINARY(pRaw, dataPos, buf, tlen, SUB_DECODE_OVER);
|
||||||
SDB_GET_RESERVE(pRaw, dataPos, MND_SUBSCRIBE_RESERVE_SIZE, SUB_DECODE_OVER);
|
SDB_GET_RESERVE(pRaw, dataPos, MND_SUBSCRIBE_RESERVE_SIZE, SUB_DECODE_OVER);
|
||||||
|
|
||||||
if (tDecodeSubscribeObj(buf, pSub) == NULL) {
|
if (tDecodeSubscribeObj(buf, pSub, sver) == NULL) {
|
||||||
goto SUB_DECODE_OVER;
|
goto SUB_DECODE_OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,6 +953,10 @@ static int32_t mndSubActionUpdate(SSdb *pSdb, SMqSubscribeObj *pOldSub, SMqSubsc
|
||||||
pOldSub->unassignedVgs = pNewSub->unassignedVgs;
|
pOldSub->unassignedVgs = pNewSub->unassignedVgs;
|
||||||
pNewSub->unassignedVgs = tmp1;
|
pNewSub->unassignedVgs = tmp1;
|
||||||
|
|
||||||
|
SArray *tmp2 = pOldSub->offsetRows;
|
||||||
|
pOldSub->offsetRows = pNewSub->offsetRows;
|
||||||
|
pNewSub->offsetRows = tmp2;
|
||||||
|
|
||||||
taosWUnLockLatch(&pOldSub->lock);
|
taosWUnLockLatch(&pOldSub->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1028,6 +1095,61 @@ END:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t buildResult(SSDataBlock *pBlock, int32_t* numOfRows, int64_t consumerId, const char* topic, const char* cgroup, SArray* vgs, SArray *offsetRows){
|
||||||
|
int32_t sz = taosArrayGetSize(vgs);
|
||||||
|
for (int32_t j = 0; j < sz; j++) {
|
||||||
|
SMqVgEp *pVgEp = taosArrayGetP(vgs, j);
|
||||||
|
|
||||||
|
SColumnInfoData *pColInfo;
|
||||||
|
int32_t cols = 0;
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)topic, false);
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)cgroup, false);
|
||||||
|
|
||||||
|
// vg id
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)&pVgEp->vgId, false);
|
||||||
|
|
||||||
|
// consumer id
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)&consumerId, consumerId == -1);
|
||||||
|
|
||||||
|
mDebug("mnd show subscriptions: topic %s, consumer:0x%" PRIx64 " cgroup %s vgid %d", varDataVal(topic),
|
||||||
|
consumerId, varDataVal(cgroup), pVgEp->vgId);
|
||||||
|
|
||||||
|
// offset
|
||||||
|
OffsetRows *data = NULL;
|
||||||
|
for(int i = 0; i < taosArrayGetSize(offsetRows); i++){
|
||||||
|
OffsetRows *tmp = taosArrayGet(offsetRows, i);
|
||||||
|
if(tmp->vgId != pVgEp->vgId){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
data = tmp;
|
||||||
|
}
|
||||||
|
if(data){
|
||||||
|
// vg id
|
||||||
|
char buf[TSDB_OFFSET_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
|
tFormatOffset(varDataVal(buf), TSDB_OFFSET_LEN, &data->offset);
|
||||||
|
varDataSetLen(buf, strlen(varDataVal(buf)));
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)buf, false);
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetVal(pColInfo, *numOfRows, (const char *)&data->rows, false);
|
||||||
|
}else{
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetNULL(pColInfo, *numOfRows);
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
colDataSetNULL(pColInfo, *numOfRows);
|
||||||
|
mError("mnd show subscriptions: do not find vgId:%d in offsetRows", pVgEp->vgId);
|
||||||
|
}
|
||||||
|
(*numOfRows)++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rowsCapacity) {
|
int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rowsCapacity) {
|
||||||
SMnode *pMnode = pReq->info.node;
|
SMnode *pMnode = pReq->info.node;
|
||||||
SSdb *pSdb = pMnode->pSdb;
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
@ -1048,6 +1170,13 @@ int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock
|
||||||
blockDataEnsureCapacity(pBlock, numOfRows + pSub->vgNum);
|
blockDataEnsureCapacity(pBlock, numOfRows + pSub->vgNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// topic and cgroup
|
||||||
|
char topic[TSDB_TOPIC_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
|
char cgroup[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
|
mndSplitSubscribeKey(pSub->key, varDataVal(topic), varDataVal(cgroup), false);
|
||||||
|
varDataSetLen(topic, strlen(varDataVal(topic)));
|
||||||
|
varDataSetLen(cgroup, strlen(varDataVal(cgroup)));
|
||||||
|
|
||||||
SMqConsumerEp *pConsumerEp = NULL;
|
SMqConsumerEp *pConsumerEp = NULL;
|
||||||
void *pIter = NULL;
|
void *pIter = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -1055,97 +1184,11 @@ int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock
|
||||||
if (pIter == NULL) break;
|
if (pIter == NULL) break;
|
||||||
pConsumerEp = (SMqConsumerEp *)pIter;
|
pConsumerEp = (SMqConsumerEp *)pIter;
|
||||||
|
|
||||||
int32_t sz = taosArrayGetSize(pConsumerEp->vgs);
|
buildResult(pBlock, &numOfRows, pConsumerEp->consumerId, topic, cgroup, pConsumerEp->vgs, pConsumerEp->offsetRows);
|
||||||
for (int32_t j = 0; j < sz; j++) {
|
|
||||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
|
|
||||||
|
|
||||||
SColumnInfoData *pColInfo;
|
|
||||||
int32_t cols = 0;
|
|
||||||
|
|
||||||
// topic and cgroup
|
|
||||||
char topic[TSDB_TOPIC_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
|
||||||
char cgroup[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0};
|
|
||||||
mndSplitSubscribeKey(pSub->key, varDataVal(topic), varDataVal(cgroup), false);
|
|
||||||
varDataSetLen(topic, strlen(varDataVal(topic)));
|
|
||||||
varDataSetLen(cgroup, strlen(varDataVal(cgroup)));
|
|
||||||
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)topic, false);
|
|
||||||
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)cgroup, false);
|
|
||||||
|
|
||||||
// vg id
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pVgEp->vgId, false);
|
|
||||||
|
|
||||||
// consumer id
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pConsumerEp->consumerId, false);
|
|
||||||
|
|
||||||
mDebug("mnd show subscriptions: topic %s, consumer:0x%" PRIx64 " cgroup %s vgid %d", varDataVal(topic),
|
|
||||||
pConsumerEp->consumerId, varDataVal(cgroup), pVgEp->vgId);
|
|
||||||
|
|
||||||
// offset
|
|
||||||
#if 0
|
|
||||||
// subscribe time
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pSub->subscribeTime, false);
|
|
||||||
|
|
||||||
// rebalance time
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pSub->rebalanceTime, pConsumer->rebalanceTime == 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
numOfRows++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not show for cleared subscription
|
// do not show for cleared subscription
|
||||||
int32_t sz = taosArrayGetSize(pSub->unassignedVgs);
|
buildResult(pBlock, &numOfRows, -1, topic, cgroup, pSub->unassignedVgs, pSub->offsetRows);
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
|
||||||
SMqVgEp *pVgEp = taosArrayGetP(pSub->unassignedVgs, i);
|
|
||||||
|
|
||||||
SColumnInfoData *pColInfo;
|
|
||||||
int32_t cols = 0;
|
|
||||||
|
|
||||||
// topic and cgroup
|
|
||||||
char topic[TSDB_TOPIC_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
|
||||||
char cgroup[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0};
|
|
||||||
mndSplitSubscribeKey(pSub->key, varDataVal(topic), varDataVal(cgroup), false);
|
|
||||||
varDataSetLen(topic, strlen(varDataVal(topic)));
|
|
||||||
varDataSetLen(cgroup, strlen(varDataVal(cgroup)));
|
|
||||||
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)topic, false);
|
|
||||||
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)cgroup, false);
|
|
||||||
|
|
||||||
// vg id
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pVgEp->vgId, false);
|
|
||||||
|
|
||||||
// consumer id
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, NULL, true);
|
|
||||||
|
|
||||||
mDebug("mnd show subscriptions(unassigned): topic %s, cgroup %s vgid %d", varDataVal(topic), varDataVal(cgroup),
|
|
||||||
pVgEp->vgId);
|
|
||||||
|
|
||||||
// offset
|
|
||||||
#if 0
|
|
||||||
// subscribe time
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pSub->subscribeTime, false);
|
|
||||||
|
|
||||||
// rebalance time
|
|
||||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
|
||||||
colDataSetVal(pColInfo, numOfRows, (const char *)&pSub->rebalanceTime, pConsumer->rebalanceTime == 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
numOfRows++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBlock->info.rows = numOfRows;
|
pBlock->info.rows = numOfRows;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "mndSync.h"
|
#include "mndSync.h"
|
||||||
#include "mndCluster.h"
|
#include "mndCluster.h"
|
||||||
#include "mndTrans.h"
|
#include "mndTrans.h"
|
||||||
|
#include "mndVgroup.h"
|
||||||
|
|
||||||
static int32_t mndSyncEqCtrlMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
static int32_t mndSyncEqCtrlMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
||||||
if (pMsg == NULL || pMsg->pCont == NULL) {
|
if (pMsg == NULL || pMsg->pCont == NULL) {
|
||||||
|
@ -73,76 +74,200 @@ static int32_t mndSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndProcessWriteMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
static int32_t mndTransValidatePrepareAction(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
|
||||||
SMnode *pMnode = pFsm->data;
|
SSdbRow *pRow = NULL;
|
||||||
|
int32_t code = -1;
|
||||||
|
|
||||||
|
if (pAction->msgType == TDMT_MND_CREATE_VG) {
|
||||||
|
pRow = mndVgroupActionDecode(pAction->pRaw);
|
||||||
|
if (pRow == NULL) goto _OUT;
|
||||||
|
|
||||||
|
SVgObj *pVgroup = sdbGetRowObj(pRow);
|
||||||
|
if (pVgroup == NULL) goto _OUT;
|
||||||
|
|
||||||
|
int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
|
||||||
|
if (maxVgId > pVgroup->vgId) {
|
||||||
|
mError("trans:%d, failed to satisfy vgroup id %d of prepare action. maxVgId:%d", pTrans->id, pVgroup->vgId,
|
||||||
|
maxVgId);
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
_OUT:
|
||||||
|
taosMemoryFreeClear(pRow);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndTransValidatePrepareStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
int32_t code = -1;
|
||||||
|
int32_t action = 0;
|
||||||
|
|
||||||
|
int32_t numOfActions = taosArrayGetSize(pTrans->prepareActions);
|
||||||
|
if (numOfActions == 0) {
|
||||||
|
code = 0;
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInfo("trans:%d, validate %d prepare actions.", pTrans->id, numOfActions);
|
||||||
|
|
||||||
|
for (action = 0; action < numOfActions; ++action) {
|
||||||
|
STransAction *pAction = taosArrayGet(pTrans->prepareActions, action);
|
||||||
|
|
||||||
|
if (pAction->actionType != TRANS_ACTION_RAW) {
|
||||||
|
mError("trans:%d, prepare action:%d of unexpected type:%d", pTrans->id, action, pAction->actionType);
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = mndTransValidatePrepareAction(pMnode, pTrans, pAction);
|
||||||
|
if (code != 0) {
|
||||||
|
mError("trans:%d, failed to validate prepare action: %d, numOfActions:%d", pTrans->id, action, numOfActions);
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
_OUT:
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndTransValidateImp(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
if (pTrans->stage == TRN_STAGE_PREPARE) {
|
||||||
|
if (mndTransCheckConflict(pMnode, pTrans) < 0) {
|
||||||
|
mError("trans:%d, failed to validate trans conflicts.", pTrans->id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mndTransValidatePrepareStage(pMnode, pTrans);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndTransValidate(SMnode *pMnode, SSdbRaw *pRaw) {
|
||||||
|
STrans *pTrans = NULL;
|
||||||
|
int32_t code = -1;
|
||||||
|
|
||||||
|
SSdbRow *pRow = mndTransDecode(pRaw);
|
||||||
|
if (pRow == NULL) goto _OUT;
|
||||||
|
|
||||||
|
pTrans = sdbGetRowObj(pRow);
|
||||||
|
if (pTrans == NULL) goto _OUT;
|
||||||
|
|
||||||
|
code = mndTransValidateImp(pMnode, pTrans);
|
||||||
|
|
||||||
|
_OUT:
|
||||||
|
if (pTrans) mndTransDropData(pTrans);
|
||||||
|
if (pRow) taosMemoryFreeClear(pRow);
|
||||||
|
if (code) terrno = (terrno ? terrno : TSDB_CODE_MND_TRANS_CONFLICT);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mndProcessWriteMsg(SMnode *pMnode, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
||||||
|
terrno = TSDB_CODE_SUCCESS;
|
||||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||||
SSdbRaw *pRaw = pMsg->pCont;
|
SSdbRaw *pRaw = pMsg->pCont;
|
||||||
|
STrans *pTrans = NULL;
|
||||||
|
int32_t code = -1;
|
||||||
int32_t transId = sdbGetIdFromRaw(pMnode->pSdb, pRaw);
|
int32_t transId = sdbGetIdFromRaw(pMnode->pSdb, pRaw);
|
||||||
|
|
||||||
|
if (transId <= 0) {
|
||||||
|
mError("trans:%d, invalid commit msg, cache transId:%d seq:%" PRId64, transId, pMgmt->transId, pMgmt->transSeq);
|
||||||
|
terrno = TSDB_CODE_INVALID_MSG;
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
mInfo("trans:%d, is proposed, saved:%d code:0x%x, apply index:%" PRId64 " term:%" PRIu64 " config:%" PRId64
|
mInfo("trans:%d, is proposed, saved:%d code:0x%x, apply index:%" PRId64 " term:%" PRIu64 " config:%" PRId64
|
||||||
" role:%s raw:%p sec:%d seq:%" PRId64,
|
" role:%s raw:%p sec:%d seq:%" PRId64,
|
||||||
transId, pMgmt->transId, pMeta->code, pMeta->index, pMeta->term, pMeta->lastConfigIndex, syncStr(pMeta->state),
|
transId, pMgmt->transId, pMeta->code, pMeta->index, pMeta->term, pMeta->lastConfigIndex, syncStr(pMeta->state),
|
||||||
pRaw, pMgmt->transSec, pMgmt->transSeq);
|
pRaw, pMgmt->transSec, pMgmt->transSeq);
|
||||||
|
|
||||||
if (pMeta->code == 0) {
|
code = mndTransValidate(pMnode, pRaw);
|
||||||
int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pRaw);
|
if (code != 0) {
|
||||||
if (code != 0) {
|
mError("trans:%d, failed to validate requested trans since %s", transId, terrstr());
|
||||||
mError("trans:%d, failed to write to sdb since %s", transId, terrstr());
|
code = 0;
|
||||||
return 0;
|
pMeta->code = terrno;
|
||||||
}
|
goto _OUT;
|
||||||
sdbSetApplyInfo(pMnode->pSdb, pMeta->index, pMeta->term, pMeta->lastConfigIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taosThreadMutexLock(&pMgmt->lock);
|
code = sdbWriteWithoutFree(pMnode->pSdb, pRaw);
|
||||||
pMgmt->errCode = pMeta->code;
|
if (code != 0) {
|
||||||
|
mError("trans:%d, failed to write to sdb since %s", transId, terrstr());
|
||||||
if (transId <= 0) {
|
code = 0;
|
||||||
taosThreadMutexUnlock(&pMgmt->lock);
|
pMeta->code = terrno;
|
||||||
mError("trans:%d, invalid commit msg, cache transId:%d seq:%" PRId64, transId, pMgmt->transId, pMgmt->transSeq);
|
goto _OUT;
|
||||||
} else if (transId == pMgmt->transId) {
|
|
||||||
if (pMgmt->errCode != 0) {
|
|
||||||
mError("trans:%d, failed to propose since %s, post sem", transId, tstrerror(pMgmt->errCode));
|
|
||||||
} else {
|
|
||||||
mInfo("trans:%d, is proposed and post sem, seq:%" PRId64, transId, pMgmt->transSeq);
|
|
||||||
}
|
|
||||||
pMgmt->transId = 0;
|
|
||||||
pMgmt->transSec = 0;
|
|
||||||
pMgmt->transSeq = 0;
|
|
||||||
tsem_post(&pMgmt->syncSem);
|
|
||||||
taosThreadMutexUnlock(&pMgmt->lock);
|
|
||||||
} else {
|
|
||||||
taosThreadMutexUnlock(&pMgmt->lock);
|
|
||||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
|
||||||
if (pTrans != NULL) {
|
|
||||||
mInfo("trans:%d, execute in mnode which not leader or sync timeout, createTime:%" PRId64 " saved trans:%d",
|
|
||||||
transId, pTrans->createdTime, pMgmt->transId);
|
|
||||||
mndTransExecute(pMnode, pTrans, false);
|
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
|
||||||
} else {
|
|
||||||
mError("trans:%d, not found while execute in mnode since %s", transId, terrstr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pTrans = mndAcquireTrans(pMnode, transId);
|
||||||
|
if (pTrans == NULL) {
|
||||||
|
mError("trans:%d, not found while execute in mnode since %s", transId, terrstr());
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTrans->stage == TRN_STAGE_PREPARE) {
|
||||||
|
bool continueExec = mndTransPerformPrepareStage(pMnode, pTrans);
|
||||||
|
if (!continueExec) goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTrans->id != pMgmt->transId) {
|
||||||
|
mInfo("trans:%d, execute in mnode which not leader or sync timeout, createTime:%" PRId64 " saved trans:%d",
|
||||||
|
pTrans->id, pTrans->createdTime, pMgmt->transId);
|
||||||
|
mndTransRefresh(pMnode, pTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbSetApplyInfo(pMnode->pSdb, pMeta->index, pMeta->term, pMeta->lastConfigIndex);
|
||||||
sdbWriteFile(pMnode->pSdb, tsMndSdbWriteDelta);
|
sdbWriteFile(pMnode->pSdb, tsMndSdbWriteDelta);
|
||||||
|
code = 0;
|
||||||
|
|
||||||
|
_OUT:
|
||||||
|
if (pTrans) mndReleaseTrans(pMnode, pTrans);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndPostMgmtCode(SMnode *pMnode, int32_t code) {
|
||||||
|
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||||
|
taosThreadMutexLock(&pMgmt->lock);
|
||||||
|
if (pMgmt->transId == 0) {
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMgmt->transId = 0;
|
||||||
|
pMgmt->transSec = 0;
|
||||||
|
pMgmt->transSeq = 0;
|
||||||
|
pMgmt->errCode = code;
|
||||||
|
tsem_post(&pMgmt->syncSem);
|
||||||
|
|
||||||
|
if (pMgmt->errCode != 0) {
|
||||||
|
mError("trans:%d, failed to propose since %s, post sem", pMgmt->transId, tstrerror(pMgmt->errCode));
|
||||||
|
} else {
|
||||||
|
mInfo("trans:%d, is proposed and post sem, seq:%" PRId64, pMgmt->transId, pMgmt->transSeq);
|
||||||
|
}
|
||||||
|
|
||||||
|
_OUT:
|
||||||
|
taosThreadMutexUnlock(&pMgmt->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
int32_t mndSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
||||||
int32_t code = 0;
|
SMnode *pMnode = pFsm->data;
|
||||||
|
int32_t code = pMsg->code;
|
||||||
|
if (code != 0) {
|
||||||
|
goto _OUT;
|
||||||
|
}
|
||||||
|
|
||||||
pMsg->info.conn.applyIndex = pMeta->index;
|
pMsg->info.conn.applyIndex = pMeta->index;
|
||||||
pMsg->info.conn.applyTerm = pMeta->term;
|
pMsg->info.conn.applyTerm = pMeta->term;
|
||||||
|
pMeta->code = 0;
|
||||||
|
|
||||||
if (pMsg->code == 0) {
|
atomic_store_64(&pMnode->applied, pMsg->info.conn.applyIndex);
|
||||||
SMnode *pMnode = pFsm->data;
|
|
||||||
atomic_store_64(&pMnode->applied, pMsg->info.conn.applyIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!syncUtilUserCommit(pMsg->msgType)) {
|
if (!syncUtilUserCommit(pMsg->msgType)) {
|
||||||
goto _out;
|
goto _OUT;
|
||||||
}
|
}
|
||||||
code = mndProcessWriteMsg(pFsm, pMsg, pMeta);
|
|
||||||
|
|
||||||
_out:
|
code = mndProcessWriteMsg(pMnode, pMsg, pMeta);
|
||||||
|
|
||||||
|
_OUT:
|
||||||
|
mndPostMgmtCode(pMnode, code ? code : pMeta->code);
|
||||||
rpcFreeCont(pMsg->pCont);
|
rpcFreeCont(pMsg->pCont);
|
||||||
pMsg->pCont = NULL;
|
pMsg->pCont = NULL;
|
||||||
return code;
|
return code;
|
||||||
|
|
|
@ -753,7 +753,7 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransSetDbName(pTrans, pTopic->db, NULL);
|
mndTransSetDbName(pTrans, pTopic->db, NULL);
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
mndReleaseTopic(pMnode, pTopic);
|
mndReleaseTopic(pMnode, pTopic);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -23,28 +23,25 @@
|
||||||
#include "mndSync.h"
|
#include "mndSync.h"
|
||||||
#include "mndUser.h"
|
#include "mndUser.h"
|
||||||
|
|
||||||
#define TRANS_VER_NUMBER 1
|
#define TRANS_VER1_NUMBER 1
|
||||||
|
#define TRANS_VER2_NUMBER 2
|
||||||
#define TRANS_ARRAY_SIZE 8
|
#define TRANS_ARRAY_SIZE 8
|
||||||
#define TRANS_RESERVE_SIZE 48
|
#define TRANS_RESERVE_SIZE 48
|
||||||
|
|
||||||
static SSdbRaw *mndTransActionEncode(STrans *pTrans);
|
|
||||||
static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw);
|
|
||||||
static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans);
|
static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans);
|
||||||
static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *OldTrans, STrans *pOld);
|
static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *OldTrans, STrans *pOld);
|
||||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc);
|
static int32_t mndTransDelete(SSdb *pSdb, STrans *pTrans, bool callFunc);
|
||||||
|
|
||||||
static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw);
|
static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw);
|
||||||
static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction);
|
static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction);
|
||||||
static void mndTransDropLogs(SArray *pArray);
|
static void mndTransDropLogs(SArray *pArray);
|
||||||
static void mndTransDropActions(SArray *pArray);
|
static void mndTransDropActions(SArray *pArray);
|
||||||
static void mndTransDropData(STrans *pTrans);
|
|
||||||
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray);
|
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray);
|
||||||
static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans);
|
static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans);
|
||||||
static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans);
|
static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans);
|
||||||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans);
|
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans);
|
||||||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans);
|
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans);
|
||||||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans);
|
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans);
|
|
||||||
static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans);
|
||||||
|
@ -52,7 +49,7 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans);
|
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans);
|
||||||
static bool mndCannotExecuteTransAction(SMnode *pMnode) { return !pMnode->deploy && !mndIsLeader(pMnode); }
|
static bool mndCannotExecuteTransAction(SMnode *pMnode) { return !pMnode->deploy && !mndIsLeader(pMnode); }
|
||||||
|
|
||||||
static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans);
|
static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans);
|
||||||
|
@ -67,11 +64,11 @@ int32_t mndInitTrans(SMnode *pMnode) {
|
||||||
SSdbTable table = {
|
SSdbTable table = {
|
||||||
.sdbType = SDB_TRANS,
|
.sdbType = SDB_TRANS,
|
||||||
.keyType = SDB_KEY_INT32,
|
.keyType = SDB_KEY_INT32,
|
||||||
.encodeFp = (SdbEncodeFp)mndTransActionEncode,
|
.encodeFp = (SdbEncodeFp)mndTransEncode,
|
||||||
.decodeFp = (SdbDecodeFp)mndTransActionDecode,
|
.decodeFp = (SdbDecodeFp)mndTransDecode,
|
||||||
.insertFp = (SdbInsertFp)mndTransActionInsert,
|
.insertFp = (SdbInsertFp)mndTransActionInsert,
|
||||||
.updateFp = (SdbUpdateFp)mndTransActionUpdate,
|
.updateFp = (SdbUpdateFp)mndTransActionUpdate,
|
||||||
.deleteFp = (SdbDeleteFp)mndTransActionDelete,
|
.deleteFp = (SdbDeleteFp)mndTransDelete,
|
||||||
};
|
};
|
||||||
|
|
||||||
mndSetMsgHandle(pMnode, TDMT_MND_TRANS_TIMER, mndProcessTransTimer);
|
mndSetMsgHandle(pMnode, TDMT_MND_TRANS_TIMER, mndProcessTransTimer);
|
||||||
|
@ -103,15 +100,55 @@ static int32_t mndTransGetActionsSize(SArray *pArray) {
|
||||||
return rawDataLen;
|
return rawDataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
static int32_t mndTransEncodeAction(SSdbRaw *pRaw, int32_t *offset, SArray *pActions, int32_t actionsNum) {
|
||||||
|
int32_t dataPos = *offset;
|
||||||
|
int8_t unused = 0;
|
||||||
|
int32_t ret = -1;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < actionsNum; ++i) {
|
||||||
|
STransAction *pAction = taosArrayGet(pActions, i);
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pAction->retryCode, _OVER)
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, pAction->reserved, _OVER)
|
||||||
|
if (pAction->actionType == TRANS_ACTION_RAW) {
|
||||||
|
int32_t len = sdbGetRawTotalSize(pAction->pRaw);
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->rawWritten*/, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, len, _OVER)
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
|
||||||
|
} else if (pAction->actionType == TRANS_ACTION_MSG) {
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
|
||||||
|
SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgSent*/, _OVER)
|
||||||
|
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgReceived*/, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
|
||||||
|
} else {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
*offset = dataPos;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSdbRaw *mndTransEncode(STrans *pTrans) {
|
||||||
|
terrno = TSDB_CODE_INVALID_MSG;
|
||||||
|
int8_t sver = taosArrayGetSize(pTrans->prepareActions) ? TRANS_VER2_NUMBER : TRANS_VER1_NUMBER;
|
||||||
|
|
||||||
int32_t rawDataLen = sizeof(STrans) + TRANS_RESERVE_SIZE + pTrans->paramLen;
|
int32_t rawDataLen = sizeof(STrans) + TRANS_RESERVE_SIZE + pTrans->paramLen;
|
||||||
|
rawDataLen += mndTransGetActionsSize(pTrans->prepareActions);
|
||||||
rawDataLen += mndTransGetActionsSize(pTrans->redoActions);
|
rawDataLen += mndTransGetActionsSize(pTrans->redoActions);
|
||||||
rawDataLen += mndTransGetActionsSize(pTrans->undoActions);
|
rawDataLen += mndTransGetActionsSize(pTrans->undoActions);
|
||||||
rawDataLen += mndTransGetActionsSize(pTrans->commitActions);
|
rawDataLen += mndTransGetActionsSize(pTrans->commitActions);
|
||||||
|
|
||||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_TRANS, TRANS_VER_NUMBER, rawDataLen);
|
SSdbRaw *pRaw = sdbAllocRaw(SDB_TRANS, sver, rawDataLen);
|
||||||
if (pRaw == NULL) {
|
if (pRaw == NULL) {
|
||||||
mError("trans:%d, failed to alloc raw since %s", pTrans->id, terrstr());
|
mError("trans:%d, failed to alloc raw since %s", pTrans->id, terrstr());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -131,91 +168,22 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pTrans->stbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
SDB_SET_BINARY(pRaw, dataPos, pTrans->stbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pTrans->redoActionPos, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pTrans->redoActionPos, _OVER)
|
||||||
|
|
||||||
|
int32_t prepareActionNum = taosArrayGetSize(pTrans->prepareActions);
|
||||||
int32_t redoActionNum = taosArrayGetSize(pTrans->redoActions);
|
int32_t redoActionNum = taosArrayGetSize(pTrans->redoActions);
|
||||||
int32_t undoActionNum = taosArrayGetSize(pTrans->undoActions);
|
int32_t undoActionNum = taosArrayGetSize(pTrans->undoActions);
|
||||||
int32_t commitActionNum = taosArrayGetSize(pTrans->commitActions);
|
int32_t commitActionNum = taosArrayGetSize(pTrans->commitActions);
|
||||||
|
|
||||||
|
if (sver > TRANS_VER1_NUMBER) {
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, prepareActionNum, _OVER)
|
||||||
|
}
|
||||||
SDB_SET_INT32(pRaw, dataPos, redoActionNum, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, redoActionNum, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, undoActionNum, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, undoActionNum, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, commitActionNum, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, commitActionNum, _OVER)
|
||||||
|
|
||||||
int8_t unused = 0;
|
if (mndTransEncodeAction(pRaw, &dataPos, pTrans->prepareActions, prepareActionNum) < 0) goto _OVER;
|
||||||
for (int32_t i = 0; i < redoActionNum; ++i) {
|
if (mndTransEncodeAction(pRaw, &dataPos, pTrans->redoActions, redoActionNum) < 0) goto _OVER;
|
||||||
STransAction *pAction = taosArrayGet(pTrans->redoActions, i);
|
if (mndTransEncodeAction(pRaw, &dataPos, pTrans->undoActions, undoActionNum) < 0) goto _OVER;
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
|
if (mndTransEncodeAction(pRaw, &dataPos, pTrans->commitActions, commitActionNum) < 0) goto _OVER;
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->retryCode, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->reserved, _OVER)
|
|
||||||
if (pAction->actionType == TRANS_ACTION_RAW) {
|
|
||||||
int32_t len = sdbGetRawTotalSize(pAction->pRaw);
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->rawWritten*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, len, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
|
|
||||||
} else if (pAction->actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
|
|
||||||
SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgSent*/, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgReceived*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
|
|
||||||
} else {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < undoActionNum; ++i) {
|
|
||||||
STransAction *pAction = taosArrayGet(pTrans->undoActions, i);
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->retryCode, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->reserved, _OVER)
|
|
||||||
if (pAction->actionType == TRANS_ACTION_RAW) {
|
|
||||||
int32_t len = sdbGetRawTotalSize(pAction->pRaw);
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->rawWritten*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, len, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
|
|
||||||
} else if (pAction->actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
|
|
||||||
SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgSent*/, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgReceived*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
|
|
||||||
} else {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < commitActionNum; ++i) {
|
|
||||||
STransAction *pAction = taosArrayGet(pTrans->commitActions, i);
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->id, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->errCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->acceptableCode, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->retryCode, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->actionType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->stage, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, pAction->reserved, _OVER)
|
|
||||||
if (pAction->actionType == TRANS_ACTION_RAW) {
|
|
||||||
int32_t len = sdbGetRawTotalSize(pAction->pRaw);
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->rawWritten*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, len, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pRaw, len, _OVER)
|
|
||||||
} else if (pAction->actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, (void *)&pAction->epSet, sizeof(SEpSet), _OVER)
|
|
||||||
SDB_SET_INT16(pRaw, dataPos, pAction->msgType, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgSent*/, _OVER)
|
|
||||||
SDB_SET_INT8(pRaw, dataPos, unused /*pAction->msgReceived*/, _OVER)
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pAction->contLen, _OVER)
|
|
||||||
SDB_SET_BINARY(pRaw, dataPos, pAction->pCont, pAction->contLen, _OVER)
|
|
||||||
} else {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, pTrans->startFunc, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pTrans->startFunc, _OVER)
|
||||||
SDB_SET_INT32(pRaw, dataPos, pTrans->stopFunc, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, pTrans->stopFunc, _OVER)
|
||||||
|
@ -242,23 +210,76 @@ _OVER:
|
||||||
return pRaw;
|
return pRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
|
static int32_t mndTransDecodeAction(SSdbRaw *pRaw, int32_t *offset, SArray *pActions, int32_t actionNum) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
STransAction action = {0};
|
||||||
|
int32_t dataPos = *offset;
|
||||||
|
int8_t unused = 0;
|
||||||
|
int8_t stage = 0;
|
||||||
|
int8_t actionType = 0;
|
||||||
|
int32_t dataLen = 0;
|
||||||
|
int32_t ret = -1;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < actionNum; ++i) {
|
||||||
|
memset(&action, 0, sizeof(action));
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &action.retryCode, _OVER)
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &actionType, _OVER)
|
||||||
|
action.actionType = actionType;
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &stage, _OVER)
|
||||||
|
action.stage = stage;
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &action.reserved, _OVER)
|
||||||
|
if (action.actionType == TRANS_ACTION_RAW) {
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.rawWritten*/, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
|
||||||
|
action.pRaw = taosMemoryMalloc(dataLen);
|
||||||
|
if (action.pRaw == NULL) goto _OVER;
|
||||||
|
mTrace("raw:%p, is created", action.pRaw);
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
|
||||||
|
if (taosArrayPush(pActions, &action) == NULL) goto _OVER;
|
||||||
|
action.pRaw = NULL;
|
||||||
|
} else if (action.actionType == TRANS_ACTION_MSG) {
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
|
||||||
|
tmsgUpdateDnodeEpSet(&action.epSet);
|
||||||
|
SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgSent*/, _OVER)
|
||||||
|
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgReceived*/, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
|
||||||
|
action.pCont = taosMemoryMalloc(action.contLen);
|
||||||
|
if (action.pCont == NULL) goto _OVER;
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
|
||||||
|
if (taosArrayPush(pActions, &action) == NULL) goto _OVER;
|
||||||
|
action.pCont = NULL;
|
||||||
|
} else {
|
||||||
|
if (taosArrayPush(pActions, &action) == NULL) goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
*offset = dataPos;
|
||||||
|
taosMemoryFreeClear(action.pCont);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSdbRow *mndTransDecode(SSdbRaw *pRaw) {
|
||||||
|
terrno = TSDB_CODE_INVALID_MSG;
|
||||||
|
|
||||||
SSdbRow *pRow = NULL;
|
SSdbRow *pRow = NULL;
|
||||||
STrans *pTrans = NULL;
|
STrans *pTrans = NULL;
|
||||||
char *pData = NULL;
|
char *pData = NULL;
|
||||||
int32_t dataLen = 0;
|
int32_t dataLen = 0;
|
||||||
int8_t sver = 0;
|
int8_t sver = 0;
|
||||||
|
int32_t prepareActionNum = 0;
|
||||||
int32_t redoActionNum = 0;
|
int32_t redoActionNum = 0;
|
||||||
int32_t undoActionNum = 0;
|
int32_t undoActionNum = 0;
|
||||||
int32_t commitActionNum = 0;
|
int32_t commitActionNum = 0;
|
||||||
int32_t dataPos = 0;
|
int32_t dataPos = 0;
|
||||||
STransAction action = {0};
|
|
||||||
|
|
||||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
|
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
|
||||||
|
|
||||||
if (sver != TRANS_VER_NUMBER) {
|
if (sver != TRANS_VER1_NUMBER && sver != TRANS_VER2_NUMBER) {
|
||||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
@ -294,127 +315,28 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
|
||||||
SDB_GET_BINARY(pRaw, dataPos, pTrans->dbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
SDB_GET_BINARY(pRaw, dataPos, pTrans->dbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
||||||
SDB_GET_BINARY(pRaw, dataPos, pTrans->stbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
SDB_GET_BINARY(pRaw, dataPos, pTrans->stbname, TSDB_TABLE_FNAME_LEN, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->redoActionPos, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pTrans->redoActionPos, _OVER)
|
||||||
|
|
||||||
|
if (sver > TRANS_VER1_NUMBER) {
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &prepareActionNum, _OVER)
|
||||||
|
}
|
||||||
SDB_GET_INT32(pRaw, dataPos, &redoActionNum, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &redoActionNum, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &undoActionNum, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &undoActionNum, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &commitActionNum, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &commitActionNum, _OVER)
|
||||||
|
|
||||||
|
pTrans->prepareActions = taosArrayInit(prepareActionNum, sizeof(STransAction));
|
||||||
pTrans->redoActions = taosArrayInit(redoActionNum, sizeof(STransAction));
|
pTrans->redoActions = taosArrayInit(redoActionNum, sizeof(STransAction));
|
||||||
pTrans->undoActions = taosArrayInit(undoActionNum, sizeof(STransAction));
|
pTrans->undoActions = taosArrayInit(undoActionNum, sizeof(STransAction));
|
||||||
pTrans->commitActions = taosArrayInit(commitActionNum, sizeof(STransAction));
|
pTrans->commitActions = taosArrayInit(commitActionNum, sizeof(STransAction));
|
||||||
|
|
||||||
|
if (pTrans->prepareActions == NULL) goto _OVER;
|
||||||
if (pTrans->redoActions == NULL) goto _OVER;
|
if (pTrans->redoActions == NULL) goto _OVER;
|
||||||
if (pTrans->undoActions == NULL) goto _OVER;
|
if (pTrans->undoActions == NULL) goto _OVER;
|
||||||
if (pTrans->commitActions == NULL) goto _OVER;
|
if (pTrans->commitActions == NULL) goto _OVER;
|
||||||
|
|
||||||
int8_t unused = 0;
|
if (mndTransDecodeAction(pRaw, &dataPos, pTrans->prepareActions, prepareActionNum) < 0) goto _OVER;
|
||||||
for (int32_t i = 0; i < redoActionNum; ++i) {
|
if (mndTransDecodeAction(pRaw, &dataPos, pTrans->redoActions, redoActionNum) < 0) goto _OVER;
|
||||||
memset(&action, 0, sizeof(action));
|
if (mndTransDecodeAction(pRaw, &dataPos, pTrans->undoActions, undoActionNum) < 0) goto _OVER;
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
|
if (mndTransDecodeAction(pRaw, &dataPos, pTrans->commitActions, commitActionNum) < 0) goto _OVER;
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.retryCode, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &actionType, _OVER)
|
|
||||||
action.actionType = actionType;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &stage, _OVER)
|
|
||||||
action.stage = stage;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &action.reserved, _OVER)
|
|
||||||
if (action.actionType == TRANS_ACTION_RAW) {
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.rawWritten*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
|
|
||||||
action.pRaw = taosMemoryMalloc(dataLen);
|
|
||||||
if (action.pRaw == NULL) goto _OVER;
|
|
||||||
mTrace("raw:%p, is created", action.pRaw);
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pRaw = NULL;
|
|
||||||
} else if (action.actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
|
|
||||||
tmsgUpdateDnodeEpSet(&action.epSet);
|
|
||||||
SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgSent*/, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgReceived*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
|
|
||||||
action.pCont = taosMemoryMalloc(action.contLen);
|
|
||||||
if (action.pCont == NULL) goto _OVER;
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pCont = NULL;
|
|
||||||
} else {
|
|
||||||
if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < undoActionNum; ++i) {
|
|
||||||
memset(&action, 0, sizeof(action));
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.retryCode, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &actionType, _OVER)
|
|
||||||
action.actionType = actionType;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &stage, _OVER)
|
|
||||||
action.stage = stage;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &action.reserved, _OVER)
|
|
||||||
if (action.actionType == TRANS_ACTION_RAW) {
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.rawWritten*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
|
|
||||||
action.pRaw = taosMemoryMalloc(dataLen);
|
|
||||||
if (action.pRaw == NULL) goto _OVER;
|
|
||||||
mTrace("raw:%p, is created", action.pRaw);
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pRaw = NULL;
|
|
||||||
} else if (action.actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
|
|
||||||
SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgSent*/, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgReceived*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
|
|
||||||
action.pCont = taosMemoryMalloc(action.contLen);
|
|
||||||
if (action.pCont == NULL) goto _OVER;
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pCont = NULL;
|
|
||||||
} else {
|
|
||||||
if (taosArrayPush(pTrans->undoActions, &action) == NULL) goto _OVER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < commitActionNum; ++i) {
|
|
||||||
memset(&action, 0, sizeof(action));
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.id, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.errCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.acceptableCode, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.retryCode, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &actionType, _OVER)
|
|
||||||
action.actionType = actionType;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &stage, _OVER)
|
|
||||||
action.stage = stage;
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &action.reserved, _OVER)
|
|
||||||
if (action.actionType) {
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.rawWritten*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &dataLen, _OVER)
|
|
||||||
action.pRaw = taosMemoryMalloc(dataLen);
|
|
||||||
if (action.pRaw == NULL) goto _OVER;
|
|
||||||
mTrace("raw:%p, is created", action.pRaw);
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)action.pRaw, dataLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->commitActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pRaw = NULL;
|
|
||||||
} else if (action.actionType == TRANS_ACTION_MSG) {
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, (void *)&action.epSet, sizeof(SEpSet), _OVER);
|
|
||||||
SDB_GET_INT16(pRaw, dataPos, &action.msgType, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgSent*/, _OVER)
|
|
||||||
SDB_GET_INT8(pRaw, dataPos, &unused /*&action.msgReceived*/, _OVER)
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &action.contLen, _OVER)
|
|
||||||
action.pCont = taosMemoryMalloc(action.contLen);
|
|
||||||
if (action.pCont == NULL) goto _OVER;
|
|
||||||
SDB_GET_BINARY(pRaw, dataPos, action.pCont, action.contLen, _OVER);
|
|
||||||
if (taosArrayPush(pTrans->commitActions, &action) == NULL) goto _OVER;
|
|
||||||
action.pCont = NULL;
|
|
||||||
} else {
|
|
||||||
if (taosArrayPush(pTrans->redoActions, &action) == NULL) goto _OVER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->startFunc, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pTrans->startFunc, _OVER)
|
||||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->stopFunc, _OVER)
|
SDB_GET_INT32(pRaw, dataPos, &pTrans->stopFunc, _OVER)
|
||||||
|
@ -434,7 +356,6 @@ _OVER:
|
||||||
mError("trans:%d, failed to parse from raw:%p since %s", pTrans->id, pRaw, terrstr());
|
mError("trans:%d, failed to parse from raw:%p since %s", pTrans->id, pRaw, terrstr());
|
||||||
mndTransDropData(pTrans);
|
mndTransDropData(pTrans);
|
||||||
taosMemoryFreeClear(pRow);
|
taosMemoryFreeClear(pRow);
|
||||||
taosMemoryFreeClear(action.pCont);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +379,7 @@ static const char *mndTransStr(ETrnStage stage) {
|
||||||
return "commit";
|
return "commit";
|
||||||
case TRN_STAGE_COMMIT_ACTION:
|
case TRN_STAGE_COMMIT_ACTION:
|
||||||
return "commitAction";
|
return "commitAction";
|
||||||
case TRN_STAGE_FINISHED:
|
case TRN_STAGE_FINISH:
|
||||||
return "finished";
|
return "finished";
|
||||||
case TRN_STAGE_PRE_FINISH:
|
case TRN_STAGE_PRE_FINISH:
|
||||||
return "pre-finish";
|
return "pre-finish";
|
||||||
|
@ -519,7 +440,11 @@ static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mndTransDropData(STrans *pTrans) {
|
void mndTransDropData(STrans *pTrans) {
|
||||||
|
if (pTrans->prepareActions != NULL) {
|
||||||
|
mndTransDropActions(pTrans->prepareActions);
|
||||||
|
pTrans->prepareActions = NULL;
|
||||||
|
}
|
||||||
if (pTrans->redoActions != NULL) {
|
if (pTrans->redoActions != NULL) {
|
||||||
mndTransDropActions(pTrans->redoActions);
|
mndTransDropActions(pTrans->redoActions);
|
||||||
pTrans->redoActions = NULL;
|
pTrans->redoActions = NULL;
|
||||||
|
@ -549,7 +474,7 @@ static void mndTransDropData(STrans *pTrans) {
|
||||||
(void)taosThreadMutexDestroy(&pTrans->mutex);
|
(void)taosThreadMutexDestroy(&pTrans->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) {
|
static int32_t mndTransDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) {
|
||||||
mInfo("trans:%d, perform delete action, row:%p stage:%s callfunc:%d, stopFunc:%d", pTrans->id, pTrans,
|
mInfo("trans:%d, perform delete action, row:%p stage:%s callfunc:%d, stopFunc:%d", pTrans->id, pTrans,
|
||||||
mndTransStr(pTrans->stage), callFunc, pTrans->stopFunc);
|
mndTransStr(pTrans->stage), callFunc, pTrans->stopFunc);
|
||||||
|
|
||||||
|
@ -586,10 +511,11 @@ static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
|
||||||
pOld->id, pOld, mndTransStr(pOld->stage), pOld->createdTime, pNew, mndTransStr(pNew->stage),
|
pOld->id, pOld, mndTransStr(pOld->stage), pOld->createdTime, pNew, mndTransStr(pNew->stage),
|
||||||
pNew->createdTime);
|
pNew->createdTime);
|
||||||
// only occured while sync timeout
|
// only occured while sync timeout
|
||||||
terrno = TSDB_CODE_MND_TRNAS_SYNC_TIMEOUT;
|
terrno = TSDB_CODE_MND_TRANS_SYNC_TIMEOUT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mndTransUpdateActions(pOld->prepareActions, pNew->prepareActions);
|
||||||
mndTransUpdateActions(pOld->redoActions, pNew->redoActions);
|
mndTransUpdateActions(pOld->redoActions, pNew->redoActions);
|
||||||
mndTransUpdateActions(pOld->undoActions, pNew->undoActions);
|
mndTransUpdateActions(pOld->undoActions, pNew->undoActions);
|
||||||
mndTransUpdateActions(pOld->commitActions, pNew->commitActions);
|
mndTransUpdateActions(pOld->commitActions, pNew->commitActions);
|
||||||
|
@ -607,7 +533,7 @@ static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOld->stage == TRN_STAGE_PRE_FINISH) {
|
if (pOld->stage == TRN_STAGE_PRE_FINISH) {
|
||||||
pOld->stage = TRN_STAGE_FINISHED;
|
pOld->stage = TRN_STAGE_FINISH;
|
||||||
mTrace("trans:%d, stage from pre-finish to finished since perform update action", pNew->id);
|
mTrace("trans:%d, stage from pre-finish to finished since perform update action", pNew->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,6 +572,7 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnConflct conflict,
|
||||||
pTrans->conflict = conflict;
|
pTrans->conflict = conflict;
|
||||||
pTrans->exec = TRN_EXEC_PARALLEL;
|
pTrans->exec = TRN_EXEC_PARALLEL;
|
||||||
pTrans->createdTime = taosGetTimestampMs();
|
pTrans->createdTime = taosGetTimestampMs();
|
||||||
|
pTrans->prepareActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
||||||
pTrans->redoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
pTrans->redoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
||||||
pTrans->undoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
pTrans->undoActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
||||||
pTrans->commitActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
pTrans->commitActions = taosArrayInit(TRANS_ARRAY_SIZE, sizeof(STransAction));
|
||||||
|
@ -728,6 +655,13 @@ int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw) {
|
||||||
return mndTransAppendAction(pTrans->commitActions, &action);
|
return mndTransAppendAction(pTrans->commitActions, &action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t mndTransAppendPrepareAction(STrans *pTrans, STransAction *pAction) {
|
||||||
|
pAction->stage = TRN_STAGE_PREPARE;
|
||||||
|
pAction->actionType = TRANS_ACTION_RAW;
|
||||||
|
pAction->mTraceId = pTrans->mTraceId;
|
||||||
|
return mndTransAppendAction(pTrans->prepareActions, pAction);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction) {
|
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction) {
|
||||||
pAction->stage = TRN_STAGE_REDO_ACTION;
|
pAction->stage = TRN_STAGE_REDO_ACTION;
|
||||||
pAction->actionType = TRANS_ACTION_MSG;
|
pAction->actionType = TRANS_ACTION_MSG;
|
||||||
|
@ -800,7 +734,7 @@ void mndTransSetParallel(STrans *pTrans) { pTrans->exec = TRN_EXEC_PARALLEL; }
|
||||||
void mndTransSetOper(STrans *pTrans, EOperType oper) { pTrans->oper = oper; }
|
void mndTransSetOper(STrans *pTrans, EOperType oper) { pTrans->oper = oper; }
|
||||||
|
|
||||||
static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
|
static int32_t mndTransSync(SMnode *pMnode, STrans *pTrans) {
|
||||||
SSdbRaw *pRaw = mndTransActionEncode(pTrans);
|
SSdbRaw *pRaw = mndTransEncode(pTrans);
|
||||||
if (pRaw == NULL) {
|
if (pRaw == NULL) {
|
||||||
mError("trans:%d, failed to encode while sync trans since %s", pTrans->id, terrstr());
|
mError("trans:%d, failed to encode while sync trans since %s", pTrans->id, terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -872,7 +806,7 @@ static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
|
||||||
return conflict;
|
return conflict;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndTrancCheckConflict(SMnode *pMnode, STrans *pTrans) {
|
int32_t mndTransCheckConflict(SMnode *pMnode, STrans *pTrans) {
|
||||||
if (pTrans->conflict == TRN_CONFLICT_DB || pTrans->conflict == TRN_CONFLICT_DB_INSIDE) {
|
if (pTrans->conflict == TRN_CONFLICT_DB || pTrans->conflict == TRN_CONFLICT_DB_INSIDE) {
|
||||||
if (strlen(pTrans->dbname) == 0 && strlen(pTrans->stbname) == 0) {
|
if (strlen(pTrans->dbname) == 0 && strlen(pTrans->stbname) == 0) {
|
||||||
terrno = TSDB_CODE_MND_TRANS_CONFLICT;
|
terrno = TSDB_CODE_MND_TRANS_CONFLICT;
|
||||||
|
@ -891,7 +825,7 @@ int32_t mndTrancCheckConflict(SMnode *pMnode, STrans *pTrans) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
||||||
if (mndTrancCheckConflict(pMnode, pTrans) != 0) {
|
if (mndTransCheckConflict(pMnode, pTrans) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,7 +856,7 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
||||||
pTrans->rpcRsp = NULL;
|
pTrans->rpcRsp = NULL;
|
||||||
pTrans->rpcRspLen = 0;
|
pTrans->rpcRspLen = 0;
|
||||||
|
|
||||||
mndTransExecute(pMnode, pNew, true);
|
mndTransExecute(pMnode, pNew);
|
||||||
mndReleaseTrans(pMnode, pNew);
|
mndReleaseTrans(pMnode, pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -961,7 +895,7 @@ static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans) {
|
||||||
bool sendRsp = false;
|
bool sendRsp = false;
|
||||||
int32_t code = pTrans->code;
|
int32_t code = pTrans->code;
|
||||||
|
|
||||||
if (pTrans->stage == TRN_STAGE_FINISHED) {
|
if (pTrans->stage == TRN_STAGE_FINISH) {
|
||||||
sendRsp = true;
|
sendRsp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,7 +937,7 @@ static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans) {
|
||||||
code = TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL;
|
code = TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL;
|
||||||
}
|
}
|
||||||
if (code == TSDB_CODE_SYN_TIMEOUT) {
|
if (code == TSDB_CODE_SYN_TIMEOUT) {
|
||||||
code = TSDB_CODE_MND_TRNAS_SYNC_TIMEOUT;
|
code = TSDB_CODE_MND_TRANS_SYNC_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0 && code == 0) {
|
if (i != 0 && code == 0) {
|
||||||
|
@ -1104,7 +1038,7 @@ int32_t mndTransProcessRsp(SRpcMsg *pRsp) {
|
||||||
mInfo("trans:%d, invalid action, index:%d, code:0x%x", transId, action, pRsp->code);
|
mInfo("trans:%d, invalid action, index:%d, code:0x%x", transId, action, pRsp->code);
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransExecute(pMnode, pTrans, true);
|
mndTransExecute(pMnode, pTrans);
|
||||||
|
|
||||||
_OVER:
|
_OVER:
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
mndReleaseTrans(pMnode, pTrans);
|
||||||
|
@ -1392,8 +1326,25 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
|
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
bool continueExec = true;
|
bool continueExec = true;
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
int32_t numOfActions = taosArrayGetSize(pTrans->prepareActions);
|
||||||
|
if (numOfActions == 0) goto _OVER;
|
||||||
|
|
||||||
|
mInfo("trans:%d, execute %d prepare actions.", pTrans->id, numOfActions);
|
||||||
|
|
||||||
|
for (int32_t action = 0; action < numOfActions; ++action) {
|
||||||
|
STransAction *pAction = taosArrayGet(pTrans->prepareActions, action);
|
||||||
|
code = mndTransExecSingleAction(pMnode, pTrans, pAction);
|
||||||
|
if (code != 0) {
|
||||||
|
mError("trans:%d, failed to execute prepare action:%d, numOfActions:%d", pTrans->id, action, numOfActions);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_OVER:
|
||||||
pTrans->stage = TRN_STAGE_REDO_ACTION;
|
pTrans->stage = TRN_STAGE_REDO_ACTION;
|
||||||
mInfo("trans:%d, stage from prepare to redoAction", pTrans->id);
|
mInfo("trans:%d, stage from prepare to redoAction", pTrans->id);
|
||||||
return continueExec;
|
return continueExec;
|
||||||
|
@ -1476,7 +1427,7 @@ static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
pTrans->code = 0;
|
pTrans->code = 0;
|
||||||
pTrans->stage = TRN_STAGE_FINISHED; // TRN_STAGE_PRE_FINISH is not necessary
|
pTrans->stage = TRN_STAGE_FINISH; // TRN_STAGE_PRE_FINISH is not necessary
|
||||||
mInfo("trans:%d, stage from commitAction to finished", pTrans->id);
|
mInfo("trans:%d, stage from commitAction to finished", pTrans->id);
|
||||||
continueExec = true;
|
continueExec = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1528,14 +1479,14 @@ static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mndTransPerfromPreFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
static bool mndTransPerformPreFinishStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
if (mndCannotExecuteTransAction(pMnode)) return false;
|
if (mndCannotExecuteTransAction(pMnode)) return false;
|
||||||
|
|
||||||
bool continueExec = true;
|
bool continueExec = true;
|
||||||
int32_t code = mndTransPreFinish(pMnode, pTrans);
|
int32_t code = mndTransPreFinish(pMnode, pTrans);
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
pTrans->stage = TRN_STAGE_FINISHED;
|
pTrans->stage = TRN_STAGE_FINISH;
|
||||||
mInfo("trans:%d, stage from pre-finish to finish", pTrans->id);
|
mInfo("trans:%d, stage from pre-finish to finish", pTrans->id);
|
||||||
continueExec = true;
|
continueExec = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1547,10 +1498,10 @@ static bool mndTransPerfromPreFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
bool continueExec = false;
|
bool continueExec = false;
|
||||||
|
|
||||||
SSdbRaw *pRaw = mndTransActionEncode(pTrans);
|
SSdbRaw *pRaw = mndTransEncode(pTrans);
|
||||||
if (pRaw == NULL) {
|
if (pRaw == NULL) {
|
||||||
mError("trans:%d, failed to encode while finish trans since %s", pTrans->id, terrstr());
|
mError("trans:%d, failed to encode while finish trans since %s", pTrans->id, terrstr());
|
||||||
return false;
|
return false;
|
||||||
|
@ -1567,12 +1518,12 @@ static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
void mndTransExecuteImp(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||||
bool continueExec = true;
|
bool continueExec = true;
|
||||||
|
|
||||||
while (continueExec) {
|
while (continueExec) {
|
||||||
mInfo("trans:%d, continue to execute, stage:%s createTime:%" PRId64 " leader:%d", pTrans->id,
|
mInfo("trans:%d, continue to execute, stage:%s createTime:%" PRId64 " topHalf:%d", pTrans->id,
|
||||||
mndTransStr(pTrans->stage), pTrans->createdTime, isLeader);
|
mndTransStr(pTrans->stage), pTrans->createdTime, topHalf);
|
||||||
pTrans->lastExecTime = taosGetTimestampMs();
|
pTrans->lastExecTime = taosGetTimestampMs();
|
||||||
switch (pTrans->stage) {
|
switch (pTrans->stage) {
|
||||||
case TRN_STAGE_PREPARE:
|
case TRN_STAGE_PREPARE:
|
||||||
|
@ -1582,7 +1533,7 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
||||||
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_COMMIT:
|
case TRN_STAGE_COMMIT:
|
||||||
if (isLeader) {
|
if (topHalf) {
|
||||||
continueExec = mndTransPerformCommitStage(pMnode, pTrans);
|
continueExec = mndTransPerformCommitStage(pMnode, pTrans);
|
||||||
} else {
|
} else {
|
||||||
mInfo("trans:%d, can not commit since not leader", pTrans->id);
|
mInfo("trans:%d, can not commit since not leader", pTrans->id);
|
||||||
|
@ -1593,7 +1544,7 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
||||||
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_ROLLBACK:
|
case TRN_STAGE_ROLLBACK:
|
||||||
if (isLeader) {
|
if (topHalf) {
|
||||||
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
|
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
|
||||||
} else {
|
} else {
|
||||||
mInfo("trans:%d, can not rollback since not leader", pTrans->id);
|
mInfo("trans:%d, can not rollback since not leader", pTrans->id);
|
||||||
|
@ -1604,15 +1555,15 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
||||||
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
|
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_PRE_FINISH:
|
case TRN_STAGE_PRE_FINISH:
|
||||||
if (isLeader) {
|
if (topHalf) {
|
||||||
continueExec = mndTransPerfromPreFinishedStage(pMnode, pTrans);
|
continueExec = mndTransPerformPreFinishStage(pMnode, pTrans);
|
||||||
} else {
|
} else {
|
||||||
mInfo("trans:%d, can not pre-finish since not leader", pTrans->id);
|
mInfo("trans:%d, can not pre-finish since not leader", pTrans->id);
|
||||||
continueExec = false;
|
continueExec = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRN_STAGE_FINISHED:
|
case TRN_STAGE_FINISH:
|
||||||
continueExec = mndTransPerfromFinishedStage(pMnode, pTrans);
|
continueExec = mndTransPerformFinishStage(pMnode, pTrans);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continueExec = false;
|
continueExec = false;
|
||||||
|
@ -1623,6 +1574,16 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans, bool isLeader) {
|
||||||
mndTransSendRpcRsp(pMnode, pTrans);
|
mndTransSendRpcRsp(pMnode, pTrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mndTransExecute(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
bool topHalf = true;
|
||||||
|
return mndTransExecuteImp(pMnode, pTrans, topHalf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mndTransRefresh(SMnode *pMnode, STrans *pTrans) {
|
||||||
|
bool topHalf = false;
|
||||||
|
return mndTransExecuteImp(pMnode, pTrans, topHalf);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mndProcessTransTimer(SRpcMsg *pReq) {
|
static int32_t mndProcessTransTimer(SRpcMsg *pReq) {
|
||||||
mTrace("start to process trans timer");
|
mTrace("start to process trans timer");
|
||||||
mndTransPullup(pReq->info.node);
|
mndTransPullup(pReq->info.node);
|
||||||
|
@ -1649,7 +1610,7 @@ int32_t mndKillTrans(SMnode *pMnode, STrans *pTrans) {
|
||||||
pAction->errCode = 0;
|
pAction->errCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransExecute(pMnode, pTrans, true);
|
mndTransExecute(pMnode, pTrans);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1707,7 +1668,7 @@ void mndTransPullup(SMnode *pMnode) {
|
||||||
int32_t *pTransId = taosArrayGet(pArray, i);
|
int32_t *pTransId = taosArrayGet(pArray, i);
|
||||||
STrans *pTrans = mndAcquireTrans(pMnode, *pTransId);
|
STrans *pTrans = mndAcquireTrans(pMnode, *pTransId);
|
||||||
if (pTrans != NULL) {
|
if (pTrans != NULL) {
|
||||||
mndTransExecute(pMnode, pTrans, true);
|
mndTransExecute(pMnode, pTrans);
|
||||||
}
|
}
|
||||||
mndReleaseTrans(pMnode, pTrans);
|
mndReleaseTrans(pMnode, pTrans);
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,7 +488,7 @@ SHashObj *mndDupUseDbHash(SHashObj *pOld) {
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
|
int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
|
||||||
memcpy(pNew, pUser, sizeof(SUserObj));
|
memcpy(pNew, pUser, sizeof(SUserObj));
|
||||||
pNew->authVersion++;
|
pNew->authVersion++;
|
||||||
pNew->updateTime = taosGetTimestampMs();
|
pNew->updateTime = taosGetTimestampMs();
|
||||||
|
@ -508,7 +508,7 @@ static int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mndUserFreeObj(SUserObj *pUser) {
|
void mndUserFreeObj(SUserObj *pUser) {
|
||||||
taosHashCleanup(pUser->readDbs);
|
taosHashCleanup(pUser->readDbs);
|
||||||
taosHashCleanup(pUser->writeDbs);
|
taosHashCleanup(pUser->writeDbs);
|
||||||
taosHashCleanup(pUser->topics);
|
taosHashCleanup(pUser->topics);
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#define VGROUP_VER_NUMBER 1
|
#define VGROUP_VER_NUMBER 1
|
||||||
#define VGROUP_RESERVE_SIZE 64
|
#define VGROUP_RESERVE_SIZE 64
|
||||||
|
|
||||||
static SSdbRow *mndVgroupActionDecode(SSdbRaw *pRaw);
|
|
||||||
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup);
|
static int32_t mndVgroupActionInsert(SSdb *pSdb, SVgObj *pVgroup);
|
||||||
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup);
|
static int32_t mndVgroupActionDelete(SSdb *pSdb, SVgObj *pVgroup);
|
||||||
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew);
|
static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew);
|
||||||
|
@ -483,15 +482,15 @@ static void *mndBuildDisableVnodeWriteReq(SMnode *pMnode, SDbObj *pDb, int32_t v
|
||||||
return pReq;
|
return pReq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *mndBuildAlterVnodeHashRangeReq(SMnode *pMnode, SVgObj *pVgroup, int32_t dstVgId, int32_t *pContLen) {
|
static void *mndBuildAlterVnodeHashRangeReq(SMnode *pMnode, int32_t srcVgId, SVgObj *pVgroup, int32_t *pContLen) {
|
||||||
SAlterVnodeHashRangeReq alterReq = {
|
SAlterVnodeHashRangeReq alterReq = {
|
||||||
.srcVgId = pVgroup->vgId,
|
.srcVgId = srcVgId,
|
||||||
.dstVgId = dstVgId,
|
.dstVgId = pVgroup->vgId,
|
||||||
.hashBegin = pVgroup->hashBegin,
|
.hashBegin = pVgroup->hashBegin,
|
||||||
.hashEnd = pVgroup->hashEnd,
|
.hashEnd = pVgroup->hashEnd,
|
||||||
};
|
};
|
||||||
|
|
||||||
mInfo("vgId:%d, build alter vnode hashrange req, dstVgId:%d, hashrange:[%u, %u]", pVgroup->vgId, dstVgId,
|
mInfo("vgId:%d, build alter vnode hashrange req, dstVgId:%d, hashrange:[%u, %u]", srcVgId, pVgroup->vgId,
|
||||||
pVgroup->hashBegin, pVgroup->hashEnd);
|
pVgroup->hashBegin, pVgroup->hashEnd);
|
||||||
int32_t contLen = tSerializeSAlterVnodeHashRangeReq(NULL, 0, &alterReq);
|
int32_t contLen = tSerializeSAlterVnodeHashRangeReq(NULL, 0, &alterReq);
|
||||||
if (contLen < 0) {
|
if (contLen < 0) {
|
||||||
|
@ -1207,12 +1206,12 @@ int32_t mndAddAlterVnodeConfirmAction(SMnode *pMnode, STrans *pTrans, SDbObj *pD
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVgroup, int32_t dstVgId) {
|
static int32_t mndAddAlterVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans, int32_t srcVgId, SVgObj *pVgroup) {
|
||||||
STransAction action = {0};
|
STransAction action = {0};
|
||||||
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
action.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
||||||
|
|
||||||
int32_t contLen = 0;
|
int32_t contLen = 0;
|
||||||
void *pReq = mndBuildAlterVnodeHashRangeReq(pMnode, pVgroup, dstVgId, &contLen);
|
void *pReq = mndBuildAlterVnodeHashRangeReq(pMnode, srcVgId, pVgroup, &contLen);
|
||||||
if (pReq == NULL) return -1;
|
if (pReq == NULL) return -1;
|
||||||
|
|
||||||
action.pCont = pReq;
|
action.pCont = pReq;
|
||||||
|
@ -1247,6 +1246,21 @@ int32_t mndAddAlterVnodeConfigAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t mndAddPrepareNewVgAction(SMnode *pMnode, STrans *pTrans, SVgObj *pVg) {
|
||||||
|
SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
|
||||||
|
if (pRaw == NULL) goto _err;
|
||||||
|
|
||||||
|
STransAction action = {.pRaw = pRaw, .msgType = TDMT_MND_CREATE_VG};
|
||||||
|
if (mndTransAppendPrepareAction(pTrans, &action) != 0) goto _err;
|
||||||
|
(void)sdbSetRawStatus(pRaw, SDB_STATUS_CREATING);
|
||||||
|
pRaw = NULL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
sdbFreeRaw(pRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
|
int32_t mndAddAlterVnodeReplicaAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SVgObj *pVgroup, int32_t dnodeId) {
|
||||||
SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
|
SDnodeObj *pDnode = mndAcquireDnode(pMnode, dnodeId);
|
||||||
if (pDnode == NULL) return -1;
|
if (pDnode == NULL) return -1;
|
||||||
|
@ -2241,10 +2255,13 @@ static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndTransCommitVgStatus(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus) {
|
typedef int32_t (*FpTransActionCb)(STrans *pTrans, SSdbRaw *pRaw);
|
||||||
|
|
||||||
|
static int32_t mndAddVgStatusAction(STrans *pTrans, SVgObj *pVg, ESdbStatus vgStatus, ETrnStage stage) {
|
||||||
|
FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
|
||||||
SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
|
SSdbRaw *pRaw = mndVgroupActionEncode(pVg);
|
||||||
if (pRaw == NULL) goto _err;
|
if (pRaw == NULL) goto _err;
|
||||||
if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _err;
|
if (appendActionCb(pTrans, pRaw) != 0) goto _err;
|
||||||
(void)sdbSetRawStatus(pRaw, vgStatus);
|
(void)sdbSetRawStatus(pRaw, vgStatus);
|
||||||
pRaw = NULL;
|
pRaw = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2253,18 +2270,32 @@ _err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t mndAddDbStatusAction(STrans *pTrans, SDbObj *pDb, ESdbStatus dbStatus, ETrnStage stage) {
|
||||||
|
FpTransActionCb appendActionCb = (stage == TRN_STAGE_COMMIT_ACTION) ? mndTransAppendCommitlog : mndTransAppendRedolog;
|
||||||
|
SSdbRaw *pRaw = mndDbActionEncode(pDb);
|
||||||
|
if (pRaw == NULL) goto _err;
|
||||||
|
if (appendActionCb(pTrans, pRaw) != 0) goto _err;
|
||||||
|
(void)sdbSetRawStatus(pRaw, dbStatus);
|
||||||
|
pRaw = NULL;
|
||||||
|
return 0;
|
||||||
|
_err:
|
||||||
|
sdbFreeRaw(pRaw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
|
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
STrans *pTrans = NULL;
|
STrans *pTrans = NULL;
|
||||||
SSdbRaw *pRaw = NULL;
|
|
||||||
SDbObj dbObj = {0};
|
SDbObj dbObj = {0};
|
||||||
SArray *pArray = mndBuildDnodesArray(pMnode, 0);
|
SArray *pArray = mndBuildDnodesArray(pMnode, 0);
|
||||||
|
|
||||||
pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_GLOBAL, pReq, "split-vgroup");
|
pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB, pReq, "split-vgroup");
|
||||||
if (pTrans == NULL) goto _OVER;
|
if (pTrans == NULL) goto _OVER;
|
||||||
mndTransSetSerial(pTrans);
|
mndTransSetSerial(pTrans);
|
||||||
mInfo("trans:%d, used to split vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
|
mInfo("trans:%d, used to split vgroup, vgId:%d", pTrans->id, pVgroup->vgId);
|
||||||
|
|
||||||
|
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||||
|
|
||||||
SVgObj newVg1 = {0};
|
SVgObj newVg1 = {0};
|
||||||
memcpy(&newVg1, pVgroup, sizeof(SVgObj));
|
memcpy(&newVg1, pVgroup, sizeof(SVgObj));
|
||||||
mInfo("vgId:%d, vgroup info before split, replica:%d hashBegin:%u hashEnd:%u", newVg1.vgId, newVg1.replica,
|
mInfo("vgId:%d, vgroup info before split, replica:%d hashBegin:%u hashEnd:%u", newVg1.vgId, newVg1.replica,
|
||||||
|
@ -2316,32 +2347,25 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro
|
||||||
|
|
||||||
// alter vgId and hash range
|
// alter vgId and hash range
|
||||||
int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
|
int32_t maxVgId = sdbGetMaxId(pMnode->pSdb, SDB_VGROUP);
|
||||||
if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, &newVg1, maxVgId) != 0) goto _OVER;
|
int32_t srcVgId = newVg1.vgId;
|
||||||
newVg1.vgId = maxVgId;
|
newVg1.vgId = maxVgId;
|
||||||
|
if (mndAddPrepareNewVgAction(pMnode, pTrans, &newVg1) != 0) goto _OVER;
|
||||||
|
if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg1) != 0) goto _OVER;
|
||||||
|
|
||||||
maxVgId++;
|
maxVgId++;
|
||||||
if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, &newVg2, maxVgId) != 0) goto _OVER;
|
srcVgId = newVg2.vgId;
|
||||||
newVg2.vgId = maxVgId;
|
newVg2.vgId = maxVgId;
|
||||||
|
if (mndAddPrepareNewVgAction(pMnode, pTrans, &newVg2) != 0) goto _OVER;
|
||||||
|
if (mndAddAlterVnodeHashRangeAction(pMnode, pTrans, srcVgId, &newVg2) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1) != 0) goto _OVER;
|
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg1) != 0) goto _OVER;
|
||||||
|
|
||||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2) != 0) goto _OVER;
|
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, &newVg2) != 0) goto _OVER;
|
||||||
|
|
||||||
// adjust vgroup replica
|
if (mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION) < 0) goto _OVER;
|
||||||
if (pDb->cfg.replications != newVg1.replica) {
|
if (mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION) < 0) goto _OVER;
|
||||||
if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray) != 0) goto _OVER;
|
if (mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_REDO_ACTION) < 0) goto _OVER;
|
||||||
} else {
|
|
||||||
if (mndTransCommitVgStatus(pTrans, &newVg1, SDB_STATUS_READY) < 0) goto _OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDb->cfg.replications != newVg2.replica) {
|
|
||||||
if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray) != 0) goto _OVER;
|
|
||||||
} else {
|
|
||||||
if (mndTransCommitVgStatus(pTrans, &newVg2, SDB_STATUS_READY) < 0) goto _OVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mndTransCommitVgStatus(pTrans, pVgroup, SDB_STATUS_DROPPED) < 0) goto _OVER;
|
|
||||||
|
|
||||||
|
// update db status
|
||||||
memcpy(&dbObj, pDb, sizeof(SDbObj));
|
memcpy(&dbObj, pDb, sizeof(SDbObj));
|
||||||
if (dbObj.cfg.pRetensions != NULL) {
|
if (dbObj.cfg.pRetensions != NULL) {
|
||||||
dbObj.cfg.pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
|
dbObj.cfg.pRetensions = taosArrayDup(pDb->cfg.pRetensions, NULL);
|
||||||
|
@ -2350,11 +2374,27 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro
|
||||||
dbObj.vgVersion++;
|
dbObj.vgVersion++;
|
||||||
dbObj.updateTime = taosGetTimestampMs();
|
dbObj.updateTime = taosGetTimestampMs();
|
||||||
dbObj.cfg.numOfVgroups++;
|
dbObj.cfg.numOfVgroups++;
|
||||||
pRaw = mndDbActionEncode(&dbObj);
|
if (mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_REDO_ACTION) < 0) goto _OVER;
|
||||||
if (pRaw == NULL) goto _OVER;
|
|
||||||
if (mndTransAppendCommitlog(pTrans, pRaw) != 0) goto _OVER;
|
// adjust vgroup replica
|
||||||
(void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
|
if (pDb->cfg.replications != newVg1.replica) {
|
||||||
pRaw = NULL;
|
if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg1, pArray) != 0) goto _OVER;
|
||||||
|
} else {
|
||||||
|
if (mndAddVgStatusAction(pTrans, &newVg1, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION) < 0) goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDb->cfg.replications != newVg2.replica) {
|
||||||
|
if (mndBuildAlterVgroupAction(pMnode, pTrans, pDb, pDb, &newVg2, pArray) != 0) goto _OVER;
|
||||||
|
} else {
|
||||||
|
if (mndAddVgStatusAction(pTrans, &newVg2, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION) < 0) goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mndAddVgStatusAction(pTrans, pVgroup, SDB_STATUS_DROPPED, TRN_STAGE_COMMIT_ACTION) < 0) goto _OVER;
|
||||||
|
|
||||||
|
// commit db status
|
||||||
|
dbObj.vgVersion++;
|
||||||
|
dbObj.updateTime = taosGetTimestampMs();
|
||||||
|
if (mndAddDbStatusAction(pTrans, &dbObj, SDB_STATUS_READY, TRN_STAGE_COMMIT_ACTION) < 0) goto _OVER;
|
||||||
|
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER;
|
||||||
code = 0;
|
code = 0;
|
||||||
|
@ -2362,7 +2402,6 @@ int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgro
|
||||||
_OVER:
|
_OVER:
|
||||||
taosArrayDestroy(pArray);
|
taosArrayDestroy(pArray);
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
sdbFreeRaw(pRaw);
|
|
||||||
taosArrayDestroy(dbObj.cfg.pRetensions);
|
taosArrayDestroy(dbObj.cfg.pRetensions);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ typedef enum {
|
||||||
SDB_STATUS_DROPPING = 2,
|
SDB_STATUS_DROPPING = 2,
|
||||||
SDB_STATUS_DROPPED = 3,
|
SDB_STATUS_DROPPED = 3,
|
||||||
SDB_STATUS_READY = 4,
|
SDB_STATUS_READY = 4,
|
||||||
|
SDB_STATUS_UPDATE = 5,
|
||||||
} ESdbStatus;
|
} ESdbStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -256,6 +256,7 @@ int32_t sdbWriteWithoutFree(SSdb *pSdb, SSdbRaw *pRaw) {
|
||||||
code = sdbInsertRow(pSdb, hash, pRaw, pRow, keySize);
|
code = sdbInsertRow(pSdb, hash, pRaw, pRow, keySize);
|
||||||
break;
|
break;
|
||||||
case SDB_STATUS_READY:
|
case SDB_STATUS_READY:
|
||||||
|
case SDB_STATUS_UPDATE:
|
||||||
case SDB_STATUS_DROPPING:
|
case SDB_STATUS_DROPPING:
|
||||||
code = sdbUpdateRow(pSdb, hash, pRaw, pRow, keySize);
|
code = sdbUpdateRow(pSdb, hash, pRaw, pRow, keySize);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -139,6 +139,7 @@ static STqMgmt tqMgmt = {0};
|
||||||
|
|
||||||
int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle);
|
int32_t tEncodeSTqHandle(SEncoder* pEncoder, const STqHandle* pHandle);
|
||||||
int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle);
|
int32_t tDecodeSTqHandle(SDecoder* pDecoder, STqHandle* pHandle);
|
||||||
|
void tqDestroyTqHandle(void* data);
|
||||||
|
|
||||||
// tqRead
|
// tqRead
|
||||||
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* offset);
|
int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, STaosxRsp* pRsp, SMqMetaRsp* pMetaRsp, STqOffsetVal* offset);
|
||||||
|
@ -161,6 +162,8 @@ int32_t tqMetaRestoreHandle(STQ* pTq);
|
||||||
int32_t tqMetaSaveCheckInfo(STQ* pTq, const char* key, const void* value, int32_t vLen);
|
int32_t tqMetaSaveCheckInfo(STQ* pTq, const char* key, const void* value, int32_t vLen);
|
||||||
int32_t tqMetaDeleteCheckInfo(STQ* pTq, const char* key);
|
int32_t tqMetaDeleteCheckInfo(STQ* pTq, const char* key);
|
||||||
int32_t tqMetaRestoreCheckInfo(STQ* pTq);
|
int32_t tqMetaRestoreCheckInfo(STQ* pTq);
|
||||||
|
int32_t tqMetaGetHandle(STQ* pTq, const char* key);
|
||||||
|
int32_t tqCreateHandle(STQ* pTq, SMqRebVgReq* req, STqHandle* handle);
|
||||||
|
|
||||||
STqOffsetStore* tqOffsetOpen(STQ* pTq);
|
STqOffsetStore* tqOffsetOpen(STQ* pTq);
|
||||||
void tqOffsetClose(STqOffsetStore*);
|
void tqOffsetClose(STqOffsetStore*);
|
||||||
|
|
|
@ -107,10 +107,12 @@ struct SQueryNode {
|
||||||
typedef SVCreateTbReq STbCfg;
|
typedef SVCreateTbReq STbCfg;
|
||||||
typedef SVCreateTSmaReq SSmaCfg;
|
typedef SVCreateTSmaReq SSmaCfg;
|
||||||
|
|
||||||
SMTbCursor *metaOpenTbCursor(void *pVnode);
|
SMTbCursor* metaOpenTbCursor(void* pVnode);
|
||||||
void metaCloseTbCursor(SMTbCursor *pTbCur);
|
void metaCloseTbCursor(SMTbCursor* pTbCur);
|
||||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType);
|
void metaPauseTbCursor(SMTbCursor* pTbCur);
|
||||||
int32_t metaTbCursorPrev(SMTbCursor *pTbCur, ETableType jumpTableType);
|
void metaResumeTbCursor(SMTbCursor* pTbCur, int8_t first);
|
||||||
|
int32_t metaTbCursorNext(SMTbCursor* pTbCur, ETableType jumpTableType);
|
||||||
|
int32_t metaTbCursorPrev(SMTbCursor* pTbCur, ETableType jumpTableType);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -146,6 +148,7 @@ int metaAlterSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* p
|
||||||
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq, SArray* tbUidList);
|
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq, SArray* tbUidList);
|
||||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq, STableMetaRsp** pMetaRsp);
|
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq, STableMetaRsp** pMetaRsp);
|
||||||
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids, int64_t* tbUid);
|
int metaDropTable(SMeta* pMeta, int64_t version, SVDropTbReq* pReq, SArray* tbUids, int64_t* tbUid);
|
||||||
|
int32_t metaTrimTables(SMeta* pMeta);
|
||||||
int metaTtlDropTable(SMeta* pMeta, int64_t ttl, SArray* tbUids);
|
int metaTtlDropTable(SMeta* pMeta, int64_t ttl, SArray* tbUids);
|
||||||
int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp* pMetaRsp);
|
int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp* pMetaRsp);
|
||||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock);
|
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock);
|
||||||
|
@ -154,8 +157,8 @@ int32_t metaGetTbTSchemaEx(SMeta* pMeta, tb_uid_t suid, tb_uid_t uid, in
|
||||||
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
|
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
|
||||||
int metaAlterCache(SMeta* pMeta, int32_t nPage);
|
int metaAlterCache(SMeta* pMeta, int32_t nPage);
|
||||||
|
|
||||||
int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid);
|
int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid);
|
||||||
int32_t metaTbGroupCacheClear(SMeta *pMeta, uint64_t suid);
|
int32_t metaTbGroupCacheClear(SMeta* pMeta, uint64_t suid);
|
||||||
|
|
||||||
int metaAddIndexToSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
int metaAddIndexToSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
||||||
int metaDropIndexFromSTable(SMeta* pMeta, int64_t version, SDropIndexReq* pReq);
|
int metaDropIndexFromSTable(SMeta* pMeta, int64_t version, SDropIndexReq* pReq);
|
||||||
|
@ -175,7 +178,7 @@ void* metaGetIdx(SMeta* pMeta);
|
||||||
void* metaGetIvtIdx(SMeta* pMeta);
|
void* metaGetIvtIdx(SMeta* pMeta);
|
||||||
int metaTtlSmaller(SMeta* pMeta, uint64_t time, SArray* uidList);
|
int metaTtlSmaller(SMeta* pMeta, uint64_t time, SArray* uidList);
|
||||||
|
|
||||||
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags);
|
void metaReaderInit(SMetaReader* pReader, SMeta* pMeta, int32_t flags);
|
||||||
|
|
||||||
int32_t metaCreateTSma(SMeta* pMeta, int64_t version, SSmaCfg* pCfg);
|
int32_t metaCreateTSma(SMeta* pMeta, int64_t version, SSmaCfg* pCfg);
|
||||||
int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid);
|
int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid);
|
||||||
|
@ -492,7 +495,6 @@ struct SCompactInfo {
|
||||||
|
|
||||||
void initStorageAPI(SStorageAPI* pAPI);
|
void initStorageAPI(SStorageAPI* pAPI);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
#include "osMemory.h"
|
#include "osMemory.h"
|
||||||
#include "tencode.h"
|
#include "tencode.h"
|
||||||
|
|
||||||
void _metaReaderInit(SMetaReader* pReader, void* pVnode, int32_t flags, SStoreMeta* pAPI) {
|
void _metaReaderInit(SMetaReader *pReader, void *pVnode, int32_t flags, SStoreMeta *pAPI) {
|
||||||
SMeta* pMeta = ((SVnode*)pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
metaReaderInit(pReader, pMeta, flags);
|
metaReaderInit(pReader, pMeta, flags);
|
||||||
pReader->pAPI = pAPI;
|
pReader->pAPI = pAPI;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ _err:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool metaIsTableExist(void *pVnode, tb_uid_t uid) {
|
bool metaIsTableExist(void *pVnode, tb_uid_t uid) {
|
||||||
SVnode* pVnodeObj = pVnode;
|
SVnode *pVnodeObj = pVnode;
|
||||||
metaRLock(pVnodeObj->pMeta); // query uid.idx
|
metaRLock(pVnodeObj->pMeta); // query uid.idx
|
||||||
|
|
||||||
if (tdbTbGet(pVnodeObj->pMeta->pUidIdx, &uid, sizeof(uid), NULL, NULL) < 0) {
|
if (tdbTbGet(pVnodeObj->pMeta->pUidIdx, &uid, sizeof(uid), NULL, NULL) < 0) {
|
||||||
|
@ -143,7 +143,7 @@ tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) {
|
||||||
int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) {
|
int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
SMetaReader mr = {0};
|
SMetaReader mr = {0};
|
||||||
metaReaderInit(&mr, ((SVnode*)pVnode)->pMeta, 0);
|
metaReaderInit(&mr, ((SVnode *)pVnode)->pMeta, 0);
|
||||||
code = metaReaderGetTableEntryByUid(&mr, uid);
|
code = metaReaderGetTableEntryByUid(&mr, uid);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
metaReaderClear(&mr);
|
metaReaderClear(&mr);
|
||||||
|
@ -179,7 +179,7 @@ int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) {
|
||||||
SMetaReader *pReader = &mr;
|
SMetaReader *pReader = &mr;
|
||||||
|
|
||||||
// query name.idx
|
// query name.idx
|
||||||
if (tdbTbGet(((SMeta*)pReader->pMeta)->pNameIdx, tbName, strlen(tbName) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
|
if (tdbTbGet(((SMeta *)pReader->pMeta)->pNameIdx, tbName, strlen(tbName) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
|
||||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||||
metaReaderClear(&mr);
|
metaReaderClear(&mr);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -195,7 +195,7 @@ int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) {
|
||||||
int metaGetTableTypeByName(void *pVnode, char *tbName, ETableType *tbType) {
|
int metaGetTableTypeByName(void *pVnode, char *tbName, ETableType *tbType) {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
SMetaReader mr = {0};
|
SMetaReader mr = {0};
|
||||||
metaReaderInit(&mr, ((SVnode*)pVnode)->pMeta, 0);
|
metaReaderInit(&mr, ((SVnode *)pVnode)->pMeta, 0);
|
||||||
|
|
||||||
code = metaGetTableEntryByName(&mr, tbName);
|
code = metaGetTableEntryByName(&mr, tbName);
|
||||||
if (code == 0) *tbType = mr.me.type;
|
if (code == 0) *tbType = mr.me.type;
|
||||||
|
@ -221,12 +221,13 @@ SMTbCursor *metaOpenTbCursor(void *pVnode) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVnode* pVnodeObj = pVnode;
|
SVnode *pVnodeObj = pVnode;
|
||||||
metaReaderInit(&pTbCur->mr, pVnodeObj->pMeta, 0);
|
// metaReaderInit(&pTbCur->mr, pVnodeObj->pMeta, 0);
|
||||||
|
|
||||||
tdbTbcOpen(pVnodeObj->pMeta->pUidIdx, (TBC **)&pTbCur->pDbc, NULL);
|
// tdbTbcMoveToFirst((TBC *)pTbCur->pDbc);
|
||||||
|
pTbCur->pMeta = pVnodeObj->pMeta;
|
||||||
tdbTbcMoveToFirst((TBC *)pTbCur->pDbc);
|
pTbCur->paused = 1;
|
||||||
|
metaResumeTbCursor(pTbCur, 1);
|
||||||
return pTbCur;
|
return pTbCur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,14 +235,45 @@ void metaCloseTbCursor(SMTbCursor *pTbCur) {
|
||||||
if (pTbCur) {
|
if (pTbCur) {
|
||||||
tdbFree(pTbCur->pKey);
|
tdbFree(pTbCur->pKey);
|
||||||
tdbFree(pTbCur->pVal);
|
tdbFree(pTbCur->pVal);
|
||||||
metaReaderClear(&pTbCur->mr);
|
if (!pTbCur->paused) {
|
||||||
if (pTbCur->pDbc) {
|
metaReaderClear(&pTbCur->mr);
|
||||||
tdbTbcClose((TBC *)pTbCur->pDbc);
|
if (pTbCur->pDbc) {
|
||||||
|
tdbTbcClose((TBC *)pTbCur->pDbc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
taosMemoryFree(pTbCur);
|
taosMemoryFree(pTbCur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void metaPauseTbCursor(SMTbCursor *pTbCur) {
|
||||||
|
if (!pTbCur->paused) {
|
||||||
|
metaReaderClear(&pTbCur->mr);
|
||||||
|
tdbTbcClose((TBC *)pTbCur->pDbc);
|
||||||
|
pTbCur->paused = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void metaResumeTbCursor(SMTbCursor *pTbCur, int8_t first) {
|
||||||
|
if (pTbCur->paused) {
|
||||||
|
metaReaderInit(&pTbCur->mr, pTbCur->pMeta, 0);
|
||||||
|
|
||||||
|
tdbTbcOpen(((SMeta *)pTbCur->pMeta)->pUidIdx, (TBC **)&pTbCur->pDbc, NULL);
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
tdbTbcMoveToFirst((TBC *)pTbCur->pDbc);
|
||||||
|
} else {
|
||||||
|
int c = 0;
|
||||||
|
tdbTbcMoveTo(pTbCur->pDbc, pTbCur->pKey, pTbCur->kLen, &c);
|
||||||
|
if (c < 0) {
|
||||||
|
tdbTbcMoveToPrev(pTbCur->pDbc);
|
||||||
|
} else {
|
||||||
|
tdbTbcMoveToNext(pTbCur->pDbc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pTbCur->paused = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
||||||
int ret;
|
int ret;
|
||||||
void *pBuf;
|
void *pBuf;
|
||||||
|
@ -974,7 +1006,7 @@ typedef struct {
|
||||||
} SIdxCursor;
|
} SIdxCursor;
|
||||||
|
|
||||||
int32_t metaFilterCreateTime(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
int32_t metaFilterCreateTime(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
||||||
SMeta *pMeta = ((SVnode*)pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
SMetaFltParam *param = arg;
|
SMetaFltParam *param = arg;
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
@ -1034,7 +1066,7 @@ END:
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t metaFilterTableName(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
int32_t metaFilterTableName(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
||||||
SMeta *pMeta = ((SVnode*)pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
SMetaFltParam *param = arg;
|
SMetaFltParam *param = arg;
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
@ -1101,7 +1133,7 @@ END:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int32_t metaFilterTtl(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
int32_t metaFilterTtl(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
||||||
SMeta *pMeta = ((SVnode*)pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
SMetaFltParam *param = arg;
|
SMetaFltParam *param = arg;
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
@ -1132,7 +1164,7 @@ END:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int32_t metaFilterTableIds(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
int32_t metaFilterTableIds(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
||||||
SMeta *pMeta = ((SVnode*)pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
SMetaFltParam *param = arg;
|
SMetaFltParam *param = arg;
|
||||||
|
|
||||||
SMetaEntry oStbEntry = {0};
|
SMetaEntry oStbEntry = {0};
|
||||||
|
@ -1318,7 +1350,7 @@ static int32_t metaGetTableTagByUid(SMeta *pMeta, int64_t suid, int64_t uid, voi
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t metaGetTableTagsByUids(void *pVnode, int64_t suid, SArray *uidList) {
|
int32_t metaGetTableTagsByUids(void *pVnode, int64_t suid, SArray *uidList) {
|
||||||
SMeta* pMeta = ((SVnode*) pVnode)->pMeta;
|
SMeta *pMeta = ((SVnode *)pVnode)->pMeta;
|
||||||
const int32_t LIMIT = 128;
|
const int32_t LIMIT = 128;
|
||||||
|
|
||||||
int32_t isLock = false;
|
int32_t isLock = false;
|
||||||
|
@ -1350,8 +1382,8 @@ int32_t metaGetTableTagsByUids(void *pVnode, int64_t suid, SArray *uidList) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t metaGetTableTags(void* pVnode, uint64_t suid, SArray *pUidTagInfo) {
|
int32_t metaGetTableTags(void *pVnode, uint64_t suid, SArray *pUidTagInfo) {
|
||||||
SMCtbCursor *pCur = metaOpenCtbCursor(((SVnode*)pVnode)->pMeta, suid, 1);
|
SMCtbCursor *pCur = metaOpenCtbCursor(((SVnode *)pVnode)->pMeta, suid, 1);
|
||||||
|
|
||||||
// If len > 0 means there already have uids, and we only want the
|
// If len > 0 means there already have uids, and we only want the
|
||||||
// tags of the specified tables, of which uid in the uid list. Otherwise, all table tags are retrieved and kept
|
// tags of the specified tables, of which uid in the uid list. Otherwise, all table tags are retrieved and kept
|
||||||
|
@ -1456,11 +1488,11 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t metaGetStbStats(void *pVnode, int64_t uid, int64_t* numOfTables) {
|
int32_t metaGetStbStats(void *pVnode, int64_t uid, int64_t *numOfTables) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
*numOfTables = 0;
|
*numOfTables = 0;
|
||||||
|
|
||||||
SVnode* pVnodeObj = pVnode;
|
SVnode *pVnodeObj = pVnode;
|
||||||
metaRLock(pVnodeObj->pMeta);
|
metaRLock(pVnodeObj->pMeta);
|
||||||
|
|
||||||
// fast path: search cache
|
// fast path: search cache
|
||||||
|
|
|
@ -838,22 +838,101 @@ int metaDropTable(SMeta *pMeta, int64_t version, SVDropTbReq *pReq, SArray *tbUi
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void metaDropTables(SMeta *pMeta, SArray *tbUids) {
|
||||||
|
metaWLock(pMeta);
|
||||||
|
for (int i = 0; i < TARRAY_SIZE(tbUids); ++i) {
|
||||||
|
tb_uid_t uid = *(tb_uid_t *)taosArrayGet(tbUids, i);
|
||||||
|
metaDropTableByUid(pMeta, uid, NULL);
|
||||||
|
metaDebug("batch drop table:%" PRId64, uid);
|
||||||
|
}
|
||||||
|
metaULock(pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
|
||||||
|
int32_t code = 0;
|
||||||
|
// 1, tranverse table's
|
||||||
|
// 2, validate table name using vnodeValidateTableHash
|
||||||
|
// 3, push invalidated table's uid into uidList
|
||||||
|
|
||||||
|
TBC *pCur;
|
||||||
|
code = tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
|
||||||
|
if (code < 0) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tdbTbcMoveToFirst(pCur);
|
||||||
|
if (code) {
|
||||||
|
tdbTbcClose(pCur);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pData = NULL, *pKey = NULL;
|
||||||
|
int nData = 0, nKey = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int32_t ret = tdbTbcNext(pCur, &pKey, &nKey, &pData, &nData);
|
||||||
|
if (ret < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMetaEntry me = {0};
|
||||||
|
SDecoder dc = {0};
|
||||||
|
tDecoderInit(&dc, pData, nData);
|
||||||
|
metaDecodeEntry(&dc, &me);
|
||||||
|
|
||||||
|
if (me.type != TSDB_SUPER_TABLE) {
|
||||||
|
char tbFName[TSDB_TABLE_FNAME_LEN + 1];
|
||||||
|
snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name);
|
||||||
|
tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
|
||||||
|
int32_t ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
|
||||||
|
if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) {
|
||||||
|
taosArrayPush(uidList, &me.uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tDecoderClear(&dc);
|
||||||
|
}
|
||||||
|
tdbFree(pData);
|
||||||
|
tdbFree(pKey);
|
||||||
|
tdbTbcClose(pCur);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t metaTrimTables(SMeta *pMeta) {
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
SArray *tbUids = taosArrayInit(8, sizeof(int64_t));
|
||||||
|
if (tbUids == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = metaFilterTableByHash(pMeta, tbUids);
|
||||||
|
if (code != 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (TARRAY_SIZE(tbUids) == 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
metaInfo("vgId:%d, trim %ld tables", TD_VID(pMeta->pVnode), taosArrayGetSize(tbUids));
|
||||||
|
metaDropTables(pMeta, tbUids);
|
||||||
|
|
||||||
|
end:
|
||||||
|
taosArrayDestroy(tbUids);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int metaTtlDropTable(SMeta *pMeta, int64_t ttl, SArray *tbUids) {
|
int metaTtlDropTable(SMeta *pMeta, int64_t ttl, SArray *tbUids) {
|
||||||
int ret = metaTtlSmaller(pMeta, ttl, tbUids);
|
int ret = metaTtlSmaller(pMeta, ttl, tbUids);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (taosArrayGetSize(tbUids) == 0) {
|
if (TARRAY_SIZE(tbUids) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
metaWLock(pMeta);
|
metaDropTables(pMeta, tbUids);
|
||||||
for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
|
|
||||||
tb_uid_t *uid = (tb_uid_t *)taosArrayGet(tbUids, i);
|
|
||||||
metaDropTableByUid(pMeta, *uid, NULL);
|
|
||||||
metaDebug("ttl drop table:%" PRId64, *uid);
|
|
||||||
}
|
|
||||||
metaULock(pMeta);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,7 +1078,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
|
||||||
|
|
||||||
metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1);
|
metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1);
|
||||||
metaUidCacheClear(pMeta, e.ctbEntry.suid);
|
metaUidCacheClear(pMeta, e.ctbEntry.suid);
|
||||||
metaTbGroupCacheClear(pMeta, e.ctbEntry.suid);
|
metaTbGroupCacheClear(pMeta, e.ctbEntry.suid);
|
||||||
} else if (e.type == TSDB_NORMAL_TABLE) {
|
} else if (e.type == TSDB_NORMAL_TABLE) {
|
||||||
// drop schema.db (todo)
|
// drop schema.db (todo)
|
||||||
|
|
||||||
|
@ -1011,7 +1090,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
|
||||||
|
|
||||||
metaStatsCacheDrop(pMeta, uid);
|
metaStatsCacheDrop(pMeta, uid);
|
||||||
metaUidCacheClear(pMeta, uid);
|
metaUidCacheClear(pMeta, uid);
|
||||||
metaTbGroupCacheClear(pMeta, uid);
|
metaTbGroupCacheClear(pMeta, uid);
|
||||||
--pMeta->pVnode->config.vndStats.numOfSTables;
|
--pMeta->pVnode->config.vndStats.numOfSTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1432,7 +1511,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
|
||||||
((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn);
|
((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn);
|
||||||
|
|
||||||
metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid);
|
metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid);
|
||||||
metaTbGroupCacheClear(pMeta, ctbEntry.ctbEntry.suid);
|
metaTbGroupCacheClear(pMeta, ctbEntry.ctbEntry.suid);
|
||||||
|
|
||||||
metaULock(pMeta);
|
metaULock(pMeta);
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ void tqCleanUp() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyTqHandle(void* data) {
|
void tqDestroyTqHandle(void* data) {
|
||||||
STqHandle* pData = (STqHandle*)data;
|
STqHandle* pData = (STqHandle*)data;
|
||||||
qDestroyTask(pData->execHandle.task);
|
qDestroyTask(pData->execHandle.task);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ STQ* tqOpen(const char* path, SVnode* pVnode) {
|
||||||
pTq->walLogLastVer = pVnode->pWal->vers.lastVer;
|
pTq->walLogLastVer = pVnode->pWal->vers.lastVer;
|
||||||
|
|
||||||
pTq->pHandle = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
pTq->pHandle = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||||
taosHashSetFreeFp(pTq->pHandle, destroyTqHandle);
|
taosHashSetFreeFp(pTq->pHandle, tqDestroyTqHandle);
|
||||||
|
|
||||||
taosInitRWLatch(&pTq->lock);
|
taosInitRWLatch(&pTq->lock);
|
||||||
pTq->pPushMgr = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
|
pTq->pPushMgr = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
|
||||||
|
@ -243,8 +243,8 @@ int32_t tqPushDataRsp(STqHandle* pHandle, int32_t vgId) {
|
||||||
tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP, sver,
|
tqDoSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP, sver,
|
||||||
ever);
|
ever);
|
||||||
|
|
||||||
char buf1[80] = {0};
|
char buf1[TSDB_OFFSET_LEN] = {0};
|
||||||
char buf2[80] = {0};
|
char buf2[TSDB_OFFSET_LEN] = {0};
|
||||||
tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset);
|
tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset);
|
||||||
tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset);
|
tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset);
|
||||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s", vgId,
|
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s", vgId,
|
||||||
|
@ -259,10 +259,10 @@ int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq*
|
||||||
|
|
||||||
tqDoSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type, sver, ever);
|
tqDoSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type, sver, ever);
|
||||||
|
|
||||||
char buf1[80] = {0};
|
char buf1[TSDB_OFFSET_LEN] = {0};
|
||||||
char buf2[80] = {0};
|
char buf2[TSDB_OFFSET_LEN] = {0};
|
||||||
tFormatOffset(buf1, 80, &pRsp->reqOffset);
|
tFormatOffset(buf1, TSDB_OFFSET_LEN, &pRsp->reqOffset);
|
||||||
tFormatOffset(buf2, 80, &pRsp->rspOffset);
|
tFormatOffset(buf2, TSDB_OFFSET_LEN, &pRsp->rspOffset);
|
||||||
|
|
||||||
tqDebug("tmq poll vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64, vgId,
|
tqDebug("tmq poll vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64, vgId,
|
||||||
pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
||||||
|
@ -510,8 +510,8 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
pHandle->epoch = reqEpoch;
|
pHandle->epoch = reqEpoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[80];
|
char buf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(buf, 80, &reqOffset);
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &reqOffset);
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 " (epoch %d), subkey %s, recv poll req vgId:%d, req:%s, reqId:0x%" PRIx64,
|
tqDebug("tmq poll: consumer:0x%" PRIx64 " (epoch %d), subkey %s, recv poll req vgId:%d, req:%s, reqId:0x%" PRIx64,
|
||||||
consumerId, req.epoch, pHandle->subKey, vgId, buf, req.reqId);
|
consumerId, req.epoch, pHandle->subKey, vgId, buf, req.reqId);
|
||||||
|
|
||||||
|
@ -588,7 +588,7 @@ int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
} else {
|
} else {
|
||||||
dataRsp.rspOffset.version = currentVer; // return current consume offset value
|
dataRsp.rspOffset.version = currentVer; // return current consume offset value
|
||||||
}
|
}
|
||||||
} else if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) {
|
} else if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEST) {
|
||||||
dataRsp.rspOffset.version = sver; // not consume yet, set the earliest position
|
dataRsp.rspOffset.version = sver; // not consume yet, set the earliest position
|
||||||
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
||||||
dataRsp.rspOffset.version = ever;
|
dataRsp.rspOffset.version = ever;
|
||||||
|
@ -690,13 +690,17 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SVnode* pVnode = pTq->pVnode;
|
tqDebug("vgId:%d, tq process sub req:%s, Id:0x%" PRIx64 " -> Id:0x%" PRIx64, pTq->pVnode->config.vgId, req.subKey,
|
||||||
int32_t vgId = TD_VID(pVnode);
|
|
||||||
|
|
||||||
tqDebug("vgId:%d, tq process sub req:%s, Id:0x%" PRIx64 " -> Id:0x%" PRIx64, pVnode->config.vgId, req.subKey,
|
|
||||||
req.oldConsumerId, req.newConsumerId);
|
req.oldConsumerId, req.newConsumerId);
|
||||||
|
|
||||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
STqHandle* pHandle = NULL;
|
||||||
|
while(1){
|
||||||
|
pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
||||||
|
if (pHandle || tqMetaGetHandle(pTq, req.subKey) < 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pHandle == NULL) {
|
if (pHandle == NULL) {
|
||||||
if (req.oldConsumerId != -1) {
|
if (req.oldConsumerId != -1) {
|
||||||
tqError("vgId:%d, build new consumer handle %s for consumer:0x%" PRIx64 ", but old consumerId:0x%" PRIx64,
|
tqError("vgId:%d, build new consumer handle %s for consumer:0x%" PRIx64 ", but old consumerId:0x%" PRIx64,
|
||||||
|
@ -707,86 +711,13 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
tqError("vgId:%d, tq invalid re-balance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
|
tqError("vgId:%d, tq invalid re-balance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
STqHandle handle = {0};
|
||||||
STqHandle tqHandle = {0};
|
ret = tqCreateHandle(pTq, &req, &handle);
|
||||||
pHandle = &tqHandle;
|
if(ret < 0){
|
||||||
|
tqDestroyTqHandle(&handle);
|
||||||
memcpy(pHandle->subKey, req.subKey, TSDB_SUBSCRIBE_KEY_LEN);
|
|
||||||
pHandle->consumerId = req.newConsumerId;
|
|
||||||
pHandle->epoch = -1;
|
|
||||||
|
|
||||||
pHandle->execHandle.subType = req.subType;
|
|
||||||
pHandle->fetchMeta = req.withMeta;
|
|
||||||
|
|
||||||
// TODO version should be assigned and refed during preprocess
|
|
||||||
SWalRef* pRef = walRefCommittedVer(pVnode->pWal);
|
|
||||||
if (pRef == NULL) {
|
|
||||||
ret = -1;
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
ret = tqMetaSaveHandle(pTq, req.subKey, &handle);
|
||||||
int64_t ver = pRef->refVer;
|
|
||||||
pHandle->pRef = pRef;
|
|
||||||
|
|
||||||
SReadHandle handle = {.vnode = pVnode, .initTableReader = true, .initTqReader = true, .version = ver};
|
|
||||||
initStorageAPI(&handle.api);
|
|
||||||
|
|
||||||
pHandle->snapshotVer = ver;
|
|
||||||
|
|
||||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
|
||||||
pHandle->execHandle.execCol.qmsg = taosStrdup(req.qmsg);
|
|
||||||
|
|
||||||
pHandle->execHandle.task = qCreateQueueExecTaskInfo(pHandle->execHandle.execCol.qmsg, &handle, vgId,
|
|
||||||
&pHandle->execHandle.numOfCols, req.newConsumerId);
|
|
||||||
void* scanner = NULL;
|
|
||||||
qExtractStreamScanner(pHandle->execHandle.task, &scanner);
|
|
||||||
pHandle->execHandle.pTqReader = qExtractReaderFromStreamScanner(scanner);
|
|
||||||
} else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__DB) {
|
|
||||||
pHandle->pWalReader = walOpenReader(pVnode->pWal, NULL);
|
|
||||||
pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
|
||||||
|
|
||||||
pHandle->execHandle.execDb.pFilterOutTbUid =
|
|
||||||
taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
|
||||||
buildSnapContext(handle.vnode, handle.version, 0, pHandle->execHandle.subType, pHandle->fetchMeta,
|
|
||||||
(SSnapContext**)(&handle.sContext));
|
|
||||||
|
|
||||||
pHandle->execHandle.task = qCreateQueueExecTaskInfo(NULL, &handle, vgId, NULL, req.newConsumerId);
|
|
||||||
} else if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
|
||||||
pHandle->pWalReader = walOpenReader(pVnode->pWal, NULL);
|
|
||||||
pHandle->execHandle.execTb.suid = req.suid;
|
|
||||||
pHandle->execHandle.execTb.qmsg = taosStrdup(req.qmsg);
|
|
||||||
|
|
||||||
if (strcmp(pHandle->execHandle.execTb.qmsg, "") != 0) {
|
|
||||||
if (nodesStringToNode(pHandle->execHandle.execTb.qmsg, &pHandle->execHandle.execTb.node) != 0) {
|
|
||||||
tqError("nodesStringToNode error in sub stable, since %s, vgId:%d, subkey:%s consumer:0x%" PRIx64, terrstr(),
|
|
||||||
pVnode->config.vgId, req.subKey, pHandle->consumerId);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildSnapContext(handle.vnode, handle.version, req.suid, pHandle->execHandle.subType, pHandle->fetchMeta,
|
|
||||||
(SSnapContext**)(&handle.sContext));
|
|
||||||
pHandle->execHandle.task = qCreateQueueExecTaskInfo(NULL, &handle, vgId, NULL, req.newConsumerId);
|
|
||||||
|
|
||||||
SArray* tbUidList = NULL;
|
|
||||||
ret = qGetTableList(req.suid, pVnode, pHandle->execHandle.execTb.node, &tbUidList, pHandle->execHandle.task);
|
|
||||||
if (ret != TDB_CODE_SUCCESS) {
|
|
||||||
tqError("qGetTableList error:%d vgId:%d, subkey:%s consumer:0x%" PRIx64, ret, pVnode->config.vgId, req.subKey,
|
|
||||||
pHandle->consumerId);
|
|
||||||
taosArrayDestroy(tbUidList);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
tqDebug("tq try to get ctb for stb subscribe, vgId:%d, subkey:%s consumer:0x%" PRIx64 " suid:%" PRId64,
|
|
||||||
pVnode->config.vgId, req.subKey, pHandle->consumerId, req.suid);
|
|
||||||
pHandle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
|
||||||
tqReaderSetTbUidList(pHandle->execHandle.pTqReader, tbUidList, NULL);
|
|
||||||
taosArrayDestroy(tbUidList);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosHashPut(pTq->pHandle, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
|
|
||||||
tqDebug("try to persist handle %s consumer:0x%" PRIx64, req.subKey, pHandle->consumerId);
|
|
||||||
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
|
||||||
goto end;
|
|
||||||
} else {
|
} else {
|
||||||
taosWLockLatch(&pTq->lock);
|
taosWLockLatch(&pTq->lock);
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,9 @@ int32_t tqMetaOpen(STQ* pTq) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tqMetaRestoreHandle(pTq) < 0) {
|
// if (tqMetaRestoreHandle(pTq) < 0) {
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (tqMetaRestoreCheckInfo(pTq) < 0) {
|
if (tqMetaRestoreCheckInfo(pTq) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -274,6 +274,120 @@ int32_t tqMetaDeleteHandle(STQ* pTq, const char* key) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int buildHandle(STQ* pTq, STqHandle* handle){
|
||||||
|
SVnode* pVnode = pTq->pVnode;
|
||||||
|
int32_t vgId = TD_VID(pVnode);
|
||||||
|
|
||||||
|
handle->pRef = walOpenRef(pVnode->pWal);
|
||||||
|
if (handle->pRef == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
walSetRefVer(handle->pRef, handle->snapshotVer);
|
||||||
|
|
||||||
|
SReadHandle reader = {
|
||||||
|
.vnode = pVnode,
|
||||||
|
.initTableReader = true,
|
||||||
|
.initTqReader = true,
|
||||||
|
.version = handle->snapshotVer,
|
||||||
|
};
|
||||||
|
|
||||||
|
initStorageAPI(&reader.api);
|
||||||
|
|
||||||
|
if (handle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||||
|
handle->execHandle.task =
|
||||||
|
qCreateQueueExecTaskInfo(handle->execHandle.execCol.qmsg, &reader, vgId, &handle->execHandle.numOfCols, handle->consumerId);
|
||||||
|
if (handle->execHandle.task == NULL) {
|
||||||
|
tqError("cannot create exec task for %s", handle->subKey);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void* scanner = NULL;
|
||||||
|
qExtractStreamScanner(handle->execHandle.task, &scanner);
|
||||||
|
if (scanner == NULL) {
|
||||||
|
tqError("cannot extract stream scanner for %s", handle->subKey);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
handle->execHandle.pTqReader = qExtractReaderFromStreamScanner(scanner);
|
||||||
|
if (handle->execHandle.pTqReader == NULL) {
|
||||||
|
tqError("cannot extract exec reader for %s", handle->subKey);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (handle->execHandle.subType == TOPIC_SUB_TYPE__DB) {
|
||||||
|
handle->pWalReader = walOpenReader(pVnode->pWal, NULL);
|
||||||
|
handle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
||||||
|
|
||||||
|
buildSnapContext(reader.vnode, reader.version, 0, handle->execHandle.subType, handle->fetchMeta,
|
||||||
|
(SSnapContext**)(&reader.sContext));
|
||||||
|
handle->execHandle.task = qCreateQueueExecTaskInfo(NULL, &reader, vgId, NULL, handle->consumerId);
|
||||||
|
} else if (handle->execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
||||||
|
handle->pWalReader = walOpenReader(pVnode->pWal, NULL);
|
||||||
|
|
||||||
|
if(handle->execHandle.execTb.qmsg != NULL && strcmp(handle->execHandle.execTb.qmsg, "") != 0) {
|
||||||
|
if (nodesStringToNode(handle->execHandle.execTb.qmsg, &handle->execHandle.execTb.node) != 0) {
|
||||||
|
tqError("nodesStringToNode error in sub stable, since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildSnapContext(reader.vnode, reader.version, handle->execHandle.execTb.suid, handle->execHandle.subType,
|
||||||
|
handle->fetchMeta, (SSnapContext**)(&reader.sContext));
|
||||||
|
handle->execHandle.task = qCreateQueueExecTaskInfo(NULL, &reader, vgId, NULL, handle->consumerId);
|
||||||
|
|
||||||
|
SArray* tbUidList = NULL;
|
||||||
|
int ret = qGetTableList(handle->execHandle.execTb.suid, pVnode, handle->execHandle.execTb.node, &tbUidList, handle->execHandle.task);
|
||||||
|
if(ret != TDB_CODE_SUCCESS) {
|
||||||
|
tqError("qGetTableList error:%d handle %s consumer:0x%" PRIx64, ret, handle->subKey, handle->consumerId);
|
||||||
|
taosArrayDestroy(tbUidList);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tqDebug("vgId:%d, tq try to get ctb for stb subscribe, suid:%" PRId64, pVnode->config.vgId, handle->execHandle.execTb.suid);
|
||||||
|
handle->execHandle.pTqReader = tqReaderOpen(pVnode);
|
||||||
|
tqReaderSetTbUidList(handle->execHandle.pTqReader, tbUidList, NULL);
|
||||||
|
taosArrayDestroy(tbUidList);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int restoreHandle(STQ* pTq, void* pVal, int vLen, STqHandle* handle){
|
||||||
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
|
SDecoder decoder;
|
||||||
|
tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
|
||||||
|
tDecodeSTqHandle(&decoder, handle);
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
|
||||||
|
if(buildHandle(pTq, handle) < 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tqDebug("tq restore %s consumer %" PRId64 " vgId:%d", handle->subKey, handle->consumerId, vgId);
|
||||||
|
return taosHashPut(pTq->pHandle, handle->subKey, strlen(handle->subKey), handle, sizeof(STqHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tqCreateHandle(STQ* pTq, SMqRebVgReq* req, STqHandle* handle){
|
||||||
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
|
|
||||||
|
memcpy(handle->subKey, req->subKey, TSDB_SUBSCRIBE_KEY_LEN);
|
||||||
|
handle->consumerId = req->newConsumerId;
|
||||||
|
handle->epoch = -1;
|
||||||
|
|
||||||
|
handle->execHandle.subType = req->subType;
|
||||||
|
handle->fetchMeta = req->withMeta;
|
||||||
|
if(req->subType == TOPIC_SUB_TYPE__COLUMN){
|
||||||
|
handle->execHandle.execCol.qmsg = taosStrdup(req->qmsg);
|
||||||
|
}else if(req->subType == TOPIC_SUB_TYPE__DB){
|
||||||
|
handle->execHandle.execDb.pFilterOutTbUid =
|
||||||
|
taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||||
|
}else if(req->subType == TOPIC_SUB_TYPE__TABLE){
|
||||||
|
handle->execHandle.execTb.suid = req->suid;
|
||||||
|
handle->execHandle.execTb.qmsg = taosStrdup(req->qmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->snapshotVer = walGetLastVer(pTq->pVnode->pWal);
|
||||||
|
|
||||||
|
if(buildHandle(pTq, handle) < 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tqDebug("tq restore %s consumer %" PRId64 " vgId:%d", handle->subKey, handle->consumerId, vgId);
|
||||||
|
return taosHashPut(pTq->pHandle, handle->subKey, strlen(handle->subKey), handle, sizeof(STqHandle));
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tqMetaRestoreHandle(STQ* pTq) {
|
int32_t tqMetaRestoreHandle(STQ* pTq) {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
TBC* pCur = NULL;
|
TBC* pCur = NULL;
|
||||||
|
@ -281,97 +395,40 @@ int32_t tqMetaRestoreHandle(STQ* pTq) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
|
||||||
void* pKey = NULL;
|
void* pKey = NULL;
|
||||||
int kLen = 0;
|
int kLen = 0;
|
||||||
void* pVal = NULL;
|
void* pVal = NULL;
|
||||||
int vLen = 0;
|
int vLen = 0;
|
||||||
SDecoder decoder;
|
|
||||||
|
|
||||||
tdbTbcMoveToFirst(pCur);
|
tdbTbcMoveToFirst(pCur);
|
||||||
|
|
||||||
while (tdbTbcNext(pCur, &pKey, &kLen, &pVal, &vLen) == 0) {
|
while (tdbTbcNext(pCur, &pKey, &kLen, &pVal, &vLen) == 0) {
|
||||||
STqHandle handle = {0};
|
STqHandle handle = {0};
|
||||||
tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
|
code = restoreHandle(pTq, pVal, vLen, &handle);
|
||||||
tDecodeSTqHandle(&decoder, &handle);
|
if (code < 0){
|
||||||
tDecoderClear(&decoder);
|
tqDestroyTqHandle(&handle);
|
||||||
|
break;
|
||||||
handle.pRef = walOpenRef(pTq->pVnode->pWal);
|
|
||||||
if (handle.pRef == NULL) {
|
|
||||||
code = -1;
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
walSetRefVer(handle.pRef, handle.snapshotVer);
|
|
||||||
|
|
||||||
SReadHandle reader = {
|
|
||||||
.vnode = pTq->pVnode,
|
|
||||||
.initTableReader = true,
|
|
||||||
.initTqReader = true,
|
|
||||||
.version = handle.snapshotVer
|
|
||||||
};
|
|
||||||
|
|
||||||
initStorageAPI(&reader.api);
|
|
||||||
|
|
||||||
if (handle.execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
|
||||||
handle.execHandle.task =
|
|
||||||
qCreateQueueExecTaskInfo(handle.execHandle.execCol.qmsg, &reader, vgId, &handle.execHandle.numOfCols, 0);
|
|
||||||
if (handle.execHandle.task == NULL) {
|
|
||||||
tqError("cannot create exec task for %s", handle.subKey);
|
|
||||||
code = -1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
void* scanner = NULL;
|
|
||||||
qExtractStreamScanner(handle.execHandle.task, &scanner);
|
|
||||||
if (scanner == NULL) {
|
|
||||||
tqError("cannot extract stream scanner for %s", handle.subKey);
|
|
||||||
code = -1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
handle.execHandle.pTqReader = qExtractReaderFromStreamScanner(scanner);
|
|
||||||
if (handle.execHandle.pTqReader == NULL) {
|
|
||||||
tqError("cannot extract exec reader for %s", handle.subKey);
|
|
||||||
code = -1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
} else if (handle.execHandle.subType == TOPIC_SUB_TYPE__DB) {
|
|
||||||
handle.pWalReader = walOpenReader(pTq->pVnode->pWal, NULL);
|
|
||||||
handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
|
|
||||||
|
|
||||||
buildSnapContext(reader.vnode, reader.version, 0, handle.execHandle.subType, handle.fetchMeta,
|
|
||||||
(SSnapContext**)(&reader.sContext));
|
|
||||||
handle.execHandle.task = qCreateQueueExecTaskInfo(NULL, &reader, vgId, NULL, 0);
|
|
||||||
} else if (handle.execHandle.subType == TOPIC_SUB_TYPE__TABLE) {
|
|
||||||
handle.pWalReader = walOpenReader(pTq->pVnode->pWal, NULL);
|
|
||||||
|
|
||||||
if(handle.execHandle.execTb.qmsg != NULL && strcmp(handle.execHandle.execTb.qmsg, "") != 0) {
|
|
||||||
if (nodesStringToNode(handle.execHandle.execTb.qmsg, &handle.execHandle.execTb.node) != 0) {
|
|
||||||
tqError("nodesStringToNode error in sub stable, since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buildSnapContext(reader.vnode, reader.version, handle.execHandle.execTb.suid, handle.execHandle.subType,
|
|
||||||
handle.fetchMeta, (SSnapContext**)(&reader.sContext));
|
|
||||||
handle.execHandle.task = qCreateQueueExecTaskInfo(NULL, &reader, vgId, NULL, 0);
|
|
||||||
|
|
||||||
SArray* tbUidList = NULL;
|
|
||||||
int ret = qGetTableList(handle.execHandle.execTb.suid, pTq->pVnode, handle.execHandle.execTb.node, &tbUidList, handle.execHandle.task);
|
|
||||||
if(ret != TDB_CODE_SUCCESS) {
|
|
||||||
tqError("qGetTableList error:%d handle %s consumer:0x%" PRIx64, ret, handle.subKey, handle.consumerId);
|
|
||||||
taosArrayDestroy(tbUidList);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
tqDebug("vgId:%d, tq try to get ctb for stb subscribe, suid:%" PRId64, pTq->pVnode->config.vgId, handle.execHandle.execTb.suid);
|
|
||||||
handle.execHandle.pTqReader = tqReaderOpen(pTq->pVnode);
|
|
||||||
tqReaderSetTbUidList(handle.execHandle.pTqReader, tbUidList, NULL);
|
|
||||||
taosArrayDestroy(tbUidList);
|
|
||||||
}
|
|
||||||
tqDebug("tq restore %s consumer %" PRId64 " vgId:%d", handle.subKey, handle.consumerId, vgId);
|
|
||||||
taosHashPut(pTq->pHandle, pKey, kLen, &handle, sizeof(STqHandle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
tdbFree(pKey);
|
tdbFree(pKey);
|
||||||
tdbFree(pVal);
|
tdbFree(pVal);
|
||||||
tdbTbcClose(pCur);
|
tdbTbcClose(pCur);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tqMetaGetHandle(STQ* pTq, const char* key) {
|
||||||
|
void* pVal = NULL;
|
||||||
|
int vLen = 0;
|
||||||
|
|
||||||
|
if (tdbTbGet(pTq->pExecStore, key, (int)strlen(key), &pVal, &vLen) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
STqHandle handle = {0};
|
||||||
|
int code = restoreHandle(pTq, pVal, vLen, &handle);
|
||||||
|
if (code < 0){
|
||||||
|
tqDestroyTqHandle(&handle);
|
||||||
|
}
|
||||||
|
tdbFree(pVal);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
|
@ -298,10 +298,8 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d
|
||||||
if (res == TSDB_CODE_SUCCESS) {
|
if (res == TSDB_CODE_SUCCESS) {
|
||||||
memcpy(ctbName, pTableSinkInfo->tbName, strlen(pTableSinkInfo->tbName));
|
memcpy(ctbName, pTableSinkInfo->tbName, strlen(pTableSinkInfo->tbName));
|
||||||
} else {
|
} else {
|
||||||
char* tmp = buildCtbNameByGroupId(stbFullName, pDataBlock->info.id.groupId);
|
buildCtbNameByGroupIdImpl(stbFullName, pDataBlock->info.id.groupId, ctbName);
|
||||||
memcpy(ctbName, tmp, strlen(tmp));
|
memcpy(pTableSinkInfo->tbName, ctbName, strlen(ctbName));
|
||||||
memcpy(pTableSinkInfo->tbName, tmp, strlen(tmp));
|
|
||||||
taosMemoryFree(tmp);
|
|
||||||
tqDebug("vgId:%d, gropuId:%" PRIu64 " datablock table name is null", TD_VID(pVnode),
|
tqDebug("vgId:%d, gropuId:%" PRIu64 " datablock table name is null", TD_VID(pVnode),
|
||||||
pDataBlock->info.id.groupId);
|
pDataBlock->info.id.groupId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,15 +99,15 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
||||||
if (pOffset != NULL) {
|
if (pOffset != NULL) {
|
||||||
*pOffsetVal = pOffset->val;
|
*pOffsetVal = pOffset->val;
|
||||||
|
|
||||||
char formatBuf[80];
|
char formatBuf[TSDB_OFFSET_LEN];
|
||||||
tFormatOffset(formatBuf, 80, pOffsetVal);
|
tFormatOffset(formatBuf, TSDB_OFFSET_LEN, pOffsetVal);
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64
|
tqDebug("tmq poll: consumer:0x%" PRIx64
|
||||||
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue. reqId:0x%" PRIx64,
|
", subkey %s, vgId:%d, existed offset found, offset reset to %s and continue. reqId:0x%" PRIx64,
|
||||||
consumerId, pHandle->subKey, vgId, formatBuf, pRequest->reqId);
|
consumerId, pHandle->subKey, vgId, formatBuf, pRequest->reqId);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// no poll occurs in this vnode for this topic, let's seek to the right offset value.
|
// no poll occurs in this vnode for this topic, let's seek to the right offset value.
|
||||||
if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) {
|
if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEST) {
|
||||||
if (pRequest->useSnapshot) {
|
if (pRequest->useSnapshot) {
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey:%s, vgId:%d, (earliest) set offset to be snapshot",
|
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey:%s, vgId:%d, (earliest) set offset to be snapshot",
|
||||||
consumerId, pHandle->subKey, vgId);
|
consumerId, pHandle->subKey, vgId);
|
||||||
|
@ -188,7 +188,12 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
|
||||||
|
|
||||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId);
|
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId);
|
||||||
|
|
||||||
end :
|
end : {
|
||||||
|
char buf[TSDB_OFFSET_LEN] = {0};
|
||||||
|
tFormatOffset(buf, TSDB_OFFSET_LEN, &dataRsp.rspOffset);
|
||||||
|
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64
|
||||||
|
" code:%d",
|
||||||
|
consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
|
||||||
tDeleteMqDataRsp(&dataRsp);
|
tDeleteMqDataRsp(&dataRsp);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,7 +325,7 @@ int vnodeValidateTableHash(SVnode *pVnode, char *tableFName) {
|
||||||
|
|
||||||
if (hashValue < pVnode->config.hashBegin || hashValue > pVnode->config.hashEnd) {
|
if (hashValue < pVnode->config.hashBegin || hashValue > pVnode->config.hashEnd) {
|
||||||
terrno = TSDB_CODE_VND_HASH_MISMATCH;
|
terrno = TSDB_CODE_VND_HASH_MISMATCH;
|
||||||
return TSDB_CODE_VND_HASH_MISMATCH;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "storageapi.h"
|
|
||||||
#include "vnodeInt.h"
|
|
||||||
#include "tstreamUpdate.h"
|
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
|
#include "storageapi.h"
|
||||||
|
#include "tstreamUpdate.h"
|
||||||
|
#include "vnodeInt.h"
|
||||||
|
|
||||||
static void initTsdbReaderAPI(TsdReader* pReader);
|
static void initTsdbReaderAPI(TsdReader* pReader);
|
||||||
static void initMetadataAPI(SStoreMeta* pMeta);
|
static void initMetadataAPI(SStoreMeta* pMeta);
|
||||||
|
@ -56,10 +56,10 @@ void initTsdbReaderAPI(TsdReader* pReader) {
|
||||||
pReader->tsdReaderResetStatus = tsdbReaderReset;
|
pReader->tsdReaderResetStatus = tsdbReaderReset;
|
||||||
|
|
||||||
pReader->tsdReaderGetDataBlockDistInfo = tsdbGetFileBlocksDistInfo;
|
pReader->tsdReaderGetDataBlockDistInfo = tsdbGetFileBlocksDistInfo;
|
||||||
pReader->tsdReaderGetNumOfInMemRows = tsdbGetNumOfRowsInMemTable; // todo this function should be moved away
|
pReader->tsdReaderGetNumOfInMemRows = tsdbGetNumOfRowsInMemTable; // todo this function should be moved away
|
||||||
|
|
||||||
pReader->tsdSetQueryTableList = tsdbSetTableList;
|
pReader->tsdSetQueryTableList = tsdbSetTableList;
|
||||||
pReader->tsdSetReaderTaskId = (void (*)(void *, const char *))tsdbReaderSetId;
|
pReader->tsdSetReaderTaskId = (void (*)(void*, const char*))tsdbReaderSetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initMetadataAPI(SStoreMeta* pMeta) {
|
void initMetadataAPI(SStoreMeta* pMeta) {
|
||||||
|
@ -67,6 +67,8 @@ void initMetadataAPI(SStoreMeta* pMeta) {
|
||||||
|
|
||||||
pMeta->openTableMetaCursor = metaOpenTbCursor;
|
pMeta->openTableMetaCursor = metaOpenTbCursor;
|
||||||
pMeta->closeTableMetaCursor = metaCloseTbCursor;
|
pMeta->closeTableMetaCursor = metaCloseTbCursor;
|
||||||
|
pMeta->pauseTableMetaCursor = metaPauseTbCursor;
|
||||||
|
pMeta->resumeTableMetaCursor = metaResumeTbCursor;
|
||||||
pMeta->cursorNext = metaTbCursorNext;
|
pMeta->cursorNext = metaTbCursorNext;
|
||||||
pMeta->cursorPrev = metaTbCursorPrev;
|
pMeta->cursorPrev = metaTbCursorPrev;
|
||||||
|
|
||||||
|
@ -78,7 +80,7 @@ void initMetadataAPI(SStoreMeta* pMeta) {
|
||||||
pMeta->storeGetIndexInfo = vnodeGetIdx;
|
pMeta->storeGetIndexInfo = vnodeGetIdx;
|
||||||
pMeta->getInvertIndex = vnodeGetIvtIdx;
|
pMeta->getInvertIndex = vnodeGetIvtIdx;
|
||||||
|
|
||||||
pMeta->extractTagVal = (const void *(*)(const void *, int16_t, STagVal *))metaGetTableTagVal;
|
pMeta->extractTagVal = (const void* (*)(const void*, int16_t, STagVal*))metaGetTableTagVal;
|
||||||
pMeta->getTableTags = metaGetTableTags;
|
pMeta->getTableTags = metaGetTableTags;
|
||||||
pMeta->getTableTagsByUid = metaGetTableTagsByUids;
|
pMeta->getTableTagsByUid = metaGetTableTagsByUids;
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ void initMetadataAPI(SStoreMeta* pMeta) {
|
||||||
pMeta->getTableTypeByName = metaGetTableTypeByName;
|
pMeta->getTableTypeByName = metaGetTableTypeByName;
|
||||||
pMeta->getTableNameByUid = metaGetTableNameByUid;
|
pMeta->getTableNameByUid = metaGetTableNameByUid;
|
||||||
|
|
||||||
pMeta->getTableSchema = tsdbGetTableSchema; // todo refactor
|
pMeta->getTableSchema = tsdbGetTableSchema; // todo refactor
|
||||||
pMeta->storeGetTableList = vnodeGetTableList;
|
pMeta->storeGetTableList = vnodeGetTableList;
|
||||||
|
|
||||||
pMeta->getCachedTableList = metaGetCachedTableUidList;
|
pMeta->getCachedTableList = metaGetCachedTableUidList;
|
||||||
|
@ -106,7 +108,7 @@ void initTqAPI(SStoreTqReader* pTq) {
|
||||||
|
|
||||||
pTq->tqReaderNextBlockInWal = tqNextBlockInWal;
|
pTq->tqReaderNextBlockInWal = tqNextBlockInWal;
|
||||||
|
|
||||||
pTq->tqNextBlockImpl = tqNextBlockImpl;// todo remove it
|
pTq->tqNextBlockImpl = tqNextBlockImpl; // todo remove it
|
||||||
|
|
||||||
pTq->tqReaderAddTables = tqReaderAddTbUidList;
|
pTq->tqReaderAddTables = tqReaderAddTbUidList;
|
||||||
pTq->tqReaderSetQueryTableList = tqReaderSetTbUidList;
|
pTq->tqReaderSetQueryTableList = tqReaderSetTbUidList;
|
||||||
|
@ -116,10 +118,10 @@ void initTqAPI(SStoreTqReader* pTq) {
|
||||||
pTq->tqReaderIsQueriedTable = tqReaderIsQueriedTable;
|
pTq->tqReaderIsQueriedTable = tqReaderIsQueriedTable;
|
||||||
pTq->tqReaderCurrentBlockConsumed = tqCurrentBlockConsumed;
|
pTq->tqReaderCurrentBlockConsumed = tqCurrentBlockConsumed;
|
||||||
|
|
||||||
pTq->tqReaderGetWalReader = tqGetWalReader; // todo remove it
|
pTq->tqReaderGetWalReader = tqGetWalReader; // todo remove it
|
||||||
pTq->tqReaderRetrieveTaosXBlock = tqRetrieveTaosxBlock; // todo remove it
|
pTq->tqReaderRetrieveTaosXBlock = tqRetrieveTaosxBlock; // todo remove it
|
||||||
|
|
||||||
pTq->tqReaderSetSubmitMsg = tqReaderSetSubmitMsg; // todo remove it
|
pTq->tqReaderSetSubmitMsg = tqReaderSetSubmitMsg; // todo remove it
|
||||||
pTq->tqGetResultBlock = tqGetResultBlock;
|
pTq->tqGetResultBlock = tqGetResultBlock;
|
||||||
|
|
||||||
pTq->tqReaderNextBlockFilterOut = tqNextDataBlockFilterOut;
|
pTq->tqReaderNextBlockFilterOut = tqNextDataBlockFilterOut;
|
||||||
|
@ -199,7 +201,7 @@ void initStateStoreAPI(SStateStore* pStore) {
|
||||||
pStore->streamStateClose = streamStateClose;
|
pStore->streamStateClose = streamStateClose;
|
||||||
pStore->streamStateBegin = streamStateBegin;
|
pStore->streamStateBegin = streamStateBegin;
|
||||||
pStore->streamStateCommit = streamStateCommit;
|
pStore->streamStateCommit = streamStateCommit;
|
||||||
pStore->streamStateDestroy= streamStateDestroy;
|
pStore->streamStateDestroy = streamStateDestroy;
|
||||||
pStore->streamStateDeleteCheckPoint = streamStateDeleteCheckPoint;
|
pStore->streamStateDeleteCheckPoint = streamStateDeleteCheckPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,4 +241,4 @@ void initSnapshotFn(SStoreSnapshotFn* pSnapshot) {
|
||||||
pSnapshot->destroySnapshot = destroySnapContext;
|
pSnapshot->destroySnapshot = destroySnapContext;
|
||||||
pSnapshot->getMetaTableInfoFromSnapshot = getMetaTableInfoFromSnapshot;
|
pSnapshot->getMetaTableInfoFromSnapshot = getMetaTableInfoFromSnapshot;
|
||||||
pSnapshot->getTableInfoFromSnapshot = getTableInfoFromSnapshot;
|
pSnapshot->getTableInfoFromSnapshot = getTableInfoFromSnapshot;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,12 @@ int32_t vnodeAlterReplica(const char *path, SAlterVnodeReplicaReq *pReq, STfs *p
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t vnodeVgroupIdLen(int32_t vgId) {
|
||||||
|
char tmp[TSDB_FILENAME_LEN];
|
||||||
|
sprintf(tmp, "%d", vgId);
|
||||||
|
return strlen(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t srcVgId, int32_t dstVgId, STfs *pTfs) {
|
int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t srcVgId, int32_t dstVgId, STfs *pTfs) {
|
||||||
int32_t ret = tfsRename(pTfs, srcPath, dstPath);
|
int32_t ret = tfsRename(pTfs, srcPath, dstPath);
|
||||||
if (ret != 0) return ret;
|
if (ret != 0) return ret;
|
||||||
|
@ -154,8 +160,7 @@ int32_t vnodeRenameVgroupId(const char *srcPath, const char *dstPath, int32_t sr
|
||||||
|
|
||||||
int32_t tsdbFileVgId = atoi(tsdbFilePrefixPos + 6);
|
int32_t tsdbFileVgId = atoi(tsdbFilePrefixPos + 6);
|
||||||
if (tsdbFileVgId == srcVgId) {
|
if (tsdbFileVgId == srcVgId) {
|
||||||
char *tsdbFileSurfixPos = strstr(tsdbFilePrefixPos, "f");
|
char *tsdbFileSurfixPos = tsdbFilePrefixPos + 6 + vnodeVgroupIdLen(srcVgId);
|
||||||
if (tsdbFileSurfixPos == NULL) continue;
|
|
||||||
|
|
||||||
tsdbFilePrefixPos[6] = 0;
|
tsdbFilePrefixPos[6] = 0;
|
||||||
snprintf(newRname, TSDB_FILENAME_LEN, "%s%d%s", oldRname, dstVgId, tsdbFileSurfixPos);
|
snprintf(newRname, TSDB_FILENAME_LEN, "%s%d%s", oldRname, dstVgId, tsdbFileSurfixPos);
|
||||||
|
|
|
@ -1484,6 +1484,7 @@ static int32_t vnodeConsolidateAlterHashRange(SVnode *pVnode, int64_t ver) {
|
||||||
pVnode->config.hashBegin, pVnode->config.hashEnd, ver);
|
pVnode->config.hashBegin, pVnode->config.hashEnd, ver);
|
||||||
|
|
||||||
// TODO: trim meta of tables from TDB per hash range [pVnode->config.hashBegin, pVnode->config.hashEnd]
|
// TODO: trim meta of tables from TDB per hash range [pVnode->config.hashBegin, pVnode->config.hashEnd]
|
||||||
|
code = metaTrimTables(pVnode->pMeta);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,7 +431,7 @@ static int32_t vnodeSyncApplyMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsm
|
||||||
return tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, pMsg);
|
return tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, pMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
static int32_t vnodeSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
||||||
if (pMsg->code == 0) {
|
if (pMsg->code == 0) {
|
||||||
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
||||||
}
|
}
|
||||||
|
@ -451,7 +451,7 @@ static int32_t vnodeSyncCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFs
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeSyncPreCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
static int32_t vnodeSyncPreCommitMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
||||||
if (pMeta->isWeak == 1) {
|
if (pMeta->isWeak == 1) {
|
||||||
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
return vnodeSyncApplyMsg(pFsm, pMsg, pMeta);
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ static SyncIndex vnodeSyncAppliedIndex(const SSyncFSM *pFSM) {
|
||||||
return atomic_load_64(&pVnode->state.applied);
|
return atomic_load_64(&pVnode->state.applied);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vnodeSyncRollBackMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, const SFsmCbMeta *pMeta) {
|
static void vnodeSyncRollBackMsg(const SSyncFSM *pFsm, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
||||||
SVnode *pVnode = pFsm->data;
|
SVnode *pVnode = pFsm->data;
|
||||||
vTrace("vgId:%d, rollback-cb is excuted, fsm:%p, index:%" PRId64 ", weak:%d, code:%d, state:%d %s, type:%s",
|
vTrace("vgId:%d, rollback-cb is excuted, fsm:%p, index:%" PRId64 ", weak:%d, code:%d, state:%d %s, type:%s",
|
||||||
pVnode->config.vgId, pFsm, pMeta->index, pMeta->isWeak, pMeta->code, pMeta->state, syncStr(pMeta->state),
|
pVnode->config.vgId, pFsm, pMeta->index, pMeta->isWeak, pMeta->code, pMeta->state, syncStr(pMeta->state),
|
||||||
|
|
|
@ -1593,10 +1593,13 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
|
||||||
char dbFName[TSDB_DB_FNAME_LEN];
|
char dbFName[TSDB_DB_FNAME_LEN];
|
||||||
tNameGetFullDbName(&pReq->tbName, dbFName);
|
tNameGetFullDbName(&pReq->tbName, dbFName);
|
||||||
|
|
||||||
|
// since that we add read/write previliges when create db, there is no need to check createdDbs
|
||||||
|
#if 0
|
||||||
if (pInfo->createdDbs && taosHashGet(pInfo->createdDbs, dbFName, strlen(dbFName))) {
|
if (pInfo->createdDbs && taosHashGet(pInfo->createdDbs, dbFName, strlen(dbFName))) {
|
||||||
pRes->pass = true;
|
pRes->pass = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (pReq->type) {
|
switch (pReq->type) {
|
||||||
case AUTH_TYPE_READ: {
|
case AUTH_TYPE_READ: {
|
||||||
|
|
|
@ -647,6 +647,8 @@ uint64_t calcGroupId(char* pData, int32_t len) {
|
||||||
// NOTE: only extract the initial 8 bytes of the final MD5 digest
|
// NOTE: only extract the initial 8 bytes of the final MD5 digest
|
||||||
uint64_t id = 0;
|
uint64_t id = 0;
|
||||||
memcpy(&id, context.digest, sizeof(uint64_t));
|
memcpy(&id, context.digest, sizeof(uint64_t));
|
||||||
|
if (0 == id)
|
||||||
|
memcpy(&id, context.digest + 8, sizeof(uint64_t));
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,11 @@ void destroyMergeJoinOperator(void* param) {
|
||||||
}
|
}
|
||||||
nodesDestroyNode(pJoinOperator->pCondAfterMerge);
|
nodesDestroyNode(pJoinOperator->pCondAfterMerge);
|
||||||
|
|
||||||
|
taosArrayDestroy(pJoinOperator->rowCtx.leftCreatedBlocks);
|
||||||
|
taosArrayDestroy(pJoinOperator->rowCtx.rightCreatedBlocks);
|
||||||
|
taosArrayDestroy(pJoinOperator->rowCtx.leftRowLocations);
|
||||||
|
taosArrayDestroy(pJoinOperator->rowCtx.rightRowLocations);
|
||||||
|
|
||||||
pJoinOperator->pRes = blockDataDestroy(pJoinOperator->pRes);
|
pJoinOperator->pRes = blockDataDestroy(pJoinOperator->pRes);
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,8 @@ static int32_t doIngroupLimitOffset(SLimitInfo* pLimitInfo, uint64_t groupId, SS
|
||||||
} else {
|
} else {
|
||||||
if (limitReached && (pLimitInfo->slimit.limit >= 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
if (limitReached && (pLimitInfo->slimit.limit >= 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
||||||
setOperatorCompleted(pOperator);
|
setOperatorCompleted(pOperator);
|
||||||
|
} else if (limitReached && groupId == 0) {
|
||||||
|
setOperatorCompleted(pOperator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
|
||||||
colDataAssign(pDst, pSrc, p->info.rows, &pDataBlock->info);
|
colDataAssign(pDst, pSrc, p->info.rows, &pDataBlock->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pDataBlock->info.dataLoad = 1;
|
||||||
pDataBlock->info.rows = p->info.rows;
|
pDataBlock->info.rows = p->info.rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "tdatablock.h"
|
#include "tdatablock.h"
|
||||||
#include "tmsg.h"
|
#include "tmsg.h"
|
||||||
|
|
||||||
|
#include "index.h"
|
||||||
#include "operator.h"
|
#include "operator.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "querytask.h"
|
#include "querytask.h"
|
||||||
|
@ -32,7 +33,6 @@
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
#include "ttypes.h"
|
#include "ttypes.h"
|
||||||
#include "index.h"
|
|
||||||
|
|
||||||
typedef int (*__optSysFilter)(void* a, void* b, int16_t dtype);
|
typedef int (*__optSysFilter)(void* a, void* b, int16_t dtype);
|
||||||
typedef int32_t (*__sys_filte)(void* pMeta, SNode* cond, SArray* result);
|
typedef int32_t (*__sys_filte)(void* pMeta, SNode* cond, SArray* result);
|
||||||
|
@ -540,12 +540,12 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
int32_t restore = pInfo->restore;
|
int32_t restore = pInfo->restore;
|
||||||
pInfo->restore = false;
|
pInfo->restore = false;
|
||||||
|
|
||||||
while (restore || ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0)) {
|
while (restore || ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0)) {
|
||||||
if (restore) {
|
if (restore) {
|
||||||
restore = false;
|
restore = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
|
|
||||||
|
@ -626,8 +626,8 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||||
|
|
||||||
SSysTableScanInfo* pInfo = pOperator->info;
|
SSysTableScanInfo* pInfo = pOperator->info;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -1100,8 +1100,8 @@ int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
|
static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||||
|
|
||||||
SSysTableScanInfo* pInfo = pOperator->info;
|
SSysTableScanInfo* pInfo = pOperator->info;
|
||||||
|
|
||||||
|
@ -1288,11 +1288,16 @@ static SSDataBlock* sysTableBuildUserTablesByUids(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
|
static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||||
|
int8_t firstMetaCursor = 0;
|
||||||
|
|
||||||
SSysTableScanInfo* pInfo = pOperator->info;
|
SSysTableScanInfo* pInfo = pOperator->info;
|
||||||
if (pInfo->pCur == NULL) {
|
if (pInfo->pCur == NULL) {
|
||||||
pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
|
pInfo->pCur = pAPI->metaFn.openTableMetaCursor(pInfo->readHandle.vnode);
|
||||||
|
firstMetaCursor = 1;
|
||||||
|
}
|
||||||
|
if (!firstMetaCursor) {
|
||||||
|
pAPI->metaFn.resumeTableMetaCursor(pInfo->pCur, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
blockDataCleanup(pInfo->pRes);
|
blockDataCleanup(pInfo->pRes);
|
||||||
|
@ -1436,12 +1441,14 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
|
||||||
numOfRows = 0;
|
numOfRows = 0;
|
||||||
|
|
||||||
if (pInfo->pRes->info.rows > 0) {
|
if (pInfo->pRes->info.rows > 0) {
|
||||||
|
pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfRows > 0) {
|
if (numOfRows > 0) {
|
||||||
|
pAPI->metaFn.pauseTableMetaCursor(pInfo->pCur);
|
||||||
p->info.rows = numOfRows;
|
p->info.rows = numOfRows;
|
||||||
pInfo->pRes->info.rows = numOfRows;
|
pInfo->pRes->info.rows = numOfRows;
|
||||||
|
|
||||||
|
@ -1485,7 +1492,8 @@ static SSDataBlock* sysTableScanUserTables(SOperatorInfo* pOperator) {
|
||||||
} else {
|
} else {
|
||||||
if (pInfo->showRewrite == false) {
|
if (pInfo->showRewrite == false) {
|
||||||
if (pCondition != NULL && pInfo->pIdx == NULL) {
|
if (pCondition != NULL && pInfo->pIdx == NULL) {
|
||||||
SSTabFltArg arg = {.pMeta = pInfo->readHandle.vnode, .pVnode = pInfo->readHandle.vnode, .pAPI = &pTaskInfo->storageAPI};
|
SSTabFltArg arg = {
|
||||||
|
.pMeta = pInfo->readHandle.vnode, .pVnode = pInfo->readHandle.vnode, .pAPI = &pTaskInfo->storageAPI};
|
||||||
|
|
||||||
SSysTableIndex* idx = taosMemoryMalloc(sizeof(SSysTableIndex));
|
SSysTableIndex* idx = taosMemoryMalloc(sizeof(SSysTableIndex));
|
||||||
idx->init = 0;
|
idx->init = 0;
|
||||||
|
@ -1827,7 +1835,7 @@ void destroySysScanOperator(void* param) {
|
||||||
pInfo->pIdx = NULL;
|
pInfo->pIdx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pInfo->pSchema) {
|
if (pInfo->pSchema) {
|
||||||
taosHashCleanup(pInfo->pSchema);
|
taosHashCleanup(pInfo->pSchema);
|
||||||
pInfo->pSchema = NULL;
|
pInfo->pSchema = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2144,7 +2152,7 @@ static int32_t optSysTabFilte(void* arg, SNode* cond, SArray* result) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doGetTableRowSize(SReadHandle *pHandle, uint64_t uid, int32_t* rowLen, const char* idstr) {
|
static int32_t doGetTableRowSize(SReadHandle* pHandle, uint64_t uid, int32_t* rowLen, const char* idstr) {
|
||||||
*rowLen = 0;
|
*rowLen = 0;
|
||||||
|
|
||||||
SMetaReader mr = {0};
|
SMetaReader mr = {0};
|
||||||
|
@ -2194,17 +2202,17 @@ static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
SBlockDistInfo* pBlockScanInfo = pOperator->info;
|
SBlockDistInfo* pBlockScanInfo = pOperator->info;
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
|
||||||
|
|
||||||
STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
|
STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
|
||||||
int32_t code = doGetTableRowSize(&pBlockScanInfo->readHandle, pBlockScanInfo->uid,
|
int32_t code = doGetTableRowSize(&pBlockScanInfo->readHandle, pBlockScanInfo->uid, (int32_t*)&blockDistInfo.rowSize,
|
||||||
(int32_t*)&blockDistInfo.rowSize, GET_TASKID(pTaskInfo));
|
GET_TASKID(pTaskInfo));
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
T_LONG_JMP(pTaskInfo->env, code);
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
pAPI->tsdReader.tsdReaderGetDataBlockDistInfo(pBlockScanInfo->pHandle, &blockDistInfo);
|
pAPI->tsdReader.tsdReaderGetDataBlockDistInfo(pBlockScanInfo->pHandle, &blockDistInfo);
|
||||||
blockDistInfo.numOfInmemRows = (int32_t) pAPI->tsdReader.tsdReaderGetNumOfInMemRows(pBlockScanInfo->pHandle);
|
blockDistInfo.numOfInmemRows = (int32_t)pAPI->tsdReader.tsdReaderGetNumOfInMemRows(pBlockScanInfo->pHandle);
|
||||||
|
|
||||||
SSDataBlock* pBlock = pBlockScanInfo->pResBlock;
|
SSDataBlock* pBlock = pBlockScanInfo->pResBlock;
|
||||||
|
|
||||||
|
@ -2289,7 +2297,8 @@ SOperatorInfo* createDataBlockInfoScanOperator(SReadHandle* readHandle, SBlockDi
|
||||||
size_t num = tableListGetSize(pTableListInfo);
|
size_t num = tableListGetSize(pTableListInfo);
|
||||||
void* pList = tableListGetInfo(pTableListInfo, 0);
|
void* pList = tableListGetInfo(pTableListInfo, 0);
|
||||||
|
|
||||||
code = readHandle->api.tsdReader.tsdReaderOpen(readHandle->vnode, &cond, pList, num, pInfo->pResBlock, (void**)&pInfo->pHandle, pTaskInfo->id.str, false, NULL);
|
code = readHandle->api.tsdReader.tsdReaderOpen(readHandle->vnode, &cond, pList, num, pInfo->pResBlock,
|
||||||
|
(void**)&pInfo->pHandle, pTaskInfo->id.str, false, NULL);
|
||||||
cleanupQueryTableDataCond(&cond);
|
cleanupQueryTableDataCond(&cond);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
goto _error;
|
goto _error;
|
||||||
|
@ -2316,4 +2325,4 @@ _error:
|
||||||
taosMemoryFreeClear(pInfo);
|
taosMemoryFreeClear(pInfo);
|
||||||
taosMemoryFreeClear(pOperator);
|
taosMemoryFreeClear(pOperator);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,8 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
|
||||||
|
|
||||||
|
|
||||||
// output the result
|
// output the result
|
||||||
bool hasInterp = true;
|
int32_t fillColIndex = 0;
|
||||||
|
bool hasInterp = true;
|
||||||
for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) {
|
for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) {
|
||||||
SExprInfo* pExprInfo = &pExprSup->pExprInfo[j];
|
SExprInfo* pExprInfo = &pExprSup->pExprInfo[j];
|
||||||
|
|
||||||
|
@ -307,7 +308,7 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
|
||||||
|
|
||||||
case TSDB_FILL_SET_VALUE:
|
case TSDB_FILL_SET_VALUE:
|
||||||
case TSDB_FILL_SET_VALUE_F: {
|
case TSDB_FILL_SET_VALUE_F: {
|
||||||
SVariant* pVar = &pSliceInfo->pFillColInfo[j].fillVal;
|
SVariant* pVar = &pSliceInfo->pFillColInfo[fillColIndex].fillVal;
|
||||||
|
|
||||||
if (pDst->info.type == TSDB_DATA_TYPE_FLOAT) {
|
if (pDst->info.type == TSDB_DATA_TYPE_FLOAT) {
|
||||||
float v = 0;
|
float v = 0;
|
||||||
|
@ -342,6 +343,8 @@ static bool genInterpolationResult(STimeSliceOperatorInfo* pSliceInfo, SExprSupp
|
||||||
}
|
}
|
||||||
colDataSetVal(pDst, rows, (char*)&v, false);
|
colDataSetVal(pDst, rows, (char*)&v, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++fillColIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2345,7 +2345,7 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* p
|
||||||
}
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup);
|
bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup);
|
||||||
if ((pInfo->ignoreExpiredData && isClosed) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) {
|
if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_OP(pInfo)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) {
|
||||||
startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin);
|
startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin);
|
||||||
if (startPos < 0) {
|
if (startPos < 0) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -101,7 +101,11 @@ static int32_t sortComparCleanup(SMsortComparParam* cmpParam) {
|
||||||
for (int32_t i = 0; i < cmpParam->numOfSources; ++i) {
|
for (int32_t i = 0; i < cmpParam->numOfSources; ++i) {
|
||||||
SSortSource* pSource = cmpParam->pSources[i];
|
SSortSource* pSource = cmpParam->pSources[i];
|
||||||
blockDataDestroy(pSource->src.pBlock);
|
blockDataDestroy(pSource->src.pBlock);
|
||||||
|
if (pSource->pageIdList) {
|
||||||
|
taosArrayDestroy(pSource->pageIdList);
|
||||||
|
}
|
||||||
taosMemoryFreeClear(pSource);
|
taosMemoryFreeClear(pSource);
|
||||||
|
cmpParam->pSources[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmpParam->numOfSources = 0;
|
cmpParam->numOfSources = 0;
|
||||||
|
@ -123,9 +127,11 @@ void tsortClearOrderdSource(SArray* pOrderedSource, int64_t *fetchUs, int64_t *f
|
||||||
// release pageIdList
|
// release pageIdList
|
||||||
if ((*pSource)->pageIdList) {
|
if ((*pSource)->pageIdList) {
|
||||||
taosArrayDestroy((*pSource)->pageIdList);
|
taosArrayDestroy((*pSource)->pageIdList);
|
||||||
|
(*pSource)->pageIdList = NULL;
|
||||||
}
|
}
|
||||||
if ((*pSource)->param && !(*pSource)->onlyRef) {
|
if ((*pSource)->param && !(*pSource)->onlyRef) {
|
||||||
taosMemoryFree((*pSource)->param);
|
taosMemoryFree((*pSource)->param);
|
||||||
|
(*pSource)->param = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*pSource)->onlyRef && (*pSource)->src.pBlock) {
|
if (!(*pSource)->onlyRef && (*pSource)->src.pBlock) {
|
||||||
|
|
|
@ -344,7 +344,7 @@ static int32_t getFuncInfo(SFunctionNode* pFunc) {
|
||||||
return fmGetFuncInfo(pFunc, msg, sizeof(msg));
|
return fmGetFuncInfo(pFunc, msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
static SFunctionNode* createFunction(const char* pName, SNodeList* pParameterList) {
|
SFunctionNode* createFunction(const char* pName, SNodeList* pParameterList) {
|
||||||
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||||
if (NULL == pFunc) {
|
if (NULL == pFunc) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -669,7 +669,7 @@ static int32_t selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
||||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||||
COPY_SCALAR_FIELD(precision);
|
COPY_SCALAR_FIELD(precision);
|
||||||
COPY_SCALAR_FIELD(isEmptyResult);
|
COPY_SCALAR_FIELD(isEmptyResult);
|
||||||
COPY_SCALAR_FIELD(isTimeLineResult);
|
COPY_SCALAR_FIELD(timeLineResMode);
|
||||||
COPY_SCALAR_FIELD(hasAggFuncs);
|
COPY_SCALAR_FIELD(hasAggFuncs);
|
||||||
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "querynodes.h"
|
||||||
|
|
||||||
|
#define MATCH_SCALAR_FIELD(fldname) \
|
||||||
|
do { \
|
||||||
|
if (p->fldname != pSub->fldname) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MATCH_STRING(a, b) (((a) != NULL && (b) != NULL) ? (strcmp((a), (b)) == 0) : (a) == (b))
|
||||||
|
|
||||||
|
#define MATCH_VARDATA(a, b) \
|
||||||
|
(((a) != NULL && (b) != NULL) \
|
||||||
|
? (varDataLen((a)) == varDataLen((b)) && memcmp(varDataVal((a)), varDataVal((b)), varDataLen((a))) == 0) \
|
||||||
|
: (a) == (b))
|
||||||
|
|
||||||
|
#define MATCH_STRING_FIELD(fldname) \
|
||||||
|
do { \
|
||||||
|
if (!MATCH_STRING(p->fldname, pSub->fldname)) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MATCH_VARDATA_FIELD(fldname) \
|
||||||
|
do { \
|
||||||
|
if (!MATCH_VARDATA(p->fldname, pSub->fldname)) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MATCH_OBJECT_FIELD(fldname, matchFunc) \
|
||||||
|
do { \
|
||||||
|
if (!matchFunc(p->fldname, pSub->fldname)) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MATCH_NODE_FIELD(fldname) \
|
||||||
|
do { \
|
||||||
|
if (!nodesMatchNode(pSub->fldname, p->fldname)) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MATCH_NODE_LIST_FIELD(fldname) \
|
||||||
|
do { \
|
||||||
|
if (!nodesListMatch(p->fldname, pSub->fldname)) return false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
bool nodesListMatchExists(const SNodeList* pList, const SNode* pTarget) {
|
||||||
|
if (NULL == pList || NULL == pTarget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SNode* node = NULL;
|
||||||
|
bool exists = false;
|
||||||
|
FOREACH(node, pList) {
|
||||||
|
if (nodesMatchNode(node, pTarget)) {
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nodesListMatch(const SNodeList* pList, const SNodeList* pSubList) {
|
||||||
|
if (pList == pSubList) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == pList || NULL == pSubList) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pList->length != pSubList->length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* node = NULL;
|
||||||
|
bool match = true;
|
||||||
|
FOREACH(node, pList) {
|
||||||
|
if (!nodesListMatchExists(pSubList, node)) {
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool columnNodeMatch(const SColumnNode* pSub, const SColumnNode* p) {
|
||||||
|
if (0 == strcmp(p->colName, pSub->node.aliasName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool valueNodeMatch(const SValueNode* pSub, const SValueNode* p) {
|
||||||
|
return nodesEqualNode((SNode*)pSub, (SNode*)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operatorNodeMatch(const SOperatorNode* pSub, const SOperatorNode* p) {
|
||||||
|
MATCH_SCALAR_FIELD(opType);
|
||||||
|
MATCH_NODE_FIELD(pLeft);
|
||||||
|
MATCH_NODE_FIELD(pRight);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool logicConditionNodeMatch(const SLogicConditionNode* pSub, const SLogicConditionNode* p) {
|
||||||
|
MATCH_SCALAR_FIELD(condType);
|
||||||
|
MATCH_NODE_LIST_FIELD(pParameterList);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool functionNodeMatch(const SFunctionNode* pSub, const SFunctionNode* p) {
|
||||||
|
MATCH_SCALAR_FIELD(funcId);
|
||||||
|
MATCH_STRING_FIELD(functionName);
|
||||||
|
MATCH_NODE_LIST_FIELD(pParameterList);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool whenThenNodeMatch(const SWhenThenNode* pSub, const SWhenThenNode* p) {
|
||||||
|
MATCH_NODE_FIELD(pWhen);
|
||||||
|
MATCH_NODE_FIELD(pThen);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool caseWhenNodeMatch(const SCaseWhenNode* pSub, const SCaseWhenNode* p) {
|
||||||
|
MATCH_NODE_FIELD(pCase);
|
||||||
|
MATCH_NODE_FIELD(pElse);
|
||||||
|
MATCH_NODE_LIST_FIELD(pWhenThenList);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nodesMatchNode(const SNode* pSub, const SNode* p) {
|
||||||
|
if (pSub == p) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == pSub || NULL == p) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeType(pSub) != nodeType(p)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (nodeType(p)) {
|
||||||
|
case QUERY_NODE_COLUMN:
|
||||||
|
return columnNodeMatch((const SColumnNode*)pSub, (const SColumnNode*)p);
|
||||||
|
case QUERY_NODE_VALUE:
|
||||||
|
return valueNodeMatch((const SValueNode*)pSub, (const SValueNode*)p);
|
||||||
|
case QUERY_NODE_OPERATOR:
|
||||||
|
return operatorNodeMatch((const SOperatorNode*)pSub, (const SOperatorNode*)p);
|
||||||
|
case QUERY_NODE_LOGIC_CONDITION:
|
||||||
|
return logicConditionNodeMatch((const SLogicConditionNode*)pSub, (const SLogicConditionNode*)p);
|
||||||
|
case QUERY_NODE_FUNCTION:
|
||||||
|
return functionNodeMatch((const SFunctionNode*)pSub, (const SFunctionNode*)p);
|
||||||
|
case QUERY_NODE_WHEN_THEN:
|
||||||
|
return whenThenNodeMatch((const SWhenThenNode*)pSub, (const SWhenThenNode*)p);
|
||||||
|
case QUERY_NODE_CASE_WHEN:
|
||||||
|
return caseWhenNodeMatch((const SCaseWhenNode*)pSub, (const SCaseWhenNode*)p);
|
||||||
|
case QUERY_NODE_REAL_TABLE:
|
||||||
|
case QUERY_NODE_TEMP_TABLE:
|
||||||
|
case QUERY_NODE_JOIN_TABLE:
|
||||||
|
case QUERY_NODE_GROUPING_SET:
|
||||||
|
case QUERY_NODE_ORDER_BY_EXPR:
|
||||||
|
case QUERY_NODE_LIMIT:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -953,6 +953,8 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
nodesDestroyNode(pStmt->pQuery);
|
nodesDestroyNode(pStmt->pQuery);
|
||||||
nodesDestroyList(pStmt->pTags);
|
nodesDestroyList(pStmt->pTags);
|
||||||
nodesDestroyNode(pStmt->pSubtable);
|
nodesDestroyNode(pStmt->pSubtable);
|
||||||
|
tFreeSCMCreateStreamReq(pStmt->pReq);
|
||||||
|
taosMemoryFreeClear(pStmt->pReq);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_DROP_STREAM_STMT: // no pointer field
|
case QUERY_NODE_DROP_STREAM_STMT: // no pointer field
|
||||||
|
@ -1052,6 +1054,7 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
case QUERY_NODE_QUERY: {
|
case QUERY_NODE_QUERY: {
|
||||||
SQuery* pQuery = (SQuery*)pNode;
|
SQuery* pQuery = (SQuery*)pNode;
|
||||||
nodesDestroyNode(pQuery->pRoot);
|
nodesDestroyNode(pQuery->pRoot);
|
||||||
|
nodesDestroyNode(pQuery->pPostRoot);
|
||||||
taosMemoryFreeClear(pQuery->pResSchema);
|
taosMemoryFreeClear(pQuery->pResSchema);
|
||||||
if (NULL != pQuery->pCmdMsg) {
|
if (NULL != pQuery->pCmdMsg) {
|
||||||
taosMemoryFreeClear(pQuery->pCmdMsg->pMsg);
|
taosMemoryFreeClear(pQuery->pCmdMsg->pMsg);
|
||||||
|
@ -1953,9 +1956,9 @@ static uint32_t funcNodeHash(const char* pKey, uint32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t funcNodeEqual(const void* pLeft, const void* pRight, size_t len) {
|
static int32_t funcNodeEqual(const void* pLeft, const void* pRight, size_t len) {
|
||||||
if (0 != strcmp((*(const SExprNode**)pLeft)->aliasName, (*(const SExprNode**)pRight)->aliasName)) {
|
// if (0 != strcmp((*(const SExprNode**)pLeft)->aliasName, (*(const SExprNode**)pRight)->aliasName)) {
|
||||||
return 1;
|
// return 1;
|
||||||
}
|
// }
|
||||||
return nodesEqualNode(*(const SNode**)pLeft, *(const SNode**)pRight) ? 0 : 1;
|
return nodesEqualNode(*(const SNode**)pLeft, *(const SNode**)pRight) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode
|
||||||
SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues);
|
SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues);
|
||||||
SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode);
|
SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode);
|
||||||
SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd);
|
SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd);
|
||||||
|
SNode* createInterpTimePoint(SAstCreateContext* pCxt, SNode* pPoint);
|
||||||
SNode* createWhenThenNode(SAstCreateContext* pCxt, SNode* pWhen, SNode* pThen);
|
SNode* createWhenThenNode(SAstCreateContext* pCxt, SNode* pWhen, SNode* pThen);
|
||||||
SNode* createCaseWhenNode(SAstCreateContext* pCxt, SNode* pCase, SNodeList* pWhenThenList, SNode* pElse);
|
SNode* createCaseWhenNode(SAstCreateContext* pCxt, SNode* pCase, SNodeList* pWhenThenList, SNode* pElse);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ int32_t authenticate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache*
|
||||||
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache* pMetaCache);
|
int32_t translate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache* pMetaCache);
|
||||||
int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema);
|
int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema);
|
||||||
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery);
|
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery);
|
||||||
|
int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
|
||||||
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
||||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||||
|
int32_t getTableTypeFromTableNode(SNode *pTable);
|
||||||
|
|
||||||
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
||||||
int32_t getVnodeSysTableTargetName(int32_t acctId, SNode* pWhere, SName* pName);
|
int32_t getVnodeSysTableTargetName(int32_t acctId, SNode* pWhere, SName* pName);
|
||||||
|
|
|
@ -1095,6 +1095,8 @@ having_clause_opt(A) ::= HAVING search_condition(B).
|
||||||
range_opt(A) ::= . { A = NULL; }
|
range_opt(A) ::= . { A = NULL; }
|
||||||
range_opt(A) ::=
|
range_opt(A) ::=
|
||||||
RANGE NK_LP expr_or_subquery(B) NK_COMMA expr_or_subquery(C) NK_RP. { A = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
RANGE NK_LP expr_or_subquery(B) NK_COMMA expr_or_subquery(C) NK_RP. { A = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||||
|
range_opt(A) ::=
|
||||||
|
RANGE NK_LP expr_or_subquery(B) NK_RP. { A = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||||
|
|
||||||
every_opt(A) ::= . { A = NULL; }
|
every_opt(A) ::= . { A = NULL; }
|
||||||
every_opt(A) ::= EVERY NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
every_opt(A) ::= EVERY NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||||
|
|
|
@ -704,6 +704,11 @@ SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd
|
||||||
return createBetweenAnd(pCxt, createPrimaryKeyCol(pCxt, NULL), pStart, pEnd);
|
return createBetweenAnd(pCxt, createPrimaryKeyCol(pCxt, NULL), pStart, pEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createInterpTimePoint(SAstCreateContext* pCxt, SNode* pPoint) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
return createOperatorNode(pCxt, OP_TYPE_EQUAL, createPrimaryKeyCol(pCxt, NULL), pPoint);
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createWhenThenNode(SAstCreateContext* pCxt, SNode* pWhen, SNode* pThen) {
|
SNode* createWhenThenNode(SAstCreateContext* pCxt, SNode* pWhen, SNode* pThen) {
|
||||||
CHECK_PARSER_STATUS(pCxt);
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
SWhenThenNode* pWhenThen = (SWhenThenNode*)nodesMakeNode(QUERY_NODE_WHEN_THEN);
|
SWhenThenNode* pWhenThen = (SWhenThenNode*)nodesMakeNode(QUERY_NODE_WHEN_THEN);
|
||||||
|
|
|
@ -384,6 +384,10 @@ static int32_t collectMetaKeyFromCreateStream(SCollectMetaKeyCxt* pCxt, SCreateS
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = collectMetaKeyFromQuery(pCxt, pStmt->pQuery);
|
code = collectMetaKeyFromQuery(pCxt, pStmt->pQuery);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pStmt->pOptions->fillHistory) {
|
||||||
|
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||||
|
code = reserveDbCfgForLastRow(pCxt, pSelect->pFromTable);
|
||||||
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@ typedef struct STranslateContext {
|
||||||
bool createStream;
|
bool createStream;
|
||||||
bool stableQuery;
|
bool stableQuery;
|
||||||
bool showRewrite;
|
bool showRewrite;
|
||||||
|
SNode* pPrevRoot;
|
||||||
|
SNode* pPostRoot;
|
||||||
} STranslateContext;
|
} STranslateContext;
|
||||||
|
|
||||||
typedef struct SBuildTopicContext {
|
typedef struct SBuildTopicContext {
|
||||||
|
@ -276,6 +278,10 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = {
|
||||||
static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode);
|
static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode);
|
||||||
static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode);
|
static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode);
|
||||||
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal);
|
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal);
|
||||||
|
static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt);
|
||||||
|
static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery);
|
||||||
|
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery);
|
||||||
|
static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery);
|
||||||
|
|
||||||
static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; }
|
static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; }
|
||||||
|
|
||||||
|
@ -707,6 +713,10 @@ static bool isWindowPseudoColumnFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsWindowPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsWindowPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isInterpFunc(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsInterpFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
}
|
||||||
|
|
||||||
static bool isInterpPseudoColumnFunc(const SNode* pNode) {
|
static bool isInterpPseudoColumnFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsInterpPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsInterpPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
}
|
}
|
||||||
|
@ -758,18 +768,40 @@ static SNodeList* getProjectList(const SNode* pNode) {
|
||||||
|
|
||||||
static bool isTimeLineQuery(SNode* pStmt) {
|
static bool isTimeLineQuery(SNode* pStmt) {
|
||||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
return ((SSelectStmt*)pStmt)->isTimeLineResult;
|
return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineResMode) || (TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode);
|
||||||
|
} else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) {
|
||||||
|
return TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isGlobalTimeLineQuery(SNode* pStmt) {
|
static bool isGlobalTimeLineQuery(SNode* pStmt) {
|
||||||
if (!isTimeLineQuery(pStmt)) {
|
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||||
|
return TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode;
|
||||||
|
} else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) {
|
||||||
|
return TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode;
|
||||||
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)pStmt;
|
}
|
||||||
return NULL == pSelect->pPartitionByList || NULL != pSelect->pOrderByList;
|
|
||||||
|
static bool isTimeLineAlignedQuery(SNode* pStmt) {
|
||||||
|
SSelectStmt *pSelect = (SSelectStmt *)pStmt;
|
||||||
|
if (isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!isTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (QUERY_NODE_SELECT_STMT != nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SSelectStmt *pSub = (SSelectStmt *)((STempTableNode*)pSelect->pFromTable)->pSubquery;
|
||||||
|
if (nodesListMatch(pSelect->pPartitionByList, pSub->pPartitionByList)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPrimaryKeyImpl(SNode* pExpr) {
|
static bool isPrimaryKeyImpl(SNode* pExpr) {
|
||||||
|
@ -1595,7 +1627,7 @@ static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFu
|
||||||
}
|
}
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||||
if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||||
!isTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
!isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) && !isTimeLineAlignedQuery(pCxt->pCurrStmt)) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
"%s function requires valid time series input", pFunc->functionName);
|
"%s function requires valid time series input", pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
@ -2309,7 +2341,7 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (!pSelect->onlyHasKeepOrderFunc) {
|
if (!pSelect->onlyHasKeepOrderFunc) {
|
||||||
pSelect->isTimeLineResult = false;
|
pSelect->timeLineResMode = TIME_LINE_NONE;
|
||||||
}
|
}
|
||||||
CheckAggColCoexistCxt cxt = {.pTranslateCxt = pCxt, .existCol = false};
|
CheckAggColCoexistCxt cxt = {.pTranslateCxt = pCxt, .existCol = false};
|
||||||
nodesRewriteExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
nodesRewriteExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
||||||
|
@ -2656,9 +2688,9 @@ static int32_t replaceTbName(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
|
||||||
static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
|
static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
|
||||||
if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
|
if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
|
||||||
!isTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
|
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
|
||||||
(QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) &&
|
(QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) &&
|
||||||
!isTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) {
|
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
|
||||||
"Join requires valid time series input");
|
"Join requires valid time series input");
|
||||||
}
|
}
|
||||||
|
@ -2693,7 +2725,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
|
||||||
}
|
}
|
||||||
if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) {
|
if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) {
|
||||||
if (isSelectStmt(pCxt->pCurrStmt)) {
|
if (isSelectStmt(pCxt->pCurrStmt)) {
|
||||||
((SSelectStmt*)pCxt->pCurrStmt)->isTimeLineResult = false;
|
((SSelectStmt*)pCxt->pCurrStmt)->timeLineResMode = TIME_LINE_NONE;
|
||||||
} else if (isDeleteStmt(pCxt->pCurrStmt)) {
|
} else if (isDeleteStmt(pCxt->pCurrStmt)) {
|
||||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
break;
|
break;
|
||||||
|
@ -3028,7 +3060,7 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes needFillImpl(SNode* pNode, void* pContext) {
|
static EDealRes needFillImpl(SNode* pNode, void* pContext) {
|
||||||
if (isAggFunc(pNode) && FUNCTION_TYPE_GROUP_KEY != ((SFunctionNode*)pNode)->funcType) {
|
if ((isAggFunc(pNode) || isInterpFunc(pNode)) && FUNCTION_TYPE_GROUP_KEY != ((SFunctionNode*)pNode)->funcType) {
|
||||||
*(bool*)pContext = true;
|
*(bool*)pContext = true;
|
||||||
return DEAL_RES_END;
|
return DEAL_RES_END;
|
||||||
}
|
}
|
||||||
|
@ -3052,7 +3084,7 @@ static int32_t convertFillValue(STranslateContext* pCxt, SDataType dt, SNodeList
|
||||||
code = scalarCalculateConstants(pCaseFunc, &pCell->pNode);
|
code = scalarCalculateConstants(pCaseFunc, &pCell->pNode);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_VALUE != nodeType(pCell->pNode)) {
|
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_VALUE != nodeType(pCell->pNode)) {
|
||||||
code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value is just a constant");
|
code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value can only accept constant");
|
||||||
} else if (TSDB_CODE_SUCCESS != code) {
|
} else if (TSDB_CODE_SUCCESS != code) {
|
||||||
code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch");
|
code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch");
|
||||||
}
|
}
|
||||||
|
@ -3076,6 +3108,7 @@ static int32_t checkFillValues(STranslateContext* pCxt, SFillNode* pFill, SNodeL
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
++fillNo;
|
++fillNo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3172,7 +3205,7 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST);
|
||||||
}
|
}
|
||||||
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
pCxt->currClause = SQL_CLAUSE_GROUP_BY;
|
||||||
pSelect->isTimeLineResult = false;
|
pSelect->timeLineResMode = TIME_LINE_NONE;
|
||||||
return translateExprList(pCxt, pSelect->pGroupByList);
|
return translateExprList(pCxt, pSelect->pGroupByList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3495,6 +3528,22 @@ static int32_t createDefaultFillNode(STranslateContext* pCxt, SNode** pOutput) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createDefaultEveryNode(STranslateContext* pCxt, SNode** pOutput) {
|
||||||
|
SValueNode* pEvery = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||||
|
if (NULL == pEvery) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEvery->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
pEvery->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||||
|
pEvery->isDuration = true;
|
||||||
|
pEvery->literal = taosStrdup("1s");
|
||||||
|
|
||||||
|
|
||||||
|
*pOutput = (SNode*)pEvery;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t checkEvery(STranslateContext* pCxt, SValueNode* pInterval) {
|
static int32_t checkEvery(STranslateContext* pCxt, SValueNode* pInterval) {
|
||||||
int32_t len = strlen(pInterval->literal);
|
int32_t len = strlen(pInterval->literal);
|
||||||
|
|
||||||
|
@ -3510,7 +3559,12 @@ static int32_t checkEvery(STranslateContext* pCxt, SValueNode* pInterval) {
|
||||||
static int32_t translateInterpEvery(STranslateContext* pCxt, SNode** pEvery) {
|
static int32_t translateInterpEvery(STranslateContext* pCxt, SNode** pEvery) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
code = checkEvery(pCxt, (SValueNode*)(*pEvery));
|
if (NULL == *pEvery) {
|
||||||
|
code = createDefaultEveryNode(pCxt, pEvery);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = checkEvery(pCxt, (SValueNode*)(*pEvery));
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateExpr(pCxt, pEvery);
|
code = translateExpr(pCxt, pEvery);
|
||||||
}
|
}
|
||||||
|
@ -3539,6 +3593,9 @@ static int32_t translateInterpFill(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkFill(pCxt, (SFillNode*)pSelect->pFill, (SValueNode*)pSelect->pEvery, true);
|
code = checkFill(pCxt, (SFillNode*)pSelect->pFill, (SValueNode*)pSelect->pEvery, true);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = checkFillValues(pCxt, (SFillNode*)pSelect->pFill, pSelect->pProjectionList);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -3556,8 +3613,12 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == pSelect->pRange || NULL == pSelect->pEvery || NULL == pSelect->pFill) {
|
if (NULL == pSelect->pRange || NULL == pSelect->pEvery || NULL == pSelect->pFill) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE,
|
if (pSelect->pRange != NULL && QUERY_NODE_OPERATOR == nodeType(pSelect->pRange) && pSelect->pEvery == NULL) {
|
||||||
"Missing RANGE clause, EVERY clause or FILL clause");
|
// single point interp every can be omitted
|
||||||
|
} else {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE,
|
||||||
|
"Missing RANGE clause, EVERY clause or FILL clause");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = translateExpr(pCxt, &pSelect->pRange);
|
int32_t code = translateExpr(pCxt, &pSelect->pRange);
|
||||||
|
@ -3572,7 +3633,18 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
|
||||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
||||||
int32_t code = translateExprList(pCxt, pSelect->pPartitionByList);
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if (pSelect->pPartitionByList) {
|
||||||
|
int8_t typeType = getTableTypeFromTableNode(pSelect->pFromTable);
|
||||||
|
SNode* pPar = nodesListGetNode(pSelect->pPartitionByList, 0);
|
||||||
|
if (!((TSDB_NORMAL_TABLE == typeType || TSDB_CHILD_TABLE == typeType) &&
|
||||||
|
1 == pSelect->pPartitionByList->length && (QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) {
|
||||||
|
pSelect->timeLineResMode = TIME_LINE_MULTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = translateExprList(pCxt, pSelect->pPartitionByList);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateExprList(pCxt, pSelect->pTags);
|
code = translateExprList(pCxt, pSelect->pTags);
|
||||||
}
|
}
|
||||||
|
@ -3701,9 +3773,9 @@ static void resetResultTimeline(SSelectStmt* pSelect) {
|
||||||
if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||||
isPrimaryKey((STempTableNode*)pSelect->pFromTable, pOrder)) ||
|
isPrimaryKey((STempTableNode*)pSelect->pFromTable, pOrder)) ||
|
||||||
(QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
|
(QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
|
||||||
pSelect->isTimeLineResult = true;
|
pSelect->timeLineResMode = TIME_LINE_GLOBAL;
|
||||||
} else {
|
} else {
|
||||||
pSelect->isTimeLineResult = false;
|
pSelect->timeLineResMode = TIME_LINE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3773,7 +3845,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = replaceTbName(pCxt, pSelect);
|
code = replaceTbName(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3833,8 +3905,13 @@ static int32_t translateSetOperProject(STranslateContext* pCxt, SSetOperator* pS
|
||||||
pLeftExpr = pLeftFuncExpr;
|
pLeftExpr = pLeftFuncExpr;
|
||||||
}
|
}
|
||||||
snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName);
|
snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName);
|
||||||
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList,
|
SNode* pProj = createSetOperProject(pSetOperator->stmtName, pLeft);
|
||||||
createSetOperProject(pSetOperator->stmtName, pLeft))) {
|
if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight)
|
||||||
|
&& ((SColumnNode*)pLeft)->colId == PRIMARYKEY_TIMESTAMP_COL_ID
|
||||||
|
&& ((SColumnNode*)pRight)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||||
|
((SColumnNode*)pProj)->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList, pProj)) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3846,6 +3923,10 @@ static uint8_t calcSetOperatorPrecision(SSetOperator* pSetOperator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pSetOperator) {
|
static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pSetOperator) {
|
||||||
|
if (NULL == pSetOperator->pOrderByList || pSetOperator->pOrderByList->length <= 0) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
bool other;
|
bool other;
|
||||||
int32_t code = translateOrderByPosition(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList, &other);
|
int32_t code = translateOrderByPosition(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList, &other);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -3858,6 +3939,14 @@ static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pS
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = replaceOrderByAlias(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList);
|
code = replaceOrderByAlias(pCxt, pSetOperator->pProjectionList, pSetOperator->pOrderByList);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
SNode* pOrder = ((SOrderByExprNode*)nodesListGetNode(pSetOperator->pOrderByList, 0))->pExpr;
|
||||||
|
if (isPrimaryKeyImpl(pOrder)) {
|
||||||
|
pSetOperator->timeLineResMode = TIME_LINE_GLOBAL;
|
||||||
|
} else {
|
||||||
|
pSetOperator->timeLineResMode = TIME_LINE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4910,6 +4999,7 @@ static int32_t buildTableForSampleAst(SSampleAstInfo* pInfo, SNode** pOutput) {
|
||||||
}
|
}
|
||||||
snprintf(pTable->table.dbName, sizeof(pTable->table.dbName), "%s", pInfo->pDbName);
|
snprintf(pTable->table.dbName, sizeof(pTable->table.dbName), "%s", pInfo->pDbName);
|
||||||
snprintf(pTable->table.tableName, sizeof(pTable->table.tableName), "%s", pInfo->pTableName);
|
snprintf(pTable->table.tableName, sizeof(pTable->table.tableName), "%s", pInfo->pTableName);
|
||||||
|
snprintf(pTable->table.tableAlias, sizeof(pTable->table.tableAlias), "%s", pInfo->pTableName);
|
||||||
TSWAP(pTable->pMeta, pInfo->pRollupTableMeta);
|
TSWAP(pTable->pMeta, pInfo->pRollupTableMeta);
|
||||||
*pOutput = (SNode*)pTable;
|
*pOutput = (SNode*)pTable;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -6344,7 +6434,7 @@ static int32_t subtableExprHasColumnOrPseudoColumn(SNode* pNode) {
|
||||||
static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
|
static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||||
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
|
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
|
||||||
!pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
|
!isTimeLineQuery(pStmt->pQuery) || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
|
||||||
crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect) || hasJsonTypeProjection(pSelect)) {
|
crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect) || hasJsonTypeProjection(pSelect)) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
|
||||||
}
|
}
|
||||||
|
@ -6700,6 +6790,54 @@ static int32_t translateStreamTargetTable(STranslateContext* pCxt, SCreateStream
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery) {
|
||||||
|
SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
|
if (NULL == col) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(col->tableAlias, pTable);
|
||||||
|
strcpy(col->colName, pMeta->schema[0].name);
|
||||||
|
SNodeList* pParamterList = nodesMakeList();
|
||||||
|
if (NULL == pParamterList) {
|
||||||
|
nodesDestroyNode((SNode *)col);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = nodesListStrictAppend(pParamterList, (SNode *)col);
|
||||||
|
if (code) {
|
||||||
|
nodesDestroyNode((SNode *)col);
|
||||||
|
nodesDestroyList(pParamterList);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* pFunc = (SNode*)createFunction("last", pParamterList);
|
||||||
|
if (NULL == pFunc) {
|
||||||
|
nodesDestroyList(pParamterList);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNodeList* pProjectionList = nodesMakeList();
|
||||||
|
if (NULL == pProjectionList) {
|
||||||
|
nodesDestroyList(pParamterList);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
code = nodesListStrictAppend(pProjectionList, pFunc);
|
||||||
|
if (code) {
|
||||||
|
nodesDestroyNode(pFunc);
|
||||||
|
nodesDestroyList(pProjectionList);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = createSimpleSelectStmtFromProjList(pDb, pTable, pProjectionList, (SSelectStmt **)pQuery);
|
||||||
|
if (code) {
|
||||||
|
nodesDestroyList(pProjectionList);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) {
|
static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) {
|
||||||
pCxt->createStream = true;
|
pCxt->createStream = true;
|
||||||
STableMeta* pMeta = NULL;
|
STableMeta* pMeta = NULL;
|
||||||
|
@ -6726,6 +6864,18 @@ static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt
|
||||||
getSourceDatabase(pStmt->pQuery, pCxt->pParseCxt->acctId, pReq->sourceDB);
|
getSourceDatabase(pStmt->pQuery, pCxt->pParseCxt->acctId, pReq->sourceDB);
|
||||||
code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
|
code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pStmt->pOptions->fillHistory) {
|
||||||
|
SRealTableNode* pTable = (SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable);
|
||||||
|
code = createLastTsSelectStmt(pTable->table.dbName, pTable->table.tableName, pTable->pMeta, &pStmt->pPrevQuery);
|
||||||
|
/*
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
STranslateContext cxt = {0};
|
||||||
|
int32_t code = initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt);
|
||||||
|
code = translateQuery(&cxt, pStmt->pPrevQuery);
|
||||||
|
destroyTranslateContext(&cxt);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
taosMemoryFree(pMeta);
|
taosMemoryFree(pMeta);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -6792,13 +6942,86 @@ static int32_t translateCreateStream(STranslateContext* pCxt, SCreateStreamStmt*
|
||||||
code = buildCreateStreamReq(pCxt, pStmt, &createReq);
|
code = buildCreateStreamReq(pCxt, pStmt, &createReq);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = buildCmdMsg(pCxt, TDMT_MND_CREATE_STREAM, (FSerializeFunc)tSerializeSCMCreateStreamReq, &createReq);
|
if (NULL == pStmt->pPrevQuery) {
|
||||||
|
code = buildCmdMsg(pCxt, TDMT_MND_CREATE_STREAM, (FSerializeFunc)tSerializeSCMCreateStreamReq, &createReq);
|
||||||
|
} else {
|
||||||
|
pStmt->pReq = taosMemoryMalloc(sizeof(createReq));
|
||||||
|
if (NULL == pStmt->pReq) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
memcpy(pStmt->pReq, &createReq, sizeof(createReq));
|
||||||
|
memset(&createReq, 0, sizeof(createReq));
|
||||||
|
TSWAP(pCxt->pPrevRoot, pStmt->pPrevQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tFreeSCMCreateStreamReq(&createReq);
|
tFreeSCMCreateStreamReq(&createReq);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* pInterval) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
if (QUERY_NODE_SELECT_STMT != nodeType(pStmt->pQuery)) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||||
|
if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow)) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIntervalWindowNode* pWindow = (SIntervalWindowNode*)pSelect->pWindow;
|
||||||
|
pInterval->interval = ((SValueNode*)pWindow->pInterval)->datum.i;
|
||||||
|
pInterval->intervalUnit = ((SValueNode*)pWindow->pInterval)->unit;
|
||||||
|
pInterval->offset = (NULL != pWindow->pOffset ? ((SValueNode*)pWindow->pOffset)->datum.i : 0);
|
||||||
|
pInterval->sliding = (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->datum.i : pInterval->interval);
|
||||||
|
pInterval->slidingUnit =
|
||||||
|
(NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->unit : pInterval->intervalUnit);
|
||||||
|
pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision;
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow) {
|
||||||
|
SCreateStreamStmt* pStmt = (SCreateStreamStmt*)pQuery->pRoot;
|
||||||
|
STranslateContext cxt = {0};
|
||||||
|
SInterval interval = {0};
|
||||||
|
int64_t lastTs = 0;
|
||||||
|
|
||||||
|
int32_t code = initTranslateContext(pParseCxt, NULL, &cxt);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = buildIntervalForCreateStream(pStmt, &interval);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if (pResRow && pResRow[0]) {
|
||||||
|
lastTs = *(int64_t*)pResRow[0];
|
||||||
|
} else if (interval.interval > 0) {
|
||||||
|
lastTs = convertTimePrecision(taosGetTimestampMs(), TSDB_TIME_PRECISION_MILLI, interval.precision);
|
||||||
|
} else {
|
||||||
|
lastTs = taosGetTimestampMs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if (interval.interval > 0) {
|
||||||
|
pStmt->pReq->lastTs = taosTimeTruncate(lastTs, &interval);
|
||||||
|
} else {
|
||||||
|
pStmt->pReq->lastTs = lastTs;
|
||||||
|
}
|
||||||
|
code = buildCmdMsg(&cxt, TDMT_MND_CREATE_STREAM, (FSerializeFunc)tSerializeSCMCreateStreamReq, pStmt->pReq);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = setQuery(&cxt, pQuery);
|
||||||
|
}
|
||||||
|
setRefreshMate(&cxt, pQuery);
|
||||||
|
destroyTranslateContext(&cxt);
|
||||||
|
|
||||||
|
tFreeSCMCreateStreamReq(pStmt->pReq);
|
||||||
|
taosMemoryFreeClear(pStmt->pReq);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) {
|
static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) {
|
||||||
SMDropStreamReq dropReq = {0};
|
SMDropStreamReq dropReq = {0};
|
||||||
SName name;
|
SName name;
|
||||||
|
@ -7479,8 +7702,7 @@ static SNodeList* createProjectCols(int32_t ncols, const char* const pCols[]) {
|
||||||
return pProjections;
|
return pProjections;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createSimpleSelectStmt(const char* pDb, const char* pTable, int32_t numOfProjs,
|
static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) {
|
||||||
const char* const pProjCol[], SSelectStmt** pStmt) {
|
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
||||||
if (NULL == pSelect) {
|
if (NULL == pSelect) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -7496,27 +7718,38 @@ static int32_t createSimpleSelectStmt(const char* pDb, const char* pTable, int32
|
||||||
snprintf(pRealTable->table.tableName, sizeof(pRealTable->table.tableName), "%s", pTable);
|
snprintf(pRealTable->table.tableName, sizeof(pRealTable->table.tableName), "%s", pTable);
|
||||||
snprintf(pRealTable->table.tableAlias, sizeof(pRealTable->table.tableAlias), "%s", pTable);
|
snprintf(pRealTable->table.tableAlias, sizeof(pRealTable->table.tableAlias), "%s", pTable);
|
||||||
pSelect->pFromTable = (SNode*)pRealTable;
|
pSelect->pFromTable = (SNode*)pRealTable;
|
||||||
|
pSelect->pProjectionList = pProjectionList;
|
||||||
if (numOfProjs >= 0) {
|
|
||||||
pSelect->pProjectionList = createProjectCols(numOfProjs, pProjCol);
|
|
||||||
if (NULL == pSelect->pProjectionList) {
|
|
||||||
nodesDestroyNode((SNode*)pSelect);
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*pStmt = pSelect;
|
*pStmt = pSelect;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t createSimpleSelectStmtFromCols(const char* pDb, const char* pTable, int32_t numOfProjs,
|
||||||
|
const char* const pProjCol[], SSelectStmt** pStmt) {
|
||||||
|
SNodeList* pProjectionList = NULL;
|
||||||
|
if (numOfProjs >= 0) {
|
||||||
|
pProjectionList = createProjectCols(numOfProjs, pProjCol);
|
||||||
|
if (NULL == pProjectionList) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) {
|
||||||
|
return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createSelectStmtForShow(ENodeType showType, SSelectStmt** pStmt) {
|
static int32_t createSelectStmtForShow(ENodeType showType, SSelectStmt** pStmt) {
|
||||||
const SSysTableShowAdapter* pShow = &sysTableShowAdapter[showType - SYSTABLE_SHOW_TYPE_OFFSET];
|
const SSysTableShowAdapter* pShow = &sysTableShowAdapter[showType - SYSTABLE_SHOW_TYPE_OFFSET];
|
||||||
return createSimpleSelectStmt(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, pStmt);
|
return createSimpleSelectStmtFromCols(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, pStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createSelectStmtForShowTableDist(SShowTableDistributedStmt* pStmt, SSelectStmt** pOutput) {
|
static int32_t createSelectStmtForShowTableDist(SShowTableDistributedStmt* pStmt, SSelectStmt** pOutput) {
|
||||||
return createSimpleSelectStmt(pStmt->dbName, pStmt->tableName, 0, NULL, pOutput);
|
return createSimpleSelectStmtFromCols(pStmt->dbName, pStmt->tableName, 0, NULL, pOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createOperatorNode(EOperatorType opType, const char* pColName, SNode* pRight, SNode** pOp) {
|
static int32_t createOperatorNode(EOperatorType opType, const char* pColName, SNode* pRight, SNode** pOp) {
|
||||||
|
@ -7650,7 +7883,7 @@ static int32_t createShowTableTagsProjections(SNodeList** pProjections, SNodeLis
|
||||||
static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) {
|
static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
SShowTableTagsStmt* pShow = (SShowTableTagsStmt*)pQuery->pRoot;
|
SShowTableTagsStmt* pShow = (SShowTableTagsStmt*)pQuery->pRoot;
|
||||||
SSelectStmt* pSelect = NULL;
|
SSelectStmt* pSelect = NULL;
|
||||||
int32_t code = createSimpleSelectStmt(((SValueNode*)pShow->pDbName)->literal, ((SValueNode*)pShow->pTbName)->literal,
|
int32_t code = createSimpleSelectStmtFromCols(((SValueNode*)pShow->pDbName)->literal, ((SValueNode*)pShow->pTbName)->literal,
|
||||||
-1, NULL, &pSelect);
|
-1, NULL, &pSelect);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createShowTableTagsProjections(&pSelect->pProjectionList, &pShow->pTags);
|
code = createShowTableTagsProjections(&pSelect->pProjectionList, &pShow->pTags);
|
||||||
|
@ -8975,6 +9208,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
pQuery->haveResultSet = false;
|
||||||
pQuery->execMode = QUERY_EXEC_MODE_RPC;
|
pQuery->execMode = QUERY_EXEC_MODE_RPC;
|
||||||
if (NULL != pCxt->pCmdMsg) {
|
if (NULL != pCxt->pCmdMsg) {
|
||||||
TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg);
|
TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg);
|
||||||
|
@ -9009,6 +9243,10 @@ int32_t translate(SParseContext* pParseCxt, SQuery* pQuery, SParseMetaCache* pMe
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateQuery(&cxt, pQuery->pRoot);
|
code = translateQuery(&cxt, pQuery->pRoot);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && (cxt.pPrevRoot || cxt.pPostRoot)) {
|
||||||
|
pQuery->pPrevRoot = cxt.pPrevRoot;
|
||||||
|
pQuery->pPostRoot = cxt.pPostRoot;
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = setQuery(&cxt, pQuery);
|
code = setQuery(&cxt, pQuery);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
case TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY:
|
case TSDB_CODE_PAR_CANNOT_DROP_PRIMARY_KEY:
|
||||||
return "Primary timestamp column cannot be dropped";
|
return "Primary timestamp column cannot be dropped";
|
||||||
case TSDB_CODE_PAR_INVALID_MODIFY_COL:
|
case TSDB_CODE_PAR_INVALID_MODIFY_COL:
|
||||||
return "Only binary/nchar column length could be modified, and the length can only be increased, not decreased";
|
return "Only binary/nchar/geometry column length could be modified, and the length can only be increased, not decreased";
|
||||||
case TSDB_CODE_PAR_INVALID_TBNAME:
|
case TSDB_CODE_PAR_INVALID_TBNAME:
|
||||||
return "Invalid tbname pseudo column";
|
return "Invalid tbname pseudo column";
|
||||||
case TSDB_CODE_PAR_INVALID_FUNCTION_NAME:
|
case TSDB_CODE_PAR_INVALID_FUNCTION_NAME:
|
||||||
|
@ -249,6 +249,17 @@ int32_t getNumOfTags(const STableMeta* pTableMeta) { return getTableInfo(pTableM
|
||||||
|
|
||||||
STableComInfo getTableInfo(const STableMeta* pTableMeta) { return pTableMeta->tableInfo; }
|
STableComInfo getTableInfo(const STableMeta* pTableMeta) { return pTableMeta->tableInfo; }
|
||||||
|
|
||||||
|
int32_t getTableTypeFromTableNode(SNode *pTable) {
|
||||||
|
if (NULL == pTable) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (QUERY_NODE_REAL_TABLE != nodeType(pTable)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ((SRealTableNode *)pTable)->pMeta->tableType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta) {
|
STableMeta* tableMetaDup(const STableMeta* pTableMeta) {
|
||||||
int32_t numOfFields = TABLE_TOTAL_COL_NUM(pTableMeta);
|
int32_t numOfFields = TABLE_TOTAL_COL_NUM(pTableMeta);
|
||||||
if (numOfFields > TSDB_MAX_COLUMNS || numOfFields < TSDB_MIN_COLUMNS) {
|
if (numOfFields > TSDB_MAX_COLUMNS || numOfFields < TSDB_MIN_COLUMNS) {
|
||||||
|
@ -684,7 +695,7 @@ SNode* createSelectStmtImpl(bool isDistinct, SNodeList* pProjectionList, SNode*
|
||||||
select->pProjectionList = pProjectionList;
|
select->pProjectionList = pProjectionList;
|
||||||
select->pFromTable = pTable;
|
select->pFromTable = pTable;
|
||||||
sprintf(select->stmtName, "%p", select);
|
sprintf(select->stmtName, "%p", select);
|
||||||
select->isTimeLineResult = true;
|
select->timeLineResMode = select->isDistinct ? TIME_LINE_NONE : TIME_LINE_GLOBAL;
|
||||||
select->onlyHasKeepOrderFunc = true;
|
select->onlyHasKeepOrderFunc = true;
|
||||||
select->timeRange = TSWINDOW_INITIALIZER;
|
select->timeRange = TSWINDOW_INITIALIZER;
|
||||||
return (SNode*)select;
|
return (SNode*)select;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue