Merge branch '3.0' into fix/TD-18115
This commit is contained in:
commit
72571731f7
88
Jenkinsfile2
88
Jenkinsfile2
|
@ -38,40 +38,21 @@ def pre_test(){
|
|||
sh '''
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git remote prune origin
|
||||
git fetch
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git clean -fxd
|
||||
git remote prune origin
|
||||
git fetch
|
||||
'''
|
||||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout master
|
||||
cd ${WKC}
|
||||
git checkout master
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '2.0') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout 2.0
|
||||
cd ${WKC}
|
||||
git checkout 2.0
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '3.0') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout 3.0
|
||||
cd ${WKC}
|
||||
git checkout 3.0
|
||||
'''
|
||||
} else {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout develop
|
||||
cd ${WKC}
|
||||
git checkout develop
|
||||
'''
|
||||
}
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git checkout ''' + env.CHANGE_TARGET + '''
|
||||
cd ${WKC}
|
||||
git checkout ''' + env.CHANGE_TARGET + '''
|
||||
'''
|
||||
}
|
||||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
sh '''
|
||||
|
@ -169,49 +150,24 @@ def pre_test_win(){
|
|||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git reset --hard
|
||||
git remote prune origin
|
||||
git fetch
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git reset --hard
|
||||
git remote prune origin
|
||||
git fetch
|
||||
'''
|
||||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout master
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout master
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '2.0') {
|
||||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout 2.0
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout 2.0
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '3.0') {
|
||||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout 3.0
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout 3.0
|
||||
'''
|
||||
} else {
|
||||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout develop
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout develop
|
||||
'''
|
||||
}
|
||||
bat '''
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout ''' + env.CHANGE_TARGET + '''
|
||||
'''
|
||||
bat '''
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout ''' + env.CHANGE_TARGET + '''
|
||||
'''
|
||||
}
|
||||
script {
|
||||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taosadapter
|
||||
ExternalProject_Add(taosadapter
|
||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||
GIT_TAG 766dcc4
|
||||
GIT_TAG 3d21433
|
||||
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 2d68404
|
||||
GIT_TAG 57bdfbf
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# taosws-rs
|
||||
ExternalProject_Add(taosws-rs
|
||||
GIT_REPOSITORY https://github.com/taosdata/taos-connector-rust.git
|
||||
GIT_TAG 97c4bac
|
||||
GIT_TAG 7a54d21
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosws-rs"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -47,27 +47,28 @@ If the displayed content is followed by `...` you can use this command to change
|
|||
|
||||
You can change the behavior of TDengine CLI by specifying command-line parameters. The following parameters are commonly used.
|
||||
|
||||
- -h, --host=HOST: FQDN of the server where the TDengine server is to be connected. Default is to connect to the local service
|
||||
- -P, --port=PORT: Specify the port number to be used by the server. Default is `6030`
|
||||
- -u, --user=USER: the user name to use when connecting. Default is `root`
|
||||
- -p, --password=PASSWORD: the password to use when connecting to the server. Default is `taosdata`
|
||||
- -h HOST: FQDN of the server where the TDengine server is to be connected. Default is to connect to the local service
|
||||
- -P PORT: Specify the port number to be used by the server. Default is `6030`
|
||||
- -u USER: the user name to use when connecting. Default is `root`
|
||||
- -p PASSWORD: the password to use when connecting to the server. Default is `taosdata`
|
||||
- -?, --help: print out all command-line arguments
|
||||
|
||||
And many more parameters.
|
||||
|
||||
- -c, --config-dir: Specify the directory where configuration file exists. The default is `/etc/taos`, and the default name of the configuration file in this directory is `taos.cfg`
|
||||
- -C, --dump-config: Print the configuration parameters of `taos.cfg` in the default directory or specified by -c
|
||||
- -d, --database=DATABASE: Specify the database to use when connecting to the server
|
||||
- -D, --directory=DIRECTORY: Import the SQL script file in the specified path
|
||||
- -f, --file=FILE: Execute the SQL script file in non-interactive mode
|
||||
- -k, --check=CHECK: Specify the table to be checked
|
||||
- -l, --pktlen=PKTLEN: Test package size to be used for network testing
|
||||
- -n, --netrole=NETROLE: test scope for network connection test, default is `startup`. The value can be `client`, `server`, `rpc`, `startup`, `sync`, `speed`, or `fqdn`.
|
||||
- -r, --raw-time: output the timestamp format as unsigned 64-bits integer (uint64_t in C language)
|
||||
- -s, --commands=COMMAND: execute SQL commands in non-interactive mode
|
||||
- -S, --pkttype=PKTTYPE: Specify the packet type used for network testing. The default is TCP, can be specified as either TCP or UDP when `speed` is specified to `netrole` parameter
|
||||
- -T, --thread=THREADNUM: The number of threads to import data in multi-threaded mode
|
||||
- -s, --commands: Run TDengine CLI commands without entering the terminal
|
||||
- -a AUTHSTR: The auth string to use when connecting to the server
|
||||
- -A: Generate auth string from password
|
||||
- -c CONFIGDIR: Specify the directory where configuration file exists. The default is `/etc/taos`, and the default name of the configuration file in this directory is `taos.cfg`
|
||||
- -C: Print the configuration parameters of `taos.cfg` in the default directory or specified by -c
|
||||
- -d DATABASE: Specify the database to use when connecting to the server
|
||||
- -f FILE: Execute the SQL script file in non-interactive mode
|
||||
- -k: Check the service status, 0: unavailable,1: network ok,2: service ok,3: service degraded,4: exiting
|
||||
- -l PKTLEN: Test package length to be used for network testing
|
||||
- -n NETROLE: test scope for network connection test, default is `client`. The value can be `client`, `server`
|
||||
- -N PKTNUM: Test package numbers to be used for network testing
|
||||
- -r: output the timestamp format as unsigned 64-bits integer (uint64_t in C language)
|
||||
- -s COMMAND: execute SQL commands in non-interactive mode
|
||||
- -t: Check the details of the service status,status same as -k
|
||||
- -w DISPLAYWIDTH: 客户端列显示宽度
|
||||
- -z, --timezone=TIMEZONE: Specify time zone. Default is the value of current configuration file
|
||||
- -V, --version: Print out the current version number
|
||||
|
||||
|
|
|
@ -5,12 +5,11 @@ description: "List of platforms supported by TDengine server, client, and connec
|
|||
|
||||
## List of supported platforms for TDengine server
|
||||
|
||||
| | **CentOS 7/8** | **Ubuntu 16/18/20** | **Other Linux** |
|
||||
| ------------ | -------------- | ------------------- | --------------- |
|
||||
| X64 | ● | ● | |
|
||||
| MIPS64 | | | ● |
|
||||
| ARM64 | | ○ | ○ |
|
||||
| Alpha64 | | | ○ |
|
||||
| | **Windows 10/11** | **CentOS 7.9/8** | **Ubuntu 18/20** | **Other Linux** | **UOS** | **Kylin** | **Ningsi V60/V80** | **HUAWEI EulerOS** |
|
||||
| ------------------ | ----------------- | ---------------- | ---------------- | --------------- | ------- | --------- | ------------------ | ------------------ |
|
||||
| X64 | ● | ● | ● | | ● | ● | ● | |
|
||||
| Raspberry Pi ARM64 | | | | ● | | | | |
|
||||
| HUAWEI cloud ARM64 | | | | | | | | ● |
|
||||
|
||||
Note: ● means officially tested and verified, ○ means unofficially tested and verified.
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ All executable files of TDengine are in the _/usr/local/taos/bin_ directory by d
|
|||
- _taosBenchmark_: TDengine testing tool
|
||||
- _remove.sh_: script to uninstall TDengine, please execute it carefully, link to the **rmtaos** command in the /usr/bin directory. Will remove the TDengine installation directory `/usr/local/taos`, but will keep `/etc/taos`, `/var/lib/taos`, `/var/log/taos`
|
||||
- _taosadapter_: server-side executable that provides RESTful services and accepts writing requests from a variety of other softwares
|
||||
- _tarbitrator_: provides arbitration for two-node cluster deployments
|
||||
- _TDinsight.sh_: script to download TDinsight and install it
|
||||
- _set_core.sh_: script for setting up the system to generate core dump files for easy debugging
|
||||
- _taosd-dump-cfg.gdb_: script to facilitate debugging of taosd's gdb execution.
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
sidebar_label: Docker
|
||||
title: 通过 Docker 快速体验 TDengine
|
||||
---
|
||||
:::info
|
||||
如果您希望对 TDengine 贡献代码或对内部实现感兴趣,请参考我们的 [TDengine GitHub 主页](https://github.com/taosdata/TDengine) 下载源码构建和安装.
|
||||
:::
|
||||
|
||||
本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。
|
||||
|
||||
|
@ -63,6 +66,10 @@ taos>
|
|||
|
||||
taosAdapter 是 TDengine 中提供 REST 服务的组件。下面这条命令会在容器中同时启动 `taosd` 和 `taosadapter` 两个服务组件。默认 Docker 镜像同时启动 TDengine 后台服务 taosd 和 taosAdatper。
|
||||
|
||||
```shell
|
||||
docker run -d --name tdengine -p 6041:6041 tdengine/tdengine
|
||||
```
|
||||
|
||||
可以在宿主机使用 curl 通过 RESTful 端口访问 Docker 容器内的 TDengine server。
|
||||
|
||||
```
|
||||
|
|
|
@ -89,10 +89,6 @@ T = 最新事件时间 - watermark
|
|||
|
||||
无论在哪种模式下,watermark 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。
|
||||
|
||||
## 流式计算的数据填充策略
|
||||
|
||||
TODO
|
||||
|
||||
## 流式计算与会话窗口(session window)
|
||||
|
||||
```sql
|
||||
|
@ -105,14 +101,6 @@ window_clause: {
|
|||
|
||||
其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口。
|
||||
|
||||
## 流式计算的监控与流任务分布查询
|
||||
|
||||
TODO
|
||||
|
||||
## 流式计算的内存控制与存算分离
|
||||
|
||||
TODO
|
||||
|
||||
## 流式计算的暂停与恢复
|
||||
|
||||
```sql
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
sidebar_label: 元数据库
|
||||
title: 元数据库
|
||||
sidebar_label: 元数据
|
||||
title: 存储元数据的 Information_Schema 数据库
|
||||
---
|
||||
|
||||
TDengine 内置了一个名为 `INFORMATION_SCHEMA` 的数据库,提供对数据库元数据、数据库系统信息和状态的访问,例如数据库或表的名称,当前执行的 SQL 语句等。该数据库存储有关 TDengine 维护的所有其他数据库的信息。它包含多个只读表。实际上,这些表都是视图,而不是基表,因此没有与它们关联的文件。所以对这些表只能查询,不能进行 INSERT 等写入操作。`INFORMATION_SCHEMA` 数据库旨在以一种更一致的方式来提供对 TDengine 支持的各种 SHOW 语句(如 SHOW TABLES、SHOW DATABASES)所提供的信息的访问。与 SHOW 语句相比,使用 SELECT ... FROM INFORMATION_SCHEMA.tablename 具有以下优点:
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
---
|
||||
sidebar_label: 统计数据
|
||||
title: 存储统计数据的 Performance_Schema 数据库
|
||||
---
|
||||
|
||||
TDengine 3.0 版本开始提供一个内置数据库 `performance_schema`,其中存储了与性能有关的统计数据。本节详细介绍其中的表和表结构。
|
||||
|
||||
## PERF_APP
|
||||
|
||||
提供接入集群的应用(客户端)的相关信息。也可以使用 SHOW APPS 来查询这些信息。
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :----------: | ------------ | ------------------------------- |
|
||||
| 1 | app_id | UBIGINT | 客户端 ID |
|
||||
| 2 | ip | BINARY(16) | 客户端地址 |
|
||||
| 3 | pid | INT | 客户端进程 号 |
|
||||
| 4 | name | BINARY(24) | 客户端名称 |
|
||||
| 5 | start_time | TIMESTAMP | 客户端启动时间 |
|
||||
| 6 | insert_req | UBIGINT | insert 请求次数 |
|
||||
| 7 | insert_row | UBIGINT | insert 插入行数 |
|
||||
| 8 | insert_time | UBIGINT | insert 请求的处理时间,单位微秒 |
|
||||
| 9 | insert_bytes | UBIGINT | insert 请求消息字节数 |
|
||||
| 10 | fetch_bytes | UBIGINT | 查询结果字节数 |
|
||||
| 11 | query_time | UBIGINT | 查询请求处理时间 |
|
||||
| 12 | slow_query | UBIGINT | 慢查询(处理时间 >= 3 秒)个数 |
|
||||
| 13 | total_req | UBIGINT | 总请求数 |
|
||||
| 14 | current_req | UBIGINT | 当前正在处理的请求个数 |
|
||||
| 15 | last_access | TIMESTAMP | 最后更新时间 |
|
||||
|
||||
## PERF_CONNECTIONS
|
||||
|
||||
数据库的连接的相关信息。也可以使用 SHOW CONNECTIONS 来查询这些信息。
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :---------: | ------------ | -------------------------------------------------- |
|
||||
| 1 | conn_id | INT | 连接 ID |
|
||||
| 2 | user | BINARY(24) | 用户名 |
|
||||
| 3 | app | BINARY(24) | 客户端名称 |
|
||||
| 4 | pid | UINT | 发起此连接的客户端在自己所在服务器或主机上的进程号 |
|
||||
| 5 | end_point | BINARY(128) | 客户端地址 |
|
||||
| 6 | login_time | TIMESTAMP | 登录时间 |
|
||||
| 7 | last_access | TIMESTAMP | 最后更新时间 |
|
||||
|
||||
## PERF_QUERIES
|
||||
|
||||
提供当前正在执行的 SQL 语句的信息。也可以使用 SHOW QUERIES 来查询这些信息。
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :----------: | ------------ | ---------------------------- |
|
||||
| 1 | kill_id | UBIGINT | 用来停止查询的 ID |
|
||||
| 2 | query_id | INT | 查询 ID |
|
||||
| 3 | conn_id | UINT | 连接 ID |
|
||||
| 4 | app | BINARY(24) | app 名称 |
|
||||
| 5 | pid | INT | app 在自己所在主机上的进程号 |
|
||||
| 6 | user | BINARY(24) | 用户名 |
|
||||
| 7 | end_point | BINARY(16) | 客户端地址 |
|
||||
| 8 | create_time | TIMESTAMP | 创建时间 |
|
||||
| 9 | exec_usec | BIGINT | 已执行时间 |
|
||||
| 10 | stable_query | BOOL | 是否是超级表查询 |
|
||||
| 11 | sub_num | INT | 子查询数量 |
|
||||
| 12 | sub_status | BINARY(1000) | 子查询状态 |
|
||||
| 13 | sql | BINARY(1024) | SQL 语句 |
|
||||
|
||||
## PERF_TOPICS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :---------: | ------------ | ------------------------------ |
|
||||
| 1 | topic_name | BINARY(192) | topic 名称 |
|
||||
| 2 | db_name | BINARY(64) | topic 相关的 DB |
|
||||
| 3 | create_time | TIMESTAMP | topic 的 创建时间 |
|
||||
| 4 | sql | BINARY(1024) | 创建该 topic 时所用的 SQL 语句 |
|
||||
|
||||
## PERF_CONSUMERS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :------------: | ------------ | ----------------------------------------------------------- |
|
||||
| 1 | consumer_id | BIGINT | 消费者的唯一 ID |
|
||||
| 2 | consumer_group | BINARY(192) | 消费者组 |
|
||||
| 3 | client_id | BINARY(192) | 用户自定义字符串,通过创建 consumer 时指定 client_id 来展示 |
|
||||
| 4 | status | BINARY(20) | 消费者当前状态 |
|
||||
| 5 | topics | BINARY(204) | 被订阅的 topic。若订阅多个 topic,则展示为多行 |
|
||||
| 6 | up_time | TIMESTAMP | 第一次连接 taosd 的时间 |
|
||||
| 7 | subscribe_time | TIMESTAMP | 上一次发起订阅的时间 |
|
||||
| 8 | rebalance_time | TIMESTAMP | 上一次触发 rebalance 的时间 |
|
||||
|
||||
## PERF_SUBSCRIPTIONS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :------------: | ------------ | ------------------------ |
|
||||
| 1 | topic_name | BINARY(204) | 被订阅的 topic |
|
||||
| 2 | consumer_group | BINARY(193) | 订阅者的消费者组 |
|
||||
| 3 | vgroup_id | INT | 消费者被分配的 vgroup id |
|
||||
| 4 | consumer_id | BIGINT | 消费者的唯一 id |
|
||||
|
||||
## PERF_TRANS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :--------------: | ------------ | -------- |
|
||||
| 1 | id | INT | |
|
||||
| 2 | create_time | TIMESTAMP | |
|
||||
| 3 | stage | BINARY(12) | |
|
||||
| 4 | db1 | BINARY(64) | |
|
||||
| 5 | db2 | BINARY(64) | |
|
||||
| 6 | failed_times | INT | |
|
||||
| 7 | last_exec_time | TIMESTAMP | |
|
||||
| 8 | last_action_info | BINARY(511) | |
|
||||
|
||||
## PERF_SMAS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :---------: | ------------ | ------------------------------------------- |
|
||||
| 1 | sma_name | BINARY(192) | 时间维度的预计算 (time-range-wise sma) 名称 |
|
||||
| 2 | create_time | TIMESTAMP | sma 创建时间 |
|
||||
| 3 | stable_name | BINARY(192) | sma 所属的超级表名称 |
|
||||
| 4 | vgroup_id | INT | sma 专属的 vgroup 名称 |
|
||||
|
||||
## PERF_STREAMS
|
||||
|
||||
| # | **列名** | **数据类型** | **说明** |
|
||||
| --- | :----------: | ------------ | --------------------------------------- |
|
||||
| 1 | stream_name | BINARY(64) | 流计算名称 |
|
||||
| 2 | create_time | TIMESTAMP | 创建时间 |
|
||||
| 3 | sql | BINARY(1024) | 创建流计算时提供的 SQL 语句 |
|
||||
| 4 | status | BIANRY(20) | 流当前状态 |
|
||||
| 5 | source_db | BINARY(64) | 源数据库 |
|
||||
| 6 | target_db | BIANRY(64) | 目的数据库 |
|
||||
| 7 | target_table | BINARY(192) | 流计算写入的目标表 |
|
||||
| 8 | watermark | BIGINT | watermark,详见 SQL 手册流式计算 |
|
||||
| 9 | trigger | INT | 计算结果推送模式,详见 SQL 手册流式计算 |
|
|
@ -10,14 +10,14 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速
|
|||
|
||||
目前 TDengine 的原生接口连接器可支持的平台包括:X64/X86/ARM64/ARM32/MIPS/Alpha 等硬件平台,以及 Linux/Win64/Win32 等开发环境。对照矩阵如下:
|
||||
|
||||
| **CPU** | **OS** | **JDBC** | **Python** | **Go** | **Node.js** | **C#** | **Rust** | C/C++ |
|
||||
| **CPU** | **OS** | **Java** | **Python** | **Go** | **Node.js** | **C#** | **Rust** | C/C++ |
|
||||
| -------------- | --------- | -------- | ---------- | ------ | ----------- | ------ | -------- | ----- |
|
||||
| **X86 64bit** | **Linux** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **Win64** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **Win32** | ● | ● | ● | ● | ○ | ○ | ● |
|
||||
| **X86 32bit** | **Win32** | ○ | ○ | ○ | ○ | ○ | ○ | ● |
|
||||
| **ARM64** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● |
|
||||
| **ARM32** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● |
|
||||
| **ARM32** | **Linux** | ○ | ○ | ○ | ○ | ○ | ○ | ● |
|
||||
| **MIPS 龙芯** | **Linux** | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
|
||||
| **Alpha 申威** | **Linux** | ○ | ○ | -- | -- | -- | -- | ○ |
|
||||
| **X86 海光** | **Linux** | ○ | ○ | ○ | -- | -- | -- | ○ |
|
||||
|
@ -32,6 +32,7 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
|
||||
| **TDengine 版本** | **Java** | **Python** | **Go** | **C#** | **Node.js** | **Rust** |
|
||||
| --------------------- | -------- | ---------- | ------------ | ------------- | --------------- | -------- |
|
||||
| **3.0.0.0 及以上** | 3.0.0 | 当前版本 | 3.0 分支 | 3.0.0 | 3.0.0 | 当前版本 |
|
||||
| **2.4.0.14 及以上** | 2.0.38 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 |
|
||||
| **2.4.0.6 及以上** | 2.0.37 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 |
|
||||
| **2.4.0.4 - 2.4.0.5** | 2.0.37 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 |
|
||||
|
@ -48,9 +49,8 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
| -------------- | -------- | ---------- | ------ | ------ | ----------- | -------- |
|
||||
| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **连续查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **订阅功能** | 支持 | 支持 | 支持 | 支持 | 支持 | 暂不支持 |
|
||||
| ** TMQ ** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **DataFrame** | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
|
||||
|
||||
|
@ -58,17 +58,17 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
由于不同编程语言数据库框架规范不同,并不意味着所有 C/C++ 接口都需要对应封装支持。
|
||||
:::
|
||||
|
||||
### 使用 REST 接口
|
||||
### 使用 http (REST 或 WebSocket) 接口
|
||||
|
||||
| **功能特性** | **Java** | **Python** | **Go** | **C#(暂不支持)** | **Node.js** | **Rust** |
|
||||
| ------------------------------ | -------- | ---------- | -------- | ------------------ | ----------- | -------- |
|
||||
| **连接管理** | 支持 | 支持 | 支持 | N/A | 支持 | 支持 |
|
||||
| **普通查询** | 支持 | 支持 | 支持 | N/A | 支持 | 支持 |
|
||||
| **连续查询** | 支持 | 支持 | 支持 | N/A | 支持 | 支持 |
|
||||
| **参数绑定** | 不支持 | 不支持 | 不支持 | N/A | 不支持 | 不支持 |
|
||||
| **订阅功能** | 不支持 | 不支持 | 不支持 | N/A | 不支持 | 不支持 |
|
||||
| **Schemaless** | 暂不支持 | 暂不支持 | 暂不支持 | N/A | 暂不支持 | 暂不支持 |
|
||||
| **批量拉取(基于 WebSocket)** | 支持 | 暂不支持 | 暂不支持 | N/A | 暂不支持 | 暂不支持 |
|
||||
| **参数绑定** | 不支持 | 暂不支持 | 暂不支持 | N/A | 不支持 | 支持 |
|
||||
| ** TMQ ** | 不支持 | 暂不支持 | 暂不支持 | N/A | 不支持 | 支持 |
|
||||
| **Schemaless** | 暂不支持 | 暂不支持 | 暂不支持 | N/A | 不支持 | 暂不支持 |
|
||||
| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 暂不支持 | N/A | 不支持 | 支持 |
|
||||
| **DataFrame** | 不支持 | 支持 | 不支持 | N/A | 不支持 | 不支持 |
|
||||
|
||||
:::warning
|
||||
|
|
|
@ -48,29 +48,30 @@ taos> SET MAX_BINARY_DISPLAY_WIDTH <nn>;
|
|||
|
||||
您可通过配置命令行参数来改变 TDengine CLI 的行为。以下为常用的几个命令行参数:
|
||||
|
||||
- -h, --host=HOST: 要连接的 TDengine 服务端所在服务器的 FQDN, 默认为连接本地服务
|
||||
- -P, --port=PORT: 指定服务端所用端口号
|
||||
- -u, --user=USER: 连接时使用的用户名
|
||||
- -p, --password=PASSWORD: 连接服务端时使用的密码
|
||||
- -h HOST: 要连接的 TDengine 服务端所在服务器的 FQDN, 默认为连接本地服务
|
||||
- -P PORT: 指定服务端所用端口号
|
||||
- -u USER: 连接时使用的用户名
|
||||
- -p PASSWORD: 连接服务端时使用的密码
|
||||
- -?, --help: 打印出所有命令行参数
|
||||
|
||||
还有更多其他参数:
|
||||
|
||||
- -c, --config-dir: 指定配置文件目录,Linux 环境下默认为 `/etc/taos`,该目录下的配置文件默认名称为 `taos.cfg`
|
||||
- -C, --dump-config: 打印 -c 指定的目录中 `taos.cfg` 的配置参数
|
||||
- -d, --database=DATABASE: 指定连接到服务端时使用的数据库
|
||||
- -D, --directory=DIRECTORY: 导入指定路径中的 SQL 脚本文件
|
||||
- -f, --file=FILE: 以非交互模式执行 SQL 脚本文件。文件中一个 SQL 语句只能占一行
|
||||
- -k, --check=CHECK: 指定要检查的表
|
||||
- -l, --pktlen=PKTLEN: 网络测试时使用的测试包大小
|
||||
- -n, --netrole=NETROLE: 网络连接测试时的测试范围,默认为 `startup`, 可选值为 `client`、`server`、`rpc`、`startup`、`sync`、`speed` 和 `fqdn` 之一
|
||||
- -r, --raw-time: 将时间输出出无符号 64 位整数类型(即 C 语音中 uint64_t)
|
||||
- -s, --commands=COMMAND: 以非交互模式执行的 SQL 命令
|
||||
- -S, --pkttype=PKTTYPE: 指定网络测试所用的包类型,默认为 TCP。只有 netrole 为 `speed` 时既可以指定为 TCP 也可以指定为 UDP
|
||||
- -T, --thread=THREADNUM: 以多线程模式导入数据时的线程数
|
||||
- -s, --commands: 在不进入终端的情况下运行 TDengine 命令
|
||||
- -z, --timezone=TIMEZONE: 指定时区,默认为本地时区
|
||||
- -V, --version: 打印出当前版本号
|
||||
- -a AUTHSTR: 连接服务端的授权信息
|
||||
- -A: 通过用户名和密码计算授权信息
|
||||
- -c CONFIGDIR: 指定配置文件目录,Linux 环境下默认为 `/etc/taos`,该目录下的配置文件默认名称为 `taos.cfg`
|
||||
- -C: 打印 -c 指定的目录中 `taos.cfg` 的配置参数
|
||||
- -d DATABASE: 指定连接到服务端时使用的数据库
|
||||
- -f FILE: 以非交互模式执行 SQL 脚本文件。文件中一个 SQL 语句只能占一行
|
||||
- -k: 测试服务端运行状态,0: unavailable,1: network ok,2: service ok,3: service degraded,4: exiting
|
||||
- -l PKTLEN: 网络测试时使用的测试包大小
|
||||
- -n NETROLE: 网络连接测试时的测试范围,默认为 `client`, 可选值为 `client`、`server`
|
||||
- -N PKTNUM: 网络测试时使用的测试包数量
|
||||
- -r: 将时间输出出无符号 64 位整数类型(即 C 语音中 uint64_t)
|
||||
- -s COMMAND: 以非交互模式执行的 SQL 命令
|
||||
- -t: 测试服务端启动状态,状态同-k
|
||||
- -w DISPLAYWIDTH: 客户端列显示宽度
|
||||
- -z TIMEZONE: 指定时区,默认为本地时区
|
||||
- -V: 打印出当前版本号
|
||||
|
||||
示例:
|
||||
|
||||
|
|
|
@ -5,18 +5,11 @@ description: "TDengine 服务端、客户端和连接器支持的平台列表"
|
|||
|
||||
## TDengine 服务端支持的平台列表
|
||||
|
||||
| | **CentOS 7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | **华为 EulerOS** |
|
||||
| ------------ | -------------- | ------------------- | --------------- | ------------ | ----------------- | ---------------- | ---------------- |
|
||||
| X64 | ● | ● | | ○ | ● | ● | ● |
|
||||
| 龙芯 MIPS64 | | | ● | | | | |
|
||||
| 鲲鹏 ARM64 | | ○ | ○ | | ● | | |
|
||||
| 申威 Alpha64 | | | ○ | ● | | | |
|
||||
| 飞腾 ARM64 | | ○ 优麒麟 | | | | | |
|
||||
| 海光 X64 | ● | ● | ● | ○ | ● | ● | |
|
||||
| 瑞芯微 ARM64 | | | ○ | | | | |
|
||||
| 全志 ARM64 | | | ○ | | | | |
|
||||
| 炬力 ARM64 | | | ○ | | | | |
|
||||
| 华为云 ARM64 | | | | | | | ● |
|
||||
| | **Windows 10/11** | **CentOS 7.9/8** | **Ubuntu 18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | **华为 EulerOS** |
|
||||
| ------------ | ----------------- | ---------------- | ---------------- | --------------- | ------------ | ----------------- | ---------------- | ---------------- |
|
||||
| X64 | ● | ● | ● | | ● | ● | ● | |
|
||||
| 树莓派 ARM64 | | | | ● | | | | |
|
||||
| 华为云 ARM64 | | | | | | | | ● |
|
||||
|
||||
注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ TDengine 的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
|||
- _taosBenchmark_:TDengine 测试工具
|
||||
- _remove.sh_:卸载 TDengine 的脚本,请谨慎执行,链接到/usr/bin 目录下的**rmtaos**命令。会删除 TDengine 的安装目录/usr/local/taos,但会保留/etc/taos、/var/lib/taos、/var/log/taos
|
||||
- _taosadapter_: 提供 RESTful 服务和接受其他多种软件写入请求的服务端可执行文件
|
||||
- _tarbitrator_: 提供双节点集群部署的仲裁功能
|
||||
- _TDinsight.sh_:用于下载 TDinsight 并安装的脚本
|
||||
- _set_core.sh_:用于方便调试设置系统生成 core dump 文件的脚本
|
||||
- _taosd-dump-cfg.gdb_:用于方便调试 taosd 的 gdb 执行脚本。
|
||||
|
|
|
@ -21,17 +21,17 @@
|
|||
#include "taos.h"
|
||||
|
||||
static int running = 1;
|
||||
static char dbName[64] = "tmqdb";
|
||||
static char stbName[64] = "stb";
|
||||
static char dbName[64] = "tmqdb";
|
||||
static char stbName[64] = "stb";
|
||||
static char topicName[64] = "topicname";
|
||||
|
||||
static int32_t msg_process(TAOS_RES* msg) {
|
||||
char buf[1024];
|
||||
char buf[1024];
|
||||
int32_t rows = 0;
|
||||
|
||||
const char* topicName = tmq_get_topic_name(msg);
|
||||
const char* dbName = tmq_get_db_name(msg);
|
||||
int32_t vgroupId = tmq_get_vgroup_id(msg);
|
||||
const char* dbName = tmq_get_db_name(msg);
|
||||
int32_t vgroupId = tmq_get_vgroup_id(msg);
|
||||
|
||||
printf("topic: %s\n", topicName);
|
||||
printf("db: %s\n", dbName);
|
||||
|
@ -41,14 +41,14 @@ static int32_t msg_process(TAOS_RES* msg) {
|
|||
TAOS_ROW row = taos_fetch_row(msg);
|
||||
if (row == NULL) break;
|
||||
|
||||
TAOS_FIELD* fields = taos_fetch_fields(msg);
|
||||
TAOS_FIELD* fields = taos_fetch_fields(msg);
|
||||
int32_t numOfFields = taos_field_count(msg);
|
||||
int32_t* length = taos_fetch_lengths(msg);
|
||||
int32_t precision = taos_result_precision(msg);
|
||||
const char* tbName = tmq_get_table_name(msg);
|
||||
rows++;
|
||||
int32_t* length = taos_fetch_lengths(msg);
|
||||
int32_t precision = taos_result_precision(msg);
|
||||
const char* tbName = tmq_get_table_name(msg);
|
||||
rows++;
|
||||
taos_print_row(buf, row, fields, numOfFields);
|
||||
printf("row content from %s: %s\n", (tbName != NULL ? tbName : "null table"), buf);
|
||||
printf("row content from %s: %s\n", (tbName != NULL ? tbName : "table null"), buf);
|
||||
}
|
||||
|
||||
return rows;
|
||||
|
@ -80,7 +80,8 @@ static int32_t init_env() {
|
|||
|
||||
// create super table
|
||||
printf("create super table\n");
|
||||
pRes = taos_query(pConn, "create table tmqdb.stb (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16))");
|
||||
pRes = taos_query(
|
||||
pConn, "create table tmqdb.stb (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16))");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create super table stb, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
@ -166,7 +167,6 @@ int32_t create_topic() {
|
|||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
// pRes = taos_query(pConn, "create topic topic_ctb_column with meta as database abc1");
|
||||
pRes = taos_query(pConn, "create topic topicname as select ts, c1, c2, c3 from tmqdb.stb where c1 > 1");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create topic topicname, reason:%s\n", taos_errstr(pRes));
|
||||
|
@ -184,26 +184,28 @@ void tmq_commit_cb_print(tmq_t* tmq, int32_t code, void* param) {
|
|||
|
||||
tmq_t* build_consumer() {
|
||||
tmq_conf_res_t code;
|
||||
tmq_conf_t* conf = tmq_conf_new();
|
||||
tmq_conf_t* conf = tmq_conf_new();
|
||||
code = tmq_conf_set(conf, "enable.auto.commit", "true");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "auto.commit.interval.ms", "1000");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "group.id", "cgrpName");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "client.id", "user defined name");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "td.connect.user", "root");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "td.connect.pass", "taosdata");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "auto.offset.reset", "earliest");
|
||||
code = tmq_conf_set(conf, "auto.offset.reset", "earliest");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "experimental.snapshot.enable", "true");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
code = tmq_conf_set(conf, "msg.with.table.name", "true");
|
||||
if (TMQ_CONF_OK != code) return NULL;
|
||||
|
||||
tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
|
||||
|
||||
|
||||
tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
|
||||
|
||||
tmq_t* tmq = tmq_consumer_new(conf, NULL, 0);
|
||||
tmq_conf_destroy(conf);
|
||||
return tmq;
|
||||
|
@ -211,7 +213,7 @@ tmq_t* build_consumer() {
|
|||
|
||||
tmq_list_t* build_topic_list() {
|
||||
tmq_list_t* topicList = tmq_list_new();
|
||||
int32_t code = tmq_list_append(topicList, "topicname");
|
||||
int32_t code = tmq_list_append(topicList, "topicname");
|
||||
if (code) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -228,18 +230,18 @@ void basic_consume_loop(tmq_t* tmq, tmq_list_t* topicList) {
|
|||
|
||||
int32_t totalRows = 0;
|
||||
int32_t msgCnt = 0;
|
||||
int32_t consumeDelay = 5000;
|
||||
int32_t timeout = 5000;
|
||||
while (running) {
|
||||
TAOS_RES* tmqmsg = tmq_consumer_poll(tmq, consumeDelay);
|
||||
TAOS_RES* tmqmsg = tmq_consumer_poll(tmq, timeout);
|
||||
if (tmqmsg) {
|
||||
msgCnt++;
|
||||
totalRows += msg_process(tmqmsg);
|
||||
taos_free_result(tmqmsg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
/*} else {*/
|
||||
/*break;*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fprintf(stderr, "%d msg consumed, include %d rows\n", msgCnt, totalRows);
|
||||
}
|
||||
|
||||
|
@ -256,32 +258,30 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
tmq_t* tmq = build_consumer();
|
||||
if (NULL == tmq) {
|
||||
fprintf(stderr, "%% build_consumer() fail!\n");
|
||||
fprintf(stderr, "%% build_consumer() fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmq_list_t* topic_list = build_topic_list();
|
||||
if (NULL == topic_list) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
basic_consume_loop(tmq, topic_list);
|
||||
|
||||
code = tmq_unsubscribe(tmq);
|
||||
if (code) {
|
||||
fprintf(stderr, "%% Failed to unsubscribe: %s\n", tmq_err2str(code));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "%% unsubscribe\n");
|
||||
}
|
||||
|
||||
code = tmq_consumer_close(tmq);
|
||||
if (code) {
|
||||
fprintf(stderr, "%% Failed to close consumer: %s\n", tmq_err2str(code));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "%% Consumer closed\n");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 7ed7a97715388fa144718764d6bf20f9bfc29a12
|
|
@ -196,15 +196,6 @@ DLL_EXPORT void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, vo
|
|||
DLL_EXPORT void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param);
|
||||
DLL_EXPORT const void *taos_get_raw_block(TAOS_RES *res);
|
||||
|
||||
// Shuduo: temporary enable for app build
|
||||
#if 1
|
||||
typedef void (*__taos_sub_fn_t)(TAOS_SUB *tsub, TAOS_RES *res, void *param, int code);
|
||||
DLL_EXPORT TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char *topic, const char *sql, __taos_sub_fn_t fp,
|
||||
void *param, int interval);
|
||||
DLL_EXPORT TAOS_RES *taos_consume(TAOS_SUB *tsub);
|
||||
DLL_EXPORT void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress);
|
||||
#endif
|
||||
|
||||
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList);
|
||||
DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision);
|
||||
|
||||
|
@ -281,10 +272,6 @@ DLL_EXPORT const char *tmq_get_table_name(TAOS_RES *res);
|
|||
|
||||
/* ------------------------------ TMQ END -------------------------------- */
|
||||
|
||||
#if 1 // Shuduo: temporary enable for app build
|
||||
typedef void (*TAOS_SUBSCRIBE_CALLBACK)(TAOS_SUB *tsub, TAOS_RES *res, void *param, int code);
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TSDB_SRV_STATUS_UNAVAILABLE = 0,
|
||||
TSDB_SRV_STATUS_NETWORK_OK = 1,
|
||||
|
|
|
@ -239,7 +239,7 @@ SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId
|
|||
SColumnInfoData* bdGetColumnInfoData(const SSDataBlock* pBlock, int32_t index);
|
||||
|
||||
void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress);
|
||||
const char* blockDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData);
|
||||
const char* blockDecode(SSDataBlock* pBlock, const char* pData);
|
||||
|
||||
void blockDebugShowDataBlock(SSDataBlock* pBlock, const char* flag);
|
||||
void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag);
|
||||
|
|
|
@ -200,8 +200,6 @@ struct STag {
|
|||
#if 1 //================================================================================================================================================
|
||||
// Imported since 3.0 and use bitmap to demonstrate None/Null/Norm, while use Null/Norm below 3.0 without of bitmap.
|
||||
#define TD_SUPPORT_BITMAP
|
||||
#define TD_SUPPORT_READ2
|
||||
#define TD_SUPPORT_BACK2 // suppport back compatibility of 2.0
|
||||
|
||||
#define TASSERT(x) ASSERT(x)
|
||||
|
||||
|
|
|
@ -296,13 +296,13 @@ void tFreeSSubmitRsp(SSubmitRsp* pRsp);
|
|||
#define COL_IDX_ON ((int8_t)0x2)
|
||||
#define COL_SET_NULL ((int8_t)0x10)
|
||||
#define COL_SET_VAL ((int8_t)0x20)
|
||||
typedef struct SSchema {
|
||||
struct SSchema {
|
||||
int8_t type;
|
||||
int8_t flags;
|
||||
col_id_t colId;
|
||||
int32_t bytes;
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
} SSchema;
|
||||
};
|
||||
|
||||
#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)))
|
||||
|
@ -648,7 +648,7 @@ typedef struct {
|
|||
};
|
||||
bool output; // TODO remove it later
|
||||
|
||||
int16_t type;
|
||||
int8_t type;
|
||||
int32_t bytes;
|
||||
uint8_t precision;
|
||||
uint8_t scale;
|
||||
|
@ -1364,12 +1364,13 @@ typedef struct {
|
|||
int8_t compressed;
|
||||
int8_t streamBlockType;
|
||||
int32_t compLen;
|
||||
int32_t numOfBlocks;
|
||||
int32_t numOfRows;
|
||||
int32_t numOfCols;
|
||||
int64_t skey;
|
||||
int64_t ekey;
|
||||
int64_t version; // for stream
|
||||
TSKEY watermark;// for stream
|
||||
int64_t version; // for stream
|
||||
TSKEY watermark; // for stream
|
||||
char data[];
|
||||
} SRetrieveTableRsp;
|
||||
|
||||
|
@ -3079,6 +3080,22 @@ typedef struct SDeleteRes {
|
|||
int32_t tEncodeDeleteRes(SEncoder* pCoder, const SDeleteRes* pRes);
|
||||
int32_t tDecodeDeleteRes(SDecoder* pCoder, SDeleteRes* pRes);
|
||||
|
||||
typedef struct {
|
||||
int64_t uid;
|
||||
int64_t ts;
|
||||
} SSingleDeleteReq;
|
||||
|
||||
int32_t tEncodeSSingleDeleteReq(SEncoder* pCoder, const SSingleDeleteReq* pReq);
|
||||
int32_t tDecodeSSingleDeleteReq(SDecoder* pCoder, SSingleDeleteReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
SArray* deleteReqs; // SArray<SSingleDeleteReq>
|
||||
} SBatchDeleteReq;
|
||||
|
||||
int32_t tEncodeSBatchDeleteReq(SEncoder* pCoder, const SBatchDeleteReq* pReq);
|
||||
int32_t tDecodeSBatchDeleteReq(SDecoder* pCoder, SBatchDeleteReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
int32_t msgIdx;
|
||||
int32_t msgType;
|
||||
|
|
|
@ -202,6 +202,7 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_SUBMIT_RSMA, "vnode-submit-rsma", SSubmitReq, SSubmitRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_FETCH_RSMA, "vnode-fetch-rsma", SRSmaFetchMsg, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_DELETE, "delete-data", SVDeleteReq, SVDeleteRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_BATCH_DEL, "batch-delete", SBatchDeleteReq, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_CONFIG, "alter-config", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_REPLICA, "alter-replica", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_ALTER_CONFIRM, "alter-confirm", NULL, NULL)
|
||||
|
|
|
@ -38,7 +38,8 @@ typedef struct {
|
|||
uint16_t type : 2;
|
||||
uint16_t del : 1;
|
||||
uint16_t endian : 1;
|
||||
uint16_t reserve : 12;
|
||||
uint16_t statis : 1; // 0 all normal, 1 has null or none
|
||||
uint16_t reserve : 11;
|
||||
uint16_t sver;
|
||||
};
|
||||
};
|
||||
|
@ -149,6 +150,8 @@ typedef struct {
|
|||
void *pBitmap;
|
||||
void *pOffset;
|
||||
int32_t extendedRowSize;
|
||||
bool hasNone;
|
||||
bool hasNull;
|
||||
} SRowBuilder;
|
||||
|
||||
#define TD_ROW_HEAD_LEN (sizeof(STSRow))
|
||||
|
@ -287,9 +290,13 @@ int32_t tdSRowSetTpInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t flen);
|
|||
int32_t tdSRowSetExtendedInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen,
|
||||
int32_t allNullLen, int32_t boundNullLen);
|
||||
int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf);
|
||||
static FORCE_INLINE void tdSRowEnd(SRowBuilder *pBuilder) {
|
||||
STSRow *pRow = (STSRow *)pBuilder->pBuf;
|
||||
if (pBuilder->hasNull || pBuilder->hasNone) {
|
||||
pRow->statis = 1;
|
||||
}
|
||||
}
|
||||
int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf);
|
||||
int32_t tdSRowInitEx(SRowBuilder *pBuilder, void *pBuf, uint32_t allNullLen, uint32_t boundNullLen, int32_t nCols,
|
||||
int32_t nBoundCols, int32_t flen);
|
||||
void tdSRowReset(SRowBuilder *pBuilder);
|
||||
int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, bool isCopyVarData,
|
||||
int8_t colType, int16_t colIdx, int32_t offset);
|
||||
|
@ -312,21 +319,17 @@ typedef struct {
|
|||
col_id_t kvIdx; // [0, nKvCols)
|
||||
} STSRowIter;
|
||||
|
||||
void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow);
|
||||
void tdSTSRowIterInit(STSRowIter *pIter, STSchema *pSchema);
|
||||
void tdSTSRowIterInit(STSRowIter *pIter, STSchema *pSchema);
|
||||
void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow);
|
||||
bool tdSTSRowIterFetch(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal);
|
||||
bool tdSTSRowIterNext(STSRowIter *pIter, SCellVal *pVal);
|
||||
|
||||
int32_t tdSTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow **ppRow);
|
||||
bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal);
|
||||
bool tdGetTpRowDataOfCol(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal);
|
||||
bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, col_id_t *nIdx, SCellVal *pVal);
|
||||
bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal);
|
||||
bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t flen, uint32_t offset, col_id_t colIdx,
|
||||
SCellVal *pVal);
|
||||
bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, col_id_t colIdx, SCellVal *pVal);
|
||||
void tdSCellValPrint(SCellVal *pVal, int8_t colType);
|
||||
void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_COMMON_ROW_H_*/
|
||||
#endif /*_TD_COMMON_ROW_H_*/
|
|
@ -67,6 +67,7 @@ typedef struct SInputData {
|
|||
} SInputData;
|
||||
|
||||
typedef struct SOutputData {
|
||||
int32_t numOfBlocks;
|
||||
int32_t numOfRows;
|
||||
int32_t numOfCols;
|
||||
int8_t compressed;
|
||||
|
|
|
@ -123,7 +123,8 @@ int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, char* table
|
|||
* @param handle
|
||||
* @return
|
||||
*/
|
||||
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t* useconds);
|
||||
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds);
|
||||
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pBlock, uint64_t* useconds);
|
||||
|
||||
/**
|
||||
* kill the ongoing query and free the query handle and corresponding resources automatically
|
||||
|
|
|
@ -54,10 +54,6 @@ typedef struct SFuncExecFuncs {
|
|||
FExecCombine combine;
|
||||
} SFuncExecFuncs;
|
||||
|
||||
typedef struct SFileBlockInfo {
|
||||
int32_t numBlocksOfStep;
|
||||
} SFileBlockInfo;
|
||||
|
||||
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
|
||||
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
|
@ -171,8 +167,6 @@ typedef struct tExprNode {
|
|||
};
|
||||
} tExprNode;
|
||||
|
||||
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||
|
||||
struct SScalarParam {
|
||||
bool colAlloced;
|
||||
SColumnInfoData *columnData;
|
||||
|
@ -182,14 +176,10 @@ struct SScalarParam {
|
|||
int32_t numOfRows;
|
||||
};
|
||||
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable);
|
||||
|
||||
void resetResultRowEntryResult(SqlFunctionCtx* pCtx, int32_t num);
|
||||
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell);
|
||||
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell);
|
||||
int32_t getNumOfResult(SqlFunctionCtx* pCtx, int32_t num, SSDataBlock* pResBlock);
|
||||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||
|
||||
typedef struct SPoint {
|
||||
int64_t key;
|
||||
|
|
|
@ -380,6 +380,7 @@ typedef struct SAggPhysiNode {
|
|||
SNodeList* pExprs; // these are expression list of group_by_clause and parameter expression of aggregate function
|
||||
SNodeList* pGroupKeys;
|
||||
SNodeList* pAggFuncs;
|
||||
bool mergeDataBlock;
|
||||
} SAggPhysiNode;
|
||||
|
||||
typedef struct SDownstreamSourceNode {
|
||||
|
@ -418,6 +419,7 @@ typedef struct SWinodwPhysiNode {
|
|||
int8_t igExpired;
|
||||
EOrder inputTsOrder;
|
||||
EOrder outputTsOrder;
|
||||
bool mergeDataBlock;
|
||||
} SWinodwPhysiNode;
|
||||
|
||||
typedef struct SIntervalPhysiNode {
|
||||
|
|
|
@ -44,7 +44,7 @@ extern int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict
|
|||
extern int32_t filterConverNcharColumns(SFilterInfo *pFilterInfo, int32_t rows, bool *gotNchar);
|
||||
extern int32_t filterFreeNcharColumns(SFilterInfo *pFilterInfo);
|
||||
extern void filterFreeInfo(SFilterInfo *info);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg **pColsAgg, int32_t numOfCols, int32_t numOfRows);
|
||||
|
||||
/* condition split interface */
|
||||
int32_t filterPartitionCond(SNode **pCondition, SNode **pPrimaryKeyCond, SNode **pTagIndexCond, SNode **pTagCond,
|
||||
|
|
|
@ -118,7 +118,7 @@ typedef struct {
|
|||
int64_t sourceVer;
|
||||
int64_t reqId;
|
||||
|
||||
SArray* blocks; // SArray<SSDataBlock*>
|
||||
SArray* blocks; // SArray<SSDataBlock>
|
||||
} SStreamDataBlock;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -129,6 +129,9 @@ typedef struct SSyncFSM {
|
|||
void (*FpReConfigCb)(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SReConfigCbMeta cbMeta);
|
||||
void (*FpLeaderTransferCb)(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
|
||||
void (*FpBecomeLeaderCb)(struct SSyncFSM* pFsm);
|
||||
void (*FpBecomeFollowerCb)(struct SSyncFSM* pFsm);
|
||||
|
||||
int32_t (*FpGetSnapshot)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot, void* pReaderParam, void** ppReader);
|
||||
int32_t (*FpGetSnapshotInfo)(struct SSyncFSM* pFsm, SSnapshot* pSnapshot);
|
||||
|
||||
|
|
|
@ -284,11 +284,13 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_CONSUMER_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x03EA)
|
||||
#define TSDB_CODE_MND_TOPIC_SUBSCRIBED TAOS_DEF_ERROR_CODE(0, 0x03EB)
|
||||
#define TSDB_CODE_MND_CGROUP_USED TAOS_DEF_ERROR_CODE(0, 0x03EC)
|
||||
#define TSDB_CODE_MND_TOPIC_MUST_BE_DELETED TAOS_DEF_ERROR_CODE(0, 0x03ED)
|
||||
|
||||
// mnode-stream
|
||||
#define TSDB_CODE_MND_STREAM_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03F0)
|
||||
#define TSDB_CODE_MND_STREAM_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03F1)
|
||||
#define TSDB_CODE_MND_INVALID_STREAM_OPTION TAOS_DEF_ERROR_CODE(0, 0x03F2)
|
||||
#define TSDB_CODE_MND_STREAM_MUST_BE_DELETED TAOS_DEF_ERROR_CODE(0, 0x03F3)
|
||||
|
||||
// mnode-sma
|
||||
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
|
||||
|
@ -619,6 +621,7 @@ int32_t* taosGetErrno();
|
|||
|
||||
//tmq
|
||||
#define TSDB_CODE_TMQ_INVALID_MSG TAOS_DEF_ERROR_CODE(0, 0x4000)
|
||||
#define TSDB_CODE_TMQ_CONSUMER_MISMATCH TAOS_DEF_ERROR_CODE(0, 0x4001)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -101,10 +101,6 @@ typedef struct SQueryExecMetric {
|
|||
int64_t rsp; // receive response from server, us
|
||||
} SQueryExecMetric;
|
||||
|
||||
typedef struct SHeartBeatInfo {
|
||||
void* pTimer; // timer, used to send request msg to mnode
|
||||
} SHeartBeatInfo;
|
||||
|
||||
struct SAppInstInfo {
|
||||
int64_t numOfConns;
|
||||
SCorEpSet mgmtEp;
|
||||
|
@ -256,6 +252,8 @@ SRequestObj* execQuery(uint64_t connId, const char* sql, int sqlLen, bool valida
|
|||
TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly);
|
||||
void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly);
|
||||
|
||||
int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols);
|
||||
|
||||
static FORCE_INLINE SReqResultInfo* tmqGetCurResInfo(TAOS_RES* res) {
|
||||
SMqRspObj* msg = (SMqRspObj*)res;
|
||||
return (SReqResultInfo*)&msg->resInfo;
|
||||
|
|
|
@ -611,65 +611,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionIm
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_subscribeImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
jboolean restart, jstring jtopic,
|
||||
jstring jsql, jint jinterval) {
|
||||
jlong sub = 0;
|
||||
TAOS *taos = (TAOS *)con;
|
||||
char *topic = NULL;
|
||||
char *sql = NULL;
|
||||
|
||||
jniGetGlobalMethod(env);
|
||||
jniDebug("jobj:%p, in TSDBJNIConnector_subscribeImp", jobj);
|
||||
|
||||
if (jtopic != NULL) {
|
||||
topic = (char *)(*env)->GetStringUTFChars(env, jtopic, NULL);
|
||||
}
|
||||
if (jsql != NULL) {
|
||||
sql = (char *)(*env)->GetStringUTFChars(env, jsql, NULL);
|
||||
}
|
||||
|
||||
if (topic == NULL || sql == NULL) {
|
||||
jniDebug("jobj:%p, invalid argument: topic or sql is NULL", jobj);
|
||||
return sub;
|
||||
}
|
||||
|
||||
TAOS_SUB *tsub = taos_subscribe(taos, (int)restart, topic, sql, NULL, NULL, jinterval);
|
||||
sub = (jlong)tsub;
|
||||
|
||||
if (sub == 0) {
|
||||
jniDebug("jobj:%p, failed to subscribe: topic:%s", jobj, topic);
|
||||
} else {
|
||||
jniDebug("jobj:%p, successfully subscribe: topic: %s", jobj, topic);
|
||||
}
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jtopic, topic);
|
||||
(*env)->ReleaseStringUTFChars(env, jsql, sql);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEnv *env, jobject jobj, jlong sub) {
|
||||
jniDebug("jobj:%p, in TSDBJNIConnector_consumeImp, sub:%lld", jobj, sub);
|
||||
jniGetGlobalMethod(env);
|
||||
|
||||
TAOS_SUB *tsub = (TAOS_SUB *)sub;
|
||||
TAOS_RES *res = taos_consume(tsub);
|
||||
|
||||
if (res == NULL) {
|
||||
jniError("jobj:%p, tsub:%p, taos_consume returns NULL", jobj, tsub);
|
||||
return 0l;
|
||||
}
|
||||
|
||||
return (jlong)res;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp(JNIEnv *env, jobject jobj, jlong sub,
|
||||
jboolean keepProgress) {
|
||||
TAOS_SUB *tsub = (TAOS_SUB *)sub;
|
||||
taos_unsubscribe(tsub, keepProgress);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp(JNIEnv *env, jobject jobj,
|
||||
jlong con, jbyteArray jsql) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
|
@ -1087,4 +1028,4 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_schemalessInsert
|
|||
return JNI_OUT_OF_MEMORY;
|
||||
}
|
||||
return (jlong)tres;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1571,10 +1571,18 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols) {
|
||||
int32_t cols = *(int32_t*) (p + sizeof(int32_t) * 3);
|
||||
ASSERT(numOfCols == cols);
|
||||
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t)*3 + sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t));
|
||||
}
|
||||
|
||||
static int32_t estimateJsonLen(SReqResultInfo* pResultInfo, int32_t numOfCols, int32_t numOfRows) {
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
|
||||
int32_t len = sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
// version + length + numOfRows + numOfCol + groupId + flag_segment + column_info
|
||||
int32_t len = getVersion1BlockMetaSize(p, numOfCols);
|
||||
int32_t* colLength = (int32_t*)(p + len);
|
||||
len += sizeof(int32_t) * numOfCols;
|
||||
|
||||
|
@ -1642,7 +1650,7 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
char* p1 = pResultInfo->convertJson;
|
||||
|
||||
int32_t totalLen = 0;
|
||||
int32_t len = sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
int32_t len = getVersion1BlockMetaSize(p, numOfCols);
|
||||
memcpy(p1, p, len);
|
||||
|
||||
p += len;
|
||||
|
@ -1739,7 +1747,7 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
pStart1 += colLen1;
|
||||
}
|
||||
|
||||
*(int32_t*)(pResultInfo->convertJson) = totalLen;
|
||||
*(int32_t*)(pResultInfo->convertJson + 4) = totalLen;
|
||||
pResultInfo->pData = pResultInfo->convertJson;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1762,16 +1770,31 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32
|
|||
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
|
||||
// version:
|
||||
int32_t blockVersion = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
int32_t dataLen = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
int32_t rows = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
int32_t cols = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
ASSERT(rows == numOfRows && cols == numOfCols);
|
||||
|
||||
int32_t hasColumnSeg = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
uint64_t groupId = *(uint64_t*)p;
|
||||
p += sizeof(uint64_t);
|
||||
|
||||
// check fields
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
int16_t type = *(int16_t*)p;
|
||||
p += sizeof(int16_t);
|
||||
p += sizeof(int8_t);
|
||||
|
||||
int32_t bytes = *(int32_t*)p;
|
||||
p += sizeof(int32_t);
|
||||
|
|
|
@ -939,21 +939,6 @@ const void *taos_get_raw_block(TAOS_RES *res) {
|
|||
return pRequest->body.resInfo.pData;
|
||||
}
|
||||
|
||||
TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char *topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp,
|
||||
void *param, int interval) {
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||
if (NULL == taos) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
|
|
|
@ -122,6 +122,7 @@ enum {
|
|||
TMQ_CONSUMER_STATUS__INIT = 0,
|
||||
TMQ_CONSUMER_STATUS__READY,
|
||||
TMQ_CONSUMER_STATUS__NO_TOPIC,
|
||||
TMQ_CONSUMER_STATUS__RECOVER,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -134,10 +135,8 @@ typedef struct {
|
|||
// statistics
|
||||
int64_t pollCnt;
|
||||
// offset
|
||||
/*int64_t committedOffset;*/
|
||||
/*int64_t currentOffset;*/
|
||||
STqOffsetVal committedOffsetNew;
|
||||
STqOffsetVal currentOffsetNew;
|
||||
STqOffsetVal committedOffset;
|
||||
STqOffsetVal currentOffset;
|
||||
// connection info
|
||||
int32_t vgId;
|
||||
int32_t vgStatus;
|
||||
|
@ -152,7 +151,6 @@ typedef struct {
|
|||
|
||||
SArray* vgs; // SArray<SMqClientVg>
|
||||
|
||||
int8_t isSchemaAdaptive;
|
||||
SSchemaWrapper schema;
|
||||
} SMqClientTopic;
|
||||
|
||||
|
@ -190,10 +188,9 @@ typedef struct {
|
|||
} SMqPollCbParam;
|
||||
|
||||
typedef struct {
|
||||
tmq_t* tmq;
|
||||
int8_t automatic;
|
||||
int8_t async;
|
||||
/*int8_t freeOffsets;*/
|
||||
tmq_t* tmq;
|
||||
int8_t automatic;
|
||||
int8_t async;
|
||||
int32_t waitingRspNum;
|
||||
int32_t totalRspNum;
|
||||
int32_t rspErr;
|
||||
|
@ -207,7 +204,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
SMqCommitCbParamSet* params;
|
||||
STqOffset* pOffset;
|
||||
} SMqCommitCbParam2;
|
||||
} SMqCommitCbParam;
|
||||
|
||||
tmq_conf_t* tmq_conf_new() {
|
||||
tmq_conf_t* conf = taosMemoryCalloc(1, sizeof(tmq_conf_t));
|
||||
|
@ -215,6 +212,7 @@ tmq_conf_t* tmq_conf_new() {
|
|||
conf->autoCommit = true;
|
||||
conf->autoCommitInterval = 5000;
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__EARLIEAST;
|
||||
conf->hbBgEnable = true;
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
@ -371,8 +369,8 @@ static int32_t tmqMakeTopicVgKey(char* dst, const char* topicName, int32_t vg) {
|
|||
return sprintf(dst, "%s:%d", topicName, vg);
|
||||
}
|
||||
|
||||
int32_t tmqCommitCb2(void* param, SDataBuf* pBuf, int32_t code) {
|
||||
SMqCommitCbParam2* pParam = (SMqCommitCbParam2*)param;
|
||||
int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
|
||||
SMqCommitCbParam* pParam = (SMqCommitCbParam*)param;
|
||||
SMqCommitCbParamSet* pParamSet = (SMqCommitCbParamSet*)pParam->params;
|
||||
// push into array
|
||||
#if 0
|
||||
|
@ -418,7 +416,7 @@ static int32_t tmqSendCommitReq(tmq_t* tmq, SMqClientVg* pVg, SMqClientTopic* pT
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
pOffset->val = pVg->currentOffsetNew;
|
||||
pOffset->val = pVg->currentOffset;
|
||||
|
||||
int32_t groupLen = strlen(tmq->groupId);
|
||||
memcpy(pOffset->subKey, tmq->groupId, groupLen);
|
||||
|
@ -443,7 +441,7 @@ static int32_t tmqSendCommitReq(tmq_t* tmq, SMqClientVg* pVg, SMqClientTopic* pT
|
|||
tEncodeSTqOffset(&encoder, pOffset);
|
||||
|
||||
// build param
|
||||
SMqCommitCbParam2* pParam = taosMemoryCalloc(1, sizeof(SMqCommitCbParam2));
|
||||
SMqCommitCbParam* pParam = taosMemoryCalloc(1, sizeof(SMqCommitCbParam));
|
||||
pParam->params = pParamSet;
|
||||
pParam->pOffset = pOffset;
|
||||
|
||||
|
@ -462,13 +460,13 @@ static int32_t tmqSendCommitReq(tmq_t* tmq, SMqClientVg* pVg, SMqClientTopic* pT
|
|||
pVg->vgId, pOffset->val.version);
|
||||
|
||||
// TODO: put into cb
|
||||
pVg->committedOffsetNew = pVg->currentOffsetNew;
|
||||
pVg->committedOffset = pVg->currentOffset;
|
||||
|
||||
pMsgSendInfo->requestId = generateRequestId();
|
||||
pMsgSendInfo->requestObjRefId = 0;
|
||||
pMsgSendInfo->param = pParam;
|
||||
pMsgSendInfo->paramFreeFp = taosMemoryFree;
|
||||
pMsgSendInfo->fp = tmqCommitCb2;
|
||||
pMsgSendInfo->fp = tmqCommitCb;
|
||||
pMsgSendInfo->msgType = TDMT_VND_MQ_COMMIT_OFFSET;
|
||||
// send msg
|
||||
|
||||
|
@ -504,7 +502,6 @@ int32_t tmqCommitMsgImpl(tmq_t* tmq, const TAOS_RES* msg, int8_t async, tmq_comm
|
|||
pParamSet->tmq = tmq;
|
||||
pParamSet->automatic = 0;
|
||||
pParamSet->async = async;
|
||||
/*pParamSet->freeOffsets = 1;*/
|
||||
pParamSet->userCb = userCb;
|
||||
pParamSet->userParam = userParam;
|
||||
tsem_init(&pParamSet->rspSem, 0, 0);
|
||||
|
@ -518,7 +515,7 @@ int32_t tmqCommitMsgImpl(tmq_t* tmq, const TAOS_RES* msg, int8_t async, tmq_comm
|
|||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
if (pVg->vgId != vgId) continue;
|
||||
|
||||
if (pVg->currentOffsetNew.type > 0 && !tOffsetEqual(&pVg->currentOffsetNew, &pVg->committedOffsetNew)) {
|
||||
if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) {
|
||||
if (tmqSendCommitReq(tmq, pVg, pTopic, pParamSet) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
@ -550,8 +547,8 @@ FAIL:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tmqCommitInner2(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_t async, tmq_commit_cb* userCb,
|
||||
void* userParam) {
|
||||
int32_t tmqCommitInner(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_t async, tmq_commit_cb* userCb,
|
||||
void* userParam) {
|
||||
int32_t code = -1;
|
||||
|
||||
if (msg != NULL) {
|
||||
|
@ -566,7 +563,6 @@ int32_t tmqCommitInner2(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_
|
|||
pParamSet->tmq = tmq;
|
||||
pParamSet->automatic = automatic;
|
||||
pParamSet->async = async;
|
||||
/*pParamSet->freeOffsets = 1;*/
|
||||
pParamSet->userCb = userCb;
|
||||
pParamSet->userParam = userParam;
|
||||
tsem_init(&pParamSet->rspSem, 0, 0);
|
||||
|
@ -583,7 +579,9 @@ int32_t tmqCommitInner2(tmq_t* tmq, const TAOS_RES* msg, int8_t automatic, int8_
|
|||
tscDebug("consumer:%" PRId64 ", begin commit for topic %s, vgId:%d", tmq->consumerId, pTopic->topicName,
|
||||
pVg->vgId);
|
||||
|
||||
if (pVg->currentOffsetNew.type > 0 && !tOffsetEqual(&pVg->currentOffsetNew, &pVg->committedOffsetNew)) {
|
||||
if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) {
|
||||
tscDebug("consumer: %ld, vg:%d, current %ld, committed %ld", tmq->consumerId, pVg->vgId,
|
||||
pVg->currentOffset.version, pVg->committedOffset.version);
|
||||
if (tmqSendCommitReq(tmq, pVg, pTopic, pParamSet) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -699,7 +697,7 @@ int32_t tmqHandleAllDelayedTask(tmq_t* tmq) {
|
|||
tmqAskEp(tmq, true);
|
||||
taosTmrReset(tmqAssignAskEpTask, 1000, tmq, tmqMgmt.timer, &tmq->epTimer);
|
||||
} else if (*pTaskType == TMQ_DELAYED_TASK__COMMIT) {
|
||||
tmqCommitInner2(tmq, NULL, 1, 1, tmq->commitCb, tmq->commitCbUserParam);
|
||||
tmqCommitInner(tmq, NULL, 1, 1, tmq->commitCb, tmq->commitCbUserParam);
|
||||
taosTmrReset(tmqAssignDelayedCommitTask, tmq->autoCommitInterval, tmq, tmqMgmt.timer, &tmq->commitTimer);
|
||||
} else if (*pTaskType == TMQ_DELAYED_TASK__REPORT) {
|
||||
} else {
|
||||
|
@ -888,12 +886,6 @@ FAIL:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, int32_t async) {
|
||||
return tmqCommitInner2(tmq, offsets, 0, async, tmq->commitCb, tmq->commitCbUserParam);
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||
const SArray* container = &topic_list->container;
|
||||
int32_t sz = taosArrayGetSize(container);
|
||||
|
@ -967,7 +959,11 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
code = param.rspErr;
|
||||
if (code != 0) goto FAIL;
|
||||
|
||||
int32_t retryCnt = 0;
|
||||
while (TSDB_CODE_MND_CONSUMER_NOT_READY == tmqAskEp(tmq, false)) {
|
||||
if (retryCnt++ > 10) {
|
||||
goto FAIL;
|
||||
}
|
||||
tscDebug("consumer not ready, retry");
|
||||
taosMsleep(500);
|
||||
}
|
||||
|
@ -1006,8 +1002,12 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
int32_t epoch = pParam->epoch;
|
||||
taosMemoryFree(pParam);
|
||||
if (code != 0) {
|
||||
tscWarn("msg discard from vgId:%d, epoch %d, code:%x", vgId, epoch, code);
|
||||
if (pMsg->pData) taosMemoryFreeClear(pMsg->pData);
|
||||
tscWarn("msg discard from vgId:%d, epoch %d, since %s", vgId, epoch, terrstr());
|
||||
if (pMsg->pData) taosMemoryFree(pMsg->pData);
|
||||
if (code == TSDB_CODE_TMQ_CONSUMER_MISMATCH) {
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__RECOVER);
|
||||
goto CREATE_MSG_FAIL;
|
||||
}
|
||||
if (code == TSDB_CODE_TQ_NO_COMMITTED_OFFSET) {
|
||||
SMqPollRspWrapper* pRspWrapper = taosAllocateQitem(sizeof(SMqPollRspWrapper), DEF_QITEM);
|
||||
if (pRspWrapper == NULL) {
|
||||
|
@ -1083,7 +1083,7 @@ CREATE_MSG_FAIL:
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool tmqUpdateEp2(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
||||
bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
||||
bool set = false;
|
||||
|
||||
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
||||
|
@ -1112,10 +1112,10 @@ bool tmqUpdateEp2(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
|||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
||||
sprintf(vgKey, "%s:%d", pTopicCur->topicName, pVgCur->vgId);
|
||||
char buf[80];
|
||||
tFormatOffset(buf, 80, &pVgCur->currentOffsetNew);
|
||||
tFormatOffset(buf, 80, &pVgCur->currentOffset);
|
||||
tscDebug("consumer:%" PRId64 ", epoch %d vgId:%d vgKey is %s, offset is %s", tmq->consumerId, epoch,
|
||||
pVgCur->vgId, vgKey, buf);
|
||||
taosHashPut(pHash, vgKey, strlen(vgKey), &pVgCur->currentOffsetNew, sizeof(STqOffsetVal));
|
||||
taosHashPut(pHash, vgKey, strlen(vgKey), &pVgCur->currentOffset, sizeof(STqOffsetVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1142,7 +1142,7 @@ bool tmqUpdateEp2(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
|||
|
||||
SMqClientVg clientVg = {
|
||||
.pollCnt = 0,
|
||||
.currentOffsetNew = offsetNew,
|
||||
.currentOffset = offsetNew,
|
||||
.vgId = pVgEp->vgId,
|
||||
.epSet = pVgEp->epSet,
|
||||
.vgStatus = TMQ_VG_STATUS__IDLE,
|
||||
|
@ -1166,93 +1166,6 @@ bool tmqUpdateEp2(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
|||
return set;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
||||
/*printf("call update ep %d\n", epoch);*/
|
||||
bool set = false;
|
||||
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
||||
char vgKey[TSDB_TOPIC_FNAME_LEN + 22];
|
||||
tscDebug("consumer:%" PRId64 ", update ep epoch %d to epoch %d, topic num: %d", tmq->consumerId, tmq->epoch, epoch,
|
||||
topicNumGet);
|
||||
SArray* newTopics = taosArrayInit(topicNumGet, sizeof(SMqClientTopic));
|
||||
if (newTopics == NULL) {
|
||||
return false;
|
||||
}
|
||||
SHashObj* pHash = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
|
||||
if (pHash == NULL) {
|
||||
taosArrayDestroy(newTopics);
|
||||
return false;
|
||||
}
|
||||
|
||||
// find topic, build hash
|
||||
for (int32_t i = 0; i < topicNumGet; i++) {
|
||||
SMqClientTopic topic = {0};
|
||||
SMqSubTopicEp* pTopicEp = taosArrayGet(pRsp->topics, i);
|
||||
topic.schema = pTopicEp->schema;
|
||||
taosHashClear(pHash);
|
||||
topic.topicName = strdup(pTopicEp->topic);
|
||||
tstrncpy(topic.db, pTopicEp->db, TSDB_DB_FNAME_LEN);
|
||||
|
||||
tscDebug("consumer:%" PRId64 ", update topic: %s", tmq->consumerId, topic.topicName);
|
||||
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
|
||||
for (int32_t j = 0; j < topicNumCur; j++) {
|
||||
// find old topic
|
||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, j);
|
||||
if (pTopicCur->vgs && strcmp(pTopicCur->topicName, pTopicEp->topic) == 0) {
|
||||
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
||||
tscDebug("consumer:%" PRId64 ", new vg num: %d", tmq->consumerId, vgNumCur);
|
||||
if (vgNumCur == 0) break;
|
||||
for (int32_t k = 0; k < vgNumCur; k++) {
|
||||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, k);
|
||||
sprintf(vgKey, "%s:%d", topic.topicName, pVgCur->vgId);
|
||||
tscDebug("consumer:%" PRId64 ", epoch %d vgId:%d build %s", tmq->consumerId, epoch, pVgCur->vgId, vgKey);
|
||||
taosHashPut(pHash, vgKey, strlen(vgKey), &pVgCur->currentOffset, sizeof(int64_t));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t vgNumGet = taosArrayGetSize(pTopicEp->vgs);
|
||||
topic.vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
|
||||
for (int32_t j = 0; j < vgNumGet; j++) {
|
||||
SMqSubVgEp* pVgEp = taosArrayGet(pTopicEp->vgs, j);
|
||||
sprintf(vgKey, "%s:%d", topic.topicName, pVgEp->vgId);
|
||||
int64_t* pOffset = taosHashGet(pHash, vgKey, strlen(vgKey));
|
||||
int64_t offset = pVgEp->offset;
|
||||
tscDebug("consumer:%" PRId64 ", (epoch %d) original offset of vgId:%d is %" PRId64, tmq->consumerId, epoch, pVgEp->vgId, offset);
|
||||
if (pOffset != NULL) {
|
||||
offset = *pOffset;
|
||||
tscDebug("consumer:%" PRId64 ", (epoch %d) receive offset of vgId:%d, full key is %s", tmq->consumerId, epoch, pVgEp->vgId,
|
||||
vgKey);
|
||||
}
|
||||
tscDebug("consumer:%" PRId64 ", (epoch %d) offset of vgId:%d updated to %" PRId64, tmq->consumerId, epoch, pVgEp->vgId, offset);
|
||||
SMqClientVg clientVg = {
|
||||
.pollCnt = 0,
|
||||
.currentOffset = offset,
|
||||
.vgId = pVgEp->vgId,
|
||||
.epSet = pVgEp->epSet,
|
||||
.vgStatus = TMQ_VG_STATUS__IDLE,
|
||||
.vgSkipCnt = 0,
|
||||
};
|
||||
taosArrayPush(topic.vgs, &clientVg);
|
||||
set = true;
|
||||
}
|
||||
taosArrayPush(newTopics, &topic);
|
||||
}
|
||||
if (tmq->clientTopics) taosArrayDestroy(tmq->clientTopics);
|
||||
taosHashCleanup(pHash);
|
||||
tmq->clientTopics = newTopics;
|
||||
|
||||
if (taosArrayGetSize(tmq->clientTopics) == 0)
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__NO_TOPIC);
|
||||
else
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__READY);
|
||||
|
||||
atomic_store_32(&tmq->epoch, epoch);
|
||||
return set;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t tmqAskEpCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
SMqAskEpCbParam* pParam = (SMqAskEpCbParam*)param;
|
||||
tmq_t* tmq = pParam->tmq;
|
||||
|
@ -1278,7 +1191,7 @@ int32_t tmqAskEpCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
tDecodeSMqAskEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &rsp);
|
||||
/*printf("rsp epoch %" PRId64 " sz %" PRId64 "\n", rsp.epoch, rsp.topics->size);*/
|
||||
/*printf("tmq epoch %" PRId64 " sz %" PRId64 "\n", tmq->epoch, tmq->clientTopics->size);*/
|
||||
tmqUpdateEp2(tmq, head->epoch, &rsp);
|
||||
tmqUpdateEp(tmq, head->epoch, &rsp);
|
||||
tDeleteSMqAskEpRsp(&rsp);
|
||||
} else {
|
||||
SMqAskEpRspWrapper* pWrapper = taosAllocateQitem(sizeof(SMqAskEpRspWrapper), DEF_QITEM);
|
||||
|
@ -1401,17 +1314,6 @@ int32_t tmq_seek(tmq_t* tmq, const tmq_topic_vgroup_t* offset) {
|
|||
#endif
|
||||
|
||||
SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t timeout, SMqClientTopic* pTopic, SMqClientVg* pVg) {
|
||||
/*int64_t reqOffset;*/
|
||||
/*if (pVg->currentOffset >= 0) {*/
|
||||
/*reqOffset = pVg->currentOffset;*/
|
||||
/*} else {*/
|
||||
/*if (tmq->resetOffsetCfg == TMQ_CONF__RESET_OFFSET__NONE) {*/
|
||||
/*tscError("unable to poll since no committed offset but reset offset is set to none");*/
|
||||
/*return NULL;*/
|
||||
/*}*/
|
||||
/*reqOffset = tmq->resetOffsetCfg;*/
|
||||
/*}*/
|
||||
|
||||
SMqPollReq* pReq = taosMemoryCalloc(1, sizeof(SMqPollReq));
|
||||
if (pReq == NULL) {
|
||||
return NULL;
|
||||
|
@ -1430,7 +1332,7 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t timeout, SMqClientTopic*
|
|||
pReq->consumerId = tmq->consumerId;
|
||||
pReq->epoch = tmq->epoch;
|
||||
/*pReq->currentOffset = reqOffset;*/
|
||||
pReq->reqOffset = pVg->currentOffsetNew;
|
||||
pReq->reqOffset = pVg->currentOffset;
|
||||
pReq->reqId = generateRequestId();
|
||||
|
||||
pReq->useSnapshot = tmq->useSnapshot;
|
||||
|
@ -1534,7 +1436,7 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
|
|||
/*printf("send poll\n");*/
|
||||
|
||||
char offsetFormatBuf[80];
|
||||
tFormatOffset(offsetFormatBuf, 80, &pVg->currentOffsetNew);
|
||||
tFormatOffset(offsetFormatBuf, 80, &pVg->currentOffset);
|
||||
tscDebug("consumer:%" PRId64 ", send poll to %s vgId:%d, epoch %d, req offset:%s, reqId:%" PRIu64,
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, tmq->epoch, offsetFormatBuf, pReq->reqId);
|
||||
/*printf("send vgId:%d %" PRId64 "\n", pVg->vgId, pVg->currentOffset);*/
|
||||
|
@ -1552,7 +1454,7 @@ int32_t tmqHandleNoPollRsp(tmq_t* tmq, SMqRspWrapper* rspWrapper, bool* pReset)
|
|||
if (rspWrapper->epoch > atomic_load_32(&tmq->epoch)) {
|
||||
SMqAskEpRspWrapper* pEpRspWrapper = (SMqAskEpRspWrapper*)rspWrapper;
|
||||
SMqAskEpRsp* rspMsg = &pEpRspWrapper->msg;
|
||||
tmqUpdateEp2(tmq, rspWrapper->epoch, rspMsg);
|
||||
tmqUpdateEp(tmq, rspWrapper->epoch, rspMsg);
|
||||
/*tmqClearUnhandleMsg(tmq);*/
|
||||
*pReset = true;
|
||||
} else {
|
||||
|
@ -1586,7 +1488,7 @@ void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
/*printf("vgId:%d, offset %" PRId64 " up to %" PRId64 "\n", pVg->vgId, pVg->currentOffset,
|
||||
* rspMsg->msg.rspOffset);*/
|
||||
pVg->currentOffsetNew = pollRspWrapper->dataRsp.rspOffset;
|
||||
pVg->currentOffset = pollRspWrapper->dataRsp.rspOffset;
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
if (pollRspWrapper->dataRsp.blockNum == 0) {
|
||||
taosFreeQitem(pollRspWrapper);
|
||||
|
@ -1609,8 +1511,8 @@ void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
/*printf("vgId:%d, offset %" PRId64 " up to %" PRId64 "\n", pVg->vgId, pVg->currentOffset,
|
||||
* rspMsg->msg.rspOffset);*/
|
||||
pVg->currentOffsetNew.version = pollRspWrapper->metaRsp.rspOffset;
|
||||
pVg->currentOffsetNew.type = TMQ_OFFSET__LOG;
|
||||
pVg->currentOffset.version = pollRspWrapper->metaRsp.rspOffset;
|
||||
pVg->currentOffset.type = TMQ_OFFSET__LOG;
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
// build rsp
|
||||
SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
|
||||
|
@ -1653,6 +1555,17 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__RECOVER) {
|
||||
int32_t retryCnt = 0;
|
||||
while (TSDB_CODE_MND_CONSUMER_NOT_READY == tmqAskEp(tmq, false)) {
|
||||
if (retryCnt++ > 10) {
|
||||
return NULL;
|
||||
}
|
||||
tscDebug("consumer not ready, retry");
|
||||
taosMsleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
tmqHandleAllDelayedTask(tmq);
|
||||
if (tmqPollImpl(tmq, timeout) < 0) return NULL;
|
||||
|
@ -2947,7 +2860,7 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname)
|
|||
tdSRowSetTpInfo(&rb, numOfCols, fLen);
|
||||
int32_t dataLen = 0;
|
||||
|
||||
char* pStart = pData + sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
char* pStart = pData + getVersion1BlockMetaSize(pData, numOfCols);
|
||||
int32_t* colLength = (int32_t*)pStart;
|
||||
pStart += sizeof(int32_t) * numOfCols;
|
||||
|
||||
|
@ -2977,6 +2890,7 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname)
|
|||
char* data = pCol[k].pData + pCol[k].offset[j];
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, data, true, offset, k);
|
||||
} else {
|
||||
|
||||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NULL, NULL, false, offset, k);
|
||||
}
|
||||
} else {
|
||||
|
@ -2990,6 +2904,7 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname)
|
|||
|
||||
offset += TYPE_BYTES[pColumn->type];
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
int32_t rowLen = TD_ROW_LEN(rowData);
|
||||
rowData = POINTER_SHIFT(rowData, rowLen);
|
||||
dataLen += rowLen;
|
||||
|
@ -3220,6 +3135,7 @@ static int32_t tmqWriteRaw(TAOS* taos, void* data, int32_t dataLen) {
|
|||
}
|
||||
offset += TYPE_BYTES[pColumn->type];
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
int32_t rowLen = TD_ROW_LEN(rowData);
|
||||
rowData = POINTER_SHIFT(rowData, rowLen);
|
||||
dataLen += rowLen;
|
||||
|
@ -3381,10 +3297,10 @@ int32_t tmq_write_raw(TAOS* taos, tmq_raw_data raw) {
|
|||
|
||||
void tmq_commit_async(tmq_t* tmq, const TAOS_RES* msg, tmq_commit_cb* cb, void* param) {
|
||||
//
|
||||
tmqCommitInner2(tmq, msg, 0, 1, cb, param);
|
||||
tmqCommitInner(tmq, msg, 0, 1, cb, param);
|
||||
}
|
||||
|
||||
int32_t tmq_commit_sync(tmq_t* tmq, const TAOS_RES* msg) {
|
||||
//
|
||||
return tmqCommitInner2(tmq, msg, 0, 0, NULL, NULL);
|
||||
return tmqCommitInner(tmq, msg, 0, 0, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ TEST(testCase, driverInit_Test) {
|
|||
}
|
||||
|
||||
TEST(testCase, connect_Test) {
|
||||
taos_options(TSDB_OPTION_CONFIGDIR, "/home/lisa/Documents/workspace/tdengine/sim/dnode1/cfg");
|
||||
taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg");
|
||||
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
if (pConn == NULL) {
|
||||
|
@ -670,54 +670,56 @@ TEST(testCase, projection_query_tables) {
|
|||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT_NE(pConn, nullptr);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
// TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "use abc1");
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "use abc1");
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create stable st1 (ts timestamp, k int) tags(a int)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create stable st2 (ts timestamp, k int) tags(a int)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create table tu using st1 tags(1)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
for(int32_t i = 0; i < 1; ++i) {
|
||||
printf("create table :%d\n", i);
|
||||
createNewTable(pConn, i);
|
||||
}
|
||||
|
||||
pRes = taos_query(pConn, "select * from tu");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to select from table, reason:%s\n", taos_errstr(pRes));
|
||||
taos_free_result(pRes);
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
|
||||
TAOS_ROW pRow = NULL;
|
||||
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
int32_t numOfFields = taos_num_fields(pRes);
|
||||
|
||||
char str[512] = {0};
|
||||
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
printf("%s\n", str);
|
||||
}
|
||||
pRes = taos_query(pConn, "explain verbose true select _wstart,count(*),a from st1 partition by a interval(1s)");
|
||||
printResult(pRes);
|
||||
// pRes = taos_query(pConn, "create stable st1 (ts timestamp, k int) tags(a int)");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create stable st2 (ts timestamp, k int) tags(a int)");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// pRes = taos_query(pConn, "create table tu using st1 tags(1)");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to create table tu, reason:%s\n", taos_errstr(pRes));
|
||||
// }
|
||||
// taos_free_result(pRes);
|
||||
//
|
||||
// for(int32_t i = 0; i < 1; ++i) {
|
||||
// printf("create table :%d\n", i);
|
||||
// createNewTable(pConn, i);
|
||||
// }
|
||||
//
|
||||
// pRes = taos_query(pConn, "select * from tu");
|
||||
// if (taos_errno(pRes) != 0) {
|
||||
// printf("failed to select from table, reason:%s\n", taos_errstr(pRes));
|
||||
// taos_free_result(pRes);
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
//
|
||||
// TAOS_ROW pRow = NULL;
|
||||
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
// int32_t numOfFields = taos_num_fields(pRes);
|
||||
//
|
||||
// char str[512] = {0};
|
||||
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
// printf("%s\n", str);
|
||||
// }
|
||||
|
||||
taos_free_result(pRes);
|
||||
taos_close(pConn);
|
||||
|
|
|
@ -284,8 +284,7 @@ static const SSysDbTableSchema consumerSchema[] = {
|
|||
{.name = "client_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "status", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "topics", .bytes = TSDB_TOPIC_FNAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "pid", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "end_point", .bytes = TSDB_EP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
/*{.name = "end_point", .bytes = TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},*/
|
||||
{.name = "up_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
{.name = "subscribe_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
{.name = "rebalance_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
|
|
|
@ -676,9 +676,9 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
|
|||
* @return
|
||||
*/
|
||||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
|
||||
// | total rows/total length | block group id | column schema | each column length |
|
||||
return sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t)) +
|
||||
numOfCols * sizeof(int32_t);
|
||||
// | version | total length | total rows | total columns | flag seg| block group id | column schema | each column length |
|
||||
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(uint64_t) +
|
||||
numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
}
|
||||
|
||||
double blockDataGetSerialRowSize(const SSDataBlock* pBlock) {
|
||||
|
@ -1329,10 +1329,6 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, i);
|
||||
SColumnInfoData* pSrc = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||
if (pSrc->pData == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
colDataAssign(pDst, pSrc, pDataBlock->info.rows, &pDataBlock->info);
|
||||
}
|
||||
|
||||
|
@ -1581,7 +1577,7 @@ int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
|
|||
for (int32_t i = 0; i < sz; i++) {
|
||||
SColumnInfoData* pColData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
|
||||
tlen += taosEncodeFixedI16(buf, pColData->info.colId);
|
||||
tlen += taosEncodeFixedI16(buf, pColData->info.type);
|
||||
tlen += taosEncodeFixedI8(buf, pColData->info.type);
|
||||
tlen += taosEncodeFixedI32(buf, pColData->info.bytes);
|
||||
tlen += taosEncodeFixedBool(buf, pColData->hasNull);
|
||||
|
||||
|
@ -1613,7 +1609,7 @@ void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock) {
|
|||
for (int32_t i = 0; i < sz; i++) {
|
||||
SColumnInfoData data = {0};
|
||||
buf = taosDecodeFixedI16(buf, &data.info.colId);
|
||||
buf = taosDecodeFixedI16(buf, &data.info.type);
|
||||
buf = taosDecodeFixedI8(buf, &data.info.type);
|
||||
buf = taosDecodeFixedI32(buf, &data.info.bytes);
|
||||
buf = taosDecodeFixedBool(buf, &data.hasNull);
|
||||
|
||||
|
@ -2001,6 +1997,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataB
|
|||
}
|
||||
offset += TYPE_BYTES[pCol->type]; // sum/avg would convert to int64_t/uint64_t/double during aggregation
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
dataLen += TD_ROW_LEN(rb.pBuf);
|
||||
#ifdef TD_DEBUG_PRINT_ROW
|
||||
tdSRowPrint(rb.pBuf, pTSchema, __func__);
|
||||
|
@ -2070,17 +2067,36 @@ char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId) {
|
|||
|
||||
void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols, int8_t needCompress) {
|
||||
// todo extract method
|
||||
int32_t* version = (int32_t*)data;
|
||||
*version = 1;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
int32_t* actualLen = (int32_t*)data;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
int32_t* rows = (int32_t*)data;
|
||||
*rows = pBlock->info.rows;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
int32_t* cols = (int32_t*)data;
|
||||
*cols = numOfCols;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
// flag segment.
|
||||
// the inital bit is for column info
|
||||
int32_t* flagSegment = (int32_t*)data;
|
||||
*flagSegment = (1<<31);
|
||||
|
||||
data += sizeof(int32_t);
|
||||
|
||||
uint64_t* groupId = (uint64_t*)data;
|
||||
data += sizeof(uint64_t);
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
|
||||
*((int16_t*)data) = pColInfoData->info.type;
|
||||
data += sizeof(int16_t);
|
||||
*((int8_t*)data) = pColInfoData->info.type;
|
||||
data += sizeof(int8_t);
|
||||
|
||||
*((int32_t*)data) = pColInfoData->info.bytes;
|
||||
data += sizeof(int32_t);
|
||||
|
@ -2126,12 +2142,31 @@ void blockEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_
|
|||
*groupId = pBlock->info.groupId;
|
||||
}
|
||||
|
||||
const char* blockDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData) {
|
||||
const char* blockDecode(SSDataBlock* pBlock, const char* pData) {
|
||||
const char* pStart = pData;
|
||||
|
||||
int32_t version = *(int32_t*) pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
ASSERT(version == 1);
|
||||
|
||||
// total length sizeof(int32_t)
|
||||
int32_t dataLen = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// total rows sizeof(int32_t)
|
||||
int32_t numOfRows = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// total columns sizeof(int32_t)
|
||||
int32_t numOfCols = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// has column info segment
|
||||
int32_t flagSeg = *(int32_t*)pStart;
|
||||
int32_t hasColumnInfo = (flagSeg >> 31);
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// group id sizeof(uint64_t)
|
||||
pBlock->info.groupId = *(uint64_t*)pStart;
|
||||
pStart += sizeof(uint64_t);
|
||||
|
||||
|
@ -2143,7 +2178,7 @@ const char* blockDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRow
|
|||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
pColInfoData->info.type = *(int16_t*)pStart;
|
||||
pStart += sizeof(int16_t);
|
||||
pStart += sizeof(int8_t);
|
||||
|
||||
pColInfoData->info.bytes = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
|
|
|
@ -305,7 +305,7 @@ static int32_t tDeserializeSClientHbReq(SDecoder *pDecoder, SClientHbReq *pReq)
|
|||
taosArrayPush(desc.subDesc, &sDesc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ASSERT(desc.subPlanNum == taosArrayGetSize(desc.subDesc));
|
||||
|
||||
taosArrayPush(pReq->query->queryDesc, &desc);
|
||||
|
@ -5770,3 +5770,40 @@ int32_t tDecodeSMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSSingleDeleteReq(SEncoder *pEncoder, const SSingleDeleteReq *pReq) {
|
||||
if (tEncodeI64(pEncoder, pReq->uid) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pReq->ts) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSSingleDeleteReq(SDecoder *pDecoder, SSingleDeleteReq *pReq) {
|
||||
if (tDecodeI64(pDecoder, &pReq->uid) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pReq->ts) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSBatchDeleteReq(SEncoder *pEncoder, const SBatchDeleteReq *pReq) {
|
||||
if (tEncodeI64(pEncoder, pReq->suid) < 0) return -1;
|
||||
int32_t sz = taosArrayGetSize(pReq->deleteReqs);
|
||||
if (tEncodeI32(pEncoder, sz) < 0) return -1;
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSingleDeleteReq *pOneReq = taosArrayGet(pReq->deleteReqs, i);
|
||||
if (tEncodeSSingleDeleteReq(pEncoder, pOneReq) < 0) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSBatchDeleteReq(SDecoder *pDecoder, SBatchDeleteReq *pReq) {
|
||||
if (tDecodeI64(pDecoder, &pReq->suid) < 0) return -1;
|
||||
int32_t sz;
|
||||
if (tDecodeI32(pDecoder, &sz) < 0) return -1;
|
||||
pReq->deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
if (pReq->deleteReqs == NULL) return -1;
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSingleDeleteReq deleteReq;
|
||||
if (tDecodeSSingleDeleteReq(pDecoder, &deleteReq) < 0) return -1;
|
||||
taosArrayPush(pReq->deleteReqs, &deleteReq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,13 @@ const uint8_t tdVTypeByte[2][3] = {{
|
|||
};
|
||||
|
||||
// declaration
|
||||
static uint8_t tdGetBitmapByte(uint8_t byte);
|
||||
static int32_t tdCompareColId(const void *arg1, const void *arg2);
|
||||
static FORCE_INLINE int32_t compareKvRowColId(const void *key1, const void *key2);
|
||||
static uint8_t tdGetBitmapByte(uint8_t byte);
|
||||
static bool tdSTSRowIterGetTpVal(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal);
|
||||
static bool tdSTSRowIterGetKvVal(STSRowIter *pIter, col_id_t colId, col_id_t *nIdx, SCellVal *pVal);
|
||||
static bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t flen, uint32_t offset,
|
||||
col_id_t colIdx, SCellVal *pVal);
|
||||
static bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, col_id_t colIdx, SCellVal *pVal);
|
||||
static void tdSCellValPrint(SCellVal *pVal, int8_t colType);
|
||||
|
||||
// implementation
|
||||
/**
|
||||
|
@ -330,14 +334,14 @@ void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) {
|
|||
tdSTSRowIterInit(&iter, pSchema);
|
||||
tdSTSRowIterReset(&iter, row);
|
||||
printf("%s >>>type:%d,sver:%d ", tag, (int32_t)TD_ROW_TYPE(row), (int32_t)TD_ROW_SVER(row));
|
||||
for (int i = 0; i < pSchema->numOfCols; ++i) {
|
||||
STColumn *stCol = pSchema->columns + i;
|
||||
SCellVal sVal = {255, NULL};
|
||||
if (!tdSTSRowIterNext(&iter, stCol->colId, stCol->type, &sVal)) {
|
||||
STColumn *cols = (STColumn *)&iter.pSchema->columns;
|
||||
while (true) {
|
||||
SCellVal sVal = {.valType = 255, NULL};
|
||||
if (!tdSTSRowIterNext(&iter, &sVal)) {
|
||||
break;
|
||||
}
|
||||
ASSERT(sVal.valType == 0 || sVal.valType == 1 || sVal.valType == 2);
|
||||
tdSCellValPrint(&sVal, stCol->type);
|
||||
tdSCellValPrint(&sVal, cols[iter.colIdx - 1].type);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -420,6 +424,16 @@ void tdSCellValPrint(SCellVal *pVal, int8_t colType) {
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t compareKvRowColId(const void *key1, const void *key2) {
|
||||
if (*(col_id_t *)key1 > ((SKvRowIdx *)key2)->colId) {
|
||||
return 1;
|
||||
} else if (*(col_id_t *)key1 < ((SKvRowIdx *)key2)->colId) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, col_id_t colIdx, SCellVal *pVal) {
|
||||
if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
tdRowSetVal(pVal, TD_VTYPE_NORM, TD_ROW_KEY_ADDR(pRow));
|
||||
|
@ -456,7 +470,7 @@ bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t fl
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) {
|
||||
bool tdSTSRowIterFetch(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) {
|
||||
if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
pVal->val = &pIter->pRow->ts;
|
||||
pVal->valType = TD_VTYPE_NORM;
|
||||
|
@ -477,10 +491,10 @@ bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCe
|
|||
return false;
|
||||
}
|
||||
}
|
||||
tdGetTpRowDataOfCol(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal);
|
||||
tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal);
|
||||
++pIter->colIdx;
|
||||
} else if (TD_IS_KV_ROW(pIter->pRow)) {
|
||||
return tdGetKvRowValOfColEx(pIter, colId, colType, &pIter->kvIdx, pVal);
|
||||
return tdSTSRowIterGetKvVal(pIter, colId, &pIter->kvIdx, pVal);
|
||||
} else {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
|
@ -489,13 +503,68 @@ bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCe
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, col_id_t *nIdx, SCellVal *pVal) {
|
||||
bool tdSTSRowIterNext(STSRowIter *pIter, SCellVal *pVal) {
|
||||
if (pIter->colIdx >= pIter->pSchema->numOfCols) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STColumn *pCol = &pIter->pSchema->columns[pIter->colIdx];
|
||||
|
||||
if (pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
pVal->val = &pIter->pRow->ts;
|
||||
pVal->valType = TD_VTYPE_NORM;
|
||||
++pIter->colIdx;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TD_IS_TP_ROW(pIter->pRow)) {
|
||||
tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal);
|
||||
} else if (TD_IS_KV_ROW(pIter->pRow)) {
|
||||
tdSTSRowIterGetKvVal(pIter, pCol->colId, &pIter->kvIdx, pVal);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
++pIter->colIdx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdSTSRowIterGetTpVal(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal) {
|
||||
STSRow *pRow = pIter->pRow;
|
||||
if (pRow->statis == 0) {
|
||||
pVal->valType = TD_VTYPE_NORM;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
pVal->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (tdGetBitmapValType(pIter->pBitmap, pIter->colIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (pVal->valType == TD_VTYPE_NORM) {
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
pVal->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdSTSRowIterGetKvVal(STSRowIter *pIter, col_id_t colId, col_id_t *nIdx, SCellVal *pVal) {
|
||||
STSRow *pRow = pIter->pRow;
|
||||
SKvRowIdx *pKvIdx = NULL;
|
||||
bool colFound = false;
|
||||
col_id_t kvNCols = tdRowGetNCols(pRow) - 1;
|
||||
void *pColIdx = TD_ROW_COL_IDX(pRow);
|
||||
while (*nIdx < kvNCols) {
|
||||
pKvIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(pRow), *nIdx * sizeof(SKvRowIdx));
|
||||
pKvIdx = (SKvRowIdx *)POINTER_SHIFT(pColIdx, *nIdx * sizeof(SKvRowIdx));
|
||||
if (pKvIdx->colId == colId) {
|
||||
++(*nIdx);
|
||||
pVal->val = POINTER_SHIFT(pRow, pKvIdx->offset);
|
||||
|
@ -518,48 +587,13 @@ bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
int16_t colIdx = -1;
|
||||
if (pKvIdx) colIdx = POINTER_DISTANCE(pKvIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx);
|
||||
if (tdGetBitmapValType(pIter->pBitmap, colIdx, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
if (tdGetBitmapValType(pIter->pBitmap, pIter->kvIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
}
|
||||
#else
|
||||
pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdGetTpRowDataOfCol(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal) {
|
||||
STSRow *pRow = pIter->pRow;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
pVal->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
if (tdGetBitmapValType(pIter->pBitmap, pIter->colIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
pVal->valType = TD_VTYPE_NONE;
|
||||
}
|
||||
#else
|
||||
pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t compareKvRowColId(const void *key1, const void *key2) {
|
||||
if (*(col_id_t *)key1 > ((SKvRowIdx *)key2)->colId) {
|
||||
return 1;
|
||||
} else if (*(col_id_t *)key1 < ((SKvRowIdx *)key2)->colId) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tdSTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow **ppRow) {
|
||||
STColumn *pTColumn;
|
||||
SColVal *pColVal;
|
||||
|
@ -625,7 +659,7 @@ int32_t tdSTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow **ppRow) {
|
|||
if (maxVarDataLen > 0) {
|
||||
varBuf = taosMemoryMalloc(maxVarDataLen);
|
||||
if (!varBuf) {
|
||||
if(isAlloc) {
|
||||
if (isAlloc) {
|
||||
taosMemoryFreeClear(*ppRow);
|
||||
}
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -666,12 +700,26 @@ int32_t tdSTSRowNew(SArray *pArray, STSchema *pTSchema, STSRow **ppRow) {
|
|||
|
||||
++iColVal;
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
|
||||
taosMemoryFreeClear(varBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tdCompareColId(const void *arg1, const void *arg2) {
|
||||
int32_t colId = *(int32_t *)arg1;
|
||||
STColumn *pCol = (STColumn *)arg2;
|
||||
|
||||
if (colId < pCol->colId) {
|
||||
return -1;
|
||||
} else if (colId == pCol->colId) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) {
|
||||
if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
pVal->val = &pIter->pRow->ts;
|
||||
|
@ -711,19 +759,6 @@ bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCell
|
|||
return true;
|
||||
}
|
||||
|
||||
static int32_t tdCompareColId(const void *arg1, const void *arg2) {
|
||||
int32_t colId = *(int32_t *)arg1;
|
||||
STColumn *pCol = (STColumn *)arg2;
|
||||
|
||||
if (colId < pCol->colId) {
|
||||
return -1;
|
||||
} else if (colId == pCol->colId) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tdGetBitmapValTypeII(const void *pBitmap, int16_t colIdx, TDRowValT *pValType) {
|
||||
if (!pBitmap || colIdx < 0) {
|
||||
TASSERT(0);
|
||||
|
@ -880,26 +915,29 @@ int32_t tdGetKvRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int32_
|
|||
|
||||
int32_t tdGetTpRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int8_t colType, int32_t offset,
|
||||
int16_t colIdx) {
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
if (pRow->statis == 0) {
|
||||
output->valType = TD_VTYPE_NORM;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (tdGetBitmapValType(pBitmap, colIdx, &output->valType, 0) != TSDB_CODE_SUCCESS) {
|
||||
output->valType = TD_VTYPE_NONE;
|
||||
return terrno;
|
||||
}
|
||||
if (tdValTypeIsNorm(output->valType)) {
|
||||
|
||||
if (output->valType == TD_VTYPE_NORM) {
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset));
|
||||
} else {
|
||||
output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset);
|
||||
}
|
||||
output->valType = isNull(output->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM;
|
||||
#endif
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -908,7 +946,7 @@ int32_t tdAppendColValToRow(SRowBuilder *pBuilder, col_id_t colId, int8_t colTyp
|
|||
STSRow *pRow = pBuilder->pBuf;
|
||||
if (!val) {
|
||||
#ifdef TD_SUPPORT_BITMAP
|
||||
if (tdValTypeIsNorm(valType)) {
|
||||
if (valType == TD_VTYPE_NORM) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return terrno;
|
||||
}
|
||||
|
@ -925,6 +963,21 @@ int32_t tdAppendColValToRow(SRowBuilder *pBuilder, col_id_t colId, int8_t colTyp
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
// TODO: We can avoid the type judegement by FP, but would prevent the inline scheme.
|
||||
|
||||
switch (valType) {
|
||||
case TD_VTYPE_NORM:
|
||||
break;
|
||||
case TD_VTYPE_NULL:
|
||||
if (!pBuilder->hasNull) pBuilder->hasNull = true;
|
||||
break;
|
||||
case TD_VTYPE_NONE:
|
||||
if (!pBuilder->hasNone) pBuilder->hasNone = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (TD_IS_TP_ROW(pRow)) {
|
||||
tdAppendColValToTpRow(pBuilder, valType, val, isCopyVarData, colType, colIdx, offset);
|
||||
} else {
|
||||
|
@ -951,13 +1004,11 @@ int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const vo
|
|||
|
||||
STSRow *row = pBuilder->pBuf;
|
||||
// No need to store None/Null values.
|
||||
if (tdValIsNorm(valType, val, colType)) {
|
||||
// ts key stored in STSRow.ts
|
||||
SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset);
|
||||
char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row));
|
||||
pColIdx->colId = colId;
|
||||
pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN
|
||||
|
||||
SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset);
|
||||
pColIdx->colId = colId;
|
||||
pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN
|
||||
if (valType == TD_VTYPE_NORM) {
|
||||
char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row));
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
if (isCopyVarData) {
|
||||
memcpy(ptr, val, varDataTLen(val));
|
||||
|
@ -968,26 +1019,6 @@ int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const vo
|
|||
TD_ROW_LEN(row) += TYPE_BYTES[colType];
|
||||
}
|
||||
}
|
||||
#ifdef TD_SUPPORT_BACK2
|
||||
// NULL/None value
|
||||
else {
|
||||
SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset);
|
||||
char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row));
|
||||
pColIdx->colId = colId;
|
||||
pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN
|
||||
const void *nullVal = getNullValue(colType);
|
||||
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
if (isCopyVarData) {
|
||||
memcpy(ptr, nullVal, varDataTLen(nullVal));
|
||||
}
|
||||
TD_ROW_LEN(row) += varDataTLen(nullVal);
|
||||
} else {
|
||||
memcpy(ptr, nullVal, TYPE_BYTES[colType]);
|
||||
TD_ROW_LEN(row) += TYPE_BYTES[colType];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1012,7 +1043,7 @@ int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const vo
|
|||
// 1. No need to set flen part for Null/None, just use bitmap. When upsert for the same primary TS key, the bitmap
|
||||
// should be updated simultaneously if Norm val overwrite Null/None cols.
|
||||
// 2. When consume STSRow in memory by taos client/tq, the output of Null/None cols should both be Null.
|
||||
if (tdValIsNorm(valType, val, colType)) {
|
||||
if (valType == TD_VTYPE_NORM) {
|
||||
// TODO: The layout of new data types imported since 3.0 like blob/medium blob is the same with binary/nchar.
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
// ts key stored in STSRow.ts
|
||||
|
@ -1025,24 +1056,6 @@ int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const vo
|
|||
memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), val, TYPE_BYTES[colType]);
|
||||
}
|
||||
}
|
||||
#ifdef TD_SUPPORT_BACK2
|
||||
// NULL/None value
|
||||
else {
|
||||
// TODO: Null value for new data types imported since 3.0 need to be defined.
|
||||
const void *nullVal = getNullValue(colType);
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
// ts key stored in STSRow.ts
|
||||
*(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(row), offset) = TD_ROW_LEN(row);
|
||||
|
||||
if (isCopyVarData) {
|
||||
memcpy(POINTER_SHIFT(row, TD_ROW_LEN(row)), nullVal, varDataTLen(nullVal));
|
||||
}
|
||||
TD_ROW_LEN(row) += varDataTLen(nullVal);
|
||||
} else {
|
||||
memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), nullVal, TYPE_BYTES[colType]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1092,6 +1105,9 @@ int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf) {
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (pBuilder->hasNone) pBuilder->hasNone = false;
|
||||
if (pBuilder->hasNull) pBuilder->hasNull = false;
|
||||
|
||||
TD_ROW_SET_INFO(pBuilder->pBuf, 0);
|
||||
TD_ROW_SET_TYPE(pBuilder->pBuf, pBuilder->rowType);
|
||||
|
||||
|
@ -1159,14 +1175,6 @@ int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tdSRowInitEx(SRowBuilder *pBuilder, void *pBuf, uint32_t allNullLen, uint32_t boundNullLen, int32_t nCols,
|
||||
int32_t nBoundCols, int32_t flen) {
|
||||
if (tdSRowSetExtendedInfo(pBuilder, allNullLen, boundNullLen, nCols, nBoundCols, flen) < 0) {
|
||||
return terrno;
|
||||
}
|
||||
return tdSRowResetBuf(pBuilder, pBuf);
|
||||
}
|
||||
|
||||
void tdSRowReset(SRowBuilder *pBuilder) {
|
||||
pBuilder->rowType = TD_ROW_TP;
|
||||
pBuilder->pBuf = NULL;
|
||||
|
@ -1315,7 +1323,7 @@ void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow) {
|
|||
pIter->pRow = pRow;
|
||||
pIter->pBitmap = tdGetBitmapAddr(pRow, pRow->type, pIter->pSchema->flen, tdRowGetNCols(pRow));
|
||||
pIter->offset = 0;
|
||||
pIter->colIdx = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
pIter->colIdx = 0; // PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
pIter->kvIdx = 0;
|
||||
}
|
||||
|
||||
|
@ -1353,4 +1361,4 @@ void tTSRowGetVal(STSRow *pRow, STSchema *pTSchema, int16_t iCol, SColVal *pColV
|
|||
|
||||
*pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -364,6 +364,7 @@ SArray *vmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_VND_CHECK_ALTER_INFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_CONSUME, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_SCH_QUERY_HEARTBEAT, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ SSdbRaw *mndTopicActionEncode(SMqTopicObj *pTopic);
|
|||
SSdbRow *mndTopicActionDecode(SSdbRaw *pRaw);
|
||||
|
||||
int32_t mndDropTopicByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
||||
int32_t mndCheckTopicExist(SMnode *pMnode, SDbObj *pDb);
|
||||
|
||||
const char *mndTopicGetShowName(const char topic[TSDB_TOPIC_FNAME_LEN]);
|
||||
|
||||
|
|
|
@ -131,8 +131,9 @@ static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg) {
|
|||
mInfo("receive consumer recover msg, consumer id %" PRId64 ", status %s", pRecoverMsg->consumerId,
|
||||
mndConsumerStatusName(pConsumer->status));
|
||||
|
||||
if (pConsumer->status != MQ_CONSUMER_STATUS__READY) {
|
||||
if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
terrno = TSDB_CODE_MND_CONSUMER_NOT_READY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -275,6 +276,7 @@ static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
|||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||
mInfo("try to recover consumer %ld", consumerId);
|
||||
SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
|
||||
|
||||
pRecoverMsg->consumerId = consumerId;
|
||||
|
@ -305,15 +307,14 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
|||
|
||||
ASSERT(strcmp(pReq->cgroup, pConsumer->cgroup) == 0);
|
||||
|
||||
#if 1
|
||||
atomic_store_32(&pConsumer->hbStatus, 0);
|
||||
#endif
|
||||
|
||||
// 1. check consumer status
|
||||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
#if 1
|
||||
if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||
mInfo("try to recover consumer %ld", consumerId);
|
||||
SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
|
||||
|
||||
pRecoverMsg->consumerId = consumerId;
|
||||
|
@ -326,6 +327,7 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
|||
#endif
|
||||
|
||||
if (status != MQ_CONSUMER_STATUS__READY) {
|
||||
mInfo("consumer %ld not ready, status: %s", consumerId, mndConsumerStatusName(status));
|
||||
terrno = TSDB_CODE_MND_CONSUMER_NOT_READY;
|
||||
return -1;
|
||||
}
|
||||
|
@ -939,13 +941,9 @@ static int32_t mndRetrieveConsumer(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *
|
|||
colDataAppend(pColInfo, numOfRows, NULL, true);
|
||||
}
|
||||
|
||||
// pid
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->pid, true);
|
||||
|
||||
// end point
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->ep, true);
|
||||
/*pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);*/
|
||||
/*colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->ep, true);*/
|
||||
|
||||
// up time
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
|
|
|
@ -995,11 +995,13 @@ static int32_t mndDropDb(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb) {
|
|||
mDebug("trans:%d, used to drop db:%s", pTrans->id, pDb->name);
|
||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||
|
||||
if (mndCheckTopicExist(pMnode, pDb) < 0) goto _OVER;
|
||||
|
||||
if (mndSetDropDbRedoLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndSetDropDbCommitLogs(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndDropOffsetByDB(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndDropSubByDB(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndDropTopicByDB(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
/*if (mndDropOffsetByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||
/*if (mndDropSubByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||
/*if (mndDropTopicByDB(pMnode, pTrans, pDb) != 0) goto _OVER;*/
|
||||
if (mndDropStreamByDb(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndDropSmasByDb(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
if (mndSetDropDbRedoActions(pMnode, pTrans, pDb) != 0) goto _OVER;
|
||||
|
@ -1706,7 +1708,7 @@ static void setPerfSchemaDbCfg(SDbObj *pDbObj) {
|
|||
static bool mndGetTablesOfDbFp(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
|
||||
SVgObj *pVgroup = pObj;
|
||||
int32_t *numOfTables = p1;
|
||||
int64_t uid = *(int64_t*)p2;
|
||||
int64_t uid = *(int64_t *)p2;
|
||||
if (pVgroup->dbUid == uid) {
|
||||
*numOfTables += pVgroup->numOfTables;
|
||||
}
|
||||
|
|
|
@ -837,7 +837,7 @@ int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
mError("db:%s, failed to drop stream:%s since sourceDbUid:%" PRId64 " not match with targetDbUid:%" PRId64,
|
||||
pDb->name, pStream->name, pStream->sourceDbUid, pStream->targetDbUid);
|
||||
terrno = TSDB_CODE_MND_STREAM_ALREADY_EXIST;
|
||||
terrno = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
|
||||
return -1;
|
||||
} else {
|
||||
#if 0
|
||||
|
@ -929,14 +929,31 @@ static int32_t mndRetrieveStream(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStream->status, true);
|
||||
|
||||
char sourceDB[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&n, pStream->sourceDb, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameGetDbName(&n, varDataVal(sourceDB));
|
||||
varDataSetLen(sourceDB, strlen(varDataVal(sourceDB)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStream->sourceDb, true);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&sourceDB, false);
|
||||
|
||||
char targetDB[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&n, pStream->targetDb, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameGetDbName(&n, varDataVal(targetDB));
|
||||
varDataSetLen(targetDB, strlen(varDataVal(targetDB)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStream->targetDb, true);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&targetDB, false);
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStream->targetSTbName, true);
|
||||
if (pStream->targetSTbName[0] == 0) {
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, NULL, true);
|
||||
} else {
|
||||
char targetSTB[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&n, pStream->targetSTbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
strcpy(&targetSTB[VARSTR_HEADER_SIZE], tNameGetTableName(&n));
|
||||
varDataSetLen(targetSTB, strlen(varDataVal(targetSTB)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&targetSTB, false);
|
||||
}
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pStream->watermark, false);
|
||||
|
|
|
@ -398,13 +398,27 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
|
|||
}
|
||||
}
|
||||
|
||||
// 8. TODO generate logs
|
||||
mInfo("rebalance calculation completed, rebalanced vg:");
|
||||
// 8. generate logs
|
||||
mInfo("mq rebalance: calculation completed, rebalanced vg:");
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pOutput->rebVgs); i++) {
|
||||
SMqRebOutputVg *pOutputRebVg = taosArrayGet(pOutput->rebVgs, i);
|
||||
mInfo("vgId:%d, moved from consumer:%" PRId64 ", to consumer:%" PRId64, pOutputRebVg->pVgEp->vgId,
|
||||
mInfo("mq rebalance: vgId:%d, moved from consumer:%" PRId64 ", to consumer:%" PRId64, pOutputRebVg->pVgEp->vgId,
|
||||
pOutputRebVg->oldConsumerId, pOutputRebVg->newConsumerId);
|
||||
}
|
||||
{
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pOutput->pSub->consumerHash, pIter);
|
||||
if (pIter == NULL) break;
|
||||
SMqConsumerEp *pConsumerEp = (SMqConsumerEp *)pIter;
|
||||
int32_t sz = taosArrayGetSize(pConsumerEp->vgs);
|
||||
mInfo("mq rebalance: final cfg: consumer %ld has %d vg", pConsumerEp->consumerId, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, i);
|
||||
mInfo("mq rebalance: final cfg: vg %d to consumer %ld", pVgEp->vgId, pConsumerEp->consumerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 9. clear
|
||||
taosHashCleanup(pHash);
|
||||
|
|
|
@ -166,6 +166,18 @@ void mndLeaderTransfer(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cb
|
|||
mDebug("vgId:1, mnode leader transfer finish");
|
||||
}
|
||||
|
||||
static void mndBecomeFollower(struct SSyncFSM *pFsm) {
|
||||
SMnode *pMnode = pFsm->data;
|
||||
mDebug("vgId:1, become follower");
|
||||
|
||||
// clear old leader resource
|
||||
}
|
||||
|
||||
static void mndBecomeLeader(struct SSyncFSM *pFsm) {
|
||||
SMnode *pMnode = pFsm->data;
|
||||
mDebug("vgId:1, become leader");
|
||||
}
|
||||
|
||||
SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
|
||||
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
||||
pFsm->data = pMnode;
|
||||
|
@ -175,6 +187,8 @@ SSyncFSM *mndSyncMakeFsm(SMnode *pMnode) {
|
|||
pFsm->FpRestoreFinishCb = mndRestoreFinish;
|
||||
pFsm->FpLeaderTransferCb = mndLeaderTransfer;
|
||||
pFsm->FpReConfigCb = mndReConfig;
|
||||
pFsm->FpBecomeLeaderCb = mndBecomeLeader;
|
||||
pFsm->FpBecomeFollowerCb = mndBecomeFollower;
|
||||
pFsm->FpGetSnapshot = mndSyncGetSnapshot;
|
||||
pFsm->FpGetSnapshotInfo = mndSyncGetSnapshotInfo;
|
||||
pFsm->FpSnapshotStartRead = mndSnapshotStartRead;
|
||||
|
|
|
@ -782,6 +782,26 @@ static void mndCancelGetNextTopic(SMnode *pMnode, void *pIter) {
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
||||
|
||||
int32_t mndCheckTopicExist(SMnode *pMnode, SDbObj *pDb) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
void *pIter = NULL;
|
||||
SMqTopicObj *pTopic = NULL;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pTopic);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
if (pTopic->dbUid == pDb->uid) {
|
||||
sdbRelease(pSdb, pTopic);
|
||||
terrno = TSDB_CODE_MND_TOPIC_MUST_BE_DELETED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdbRelease(pSdb, pTopic);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndDropTopicByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
||||
int32_t code = 0;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
|
|
@ -157,7 +157,7 @@ int32_t tqCheckColModifiable(STQ* pTq, int64_t tbUid, int32_t colId);
|
|||
int32_t tqProcessCheckAlterInfoReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, char* msg, int32_t msgLen, int64_t ver);
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessTaskDeployReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
|
@ -172,7 +172,7 @@ int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg);
|
|||
int32_t tsdbGetStbIdList(SMeta* pMeta, int64_t suid, SArray* list);
|
||||
|
||||
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pSchema, bool createTb, int64_t suid,
|
||||
const char* stbFullName, int32_t vgId);
|
||||
const char* stbFullName, int32_t vgId, SBatchDeleteReq* pDeleteReq);
|
||||
|
||||
// sma
|
||||
int32_t smaInit();
|
||||
|
|
|
@ -604,28 +604,44 @@ _end:
|
|||
|
||||
static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSmaInfoItem *pItem, STSchema *pTSchema,
|
||||
int64_t suid, int8_t blkType) {
|
||||
while (1) {
|
||||
SSDataBlock *output = NULL;
|
||||
uint64_t ts;
|
||||
SArray *pResList = taosArrayInit(1, POINTER_BYTES);
|
||||
if (pResList == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
int32_t code = qExecTask(taskInfo, &output, &ts);
|
||||
while (1) {
|
||||
uint64_t ts;
|
||||
int32_t code = qExecTaskOpt(taskInfo, pResList, &ts);
|
||||
if (code < 0) {
|
||||
smaError("vgId:%d, qExecTask for rsma table %" PRIi64 " level %" PRIi8 " failed since %s", SMA_VID(pSma), suid,
|
||||
pItem->level, terrstr(code));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (output) {
|
||||
#if 0
|
||||
if (taosArrayGetSize(pResList) == 0) {
|
||||
if (terrno == 0) {
|
||||
smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched yet", SMA_VID(pSma), pItem->level);
|
||||
} else {
|
||||
smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched since %s", SMA_VID(pSma), pItem->level, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pResList); ++i) {
|
||||
SSDataBlock *output = taosArrayGetP(pResList, i);
|
||||
|
||||
#if 1
|
||||
char flag[10] = {0};
|
||||
snprintf(flag, 10, "level %" PRIi8, pItem->level);
|
||||
SArray *pResult = taosArrayInit(1, sizeof(SSDataBlock));
|
||||
taosArrayPush(pResult, output);
|
||||
blockDebugShowDataBlocks(pResult, flag);
|
||||
taosArrayDestroy(pResult);
|
||||
// blockDebugShowDataBlocks(output, flag);
|
||||
// taosArrayDestroy(pResult);
|
||||
#endif
|
||||
STsdb *sinkTsdb = (pItem->level == TSDB_RETENTION_L1 ? pSma->pRSmaTsdb[0] : pSma->pRSmaTsdb[1]);
|
||||
STsdb * sinkTsdb = (pItem->level == TSDB_RETENTION_L1 ? pSma->pRSmaTsdb[0] : pSma->pRSmaTsdb[1]);
|
||||
SSubmitReq *pReq = NULL;
|
||||
|
||||
// TODO: the schema update should be handled later(TD-17965)
|
||||
if (buildSubmitReqFromDataBlock(&pReq, output, pTSchema, SMA_VID(pSma), suid) < 0) {
|
||||
smaError("vgId:%d, build submit req for rsma stable %" PRIi64 " level %" PRIi8 " failed since %s",
|
||||
|
@ -644,17 +660,14 @@ static int32_t tdRSmaFetchAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSm
|
|||
SMA_VID(pSma), suid, pItem->level, output->info.version);
|
||||
|
||||
taosMemoryFreeClear(pReq);
|
||||
} else if (terrno == 0) {
|
||||
smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched yet", SMA_VID(pSma), pItem->level);
|
||||
break;
|
||||
} else {
|
||||
smaDebug("vgId:%d, no rsma %" PRIi8 " data fetched since %s", SMA_VID(pSma), pItem->level, terrstr());
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pResList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_err:
|
||||
taosArrayDestroy(pResList);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1407,7 +1420,7 @@ int32_t tdRSmaFetchSend(SSma *pSma, SRSmaInfo *pInfo, int8_t level) {
|
|||
tEncoderClear(&encoder);
|
||||
}
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
|
||||
((SMsgHead *)pBuf)->vgId = SMA_VID(pSma);
|
||||
((SMsgHead *)pBuf)->contLen = contLen + sizeof(SMsgHead);
|
||||
|
||||
|
@ -1434,10 +1447,10 @@ _err:
|
|||
|
||||
/**
|
||||
* @brief fetch rsma data of level 2/3 and submit
|
||||
*
|
||||
* @param pSma
|
||||
* @param pMsg
|
||||
* @return int32_t
|
||||
*
|
||||
* @param pSma
|
||||
* @param pMsg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t smaProcessFetch(SSma *pSma, void *pMsg) {
|
||||
SRpcMsg *pRpcMsg = (SRpcMsg *)pMsg;
|
||||
|
|
|
@ -119,7 +119,7 @@ int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg) {
|
|||
SName stbFullName = {0};
|
||||
tNameFromString(&stbFullName, pCfg->dstTbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
SVCreateStbReq pReq = {0};
|
||||
pReq.name = (char*)tNameGetTableName(&stbFullName);
|
||||
pReq.name = (char *)tNameGetTableName(&stbFullName);
|
||||
pReq.suid = pCfg->dstTbUid;
|
||||
pReq.schemaRow = pCfg->schemaRow;
|
||||
pReq.schemaTag = pCfg->schemaTag;
|
||||
|
@ -200,8 +200,9 @@ int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
|||
goto _err;
|
||||
}
|
||||
|
||||
SBatchDeleteReq deleteReq;
|
||||
SSubmitReq *pSubmitReq = tdBlockToSubmit((const SArray *)msg, pTsmaStat->pTSchema, true, pTsmaStat->pTSma->dstTbUid,
|
||||
pTsmaStat->pTSma->dstTbName, pTsmaStat->pTSma->dstVgId);
|
||||
pTsmaStat->pTSma->dstTbName, pTsmaStat->pTSma->dstVgId, &deleteReq);
|
||||
|
||||
if (!pSubmitReq) {
|
||||
smaError("vgId:%d, failed to gen submit blk while tsma insert for smaIndex %" PRIi64 " since %s", SMA_VID(pSma),
|
||||
|
@ -230,4 +231,4 @@ int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
|
|||
_err:
|
||||
tdUnRefSmaStat(pSma, pStat);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, con
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, char* msg, int32_t msgLen) {
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, char* msg, int32_t msgLen, int64_t ver) {
|
||||
STqOffset offset = {0};
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, msg, msgLen);
|
||||
|
@ -302,6 +302,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqError("tmq poll: consumer handle mismatch for consumer:%" PRId64
|
||||
", in vgId:%d, subkey %s, handle consumer id %" PRId64,
|
||||
consumerId, TD_VID(pTq->pVnode), pReq->subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ int32_t tqRetrieveDataBlock(SSDataBlock* pBlock, STqReader* pReader) {
|
|||
for (int32_t i = 0; i < colActual; i++) {
|
||||
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
SCellVal sVal = {0};
|
||||
if (!tdSTSRowIterNext(&iter, pColData->info.colId, pColData->info.type, &sVal)) {
|
||||
if (!tdSTSRowIterFetch(&iter, pColData->info.colId, pColData->info.type, &sVal)) {
|
||||
break;
|
||||
}
|
||||
if (colDataAppend(pColData, curRow, sVal.val, sVal.valType != TD_VTYPE_NORM) < 0) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "tq.h"
|
||||
|
||||
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, bool createTb, int64_t suid,
|
||||
const char* stbFullName, int32_t vgId) {
|
||||
const char* stbFullName, int32_t vgId, SBatchDeleteReq* deleteReq) {
|
||||
SSubmitReq* ret = NULL;
|
||||
SArray* schemaReqs = NULL;
|
||||
SArray* schemaReqSz = NULL;
|
||||
|
@ -33,10 +33,13 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
schemaReqSz = taosArrayInit(sz, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.groupId,
|
||||
if (pDataBlock->info.type == STREAM_DELETE_DATA) {
|
||||
//
|
||||
}
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.groupId,
|
||||
};
|
||||
STag* pTag = NULL;
|
||||
taosArrayClear(tagArray);
|
||||
|
@ -157,6 +160,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, data, true, pColumn->offset, k);
|
||||
}
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
int32_t rowLen = TD_ROW_LEN(rowData);
|
||||
rowData = POINTER_SHIFT(rowData, rowLen);
|
||||
dataLen += rowLen;
|
||||
|
@ -176,17 +180,45 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
}
|
||||
|
||||
void tqTableSink(SStreamTask* pTask, void* vnode, int64_t ver, void* data) {
|
||||
const SArray* pRes = (const SArray*)data;
|
||||
SVnode* pVnode = (SVnode*)vnode;
|
||||
const SArray* pRes = (const SArray*)data;
|
||||
SVnode* pVnode = (SVnode*)vnode;
|
||||
SBatchDeleteReq deleteReq = {0};
|
||||
|
||||
tqDebug("vgId:%d, task %d write into table, block num: %d", TD_VID(pVnode), pTask->taskId, (int32_t)pRes->size);
|
||||
|
||||
ASSERT(pTask->tbSink.pTSchema);
|
||||
deleteReq.deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
SSubmitReq* pReq = tdBlockToSubmit(pRes, pTask->tbSink.pTSchema, true, pTask->tbSink.stbUid,
|
||||
pTask->tbSink.stbFullName, pVnode->config.vgId);
|
||||
pTask->tbSink.stbFullName, pVnode->config.vgId, &deleteReq);
|
||||
|
||||
tqDebug("vgId:%d, task %d convert blocks over, put into write-queue", TD_VID(pVnode), pTask->taskId);
|
||||
|
||||
int32_t code;
|
||||
int32_t len;
|
||||
tEncodeSize(tEncodeSBatchDeleteReq, &deleteReq, len, code);
|
||||
if (code < 0) {
|
||||
//
|
||||
ASSERT(0);
|
||||
}
|
||||
SEncoder encoder;
|
||||
void* buf = taosMemoryCalloc(1, len + sizeof(SMsgHead));
|
||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
tEncoderInit(&encoder, abuf, len);
|
||||
tEncodeSBatchDeleteReq(&encoder, &deleteReq);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
if (taosArrayGetSize(deleteReq.deleteReqs) != 0) {
|
||||
SRpcMsg msg = {
|
||||
.msgType = TDMT_VND_BATCH_DEL,
|
||||
.pCont = buf,
|
||||
.contLen = len + sizeof(SMsgHead),
|
||||
};
|
||||
if (tmsgPutToQueue(&pVnode->msgCb, WRITE_QUEUE, &msg) != 0) {
|
||||
tqDebug("failed to put into write-queue since %s", terrstr());
|
||||
}
|
||||
}
|
||||
taosArrayDestroy(deleteReq.deleteReqs);
|
||||
|
||||
/*tPrintFixedSchemaSubmitReq(pReq, pTask->tbSink.pTSchema);*/
|
||||
// build write msg
|
||||
SRpcMsg msg = {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
#include "osDef.h"
|
||||
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
|
||||
|
||||
typedef enum {
|
||||
|
@ -129,7 +130,8 @@ struct STsdbReader {
|
|||
SBlockLoadSuppInfo suppInfo;
|
||||
STsdbReadSnap* pReadSnap;
|
||||
SIOCostSummary cost;
|
||||
STSchema* pSchema;
|
||||
STSchema* pSchema;// the newest version schema
|
||||
STSchema* pMemSchema;// the previous schema for in-memory data, to avoid load schema too many times
|
||||
SDataFReader* pFileReader;
|
||||
SVersionRange verRange;
|
||||
|
||||
|
@ -145,15 +147,14 @@ static int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanI
|
|||
SRowMerger* pMerger);
|
||||
static int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, SRowMerger* pMerger,
|
||||
STsdbReader* pReader);
|
||||
static int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow);
|
||||
static int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow, uint64_t uid);
|
||||
static int32_t doAppendRowFromBlock(SSDataBlock* pResBlock, STsdbReader* pReader, SBlockData* pBlockData,
|
||||
int32_t rowIndex);
|
||||
static void setComposedBlockFlag(STsdbReader* pReader, bool composed);
|
||||
static void updateSchema(TSDBROW* pRow, uint64_t uid, STsdbReader* pReader);
|
||||
static bool hasBeenDropped(const SArray* pDelList, int32_t* index, TSDBKEY* pKey, int32_t order);
|
||||
|
||||
static void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter, SArray* pDelList, STSRow** pTSRow,
|
||||
STsdbReader* pReader);
|
||||
STsdbReader* pReader, bool* freeTSRow);
|
||||
static void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader,
|
||||
STSRow** pTSRow);
|
||||
static int32_t initDelSkylineIterator(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STbData* pMemTbData,
|
||||
|
@ -181,6 +182,7 @@ static int32_t setColumnIdSlotList(STsdbReader* pReader, SSDataBlock* pBlock) {
|
|||
|
||||
if (IS_VAR_DATA_TYPE(pCol->info.type)) {
|
||||
pSupInfo->buildBuf[i] = taosMemoryMalloc(pCol->info.bytes);
|
||||
// tsdbInfo("-------------------%d\n", pCol->info.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,6 +675,7 @@ static void doCopyColVal(SColumnInfoData* pColInfoData, int32_t rowIndex, int32_
|
|||
colDataAppendNULL(pColInfoData, rowIndex);
|
||||
} else {
|
||||
varDataSetLen(pSup->buildBuf[colIndex], pColVal->value.nData);
|
||||
ASSERT(pColVal->value.nData <= pColInfoData->info.bytes);
|
||||
memcpy(varDataVal(pSup->buildBuf[colIndex]), pColVal->value.pData, pColVal->value.nData);
|
||||
colDataAppend(pColInfoData, rowIndex, pSup->buildBuf[colIndex], false);
|
||||
}
|
||||
|
@ -1210,6 +1213,51 @@ static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo*
|
|||
return code;
|
||||
}
|
||||
|
||||
static bool tryCopyDistinctRowFromFileBlock(STsdbReader* pReader, SBlockData* pBlockData, int64_t key, SFileBlockDumpInfo* pDumpInfo) {
|
||||
|
||||
// opt version
|
||||
// 1. it is not a border point
|
||||
// 2. the direct next point is not an duplicated timestamp
|
||||
if ((pDumpInfo->rowIndex < pDumpInfo->totalRows - 1 && pReader->order == TSDB_ORDER_ASC) ||
|
||||
(pDumpInfo->rowIndex > 0 && pReader->order == TSDB_ORDER_DESC)) {
|
||||
int32_t step = pReader->order == TSDB_ORDER_ASC? 1:-1;
|
||||
|
||||
int64_t nextKey = pBlockData->aTSKEY[pDumpInfo->rowIndex + step];
|
||||
if (nextKey != key) { // merge is not needed
|
||||
doAppendRowFromBlock(pReader->pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
|
||||
pDumpInfo->rowIndex += step;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader* pReader, uint64_t uid) {
|
||||
// always set the newest schema version in pReader->pSchema
|
||||
if (pReader->pSchema == NULL) {
|
||||
pReader->pSchema = metaGetTbTSchema(pReader->pTsdb->pVnode->pMeta, uid, -1);
|
||||
}
|
||||
|
||||
if (sversion == pReader->pSchema->version) {
|
||||
return pReader->pSchema;
|
||||
}
|
||||
|
||||
if (pReader->pMemSchema == NULL) {
|
||||
int32_t code =
|
||||
metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pReader->pMemSchema);
|
||||
return pReader->pMemSchema;
|
||||
}
|
||||
|
||||
if (pReader->pMemSchema->version == sversion) {
|
||||
return pReader->pMemSchema;
|
||||
}
|
||||
|
||||
taosMemoryFree(pReader->pMemSchema);
|
||||
int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pReader->pMemSchema);
|
||||
return pReader->pMemSchema;
|
||||
}
|
||||
|
||||
static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo* pBlockScanInfo, TSDBROW* pRow,
|
||||
SIterInfo* pIter, int64_t key) {
|
||||
SRowMerger merge = {0};
|
||||
|
@ -1220,16 +1268,23 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
TSDBKEY k = TSDBROW_KEY(pRow);
|
||||
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
|
||||
SArray* pDelList = pBlockScanInfo->delSkyline;
|
||||
bool freeTSRow = false;
|
||||
uint64_t uid = pBlockScanInfo->uid;
|
||||
|
||||
// ascending order traverse
|
||||
if (ASCENDING_TRAVERSE(pReader->order)) {
|
||||
if (key < k.ts) {
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
// imem & mem are all empty, only file exist
|
||||
if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
freeTSRow = true;
|
||||
}
|
||||
} else if (k.ts < key) { // k.ts < key
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader);
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
} else { // k.ts == key, ascending order: file block ----> imem rows -----> mem rows
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
|
@ -1238,32 +1293,41 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
freeTSRow = true;
|
||||
}
|
||||
} else { // descending order scan
|
||||
if (key < k.ts) {
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader);
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, pIter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
} else if (k.ts < key) {
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
freeTSRow = true;
|
||||
}
|
||||
} else { // descending order: mem rows -----> imem rows ------> file block
|
||||
updateSchema(pRow, pBlockScanInfo->uid, pReader);
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
|
||||
tRowMergerInit(&merge, pRow, pReader->pSchema);
|
||||
tRowMergerInit(&merge, pRow, pSchema);
|
||||
doMergeRowsInBuf(pIter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
|
||||
tRowMerge(&merge, &fRow);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
freeTSRow = true;
|
||||
}
|
||||
}
|
||||
|
||||
tRowMergerClear(&merge);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
|
||||
if (freeTSRow) {
|
||||
taosMemoryFree(pTSRow);
|
||||
}
|
||||
|
||||
taosMemoryFree(pTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1280,12 +1344,12 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
ASSERT(pRow != NULL && piRow != NULL);
|
||||
|
||||
int64_t key = pBlockData->aTSKEY[pDumpInfo->rowIndex];
|
||||
bool freeTSRow = false;
|
||||
|
||||
uint64_t uid = pBlockScanInfo->uid;
|
||||
|
||||
TSDBKEY k = TSDBROW_KEY(pRow);
|
||||
TSDBKEY ik = TSDBROW_KEY(piRow);
|
||||
|
||||
if (ASCENDING_TRAVERSE(pReader->order)) {
|
||||
// [1&2] key <= [k.ts && ik.ts]
|
||||
if (key <= k.ts && key <= ik.ts) {
|
||||
|
@ -1305,7 +1369,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
}
|
||||
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else { // key > ik.ts || key > k.ts
|
||||
ASSERT(key != ik.ts);
|
||||
|
@ -1313,16 +1377,22 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
// [3] ik.ts < key <= k.ts
|
||||
// [4] ik.ts < k.ts <= key
|
||||
if (ik.ts < k.ts) {
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
if (freeTSRow) {
|
||||
taosMemoryFree(pTSRow);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// [5] k.ts < key <= ik.ts
|
||||
// [6] k.ts < ik.ts <= key
|
||||
if (k.ts < ik.ts) {
|
||||
doMergeMultiRows(pRow, uid, &pBlockScanInfo->iter, pDelList, &pTSRow, pReader);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doMergeMultiRows(pRow, uid, &pBlockScanInfo->iter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
if (freeTSRow) {
|
||||
taosMemoryFree(pTSRow);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1331,16 +1401,17 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
ASSERT(key > ik.ts && key > k.ts);
|
||||
|
||||
doMergeMemIMemRows(pRow, piRow, pBlockScanInfo, pReader, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
taosMemoryFree(pTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
} else { // descending order scan
|
||||
// [1/2] k.ts >= ik.ts && k.ts >= key
|
||||
if (k.ts >= ik.ts && k.ts >= key) {
|
||||
updateSchema(pRow, uid, pReader);
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
|
||||
tRowMergerInit(&merge, pRow, pReader->pSchema);
|
||||
tRowMergerInit(&merge, pRow, pSchema);
|
||||
doMergeRowsInBuf(&pBlockScanInfo->iter, uid, key, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
|
||||
if (ik.ts == k.ts) {
|
||||
|
@ -1355,7 +1426,7 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
}
|
||||
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
ASSERT(ik.ts != k.ts); // this case has been included in the previous if branch
|
||||
|
@ -1363,8 +1434,11 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
// [3] ik.ts > k.ts >= Key
|
||||
// [4] ik.ts > key >= k.ts
|
||||
if (ik.ts > key) {
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
if (freeTSRow) {
|
||||
taosMemoryFree(pTSRow);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1376,19 +1450,22 @@ static int32_t doMergeThreeLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
taosMemoryFree(pTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
//[7] key = ik.ts > k.ts
|
||||
if (key == ik.ts) {
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader);
|
||||
doMergeMultiRows(piRow, uid, &pBlockScanInfo->iiter, pDelList, &pTSRow, pReader, &freeTSRow);
|
||||
|
||||
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
|
||||
tRowMerge(&merge, &fRow);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, uid);
|
||||
|
||||
taosMemoryFree(pTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -1443,34 +1520,23 @@ static int32_t buildComposedDataBlockImpl(STsdbReader* pReader, STableBlockScanI
|
|||
}
|
||||
|
||||
// imem & mem are all empty, only file exist
|
||||
if (tryCopyDistinctRowFromFileBlock(pReader, pBlockData, key, pDumpInfo)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
|
||||
|
||||
// opt version
|
||||
// 1. it is not a border point
|
||||
// 2. the direct next point is not an duplicated timestamp
|
||||
if ((pDumpInfo->rowIndex < pDumpInfo->totalRows - 1 && pReader->order == TSDB_ORDER_ASC) ||
|
||||
(pDumpInfo->rowIndex > 0 && pReader->order == TSDB_ORDER_DESC)) {
|
||||
int32_t step = pReader->order == TSDB_ORDER_ASC ? 1 : -1;
|
||||
int64_t nextKey = pBlockData->aTSKEY[pDumpInfo->rowIndex + step];
|
||||
if (nextKey != key) { // merge is not needed
|
||||
doAppendRowFromBlock(pReader->pResBlock, pReader, pBlockData, pDumpInfo->rowIndex);
|
||||
pDumpInfo->rowIndex += step;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
STSRow* pTSRow = NULL;
|
||||
SRowMerger merge = {0};
|
||||
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow, pBlockScanInfo->uid);
|
||||
|
||||
taosMemoryFree(pTSRow);
|
||||
tRowMergerClear(&merge);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
|
||||
|
||||
STSRow* pTSRow = NULL;
|
||||
SRowMerger merge = {0};
|
||||
|
||||
tRowMergerInit(&merge, &fRow, pReader->pSchema);
|
||||
doMergeRowsInFileBlocks(pBlockData, pBlockScanInfo, pReader, &merge);
|
||||
tRowMergerGetRow(&merge, &pTSRow);
|
||||
doAppendRowFromTSRow(pReader->pResBlock, pReader, pTSRow);
|
||||
|
||||
taosMemoryFree(pTSRow);
|
||||
tRowMergerClear(&merge);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2083,7 +2149,7 @@ TSDBROW* getValidRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pRea
|
|||
}
|
||||
|
||||
TSDBROW* pRow = tsdbTbDataIterGet(pIter->iter);
|
||||
TSDBKEY key = TSDBROW_KEY(pRow);
|
||||
TSDBKEY key = {.ts = pRow->pTSRow->ts, .version = pRow->version};
|
||||
if (outOfTimeWindow(key.ts, &pReader->window)) {
|
||||
pIter->hasVal = false;
|
||||
return NULL;
|
||||
|
@ -2116,6 +2182,7 @@ TSDBROW* getValidRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pRea
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, SRowMerger* pMerger,
|
||||
STsdbReader* pReader) {
|
||||
while (1) {
|
||||
|
@ -2136,22 +2203,8 @@ int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDe
|
|||
break;
|
||||
}
|
||||
|
||||
int32_t sversion = TSDBROW_SVERSION(pRow);
|
||||
STSchema* pTSchema = NULL;
|
||||
if (pReader->pSchema == NULL || sversion != pReader->pSchema->version) {
|
||||
metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pTSchema);
|
||||
if (pReader->pSchema == NULL) {
|
||||
pReader->pSchema = pTSchema;
|
||||
}
|
||||
} else {
|
||||
pTSchema = pReader->pSchema;
|
||||
}
|
||||
|
||||
STSchema* pTSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, uid);
|
||||
tRowMergerAdd(pMerger, pRow, pTSchema);
|
||||
|
||||
if (pTSchema != pReader->pSchema) {
|
||||
taosMemoryFree(pTSchema);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2259,42 +2312,50 @@ int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pSc
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void updateSchema(TSDBROW* pRow, uint64_t uid, STsdbReader* pReader) {
|
||||
int32_t sversion = TSDBROW_SVERSION(pRow);
|
||||
|
||||
if (pReader->pSchema == NULL) {
|
||||
metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pReader->pSchema);
|
||||
} else if (pReader->pSchema->version != sversion) {
|
||||
taosMemoryFreeClear(pReader->pSchema);
|
||||
metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pReader->pSchema);
|
||||
}
|
||||
}
|
||||
|
||||
void doMergeMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter, SArray* pDelList, STSRow** pTSRow,
|
||||
STsdbReader* pReader) {
|
||||
STsdbReader* pReader, bool* freeTSRow) {
|
||||
|
||||
TSDBROW* pNextRow = NULL;
|
||||
TSDBROW current = *pRow;
|
||||
|
||||
{ // if the timestamp of the next valid row has a different ts, return current row directly
|
||||
pIter->hasVal = tsdbTbDataIterNext(pIter->iter);
|
||||
|
||||
if (!pIter->hasVal) {
|
||||
*pTSRow = current.pTSRow;
|
||||
*freeTSRow = false;
|
||||
return;
|
||||
} else { // has next point in mem/imem
|
||||
pNextRow = getValidRow(pIter, pDelList, pReader);
|
||||
if (pNextRow == NULL) {
|
||||
*pTSRow = current.pTSRow;
|
||||
*freeTSRow = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (current.pTSRow->ts != pNextRow->pTSRow->ts) {
|
||||
*pTSRow = current.pTSRow;
|
||||
*freeTSRow = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SRowMerger merge = {0};
|
||||
|
||||
TSDBKEY k = TSDBROW_KEY(pRow);
|
||||
// updateSchema(pRow, uid, pReader);
|
||||
int32_t sversion = TSDBROW_SVERSION(pRow);
|
||||
STSchema* pTSchema = NULL;
|
||||
if (pReader->pSchema == NULL || sversion != pReader->pSchema->version) {
|
||||
metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &pTSchema);
|
||||
if (pReader->pSchema == NULL) {
|
||||
pReader->pSchema = pTSchema;
|
||||
}
|
||||
} else {
|
||||
pTSchema = pReader->pSchema;
|
||||
}
|
||||
// get the correct schema for data in memory
|
||||
STSchema* pTSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(¤t), pReader, uid);
|
||||
|
||||
tRowMergerInit2(&merge, pReader->pSchema, pRow, pTSchema);
|
||||
doMergeRowsInBuf(pIter, uid, k.ts, pDelList, &merge, pReader);
|
||||
tRowMergerInit2(&merge, pReader->pSchema, ¤t, pTSchema);
|
||||
|
||||
STSchema* pTSchema1 = doGetSchemaForTSRow(TSDBROW_SVERSION(pNextRow), pReader, uid);
|
||||
tRowMergerAdd(&merge, pNextRow, pTSchema1);
|
||||
|
||||
doMergeRowsInBuf(pIter, uid, current.pTSRow->ts, pDelList, &merge, pReader);
|
||||
tRowMergerGetRow(&merge, pTSRow);
|
||||
tRowMergerClear(&merge);
|
||||
|
||||
if (pTSchema != pReader->pSchema) {
|
||||
taosMemoryFree(pTSchema);
|
||||
}
|
||||
*freeTSRow = true;
|
||||
}
|
||||
|
||||
void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader,
|
||||
|
@ -2305,17 +2366,17 @@ void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlo
|
|||
TSDBKEY ik = TSDBROW_KEY(piRow);
|
||||
|
||||
if (ASCENDING_TRAVERSE(pReader->order)) { // ascending order imem --> mem
|
||||
updateSchema(piRow, pBlockScanInfo->uid, pReader);
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
|
||||
tRowMergerInit(&merge, piRow, pReader->pSchema);
|
||||
tRowMergerInit(&merge, piRow, pSchema);
|
||||
doMergeRowsInBuf(&pBlockScanInfo->iiter, pBlockScanInfo->uid, ik.ts, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
|
||||
tRowMerge(&merge, pRow);
|
||||
doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
} else {
|
||||
updateSchema(pRow, pBlockScanInfo->uid, pReader);
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
|
||||
tRowMergerInit(&merge, pRow, pReader->pSchema);
|
||||
tRowMergerInit(&merge, pRow, pSchema);
|
||||
doMergeRowsInBuf(&pBlockScanInfo->iter, pBlockScanInfo->uid, k.ts, pBlockScanInfo->delSkyline, &merge, pReader);
|
||||
|
||||
tRowMerge(&merge, piRow);
|
||||
|
@ -2326,7 +2387,7 @@ void doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* pBlo
|
|||
}
|
||||
|
||||
int32_t tsdbGetNextRowInMem(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader, STSRow** pTSRow,
|
||||
int64_t endKey) {
|
||||
int64_t endKey, bool* freeTSRow) {
|
||||
TSDBROW* pRow = getValidRow(&pBlockScanInfo->iter, pBlockScanInfo->delSkyline, pReader);
|
||||
TSDBROW* piRow = getValidRow(&pBlockScanInfo->iiter, pBlockScanInfo->delSkyline, pReader);
|
||||
SArray* pDelList = pBlockScanInfo->delSkyline;
|
||||
|
@ -2352,35 +2413,36 @@ int32_t tsdbGetNextRowInMem(STableBlockScanInfo* pBlockScanInfo, STsdbReader* pR
|
|||
TSDBKEY ik = TSDBROW_KEY(piRow);
|
||||
|
||||
if (ik.ts < k.ts) { // ik.ts < k.ts
|
||||
doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader);
|
||||
doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader, freeTSRow);
|
||||
} else if (k.ts < ik.ts) {
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader);
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader, freeTSRow);
|
||||
} else { // ik.ts == k.ts
|
||||
doMergeMemIMemRows(pRow, piRow, pBlockScanInfo, pReader, pTSRow);
|
||||
*freeTSRow = true;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pBlockScanInfo->iter.hasVal && pRow != NULL) {
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader);
|
||||
doMergeMultiRows(pRow, pBlockScanInfo->uid, &pBlockScanInfo->iter, pDelList, pTSRow, pReader, freeTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pBlockScanInfo->iiter.hasVal && piRow != NULL) {
|
||||
doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader);
|
||||
doMergeMultiRows(piRow, pBlockScanInfo->uid, &pBlockScanInfo->iiter, pDelList, pTSRow, pReader, freeTSRow);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow) {
|
||||
int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow* pTSRow, uint64_t uid) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
int32_t numOfCols = (int32_t)taosArrayGetSize(pBlock->pDataBlock);
|
||||
|
||||
SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
|
||||
STSchema* pSchema = pReader->pSchema;
|
||||
STSchema* pSchema = doGetSchemaForTSRow(pTSRow->sver, pReader, uid);
|
||||
|
||||
SColVal colVal = {0};
|
||||
int32_t i = 0, j = 0;
|
||||
|
@ -2396,7 +2458,7 @@ int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, STSRow*
|
|||
col_id_t colId = pColInfoData->info.colId;
|
||||
|
||||
if (colId == pSchema->columns[j].colId) {
|
||||
tTSRowGetVal(pTSRow, pReader->pSchema, j, &colVal);
|
||||
tTSRowGetVal(pTSRow, pSchema, j, &colVal);
|
||||
doCopyColVal(pColInfoData, numOfRows, i, &colVal, pSupInfo);
|
||||
i += 1;
|
||||
j += 1;
|
||||
|
@ -2466,13 +2528,16 @@ int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t e
|
|||
|
||||
do {
|
||||
STSRow* pTSRow = NULL;
|
||||
tsdbGetNextRowInMem(pBlockScanInfo, pReader, &pTSRow, endKey);
|
||||
bool freeTSRow = false;
|
||||
tsdbGetNextRowInMem(pBlockScanInfo, pReader, &pTSRow, endKey, &freeTSRow);
|
||||
if (pTSRow == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
doAppendRowFromTSRow(pBlock, pReader, pTSRow);
|
||||
taosMemoryFree(pTSRow);
|
||||
doAppendRowFromTSRow(pBlock, pReader, pTSRow, pBlockScanInfo->uid);
|
||||
if (freeTSRow) {
|
||||
taosMemoryFree(pTSRow);
|
||||
}
|
||||
|
||||
// no data in buffer, return immediately
|
||||
if (!(pBlockScanInfo->iter.hasVal || pBlockScanInfo->iiter.hasVal)) {
|
||||
|
@ -2665,7 +2730,6 @@ void tsdbReaderClose(STsdbReader* pReader) {
|
|||
}
|
||||
|
||||
SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
|
||||
|
||||
tsdbUntakeReadSnap(pReader->pTsdb, pReader->pReadSnap);
|
||||
|
||||
taosMemoryFreeClear(pSupInfo->plist);
|
||||
|
@ -2693,16 +2757,15 @@ void tsdbReaderClose(STsdbReader* pReader) {
|
|||
SIOCostSummary* pCost = &pReader->cost;
|
||||
|
||||
tsdbDebug("%p :io-cost summary: head-file:%" PRIu64 ", head-file time:%.2f ms, SMA:%" PRId64
|
||||
" SMA-time:%.2f ms, "
|
||||
"fileBlocks:%" PRId64
|
||||
", fileBlocks-time:%.2f ms, build in-memory-block-time:%.2f ms, STableBlockScanInfo "
|
||||
"size:%.2f Kb %s",
|
||||
" SMA-time:%.2f ms, fileBlocks:%" PRId64 ", fileBlocks-time:%.2f ms, "
|
||||
"build in-memory-block-time:%.2f ms, STableBlockScanInfo size:%.2f Kb %s",
|
||||
pReader, pCost->headFileLoad, pCost->headFileLoadTime, pCost->smaData, pCost->smaLoadTime,
|
||||
pCost->numOfBlocks, pCost->blockLoadTime, pCost->buildmemBlock,
|
||||
numOfTables * sizeof(STableBlockScanInfo) / 1000.0, pReader->idStr);
|
||||
|
||||
taosMemoryFree(pReader->idStr);
|
||||
taosMemoryFree(pReader->pSchema);
|
||||
taosMemoryFree(pReader->pMemSchema);
|
||||
taosMemoryFreeClear(pReader);
|
||||
}
|
||||
|
||||
|
|
|
@ -1520,22 +1520,22 @@ void tsdbCalcColDataSMA(SColData *pColData, SColumnDataAgg *pColAgg) {
|
|||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
pColAgg->sum += colVal.value.f;
|
||||
if (pColAgg->min > colVal.value.f) {
|
||||
pColAgg->min = colVal.value.f;
|
||||
*(double*)(&pColAgg->sum) += colVal.value.f;
|
||||
if (*(double*)(&pColAgg->min) > colVal.value.f) {
|
||||
*(double*)(&pColAgg->min) = colVal.value.f;
|
||||
}
|
||||
if (pColAgg->max < colVal.value.f) {
|
||||
pColAgg->max = colVal.value.f;
|
||||
if (*(double*)(&pColAgg->max) < colVal.value.f) {
|
||||
*(double*)(&pColAgg->max) = colVal.value.f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
pColAgg->sum += colVal.value.d;
|
||||
if (pColAgg->min > colVal.value.d) {
|
||||
pColAgg->min = colVal.value.d;
|
||||
*(double*)(&pColAgg->sum) += colVal.value.d;
|
||||
if (*(double*)(&pColAgg->min) > colVal.value.d) {
|
||||
*(double*)(&pColAgg->min) = colVal.value.d;
|
||||
}
|
||||
if (pColAgg->max < colVal.value.d) {
|
||||
pColAgg->max = colVal.value.d;
|
||||
if (*(double*)(&pColAgg->max) < colVal.value.d) {
|
||||
*(double*)(&pColAgg->max) = colVal.value.d;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t version, void
|
|||
static int32_t vnodeProcessDropTtlTbReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessTrimReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
|
||||
int32_t vnodePreProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
int32_t code = 0;
|
||||
|
@ -190,6 +191,9 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
case TDMT_VND_DELETE:
|
||||
if (vnodeProcessDeleteReq(pVnode, version, pReq, len, pRsp) < 0) goto _err;
|
||||
break;
|
||||
case TDMT_VND_BATCH_DEL:
|
||||
if (vnodeProcessBatchDeleteReq(pVnode, version, pReq, len, pRsp) < 0) goto _err;
|
||||
break;
|
||||
/* TQ */
|
||||
case TDMT_VND_MQ_VG_CHANGE:
|
||||
if (tqProcessVgChangeReq(pVnode->pTq, POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)),
|
||||
|
@ -204,7 +208,7 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
break;
|
||||
case TDMT_VND_MQ_COMMIT_OFFSET:
|
||||
if (tqProcessOffsetCommitReq(pVnode->pTq, POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)),
|
||||
pMsg->contLen - sizeof(SMsgHead)) < 0) {
|
||||
pMsg->contLen - sizeof(SMsgHead), version) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
break;
|
||||
|
@ -1053,6 +1057,23 @@ static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t version, void
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessBatchDeleteReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
SBatchDeleteReq deleteReq;
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, pReq, len);
|
||||
tDecodeSBatchDeleteReq(&decoder, &deleteReq);
|
||||
|
||||
int32_t sz = taosArrayGetSize(deleteReq.deleteReqs);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSingleDeleteReq *pOneReq = taosArrayGet(deleteReq.deleteReqs, i);
|
||||
int32_t code = tsdbDeleteTableData(pVnode->pTsdb, version, deleteReq.suid, pOneReq->uid, pOneReq->ts, pOneReq->ts);
|
||||
if (code) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessDeleteReq(SVnode *pVnode, int64_t version, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
int32_t code = 0;
|
||||
SDecoder *pCoder = &(SDecoder){0};
|
||||
|
|
|
@ -672,6 +672,18 @@ static void vnodeRestoreFinish(struct SSyncFSM *pFsm) {
|
|||
vDebug("vgId:%d, sync restore finished", pVnode->config.vgId);
|
||||
}
|
||||
|
||||
static void vnodeBecomeFollower(struct SSyncFSM *pFsm) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
vDebug("vgId:%d, become follower", pVnode->config.vgId);
|
||||
|
||||
// clear old leader resource
|
||||
}
|
||||
|
||||
static void vnodeBecomeLeader(struct SSyncFSM *pFsm) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
vDebug("vgId:%d, become leader", pVnode->config.vgId);
|
||||
}
|
||||
|
||||
static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
||||
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
||||
pFsm->data = pVnode;
|
||||
|
@ -681,6 +693,8 @@ static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
|||
pFsm->FpGetSnapshotInfo = vnodeSyncGetSnapshot;
|
||||
pFsm->FpRestoreFinishCb = vnodeRestoreFinish;
|
||||
pFsm->FpLeaderTransferCb = vnodeLeaderTransfer;
|
||||
pFsm->FpBecomeLeaderCb = vnodeBecomeLeader;
|
||||
pFsm->FpBecomeFollowerCb = vnodeBecomeFollower;
|
||||
pFsm->FpReConfigCb = vnodeSyncReconfig;
|
||||
pFsm->FpSnapshotStartRead = vnodeSnapshotStartRead;
|
||||
pFsm->FpSnapshotStopRead = vnodeSnapshotStopRead;
|
||||
|
|
|
@ -43,12 +43,14 @@ extern "C" {
|
|||
#define EXPLAIN_GROUP_SORT_FORMAT "Group Sort"
|
||||
#define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s"
|
||||
#define EXPLAIN_MERGE_INTERVAL_FORMAT "Merge Interval on Column %s"
|
||||
#define EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT "Merge Aligned Interval on Column %s"
|
||||
#define EXPLAIN_FILL_FORMAT "Fill"
|
||||
#define EXPLAIN_SESSION_FORMAT "Session"
|
||||
#define EXPLAIN_STATE_WINDOW_FORMAT "StateWindow on Column %s"
|
||||
#define EXPLAIN_PARITION_FORMAT "Partition on Column %s"
|
||||
#define EXPLAIN_ORDER_FORMAT "Order: %s"
|
||||
#define EXPLAIN_FILTER_FORMAT "Filter: "
|
||||
#define EXPLAIN_MERGEBLOCKS_FORMAT "Merge ResBlocks: %s"
|
||||
#define EXPLAIN_FILL_VALUE_FORMAT "Fill Values: "
|
||||
#define EXPLAIN_ON_CONDITIONS_FORMAT "Join Cond: "
|
||||
#define EXPLAIN_TIMERANGE_FORMAT "Time Range: [%" PRId64 ", %" PRId64 "]"
|
||||
|
@ -56,9 +58,11 @@ extern "C" {
|
|||
#define EXPLAIN_TIME_WINDOWS_FORMAT "Time Window: interval=%" PRId64 "%c offset=%" PRId64 "%c sliding=%" PRId64 "%c"
|
||||
#define EXPLAIN_WINDOW_FORMAT "Window: gap=%" PRId64
|
||||
#define EXPLAIN_RATIO_TIME_FORMAT "Ratio: %f"
|
||||
#define EXPLAIN_MERGE_FORMAT "Merge"
|
||||
#define EXPLAIN_MERGE_FORMAT "SortMerge"
|
||||
#define EXPLAIN_MERGE_KEYS_FORMAT "Merge Key: "
|
||||
#define EXPLAIN_IGNORE_GROUPID_FORMAT "Ignore Group Id: %s"
|
||||
#define EXPLAIN_PARTITION_KETS_FORMAT "Partition Key: "
|
||||
#define EXPLAIN_INTERP_FORMAT "Interp"
|
||||
|
||||
#define EXPLAIN_PLANNING_TIME_FORMAT "Planning Time: %.3f ms"
|
||||
#define EXPLAIN_EXEC_TIME_FORMAT "Execution Time: %.3f ms"
|
||||
|
@ -69,6 +73,7 @@ extern "C" {
|
|||
#define EXPLAIN_LEFT_PARENTHESIS_FORMAT " ("
|
||||
#define EXPLAIN_RIGHT_PARENTHESIS_FORMAT ")"
|
||||
#define EXPLAIN_BLANK_FORMAT " "
|
||||
#define EXPLAIN_COMMA_FORMAT ", "
|
||||
#define EXPLAIN_COST_FORMAT "cost=%.2f..%.2f"
|
||||
#define EXPLAIN_ROWS_FORMAT "rows=%" PRIu64
|
||||
#define EXPLAIN_COLUMNS_FORMAT "columns=%d"
|
||||
|
@ -86,6 +91,7 @@ extern "C" {
|
|||
#define EXPLAIN_OUTPUT_ORDER_TYPE_FORMAT "output_order=%s"
|
||||
#define EXPLAIN_OFFSET_FORMAT "offset=%d"
|
||||
#define EXPLAIN_SOFFSET_FORMAT "soffset=%d"
|
||||
#define EXPLAIN_PARTITIONS_FORMAT "partitions=%d"
|
||||
|
||||
#define COMMAND_RESET_LOG "resetLog"
|
||||
#define COMMAND_SCHEDULE_POLICY "schedulePolicy"
|
||||
|
|
|
@ -535,6 +535,13 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (NULL != pTblScanNode->pGroupTags) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pTblScanNode->pGroupTags->length);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
if (pTblScanNode->scan.node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
|
@ -617,13 +624,17 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pPrjNode->mergeDataBlock? "True":"False");
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pPrjNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -707,7 +718,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pAggNode->mergeDataBlock? "True":"False");
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -906,13 +921,17 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL: {
|
||||
SMergeAlignedIntervalPhysiNode *pIntNode = (SMergeAlignedIntervalPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_MERGE_ALIGNED_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
|
@ -950,7 +969,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGEBLOCKS_FORMAT, pIntNode->window.mergeDataBlock? "True":"False");
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1122,6 +1145,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_PARTITION_KETS_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_PARTITIONS_FORMAT, pPartNode->pPartitionKeys->length);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
if (pPartNode->node.pConditions) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||
QRY_ERR_RET(nodesNodeToSQL(pPartNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE,
|
||||
|
@ -1194,11 +1222,20 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_MERGE_KEYS_FORMAT);
|
||||
if (pMergeNode->groupSort) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, "_group_id asc");
|
||||
if (LIST_LENGTH(pMergeNode->pMergeKeys) > 0) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
|
||||
}
|
||||
}
|
||||
for (int32_t i = 0; i < LIST_LENGTH(pMergeNode->pMergeKeys); ++i) {
|
||||
SOrderByExprNode *ptn = (SOrderByExprNode *)nodesListGetNode(pMergeNode->pMergeKeys, i);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, nodesGetNameFromColumnNode(ptn->pExpr));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_STRING_TYPE_FORMAT, EXPLAIN_ORDER_STRING(ptn->order));
|
||||
if (i != LIST_LENGTH(pMergeNode->pMergeKeys) - 1) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COMMA_FORMAT);
|
||||
}
|
||||
}
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
@ -1410,7 +1447,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC: {
|
||||
SInterpFuncPhysiNode *pInterpNode = (SInterpFuncPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERP_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
|
|
|
@ -266,7 +266,11 @@ typedef struct SExchangeInfo {
|
|||
SArray* pSourceDataInfo;
|
||||
tsem_t ready;
|
||||
void* pTransporter;
|
||||
SSDataBlock* pResult;
|
||||
// SArray<SSDataBlock*>, result block list, used to keep the multi-block that
|
||||
// passed by downstream operator
|
||||
SArray* pResultBlockList;
|
||||
int32_t rspBlockIndex; // indicate the return block index in pResultBlockList
|
||||
SSDataBlock* pDummyBlock; // dummy block, not keep data
|
||||
bool seqLoadData; // sequential load data or not, false by default
|
||||
int32_t current;
|
||||
SLoadRemoteDataInfo loadInfo;
|
||||
|
@ -520,6 +524,7 @@ typedef struct SBlockDistInfo {
|
|||
typedef struct SOptrBasicInfo {
|
||||
SResultRowInfo resultRowInfo;
|
||||
SSDataBlock* pRes;
|
||||
bool mergeResultBlock;
|
||||
} SOptrBasicInfo;
|
||||
|
||||
typedef struct SIntervalAggOperatorInfo {
|
||||
|
@ -554,8 +559,6 @@ typedef struct SMergeAlignedIntervalAggOperatorInfo {
|
|||
uint64_t groupId; // current groupId
|
||||
int64_t curTs; // current ts
|
||||
SSDataBlock* prefetchedBlock;
|
||||
bool inputBlocksFinished;
|
||||
|
||||
SNode* pCondition;
|
||||
} SMergeAlignedIntervalAggOperatorInfo;
|
||||
|
||||
|
@ -594,7 +597,6 @@ typedef struct SAggOperatorInfo {
|
|||
uint64_t groupId;
|
||||
SGroupResInfo groupResInfo;
|
||||
SExprSupp scalarExprSup;
|
||||
|
||||
SNode *pCondition;
|
||||
} SAggOperatorInfo;
|
||||
|
||||
|
@ -861,9 +863,10 @@ void initLimitInfo(const SNode* pLimit, const SNode* pSLimit, SLimitInfo* pLi
|
|||
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset,
|
||||
int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput, int32_t order);
|
||||
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
|
||||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList);
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, int32_t numOfOutput, SArray* pColList, char** pNextStart);
|
||||
void updateLoadRemoteInfo(SLoadRemoteDataInfo *pInfo, int32_t numOfRows, int32_t dataLen, int64_t startTs,
|
||||
SOperatorInfo* pOperator);
|
||||
|
||||
STimeWindow getFirstQualifiedTimeWindow(int64_t ts, STimeWindow* pWindow, SInterval* pInterval, int32_t order);
|
||||
|
||||
int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag);
|
||||
|
@ -898,7 +901,7 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi
|
|||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode *pScanPhyNode, const char* pUser, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SNode* pCondition, SExprInfo* pScalarExprInfo,
|
||||
int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo);
|
||||
int32_t numOfScalarExpr, bool mergeResult, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhysiNode *pNode, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
|
@ -913,14 +916,14 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
|
||||
SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
SExecTaskInfo* pTaskInfo);
|
||||
bool mergeResultBlock, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
SNode* pCondition, SExecTaskInfo* pTaskInfo);
|
||||
SNode* pCondition, bool mergeResultBlocks, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
|
||||
SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, int32_t numOfChild);
|
||||
SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
SExecTaskInfo* pTaskInfo, int32_t numOfChild);
|
||||
SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
STimeWindowAggSupp *pTwAggSupp, SExecTaskInfo* pTaskInfo);
|
||||
|
@ -1015,6 +1018,7 @@ bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap);
|
|||
int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs,
|
||||
TSKEY* pEndTs, int32_t rows, int32_t start, int64_t gap, SHashObj* pStDeleted);
|
||||
bool functionNeedToExecute(SqlFunctionCtx* pCtx);
|
||||
bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup);
|
||||
bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup);
|
||||
bool isDeletedWindow(STimeWindow* pWin, uint64_t groupId, SAggSupporter* pSup);
|
||||
void appendOneRow(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid);
|
||||
|
|
|
@ -50,7 +50,7 @@ SOperatorInfo* createLastrowScanOperator(SLastRowScanPhysiNode* pScanNode, SRead
|
|||
|
||||
STableListInfo* pTableList = &pTaskInfo->tableqinfoList;
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, 1024);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
|
||||
pInfo->pUidList = taosArrayInit(4, sizeof(int64_t));
|
||||
|
||||
|
|
|
@ -69,10 +69,10 @@ static bool needCompress(const SSDataBlock* pData, int32_t numOfCols) {
|
|||
|
||||
// clang-format off
|
||||
// data format:
|
||||
// +----------------+--------------+-----------------+--------------------------------------------+------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// |SDataCacheEntry | total length | group id | col1_schema | col2_schema | col3_schema... | column#1 length, column#2 length...| col1 bitmap | col1 data | col2 bitmap | col2 data | .... | | (4 bytes) |(8 bytes)
|
||||
// | |sizeof(int32) |sizeof(uint64_t) |(sizeof(int16_t)+sizeof(int32_t))*numOfCols | sizeof(int32_t) * numOfCols | actual size | |
|
||||
// +----------------+--------------+-----------------+--------------------------------------------+------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// +----------------+------------------+--------------+--------------+------------------+--------------------------------------------+------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// |SDataCacheEntry | version | total length | numOfRows | group id | col1_schema | col2_schema | col3_schema... | column#1 length, column#2 length...| col1 bitmap | col1 data | col2 bitmap | col2 data | .... | | (4 bytes) |(8 bytes)
|
||||
// | | sizeof(int32_t) |sizeof(int32) | sizeof(int32)| sizeof(uint64_t) | (sizeof(int8_t)+sizeof(int32_t))*numOfCols | sizeof(int32_t) * numOfCols | actual size | |
|
||||
// +----------------+------------------+--------------+--------------+------------------+--------------------------------------------+------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// The length of bitmap is decided by number of rows of this data block, and the length of each column data is
|
||||
// recorded in the first segment, next to the struct header
|
||||
// clang-format on
|
||||
|
|
|
@ -213,6 +213,10 @@ int32_t dataBlockToSubmit(SDataInserterHandle* pInserter, SSubmitReq** pReq) {
|
|||
tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, data, true, pColumn->offset, k);
|
||||
}
|
||||
}
|
||||
if(!fullCol) {
|
||||
rb.hasNone = true;
|
||||
}
|
||||
tdSRowEnd(&rb);
|
||||
|
||||
if (ignoreRow) {
|
||||
continue;
|
||||
|
|
|
@ -348,12 +348,14 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
taosThreadOnce(&initPoolOnce, initRefPool);
|
||||
atexit(cleanupRefPool);
|
||||
|
||||
qDebug("start to create subplan task, TID:0x%"PRIx64 " QID:0x%"PRIx64, taskId, pSubplan->id.queryId);
|
||||
|
||||
int32_t code = createExecTaskInfoImpl(pSubplan, pTask, readHandle, taskId, sql, model);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SDataSinkMgtCfg cfg = {.maxDataBlockNum = 1000, .maxDataBlockNumPerQuery = 100};
|
||||
SDataSinkMgtCfg cfg = {.maxDataBlockNum = 10000, .maxDataBlockNumPerQuery = 5000};
|
||||
code = dsDataSinkMgtInit(&cfg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
|
@ -372,6 +374,8 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
}
|
||||
}
|
||||
|
||||
qDebug("subplan task create completed, TID:0x%"PRIx64 " QID:0x%"PRIx64, taskId, pSubplan->id.queryId);
|
||||
|
||||
_error:
|
||||
// if failed to add ref for all tables in this query, abort current query
|
||||
return code;
|
||||
|
@ -422,6 +426,80 @@ int waitMoment(SQInfo* pQInfo) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static void freeBlock(void* param) {
|
||||
SSDataBlock* pBlock = *(SSDataBlock**) param;
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
|
||||
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
int64_t threadId = taosGetSelfPthreadId();
|
||||
|
||||
taosArrayClearEx(pResList, freeBlock);
|
||||
|
||||
int64_t curOwner = 0;
|
||||
if ((curOwner = atomic_val_compare_exchange_64(&pTaskInfo->owner, 0, threadId)) != 0) {
|
||||
qError("%s-%p execTask is now executed by thread:%p", GET_TASKID(pTaskInfo), pTaskInfo, (void*)curOwner);
|
||||
pTaskInfo->code = TSDB_CODE_QRY_IN_EXEC;
|
||||
return pTaskInfo->code;
|
||||
}
|
||||
|
||||
if (pTaskInfo->cost.start == 0) {
|
||||
pTaskInfo->cost.start = taosGetTimestampMs();
|
||||
}
|
||||
|
||||
if (isTaskKilled(pTaskInfo)) {
|
||||
atomic_store_64(&pTaskInfo->owner, 0);
|
||||
qDebug("%s already killed, abort", GET_TASKID(pTaskInfo));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// error occurs, record the error code and return to client
|
||||
int32_t ret = setjmp(pTaskInfo->env);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pTaskInfo->code = ret;
|
||||
cleanUpUdfs();
|
||||
qDebug("%s task abort due to error/cancel occurs, code:%s", GET_TASKID(pTaskInfo), tstrerror(pTaskInfo->code));
|
||||
atomic_store_64(&pTaskInfo->owner, 0);
|
||||
|
||||
return pTaskInfo->code;
|
||||
}
|
||||
|
||||
qDebug("%s execTask is launched", GET_TASKID(pTaskInfo));
|
||||
|
||||
int32_t current = 0;
|
||||
SSDataBlock* pRes = NULL;
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
while((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) {
|
||||
SSDataBlock* p = createOneDataBlock(pRes, true);
|
||||
current += p->info.rows;
|
||||
ASSERT(p->info.rows > 0);
|
||||
taosArrayPush(pResList, &p);
|
||||
|
||||
if (current >= 4096) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t el = (taosGetTimestampUs() - st);
|
||||
|
||||
pTaskInfo->cost.elapsedTime += el;
|
||||
if (NULL == pRes) {
|
||||
*useconds = pTaskInfo->cost.elapsedTime;
|
||||
}
|
||||
|
||||
cleanUpUdfs();
|
||||
uint64_t total = pTaskInfo->pRoot->resultInfo.totalRows;
|
||||
|
||||
qDebug("%s task suspended, %d rows in %d blocks returned, total:%" PRId64 " rows, in sinkNode:%d, elapsed:%.2f ms",
|
||||
GET_TASKID(pTaskInfo), current, (int32_t) taosArrayGetSize(pResList), total, 0, el / 1000.0);
|
||||
|
||||
atomic_store_64(&pTaskInfo->owner, 0);
|
||||
return pTaskInfo->code;
|
||||
}
|
||||
|
||||
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t* useconds) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
int64_t threadId = taosGetSelfPthreadId();
|
||||
|
|
|
@ -88,7 +88,7 @@ static int32_t getExprFunctionId(SExprInfo* pExprInfo) {
|
|||
|
||||
static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes);
|
||||
|
||||
static void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExpr, SSDataBlock* pSDataBlock);
|
||||
static void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExpr, SSDataBlock* pSDataBlock);
|
||||
|
||||
static void releaseQueryBuf(size_t numOfTables);
|
||||
|
||||
|
@ -136,9 +136,8 @@ SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn,
|
|||
|
||||
void operatorDummyCloseFn(void* param, int32_t numOfCols) {}
|
||||
|
||||
static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo,
|
||||
SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset,
|
||||
SqlFunctionCtx* pCtx, int32_t numOfExprs);
|
||||
static int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
||||
SGroupResInfo* pGroupResInfo);
|
||||
|
||||
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
|
||||
static void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t groupId);
|
||||
|
@ -434,7 +433,8 @@ static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pC
|
|||
for (int32_t i = 0; i < pOperator->exprSupp.numOfExprs; ++i) {
|
||||
pCtx[i].order = order;
|
||||
pCtx[i].input.numOfRows = pBlock->info.rows;
|
||||
setBlockStatisInfo(&pCtx[i], &pOperator->exprSupp.pExprInfo[i], pBlock);
|
||||
setBlockSMAInfo(&pCtx[i], &pOperator->exprSupp.pExprInfo[i], pBlock);
|
||||
pCtx[i].pSrcBlock = pBlock;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,7 +799,7 @@ static int32_t doCreateConstantValColumnAggInfo(SInputColumnInfoData* pInput, SF
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setBlockStatisInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pBlock) {
|
||||
void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pBlock) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
@ -1012,16 +1012,6 @@ static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
|
|||
// }
|
||||
//}
|
||||
|
||||
// static FORCE_INLINE bool doFilterByBlockStatistics(STaskRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis,
|
||||
// SqlFunctionCtx *pCtx, int32_t numOfRows) {
|
||||
// STaskAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
//
|
||||
// if (pDataStatis == NULL || pQueryAttr->pFilters == NULL) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return filterRangeExecute(pQueryAttr->pFilters, pDataStatis, pQueryAttr->numOfCols, numOfRows);
|
||||
// }
|
||||
#if 0
|
||||
static bool overlapWithTimeWindow(STaskAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) {
|
||||
STimeWindow w = {0};
|
||||
|
@ -1216,7 +1206,7 @@ int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableSc
|
|||
}
|
||||
|
||||
// current block has been discard due to filter applied
|
||||
// if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
|
||||
// if (!doFilterByBlockSMA(pRuntimeEnv, pBlock->pBlockAgg, pTableScanInfo->pCtx, pBlockInfo->rows)) {
|
||||
// pCost->skipBlocks += 1;
|
||||
// qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey,
|
||||
// pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
|
@ -1287,8 +1277,12 @@ void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
|
|||
}
|
||||
|
||||
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset) {
|
||||
bool init = false;
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
pCtx[i].resultInfo = getResultEntryInfo(pResult, i, rowEntryInfoOffset);
|
||||
if (init) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo;
|
||||
if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
|
||||
|
@ -1305,6 +1299,8 @@ void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numO
|
|||
} else {
|
||||
pResInfo->initialized = true;
|
||||
}
|
||||
} else {
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1512,19 +1508,24 @@ int32_t finalizeResultRowIntoResultDataBlock(SDiskbasedBuf* pBuf, SResultRowPosi
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
|
||||
SGroupResInfo* pGroupResInfo, const int32_t* rowCellOffset, SqlFunctionCtx* pCtx,
|
||||
int32_t numOfExprs) {
|
||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||
int32_t start = pGroupResInfo->index;
|
||||
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
||||
SGroupResInfo* pGroupResInfo) {
|
||||
SExprInfo* pExprInfo = pSup->pExprInfo;
|
||||
int32_t numOfExprs = pSup->numOfExprs;
|
||||
int32_t* rowEntryOffset = pSup->rowEntryInfoOffset;
|
||||
SqlFunctionCtx* pCtx = pSup->pCtx;
|
||||
|
||||
for (int32_t i = start; i < numOfRows; i += 1) {
|
||||
int32_t numOfRows = getNumOfTotalRes(pGroupResInfo);
|
||||
|
||||
for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) {
|
||||
SResKeyPos* pPos = taosArrayGetP(pGroupResInfo->pRows, i);
|
||||
SFilePage* page = getBufPage(pBuf, pPos->pos.pageId);
|
||||
|
||||
SResultRow* pRow = (SResultRow*)((char*)page + pPos->pos.offset);
|
||||
|
||||
doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowCellOffset);
|
||||
doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset);
|
||||
|
||||
// no results, continue to check the next one
|
||||
if (pRow->numOfRows == 0) {
|
||||
pGroupResInfo->index += 1;
|
||||
releaseBufPage(pBuf, page);
|
||||
|
@ -1542,6 +1543,7 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
|||
}
|
||||
|
||||
if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
|
||||
ASSERT(pBlock->info.rows > 0);
|
||||
releaseBufPage(pBuf, page);
|
||||
break;
|
||||
}
|
||||
|
@ -1551,7 +1553,7 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
|||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||
int32_t slotId = pExprInfo[j].base.resSchema.slotId;
|
||||
|
||||
pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowCellOffset);
|
||||
pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset);
|
||||
if (pCtx[j].fpSet.finalize) {
|
||||
#ifdef BUF_PAGE_DEBUG
|
||||
qDebug("\npage_finalize %d", numOfExprs);
|
||||
|
@ -1584,26 +1586,19 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI
|
|||
|
||||
releaseBufPage(pBuf, page);
|
||||
pBlock->info.rows += pRow->numOfRows;
|
||||
// if (pBlock->info.rows >= pBlock->info.capacity) { // output buffer is full
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
qDebug("%s result generated, rows:%d, groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
||||
pBlock->info.groupId);
|
||||
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
|
||||
SDiskbasedBuf* pBuf) {
|
||||
SExprInfo* pExprInfo = pOperator->exprSupp.pExprInfo;
|
||||
int32_t numOfExprs = pOperator->exprSupp.numOfExprs;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
int32_t* rowCellOffset = pOperator->exprSupp.rowEntryInfoOffset;
|
||||
SSDataBlock* pBlock = pbInfo->pRes;
|
||||
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
||||
SSDataBlock* pBlock = pbInfo->pRes;
|
||||
|
||||
// set output datablock version
|
||||
pBlock->info.version = pTaskInfo->version;
|
||||
|
@ -1615,30 +1610,22 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
|
|||
|
||||
// clear the existed group id
|
||||
pBlock->info.groupId = 0;
|
||||
doCopyToSDataBlock(pTaskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, rowCellOffset, pCtx, numOfExprs);
|
||||
}
|
||||
|
||||
static void updateNumOfRowsInResultRows(SqlFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo,
|
||||
int32_t* rowEntryInfoOffset) {
|
||||
// update the number of result for each, only update the number of rows for the corresponding window result.
|
||||
// if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) {
|
||||
// return;
|
||||
// }
|
||||
#if 0
|
||||
for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
SResultRow* pResult = pResultRowInfo->pResult[i];
|
||||
|
||||
for (int32_t j = 0; j < numOfOutput; ++j) {
|
||||
int32_t functionId = pCtx[j].functionId;
|
||||
if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
|
||||
continue;
|
||||
if (!pbInfo->mergeResultBlock) {
|
||||
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
|
||||
} else {
|
||||
while(hasRemainResults(pGroupResInfo)) {
|
||||
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
|
||||
if (pBlock->info.rows >= pOperator->resultInfo.threshold) {
|
||||
break;
|
||||
}
|
||||
|
||||
SResultRowEntryInfo* pCell = getResultEntryInfo(pResult, j, rowEntryInfoOffset);
|
||||
pResult->numOfRows = (uint16_t)(TMAX(pResult->numOfRows, pCell->numOfRes));
|
||||
// clearing group id to continue to merge data that belong to different groups
|
||||
pBlock->info.groupId = 0;
|
||||
}
|
||||
|
||||
// clear the group id info in SSDataBlock, since the client does not need it
|
||||
pBlock->info.groupId = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data, int8_t compressed) {
|
||||
|
@ -1976,9 +1963,11 @@ int32_t loadRemoteDataCallback(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
pRsp->compLen = htonl(pRsp->compLen);
|
||||
pRsp->numOfCols = htonl(pRsp->numOfCols);
|
||||
pRsp->useconds = htobe64(pRsp->useconds);
|
||||
pRsp->numOfBlocks = htonl(pRsp->numOfBlocks);
|
||||
|
||||
ASSERT(pRsp != NULL);
|
||||
qDebug("%s fetch rsp received, index:%d, rows:%d", pSourceDataInfo->taskId, index, pRsp->numOfRows);
|
||||
qDebug("%s fetch rsp received, index:%d, blocks:%d, rows:%d", pSourceDataInfo->taskId, index, pRsp->numOfBlocks,
|
||||
pRsp->numOfRows);
|
||||
} else {
|
||||
pSourceDataInfo->code = code;
|
||||
qDebug("%s fetch rsp received, index:%d, error:%d", pSourceDataInfo->taskId, index, tstrerror(code));
|
||||
|
@ -2062,13 +2051,19 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
|
||||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList) {
|
||||
void updateLoadRemoteInfo(SLoadRemoteDataInfo* pInfo, int32_t numOfRows, int32_t dataLen, int64_t startTs,
|
||||
SOperatorInfo* pOperator) {
|
||||
pInfo->totalRows += numOfRows;
|
||||
pInfo->totalSize += dataLen;
|
||||
pInfo->totalElapsed += (taosGetTimestampUs() - startTs);
|
||||
pOperator->resultInfo.totalRows += numOfRows;
|
||||
}
|
||||
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, char* pData, int32_t numOfOutput, SArray* pColList,
|
||||
char** pNextStart) {
|
||||
if (pColList == NULL) { // data from other sources
|
||||
blockDataCleanup(pRes);
|
||||
// blockDataEnsureCapacity(pRes, numOfRows);
|
||||
blockDecode(pRes, numOfOutput, numOfRows, pData);
|
||||
*pNextStart = (char*) blockDecode(pRes, pData);
|
||||
} else { // extract data according to pColList
|
||||
ASSERT(numOfOutput == taosArrayGetSize(pColList));
|
||||
char* pStart = pData;
|
||||
|
@ -2092,28 +2087,17 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLo
|
|||
blockDataAppendColInfo(pBlock, &idata);
|
||||
}
|
||||
|
||||
blockDecode(pBlock, numOfCols, numOfRows, pStart);
|
||||
blockDataEnsureCapacity(pRes, numOfRows);
|
||||
blockDecode(pBlock, pStart);
|
||||
blockDataEnsureCapacity(pRes, pBlock->info.rows);
|
||||
|
||||
// data from mnode
|
||||
pRes->info.rows = numOfRows;
|
||||
pRes->info.rows = pBlock->info.rows;
|
||||
relocateColumnData(pRes, pColList, pBlock->pDataBlock, false);
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
|
||||
// todo move this to time window aggregator, since the primary timestamp may not be known by exchange operator.
|
||||
blockDataUpdateTsWindow(pRes, 0);
|
||||
|
||||
int64_t el = taosGetTimestampUs() - startTs;
|
||||
|
||||
pLoadInfo->totalRows += numOfRows;
|
||||
pLoadInfo->totalSize += compLen;
|
||||
|
||||
if (total != NULL) {
|
||||
*total += numOfRows;
|
||||
}
|
||||
|
||||
pLoadInfo->totalElapsed += el;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2135,8 +2119,8 @@ static void* setAllSourcesCompleted(SOperatorInfo* pOperator, int64_t startTs) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeInfo* pExchangeInfo,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
int32_t code = 0;
|
||||
int64_t startTs = taosGetTimestampUs();
|
||||
size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
|
||||
|
@ -2162,7 +2146,6 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
||||
SDownstreamSourceNode* pSource = taosArrayGet(pExchangeInfo->pSources, i);
|
||||
|
||||
SSDataBlock* pRes = pExchangeInfo->pResult;
|
||||
SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
|
||||
if (pRsp->numOfRows == 0) {
|
||||
qDebug("%s vgId:%d, taskId:0x%" PRIx64 " execId:%d index:%d completed, rowsOfSource:%" PRIu64
|
||||
|
@ -2175,29 +2158,35 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
continue;
|
||||
}
|
||||
|
||||
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
|
||||
code =
|
||||
extractDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
if (code != 0) {
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
goto _error;
|
||||
SRetrieveTableRsp* pRetrieveRsp = pDataInfo->pRsp;
|
||||
int32_t index = 0;
|
||||
char* pStart = pRetrieveRsp->data;
|
||||
while(index++ < pRetrieveRsp->numOfBlocks) {
|
||||
SSDataBlock* pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false);
|
||||
code = extractDataBlockFromFetchRsp(pb, pStart, pRetrieveRsp->numOfCols, NULL, &pStart);
|
||||
if (code != 0) {
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
goto _error;
|
||||
}
|
||||
|
||||
taosArrayPush(pExchangeInfo->pResultBlockList, &pb);
|
||||
}
|
||||
|
||||
updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, startTs, pOperator);
|
||||
|
||||
if (pRsp->completed == 1) {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64
|
||||
" execId:%d"
|
||||
" index:%d completed, numOfRows:%d, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64 ", totalBytes:%" PRIu64
|
||||
", completed:%d try next %d/%" PRIzu,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, i, pRes->info.rows,
|
||||
pDataInfo->totalRows, pLoadInfo->totalRows, pLoadInfo->totalSize, completed + 1, i + 1, totalSources);
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d"
|
||||
" index:%d completed, blocks:%d, numOfRows:%d, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64 ", total:%.2f Kb,"
|
||||
" completed:%d try next %d/%" PRIzu,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, i, pRsp->numOfBlocks,
|
||||
pRsp->numOfRows, pDataInfo->totalRows, pLoadInfo->totalRows, pLoadInfo->totalSize / 1024.0,
|
||||
completed + 1, i + 1, totalSources);
|
||||
completed += 1;
|
||||
pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
|
||||
} else {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d numOfRows:%d, totalRows:%" PRIu64
|
||||
", totalBytes:%" PRIu64,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, pRes->info.rows,
|
||||
pLoadInfo->totalRows, pLoadInfo->totalSize);
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d blocks:%d, numOfRows:%d, totalRows:%" PRIu64
|
||||
", total:%.2f Kb", GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId,
|
||||
pRsp->numOfBlocks, pRsp->numOfRows, pLoadInfo->totalRows, pLoadInfo->totalSize/1024.0);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
|
@ -2211,11 +2200,12 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
}
|
||||
}
|
||||
|
||||
return pExchangeInfo->pResult;
|
||||
return;
|
||||
}
|
||||
|
||||
if (completed == totalSources) {
|
||||
return setAllSourcesCompleted(pOperator, startTs);
|
||||
setAllSourcesCompleted(pOperator, startTs);
|
||||
return;
|
||||
}
|
||||
|
||||
sched_yield();
|
||||
|
@ -2223,7 +2213,6 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
|
||||
_error:
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
|
||||
|
@ -2253,7 +2242,7 @@ static int32_t prepareConcurrentlyLoad(SOperatorInfo* pOperator) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
||||
static int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
|
||||
SExchangeInfo* pExchangeInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
|
@ -2262,7 +2251,8 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
|
||||
while (1) {
|
||||
if (pExchangeInfo->current >= totalSources) {
|
||||
return setAllSourcesCompleted(pOperator, startTs);
|
||||
setAllSourcesCompleted(pOperator, startTs);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
doSendFetchDataRequest(pExchangeInfo, pTaskInfo, pExchangeInfo->current);
|
||||
|
@ -2275,7 +2265,7 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
qError("%s vgId:%d, taskID:0x%" PRIx64 " execId:%d error happens, code:%s", GET_TASKID(pTaskInfo),
|
||||
pSource->addr.nodeId, pSource->taskId, pSource->execId, tstrerror(pDataInfo->code));
|
||||
pOperator->pTaskInfo->code = pDataInfo->code;
|
||||
return NULL;
|
||||
return pOperator->pTaskInfo->code;
|
||||
}
|
||||
|
||||
SRetrieveTableRsp* pRsp = pDataInfo->pRsp;
|
||||
|
@ -2292,16 +2282,15 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
continue;
|
||||
}
|
||||
|
||||
SSDataBlock* pRes = pExchangeInfo->pResult;
|
||||
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
|
||||
int32_t code =
|
||||
extractDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
SRetrieveTableRsp* pRetrieveRsp = pDataInfo->pRsp;
|
||||
|
||||
char* pStart = pRetrieveRsp->data;
|
||||
int32_t code = extractDataBlockFromFetchRsp(NULL, pStart, pRetrieveRsp->numOfCols, NULL, &pStart);
|
||||
|
||||
if (pRsp->completed == 1) {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d numOfRows:%d, rowsOfSource:%" PRIu64
|
||||
", totalRows:%" PRIu64 ", totalBytes:%" PRIu64 " try next %d/%" PRIzu,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, pRes->info.rows,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, pRetrieveRsp->numOfRows,
|
||||
pDataInfo->totalRows, pLoadInfo->totalRows, pLoadInfo->totalSize, pExchangeInfo->current + 1,
|
||||
totalSources);
|
||||
|
||||
|
@ -2310,13 +2299,15 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
} else {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " execId:%d numOfRows:%d, totalRows:%" PRIu64
|
||||
", totalBytes:%" PRIu64,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, pRes->info.rows,
|
||||
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pSource->execId, pRetrieveRsp->numOfRows,
|
||||
pLoadInfo->totalRows, pLoadInfo->totalSize);
|
||||
}
|
||||
|
||||
pOperator->resultInfo.totalRows += pRes->info.rows;
|
||||
updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, startTs, pOperator);
|
||||
pDataInfo->totalRows += pRetrieveRsp->numOfRows;
|
||||
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
return pExchangeInfo->pResult;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2340,6 +2331,11 @@ static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void freeBlock(void* pParam) {
|
||||
SSDataBlock* pBlock = *(SSDataBlock**)pParam;
|
||||
blockDataDestroy(pBlock);
|
||||
}
|
||||
|
||||
static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) {
|
||||
SExchangeInfo* pExchangeInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -2349,9 +2345,9 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
|
||||
SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
|
||||
size_t totalSources = taosArrayGetSize(pExchangeInfo->pSources);
|
||||
|
||||
SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
qDebug("%s all %" PRIzu " source(s) are exhausted, total rows:%" PRIu64 " bytes:%" PRIu64 ", elapsed:%.2f ms",
|
||||
GET_TASKID(pTaskInfo), totalSources, pLoadInfo->totalRows, pLoadInfo->totalSize,
|
||||
|
@ -2359,11 +2355,23 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (pExchangeInfo->seqLoadData) {
|
||||
return seqLoadRemoteData(pOperator);
|
||||
} else {
|
||||
return concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
|
||||
size_t size = taosArrayGetSize(pExchangeInfo->pResultBlockList);
|
||||
if (size == 0 || pExchangeInfo->rspBlockIndex >= size) {
|
||||
pExchangeInfo->rspBlockIndex = 0;
|
||||
taosArrayClearEx(pExchangeInfo->pResultBlockList, freeBlock);
|
||||
if (pExchangeInfo->seqLoadData) {
|
||||
seqLoadRemoteData(pOperator);
|
||||
} else {
|
||||
concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo);
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pExchangeInfo->pResultBlockList) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// we have buffered retrieved datablock, return it directly
|
||||
return taosArrayGetP(pExchangeInfo->pResultBlockList, pExchangeInfo->rspBlockIndex++);
|
||||
}
|
||||
|
||||
static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator) {
|
||||
|
@ -2380,26 +2388,24 @@ static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ASSERT(pBlock == pExchangeInfo->pResult);
|
||||
|
||||
SLimitInfo* pLimitInfo = &pExchangeInfo->limitInfo;
|
||||
if (hasLimitOffsetInfo(pLimitInfo)) {
|
||||
int32_t status = handleLimitOffset(pOperator, pLimitInfo, pExchangeInfo->pResult, false);
|
||||
int32_t status = handleLimitOffset(pOperator, pLimitInfo, pBlock, false);
|
||||
if (status == PROJECT_RETRIEVE_CONTINUE) {
|
||||
continue;
|
||||
} else if (status == PROJECT_RETRIEVE_DONE) {
|
||||
size_t rows = pExchangeInfo->pResult->info.rows;
|
||||
size_t rows = pBlock->info.rows;
|
||||
pExchangeInfo->limitInfo.numOfOutputRows += rows;
|
||||
|
||||
if (rows == 0) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
} else {
|
||||
return pExchangeInfo->pResult;
|
||||
return pBlock;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return pExchangeInfo->pResult;
|
||||
return pBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2462,16 +2468,18 @@ SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode
|
|||
}
|
||||
|
||||
tsem_init(&pInfo->ready, 0, 0);
|
||||
pInfo->pDummyBlock = createResDataBlock(pExNode->node.pOutputDataBlockDesc);
|
||||
pInfo->pResultBlockList = taosArrayInit(1, POINTER_BYTES);
|
||||
|
||||
pInfo->seqLoadData = false;
|
||||
pInfo->pTransporter = pTransporter;
|
||||
pInfo->pResult = createResDataBlock(pExNode->node.pOutputDataBlockDesc);
|
||||
|
||||
pOperator->name = "ExchangeOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pResult->pDataBlock);
|
||||
pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pDummyBlock->pDataBlock);
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL,
|
||||
|
@ -2990,6 +2998,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t rows = blockDataGetNumOfRows(pInfo->pRes);
|
||||
pOperator->resultInfo.totalRows += rows;
|
||||
|
||||
|
@ -3413,6 +3422,7 @@ int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t n
|
|||
}
|
||||
int32_t code = createDiskbasedBuf(&pAggSup->pResultBuf, defaultPgsz, defaultBufsz, pKey, tsTempDir);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("Create agg result buf failed since %s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -3432,7 +3442,11 @@ int32_t initAggInfo(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInf
|
|||
return code;
|
||||
}
|
||||
|
||||
doInitAggInfoSup(pAggSup, pSup->pCtx, numOfCols, keyBufSize, pkey);
|
||||
code = doInitAggInfoSup(pAggSup, pSup->pCtx, numOfCols, keyBufSize, pkey);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
pSup->pCtx[i].pBuf = pAggSup->pResultBuf;
|
||||
}
|
||||
|
@ -3498,17 +3512,16 @@ void cleanupExprSupp(SExprSupp* pSupp) {
|
|||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResultBlock, SNode* pCondition, SExprInfo* pScalarExprInfo,
|
||||
int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo) {
|
||||
int32_t numOfScalarExpr, bool mergeResult, SExecTaskInfo* pTaskInfo) {
|
||||
SAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
int32_t numOfRows = 1024;
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
|
||||
initResultSizeInfo(&pOperator->resultInfo, numOfRows);
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
int32_t code = initAggInfo(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
|
@ -3520,6 +3533,7 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->binfo.mergeResultBlock = mergeResult;
|
||||
pInfo->groupId = UINT64_MAX;
|
||||
pInfo->pCondition = pCondition;
|
||||
pOperator->name = "TableAggregate";
|
||||
|
@ -3601,12 +3615,15 @@ void doDestroyExchangeOperatorInfo(void* param) {
|
|||
|
||||
taosArrayDestroy(pExInfo->pSources);
|
||||
taosArrayDestroy(pExInfo->pSourceDataInfo);
|
||||
if (pExInfo->pResult != NULL) {
|
||||
pExInfo->pResult = blockDataDestroy(pExInfo->pResult);
|
||||
|
||||
if (pExInfo->pResultBlockList != NULL) {
|
||||
taosArrayDestroyEx(pExInfo->pResultBlockList, freeBlock);
|
||||
pExInfo->pResultBlockList = NULL;
|
||||
}
|
||||
|
||||
tsem_destroy(&pExInfo->ready);
|
||||
blockDataDestroy(pExInfo->pDummyBlock);
|
||||
|
||||
tsem_destroy(&pExInfo->ready);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
@ -4071,7 +4088,11 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
pOperator->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
|
||||
|
||||
if (pOperator != NULL) {
|
||||
pOperator->resultDataBlockId = pPhyNode->pOutputDataBlockDesc->dataBlockId;
|
||||
}
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
|
@ -4110,7 +4131,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
pScalarExprInfo, numOfScalarExpr, pTaskInfo);
|
||||
} else {
|
||||
pOptr = createAggregateOperatorInfo(ops[0], pExprInfo, num, pResBlock, pAggNode->node.pConditions,
|
||||
pScalarExprInfo, numOfScalarExpr, pTaskInfo);
|
||||
pScalarExprInfo, numOfScalarExpr, pAggNode->mergeDataBlock, pTaskInfo);
|
||||
}
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL == type || QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL == type) {
|
||||
SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode;
|
||||
|
@ -4152,7 +4173,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
|
||||
int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
|
||||
pOptr = createMergeAlignedIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId,
|
||||
pPhyNode->pConditions, pTaskInfo);
|
||||
pPhyNode->pConditions, pIntervalPhyNode->window.mergeDataBlock, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_INTERVAL == type) {
|
||||
SMergeIntervalPhysiNode* pIntervalPhyNode = (SMergeIntervalPhysiNode*)pPhyNode;
|
||||
|
||||
|
@ -4167,7 +4188,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
.precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision};
|
||||
|
||||
int32_t tsSlotId = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId;
|
||||
pOptr = createMergeIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, pTaskInfo);
|
||||
pOptr = createMergeIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, tsSlotId, pIntervalPhyNode->window.mergeDataBlock, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL == type) {
|
||||
int32_t children = 0;
|
||||
pOptr = createStreamFinalIntervalOperatorInfo(ops[0], pPhyNode, pTaskInfo, children);
|
||||
|
|
|
@ -727,7 +727,7 @@ static void destroyPartitionOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
taosMemoryFree(pInfo->columnOffset);
|
||||
|
||||
cleanupExprSupp(&pInfo->scalarSup);
|
||||
|
||||
destroyDiskbasedBuf(pInfo->pBuf);
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,8 @@ void destroyMergeJoinOperator(void* param, int32_t numOfOutput) {
|
|||
SJoinOperatorInfo* pJoinOperator = (SJoinOperatorInfo*)param;
|
||||
nodesDestroyNode(pJoinOperator->pCondAfterMerge);
|
||||
|
||||
pJoinOperator->pRes = blockDataDestroy(pJoinOperator->pRes);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "executorimpl.h"
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "os.h"
|
||||
#include "querynodes.h"
|
||||
#include "systable.h"
|
||||
#include "tname.h"
|
||||
|
@ -227,6 +228,57 @@ static int32_t doDynamicPruneDataBlock(SOperatorInfo* pOperator, SDataBlockInfo*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool doFilterByBlockSMA(const SNode* pFilterNode, SColumnDataAgg** pColsAgg, int32_t numOfCols,
|
||||
int32_t numOfRows) {
|
||||
if (pColsAgg == NULL || pFilterNode == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SFilterInfo* filter = NULL;
|
||||
|
||||
// todo move to the initialization function
|
||||
int32_t code = filterInitFromNode((SNode*)pFilterNode, &filter, 0);
|
||||
bool keep = filterRangeExecute(filter, pColsAgg, numOfCols, numOfRows);
|
||||
|
||||
filterFreeInfo(filter);
|
||||
return keep;
|
||||
}
|
||||
|
||||
static bool doLoadBlockSMA(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo) {
|
||||
bool allColumnsHaveAgg = true;
|
||||
SColumnDataAgg** pColAgg = NULL;
|
||||
|
||||
int32_t code = tsdbRetrieveDatablockSMA(pTableScanInfo->dataReader, &pColAgg, &allColumnsHaveAgg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
if (!allColumnsHaveAgg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (allColumnsHaveAgg == true) {
|
||||
int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
||||
|
||||
// todo create this buffer during creating operator
|
||||
if (pBlock->pBlockAgg == NULL) {
|
||||
pBlock->pBlockAgg = taosMemoryCalloc(numOfCols, POINTER_BYTES);
|
||||
if (pBlock->pBlockAgg == NULL) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTableScanInfo->pColMatchInfo); ++i) {
|
||||
SColMatchInfo* pColMatchInfo = taosArrayGet(pTableScanInfo->pColMatchInfo, i);
|
||||
if (!pColMatchInfo->output) {
|
||||
continue;
|
||||
}
|
||||
pBlock->pBlockAgg[pColMatchInfo->targetSlotId] = pColAgg[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
|
||||
uint32_t* status) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -236,6 +288,7 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca
|
|||
|
||||
pCost->totalBlocks += 1;
|
||||
pCost->totalRows += pBlock->info.rows;
|
||||
bool loadSMA = false;
|
||||
|
||||
*status = pInfo->dataBlockLoadFlag;
|
||||
if (pTableScanInfo->pFilterNode != NULL ||
|
||||
|
@ -259,60 +312,50 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca
|
|||
return TSDB_CODE_SUCCESS;
|
||||
} else if (*status == FUNC_DATA_REQUIRED_STATIS_LOAD) {
|
||||
pCost->loadBlockStatis += 1;
|
||||
|
||||
bool allColumnsHaveAgg = true;
|
||||
SColumnDataAgg** pColAgg = NULL;
|
||||
|
||||
int32_t code = tsdbRetrieveDatablockSMA(pTableScanInfo->dataReader, &pColAgg, &allColumnsHaveAgg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
if (allColumnsHaveAgg == true) {
|
||||
int32_t numOfCols = taosArrayGetSize(pBlock->pDataBlock);
|
||||
|
||||
// todo create this buffer during creating operator
|
||||
if (pBlock->pBlockAgg == NULL) {
|
||||
pBlock->pBlockAgg = taosMemoryCalloc(numOfCols, POINTER_BYTES);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTableScanInfo->pColMatchInfo); ++i) {
|
||||
SColMatchInfo* pColMatchInfo = taosArrayGet(pTableScanInfo->pColMatchInfo, i);
|
||||
if (!pColMatchInfo->output) {
|
||||
continue;
|
||||
}
|
||||
pBlock->pBlockAgg[pColMatchInfo->targetSlotId] = pColAgg[i];
|
||||
}
|
||||
|
||||
loadSMA = true; // mark the operation of load sma;
|
||||
bool success = doLoadBlockSMA(pTableScanInfo, pBlock, pTaskInfo);
|
||||
if (success) { // failed to load the block sma data, data block statistics does not exist, load data block instead
|
||||
qDebug("%s data block SMA loaded, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
|
||||
pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else { // failed to load the block sma data, data block statistics does not exist, load data block instead
|
||||
} else {
|
||||
qDebug("%s failed to load SMA, since not all columns have SMA", GET_TASKID(pTaskInfo));
|
||||
*status = FUNC_DATA_REQUIRED_DATA_LOAD;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(*status == FUNC_DATA_REQUIRED_DATA_LOAD);
|
||||
|
||||
// todo filter data block according to the block sma data firstly
|
||||
// try to filter data block according to sma info
|
||||
if (pTableScanInfo->pFilterNode != NULL && (!loadSMA)) {
|
||||
bool success = doLoadBlockSMA(pTableScanInfo, pBlock, pTaskInfo);
|
||||
if (success) {
|
||||
size_t size = taosArrayGetSize(pBlock->pDataBlock);
|
||||
bool keep = doFilterByBlockSMA(pTableScanInfo->pFilterNode, pBlock->pBlockAgg, size, pBlockInfo->rows);
|
||||
if (!keep) {
|
||||
qDebug("%s data block filter out by block SMA, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
|
||||
pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
pCost->filterOutBlocks += 1;
|
||||
(*status) = FUNC_DATA_REQUIRED_FILTEROUT;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// free the sma info, since it should not be involved in later computing process.
|
||||
taosMemoryFreeClear(pBlock->pBlockAgg);
|
||||
|
||||
// try to filter data block according to current results
|
||||
doDynamicPruneDataBlock(pOperator, pBlockInfo, status);
|
||||
if (*status == FUNC_DATA_REQUIRED_NOT_LOAD) {
|
||||
qDebug("%s data block skipped, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
|
||||
qDebug("%s data block skipped due to dynamic prune, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo),
|
||||
pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
pCost->skipBlocks += 1;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!doFilterByBlockStatistics(pBlock->pBlockStatis, pTableScanInfo->pCtx, pBlockInfo->rows)) {
|
||||
pCost->filterOutBlocks += 1;
|
||||
qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo), pBlockInfo->window.skey,
|
||||
pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
(*status) = FUNC_DATA_REQUIRED_FILTEROUT;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
pCost->totalCheckedRows += pBlock->info.rows;
|
||||
pCost->loadBlocks += 1;
|
||||
|
||||
|
@ -470,6 +513,11 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
|||
pBlock->info = binfo;
|
||||
ASSERT(binfo.uid != 0);
|
||||
|
||||
uint64_t* groupId = taosHashGet(pTaskInfo->tableqinfoList.map, &pBlock->info.uid, sizeof(int64_t));
|
||||
if (groupId) {
|
||||
pBlock->info.groupId = *groupId;
|
||||
}
|
||||
|
||||
uint32_t status = 0;
|
||||
int32_t code = loadDataBlock(pOperator, pTableScanInfo, pBlock, &status);
|
||||
// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
|
||||
|
@ -482,11 +530,6 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
|||
continue;
|
||||
}
|
||||
|
||||
uint64_t* groupId = taosHashGet(pTaskInfo->tableqinfoList.map, &pBlock->info.uid, sizeof(int64_t));
|
||||
if (groupId) {
|
||||
pBlock->info.groupId = *groupId;
|
||||
}
|
||||
|
||||
pOperator->resultInfo.totalRows = pTableScanInfo->readRecorder.totalRows;
|
||||
pTableScanInfo->readRecorder.elapsedTime += (taosGetTimestampUs() - st) / 1000.0;
|
||||
|
||||
|
@ -527,7 +570,7 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) {
|
|||
if (pTableScanInfo->scanTimes < pTableScanInfo->scanInfo.numOfAsc) {
|
||||
setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
|
||||
pTableScanInfo->scanFlag = REPEAT_SCAN;
|
||||
qDebug("%s start to repeat ascending order scan data blocks due to query func required", GET_TASKID(pTaskInfo));
|
||||
qDebug("%s start to repeat ascending order scan data SELECT last_row(*),hostname from cpu group by hostname;blocks due to query func required", GET_TASKID(pTaskInfo));
|
||||
|
||||
// do prepare for the next round table scan operation
|
||||
tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond);
|
||||
|
@ -539,10 +582,9 @@ static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) {
|
|||
if (pTableScanInfo->cond.order == TSDB_ORDER_ASC) {
|
||||
prepareForDescendingScan(pTableScanInfo, pOperator->exprSupp.pCtx, 0);
|
||||
tsdbReaderReset(pTableScanInfo->dataReader, &pTableScanInfo->cond);
|
||||
qDebug("%s start to descending order scan data blocks due to query func required", GET_TASKID(pTaskInfo));
|
||||
}
|
||||
|
||||
qDebug("%s start to descending order scan data blocks due to query func required", GET_TASKID(pTaskInfo));
|
||||
|
||||
while (pTableScanInfo->scanTimes < total) {
|
||||
SSDataBlock* p = doTableScanImpl(pOperator);
|
||||
if (p != NULL) {
|
||||
|
@ -682,9 +724,6 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
|||
}
|
||||
|
||||
pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};
|
||||
// pInfo->scanInfo = (SScanInfo){.numOfAsc = 0, .numOfDesc = 1}; // for debug purpose
|
||||
// pInfo->cond.order = TSDB_ORDER_DESC;
|
||||
|
||||
pInfo->pdInfo.interval = extractIntervalInfo(pTableScanNode);
|
||||
pInfo->readHandle = *readHandle;
|
||||
pInfo->sample.sampleRatio = pTableScanNode->ratio;
|
||||
|
@ -1135,10 +1174,15 @@ static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock
|
|||
for (int32_t rowId = 0; rowId < pBlock->info.rows; rowId++) {
|
||||
SResultRowInfo dumyInfo;
|
||||
dumyInfo.cur.pageId = -1;
|
||||
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCol[rowId], &pInfo->interval, TSDB_ORDER_ASC);
|
||||
bool isClosed = false;
|
||||
STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
|
||||
if (isOverdue(tsCol[rowId], &pInfo->twAggSup)) {
|
||||
win = getActiveTimeWindow(NULL, &dumyInfo, tsCol[rowId], &pInfo->interval, TSDB_ORDER_ASC);
|
||||
isClosed = isCloseWindow(&win, &pInfo->twAggSup);
|
||||
}
|
||||
// must check update info first.
|
||||
bool update = updateInfoIsUpdated(pInfo->pUpdateInfo, pBlock->info.uid, tsCol[rowId]);
|
||||
if ((update || (isSignleIntervalWindow(pInfo) && isCloseWindow(&win, &pInfo->twAggSup) &&
|
||||
if ((update || (isSignleIntervalWindow(pInfo) && isClosed &&
|
||||
isDeletedWindow(&win, pBlock->info.groupId, pInfo->sessionSup.pIntervalAggSup))) && out) {
|
||||
appendOneRow(pInfo->pUpdateDataRes, tsCol + rowId, tsCol + rowId, &pBlock->info.uid);
|
||||
}
|
||||
|
@ -2276,8 +2320,9 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
|
||||
extractDataBlockFromFetchRsp(pInfo->pRes, &pInfo->loadInfo, pRsp->numOfRows, pRsp->data, pRsp->compLen,
|
||||
pOperator->exprSupp.numOfExprs, startTs, NULL, pInfo->scanCols);
|
||||
char* pStart = pRsp->data;
|
||||
extractDataBlockFromFetchRsp(pInfo->pRes, pRsp->data, pOperator->exprSupp.numOfExprs, pInfo->scanCols, &pStart);
|
||||
updateLoadRemoteInfo(&pInfo->loadInfo, pRsp->numOfRows, pRsp->compLen, startTs, pOperator);
|
||||
|
||||
// todo log the filter info
|
||||
doFilterResult(pInfo);
|
||||
|
@ -2418,81 +2463,6 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
|
|||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
#if 0
|
||||
int32_t maxNumOfTables = (int32_t)pResultInfo->capacity;
|
||||
|
||||
STagScanInfo *pInfo = pOperator->info;
|
||||
SSDataBlock *pRes = pInfo->pRes;
|
||||
|
||||
int32_t count = 0;
|
||||
SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0);
|
||||
|
||||
int32_t functionId = getExprFunctionId(&pOperator->exprSupp.pExprInfo[0]);
|
||||
if (functionId == FUNCTION_TID_TAG) { // return the tags & table Id
|
||||
assert(pQueryAttr->numOfOutput == 1);
|
||||
|
||||
SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[0];
|
||||
int32_t rsize = pExprInfo->base.resSchema.bytes;
|
||||
|
||||
count = 0;
|
||||
|
||||
int16_t bytes = pExprInfo->base.resSchema.bytes;
|
||||
int16_t type = pExprInfo->base.resSchema.type;
|
||||
|
||||
for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) {
|
||||
if (pQueryAttr->tagColList[i].colId == pExprInfo->base.pColumns->info.colId) {
|
||||
bytes = pQueryAttr->tagColList[i].bytes;
|
||||
type = pQueryAttr->tagColList[i].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0);
|
||||
|
||||
while(pInfo->curPos < pInfo->totalTables && count < maxNumOfTables) {
|
||||
int32_t i = pInfo->curPos++;
|
||||
STableQueryInfo *item = taosArrayGetP(pa, i);
|
||||
|
||||
char *output = pColInfo->pData + count * rsize;
|
||||
varDataSetLen(output, rsize - VARSTR_HEADER_SIZE);
|
||||
|
||||
output = varDataVal(output);
|
||||
STableId* id = TSDB_TABLEID(item->pTable);
|
||||
|
||||
*(int16_t *)output = 0;
|
||||
output += sizeof(int16_t);
|
||||
|
||||
*(int64_t *)output = id->uid; // memory align problem, todo serialize
|
||||
output += sizeof(id->uid);
|
||||
|
||||
*(int32_t *)output = id->tid;
|
||||
output += sizeof(id->tid);
|
||||
|
||||
*(int32_t *)output = pQueryAttr->vgId;
|
||||
output += sizeof(pQueryAttr->vgId);
|
||||
|
||||
char* data = NULL;
|
||||
if (pExprInfo->base.pColumns->info.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
data = tsdbGetTableName(item->pTable);
|
||||
} else {
|
||||
data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.pColumns->info.colId, type, bytes);
|
||||
}
|
||||
|
||||
doSetTagValueToResultBuf(output, data, type, bytes);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
//qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_TASKID(pRuntimeEnv), count);
|
||||
} else if (functionId == FUNCTION_COUNT) {// handle the "count(tbname)" query
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0);
|
||||
*(int64_t*)pColInfo->pData = pInfo->totalTables;
|
||||
count = 1;
|
||||
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
//qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_TASKID(pRuntimeEnv), count);
|
||||
} else { // return only the tags|table name etc.
|
||||
#endif
|
||||
|
||||
STagScanInfo* pInfo = pOperator->info;
|
||||
SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[0];
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
|
@ -2570,6 +2540,8 @@ static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
STagScanInfo* pInfo = (STagScanInfo*)param;
|
||||
pInfo->pRes = blockDataDestroy(pInfo->pRes);
|
||||
|
||||
taosArrayDestroy(pInfo->pColMatchInfo);
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
}
|
||||
|
||||
|
@ -2625,11 +2597,17 @@ _error:
|
|||
int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags, bool groupSort, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, SNode* pTagCond, SNode* pTagIndexCond,
|
||||
const char* idStr) {
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
int32_t code = getTableList(pHandle->meta, pHandle->vnode, pScanNode, pTagCond, pTagIndexCond, pTableListInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
int64_t st1 = taosGetTimestampUs();
|
||||
qDebug("generate queried table list completed, elapsed time:%.2f ms %s", (st1-st)/1000.0, idStr);
|
||||
|
||||
if (taosArrayGetSize(pTableListInfo->pTableList) == 0) {
|
||||
qDebug("no table qualified for query, %s" PRIx64, idStr);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2641,6 +2619,9 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags
|
|||
return code;
|
||||
}
|
||||
|
||||
int64_t st2 = taosGetTimestampUs();
|
||||
qDebug("generate group id map completed, elapsed time:%.2f ms %s", (st2-st1)/1000.0, idStr);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2731,7 +2712,7 @@ static int32_t loadDataBlockFromOneTable(SOperatorInfo* pOperator, STableMergeSc
|
|||
|
||||
// todo filter data block according to the block sma data firstly
|
||||
#if 0
|
||||
if (!doFilterByBlockStatistics(pBlock->pBlockStatis, pTableScanInfo->pCtx, pBlockInfo->rows)) {
|
||||
if (!doFilterByBlockSMA(pBlock->pBlockStatis, pTableScanInfo->pCtx, pBlockInfo->rows)) {
|
||||
pCost->filterOutBlocks += 1;
|
||||
qDebug("%s data block filter out, brange:%" PRId64 "-%" PRId64 ", rows:%d", GET_TASKID(pTaskInfo), pBlockInfo->window.skey,
|
||||
pBlockInfo->window.ekey, pBlockInfo->rows);
|
||||
|
|
|
@ -658,7 +658,7 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
|
||||
blockDataDestroy(p);
|
||||
|
||||
qDebug("%s get sorted row blocks, rows:%d", GET_TASKID(pTaskInfo), pDataBlock->info.rows);
|
||||
qDebug("%s get sorted block, groupId:%0x"PRIx64" rows:%d", GET_TASKID(pTaskInfo), pDataBlock->info.groupId, pDataBlock->info.rows);
|
||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -851,23 +851,34 @@ static int32_t saveResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t g
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t saveWinResult(int64_t ts, int32_t pageId, int32_t offset, uint64_t groupId, SHashObj* pUpdatedMap) {
|
||||
SResKeyPos* newPos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
|
||||
if (newPos == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
newPos->groupId = groupId;
|
||||
newPos->pos = (SResultRowPosition){.pageId = pageId, .offset = offset};
|
||||
*(int64_t*)newPos->key = ts;
|
||||
SWinRes key = {.ts = ts, .groupId = groupId};
|
||||
if (taosHashPut(pUpdatedMap, &key, sizeof(SWinRes), &newPos, sizeof(void*)) != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(newPos);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t saveWinResultRow(SResultRow* result, uint64_t groupId, SHashObj* pUpdatedMap) {
|
||||
return saveWinResult(result->win.skey, result->pageId, result->offset, groupId, pUpdatedMap);;
|
||||
}
|
||||
|
||||
static int32_t saveResultRow(SResultRow* result, uint64_t groupId, SArray* pUpdated) {
|
||||
return saveResult(result->win.skey, result->pageId, result->offset, groupId, pUpdated);
|
||||
}
|
||||
|
||||
static void removeResult(SArray* pUpdated, SWinRes* pKey) {
|
||||
int32_t size = taosArrayGetSize(pUpdated);
|
||||
int32_t index = binarySearchCom(pUpdated, size, pKey, TSDB_ORDER_DESC, compareResKey);
|
||||
if (index >= 0 && 0 == compareResKey(pKey, pUpdated, index)) {
|
||||
taosArrayRemove(pUpdated, index);
|
||||
}
|
||||
}
|
||||
|
||||
static void removeResults(SArray* pWins, SArray* pUpdated) {
|
||||
static void removeResults(SArray* pWins, SHashObj* pUpdatedMap) {
|
||||
int32_t size = taosArrayGetSize(pWins);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
SWinRes* pW = taosArrayGet(pWins, i);
|
||||
removeResult(pUpdated, pW);
|
||||
taosHashRemove(pUpdatedMap, pW, sizeof(SWinRes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,11 +905,14 @@ int32_t compareWinRes(void* pKey, void* data, int32_t index) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void removeDeleteResults(SArray* pUpdated, SArray* pDelWins) {
|
||||
int32_t upSize = taosArrayGetSize(pUpdated);
|
||||
static void removeDeleteResults(SHashObj* pUpdatedMap, SArray* pDelWins) {
|
||||
if (!pUpdatedMap || taosHashGetSize(pUpdatedMap) == 0) {
|
||||
return;
|
||||
}
|
||||
int32_t delSize = taosArrayGetSize(pDelWins);
|
||||
for (int32_t i = 0; i < upSize; i++) {
|
||||
SResKeyPos* pResKey = taosArrayGetP(pUpdated, i);
|
||||
void* pIte = NULL;
|
||||
while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) {
|
||||
SResKeyPos* pResKey = (SResKeyPos*)pIte;
|
||||
int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinRes);
|
||||
if (index >= 0 && 0 == compareWinRes(pResKey, pDelWins, index)) {
|
||||
taosArrayRemove(pDelWins, index);
|
||||
|
@ -914,7 +928,7 @@ bool isOverdue(TSKEY ts, STimeWindowAggSupp* pSup) {
|
|||
bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup) { return isOverdue(pWin->ekey, pSup); }
|
||||
|
||||
static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pBlock,
|
||||
int32_t scanFlag, SArray* pUpdated) {
|
||||
int32_t scanFlag, SHashObj* pUpdatedMap) {
|
||||
SIntervalAggOperatorInfo* pInfo = (SIntervalAggOperatorInfo*)pOperatorInfo->info;
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||
|
@ -940,7 +954,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
|||
}
|
||||
|
||||
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM && pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
saveResultRow(pResult, tableGroupId, pUpdated);
|
||||
saveWinResultRow(pResult, tableGroupId, pUpdatedMap);
|
||||
setResultBufPageDirty(pInfo->aggSup.pResultBuf, &pResultRowInfo->cur);
|
||||
}
|
||||
}
|
||||
|
@ -997,7 +1011,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
|||
}
|
||||
|
||||
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM && pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) {
|
||||
saveResultRow(pResult, tableGroupId, pUpdated);
|
||||
saveWinResultRow(pResult, tableGroupId, pUpdatedMap);
|
||||
setResultBufPageDirty(pInfo->aggSup.pResultBuf, &pResultRowInfo->cur);
|
||||
}
|
||||
|
||||
|
@ -1437,7 +1451,7 @@ static void doClearWindows(SAggSupporter* pAggSup, SExprSupp* pSup1, SInterval*
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) {
|
||||
static int32_t getAllIntervalWindow(SHashObj* pHashMap, SHashObj* resWins) {
|
||||
void* pIte = NULL;
|
||||
size_t keyLen = 0;
|
||||
while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) {
|
||||
|
@ -1446,7 +1460,7 @@ static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) {
|
|||
ASSERT(keyLen == GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY)));
|
||||
TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t));
|
||||
SResultRowPosition* pPos = (SResultRowPosition*)pIte;
|
||||
int32_t code = saveResult(ts, pPos->pageId, pPos->offset, groupId, resWins);
|
||||
int32_t code = saveWinResult(ts, pPos->pageId, pPos->offset, groupId, resWins);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1455,7 +1469,7 @@ static int32_t getAllIntervalWindow(SHashObj* pHashMap, SArray* resWins) {
|
|||
}
|
||||
|
||||
static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup, SInterval* pInterval,
|
||||
SHashObj* pPullDataMap, SArray* closeWins, SArray* pRecyPages,
|
||||
SHashObj* pPullDataMap, SHashObj* closeWins, SArray* pRecyPages,
|
||||
SDiskbasedBuf* pDiscBuf) {
|
||||
qDebug("===stream===close interval window");
|
||||
void* pIte = NULL;
|
||||
|
@ -1487,7 +1501,7 @@ static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup,
|
|||
}
|
||||
SResultRowPosition* pPos = (SResultRowPosition*)pIte;
|
||||
if (pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
int32_t code = saveResult(ts, pPos->pageId, pPos->offset, groupId, closeWins);
|
||||
int32_t code = saveWinResult(ts, pPos->pageId, pPos->offset, groupId, closeWins);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1577,11 +1591,14 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
|
||||
SArray* pUpdated = taosArrayInit(4, POINTER_BYTES); // SResKeyPos
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
|
||||
SHashObj* pUpdatedMap = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
// qInfo("===stream===%ld", pBlock->info.version);
|
||||
printDataBlock(pBlock, "single interval recv");
|
||||
|
||||
if (pBlock->info.type == STREAM_CLEAR) {
|
||||
|
@ -1594,7 +1611,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
doDeleteSpecifyIntervalWindow(&pInfo->aggSup, pBlock, pInfo->pDelWins, &pInfo->interval);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdated);
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1617,17 +1634,24 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, MAIN_SCAN, pUpdated);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, MAIN_SCAN, pUpdatedMap);
|
||||
}
|
||||
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, pUpdated,
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, pUpdatedMap,
|
||||
pInfo->pRecycledPages, pInfo->aggSup.pResultBuf);
|
||||
|
||||
void* pIte = NULL;
|
||||
while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) {
|
||||
taosArrayPush(pUpdated, pIte);
|
||||
}
|
||||
taosHashCleanup(pUpdatedMap);
|
||||
taosArraySort(pUpdated, resultrowComparAsc);
|
||||
|
||||
finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset);
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
removeDeleteResults(pUpdated, pInfo->pDelWins);
|
||||
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
|
||||
doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes);
|
||||
if (pInfo->pDelRes->info.rows > 0) {
|
||||
return pInfo->pDelRes;
|
||||
|
@ -1695,7 +1719,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
|
||||
static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) {
|
||||
for (int32_t i = 0; i < numOfCols; i++) {
|
||||
if (!fmIsInvertible(pFCtx[i].functionId)) {
|
||||
if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1781,6 +1805,7 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
pInfo->twAggSup = *pTwAggSupp;
|
||||
pInfo->ignoreExpiredData = pPhyNode->window.igExpired;
|
||||
pInfo->pCondition = pPhyNode->window.node.pConditions;
|
||||
pInfo->binfo.mergeResultBlock = pPhyNode->window.mergeDataBlock;
|
||||
|
||||
if (pPhyNode->window.pExprs != NULL) {
|
||||
int32_t numOfScalar = 0;
|
||||
|
@ -2866,7 +2891,7 @@ STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) {
|
|||
}
|
||||
|
||||
static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t tableGroupId,
|
||||
SArray* pUpdated) {
|
||||
SHashObj* pUpdatedMap) {
|
||||
SStreamFinalIntervalOperatorInfo* pInfo = (SStreamFinalIntervalOperatorInfo*)pOperatorInfo->info;
|
||||
SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo);
|
||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||
|
@ -2948,8 +2973,8 @@ static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBloc
|
|||
forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey,
|
||||
NULL, TSDB_ORDER_ASC);
|
||||
}
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdated) {
|
||||
saveResultRow(pResult, tableGroupId, pUpdated);
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) {
|
||||
saveWinResultRow(pResult, tableGroupId, pUpdatedMap);
|
||||
setResultBufPageDirty(pInfo->aggSup.pResultBuf, &pResultRowInfo->cur);
|
||||
}
|
||||
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, true);
|
||||
|
@ -3055,6 +3080,8 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
SStreamFinalIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
SArray* pUpdated = taosArrayInit(4, POINTER_BYTES);
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
|
||||
SHashObj* pUpdatedMap = taosHashInit(1024, hashFn, false, HASH_NO_LOCK);
|
||||
TSKEY maxTs = INT64_MIN;
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
|
@ -3112,7 +3139,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
clearSpecialDataBlock(pInfo->pUpdateRes);
|
||||
removeDeleteResults(pUpdated, pInfo->pDelWins);
|
||||
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
qDebug("%s return data", IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
|
||||
break;
|
||||
|
@ -3139,7 +3166,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
taosArrayDestroy(pUpWins);
|
||||
continue;
|
||||
}
|
||||
removeResults(pUpWins, pUpdated);
|
||||
removeResults(pUpWins, pUpdatedMap);
|
||||
copyDataBlock(pInfo->pUpdateRes, pBlock);
|
||||
// copyUpdateDataBlock(pInfo->pUpdateRes, pBlock, pInfo->primaryTsIndex);
|
||||
pInfo->returnUpdate = true;
|
||||
|
@ -3157,15 +3184,15 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
pOperator->exprSupp.numOfExprs, pOperator->pTaskInfo, pUpdated);
|
||||
continue;
|
||||
}
|
||||
removeResults(pInfo->pDelWins, pUpdated);
|
||||
removeResults(pInfo->pDelWins, pUpdatedMap);
|
||||
break;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) {
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdated);
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) {
|
||||
SArray* pUpWins = taosArrayInit(8, sizeof(SWinRes));
|
||||
doClearWindows(&pInfo->aggSup, pSup, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, pUpWins);
|
||||
removeResults(pUpWins, pUpdated);
|
||||
removeResults(pUpWins, pUpdatedMap);
|
||||
taosArrayDestroy(pUpWins);
|
||||
if (taosArrayGetSize(pUpdated) > 0) {
|
||||
break;
|
||||
|
@ -3181,7 +3208,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL);
|
||||
}
|
||||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, pInfo->order, MAIN_SCAN, true);
|
||||
doHashInterval(pOperator, pBlock, pBlock->info.groupId, pUpdated);
|
||||
doHashInterval(pOperator, pBlock, pBlock->info.groupId, pUpdatedMap);
|
||||
if (IS_FINAL_OP(pInfo)) {
|
||||
int32_t chIndex = getChildIndex(pBlock);
|
||||
int32_t size = taosArrayGetSize(pInfo->pChildren);
|
||||
|
@ -3206,12 +3233,19 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
|
||||
if (IS_FINAL_OP(pInfo)) {
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, pInfo->pPullDataMap,
|
||||
pUpdated, pInfo->pRecycledPages, pInfo->aggSup.pResultBuf);
|
||||
pUpdatedMap, pInfo->pRecycledPages, pInfo->aggSup.pResultBuf);
|
||||
closeChildIntervalWindow(pInfo->pChildren, pInfo->twAggSup.maxTs);
|
||||
} else {
|
||||
pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs;
|
||||
}
|
||||
|
||||
void* pIte = NULL;
|
||||
while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) {
|
||||
taosArrayPush(pUpdated, pIte);
|
||||
}
|
||||
taosHashCleanup(pUpdatedMap);
|
||||
taosArraySort(pUpdated, resultrowComparAsc);
|
||||
|
||||
finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset);
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
@ -4894,20 +4928,25 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
int32_t numOfOutput = pSup->numOfExprs;
|
||||
int64_t* tsCols = extractTsCol(pBlock, iaInfo);
|
||||
uint64_t tableGroupId = pBlock->info.groupId;
|
||||
TSKEY currTs = getStartTsKey(&pBlock->info.window, tsCols);
|
||||
SResultRow* pResult = NULL;
|
||||
|
||||
TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols);
|
||||
|
||||
// there is an result exists
|
||||
if (miaInfo->curTs != INT64_MIN) {
|
||||
ASSERT(taosHashGetSize(iaInfo->aggSup.pResultRowHashTable) == 1);
|
||||
if (currTs != miaInfo->curTs) {
|
||||
|
||||
if (ts != miaInfo->curTs) {
|
||||
outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, miaInfo->curTs);
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
miaInfo->curTs = ts;
|
||||
}
|
||||
} else {
|
||||
miaInfo->curTs = ts;
|
||||
ASSERT(taosHashGetSize(iaInfo->aggSup.pResultRowHashTable) == 0);
|
||||
}
|
||||
|
||||
STimeWindow win = {0};
|
||||
win.skey = currTs;
|
||||
win.skey = miaInfo->curTs;
|
||||
win.ekey =
|
||||
taosTimeAdd(win.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit, iaInfo->interval.precision) - 1;
|
||||
|
||||
|
@ -4918,12 +4957,11 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
miaInfo->curTs = win.skey;
|
||||
int32_t currPos = startPos;
|
||||
|
||||
STimeWindow currWin = win;
|
||||
while (++currPos < pBlock->info.rows) {
|
||||
if (tsCols[currPos] == currTs) {
|
||||
if (tsCols[currPos] == miaInfo->curTs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4931,11 +4969,10 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, currPos - startPos,
|
||||
tsCols, pBlock->info.rows, numOfOutput, iaInfo->inputOrder);
|
||||
|
||||
outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs);
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, miaInfo->curTs);
|
||||
miaInfo->curTs = tsCols[currPos];
|
||||
|
||||
currTs = tsCols[currPos];
|
||||
currWin.skey = currTs;
|
||||
currWin.skey = miaInfo->curTs;
|
||||
currWin.ekey = taosTimeAdd(currWin.skey, iaInfo->interval.interval, iaInfo->interval.intervalUnit,
|
||||
iaInfo->interval.precision) -
|
||||
1;
|
||||
|
@ -4953,83 +4990,97 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
updateTimeWindowInfo(&iaInfo->twAggSup.timeWindowData, &currWin, true);
|
||||
doApplyFunctions(pTaskInfo, pSup->pCtx, &currWin, &iaInfo->twAggSup.timeWindowData, startPos, currPos - startPos,
|
||||
tsCols, pBlock->info.rows, numOfOutput, iaInfo->inputOrder);
|
||||
|
||||
if (currPos >= pBlock->info.rows) {
|
||||
// we need to see next block if exists
|
||||
} else {
|
||||
ASSERT(0);
|
||||
outputMergeAlignedIntervalResult(pOperatorInfo, tableGroupId, pResultBlock, currTs);
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) {
|
||||
|
||||
static void doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperator->info;
|
||||
SIntervalAggOperatorInfo* iaInfo = miaInfo->intervalAggOperatorInfo;
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SSDataBlock* pRes = iaInfo->binfo.pRes;
|
||||
|
||||
blockDataCleanup(pRes);
|
||||
blockDataEnsureCapacity(pRes, pOperator->resultInfo.capacity);
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
int32_t scanFlag = MAIN_SCAN;
|
||||
|
||||
if (!miaInfo->inputBlocksFinished) {
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
int32_t scanFlag = MAIN_SCAN;
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (miaInfo->prefetchedBlock == NULL) {
|
||||
pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
} else {
|
||||
pBlock = miaInfo->prefetchedBlock;
|
||||
miaInfo->prefetchedBlock = NULL;
|
||||
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (miaInfo->prefetchedBlock == NULL) {
|
||||
pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
} else {
|
||||
pBlock = miaInfo->prefetchedBlock;
|
||||
miaInfo->groupId = pBlock->info.groupId;
|
||||
miaInfo->prefetchedBlock = NULL;
|
||||
}
|
||||
|
||||
if (pBlock == NULL) {
|
||||
// close last unfinalized time window
|
||||
if (miaInfo->curTs != INT64_MIN) {
|
||||
ASSERT(taosHashGetSize(iaInfo->aggSup.pResultRowHashTable) == 1);
|
||||
outputMergeAlignedIntervalResult(pOperator, miaInfo->groupId, pRes, miaInfo->curTs);
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
}
|
||||
|
||||
doSetOperatorCompleted(pOperator);
|
||||
miaInfo->inputBlocksFinished = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!miaInfo->hasGroupId) {
|
||||
miaInfo->hasGroupId = true;
|
||||
miaInfo->groupId = pBlock->info.groupId;
|
||||
} else if (miaInfo->groupId != pBlock->info.groupId) {
|
||||
// if there are unclosed time window, close it firstly.
|
||||
ASSERT(miaInfo->curTs != INT64_MIN);
|
||||
outputMergeAlignedIntervalResult(pOperator, miaInfo->groupId, pRes, miaInfo->curTs);
|
||||
miaInfo->prefetchedBlock = pBlock;
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
break;
|
||||
}
|
||||
|
||||
getTableScanInfo(pOperator, &iaInfo->inputOrder, &scanFlag);
|
||||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, iaInfo->inputOrder, scanFlag, true);
|
||||
doMergeAlignedIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes);
|
||||
doFilter(miaInfo->pCondition, pRes, NULL);
|
||||
if (pRes->info.rows >= pOperator->resultInfo.capacity) {
|
||||
break;
|
||||
}
|
||||
miaInfo->groupId = pBlock->info.groupId;
|
||||
}
|
||||
|
||||
pRes->info.groupId = miaInfo->groupId;
|
||||
if (pBlock == NULL) {
|
||||
// close last unfinalized time window
|
||||
if (miaInfo->curTs != INT64_MIN) {
|
||||
ASSERT(taosHashGetSize(iaInfo->aggSup.pResultRowHashTable) == 1);
|
||||
outputMergeAlignedIntervalResult(pOperator, miaInfo->groupId, pRes, miaInfo->curTs);
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
}
|
||||
|
||||
doSetOperatorCompleted(pOperator);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!miaInfo->hasGroupId) {
|
||||
miaInfo->hasGroupId = true;
|
||||
miaInfo->groupId = pBlock->info.groupId;
|
||||
} else if (miaInfo->groupId != pBlock->info.groupId) {
|
||||
// if there are unclosed time window, close it firstly.
|
||||
ASSERT(miaInfo->curTs != INT64_MIN);
|
||||
outputMergeAlignedIntervalResult(pOperator, miaInfo->groupId, pRes, miaInfo->curTs);
|
||||
miaInfo->prefetchedBlock = pBlock;
|
||||
miaInfo->curTs = INT64_MIN;
|
||||
break;
|
||||
}
|
||||
|
||||
getTableScanInfo(pOperator, &iaInfo->inputOrder, &scanFlag);
|
||||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, iaInfo->inputOrder, scanFlag, true);
|
||||
doMergeAlignedIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes);
|
||||
|
||||
doFilter(miaInfo->pCondition, pRes, NULL);
|
||||
if (pRes->info.rows >= pOperator->resultInfo.capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pRes->info.groupId = miaInfo->groupId;
|
||||
miaInfo->hasGroupId = false;
|
||||
}
|
||||
|
||||
static SSDataBlock* mergeAlignedIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
SMergeAlignedIntervalAggOperatorInfo* pMiaInfo = pOperator->info;
|
||||
SIntervalAggOperatorInfo* iaInfo = pMiaInfo->intervalAggOperatorInfo;
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSDataBlock* pRes = iaInfo->binfo.pRes;
|
||||
blockDataCleanup(pRes);
|
||||
|
||||
if (iaInfo->binfo.mergeResultBlock) {
|
||||
while(1) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pRes->info.rows >= pOperator->resultInfo.threshold) {
|
||||
break;
|
||||
}
|
||||
|
||||
doMergeAlignedIntervalAgg(pOperator);
|
||||
}
|
||||
} else {
|
||||
doMergeAlignedIntervalAgg(pOperator);
|
||||
}
|
||||
|
||||
size_t rows = pRes->info.rows;
|
||||
pOperator->resultInfo.totalRows += rows;
|
||||
|
@ -5038,7 +5089,7 @@ static SSDataBlock* doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo,
|
||||
int32_t numOfCols, SSDataBlock* pResBlock, SInterval* pInterval,
|
||||
int32_t primaryTsSlotId, SNode* pCondition,
|
||||
int32_t primaryTsSlotId, SNode* pCondition, bool mergeResultBlock,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SMergeAlignedIntervalAggOperatorInfo* miaInfo = taosMemoryCalloc(1, sizeof(SMergeAlignedIntervalAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
|
@ -5062,6 +5113,7 @@ SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
iaInfo->interval = *pInterval;
|
||||
iaInfo->execModel = pTaskInfo->execModel;
|
||||
iaInfo->primaryTsIndex = primaryTsSlotId;
|
||||
iaInfo->binfo.mergeResultBlock = mergeResultBlock;
|
||||
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||
|
@ -5082,6 +5134,7 @@ SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
}
|
||||
|
||||
initResultRowInfo(&iaInfo->binfo.resultRowInfo);
|
||||
blockDataEnsureCapacity(iaInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
|
||||
pOperator->name = "TimeMergeAlignedIntervalAggOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_MERGE_ALIGNED_INTERVAL;
|
||||
|
@ -5092,7 +5145,7 @@ SOperatorInfo* createMergeAlignedIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
pOperator->exprSupp.numOfExprs = numOfCols;
|
||||
pOperator->info = miaInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doMergeAlignedIntervalAgg, NULL, NULL,
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, mergeAlignedIntervalAgg, NULL, NULL,
|
||||
destroyMergeAlignedIntervalOperatorInfo, NULL, NULL, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
|
@ -5350,7 +5403,7 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
bool mergeBlock, SExecTaskInfo* pTaskInfo) {
|
||||
SMergeIntervalAggOperatorInfo* miaInfo = taosMemoryCalloc(1, sizeof(SMergeIntervalAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (miaInfo == NULL || pOperator == NULL) {
|
||||
|
@ -5364,6 +5417,7 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprI
|
|||
iaInfo->inputOrder = TSDB_ORDER_ASC;
|
||||
iaInfo->interval = *pInterval;
|
||||
iaInfo->execModel = pTaskInfo->execModel;
|
||||
iaInfo->binfo.mergeResultBlock = mergeBlock;
|
||||
|
||||
iaInfo->primaryTsIndex = primaryTsSlotId;
|
||||
|
||||
|
|
|
@ -13,38 +13,37 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "tsimplehash.h"
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define SHASH_DEFAULT_LOAD_FACTOR 0.75
|
||||
#define HASH_MAX_CAPACITY (1024*1024*16)
|
||||
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
||||
#define SHASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * SHASH_DEFAULT_LOAD_FACTOR)
|
||||
|
||||
#define GET_SHASH_NODE_KEY(_n, _dl) ((char*)(_n) + sizeof(SHNode) + (_dl))
|
||||
#define GET_SHASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHNode))
|
||||
#define GET_SHASH_NODE_KEY(_n, _dl) ((char *)(_n) + sizeof(SHNode) + (_dl))
|
||||
#define GET_SHASH_NODE_DATA(_n) ((char *)(_n) + sizeof(SHNode))
|
||||
|
||||
#define HASH_INDEX(v, c) ((v) & ((c)-1))
|
||||
#define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * SHASH_DEFAULT_LOAD_FACTOR)
|
||||
#define HASH_INDEX(v, c) ((v) & ((c)-1))
|
||||
|
||||
#define FREE_HASH_NODE(_n) \
|
||||
do { \
|
||||
taosMemoryFreeClear(_n); \
|
||||
#define FREE_HASH_NODE(_n) \
|
||||
do { \
|
||||
taosMemoryFreeClear(_n); \
|
||||
} while (0);
|
||||
|
||||
typedef struct SHNode {
|
||||
struct SHNode *next;
|
||||
char data[];
|
||||
struct SHNode *next;
|
||||
char data[];
|
||||
} SHNode;
|
||||
|
||||
struct SSHashObj {
|
||||
SHNode **hashList;
|
||||
size_t capacity; // number of slots
|
||||
int64_t size; // number of elements in hash table
|
||||
_hash_fn_t hashFp; // hash function
|
||||
_equal_fn_t equalFp; // equal function
|
||||
int32_t keyLen;
|
||||
int32_t dataLen;
|
||||
SHNode **hashList;
|
||||
size_t capacity; // number of slots
|
||||
int64_t size; // number of elements in hash table
|
||||
_hash_fn_t hashFp; // hash function
|
||||
_equal_fn_t equalFp; // equal function
|
||||
int32_t keyLen;
|
||||
int32_t dataLen;
|
||||
};
|
||||
|
||||
static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
|
||||
|
@ -62,7 +61,7 @@ SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn, size_t keyLen, size_t
|
|||
capacity = 4;
|
||||
}
|
||||
|
||||
SSHashObj* pHashObj = (SSHashObj*) taosMemoryCalloc(1, sizeof(SSHashObj));
|
||||
SSHashObj *pHashObj = (SSHashObj *)taosMemoryCalloc(1, sizeof(SSHashObj));
|
||||
if (pHashObj == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
|
@ -72,7 +71,7 @@ SSHashObj *tSimpleHashInit(size_t capacity, _hash_fn_t fn, size_t keyLen, size_t
|
|||
pHashObj->capacity = taosHashCapacity((int32_t)capacity);
|
||||
|
||||
pHashObj->equalFp = memcmp;
|
||||
pHashObj->hashFp = fn;
|
||||
pHashObj->hashFp = fn;
|
||||
ASSERT((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
|
||||
|
||||
pHashObj->keyLen = keyLen;
|
||||
|
@ -91,7 +90,7 @@ int32_t tSimpleHashGetSize(const SSHashObj *pHashObj) {
|
|||
if (pHashObj == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return (int32_t)atomic_load_64((int64_t*)&pHashObj->size);
|
||||
return (int32_t)atomic_load_64((int64_t *)&pHashObj->size);
|
||||
}
|
||||
|
||||
static SHNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
|
||||
|
@ -108,41 +107,42 @@ static SHNode *doCreateHashNode(const void *key, size_t keyLen, const void *pDat
|
|||
}
|
||||
|
||||
static void taosHashTableResize(SSHashObj *pHashObj) {
|
||||
if (!HASH_NEED_RESIZE(pHashObj)) {
|
||||
if (!SHASH_NEED_RESIZE(pHashObj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t newCapacity = (int32_t)(pHashObj->capacity << 1u);
|
||||
if (newCapacity > HASH_MAX_CAPACITY) {
|
||||
// uDebug("current capacity:%zu, maximum capacity:%d, no resize applied due to limitation is reached",
|
||||
// pHashObj->capacity, HASH_MAX_CAPACITY);
|
||||
// uDebug("current capacity:%zu, maximum capacity:%d, no resize applied due to limitation is reached",
|
||||
// pHashObj->capacity, HASH_MAX_CAPACITY);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
void *pNewEntryList = taosMemoryRealloc(pHashObj->hashList, sizeof(void *) * newCapacity);
|
||||
void *pNewEntryList = taosMemoryRealloc(pHashObj->hashList, sizeof(void *) * newCapacity);
|
||||
if (pNewEntryList == NULL) {
|
||||
// qWarn("hash resize failed due to out of memory, capacity remain:%zu", pHashObj->capacity);
|
||||
// qWarn("hash resize failed due to out of memory, capacity remain:%zu", pHashObj->capacity);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t inc = newCapacity - pHashObj->capacity;
|
||||
memset((char*)pNewEntryList + pHashObj->capacity * sizeof(void*), 0, inc);
|
||||
memset((char *)pNewEntryList + pHashObj->capacity * sizeof(void *), 0, inc);
|
||||
|
||||
pHashObj->hashList = pNewEntryList;
|
||||
pHashObj->capacity = newCapacity;
|
||||
|
||||
for (int32_t idx = 0; idx < pHashObj->capacity; ++idx) {
|
||||
SHNode* pNode = pHashObj->hashList[idx];
|
||||
SHNode *pNext;
|
||||
SHNode *pPrev = NULL;
|
||||
|
||||
SHNode *pNode = pHashObj->hashList[idx];
|
||||
if (pNode == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SHNode *pNext;
|
||||
SHNode *pPrev = NULL;
|
||||
|
||||
|
||||
while (pNode != NULL) {
|
||||
void* key = GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen);
|
||||
void *key = GET_SHASH_NODE_KEY(pNode, pHashObj->dataLen);
|
||||
uint32_t hashVal = (*pHashObj->hashFp)(key, (uint32_t)pHashObj->dataLen);
|
||||
|
||||
int32_t newIdx = HASH_INDEX(hashVal, pHashObj->capacity);
|
||||
|
@ -166,8 +166,9 @@ static void taosHashTableResize(SSHashObj *pHashObj) {
|
|||
|
||||
int64_t et = taosGetTimestampUs();
|
||||
|
||||
// uDebug("hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms", (int32_t)pHashObj->capacity,
|
||||
// ((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
|
||||
// uDebug("hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms",
|
||||
// (int32_t)pHashObj->capacity,
|
||||
// ((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
|
||||
}
|
||||
|
||||
int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data) {
|
||||
|
@ -210,7 +211,7 @@ int32_t tSimpleHashPut(SSHashObj *pHashObj, const void *key, const void *data) {
|
|||
pNewNode->next = pHashObj->hashList[slot];
|
||||
pHashObj->hashList[slot] = pNewNode;
|
||||
atomic_add_fetch_64(&pHashObj->size, 1);
|
||||
} else { //update data
|
||||
} else { // update data
|
||||
memcpy(GET_SHASH_NODE_DATA(pNode), data, pHashObj->dataLen);
|
||||
}
|
||||
|
||||
|
@ -230,9 +231,7 @@ static FORCE_INLINE SHNode *doSearchInEntryList(SSHashObj *pHashObj, const void
|
|||
return pNode;
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool taosHashTableEmpty(const SSHashObj *pHashObj) {
|
||||
return tSimpleHashGetSize(pHashObj) == 0;
|
||||
}
|
||||
static FORCE_INLINE bool taosHashTableEmpty(const SSHashObj *pHashObj) { return tSimpleHashGetSize(pHashObj) == 0; }
|
||||
|
||||
void *tSimpleHashGet(SSHashObj *pHashObj, const void *key) {
|
||||
if (pHashObj == NULL || taosHashTableEmpty(pHashObj) || key == NULL) {
|
||||
|
@ -299,9 +298,9 @@ size_t tSimpleHashGetMemSize(const SSHashObj *pHashObj) {
|
|||
return (pHashObj->capacity * sizeof(void *)) + sizeof(SHNode) * tSimpleHashGetSize(pHashObj) + sizeof(SSHashObj);
|
||||
}
|
||||
|
||||
void *tSimpleHashGetKey(const SSHashObj* pHashObj, void *data, size_t* keyLen) {
|
||||
void *tSimpleHashGetKey(const SSHashObj *pHashObj, void *data, size_t *keyLen) {
|
||||
int32_t offset = offsetof(SHNode, data);
|
||||
SHNode *node = ((SHNode*)(char*)data - offset);
|
||||
SHNode *node = ((SHNode *)(char *)data - offset);
|
||||
if (keyLen != NULL) {
|
||||
*keyLen = pHashObj->keyLen;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TAGGFUNCTION_H
|
||||
#define TDENGINE_TAGGFUNCTION_H
|
||||
#ifndef TDENGINE_TFUNCTIONINT_H
|
||||
#define TDENGINE_TFUNCTIONINT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -28,17 +28,6 @@ extern "C" {
|
|||
#include "function.h"
|
||||
#include "tudf.h"
|
||||
|
||||
#define AVG_FUNCTION_INTER_BUFFER_SIZE 50
|
||||
|
||||
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
|
||||
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
|
||||
|
||||
typedef struct SInterpInfoDetail {
|
||||
TSKEY ts; // interp specified timestamp
|
||||
int8_t type;
|
||||
int8_t primaryCol;
|
||||
} SInterpInfoDetail;
|
||||
|
||||
bool topbot_datablock_filter(SqlFunctionCtx *pCtx, const char *minval, const char *maxval);
|
||||
|
||||
/**
|
||||
|
@ -57,4 +46,4 @@ static FORCE_INLINE void initResultRowEntry(SResultRowEntryInfo *pResInfo, int32
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_TAGGFUNCTION_H
|
||||
#endif // TDENGINE_TFUNCTIONINT_H
|
|
@ -1575,7 +1575,8 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType) {
|
||||
if (!IS_SIGNED_NUMERIC_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType &&
|
||||
TSDB_DATA_TYPE_TIMESTAMP != colType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -2150,7 +2151,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
},
|
||||
{
|
||||
.name = "_apercentile_partial",
|
||||
.type = FUNCTION_TYPE_APERCENTILE_PARTIAL | FUNC_MGT_TIMELINE_FUNC,
|
||||
.type = FUNCTION_TYPE_APERCENTILE_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateApercentilePartial,
|
||||
.getEnvFunc = getApercentileFuncEnv,
|
||||
|
@ -2163,7 +2164,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_apercentile_merge",
|
||||
.type = FUNCTION_TYPE_APERCENTILE_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateApercentileMerge,
|
||||
.getEnvFunc = getApercentileFuncEnv,
|
||||
.initFunc = apercentileFunctionSetup,
|
||||
|
@ -2256,8 +2257,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.finalizeFunc = elapsedFinalize,
|
||||
.invertFunc = NULL,
|
||||
.combineFunc = elapsedCombine,
|
||||
//.pPartialFunc = "_elapsed_partial",
|
||||
//.pMergeFunc = "_elapsed_merge"
|
||||
},
|
||||
{
|
||||
.name = "_elapsed_partial",
|
||||
|
@ -2324,10 +2323,13 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.type = FUNCTION_TYPE_LAST_ROW,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||
.translateFunc = translateFirstLast,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = lastRowFunction,
|
||||
.sprocessFunc = firstLastScalarFunction,
|
||||
.pPartialFunc = "_last_row_partial",
|
||||
.pMergeFunc = "_last_row_merge",
|
||||
.finalizeFunc = firstLastFinalize
|
||||
},
|
||||
{
|
||||
|
@ -2340,6 +2342,27 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = cachedLastRowFunction,
|
||||
.finalizeFunc = firstLastFinalize
|
||||
},
|
||||
{
|
||||
.name = "_last_row_partial",
|
||||
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||
.translateFunc = translateFirstLastPartial,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = lastRowFunction,
|
||||
.finalizeFunc = firstLastPartialFinalize,
|
||||
},
|
||||
{
|
||||
.name = "_last_row_merge",
|
||||
.type = FUNCTION_TYPE_LAST_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||
.translateFunc = translateFirstLastMerge,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = lastFunctionMerge,
|
||||
.finalizeFunc = firstLastFinalize,
|
||||
},
|
||||
{
|
||||
.name = "first",
|
||||
.type = FUNCTION_TYPE_FIRST,
|
||||
|
@ -2396,6 +2419,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.type = FUNCTION_TYPE_LAST_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
||||
.translateFunc = translateFirstLastPartial,
|
||||
.dynDataRequiredFunc = lastDynDataReq,
|
||||
.getEnvFunc = getFirstLastFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = lastFunction,
|
||||
|
@ -2428,7 +2452,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "histogram",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
||||
.translateFunc = translateHistogram,
|
||||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = histogramFunctionSetup,
|
||||
|
@ -2443,7 +2467,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_histogram_partial",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC,
|
||||
.translateFunc = translateHistogramPartial,
|
||||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = histogramFunctionSetup,
|
||||
|
@ -2455,7 +2479,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "_histogram_merge",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_ROWS_FUNC | FUNC_MGT_FORBID_FILL_FUNC,
|
||||
.translateFunc = translateHistogramMerge,
|
||||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -2467,7 +2491,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "hyperloglog",
|
||||
.type = FUNCTION_TYPE_HYPERLOGLOG,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateHLL,
|
||||
.getEnvFunc = getHLLFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
|
@ -2481,7 +2505,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
},
|
||||
{
|
||||
.name = "_hyperloglog_partial",
|
||||
.type = FUNCTION_TYPE_HYPERLOGLOG_PARTIAL | FUNC_MGT_TIMELINE_FUNC,
|
||||
.type = FUNCTION_TYPE_HYPERLOGLOG_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateHLLPartial,
|
||||
.getEnvFunc = getHLLFuncEnv,
|
||||
|
@ -2493,7 +2517,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
},
|
||||
{
|
||||
.name = "_hyperloglog_merge",
|
||||
.type = FUNCTION_TYPE_HYPERLOGLOG_MERGE | FUNC_MGT_TIMELINE_FUNC,
|
||||
.type = FUNCTION_TYPE_HYPERLOGLOG_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateHLLMerge,
|
||||
.getEnvFunc = getHLLFuncEnv,
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
#include "function.h"
|
||||
#include "query.h"
|
||||
#include "querynodes.h"
|
||||
#include "taggfunction.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdigest.h"
|
||||
#include "tfunctionInt.h"
|
||||
#include "tglobal.h"
|
||||
#include "thistogram.h"
|
||||
#include "tpercentile.h"
|
||||
|
@ -312,14 +312,6 @@ typedef struct SGroupKeyInfo {
|
|||
#define GET_TS_LIST(x) ((TSKEY*)((x)->ptsList))
|
||||
#define GET_TS_DATA(x, y) (GET_TS_LIST(x)[(y)])
|
||||
|
||||
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
|
||||
do { \
|
||||
for (int32_t _i = 0; _i < (ctx)->tagInfo.numOfTagCols; ++_i) { \
|
||||
SqlFunctionCtx* __ctx = (ctx)->tagInfo.pTagCtxList[_i]; \
|
||||
__ctx->fpSet.process(__ctx); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DO_UPDATE_SUBSID_RES(ctx, ts) \
|
||||
do { \
|
||||
for (int32_t _i = 0; _i < (ctx)->subsidiaries.num; ++_i) { \
|
||||
|
@ -506,8 +498,7 @@ int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock,
|
|||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||
cleanupResultRowEntry(pResInfo);
|
||||
pResInfo->isNullRes = (pResInfo->isNullRes == 1) ? 1 : (pResInfo->numOfRes == 0);;
|
||||
|
||||
char* in = finalResult;
|
||||
colDataAppend(pCol, pBlock->info.rows, in, pResInfo->isNullRes);
|
||||
|
@ -2970,25 +2961,24 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
|||
|
||||
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
|
||||
SInputColumnInfoData* pColInfo = &pCtx->input;
|
||||
int32_t start = pColInfo->startRowIndex;
|
||||
|
||||
pOutput->bytes = pInput->bytes;
|
||||
TSKEY* tsIn = &pInput->ts;
|
||||
TSKEY* tsOut = &pOutput->ts;
|
||||
|
||||
int32_t start = pColInfo->startRowIndex;
|
||||
if (pOutput->hasResult) {
|
||||
if (isFirst) {
|
||||
if (*tsIn > *tsOut) {
|
||||
if (pInput->ts > pOutput->ts) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (*tsIn < *tsOut) {
|
||||
if (pInput->ts < pOutput->ts) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*tsOut = *tsIn;
|
||||
pOutput->isNull = pInput->isNull;
|
||||
pOutput->ts = pInput->ts;
|
||||
pOutput->bytes = pInput->bytes;
|
||||
|
||||
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
|
||||
saveTupleData(pCtx->pSrcBlock, start, pCtx, pOutput);
|
||||
|
||||
|
@ -3015,7 +3005,6 @@ static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuer
|
|||
}
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3116,9 +3105,9 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) {
|
|||
TSKEY startKey = getRowPTs(pInput->pPTS, 0);
|
||||
TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1);
|
||||
|
||||
#if 0
|
||||
int32_t blockDataOrder = (startKey <= endKey) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
|
||||
|
||||
#if 0
|
||||
// the optimized version only function if all tuples in one block are monotonious increasing or descreasing.
|
||||
// this is NOT always works if project operator exists in downstream.
|
||||
if (blockDataOrder == TSDB_ORDER_ASC) {
|
||||
|
@ -3158,6 +3147,7 @@ int32_t lastRowFunction(SqlFunctionCtx* pCtx) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
SET_VAL(pResInfo, numOfElems, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -3188,6 +3178,8 @@ bool diffFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
|||
static void doSetPrevVal(SDiffInfo* pDiffInfo, int32_t type, const char* pv) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
pDiffInfo->prev.i64 = *(bool*)pv? 1:0;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
pDiffInfo->prev.i64 = *(int8_t*)pv;
|
||||
break;
|
||||
|
@ -3197,6 +3189,7 @@ static void doSetPrevVal(SDiffInfo* pDiffInfo, int32_t type, const char* pv) {
|
|||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
pDiffInfo->prev.i64 = *(int16_t*)pv;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
pDiffInfo->prev.i64 = *(int64_t*)pv;
|
||||
break;
|
||||
|
@ -3250,6 +3243,7 @@ static void doHandleDiff(SDiffInfo* pDiffInfo, int32_t type, const char* pv, SCo
|
|||
pDiffInfo->prev.i64 = v;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)pv;
|
||||
int64_t delta = factor * (v - pDiffInfo->prev.i64); // direct previous may be null
|
||||
|
@ -4281,9 +4275,9 @@ static int32_t histogramFunctionImpl(SqlFunctionCtx* pCtx, bool isPartial) {
|
|||
}
|
||||
|
||||
if (!isPartial) {
|
||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, pInfo->numOfBins);
|
||||
GET_RES_INFO(pCtx)->numOfRes = pInfo->numOfBins;
|
||||
} else {
|
||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,11 @@ EFuncDataRequired fmFuncDynDataRequired(int32_t funcId, void* pRes, STimeWindow*
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
const char* name = funcMgtBuiltins[funcId].name;
|
||||
if ((strcmp(name, "_group_key") == 0) || (strcmp(name, "_select_value") == 0)) {
|
||||
return FUNC_DATA_REQUIRED_NOT_LOAD;
|
||||
}
|
||||
|
||||
if (funcMgtBuiltins[funcId].dynDataRequiredFunc == NULL) {
|
||||
return FUNC_DATA_REQUIRED_DATA_LOAD;
|
||||
} else {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* 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 "function.h"
|
||||
#include "os.h"
|
||||
|
||||
#include "texception.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *));
|
||||
|
||||
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
||||
if (pNode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pNode->nodeType == TEXPR_BINARYEXPR_NODE || pNode->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
doExprTreeDestroy(&pNode, fp);
|
||||
}
|
||||
taosMemoryFree(pNode);
|
||||
}
|
||||
|
||||
static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
||||
if (*pExpr == NULL) {
|
||||
return;
|
||||
}
|
||||
taosMemoryFree(*pExpr);
|
||||
*pExpr = NULL;
|
||||
}
|
||||
|
||||
// TODO: these three functions should be made global
|
||||
static void* exception_calloc(size_t nmemb, size_t size) {
|
||||
void* p = taosMemoryCalloc(nmemb, size);
|
||||
if (p == NULL) {
|
||||
THROW(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void* exception_malloc(size_t size) {
|
||||
void* p = taosMemoryMalloc(size);
|
||||
if (p == NULL) {
|
||||
THROW(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static UNUSED_FUNC char* exception_strdup(const char* str) {
|
||||
char* p = strdup(str);
|
||||
if (p == NULL) {
|
||||
THROW(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tmsg.h"
|
||||
#include "thash.h"
|
||||
#include "ttypes.h"
|
||||
|
||||
#include "function.h"
|
||||
#include "tbuffer.h"
|
||||
#include "tcompression.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tfunctionInt.h"
|
||||
#include "thistogram.h"
|
||||
#include "tpercentile.h"
|
||||
#include "ttszip.h"
|
||||
#include "tudf.h"
|
||||
|
||||
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell) {
|
||||
pCell->initialized = false;
|
||||
}
|
||||
|
||||
int32_t getNumOfResult(SqlFunctionCtx* pCtx, int32_t num, SSDataBlock* pResBlock) {
|
||||
int32_t maxRows = 0;
|
||||
|
||||
for (int32_t j = 0; j < num; ++j) {
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(&pCtx[j]);
|
||||
if (pResInfo != NULL && maxRows < pResInfo->numOfRes) {
|
||||
maxRows = pResInfo->numOfRes;
|
||||
}
|
||||
}
|
||||
|
||||
assert(maxRows >= 0);
|
||||
|
||||
blockDataEnsureCapacity(pResBlock, maxRows);
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
SColumnInfoData* pCol = taosArrayGet(pResBlock->pDataBlock, i);
|
||||
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(&pCtx[i]);
|
||||
if (pResInfo->numOfRes == 0) {
|
||||
for(int32_t j = 0; j < pResInfo->numOfRes; ++j) {
|
||||
colDataAppend(pCol, j, NULL, true); // TODO add set null data api
|
||||
}
|
||||
} else {
|
||||
for (int32_t j = 0; j < pResInfo->numOfRes; ++j) {
|
||||
colDataAppend(pCol, j, GET_ROWCELL_INTERBUF(pResInfo), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pResBlock->info.rows = maxRows;
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry) {
|
||||
assert(pEntry != NULL);
|
||||
return pEntry->complete;
|
||||
}
|
||||
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry) {
|
||||
return pEntry->initialized;
|
||||
}
|
|
@ -1787,6 +1787,7 @@ static int32_t jsonToPhysiJoinNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkAggPhysiPlanExprs = "Exprs";
|
||||
static const char* jkAggPhysiPlanGroupKeys = "GroupKeys";
|
||||
static const char* jkAggPhysiPlanAggFuncs = "AggFuncs";
|
||||
static const char* jkAggPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||
|
||||
static int32_t physiAggNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SAggPhysiNode* pNode = (const SAggPhysiNode*)pObj;
|
||||
|
@ -1801,6 +1802,9 @@ static int32_t physiAggNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkAggPhysiPlanAggFuncs, pNode->pAggFuncs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkAggPhysiPlanMergeDataBlock, pNode->mergeDataBlock);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1818,6 +1822,9 @@ static int32_t jsonToPhysiAggNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkAggPhysiPlanAggFuncs, &pNode->pAggFuncs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkAggPhysiPlanMergeDataBlock, &pNode->mergeDataBlock);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1950,8 +1957,9 @@ static const char* jkWindowPhysiPlanTsEnd = "TsEnd";
|
|||
static const char* jkWindowPhysiPlanTriggerType = "TriggerType";
|
||||
static const char* jkWindowPhysiPlanWatermark = "Watermark";
|
||||
static const char* jkWindowPhysiPlanIgnoreExpired = "IgnoreExpired";
|
||||
static const char* jkWindowPhysiPlanInputTsOrder = "inputTsOrder";
|
||||
static const char* jkWindowPhysiPlanInputTsOrder = "InputTsOrder";
|
||||
static const char* jkWindowPhysiPlanOutputTsOrder = "outputTsOrder";
|
||||
static const char* jkWindowPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||
|
||||
static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SWinodwPhysiNode* pNode = (const SWinodwPhysiNode*)pObj;
|
||||
|
@ -1984,6 +1992,9 @@ static int32_t physiWindowNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkWindowPhysiPlanOutputTsOrder, pNode->outputTsOrder);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkWindowPhysiPlanMergeDataBlock, pNode->mergeDataBlock);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2019,6 +2030,9 @@ static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
tjsonGetNumberValue(pJson, jkWindowPhysiPlanOutputTsOrder, pNode->outputTsOrder, code);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkWindowPhysiPlanMergeDataBlock, &pNode->mergeDataBlock);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2161,7 +2175,6 @@ static int32_t jsonToPhysiSessionWindowNode(const SJson* pJson, void* pObj) {
|
|||
int32_t code = jsonToPhysiWindowNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
tjsonGetNumberValue(pJson, jkSessionWindowPhysiPlanGap, pNode->gap, code);
|
||||
;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
#include "parInt.h"
|
||||
#include "parToken.h"
|
||||
#include "parUtil.h"
|
||||
#include "query.h"
|
||||
#include "tglobal.h"
|
||||
#include "ttime.h"
|
||||
#include "ttypes.h"
|
||||
#include "query.h"
|
||||
|
||||
#define NEXT_TOKEN(pSql, sToken) \
|
||||
do { \
|
||||
|
@ -1189,15 +1189,13 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks,
|
|||
if (!isParseBindParam) {
|
||||
// set the null value for the columns that do not assign values
|
||||
if ((spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) {
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE
|
||||
tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(schema[i].type), true, schema[i].type, i,
|
||||
spd->cols[i].toffset);
|
||||
}
|
||||
}
|
||||
pBuilder->hasNone = true;
|
||||
}
|
||||
|
||||
tdSRowEnd(pBuilder);
|
||||
|
||||
*gotRow = true;
|
||||
|
||||
#ifdef TD_DEBUG_PRINT_ROW
|
||||
STSchema* pSTSchema = tdGetSTSChemaFromSSChema(schema, spd->numOfCols, 1);
|
||||
tdSRowPrint(row, pSTSchema, __func__);
|
||||
|
@ -1266,7 +1264,8 @@ static int32_t parseValuesClause(SInsertParseContext* pCxt, STableDataBlocks* da
|
|||
|
||||
SSubmitBlk* pBlocks = (SSubmitBlk*)(dataBuf->pData);
|
||||
if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, dataBuf, numOfRows)) {
|
||||
return buildInvalidOperationMsg(&pCxt->msg, "too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
return buildInvalidOperationMsg(&pCxt->msg,
|
||||
"too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
}
|
||||
|
||||
dataBuf->numOfTables = 1;
|
||||
|
@ -1338,7 +1337,8 @@ static int32_t parseDataFromFile(SInsertParseContext* pCxt, SToken filePath, STa
|
|||
|
||||
SSubmitBlk* pBlocks = (SSubmitBlk*)(dataBuf->pData);
|
||||
if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, dataBuf, numOfRows)) {
|
||||
return buildInvalidOperationMsg(&pCxt->msg, "too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
return buildInvalidOperationMsg(&pCxt->msg,
|
||||
"too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
}
|
||||
|
||||
dataBuf->numOfTables = 1;
|
||||
|
@ -1975,13 +1975,9 @@ int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, in
|
|||
}
|
||||
// set the null value for the columns that do not assign values
|
||||
if ((spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) {
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE
|
||||
tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(pSchema[i].type), true, pSchema[i].type, i,
|
||||
spd->cols[i].toffset);
|
||||
}
|
||||
}
|
||||
pBuilder->hasNone = true;
|
||||
}
|
||||
tdSRowEnd(pBuilder);
|
||||
#ifdef TD_DEBUG_PRINT_ROW
|
||||
STSchema* pSTSchema = tdGetSTSChemaFromSSChema(pSchema, spd->numOfCols, 1);
|
||||
tdSRowPrint(row, pSTSchema, __func__);
|
||||
|
@ -2058,14 +2054,11 @@ int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBu
|
|||
|
||||
// set the null value for the columns that do not assign values
|
||||
if (rowEnd && (spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) {
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE
|
||||
tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(pSchema[i].type), true, pSchema[i].type, i,
|
||||
spd->cols[i].toffset);
|
||||
}
|
||||
}
|
||||
pBuilder->hasNone = true;
|
||||
}
|
||||
if (rowEnd) {
|
||||
tdSRowEnd(pBuilder);
|
||||
}
|
||||
|
||||
#ifdef TD_DEBUG_PRINT_ROW
|
||||
if (rowEnd) {
|
||||
STSchema* pSTSchema = tdGetSTSChemaFromSSChema(pSchema, spd->numOfCols, 1);
|
||||
|
@ -2080,7 +2073,8 @@ int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBu
|
|||
|
||||
SSubmitBlk* pBlocks = (SSubmitBlk*)(pDataBlock->pData);
|
||||
if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, pDataBlock, bind->num)) {
|
||||
return buildInvalidOperationMsg(&pBuf, "too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
return buildInvalidOperationMsg(&pBuf,
|
||||
"too many rows in sql, total number of rows should be less than INT32_MAX");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2437,14 +2431,10 @@ int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols
|
|||
|
||||
// set the null value for the columns that do not assign values
|
||||
if ((spd->numOfBound < spd->numOfCols) && TD_IS_TP_ROW(row)) {
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (spd->cols[i].valStat == VAL_STAT_NONE) { // the primary TS key is not VAL_STAT_NONE
|
||||
tdAppendColValToTpRow(pBuilder, TD_VTYPE_NONE, getNullValue(pSchema[i].type), true, pSchema[i].type, i,
|
||||
spd->cols[i].toffset);
|
||||
}
|
||||
}
|
||||
pBuilder->hasNone = true;
|
||||
}
|
||||
|
||||
tdSRowEnd(pBuilder);
|
||||
pDataBlock->size += extendedRowSize;
|
||||
}
|
||||
|
||||
|
|
|
@ -486,11 +486,11 @@ static int32_t tdBlockRowMerge(STableMeta* pTableMeta, SBlockKeyTuple* pEndKeyTp
|
|||
void* pDestRow = NULL;
|
||||
++((*pBlkRowMerger)->index);
|
||||
if ((*pBlkRowMerger)->index < taosArrayGetSize((*pBlkRowMerger)->rowArray)) {
|
||||
void* pAlloc = *(void**)taosArrayGet((*pBlkRowMerger)->rowArray, (*pBlkRowMerger)->index);
|
||||
if (tRealloc((uint8_t**)&pAlloc, rowSize) != 0) {
|
||||
void** pAlloc = (void**)taosArrayGet((*pBlkRowMerger)->rowArray, (*pBlkRowMerger)->index);
|
||||
if (tRealloc((uint8_t**)pAlloc, rowSize) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pDestRow = pAlloc;
|
||||
pDestRow = *pAlloc;
|
||||
} else {
|
||||
if (tRealloc((uint8_t**)&pDestRow, rowSize) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -659,6 +659,7 @@ static int trimDataBlock(void* pDataBlock, STableDataBlocks* pTableDataBlock, SB
|
|||
toffset += TYPE_BYTES[colType];
|
||||
p += pSchema[j].bytes;
|
||||
}
|
||||
tdSRowEnd(&builder);
|
||||
int32_t rowLen = TD_ROW_LEN((STSRow*)pDataBlock);
|
||||
pDataBlock = (char*)pDataBlock + rowLen;
|
||||
pBlock->dataLen += rowLen;
|
||||
|
|
|
@ -342,7 +342,7 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
pJoin->inputTsOrder = ORDER_ASC;
|
||||
pJoin->node.groupAction = GROUP_ACTION_CLEAR;
|
||||
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL;
|
||||
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL;
|
||||
pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -468,6 +468,16 @@ static int32_t createGroupKeysFromPartKeys(SNodeList* pPartKeys, SNodeList** pOu
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EGroupAction getGroupAction(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
return (pCxt->pPlanCxt->streamQuery || NULL != pSelect->pLimit || NULL != pSelect->pSlimit) ? GROUP_ACTION_KEEP
|
||||
: GROUP_ACTION_NONE;
|
||||
}
|
||||
|
||||
static EDataOrderLevel getRequireDataOrder(bool needTimeline, SSelectStmt* pSelect) {
|
||||
return needTimeline ? (NULL != pSelect->pPartitionByList ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_GLOBAL)
|
||||
: DATA_ORDER_LEVEL_NONE;
|
||||
}
|
||||
|
||||
static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||
if (!pSelect->hasAggFuncs && NULL == pSelect->pGroupByList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -481,9 +491,9 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
pAgg->hasLastRow = pSelect->hasLastRowFunc;
|
||||
pAgg->hasTimeLineFunc = pSelect->hasTimeLineFunc;
|
||||
pAgg->onlyHasKeepOrderFunc = pSelect->onlyHasKeepOrderFunc;
|
||||
pAgg->node.groupAction = GROUP_ACTION_SET;
|
||||
pAgg->node.requireDataOrder = pAgg->hasTimeLineFunc ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_NONE;
|
||||
pAgg->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
pAgg->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pAgg->node.requireDataOrder = getRequireDataOrder(pAgg->hasTimeLineFunc, pSelect);
|
||||
pAgg->node.resultDataOrder = pAgg->onlyHasKeepOrderFunc ? pAgg->node.requireDataOrder : DATA_ORDER_LEVEL_NONE;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -552,9 +562,8 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
|
|||
pIdfRowsFunc->isTailFunc = pSelect->hasTailFunc;
|
||||
pIdfRowsFunc->isUniqueFunc = pSelect->hasUniqueFunc;
|
||||
pIdfRowsFunc->isTimeLineFunc = pSelect->hasTimeLineFunc;
|
||||
pIdfRowsFunc->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pIdfRowsFunc->node.requireDataOrder =
|
||||
pIdfRowsFunc->isTimeLineFunc ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_NONE;
|
||||
pIdfRowsFunc->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pIdfRowsFunc->node.requireDataOrder = getRequireDataOrder(pIdfRowsFunc->isTimeLineFunc, pSelect);
|
||||
pIdfRowsFunc->node.resultDataOrder = pIdfRowsFunc->node.requireDataOrder;
|
||||
|
||||
// indefinite rows functions and _select_values functions
|
||||
|
@ -587,8 +596,8 @@ static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pInterpFunc->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pInterpFunc->node.requireDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pInterpFunc->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pInterpFunc->node.requireDataOrder = getRequireDataOrder(true, pSelect);
|
||||
pInterpFunc->node.resultDataOrder = pInterpFunc->node.requireDataOrder;
|
||||
|
||||
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsInterpFunc, &pInterpFunc->pFuncs);
|
||||
|
@ -663,9 +672,11 @@ static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindo
|
|||
}
|
||||
|
||||
pWindow->winType = WINDOW_TYPE_STATE;
|
||||
pWindow->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pWindow->node.requireDataOrder = pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pWindow->node.resultDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pWindow->node.requireDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
|
||||
pWindow->node.resultDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
|
||||
pWindow->pStateExpr = nodesCloneNode(pState->pExpr);
|
||||
pWindow->pTspk = nodesCloneNode(pState->pCol);
|
||||
if (NULL == pWindow->pStateExpr || NULL == pWindow->pTspk) {
|
||||
|
@ -686,9 +697,11 @@ static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionW
|
|||
pWindow->winType = WINDOW_TYPE_SESSION;
|
||||
pWindow->sessionGap = ((SValueNode*)pSession->pGap)->datum.i;
|
||||
pWindow->windowAlgo = pCxt->pPlanCxt->streamQuery ? SESSION_ALGO_STREAM_SINGLE : SESSION_ALGO_MERGE;
|
||||
pWindow->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pWindow->node.requireDataOrder = pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pWindow->node.resultDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pWindow->node.requireDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
|
||||
pWindow->node.resultDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
|
||||
|
||||
pWindow->pTspk = nodesCloneNode((SNode*)pSession->pCol);
|
||||
if (NULL == pWindow->pTspk) {
|
||||
|
@ -715,9 +728,13 @@ static int32_t createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SInterva
|
|||
pWindow->slidingUnit =
|
||||
(NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->unit : pWindow->intervalUnit);
|
||||
pWindow->windowAlgo = pCxt->pPlanCxt->streamQuery ? INTERVAL_ALGO_STREAM_SINGLE : INTERVAL_ALGO_HASH;
|
||||
pWindow->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pWindow->node.requireDataOrder = pSelect->hasTimeLineFunc ? DATA_ORDER_LEVEL_IN_GROUP : DATA_ORDER_LEVEL_IN_BLOCK;
|
||||
pWindow->node.resultDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pWindow->node.groupAction = (NULL != pInterval->pFill ? GROUP_ACTION_KEEP : getGroupAction(pCxt, pSelect));
|
||||
pWindow->node.requireDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery
|
||||
? DATA_ORDER_LEVEL_IN_BLOCK
|
||||
: (pSelect->hasTimeLineFunc ? getRequireDataOrder(true, pSelect) : DATA_ORDER_LEVEL_IN_BLOCK);
|
||||
pWindow->node.resultDataOrder =
|
||||
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : getRequireDataOrder(true, pSelect);
|
||||
|
||||
pWindow->pTspk = nodesCloneNode(pInterval->pCol);
|
||||
if (NULL == pWindow->pTspk) {
|
||||
|
@ -763,9 +780,9 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pFill->node.groupAction = GROUP_ACTION_KEEP;
|
||||
pFill->node.requireDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pFill->node.resultDataOrder = DATA_ORDER_LEVEL_IN_GROUP;
|
||||
pFill->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||
pFill->node.requireDataOrder = getRequireDataOrder(true, pSelect);
|
||||
pFill->node.resultDataOrder = pFill->node.requireDataOrder;
|
||||
pFill->inputTsOrder = ORDER_ASC;
|
||||
|
||||
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WINDOW, NULL, COLLECT_COL_TYPE_ALL, &pFill->node.pTargets);
|
||||
|
@ -938,7 +955,7 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pAgg->node.groupAction = GROUP_ACTION_SET;
|
||||
pAgg->node.groupAction = GROUP_ACTION_CLEAR;
|
||||
pAgg->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
pAgg->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ static int32_t scanPathOptGetScanOrder(SScanLogicNode* pScan, EScanOrder* pScanO
|
|||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (FUNCTION_TYPE_FIRST == pFunc->funcType) {
|
||||
hasFirst = true;
|
||||
} else if (FUNCTION_TYPE_LAST == pFunc->funcType) {
|
||||
} else if (FUNCTION_TYPE_LAST == pFunc->funcType || FUNCTION_TYPE_LAST_ROW == pFunc->funcType) {
|
||||
hasLast = true;
|
||||
} else if (FUNCTION_TYPE_SELECT_VALUE != pFunc->funcType) {
|
||||
otherFunc = true;
|
||||
|
|
|
@ -825,6 +825,8 @@ static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pAgg->mergeDataBlock = (GROUP_ACTION_KEEP == pAggLogicNode->node.groupAction ? false : true);
|
||||
|
||||
SNodeList* pPrecalcExprs = NULL;
|
||||
SNodeList* pGroupKeys = NULL;
|
||||
SNodeList* pAggFuncs = NULL;
|
||||
|
@ -983,7 +985,7 @@ static bool projectCanMergeDataBlock(SProjectLogicNode* pProject) {
|
|||
return true;
|
||||
}
|
||||
if (1 != LIST_LENGTH(pProject->node.pChildren)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProject->node.pChildren, 0);
|
||||
return DATA_ORDER_LEVEL_GLOBAL == pChild->resultDataOrder ? true : false;
|
||||
|
@ -1092,6 +1094,7 @@ static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList*
|
|||
pWindow->igExpired = pWindowLogicNode->igExpired;
|
||||
pWindow->inputTsOrder = pWindowLogicNode->inputTsOrder;
|
||||
pWindow->outputTsOrder = pWindowLogicNode->outputTsOrder;
|
||||
pWindow->mergeDataBlock = (GROUP_ACTION_KEEP == pWindowLogicNode->node.groupAction ? false : true);
|
||||
|
||||
SNodeList* pPrecalcExprs = NULL;
|
||||
SNodeList* pFuncs = NULL;
|
||||
|
|
|
@ -393,6 +393,8 @@ static int32_t stbSplCreatePartWindowNode(SWindowLogicNode* pMergeWindow, SLogic
|
|||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pPartWin->node.groupAction = GROUP_ACTION_KEEP;
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pMergeWindow->node.pTargets = pTargets;
|
||||
pMergeWindow->node.pConditions = pConditions;
|
||||
|
@ -723,6 +725,8 @@ static int32_t stbSplCreatePartAggNode(SAggLogicNode* pMergeAgg, SLogicNode** pO
|
|||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pPartAgg->node.groupAction = GROUP_ACTION_KEEP;
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pGroupKeys) {
|
||||
pPartAgg->pGroupKeys = pGroupKeys;
|
||||
code = createColumnByRewriteExprs(pPartAgg->pGroupKeys, &pPartAgg->node.pTargets);
|
||||
|
|
|
@ -232,7 +232,8 @@ static int32_t adjustPartitionDataRequirement(SPartitionLogicNode* pPart, EDataO
|
|||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
pPart->node.resultDataOrder = requirement;
|
||||
pPart->node.requireDataOrder = requirement;
|
||||
pPart->node.requireDataOrder =
|
||||
(requirement >= DATA_ORDER_LEVEL_IN_BLOCK ? DATA_ORDER_LEVEL_GLOBAL : DATA_ORDER_LEVEL_NONE);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,22 @@ TEST_F(PlanGroupByTest, basic) {
|
|||
run("SELECT c1 + c3, SUM(c4 * c5) FROM t1 WHERE CONCAT(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
|
||||
|
||||
run("SELECT SUM(CEIL(c1)) FROM t1 GROUP BY CEIL(c1)");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1");
|
||||
|
||||
run("SELECT c1 FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT SUM(c1) FROM st1 GROUP BY c2 HAVING SUM(c1) IS NOT NULL");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, withPartitionBy) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT LAST(ts), TBNAME FROM st1 PARTITION BY TBNAME");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 PARTITION BY c2 GROUP BY c1");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, withOrderBy) {
|
||||
|
@ -43,14 +59,12 @@ TEST_F(PlanGroupByTest, withOrderBy) {
|
|||
// run("SELECT COUNT(*), SUM(c1) a FROM t1 ORDER BY a");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, aggFunc) {
|
||||
TEST_F(PlanGroupByTest, multiResFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1");
|
||||
|
||||
run("SELECT LAST(*), FIRST(*) FROM t1 GROUP BY c1");
|
||||
|
||||
run("SELECT SUM(10), COUNT(c1) FROM t1 GROUP BY c2");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, selectFunc) {
|
||||
|
@ -67,17 +81,3 @@ TEST_F(PlanGroupByTest, selectFunc) {
|
|||
run("SELECT MAX(c1), c2 FROM t1 GROUP BY c3");
|
||||
run("SELECT MAX(c1), t1.* FROM t1 GROUP BY c3");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, stable) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1");
|
||||
|
||||
run("SELECT c1 FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 PARTITION BY c2 GROUP BY c1");
|
||||
|
||||
run("SELECT SUM(c1) FROM st1 GROUP BY c2 HAVING SUM(c1) IS NOT NULL");
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ extern "C" {
|
|||
#define QW_DEFAULT_SHORT_RUN_TIMES 2
|
||||
#define QW_DEFAULT_HEARTBEAT_MSEC 5000
|
||||
#define QW_SCH_TIMEOUT_MSEC 180000
|
||||
#define QW_MIN_RES_ROWS 4096
|
||||
|
||||
enum {
|
||||
QW_PHASE_PRE_QUERY = 1,
|
||||
|
@ -135,6 +136,7 @@ typedef struct SQWTaskCtx {
|
|||
int32_t msgType;
|
||||
int32_t fetchType;
|
||||
int32_t execId;
|
||||
int32_t level;
|
||||
|
||||
bool queryRsped;
|
||||
bool queryEnd;
|
||||
|
|
|
@ -12,14 +12,16 @@
|
|||
int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp) {
|
||||
int32_t msgSize = sizeof(SRetrieveTableRsp) + length;
|
||||
|
||||
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(msgSize);
|
||||
SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcReallocCont(*rsp, msgSize);
|
||||
if (NULL == pRsp) {
|
||||
qError("rpcMallocCont %d failed", msgSize);
|
||||
QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
||||
|
||||
if (NULL == *rsp) {
|
||||
memset(pRsp, 0, sizeof(SRetrieveTableRsp));
|
||||
}
|
||||
|
||||
*rsp = pRsp;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -35,6 +37,7 @@ void qwBuildFetchRsp(void *msg, SOutputData *input, int32_t len, bool qComplete)
|
|||
rsp->compLen = htonl(len);
|
||||
rsp->numOfRows = htonl(input->numOfRows);
|
||||
rsp->numOfCols = htonl(input->numOfCols);
|
||||
rsp->numOfBlocks = htonl(input->numOfBlocks);
|
||||
}
|
||||
|
||||
void qwFreeFetchRsp(void *msg) {
|
||||
|
|
|
@ -75,22 +75,20 @@ int32_t qwHandleTaskComplete(QW_FPARAMS_DEF, SQWTaskCtx *ctx) {
|
|||
int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryStop) {
|
||||
int32_t code = 0;
|
||||
bool qcontinue = true;
|
||||
SSDataBlock *pRes = NULL;
|
||||
uint64_t useconds = 0;
|
||||
int32_t i = 0;
|
||||
int32_t execNum = 0;
|
||||
qTaskInfo_t taskHandle = ctx->taskHandle;
|
||||
DataSinkHandle sinkHandle = ctx->sinkHandle;
|
||||
|
||||
SArray* pResList = taosArrayInit(4, POINTER_BYTES);
|
||||
while (true) {
|
||||
QW_TASK_DLOG("start to execTask, loopIdx:%d", i++);
|
||||
|
||||
pRes = NULL;
|
||||
|
||||
// if *taskHandle is NULL, it's killed right now
|
||||
if (taskHandle) {
|
||||
qwDbgSimulateSleep();
|
||||
code = qExecTask(taskHandle, &pRes, &useconds);
|
||||
code = qExecTaskOpt(taskHandle, pResList, &useconds);
|
||||
if (code) {
|
||||
if (code != TSDB_CODE_OPS_NOT_SUPPORT) {
|
||||
QW_TASK_ELOG("qExecTask failed, code:%x - %s", code, tstrerror(code));
|
||||
|
@ -103,9 +101,8 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryStop) {
|
|||
|
||||
++execNum;
|
||||
|
||||
if (NULL == pRes) {
|
||||
if (taosArrayGetSize(pResList) == 0) {
|
||||
QW_TASK_DLOG("qExecTask end with empty res, useconds:%" PRIu64, useconds);
|
||||
|
||||
dsEndPut(sinkHandle, useconds);
|
||||
|
||||
QW_ERR_RET(qwHandleTaskComplete(QW_FPARAMS(), ctx));
|
||||
|
@ -117,19 +114,20 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryStop) {
|
|||
break;
|
||||
}
|
||||
|
||||
int32_t rows = pRes->info.rows;
|
||||
for(int32_t j = 0; j < taosArrayGetSize(pResList); ++j) {
|
||||
SSDataBlock *pRes = taosArrayGetP(pResList, j);
|
||||
ASSERT(pRes->info.rows > 0);
|
||||
|
||||
ASSERT(pRes->info.rows > 0);
|
||||
SInputData inputData = {.pData = pRes};
|
||||
code = dsPutDataBlock(sinkHandle, &inputData, &qcontinue);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsPutDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
SInputData inputData = {.pData = pRes};
|
||||
code = dsPutDataBlock(sinkHandle, &inputData, &qcontinue);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsPutDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
QW_TASK_DLOG("data put into sink, rows:%d, continueExecTask:%d", pRes->info.rows, qcontinue);
|
||||
}
|
||||
|
||||
QW_TASK_DLOG("data put into sink, rows:%d, continueExecTask:%d", rows, qcontinue);
|
||||
|
||||
if (!qcontinue) {
|
||||
if (queryStop) {
|
||||
*queryStop = true;
|
||||
|
@ -151,6 +149,7 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryStop) {
|
|||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pResList);
|
||||
QW_RET(code);
|
||||
}
|
||||
|
||||
|
@ -203,57 +202,88 @@ int32_t qwGetQueryResFromSink(QW_FPARAMS_DEF, SQWTaskCtx *ctx, int32_t *dataLen,
|
|||
SRetrieveTableRsp *rsp = NULL;
|
||||
bool queryEnd = false;
|
||||
int32_t code = 0;
|
||||
SOutputData output = {0};
|
||||
|
||||
dsGetDataLength(ctx->sinkHandle, &len, &queryEnd);
|
||||
*dataLen = 0;
|
||||
|
||||
if (len < 0) {
|
||||
QW_TASK_ELOG("invalid length from dsGetDataLength, length:%d", len);
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
while (true) {
|
||||
dsGetDataLength(ctx->sinkHandle, &len, &queryEnd);
|
||||
|
||||
if (len == 0) {
|
||||
if (queryEnd) {
|
||||
code = dsGetDataBlock(ctx->sinkHandle, pOutput);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsGetDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
QW_TASK_DLOG_E("no data in sink and query end");
|
||||
|
||||
qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_SUCC);
|
||||
QW_ERR_RET(qwMallocFetchRsp(len, &rsp));
|
||||
|
||||
*rspMsg = rsp;
|
||||
*dataLen = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
if (len < 0) {
|
||||
QW_TASK_ELOG("invalid length from dsGetDataLength, length:%d", len);
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
pOutput->bufStatus = DS_BUF_EMPTY;
|
||||
if (len == 0) {
|
||||
if (queryEnd) {
|
||||
code = dsGetDataBlock(ctx->sinkHandle, &output);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsGetDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
QW_TASK_DLOG("no more data in sink and query end, fetched blocks %d rows %d", pOutput->numOfBlocks, pOutput->numOfRows);
|
||||
|
||||
qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_SUCC);
|
||||
if (NULL == rsp) {
|
||||
QW_ERR_RET(qwMallocFetchRsp(len, &rsp));
|
||||
*pOutput = output;
|
||||
} else {
|
||||
pOutput->queryEnd = output.queryEnd;
|
||||
pOutput->bufStatus = output.bufStatus;
|
||||
pOutput->useconds = output.useconds;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
pOutput->bufStatus = DS_BUF_EMPTY;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Got data from sink
|
||||
QW_TASK_DLOG("there are data in sink, dataLength:%d", len);
|
||||
|
||||
*dataLen += len;
|
||||
|
||||
QW_ERR_RET(qwMallocFetchRsp(*dataLen, &rsp));
|
||||
|
||||
output.pData = rsp->data + *dataLen - len;
|
||||
code = dsGetDataBlock(ctx->sinkHandle, &output);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsGetDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
pOutput->queryEnd = output.queryEnd;
|
||||
pOutput->precision = output.precision;
|
||||
pOutput->bufStatus = output.bufStatus;
|
||||
pOutput->useconds = output.useconds;
|
||||
pOutput->compressed = output.compressed;
|
||||
pOutput->numOfCols = output.numOfCols;
|
||||
pOutput->numOfRows += output.numOfRows;
|
||||
pOutput->numOfBlocks++;
|
||||
|
||||
if (DS_BUF_EMPTY == pOutput->bufStatus && pOutput->queryEnd) {
|
||||
QW_TASK_DLOG("task all data fetched and done, fetched blocks %d rows %d", pOutput->numOfBlocks, pOutput->numOfRows);
|
||||
qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_SUCC);
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == ctx->level) {
|
||||
QW_TASK_DLOG("task fetched blocks %d rows %d, level %d", pOutput->numOfBlocks, pOutput->numOfRows, ctx->level);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pOutput->numOfRows >= QW_MIN_RES_ROWS) {
|
||||
QW_TASK_DLOG("task fetched blocks %d rows %d reaches the min rows", pOutput->numOfBlocks, pOutput->numOfRows);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Got data from sink
|
||||
QW_TASK_DLOG("there are data in sink, dataLength:%d", len);
|
||||
|
||||
*dataLen = len;
|
||||
|
||||
QW_ERR_RET(qwMallocFetchRsp(len, &rsp));
|
||||
*rspMsg = rsp;
|
||||
|
||||
pOutput->pData = rsp->data;
|
||||
code = dsGetDataBlock(ctx->sinkHandle, pOutput);
|
||||
if (code) {
|
||||
QW_TASK_ELOG("dsGetDataBlock failed, code:%x - %s", code, tstrerror(code));
|
||||
QW_ERR_RET(code);
|
||||
}
|
||||
|
||||
if (DS_BUF_EMPTY == pOutput->bufStatus && pOutput->queryEnd) {
|
||||
QW_TASK_DLOG_E("task all data fetched, done");
|
||||
qwUpdateTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_SUCC);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -552,6 +582,7 @@ int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, char* sql) {
|
|||
|
||||
// queryRsped = true;
|
||||
|
||||
ctx->level = plan->level;
|
||||
atomic_store_ptr(&ctx->taskHandle, pTaskInfo);
|
||||
atomic_store_ptr(&ctx->sinkHandle, sinkHandle);
|
||||
|
||||
|
|
|
@ -3245,11 +3245,11 @@ _return:
|
|||
return code;
|
||||
}
|
||||
|
||||
bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows) {
|
||||
bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg **pDataStatis, int32_t numOfCols, int32_t numOfRows) {
|
||||
if (info->scalarMode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (FILTER_EMPTY_RES(info)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3265,7 +3265,7 @@ bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t
|
|||
int32_t index = -1;
|
||||
SFilterRangeCtx *ctx = info->colRange[k];
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
if (pDataStatis[i].colId == ctx->colId) {
|
||||
if (pDataStatis[i]->colId == ctx->colId) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -3281,13 +3281,13 @@ bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t
|
|||
break;
|
||||
}
|
||||
|
||||
if (pDataStatis[index].numOfNull <= 0) {
|
||||
if (pDataStatis[index]->numOfNull <= 0) {
|
||||
if (ctx->isnull && !ctx->notnull && !ctx->isrange) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
} else if (pDataStatis[index].numOfNull > 0) {
|
||||
if (pDataStatis[index].numOfNull == numOfRows) {
|
||||
} else if (pDataStatis[index]->numOfNull > 0) {
|
||||
if (pDataStatis[index]->numOfNull == numOfRows) {
|
||||
if ((ctx->notnull || ctx->isrange) && (!ctx->isnull)) {
|
||||
ret = false;
|
||||
break;
|
||||
|
@ -3301,7 +3301,7 @@ bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t
|
|||
}
|
||||
}
|
||||
|
||||
SColumnDataAgg* pDataBlockst = &pDataStatis[index];
|
||||
SColumnDataAgg* pDataBlockst = pDataStatis[index];
|
||||
|
||||
SFilterRangeNode *r = ctx->rs;
|
||||
float minv = 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
|
||||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
||||
|
||||
SStreamQueueItem* streamAppendQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem);
|
||||
SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem);
|
||||
void streamFreeQitem(SStreamQueueItem* data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -27,10 +27,9 @@ int32_t streamDispatchReqToData(const SStreamDispatchReq* pReq, SStreamDataBlock
|
|||
ASSERT(pReq->blockNum == taosArrayGetSize(pReq->dataLen));
|
||||
|
||||
for (int32_t i = 0; i < blockNum; i++) {
|
||||
/*int32_t len = *(int32_t*)taosArrayGet(pReq->dataLen, i);*/
|
||||
SRetrieveTableRsp* pRetrieve = taosArrayGetP(pReq->data, i);
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pArray, i);
|
||||
blockDecode(pDataBlock, htonl(pRetrieve->numOfCols), htonl(pRetrieve->numOfRows), pRetrieve->data);
|
||||
blockDecode(pDataBlock, pRetrieve->data);
|
||||
// TODO: refactor
|
||||
pDataBlock->info.window.skey = be64toh(pRetrieve->skey);
|
||||
pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey);
|
||||
|
@ -52,7 +51,7 @@ int32_t streamRetrieveReqToData(const SStreamRetrieveReq* pReq, SStreamDataBlock
|
|||
taosArraySetSize(pArray, 1);
|
||||
SRetrieveTableRsp* pRetrieve = pReq->pRetrieve;
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pArray, 0);
|
||||
blockDecode(pDataBlock, htonl(pRetrieve->numOfCols), htonl(pRetrieve->numOfRows), pRetrieve->data);
|
||||
blockDecode(pDataBlock, pRetrieve->data);
|
||||
// TODO: refactor
|
||||
pDataBlock->info.window.skey = be64toh(pRetrieve->skey);
|
||||
pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey);
|
||||
|
@ -125,7 +124,7 @@ void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) {
|
|||
}
|
||||
}
|
||||
|
||||
SStreamQueueItem* streamAppendQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem) {
|
||||
SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem) {
|
||||
ASSERT(elem);
|
||||
if (dst->type == STREAM_INPUT__DATA_BLOCK && elem->type == STREAM_INPUT__DATA_BLOCK) {
|
||||
SStreamDataBlock* pBlock = (SStreamDataBlock*)dst;
|
||||
|
@ -172,8 +171,8 @@ void streamFreeQitem(SStreamQueueItem* data) {
|
|||
int32_t ref = atomic_sub_fetch_32(pRef, 1);
|
||||
ASSERT(ref >= 0);
|
||||
if (ref == 0) {
|
||||
void* data = taosArrayGetP(pMerge->reqs, i);
|
||||
taosMemoryFree(data);
|
||||
void* dataStr = taosArrayGetP(pMerge->reqs, i);
|
||||
taosMemoryFree(dataStr);
|
||||
taosMemoryFree(pRef);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -370,80 +370,6 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t streamBuildDispatchMsg(SStreamTask* pTask, const SStreamDataBlock* data, SRpcMsg* pMsg, SEpSet** ppEpSet) {
|
||||
void* buf = NULL;
|
||||
int32_t code = -1;
|
||||
int32_t blockNum = taosArrayGetSize(data->blocks);
|
||||
ASSERT(blockNum != 0);
|
||||
|
||||
SStreamDispatchReq req = {
|
||||
.streamId = pTask->streamId,
|
||||
.dataSrcVgId = data->srcVgId,
|
||||
.upstreamTaskId = pTask->taskId,
|
||||
.upstreamChildId = pTask->selfChildId,
|
||||
.upstreamNodeId = pTask->nodeId,
|
||||
.blockNum = blockNum,
|
||||
};
|
||||
|
||||
req.data = taosArrayInit(blockNum, sizeof(void*));
|
||||
req.dataLen = taosArrayInit(blockNum, sizeof(int32_t));
|
||||
if (req.data == NULL || req.dataLen == NULL) {
|
||||
goto FAIL;
|
||||
}
|
||||
for (int32_t i = 0; i < blockNum; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(data->blocks, i);
|
||||
if (streamAddBlockToDispatchMsg(pDataBlock, &req) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
int32_t vgId = 0;
|
||||
int32_t downstreamTaskId = 0;
|
||||
// find ep
|
||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||
vgId = pTask->fixedEpDispatcher.nodeId;
|
||||
*ppEpSet = &pTask->fixedEpDispatcher.epSet;
|
||||
downstreamTaskId = pTask->fixedEpDispatcher.taskId;
|
||||
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||
// TODO get ctbName for each block
|
||||
SSDataBlock* pBlock = taosArrayGet(data->blocks, 0);
|
||||
char* ctbName = buildCtbNameByGroupId(pTask->shuffleDispatcher.stbFullName, pBlock->info.groupId);
|
||||
// TODO: get hash function by hashMethod
|
||||
|
||||
// get groupId, compute hash value
|
||||
uint32_t hashValue = MurmurHash3_32(ctbName, strlen(ctbName));
|
||||
|
||||
// get node
|
||||
// TODO: optimize search process
|
||||
SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
|
||||
int32_t sz = taosArrayGetSize(vgInfo);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i);
|
||||
ASSERT(pVgInfo->vgId > 0);
|
||||
if (hashValue >= pVgInfo->hashBegin && hashValue <= pVgInfo->hashEnd) {
|
||||
vgId = pVgInfo->vgId;
|
||||
downstreamTaskId = pVgInfo->taskId;
|
||||
*ppEpSet = &pVgInfo->epSet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(vgId > 0 || vgId == SNODE_HANDLE);
|
||||
req.taskId = downstreamTaskId;
|
||||
|
||||
qDebug("dispatch from task %d (child id %d) to down stream task %d in vnode %d", pTask->taskId, pTask->selfChildId,
|
||||
downstreamTaskId, vgId);
|
||||
|
||||
streamDispatchOneReq(pTask, &req, vgId, *ppEpSet);
|
||||
|
||||
code = 0;
|
||||
FAIL:
|
||||
if (code < 0 && buf) rpcFreeCont(buf);
|
||||
if (req.data) taosArrayDestroyP(req.data, (FDelete)taosMemoryFree);
|
||||
if (req.dataLen) taosArrayDestroy(req.dataLen);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t streamDispatch(SStreamTask* pTask) {
|
||||
ASSERT(pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH);
|
||||
|
||||
|
@ -461,7 +387,7 @@ int32_t streamDispatch(SStreamTask* pTask) {
|
|||
}
|
||||
ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK);
|
||||
|
||||
qDebug("stream continue dispatching: task %d", pTask->taskId);
|
||||
qDebug("stream dispatching: task %d", pTask->taskId);
|
||||
|
||||
int32_t code = 0;
|
||||
if (streamDispatchAllBlocks(pTask, pBlock) < 0) {
|
||||
|
|
|
@ -82,17 +82,6 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, const void* data, SArray*
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static FORCE_INLINE int32_t streamUpdateVer(SStreamTask* pTask, SStreamDataBlock* pBlock) {
|
||||
ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK);
|
||||
int32_t childId = pBlock->childId;
|
||||
int64_t ver = pBlock->sourceVer;
|
||||
SStreamChildEpInfo* pChildInfo = taosArrayGetP(pTask->childEpInfo, childId);
|
||||
/*pChildInfo-> = ver;*/
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t streamPipelineExec(SStreamTask* pTask, int32_t batchNum, bool dispatch) {
|
||||
ASSERT(pTask->taskLevel != TASK_LEVEL__SINK);
|
||||
|
||||
|
@ -150,10 +139,11 @@ int32_t streamPipelineExec(SStreamTask* pTask, int32_t batchNum, bool dispatch)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: handle version
|
||||
int32_t streamExecForAll(SStreamTask* pTask) {
|
||||
while (1) {
|
||||
int32_t cnt = 1;
|
||||
int32_t batchCnt = 1;
|
||||
void* data = NULL;
|
||||
while (1) {
|
||||
SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue);
|
||||
|
@ -169,13 +159,12 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
}
|
||||
} else {
|
||||
void* newRet;
|
||||
if ((newRet = streamAppendQueueItem(data, qItem)) == NULL) {
|
||||
if ((newRet = streamMergeQueueItem(data, qItem)) == NULL) {
|
||||
streamQueueProcessFail(pTask->inputQueue);
|
||||
break;
|
||||
} else {
|
||||
cnt++;
|
||||
batchCnt++;
|
||||
data = newRet;
|
||||
/*streamUpdateVer(pTask, (SStreamDataBlock*)qItem);*/
|
||||
streamQueueProcessSuccess(pTask->inputQueue);
|
||||
}
|
||||
}
|
||||
|
@ -198,16 +187,14 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
|
||||
SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
|
||||
|
||||
qDebug("stream task %d exec begin, msg batch: %d", pTask->taskId, cnt);
|
||||
qDebug("stream task %d exec begin, msg batch: %d", pTask->taskId, batchCnt);
|
||||
streamTaskExecImpl(pTask, data, pRes);
|
||||
qDebug("stream task %d exec end", pTask->taskId);
|
||||
|
||||
if (taosArrayGetSize(pRes) != 0) {
|
||||
SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM);
|
||||
if (qRes == NULL) {
|
||||
// TODO log failed ver
|
||||
streamQueueProcessFail(pTask->inputQueue);
|
||||
taosArrayDestroy(pRes);
|
||||
taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
|
||||
streamFreeQitem(data);
|
||||
return -1;
|
||||
}
|
||||
|
@ -218,17 +205,18 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
|||
SStreamDataSubmit* pSubmit = (SStreamDataSubmit*)data;
|
||||
qRes->childId = pTask->selfChildId;
|
||||
qRes->sourceVer = pSubmit->ver;
|
||||
} else if (((SStreamQueueItem*)data)->type == STREAM_INPUT__MERGED_SUBMIT) {
|
||||
SStreamMergedSubmit* pMerged = (SStreamMergedSubmit*)data;
|
||||
qRes->childId = pTask->selfChildId;
|
||||
qRes->sourceVer = pMerged->ver;
|
||||
}
|
||||
|
||||
if (streamTaskOutput(pTask, qRes) < 0) {
|
||||
// TODO save failed ver
|
||||
/*streamQueueProcessFail(pTask->inputQueue);*/
|
||||
taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes);
|
||||
taosFreeQitem(qRes);
|
||||
streamFreeQitem(data);
|
||||
taosFreeQitem(qRes);
|
||||
return -1;
|
||||
}
|
||||
/*streamQueueProcessSuccess(pTask->inputQueue);*/
|
||||
} else {
|
||||
taosArrayDestroy(pRes);
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ SUpdateInfo *updateInfoInit(int64_t interval, int32_t precision, int64_t waterma
|
|||
}
|
||||
pInfo->numBuckets = DEFAULT_BUCKET_SIZE;
|
||||
pInfo->pCloseWinSBF = NULL;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT);
|
||||
pInfo->pMap = taosHashInit(DEFAULT_MAP_CAPACITY, hashFn, true, HASH_NO_LOCK);
|
||||
pInfo->maxVersion = 0;
|
||||
pInfo->scanGroupId = 0;
|
||||
|
|
|
@ -163,6 +163,7 @@ typedef struct SSyncNode {
|
|||
bool changing;
|
||||
|
||||
int64_t startTime;
|
||||
int64_t leaderTime;
|
||||
int64_t lastReplicateTime;
|
||||
|
||||
} SSyncNode;
|
||||
|
|
|
@ -32,9 +32,9 @@ typedef struct SRespStub {
|
|||
} SRespStub;
|
||||
|
||||
typedef struct SSyncRespMgr {
|
||||
SHashObj * pRespHash;
|
||||
SHashObj *pRespHash;
|
||||
int64_t ttl;
|
||||
void * data;
|
||||
void *data;
|
||||
TdThreadMutex mutex;
|
||||
uint64_t seqNum;
|
||||
} SSyncRespMgr;
|
||||
|
@ -46,7 +46,8 @@ int32_t syncRespMgrDel(SSyncRespMgr *pObj, uint64_t index);
|
|||
int32_t syncRespMgrGet(SSyncRespMgr *pObj, uint64_t index, SRespStub *pStub);
|
||||
int32_t syncRespMgrGetAndDel(SSyncRespMgr *pObj, uint64_t index, SRespStub *pStub);
|
||||
void syncRespClean(SSyncRespMgr *pObj);
|
||||
void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl);
|
||||
void syncRespCleanRsp(SSyncRespMgr *pObj);
|
||||
void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl, bool rsp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue