Merge remote-tracking branch 'origin/3.0' into dynamicIdx
This commit is contained in:
commit
bfd711c08f
|
@ -430,7 +430,7 @@ pipeline {
|
|||
date
|
||||
rm -rf ${WKC}/debug
|
||||
cd ${WKC}/tests/parallel_test
|
||||
time ./container_build.sh -w ${WKDIR} -t 10 -e
|
||||
time ./container_build.sh -w ${WKDIR} -e
|
||||
'''
|
||||
def extra_param = ""
|
||||
def log_server_file = "/home/log_server.json"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "3.0.2.2")
|
||||
SET(TD_VER_NUMBER "3.0.2.4")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taosadapter
|
||||
ExternalProject_Add(taosadapter
|
||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||
GIT_TAG a2e9920
|
||||
GIT_TAG 213f8b3
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taos-tools
|
||||
ExternalProject_Add(taos-tools
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
|
||||
GIT_TAG 94d6895
|
||||
GIT_TAG 5c53cc8
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -94,22 +94,21 @@ void close() throws SQLException;
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
class TaosConsumer():
|
||||
def __init__(self, *topics, **configs)
|
||||
class Consumer:
|
||||
def subscribe(self, topics):
|
||||
pass
|
||||
|
||||
def __iter__(self)
|
||||
def unsubscribe(self):
|
||||
pass
|
||||
|
||||
def __next__(self)
|
||||
def poll(self, timeout: float = 1.0):
|
||||
pass
|
||||
|
||||
def sync_next(self)
|
||||
|
||||
def subscription(self)
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def unsubscribe(self)
|
||||
|
||||
def close(self)
|
||||
|
||||
def __del__(self)
|
||||
def commit(self, message):
|
||||
pass
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -117,19 +116,22 @@ class TaosConsumer():
|
|||
<TabItem label="Go" value="Go">
|
||||
|
||||
```go
|
||||
func NewConsumer(conf *Config) (*Consumer, error)
|
||||
func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)
|
||||
|
||||
func (c *Consumer) Close() error
|
||||
// rebalanceCb is reserved for compatibility purpose
|
||||
func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error
|
||||
|
||||
func (c *Consumer) Commit(ctx context.Context, message unsafe.Pointer) error
|
||||
// rebalanceCb is reserved for compatibility purpose
|
||||
func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error
|
||||
|
||||
func (c *Consumer) FreeMessage(message unsafe.Pointer)
|
||||
func (c *Consumer) Poll(timeoutMs int) tmq.Event
|
||||
|
||||
func (c *Consumer) Poll(timeout time.Duration) (*Result, error)
|
||||
|
||||
func (c *Consumer) Subscribe(topics []string) error
|
||||
// tmq.TopicPartition is reserved for compatibility purpose
|
||||
func (c *Consumer) Commit() ([]tmq.TopicPartition, error)
|
||||
|
||||
func (c *Consumer) Unsubscribe() error
|
||||
|
||||
func (c *Consumer) Close() error
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -357,50 +359,20 @@ public class MetersDeserializer extends ReferenceDeserializer<Meters> {
|
|||
<TabItem label="Go" value="Go">
|
||||
|
||||
```go
|
||||
config := tmq.NewConfig()
|
||||
defer config.Destroy()
|
||||
err = config.SetGroupID("test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetAutoOffsetReset("earliest")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectIP("127.0.0.1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectUser("root")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPass("taosdata")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPort("6030")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetMsgWithTableName(true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableHeartBeat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableAutoCommit(func(result *wrapper.TMQCommitCallbackResult) {
|
||||
if result.ErrCode != 0 {
|
||||
errStr := wrapper.TMQErr2Str(result.ErrCode)
|
||||
err := errors.NewError(int(result.ErrCode), errStr)
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
conf := &tmq.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "earliest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_c",
|
||||
"enable.auto.commit": "false",
|
||||
"enable.heartbeat.background": "true",
|
||||
"experimental.snapshot.enable": "true",
|
||||
"msg.with.table.name": "true",
|
||||
}
|
||||
consumer, err := NewConsumer(conf)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -422,23 +394,31 @@ let mut consumer = tmq.build()?;
|
|||
|
||||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
from taos.tmq import Consumer
|
||||
|
||||
# Syntax: `consumer = Consumer(configs)`
|
||||
#
|
||||
# Example:
|
||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||
```
|
||||
|
||||
Python programs use the following parameters:
|
||||
|
||||
| Parameter | Type | Description | Remarks |
|
||||
| :----------------------------: | :----: | -------------------------------------------------------- | ------------------------------------------- |
|
||||
| `td_connect_ip` | string | Used in establishing a connection; same as `taos_connect` | |
|
||||
| `td_connect_user` | string | Used in establishing a connection; same as `taos_connect` | |
|
||||
| `td_connect_pass` | string | Used in establishing a connection; same as `taos_connect` | |
|
||||
| `td_connect_port` | string | Used in establishing a connection; same as `taos_connect` | |
|
||||
| `group_id` | string | Consumer group ID; consumers with the same ID are in the same group | **Required**. Maximum length: 192. |
|
||||
| `client_id` | string | Client ID | Maximum length: 192. |
|
||||
| `auto_offset_reset` | string | Initial offset for the consumer group | Specify `earliest`, `latest`, or `none`(default) |
|
||||
| `enable_auto_commit` | string | Commit automatically | Specify `true` or `false`. |
|
||||
| `auto_commit_interval_ms` | string | Interval for automatic commits, in milliseconds |
|
||||
| `enable_heartbeat_background` | string | Backend heartbeat; if enabled, the consumer does not go offline even if it has not polled for a long time | Specify `true` or `false`. |
|
||||
| `experimental_snapshot_enable` | string | Specify whether to consume messages from the WAL or from TSBS | Specify `true` or `false`. |
|
||||
| `msg_with_table_name` | string | Specify whether to deserialize table names from messages | Specify `true` or `false`.
|
||||
| `timeout` | int | Consumer pull timeout | |
|
||||
| Parameter | Type | Description | Remarks |
|
||||
|:---------:|:----:|:-----------:|:-------:|
|
||||
| `td.connect.ip` | string | Used in establishing a connection||
|
||||
| `td.connect.user` | string | Used in establishing a connection||
|
||||
| `td.connect.pass` | string | Used in establishing a connection||
|
||||
| `td.connect.port` | string | Used in establishing a connection||
|
||||
| `group.id` | string | Consumer group ID; consumers with the same ID are in the same group | **Required**. Maximum length: 192 |
|
||||
| `client.id` | string | Client ID | Maximum length: 192 |
|
||||
| `msg.with.table.name` | string | Specify whether to deserialize table names from messages | pecify `true` or `false` |
|
||||
| `enable.auto.commit` | string | Commit automatically | pecify `true` or `false` |
|
||||
| `auto.commit.interval.ms` | string | Interval for automatic commits, in milliseconds | |
|
||||
| `auto.offset.reset` | string | Initial offset for the consumer group | Specify `earliest`, `latest`, or `none`(default) |
|
||||
| `experimental.snapshot.enable` | string | Specify whether to consume messages from the WAL or from TSDB | Specify `true` or `false` |
|
||||
| `enable.heartbeat.background` | string | Backend heartbeat; if enabled, the consumer does not go offline even if it has not polled for a long time | Specify `true` or `false` |
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
@ -523,11 +503,7 @@ consumer.subscribe(topics);
|
|||
<TabItem value="Go" label="Go">
|
||||
|
||||
```go
|
||||
consumer, err := tmq.NewConsumer(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe([]string{"example_tmq_topic"})
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -545,7 +521,7 @@ consumer.subscribe(["tmq_meters"]).await?;
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
consumer = TaosConsumer('topic_ctb_column', group_id='vg2')
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -611,13 +587,17 @@ while(running){
|
|||
|
||||
```go
|
||||
for {
|
||||
result, err := consumer.Poll(time.Second)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
ev := consumer.Poll(0)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Println(e.Value())
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
fmt.Println(result)
|
||||
consumer.Commit(context.Background(), result.Message)
|
||||
consumer.FreeMessage(result.Message)
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -660,9 +640,17 @@ for {
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
for msg in consumer:
|
||||
for row in msg:
|
||||
print(row)
|
||||
while True:
|
||||
res = consumer.poll(100)
|
||||
if not res:
|
||||
continue
|
||||
err = res.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = res.value()
|
||||
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -729,7 +717,11 @@ consumer.close();
|
|||
<TabItem value="Go" label="Go">
|
||||
|
||||
```go
|
||||
consumer.Close()
|
||||
/* Unsubscribe */
|
||||
_ = consumer.Unsubscribe()
|
||||
|
||||
/* Close consumer */
|
||||
_ = consumer.Close()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
@ -22,7 +22,7 @@ Helm uses the kubectl and kubeconfig configurations to perform Kubernetes operat
|
|||
To use TDengine Chart, download it from GitHub:
|
||||
|
||||
```bash
|
||||
wget https://github.com/taosdata/TDengine-Operator/raw/3.0/helm/tdengine-3.0.0.tgz
|
||||
wget https://github.com/taosdata/TDengine-Operator/raw/3.0/helm/tdengine-3.0.2.tgz
|
||||
|
||||
```
|
||||
|
||||
|
@ -38,7 +38,7 @@ With minikube, the default value is standard.
|
|||
Use Helm commands to install TDengine:
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz \
|
||||
helm install tdengine tdengine-3.0.2.tgz \
|
||||
--set storage.className=<your storage class name>
|
||||
|
||||
```
|
||||
|
@ -46,7 +46,7 @@ helm install tdengine tdengine-3.0.0.tgz \
|
|||
You can configure a small storage size in minikube to ensure that your deployment does not exceed your available disk space.
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz \
|
||||
helm install tdengine tdengine-3.0.2.tgz \
|
||||
--set storage.className=standard \
|
||||
--set storage.dataSize=2Gi \
|
||||
--set storage.logSize=10Mi
|
||||
|
@ -83,14 +83,14 @@ You can configure custom parameters in TDengine with the `values.yaml` file.
|
|||
Run the `helm show values` command to see all parameters supported by TDengine Chart.
|
||||
|
||||
```bash
|
||||
helm show values tdengine-3.0.0.tgz
|
||||
helm show values tdengine-3.0.2.tgz
|
||||
|
||||
```
|
||||
|
||||
Save the output of this command as `values.yaml`. Then you can modify this file with your desired values and use it to deploy a TDengine cluster:
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz -f values.yaml
|
||||
helm install tdengine tdengine-3.0.2.tgz -f values.yaml
|
||||
|
||||
```
|
||||
|
||||
|
@ -107,7 +107,7 @@ image:
|
|||
prefix: tdengine/tdengine
|
||||
#pullPolicy: Always
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
# tag: "3.0.0.0"
|
||||
# tag: "3.0.2.0"
|
||||
|
||||
service:
|
||||
# ClusterIP is the default service type, use NodeIP only if you know what you are doing.
|
||||
|
@ -155,15 +155,15 @@ clusterDomainSuffix: ""
|
|||
# See the [Configuration Variables](../../reference/config)
|
||||
#
|
||||
# Note:
|
||||
# 1. firstEp/secondEp: should not be setted here, it's auto generated at scale-up.
|
||||
# 2. serverPort: should not be setted, we'll use the default 6030 in many places.
|
||||
# 3. fqdn: will be auto generated in kubenetes, user should not care about it.
|
||||
# 1. firstEp/secondEp: should not be set here, it's auto generated at scale-up.
|
||||
# 2. serverPort: should not be set, we'll use the default 6030 in many places.
|
||||
# 3. fqdn: will be auto generated in kubernetes, user should not care about it.
|
||||
# 4. role: currently role is not supported - every node is able to be mnode and vnode.
|
||||
#
|
||||
# Btw, keep quotes "" around the value like below, even the value will be number or not.
|
||||
taoscfg:
|
||||
# Starts as cluster or not, must be 0 or 1.
|
||||
# 0: all pods will start as a seperate TDengine server
|
||||
# 0: all pods will start as a separate TDengine server
|
||||
# 1: pods will start as TDengine server cluster. [default]
|
||||
CLUSTER: "1"
|
||||
|
||||
|
|
|
@ -355,26 +355,29 @@ The `af` package encapsulates TDengine advanced functions such as connection man
|
|||
|
||||
#### Subscribe
|
||||
|
||||
* `func NewConsumer(conf *Config) (*Consumer, error)`
|
||||
* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)`
|
||||
|
||||
Creates consumer group.
|
||||
|
||||
* `func (c *Consumer) Subscribe(topics []string) error`
|
||||
* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error`
|
||||
Note: `rebalanceCb` is reserved for compatibility purpose
|
||||
|
||||
Subscribes a topic.
|
||||
|
||||
* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error`
|
||||
Note: `rebalanceCb` is reserved for compatibility purpose
|
||||
|
||||
Subscribes to topics.
|
||||
|
||||
* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
|
||||
* `func (c *Consumer) Poll(timeoutMs int) tmq.Event`
|
||||
|
||||
Polling information.
|
||||
|
||||
* `func (c *Consumer) Commit(ctx context.Context, message unsafe.Pointer) error`
|
||||
* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)`
|
||||
Note: `tmq.TopicPartition` is reserved for compatibility purpose
|
||||
|
||||
Commit information.
|
||||
|
||||
* `func (c *Consumer) FreeMessage(message unsafe.Pointer)`
|
||||
|
||||
Free information.
|
||||
|
||||
* `func (c *Consumer) Unsubscribe() error`
|
||||
|
||||
Unsubscribe.
|
||||
|
@ -441,25 +444,36 @@ Close consumer.
|
|||
|
||||
### Subscribe via WebSocket
|
||||
|
||||
* `func NewConsumer(config *Config) (*Consumer, error)`
|
||||
* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)`
|
||||
|
||||
Creates consumer group.
|
||||
Creates consumer group.
|
||||
|
||||
* `func (c *Consumer) Subscribe(topic []string) error`
|
||||
* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error`
|
||||
Note: `rebalanceCb` is reserved for compatibility purpose
|
||||
|
||||
Subscribes to topics.
|
||||
Subscribes a topic.
|
||||
|
||||
* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
|
||||
* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error`
|
||||
Note: `rebalanceCb` is reserved for compatibility purpose
|
||||
|
||||
Polling information.
|
||||
Subscribes to topics.
|
||||
|
||||
* `func (c *Consumer) Commit(messageID uint64) error`
|
||||
* `func (c *Consumer) Poll(timeoutMs int) tmq.Event`
|
||||
|
||||
Commit information.
|
||||
Polling information.
|
||||
|
||||
* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)`
|
||||
Note: `tmq.TopicPartition` is reserved for compatibility purpose
|
||||
|
||||
Commit information.
|
||||
|
||||
* `func (c *Consumer) Unsubscribe() error`
|
||||
|
||||
Unsubscribe.
|
||||
|
||||
* `func (c *Consumer) Close() error`
|
||||
|
||||
Close consumer.
|
||||
Close consumer.
|
||||
|
||||
For a complete example see [GitHub sample file](https://github.com/taosdata/driver-go/blob/3.0/examples/tmqoverws/main.go)
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
|
|||
|
||||
`TDengine.Connector` is a C# language connector provided by TDengine that allows C# developers to develop C# applications that access TDengine cluster data.
|
||||
|
||||
The `TDengine.Connector` connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc.The `TDengine.Connector` also supports WebSocket and developers can build connection through DSN, which supports data writing, querying, and parameter binding, etc.
|
||||
The `TDengine.Connector` connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc.The `TDengine.Connector` also supports WebSocket from v3.0.1 and developers can build connection through DSN, which supports data writing, querying, and parameter binding, etc.
|
||||
|
||||
This article describes how to install `TDengine.Connector` in a Linux or Windows environment and connect to TDengine clusters via `TDengine.Connector` to perform basic operations such as data writing and querying.
|
||||
|
||||
|
@ -66,31 +66,43 @@ Please refer to [version support list](/reference/connector#version-support)
|
|||
* [Nuget Client](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (optional installation)
|
||||
* Install TDengine client driver, please refer to [Install client driver](/reference/connector/#install-client-driver) for details
|
||||
|
||||
### Install via dotnet CLI
|
||||
### Install `TDengine.Connector`
|
||||
|
||||
<Tabs defaultValue="CLI">
|
||||
<TabItem value="CLI" label="Get C# driver using dotnet CLI">
|
||||
<TabItem value="CLI" label="Native Connection">
|
||||
|
||||
You can reference the `TDengine.Connector` published in Nuget to the current project via the `dotnet` command under the path of the existing .NET project.
|
||||
You can reference the `TDengine.Connector` published in Nuget to the current project via the `dotnet` CLI under the path of the existing .NET project.
|
||||
|
||||
``` bash
|
||||
dotnet add package TDengine.Connector
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="source" label="Use source code to get C# driver">
|
||||
You may also modify the current.NET project file. You can include the following 'ItemGroup' in your project file (.csproj).
|
||||
|
||||
You can [download the source code](https://github.com/taosdata/taos-connector-dotnet/tree/3.0) and directly reference the latest version of the TDengine.Connector library.
|
||||
|
||||
```bash
|
||||
git clone -b 3.0 https://github.com/taosdata/taos-connector-dotnet.git
|
||||
cd taos-connector-dotnet
|
||||
cp -r src/ myProject
|
||||
|
||||
cd myProject
|
||||
dotnet add exmaple.csproj reference src/TDengine.csproj
|
||||
``` XML
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="source" label="WebSocket Connection">
|
||||
|
||||
In this scenario, modifying your project file is required in order to copy the WebSocket dependency dynamic library from the nuget package into your project.
|
||||
```XML
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Target Name="copyDLLDepency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
```
|
||||
|
||||
Notice: `TDengine.Connector` only version>= 3.0.2 includes the dynamic library for WebSocket.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
@ -265,6 +277,7 @@ ws://localhost:6041/test
|
|||
|
||||
| TDengine.Connector | Description |
|
||||
|--------------------|--------------------------------|
|
||||
| 3.0.2 | Support .NET Framework 4.5 and above. Support .Net standard 2.0. Nuget package includes dynamic library for WebSocket.|
|
||||
| 3.0.1 | Support WebSocket and Cloud,With function query, insert, and parameter binding|
|
||||
| 3.0.0 | Supports TDengine 3.0.0.0. TDengine 2.x is not supported. Added `TDengine.Impl.GetData()` interface to deserialize query results. |
|
||||
| 1.0.7 | Fixed TDengine.Query() memory leak. |
|
||||
|
|
|
@ -33,7 +33,7 @@ TDengine 3.0 is not compatible with the configuration and data files from previo
|
|||
4. Install TDengine 3.0.
|
||||
5. For assistance in migrating data to TDengine 3.0, contact [TDengine Support](https://tdengine.com/support).
|
||||
|
||||
### 4. How can I resolve the "Unable to establish connection" error?
|
||||
### 2. How can I resolve the "Unable to establish connection" error?
|
||||
|
||||
This error indicates that the client could not connect to the server. Perform the following troubleshooting steps:
|
||||
|
||||
|
@ -68,7 +68,7 @@ This error indicates that the client could not connect to the server. Perform th
|
|||
|
||||
11. You can also use the TDengine CLI to diagnose network issues. For more information, see [Problem Diagnostics](https://docs.tdengine.com/operation/diagnose/).
|
||||
|
||||
### 5. How can I resolve the "Unable to resolve FQDN" error?
|
||||
### 3. How can I resolve the "Unable to resolve FQDN" error?
|
||||
|
||||
Clients and dnodes must be able to resolve the FQDN of each required node. You can confirm your configuration as follows:
|
||||
|
||||
|
@ -79,15 +79,15 @@ Clients and dnodes must be able to resolve the FQDN of each required node. You c
|
|||
5. If TDengine has been previously installed and the `hostname` was modified, open `dnode.json` in the `data` folder and verify that the endpoint configuration is correct. The default location of the dnode file is `/var/lib/taos/dnode`. Ensure that you clean up previous installations before reinstalling TDengine.
|
||||
6. Confirm whether FQDNs are preconfigured in `/etc/hosts` and `/etc/hostname`.
|
||||
|
||||
### 6. What is the most effective way to write data to TDengine?
|
||||
### 4. What is the most effective way to write data to TDengine?
|
||||
|
||||
Writing data in batches provides higher efficiency in most situations. You can insert one or more data records into one or more tables in a single SQL statement.
|
||||
|
||||
### 9. Why are table names not fully displayed?
|
||||
### 5. Why are table names not fully displayed?
|
||||
|
||||
The number of columns in the TDengine CLI terminal display is limited. This can cause table names to be cut off, and if you use an incomplete name in a statement, the "Table does not exist" error will occur. You can increase the display size with the `maxBinaryDisplayWidth` parameter or the SQL statement `set max_binary_display_width`. You can also append `\G` to your SQL statement to bypass this limitation.
|
||||
|
||||
### 10. How can I migrate data?
|
||||
### 6. How can I migrate data?
|
||||
|
||||
In TDengine, the `hostname` uniquely identifies a machine. When you move data files to a new machine, you must configure the new machine to have the same `host name` as the original machine.
|
||||
|
||||
|
@ -97,7 +97,7 @@ The data structure of previous versions of TDengine is not compatible with versi
|
|||
|
||||
:::
|
||||
|
||||
### 11. How can I temporary change the log level from the TDengine Client?
|
||||
### 7. How can I temporary change the log level from the TDengine Client?
|
||||
|
||||
To change the log level for debugging purposes, you can use the following command:
|
||||
|
||||
|
@ -118,14 +118,14 @@ Use `resetlog` to remove all logs generated on the local client. Use the other p
|
|||
|
||||
For each parameter, you can set the value to `131` (error and warning), `135` (error, warning, and debug), or `143` (error, warning, debug, and trace).
|
||||
|
||||
### Why do TDengine components written in Go fail to compile?
|
||||
### 8. Why do TDengine components written in Go fail to compile?
|
||||
|
||||
TDengine includes taosAdapter, an independent component written in Go. This component provides the REST API as well as data access for other products such as Prometheus and Telegraf.
|
||||
When using the develop branch, you must run `git submodule update --init --recursive` to download the taosAdapter repository and then compile it.
|
||||
|
||||
TDengine Go components require Go version 1.14 or later.
|
||||
|
||||
### 13. How can I query the storage space being used by my data?
|
||||
### 9. How can I query the storage space being used by my data?
|
||||
|
||||
The TDengine data files are stored in `/var/lib/taos` by default. Log files are stored in `/var/log/taos`.
|
||||
|
||||
|
@ -133,7 +133,7 @@ To see how much space your data files occupy, run `du -sh /var/lib/taos/vnode --
|
|||
|
||||
If you want to see how much space is occupied by a single database, first determine which vgroup is storing the database by running `show vgroups`. Then check `/var/lib/taos/vnode` for the files associated with the vgroup ID.
|
||||
|
||||
### 15. How is timezone information processed for timestamps?
|
||||
### 10. How is timezone information processed for timestamps?
|
||||
|
||||
TDengine uses the timezone of the client for timestamps. The server timezone does not affect timestamps. The client converts Unix timestamps in SQL statements to UTC before sending them to the server. When you query data on the server, it provides timestamps in UTC to the client, which converts them to its local time.
|
||||
|
||||
|
@ -144,13 +144,13 @@ Timestamps are processed as follows:
|
|||
3. A timezone explicitly specified when establishing a connection to TDengine through a connector takes precedence over `taos.cfg` and the system timezone. For example, the Java connector allows you to specify a timezone in the JDBC URL.
|
||||
4. If you use an RFC 3339 timestamp (2013-04-12T15:52:01.123+08:00), or an ISO 8601 timestamp (2013-04-12T15:52:01.123+0800), the timezone specified in the timestamp is used instead of the timestamps configured using any other method.
|
||||
|
||||
### 16. Which network ports are required by TDengine?
|
||||
### 11. Which network ports are required by TDengine?
|
||||
|
||||
See [serverPort](https://docs.tdengine.com/reference/config/#serverport) in Configuration Parameters.
|
||||
|
||||
Note that ports are specified using 6030 as the default first port. If you change this port, all other ports change as well.
|
||||
|
||||
### 17. Why do applications such as Grafana fail to connect to TDengine over the REST API?
|
||||
### 12. Why do applications such as Grafana fail to connect to TDengine over the REST API?
|
||||
|
||||
In TDengine, the REST API is provided by taosAdapter. Ensure that taosAdapter is running before you connect an application to TDengine over the REST API. You can run `systemctl start taosadapter` to start the service.
|
||||
|
||||
|
@ -158,7 +158,7 @@ Note that the log path for taosAdapter must be configured separately. The defaul
|
|||
|
||||
For more information, see [taosAdapter](https://docs.tdengine.com/reference/taosadapter/).
|
||||
|
||||
### 18. How can I resolve out-of-memory (OOM) errors?
|
||||
### 13. How can I resolve out-of-memory (OOM) errors?
|
||||
|
||||
OOM errors are thrown by the operating system when its memory, including swap, becomes insufficient and it needs to terminate processes to remain operational. Most OOM errors in TDengine occur for one of the following reasons: free memory is less than the value of `vm.min_free_kbytes` or free memory is less than the size of the request. If TDengine occupies reserved memory, an OOM error can occur even when free memory is sufficient.
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ For TDengine 2.x installation packages by version, please visit [here](https://w
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 3.0.2.4
|
||||
|
||||
<Release type="tdengine" version="3.0.2.4" />
|
||||
|
||||
## 3.0.2.3
|
||||
|
||||
<Release type="tdengine" version="3.0.2.3" />
|
||||
|
|
|
@ -10,6 +10,10 @@ For other historical version installers, please visit [here](https://www.taosdat
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 2.4.2
|
||||
|
||||
<Release type="tools" version="2.4.2" />
|
||||
|
||||
## 2.4.1
|
||||
|
||||
<Release type="tools" version="2.4.1" />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace TDengineExample
|
|||
|
||||
// 5. execute
|
||||
res = TDengine.StmtExecute(stmt);
|
||||
CheckStmtRes(res, "faild to execute");
|
||||
CheckStmtRes(res, "failed to execute");
|
||||
|
||||
// 6. free
|
||||
TaosMultiBind.FreeTaosBind(tags);
|
||||
|
@ -92,7 +92,7 @@ namespace TDengineExample
|
|||
int code = TDengine.StmtClose(stmt);
|
||||
if (code != 0)
|
||||
{
|
||||
throw new Exception($"falied to close stmt, {code} reason: {TDengine.StmtErrorStr(stmt)} ");
|
||||
throw new Exception($"failed to close stmt, {code} reason: {TDengine.StmtErrorStr(stmt)} ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -7,7 +7,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.1" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -2,5 +2,5 @@ module goexample
|
|||
|
||||
go 1.17
|
||||
|
||||
require github.com/taosdata/driver-go/v3 3.0
|
||||
require github.com/taosdata/driver-go/v3 v3.1.0
|
||||
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
"os"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/af/tmq"
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/errors"
|
||||
"github.com/taosdata/driver-go/v3/wrapper"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -28,55 +23,26 @@ func main() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config := tmq.NewConfig()
|
||||
defer config.Destroy()
|
||||
err = config.SetGroupID("test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetAutoOffsetReset("earliest")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectIP("127.0.0.1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectUser("root")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPass("taosdata")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPort("6030")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetMsgWithTableName(true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableHeartBeat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableAutoCommit(func(result *wrapper.TMQCommitCallbackResult) {
|
||||
if result.ErrCode != 0 {
|
||||
errStr := wrapper.TMQErr2Str(result.ErrCode)
|
||||
err := errors.NewError(int(result.ErrCode), errStr)
|
||||
panic(err)
|
||||
}
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "earliest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"enable.heartbeat.background": "true",
|
||||
"experimental.snapshot.enable": "true",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
consumer, err := tmq.NewConsumer(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe([]string{"example_tmq_topic"})
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -88,19 +54,25 @@ func main() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
result, err := consumer.Poll(time.Second)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(0)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Println(e.String())
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
if result.Type != common.TMQ_RES_DATA {
|
||||
panic("want message type 1 got " + strconv.Itoa(int(result.Type)))
|
||||
}
|
||||
data, _ := json.Marshal(result.Data)
|
||||
fmt.Println(string(data))
|
||||
consumer.Commit(context.Background(), result.Message)
|
||||
consumer.FreeMessage(result.Message)
|
||||
break
|
||||
}
|
||||
consumer.Close()
|
||||
err = consumer.Unsubscribe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@ cursor.execute("CREATE DATABASE power")
|
|||
cursor.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
|
||||
|
||||
# insert data
|
||||
cursor.execute("""INSERT INTO power.d1001 USING power.meters TAGS(California.SanFrancisco, 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
power.d1002 USING power.meters TAGS(California.SanFrancisco, 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
power.d1003 USING power.meters TAGS(California.LosAngeles, 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
power.d1004 USING power.meters TAGS(California.LosAngeles, 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)""")
|
||||
cursor.execute("""INSERT INTO power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
power.d1003 USING power.meters TAGS('California.LosAngeles', 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
power.d1004 USING power.meters TAGS('California.LosAngeles', 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)""")
|
||||
print("inserted row count:", cursor.rowcount)
|
||||
|
||||
# query data
|
||||
|
|
|
@ -25,10 +25,10 @@ def create_stable(conn: taos.TaosConnection):
|
|||
|
||||
|
||||
# The generated SQL is:
|
||||
# INSERT INTO d1001 USING meters TAGS(California.SanFrancisco, 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
# d1002 USING meters TAGS(California.SanFrancisco, 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
# d1003 USING meters TAGS(California.LosAngeles, 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
# d1004 USING meters TAGS(California.LosAngeles, 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
|
||||
# INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
# d1002 USING meters TAGS('California.SanFrancisco', 3) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
# d1003 USING meters TAGS('California.LosAngeles', 2) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
# d1004 USING meters TAGS('California.LosAngeles', 3) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
|
||||
|
||||
def get_sql():
|
||||
global lines
|
||||
|
|
|
@ -1,58 +1,48 @@
|
|||
from taos.tmq import Consumer
|
||||
import taos
|
||||
from taos.tmq import *
|
||||
|
||||
conn = taos.connect()
|
||||
|
||||
print("init")
|
||||
conn.execute("drop topic if exists topic_ctb_column")
|
||||
conn.execute("drop database if exists py_tmq")
|
||||
conn.execute("create database if not exists py_tmq vgroups 2")
|
||||
conn.select_db("py_tmq")
|
||||
conn.execute(
|
||||
"create stable if not exists stb1 (ts timestamp, c1 int, c2 float, c3 binary(10)) tags(t1 int)"
|
||||
)
|
||||
conn.execute("create table if not exists tb1 using stb1 tags(1)")
|
||||
conn.execute("create table if not exists tb2 using stb1 tags(2)")
|
||||
conn.execute("create table if not exists tb3 using stb1 tags(3)")
|
||||
|
||||
print("create topic")
|
||||
conn.execute(
|
||||
"create topic if not exists topic_ctb_column as select ts, c1, c2, c3 from stb1"
|
||||
)
|
||||
|
||||
print("build consumer")
|
||||
conf = TaosTmqConf()
|
||||
conf.set("group.id", "tg2")
|
||||
conf.set("td.connect.user", "root")
|
||||
conf.set("td.connect.pass", "taosdata")
|
||||
conf.set("enable.auto.commit", "true")
|
||||
|
||||
|
||||
def tmq_commit_cb_print(tmq, resp, offset, param=None):
|
||||
print(f"commit: {resp}, tmq: {tmq}, offset: {offset}, param: {param}")
|
||||
def init_tmq_env(db, topic):
|
||||
conn = taos.connect()
|
||||
conn.execute("drop topic if exists {}".format(topic))
|
||||
conn.execute("drop database if exists {}".format(db))
|
||||
conn.execute("create database if not exists {}".format(db))
|
||||
conn.select_db(db)
|
||||
conn.execute(
|
||||
"create stable if not exists stb1 (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16))")
|
||||
conn.execute("create table if not exists tb1 using stb1 tags(1, 't1')")
|
||||
conn.execute("create table if not exists tb2 using stb1 tags(2, 't2')")
|
||||
conn.execute("create table if not exists tb3 using stb1 tags(3, 't3')")
|
||||
conn.execute("create topic if not exists {} as select ts, c1, c2, c3 from stb1".format(topic))
|
||||
conn.execute("insert into tb1 values (now, 1, 1.0, 'tmq test')")
|
||||
conn.execute("insert into tb2 values (now, 2, 2.0, 'tmq test')")
|
||||
conn.execute("insert into tb3 values (now, 3, 3.0, 'tmq test')")
|
||||
|
||||
|
||||
conf.set_auto_commit_cb(tmq_commit_cb_print, None)
|
||||
tmq = conf.new_consumer()
|
||||
if __name__ == '__main__':
|
||||
init_tmq_env("tmq_test", "tmq_test_topic") # init env
|
||||
consumer = Consumer(
|
||||
{
|
||||
"group.id": "tg2",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"enable.auto.commit": "true",
|
||||
}
|
||||
)
|
||||
consumer.subscribe(["tmq_test_topic"])
|
||||
|
||||
print("build topic list")
|
||||
try:
|
||||
while True:
|
||||
res = consumer.poll(100)
|
||||
if not res:
|
||||
continue
|
||||
err = res.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = res.value()
|
||||
|
||||
topic_list = TaosTmqList()
|
||||
topic_list.append("topic_ctb_column")
|
||||
|
||||
print("basic consume loop")
|
||||
tmq.subscribe(topic_list)
|
||||
|
||||
sub_list = tmq.subscription()
|
||||
|
||||
print("subscribed topics: ", sub_list)
|
||||
|
||||
while 1:
|
||||
res = tmq.poll(1000)
|
||||
if res:
|
||||
topic = res.get_topic_name()
|
||||
vg = res.get_vgroup_id()
|
||||
db = res.get_db_name()
|
||||
print(f"topic: {topic}\nvgroup id: {vg}\ndb: {db}")
|
||||
for row in res:
|
||||
print(row)
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
finally:
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/python3
|
||||
from taosws import Consumer
|
||||
|
||||
conf = {
|
||||
"td.connect.websocket.scheme": "ws",
|
||||
"group.id": "0",
|
||||
}
|
||||
consumer = Consumer(conf)
|
||||
|
||||
consumer.subscribe(["test"])
|
||||
|
||||
while True:
|
||||
message = consumer.poll(timeout=1.0)
|
||||
if message:
|
||||
id = message.vgroup()
|
||||
topic = message.topic()
|
||||
database = message.database()
|
||||
|
||||
for block in message:
|
||||
nrows = block.nrows()
|
||||
ncols = block.ncols()
|
||||
for row in block:
|
||||
print(row)
|
||||
values = block.fetchall()
|
||||
print(nrows, ncols)
|
||||
|
||||
# consumer.commit(message)
|
||||
else:
|
||||
break
|
||||
|
||||
consumer.close()
|
|
@ -4,6 +4,7 @@ description: '快速设置 TDengine 环境并体验其高效写入和查询'
|
|||
---
|
||||
|
||||
import xiaot from './xiaot.webp'
|
||||
import xiaot_new from './xiaot-new.webp'
|
||||
import channel from './channel.webp'
|
||||
import official_account from './official-account.webp'
|
||||
|
||||
|
@ -35,13 +36,13 @@ TDengine 知识地图中涵盖了 TDengine 的各种知识点,揭示了各概
|
|||
|
||||
<table width="100%">
|
||||
<tr align="center">
|
||||
<td style={{padding:'1em 3em',border:0}}><img src={xiaot} alt="小 T 的二维码" width="200" /></td>
|
||||
<td style={{padding:'1em 3em',border:0}}><img src={xiaot_new} alt="小 T 的二维码" width="200" /></td>
|
||||
<td style={{padding:'1em 3em',border:0}}><img src={channel} alt="TDengine 微信视频号" width="200" /></td>
|
||||
<td style={{padding:'1em 3em',border:0}}><img src={official_account} alt="TDengine 微信公众号" width="200" /></td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td style={{padding:'1em 3em',border:0}}>加入“物联网大数据技术前沿群”<br/>与大家进行技术交流</td>
|
||||
<td style={{padding:'1em 3em',border:0}}>关注 TDengine 微信视频号<br/>收看技术直播与教学视频</td>
|
||||
<td style={{padding:'1em 3em',border:0}}>关注 TDengine 微信公众号<br/>阅读核心技术与行业案例文章</td>
|
||||
<td style={{padding:'1em 3em',border:0}}>加入“物联网大数据技术群”<br/>与大家进行技术交流</td>
|
||||
<td style={{padding:'1em 3em',border:0}}>关注 TDengine 视频号<br/>收看技术直播与教学视频</td>
|
||||
<td style={{padding:'1em 3em',border:0}}>关注 TDengine 公众号<br/>阅读技术文章与行业案例</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
|
@ -92,22 +92,21 @@ void close() throws SQLException;
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
class TaosConsumer():
|
||||
def __init__(self, *topics, **configs)
|
||||
class Consumer:
|
||||
def subscribe(self, topics):
|
||||
pass
|
||||
|
||||
def __iter__(self)
|
||||
def unsubscribe(self):
|
||||
pass
|
||||
|
||||
def __next__(self)
|
||||
def poll(self, timeout: float = 1.0):
|
||||
pass
|
||||
|
||||
def sync_next(self)
|
||||
|
||||
def subscription(self)
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def unsubscribe(self)
|
||||
|
||||
def close(self)
|
||||
|
||||
def __del__(self)
|
||||
def commit(self, message):
|
||||
pass
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -115,19 +114,22 @@ class TaosConsumer():
|
|||
<TabItem label="Go" value="Go">
|
||||
|
||||
```go
|
||||
func NewConsumer(conf *Config) (*Consumer, error)
|
||||
func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)
|
||||
|
||||
func (c *Consumer) Close() error
|
||||
// 出于兼容目的保留 rebalanceCb 参数,当前未使用
|
||||
func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error
|
||||
|
||||
func (c *Consumer) Commit(ctx context.Context, message unsafe.Pointer) error
|
||||
// 出于兼容目的保留 rebalanceCb 参数,当前未使用
|
||||
func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error
|
||||
|
||||
func (c *Consumer) FreeMessage(message unsafe.Pointer)
|
||||
func (c *Consumer) Poll(timeoutMs int) tmq.Event
|
||||
|
||||
func (c *Consumer) Poll(timeout time.Duration) (*Result, error)
|
||||
|
||||
func (c *Consumer) Subscribe(topics []string) error
|
||||
// 出于兼容目的保留 tmq.TopicPartition 参数,当前未使用
|
||||
func (c *Consumer) Commit() ([]tmq.TopicPartition, error)
|
||||
|
||||
func (c *Consumer) Unsubscribe() error
|
||||
|
||||
func (c *Consumer) Close() error
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -355,50 +357,20 @@ public class MetersDeserializer extends ReferenceDeserializer<Meters> {
|
|||
<TabItem label="Go" value="Go">
|
||||
|
||||
```go
|
||||
config := tmq.NewConfig()
|
||||
defer config.Destroy()
|
||||
err = config.SetGroupID("test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetAutoOffsetReset("earliest")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectIP("127.0.0.1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectUser("root")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPass("taosdata")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetConnectPort("6030")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.SetMsgWithTableName(true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableHeartBeat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = config.EnableAutoCommit(func(result *wrapper.TMQCommitCallbackResult) {
|
||||
if result.ErrCode != 0 {
|
||||
errStr := wrapper.TMQErr2Str(result.ErrCode)
|
||||
err := errors.NewError(int(result.ErrCode), errStr)
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
conf := &tmq.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "earliest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_c",
|
||||
"enable.auto.commit": "false",
|
||||
"enable.heartbeat.background": "true",
|
||||
"experimental.snapshot.enable": "true",
|
||||
"msg.with.table.name": "true",
|
||||
}
|
||||
consumer, err := NewConsumer(conf)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -420,34 +392,33 @@ let mut consumer = tmq.build()?;
|
|||
|
||||
<TabItem value="Python" label="Python">
|
||||
|
||||
Python 语言下引入 `taos` 库的 `TaosConsumer` 类,创建一个 Consumer 示例:
|
||||
Python 语言下引入 `taos` 库的 `Consumer` 类,创建一个 Consumer 示例:
|
||||
|
||||
```python
|
||||
from taos.tmq import TaosConsumer
|
||||
from taos.tmq import Consumer
|
||||
|
||||
# Syntax: `consumer = TaosConsumer(*topics, **args)`
|
||||
# Syntax: `consumer = Consumer(configs)`
|
||||
#
|
||||
# Example:
|
||||
consumer = TaosConsumer('topic1', 'topic2', td_connect_ip = "127.0.0.1", group_id = "local")
|
||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||
```
|
||||
|
||||
其中,元组类型参数被视为 *Topics*,字典类型参数用于以下订阅配置设置:
|
||||
其中,`configs` 为 dict 类型,传递创建 Consumer 的参数。可以配置的参数有:
|
||||
|
||||
| 参数名称 | 类型 | 参数说明 | 备注 |
|
||||
| :----------------------------: | :----: | -------------------------------------------------------- | ------------------------------------------- |
|
||||
| `td_connect_ip` | string | 用于创建连接,同 `taos_connect` | |
|
||||
| `td_connect_user` | string | 用于创建连接,同 `taos_connect` | |
|
||||
| `td_connect_pass` | string | 用于创建连接,同 `taos_connect` | |
|
||||
| `td_connect_port` | string | 用于创建连接,同 `taos_connect` | |
|
||||
| `group_id` | string | 消费组 ID,同一消费组共享消费进度 | **必填项**。最大长度:192。 |
|
||||
| `client_id` | string | 客户端 ID | 最大长度:192。 |
|
||||
| `auto_offset_reset` | string | 消费组订阅的初始位置 | 可选:`earliest`(default), `latest`, `none` |
|
||||
| `enable_auto_commit` | string | 启用自动提交 | 合法值:`true`, `false`,默认为 true |
|
||||
| `auto_commit_interval_ms` | string | 以毫秒为单位的自动提交时间间隔 | 默认值:5000 ms |
|
||||
| `enable_heartbeat_background` | string | 启用后台心跳,启用后即使长时间不 poll 消息也不会造成离线 | 合法值:`true`, `false` |
|
||||
| `experimental_snapshot_enable` | string | 是否允许从 TSDB 消费数据 | 合法值:`true`, `false` |
|
||||
| `msg_with_table_name` | string | 是否允许从消息中解析表名,不适用于列订阅 | 合法值:`true`, `false` |
|
||||
| `timeout` | int | 消费者拉取数据的超时时间 | |
|
||||
| 参数名称 | 类型 | 参数说明 | 备注 |
|
||||
|:------:|:----:|:-------:|:---:|
|
||||
| `td.connect.ip` | string | 用于创建连接||
|
||||
| `td.connect.user` | string | 用于创建连接||
|
||||
| `td.connect.pass` | string | 用于创建连接||
|
||||
| `td.connect.port` | string | 用于创建连接||
|
||||
| `group.id` | string | 消费组 ID,同一消费组共享消费进度 | **必填项**。最大长度:192 |
|
||||
| `client.id` | string | 客户端 ID | 最大长度:192 |
|
||||
| `msg.with.table.name` | string | 是否允许从消息中解析表名,不适用于列订阅 | 合法值:`true`, `false` |
|
||||
| `enable.auto.commit` | string | 启用自动提交 | 合法值:`true`, `false` |
|
||||
| `auto.commit.interval.ms` | string | 以毫秒为单位的自动提交时间间隔 | 默认值:5000 ms |
|
||||
| `auto.offset.reset` | string | 消费组订阅的初始位置 | 可选:`earliest`(default), `latest`, `none` |
|
||||
| `experimental.snapshot.enable` | string | 是否允许从 TSDB 消费数据 | 合法值:`true`, `false` |
|
||||
| `enable.heartbeat.background` | string | 启用后台心跳,启用后即使长时间不 poll 消息也不会造成离线 | 合法值:`true`, `false` |
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
@ -532,11 +503,7 @@ consumer.subscribe(topics);
|
|||
<TabItem value="Go" label="Go">
|
||||
|
||||
```go
|
||||
consumer, err := tmq.NewConsumer(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe([]string{"example_tmq_topic"})
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -554,7 +521,7 @@ consumer.subscribe(["tmq_meters"]).await?;
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
consumer = TaosConsumer('topic_ctb_column', group_id='vg2')
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -620,13 +587,17 @@ while(running){
|
|||
|
||||
```go
|
||||
for {
|
||||
result, err := consumer.Poll(time.Second)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
ev := consumer.Poll(0)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Println(e.Value())
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
fmt.Println(result)
|
||||
consumer.Commit(context.Background(), result.Message)
|
||||
consumer.FreeMessage(result.Message)
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -669,9 +640,17 @@ for {
|
|||
<TabItem value="Python" label="Python">
|
||||
|
||||
```python
|
||||
for msg in consumer:
|
||||
for row in msg:
|
||||
print(row)
|
||||
while True:
|
||||
res = consumer.poll(100)
|
||||
if not res:
|
||||
continue
|
||||
err = res.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = res.value()
|
||||
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -738,7 +717,11 @@ consumer.close();
|
|||
<TabItem value="Go" label="Go">
|
||||
|
||||
```go
|
||||
consumer.Close()
|
||||
/* Unsubscribe */
|
||||
_ = consumer.Unsubscribe()
|
||||
|
||||
/* Close consumer */
|
||||
_ = consumer.Close()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
@ -15,7 +15,7 @@ import GoOpenTSDBTelnet from "../07-develop/03-insert-data/_go_opts_telnet.mdx"
|
|||
import GoOpenTSDBJson from "../07-develop/03-insert-data/_go_opts_json.mdx"
|
||||
import GoQuery from "../07-develop/04-query-data/_go.mdx"
|
||||
|
||||
`driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言[ database/sql ](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。
|
||||
`driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。
|
||||
|
||||
`driver-go` 提供两种建立连接的方式。一种是**原生连接**,它通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 运行实例,支持数据写入、查询、订阅、schemaless 接口和参数绑定接口等功能。另外一种是 **REST 连接**,它通过 taosAdapter 提供的 REST 接口连接 TDengine 运行实例。REST 连接实现的功能特性集合和原生连接有少量不同。
|
||||
|
||||
|
@ -112,6 +112,7 @@ REST 连接支持所有能运行 Go 的平台。
|
|||
```text
|
||||
username:password@protocol(address)/dbname?param=value
|
||||
```
|
||||
|
||||
### 使用连接器进行连接
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
|
@ -176,6 +177,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket 连接">
|
||||
|
||||
|
@ -207,6 +209,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
@ -357,33 +360,32 @@ func main() {
|
|||
|
||||
#### 订阅
|
||||
|
||||
* `func NewConsumer(conf *Config) (*Consumer, error)`
|
||||
* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)`
|
||||
|
||||
创建消费者。
|
||||
创建消费者。
|
||||
|
||||
* `func (c *Consumer) Subscribe(topics []string) error`
|
||||
* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error`
|
||||
注意:出于兼容目的保留 `rebalanceCb` 参数,当前未使用
|
||||
|
||||
订阅主题。
|
||||
订阅单个主题。
|
||||
|
||||
* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
|
||||
* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error`
|
||||
注意:出于兼容目的保留 `rebalanceCb` 参数,当前未使用
|
||||
|
||||
轮询消息。
|
||||
订阅主题。
|
||||
|
||||
* `func (c *Consumer) Commit(ctx context.Context, message unsafe.Pointer) error`
|
||||
* `func (c *Consumer) Poll(timeoutMs int) tmq.Event`
|
||||
|
||||
提交消息。
|
||||
轮询消息。
|
||||
|
||||
* `func (c *Consumer) FreeMessage(message unsafe.Pointer)`
|
||||
* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)`
|
||||
注意:出于兼容目的保留 `tmq.TopicPartition` 参数,当前未使用
|
||||
|
||||
释放消息。
|
||||
|
||||
* `func (c *Consumer) Unsubscribe() error`
|
||||
|
||||
取消订阅。
|
||||
提交消息。
|
||||
|
||||
* `func (c *Consumer) Close() error`
|
||||
|
||||
关闭消费者。
|
||||
关闭连接。
|
||||
|
||||
#### schemaless
|
||||
|
||||
|
@ -443,25 +445,32 @@ func main() {
|
|||
|
||||
### 通过 WebSocket 订阅
|
||||
|
||||
* `func NewConsumer(config *Config) (*Consumer, error)`
|
||||
* `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)`
|
||||
|
||||
创建消费者。
|
||||
创建消费者。
|
||||
|
||||
* `func (c *Consumer) Subscribe(topic []string) error`
|
||||
* `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error`
|
||||
注意:出于兼容目的保留 `rebalanceCb` 参数,当前未使用
|
||||
|
||||
订阅主题。
|
||||
订阅单个主题。
|
||||
|
||||
* `func (c *Consumer) Poll(timeout time.Duration) (*Result, error)`
|
||||
* `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error`
|
||||
注意:出于兼容目的保留 `rebalanceCb` 参数,当前未使用
|
||||
|
||||
轮询消息。
|
||||
订阅主题。
|
||||
|
||||
* `func (c *Consumer) Commit(messageID uint64) error`
|
||||
* `func (c *Consumer) Poll(timeoutMs int) tmq.Event`
|
||||
|
||||
提交消息。
|
||||
轮询消息。
|
||||
|
||||
* `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)`
|
||||
注意:出于兼容目的保留 `tmq.TopicPartition` 参数,当前未使用
|
||||
|
||||
提交消息。
|
||||
|
||||
* `func (c *Consumer) Close() error`
|
||||
|
||||
关闭消费者。
|
||||
关闭连接。
|
||||
|
||||
完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/driver-go/blob/3.0/examples/tmqoverws/main.go)
|
||||
|
||||
|
|
|
@ -78,6 +78,14 @@ pip3 install git+https://github.com/taosdata/taos-connector-python.git
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 安装 `taos-ws`(可选)
|
||||
|
||||
taos-ws 提供了通过 websocket 连接 TDengine 的能力,可选安装 taos-ws 以获得 websocket 连接 TDengine 的能力。
|
||||
|
||||
```
|
||||
pip3 install taos-ws-py
|
||||
```
|
||||
|
||||
### 安装验证
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
|
@ -306,6 +314,30 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 数据订阅
|
||||
|
||||
连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅](../../develop/tmq/)。
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<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)。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_example.py}}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="rest" label="websocket 连接">
|
||||
|
||||
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 其它示例程序
|
||||
|
||||
| 示例程序链接 | 示例程序内容 |
|
||||
|
@ -314,7 +346,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线
|
|||
| [bind_row.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-row.py) | 参数绑定,一次绑定一行 |
|
||||
| [insert_lines.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/insert-lines.py) | InfluxDB 行协议写入 |
|
||||
| [json_tag.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/json-tag.py) | 使用 JSON 类型的标签 |
|
||||
| [tmq.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/tmq.py) | tmq 订阅 |
|
||||
| [tmq_consumer.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/tmq_consumer.py) | tmq 订阅 |
|
||||
|
||||
## 其它说明
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx"
|
|||
|
||||
`TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。
|
||||
|
||||
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 `TDengine.Connector` 还支持 WebSocket,通过 DSN 建立 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。
|
||||
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 `TDengine.Connector` 自 v3.0.1 起还支持 WebSocket,通过 DSN 建立 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。
|
||||
|
||||
本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。
|
||||
|
||||
|
@ -67,30 +67,45 @@ import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx"
|
|||
* [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装)
|
||||
* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
|
||||
|
||||
### 使用 dotnet CLI 安装
|
||||
### 安装 TDengine.Connector
|
||||
|
||||
<Tabs defaultValue="CLI">
|
||||
<TabItem value="CLI" label="使用 dotnet CLI 获取 C# 驱动">
|
||||
<TabItem value="CLI" label="使用本地连接">
|
||||
|
||||
可以在当前 .NET 项目的路径下,通过 dotnet 命令引用 Nuget 中发布的 `TDengine.Connector` 到当前项目。
|
||||
可以在当前 .NET 项目的路径下,通过 dotnet CLI 添加 Nuget package `TDengine.Connector` 到当前项目。
|
||||
|
||||
``` bash
|
||||
dotnet add package TDengine.Connector
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="source" label="使用源码获取 C# 驱动">
|
||||
也可以修改当前项目的 `.csproj` 文件,添加如下 ItemGroup。
|
||||
|
||||
也可以[下载源码](https://github.com/taosdata/taos-connector-dotnet/tree/3.0),直接引用 TDengine.Connector 库
|
||||
|
||||
```bash
|
||||
git clone -b 3.0 https://github.com/taosdata/taos-connector-dotnet.git
|
||||
cd taos-connector-dotnet
|
||||
cp -r src/ myProject
|
||||
|
||||
cd myProject
|
||||
dotnet add exmaple.csproj reference src/TDengine.csproj
|
||||
``` XML
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="source" label="使用 WebSocket 连接">
|
||||
|
||||
需要修改目标项目的 `.csproj` 项目文件,将 `.nupkg` 中的 `runtimes` 目录中的动态库复制到当前项目的 `$(OutDir)` 目录下。
|
||||
|
||||
```XML
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Target Name="copyDLLDepency" BeforeTargets="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
```
|
||||
|
||||
注意:`TDengine.Connector` 自 version>= 3.0.2 的 nuget package 中才会有动态库( taosws.dll,libtaows.so )。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
@ -148,9 +163,9 @@ namespace TDengineExample
|
|||
|
||||
各部分意义见下表:
|
||||
|
||||
* **protocol**: 显示指定以何种方式建立连接,例如:`ws://localhost:6041` 指定以 Websocket 方式建立连接(支持http/ws)。
|
||||
* **protocol**: 显示指定以何种方式建立连接,例如:`ws://localhost:6041` 指定以 Websocket 方式建立连接(支持 http/ws )。
|
||||
|
||||
* **username/password**: 用于创建连接的用户名及密码(默认`root/taosdata`)。
|
||||
* **username/password**: 用于创建连接的用户名及密码(默认 `root/taosdata` )。
|
||||
|
||||
* **host/port**: 指定创建连接的服务器及端口,WebSocket 连接默认为 `localhost:6041` 。
|
||||
|
||||
|
@ -266,6 +281,7 @@ namespace TDengineExample
|
|||
|
||||
| TDengine.Connector | 说明 |
|
||||
|--------------------|--------------------------------|
|
||||
| 3.0.2 | 支持 .NET Framework 4.5 及以上,支持 .NET standard 2.0。Nuget Package 包含 WebSocket 动态库。 |
|
||||
| 3.0.1 | 支持 WebSocket 和 Cloud,查询,插入,参数绑定。 |
|
||||
| 3.0.0 | 支持 TDengine 3.0.0.0,不兼容 2.x。新增接口TDengine.Impl.GetData(),解析查询结果。 |
|
||||
| 1.0.7 | 修复 TDengine.Query()内存泄露。 |
|
||||
|
|
|
@ -4,7 +4,7 @@ title: 使用 Helm 部署 TDengine 集群
|
|||
description: 使用 Helm 部署 TDengine 集群的详细指南
|
||||
---
|
||||
|
||||
Helm 是 Kubernetes 的包管理器,上一节使用 Kubernets 部署 TDengine 集群的操作已经足够简单,但 Helm 依然可以提供更强大的能力。
|
||||
Helm 是 Kubernetes 的包管理器,上一节使用 Kubernetes 部署 TDengine 集群的操作已经足够简单,但 Helm 依然可以提供更强大的能力。
|
||||
|
||||
## 安装 Helm
|
||||
|
||||
|
@ -23,7 +23,7 @@ Helm 会使用 kubectl 和 kubeconfig 的配置来操作 Kubernetes,可以参
|
|||
TDengine Chart 尚未发布到 Helm 仓库,当前可以从 GitHub 直接下载:
|
||||
|
||||
```bash
|
||||
wget https://github.com/taosdata/TDengine-Operator/raw/3.0/helm/tdengine-3.0.0.tgz
|
||||
wget https://github.com/taosdata/TDengine-Operator/raw/3.0/helm/tdengine-3.0.2.tgz
|
||||
|
||||
```
|
||||
|
||||
|
@ -39,7 +39,7 @@ kubectl get storageclass
|
|||
之后,使用 helm 命令安装:
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz \
|
||||
helm install tdengine tdengine-3.0.2.tgz \
|
||||
--set storage.className=<your storage class name>
|
||||
|
||||
```
|
||||
|
@ -47,7 +47,7 @@ helm install tdengine tdengine-3.0.0.tgz \
|
|||
在 minikube 环境下,可以设置一个较小的容量避免超出磁盘可用空间:
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz \
|
||||
helm install tdengine tdengine-3.0.2.tgz \
|
||||
--set storage.className=standard \
|
||||
--set storage.dataSize=2Gi \
|
||||
--set storage.logSize=10Mi
|
||||
|
@ -84,14 +84,14 @@ TDengine 支持 `values.yaml` 自定义。
|
|||
通过 helm show values 可以获取 TDengine Chart 支持的全部 values 列表:
|
||||
|
||||
```bash
|
||||
helm show values tdengine-3.0.0.tgz
|
||||
helm show values tdengine-3.0.2.tgz
|
||||
|
||||
```
|
||||
|
||||
你可以将结果保存为 values.yaml,之后可以修改其中的各项参数,如 replica 数量,存储类名称,容量大小,TDengine 配置等,然后使用如下命令安装 TDengine 集群:
|
||||
|
||||
```bash
|
||||
helm install tdengine tdengine-3.0.0.tgz -f values.yaml
|
||||
helm install tdengine tdengine-3.0.2.tgz -f values.yaml
|
||||
|
||||
```
|
||||
|
||||
|
@ -108,7 +108,7 @@ image:
|
|||
prefix: tdengine/tdengine
|
||||
#pullPolicy: Always
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
# tag: "3.0.0.0"
|
||||
# tag: "3.0.2.0"
|
||||
|
||||
service:
|
||||
# ClusterIP is the default service type, use NodeIP only if you know what you are doing.
|
||||
|
@ -156,15 +156,15 @@ clusterDomainSuffix: ""
|
|||
# See the variable list at https://www.taosdata.com/cn/documentation/administrator .
|
||||
#
|
||||
# Note:
|
||||
# 1. firstEp/secondEp: should not be setted here, it's auto generated at scale-up.
|
||||
# 2. serverPort: should not be setted, we'll use the default 6030 in many places.
|
||||
# 3. fqdn: will be auto generated in kubenetes, user should not care about it.
|
||||
# 1. firstEp/secondEp: should not be set here, it's auto generated at scale-up.
|
||||
# 2. serverPort: should not be set, we'll use the default 6030 in many places.
|
||||
# 3. fqdn: will be auto generated in kubernetes, user should not care about it.
|
||||
# 4. role: currently role is not supported - every node is able to be mnode and vnode.
|
||||
#
|
||||
# Btw, keep quotes "" around the value like below, even the value will be number or not.
|
||||
taoscfg:
|
||||
# Starts as cluster or not, must be 0 or 1.
|
||||
# 0: all pods will start as a seperate TDengine server
|
||||
# 0: all pods will start as a separate TDengine server
|
||||
# 1: pods will start as TDengine server cluster. [default]
|
||||
CLUSTER: "1"
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@ TDengine 2.x 各版本安装包请访问[这里](https://www.taosdata.com/all-do
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 3.0.2.4
|
||||
|
||||
<Release type="tdengine" version="3.0.2.4" />
|
||||
|
||||
## 3.0.2.3
|
||||
|
||||
<Release type="tdengine" version="3.0.2.3" />
|
||||
|
|
|
@ -10,6 +10,10 @@ taosTools 各版本安装包下载链接如下:
|
|||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 2.4.2
|
||||
|
||||
<Release type="tools" version="2.4.2" />
|
||||
|
||||
## 2.4.1
|
||||
|
||||
<Release type="tools" version="2.4.1" />
|
||||
|
|
|
@ -208,6 +208,7 @@ DLL_EXPORT TAOS_ROW *taos_result_block(TAOS_RES *res);
|
|||
|
||||
DLL_EXPORT const char *taos_get_server_info(TAOS *taos);
|
||||
DLL_EXPORT const char *taos_get_client_info();
|
||||
DLL_EXPORT int taos_get_current_db(TAOS *taos, char *database, int len, int *required);
|
||||
|
||||
DLL_EXPORT const char *taos_errstr(TAOS_RES *res);
|
||||
DLL_EXPORT int taos_errno(TAOS_RES *res);
|
||||
|
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
#define TSDB_INS_TABLE_STABLES "ins_stables"
|
||||
#define TSDB_INS_TABLE_TABLES "ins_tables"
|
||||
#define TSDB_INS_TABLE_TAGS "ins_tags"
|
||||
#define TSDB_INS_TABLE_COLS "ins_columns"
|
||||
#define TSDB_INS_TABLE_TABLE_DISTRIBUTED "ins_table_distributed"
|
||||
#define TSDB_INS_TABLE_USERS "ins_users"
|
||||
#define TSDB_INS_TABLE_LICENCES "ins_grants"
|
||||
|
|
|
@ -41,6 +41,12 @@ typedef struct SBlockOrderInfo {
|
|||
BMCharPos(bm_, r_) |= (1u << (7u - BitPos(r_))); \
|
||||
} while (0)
|
||||
|
||||
#define colDataSetNull_f_s(c_, r_) \
|
||||
do { \
|
||||
colDataSetNull_f((c_)->nullbitmap, r_); \
|
||||
memset(((char*)(c_)->pData) + (c_)->info.bytes * (r_), 0, (c_)->info.bytes); \
|
||||
} while (0)
|
||||
|
||||
#define colDataClearNull_f(bm_, r_) \
|
||||
do { \
|
||||
BMCharPos(bm_, r_) &= ((char)(~(1u << (7u - BitPos(r_))))); \
|
||||
|
@ -136,7 +142,7 @@ static FORCE_INLINE void colDataAppendNULL(SColumnInfoData* pColumnInfoData, uin
|
|||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
colDataSetNull_var(pColumnInfoData, currentRow); // it is a null value of VAR type.
|
||||
} else {
|
||||
colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow);
|
||||
colDataSetNull_f_s(pColumnInfoData, currentRow);
|
||||
}
|
||||
|
||||
pColumnInfoData->hasNull = true;
|
||||
|
@ -151,6 +157,7 @@ static FORCE_INLINE void colDataAppendNNULL(SColumnInfoData* pColumnInfoData, ui
|
|||
for (int32_t i = start; i < start + nRows; ++i) {
|
||||
colDataSetNull_f(pColumnInfoData->nullbitmap, i);
|
||||
}
|
||||
memset(pColumnInfoData->pData + start * pColumnInfoData->info.bytes, 0, pColumnInfoData->info.bytes * nRows);
|
||||
}
|
||||
|
||||
pColumnInfoData->hasNull = true;
|
||||
|
@ -231,7 +238,6 @@ int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullF
|
|||
|
||||
int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows, bool clearPayload);
|
||||
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows);
|
||||
int32_t blockDataEnsureCapacityNoClear(SSDataBlock* pDataBlock, uint32_t numOfRows);
|
||||
|
||||
void colInfoDataCleanup(SColumnInfoData* pColumn, uint32_t numOfRows);
|
||||
void blockDataCleanup(SSDataBlock* pDataBlock);
|
||||
|
|
|
@ -115,6 +115,7 @@ typedef enum _mgmt_table {
|
|||
TSDB_MGMT_TABLE_STREAMS,
|
||||
TSDB_MGMT_TABLE_TABLE,
|
||||
TSDB_MGMT_TABLE_TAG,
|
||||
TSDB_MGMT_TABLE_COL,
|
||||
TSDB_MGMT_TABLE_USER,
|
||||
TSDB_MGMT_TABLE_GRANTS,
|
||||
TSDB_MGMT_TABLE_VGROUP,
|
||||
|
@ -345,8 +346,13 @@ void tFreeSSubmitRsp(SSubmitRsp* pRsp);
|
|||
#define COL_IS_SET(FLG) (((FLG) & (COL_SET_VAL | COL_SET_NULL)) != 0)
|
||||
#define COL_CLR_SET(FLG) ((FLG) &= (~(COL_SET_VAL | COL_SET_NULL)))
|
||||
|
||||
<<<<<<< HEAD
|
||||
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == COL_SMA_ON)
|
||||
#define IS_IDX_ON(s) (((s)->flags & 0x2) == COL_IDX_ON)
|
||||
=======
|
||||
#define IS_BSMA_ON(s) (((s)->flags & 0x01) == COL_SMA_ON)
|
||||
#define IS_SET_NULL(s) (((s)->flags & COL_SET_NULL) == COL_SET_NULL)
|
||||
>>>>>>> origin/3.0
|
||||
|
||||
#define SSCHMEA_TYPE(s) ((s)->type)
|
||||
#define SSCHMEA_FLAGS(s) ((s)->flags)
|
||||
|
@ -384,6 +390,13 @@ static FORCE_INLINE void tDeleteSSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSSchemaWrapperForHash(void* pSchemaWrapper) {
|
||||
if (pSchemaWrapper != NULL && *(SSchemaWrapper**)pSchemaWrapper != NULL) {
|
||||
taosMemoryFree((*(SSchemaWrapper**)pSchemaWrapper)->pSchema);
|
||||
taosMemoryFree(*(SSchemaWrapper**)pSchemaWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t taosEncodeSSchema(void** buf, const SSchema* pSchema) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI8(buf, pSchema->type);
|
||||
|
@ -1395,6 +1408,7 @@ typedef struct {
|
|||
char db[TSDB_DB_FNAME_LEN];
|
||||
char tb[TSDB_TABLE_NAME_LEN];
|
||||
char user[TSDB_USER_LEN];
|
||||
char filterTb[TSDB_TABLE_NAME_LEN];
|
||||
int64_t showId;
|
||||
} SRetrieveTableReq;
|
||||
|
||||
|
@ -1757,6 +1771,12 @@ typedef struct {
|
|||
#define STREAM_CREATE_STABLE_TRUE 1
|
||||
#define STREAM_CREATE_STABLE_FALSE 0
|
||||
|
||||
typedef struct SColLocation {
|
||||
int16_t slotId;
|
||||
col_id_t colId;
|
||||
int8_t type;
|
||||
} SColLocation;
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_STREAM_FNAME_LEN];
|
||||
char sourceDB[TSDB_DB_FNAME_LEN];
|
||||
|
@ -1774,7 +1794,9 @@ typedef struct {
|
|||
// 3.0.20
|
||||
int64_t checkpointFreq; // ms
|
||||
// 3.0.2.3
|
||||
int8_t createStb;
|
||||
int8_t createStb;
|
||||
uint64_t targetStbUid;
|
||||
SArray* fillNullCols; // array of SColLocation
|
||||
} SCMCreateStreamReq;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef enum {
|
|||
QUEUE_MAX,
|
||||
} EQueueType;
|
||||
|
||||
typedef int32_t (*UpdateDnodeInfoFp)(void* pData, int32_t* dnodeId, int64_t* clusterId, char* fqdn, uint16_t* port);
|
||||
typedef bool (*UpdateDnodeInfoFp)(void* pData, int32_t* dnodeId, int64_t* clusterId, char* fqdn, uint16_t* port);
|
||||
typedef int32_t (*PutToQueueFp)(void* pMgmt, EQueueType qtype, SRpcMsg* pMsg);
|
||||
typedef int32_t (*GetQueueSizeFp)(void* pMgmt, int32_t vgId, EQueueType qtype);
|
||||
typedef int32_t (*SendReqFp)(const SEpSet* pEpSet, SRpcMsg* pMsg);
|
||||
|
@ -70,7 +70,8 @@ void tmsgSendRsp(SRpcMsg* pMsg);
|
|||
void tmsgRegisterBrokenLinkArg(SRpcMsg* pMsg);
|
||||
void tmsgReleaseHandle(SRpcHandleInfo* pHandle, int8_t type);
|
||||
void tmsgReportStartup(const char* name, const char* desc);
|
||||
int32_t tmsgUpdateDnodeInfo(int32_t* dnodeId, int64_t* clusterId, char* fqdn, uint16_t* port);
|
||||
bool tmsgUpdateDnodeInfo(int32_t* dnodeId, int64_t* clusterId, char* fqdn, uint16_t* port);
|
||||
void tmsgUpdateDnodeEpSet(SEpSet* epset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -501,7 +501,7 @@ enum {
|
|||
#define DEFAULT_PAGESIZE 4096
|
||||
|
||||
#define VNODE_TIMEOUT_SEC 60
|
||||
#define MNODE_TIMEOUT_SEC 10
|
||||
#define MNODE_TIMEOUT_SEC 60
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -365,6 +365,7 @@ void doDestroyRequest(void *p) {
|
|||
taosMemoryFreeClear(pRequest->pDb);
|
||||
|
||||
doFreeReqResultInfo(&pRequest->body.resInfo);
|
||||
tsem_destroy(&pRequest->body.rspSem);
|
||||
|
||||
taosArrayDestroy(pRequest->tableList);
|
||||
taosArrayDestroy(pRequest->dbList);
|
||||
|
@ -379,6 +380,9 @@ void doDestroyRequest(void *p) {
|
|||
}
|
||||
|
||||
if (pRequest->syncQuery) {
|
||||
if (pRequest->body.param){
|
||||
tsem_destroy(&((SSyncQueryParam*)pRequest->body.param)->sem);
|
||||
}
|
||||
taosMemoryFree(pRequest->body.param);
|
||||
}
|
||||
|
||||
|
@ -428,7 +432,11 @@ _return:
|
|||
|
||||
taosLogCrashInfo("taos", pMsg, msgLen, signum, sigInfo);
|
||||
|
||||
#ifdef _TD_DARWIN_64
|
||||
exit(signum);
|
||||
#elif defined(WINDOWS)
|
||||
exit(signum);
|
||||
#endif
|
||||
}
|
||||
|
||||
void crashReportThreadFuncUnexpectedStopped(void) { atomic_store_32(&clientStop, -1); }
|
||||
|
|
|
@ -159,6 +159,12 @@ STscObj* taos_connect_internal(const char* ip, const char* user, const char* pas
|
|||
return taosConnectImpl(user, &secretEncrypt[0], localDb, NULL, NULL, *pInst, connType);
|
||||
}
|
||||
|
||||
void freeQueryParam(SSyncQueryParam* param) {
|
||||
if (param == NULL) return;
|
||||
tsem_destroy(¶m->sem);
|
||||
taosMemoryFree(param);
|
||||
}
|
||||
|
||||
int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql,
|
||||
SRequestObj** pRequest, int64_t reqid) {
|
||||
*pRequest = createRequest(connId, TSDB_SQL_SELECT, reqid);
|
||||
|
@ -180,17 +186,18 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
|
|||
(*pRequest)->sqlLen = sqlLen;
|
||||
(*pRequest)->validateOnly = validateSql;
|
||||
|
||||
SSyncQueryParam* newpParam;
|
||||
if (param == NULL) {
|
||||
SSyncQueryParam* pParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
|
||||
if (pParam == NULL) {
|
||||
newpParam = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
|
||||
if (newpParam == NULL) {
|
||||
destroyRequest(*pRequest);
|
||||
*pRequest = NULL;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
tsem_init(&pParam->sem, 0, 0);
|
||||
pParam->pRequest = (*pRequest);
|
||||
param = pParam;
|
||||
tsem_init(&newpParam->sem, 0, 0);
|
||||
newpParam->pRequest = (*pRequest);
|
||||
param = newpParam;
|
||||
}
|
||||
|
||||
(*pRequest)->body.param = param;
|
||||
|
@ -201,8 +208,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
|
|||
if (err) {
|
||||
tscError("%" PRId64 " failed to add to request container, reqId:0x%" PRIx64 ", conn:%" PRId64 ", %s",
|
||||
(*pRequest)->self, (*pRequest)->requestId, pTscObj->id, sql);
|
||||
|
||||
taosMemoryFree(param);
|
||||
freeQueryParam(newpParam);
|
||||
destroyRequest(*pRequest);
|
||||
*pRequest = NULL;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -214,6 +220,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param,
|
|||
nodesCreateAllocator((*pRequest)->requestId, tsQueryNodeChunkSize, &((*pRequest)->allocatorRefId))) {
|
||||
tscError("%" PRId64 " failed to create node allocator, reqId:0x%" PRIx64 ", conn:%" PRId64 ", %s",
|
||||
(*pRequest)->self, (*pRequest)->requestId, pTscObj->id, sql);
|
||||
freeQueryParam(newpParam);
|
||||
destroyRequest(*pRequest);
|
||||
*pRequest = NULL;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
|
|
@ -435,6 +435,22 @@ const char *taos_data_type(int type) {
|
|||
return "TSDB_DATA_TYPE_NCHAR";
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
return "TSDB_DATA_TYPE_JSON";
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
return "TSDB_DATA_TYPE_UTINYINT";
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
return "TSDB_DATA_TYPE_USMALLINT";
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
return "TSDB_DATA_TYPE_UINT";
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
return "TSDB_DATA_TYPE_UBIGINT";
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
return "TSDB_DATA_TYPE_VARBINARY";
|
||||
case TSDB_DATA_TYPE_DECIMAL:
|
||||
return "TSDB_DATA_TYPE_DECIMAL";
|
||||
case TSDB_DATA_TYPE_BLOB:
|
||||
return "TSDB_DATA_TYPE_BLOB";
|
||||
case TSDB_DATA_TYPE_MEDIUMBLOB:
|
||||
return "TSDB_DATA_TYPE_MEDIUMBLOB";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
@ -675,6 +691,32 @@ const char *taos_get_server_info(TAOS *taos) {
|
|||
return pTscObj->sDetailVer;
|
||||
}
|
||||
|
||||
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
|
||||
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
|
||||
if (pTscObj == NULL) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int code = TSDB_CODE_SUCCESS;
|
||||
taosThreadMutexLock(&pTscObj->mutex);
|
||||
if(database == NULL || len <= 0){
|
||||
if(required != NULL) *required = strlen(pTscObj->db) + 1;
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
code = -1;
|
||||
}else if(len < strlen(pTscObj->db) + 1){
|
||||
tstrncpy(database, pTscObj->db, len);
|
||||
if(required) *required = strlen(pTscObj->db) + 1;
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
code = -1;
|
||||
}else{
|
||||
strcpy(database, pTscObj->db);
|
||||
code = 0;
|
||||
}
|
||||
taosThreadMutexUnlock(&pTscObj->mutex);
|
||||
return code;
|
||||
}
|
||||
|
||||
static void destoryTablesReq(void *p) {
|
||||
STablesReq *pRes = (STablesReq *)p;
|
||||
taosArrayDestroy(pRes->pTables);
|
||||
|
|
|
@ -521,7 +521,7 @@ STableMeta *smlGetMeta(SSmlHandle *info, const void *measure, int32_t measureLen
|
|||
memcpy(pName.tname, measure, measureLen);
|
||||
|
||||
int32_t code = catalogGetSTableMeta(info->pCatalog, &conn, &pName, &pTableMeta);
|
||||
if(code != TSDB_CODE_SUCCESS){
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
return pTableMeta;
|
||||
|
@ -996,7 +996,7 @@ static int32_t smlUpdateMeta(SHashObj *metaHash, SArray *metaArray, SArray *cols
|
|||
}
|
||||
} else {
|
||||
size_t tmp = taosArrayGetSize(metaArray);
|
||||
if(tmp > INT16_MAX){
|
||||
if (tmp > INT16_MAX) {
|
||||
uError("too many cols or tags");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1017,9 +1017,9 @@ void smlDestroyTableInfo(SSmlHandle *info, SSmlTableInfo *tag) {
|
|||
taosHashCleanup(kvHash);
|
||||
}
|
||||
|
||||
if(info->parseJsonByLib){
|
||||
if (info->parseJsonByLib) {
|
||||
SSmlLineInfo *key = (SSmlLineInfo *)(tag->key);
|
||||
if(key != NULL) taosMemoryFree(key->tags);
|
||||
if (key != NULL) taosMemoryFree(key->tags);
|
||||
}
|
||||
taosMemoryFree(tag->key);
|
||||
taosArrayDestroy(tag->cols);
|
||||
|
@ -1027,10 +1027,10 @@ void smlDestroyTableInfo(SSmlHandle *info, SSmlTableInfo *tag) {
|
|||
taosMemoryFree(tag);
|
||||
}
|
||||
|
||||
void clearColValArray(SArray* pCols) {
|
||||
void clearColValArray(SArray *pCols) {
|
||||
int32_t num = taosArrayGetSize(pCols);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SColVal* pCol = taosArrayGet(pCols, i);
|
||||
SColVal *pCol = taosArrayGet(pCols, i);
|
||||
if (TSDB_DATA_TYPE_NCHAR == pCol->type) {
|
||||
taosMemoryFreeClear(pCol->value.pData);
|
||||
}
|
||||
|
@ -1066,7 +1066,7 @@ void smlDestroyInfo(SSmlHandle *info) {
|
|||
// destroy info->pVgHash
|
||||
taosHashCleanup(info->pVgHash);
|
||||
|
||||
for(int i = 0; i< taosArrayGetSize(info->tagJsonArray); i++){
|
||||
for (int i = 0; i < taosArrayGetSize(info->tagJsonArray); i++) {
|
||||
cJSON *tags = (cJSON *)taosArrayGetP(info->tagJsonArray, i);
|
||||
cJSON_Delete(tags);
|
||||
}
|
||||
|
@ -1079,7 +1079,7 @@ void smlDestroyInfo(SSmlHandle *info) {
|
|||
if (!info->dataFormat) {
|
||||
for (int i = 0; i < info->lineNum; i++) {
|
||||
taosArrayDestroy(info->lines[i].colArray);
|
||||
if(info->parseJsonByLib){
|
||||
if (info->parseJsonByLib) {
|
||||
taosMemoryFree(info->lines[i].tags);
|
||||
}
|
||||
}
|
||||
|
@ -1232,7 +1232,7 @@ static int32_t smlInsertData(SSmlHandle *info) {
|
|||
|
||||
SSmlSTableMeta *pMeta =
|
||||
(SSmlSTableMeta *)nodeListGet(info->superTables, tableData->sTableName, tableData->sTableNameLen, NULL);
|
||||
if(unlikely(NULL == pMeta || NULL == pMeta->tableMeta)){
|
||||
if (unlikely(NULL == pMeta || NULL == pMeta->tableMeta)) {
|
||||
uError("SML:0x%" PRIx64 " NULL == pMeta. table name: %s", info->id, tableData->childTableName);
|
||||
return TSDB_CODE_SML_INTERNAL_ERROR;
|
||||
}
|
||||
|
@ -1300,7 +1300,7 @@ int32_t smlClearForRerun(SSmlHandle *info) {
|
|||
pList = pList->next;
|
||||
}
|
||||
|
||||
if (!info->dataFormat){
|
||||
if (!info->dataFormat) {
|
||||
if (unlikely(info->lines != NULL)) {
|
||||
uError("SML:0x%" PRIx64 " info->lines != NULL", info->id);
|
||||
return TSDB_CODE_SML_INVALID_DATA;
|
||||
|
|
|
@ -67,6 +67,8 @@ static const SSysDbTableSchema clusterSchema[] = {
|
|||
{.name = "name", .bytes = TSDB_CLUSTER_ID_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "uptime", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true},
|
||||
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true},
|
||||
{.name = "version", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "expire_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true},
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema userDBSchema[] = {
|
||||
|
@ -176,6 +178,18 @@ static const SSysDbTableSchema userTagsSchema[] = {
|
|||
{.name = "tag_value", .bytes = TSDB_MAX_TAGS_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema userColsSchema[] = {
|
||||
{.name = "table_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "table_type", .bytes = 21 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "col_name", .bytes = TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "col_type", .bytes = 32 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "col_length", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||
{.name = "col_precision", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||
{.name = "col_scale", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||
{.name = "col_nullable", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema userTblDistSchema[] = {
|
||||
{.name = "db_name", .bytes = 32 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
{.name = "table_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||
|
@ -292,6 +306,7 @@ static const SSysTableMeta infosMeta[] = {
|
|||
{TSDB_INS_TABLE_STABLES, userStbsSchema, tListLen(userStbsSchema), false},
|
||||
{TSDB_INS_TABLE_TABLES, userTblsSchema, tListLen(userTblsSchema), false},
|
||||
{TSDB_INS_TABLE_TAGS, userTagsSchema, tListLen(userTagsSchema), false},
|
||||
{TSDB_INS_TABLE_COLS, userColsSchema, tListLen(userColsSchema), false},
|
||||
// {TSDB_INS_TABLE_TABLE_DISTRIBUTED, userTblDistSchema, tListLen(userTblDistSchema)},
|
||||
{TSDB_INS_TABLE_USERS, userUsersSchema, tListLen(userUsersSchema), false},
|
||||
{TSDB_INS_TABLE_LICENCES, grantsSchema, tListLen(grantsSchema), true},
|
||||
|
|
|
@ -70,7 +70,7 @@ int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t currentRow, con
|
|||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
pColumnInfoData->varmeta.offset[currentRow] = -1; // it is a null value of VAR type.
|
||||
} else {
|
||||
colDataSetNull_f(pColumnInfoData->nullbitmap, currentRow);
|
||||
colDataSetNull_f_s(pColumnInfoData, currentRow);
|
||||
}
|
||||
|
||||
pColumnInfoData->hasNull = true;
|
||||
|
@ -315,8 +315,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int
|
|||
|
||||
int32_t colDataAssign(SColumnInfoData* pColumnInfoData, const SColumnInfoData* pSource, int32_t numOfRows,
|
||||
const SDataBlockInfo* pBlockInfo) {
|
||||
if (pColumnInfoData->info.type != pSource->info.type ||
|
||||
(pBlockInfo != NULL && pBlockInfo->capacity < numOfRows)) {
|
||||
if (pColumnInfoData->info.type != pSource->info.type || (pBlockInfo != NULL && pBlockInfo->capacity < numOfRows)) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -826,7 +825,7 @@ static int32_t blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataB
|
|||
} else {
|
||||
for (int32_t j = 0; j < pDataBlock->info.rows; ++j) {
|
||||
if (colDataIsNull_f(pSrc->nullbitmap, index[j])) {
|
||||
colDataSetNull_f(pDst->nullbitmap, j);
|
||||
colDataSetNull_f_s(pDst, j);
|
||||
continue;
|
||||
}
|
||||
memcpy(pDst->pData + j * pDst->info.bytes, pSrc->pData + index[j] * pDst->info.bytes, pDst->info.bytes);
|
||||
|
@ -1162,16 +1161,17 @@ void blockDataEmpty(SSDataBlock* pDataBlock) {
|
|||
pInfo->window.skey = 0;
|
||||
}
|
||||
|
||||
// todo temporarily disable it
|
||||
/*
|
||||
* NOTE: the type of the input column may be TSDB_DATA_TYPE_NULL, which is used to denote
|
||||
* the all NULL value in this column. It is an internal representation of all NULL value column, and no visible to
|
||||
* any users. The length of TSDB_DATA_TYPE_NULL is 0, and it is an special case.
|
||||
*/
|
||||
static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* pBlockInfo, uint32_t numOfRows,
|
||||
bool clearPayload) {
|
||||
if (numOfRows <= 0 || numOfRows <= pBlockInfo->capacity) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// todo temp disable it
|
||||
// ASSERT(pColumn->info.bytes != 0);
|
||||
|
||||
int32_t existedRows = pBlockInfo->rows;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColumn->info.type)) {
|
||||
|
@ -1196,7 +1196,8 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo*
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// make sure the allocated memory is MALLOC_ALIGN_BYTES aligned
|
||||
// here we employ the aligned malloc function, to make sure that the address of allocated memory is aligned
|
||||
// to MALLOC_ALIGN_BYTES
|
||||
tmp = taosMemoryMallocAlign(MALLOC_ALIGN_BYTES, numOfRows * pColumn->info.bytes);
|
||||
if (tmp == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -1210,7 +1211,7 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo*
|
|||
|
||||
pColumn->pData = tmp;
|
||||
|
||||
// todo remove it soon
|
||||
// check if the allocated memory is aligned to the requried bytes.
|
||||
#if defined LINUX
|
||||
if ((((uint64_t)pColumn->pData) & (MALLOC_ALIGN_BYTES - 1)) != 0x0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -1251,25 +1252,6 @@ int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||
code = doEnsureCapacity(p, &pDataBlock->info, numOfRows, true);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
pDataBlock->info.capacity = numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t blockDataEnsureCapacityNoClear(SSDataBlock* pDataBlock, uint32_t numOfRows) {
|
||||
int32_t code = 0;
|
||||
if (numOfRows == 0 || numOfRows <= pDataBlock->info.capacity) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||
|
@ -1963,7 +1945,7 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
|
|||
"|rows:%d|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n",
|
||||
flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId,
|
||||
pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version,
|
||||
pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName);
|
||||
pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName);
|
||||
if (len >= size - 1) return dumpBuf;
|
||||
|
||||
for (int32_t j = 0; j < rows; j++) {
|
||||
|
|
|
@ -3066,7 +3066,7 @@ int32_t tSerializeSTableIndexRsp(void *buf, int32_t bufLen, const STableIndexRsp
|
|||
|
||||
void tFreeSerializeSTableIndexRsp(STableIndexRsp *pRsp) {
|
||||
if (pRsp->pIndex != NULL) {
|
||||
taosArrayDestroy(pRsp->pIndex);
|
||||
tFreeSTableIndexRsp(pRsp);
|
||||
pRsp->pIndex = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -3256,6 +3256,7 @@ int32_t tSerializeSRetrieveTableReq(void *buf, int32_t bufLen, SRetrieveTableReq
|
|||
if (tEncodeI64(&encoder, pReq->showId) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->tb) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->filterTb) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->user) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
|
@ -3272,6 +3273,7 @@ int32_t tDeserializeSRetrieveTableReq(void *buf, int32_t bufLen, SRetrieveTableR
|
|||
if (tDecodeI64(&decoder, &pReq->showId) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->tb) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->filterTb) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1;
|
||||
|
||||
tEndDecode(&decoder);
|
||||
|
@ -5490,6 +5492,14 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS
|
|||
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
|
||||
}
|
||||
if (tEncodeI8(&encoder, pReq->createStb) < 0) return -1;
|
||||
if (tEncodeU64(&encoder, pReq->targetStbUid) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, taosArrayGetSize(pReq->fillNullCols)) < 0) return -1;
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pReq->fillNullCols); ++i) {
|
||||
SColLocation *pCol = taosArrayGet(pReq->fillNullCols, i);
|
||||
if (tEncodeI16(&encoder, pCol->slotId) < 0) return -1;
|
||||
if (tEncodeI16(&encoder, pCol->colId) < 0) return -1;
|
||||
if (tEncodeI8(&encoder, pCol->type) < 0) return -1;
|
||||
}
|
||||
|
||||
tEndEncode(&encoder);
|
||||
|
||||
|
@ -5551,6 +5561,27 @@ int32_t tDeserializeSCMCreateStreamReq(void *buf, int32_t bufLen, SCMCreateStrea
|
|||
}
|
||||
}
|
||||
if (tDecodeI8(&decoder, &pReq->createStb) < 0) return -1;
|
||||
if (tDecodeU64(&decoder, &pReq->targetStbUid) < 0) return -1;
|
||||
int32_t numOfFillNullCols = 0;
|
||||
if (tDecodeI32(&decoder, &numOfFillNullCols) < 0) return -1;
|
||||
if (numOfFillNullCols > 0) {
|
||||
pReq->fillNullCols = taosArrayInit(numOfFillNullCols, sizeof(SColLocation));
|
||||
if (pReq->fillNullCols == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfFillNullCols; ++i) {
|
||||
SColLocation col = {0};
|
||||
if (tDecodeI16(&decoder, &col.slotId) < 0) return -1;
|
||||
if (tDecodeI16(&decoder, &col.colId) < 0) return -1;
|
||||
if (tDecodeI8(&decoder, &col.type) < 0) return -1;
|
||||
if (taosArrayPush(pReq->fillNullCols, &col) == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tEndDecode(&decoder);
|
||||
|
||||
|
@ -5620,6 +5651,7 @@ void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) {
|
|||
taosArrayDestroy(pReq->pTags);
|
||||
taosMemoryFreeClear(pReq->sql);
|
||||
taosMemoryFreeClear(pReq->ast);
|
||||
taosArrayDestroy(pReq->fillNullCols);
|
||||
}
|
||||
|
||||
int32_t tEncodeSRSmaParam(SEncoder *pCoder, const SRSmaParam *pRSmaParam) {
|
||||
|
|
|
@ -160,9 +160,7 @@ int32_t tNameGetFullDbName(const SName* name, char* dst) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool tNameIsEmpty(const SName* name) {
|
||||
return name->type == 0 || name->acctId == 0;
|
||||
}
|
||||
bool tNameIsEmpty(const SName* name) { return name->type == 0 || name->acctId == 0; }
|
||||
|
||||
const char* tNameGetTableName(const SName* name) {
|
||||
ASSERT(name != NULL && name->type == TSDB_TABLE_NAME_T);
|
||||
|
@ -328,5 +326,4 @@ void buildChildTableName(RandTableName* rName) {
|
|||
strcat(rName->ctbShortName, temp);
|
||||
}
|
||||
taosStringBuilderDestroy(&sb);
|
||||
// rName->uid = *(uint64_t*)(context.digest);
|
||||
}
|
||||
|
|
|
@ -100,7 +100,11 @@ _return:
|
|||
|
||||
taosLogCrashInfo("taosd", pMsg, msgLen, signum, sigInfo);
|
||||
|
||||
#ifdef _TD_DARWIN_64
|
||||
exit(signum);
|
||||
#elif defined(WINDOWS)
|
||||
exit(signum);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dmSetSignalHandle() {
|
||||
|
|
|
@ -17,117 +17,97 @@
|
|||
#include "mmInt.h"
|
||||
#include "tjson.h"
|
||||
|
||||
int32_t mmReadFile(const char *path, SMnodeOpt *pOption) {
|
||||
int32_t code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = 4096;
|
||||
char *content = taosMemoryCalloc(1, maxLen + 1);
|
||||
cJSON *root = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
TdFilePtr pFile = NULL;
|
||||
static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) {
|
||||
int32_t code = 0;
|
||||
|
||||
tjsonGetInt32ValueFromDouble(pJson, "deployed", pOption->deploy, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetInt32ValueFromDouble(pJson, "selfIndex", pOption->selfIndex, code);
|
||||
if (code < 0) return 0;
|
||||
|
||||
SJson *replicas = tjsonGetObjectItem(pJson, "replicas");
|
||||
if (replicas == NULL) return 0;
|
||||
pOption->numOfReplicas = tjsonGetArraySize(replicas);
|
||||
|
||||
for (int32_t i = 0; i < pOption->numOfReplicas; ++i) {
|
||||
SJson *replica = tjsonGetArrayItem(replicas, i);
|
||||
if (replica == NULL) return -1;
|
||||
|
||||
SReplica *pReplica = pOption->replicas + i;
|
||||
tjsonGetInt32ValueFromDouble(replica, "id", pReplica->id, code);
|
||||
if (code < 0) return -1;
|
||||
code = tjsonGetStringValue(replica, "fqdn", pReplica->fqdn);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetUInt16ValueFromDouble(replica, "port", pReplica->port, code);
|
||||
if (code < 0) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mmReadFile(const char *path, SMnodeOpt *pOption) {
|
||||
int32_t code = -1;
|
||||
TdFilePtr pFile = NULL;
|
||||
char *pData = NULL;
|
||||
SJson *pJson = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
snprintf(file, sizeof(file), "%s%smnode.json", path, TD_DIRSEP);
|
||||
|
||||
if (taosStatFile(file, NULL, NULL) < 0) {
|
||||
dInfo("mnode file:%s not exist", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
code = 0;
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to open mnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
len = (int32_t)taosReadFile(pFile, content, maxLen);
|
||||
if (len <= 0) {
|
||||
dError("failed to read %s since content is null", file);
|
||||
int64_t size = 0;
|
||||
if (taosFStatFile(pFile, &size, NULL) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to fstat mnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content[len] = 0;
|
||||
root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
dError("failed to read %s since invalid json format", file);
|
||||
pData = taosMemoryMalloc(size + 1);
|
||||
if (pData == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *deployed = cJSON_GetObjectItem(root, "deployed");
|
||||
if (!deployed || deployed->type != cJSON_Number) {
|
||||
dError("failed to read %s since deployed not found", file);
|
||||
if (taosReadFile(pFile, pData, size) != size) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to read mnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
pOption->deploy = deployed->valueint;
|
||||
|
||||
cJSON *selfIndex = cJSON_GetObjectItem(root, "selfIndex");
|
||||
if (selfIndex) {
|
||||
if (selfIndex->type != cJSON_Number) {
|
||||
dError("failed to read %s since selfIndex not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
pOption->selfIndex = selfIndex->valueint;
|
||||
pData[size] = '\0';
|
||||
|
||||
pJson = tjsonParse(pData);
|
||||
if (pJson == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *replicas = cJSON_GetObjectItem(root, "replicas");
|
||||
if (replicas) {
|
||||
if (replicas->type != cJSON_Array) {
|
||||
dError("failed to read %s since replicas not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int32_t numOfReplicas = cJSON_GetArraySize(replicas);
|
||||
if (numOfReplicas <= 0) {
|
||||
dError("failed to read %s since numOfReplicas:%d invalid", file, numOfReplicas);
|
||||
goto _OVER;
|
||||
}
|
||||
pOption->numOfReplicas = numOfReplicas;
|
||||
|
||||
for (int32_t i = 0; i < numOfReplicas; ++i) {
|
||||
SReplica *pReplica = pOption->replicas + i;
|
||||
|
||||
cJSON *replica = cJSON_GetArrayItem(replicas, i);
|
||||
if (replica == NULL) break;
|
||||
|
||||
cJSON *id = cJSON_GetObjectItem(replica, "id");
|
||||
if (id) {
|
||||
if (id->type != cJSON_Number) {
|
||||
dError("failed to read %s since id not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
if (pReplica) {
|
||||
pReplica->id = id->valueint;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *fqdn = cJSON_GetObjectItem(replica, "fqdn");
|
||||
if (fqdn) {
|
||||
if (fqdn->type != cJSON_String || fqdn->valuestring == NULL) {
|
||||
dError("failed to read %s since fqdn not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
if (pReplica) {
|
||||
tstrncpy(pReplica->fqdn, fqdn->valuestring, TSDB_FQDN_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *port = cJSON_GetObjectItem(replica, "port");
|
||||
if (port) {
|
||||
if (port->type != cJSON_Number) {
|
||||
dError("failed to read %s since port not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
if (pReplica) {
|
||||
pReplica->port = (uint16_t)port->valueint;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mmDecodeOption(pJson, pOption) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
dInfo("succceed to read mnode file %s", file);
|
||||
|
||||
_OVER:
|
||||
if (content != NULL) taosMemoryFree(content);
|
||||
if (root != NULL) cJSON_Delete(root);
|
||||
if (pData != NULL) taosMemoryFree(pData);
|
||||
if (pJson != NULL) cJSON_Delete(pJson);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
if (code == 0) {
|
||||
dDebug("succcessed to read file %s, deployed:%d", file, pOption->deploy);
|
||||
}
|
||||
|
||||
terrno = code;
|
||||
if (code != 0) {
|
||||
dError("failed to read mnode file:%s since %s", file, terrstr());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "vmInt.h"
|
||||
#include "tjson.h"
|
||||
#include "vmInt.h"
|
||||
|
||||
#define MAX_CONTENT_LEN 2 * 1024 * 1024
|
||||
|
||||
|
@ -46,102 +46,108 @@ SVnodeObj **vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes) {
|
|||
return pVnodes;
|
||||
}
|
||||
|
||||
int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) {
|
||||
int32_t code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = MAX_CONTENT_LEN;
|
||||
char *content = taosMemoryCalloc(1, maxLen + 1);
|
||||
cJSON *root = NULL;
|
||||
FILE *fp = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
static int32_t vmDecodeVnodeList(SJson *pJson, SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) {
|
||||
int32_t code = -1;
|
||||
SWrapperCfg *pCfgs = NULL;
|
||||
TdFilePtr pFile = NULL;
|
||||
*ppCfgs = NULL;
|
||||
|
||||
snprintf(file, sizeof(file), "%s%svnodes.json", pMgmt->path, TD_DIRSEP);
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
dInfo("file %s not exist", file);
|
||||
code = 0;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (content == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = (int32_t)taosReadFile(pFile, content, maxLen);
|
||||
if (len <= 0) {
|
||||
dError("failed to read %s since content is null", file);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content[len] = 0;
|
||||
root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
dError("failed to read %s since invalid json format", file);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *vnodes = cJSON_GetObjectItem(root, "vnodes");
|
||||
if (!vnodes || vnodes->type != cJSON_Array) {
|
||||
dError("failed to read %s since vnodes not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
SJson *vnodes = tjsonGetObjectItem(pJson, "vnodes");
|
||||
if (vnodes == NULL) return -1;
|
||||
|
||||
int32_t vnodesNum = cJSON_GetArraySize(vnodes);
|
||||
if (vnodesNum > 0) {
|
||||
pCfgs = taosMemoryCalloc(vnodesNum, sizeof(SWrapperCfg));
|
||||
if (pCfgs == NULL) {
|
||||
dError("failed to read %s since out of memory", file);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < vnodesNum; ++i) {
|
||||
cJSON *vnode = cJSON_GetArrayItem(vnodes, i);
|
||||
SWrapperCfg *pCfg = &pCfgs[i];
|
||||
|
||||
cJSON *vgId = cJSON_GetObjectItem(vnode, "vgId");
|
||||
if (!vgId || vgId->type != cJSON_Number) {
|
||||
dError("failed to read %s since vgId not found", file);
|
||||
taosMemoryFree(pCfgs);
|
||||
goto _OVER;
|
||||
}
|
||||
pCfg->vgId = vgId->valueint;
|
||||
snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCfg->vgId);
|
||||
|
||||
cJSON *dropped = cJSON_GetObjectItem(vnode, "dropped");
|
||||
if (!dropped || dropped->type != cJSON_Number) {
|
||||
dError("failed to read %s since dropped not found", file);
|
||||
taosMemoryFree(pCfgs);
|
||||
goto _OVER;
|
||||
}
|
||||
pCfg->dropped = dropped->valueint;
|
||||
|
||||
cJSON *vgVersion = cJSON_GetObjectItem(vnode, "vgVersion");
|
||||
if (!vgVersion || vgVersion->type != cJSON_Number) {
|
||||
dError("failed to read %s since vgVersion not found", file);
|
||||
taosMemoryFree(pCfgs);
|
||||
goto _OVER;
|
||||
}
|
||||
pCfg->vgVersion = vgVersion->valueint;
|
||||
}
|
||||
|
||||
*ppCfgs = pCfgs;
|
||||
if (pCfgs == NULL) return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < vnodesNum; ++i) {
|
||||
SJson *vnode = tjsonGetArrayItem(vnodes, i);
|
||||
if (vnode == NULL) goto _OVER;
|
||||
|
||||
SWrapperCfg *pCfg = &pCfgs[i];
|
||||
tjsonGetInt32ValueFromDouble(vnode, "vgId", pCfg->vgId, code);
|
||||
if (code < 0) goto _OVER;
|
||||
tjsonGetInt32ValueFromDouble(vnode, "dropped", pCfg->dropped, code);
|
||||
if (code < 0) goto _OVER;
|
||||
tjsonGetInt32ValueFromDouble(vnode, "vgVersion", pCfg->vgVersion, code);
|
||||
if (code < 0) goto _OVER;
|
||||
|
||||
snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCfg->vgId);
|
||||
}
|
||||
|
||||
*numOfVnodes = vnodesNum;
|
||||
code = 0;
|
||||
dInfo("succcessed to read file %s, numOfVnodes:%d", file, vnodesNum);
|
||||
*ppCfgs = pCfgs;
|
||||
*numOfVnodes = vnodesNum;
|
||||
|
||||
_OVER:
|
||||
if (content != NULL) taosMemoryFree(content);
|
||||
if (root != NULL) cJSON_Delete(root);
|
||||
if (*ppCfgs == NULL) taosMemoryFree(pCfgs);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) {
|
||||
int32_t code = -1;
|
||||
TdFilePtr pFile = NULL;
|
||||
char *pData = NULL;
|
||||
SJson *pJson = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
SWrapperCfg *pCfgs = NULL;
|
||||
snprintf(file, sizeof(file), "%s%svnodes.json", pMgmt->path, TD_DIRSEP);
|
||||
|
||||
if (taosStatFile(file, NULL, NULL) < 0) {
|
||||
dInfo("vnode file:%s not exist", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to open vnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int64_t size = 0;
|
||||
if (taosFStatFile(pFile, &size, NULL) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to fstat mnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pData = taosMemoryMalloc(size + 1);
|
||||
if (pData == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (taosReadFile(pFile, pData, size) != size) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to read vnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pData[size] = '\0';
|
||||
|
||||
pJson = tjsonParse(pData);
|
||||
if (pJson == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (vmDecodeVnodeList(pJson, pMgmt, ppCfgs, numOfVnodes) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
dInfo("succceed to read vnode file %s", file);
|
||||
|
||||
_OVER:
|
||||
if (pData != NULL) taosMemoryFree(pData);
|
||||
if (pJson != NULL) cJSON_Delete(pJson);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
|
||||
terrno = code;
|
||||
if (code != 0) {
|
||||
dError("failed to read vnode file:%s since %s", file, terrstr());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
|
|||
pNode->nodeId = pCreate->replicas[i].id;
|
||||
pNode->nodePort = pCreate->replicas[i].port;
|
||||
tstrncpy(pNode->nodeFqdn, pCreate->replicas[i].fqdn, TSDB_FQDN_LEN);
|
||||
(void)tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort);
|
||||
tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,7 @@ static int32_t vmTsmaAdjustDays(SVnodeCfg *pCfg, SCreateVnodeReq *pReq) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int32_t vmTsmaProcessCreate(SVnode *pVnode, SCreateVnodeReq *pReq) {
|
||||
if (pReq->isTsma) {
|
||||
SMsgHead *smaMsg = pReq->pTsma;
|
||||
|
@ -165,6 +166,7 @@ static int32_t vmTsmaProcessCreate(SVnode *pVnode, SCreateVnodeReq *pReq) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||
SCreateVnodeReq req = {0};
|
||||
|
@ -245,12 +247,14 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
#if 0
|
||||
code = vmTsmaProcessCreate(pImpl, &req);
|
||||
if (code != 0) {
|
||||
dError("vgId:%d, failed to create tsma since %s", req.vgId, terrstr());
|
||||
code = terrno;
|
||||
goto _OVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
code = vnodeStart(pImpl);
|
||||
if (code != 0) {
|
||||
|
|
|
@ -343,13 +343,12 @@ static void vmCheckSyncTimeout(SVnodeMgmt *pMgmt) {
|
|||
int32_t numOfVnodes = 0;
|
||||
SVnodeObj **ppVnodes = vmGetVnodeListFromHash(pMgmt, &numOfVnodes);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
SVnodeObj *pVnode = ppVnodes[i];
|
||||
vnodeSyncCheckTimeout(pVnode->pImpl);
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
}
|
||||
|
||||
if (ppVnodes != NULL) {
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
SVnodeObj *pVnode = ppVnodes[i];
|
||||
vnodeSyncCheckTimeout(pVnode->pImpl);
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
}
|
||||
taosMemoryFree(ppVnodes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "dmMgmt.h"
|
||||
|
||||
static SDnode global = {0};
|
||||
static SDnode globalDnode = {0};
|
||||
|
||||
SDnode *dmInstance() { return &global; }
|
||||
SDnode *dmInstance() { return &globalDnode; }
|
||||
|
||||
static int32_t dmCheckRepeatInit(SDnode *pDnode) {
|
||||
if (atomic_val_compare_exchange_8(&pDnode->once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
|
||||
|
@ -270,6 +270,6 @@ void dmReportStartup(const char *pName, const char *pDesc) {
|
|||
}
|
||||
|
||||
int64_t dmGetClusterId() {
|
||||
return global.data.clusterId;
|
||||
return globalDnode.data.clusterId;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,13 @@ static void dmClearVars(SDnode *pDnode) {
|
|||
|
||||
SDnodeData *pData = &pDnode->data;
|
||||
taosThreadRwlockWrlock(&pData->lock);
|
||||
if (pData->oldDnodeEps != NULL) {
|
||||
if (dmWriteEps(pData) == 0) {
|
||||
dmRemoveDnodePairs(pData);
|
||||
}
|
||||
taosArrayDestroy(pData->oldDnodeEps);
|
||||
pData->oldDnodeEps = NULL;
|
||||
}
|
||||
if (pData->dnodeEps != NULL) {
|
||||
taosArrayDestroy(pData->dnodeEps);
|
||||
pData->dnodeEps = NULL;
|
||||
|
|
|
@ -100,6 +100,7 @@ typedef struct {
|
|||
bool stopped;
|
||||
SEpSet mnodeEps;
|
||||
SArray *dnodeEps;
|
||||
SArray *oldDnodeEps;
|
||||
SHashObj *dnodeHash;
|
||||
TdThreadRwlock lock;
|
||||
SMsgCb msgCb;
|
||||
|
@ -167,7 +168,8 @@ void dmUpdateEps(SDnodeData *pData, SArray *pDnodeEps);
|
|||
void dmGetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet);
|
||||
void dmGetMnodeEpSetForRedirect(SDnodeData *pData, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
void dmSetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet);
|
||||
int32_t dmUpdateDnodeInfo(void *pData, int32_t *dnodeId, int64_t *clusterId, char *fqdn, uint16_t *port);
|
||||
bool dmUpdateDnodeInfo(void *pData, int32_t *dnodeId, int64_t *clusterId, char *fqdn, uint16_t *port);
|
||||
void dmRemoveDnodePairs(SDnodeData *pData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -18,9 +18,18 @@
|
|||
#include "tjson.h"
|
||||
#include "tmisce.h"
|
||||
|
||||
static void dmPrintEps(SDnodeData *pData);
|
||||
static bool dmIsEpChanged(SDnodeData *pData, int32_t dnodeId, const char *ep);
|
||||
static void dmResetEps(SDnodeData *pData, SArray *dnodeEps);
|
||||
typedef struct {
|
||||
int32_t id;
|
||||
uint16_t oldPort;
|
||||
uint16_t newPort;
|
||||
char oldFqdn[TSDB_FQDN_LEN];
|
||||
char newFqdn[TSDB_FQDN_LEN];
|
||||
} SDnodeEpPair;
|
||||
|
||||
static void dmPrintEps(SDnodeData *pData);
|
||||
static bool dmIsEpChanged(SDnodeData *pData, int32_t dnodeId, const char *ep);
|
||||
static void dmResetEps(SDnodeData *pData, SArray *dnodeEps);
|
||||
static int32_t dmReadDnodePairs(SDnodeData *pData);
|
||||
|
||||
static void dmGetDnodeEp(SDnodeData *pData, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort) {
|
||||
taosThreadRwlockRdlock(&pData->lock);
|
||||
|
@ -41,14 +50,49 @@ static void dmGetDnodeEp(SDnodeData *pData, int32_t dnodeId, char *pEp, char *pF
|
|||
taosThreadRwlockUnlock(&pData->lock);
|
||||
}
|
||||
|
||||
static int32_t dmDecodeEps(SJson *pJson, SDnodeData *pData) {
|
||||
int32_t code = 0;
|
||||
|
||||
tjsonGetInt32ValueFromDouble(pJson, "dnodeId", pData->dnodeId, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "dnodeVer", pData->dnodeVer, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "clusterId", pData->clusterId, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetInt32ValueFromDouble(pJson, "dropped", pData->dropped, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
SJson *dnodes = tjsonGetObjectItem(pJson, "dnodes");
|
||||
if (dnodes == NULL) return 0;
|
||||
int32_t numOfDnodes = tjsonGetArraySize(dnodes);
|
||||
|
||||
for (int32_t i = 0; i < numOfDnodes; ++i) {
|
||||
SJson *dnode = tjsonGetArrayItem(dnodes, i);
|
||||
if (dnode == NULL) return -1;
|
||||
|
||||
SDnodeEp dnodeEp = {0};
|
||||
tjsonGetInt32ValueFromDouble(dnode, "id", dnodeEp.id, code);
|
||||
if (code < 0) return -1;
|
||||
code = tjsonGetStringValue(dnode, "fqdn", dnodeEp.ep.fqdn);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetUInt16ValueFromDouble(dnode, "port", dnodeEp.ep.port, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetInt8ValueFromDouble(dnode, "isMnode", dnodeEp.isMnode, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
if (taosArrayPush(pData->dnodeEps, &dnodeEp) == NULL) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t dmReadEps(SDnodeData *pData) {
|
||||
int32_t code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = 256 * 1024;
|
||||
char *content = taosMemoryCalloc(1, maxLen + 1);
|
||||
cJSON *root = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
int32_t code = -1;
|
||||
TdFilePtr pFile = NULL;
|
||||
char *content = NULL;
|
||||
SJson *pJson = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
snprintf(file, sizeof(file), "%s%sdnode%sdnode.json", tsDataDir, TD_DIRSEP, TD_DIRSEP);
|
||||
|
||||
pData->dnodeEps = taosArrayInit(1, sizeof(SDnodeEp));
|
||||
if (pData->dnodeEps == NULL) {
|
||||
|
@ -56,113 +100,64 @@ int32_t dmReadEps(SDnodeData *pData) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
snprintf(file, sizeof(file), "%s%sdnode%sdnode.json", tsDataDir, TD_DIRSEP, TD_DIRSEP);
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
if (taosStatFile(file, NULL, NULL) < 0) {
|
||||
dInfo("dnode file:%s not exist", file);
|
||||
code = 0;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
len = (int32_t)taosReadFile(pFile, content, maxLen);
|
||||
if (len <= 0) {
|
||||
dError("failed to read %s since content is null", file);
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to open dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content[len] = 0;
|
||||
root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
dError("failed to read %s since invalid json format", file);
|
||||
int64_t size = 0;
|
||||
if (taosFStatFile(pFile, &size, NULL) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to fstat dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *dnodeId = cJSON_GetObjectItem(root, "dnodeId");
|
||||
if (!dnodeId || dnodeId->type != cJSON_Number) {
|
||||
dError("failed to read %s since dnodeId not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
pData->dnodeId = dnodeId->valueint;
|
||||
|
||||
cJSON *dnodeVer = cJSON_GetObjectItem(root, "dnodeVer");
|
||||
if (!dnodeVer || dnodeVer->type != cJSON_String) {
|
||||
dError("failed to read %s since dnodeVer not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
pData->dnodeVer = atoll(dnodeVer->valuestring);
|
||||
|
||||
cJSON *clusterId = cJSON_GetObjectItem(root, "clusterId");
|
||||
if (!clusterId || clusterId->type != cJSON_String) {
|
||||
dError("failed to read %s since clusterId not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
pData->clusterId = atoll(clusterId->valuestring);
|
||||
|
||||
cJSON *dropped = cJSON_GetObjectItem(root, "dropped");
|
||||
if (!dropped || dropped->type != cJSON_Number) {
|
||||
dError("failed to read %s since dropped not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
pData->dropped = dropped->valueint;
|
||||
|
||||
cJSON *dnodes = cJSON_GetObjectItem(root, "dnodes");
|
||||
if (!dnodes || dnodes->type != cJSON_Array) {
|
||||
dError("failed to read %s since dnodes not found", file);
|
||||
content = taosMemoryMalloc(size + 1);
|
||||
if (content == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int32_t numOfDnodes = cJSON_GetArraySize(dnodes);
|
||||
if (numOfDnodes <= 0) {
|
||||
dError("failed to read %s since numOfDnodes:%d invalid", file, numOfDnodes);
|
||||
if (taosReadFile(pFile, content, size) != size) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to read dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfDnodes; ++i) {
|
||||
cJSON *node = cJSON_GetArrayItem(dnodes, i);
|
||||
if (node == NULL) break;
|
||||
content[size] = '\0';
|
||||
|
||||
SDnodeEp dnodeEp = {0};
|
||||
pJson = tjsonParse(content);
|
||||
if (pJson == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *did = cJSON_GetObjectItem(node, "id");
|
||||
if (!did || did->type != cJSON_Number) {
|
||||
dError("failed to read %s since dnodeId not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
dnodeEp.id = did->valueint;
|
||||
|
||||
cJSON *dnodeFqdn = cJSON_GetObjectItem(node, "fqdn");
|
||||
if (!dnodeFqdn || dnodeFqdn->type != cJSON_String || dnodeFqdn->valuestring == NULL) {
|
||||
dError("failed to read %s since dnodeFqdn not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
tstrncpy(dnodeEp.ep.fqdn, dnodeFqdn->valuestring, TSDB_FQDN_LEN);
|
||||
|
||||
cJSON *dnodePort = cJSON_GetObjectItem(node, "port");
|
||||
if (!dnodePort || dnodePort->type != cJSON_Number) {
|
||||
dError("failed to read %s since dnodePort not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
dnodeEp.ep.port = dnodePort->valueint;
|
||||
|
||||
cJSON *isMnode = cJSON_GetObjectItem(node, "isMnode");
|
||||
if (!isMnode || isMnode->type != cJSON_Number) {
|
||||
dError("failed to read %s since isMnode not found", file);
|
||||
goto _OVER;
|
||||
}
|
||||
dnodeEp.isMnode = isMnode->valueint;
|
||||
|
||||
taosArrayPush(pData->dnodeEps, &dnodeEp);
|
||||
if (dmDecodeEps(pJson, pData) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
dDebug("succcessed to read file %s", file);
|
||||
dInfo("succceed to read dnode file %s", file);
|
||||
|
||||
_OVER:
|
||||
if (content != NULL) taosMemoryFree(content);
|
||||
if (root != NULL) cJSON_Delete(root);
|
||||
if (pJson != NULL) cJSON_Delete(pJson);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
|
||||
if (code != 0) {
|
||||
dError("failed to read dnode file:%s since %s", file, terrstr());
|
||||
return code;
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pData->dnodeEps) == 0) {
|
||||
SDnodeEp dnodeEp = {0};
|
||||
dnodeEp.isMnode = 1;
|
||||
|
@ -170,15 +165,19 @@ _OVER:
|
|||
taosArrayPush(pData->dnodeEps, &dnodeEp);
|
||||
}
|
||||
|
||||
dDebug("reset dnode list on startup");
|
||||
dmResetEps(pData, pData->dnodeEps);
|
||||
|
||||
if (dmIsEpChanged(pData, pData->dnodeId, tsLocalEp)) {
|
||||
dError("localEp %s different with %s and need reconfigured", tsLocalEp, file);
|
||||
if (dmReadDnodePairs(pData) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dDebug("reset dnode list on startup");
|
||||
dmResetEps(pData, pData->dnodeEps);
|
||||
|
||||
if (pData->oldDnodeEps == NULL && dmIsEpChanged(pData, pData->dnodeId, tsLocalEp)) {
|
||||
dError("localEp %s different with %s and need reconfigured", tsLocalEp, file);
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
terrno = code;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -238,7 +237,8 @@ int32_t dmWriteEps(SDnodeData *pData) {
|
|||
|
||||
code = 0;
|
||||
pData->updateTime = taosGetTimestampMs();
|
||||
dInfo("succeed to write dnode file:%s, dnodeVer:%" PRId64, realfile, pData->dnodeVer);
|
||||
dInfo("succeed to write dnode file:%s, num:%d ver:%" PRId64, realfile, (int32_t)taosArrayGetSize(pData->dnodeEps),
|
||||
pData->dnodeVer);
|
||||
|
||||
_OVER:
|
||||
if (pJson != NULL) tjsonDelete(pJson);
|
||||
|
@ -247,7 +247,7 @@ _OVER:
|
|||
|
||||
if (code != 0) {
|
||||
if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dInfo("succeed to write dnode file:%s since %s, dnodeVer:%" PRId64, realfile, terrstr(), pData->dnodeVer);
|
||||
dError("failed to write dnode file:%s since %s, dnodeVer:%" PRId64, realfile, terrstr(), pData->dnodeVer);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -348,40 +348,210 @@ void dmSetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t dmUpdateDnodeInfo(void *data, int32_t *dnodeId, int64_t *clusterId, char *fqdn, uint16_t *port) {
|
||||
bool dmUpdateDnodeInfo(void *data, int32_t *did, int64_t *clusterId, char *fqdn, uint16_t *port) {
|
||||
bool updated = false;
|
||||
SDnodeData *pData = data;
|
||||
int32_t ret = -1;
|
||||
int32_t dnodeId = -1;
|
||||
if (did != NULL) dnodeId = *did;
|
||||
|
||||
taosThreadRwlockRdlock(&pData->lock);
|
||||
if (*dnodeId <= 0) {
|
||||
for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pData->dnodeEps); ++i) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(pData->dnodeEps, i);
|
||||
if (strcmp(pDnodeEp->ep.fqdn, fqdn) == 0 && pDnodeEp->ep.port == *port) {
|
||||
dInfo("dnode:%s:%u, update dnodeId from %d to %d", fqdn, *port, *dnodeId, pDnodeEp->id);
|
||||
*dnodeId = pDnodeEp->id;
|
||||
*clusterId = pData->clusterId;
|
||||
ret = 0;
|
||||
|
||||
if (pData->oldDnodeEps != NULL) {
|
||||
int32_t size = (int32_t)taosArrayGetSize(pData->oldDnodeEps);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SDnodeEpPair *pair = taosArrayGet(pData->oldDnodeEps, i);
|
||||
if (strcmp(pair->oldFqdn, fqdn) == 0 && pair->oldPort == *port) {
|
||||
dInfo("dnode:%d, update ep:%s:%u to %s:%u", dnodeId, fqdn, *port, pair->newFqdn, pair->newPort);
|
||||
tstrncpy(fqdn, pair->newFqdn, TSDB_FQDN_LEN);
|
||||
*port = pair->newPort;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
dInfo("dnode:%s:%u, failed to update dnodeId:%d", fqdn, *port, *dnodeId);
|
||||
}
|
||||
} else {
|
||||
SDnodeEp *pDnodeEp = taosHashGet(pData->dnodeHash, dnodeId, sizeof(int32_t));
|
||||
if (pDnodeEp) {
|
||||
if (strcmp(pDnodeEp->ep.fqdn, fqdn) != 0) {
|
||||
dInfo("dnode:%d, update port from %s to %s", *dnodeId, fqdn, pDnodeEp->ep.fqdn);
|
||||
tstrncpy(fqdn, pDnodeEp->ep.fqdn, TSDB_FQDN_LEN);
|
||||
}
|
||||
if (pDnodeEp->ep.port != *port) {
|
||||
dInfo("dnode:%d, update port from %u to %u", *dnodeId, *port, pDnodeEp->ep.port);
|
||||
*port = pDnodeEp->ep.port;
|
||||
}
|
||||
*clusterId = pData->clusterId;
|
||||
ret = 0;
|
||||
} else {
|
||||
dInfo("dnode:%d, failed to update dnode info", *dnodeId);
|
||||
}
|
||||
}
|
||||
|
||||
if (did != NULL && dnodeId <= 0) {
|
||||
int32_t size = (int32_t)taosArrayGetSize(pData->dnodeEps);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(pData->dnodeEps, i);
|
||||
if (strcmp(pDnodeEp->ep.fqdn, fqdn) == 0 && pDnodeEp->ep.port == *port) {
|
||||
dInfo("dnode:%s:%u, update dnodeId to dnode:%d", fqdn, *port, pDnodeEp->id);
|
||||
*did = pDnodeEp->id;
|
||||
if (clusterId != NULL) *clusterId = pData->clusterId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dnodeId > 0) {
|
||||
SDnodeEp *pDnodeEp = taosHashGet(pData->dnodeHash, &dnodeId, sizeof(int32_t));
|
||||
if (pDnodeEp) {
|
||||
if (strcmp(pDnodeEp->ep.fqdn, fqdn) != 0 || pDnodeEp->ep.port != *port) {
|
||||
dInfo("dnode:%d, update ep:%s:%u to %s:%u", dnodeId, fqdn, *port, pDnodeEp->ep.fqdn, pDnodeEp->ep.port);
|
||||
tstrncpy(fqdn, pDnodeEp->ep.fqdn, TSDB_FQDN_LEN);
|
||||
*port = pDnodeEp->ep.port;
|
||||
updated = true;
|
||||
}
|
||||
if (clusterId != NULL) *clusterId = pData->clusterId;
|
||||
}
|
||||
}
|
||||
|
||||
taosThreadRwlockUnlock(&pData->lock);
|
||||
return ret;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
static int32_t dmDecodeEpPairs(SJson *pJson, SDnodeData *pData) {
|
||||
int32_t code = 0;
|
||||
|
||||
SJson *dnodes = tjsonGetObjectItem(pJson, "dnodes");
|
||||
if (dnodes == NULL) return 0;
|
||||
int32_t numOfDnodes = tjsonGetArraySize(dnodes);
|
||||
|
||||
for (int32_t i = 0; i < numOfDnodes; ++i) {
|
||||
SJson *dnode = tjsonGetArrayItem(dnodes, i);
|
||||
if (dnode == NULL) return -1;
|
||||
|
||||
SDnodeEpPair pair = {0};
|
||||
tjsonGetInt32ValueFromDouble(dnode, "id", pair.id, code);
|
||||
if (code < 0) return -1;
|
||||
code = tjsonGetStringValue(dnode, "fqdn", pair.oldFqdn);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetUInt16ValueFromDouble(dnode, "port", pair.oldPort, code);
|
||||
if (code < 0) return -1;
|
||||
code = tjsonGetStringValue(dnode, "new_fqdn", pair.newFqdn);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetUInt16ValueFromDouble(dnode, "new_port", pair.newPort, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
if (taosArrayPush(pData->oldDnodeEps, &pair) == NULL) return -1;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void dmRemoveDnodePairs(SDnodeData *pData) {
|
||||
char file[PATH_MAX] = {0};
|
||||
char bak[PATH_MAX] = {0};
|
||||
snprintf(file, sizeof(file), "%s%sdnode%sep.json", tsDataDir, TD_DIRSEP, TD_DIRSEP);
|
||||
snprintf(bak, sizeof(bak), "%s%sdnode%sep.json.bak", tsDataDir, TD_DIRSEP, TD_DIRSEP);
|
||||
dInfo("dnode file:%s is rename to bak file", file);
|
||||
(void)taosRenameFile(file, bak);
|
||||
}
|
||||
|
||||
static int32_t dmReadDnodePairs(SDnodeData *pData) {
|
||||
int32_t code = -1;
|
||||
TdFilePtr pFile = NULL;
|
||||
char *content = NULL;
|
||||
SJson *pJson = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
snprintf(file, sizeof(file), "%s%sdnode%sep.json", tsDataDir, TD_DIRSEP, TD_DIRSEP);
|
||||
|
||||
if (taosStatFile(file, NULL, NULL) < 0) {
|
||||
dDebug("dnode file:%s not exist", file);
|
||||
code = 0;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to open dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int64_t size = 0;
|
||||
if (taosFStatFile(pFile, &size, NULL) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to fstat dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content = taosMemoryMalloc(size + 1);
|
||||
if (content == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (taosReadFile(pFile, content, size) != size) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to read dnode file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content[size] = '\0';
|
||||
|
||||
pJson = tjsonParse(content);
|
||||
if (pJson == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pData->oldDnodeEps = taosArrayInit(1, sizeof(SDnodeEpPair));
|
||||
if (pData->oldDnodeEps == NULL) {
|
||||
dError("failed to calloc dnodeEp array since %s", strerror(errno));
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dmDecodeEpPairs(pJson, pData) < 0) {
|
||||
taosArrayDestroy(pData->oldDnodeEps);
|
||||
pData->oldDnodeEps = NULL;
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
dInfo("succceed to read dnode file %s", file);
|
||||
|
||||
_OVER:
|
||||
if (content != NULL) taosMemoryFree(content);
|
||||
if (pJson != NULL) cJSON_Delete(pJson);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
|
||||
if (code != 0) {
|
||||
dError("failed to read dnode file:%s since %s", file, terrstr());
|
||||
return code;
|
||||
}
|
||||
|
||||
// update old fqdn and port
|
||||
for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pData->oldDnodeEps); ++i) {
|
||||
SDnodeEpPair *pair = taosArrayGet(pData->oldDnodeEps, i);
|
||||
for (int32_t j = 0; j < (int32_t)taosArrayGetSize(pData->dnodeEps); ++j) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(pData->dnodeEps, j);
|
||||
if (pDnodeEp->id == pair->id) {
|
||||
tstrncpy(pair->oldFqdn, pDnodeEp->ep.fqdn, TSDB_FQDN_LEN);
|
||||
pair->oldPort = pDnodeEp->ep.port;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check new fqdn and port
|
||||
for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pData->oldDnodeEps); ++i) {
|
||||
SDnodeEpPair *pair = taosArrayGet(pData->oldDnodeEps, i);
|
||||
for (int32_t j = 0; j < (int32_t)taosArrayGetSize(pData->dnodeEps); ++j) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(pData->dnodeEps, j);
|
||||
if (pDnodeEp->id != pair->id &&
|
||||
(strcmp(pDnodeEp->ep.fqdn, pair->newFqdn) == 0 && pDnodeEp->ep.port == pair->newPort)) {
|
||||
dError("dnode:%d, can't update ep:%s:%u to %s:%u since already exists as dnode:%d", pair->id, pair->oldFqdn,
|
||||
pair->oldPort, pair->newFqdn, pair->newPort, pDnodeEp->id);
|
||||
taosArrayDestroy(pData->oldDnodeEps);
|
||||
pData->oldDnodeEps = NULL;
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pData->oldDnodeEps); ++i) {
|
||||
SDnodeEpPair *pair = taosArrayGet(pData->oldDnodeEps, i);
|
||||
for (int32_t j = 0; j < (int32_t)taosArrayGetSize(pData->dnodeEps); ++j) {
|
||||
SDnodeEp *pDnodeEp = taosArrayGet(pData->dnodeEps, j);
|
||||
if (strcmp(pDnodeEp->ep.fqdn, pair->oldFqdn) == 0 && pDnodeEp->ep.port == pair->oldPort) {
|
||||
dInfo("dnode:%d, will update ep:%s:%u to %s:%u", pDnodeEp->id, pDnodeEp->ep.fqdn, pDnodeEp->ep.port,
|
||||
pair->newFqdn, pair->newPort);
|
||||
tstrncpy(pDnodeEp->ep.fqdn, pair->newFqdn, TSDB_FQDN_LEN);
|
||||
pDnodeEp->ep.port = pair->newPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pData->dnodeVer = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,48 +19,81 @@
|
|||
|
||||
#define MAXLEN 1024
|
||||
|
||||
int32_t dmReadFile(const char *path, const char *name, bool *pDeployed) {
|
||||
int32_t code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
int64_t len = 0;
|
||||
char content[MAXLEN + 1] = {0};
|
||||
cJSON *root = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
TdFilePtr pFile = NULL;
|
||||
static int32_t dmDecodeFile(SJson *pJson, bool *deployed) {
|
||||
int32_t code = 0;
|
||||
int32_t value = 0;
|
||||
|
||||
tjsonGetInt32ValueFromDouble(pJson, "deployed", value, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
*deployed = (value != 0);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t dmReadFile(const char *path, const char *name, bool *pDeployed) {
|
||||
int32_t code = -1;
|
||||
TdFilePtr pFile = NULL;
|
||||
char *content = NULL;
|
||||
SJson *pJson = NULL;
|
||||
char file[PATH_MAX] = {0};
|
||||
snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
|
||||
if (taosStatFile(file, NULL, NULL) < 0) {
|
||||
dInfo("file:%s not exist", file);
|
||||
code = 0;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
len = taosReadFile(pFile, content, MAXLEN);
|
||||
if (len <= 0) {
|
||||
dError("failed to read %s since content is null", file);
|
||||
pFile = taosOpenFile(file, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to open file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
dError("failed to read %s since invalid json format", file);
|
||||
int64_t size = 0;
|
||||
if (taosFStatFile(pFile, &size, NULL) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to fstat file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
cJSON *deployed = cJSON_GetObjectItem(root, "deployed");
|
||||
if (!deployed || deployed->type != cJSON_Number) {
|
||||
dError("failed to read %s since deployed not found", file);
|
||||
content = taosMemoryMalloc(size + 1);
|
||||
if (content == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (taosReadFile(pFile, content, size) != size) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to read file:%s since %s", file, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
content[size] = '\0';
|
||||
|
||||
pJson = tjsonParse(content);
|
||||
if (pJson == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dmDecodeFile(pJson, pDeployed) < 0) {
|
||||
terrno = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||
goto _OVER;
|
||||
}
|
||||
*pDeployed = deployed->valueint != 0;
|
||||
|
||||
dDebug("succcessed to read file %s, deployed:%d", file, *pDeployed);
|
||||
code = 0;
|
||||
dInfo("succceed to read mnode file %s", file);
|
||||
|
||||
_OVER:
|
||||
if (root != NULL) cJSON_Delete(root);
|
||||
if (content != NULL) taosMemoryFree(content);
|
||||
if (pJson != NULL) cJSON_Delete(pJson);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
|
||||
terrno = code;
|
||||
if (code != 0) {
|
||||
dError("failed to read dnode file:%s since %s", file, terrstr());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -444,6 +444,7 @@ typedef struct {
|
|||
STableMetaRsp* pMeta;
|
||||
bool sysDbRsp;
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
char filterTb[TSDB_TABLE_NAME_LEN];
|
||||
} SShowObj;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#define CLUSTER_VER_NUMBE 1
|
||||
#define CLUSTER_RESERVE_SIZE 60
|
||||
char tsVersionName[16] = "community";
|
||||
int64_t tsExpireTime = 0;
|
||||
|
||||
static SSdbRaw *mndClusterActionEncode(SClusterObj *pCluster);
|
||||
static SSdbRow *mndClusterActionDecode(SSdbRaw *pRaw);
|
||||
|
@ -291,6 +293,18 @@ static int32_t mndRetrieveClusters(SRpcMsg *pMsg, SShowObj *pShow, SSDataBlock *
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pCluster->createdTime, false);
|
||||
|
||||
char ver[12] = {0};
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(ver, tsVersionName, pShow->pMeta->pSchemas[cols].bytes);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)ver, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
if (tsExpireTime <= 0) {
|
||||
colDataAppendNULL(pColInfo, numOfRows);
|
||||
} else {
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&tsExpireTime, false);
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pCluster);
|
||||
numOfRows++;
|
||||
}
|
||||
|
|
|
@ -745,6 +745,7 @@ SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw) {
|
|||
if (tDecodeSMqConsumerObj(buf, pConsumer) == NULL) {
|
||||
goto CM_DECODE_OVER;
|
||||
}
|
||||
tmsgUpdateDnodeEpSet(&pConsumer->ep);
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
|
|
@ -180,6 +180,9 @@ static SSdbRow *mndDnodeActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_RESERVE(pRaw, dataPos, TSDB_DNODE_RESERVE_SIZE, _OVER)
|
||||
|
||||
terrno = 0;
|
||||
if (tmsgUpdateDnodeInfo(&pDnode->id, NULL, pDnode->fqdn, &pDnode->port)) {
|
||||
mInfo("dnode:%d, endpoint changed", pDnode->id);
|
||||
}
|
||||
|
||||
_OVER:
|
||||
if (terrno != 0) {
|
||||
|
@ -188,7 +191,7 @@ _OVER:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mTrace("dnode:%d, decode from raw:%p, row:%p", pDnode->id, pRaw, pDnode);
|
||||
mTrace("dnode:%d, decode from raw:%p, row:%p ep:%s:%u", pDnode->id, pRaw, pDnode, pDnode->fqdn, pDnode->port);
|
||||
return pRow;
|
||||
}
|
||||
|
||||
|
@ -308,7 +311,8 @@ void mndGetDnodeData(SMnode *pMnode, SArray *pDnodeEps) {
|
|||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
ESdbStatus objStatus = 0;
|
||||
pIter = sdbFetchAll(pSdb, SDB_DNODE, pIter, (void **)&pDnode, &objStatus, true);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
SDnodeEp dnodeEp = {0};
|
||||
|
|
|
@ -293,7 +293,7 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
mInfo("func:%s, start to create", createReq.name);
|
||||
mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndMnode.h"
|
||||
#include "mndCluster.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
#include "tmisce.h"
|
||||
#include "mndCluster.h"
|
||||
|
||||
#define MNODE_VER_NUMBER 1
|
||||
#define MNODE_RESERVE_SIZE 64
|
||||
|
@ -181,9 +181,8 @@ _OVER:
|
|||
|
||||
static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj) {
|
||||
mTrace("mnode:%d, perform insert action, row:%p", pObj->id, pObj);
|
||||
pObj->pDnode = sdbAcquire(pSdb, SDB_DNODE, &pObj->id);
|
||||
pObj->pDnode = sdbAcquireNotReadyObj(pSdb, SDB_DNODE, &pObj->id);
|
||||
if (pObj->pDnode == NULL) {
|
||||
terrno = TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
mError("mnode:%d, failed to perform insert action since %s", pObj->id, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "systable.h"
|
||||
|
||||
#define SHOW_STEP_SIZE 100
|
||||
#define SHOW_COLS_STEP_SIZE 4096
|
||||
|
||||
static SShowObj *mndCreateShowObj(SMnode *pMnode, SRetrieveTableReq *pReq);
|
||||
static void mndFreeShowObj(SShowObj *pShow);
|
||||
|
@ -76,6 +77,8 @@ static int32_t convertToRetrieveType(char *name, int32_t len) {
|
|||
type = TSDB_MGMT_TABLE_TABLE;
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_TAGS, len) == 0) {
|
||||
type = TSDB_MGMT_TABLE_TAG;
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_COLS, len) == 0) {
|
||||
type = TSDB_MGMT_TABLE_COL;
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_TABLE_DISTRIBUTED, len) == 0) {
|
||||
// type = TSDB_MGMT_TABLE_DIST;
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_USERS, len) == 0) {
|
||||
|
@ -131,6 +134,7 @@ static SShowObj *mndCreateShowObj(SMnode *pMnode, SRetrieveTableReq *pReq) {
|
|||
showObj.pMnode = pMnode;
|
||||
showObj.type = convertToRetrieveType(pReq->tb, tListLen(pReq->tb));
|
||||
memcpy(showObj.db, pReq->db, TSDB_DB_FNAME_LEN);
|
||||
strncpy(showObj.filterTb, pReq->filterTb, TSDB_TABLE_NAME_LEN);
|
||||
|
||||
int32_t keepTime = tsShellActivityTimer * 6 * 1000;
|
||||
SShowObj *pShow = taosCachePut(pMgmt->cache, &showId, sizeof(int64_t), &showObj, size, keepTime);
|
||||
|
@ -190,13 +194,15 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) {
|
|||
int32_t rowsToRead = SHOW_STEP_SIZE;
|
||||
int32_t size = 0;
|
||||
int32_t rowsRead = 0;
|
||||
|
||||
mDebug("mndProcessRetrieveSysTableReq start");
|
||||
SRetrieveTableReq retrieveReq = {0};
|
||||
if (tDeserializeSRetrieveTableReq(pReq->pCont, pReq->contLen, &retrieveReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mDebug("mndProcessRetrieveSysTableReq tb:%s", retrieveReq.tb);
|
||||
|
||||
if (retrieveReq.showId == 0) {
|
||||
STableMetaRsp *pMeta = taosHashGet(pMnode->infosMeta, retrieveReq.tb, strlen(retrieveReq.tb));
|
||||
if (pMeta == NULL) {
|
||||
|
@ -226,6 +232,9 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
if(pShow->type == TSDB_MGMT_TABLE_COL){ // expend capacity for ins_columns
|
||||
rowsToRead = SHOW_COLS_STEP_SIZE;
|
||||
}
|
||||
ShowRetrieveFp retrieveFp = pMgmt->retrieveFps[pShow->type];
|
||||
if (retrieveFp == NULL) {
|
||||
mndReleaseShowObj(pShow, false);
|
||||
|
|
|
@ -202,11 +202,13 @@ static SSdbRow *mndSmaActionDecode(SSdbRaw *pRaw) {
|
|||
|
||||
_OVER:
|
||||
if (terrno != 0) {
|
||||
mError("sma:%s, failed to decode from raw:%p since %s", pSma == NULL ? "null" : pSma->name, pRaw, terrstr());
|
||||
taosMemoryFreeClear(pSma->expr);
|
||||
taosMemoryFreeClear(pSma->tagsFilter);
|
||||
taosMemoryFreeClear(pSma->sql);
|
||||
taosMemoryFreeClear(pSma->ast);
|
||||
if (pSma != NULL) {
|
||||
mError("sma:%s, failed to decode from raw:%p since %s", pSma->name, pRaw, terrstr());
|
||||
taosMemoryFreeClear(pSma->expr);
|
||||
taosMemoryFreeClear(pSma->tagsFilter);
|
||||
taosMemoryFreeClear(pSma->sql);
|
||||
taosMemoryFreeClear(pSma->ast);
|
||||
}
|
||||
taosMemoryFreeClear(pRow);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -457,8 +459,10 @@ static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans,
|
|||
|
||||
int32_t contLen = 0;
|
||||
void *pReq = mndBuildCreateVnodeReq(pMnode, pDnode, pDb, pVgroup, &contLen);
|
||||
taosMemoryFreeClear(pSmaReq);
|
||||
if (pReq == NULL) return -1;
|
||||
if (pReq == NULL) {
|
||||
taosMemoryFreeClear(pSmaReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
action.pCont = pReq;
|
||||
action.contLen = contLen;
|
||||
|
@ -466,10 +470,21 @@ static int32_t mndSetCreateSmaVgroupRedoActions(SMnode *pMnode, STrans *pTrans,
|
|||
action.acceptableCode = TSDB_CODE_VND_ALREADY_EXIST;
|
||||
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
taosMemoryFreeClear(pSmaReq);
|
||||
taosMemoryFree(pReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
action.pCont = pSmaReq;
|
||||
action.contLen = smaContLen;
|
||||
action.msgType = TDMT_VND_CREATE_SMA;
|
||||
action.acceptableCode = TSDB_CODE_TSMA_ALREADY_EXIST;
|
||||
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
taosMemoryFreeClear(pSmaReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ static int32_t mndProcessAlterStbReq(SRpcMsg *pReq);
|
|||
static int32_t mndProcessDropStbReq(SRpcMsg *pReq);
|
||||
static int32_t mndProcessTableMetaReq(SRpcMsg *pReq);
|
||||
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter);
|
||||
static int32_t mndProcessTableCfgReq(SRpcMsg *pReq);
|
||||
static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp,
|
||||
|
@ -72,6 +73,7 @@ int32_t mndInitStb(SMnode *pMnode) {
|
|||
mndSetMsgHandle(pMnode, TDMT_MND_TABLE_META, mndProcessTableMetaReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TTL_TIMER, mndProcessTtlTimer);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TABLE_CFG, mndProcessTableCfgReq);
|
||||
// mndSetMsgHandle(pMnode, TDMT_MND_SYSTABLE_RETRIEVE, mndProcessRetrieveStbReq);
|
||||
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_INDEX, mndProcessCreateIndexReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_DROP_INDEX, mndProcessDropIndexReq);
|
||||
|
@ -81,6 +83,9 @@ int32_t mndInitStb(SMnode *pMnode) {
|
|||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_STB, mndRetrieveStb);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_STB, mndCancelGetNextStb);
|
||||
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_COL, mndRetrieveStbCol);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_COL, mndCancelGetNextStb);
|
||||
|
||||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
|
@ -2534,6 +2539,283 @@ void mndExtractTbNameFromStbFullName(const char *stbFullName, char *dst, int32_t
|
|||
}
|
||||
}
|
||||
|
||||
//static int32_t mndProcessRetrieveStbReq(SRpcMsg *pReq) {
|
||||
// SMnode *pMnode = pReq->info.node;
|
||||
// SShowMgmt *pMgmt = &pMnode->showMgmt;
|
||||
// SShowObj *pShow = NULL;
|
||||
// int32_t rowsToRead = SHOW_STEP_SIZE;
|
||||
// int32_t rowsRead = 0;
|
||||
//
|
||||
// SRetrieveTableReq retrieveReq = {0};
|
||||
// if (tDeserializeSRetrieveTableReq(pReq->pCont, pReq->contLen, &retrieveReq) != 0) {
|
||||
// terrno = TSDB_CODE_INVALID_MSG;
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// SMnode *pMnode = pReq->info.node;
|
||||
// SSdb *pSdb = pMnode->pSdb;
|
||||
// int32_t numOfRows = 0;
|
||||
// SDbObj *pDb = NULL;
|
||||
// ESdbStatus objStatus = 0;
|
||||
//
|
||||
// SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
|
||||
// if (pUser == NULL) return 0;
|
||||
// bool sysinfo = pUser->sysInfo;
|
||||
//
|
||||
// // Append the information_schema database into the result.
|
||||
//// if (!pShow->sysDbRsp) {
|
||||
//// SDbObj infoschemaDb = {0};
|
||||
//// setInformationSchemaDbCfg(pMnode, &infoschemaDb);
|
||||
//// size_t numOfTables = 0;
|
||||
//// getVisibleInfosTablesNum(sysinfo, &numOfTables);
|
||||
//// mndDumpDbInfoData(pMnode, pBlock, &infoschemaDb, pShow, numOfRows, numOfTables, true, 0, 1);
|
||||
////
|
||||
//// numOfRows += 1;
|
||||
////
|
||||
//// SDbObj perfschemaDb = {0};
|
||||
//// setPerfSchemaDbCfg(pMnode, &perfschemaDb);
|
||||
//// numOfTables = 0;
|
||||
//// getPerfDbMeta(NULL, &numOfTables);
|
||||
//// mndDumpDbInfoData(pMnode, pBlock, &perfschemaDb, pShow, numOfRows, numOfTables, true, 0, 1);
|
||||
////
|
||||
//// numOfRows += 1;
|
||||
//// pShow->sysDbRsp = true;
|
||||
//// }
|
||||
//
|
||||
// SSDataBlock* p = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_COLS);
|
||||
// blockDataEnsureCapacity(p, rowsToRead);
|
||||
//
|
||||
// size_t size = 0;
|
||||
// const SSysTableMeta* pSysDbTableMeta = NULL;
|
||||
//
|
||||
// getInfosDbMeta(&pSysDbTableMeta, &size);
|
||||
// p->info.rows = buildDbColsInfoBlock(sysinfo, p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB);
|
||||
//
|
||||
// getPerfDbMeta(&pSysDbTableMeta, &size);
|
||||
// p->info.rows = buildDbColsInfoBlock(sysinfo, p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB);
|
||||
//
|
||||
// blockDataDestroy(p);
|
||||
//
|
||||
//
|
||||
// while (numOfRows < rowsToRead) {
|
||||
// pShow->pIter = sdbFetchAll(pSdb, SDB_DB, pShow->pIter, (void **)&pDb, &objStatus, true);
|
||||
// if (pShow->pIter == NULL) break;
|
||||
// if (strncmp(retrieveReq.db, pDb->name, strlen(retrieveReq.db)) != 0){
|
||||
// continue;
|
||||
// }
|
||||
// if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_READ_OR_WRITE_DB, pDb) != 0) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// while (numOfRows < rowsToRead) {
|
||||
// pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
|
||||
// if (pShow->pIter == NULL) break;
|
||||
//
|
||||
// if (pDb != NULL && pStb->dbUid != pDb->uid) {
|
||||
// sdbRelease(pSdb, pStb);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// cols = 0;
|
||||
//
|
||||
// SName name = {0};
|
||||
// char stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
// mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
|
||||
// varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
|
||||
//
|
||||
// SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)stbName, false);
|
||||
//
|
||||
// char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
// tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
|
||||
// tNameGetDbName(&name, varDataVal(db));
|
||||
// varDataSetLen(db, strlen(varDataVal(db)));
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)db, false);
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)&pStb->createdTime, false);
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)&pStb->numOfColumns, false);
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)&pStb->numOfTags, false);
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)&pStb->updateTime, false); // number of tables
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// if (pStb->commentLen > 0) {
|
||||
// char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
// STR_TO_VARSTR(comment, pStb->comment);
|
||||
// colDataAppend(pColInfo, numOfRows, comment, false);
|
||||
// } else if (pStb->commentLen == 0) {
|
||||
// char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
|
||||
// STR_TO_VARSTR(comment, "");
|
||||
// colDataAppend(pColInfo, numOfRows, comment, false);
|
||||
// } else {
|
||||
// colDataAppendNULL(pColInfo, numOfRows);
|
||||
// }
|
||||
//
|
||||
// char watermark[64 + VARSTR_HEADER_SIZE] = {0};
|
||||
// sprintf(varDataVal(watermark), "%" PRId64 "a,%" PRId64 "a", pStb->watermark[0], pStb->watermark[1]);
|
||||
// varDataSetLen(watermark, strlen(varDataVal(watermark)));
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)watermark, false);
|
||||
//
|
||||
// char maxDelay[64 + VARSTR_HEADER_SIZE] = {0};
|
||||
// sprintf(varDataVal(maxDelay), "%" PRId64 "a,%" PRId64 "a", pStb->maxdelay[0], pStb->maxdelay[1]);
|
||||
// varDataSetLen(maxDelay, strlen(varDataVal(maxDelay)));
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)maxDelay, false);
|
||||
//
|
||||
// char rollup[160 + VARSTR_HEADER_SIZE] = {0};
|
||||
// int32_t rollupNum = (int32_t)taosArrayGetSize(pStb->pFuncs);
|
||||
// char *sep = ", ";
|
||||
// int32_t sepLen = strlen(sep);
|
||||
// int32_t rollupLen = sizeof(rollup) - VARSTR_HEADER_SIZE - 2;
|
||||
// for (int32_t i = 0; i < rollupNum; ++i) {
|
||||
// char *funcName = taosArrayGet(pStb->pFuncs, i);
|
||||
// if (i) {
|
||||
// strncat(varDataVal(rollup), sep, rollupLen);
|
||||
// rollupLen -= sepLen;
|
||||
// }
|
||||
// strncat(varDataVal(rollup), funcName, rollupLen);
|
||||
// rollupLen -= strlen(funcName);
|
||||
// }
|
||||
// varDataSetLen(rollup, strlen(varDataVal(rollup)));
|
||||
//
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
// colDataAppend(pColInfo, numOfRows, (const char *)rollup, false);
|
||||
//
|
||||
// numOfRows++;
|
||||
// sdbRelease(pSdb, pStb);
|
||||
// }
|
||||
//
|
||||
// if (pDb != NULL) {
|
||||
// mndReleaseDb(pMnode, pDb);
|
||||
// }
|
||||
//
|
||||
// sdbRelease(pSdb, pDb);
|
||||
// }
|
||||
//
|
||||
// pShow->numOfRows += numOfRows;
|
||||
// mndReleaseUser(pMnode, pUser);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ShowRetrieveFp retrieveFp = pMgmt->retrieveFps[pShow->type];
|
||||
// if (retrieveFp == NULL) {
|
||||
// mndReleaseShowObj(pShow, false);
|
||||
// terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||
// mError("show:0x%" PRIx64 ", failed to retrieve data since %s", pShow->id, terrstr());
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// mDebug("show:0x%" PRIx64 ", start retrieve data, type:%d", pShow->id, pShow->type);
|
||||
// if (retrieveReq.user[0] != 0) {
|
||||
// memcpy(pReq->info.conn.user, retrieveReq.user, TSDB_USER_LEN);
|
||||
// } else {
|
||||
// memcpy(pReq->info.conn.user, TSDB_DEFAULT_USER, strlen(TSDB_DEFAULT_USER) + 1);
|
||||
// }
|
||||
// if (retrieveReq.db[0] && mndCheckShowPrivilege(pMnode, pReq->info.conn.user, pShow->type, retrieveReq.db) != 0) {
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// int32_t numOfCols = pShow->pMeta->numOfColumns;
|
||||
//
|
||||
// SSDataBlock *pBlock = createDataBlock();
|
||||
// for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
// SColumnInfoData idata = {0};
|
||||
//
|
||||
// SSchema *p = &pShow->pMeta->pSchemas[i];
|
||||
//
|
||||
// idata.info.bytes = p->bytes;
|
||||
// idata.info.type = p->type;
|
||||
// idata.info.colId = p->colId;
|
||||
// blockDataAppendColInfo(pBlock, &idata);
|
||||
// }
|
||||
//
|
||||
// blockDataEnsureCapacity(pBlock, rowsToRead);
|
||||
//
|
||||
// if (mndCheckRetrieveFinished(pShow)) {
|
||||
// mDebug("show:0x%" PRIx64 ", read finished, numOfRows:%d", pShow->id, pShow->numOfRows);
|
||||
// rowsRead = 0;
|
||||
// } else {
|
||||
// rowsRead = (*retrieveFp)(pReq, pShow, pBlock, rowsToRead);
|
||||
// if (rowsRead < 0) {
|
||||
// terrno = rowsRead;
|
||||
// mDebug("show:0x%" PRIx64 ", retrieve completed", pShow->id);
|
||||
// mndReleaseShowObj(pShow, true);
|
||||
// blockDataDestroy(pBlock);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// pBlock->info.rows = rowsRead;
|
||||
// mDebug("show:0x%" PRIx64 ", stop retrieve data, rowsRead:%d numOfRows:%d", pShow->id, rowsRead, pShow->numOfRows);
|
||||
// }
|
||||
//
|
||||
// size = sizeof(SRetrieveMetaTableRsp) + sizeof(int32_t) + sizeof(SSysTableSchema) * pShow->pMeta->numOfColumns +
|
||||
// blockDataGetSize(pBlock) + blockDataGetSerialMetaSize(taosArrayGetSize(pBlock->pDataBlock));
|
||||
//
|
||||
// SRetrieveMetaTableRsp *pRsp = rpcMallocCont(size);
|
||||
// if (pRsp == NULL) {
|
||||
// mndReleaseShowObj(pShow, false);
|
||||
// terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
// mError("show:0x%" PRIx64 ", failed to retrieve data since %s", pShow->id, terrstr());
|
||||
// blockDataDestroy(pBlock);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// pRsp->handle = htobe64(pShow->id);
|
||||
//
|
||||
// if (rowsRead > 0) {
|
||||
// char *pStart = pRsp->data;
|
||||
// SSchema *ps = pShow->pMeta->pSchemas;
|
||||
//
|
||||
// *(int32_t *)pStart = htonl(pShow->pMeta->numOfColumns);
|
||||
// pStart += sizeof(int32_t); // number of columns
|
||||
//
|
||||
// for (int32_t i = 0; i < pShow->pMeta->numOfColumns; ++i) {
|
||||
// SSysTableSchema *pSchema = (SSysTableSchema *)pStart;
|
||||
// pSchema->bytes = htonl(ps[i].bytes);
|
||||
// pSchema->colId = htons(ps[i].colId);
|
||||
// pSchema->type = ps[i].type;
|
||||
//
|
||||
// pStart += sizeof(SSysTableSchema);
|
||||
// }
|
||||
//
|
||||
// int32_t len = blockEncode(pBlock, pStart, pShow->pMeta->numOfColumns);
|
||||
// }
|
||||
//
|
||||
// pRsp->numOfRows = htonl(rowsRead);
|
||||
// pRsp->precision = TSDB_TIME_PRECISION_MILLI; // millisecond time precision
|
||||
// pReq->info.rsp = pRsp;
|
||||
// pReq->info.rspLen = size;
|
||||
//
|
||||
// if (rowsRead == 0 || rowsRead < rowsToRead) {
|
||||
// pRsp->completed = 1;
|
||||
// mDebug("show:0x%" PRIx64 ", retrieve completed", pShow->id);
|
||||
// mndReleaseShowObj(pShow, true);
|
||||
// } else {
|
||||
// mDebug("show:0x%" PRIx64 ", retrieve not completed yet", pShow->id);
|
||||
// mndReleaseShowObj(pShow, false);
|
||||
// }
|
||||
//
|
||||
// blockDataDestroy(pBlock);
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
//}
|
||||
|
||||
|
||||
static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
@ -2644,6 +2926,187 @@ static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
|
|||
return numOfRows;
|
||||
}
|
||||
|
||||
static int32_t buildDbColsInfoBlock(const SSDataBlock* p, const SSysTableMeta* pSysDbTableMeta, size_t size,
|
||||
const char* dbName, const char* tbName) {
|
||||
char tName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char dName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
int32_t numOfRows = p->info.rows;
|
||||
|
||||
STR_TO_VARSTR(dName, dbName);
|
||||
STR_TO_VARSTR(typeName, "SYSTEM_TABLE");
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
const SSysTableMeta* pm = &pSysDbTableMeta[i];
|
||||
// if (pm->sysInfo) {
|
||||
// continue;
|
||||
// }
|
||||
if(tbName[0] && strncmp(tbName, pm->name, TSDB_TABLE_NAME_LEN) != 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
STR_TO_VARSTR(tName, pm->name);
|
||||
|
||||
for(int32_t j = 0; j < pm->colNum; j++){
|
||||
// table name
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(p->pDataBlock, 0);
|
||||
colDataAppend(pColInfoData, numOfRows, tName, false);
|
||||
|
||||
// database name
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 1);
|
||||
colDataAppend(pColInfoData, numOfRows, dName, false);
|
||||
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 2);
|
||||
colDataAppend(pColInfoData, numOfRows, typeName, false);
|
||||
|
||||
// col name
|
||||
char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(colName, pm->schema[j].name);
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 3);
|
||||
colDataAppend(pColInfoData, numOfRows, colName, false);
|
||||
|
||||
// col type
|
||||
int8_t colType = pm->schema[j].type;
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 4);
|
||||
char colTypeStr[VARSTR_HEADER_SIZE + 32];
|
||||
int colTypeLen = sprintf(varDataVal(colTypeStr), "%s", tDataTypes[colType].name);
|
||||
if (colType == TSDB_DATA_TYPE_VARCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(pm->schema[j].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(
|
||||
varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((pm->schema[j].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*)colTypeStr, false);
|
||||
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 5);
|
||||
colDataAppend(pColInfoData, numOfRows, (const char*)&pm->schema[j].bytes, false);
|
||||
for (int32_t k = 6; k <= 8; ++k) {
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, k);
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
}
|
||||
|
||||
numOfRows += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static int32_t buildSysDbColsInfo(SSDataBlock* p, char* db, char* tb) {
|
||||
size_t size = 0;
|
||||
const SSysTableMeta* pSysDbTableMeta = NULL;
|
||||
|
||||
if(db[0] && strncmp(db, TSDB_INFORMATION_SCHEMA_DB, TSDB_DB_FNAME_LEN) != 0 && strncmp(db, TSDB_PERFORMANCE_SCHEMA_DB, TSDB_DB_FNAME_LEN) != 0){
|
||||
return p->info.rows;
|
||||
}
|
||||
|
||||
getInfosDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_INFORMATION_SCHEMA_DB, tb);
|
||||
|
||||
getPerfDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbColsInfoBlock(p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB, tb);
|
||||
|
||||
return p->info.rows;
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStbObj *pStb = NULL;
|
||||
|
||||
int32_t numOfRows = buildSysDbColsInfo(pBlock, pShow->db, pShow->filterTb);
|
||||
mDebug("mndRetrieveStbCol get system table cols, rows:%d, db:%s", numOfRows, pShow->db);
|
||||
SDbObj *pDb = NULL;
|
||||
if (strlen(pShow->db) > 0) {
|
||||
pDb = mndAcquireDb(pMnode, pShow->db);
|
||||
if (pDb == NULL) return terrno;
|
||||
}
|
||||
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(typeName, "SUPER_TABLE");
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_STB, pShow->pIter, (void **)&pStb);
|
||||
if (pShow->pIter == NULL) break;
|
||||
|
||||
if (pDb != NULL && pStb->dbUid != pDb->uid) {
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
|
||||
SName name = {0};
|
||||
char stbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
mndExtractTbNameFromStbFullName(pStb->name, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN);
|
||||
if(pShow->filterTb[0] && strncmp(pShow->filterTb, &stbName[VARSTR_HEADER_SIZE], TSDB_TABLE_NAME_LEN) != 0){
|
||||
sdbRelease(pSdb, pStb);
|
||||
continue;
|
||||
}
|
||||
varDataSetLen(stbName, strlen(&stbName[VARSTR_HEADER_SIZE]));
|
||||
|
||||
mDebug("mndRetrieveStbCol get stable cols, stable name:%s, db:%s", pStb->name, pStb->db);
|
||||
|
||||
char db[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&name, pStb->db, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameGetDbName(&name, varDataVal(db));
|
||||
varDataSetLen(db, strlen(varDataVal(db)));
|
||||
|
||||
for(int i = 0; i < pStb->numOfColumns; i++){
|
||||
int32_t cols = 0;
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)stbName, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)db, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, typeName, false);
|
||||
|
||||
// col name
|
||||
char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(colName, pStb->pColumns[i].name);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, colName, false);
|
||||
|
||||
// col type
|
||||
int8_t colType = pStb->pColumns[i].type;
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
char colTypeStr[VARSTR_HEADER_SIZE + 32];
|
||||
int colTypeLen = sprintf(varDataVal(colTypeStr), "%s", tDataTypes[colType].name);
|
||||
if (colType == TSDB_DATA_TYPE_VARCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(
|
||||
varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((pStb->pColumns[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataAppend(pColInfo, numOfRows, (char*)colTypeStr, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char*)&pStb->pColumns[i].bytes, false);
|
||||
while(cols < pShow->numOfColumns) {
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppendNULL(pColInfo, numOfRows);
|
||||
}
|
||||
numOfRows++;
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pStb);
|
||||
}
|
||||
|
||||
if (pDb != NULL) {
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
}
|
||||
|
||||
pShow->numOfRows += numOfRows;
|
||||
mDebug("mndRetrieveStbCol success, rows:%d, pShow->numOfRows:%d", numOfRows, pShow->numOfRows);
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
|
|
|
@ -314,7 +314,11 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj,
|
|||
}
|
||||
tstrncpy(pObj->targetDb, pTargetDb->name, TSDB_DB_FNAME_LEN);
|
||||
|
||||
pObj->targetStbUid = mndGenerateUid(pObj->targetSTbName, TSDB_TABLE_FNAME_LEN);
|
||||
if (pCreate->createStb == STREAM_CREATE_STABLE_TRUE) {
|
||||
pObj->targetStbUid = mndGenerateUid(pObj->targetSTbName, TSDB_TABLE_FNAME_LEN);
|
||||
} else {
|
||||
pObj->targetStbUid = pCreate->targetStbUid;
|
||||
}
|
||||
pObj->targetDbUid = pTargetDb->uid;
|
||||
mndReleaseDb(pMnode, pTargetDb);
|
||||
|
||||
|
@ -334,6 +338,38 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj,
|
|||
goto FAIL;
|
||||
}
|
||||
|
||||
int32_t numOfNULL = taosArrayGetSize(pCreate->fillNullCols);
|
||||
if(numOfNULL > 0) {
|
||||
pObj->outputSchema.nCols += numOfNULL;
|
||||
SSchema* pFullSchema = taosMemoryCalloc(pObj->outputSchema.nCols, sizeof(SSchema));
|
||||
if (!pFullSchema) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
int32_t nullIndex = 0;
|
||||
int32_t dataIndex = 0;
|
||||
for (int16_t i = 0; i < pObj->outputSchema.nCols; i++) {
|
||||
SColLocation* pos = taosArrayGet(pCreate->fillNullCols, nullIndex);
|
||||
if (i < pos->slotId) {
|
||||
pFullSchema[i].bytes = pObj->outputSchema.pSchema[dataIndex].bytes;
|
||||
pFullSchema[i].colId = i + 1; // pObj->outputSchema.pSchema[dataIndex].colId;
|
||||
pFullSchema[i].flags = pObj->outputSchema.pSchema[dataIndex].flags;
|
||||
strcpy(pFullSchema[i].name, pObj->outputSchema.pSchema[dataIndex].name);
|
||||
pFullSchema[i].type = pObj->outputSchema.pSchema[dataIndex].type;
|
||||
dataIndex++;
|
||||
} else {
|
||||
pFullSchema[i].bytes = 0;
|
||||
pFullSchema[i].colId = pos->colId;
|
||||
pFullSchema[i].flags = COL_SET_NULL;
|
||||
memset(pFullSchema[i].name, 0, TSDB_COL_NAME_LEN);
|
||||
pFullSchema[i].type = pos->type;
|
||||
nullIndex++;
|
||||
}
|
||||
}
|
||||
taosMemoryFree(pObj->outputSchema.pSchema);
|
||||
pObj->outputSchema.pSchema = pFullSchema;
|
||||
}
|
||||
|
||||
SPlanContext cxt = {
|
||||
.pAstRoot = pAst,
|
||||
.topicQuery = false,
|
||||
|
|
|
@ -760,6 +760,27 @@ static SSdbRow *mndSubActionDecode(SSdbRaw *pRaw) {
|
|||
goto SUB_DECODE_OVER;
|
||||
}
|
||||
|
||||
// update epset saved in mnode
|
||||
if (pSub->unassignedVgs != NULL) {
|
||||
int32_t size = (int32_t)taosArrayGetSize(pSub->unassignedVgs);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SMqVgEp *pMqVgEp = taosArrayGet(pSub->unassignedVgs, i);
|
||||
tmsgUpdateDnodeEpSet(&pMqVgEp->epSet);
|
||||
}
|
||||
}
|
||||
if (pSub->consumerHash != NULL) {
|
||||
void *pIter = taosHashIterate(pSub->consumerHash, NULL);
|
||||
while (pIter) {
|
||||
SMqConsumerEp *pConsumerEp = pIter;
|
||||
int32_t size = (int32_t)taosArrayGetSize(pConsumerEp->vgs);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SMqVgEp *pMqVgEp = taosArrayGet(pConsumerEp->vgs, i);
|
||||
tmsgUpdateDnodeEpSet(&pMqVgEp->epSet);
|
||||
}
|
||||
pIter = taosHashIterate(pSub->consumerHash, pIter);
|
||||
}
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
SUB_DECODE_OVER:
|
||||
|
|
|
@ -271,9 +271,11 @@ SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
|
|||
int32_t mndInitSync(SMnode *pMnode) {
|
||||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
taosThreadMutexInit(&pMgmt->lock, NULL);
|
||||
taosThreadMutexLock(&pMgmt->lock);
|
||||
pMgmt->transId = 0;
|
||||
pMgmt->transSec = 0;
|
||||
pMgmt->transSeq = 0;
|
||||
taosThreadMutexUnlock(&pMgmt->lock);
|
||||
|
||||
SSyncInfo syncInfo = {
|
||||
.snapshotStrategy = SYNC_STRATEGY_STANDARD_SNAPSHOT,
|
||||
|
@ -369,6 +371,7 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, int32_t transId) {
|
|||
if (pMgmt->transId != 0) {
|
||||
mError("trans:%d, can't be proposed since trans:%d already waiting for confirm", transId, pMgmt->transId);
|
||||
taosThreadMutexUnlock(&pMgmt->lock);
|
||||
rpcFreeCont(req.pCont);
|
||||
terrno = TSDB_CODE_MND_LAST_TRANS_NOT_FINISHED;
|
||||
return terrno;
|
||||
}
|
||||
|
|
|
@ -329,6 +329,7 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
|
|||
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)
|
||||
|
|
|
@ -1441,10 +1441,10 @@ static int32_t mndRedistributeVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb,
|
|||
|
||||
{
|
||||
SSdbRaw *pRaw = mndVgroupActionEncode(&newVg);
|
||||
if (pRaw == NULL) return -1;
|
||||
if (pRaw == NULL) goto _OVER;
|
||||
if (mndTransAppendCommitlog(pTrans, pRaw) != 0) {
|
||||
sdbFreeRaw(pRaw);
|
||||
return -1;
|
||||
goto _OVER;
|
||||
}
|
||||
(void)sdbSetRawStatus(pRaw, SDB_STATUS_READY);
|
||||
}
|
||||
|
|
|
@ -291,6 +291,7 @@ int32_t sdbWriteWithoutFree(SSdb *pSdb, SSdbRaw *pRaw);
|
|||
* @return void* The object of the row.
|
||||
*/
|
||||
void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey);
|
||||
void *sdbAcquireNotReadyObj(SSdb *pSdb, ESdbType type, const void *pKey);
|
||||
|
||||
/**
|
||||
* @brief Release a row from sdb.
|
||||
|
|
|
@ -228,11 +228,12 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
|
|||
int32_t readLen = 0;
|
||||
int64_t ret = 0;
|
||||
char file[PATH_MAX] = {0};
|
||||
int32_t bufLen = TSDB_MAX_MSG_SIZE;
|
||||
|
||||
snprintf(file, sizeof(file), "%s%ssdb.data", pSdb->currDir, TD_DIRSEP);
|
||||
mInfo("start to read sdb file:%s", file);
|
||||
|
||||
SSdbRaw *pRaw = taosMemoryMalloc(TSDB_MAX_MSG_SIZE + 100);
|
||||
SSdbRaw *pRaw = taosMemoryMalloc(bufLen + 100);
|
||||
if (pRaw == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("failed read sdb file since %s", terrstr());
|
||||
|
@ -275,14 +276,15 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
|
|||
}
|
||||
|
||||
readLen = pRaw->dataLen + sizeof(int32_t);
|
||||
if (readLen >= pRaw->dataLen) {
|
||||
SSdbRaw *pNewRaw = taosMemoryMalloc(pRaw->dataLen + TSDB_MAX_MSG_SIZE);
|
||||
if (readLen >= bufLen) {
|
||||
bufLen = pRaw->dataLen * 2;
|
||||
SSdbRaw *pNewRaw = taosMemoryMalloc(bufLen + 100);
|
||||
if (pNewRaw == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mError("failed read sdb file since malloc new sdbRaw size:%d failed", pRaw->dataLen + TSDB_MAX_MSG_SIZE);
|
||||
mError("failed read sdb file since malloc new sdbRaw size:%d failed", bufLen);
|
||||
goto _OVER;
|
||||
}
|
||||
mInfo("malloc new sdbRaw size:%d, type:%d", pRaw->dataLen + TSDB_MAX_MSG_SIZE, pRaw->type);
|
||||
mInfo("malloc new sdb raw size:%d, type:%d", bufLen, pRaw->type);
|
||||
memcpy(pNewRaw, pRaw, sizeof(SSdbRaw));
|
||||
sdbFreeRaw(pRaw);
|
||||
pRaw = pNewRaw;
|
||||
|
|
|
@ -270,7 +270,7 @@ int32_t sdbWrite(SSdb *pSdb, SSdbRaw *pRaw) {
|
|||
return code;
|
||||
}
|
||||
|
||||
void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey) {
|
||||
void *sdbAcquireAll(SSdb *pSdb, ESdbType type, const void *pKey, bool onlyReady) {
|
||||
terrno = 0;
|
||||
|
||||
SHashObj *hash = sdbGetHash(pSdb, type);
|
||||
|
@ -306,10 +306,24 @@ void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (pRet == NULL) {
|
||||
if (!onlyReady) {
|
||||
terrno = 0;
|
||||
atomic_add_fetch_32(&pRow->refCount, 1);
|
||||
pRet = pRow->pObj;
|
||||
sdbPrintOper(pSdb, pRow, "acquire");
|
||||
}
|
||||
}
|
||||
|
||||
sdbUnLock(pSdb, type);
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void *sdbAcquire(SSdb *pSdb, ESdbType type, const void *pKey) { return sdbAcquireAll(pSdb, type, pKey, true); }
|
||||
void *sdbAcquireNotReadyObj(SSdb *pSdb, ESdbType type, const void *pKey) {
|
||||
return sdbAcquireAll(pSdb, type, pKey, false);
|
||||
}
|
||||
|
||||
static void sdbCheckRow(SSdb *pSdb, SSdbRow *pRow) {
|
||||
int32_t type = pRow->type;
|
||||
sdbWriteLock(pSdb, type);
|
||||
|
|
|
@ -152,7 +152,7 @@ typedef struct SMTbCursor SMTbCursor;
|
|||
|
||||
SMTbCursor *metaOpenTbCursor(SMeta *pMeta);
|
||||
void metaCloseTbCursor(SMTbCursor *pTbCur);
|
||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur);
|
||||
int32_t metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType);
|
||||
#endif
|
||||
|
||||
// tsdb
|
||||
|
|
|
@ -310,7 +310,7 @@ void metaCloseTbCursor(SMTbCursor *pTbCur) {
|
|||
}
|
||||
}
|
||||
|
||||
int metaTbCursorNext(SMTbCursor *pTbCur) {
|
||||
int metaTbCursorNext(SMTbCursor *pTbCur, ETableType jumpTableType) {
|
||||
int ret;
|
||||
void *pBuf;
|
||||
STbCfg tbCfg;
|
||||
|
@ -324,7 +324,7 @@ int metaTbCursorNext(SMTbCursor *pTbCur) {
|
|||
tDecoderClear(&pTbCur->mr.coder);
|
||||
|
||||
metaGetTableEntryByVersion(&pTbCur->mr, ((SUidIdxVal *)pTbCur->pVal)[0].version, *(tb_uid_t *)pTbCur->pKey);
|
||||
if (pTbCur->mr.me.type == TSDB_SUPER_TABLE) {
|
||||
if (pTbCur->mr.me.type == jumpTableType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,13 @@ static int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *
|
|||
static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg);
|
||||
static int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
|
||||
|
||||
// TODO: Who is responsible for resource allocate and release?
|
||||
int32_t tdProcessTSmaInsert(SSma *pSma, int64_t indexUid, const char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((code = tdProcessTSmaInsertImpl(pSma, indexUid, msg)) < 0) {
|
||||
smaWarn("vgId:%d, insert tsma data failed since %s", SMA_VID(pSma), tstrerror(terrno));
|
||||
}
|
||||
// TODO: destroy SSDataBlocks(msg)
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -42,7 +41,6 @@ int32_t tdProcessTSmaCreate(SSma *pSma, int64_t version, const char *msg) {
|
|||
if ((code = tdProcessTSmaCreateImpl(pSma, version, msg)) < 0) {
|
||||
smaWarn("vgId:%d, create tsma failed since %s", SMA_VID(pSma), tstrerror(terrno));
|
||||
}
|
||||
// TODO: destroy SSDataBlocks(msg)
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -258,28 +256,23 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
|
||||
SSubmitTbData *pTbData = (SSubmitTbData *)taosMemoryCalloc(1, sizeof(SSubmitTbData));
|
||||
if (!pTbData) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
SSubmitTbData tbData = {0};
|
||||
|
||||
|
||||
if (!(pTbData->aRowP = taosArrayInit(rows, sizeof(SRow *)))) {
|
||||
taosMemoryFree(pTbData);
|
||||
if (!(tbData.aRowP = taosArrayInit(rows, sizeof(SRow *)))) {
|
||||
goto _end;
|
||||
}
|
||||
pTbData->suid = suid;
|
||||
pTbData->uid = 0; // uid is assigned by vnode
|
||||
pTbData->sver = pTSchema->version;
|
||||
tbData.suid = suid;
|
||||
tbData.uid = 0; // uid is assigned by vnode
|
||||
tbData.sver = pTSchema->version;
|
||||
|
||||
if (createTb) {
|
||||
pTbData->pCreateTbReq = taosArrayGetP(createTbArray, i);
|
||||
if (pTbData->pCreateTbReq) pTbData->flags = SUBMIT_REQ_AUTO_CREATE_TABLE;
|
||||
tbData.pCreateTbReq = taosArrayGetP(createTbArray, i);
|
||||
if (tbData.pCreateTbReq) tbData.flags = SUBMIT_REQ_AUTO_CREATE_TABLE;
|
||||
}
|
||||
|
||||
if (!pVals && !(pVals = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal)))) {
|
||||
taosArrayDestroy(pTbData->aRowP);
|
||||
taosMemoryFree(pTbData);
|
||||
taosArrayDestroy(tbData.aRowP);
|
||||
goto _end;
|
||||
}
|
||||
|
||||
|
@ -307,14 +300,13 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
}
|
||||
SRow *pRow = NULL;
|
||||
if ((terrno = tRowBuild(pVals, (STSchema *)pTSchema, &pRow)) < 0) {
|
||||
tDestroySSubmitTbData(pTbData, TSDB_MSG_FLG_ENCODE);
|
||||
tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||
goto _end;
|
||||
}
|
||||
ASSERT(pRow);
|
||||
taosArrayPush(pTbData->aRowP, &pRow);
|
||||
taosArrayPush(tbData.aRowP, &pRow);
|
||||
}
|
||||
|
||||
taosArrayPush(pReq->aSubmitTbData, pTbData);
|
||||
taosArrayPush(pReq->aSubmitTbData, &tbData);
|
||||
}
|
||||
|
||||
// encode
|
||||
|
@ -336,9 +328,13 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
tEncoderClear(&encoder);
|
||||
}
|
||||
_end:
|
||||
taosArrayDestroy(createTbArray);
|
||||
taosArrayDestroy(tagArray);
|
||||
taosArrayDestroy(pVals);
|
||||
tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
|
||||
if (pReq) {
|
||||
tDestroySSubmitReq2(pReq, TSDB_MSG_FLG_ENCODE);
|
||||
taosMemoryFree(pReq);
|
||||
}
|
||||
|
||||
if (terrno != 0) {
|
||||
rpcFreeCont(pBuf);
|
||||
|
|
|
@ -323,19 +323,10 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d
|
|||
taosArrayDestroy(tagArray);
|
||||
}
|
||||
|
||||
static int32_t encodeCreateChildTableForRPC(SVCreateTbReq* req, int32_t vgId, void** pBuf, int32_t* contLen) {
|
||||
static int32_t encodeCreateChildTableForRPC(SVCreateTbBatchReq* pReqs, int32_t vgId, void** pBuf, int32_t* contLen) {
|
||||
int32_t ret = 0;
|
||||
SVCreateTbBatchReq reqs = {0};
|
||||
|
||||
reqs.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
|
||||
if (NULL == reqs.pArray) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
taosArrayPush(reqs.pArray, req);
|
||||
reqs.nReqs = 1;
|
||||
|
||||
tEncodeSize(tEncodeSVCreateTbBatchReq, &reqs, *contLen, ret);
|
||||
tEncodeSize(tEncodeSVCreateTbBatchReq, pReqs, *contLen, ret);
|
||||
if (ret < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
|
@ -350,7 +341,7 @@ static int32_t encodeCreateChildTableForRPC(SVCreateTbReq* req, int32_t vgId, vo
|
|||
((SMsgHead*)(*pBuf))->contLen = htonl(*contLen);
|
||||
SEncoder coder = {0};
|
||||
tEncoderInit(&coder, POINTER_SHIFT(*pBuf, sizeof(SMsgHead)), (*contLen) - sizeof(SMsgHead) );
|
||||
if (tEncodeSVCreateTbBatchReq(&coder, &reqs) < 0) {
|
||||
if (tEncodeSVCreateTbBatchReq(&coder, pReqs) < 0) {
|
||||
rpcFreeCont(*pBuf);
|
||||
*pBuf = NULL;
|
||||
*contLen = 0;
|
||||
|
@ -361,14 +352,13 @@ static int32_t encodeCreateChildTableForRPC(SVCreateTbReq* req, int32_t vgId, vo
|
|||
tEncoderClear(&coder);
|
||||
|
||||
end:
|
||||
taosArrayDestroy(reqs.pArray);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t tqPutReqToQueue(SVnode* pVnode, SVCreateTbReq* pReq) {
|
||||
int32_t tqPutReqToQueue(SVnode* pVnode, SVCreateTbBatchReq* pReqs) {
|
||||
void* buf = NULL;
|
||||
int32_t tlen = 0;
|
||||
encodeCreateChildTableForRPC(pReq, TD_VID(pVnode), &buf, &tlen);
|
||||
encodeCreateChildTableForRPC(pReqs, TD_VID(pVnode), &buf, &tlen);
|
||||
|
||||
SRpcMsg msg = {
|
||||
.msgType = TDMT_VND_CREATE_TABLE,
|
||||
|
@ -387,6 +377,7 @@ _error:
|
|||
tqError("failed to encode submit req since %s", terrstr());
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
|
||||
const SArray* pBlocks = (const SArray*)data;
|
||||
SVnode* pVnode = (SVnode*)vnode;
|
||||
|
@ -402,6 +393,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
void* pBuf = NULL;
|
||||
SArray* tagArray = NULL;
|
||||
SArray* pVals = NULL;
|
||||
SArray* crTblArray = NULL;
|
||||
|
||||
for (int32_t i = 0; i < blockSz; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||
|
@ -442,8 +434,14 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
tqDebug("failed to put delete req into write-queue since %s", terrstr());
|
||||
}
|
||||
} else if (pDataBlock->info.type == STREAM_CREATE_CHILD_TABLE) {
|
||||
SVCreateTbBatchReq reqs = {0};
|
||||
crTblArray = reqs.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
|
||||
if (NULL == reqs.pArray) {
|
||||
goto _end;
|
||||
}
|
||||
for (int32_t rowId = 0; rowId < rows; rowId++) {
|
||||
SVCreateTbReq* pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateStbReq));
|
||||
SVCreateTbReq createTbReq = {0};
|
||||
SVCreateTbReq* pCreateTbReq = &createTbReq;
|
||||
if (!pCreateTbReq) {
|
||||
goto _end;
|
||||
}
|
||||
|
@ -511,6 +509,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
pCreateTbReq->ctb.pTag = (uint8_t*)pTag;
|
||||
|
||||
// set table name
|
||||
|
@ -524,13 +523,15 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
pCreateTbReq->name = taosMemoryCalloc(1, varDataLen(pTbData) + 1);
|
||||
memcpy(pCreateTbReq->name, varDataVal(pTbData), varDataLen(pTbData));
|
||||
}
|
||||
|
||||
if (tqPutReqToQueue(pVnode, pCreateTbReq) != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
}
|
||||
tdDestroySVCreateTbReq(pCreateTbReq);
|
||||
taosMemoryFreeClear(pCreateTbReq);
|
||||
taosArrayPush(reqs.pArray, pCreateTbReq);
|
||||
}
|
||||
reqs.nReqs = taosArrayGetSize(reqs.pArray);
|
||||
if (tqPutReqToQueue(pVnode, &reqs) != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
}
|
||||
tagArray = taosArrayDestroy(tagArray);
|
||||
taosArrayDestroyEx(crTblArray, (FDelete)tdDestroySVCreateTbReq);
|
||||
crTblArray = NULL;
|
||||
} else {
|
||||
SSubmitTbData tbData = {0};
|
||||
tqDebug("tq sink pipe2, convert block1 %d, rows: %d", i, rows);
|
||||
|
@ -579,7 +580,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
goto _end;
|
||||
}
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.cid = pTSchema->numOfCols + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.id.groupId,
|
||||
};
|
||||
|
@ -638,28 +639,37 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
|
||||
for (int32_t j = 0; j < rows; j++) {
|
||||
taosArrayClear(pVals);
|
||||
int32_t dataIndex = 0;
|
||||
for (int32_t k = 0; k < pTSchema->numOfCols; k++) {
|
||||
const STColumn* pCol = &pTSchema->columns[k];
|
||||
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, k);
|
||||
if (k == 0) {
|
||||
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex);
|
||||
void* colData = colDataGetData(pColData, j);
|
||||
tqDebug("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData);
|
||||
}
|
||||
if (colDataIsNull_s(pColData, j)) {
|
||||
if (IS_SET_NULL(pCol)) {
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
void* colData = colDataGetData(pColData, j);
|
||||
if (IS_STR_DATA_TYPE(pCol->type)) {
|
||||
SValue sv =
|
||||
(SValue){.nData = varDataLen(colData), .pData = varDataVal(colData)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
} else{
|
||||
SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex);
|
||||
if (colDataIsNull_s(pColData, j)) {
|
||||
SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type);
|
||||
taosArrayPush(pVals, &cv);
|
||||
dataIndex++;
|
||||
} else {
|
||||
SValue sv;
|
||||
memcpy(&sv.val, colData, tDataTypes[pCol->type].bytes);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
void* colData = colDataGetData(pColData, j);
|
||||
if (IS_STR_DATA_TYPE(pCol->type)) {
|
||||
SValue sv =
|
||||
(SValue){.nData = varDataLen(colData), .pData = varDataVal(colData)}; // address copy, no value
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
} else {
|
||||
SValue sv;
|
||||
memcpy(&sv.val, colData, tDataTypes[pCol->type].bytes);
|
||||
SColVal cv = COL_VAL_VALUE(pCol->colId, pCol->type, sv);
|
||||
taosArrayPush(pVals, &cv);
|
||||
}
|
||||
dataIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -716,5 +726,6 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
|||
_end:
|
||||
taosArrayDestroy(tagArray);
|
||||
taosArrayDestroy(pVals);
|
||||
taosArrayDestroyEx(crTblArray, (FDelete)tdDestroySVCreateTbReq);
|
||||
// TODO: change
|
||||
}
|
||||
|
|
|
@ -2353,32 +2353,33 @@ static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanI
|
|||
SBlockData* pBlockData, SLastBlockReader* pLastBlockReader) {
|
||||
SFileBlockDumpInfo* pDumpInfo = &pReader->status.fBlockDumpInfo;
|
||||
|
||||
TSDBROW *pRow = NULL, *piRow = NULL;
|
||||
int64_t key = (pBlockData->nRow > 0 && (!pDumpInfo->allDumped)) ? pBlockData->aTSKEY[pDumpInfo->rowIndex] : INT64_MIN;
|
||||
if (pBlockScanInfo->iter.hasVal && pBlockScanInfo->iiter.hasVal) {
|
||||
return doMergeMultiLevelRows(pReader, pBlockScanInfo, pBlockData, pLastBlockReader);
|
||||
} else {
|
||||
TSDBROW *pRow = NULL, *piRow = NULL;
|
||||
if (pBlockScanInfo->iter.hasVal) {
|
||||
pRow = getValidMemRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader);
|
||||
}
|
||||
|
||||
if (pBlockScanInfo->iiter.hasVal) {
|
||||
piRow = getValidMemRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader);
|
||||
}
|
||||
|
||||
// imem + file + last block
|
||||
if (pBlockScanInfo->iiter.hasVal) {
|
||||
return doMergeBufAndFileRows(pReader, pBlockScanInfo, piRow, &pBlockScanInfo->iiter, key, pLastBlockReader);
|
||||
}
|
||||
|
||||
// mem + file + last block
|
||||
if (pBlockScanInfo->iter.hasVal) {
|
||||
return doMergeBufAndFileRows(pReader, pBlockScanInfo, pRow, &pBlockScanInfo->iter, key, pLastBlockReader);
|
||||
}
|
||||
|
||||
// files data blocks + last block
|
||||
return mergeFileBlockAndLastBlock(pReader, pLastBlockReader, key, pBlockScanInfo, pBlockData);
|
||||
if (pBlockScanInfo->iter.hasVal) {
|
||||
pRow = getValidMemRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader);
|
||||
}
|
||||
|
||||
if (pBlockScanInfo->iiter.hasVal) {
|
||||
piRow = getValidMemRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader);
|
||||
}
|
||||
|
||||
// two levels of mem-table does contain the valid rows
|
||||
if (pRow != NULL && piRow != NULL) {
|
||||
return doMergeMultiLevelRows(pReader, pBlockScanInfo, pBlockData, pLastBlockReader);
|
||||
}
|
||||
|
||||
// imem + file + last block
|
||||
if (pBlockScanInfo->iiter.hasVal) {
|
||||
return doMergeBufAndFileRows(pReader, pBlockScanInfo, piRow, &pBlockScanInfo->iiter, key, pLastBlockReader);
|
||||
}
|
||||
|
||||
// mem + file + last block
|
||||
if (pBlockScanInfo->iter.hasVal) {
|
||||
return doMergeBufAndFileRows(pReader, pBlockScanInfo, pRow, &pBlockScanInfo->iter, key, pLastBlockReader);
|
||||
}
|
||||
|
||||
// files data blocks + last block
|
||||
return mergeFileBlockAndLastBlock(pReader, pLastBlockReader, key, pBlockScanInfo, pBlockData);
|
||||
}
|
||||
|
||||
static int32_t loadNeighborIfOverlap(SFileDataBlockInfo* pBlockInfo, STableBlockScanInfo* pBlockScanInfo,
|
||||
|
@ -2854,7 +2855,37 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
TSDBKEY keyInBuf = getCurrentKeyInBuf(pScanInfo, pReader);
|
||||
|
||||
if (pBlockInfo == NULL) { // build data block from last data file
|
||||
code = buildComposedDataBlock(pReader);
|
||||
SBlockData* pBData = &pReader->status.fileBlockData;
|
||||
tBlockDataReset(pBData);
|
||||
|
||||
SSDataBlock* pResBlock = pReader->pResBlock;
|
||||
tsdbDebug("load data in last block firstly, due to desc scan data, %s", pReader->idStr);
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
while (1) {
|
||||
bool hasBlockLData = hasDataInLastBlock(pLastBlockReader);
|
||||
|
||||
// no data in last block and block, no need to proceed.
|
||||
if (hasBlockLData == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
buildComposedDataBlockImpl(pReader, pScanInfo, &pReader->status.fileBlockData, pLastBlockReader);
|
||||
if (pResBlock->info.rows >= pReader->capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double el = (taosGetTimestampUs() - st) / 1000.0;
|
||||
updateComposedBlockInfo(pReader, el, pScanInfo);
|
||||
|
||||
if (pResBlock->info.rows > 0) {
|
||||
tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64
|
||||
" rows:%d, elapsed time:%.2f ms %s",
|
||||
pReader, pResBlock->info.id.uid, pResBlock->info.window.skey, pResBlock->info.window.ekey,
|
||||
pResBlock->info.rows, el, pReader->idStr);
|
||||
}
|
||||
} else if (fileBlockShouldLoad(pReader, pBlockInfo, pBlock, pScanInfo, keyInBuf, pLastBlockReader)) {
|
||||
code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData, pScanInfo->uid);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -2873,10 +2904,38 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
// only return the rows in last block
|
||||
int64_t tsLast = getCurrentKeyInLastBlock(pLastBlockReader);
|
||||
ASSERT(tsLast >= pBlock->maxKey.ts);
|
||||
tBlockDataReset(&pReader->status.fileBlockData);
|
||||
|
||||
SBlockData* pBData = &pReader->status.fileBlockData;
|
||||
tBlockDataReset(pBData);
|
||||
|
||||
SSDataBlock* pResBlock = pReader->pResBlock;
|
||||
tsdbDebug("load data in last block firstly, due to desc scan data, %s", pReader->idStr);
|
||||
code = buildComposedDataBlock(pReader);
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
while (1) {
|
||||
bool hasBlockLData = hasDataInLastBlock(pLastBlockReader);
|
||||
|
||||
// no data in last block and block, no need to proceed.
|
||||
if (hasBlockLData == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
buildComposedDataBlockImpl(pReader, pScanInfo, &pReader->status.fileBlockData, pLastBlockReader);
|
||||
if (pResBlock->info.rows >= pReader->capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double el = (taosGetTimestampUs() - st) / 1000.0;
|
||||
updateComposedBlockInfo(pReader, el, pScanInfo);
|
||||
|
||||
if (pResBlock->info.rows > 0) {
|
||||
tsdbDebug("%p uid:%" PRIu64 ", composed data block created, brange:%" PRIu64 "-%" PRIu64
|
||||
" rows:%d, elapsed time:%.2f ms %s",
|
||||
pReader, pResBlock->info.id.uid, pResBlock->info.window.skey, pResBlock->info.window.ekey,
|
||||
pResBlock->info.rows, el, pReader->idStr);
|
||||
}
|
||||
} else { // whole block is required, return it directly
|
||||
SDataBlockInfo* pInfo = &pReader->pResBlock->info;
|
||||
pInfo->rows = pBlock->nRow;
|
||||
|
|
|
@ -637,7 +637,7 @@ SColVal *tsdbRowIterNext(STSDBRowIter *pIter) {
|
|||
}
|
||||
} else {
|
||||
ASSERT(0);
|
||||
return NULL; // suppress error report by compiler
|
||||
return NULL; // suppress error report by compiler
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,6 +683,18 @@ int32_t tsdbRowMergerInit2(SRowMerger *pMerger, STSchema *pResTSchema, TSDBROW *
|
|||
}
|
||||
|
||||
tsdbRowGetColVal(pRow, pTSchema, jCol++, pColVal);
|
||||
if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
|
||||
pColVal->value.pData = NULL;
|
||||
code = tRealloc(&pColVal->value.pData, pColVal->value.nData);
|
||||
if (code) goto _exit;
|
||||
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
|
||||
}
|
||||
}
|
||||
|
||||
if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
|
@ -721,12 +733,35 @@ int32_t tsdbRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema)
|
|||
|
||||
if (key.version > pMerger->version) {
|
||||
if (!COL_VAL_IS_NONE(pColVal)) {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
SColVal *tColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
|
||||
if (code) return code;
|
||||
|
||||
tColVal->value.nData = pColVal->value.nData;
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(tColVal->value.pData, pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
tColVal->flag = 0;
|
||||
} else {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
} else if (key.version < pMerger->version) {
|
||||
SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
|
||||
if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
if ((!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
|
||||
if (code) return code;
|
||||
|
||||
tColVal->value.nData = pColVal->value.nData;
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(tColVal->value.pData, pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
tColVal->flag = 0;
|
||||
} else {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(0 && "dup versions not allowed");
|
||||
|
@ -766,6 +801,18 @@ int32_t tsdbRowMergerInit(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema
|
|||
// other
|
||||
for (int16_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
|
||||
tsdbRowGetColVal(pRow, pTSchema, iCol, pColVal);
|
||||
if ((!COL_VAL_IS_NONE(pColVal)) && (!COL_VAL_IS_NULL(pColVal)) && IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
uint8_t *pVal = pColVal->value.pData;
|
||||
|
||||
pColVal->value.pData = NULL;
|
||||
code = tRealloc(&pColVal->value.pData, pColVal->value.nData);
|
||||
if (code) goto _exit;
|
||||
|
||||
if (pColVal->value.nData) {
|
||||
memcpy(pColVal->value.pData, pVal, pColVal->value.nData);
|
||||
}
|
||||
}
|
||||
|
||||
if (taosArrayPush(pMerger->pArray, pColVal) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
|
@ -776,7 +823,16 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
void tsdbRowMergerClear(SRowMerger *pMerger) { taosArrayDestroy(pMerger->pArray); }
|
||||
void tsdbRowMergerClear(SRowMerger *pMerger) {
|
||||
for (int32_t iCol = 1; iCol < pMerger->pTSchema->numOfCols; iCol++) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (IS_VAR_DATA_TYPE(pTColVal->type)) {
|
||||
tFree(pTColVal->value.pData);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pMerger->pArray);
|
||||
}
|
||||
|
||||
int32_t tsdbRowMerge(SRowMerger *pMerger, TSDBROW *pRow) {
|
||||
int32_t code = 0;
|
||||
|
@ -790,12 +846,47 @@ int32_t tsdbRowMerge(SRowMerger *pMerger, TSDBROW *pRow) {
|
|||
|
||||
if (key.version > pMerger->version) {
|
||||
if (!COL_VAL_IS_NONE(pColVal)) {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
SColVal *pTColVal = taosArrayGet(pMerger->pArray, iCol);
|
||||
if (!COL_VAL_IS_NULL(pColVal)) {
|
||||
code = tRealloc(&pTColVal->value.pData, pColVal->value.nData);
|
||||
if (code) goto _exit;
|
||||
|
||||
pTColVal->value.nData = pColVal->value.nData;
|
||||
if (pTColVal->value.nData) {
|
||||
memcpy(pTColVal->value.pData, pColVal->value.pData, pTColVal->value.nData);
|
||||
}
|
||||
pTColVal->flag = 0;
|
||||
} else {
|
||||
tFree(pTColVal->value.pData);
|
||||
pTColVal->value.pData = NULL;
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
} else {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
} else if (key.version < pMerger->version) {
|
||||
SColVal *tColVal = (SColVal *)taosArrayGet(pMerger->pArray, iCol);
|
||||
if (COL_VAL_IS_NONE(tColVal) && !COL_VAL_IS_NONE(pColVal)) {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
if (IS_VAR_DATA_TYPE(pColVal->type)) {
|
||||
if (!COL_VAL_IS_NULL(pColVal)) {
|
||||
code = tRealloc(&tColVal->value.pData, pColVal->value.nData);
|
||||
if (code) goto _exit;
|
||||
|
||||
tColVal->value.nData = pColVal->value.nData;
|
||||
if (tColVal->value.nData) {
|
||||
memcpy(tColVal->value.pData, pColVal->value.pData, tColVal->value.nData);
|
||||
}
|
||||
tColVal->flag = 0;
|
||||
} else {
|
||||
tFree(tColVal->value.pData);
|
||||
tColVal->value.pData = NULL;
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
} else {
|
||||
taosArraySet(pMerger->pArray, iCol, pColVal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(0);
|
||||
|
|
|
@ -451,8 +451,7 @@ static int vnodeCommitImpl(SCommitInfo *pInfo) {
|
|||
snprintf(dir, TSDB_FILENAME_LEN, "%s", pVnode->path);
|
||||
}
|
||||
|
||||
// walBeginSnapshot(pVnode->pWal, pVnode->state.applied);
|
||||
syncBeginSnapshot(pVnode->sync, pVnode->state.applied);
|
||||
syncBeginSnapshot(pVnode->sync, pInfo->info.state.committed);
|
||||
|
||||
// commit each sub-system
|
||||
code = tsdbCommit(pVnode->pTsdb, pInfo);
|
||||
|
@ -494,7 +493,6 @@ static int vnodeCommitImpl(SCommitInfo *pInfo) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// walEndSnapshot(pVnode->pWal);
|
||||
syncEndSnapshot(pVnode->sync);
|
||||
|
||||
_exit:
|
||||
|
|
|
@ -134,6 +134,21 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// save vnode info on dnode ep changed
|
||||
bool updated = false;
|
||||
SSyncCfg *pCfg = &info.config.syncCfg;
|
||||
for (int32_t i = 0; i < pCfg->replicaNum; ++i) {
|
||||
SNodeInfo *pNode = &pCfg->nodeInfo[i];
|
||||
if (tmsgUpdateDnodeInfo(&pNode->nodeId, &pNode->clusterId, pNode->nodeFqdn, &pNode->nodePort)) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
vInfo("vgId:%d, save vnode info since dnode info changed", info.config.vgId);
|
||||
(void)vnodeSaveInfo(dir, &info);
|
||||
(void)vnodeCommitInfo(dir, &info);
|
||||
}
|
||||
|
||||
// create handle
|
||||
pVnode = taosMemoryCalloc(1, sizeof(*pVnode) + strlen(path) + 1);
|
||||
if (pVnode == NULL) {
|
||||
|
|
|
@ -64,6 +64,9 @@ extern "C" {
|
|||
#define EXPLAIN_IGNORE_GROUPID_FORMAT "Ignore Group Id: %s"
|
||||
#define EXPLAIN_PARTITION_KETS_FORMAT "Partition Key: "
|
||||
#define EXPLAIN_INTERP_FORMAT "Interp"
|
||||
#define EXPLAIN_EVENT_FORMAT "Event"
|
||||
#define EXPLAIN_EVENT_START_FORMAT "Start Cond: "
|
||||
#define EXPLAIN_EVENT_END_FORMAT "End Cond: "
|
||||
|
||||
#define EXPLAIN_PLANNING_TIME_FORMAT "Planning Time: %.3f ms"
|
||||
#define EXPLAIN_EXEC_TIME_FORMAT "Execution Time: %.3f ms"
|
||||
|
|
|
@ -114,129 +114,7 @@ _return:
|
|||
|
||||
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
|
||||
int32_t tlen = 0;
|
||||
SNodeList *pPhysiChildren = NULL;
|
||||
|
||||
switch (pNode->type) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
||||
STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
|
||||
pPhysiChildren = pTagScanNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {
|
||||
STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
|
||||
pPhysiChildren = pTblScanNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
|
||||
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
|
||||
pPhysiChildren = pSTblScanNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
|
||||
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
|
||||
pPhysiChildren = pPrjNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: {
|
||||
SSortMergeJoinPhysiNode *pJoinNode = (SSortMergeJoinPhysiNode *)pNode;
|
||||
pPhysiChildren = pJoinNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_AGG: {
|
||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||
pPhysiChildren = pAggNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
|
||||
SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
|
||||
pPhysiChildren = pExchNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT: {
|
||||
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
|
||||
pPhysiChildren = pSortNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: {
|
||||
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
||||
pPhysiChildren = pIntNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_SESSION: {
|
||||
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
|
||||
pPhysiChildren = pSessNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE: {
|
||||
SStateWinodwPhysiNode *pStateNode = (SStateWinodwPhysiNode *)pNode;
|
||||
pPhysiChildren = pStateNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
|
||||
SPartitionPhysiNode *partitionPhysiNode = (SPartitionPhysiNode *)pNode;
|
||||
pPhysiChildren = partitionPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE: {
|
||||
SMergePhysiNode *mergePhysiNode = (SMergePhysiNode *)pNode;
|
||||
pPhysiChildren = mergePhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC: {
|
||||
SIndefRowsFuncPhysiNode *indefPhysiNode = (SIndefRowsFuncPhysiNode *)pNode;
|
||||
pPhysiChildren = indefPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
|
||||
SMergeAlignedIntervalPhysiNode *intPhysiNode = (SMergeAlignedIntervalPhysiNode *)pNode;
|
||||
pPhysiChildren = intPhysiNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL: {
|
||||
SFillPhysiNode *fillPhysiNode = (SFillPhysiNode *)pNode;
|
||||
pPhysiChildren = fillPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: {
|
||||
STableMergeScanPhysiNode *mergePhysiNode = (STableMergeScanPhysiNode *)pNode;
|
||||
pPhysiChildren = mergePhysiNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: {
|
||||
SBlockDistScanPhysiNode *distPhysiNode = (SBlockDistScanPhysiNode *)pNode;
|
||||
pPhysiChildren = distPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: {
|
||||
SLastRowScanPhysiNode *lastRowPhysiNode = (SLastRowScanPhysiNode *)pNode;
|
||||
pPhysiChildren = lastRowPhysiNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
|
||||
STableCountScanPhysiNode *tableCountPhysiNode = (STableCountScanPhysiNode *)pNode;
|
||||
pPhysiChildren = tableCountPhysiNode->scan.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: {
|
||||
SGroupSortPhysiNode *groupSortPhysiNode = (SGroupSortPhysiNode *)pNode;
|
||||
pPhysiChildren = groupSortPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL: {
|
||||
SMergeIntervalPhysiNode *mergeIntPhysiNode = (SMergeIntervalPhysiNode *)pNode;
|
||||
pPhysiChildren = mergeIntPhysiNode->window.node.pChildren;
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
|
||||
SInterpFuncPhysiNode *interpPhysiNode = (SInterpFuncPhysiNode *)pNode;
|
||||
pPhysiChildren = interpPhysiNode->node.pChildren;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("not supported physical node type %d", pNode->type);
|
||||
QRY_ERR_RET(TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
SNodeList *pPhysiChildren = pNode->pChildren;
|
||||
|
||||
if (pPhysiChildren) {
|
||||
*pChildren = nodesMakeList();
|
||||
|
@ -1583,6 +1461,36 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT: {
|
||||
SEventWinodwPhysiNode *pEventNode = (SEventWinodwPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_EVENT_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pEventNode->window.pFuncs->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pEventNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
if (verbose) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_START_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pEventNode->pStartCond, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_EVENT_END_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pEventNode->pEndCond, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qError("not supported physical node type %d", pNode->type);
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
|
|
|
@ -718,7 +718,8 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
|
|||
|
||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo);
|
||||
void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimitInfo);
|
||||
void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator);
|
||||
void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo);
|
||||
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator);
|
||||
|
||||
void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfoData* pTimeWindowData,
|
||||
int32_t offset, int32_t forwardStep, int32_t numOfTotal, int32_t numOfOutput);
|
||||
|
@ -742,6 +743,7 @@ void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle);
|
|||
void setTbNameColData(const SSDataBlock* pBlock, SColumnInfoData* pColInfoData, int32_t functionId, const char* name);
|
||||
|
||||
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset);
|
||||
void clearResultRowInitFlag(SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
|
||||
SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData,
|
||||
int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo,
|
||||
|
@ -813,6 +815,8 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
SOperatorInfo* createStreamFillOperatorInfo(SOperatorInfo* downstream, SStreamFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createGroupSortOperatorInfo(SOperatorInfo* downstream, SGroupSortPhysiNode* pSortPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo);
|
||||
// clang-format on
|
||||
|
||||
int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
|
||||
|
@ -872,6 +876,10 @@ void appendCreateTableRow(SStreamState* pState, SExprSupp* pTableSup, SExprSu
|
|||
SSDataBlock* buildCreateTableBlock(SExprSupp* tbName, SExprSupp* tag);
|
||||
SExprInfo* createExpr(SNodeList* pNodeList, int32_t* numOfExprs);
|
||||
|
||||
void copyResultrowToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultRow* pRow, SqlFunctionCtx* pCtx,
|
||||
SSDataBlock* pBlock, const int32_t* rowEntryOffset, SExecTaskInfo* pTaskInfo);
|
||||
void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs, const int32_t* rowEntryOffset) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* 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 "executorimpl.h"
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tcommon.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "ttime.h"
|
||||
|
||||
typedef struct SEventWindowOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SAggSupporter aggSup;
|
||||
SExprSupp scalarSup;
|
||||
SGroupResInfo groupResInfo;
|
||||
SWindowRowsSup winSup;
|
||||
bool hasKey;
|
||||
SStateKeys stateKey;
|
||||
int32_t tsSlotId; // primary timestamp column slot id
|
||||
STimeWindowAggSupp twAggSup;
|
||||
|
||||
SFilterInfo* pStartCondInfo;
|
||||
SFilterInfo* pEndCondInfo;
|
||||
bool inWindow;
|
||||
SResultRow* pRow;
|
||||
} SEventWindowOperatorInfo;
|
||||
|
||||
static SSDataBlock* eventWindowAggregate(SOperatorInfo* pOperator);
|
||||
static void destroyEWindowOperatorInfo(void* param);
|
||||
static void eventWindowAggImpl(SOperatorInfo* pOperator, SEventWindowOperatorInfo* pInfo, SSDataBlock* pBlock);
|
||||
static SSDataBlock* doEventWindowAgg(SOperatorInfo* pOperator);
|
||||
|
||||
// todo : move to util
|
||||
static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex,
|
||||
uint64_t groupId) {
|
||||
pRowSup->startRowIndex = rowIndex;
|
||||
pRowSup->numOfRows = 0;
|
||||
pRowSup->win.skey = tsList[rowIndex];
|
||||
pRowSup->groupId = groupId;
|
||||
}
|
||||
|
||||
static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) {
|
||||
pRowSup->win.ekey = ts;
|
||||
pRowSup->prevTs = ts;
|
||||
pRowSup->numOfRows += 1;
|
||||
pRowSup->groupId = groupId;
|
||||
}
|
||||
|
||||
static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, bool includeEndpoint) {
|
||||
int64_t* ts = (int64_t*)pColData->pData;
|
||||
int32_t delta = includeEndpoint ? 1 : 0;
|
||||
|
||||
int64_t duration = pWin->ekey - pWin->skey + delta;
|
||||
ts[2] = duration; // set the duration
|
||||
ts[3] = pWin->skey; // window start key
|
||||
ts[4] = pWin->ekey + delta; // window end key
|
||||
}
|
||||
|
||||
SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SEventWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SEventWindowOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SEventWinodwPhysiNode* pEventWindowNode = (SEventWinodwPhysiNode*)physiNode;
|
||||
|
||||
int32_t tsSlotId = ((SColumnNode*)pEventWindowNode->window.pTspk)->slotId;
|
||||
int32_t code = filterInitFromNode((SNode*)pEventWindowNode->pStartCond, &pInfo->pStartCondInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = filterInitFromNode((SNode*)pEventWindowNode->pEndCond, &pInfo->pEndCondInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
if (pEventWindowNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalarExpr = 0;
|
||||
SExprInfo* pScalarExprInfo = createExprInfo(pEventWindowNode->window.pExprs, NULL, &numOfScalarExpr);
|
||||
code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, numOfScalarExpr);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
code = filterInitFromNode((SNode*)pEventWindowNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
|
||||
int32_t num = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pEventWindowNode->window.pFuncs, NULL, &num);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
|
||||
code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, num, keyBufSize, pTaskInfo->id.str,
|
||||
pTaskInfo->streamInfo.pState);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SSDataBlock* pResBlock = createDataBlockFromDescNode(pEventWindowNode->window.node.pOutputDataBlockDesc);
|
||||
blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
|
||||
|
||||
initBasicInfo(&pInfo->binfo, pResBlock);
|
||||
initResultRowInfo(&pInfo->binfo.resultRowInfo);
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){.waterMark = pEventWindowNode->window.watermark,
|
||||
.calTrigger = pEventWindowNode->window.triggerType};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->tsSlotId = tsSlotId;
|
||||
|
||||
setOperatorInfo(pOperator, "EventWindowOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE, true, OP_NOT_OPENED, pInfo,
|
||||
pTaskInfo);
|
||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, eventWindowAggregate, NULL, destroyEWindowOperatorInfo,
|
||||
optrDefaultBufFn, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
if (pInfo != NULL) {
|
||||
destroyEWindowOperatorInfo(pInfo);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pOperator);
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void destroyEWindowOperatorInfo(void* param) {
|
||||
SEventWindowOperatorInfo* pInfo = (SEventWindowOperatorInfo*)param;
|
||||
if (pInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pInfo->pRow != NULL) {
|
||||
taosMemoryFree(pInfo->pRow);
|
||||
}
|
||||
|
||||
if (pInfo->pStartCondInfo != NULL) {
|
||||
filterFreeInfo(pInfo->pStartCondInfo);
|
||||
pInfo->pStartCondInfo = NULL;
|
||||
}
|
||||
|
||||
if (pInfo->pEndCondInfo != NULL) {
|
||||
filterFreeInfo(pInfo->pEndCondInfo);
|
||||
pInfo->pEndCondInfo = NULL;
|
||||
}
|
||||
|
||||
cleanupBasicInfo(&pInfo->binfo);
|
||||
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||
|
||||
cleanupAggSup(&pInfo->aggSup);
|
||||
cleanupGroupResInfo(&pInfo->groupResInfo);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
static SSDataBlock* eventWindowAggregate(SOperatorInfo* pOperator) {
|
||||
SEventWindowOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
int32_t order = TSDB_ORDER_ASC;
|
||||
|
||||
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||
|
||||
blockDataCleanup(pRes);
|
||||
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
setInputDataBlock(pSup, pBlock, order, MAIN_SCAN, true);
|
||||
blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId);
|
||||
|
||||
// there is an scalar expression that needs to be calculated right before apply the group aggregation.
|
||||
if (pInfo->scalarSup.pExprInfo != NULL) {
|
||||
pTaskInfo->code = projectApplyFunctions(pInfo->scalarSup.pExprInfo, pBlock, pBlock, pInfo->scalarSup.pCtx,
|
||||
pInfo->scalarSup.numOfExprs, NULL);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||
}
|
||||
}
|
||||
|
||||
eventWindowAggImpl(pOperator, pInfo, pBlock);
|
||||
if (pRes->info.rows >= pOperator->resultInfo.threshold) {
|
||||
return pRes;
|
||||
}
|
||||
}
|
||||
|
||||
return pRes->info.rows == 0 ? NULL : pRes;
|
||||
}
|
||||
|
||||
static int32_t setSingleOutputTupleBufv1(SResultRowInfo* pResultRowInfo, STimeWindow* win, SResultRow** pResult,
|
||||
SExprSupp* pExprSup, SAggSupporter* pAggSup) {
|
||||
if (*pResult == NULL) {
|
||||
SResultRow* p = taosMemoryCalloc(1, pAggSup->resultRowSize);
|
||||
pResultRowInfo->cur = (SResultRowPosition){.pageId = p->pageId, .offset = p->offset};
|
||||
*pResult = p;
|
||||
}
|
||||
|
||||
(*pResult)->win = *win;
|
||||
|
||||
clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
|
||||
setResultRowInitCtx(*pResult, pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void doEventWindowAggImpl(SEventWindowOperatorInfo* pInfo, SExprSupp* pSup, int32_t startIndex, int32_t endIndex,
|
||||
const SSDataBlock* pBlock, int64_t* tsList, SExecTaskInfo* pTaskInfo) {
|
||||
SWindowRowsSup* pRowSup = &pInfo->winSup;
|
||||
|
||||
int32_t numOfOutput = pSup->numOfExprs;
|
||||
int32_t numOfRows = endIndex - startIndex + 1;
|
||||
|
||||
doKeepTuple(pRowSup, tsList[endIndex], pBlock->info.id.groupId);
|
||||
|
||||
int32_t ret =
|
||||
setSingleOutputTupleBufv1(&pInfo->binfo.resultRowInfo, &pRowSup->win, &pInfo->pRow, pSup, &pInfo->aggSup);
|
||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false);
|
||||
applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startIndex, numOfRows,
|
||||
pBlock->info.rows, numOfOutput);
|
||||
}
|
||||
|
||||
void eventWindowAggImpl(SOperatorInfo* pOperator, SEventWindowOperatorInfo* pInfo, SSDataBlock* pBlock) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
|
||||
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||
int64_t gid = pBlock->info.id.groupId;
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||
TSKEY* tsList = (TSKEY*)pColInfoData->pData;
|
||||
|
||||
SColumnInfoData *ps = NULL, *pe = NULL;
|
||||
|
||||
SWindowRowsSup* pRowSup = &pInfo->winSup;
|
||||
pRowSup->numOfRows = 0;
|
||||
|
||||
SFilterColumnParam param1 = {.numOfCols = taosArrayGetSize(pBlock->pDataBlock), .pDataBlock = pBlock->pDataBlock};
|
||||
int32_t code = filterSetDataFromSlotId(pInfo->pStartCondInfo, ¶m1);
|
||||
|
||||
int32_t status1 = 0;
|
||||
bool keep1 = filterExecute(pInfo->pStartCondInfo, pBlock, &ps, NULL, param1.numOfCols, &status1);
|
||||
|
||||
SFilterColumnParam param2 = {.numOfCols = taosArrayGetSize(pBlock->pDataBlock), .pDataBlock = pBlock->pDataBlock};
|
||||
code = filterSetDataFromSlotId(pInfo->pEndCondInfo, ¶m2);
|
||||
|
||||
int32_t status2 = 0;
|
||||
bool keep2 = filterExecute(pInfo->pEndCondInfo, pBlock, &pe, NULL, param2.numOfCols, &status2);
|
||||
|
||||
int32_t rowIndex = 0;
|
||||
int32_t startIndex = pInfo->inWindow ? 0 : -1;
|
||||
|
||||
while (rowIndex < pBlock->info.rows) {
|
||||
if (pInfo->inWindow) { // let's find the first end value
|
||||
for (rowIndex = startIndex; rowIndex < pBlock->info.rows; ++rowIndex) {
|
||||
if (((bool*)pe->pData)[rowIndex]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rowIndex < pBlock->info.rows) {
|
||||
doEventWindowAggImpl(pInfo, pSup, startIndex, rowIndex, pBlock, tsList, pTaskInfo);
|
||||
|
||||
doUpdateNumOfRows(pSup->pCtx, pInfo->pRow, pSup->numOfExprs, pSup->rowEntryInfoOffset);
|
||||
|
||||
// check buffer size
|
||||
if (pRes->info.rows + pInfo->pRow->numOfRows >= pRes->info.capacity) {
|
||||
int32_t newSize = pRes->info.rows + pInfo->pRow->numOfRows;
|
||||
blockDataEnsureCapacity(pRes, newSize);
|
||||
}
|
||||
|
||||
copyResultrowToDataBlock(pSup->pExprInfo, pSup->numOfExprs, pInfo->pRow, pSup->pCtx, pRes,
|
||||
pSup->rowEntryInfoOffset, pTaskInfo);
|
||||
|
||||
pRes->info.rows += pInfo->pRow->numOfRows;
|
||||
|
||||
pInfo->inWindow = false;
|
||||
rowIndex += 1;
|
||||
} else {
|
||||
doEventWindowAggImpl(pInfo, pSup, startIndex, pBlock->info.rows - 1, pBlock, tsList, pTaskInfo);
|
||||
}
|
||||
} else { // find the first start value that is fulfill for the start condition
|
||||
for (; rowIndex < pBlock->info.rows; ++rowIndex) {
|
||||
if (((bool*)ps->pData)[rowIndex]) {
|
||||
doKeepNewWindowStartInfo(pRowSup, tsList, rowIndex, gid);
|
||||
pInfo->inWindow = true;
|
||||
startIndex = rowIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pInfo->inWindow) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colDataDestroy(ps);
|
||||
taosMemoryFree(ps);
|
||||
colDataDestroy(pe);
|
||||
taosMemoryFree(pe);
|
||||
}
|
|
@ -584,7 +584,13 @@ int32_t doExtractResultBlocks(SExchangeInfo* pExchangeInfo, SSourceDataInfo* pDa
|
|||
int32_t index = 0;
|
||||
int32_t code = 0;
|
||||
while (index++ < pRetrieveRsp->numOfBlocks) {
|
||||
SSDataBlock* pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false);
|
||||
SSDataBlock* pb = NULL;
|
||||
if (taosArrayGetSize(pExchangeInfo->pRecycledBlocks) > 0) {
|
||||
pb = *(SSDataBlock**)taosArrayPop(pExchangeInfo->pRecycledBlocks);
|
||||
blockDataCleanup(pb);
|
||||
} else {
|
||||
pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false);
|
||||
}
|
||||
|
||||
code = extractDataBlockFromFetchRsp(pb, pStart, NULL, &pStart);
|
||||
if (code != 0) {
|
||||
|
@ -732,9 +738,7 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa
|
|||
}
|
||||
|
||||
// reset the value for a new group data
|
||||
pLimitInfo->numOfOutputRows = 0;
|
||||
pLimitInfo->remainOffset = pLimitInfo->limit.offset;
|
||||
|
||||
resetLimitInfoForNextGroup(pLimitInfo);
|
||||
// existing rows that belongs to previous group.
|
||||
if (pBlock->info.rows > 0) {
|
||||
return PROJECT_RETRIEVE_DONE;
|
||||
|
@ -760,7 +764,12 @@ int32_t handleLimitOffset(SOperatorInfo* pOperator, SLimitInfo* pLimitInfo, SSDa
|
|||
int32_t keepRows = (int32_t)(pLimitInfo->limit.limit - pLimitInfo->numOfOutputRows);
|
||||
blockDataKeepFirstNRows(pBlock, keepRows);
|
||||
if (pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups) {
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
setOperatorCompleted(pOperator);
|
||||
} else {
|
||||
// current group limitation is reached, and future blocks of this group need to be discarded.
|
||||
if (pBlock->info.rows == 0) {
|
||||
return PROJECT_RETRIEVE_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PROJECT_RETRIEVE_DONE;
|
||||
|
|
|
@ -954,7 +954,7 @@ static int32_t optimizeTbnameInCondImpl(void* metaHandle, int64_t suid, SArray*
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
qWarn("failed to get tableIds from by table name: %s, reason: %s", name, tstrerror(terrno));
|
||||
// qWarn("failed to get tableIds from by table name: %s, reason: %s", name, tstrerror(terrno));
|
||||
terrno = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1771,6 +1771,11 @@ void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLimit
|
|||
pLimitInfo->remainGroupOffset = slimit.offset;
|
||||
}
|
||||
|
||||
void resetLimitInfoForNextGroup(SLimitInfo* pLimitInfo) {
|
||||
pLimitInfo->numOfOutputRows = 0;
|
||||
pLimitInfo->remainOffset = pLimitInfo->limit.offset;
|
||||
}
|
||||
|
||||
uint64_t tableListGetSize(const STableListInfo* pTableList) {
|
||||
ASSERT(taosArrayGetSize(pTableList->pTableList) == taosHashGetSize(pTableList->map));
|
||||
return taosArrayGetSize(pTableList->pTableList);
|
||||
|
|
|
@ -833,6 +833,20 @@ void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numO
|
|||
}
|
||||
}
|
||||
|
||||
void clearResultRowInitFlag(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo;
|
||||
if (pResInfo == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pResInfo->initialized = false;
|
||||
pResInfo->numOfRes = 0;
|
||||
pResInfo->isNullRes = 0;
|
||||
pResInfo->complete = false;
|
||||
}
|
||||
}
|
||||
|
||||
void doFilter(SSDataBlock* pBlock, SFilterInfo* pFilterInfo, SColMatchInfo* pColMatchInfo) {
|
||||
if (pFilterInfo == NULL || pBlock->info.rows == 0) {
|
||||
return;
|
||||
|
@ -892,12 +906,11 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SColumnInfoD
|
|||
}
|
||||
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pDst->info.type)) {
|
||||
int32_t j = 0;
|
||||
pDst->varmeta.length = 0;
|
||||
|
||||
while(j < totalRows) {
|
||||
while (j < totalRows) {
|
||||
if (pIndicator[j] == 0) {
|
||||
j += 1;
|
||||
continue;
|
||||
|
@ -1050,8 +1063,7 @@ static void setExecutionContext(SOperatorInfo* pOperator, int32_t numOfOutput, u
|
|||
pAggInfo->groupId = groupId;
|
||||
}
|
||||
|
||||
static void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs,
|
||||
const int32_t* rowEntryOffset) {
|
||||
void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t numOfExprs, const int32_t* rowEntryOffset) {
|
||||
bool returnNotNull = false;
|
||||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||
SResultRowEntryInfo* pResInfo = getResultEntryInfo(pRow, j, rowEntryOffset);
|
||||
|
@ -1074,8 +1086,8 @@ static void doUpdateNumOfRows(SqlFunctionCtx* pCtx, SResultRow* pRow, int32_t nu
|
|||
}
|
||||
}
|
||||
|
||||
static void doCopyResultToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultRow* pRow, SqlFunctionCtx* pCtx,
|
||||
SSDataBlock* pBlock, const int32_t* rowEntryOffset, SExecTaskInfo* pTaskInfo) {
|
||||
void copyResultrowToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SResultRow* pRow, SqlFunctionCtx* pCtx,
|
||||
SSDataBlock* pBlock, const int32_t* rowEntryOffset, SExecTaskInfo* pTaskInfo) {
|
||||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||
int32_t slotId = pExprInfo[j].base.resSchema.slotId;
|
||||
|
||||
|
@ -1111,7 +1123,7 @@ static void doCopyResultToDataBlock(SExprInfo* pExprInfo, int32_t numOfExprs, SR
|
|||
// todo refactor. SResultRow has direct pointer in miainfo
|
||||
int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPosition, SExprSupp* pSup,
|
||||
SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
|
||||
SFilePage* page = getBufPage(pBuf, resultRowPosition->pageId);
|
||||
SFilePage* page = getBufPage(pBuf, resultRowPosition->pageId);
|
||||
if (page == NULL) {
|
||||
qError("failed to get buffer, code:%s, %s", tstrerror(terrno), GET_TASKID(pTaskInfo));
|
||||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
|
@ -1141,7 +1153,7 @@ int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPos
|
|||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
doCopyResultToDataBlock(pExprInfo, pSup->numOfExprs, pRow, pCtx, pBlock, rowEntryOffset, pTaskInfo);
|
||||
copyResultrowToDataBlock(pExprInfo, pSup->numOfExprs, pRow, pCtx, pBlock, rowEntryOffset, pTaskInfo);
|
||||
|
||||
releaseBufPage(pBuf, page);
|
||||
pBlock->info.rows += pRow->numOfRows;
|
||||
|
@ -1193,7 +1205,7 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprS
|
|||
}
|
||||
|
||||
pGroupResInfo->index += 1;
|
||||
doCopyResultToDataBlock(pExprInfo, numOfExprs, pRow, pCtx, pBlock, rowEntryOffset, pTaskInfo);
|
||||
copyResultrowToDataBlock(pExprInfo, numOfExprs, pRow, pCtx, pBlock, rowEntryOffset, pTaskInfo);
|
||||
|
||||
releaseBufPage(pBuf, page);
|
||||
pBlock->info.rows += pRow->numOfRows;
|
||||
|
@ -2222,8 +2234,6 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pOperator = createCacherowsScanOperator(pScanNode, pHandle, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
|
||||
pOperator = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
if (pOperator != NULL) {
|
||||
|
@ -2312,8 +2322,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) {
|
||||
pOptr = createTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT == type) {
|
||||
pOptr = createEventwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo);
|
||||
}
|
||||
|
||||
taosMemoryFree(ops);
|
||||
|
|
|
@ -175,8 +175,7 @@ static int32_t setInfoForNewGroup(SSDataBlock* pBlock, SLimitInfo* pLimitInfo, S
|
|||
|
||||
// reset the value for a new group data
|
||||
// existing rows that belongs to previous group.
|
||||
pLimitInfo->numOfOutputRows = 0;
|
||||
pLimitInfo->remainOffset = pLimitInfo->limit.offset;
|
||||
resetLimitInfoForNextGroup(pLimitInfo);
|
||||
}
|
||||
|
||||
return PROJECT_RETRIEVE_DONE;
|
||||
|
@ -200,10 +199,18 @@ static int32_t doIngroupLimitOffset(SLimitInfo* pLimitInfo, uint64_t groupId, SS
|
|||
if (pLimitInfo->limit.limit >= 0 && pLimitInfo->numOfOutputRows + pBlock->info.rows >= pLimitInfo->limit.limit) {
|
||||
int32_t keepRows = (int32_t)(pLimitInfo->limit.limit - pLimitInfo->numOfOutputRows);
|
||||
blockDataKeepFirstNRows(pBlock, keepRows);
|
||||
|
||||
// TODO: optimize it later when partition by + limit
|
||||
// all retrieved requirement has been fulfilled, let's finish this
|
||||
if ((pLimitInfo->slimit.limit == -1 && pLimitInfo->currentGroupId == 0) ||
|
||||
(pLimitInfo->slimit.limit > 0 && pLimitInfo->slimit.limit <= pLimitInfo->numOfOutputGroups)) {
|
||||
setOperatorCompleted(pOperator);
|
||||
} else {
|
||||
// Even current group is done, there may be many vgroups remain existed, and we need to continue to retrieve data
|
||||
// from next group. So let's continue this retrieve process
|
||||
if (keepRows == 0) {
|
||||
return PROJECT_RETRIEVE_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +365,6 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
|
||||
}
|
||||
|
||||
// printDataBlock1(p, "project");
|
||||
return (p->info.rows > 0) ? p : NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ static void doSetTagColumnData(STableScanBase* pTableScanInfo, SSDataBlock* pBlo
|
|||
}
|
||||
|
||||
// todo handle the slimit info
|
||||
void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator) {
|
||||
bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo, SOperatorInfo* pOperator) {
|
||||
SLimit* pLimit = &pLimitInfo->limit;
|
||||
const char* id = GET_TASKID(pTaskInfo);
|
||||
|
||||
|
@ -266,6 +266,7 @@ void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo
|
|||
pLimitInfo->remainOffset -= pBlock->info.rows;
|
||||
blockDataEmpty(pBlock);
|
||||
qDebug("current block ignore due to offset, current:%" PRId64 ", %s", pLimitInfo->remainOffset, id);
|
||||
return false;
|
||||
} else {
|
||||
blockDataTrimFirstNRows(pBlock, pLimitInfo->remainOffset);
|
||||
pLimitInfo->remainOffset = 0;
|
||||
|
@ -274,13 +275,14 @@ void applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo
|
|||
|
||||
if (pLimit->limit != -1 && pLimit->limit <= (pLimitInfo->numOfOutputRows + pBlock->info.rows)) {
|
||||
// limit the output rows
|
||||
int32_t overflowRows = pLimitInfo->numOfOutputRows + pBlock->info.rows - pLimit->limit;
|
||||
int32_t keep = pBlock->info.rows - overflowRows;
|
||||
int32_t keep = (int32_t)(pLimit->limit - pLimitInfo->numOfOutputRows);
|
||||
|
||||
blockDataKeepFirstNRows(pBlock, keep);
|
||||
qDebug("output limit %" PRId64 " has reached, %s", pLimit->limit, id);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableScanInfo, SSDataBlock* pBlock,
|
||||
|
@ -395,7 +397,10 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableSca
|
|||
}
|
||||
}
|
||||
|
||||
applyLimitOffset(&pTableScanInfo->limitInfo, pBlock, pTaskInfo, pOperator);
|
||||
bool limitReached = applyLimitOffset(&pTableScanInfo->limitInfo, pBlock, pTaskInfo, pOperator);
|
||||
if (limitReached) { // set operator flag is done
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
|
||||
pCost->totalRows += pBlock->info.rows;
|
||||
pTableScanInfo->limitInfo.numOfOutputRows = pCost->totalRows;
|
||||
|
@ -772,8 +777,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
|||
|
||||
// reset value for the next group data output
|
||||
pOperator->status = OP_OPENED;
|
||||
pInfo->base.limitInfo.numOfOutputRows = 0;
|
||||
pInfo->base.limitInfo.remainOffset = pInfo->base.limitInfo.limit.offset;
|
||||
resetLimitInfoForNextGroup(&pInfo->base.limitInfo);
|
||||
|
||||
int32_t num = 0;
|
||||
STableKeyInfo* pList = NULL;
|
||||
|
@ -1716,6 +1720,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
|||
/*resetTableScanInfo(pTSInfo, pWin);*/
|
||||
tsdbReaderClose(pTSInfo->base.dataReader);
|
||||
pTSInfo->base.dataReader = NULL;
|
||||
pInfo->pTableScanOp->status = OP_OPENED;
|
||||
|
||||
pTSInfo->scanTimes = 0;
|
||||
pTSInfo->currentGroupId = -1;
|
||||
|
@ -2684,9 +2689,12 @@ int32_t stopGroupTableMergeScan(SOperatorInfo* pOperator) {
|
|||
taosArrayDestroy(pInfo->queryConds);
|
||||
pInfo->queryConds = NULL;
|
||||
|
||||
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// all data produced by this function only belongs to one group
|
||||
// slimit/soffset does not need to be concerned here, since this function only deal with data within one group.
|
||||
SSDataBlock* getSortedTableMergeScanBlockData(SSortHandle* pHandle, SSDataBlock* pResBlock, int32_t capacity,
|
||||
SOperatorInfo* pOperator) {
|
||||
STableMergeScanInfo* pInfo = pOperator->info;
|
||||
|
@ -2706,10 +2714,12 @@ SSDataBlock* getSortedTableMergeScanBlockData(SSortHandle* pHandle, SSDataBlock*
|
|||
}
|
||||
}
|
||||
|
||||
qDebug("%s get sorted row blocks, rows:%d", GET_TASKID(pTaskInfo), pResBlock->info.rows);
|
||||
applyLimitOffset(&pInfo->limitInfo, pResBlock, pTaskInfo, pOperator);
|
||||
pInfo->limitInfo.numOfOutputRows += pResBlock->info.rows;
|
||||
|
||||
qDebug("%s get sorted row block, rows:%d, limit:%"PRId64, GET_TASKID(pTaskInfo), pResBlock->info.rows,
|
||||
pInfo->limitInfo.numOfOutputRows);
|
||||
|
||||
return (pResBlock->info.rows > 0) ? pResBlock : NULL;
|
||||
}
|
||||
|
||||
|
@ -2748,11 +2758,13 @@ SSDataBlock* doTableMergeScan(SOperatorInfo* pOperator) {
|
|||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
return pBlock;
|
||||
} else {
|
||||
// Data of this group are all dumped, let's try the next group
|
||||
stopGroupTableMergeScan(pOperator);
|
||||
if (pInfo->tableEndIndex >= tableListSize - 1) {
|
||||
setOperatorCompleted(pOperator);
|
||||
break;
|
||||
}
|
||||
|
||||
pInfo->tableStartIndex = pInfo->tableEndIndex + 1;
|
||||
pInfo->groupId = tableListGetInfo(pTaskInfo->pTableInfoList, pInfo->tableStartIndex)->groupId;
|
||||
startGroupTableMergeScan(pOperator);
|
||||
|
@ -3221,7 +3233,9 @@ static void buildVnodeGroupedNtbTableCount(STableCountScanOperatorInfo* pInfo, S
|
|||
uint64_t groupId = calcGroupId(fullStbName, strlen(fullStbName));
|
||||
pRes->info.id.groupId = groupId;
|
||||
int64_t ntbNum = metaGetNtbNum(pInfo->readHandle.meta);
|
||||
fillTableCountScanDataBlock(pSupp, dbName, "", ntbNum, pRes);
|
||||
if (ntbNum != 0) {
|
||||
fillTableCountScanDataBlock(pSupp, dbName, "", ntbNum, pRes);
|
||||
}
|
||||
}
|
||||
|
||||
static void buildVnodeGroupedStbTableCount(STableCountScanOperatorInfo* pInfo, STableCountScanSupp* pSupp,
|
||||
|
|
|
@ -680,11 +680,13 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
break;
|
||||
}
|
||||
|
||||
bool limitReached = applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo, pOperator);
|
||||
if (limitReached) {
|
||||
resetLimitInfoForNextGroup(&pInfo->limitInfo);
|
||||
}
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
applyLimitOffset(&pInfo->limitInfo, p, pTaskInfo, pOperator);
|
||||
if (p->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,7 +700,6 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
colDataAssign(pDst, pSrc, p->info.rows, &pDataBlock->info);
|
||||
}
|
||||
|
||||
pInfo->limitInfo.numOfOutputRows += p->info.rows;
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.id.groupId = pInfo->groupId;
|
||||
pDataBlock->info.dataLoad = 1;
|
||||
|
|
|
@ -140,6 +140,10 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
|
|||
SMetaReader* smrChildTable, const char* dbname, const char* tableName,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock);
|
||||
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock,
|
||||
char* tName, SSchemaWrapper* schemaRow, char* tableType);
|
||||
|
||||
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
|
||||
SFilterInfo* pFilterInfo);
|
||||
|
||||
|
@ -413,6 +417,176 @@ static bool sysTableIsCondOnOneTable(SNode* pCond, char* condTable) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
|
||||
qDebug("sysTableScanUserCols get cols start");
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SSysTableScanInfo* pInfo = pOperator->info;
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
blockDataCleanup(pInfo->pRes);
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
SSDataBlock* dataBlock = buildInfoSchemaTableMetaBlock(TSDB_INS_TABLE_COLS);
|
||||
blockDataEnsureCapacity(dataBlock, pOperator->resultInfo.capacity);
|
||||
|
||||
const char* db = NULL;
|
||||
int32_t vgId = 0;
|
||||
vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId);
|
||||
|
||||
SName sn = {0};
|
||||
char dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&sn, db, T_NAME_ACCT | T_NAME_DB);
|
||||
|
||||
tNameGetDbName(&sn, varDataVal(dbname));
|
||||
varDataSetLen(dbname, strlen(varDataVal(dbname)));
|
||||
|
||||
// optimize when sql like where table_name='tablename' and xxx.
|
||||
if (pInfo->req.filterTb[0]) {
|
||||
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(tableName, pInfo->req.filterTb);
|
||||
|
||||
SMetaReader smrTable = {0};
|
||||
metaReaderInit(&smrTable, pInfo->readHandle.meta, 0);
|
||||
int32_t code = metaGetTableEntryByName(&smrTable, pInfo->req.filterTb);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// terrno has been set by metaGetTableEntryByName, therefore, return directly
|
||||
metaReaderClear(&smrTable);
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smrTable.me.type == TSDB_SUPER_TABLE) {
|
||||
metaReaderClear(&smrTable);
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smrTable.me.type == TSDB_CHILD_TABLE) {
|
||||
int64_t suid = smrTable.me.ctbEntry.suid;
|
||||
metaReaderClear(&smrTable);
|
||||
metaReaderInit(&smrTable, pInfo->readHandle.meta, 0);
|
||||
code = metaGetTableEntryByUid(&smrTable, suid);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// terrno has been set by metaGetTableEntryByName, therefore, return directly
|
||||
metaReaderClear(&smrTable);
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
SSchemaWrapper *schemaRow = NULL;
|
||||
if(smrTable.me.type == TSDB_SUPER_TABLE){
|
||||
schemaRow = &smrTable.me.stbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "CHILD_TABLE");
|
||||
}else if(smrTable.me.type == TSDB_NORMAL_TABLE){
|
||||
schemaRow = &smrTable.me.ntbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
|
||||
}
|
||||
|
||||
sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName);
|
||||
metaReaderClear(&smrTable);
|
||||
|
||||
if (numOfRows > 0) {
|
||||
relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
|
||||
numOfRows = 0;
|
||||
}
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
|
||||
setOperatorCompleted(pOperator);
|
||||
return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
|
||||
}
|
||||
|
||||
int32_t ret = 0;
|
||||
if (pInfo->pCur == NULL) {
|
||||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
|
||||
}
|
||||
|
||||
SHashObj *stableSchema = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||
taosHashSetFreeFp(stableSchema, tDeleteSSchemaWrapperForHash);
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur, TSDB_TABLE_MAX)) == 0) {
|
||||
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
|
||||
SSchemaWrapper *schemaRow = NULL;
|
||||
|
||||
if(pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE){
|
||||
qDebug("sysTableScanUserCols cursor get super table");
|
||||
void *schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t));
|
||||
if(schema == NULL){
|
||||
SSchemaWrapper *schemaWrapper = tCloneSSchemaWrapper(&pInfo->pCur->mr.me.stbEntry.schemaRow);
|
||||
taosHashPut(stableSchema, &pInfo->pCur->mr.me.uid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
|
||||
}
|
||||
continue;
|
||||
}else if (pInfo->pCur->mr.me.type == TSDB_CHILD_TABLE) {
|
||||
qDebug("sysTableScanUserCols cursor get child table");
|
||||
STR_TO_VARSTR(typeName, "CHILD_TABLE");
|
||||
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
|
||||
|
||||
int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
|
||||
void *schema = taosHashGet(stableSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
|
||||
if(schema != NULL){
|
||||
schemaRow = *(SSchemaWrapper **)schema;
|
||||
}else{
|
||||
tDecoderClear(&pInfo->pCur->mr.coder);
|
||||
int code = metaGetTableEntryByUid(&pInfo->pCur->mr, suid);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// terrno has been set by metaGetTableEntryByName, therefore, return directly
|
||||
qError("sysTableScanUserCols get meta by suid:%"PRId64 " error, code:%d", suid, code);
|
||||
blockDataDestroy(dataBlock);
|
||||
pInfo->loadInfo.totalRows = 0;
|
||||
taosHashCleanup(stableSchema);
|
||||
return NULL;
|
||||
}
|
||||
schemaRow = &pInfo->pCur->mr.me.stbEntry.schemaRow;
|
||||
}
|
||||
}else if(pInfo->pCur->mr.me.type == TSDB_NORMAL_TABLE){
|
||||
qDebug("sysTableScanUserCols cursor get normal table");
|
||||
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
|
||||
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
|
||||
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
|
||||
}else{
|
||||
qDebug("sysTableScanUserCols cursor get invalid table");
|
||||
continue;
|
||||
}
|
||||
|
||||
sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName);
|
||||
|
||||
if (numOfRows >= pOperator->resultInfo.capacity) {
|
||||
relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
|
||||
numOfRows = 0;
|
||||
|
||||
if (pInfo->pRes->info.rows > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taosHashCleanup(stableSchema);
|
||||
|
||||
if (numOfRows > 0) {
|
||||
relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo);
|
||||
numOfRows = 0;
|
||||
}
|
||||
|
||||
blockDataDestroy(dataBlock);
|
||||
if (ret != 0) {
|
||||
metaCloseTbCursor(pInfo->pCur);
|
||||
pInfo->pCur = NULL;
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
|
||||
pInfo->loadInfo.totalRows += pInfo->pRes->info.rows;
|
||||
qDebug("sysTableScanUserCols get cols success, rows:%" PRIu64, pInfo->loadInfo.totalRows);
|
||||
|
||||
return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
|
||||
}
|
||||
|
||||
static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SSysTableScanInfo* pInfo = pOperator->info;
|
||||
|
@ -491,7 +665,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
|
|||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
|
||||
}
|
||||
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur)) == 0) {
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
|
||||
if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE) {
|
||||
continue;
|
||||
}
|
||||
|
@ -728,6 +902,67 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname,
|
||||
int32_t* pNumOfRows, const SSDataBlock* dataBlock, char* tName,
|
||||
SSchemaWrapper* schemaRow, char* tableType) {
|
||||
if(schemaRow == NULL){
|
||||
qError("sysTableUserColsFillOneTableCols schemaRow is NULL");
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t numOfRows = *pNumOfRows;
|
||||
|
||||
int32_t numOfCols = schemaRow->nCols;
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = NULL;
|
||||
|
||||
// table name
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 0);
|
||||
colDataAppend(pColInfoData, numOfRows, tName, false);
|
||||
|
||||
// database name
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 1);
|
||||
colDataAppend(pColInfoData, numOfRows, dbname, false);
|
||||
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 2);
|
||||
colDataAppend(pColInfoData, numOfRows, tableType, false);
|
||||
|
||||
// col name
|
||||
char colName[TSDB_COL_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(colName, schemaRow->pSchema[i].name);
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 3);
|
||||
colDataAppend(pColInfoData, numOfRows, colName, false);
|
||||
|
||||
// col type
|
||||
int8_t colType = schemaRow->pSchema[i].type;
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 4);
|
||||
char colTypeStr[VARSTR_HEADER_SIZE + 32];
|
||||
int colTypeLen = sprintf(varDataVal(colTypeStr), "%s", tDataTypes[colType].name);
|
||||
if (colType == TSDB_DATA_TYPE_VARCHAR) {
|
||||
colTypeLen += sprintf(varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)(schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE));
|
||||
} else if (colType == TSDB_DATA_TYPE_NCHAR) {
|
||||
colTypeLen += sprintf(
|
||||
varDataVal(colTypeStr) + colTypeLen, "(%d)",
|
||||
(int32_t)((schemaRow->pSchema[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||
}
|
||||
varDataSetLen(colTypeStr, colTypeLen);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*)colTypeStr, false);
|
||||
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 5);
|
||||
colDataAppend(pColInfoData, numOfRows, (const char*)&schemaRow->pSchema[i].bytes, false);
|
||||
|
||||
for (int32_t j = 6; j <= 8; ++j) {
|
||||
pColInfoData = taosArrayGet(dataBlock->pDataBlock, j);
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
}
|
||||
++numOfRows;
|
||||
}
|
||||
|
||||
*pNumOfRows = numOfRows;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SSDataBlock* buildInfoSchemaTableMetaBlock(char* tableName) {
|
||||
size_t size = 0;
|
||||
const SSysTableMeta* pMeta = NULL;
|
||||
|
@ -1029,7 +1264,7 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
|
|||
char n[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
|
||||
int32_t ret = 0;
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur)) == 0) {
|
||||
while ((ret = metaTbCursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
|
||||
STR_TO_VARSTR(n, pInfo->pCur->mr.me.name);
|
||||
|
||||
// table name
|
||||
|
@ -1315,12 +1550,19 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
if (pInfo->showRewrite) {
|
||||
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||
sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||
}else if(strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0){
|
||||
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||
if(dbName[0]) sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||
sysTableIsCondOnOneTable(pInfo->pCondition, pInfo->req.filterTb);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0) {
|
||||
pBlock = sysTableScanUserTables(pOperator);
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0) {
|
||||
pBlock = sysTableScanUserTags(pOperator);
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->readHandle.mnd == NULL) {
|
||||
pBlock = sysTableScanUserCols(pOperator);
|
||||
} else if (strncasecmp(name, TSDB_INS_TABLE_STABLES, TSDB_TABLE_FNAME_LEN) == 0 && pInfo->showRewrite &&
|
||||
IS_SYS_DBNAME(dbName)) {
|
||||
pBlock = sysTableScanUserSTables(pOperator);
|
||||
|
@ -1391,7 +1633,7 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
|
|||
tsem_wait(&pInfo->ready);
|
||||
|
||||
if (pTaskInfo->code) {
|
||||
qDebug("%s load meta data from mnode failed, totalRows:%" PRIu64 ", code:%s", GET_TASKID(pTaskInfo),
|
||||
qError("%s load meta data from mnode failed, totalRows:%" PRIu64 ", code:%s", GET_TASKID(pTaskInfo),
|
||||
pInfo->loadInfo.totalRows, tstrerror(pTaskInfo->code));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1427,6 +1669,7 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
|
|||
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode,
|
||||
const char* pUser, SExecTaskInfo* pTaskInfo) {
|
||||
int32_t code = TDB_CODE_SUCCESS;
|
||||
SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -1437,7 +1680,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScan
|
|||
SDataBlockDescNode* pDescNode = pScanNode->node.pOutputDataBlockDesc;
|
||||
|
||||
int32_t num = 0;
|
||||
int32_t code = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
|
||||
code = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID, &pInfo->matchInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -1513,7 +1756,8 @@ void destroySysScanOperator(void* param) {
|
|||
|
||||
const char* name = tNameGetTableName(&pInfo->name);
|
||||
if (strncasecmp(name, TSDB_INS_TABLE_TABLES, TSDB_TABLE_FNAME_LEN) == 0 ||
|
||||
strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 || pInfo->pCur != NULL) {
|
||||
strncasecmp(name, TSDB_INS_TABLE_TAGS, TSDB_TABLE_FNAME_LEN) == 0 ||
|
||||
strncasecmp(name, TSDB_INS_TABLE_COLS, TSDB_TABLE_FNAME_LEN) == 0|| pInfo->pCur != NULL) {
|
||||
metaCloseTbCursor(pInfo->pCur);
|
||||
pInfo->pCur = NULL;
|
||||
}
|
||||
|
@ -1918,6 +2162,13 @@ static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
|
|||
colDataAppend(pColInfo, 0, p, false);
|
||||
taosMemoryFree(p);
|
||||
|
||||
// make the valgrind happy that all memory buffer has been initialized already.
|
||||
if (slotId != 0) {
|
||||
SColumnInfoData* p1 = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
int64_t v = 0;
|
||||
colDataAppendInt64(p1, 0, &v);
|
||||
}
|
||||
|
||||
pBlock->info.rows = 1;
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
return pBlock;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue