Merge branch '3.0' into enh/3.0/TS-5007
This commit is contained in:
commit
405d924a6f
|
@ -162,3 +162,4 @@ geos_c.h
|
|||
source/libs/parser/src/sql.c
|
||||
include/common/ttokenauto.h
|
||||
!packaging/smokeTest/pytest_require.txt
|
||||
tdengine-test-dir
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# timezone
|
||||
ExternalProject_Add(tz
|
||||
GIT_REPOSITORY https://github.com/eggert/tz.git
|
||||
GIT_TAG main
|
||||
SOURCE_DIR "${TD_CONTRIB_DIR}/tz"
|
||||
BINARY_DIR ""
|
||||
CONFIGURE_COMMAND ""
|
||||
#BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
GIT_SHALLOW true
|
||||
GIT_PROGRESS true
|
||||
BUILD_COMMAND ""
|
||||
)
|
||||
|
|
@ -106,6 +106,10 @@ cat("${TD_SUPPORT_DIR}/zlib_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
|||
# cJson
|
||||
cat("${TD_SUPPORT_DIR}/cjson_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
|
||||
if(NOT ${TD_WINDOWS})
|
||||
cat("${TD_SUPPORT_DIR}/tz_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
endif(NOT ${TD_WINDOWS})
|
||||
|
||||
# xz
|
||||
# cat("${TD_SUPPORT_DIR}/xz_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||
|
||||
|
@ -651,6 +655,35 @@ if(${TD_LINUX} AND ${BUILD_WITH_S3})
|
|||
add_subdirectory(azure-cmake EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
IF(TD_LINUX)
|
||||
SET(TZ_OUTPUT_PATH /usr/share/zoneinfo)
|
||||
ELSEIF(TD_DARWIN)
|
||||
SET(TZ_OUTPUT_PATH /var/db/timezone/zoneinfo)
|
||||
ENDIF()
|
||||
|
||||
|
||||
if(NOT ${TD_WINDOWS})
|
||||
MESSAGE(STATUS "timezone file path: " ${TZ_OUTPUT_PATH})
|
||||
|
||||
execute_process(
|
||||
COMMAND make TZDIR=${TZ_OUTPUT_PATH}/ clean tzdir.h
|
||||
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/tz"
|
||||
)
|
||||
|
||||
set(TZ_SRC_DIR "${TD_SOURCE_DIR}/source/os/src/timezone")
|
||||
file(REMOVE_RECURSE ${TZ_SRC_DIR})
|
||||
file(MAKE_DIRECTORY ${TZ_SRC_DIR})
|
||||
file(COPY ${TD_CONTRIB_DIR}/tz/private.h ${TD_CONTRIB_DIR}/tz/tzdir.h ${TD_CONTRIB_DIR}/tz/tzfile.h
|
||||
${TD_CONTRIB_DIR}/tz/localtime.c ${TD_CONTRIB_DIR}/tz/strftime.c
|
||||
DESTINATION ${TZ_SRC_DIR})
|
||||
endif(NOT ${TD_WINDOWS})
|
||||
|
||||
#if(NOT ${TD_WINDOWS})
|
||||
# execute_process(
|
||||
# COMMAND make CFLAGS+=-fPIC CFLAGS+=-g TZDIR=${TZ_OUTPUT_PATH} clean libtz.a
|
||||
# WORKING_DIRECTORY "${TD_CONTRIB_DIR}/tz"
|
||||
# )
|
||||
#endif(NOT ${TD_WINDOWS})
|
||||
# ================================================================================================
|
||||
# Build test
|
||||
# ================================================================================================
|
||||
|
|
|
@ -164,9 +164,6 @@ If you are using Maven to manage your project, simply add the following dependen
|
|||
pip3 install taospy[ws]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
- **Installation Verification**
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
|
@ -199,8 +196,8 @@ import taosws
|
|||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</TabItem>
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Go" value="go">
|
||||
|
||||
Edit `go.mod` to add the `driver-go` dependency.
|
||||
|
|
|
@ -12,7 +12,7 @@ TDengine is configured by default with only one root user, who has the highest p
|
|||
Only the root user can perform the operation of creating users, with the syntax as follows.
|
||||
|
||||
```sql
|
||||
create user user_name pass'password' [sysinfo {1|0}]
|
||||
create user user_name pass'password' [sysinfo {1|0}] [createdb {1|0}]
|
||||
```
|
||||
|
||||
The parameters are explained as follows.
|
||||
|
@ -20,6 +20,7 @@ The parameters are explained as follows.
|
|||
- user_name: Up to 23 B long.
|
||||
- password: Up to 128 B long, valid characters include letters and numbers as well as special characters other than single and double quotes, apostrophes, backslashes, and spaces, and it cannot be empty.
|
||||
- sysinfo: Whether the user can view system information. 1 means they can view it, 0 means they cannot. System information includes server configuration information, various node information such as dnode, query node (qnode), etc., as well as storage-related information, etc. The default is to view system information.
|
||||
- createdb: Whether the user can create databases. 1 means they can create databases, 0 means they cannot. The default value is 0. // Supported starting from TDengine Enterprise version 3.3.2.0
|
||||
|
||||
The following SQL can create a user named test with the password 123456 who can view system information.
|
||||
|
||||
|
@ -51,6 +52,7 @@ alter_user_clause: {
|
|||
pass 'literal'
|
||||
| enable value
|
||||
| sysinfo value
|
||||
| createdb value
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -59,6 +61,7 @@ The parameters are explained as follows.
|
|||
- pass: Modify the user's password.
|
||||
- enable: Whether to enable the user. 1 means to enable this user, 0 means to disable this user.
|
||||
- sysinfo: Whether the user can view system information. 1 means they can view system information, 0 means they cannot.
|
||||
- createdb: Whether the user can create databases. 1 means they can create databases, 0 means they cannot. // Supported starting from TDengine Enterprise version 3.3.2.0
|
||||
|
||||
The following SQL disables the user test.
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ alter_table_option: {
|
|||
### Modify Subtable Tag Value
|
||||
|
||||
```sql
|
||||
ALTER TABLE tb_name SET tag tag_name=new_tag_value;
|
||||
ALTER TABLE tb_name SET TAG tag_name1=new_tag_value1,tag_name2=new_tag_value2...;
|
||||
```
|
||||
|
||||
### Modify Table Lifespan
|
||||
|
|
|
@ -8,7 +8,7 @@ User and permission management is a feature of TDengine Enterprise Edition. This
|
|||
## Create User
|
||||
|
||||
```sql
|
||||
CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
|
||||
CREATE USER user_name PASS 'password' [SYSINFO {1|0}] [CREATEDB {1|0}];
|
||||
```
|
||||
|
||||
The username can be up to 23 bytes long.
|
||||
|
@ -17,6 +17,8 @@ The password can be up to 31 bytes long. The password can include letters, numbe
|
|||
|
||||
`SYSINFO` indicates whether the user can view system information. `1` means they can view, `0` means they have no permission to view. System information includes service configuration, dnode, vnode, storage, etc. The default value is `1`.
|
||||
|
||||
`CREATEDB` indicates whether the user can create databases. `1` means they can create databases, `0` means they have no permission to create databases. The default value is `0`. // Supported starting from TDengine Enterprise version 3.3.2.0
|
||||
|
||||
In the example below, we create a user with the password `123456` who can view system information.
|
||||
|
||||
```sql
|
||||
|
@ -76,7 +78,7 @@ alter_user_clause: {
|
|||
- PASS: Change the password, followed by the new password
|
||||
- ENABLE: Enable or disable the user, `1` means enable, `0` means disable
|
||||
- SYSINFO: Allow or prohibit viewing system information, `1` means allow, `0` means prohibit
|
||||
- CREATEDB: Allow or prohibit creating databases, `1` means allow, `0` means prohibit
|
||||
- CREATEDB: Allow or prohibit creating databases, `1` means allow, `0` means prohibit. // Supported starting from TDengine Enterprise version 3.3.2.0
|
||||
|
||||
The following example disables the user named `test`:
|
||||
|
||||
|
|
|
@ -28,13 +28,14 @@ In this document, it specifically refers to the internal levels of the second-le
|
|||
|
||||
- Default compression algorithms list and applicable range for each data type
|
||||
|
||||
| Data Type | Available Encoding Algorithms | Default Encoding Algorithm | Available Compression Algorithms|Default Compression Algorithm| Default Compression Level|
|
||||
| :-----------:|:----------:|:-------:|:-------:|:----------:|:----:|
|
||||
| tinyint/untinyint/smallint/usmallint/int/uint | simple8b| simple8b | lz4/zlib/zstd/xz| lz4 | medium|
|
||||
| bigint/ubigint/timestamp | simple8b/delta-i | delta-i |lz4/zlib/zstd/xz | lz4| medium|
|
||||
|float/double | delta-d|delta-d |lz4/zlib/zstd/xz/tsz|lz4| medium|
|
||||
|binary/nchar| disabled| disabled|lz4/zlib/zstd/xz| lz4| medium|
|
||||
|bool| bit-packing| bit-packing| lz4/zlib/zstd/xz| lz4| medium|
|
||||
| Data Type |Available Encoding Algorithms | Default Encoding Algorithm | Available Compression Algorithms | Default Compression Algorithm | Default Compression Level |
|
||||
|:------------------------------------:|:----------------:|:-----------:|:--------------------:|:----:|:------:|
|
||||
| int/uint | simple8b | simple8b | lz4/zlib/zstd/xz | lz4 | medium |
|
||||
| tinyint/untinyint/smallint/usmallint | simple8b | simple8b | lz4/zlib/zstd/xz | zlib | medium |
|
||||
| bigint/ubigint/timestamp | simple8b/delta-i | delta-i | lz4/zlib/zstd/xz | lz4 | medium |
|
||||
| float/double | delta-d | delta-d | lz4/zlib/zstd/xz/tsz | lz4 | medium |
|
||||
| binary/nchar | disabled | disabled | lz4/zlib/zstd/xz | zstd | medium |
|
||||
| bool | bit-packing | bit-packing | lz4/zlib/zstd/xz | zstd | medium |
|
||||
|
||||
## SQL Syntax
|
||||
|
||||
|
|
|
@ -688,6 +688,27 @@ The basic API is used to establish database connections and provide a runtime en
|
|||
- `arg`: [Input] Setting item value.
|
||||
- **Return Value**: `0`: Success, `-1`: Failure.
|
||||
|
||||
- `int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...)`
|
||||
- **description**:Set each connection option on the client side. Currently, it supports character set setting(`TSDB_OPTION_CONNECTION_CHARSET`), time zone setting(`TSDB_OPTION_CONNECTION_TIMEZONE`), user IP setting(`TSDB_OPTION_CONNECTION_USER_IP`), and user APP setting(`TSDB_OPTION_CONNECTION_USER_APP`).
|
||||
- **input**:
|
||||
- `taos`: returned by taos_connect.
|
||||
- `option`: option name.
|
||||
- `arg`: option value.
|
||||
- **return**:
|
||||
- `0`: success.
|
||||
- `others`: fail.
|
||||
- **notice**:
|
||||
- The character set and time zone default to the current settings of the operating system, and Windows does not support connection level time zone settings.
|
||||
- When arg is NULL, it means resetting the option.
|
||||
- This interface is only valid for the current connection and will not affect other connections.
|
||||
- If the same parameter is called multiple times, the latter shall prevail and can be used as a modification method.
|
||||
- The option of TSDB_OPTION_CONNECTION_CLEAR is used to reset all connection options.
|
||||
- After resetting the time zone and character set, using the operating system settings, the user IP and user app will be reset to empty.
|
||||
- The values of the connection options are all string type, and the maximum value of the user app parameter is 23, which will be truncated if exceeded; Error reported when other parameters are illegal.
|
||||
- If time zone value can not be used to find a time zone file or can not be interpreted as a direct specification, UTC is used, which is the same as the operating system time zone rules. Please refer to the tzset function description for details. You can view the current time zone of the connection by sql:select timezone().
|
||||
- Time zones and character sets only work on the client side and do not affect related behaviors on the server side.
|
||||
- The time zone file uses the operating system time zone file and can be updated by oneself. If there is an error when setting the time zone, please check if the time zone file or path (mac:/var/db/timezone/zoneinfo, Linux:/var/share/zoneinfo) is correct.
|
||||
|
||||
- `char *taos_get_client_info()`
|
||||
- **Interface Description**: Gets client version information.
|
||||
- **Return Value**: Returns client version information.
|
||||
|
|
|
@ -505,6 +505,7 @@ This document details the server error codes that may be encountered when using
|
|||
| 0x80003103 | Invalid tsma state | The vgroup of the stream computing result is inconsistent with the vgroup that created the TSMA index | Check error logs, contact development for handling |
|
||||
| 0x80003104 | Invalid tsma pointer | Processing the results issued by stream computing, the message body is a null pointer. | Check error logs, contact development for handling |
|
||||
| 0x80003105 | Invalid tsma parameters | Processing the results issued by stream computing, the result count is 0. | Check error logs, contact development for handling |
|
||||
| 0x80003113 | Tsma optimization cannot be applied with INTERVAL AUTO offset. | Tsma optimization cannot be enabled with INTERVAL AUTO OFFSET under the current query conditions. | Use SKIP_TSMA Hint or specify a manual INTERVAL OFFSET. |
|
||||
| 0x80003150 | Invalid rsma env | Rsma execution environment is abnormal. | Check error logs, contact development for handling |
|
||||
| 0x80003151 | Invalid rsma state | Rsma execution state is abnormal. | Check error logs, contact development for handling |
|
||||
| 0x80003152 | Rsma qtaskinfo creation error | Creating stream computing environment failed. | Check error logs, contact development for handling |
|
||||
|
|
|
@ -37,7 +37,7 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速
|
|||
|
||||
关键不同点在于:
|
||||
|
||||
1. 使用 原生连接,需要保证客户端的驱动程序 taosc 和服务端的 TDengine 版本配套。
|
||||
1. 使用 原生连接,需要保证客户端的驱动程序 taosc 和服务端的 TDengine 版本保持一致。
|
||||
2. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但是无法体验数据订阅和二进制数据类型等功能。另外与 原生连接 和 WebSocket 连接相比,REST连接的性能最低。REST 接口是无状态的。在使用 REST 连接时,需要在 SQL 中指定表、超级表的数据库名称。
|
||||
3. 使用 WebSocket 连接,用户也无需安装客户端驱动程序 taosc。
|
||||
4. 连接云服务实例,必须使用 REST 连接 或 WebSocket 连接。
|
||||
|
|
|
@ -12,13 +12,14 @@ TDengine 默认仅配置了一个 root 用户,该用户拥有最高权限。TD
|
|||
|
||||
创建用户的操作只能由 root 用户进行,语法如下。
|
||||
```sql
|
||||
create user user_name pass'password' [sysinfo {1|0}]
|
||||
create user user_name pass'password' [sysinfo {1|0}] [createdb {1|0}]
|
||||
```
|
||||
|
||||
相关参数说明如下。
|
||||
- user_name:最长为 23 B。
|
||||
- password:最长为 128 B,合法字符包括字母和数字以及单双引号、撇号、反斜杠和空格以外的特殊字符,且不可以为空。
|
||||
- sysinfo :用户是否可以查看系统信息。1 表示可以查看,0 表示不可以查看。系统信息包括服务端配置信息、服务端各种节点信息,如 dnode、查询节点(qnode)等,以及与存储相关的信息等。默认为可以查看系统信息。
|
||||
- createdb:用户是否可以创建数据库。1 表示可以创建,0 表示不可以创建。缺省值为 0。// 从 TDengine 企业版 3.3.2.0 开始支持
|
||||
|
||||
如下 SQL 可以创建密码为 123456 且可以查看系统信息的用户 test。
|
||||
|
||||
|
@ -47,6 +48,7 @@ alter_user_clause: {
|
|||
pass 'literal'
|
||||
| enable value
|
||||
| sysinfo value
|
||||
| createdb value
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -54,6 +56,7 @@ alter_user_clause: {
|
|||
- pass:修改用户密码。
|
||||
- enable:是否启用用户。1 表示启用此用户,0 表示禁用此用户。
|
||||
- sysinfo :用户是否可查看系统信息。1 表示可以查看系统信息,0 表示不可以查看系统信息
|
||||
- createdb:用户是否可创建数据库。1 表示可以创建数据库,0 表示不可以创建数据库。// 从 TDengine 企业版 3.3.2.0 开始支持
|
||||
|
||||
如下 SQL 禁用 test 用户。
|
||||
```sql
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 212 KiB |
Binary file not shown.
After Width: | Height: | Size: 222 KiB |
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
|
@ -145,6 +145,44 @@ TDinsight 仪表盘旨在提供 TDengine 相关资源的使用情况和状态,
|
|||
|
||||
还有上述分类的细分维度折线图。
|
||||
|
||||
### 预配置告警规则自动导入
|
||||
|
||||
涛思总结用户使用经验,整理出 14 个常用的告警规则(alert rule),能够对集群关键指标进行监测并及时上报指标异常、超限等告警信息。
|
||||
从 TDengine-server 3.3.4.3 版本(tdengine-datasource 3.6.3)开始,TDengine Datasource 支持预配置告警规则自动导入功能,用户可将 14 个告警规则一键导入 Grafana(11 及以上版本),直接使用。
|
||||
预配置告警规则导入方法如下图所示,在 tdengine-datasource setting 界面,打开 “Load Tengine Alert” 开关,点击 “Save & test” 按钮后,插件会自动加载上述告警规则, 规则会放入以数据源名称 + “-alert” 的 grafana 告警目录中。如不需要,关闭 “Load TDengine Alert” 开关,点击 “Clear TDengine Alert” 旁边的按钮则会清除此数据源已导入的所有告警规则。
|
||||
|
||||

|
||||
|
||||
导入后,点击 Grafana 左侧 “Alert rules” ,可查看当前所有告警规则。
|
||||
用户只需配置联络点(Contact points),即可获取告警通知。联络点配置方法见[告警配置](https://docs.taosdata.com/third-party/visual/grafana/#%E5%91%8A%E8%AD%A6%E9%85%8D%E7%BD%AE)。
|
||||
|
||||

|
||||
|
||||
14 个告警规则具体配置如下:
|
||||
|
||||
| 规则名称| 规则阈值| 无监控数据时的行为 | 数据扫描间隔 |持续时间 | 执行SQL |
|
||||
| ------ | --------- | ---------------- | ----------- |------- |----------------------|
|
||||
|dnode 节点的CPU负载|均值 > 80%|触发告警|5分钟|5分钟 |`select now(), dnode_id, last(cpu_system) as cup_use from log.taosd_dnodes_info where _ts >= (now- 5m) and _ts < now partition by dnode_id having first(_ts) > 0 `|
|
||||
|dnode 节点的的内存 |均值 > 60%|触发告警|5分钟|5分钟|`select now(), dnode_id, last(mem_engine) / last(mem_total) * 100 as taosd from log.taosd_dnodes_info where _ts >= (now- 5m) and _ts <now partition by dnode_id`|
|
||||
|dnode 节点的磁盘容量占用 | > 80%|触发告警|5分钟|5分钟|`select now(), dnode_id, data_dir_level, data_dir_name, last(used) / last(total) * 100 as used from log.taosd_dnodes_data_dirs where _ts >= (now - 5m) and _ts < now partition by dnode_id, data_dir_level, data_dir_name`|
|
||||
|集群授权到期 |< 60天|触发告警|1天|0秒|`select now(), cluster_id, last(grants_expire_time) / 86400 as expire_time from log.taosd_cluster_info where _ts >= (now - 24h) and _ts < now partition by cluster_id having first(_ts) > 0 `|
|
||||
|测点数达到授权测点数|>= 90%|触发告警|1天|0秒|`select now(), cluster_id, CASE WHEN max(grants_timeseries_total) > 0.0 THEN max(grants_timeseries_used) /max(grants_timeseries_total) * 100.0 ELSE 0.0 END AS result from log.taosd_cluster_info where _ts >= (now - 30s) and _ts < now partition by cluster_id having timetruncate(first(_ts), 1m) > 0`|
|
||||
|查询并发请求数 | > 100|不触发报警|1分钟|0秒|`select now() as ts, count(*) as slow_count from performance_schema.perf_queries`|
|
||||
|慢查询执行最长时间 (无时间窗口) |> 300秒|不触发报警|1分钟|0秒|`select now() as ts, count(*) as slow_count from performance_schema.perf_queries where exec_usec>300000000`|
|
||||
|dnode下线 |total != alive|触发告警|30秒|0秒|`select now(), cluster_id, last(dnodes_total) - last(dnodes_alive) as dnode_offline from log.taosd_cluster_info where _ts >= (now -30s) and _ts < now partition by cluster_id having first(_ts) > 0`|
|
||||
|vnode下线 |total != alive|触发告警|30秒|0秒|`select now(), cluster_id, last(vnodes_total) - last(vnodes_alive) as vnode_offline from log.taosd_cluster_info where _ts >= (now - 30s) and _ts < now partition by cluster_id having first(_ts) > 0 `|
|
||||
|数据删除请求数 |> 0|不触发报警|30秒|0秒|``select now(), count(`count`) as `delete_count` from log.taos_sql_req where sql_type = 'delete' and _ts >= (now -30s) and _ts < now``|
|
||||
|Adapter RESTful 请求失败 |> 5|不触发报警|30秒|0秒|``select now(), sum(`fail`) as `Failed` from log.adapter_requests where req_type=0 and ts >= (now -30s) and ts < now``|
|
||||
|Adapter WebSocket 请求失败 |> 5|不触发报警|30秒|0秒|``select now(), sum(`fail`) as `Failed` from log.adapter_requests where req_type=1 and ts >= (now -30s) and ts < now``|
|
||||
|dnode 数据上报缺少 |< 3|触发告警|180秒|0秒|`select now(), cluster_id, count(*) as dnode_report from log.taosd_cluster_info where _ts >= (now -180s) and _ts < now partition by cluster_id having timetruncate(first(_ts), 1h) > 0`|
|
||||
|dnode 重启 |max(update_time) > last(update_time)|触发告警|90秒|0秒|`select now(), dnode_id, max(uptime) - last(uptime) as dnode_restart from log.taosd_dnodes_info where _ts >= (now - 90s) and _ts < now partition by dnode_id`|
|
||||
|
||||
用户可参考上述告警规则,根据自己业务需求进行修改与完善。
|
||||
Grafana7.5 及以下版本,Dashboards 与 Alert rules 功能合在一起,而之后的新版本两个功能是分开的。为兼容 Grafana7.5 及以下版本,TDinsight 面板中增加了 Alert Used Only 面板,仅 Grafana7.5 及以下版本需要使用。
|
||||
|
||||

|
||||
|
||||
|
||||
## 升级
|
||||
下面三种方式都可以进行升级:
|
||||
- 用图形界面,若有新版本,可以在 ”TDengine Datasource“ 插件页面点击 update 升级。
|
||||
|
@ -155,10 +193,11 @@ TDinsight 仪表盘旨在提供 TDengine 相关资源的使用情况和状态,
|
|||
针对不同的安装方式,卸载时:
|
||||
- 用图形界面,在 ”TDengine Datasource“ 插件页面点击 ”Uninstall“ 卸载。
|
||||
- 通过 `TDinsight.sh` 脚本安装的 TDinsight,可以使用命令行 `TDinsight.sh -R` 清理相关资源。
|
||||
- 手动安装的 TDinsight,要完全卸载,需要清理以下内容:
|
||||
- 手动安装的 TDinsight,要完全卸载,需要按照顺序清理以下内容:
|
||||
1. Grafana 中的 TDinsight Dashboard。
|
||||
2. Grafana 中的 Data Source 数据源。
|
||||
3. 从插件安装目录删除 `tdengine-datasource` 插件。
|
||||
2. Grafana 中的 Alert rules 告警规则。
|
||||
3. Grafana 中的 Data Source 数据源。
|
||||
4. 从插件安装目录删除 `tdengine-datasource` 插件。
|
||||
|
||||
## 附录
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ alter_table_option: {
|
|||
### 修改子表标签值
|
||||
|
||||
```
|
||||
ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
|
||||
ALTER TABLE tb_name SET TAG tag_name1=new_tag_value1,tag_name2=new_tag_value2...;
|
||||
```
|
||||
|
||||
### 修改表生命周期
|
||||
|
|
|
@ -9,7 +9,7 @@ description: 本节讲述基本的用户管理功能
|
|||
## 创建用户
|
||||
|
||||
```sql
|
||||
CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
|
||||
CREATE USER user_name PASS 'password' [SYSINFO {1|0}] [CREATEDB {1|0}];
|
||||
```
|
||||
|
||||
用户名最长不超过 23 个字节。
|
||||
|
@ -18,6 +18,8 @@ CREATE USER user_name PASS 'password' [SYSINFO {1|0}];
|
|||
|
||||
`SYSINFO` 表示该用户是否能够查看系统信息。`1` 表示可以查看,`0` 表示无权查看。系统信息包括服务配置、dnode、vnode、存储等信息。缺省值为 `1`。
|
||||
|
||||
`CREATEDB` 表示该用户是否能够创建数据库。`1` 表示可以创建,`0` 表示无权创建。缺省值为 `0`。// 从 TDengine 企业版 3.3.2.0 开始支持
|
||||
|
||||
在下面的示例中,我们创建一个密码为 `123456` 且可以查看系统信息的用户。
|
||||
|
||||
```sql
|
||||
|
@ -77,7 +79,7 @@ alter_user_clause: {
|
|||
- PASS: 修改密码,后跟新密码
|
||||
- ENABLE: 启用或禁用该用户,`1` 表示启用,`0` 表示禁用
|
||||
- SYSINFO: 允许或禁止查看系统信息,`1` 表示允许,`0` 表示禁止
|
||||
- CREATEDB: 允许或禁止创建数据库,`1` 表示允许,`0` 表示禁止
|
||||
- CREATEDB: 允许或禁止创建数据库,`1` 表示允许,`0` 表示禁止。// 从 TDengine 企业版 3.3.2.0 开始支持
|
||||
|
||||
下面的示例禁用了名为 `test` 的用户:
|
||||
|
||||
|
|
|
@ -29,14 +29,15 @@ description: 可配置压缩算法
|
|||
|
||||
- 各个数据类型的默认压缩算法列表和适用范围
|
||||
|
||||
| 数据类型 | 可选编码算法 | 编码算法默认值 | 可选压缩算法|压缩算法默认值| 压缩等级默认值|
|
||||
| :-----------:|:----------:|:-------:|:-------:|:----------:|:----:|
|
||||
| int/uint | simple8b| simple8b | lz4/zlib/zstd/xz| lz4 | medium|
|
||||
| tinyint/untinyint/smallint/usmallint | simple8b| simple8b | lz4/zlib/zstd/xz| zlib | medium|
|
||||
| bigint/ubigint/timestamp | simple8b/delta-i | delta-i |lz4/zlib/zstd/xz | lz4| medium|
|
||||
|float/double | delta-d|delta-d |lz4/zlib/zstd/xz/tsz|lz4| medium|
|
||||
|binary/nchar| disabled| disabled|lz4/zlib/zstd/xz| zstd| medium|
|
||||
|bool| bit-packing| bit-packing| lz4/zlib/zstd/xz| zstd| medium|
|
||||
| 数据类型 | 可选编码算法 | 编码算法默认值 | 可选压缩算法 | 压缩算法默认值 |压缩等级默认值|
|
||||
|:------------------------------------:|:----------------:|:-----------:|:--------------------:|:----:|:------:|
|
||||
| int/uint | simple8b | simple8b | lz4/zlib/zstd/xz | lz4 | medium |
|
||||
| tinyint/untinyint/smallint/usmallint | simple8b | simple8b | lz4/zlib/zstd/xz | zlib | medium |
|
||||
| bigint/ubigint/timestamp | simple8b/delta-i | delta-i | lz4/zlib/zstd/xz | lz4 | medium |
|
||||
| float/double | delta-d | delta-d | lz4/zlib/zstd/xz/tsz | lz4 | medium |
|
||||
| binary/nchar | disabled | disabled | lz4/zlib/zstd/xz | zstd | medium |
|
||||
| bool | bit-packing | bit-packing | lz4/zlib/zstd/xz | zstd | medium |
|
||||
|
||||
|
||||
## SQL 语法
|
||||
|
||||
|
|
|
@ -686,6 +686,25 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一
|
|||
- `arg`:[入参] 设置项值。
|
||||
- **返回值**:`0`:成功,`-1`:失败。
|
||||
|
||||
- `int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...)`
|
||||
- **接口说明**:设置客户端每个连接选项,目前支持字符集设置(`TSDB_OPTION_CONNECTION_CHARSET`)、时区设置(`TSDB_OPTION_CONNECTION_TIMEZONE`)、用户 IP 设置(`TSDB_OPTION_CONNECTION_USER_IP`)、用户 APP 设置(`TSDB_OPTION_CONNECTION_USER_APP`)。
|
||||
- **参数说明**:
|
||||
- `taos`: [入参] taos_connect 返回的连接句柄。
|
||||
- `option`:[入参] 设置项类型。
|
||||
- `arg`:[入参] 设置项值。
|
||||
- **返回值**:`0`:成功,`非0`:失败。
|
||||
- **说明**:
|
||||
- 字符集、时区默认为操作系统当前设置,windows 不支持连接级别的时区设置。
|
||||
- arg 为 NULL 时表示重置该选项。
|
||||
- 该接口只对当前连接有效,不会影响其他连接。
|
||||
- 同样参数多次调用该接口,以后面的为准,可以作为修改的方法。
|
||||
- TSDB_OPTION_CONNECTION_CLEAR 选项用于重置所有连接选项。
|
||||
- 时区和字符集重置后,使用系统的设置,user ip 和 user app 重置后为空。
|
||||
- 连接选项的值都是 string 类型,user app 参数值最大为 23,超过该值会被截断;其他参数非法时报错。
|
||||
- 时区配置找不到时区文件或者不能按照规范解释时,默认为 UTC,和操作系统时区规则相同,详见 tzset 函数说明。可通过 select timezone() 查看当前连接的时区。
|
||||
- 时区和字符集只在 client 侧起作用,对于在服务端的相关行为不起作用。
|
||||
- 时区文件使用操作系统时区文件,可以自行更新操作系统时区文件。如果设置时区报错,请检查是否有时区文件或路径(mac:/var/db/timezone/zoneinfo, linux:/usr/share/zoneinfo)是否正确。
|
||||
|
||||
- `char *taos_get_client_info()`
|
||||
- **接口说明**:获取客户端版本信息。
|
||||
- **返回值**:返回客户端版本信息。
|
||||
|
|
|
@ -524,6 +524,7 @@ description: TDengine 服务端的错误码列表和详细说明
|
|||
| 0x80003103 | Invalid tsma state | 流计算下发结果的 vgroup 与创建 TSMA index 的 vgroup 不一致 | 检查错误日志,联系开发处理 |
|
||||
| 0x80003104 | Invalid tsma pointer | 在处理写入流计算下发的结果,消息体为空指针。 | 检查错误日志,联系开发处理 |
|
||||
| 0x80003105 | Invalid tsma parameters | 在处理写入流计算下发的结果,结果数量为0。 | 检查错误日志,联系开发处理 |
|
||||
| 0x80003113 | Tsma optimization cannot be applied with INTERVAL AUTO offset. | 当前查询条件下使用 INTERVAL AUTO OFFSET 无法启用 tsma 优化。 | 使用 SKIP_TSMA Hint 或者手动指定 INTERVAL OFFSET。 |
|
||||
| 0x80003150 | Invalid rsma env | Rsma 执行环境异常。 | 检查错误日志,联系开发处理 |
|
||||
| 0x80003151 | Invalid rsma state | Rsma 执行状态异常。 | 检查错误日志,联系开发处理 |
|
||||
| 0x80003152 | Rsma qtaskinfo creation error | 创建流计算环境异常。 | 检查错误日志,联系开发处理 |
|
||||
|
|
|
@ -64,6 +64,15 @@ typedef enum {
|
|||
TSDB_MAX_OPTIONS
|
||||
} TSDB_OPTION;
|
||||
|
||||
typedef enum {
|
||||
TSDB_OPTION_CONNECTION_CLEAR = -1, // means clear all option in this connection
|
||||
TSDB_OPTION_CONNECTION_CHARSET, // charset, Same as the scope supported by the system
|
||||
TSDB_OPTION_CONNECTION_TIMEZONE, // timezone, Same as the scope supported by the system
|
||||
TSDB_OPTION_CONNECTION_USER_IP, // user ip
|
||||
TSDB_OPTION_CONNECTION_USER_APP, // user app, max lengthe is 23, truncated if longer than 23
|
||||
TSDB_MAX_OPTIONS_CONNECTION
|
||||
} TSDB_OPTION_CONNECTION;
|
||||
|
||||
typedef enum {
|
||||
TSDB_SML_UNKNOWN_PROTOCOL = 0,
|
||||
TSDB_SML_LINE_PROTOCOL = 1,
|
||||
|
@ -174,11 +183,12 @@ typedef struct TAOS_STMT_OPTIONS {
|
|||
|
||||
DLL_EXPORT void taos_cleanup(void);
|
||||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||
DLL_EXPORT int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...);
|
||||
DLL_EXPORT setConfRet taos_set_config(const char *config);
|
||||
DLL_EXPORT int taos_init(void);
|
||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
||||
DLL_EXPORT void taos_close(TAOS *taos);
|
||||
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
||||
DLL_EXPORT void taos_close(TAOS *taos);
|
||||
|
||||
DLL_EXPORT const char *taos_data_type(int type);
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag);
|
|||
int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag);
|
||||
int32_t tTagToValArray(const STag *pTag, SArray **ppArray);
|
||||
void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove
|
||||
int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf);
|
||||
int32_t parseJsontoTagData(const char *json, SArray *pTagVals, STag **ppTag, void *pMsgBuf, void *charsetCxt);
|
||||
|
||||
// SColData ================================
|
||||
typedef struct {
|
||||
|
|
|
@ -1242,7 +1242,7 @@ typedef struct {
|
|||
} STsBufInfo;
|
||||
|
||||
typedef struct {
|
||||
int32_t tz; // query client timezone
|
||||
void* timezone;
|
||||
char intervalUnit;
|
||||
char slidingUnit;
|
||||
char offsetUnit;
|
||||
|
@ -3476,6 +3476,8 @@ typedef struct {
|
|||
SAppHbReq app;
|
||||
SQueryHbReqBasic* query;
|
||||
SHashObj* info; // hash<Skv.key, Skv>
|
||||
char userApp[TSDB_APP_NAME_LEN];
|
||||
uint32_t userIp;
|
||||
} SClientHbReq;
|
||||
|
||||
typedef struct {
|
||||
|
@ -3897,7 +3899,7 @@ typedef struct {
|
|||
int8_t igExists;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
int8_t timezone;
|
||||
int8_t timezone; // int8_t is not enough, timezone is unit of second
|
||||
int32_t dstVgId; // for stream
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
|
|
|
@ -61,22 +61,9 @@ static FORCE_INLINE int64_t taosGetTimestamp(int32_t precision) {
|
|||
* precision == TSDB_TIME_PRECISION_MILLI, it returns timestamp in millisecond.
|
||||
* precision == TSDB_TIME_PRECISION_NANO, it returns timestamp in nanosecond.
|
||||
*/
|
||||
static FORCE_INLINE int64_t taosGetTimestampToday(int32_t precision) {
|
||||
int64_t factor = (precision == TSDB_TIME_PRECISION_MILLI) ? 1000
|
||||
: (precision == TSDB_TIME_PRECISION_MICRO) ? 1000000
|
||||
: 1000000000;
|
||||
time_t t;
|
||||
(void) taosTime(&t);
|
||||
struct tm tm;
|
||||
(void) taosLocalTime(&t, &tm, NULL, 0);
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
int64_t taosGetTimestampToday(int32_t precision, timezone_t tz);
|
||||
|
||||
return (int64_t)taosMktime(&tm) * factor;
|
||||
}
|
||||
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision, timezone_t tz);
|
||||
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval);
|
||||
int64_t taosTimeGetIntervalEnd(int64_t ts, const SInterval* pInterval);
|
||||
|
@ -86,13 +73,12 @@ void calcIntervalAutoOffset(SInterval* interval);
|
|||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision, bool negativeAllow);
|
||||
|
||||
int32_t taosParseTime(const char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t dayligth);
|
||||
void deltaToUtcInitOnce();
|
||||
int32_t taosParseTime(const char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, timezone_t tz);
|
||||
char getPrecisionUnit(int32_t precision);
|
||||
|
||||
int64_t convertTimePrecision(int64_t ts, int32_t fromPrecision, int32_t toPrecision);
|
||||
int32_t convertTimeFromPrecisionToUnit(int64_t time, int32_t fromPrecision, char toUnit, int64_t* pRes);
|
||||
int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec, int64_t* timeVal);
|
||||
int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec, int64_t* timeVal, timezone_t tz, void* charsetCxt);
|
||||
int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision);
|
||||
|
||||
int32_t taosFormatUtcTime(char* buf, int32_t bufLen, int64_t ts, int32_t precision);
|
||||
|
@ -102,8 +88,8 @@ struct STm {
|
|||
int64_t fsec; // in NANOSECOND
|
||||
};
|
||||
|
||||
int32_t taosTs2Tm(int64_t ts, int32_t precision, struct STm* tm);
|
||||
int32_t taosTm2Ts(struct STm* tm, int64_t* ts, int32_t precision);
|
||||
int32_t taosTs2Tm(int64_t ts, int32_t precision, struct STm* tm, timezone_t tz);
|
||||
int32_t taosTm2Ts(struct STm* tm, int64_t* ts, int32_t precision, timezone_t tz);
|
||||
|
||||
/// @brief convert a timestamp to a formatted string
|
||||
/// @param format the timestamp format, must null terminated
|
||||
|
@ -112,7 +98,7 @@ int32_t taosTm2Ts(struct STm* tm, int64_t* ts, int32_t precision);
|
|||
/// formats array; If not NULL, [formats] will be used instead of [format] to skip parse formats again.
|
||||
/// @param out output buffer, should be initialized by memset
|
||||
/// @notes remember to free the generated formats
|
||||
int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t precision, char* out, int32_t outLen);
|
||||
int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t precision, char* out, int32_t outLen, timezone_t tz);
|
||||
/// @brief convert a formatted timestamp string to a timestamp
|
||||
/// @param format must null terminated
|
||||
/// @param [in, out] formats, see taosTs2Char
|
||||
|
@ -120,7 +106,7 @@ int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t pr
|
|||
/// @retval 0 for success, otherwise error occured
|
||||
/// @notes remember to free the generated formats even when error occured
|
||||
int32_t taosChar2Ts(const char* format, SArray** formats, const char* tsStr, int64_t* ts, int32_t precision, char* errMsg,
|
||||
int32_t errMsgLen);
|
||||
int32_t errMsgLen, timezone_t tz);
|
||||
|
||||
int32_t TEST_ts2char(const char* format, int64_t ts, int32_t precision, char* out, int32_t outLen);
|
||||
int32_t TEST_char2ts(const char* format, int64_t* ts, int32_t precision, const char* tsStr);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
typedef struct SExplainCtx SExplainCtx;
|
||||
|
||||
int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode *pStmt, SRetrieveTableRsp **pRsp, int8_t biMode);
|
||||
int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode *pStmt, SRetrieveTableRsp **pRsp, int8_t biMode, void* charsetCxt);
|
||||
|
||||
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp);
|
||||
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs);
|
||||
|
|
|
@ -292,8 +292,16 @@ struct SScalarParam {
|
|||
void *param; // other parameter, such as meta handle from vnode, to extract table name/tag value
|
||||
int32_t numOfRows;
|
||||
int32_t numOfQualified; // number of qualified elements in the final results
|
||||
timezone_t tz;
|
||||
void *charsetCxt;
|
||||
};
|
||||
|
||||
static inline void setTzCharset(SScalarParam* param, timezone_t tz, void* charsetCxt){
|
||||
if (param == NULL) return;
|
||||
param->tz = tz;
|
||||
param->charsetCxt = charsetCxt;
|
||||
}
|
||||
|
||||
#define cleanupResultRowEntry(p) p->initialized = false
|
||||
#define isRowEntryCompleted(p) (p->complete)
|
||||
#define isRowEntryInitialized(p) (p->initialized)
|
||||
|
|
|
@ -129,8 +129,10 @@ typedef struct SValueNode {
|
|||
double d;
|
||||
char* p;
|
||||
} datum;
|
||||
int64_t typeData;
|
||||
int8_t unit;
|
||||
int64_t typeData;
|
||||
int8_t unit;
|
||||
timezone_t tz;
|
||||
void *charsetCxt;
|
||||
} SValueNode;
|
||||
|
||||
typedef struct SLeftValueNode {
|
||||
|
@ -159,6 +161,8 @@ typedef struct SOperatorNode {
|
|||
EOperatorType opType;
|
||||
SNode* pLeft;
|
||||
SNode* pRight;
|
||||
timezone_t tz;
|
||||
void* charsetCxt;
|
||||
} SOperatorNode;
|
||||
|
||||
typedef struct SLogicConditionNode {
|
||||
|
@ -190,7 +194,9 @@ typedef struct SFunctionNode {
|
|||
bool hasOriginalFunc;
|
||||
int32_t originalFuncId;
|
||||
ETrimType trimType;
|
||||
bool dual; // whether select stmt without from stmt, true for without.
|
||||
bool dual; // whether select stmt without from stmt, true for without.
|
||||
timezone_t tz;
|
||||
void *charsetCxt;
|
||||
} SFunctionNode;
|
||||
|
||||
typedef struct STableNode {
|
||||
|
@ -332,6 +338,7 @@ typedef struct SIntervalWindowNode {
|
|||
SNode* pSliding; // SValueNode
|
||||
SNode* pFill;
|
||||
STimeWindow timeRange;
|
||||
void* timezone;
|
||||
} SIntervalWindowNode;
|
||||
|
||||
typedef struct SEventWindowNode {
|
||||
|
@ -401,6 +408,8 @@ typedef struct SCaseWhenNode {
|
|||
SNode* pCase;
|
||||
SNode* pElse;
|
||||
SNodeList* pWhenThenList;
|
||||
timezone_t tz;
|
||||
void* charsetCxt;
|
||||
} SCaseWhenNode;
|
||||
|
||||
typedef struct SWindowOffsetNode {
|
||||
|
|
|
@ -101,6 +101,8 @@ typedef struct SParseContext {
|
|||
int8_t biMode;
|
||||
SArray* pSubMetaList;
|
||||
setQueryFn setQueryFp;
|
||||
timezone_t timezone;
|
||||
void *charsetCxt;
|
||||
} SParseContext;
|
||||
|
||||
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery);
|
||||
|
@ -139,28 +141,28 @@ void qDestroyStmtDataBlock(STableDataCxt* pBlock);
|
|||
STableMeta* qGetTableMetaInDataBlock(STableDataCxt* pDataBlock);
|
||||
int32_t qCloneCurrentTbData(STableDataCxt* pDataBlock, SSubmitTbData** pData);
|
||||
|
||||
int32_t qStmtBindParams(SQuery* pQuery, TAOS_MULTI_BIND* pParams, int32_t colIdx);
|
||||
int32_t qStmtBindParams(SQuery* pQuery, TAOS_MULTI_BIND* pParams, int32_t colIdx, void *charsetCxt);
|
||||
int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery);
|
||||
int32_t qBindStmtStbColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
STSchema** pTSchema, SBindInfo* pBindInfos);
|
||||
int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
STSchema** pTSchema, SBindInfo* pBindInfos, void* charsetCxt);
|
||||
int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, void* charsetCxt);
|
||||
int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
int32_t colIdx, int32_t rowNum);
|
||||
int32_t colIdx, int32_t rowNum, void* charsetCxt);
|
||||
int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool hasCtbName, int32_t* fieldNum,
|
||||
TAOS_FIELD_STB** fields);
|
||||
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
|
||||
TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, void* charsetCxt);
|
||||
|
||||
int32_t qStmtBindParams2(SQuery* pQuery, TAOS_STMT2_BIND* pParams, int32_t colIdx);
|
||||
int32_t qStmtBindParams2(SQuery* pQuery, TAOS_STMT2_BIND* pParams, int32_t colIdx, void* charsetCxt);
|
||||
int32_t qBindStmtStbColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
STSchema** pTSchema, SBindInfo2* pBindInfos);
|
||||
int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
STSchema** pTSchema, SBindInfo2* pBindInfos, void *charsetCxt);
|
||||
int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen, void *charsetCxt);
|
||||
int32_t qBindStmtSingleColValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
int32_t colIdx, int32_t rowNum);
|
||||
int32_t colIdx, int32_t rowNum, void *charsetCxt);
|
||||
int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
|
||||
TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||
TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen, void *charsetCxt);
|
||||
|
||||
void destroyBoundColumnInfo(void* pBoundInfo);
|
||||
int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char* msgBuf,
|
||||
|
@ -170,13 +172,13 @@ void qDestroyBoundColInfo(void* pInfo);
|
|||
|
||||
int32_t smlInitHandle(SQuery** query);
|
||||
int32_t smlBuildRow(STableDataCxt* pTableCxt);
|
||||
int32_t smlBuildCol(STableDataCxt* pTableCxt, SSchema* schema, void* kv, int32_t index);
|
||||
int32_t smlBuildCol(STableDataCxt* pTableCxt, SSchema* schema, void* kv, int32_t index, void* charsetCxt);
|
||||
int32_t smlInitTableDataCtx(SQuery* query, STableMeta* pTableMeta, STableDataCxt** cxt);
|
||||
|
||||
void clearColValArraySml(SArray* pCols);
|
||||
int32_t smlBindData(SQuery* handle, bool dataFormat, SArray* tags, SArray* colsSchema, SArray* cols,
|
||||
STableMeta* pTableMeta, char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl,
|
||||
char* msgBuf, int32_t msgBufLen);
|
||||
char* msgBuf, int32_t msgBufLen, void* charsetCxt);
|
||||
int32_t smlBuildOutput(SQuery* handle, SHashObj* pVgHash);
|
||||
int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreateTbReq* pCreateTb, void* fields,
|
||||
int numFields, bool needChangeLength, char* errstr, int32_t errstrLen, bool raw);
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct SPlanContext {
|
|||
int64_t allocatorId;
|
||||
bool destHasPrimaryKey;
|
||||
bool sourceHasPrimaryKey;
|
||||
void* timezone;
|
||||
} SPlanContext;
|
||||
|
||||
// Create the physical plan for the query, according to the AST.
|
||||
|
|
|
@ -194,6 +194,7 @@ typedef struct SBoundColInfo {
|
|||
int32_t numOfCols;
|
||||
int32_t numOfBound;
|
||||
bool hasBoundCols;
|
||||
bool mixTagsCols;
|
||||
} SBoundColInfo;
|
||||
|
||||
typedef struct STableColsData {
|
||||
|
@ -337,7 +338,7 @@ SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* nam
|
|||
|
||||
void destroyQueryExecRes(SExecResult* pRes);
|
||||
int32_t dataConverToStr(char* str, int64_t capacity, int type, void* buf, int32_t bufSize, int32_t* len);
|
||||
void parseTagDatatoJson(void* p, char** jsonStr);
|
||||
void parseTagDatatoJson(void* p, char** jsonStr, void *charsetCxt);
|
||||
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst);
|
||||
void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType);
|
||||
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
|
||||
|
|
|
@ -105,7 +105,6 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara
|
|||
int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t timeZoneStrLen();
|
||||
int32_t timezoneFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t weekdayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
int32_t dayofweekFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
|
|
@ -48,13 +48,13 @@ void atomic_store_8(int8_t volatile *ptr, int8_t val);
|
|||
void atomic_store_16(int16_t volatile *ptr, int16_t val);
|
||||
void atomic_store_32(int32_t volatile *ptr, int32_t val);
|
||||
void atomic_store_64(int64_t volatile *ptr, int64_t val);
|
||||
double atomic_store_double(double volatile *ptr, double val);
|
||||
void atomic_store_double(double volatile *ptr, double val);
|
||||
void atomic_store_ptr(void *ptr, void *val);
|
||||
int8_t atomic_exchange_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_exchange_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_exchange_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_exchange_64(int64_t volatile *ptr, int64_t val);
|
||||
double atomic_exchange_double(double volatile *ptr, int64_t val);
|
||||
double atomic_exchange_double(double volatile *ptr, double val);
|
||||
void *atomic_exchange_ptr(void *ptr, void *val);
|
||||
int8_t atomic_val_compare_exchange_8(int8_t volatile *ptr, int8_t oldval, int8_t newval);
|
||||
int16_t atomic_val_compare_exchange_16(int16_t volatile *ptr, int16_t oldval, int16_t newval);
|
||||
|
@ -71,7 +71,7 @@ int16_t atomic_fetch_add_16(int16_t volatile *ptr, int16_t val);
|
|||
int32_t atomic_fetch_add_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_fetch_add_64(int64_t volatile *ptr, int64_t val);
|
||||
double atomic_fetch_add_double(double volatile *ptr, double val);
|
||||
void *atomic_fetch_add_ptr(void *ptr, void *val);
|
||||
void *atomic_fetch_add_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_sub_fetch_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_sub_fetch_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_sub_fetch_32(int32_t volatile *ptr, int32_t val);
|
||||
|
@ -82,37 +82,37 @@ int16_t atomic_fetch_sub_16(int16_t volatile *ptr, int16_t val);
|
|||
int32_t atomic_fetch_sub_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_fetch_sub_64(int64_t volatile *ptr, int64_t val);
|
||||
double atomic_fetch_sub_double(double volatile *ptr, double val);
|
||||
void *atomic_fetch_sub_ptr(void *ptr, void *val);
|
||||
void *atomic_fetch_sub_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_and_fetch_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_and_fetch_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_and_fetch_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_and_fetch_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_and_fetch_ptr(void *ptr, void *val);
|
||||
void *atomic_and_fetch_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_fetch_and_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_fetch_and_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_fetch_and_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_fetch_and_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_fetch_and_ptr(void *ptr, void *val);
|
||||
void *atomic_fetch_and_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_or_fetch_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_or_fetch_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_or_fetch_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_or_fetch_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_or_fetch_ptr(void *ptr, void *val);
|
||||
void *atomic_or_fetch_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_fetch_or_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_fetch_or_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_fetch_or_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_fetch_or_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_fetch_or_ptr(void *ptr, void *val);
|
||||
void *atomic_fetch_or_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_xor_fetch_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_xor_fetch_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_xor_fetch_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_xor_fetch_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_xor_fetch_ptr(void *ptr, void *val);
|
||||
void *atomic_xor_fetch_ptr(void *ptr, int64_t val);
|
||||
int8_t atomic_fetch_xor_8(int8_t volatile *ptr, int8_t val);
|
||||
int16_t atomic_fetch_xor_16(int16_t volatile *ptr, int16_t val);
|
||||
int32_t atomic_fetch_xor_32(int32_t volatile *ptr, int32_t val);
|
||||
int64_t atomic_fetch_xor_64(int64_t volatile *ptr, int64_t val);
|
||||
void *atomic_fetch_xor_ptr(void *ptr, void *val);
|
||||
void *atomic_fetch_xor_ptr(void *ptr, int64_t val);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define tmemory_barrier(order) MemoryBarrier()
|
||||
|
|
|
@ -25,10 +25,9 @@ extern "C" {
|
|||
|
||||
extern char tsOsName[];
|
||||
extern char tsTimezoneStr[];
|
||||
extern enum TdTimezone tsTimezone;
|
||||
extern char tsCharset[];
|
||||
extern void *tsCharsetCxt;
|
||||
extern char tsLocale[];
|
||||
extern int8_t tsDaylight;
|
||||
extern bool tsEnableCoreFile;
|
||||
extern int64_t tsPageSizeKB;
|
||||
extern int64_t tsOpenMax;
|
||||
|
@ -67,8 +66,7 @@ bool osDataSpaceSufficient();
|
|||
bool osTempSpaceSufficient();
|
||||
|
||||
int32_t osSetTimezone(const char *timezone);
|
||||
void osSetSystemLocale(const char *inLocale, const char *inCharSet);
|
||||
void osSetProcPath(int32_t argc, char **argv);
|
||||
void osSetProcPath(int32_t argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
|||
|
||||
char *taosCharsetReplace(char *charsetstr);
|
||||
void taosGetSystemLocale(char *outLocale, char *outCharset);
|
||||
int32_t taosSetSystemLocale(const char *inLocale, const char *inCharSet);
|
||||
int32_t taosSetSystemLocale(const char *inLocale);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#define epoll_create EPOLL_CREATE_FUNC_TAOS_FORBID
|
||||
#define epoll_ctl EPOLL_CTL_FUNC_TAOS_FORBID
|
||||
#define epoll_wait EPOLL_WAIT_FUNC_TAOS_FORBID
|
||||
#define inet_addr INET_ADDR_FUNC_TAOS_FORBID
|
||||
#define inet_ntoa INET_NTOA_FUNC_TAOS_FORBID
|
||||
#define inet_addr INET_ADDR_FUNC_TAOS_FORBID
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS)
|
||||
|
@ -55,10 +55,10 @@
|
|||
#define __BIG_ENDIAN BIG_ENDIAN
|
||||
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#define __PDP_ENDIAN PDP_ENDIAN
|
||||
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(_TD_DARWIN_64)
|
||||
#include <osEok.h>
|
||||
|
@ -162,10 +162,10 @@ int32_t taosGetSocketName(TdSocketPtr pSocket, struct sockaddr *destAddr, int *a
|
|||
int32_t taosBlockSIGPIPE();
|
||||
int32_t taosGetIpv4FromFqdn(const char *fqdn, uint32_t *ip);
|
||||
int32_t taosGetFqdn(char *);
|
||||
void tinet_ntoa(char *ipstr, uint32_t ip);
|
||||
uint32_t ip2uint(const char *const ip_addr);
|
||||
void taosInetNtoa(char *ipstr, uint32_t ip);
|
||||
uint32_t taosInetAddr(const char *ipstr);
|
||||
int32_t taosIgnSIGPIPE();
|
||||
const char *taosInetNtoa(struct in_addr ipInt, char *dstStr, int32_t len);
|
||||
const char *taosInetNtop(struct in_addr ipInt, char *dstStr, int32_t len);
|
||||
|
||||
uint64_t taosHton64(uint64_t val);
|
||||
uint64_t taosNtoh64(uint64_t val);
|
||||
|
|
|
@ -22,12 +22,24 @@ extern "C" {
|
|||
|
||||
typedef wchar_t TdWchar;
|
||||
typedef int32_t TdUcs4;
|
||||
#if !defined(DISALLOW_NCHAR_WITHOUT_ICONV) && defined(DARWIN)
|
||||
#if !defined(DISALLOW_NCHAR_WITHOUT_ICONV)// && defined(DARWIN)
|
||||
#include "iconv.h"
|
||||
#else
|
||||
typedef void *iconv_t;
|
||||
#endif
|
||||
typedef enum { M2C = 0, C2M } ConvType;
|
||||
typedef enum { M2C = 0, C2M, CM_NUM } ConvType;
|
||||
|
||||
typedef struct {
|
||||
iconv_t conv;
|
||||
int8_t inUse;
|
||||
} SConv;
|
||||
|
||||
typedef struct {
|
||||
SConv *gConv[CM_NUM];
|
||||
int32_t convUsed[CM_NUM];
|
||||
int32_t gConvMaxNum[CM_NUM];
|
||||
char charset[TD_CHARSET_LEN];
|
||||
} SConvInfo;
|
||||
|
||||
// If the error is in a third-party library, place this header file under the third-party library header file.
|
||||
// When you want to use this feature, you should find or add the same function in the following section.
|
||||
|
@ -78,13 +90,11 @@ int32_t taosStr2int16(const char *str, int16_t *val);
|
|||
int32_t taosStr2int32(const char *str, int32_t *val);
|
||||
int32_t taosStr2int8(const char *str, int8_t *val);
|
||||
|
||||
int32_t taosConvInit(void);
|
||||
void taosConvDestroy();
|
||||
iconv_t taosAcquireConv(int32_t *idx, ConvType type);
|
||||
void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type);
|
||||
int32_t taosUcs4ToMbs(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs);
|
||||
iconv_t taosAcquireConv(int32_t *idx, ConvType type, void* charsetCxt);
|
||||
void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type, void* charsetCxt);
|
||||
int32_t taosUcs4ToMbs(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, void* charsetCxt);
|
||||
int32_t taosUcs4ToMbsEx(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, iconv_t conv);
|
||||
bool taosMbsToUcs4(const char *mbs, size_t mbs_len, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len);
|
||||
bool taosMbsToUcs4(const char *mbs, size_t mbs_len, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len, void* charsetCxt);
|
||||
int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes);
|
||||
int32_t tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4);
|
||||
bool taosValidateEncodec(const char *encodec);
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
// When you want to use this feature, you should find or add the same function in the following section.
|
||||
#ifndef ALLOW_FORBID_FUNC
|
||||
#define strptime STRPTIME_FUNC_TAOS_FORBID
|
||||
#define strftime STRFTIME_FUNC_TAOS_FORBID
|
||||
#define gettimeofday GETTIMEOFDAY_FUNC_TAOS_FORBID
|
||||
#define localtime LOCALTIME_FUNC_TAOS_FORBID
|
||||
#define localtime_s LOCALTIMES_FUNC_TAOS_FORBID
|
||||
|
@ -42,6 +43,7 @@ extern "C" {
|
|||
#define MILLISECOND_PER_SECOND ((int64_t)1000LL)
|
||||
#endif
|
||||
|
||||
#include "osTimezone.h"
|
||||
#define MILLISECOND_PER_MINUTE (MILLISECOND_PER_SECOND * 60)
|
||||
#define MILLISECOND_PER_HOUR (MILLISECOND_PER_MINUTE * 60)
|
||||
#define MILLISECOND_PER_DAY (MILLISECOND_PER_HOUR * 24)
|
||||
|
@ -91,13 +93,17 @@ static FORCE_INLINE int64_t taosGetMonoTimestampMs() {
|
|||
}
|
||||
|
||||
char *taosStrpTime(const char *buf, const char *fmt, struct tm *tm);
|
||||
struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf, int32_t bufSize);
|
||||
struct tm *taosLocalTimeNolock(struct tm *result, const time_t *timep, int dst);
|
||||
size_t taosStrfTime(char *s, size_t maxsize, char const *format, struct tm const *t);
|
||||
struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf, int32_t bufSize, timezone_t tz);
|
||||
struct tm *taosGmTimeR(const time_t *timep, struct tm *result);
|
||||
time_t taosTimeGm(struct tm *tmp);
|
||||
int32_t taosTime(time_t *t);
|
||||
time_t taosMktime(struct tm *timep);
|
||||
time_t taosMktime(struct tm *timep, timezone_t tz);
|
||||
int64_t user_mktime64(const uint32_t year, const uint32_t mon, const uint32_t day, const uint32_t hour,
|
||||
const uint32_t min, const uint32_t sec, int64_t time_zone);
|
||||
|
||||
//struct tm *taosLocalTimeRz(timezone_t state, const time_t *timep, struct tm *result);
|
||||
//time_t taosMktimeRz(timezone_t state, struct tm *timep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,43 +20,29 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// If the error is in a third-party library, place this header file under the third-party library header file.
|
||||
// When you want to use this feature, you should find or add the same function in the following section.
|
||||
#ifndef ALLOW_FORBID_FUNC
|
||||
#define tzset TZSET_FUNC_TAOS_FORBID
|
||||
#define TdEastZone8 8*60*60
|
||||
#define TZ_UNKNOWN "n/a"
|
||||
|
||||
extern void* pTimezoneNameMap;
|
||||
|
||||
#ifdef WINDOWS
|
||||
typedef void *timezone_t;
|
||||
#else
|
||||
typedef struct state *timezone_t;
|
||||
|
||||
struct tm* localtime_rz(timezone_t , time_t const *, struct tm *);
|
||||
time_t mktime_z(timezone_t, struct tm *);
|
||||
timezone_t tzalloc(char const *);
|
||||
void tzfree(timezone_t);
|
||||
void getTimezoneStr(char *tz);
|
||||
|
||||
#endif
|
||||
|
||||
enum TdTimezone {
|
||||
TdWestZone12 = -12,
|
||||
TdWestZone11,
|
||||
TdWestZone10,
|
||||
TdWestZone9,
|
||||
TdWestZone8,
|
||||
TdWestZone7,
|
||||
TdWestZone6,
|
||||
TdWestZone5,
|
||||
TdWestZone4,
|
||||
TdWestZone3,
|
||||
TdWestZone2,
|
||||
TdWestZone1,
|
||||
TdZeroZone,
|
||||
TdEastZone1,
|
||||
TdEastZone2,
|
||||
TdEastZone3,
|
||||
TdEastZone4,
|
||||
TdEastZone5,
|
||||
TdEastZone6,
|
||||
TdEastZone7,
|
||||
TdEastZone8,
|
||||
TdEastZone9,
|
||||
TdEastZone10,
|
||||
TdEastZone11,
|
||||
TdEastZone12
|
||||
};
|
||||
|
||||
int32_t taosGetSystemTimezone(char *outTimezone, enum TdTimezone *tsTimezone);
|
||||
int32_t taosSetSystemTimezone(const char *inTimezone, char *outTimezone, int8_t *outDaylight, enum TdTimezone *tsTimezone);
|
||||
|
||||
int32_t taosGetLocalTimezoneOffset();
|
||||
int32_t taosGetSystemTimezone(char *outTimezone);
|
||||
int32_t taosSetGlobalTimezone(const char *tz);
|
||||
int32_t taosFormatTimezoneStr(time_t t, const char* tzStr, timezone_t sp, char *outTimezoneStr);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -211,6 +211,7 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_TSC_COMPRESS_LEVEL_ERROR TAOS_DEF_ERROR_CODE(0, 0x0234)
|
||||
#define TSDB_CODE_TSC_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0x0235)
|
||||
#define TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR TAOS_DEF_ERROR_CODE(0, 0x0236)
|
||||
#define TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS TAOS_DEF_ERROR_CODE(0, 0x0237)
|
||||
#define TSDB_CODE_TSC_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x02FF)
|
||||
|
||||
// mnode-common
|
||||
|
@ -481,7 +482,7 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_DNODE_INVALID_MONITOR_PARAS TAOS_DEF_ERROR_CODE(0, 0x0429)
|
||||
#define TSDB_CODE_MNODE_STOPPED TAOS_DEF_ERROR_CODE(0, 0x042A)
|
||||
|
||||
// anode
|
||||
// anode
|
||||
#define TSDB_CODE_MND_ANODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0430)
|
||||
#define TSDB_CODE_MND_ANODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0431)
|
||||
#define TSDB_CODE_MND_ANODE_TOO_LONG_URL TAOS_DEF_ERROR_CODE(0, 0x0432)
|
||||
|
|
|
@ -34,7 +34,8 @@ typedef enum {
|
|||
CFG_STYPE_APOLLO_URL,
|
||||
CFG_STYPE_ARG_LIST,
|
||||
CFG_STYPE_TAOS_OPTIONS,
|
||||
CFG_STYPE_ALTER_CMD,
|
||||
CFG_STYPE_ALTER_CLIENT_CMD,
|
||||
CFG_STYPE_ALTER_SERVER_CMD,
|
||||
} ECfgSrcType;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TCONV_H
|
||||
#define TDENGINE_TCONV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#include "osString.h"
|
||||
//
|
||||
//bool taosValidateEncodec(const char *encodec);
|
||||
//int32_t taosUcs4len(TdUcs4 *ucs4);
|
||||
void* taosConvInit(const char* charset);
|
||||
void taosConvDestroy();
|
||||
//iconv_t taosAcquireConv(int32_t *idx, ConvType type, void* charsetCxt);
|
||||
//void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type, void* charsetCxt);
|
||||
//int32_t taosUcs4ToMbs(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, void* charsetCxt);
|
||||
//int32_t taosUcs4ToMbsEx(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, iconv_t conv);
|
||||
//bool taosMbsToUcs4(const char *mbs, size_t mbs_len, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len, void* charsetCxt);
|
||||
//int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes);
|
||||
//int32_t tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_TCONV_H
|
|
@ -426,21 +426,26 @@ static FORCE_INLINE int32_t tDecodeBinary(SDecoder* pCoder, uint8_t** val, uint3
|
|||
|
||||
static FORCE_INLINE int32_t tDecodeCStrAndLen(SDecoder* pCoder, char** val, uint32_t* len) {
|
||||
TAOS_CHECK_RETURN(tDecodeBinary(pCoder, (uint8_t**)val, len));
|
||||
(*len) -= 1;
|
||||
if (*len > 0) { // notice!!! *len maybe 0
|
||||
(*len) -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeCStr(SDecoder* pCoder, char** val) {
|
||||
uint32_t len;
|
||||
uint32_t len = 0;
|
||||
return tDecodeCStrAndLen(pCoder, val, &len);
|
||||
}
|
||||
|
||||
static int32_t tDecodeCStrTo(SDecoder* pCoder, char* val) {
|
||||
char* pStr;
|
||||
uint32_t len;
|
||||
char* pStr = NULL;
|
||||
uint32_t len = 0;
|
||||
TAOS_CHECK_RETURN(tDecodeCStrAndLen(pCoder, &pStr, &len));
|
||||
|
||||
TAOS_MEMCPY(val, pStr, len + 1);
|
||||
if (len < pCoder->size) {
|
||||
TAOS_MEMCPY(val, pStr, len + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -492,12 +497,14 @@ static FORCE_INLINE int32_t tDecodeBinaryAlloc32(SDecoder* pCoder, void** val, u
|
|||
|
||||
static FORCE_INLINE int32_t tDecodeCStrAndLenAlloc(SDecoder* pCoder, char** val, uint64_t* len) {
|
||||
TAOS_CHECK_RETURN(tDecodeBinaryAlloc(pCoder, (void**)val, len));
|
||||
(*len) -= 1;
|
||||
if (*len > 0){
|
||||
(*len) -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tDecodeCStrAlloc(SDecoder* pCoder, char** val) {
|
||||
uint64_t len;
|
||||
uint64_t len = 0;
|
||||
return tDecodeCStrAndLenAlloc(pCoder, val, &len);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,6 @@ int32_t taosHexStrToByteArray(char hexstr[], char bytes[]);
|
|||
int32_t tintToHex(uint64_t val, char hex[]);
|
||||
int32_t titoa(uint64_t val, size_t radix, char str[]);
|
||||
|
||||
char *taosIpStr(uint32_t ipInt);
|
||||
uint32_t ip2uint(const char *const ip_addr);
|
||||
void taosIp2String(uint32_t ip, char *str);
|
||||
void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
||||
|
||||
void *tmemmem(const char *haystack, int hlen, const char *needle, int nlen);
|
||||
|
||||
int32_t parseCfgReal(const char *str, float *out);
|
||||
|
|
|
@ -1,59 +1,80 @@
|
|||
import subprocess
|
||||
import re
|
||||
|
||||
# 执行 git fetch 命令并捕获输出
|
||||
def git_fetch():
|
||||
result = subprocess.run(['git', 'fetch'], capture_output=True, text=True)
|
||||
return result
|
||||
|
||||
# 解析分支名称
|
||||
def git_prune():
|
||||
# git remote prune origin
|
||||
print("git remote prune origin")
|
||||
result = subprocess.run(['git', 'remote', 'prune', 'origin'], capture_output=True, text=True)
|
||||
return result
|
||||
|
||||
def parse_branch_name_type1(error_output):
|
||||
# 使用正则表达式匹配 'is at' 前的分支名称
|
||||
# error: cannot lock ref 'refs/remotes/origin/fix/3.0/TD-32817': is at 7af5 but expected eaba
|
||||
# match the branch name before ‘is at’ with a regular expression
|
||||
match = re.search(r"error: cannot lock ref '(refs/remotes/origin/[^']+)': is at", error_output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
# 解析第二种错误中的分支名称
|
||||
def parse_branch_name_type2(error_output):
|
||||
# 使用正则表达式匹配 'exists' 前的第一个引号内的分支名称
|
||||
# match the branch name before ‘exists; cannot create’ with a regular expression
|
||||
match = re.search(r"'(refs/remotes/origin/[^']+)' exists;", error_output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
# 执行 git update-ref -d 命令
|
||||
# parse branch name from error output of git remote prune origin
|
||||
def parse_branch_name_type3(error_output):
|
||||
# match the branch name before the first single quote before 'Unable to' with a regular expression
|
||||
# git error: could not delete references: cannot lock ref 'refs/remotes/origin/test/3.0/TS-4893': Unable to create 'D:/workspace/main/TDinternal/community/.git/refs/remotes/origin/test/3.0/TS-4893.lock': File exists
|
||||
match = re.search(r"references: cannot lock ref '(refs/remotes/origin/[^']+)': Unable to", error_output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
|
||||
# execute git update-ref -d <branch_name> to delete the ref
|
||||
def git_update_ref(branch_name):
|
||||
if branch_name:
|
||||
subprocess.run(['git', 'update-ref', '-d', f'{branch_name}'], check=True)
|
||||
|
||||
# 解析错误类型并执行相应的修复操作
|
||||
# parse error type and execute corresponding repair operation
|
||||
def handle_error(error_output):
|
||||
# 错误类型1:本地引用的提交ID与远程不一致
|
||||
if "is at" in error_output and "but expected" in error_output:
|
||||
branch_name = parse_branch_name_type1(error_output)
|
||||
if branch_name:
|
||||
print(f"Detected error type 1, attempting to delete ref for branch: {branch_name}")
|
||||
git_update_ref(branch_name)
|
||||
else:
|
||||
print("Error parsing branch name for type 1.")
|
||||
# 错误类型2:尝试创建新的远程引用时,本地已经存在同名的引用
|
||||
elif "exists; cannot create" in error_output:
|
||||
branch_name = parse_branch_name_type2(error_output)
|
||||
if branch_name:
|
||||
print(f"Detected error type 2, attempting to delete ref for branch: {branch_name}")
|
||||
git_update_ref(branch_name)
|
||||
else:
|
||||
print("Error parsing branch name for type 2.")
|
||||
error_types = [
|
||||
("is at", "but expected", parse_branch_name_type1, "type 1"),
|
||||
("exists; cannot create", None, parse_branch_name_type2, "type 2"),
|
||||
("Unable to create", "File exists", parse_branch_name_type3, "type 3")
|
||||
]
|
||||
|
||||
for error_type in error_types:
|
||||
if error_type[0] in error_output and (error_type[1] is None or error_type[1] in error_output):
|
||||
branch_name = error_type[2](error_output)
|
||||
if branch_name:
|
||||
print(f"Detected error {error_type[3]}, attempting to delete ref for branch: {branch_name}")
|
||||
git_update_ref(branch_name)
|
||||
else:
|
||||
print(f"Error parsing branch name for {error_type[3]}.")
|
||||
break
|
||||
|
||||
# 主函数
|
||||
def main():
|
||||
fetch_result = git_fetch()
|
||||
if fetch_result.returncode != 0: # 如果 git fetch 命令失败
|
||||
if fetch_result.returncode != 0:
|
||||
error_output = fetch_result.stderr
|
||||
handle_error(error_output)
|
||||
else:
|
||||
print("Git fetch successful.")
|
||||
|
||||
prune_result = git_prune()
|
||||
print(prune_result.returncode)
|
||||
if prune_result.returncode != 0:
|
||||
error_output = prune_result.stderr
|
||||
print(error_output)
|
||||
handle_error(error_output)
|
||||
else:
|
||||
print("Git prune successful.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -52,6 +52,7 @@ else
|
|||
installDir="/usr/local/taos"
|
||||
fi
|
||||
fi
|
||||
|
||||
install_main_dir=${installDir}
|
||||
bin_dir="${installDir}/bin"
|
||||
cfg_dir="${installDir}/cfg"
|
||||
|
|
|
@ -154,6 +154,13 @@ typedef struct {
|
|||
__taos_notify_fn_t fp;
|
||||
} SWhiteListInfo;
|
||||
|
||||
typedef struct {
|
||||
timezone_t timezone;
|
||||
void *charsetCxt;
|
||||
char userApp[TSDB_APP_NAME_LEN];
|
||||
uint32_t userIp;
|
||||
}SOptionInfo;
|
||||
|
||||
typedef struct STscObj {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
|
@ -176,6 +183,7 @@ typedef struct STscObj {
|
|||
SPassInfo passInfo;
|
||||
SWhiteListInfo whiteListInfo;
|
||||
STscNotifyInfo userDroppedInfo;
|
||||
SOptionInfo optionInfo;
|
||||
} STscObj;
|
||||
|
||||
typedef struct STscDbg {
|
||||
|
@ -212,6 +220,7 @@ typedef struct SReqResultInfo {
|
|||
int32_t precision;
|
||||
int32_t payloadLen;
|
||||
char* convertJson;
|
||||
void* charsetCxt;
|
||||
} SReqResultInfo;
|
||||
|
||||
typedef struct SRequestSendRecvBody {
|
||||
|
@ -339,6 +348,7 @@ extern int32_t clientReqRefPool;
|
|||
extern int32_t clientConnRefPool;
|
||||
extern int32_t timestampDeltaLimit;
|
||||
extern int64_t lastClusterId;
|
||||
extern SHashObj* pTimezoneMap;
|
||||
|
||||
__async_send_cb_fn_t getMsgRspHandle(int32_t msgType);
|
||||
|
||||
|
@ -438,6 +448,9 @@ void stopAllQueries(SRequestObj* pRequest);
|
|||
void doRequestCallback(SRequestObj* pRequest, int32_t code);
|
||||
void freeQueryParam(SSyncQueryParam* param);
|
||||
|
||||
int32_t tzInit();
|
||||
void tzCleanup();
|
||||
|
||||
#ifdef TD_ENTERPRISE
|
||||
int32_t clientParseSqlImpl(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effeciveUser,
|
||||
SParseSqlRes* pRes);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "tsched.h"
|
||||
#include "ttime.h"
|
||||
#include "tversion.h"
|
||||
#include "tconv.h"
|
||||
|
||||
#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL)
|
||||
#include "cus_name.h"
|
||||
|
@ -74,6 +75,7 @@ int64_t lastClusterId = 0;
|
|||
int32_t clientReqRefPool = -1;
|
||||
int32_t clientConnRefPool = -1;
|
||||
int32_t clientStop = -1;
|
||||
SHashObj* pTimezoneMap = NULL;
|
||||
|
||||
int32_t timestampDeltaLimit = 900; // s
|
||||
|
||||
|
@ -559,6 +561,7 @@ int32_t createRequest(uint64_t connId, int32_t type, int64_t reqid, SRequestObj
|
|||
(*pRequest)->metric.start = taosGetTimestampUs();
|
||||
|
||||
(*pRequest)->body.resInfo.convertUcs4 = true; // convert ucs4 by default
|
||||
(*pRequest)->body.resInfo.charsetCxt = pTscObj->optionInfo.charsetCxt;
|
||||
(*pRequest)->type = type;
|
||||
(*pRequest)->allocatorRefId = -1;
|
||||
|
||||
|
@ -956,25 +959,31 @@ void taos_init_imp(void) {
|
|||
return;
|
||||
}
|
||||
taosHashSetFreeFp(appInfo.pInstMap, destroyAppInst);
|
||||
deltaToUtcInitOnce();
|
||||
|
||||
const char *logName = CUS_PROMPT "slog";
|
||||
ENV_ERR_RET(taosInitLogOutput(&logName), "failed to init log output");
|
||||
if (taosCreateLog(logName, 10, configDir, NULL, NULL, NULL, NULL, 1) != 0) {
|
||||
(void)printf(" WARING: Create %s failed:%s. configDir=%s\n", logName, strerror(errno), configDir);
|
||||
tscInitRes = -1;
|
||||
tscInitRes = terrno;
|
||||
return;
|
||||
}
|
||||
|
||||
ENV_ERR_RET(taosInitCfg(configDir, NULL, NULL, NULL, NULL, 1), "failed to init cfg");
|
||||
|
||||
initQueryModuleMsgHandle();
|
||||
ENV_ERR_RET(taosConvInit(), "failed to init conv");
|
||||
if ((tsCharsetCxt = taosConvInit(tsCharset)) == NULL){
|
||||
tscInitRes = terrno;
|
||||
tscError("failed to init conv");
|
||||
return;
|
||||
}
|
||||
#ifndef WINDOWS
|
||||
ENV_ERR_RET(tzInit(), "failed to init timezone");
|
||||
#endif
|
||||
ENV_ERR_RET(monitorInit(), "failed to init monitor");
|
||||
ENV_ERR_RET(rpcInit(), "failed to init rpc");
|
||||
|
||||
if (InitRegexCache() != 0) {
|
||||
tscInitRes = -1;
|
||||
tscInitRes = terrno;
|
||||
(void)printf("failed to init regex cache\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1194,6 +1194,9 @@ int32_t hbGatherAllInfo(SAppHbMgr *pAppHbMgr, SClientHbBatchReq **pBatchReq) {
|
|||
continue;
|
||||
}
|
||||
|
||||
tstrncpy(pOneReq->userApp, pTscObj->optionInfo.userApp, sizeof(pOneReq->userApp));
|
||||
pOneReq->userIp = pTscObj->optionInfo.userIp;
|
||||
|
||||
pOneReq = taosArrayPush((*pBatchReq)->reqs, pOneReq);
|
||||
if (NULL == pOneReq) {
|
||||
releaseTscObj(connKey->tscRid);
|
||||
|
|
|
@ -300,7 +300,9 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
.svrVer = pTscObj->sVer,
|
||||
.nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
|
||||
.isStmtBind = pRequest->isStmtBind,
|
||||
.setQueryFp = setQueryRequest};
|
||||
.setQueryFp = setQueryRequest,
|
||||
.timezone = pTscObj->optionInfo.timezone,
|
||||
.charsetCxt = pTscObj->optionInfo.charsetCxt,};
|
||||
|
||||
cxt.mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
|
||||
int32_t code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &cxt.pCatalog);
|
||||
|
@ -331,7 +333,7 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
||||
SRetrieveTableRsp* pRsp = NULL;
|
||||
int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode, pRequest->pTscObj->optionInfo.charsetCxt);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4);
|
||||
}
|
||||
|
@ -369,7 +371,7 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
}
|
||||
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp,
|
||||
atomic_load_8(&pRequest->pTscObj->biMode));
|
||||
atomic_load_8(&pRequest->pTscObj->biMode), pRequest->pTscObj->optionInfo.charsetCxt);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4);
|
||||
}
|
||||
|
@ -507,6 +509,7 @@ int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArra
|
|||
.pMsg = pRequest->msgBuf,
|
||||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
|
||||
.pUser = pRequest->pTscObj->user,
|
||||
.timezone = pRequest->pTscObj->optionInfo.timezone,
|
||||
.sysInfo = pRequest->pTscObj->sysInfo};
|
||||
|
||||
return qCreateQueryPlan(&cxt, pPlan, pNodeList);
|
||||
|
@ -1361,6 +1364,7 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat
|
|||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
|
||||
.pUser = pRequest->pTscObj->user,
|
||||
.sysInfo = pRequest->pTscObj->sysInfo,
|
||||
.timezone = pRequest->pTscObj->optionInfo.timezone,
|
||||
.allocatorId = pRequest->allocatorRefId};
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = qCreateQueryPlan(&cxt, &pDag, pMnodeList);
|
||||
|
@ -2086,7 +2090,7 @@ static int32_t doPrepareResPtr(SReqResultInfo* pResInfo) {
|
|||
|
||||
static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
|
||||
int32_t idx = -1;
|
||||
iconv_t conv = taosAcquireConv(&idx, C2M);
|
||||
iconv_t conv = taosAcquireConv(&idx, C2M, pResultInfo->charsetCxt);
|
||||
if (conv == (iconv_t)-1) return TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
|
||||
for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
|
||||
|
@ -2096,7 +2100,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
|
|||
if (type == TSDB_DATA_TYPE_NCHAR && colLength[i] > 0) {
|
||||
char* p = taosMemoryRealloc(pResultInfo->convertBuf[i], colLength[i]);
|
||||
if (p == NULL) {
|
||||
taosReleaseConv(idx, conv, C2M);
|
||||
taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
@ -2113,7 +2117,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
|
|||
"doConvertUCS4 error, invalid data. len:%d, bytes:%d, (p + len):%p, (pResultInfo->convertBuf[i] + "
|
||||
"colLength[i]):%p",
|
||||
len, bytes, (p + len), (pResultInfo->convertBuf[i] + colLength[i]));
|
||||
taosReleaseConv(idx, conv, C2M);
|
||||
taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
|
||||
return TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2127,7 +2131,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
|
|||
pResultInfo->row[i] = pResultInfo->pCol[i].pData;
|
||||
}
|
||||
}
|
||||
taosReleaseConv(idx, conv, C2M);
|
||||
taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2292,7 +2296,7 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo) {
|
|||
varDataSetLen(dst, strlen(varDataVal(dst)));
|
||||
} else if (tTagIsJson(data)) {
|
||||
char* jsonString = NULL;
|
||||
parseTagDatatoJson(data, &jsonString);
|
||||
parseTagDatatoJson(data, &jsonString, pResultInfo->charsetCxt);
|
||||
if (jsonString == NULL) {
|
||||
tscError("doConvertJson error: parseTagDatatoJson failed");
|
||||
return terrno;
|
||||
|
@ -2302,9 +2306,10 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo) {
|
|||
} else if (jsonInnerType == TSDB_DATA_TYPE_NCHAR) { // value -> "value"
|
||||
*(char*)varDataVal(dst) = '\"';
|
||||
int32_t length = taosUcs4ToMbs((TdUcs4*)varDataVal(jsonInnerData), varDataLen(jsonInnerData),
|
||||
varDataVal(dst) + CHAR_BYTES);
|
||||
varDataVal(dst) + CHAR_BYTES, pResultInfo->charsetCxt);
|
||||
if (length <= 0) {
|
||||
tscError("charset:%s to %s. convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset);
|
||||
tscError("charset:%s to %s. convert failed.", DEFAULT_UNICODE_ENCODEC,
|
||||
pResultInfo->charsetCxt != NULL ? ((SConvInfo *)(pResultInfo->charsetCxt))->charset : tsCharset);
|
||||
length = 0;
|
||||
}
|
||||
varDataSetLen(dst, length + CHAR_BYTES * 2);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
#include "version.h"
|
||||
#include "tconv.h"
|
||||
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
#define TSC_VAR_RELEASED 0
|
||||
|
@ -38,11 +39,13 @@ static int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
|||
static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper);
|
||||
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||
if (arg == NULL) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
static int32_t lock = 0;
|
||||
|
||||
for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
|
||||
if (i % 1000 == 0) {
|
||||
tscInfo("haven't acquire lock after spin %d times.", i);
|
||||
(void)sched_yield();
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +54,167 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
atomic_store_32(&lock, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
static void freeTz(void *p){
|
||||
timezone_t tz = *(timezone_t *)p;
|
||||
tzfree(tz);
|
||||
}
|
||||
|
||||
int32_t tzInit(){
|
||||
pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
|
||||
if (pTimezoneMap == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
taosHashSetFreeFp(pTimezoneMap, freeTz);
|
||||
|
||||
pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK);
|
||||
if (pTimezoneNameMap == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tzCleanup(){
|
||||
taosHashCleanup(pTimezoneMap);
|
||||
taosHashCleanup(pTimezoneNameMap);
|
||||
}
|
||||
|
||||
static timezone_t setConnnectionTz(const char* val){
|
||||
timezone_t tz = NULL;
|
||||
timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
|
||||
if (tmp != NULL && *tmp != NULL){
|
||||
tz = *tmp;
|
||||
goto END;
|
||||
}
|
||||
|
||||
tscDebug("set timezone to %s", val);
|
||||
tz = tzalloc(val);
|
||||
if (tz == NULL) {
|
||||
tscWarn("%s unknown timezone %s change to UTC", __func__, val);
|
||||
tz = tzalloc("UTC");
|
||||
if (tz == NULL) {
|
||||
tscError("%s set timezone UTC error", __func__);
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
int32_t code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t));
|
||||
if (code != 0){
|
||||
tscError("%s put timezone to tz map error:%d", __func__, code);
|
||||
tzfree(tz);
|
||||
tz = NULL;
|
||||
goto END;
|
||||
}
|
||||
|
||||
time_t tx1 = taosGetTimestampSec();
|
||||
char output[TD_TIMEZONE_LEN] = {0};
|
||||
taosFormatTimezoneStr(tx1, val, tz, output);
|
||||
code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
|
||||
if (code != 0){
|
||||
tscError("failed to put timezone %s to map", val);
|
||||
}
|
||||
|
||||
END:
|
||||
return tz;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char* val){
|
||||
if (taos == NULL) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
if (option == TSDB_OPTION_CONNECTION_TIMEZONE){
|
||||
return TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION){
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
int32_t code = taos_init();
|
||||
// initialize global config
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
|
||||
if (NULL == pObj) {
|
||||
tscError("invalid parameter for %s", __func__);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (option == TSDB_OPTION_CONNECTION_CLEAR){
|
||||
val = NULL;
|
||||
}
|
||||
|
||||
if (option == TSDB_OPTION_CONNECTION_CHARSET || option == TSDB_OPTION_CONNECTION_CLEAR) {
|
||||
if (val != NULL) {
|
||||
if (!taosValidateEncodec(val)) {
|
||||
code = terrno;
|
||||
goto END;
|
||||
}
|
||||
void *tmp = taosConvInit(val);
|
||||
if (tmp == NULL) {
|
||||
code = terrno;
|
||||
goto END;
|
||||
}
|
||||
pObj->optionInfo.charsetCxt = tmp;
|
||||
}else{
|
||||
pObj->optionInfo.charsetCxt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (option == TSDB_OPTION_CONNECTION_TIMEZONE || option == TSDB_OPTION_CONNECTION_CLEAR) {
|
||||
#ifndef WINDOWS
|
||||
if (val != NULL){
|
||||
if (val[0] == 0){
|
||||
val = "UTC";
|
||||
}
|
||||
timezone_t tz = setConnnectionTz(val);
|
||||
if (tz == NULL){
|
||||
code = terrno;
|
||||
goto END;
|
||||
}
|
||||
pObj->optionInfo.timezone = tz;
|
||||
} else {
|
||||
pObj->optionInfo.timezone = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (option == TSDB_OPTION_CONNECTION_USER_APP || option == TSDB_OPTION_CONNECTION_CLEAR) {
|
||||
if (val != NULL) {
|
||||
tstrncpy(pObj->optionInfo.userApp, val, sizeof(pObj->optionInfo.userApp));
|
||||
} else {
|
||||
pObj->optionInfo.userApp[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
|
||||
if (val != NULL) {
|
||||
pObj->optionInfo.userIp = taosInetAddr(val);
|
||||
if (pObj->optionInfo.userIp == INADDR_NONE){
|
||||
code = TSDB_CODE_INVALID_PARA;
|
||||
goto END;
|
||||
}
|
||||
} else {
|
||||
pObj->optionInfo.userIp = INADDR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
return code;
|
||||
}
|
||||
|
||||
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...){
|
||||
return setConnectionOption(taos, option, (const char *)arg);
|
||||
}
|
||||
|
||||
// this function may be called by user or system, or by both simultaneously.
|
||||
void taos_cleanup(void) {
|
||||
tscDebug("start to cleanup client environment");
|
||||
|
@ -73,6 +237,9 @@ void taos_cleanup(void) {
|
|||
tscWarn("failed to cleanup task queue");
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
tzCleanup();
|
||||
#endif
|
||||
tmqMgmtClose();
|
||||
|
||||
int32_t id = clientReqRefPool;
|
||||
|
@ -1244,7 +1411,9 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SS
|
|||
.allocatorId = pRequest->allocatorRefId,
|
||||
.parseSqlFp = clientParseSql,
|
||||
.parseSqlParam = pWrapper,
|
||||
.setQueryFp = setQueryRequest};
|
||||
.setQueryFp = setQueryRequest,
|
||||
.timezone = pTscObj->optionInfo.timezone,
|
||||
.charsetCxt = pTscObj->optionInfo.charsetCxt};
|
||||
int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
|
||||
(*pCxt)->biMode = biMode;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -52,6 +52,22 @@
|
|||
|
||||
#define TMQ_META_VERSION "1.0"
|
||||
|
||||
static bool tmqAddJsonObjectItem(cJSON *object, const char *string, cJSON *item){
|
||||
bool ret = cJSON_AddItemToObject(object, string, item);
|
||||
if (!ret){
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static bool tmqAddJsonArrayItem(cJSON *array, cJSON *item){
|
||||
bool ret = cJSON_AddItemToArray(array, item);
|
||||
if (!ret){
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int32_t tmqWriteBatchMetaDataImpl(TAOS* taos, void* meta, int32_t metaLen);
|
||||
static tb_uid_t processSuid(tb_uid_t suid, char* db) { return suid + MurmurHash3_32(db, strlen(db)); }
|
||||
static void buildCreateTableJson(SSchemaWrapper* schemaRow, SSchemaWrapper* schemaTag, char* name, int64_t id, int8_t t,
|
||||
|
@ -68,41 +84,43 @@ static void buildCreateTableJson(SSchemaWrapper* schemaRow, SSchemaWrapper* sche
|
|||
cJSON* type = cJSON_CreateString("create");
|
||||
RAW_NULL_CHECK(type);
|
||||
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
cJSON* tableType = cJSON_CreateString(t == TSDB_NORMAL_TABLE ? "normal" : "super");
|
||||
RAW_NULL_CHECK(tableType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableType", tableType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableType", tableType));
|
||||
cJSON* tableName = cJSON_CreateString(name);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableName", tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableName", tableName));
|
||||
|
||||
cJSON* columns = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(columns);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "columns", columns));
|
||||
|
||||
for (int i = 0; i < schemaRow->nCols; i++) {
|
||||
cJSON* column = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(column);
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(columns, column));
|
||||
SSchema* s = schemaRow->pSchema + i;
|
||||
cJSON* cname = cJSON_CreateString(s->name);
|
||||
RAW_NULL_CHECK(cname);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "name", cname));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "name", cname));
|
||||
cJSON* ctype = cJSON_CreateNumber(s->type);
|
||||
RAW_NULL_CHECK(ctype);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "type", ctype));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "type", ctype));
|
||||
if (s->type == TSDB_DATA_TYPE_BINARY || s->type == TSDB_DATA_TYPE_VARBINARY || s->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = s->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "length", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "length", cbytes));
|
||||
} else if (s->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (s->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "length", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "length", cbytes));
|
||||
}
|
||||
cJSON* isPk = cJSON_CreateBool(s->flags & COL_IS_KEY);
|
||||
RAW_NULL_CHECK(isPk);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "isPrimarykey", isPk));
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(columns, column));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "isPrimarykey", isPk));
|
||||
|
||||
if (pColCmprRow == NULL) {
|
||||
continue;
|
||||
|
@ -124,44 +142,44 @@ static void buildCreateTableJson(SSchemaWrapper* schemaRow, SSchemaWrapper* sche
|
|||
|
||||
cJSON* encodeJson = cJSON_CreateString(encode);
|
||||
RAW_NULL_CHECK(encodeJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "encode", encodeJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "encode", encodeJson));
|
||||
|
||||
cJSON* compressJson = cJSON_CreateString(compress);
|
||||
RAW_NULL_CHECK(compressJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "compress", compressJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "compress", compressJson));
|
||||
|
||||
cJSON* levelJson = cJSON_CreateString(level);
|
||||
RAW_NULL_CHECK(levelJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(column, "level", levelJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(column, "level", levelJson));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "columns", columns));
|
||||
|
||||
cJSON* tags = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(tags);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tags", tags));
|
||||
|
||||
for (int i = 0; schemaTag && i < schemaTag->nCols; i++) {
|
||||
cJSON* tag = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(tag);
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(tags, tag));
|
||||
SSchema* s = schemaTag->pSchema + i;
|
||||
cJSON* tname = cJSON_CreateString(s->name);
|
||||
RAW_NULL_CHECK(tname);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "name", tname));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "name", tname));
|
||||
cJSON* ttype = cJSON_CreateNumber(s->type);
|
||||
RAW_NULL_CHECK(ttype);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "type", ttype));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "type", ttype));
|
||||
if (s->type == TSDB_DATA_TYPE_BINARY || s->type == TSDB_DATA_TYPE_VARBINARY || s->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = s->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "length", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "length", cbytes));
|
||||
} else if (s->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (s->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "length", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "length", cbytes));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(tags, tag));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tags", tags));
|
||||
|
||||
end:
|
||||
*pJson = json;
|
||||
|
@ -175,7 +193,7 @@ static int32_t setCompressOption(cJSON* json, uint32_t para) {
|
|||
RAW_NULL_CHECK(encodeStr);
|
||||
cJSON* encodeJson = cJSON_CreateString(encodeStr);
|
||||
RAW_NULL_CHECK(encodeJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "encode", encodeJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "encode", encodeJson));
|
||||
return code;
|
||||
}
|
||||
uint8_t compress = COMPRESS_L2_TYPE_U32(para);
|
||||
|
@ -184,7 +202,7 @@ static int32_t setCompressOption(cJSON* json, uint32_t para) {
|
|||
RAW_NULL_CHECK(compressStr);
|
||||
cJSON* compressJson = cJSON_CreateString(compressStr);
|
||||
RAW_NULL_CHECK(compressJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "compress", compressJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "compress", compressJson));
|
||||
return code;
|
||||
}
|
||||
uint8_t level = COMPRESS_L2_TYPE_LEVEL_U32(para);
|
||||
|
@ -193,7 +211,7 @@ static int32_t setCompressOption(cJSON* json, uint32_t para) {
|
|||
RAW_NULL_CHECK(levelStr);
|
||||
cJSON* levelJson = cJSON_CreateString(levelStr);
|
||||
RAW_NULL_CHECK(levelJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "level", levelJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "level", levelJson));
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -214,19 +232,19 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("alter");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
SName name = {0};
|
||||
RAW_RETURN_CHECK(tNameFromString(&name, req.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE));
|
||||
cJSON* tableType = cJSON_CreateString("super");
|
||||
RAW_NULL_CHECK(tableType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableType", tableType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableType", tableType));
|
||||
cJSON* tableName = cJSON_CreateString(name.tname);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableName", tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableName", tableName));
|
||||
|
||||
cJSON* alterType = cJSON_CreateNumber(req.alterType);
|
||||
RAW_NULL_CHECK(alterType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "alterType", alterType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "alterType", alterType));
|
||||
switch (req.alterType) {
|
||||
case TSDB_ALTER_TABLE_ADD_TAG:
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN: {
|
||||
|
@ -234,22 +252,22 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(field);
|
||||
cJSON* colName = cJSON_CreateString(field->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(field->type);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = field->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (field->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (field->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -258,22 +276,22 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(field);
|
||||
cJSON* colName = cJSON_CreateString(field->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(field->type);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = field->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (field->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (field->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
RAW_RETURN_CHECK(setCompressOption(json, field->compress));
|
||||
break;
|
||||
|
@ -284,7 +302,7 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(field);
|
||||
cJSON* colName = cJSON_CreateString(field->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES:
|
||||
|
@ -293,21 +311,21 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(field);
|
||||
cJSON* colName = cJSON_CreateString(field->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(field->type);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
field->type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = field->bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (field->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (field->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -319,10 +337,10 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(newField);
|
||||
cJSON* colName = cJSON_CreateString(oldField->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colNewName = cJSON_CreateString(newField->name);
|
||||
RAW_NULL_CHECK(colNewName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colNewName", colNewName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colNewName", colNewName));
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS: {
|
||||
|
@ -330,7 +348,7 @@ static void buildAlterSTableJson(void* alterData, int32_t alterDataLen, cJSON**
|
|||
RAW_NULL_CHECK(field);
|
||||
cJSON* colName = cJSON_CreateString(field->name);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
RAW_RETURN_CHECK(setCompressOption(json, field->bytes));
|
||||
break;
|
||||
}
|
||||
|
@ -391,51 +409,47 @@ static void buildChildElement(cJSON* json, SVCreateTbReq* pCreateReq) {
|
|||
int64_t id = pCreateReq->uid;
|
||||
uint8_t tagNum = pCreateReq->ctb.tagNum;
|
||||
int32_t code = 0;
|
||||
cJSON* tags = NULL;
|
||||
SArray* pTagVals = NULL;
|
||||
char* pJson = NULL;
|
||||
|
||||
cJSON* tableName = cJSON_CreateString(name);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableName", tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableName", tableName));
|
||||
cJSON* using = cJSON_CreateString(sname);
|
||||
RAW_NULL_CHECK(using);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "using", using));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "using", using));
|
||||
cJSON* tagNumJson = cJSON_CreateNumber(tagNum);
|
||||
RAW_NULL_CHECK(tagNumJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tagNum", tagNumJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tagNum", tagNumJson));
|
||||
|
||||
tags = cJSON_CreateArray();
|
||||
cJSON* tags = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(tags);
|
||||
SArray* pTagVals = NULL;
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tags", tags));
|
||||
RAW_RETURN_CHECK(tTagToValArray(pTag, &pTagVals));
|
||||
|
||||
if (tTagIsJson(pTag)) {
|
||||
STag* p = (STag*)pTag;
|
||||
if (p->nTag == 0) {
|
||||
uError("p->nTag == 0");
|
||||
goto end;
|
||||
}
|
||||
char* pJson = NULL;
|
||||
parseTagDatatoJson(pTag, &pJson);
|
||||
if (pJson == NULL) {
|
||||
uError("parseTagDatatoJson failed, pJson == NULL");
|
||||
goto end;
|
||||
}
|
||||
parseTagDatatoJson(pTag, &pJson, NULL);
|
||||
RAW_NULL_CHECK(pJson);
|
||||
cJSON* tag = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(tag);
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(tags, tag));
|
||||
STagVal* pTagVal = taosArrayGet(pTagVals, 0);
|
||||
RAW_NULL_CHECK(pTagVal);
|
||||
char* ptname = taosArrayGet(tagName, 0);
|
||||
RAW_NULL_CHECK(ptname);
|
||||
cJSON* tname = cJSON_CreateString(ptname);
|
||||
RAW_NULL_CHECK(tname);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "name", tname));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "name", tname));
|
||||
cJSON* ttype = cJSON_CreateNumber(TSDB_DATA_TYPE_JSON);
|
||||
RAW_NULL_CHECK(ttype);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "type", ttype));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "type", ttype));
|
||||
cJSON* tvalue = cJSON_CreateString(pJson);
|
||||
RAW_NULL_CHECK(tvalue);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "value", tvalue));
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(tags, tag));
|
||||
taosMemoryFree(pJson);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "value", tvalue));
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -444,36 +458,34 @@ static void buildChildElement(cJSON* json, SVCreateTbReq* pCreateReq) {
|
|||
RAW_NULL_CHECK(pTagVal);
|
||||
cJSON* tag = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(tag);
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(tags, tag));
|
||||
char* ptname = taosArrayGet(tagName, i);
|
||||
RAW_NULL_CHECK(ptname);
|
||||
cJSON* tname = cJSON_CreateString(ptname);
|
||||
RAW_NULL_CHECK(tname);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "name", tname));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "name", tname));
|
||||
cJSON* ttype = cJSON_CreateNumber(pTagVal->type);
|
||||
RAW_NULL_CHECK(ttype);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "type", ttype));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "type", ttype));
|
||||
|
||||
cJSON* tvalue = NULL;
|
||||
if (IS_VAR_DATA_TYPE(pTagVal->type)) {
|
||||
char* buf = NULL;
|
||||
int64_t bufSize = 0;
|
||||
if (pTagVal->type == TSDB_DATA_TYPE_VARBINARY) {
|
||||
bufSize = pTagVal->nData * 2 + 2 + 3;
|
||||
} else {
|
||||
bufSize = pTagVal->nData + 3;
|
||||
}
|
||||
buf = taosMemoryCalloc(bufSize, 1);
|
||||
|
||||
char* buf = taosMemoryCalloc(bufSize, 1);
|
||||
RAW_NULL_CHECK(buf);
|
||||
if (!buf) goto end;
|
||||
if (dataConverToStr(buf, bufSize, pTagVal->type, pTagVal->pData, pTagVal->nData, NULL) != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(buf);
|
||||
goto end;
|
||||
}
|
||||
|
||||
tvalue = cJSON_CreateString(buf);
|
||||
RAW_NULL_CHECK(tvalue);
|
||||
taosMemoryFree(buf);
|
||||
RAW_NULL_CHECK(tvalue);
|
||||
} else {
|
||||
double val = 0;
|
||||
GET_TYPED_DATA(val, double, pTagVal->type, &pTagVal->i64);
|
||||
|
@ -481,12 +493,11 @@ static void buildChildElement(cJSON* json, SVCreateTbReq* pCreateReq) {
|
|||
RAW_NULL_CHECK(tvalue);
|
||||
}
|
||||
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(tag, "value", tvalue));
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(tags, tag));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(tag, "value", tvalue));
|
||||
}
|
||||
|
||||
end:
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tags", tags));
|
||||
taosMemoryFree(pJson);
|
||||
taosArrayDestroy(pTagVals);
|
||||
}
|
||||
|
||||
|
@ -497,22 +508,23 @@ static void buildCreateCTableJson(SVCreateTbReq* pCreateReq, int32_t nReqs, cJSO
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("create");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
|
||||
cJSON* tableType = cJSON_CreateString("child");
|
||||
RAW_NULL_CHECK(tableType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableType", tableType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableType", tableType));
|
||||
|
||||
buildChildElement(json, pCreateReq);
|
||||
cJSON* createList = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(createList);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "createList", createList));
|
||||
|
||||
for (int i = 0; nReqs > 1 && i < nReqs; i++) {
|
||||
cJSON* create = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(create);
|
||||
buildChildElement(create, pCreateReq + i);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(createList, create));
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(createList, create));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "createList", createList));
|
||||
|
||||
end:
|
||||
*pJson = json;
|
||||
|
@ -619,62 +631,62 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("alter");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
cJSON* tableType = cJSON_CreateString(vAlterTbReq.action == TSDB_ALTER_TABLE_UPDATE_TAG_VAL ||
|
||||
vAlterTbReq.action == TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL
|
||||
? "child"
|
||||
: "normal");
|
||||
RAW_NULL_CHECK(tableType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableType", tableType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableType", tableType));
|
||||
cJSON* tableName = cJSON_CreateString(vAlterTbReq.tbName);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableName", tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableName", tableName));
|
||||
cJSON* alterType = cJSON_CreateNumber(vAlterTbReq.action);
|
||||
RAW_NULL_CHECK(alterType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "alterType", alterType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "alterType", alterType));
|
||||
|
||||
switch (vAlterTbReq.action) {
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(vAlterTbReq.type);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
|
||||
if (vAlterTbReq.type == TSDB_DATA_TYPE_BINARY || vAlterTbReq.type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
vAlterTbReq.type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = vAlterTbReq.bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (vAlterTbReq.type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (vAlterTbReq.bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(vAlterTbReq.type);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
|
||||
if (vAlterTbReq.type == TSDB_DATA_TYPE_BINARY || vAlterTbReq.type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
vAlterTbReq.type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = vAlterTbReq.bytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (vAlterTbReq.type == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (vAlterTbReq.bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
RAW_RETURN_CHECK(setCompressOption(json, vAlterTbReq.compress));
|
||||
break;
|
||||
|
@ -682,43 +694,43 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
case TSDB_ALTER_TABLE_DROP_COLUMN: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colType = cJSON_CreateNumber(vAlterTbReq.colModType);
|
||||
RAW_NULL_CHECK(colType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colType", colType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colType", colType));
|
||||
if (vAlterTbReq.colModType == TSDB_DATA_TYPE_BINARY || vAlterTbReq.colModType == TSDB_DATA_TYPE_VARBINARY ||
|
||||
vAlterTbReq.colModType == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
int32_t length = vAlterTbReq.colModBytes - VARSTR_HEADER_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
} else if (vAlterTbReq.colModType == TSDB_DATA_TYPE_NCHAR) {
|
||||
int32_t length = (vAlterTbReq.colModBytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
cJSON* cbytes = cJSON_CreateNumber(length);
|
||||
RAW_NULL_CHECK(cbytes);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colLength", cbytes));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colLength", cbytes));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
cJSON* colNewName = cJSON_CreateString(vAlterTbReq.colNewName);
|
||||
RAW_NULL_CHECK(colNewName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colNewName", colNewName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colNewName", colNewName));
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: {
|
||||
cJSON* tagName = cJSON_CreateString(vAlterTbReq.tagName);
|
||||
RAW_NULL_CHECK(tagName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", tagName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", tagName));
|
||||
|
||||
bool isNull = vAlterTbReq.isNull;
|
||||
if (vAlterTbReq.tagType == TSDB_DATA_TYPE_JSON) {
|
||||
|
@ -733,7 +745,7 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
uError("processAlterTable isJson false");
|
||||
goto end;
|
||||
}
|
||||
parseTagDatatoJson(vAlterTbReq.pTagVal, &buf);
|
||||
parseTagDatatoJson(vAlterTbReq.pTagVal, &buf, NULL);
|
||||
if (buf == NULL) {
|
||||
uError("parseTagDatatoJson failed, buf == NULL");
|
||||
goto end;
|
||||
|
@ -757,12 +769,12 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
cJSON* colValue = cJSON_CreateString(buf);
|
||||
taosMemoryFree(buf);
|
||||
RAW_NULL_CHECK(colValue);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colValue", colValue));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colValue", colValue));
|
||||
}
|
||||
|
||||
cJSON* isNullCJson = cJSON_CreateBool(isNull);
|
||||
RAW_NULL_CHECK(isNullCJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colValueNull", isNullCJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colValueNull", isNullCJson));
|
||||
break;
|
||||
}
|
||||
case TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL: {
|
||||
|
@ -774,14 +786,17 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
|
||||
cJSON* tags = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(tags);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tags", tags));
|
||||
|
||||
for (int32_t i = 0; i < nTags; i++) {
|
||||
cJSON* member = cJSON_CreateObject();
|
||||
RAW_NULL_CHECK(member);
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(tags, member));
|
||||
|
||||
SMultiTagUpateVal* pTagVal = taosArrayGet(vAlterTbReq.pMultiTag, i);
|
||||
cJSON* tagName = cJSON_CreateString(pTagVal->tagName);
|
||||
RAW_NULL_CHECK(tagName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(member, "colName", tagName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(member, "colName", tagName));
|
||||
|
||||
if (pTagVal->tagType == TSDB_DATA_TYPE_JSON) {
|
||||
uError("processAlterTable isJson false");
|
||||
|
@ -789,14 +804,13 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
}
|
||||
bool isNull = pTagVal->isNull;
|
||||
if (!isNull) {
|
||||
char* buf = NULL;
|
||||
int64_t bufSize = 0;
|
||||
if (pTagVal->tagType == TSDB_DATA_TYPE_VARBINARY) {
|
||||
bufSize = pTagVal->nTagVal * 2 + 2 + 3;
|
||||
} else {
|
||||
bufSize = pTagVal->nTagVal + 3;
|
||||
}
|
||||
buf = taosMemoryCalloc(bufSize, 1);
|
||||
char* buf = taosMemoryCalloc(bufSize, 1);
|
||||
RAW_NULL_CHECK(buf);
|
||||
if (dataConverToStr(buf, bufSize, pTagVal->tagType, pTagVal->pTagVal, pTagVal->nTagVal, NULL) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
|
@ -806,21 +820,19 @@ static void processAlterTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
cJSON* colValue = cJSON_CreateString(buf);
|
||||
taosMemoryFree(buf);
|
||||
RAW_NULL_CHECK(colValue);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(member, "colValue", colValue));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(member, "colValue", colValue));
|
||||
}
|
||||
cJSON* isNullCJson = cJSON_CreateBool(isNull);
|
||||
RAW_NULL_CHECK(isNullCJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(member, "colValueNull", isNullCJson));
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(tags, member));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(member, "colValueNull", isNullCJson));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tags", tags));
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS: {
|
||||
cJSON* colName = cJSON_CreateString(vAlterTbReq.colName);
|
||||
RAW_NULL_CHECK(colName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "colName", colName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "colName", colName));
|
||||
RAW_RETURN_CHECK(setCompressOption(json, vAlterTbReq.compress));
|
||||
break;
|
||||
}
|
||||
|
@ -858,13 +870,13 @@ static void processDropSTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("drop");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
cJSON* tableType = cJSON_CreateString("super");
|
||||
RAW_NULL_CHECK(tableType);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableType", tableType));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableType", tableType));
|
||||
cJSON* tableName = cJSON_CreateString(req.name);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableName", tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableName", tableName));
|
||||
|
||||
end:
|
||||
uDebug("processDropSTable return");
|
||||
|
@ -897,10 +909,10 @@ static void processDeleteTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("delete");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
cJSON* sqlJson = cJSON_CreateString(sql);
|
||||
RAW_NULL_CHECK(sqlJson);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "sql", sqlJson));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "sql", sqlJson));
|
||||
|
||||
end:
|
||||
uDebug("processDeleteTable return");
|
||||
|
@ -928,16 +940,17 @@ static void processDropTable(SMqMetaRsp* metaRsp, cJSON** pJson) {
|
|||
RAW_NULL_CHECK(json);
|
||||
cJSON* type = cJSON_CreateString("drop");
|
||||
RAW_NULL_CHECK(type);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "type", type));
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "type", type));
|
||||
cJSON* tableNameList = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(tableNameList);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(json, "tableNameList", tableNameList));
|
||||
|
||||
for (int32_t iReq = 0; iReq < req.nReqs; iReq++) {
|
||||
SVDropTbReq* pDropTbReq = req.pReqs + iReq;
|
||||
cJSON* tableName = cJSON_CreateString(pDropTbReq->name);
|
||||
RAW_NULL_CHECK(tableName);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(tableNameList, tableName));
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(tableNameList, tableName));
|
||||
}
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(json, "tableNameList", tableNameList));
|
||||
|
||||
end:
|
||||
uDebug("processDropTable return");
|
||||
|
@ -2183,6 +2196,8 @@ static void processBatchMetaToJson(SMqBatchMetaRsp* pMsgRsp, char** string) {
|
|||
RAW_FALSE_CHECK(cJSON_AddStringToObject(pJson, "tmq_meta_version", TMQ_META_VERSION));
|
||||
cJSON* pMetaArr = cJSON_CreateArray();
|
||||
RAW_NULL_CHECK(pMetaArr);
|
||||
RAW_FALSE_CHECK(tmqAddJsonObjectItem(pJson, "metas", pMetaArr));
|
||||
|
||||
int32_t num = taosArrayGetSize(rsp.batchMetaReq);
|
||||
for (int32_t i = 0; i < num; i++) {
|
||||
int32_t* len = taosArrayGet(rsp.batchMetaLen, i);
|
||||
|
@ -2198,10 +2213,9 @@ static void processBatchMetaToJson(SMqBatchMetaRsp* pMsgRsp, char** string) {
|
|||
cJSON* pItem = NULL;
|
||||
processSimpleMeta(&metaRsp, &pItem);
|
||||
tDeleteMqMetaRsp(&metaRsp);
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToArray(pMetaArr, pItem));
|
||||
RAW_FALSE_CHECK(tmqAddJsonArrayItem(pMetaArr, pItem));
|
||||
}
|
||||
|
||||
RAW_FALSE_CHECK(cJSON_AddItemToObject(pJson, "metas", pMetaArr));
|
||||
tDeleteMqBatchMetaRsp(&rsp);
|
||||
char* fullStr = cJSON_PrintUnformatted(pJson);
|
||||
cJSON_Delete(pJson);
|
||||
|
|
|
@ -267,7 +267,7 @@ bool isSmlColAligned(SSmlHandle *info, int cnt, SSmlKv *kv) {
|
|||
goto END;
|
||||
}
|
||||
// bind data
|
||||
int32_t ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kv, cnt + 1);
|
||||
int32_t ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kv, cnt + 1, info->taos->optionInfo.charsetCxt);
|
||||
if (unlikely(ret != TSDB_CODE_SUCCESS)) {
|
||||
uDebug("smlBuildCol error, retry");
|
||||
goto END;
|
||||
|
@ -411,8 +411,8 @@ int32_t smlParseEndTelnetJsonFormat(SSmlHandle *info, SSmlLineInfo *elements, SS
|
|||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
uDebug("SML:0x%" PRIx64 " %s format true, ts:%" PRId64, info->id, __FUNCTION__ , kvTs->i);
|
||||
SML_CHECK_CODE(smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kvTs, 0));
|
||||
SML_CHECK_CODE(smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kv, 1));
|
||||
SML_CHECK_CODE(smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kvTs, 0, info->taos->optionInfo.charsetCxt));
|
||||
SML_CHECK_CODE(smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kv, 1, info->taos->optionInfo.charsetCxt));
|
||||
SML_CHECK_CODE(smlBuildRow(info->currTableDataCtx));
|
||||
|
||||
END:
|
||||
|
@ -438,7 +438,7 @@ END:
|
|||
int32_t smlParseEndLine(SSmlHandle *info, SSmlLineInfo *elements, SSmlKv *kvTs) {
|
||||
if (info->dataFormat) {
|
||||
uDebug("SML:0x%" PRIx64 " %s format true, ts:%" PRId64, info->id, __FUNCTION__, kvTs->i);
|
||||
int32_t ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kvTs, 0);
|
||||
int32_t ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, kvTs, 0, info->taos->optionInfo.charsetCxt);
|
||||
if (ret == TSDB_CODE_SUCCESS) {
|
||||
ret = smlBuildRow(info->currTableDataCtx);
|
||||
}
|
||||
|
@ -1486,7 +1486,7 @@ static int32_t smlInsertData(SSmlHandle *info) {
|
|||
|
||||
SML_CHECK_CODE(smlBindData(info->pQuery, info->dataFormat, tableData->tags, (*pMeta)->cols, tableData->cols,
|
||||
(*pMeta)->tableMeta, tableData->childTableName, measure, measureLen, info->ttl, info->msgBuf.buf,
|
||||
info->msgBuf.len));
|
||||
info->msgBuf.len, info->taos->optionInfo.charsetCxt));
|
||||
taosMemoryFreeClear(measure);
|
||||
oneTable = (SSmlTableInfo **)taosHashIterate(info->childTables, oneTable);
|
||||
}
|
||||
|
|
|
@ -1071,7 +1071,7 @@ int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) {
|
|||
tscDebug("start to bind stmt tag values");
|
||||
STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.stbFName,
|
||||
pStmt->bInfo.sname.tname, tags, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen));
|
||||
pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1239,7 +1239,7 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
|
|||
}
|
||||
|
||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||
STMT_ERR_RET(qStmtBindParams(pStmt->sql.pQuery, bind, colIdx));
|
||||
STMT_ERR_RET(qStmtBindParams(pStmt->sql.pQuery, bind, colIdx, pStmt->taos->optionInfo.charsetCxt));
|
||||
|
||||
SParseContext ctx = {.requestId = pStmt->exec.pRequest->requestId,
|
||||
.acctId = pStmt->taos->acctId,
|
||||
|
@ -1325,10 +1325,10 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
|
|||
if (pStmt->sql.stbInterlaceMode) {
|
||||
(*pDataBlock)->pData->flags = 0;
|
||||
code = qBindStmtStbColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo);
|
||||
pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt);
|
||||
} else {
|
||||
code =
|
||||
qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen);
|
||||
qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt);
|
||||
}
|
||||
|
||||
if (code) {
|
||||
|
@ -1353,7 +1353,7 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) {
|
|||
}
|
||||
|
||||
code = qBindStmtSingleColValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum);
|
||||
pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt);
|
||||
if (code) {
|
||||
tscError("qBindStmtSingleColValue failed, error:%s", tstrerror(code));
|
||||
STMT_ERR_RET(code);
|
||||
|
|
|
@ -1015,7 +1015,7 @@ int stmtSetTbTags2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* tags) {
|
|||
tscDebug("start to bind stmt tag values");
|
||||
STMT_ERR_RET(qBindStmtTagsValue2(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.stbFName,
|
||||
pStmt->bInfo.sname.tname, tags, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen));
|
||||
pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1094,6 +1094,13 @@ static int stmtFetchStbColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIEL
|
|||
}
|
||||
|
||||
STMT_ERR_RET(qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.preCtbname, fieldNum, fields));
|
||||
if (pStmt->bInfo.tbType == TSDB_SUPER_TABLE) {
|
||||
pStmt->bInfo.needParse = true;
|
||||
if (taosHashRemove(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName)) != 0) {
|
||||
tscError("get fileds %s remove exec blockHash fail", pStmt->bInfo.tbFName);
|
||||
STMT_ERR_RET(TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1324,7 +1331,7 @@ int stmtBindBatch2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* bind, int32_t colIdx) {
|
|||
}
|
||||
|
||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||
STMT_ERR_RET(qStmtBindParams2(pStmt->sql.pQuery, bind, colIdx));
|
||||
STMT_ERR_RET(qStmtBindParams2(pStmt->sql.pQuery, bind, colIdx, pStmt->taos->optionInfo.charsetCxt));
|
||||
|
||||
SParseContext ctx = {.requestId = pStmt->exec.pRequest->requestId,
|
||||
.acctId = pStmt->taos->acctId,
|
||||
|
@ -1408,10 +1415,10 @@ int stmtBindBatch2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* bind, int32_t colIdx) {
|
|||
if (pStmt->sql.stbInterlaceMode) {
|
||||
(*pDataBlock)->pData->flags = 0;
|
||||
code = qBindStmtStbColsValue2(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo);
|
||||
pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt);
|
||||
} else {
|
||||
code =
|
||||
qBindStmtColsValue2(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen);
|
||||
qBindStmtColsValue2(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt);
|
||||
}
|
||||
|
||||
if (code) {
|
||||
|
@ -1436,7 +1443,7 @@ int stmtBindBatch2(TAOS_STMT2* stmt, TAOS_STMT2_BIND* bind, int32_t colIdx) {
|
|||
}
|
||||
|
||||
code = qBindStmtSingleColValue2(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf,
|
||||
pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum);
|
||||
pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt);
|
||||
if (code) {
|
||||
tscError("qBindStmtSingleColValue failed, error:%s", tstrerror(code));
|
||||
STMT_ERR_RET(code);
|
||||
|
|
|
@ -11,6 +11,12 @@ TARGET_LINK_LIBRARIES(
|
|||
os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(connectOptionsTest connectOptionsTest.cpp)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
connectOptionsTest
|
||||
os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(tmqTest tmqTest.cpp)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
tmqTest
|
||||
|
@ -41,11 +47,21 @@ TARGET_INCLUDE_DIRECTORIES(
|
|||
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
connectOptionsTest
|
||||
PUBLIC "${TD_SOURCE_DIR}/include/client/"
|
||||
PRIVATE "${TD_SOURCE_DIR}/source/client/inc"
|
||||
)
|
||||
|
||||
IF(${TD_LINUX})
|
||||
add_test(
|
||||
NAME clientTest
|
||||
COMMAND clientTest
|
||||
)
|
||||
add_test(
|
||||
NAME connectOptionsTest
|
||||
COMMAND connectOptionsTest
|
||||
)
|
||||
ENDIF ()
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
|
@ -80,3 +96,4 @@ add_test(
|
|||
NAME userOperTest
|
||||
COMMAND userOperTest
|
||||
)
|
||||
|
||||
|
|
|
@ -1609,5 +1609,4 @@ TEST(clientCase, timezone_Test) {
|
|||
taos_close(pConn);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -0,0 +1,946 @@
|
|||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "taoserror.h"
|
||||
#include "tglobal.h"
|
||||
#include "thash.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
#include "executor.h"
|
||||
#include "taos.h"
|
||||
#include "clientInt.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TAOS* getConnWithGlobalOption(const char *tz){
|
||||
int code = taos_options(TSDB_OPTION_TIMEZONE, tz);
|
||||
ASSERT(code == 0);
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConn != nullptr);
|
||||
return pConn;
|
||||
}
|
||||
|
||||
TAOS* getConnWithOption(const char *tz){
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConn != nullptr);
|
||||
if (tz != NULL){
|
||||
int code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, tz);
|
||||
ASSERT(code == 0);
|
||||
}
|
||||
return pConn;
|
||||
}
|
||||
|
||||
void execQuery(TAOS* pConn, const char *sql){
|
||||
TAOS_RES* pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == TSDB_CODE_SUCCESS);
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void execQueryFail(TAOS* pConn, const char *sql){
|
||||
printf("execQueryFail: %s\n", sql);
|
||||
TAOS_RES* pRes = taos_query(pConn, sql);
|
||||
#ifndef WINDOWS
|
||||
ASSERT(taos_errno(pRes) != TSDB_CODE_SUCCESS);
|
||||
#endif
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void checkRows(TAOS* pConn, const char *sql, int32_t expectedRows){
|
||||
printf("checkRows sql:%s,rows:%d\n", sql, expectedRows);
|
||||
TAOS_RES* pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == TSDB_CODE_SUCCESS);
|
||||
TAOS_ROW pRow = NULL;
|
||||
int rows = 0;
|
||||
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
rows++;
|
||||
}
|
||||
ASSERT(rows == expectedRows);
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void check_timezone(TAOS* pConn, const char *sql, const char* tz){
|
||||
TAOS_RES *pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == 0);
|
||||
TAOS_ROW row = NULL;
|
||||
while ((row = taos_fetch_row(pRes)) != NULL) {
|
||||
if (strcmp((const char*)row[0], "timezone") == 0){
|
||||
ASSERT(strstr((const char*)row[1], tz) != NULL);
|
||||
}
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void check_sql_result_partial(TAOS* pConn, const char *sql, const char* result){
|
||||
TAOS_RES *pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == 0);
|
||||
TAOS_ROW row = NULL;
|
||||
while ((row = taos_fetch_row(pRes)) != NULL) {
|
||||
ASSERT(strstr((const char*)row[0], result) != NULL);
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
int64_t get_sql_result(TAOS* pConn, const char *sql){
|
||||
int64_t ts = 0;
|
||||
TAOS_RES *pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == 0);
|
||||
TAOS_ROW row = NULL;
|
||||
while ((row = taos_fetch_row(pRes)) != NULL) {
|
||||
ts = *(int64_t*)row[0];
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
return ts;
|
||||
}
|
||||
|
||||
void check_sql_result(TAOS* pConn, const char *sql, const char* result){
|
||||
printf("check_sql_result sql:%s,result:%s\n", sql, result);
|
||||
TAOS_RES *pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == 0);
|
||||
TAOS_ROW row = NULL;
|
||||
while ((row = taos_fetch_row(pRes)) != NULL) {
|
||||
#ifndef WINDOWS
|
||||
ASSERT (memcmp((const char*)row[0], result, strlen(result)) == 0);
|
||||
#endif
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void check_sql_result_integer(TAOS* pConn, const char *sql, int64_t result){
|
||||
printf("check_sql_result_integer sql:%s,result:%ld\n", sql, result);
|
||||
TAOS_RES *pRes = taos_query(pConn, sql);
|
||||
ASSERT(taos_errno(pRes) == 0);
|
||||
TAOS_ROW row = NULL;
|
||||
while ((row = taos_fetch_row(pRes)) != NULL) {
|
||||
#ifndef WINDOWS
|
||||
ASSERT (*(int64_t*)row[0] == result);
|
||||
#endif
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void check_set_timezone(TAOS* optionFunc(const char *tz)){
|
||||
{
|
||||
TAOS* pConn = optionFunc("UTC-8");
|
||||
check_timezone(pConn, "show local variables", "UTC-8");
|
||||
|
||||
execQuery(pConn, "drop database if exists db1");
|
||||
execQuery(pConn, "create database db1");
|
||||
execQuery(pConn, "create table db1.t1 (ts timestamp, v int)");
|
||||
|
||||
execQuery(pConn, "insert into db1.t1 values('2023-09-16 17:00:00', 1)");
|
||||
checkRows(pConn, "select * from db1.t1 where ts == '2023-09-16 17:00:00'", 1);
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
{
|
||||
TAOS* pConn = optionFunc("UTC+8");
|
||||
check_timezone(pConn, "show local variables", "UTC+8");
|
||||
checkRows(pConn, "select * from db1.t1 where ts == '2023-09-16 01:00:00'", 1);
|
||||
execQuery(pConn, "insert into db1.t1 values('2023-09-16 17:00:01', 1)");
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
{
|
||||
TAOS* pConn = optionFunc("UTC+0");
|
||||
check_timezone(pConn, "show local variables", "UTC+0");
|
||||
checkRows(pConn, "select * from db1.t1 where ts == '2023-09-16 09:00:00'", 1);
|
||||
checkRows(pConn, "select * from db1.t1 where ts == '2023-09-17 01:00:01'", 1);
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_TAOS_OPTION_POINTER(taos, option, isnull) \
|
||||
{ \
|
||||
STscObj* pObj = acquireTscObj(*(int64_t*)taos); \
|
||||
ASSERT(pObj != nullptr); \
|
||||
if (isnull) { \
|
||||
ASSERT(pObj->optionInfo.option == nullptr); \
|
||||
} else { \
|
||||
ASSERT(pObj->optionInfo.option != nullptr); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_TAOS_OPTION_APP(taos, option, val) \
|
||||
{ \
|
||||
STscObj* pObj = acquireTscObj(*(int64_t*)taos); \
|
||||
ASSERT(pObj != nullptr); \
|
||||
ASSERT(strcmp(pObj->optionInfo.option, val) == 0); \
|
||||
}
|
||||
|
||||
#define CHECK_TAOS_OPTION_IP_ERROR(taos, option, val) \
|
||||
{ \
|
||||
STscObj* pObj = acquireTscObj(*(int64_t*)taos); \
|
||||
ASSERT(pObj != nullptr); \
|
||||
ASSERT(pObj->optionInfo.option == val); \
|
||||
}
|
||||
|
||||
#define CHECK_TAOS_OPTION_IP(taos, option, val) \
|
||||
{ \
|
||||
STscObj* pObj = acquireTscObj(*(int64_t*)taos); \
|
||||
ASSERT(pObj != nullptr); \
|
||||
char ip[TD_IP_LEN] = {0}; \
|
||||
taosInetNtoa(ip, pObj->optionInfo.option); \
|
||||
ASSERT(strcmp(ip, val) == 0); \
|
||||
}
|
||||
|
||||
TEST(connectionCase, setConnectionOption_Test) {
|
||||
int32_t code = taos_options_connection(NULL, TSDB_OPTION_CONNECTION_CHARSET, NULL);
|
||||
ASSERT(code != 0);
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConn != nullptr);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_MAX_OPTIONS_CONNECTION, NULL);
|
||||
ASSERT(code != 0);
|
||||
|
||||
// test charset
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CHARSET, "");
|
||||
ASSERT(code != 0);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CHARSET, NULL);
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, charsetCxt, true);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CHARSET, "Asia/Shanghai");
|
||||
ASSERT(code != 0);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CHARSET, "gbk");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, charsetCxt, false);
|
||||
|
||||
#ifndef WINDOWS
|
||||
// test timezone
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, "");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, false);
|
||||
check_sql_result(pConn, "select timezone()", "UTC (UTC, +0000)");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, NULL);
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, true);
|
||||
check_sql_result(pConn, "select timezone()", "Asia/Shanghai (CST, +0800)");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, "UTC");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, false);
|
||||
check_sql_result(pConn, "select timezone()", "UTC (UTC, +0000)");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, "Asia/Kolkata");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, false);
|
||||
check_sql_result(pConn, "select timezone()", "Asia/Kolkata (IST, +0530)");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, "adbc");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, false);
|
||||
check_sql_result(pConn, "select timezone()", "adbc (UTC, +0000)");
|
||||
#endif
|
||||
|
||||
// test user APP
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_APP, "");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_APP(pConn, userApp, "");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_APP, NULL);
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_APP(pConn, userApp, "");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_APP, "aaaaaaaaaaaaaaaaaaaaaabbbbbbb");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_APP(pConn, userApp, "aaaaaaaaaaaaaaaaaaaaaab");
|
||||
|
||||
|
||||
// test user IP
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "");
|
||||
ASSERT(code != 0);
|
||||
CHECK_TAOS_OPTION_IP_ERROR(pConn, userIp, INADDR_NONE);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, NULL);
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_IP_ERROR(pConn, userIp, INADDR_NONE);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "aaaaaaaaaaaaaaaaaaaaaabbbbbbb");
|
||||
ASSERT(code != 0);
|
||||
CHECK_TAOS_OPTION_IP_ERROR(pConn, userIp, INADDR_NONE);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "1292.168.0.2");
|
||||
ASSERT(code != 0);
|
||||
CHECK_TAOS_OPTION_IP_ERROR(pConn, userIp, INADDR_NONE);
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "192.168.0.2");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_IP(pConn, userIp, "192.168.0.2");
|
||||
|
||||
taosMsleep(2 * HEARTBEAT_INTERVAL);
|
||||
|
||||
//test user APP and user IP
|
||||
check_sql_result(pConn, "select user_app from performance_schema.perf_connections", "aaaaaaaaaaaaaaaaaaaaaab");
|
||||
check_sql_result(pConn, "select user_ip from performance_schema.perf_connections", "192.168.0.2");
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "192.168.1.2");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_IP(pConn, userIp, "192.168.1.2");
|
||||
|
||||
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_APP, "user");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_APP(pConn, userApp, "user");
|
||||
|
||||
taosMsleep(2 * HEARTBEAT_INTERVAL);
|
||||
|
||||
check_sql_result(pConn, "select user_app from performance_schema.perf_connections", "user");
|
||||
check_sql_result(pConn, "select user_ip from performance_schema.perf_connections", "192.168.1.2");
|
||||
|
||||
|
||||
// test clear
|
||||
code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CLEAR, "192.168.0.2");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, charsetCxt, true);
|
||||
|
||||
#ifndef WINDOWS
|
||||
CHECK_TAOS_OPTION_POINTER(pConn, timezone, true);
|
||||
check_sql_result(pConn, "select timezone()", "Asia/Shanghai (CST, +0800)");
|
||||
#endif
|
||||
|
||||
CHECK_TAOS_OPTION_APP(pConn, userApp, "");
|
||||
CHECK_TAOS_OPTION_IP_ERROR(pConn, userIp, INADDR_NONE);
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
TEST(charsetCase, charset_Test) {
|
||||
// 1. build connection with different charset
|
||||
TAOS* pConnGbk = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConnGbk != nullptr);
|
||||
|
||||
TAOS* pConnUTF8 = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConnUTF8 != nullptr);
|
||||
|
||||
TAOS* pConnDefault = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConnDefault != nullptr);
|
||||
|
||||
int32_t code = taos_options_connection(pConnGbk, TSDB_OPTION_CONNECTION_CHARSET, "gbk");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConnGbk, charsetCxt, false);
|
||||
|
||||
code = taos_options_connection(pConnUTF8, TSDB_OPTION_CONNECTION_CHARSET, "UTF-8");
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConnUTF8, charsetCxt, false);
|
||||
|
||||
// 2. build test string
|
||||
char sqlTag[256] = {0};
|
||||
char sqlCol[256] = {0};
|
||||
|
||||
// 芬 gbk encode is 0xB7D2, UTF-8 encode is 0xE88AAC
|
||||
// 中国 gbk encode is 0xD6D0B9FA, UTF-8 encode is 0xE4B8ADE59BBD
|
||||
char fenUtf8[32] = {0};
|
||||
char fenGbk[32] = {0};
|
||||
char zhongGbk[32] = {0};
|
||||
char zhongguoUtf8[32] = {0};
|
||||
char guoUtf8[32] = {0};
|
||||
char zhongguoGbk[32] = {0};
|
||||
snprintf(fenUtf8, sizeof(fenUtf8), "%c%c%c", 0xE8, 0x8A, 0xAC);
|
||||
snprintf(fenGbk, sizeof(fenGbk), "%c%c", 0xB7, 0xD2);
|
||||
snprintf(zhongguoUtf8, sizeof(zhongguoUtf8), "%c%c%c%c%c%c", 0xE4, 0xB8, 0xAD, 0xE5, 0x9B, 0xBD);
|
||||
snprintf(guoUtf8, sizeof(guoUtf8), "%c%c%c", 0xE5, 0x9B, 0xBD);
|
||||
snprintf(zhongguoGbk, sizeof(zhongguoGbk), "%c%c%c%c", 0xD6, 0xD0, 0xB9, 0xFA);
|
||||
snprintf(zhongGbk, sizeof(zhongGbk), "%c%c", 0xD6, 0xD0);
|
||||
|
||||
// 3. create stable
|
||||
execQuery(pConnGbk, "drop database if exists db1");
|
||||
execQuery(pConnGbk, "create database db1");
|
||||
execQuery(pConnGbk, "create table db1.stb (ts timestamp, c1 nchar(32), c2 int) tags(t1 timestamp, t2 nchar(32), t3 int)");
|
||||
|
||||
// 4. test tag with different charset
|
||||
snprintf(sqlTag, sizeof(sqlTag), "create table db1.ctb1 using db1.stb tags('2023-09-16 17:00:00+05:00', '%s', 1)", fenUtf8);
|
||||
execQueryFail(pConnGbk, sqlTag);
|
||||
|
||||
snprintf(sqlTag, sizeof(sqlTag), "create table db1.ctb1 using db1.stb tags('2023-09-16 17:00:00+05:00', '%s', 1)", fenGbk);
|
||||
execQuery(pConnGbk, sqlTag);
|
||||
|
||||
// 5. test column with different charset
|
||||
snprintf(sqlCol, sizeof(sqlCol), "insert into db1.ctb1 values(1732178775133, '%s', 1)", zhongguoUtf8);
|
||||
execQueryFail(pConnGbk, sqlCol);
|
||||
|
||||
snprintf(sqlCol, sizeof(sqlCol), "insert into db1.ctb1 values(1732178775133, '%s', 1)", zhongguoGbk);
|
||||
execQuery(pConnGbk, sqlCol);
|
||||
|
||||
// 6. check result with different charset
|
||||
check_sql_result(pConnGbk, "select t2 from db1.ctb1", fenGbk);
|
||||
check_sql_result(pConnUTF8, "select t2 from db1.ctb1", fenUtf8);
|
||||
|
||||
check_sql_result(pConnGbk, "select c1 from db1.ctb1", zhongguoGbk);
|
||||
check_sql_result(pConnUTF8, "select c1 from db1.ctb1", zhongguoUtf8);
|
||||
|
||||
// 7. test function with different charset
|
||||
// 7.1 concat
|
||||
char zhongguofenGbk[32] = {0};
|
||||
snprintf(zhongguofenGbk, sizeof(zhongguofenGbk), "%s%s", zhongguoGbk, fenGbk);
|
||||
char sql[256] = {0};
|
||||
snprintf(sql, sizeof(sql), "select concat(c1, '%s') from db1.ctb1", fenGbk);
|
||||
execQueryFail(pConnGbk, sql);
|
||||
snprintf(sql, sizeof(sql), "select concat(c1, '%s') from db1.ctb1", fenUtf8);
|
||||
check_sql_result(pConnGbk, sql, zhongguofenGbk);
|
||||
|
||||
// 7.2 trim
|
||||
snprintf(sql, sizeof(sql), "select trim(LEADING c1 from '%s') from db1.ctb1", zhongguofenGbk);
|
||||
check_sql_result(pConnGbk, sql, zhongguofenGbk);
|
||||
char zhongguofenUtf8[32] = {0};
|
||||
snprintf(zhongguofenUtf8, sizeof(zhongguofenUtf8), "%s%s", zhongguoUtf8, fenUtf8);
|
||||
snprintf(sql, sizeof(sql), "select trim(LEADING c1 from '%s') from db1.ctb1", zhongguofenUtf8);
|
||||
check_sql_result(pConnGbk, sql, fenUtf8);
|
||||
|
||||
check_sql_result(pConnGbk, "select char(c1) from db1.ctb1", "");
|
||||
|
||||
check_sql_result_integer(pConnGbk, "select ascii(c1) from db1.ctb1", 0xE4);
|
||||
check_sql_result_integer(pConnUTF8, "select ascii(c1) from db1.ctb1", 0xE4);
|
||||
check_sql_result_integer(pConnGbk, "select LENGTH(c1) from db1.ctb1", 8);
|
||||
check_sql_result_integer(pConnUTF8, "select LENGTH(c1) from db1.ctb1", 8);
|
||||
check_sql_result_integer(pConnGbk, "select CHAR_LENGTH(c1) from db1.ctb1", 2);
|
||||
check_sql_result_integer(pConnUTF8, "select CHAR_LENGTH(c1) from db1.ctb1", 2);
|
||||
|
||||
execQuery(pConnGbk, "select LOWER(c1) from db1.ctb1");
|
||||
execQuery(pConnGbk, "select UPPER(c1) from db1.ctb1");
|
||||
|
||||
snprintf(sql, sizeof(sql), "select position(c1 in '%s') from db1.ctb1", zhongguofenGbk);
|
||||
check_sql_result_integer(pConnGbk, sql, 0);
|
||||
|
||||
snprintf(sql, sizeof(sql), "select position('%s' in c1) from db1.ctb1", guoUtf8);
|
||||
check_sql_result_integer(pConnUTF8, sql, 2);
|
||||
|
||||
snprintf(sql, sizeof(sql), "select replace(c1, '%s', 'a') from db1.ctb1", zhongguoGbk);
|
||||
execQueryFail(pConnGbk, sql);
|
||||
|
||||
snprintf(sql, sizeof(sql), "select replace(c1, '%s', 'a') from db1.ctb1", zhongguoUtf8);
|
||||
check_sql_result(pConnUTF8, sql, "a");
|
||||
|
||||
snprintf(sql, sizeof(sql), "%s%s", zhongguoGbk, zhongguoGbk);
|
||||
check_sql_result(pConnGbk, "select repeat(c1, 2) from db1.ctb1", sql);
|
||||
|
||||
check_sql_result(pConnGbk, "select cast(c1 as binary(32)) from db1.ctb1", zhongguoUtf8);
|
||||
|
||||
check_sql_result(pConnUTF8, "select substr(c1,2,1) from db1.ctb1", guoUtf8);
|
||||
|
||||
snprintf(sql, sizeof(sql), "select SUBSTRING_INDEX(c1,'%s',1) from db1.ctb1", guoUtf8);
|
||||
check_sql_result(pConnGbk, sql, zhongGbk);
|
||||
|
||||
// 8. test default charset
|
||||
snprintf(sqlCol, sizeof(sqlCol), "insert into db1.ctb1 values(1732178775134, '%s', 1)", zhongguoUtf8);
|
||||
execQuery(pConnDefault, sqlCol);
|
||||
check_sql_result(pConnDefault, "select c1 from db1.ctb1 where ts = 1732178775134", zhongguoUtf8);
|
||||
|
||||
// 9. test json tag with different charset
|
||||
execQuery(pConnUTF8, "create table db1.jsta (ts timestamp, c1 nchar(32), c2 int) tags(t1 json)");
|
||||
snprintf(sqlCol, sizeof(sqlCol), "create table db1.jsta1 using db1.jsta tags('{\"k\":\"%s\"}')", fenUtf8);
|
||||
execQuery(pConnUTF8, sqlCol);
|
||||
snprintf(sqlCol, sizeof(sqlCol), "insert into db1.jsta1 values(1732178775133, '%s', 1)", zhongguoUtf8);
|
||||
execQuery(pConnUTF8, sqlCol);
|
||||
|
||||
char resJsonTag[32] = {0};
|
||||
snprintf(resJsonTag, sizeof(resJsonTag), "{\"k\":\"%s\"}", fenGbk);
|
||||
check_sql_result(pConnGbk, "select t1 from db1.jsta1", resJsonTag);
|
||||
|
||||
// 10. reset charset to default(utf-8
|
||||
code = taos_options_connection(pConnGbk, TSDB_OPTION_CONNECTION_CHARSET, NULL);
|
||||
ASSERT(code == 0);
|
||||
CHECK_TAOS_OPTION_POINTER(pConnGbk, charsetCxt, true);
|
||||
check_sql_result(pConnGbk, "select t2 from db1.ctb1 where ts = 1732178775134", fenUtf8);
|
||||
check_sql_result(pConnGbk, "select c1 from db1.ctb1 where ts = 1732178775134", zhongguoUtf8);
|
||||
|
||||
taos_close(pConnGbk);
|
||||
taos_close(pConnUTF8);
|
||||
taos_close(pConnDefault);
|
||||
|
||||
}
|
||||
|
||||
TEST(charsetCase, alter_charset_Test) {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
ASSERT(pConn != nullptr);
|
||||
|
||||
execQueryFail(pConn, "alter dnode 1 'charset gbk'");
|
||||
execQueryFail(pConn, "local 'charset gbk'");
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
TEST(timezoneCase, set_timezone_Test) {
|
||||
check_set_timezone(getConnWithGlobalOption);
|
||||
check_set_timezone(getConnWithOption);
|
||||
}
|
||||
|
||||
TEST(timezoneCase, alter_timezone_Test) {
|
||||
TAOS* pConn = getConnWithGlobalOption("UTC-8");
|
||||
check_timezone(pConn, "show local variables", "UTC-8");
|
||||
|
||||
execQuery(pConn, "alter local 'timezone Asia/Kolkata'");
|
||||
check_timezone(pConn, "show local variables", "Asia/Kolkata");
|
||||
|
||||
execQuery(pConn, "alter local 'timezone Asia/Shanghai'");
|
||||
check_timezone(pConn, "show local variables", "Asia/Shanghai");
|
||||
|
||||
execQueryFail(pConn, "alter dnode 1 'timezone Asia/Kolkata'");
|
||||
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
char *tz_test[] = {
|
||||
"2023-09-16 17:00:00+",
|
||||
"2023-09-16 17:00:00+a",
|
||||
"2023-09-16 17:00:00+8",
|
||||
"2023-09-16 17:00:00+832",
|
||||
"2023-09-16 17:00:00+8323",
|
||||
"2023-09-16 17:00:00+:",
|
||||
"2023-09-16 17:00:00+8:",
|
||||
"2023-09-16 17:00:00++:",
|
||||
"2023-09-16 17:00:00+d:",
|
||||
"2023-09-16 17:00:00+09:",
|
||||
"2023-09-16 17:00:00+8f:",
|
||||
"2023-09-16 17:00:00+080:",
|
||||
"2023-09-16 17:00:00+:30",
|
||||
"2023-09-16 17:00:00+:3",
|
||||
"2023-09-16 17:00:00+:093",
|
||||
"2023-09-16 17:00:00+:-30",
|
||||
"2023-09-16 17:00:00++:-30",
|
||||
"2023-09-16 17:00:00+8:8",
|
||||
"2023-09-16 17:00:00+8:2a",
|
||||
"2023-09-16 17:00:00+8:08",
|
||||
"2023-09-16 17:00:00+8:038",
|
||||
"2023-09-16 17:00:00+08:8",
|
||||
"2023-09-16 17:00:00+09:3a",
|
||||
"2023-09-16 17:00:00+09:abc",
|
||||
"2023-09-16 17:00:00+09:001",
|
||||
};
|
||||
|
||||
void do_insert_failed(){
|
||||
TAOS* pConn = getConnWithGlobalOption("UTC-8");
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (tz_test) / sizeof (tz_test[0]); ++i){
|
||||
char sql[1024] = {0};
|
||||
(void)snprintf(sql, sizeof(sql), "insert into db1.ctb1 values('%s', '%s', 1)", tz_test[i], tz_test[i]);
|
||||
|
||||
execQueryFail(pConn, sql);
|
||||
}
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
struct insert_params
|
||||
{
|
||||
const char *tz;
|
||||
const char *tbname;
|
||||
const char *t1;
|
||||
const char *t2;
|
||||
};
|
||||
|
||||
struct insert_params params1[] = {
|
||||
{"UTC", "ntb", "2023-09-16 17:00:00", "2023-09-16 17:00:00+08:00"},
|
||||
{"UTC", "ctb1", "2023-09-16 17:00:00", "2023-09-16 17:00:00+08:00"},
|
||||
};
|
||||
|
||||
struct insert_params params2[] = {
|
||||
{"UTC+9", "ntb", "2023-09-16 08:00:00", "2023-09-16 08:00:00-01:00"},
|
||||
{"UTC+9", "ctb1", "2023-09-16 08:00:00", "2023-09-16 11:00:00+02:00"},
|
||||
};
|
||||
|
||||
void do_insert(struct insert_params params){
|
||||
TAOS* pConn = getConnWithOption(params.tz);
|
||||
char sql[1024] = {0};
|
||||
(void)snprintf(sql, sizeof(sql), "insert into db1.%s values('%s', '%s', 1)", params.tbname, params.t1, params.t2);
|
||||
execQuery(pConn, sql);
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
void do_select(struct insert_params params){
|
||||
TAOS* pConn = getConnWithOption(params.tz);
|
||||
char sql[1024] = {0};
|
||||
(void)snprintf(sql, sizeof(sql), "select * from db1.%s where ts == '%s' and c1 == '%s'", params.tbname, params.t1, params.t2);
|
||||
checkRows(pConn, sql, 1);
|
||||
taos_close(pConn);
|
||||
}
|
||||
|
||||
// test insert string and integer to timestamp both normal table and child table(and tag)
|
||||
TEST(timezoneCase, insert_with_timezone_Test) {
|
||||
/*
|
||||
* 1. prepare data, create db and tables
|
||||
*/
|
||||
TAOS* pConn1 = getConnWithOption("UTC+2");
|
||||
execQuery(pConn1, "drop database if exists db1");
|
||||
execQuery(pConn1, "create database db1");
|
||||
execQuery(pConn1, "create table db1.ntb (ts timestamp, c1 timestamp, c2 int)");
|
||||
execQuery(pConn1, "create table db1.stb (ts timestamp, c1 timestamp, c2 int) tags(t1 timestamp, t2 timestamp, t3 int)");
|
||||
execQuery(pConn1, "create table db1.ctb1 using db1.stb tags(\"2023-09-16 17:00:00+05:00\", \"2023-09-16 17:00:00\", 1)");
|
||||
execQuery(pConn1, "create table db1.ctb2 using db1.stb tags(1732178775000, 1732178775000, 1)");
|
||||
execQuery(pConn1, "insert into db1.ntb values(1732178775133, 1732178775133, 1)");
|
||||
execQuery(pConn1, "insert into db1.ctb1 values(1732178775133, 1732178775133, 1)"); //2024-11-21 10:46:15.133+02:00
|
||||
execQuery(pConn1, "insert into db1.ctb2 values(1732178775133, 1732178775133, 1)");
|
||||
|
||||
/*
|
||||
* 2. test tag and timestamp with integer format
|
||||
*/
|
||||
TAOS* pConn2 = getConnWithOption("UTC-2");
|
||||
checkRows(pConn2, "select * from db1.stb where t1 == '2023-09-16 17:00:00+05:00' and t2 == '2023-09-16 21:00:00'", 1);
|
||||
checkRows(pConn2, "select * from db1.stb where t1 == '2024-11-21 16:46:15+08:00' and t2 == '2024-11-21 09:46:15+01:00'", 1);
|
||||
checkRows(pConn2, "select * from db1.ntb where ts == '2024-11-21 09:46:15.133+01:00' and c1 == '2024-11-21 10:46:15.133'", 1);
|
||||
checkRows(pConn2, "select * from db1.ctb1 where ts == '2024-11-21 09:46:15.133+01:00' and c1 == '2024-11-21 10:46:15.133'", 1);
|
||||
|
||||
check_sql_result(pConn2, "select TO_ISO8601(ts) from db1.ctb1", "2024-11-21T10:46:15.133+0200"); // 2024-01-01 23:00:00+0200
|
||||
|
||||
|
||||
/*
|
||||
* 3. test timestamp with string format
|
||||
*/
|
||||
for (unsigned int i = 0; i < sizeof (params1) / sizeof (params1[0]); ++i){
|
||||
do_insert(params1[i]);
|
||||
do_select(params1[i]);
|
||||
do_select(params2[i]);
|
||||
}
|
||||
|
||||
do_insert_failed();
|
||||
/*
|
||||
* 4. test NULL timezone, use default timezone UTC-8
|
||||
*/
|
||||
TAOS* pConn3 = getConnWithOption(NULL);
|
||||
checkRows(pConn3, "select * from db1.stb where t1 == '2023-09-16 20:00:00' and t2 == '2023-09-17 03:00:00'", 2);
|
||||
checkRows(pConn3, "select * from db1.stb where t1 == 1732178775000 and t2 == 1732178775000", 1);
|
||||
checkRows(pConn3, "select * from db1.ntb where ts == '2024-11-21 16:46:15.133' and c1 == '2024-11-21 16:46:15.133'", 1);
|
||||
checkRows(pConn3, "select * from db1.ctb1 where ts == '2023-09-17 01:00:00' and c1 == '2023-09-16 17:00:00'", 1);
|
||||
|
||||
/*
|
||||
* 5. test multi connection with different timezone
|
||||
*/
|
||||
checkRows(pConn2, "select * from db1.ctb1 where ts == '2024-11-21 09:46:15.133+01:00' and c1 == '2024-11-21 10:46:15.133'", 1);
|
||||
checkRows(pConn1, "select * from db1.ctb1 where ts == '2024-11-21 09:46:15.133+01:00' and c1 == '2024-11-21 06:46:15.133'", 1);
|
||||
|
||||
taos_close(pConn1);
|
||||
taos_close(pConn2);
|
||||
taos_close(pConn3);
|
||||
}
|
||||
|
||||
TEST(timezoneCase, func_timezone_Test) {
|
||||
TAOS* pConn = getConnWithGlobalOption("UTC+8");
|
||||
check_sql_result(pConn, "select timezone()", "UTC+8 (UTC, -0800)");
|
||||
taos_close(pConn);
|
||||
|
||||
pConn = getConnWithOption("UTC-2");
|
||||
|
||||
execQuery(pConn, "drop database if exists db1");
|
||||
execQuery(pConn, "create database db1");
|
||||
execQuery(pConn, "create table db1.ntb (ts timestamp, c1 binary(32), c2 int)");
|
||||
execQuery(pConn, "insert into db1.ntb values(1704142800000, '2024-01-01 23:00:00', 1)"); // 2024-01-01 23:00:00+0200
|
||||
|
||||
// test timezone
|
||||
check_sql_result(pConn, "select timezone()", "UTC-2 (UTC, +0200)");
|
||||
|
||||
// test timetruncate
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 23:00:00', 1d, 0))", "2024-01-01T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00', 1d, 0))", "2023-12-31T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00+0300', 1d, 0))", "2023-12-31T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00-0300', 1d, 0))", "2024-01-01T02:00:00.000+0200");
|
||||
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 23:00:00', 1w, 0))", "2024-01-04T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00', 1w, 0))", "2023-12-28T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00+0300', 1w, 0))", "2023-12-28T02:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00-0300', 1w, 0))", "2024-01-04T02:00:00.000+0200");
|
||||
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 23:00:00', 1d, 1))", "2024-01-01T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00', 1d, 1))", "2024-01-01T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00+0500', 1d, 1))", "2023-12-31T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-01 01:00:00-0300', 1d, 1))", "2024-01-01T00:00:00.000+0200");
|
||||
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 23:00:00', 1w, 1))", "2024-01-04T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00', 1w, 1))", "2024-01-04T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00+0500', 1w, 1))", "2023-12-28T00:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE('2024-01-04 01:00:00-0300', 1w, 1))", "2024-01-04T00:00:00.000+0200");
|
||||
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE(1704142800000, 1d, 0))", "2024-01-01T02:00:00.000+0200"); // 2024-01-01 23:00:00+0200
|
||||
check_sql_result(pConn, "select TO_ISO8601(TIMETRUNCATE(ts, 1w, 1)) from db1.ntb", "2023-12-28T00:00:00.000+0200"); // 2024-01-01 23:00:00+0200
|
||||
|
||||
// TODAY
|
||||
check_sql_result_partial(pConn, "select TO_ISO8601(today())", "T00:00:00.000+0200");
|
||||
|
||||
// NOW
|
||||
check_sql_result_partial(pConn, "select TO_ISO8601(now())", "+0200");
|
||||
|
||||
// WEEKDAY
|
||||
check_sql_result_integer(pConn, "select WEEKDAY('2024-01-01')", 0);
|
||||
check_sql_result_integer(pConn, "select WEEKDAY('2024-01-01 03:00:00')", 0);
|
||||
check_sql_result_integer(pConn, "select WEEKDAY('2024-01-01 23:00:00+0200')", 0);
|
||||
check_sql_result_integer(pConn, "select WEEKDAY('2024-01-01 23:00:00-1100')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEKDAY(1704142800000)", 0);
|
||||
check_sql_result_integer(pConn, "select WEEKDAY(ts) from db1.ntb", 1);
|
||||
|
||||
// DAYOFWEEK
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK('2024-01-01')", 2);
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK('2024-01-01 03:00:00')", 2);
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK('2024-01-01 23:00:00+0200')", 2);
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK('2024-01-01 23:00:00-1100')", 3);
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK(1704142800000)", 2);
|
||||
check_sql_result_integer(pConn, "select DAYOFWEEK(ts) from db1.ntb", 3);
|
||||
|
||||
// WEEK
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07 02:00:00')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07 02:00:00+0200')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07 02:00:00+1100')", 0);
|
||||
check_sql_result_integer(pConn, "select WEEK(1704142800000)", 0); // 2024-01-01 23:00:00+0200
|
||||
check_sql_result_integer(pConn, "select WEEK(ts) from db1.ntb", 0); // 2024-01-01 23:00:00+0200
|
||||
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07', 3)", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07 02:00:00', 3)", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-07 02:00:00+0200', 3)", 1);
|
||||
check_sql_result_integer(pConn, "select WEEK('2024-01-01 02:00:00+1100', 3)", 52);
|
||||
check_sql_result_integer(pConn, "select WEEK(1704142800000, 3)", 1); // 2024-01-01 23:00:00+0200
|
||||
check_sql_result_integer(pConn, "select WEEK(ts, 3) from db1.ntb", 1); // 2024-01-01 23:00:00+0200
|
||||
|
||||
// WEEKOFYEAR
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR('2024-01-07')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR('2024-01-07 02:00:00')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR('2024-01-07 02:00:00+0200')", 1);
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR('2024-01-01 02:00:00+1100')", 52);
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR(1704142800000)", 1); // 2024-01-01 23:00:00+0200
|
||||
check_sql_result_integer(pConn, "select WEEKOFYEAR(ts) from db1.ntb", 1); // 2024-01-01 23:00:00+0200
|
||||
|
||||
// TO_ISO8601
|
||||
check_sql_result(pConn, "select TO_ISO8601(ts) from db1.ntb", "2024-01-01T23:00:00.000+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(ts,'-08') from db1.ntb", "2024-01-01T13:00:00.000-08");
|
||||
check_sql_result(pConn, "select TO_ISO8601(1)", "1970-01-01T02:00:00.001+0200");
|
||||
check_sql_result(pConn, "select TO_ISO8601(1,'+0800')", "1970-01-01T08:00:00.001+0800");
|
||||
|
||||
// TO_UNIXTIMESTAMP
|
||||
check_sql_result_integer(pConn, "select TO_UNIXTIMESTAMP(c1) from db1.ntb", 1704121200000); // use timezone in server UTC-8
|
||||
check_sql_result_integer(pConn, "select TO_UNIXTIMESTAMP('2024-01-01T23:00:00.000+0200')", 1704142800000);
|
||||
check_sql_result_integer(pConn, "select TO_UNIXTIMESTAMP('2024-01-01T13:00:00.000-08')", 1704142800000);
|
||||
check_sql_result_integer(pConn, "select TO_UNIXTIMESTAMP('2024-01-01T23:00:00.001')", 1704142800001);
|
||||
|
||||
// TO_TIMESTAMP
|
||||
check_sql_result_integer(pConn, "select TO_TIMESTAMP(c1,'yyyy-mm-dd hh24:mi:ss') from db1.ntb", 1704121200000); // use timezone in server UTC-8
|
||||
check_sql_result_integer(pConn, "select TO_TIMESTAMP('2024-01-01 23:00:00+02:00', 'yyyy-mm-dd hh24:mi:ss tzh')", 1704142800000);
|
||||
check_sql_result_integer(pConn, "select TO_TIMESTAMP('2024-01-01T13:00:00-08', 'yyyy-mm-ddThh24:mi:ss tzh')", 1704142800000);
|
||||
check_sql_result_integer(pConn, "select TO_TIMESTAMP('2024/01/01 23:00:00', 'yyyy/mm/dd hh24:mi:ss')", 1704142800000);
|
||||
|
||||
// TO_CHAR
|
||||
check_sql_result(pConn, "select TO_CHAR(ts,'yyyy-mm-dd hh24:mi:ss') from db1.ntb", "2024-01-02 05:00:00"); // use timezone in server UTC-8
|
||||
check_sql_result(pConn, "select TO_CHAR(cast(1704142800000 as timestamp), 'yyyy-mm-dd hh24:mi:ss tzh')", "2024-01-01 23:00:00 +02");
|
||||
check_sql_result(pConn, "select TO_CHAR(cast(1704142800000 as timestamp), 'yyyy-mm-dd hh24:mi:ss')", "2024-01-01 23:00:00");
|
||||
|
||||
// TIMEDIFF
|
||||
check_sql_result_integer(pConn, "select TIMEDIFF(c1, '2024-01-01T23:00:00.001+02') from db1.ntb", -21600001); // use timezone in server UTC-8
|
||||
check_sql_result_integer(pConn, "select TIMEDIFF(c1, '2024-01-01T23:00:00.001') from db1.ntb", -1); // use timezone in server UTC-8
|
||||
check_sql_result_integer(pConn, "select TIMEDIFF('2024-01-01T23:00:00.001', '2024-01-01T13:00:00.000-08')", 1);
|
||||
|
||||
// CAST
|
||||
check_sql_result_integer(pConn, "select CAST(c1 as timestamp) from db1.ntb", 1704121200000);
|
||||
check_sql_result_integer(pConn, "select CAST('2024-01-01T23:00:00.000+02' as timestamp)", 1704142800000);
|
||||
check_sql_result_integer(pConn, "select CAST('2024-01-01T23:00:00.000' as timestamp)", 1704142800000);
|
||||
|
||||
taos_close(pConn);
|
||||
|
||||
// hash join
|
||||
pConn = getConnWithOption("UTC+1");
|
||||
|
||||
execQuery(pConn, "drop database if exists db1");
|
||||
execQuery(pConn, "create database db1");
|
||||
execQuery(pConn, "create table db1.ntb (ts timestamp, c1 binary(32), c2 int)");
|
||||
execQuery(pConn, "create table db1.ntb1 (ts timestamp, c1 binary(32), c2 int)");
|
||||
execQuery(pConn, "insert into db1.ntb values(1703987400000, '2023-12-31 00:50:00', 1)"); // 2023-12-31 00:50:00-0100
|
||||
execQuery(pConn, "insert into db1.ntb1 values(1704070200000, '2023-12-31 23:50:00', 11)"); // 2023-12-31 23:50:00-0100
|
||||
checkRows(pConn, "select a.ts,b.ts from db1.ntb a join db1.ntb1 b on timetruncate(a.ts, 1d) = timetruncate(b.ts, 1d)", 1);
|
||||
|
||||
// operator +1n +1y
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2023-01-31T00:00:00.000-01' as timestamp) + 1n)", "2023-02-28T00:00:00.000-0100");
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2024-01-31T00:00:00.000-01' as timestamp) + 1n)", "2024-02-29T00:00:00.000-0100");
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2024-02-29T00:00:00.000-01' as timestamp) + 1y)", "2025-02-28T00:00:00.000-0100");
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2024-01-31T00:00:00.000-01' as timestamp) + 1y)", "2025-01-31T00:00:00.000-0100");
|
||||
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2024-01-01T00:00:00.000+01' as timestamp) + 1n)", "2024-01-31T22:00:00.000-0100");
|
||||
check_sql_result(pConn, "select TO_ISO8601(CAST('2024-01-01T00:00:00.000+01' as timestamp) + 1y)", "2024-12-31T22:00:00.000-0100");
|
||||
|
||||
// case when
|
||||
check_sql_result_integer(pConn, "select case CAST('2024-01-01T00:00:00.000+01' as timestamp) when 1704063600000 then 1 end", 1);
|
||||
check_sql_result_integer(pConn, "select case CAST('2024-01-01T00:00:00.000' as timestamp) when 1704070800000 then 1 end", 1);
|
||||
|
||||
taos_close(pConn);
|
||||
|
||||
}
|
||||
|
||||
time_t time_winter = 1731323281; // 2024-11-11 19:08:01+0800
|
||||
time_t time_summer = 1731323281 - 120 * 24 * 60 * 60;
|
||||
|
||||
struct test_times
|
||||
{
|
||||
const char *name;
|
||||
time_t t;
|
||||
const char *timezone;
|
||||
} test_tz[] = {
|
||||
{"", time_winter, " (UTC, +0000)"},
|
||||
{"America/New_York", time_winter, "America/New_York (EST, -0500)"}, // 2024-11-11 19:08:01+0800
|
||||
{"America/New_York", time_summer, "America/New_York (EDT, -0400)"},
|
||||
{"Asia/Kolkata", time_winter, "Asia/Kolkata (IST, +0530)"},
|
||||
{"Asia/Shanghai", time_winter, "Asia/Shanghai (CST, +0800)"},
|
||||
{"Europe/London", time_winter, "Europe/London (GMT, +0000)"},
|
||||
{"Europe/London", time_summer, "Europe/London (BST, +0100)"}
|
||||
};
|
||||
|
||||
void timezone_str_test(const char* tz, time_t t, const char* tzStr) {
|
||||
int code = setenv("TZ", tz, 1);
|
||||
ASSERT(-1 != code);
|
||||
tzset();
|
||||
|
||||
char str1[TD_TIMEZONE_LEN] = {0};
|
||||
ASSERT(taosFormatTimezoneStr(t, tz, NULL, str1) == 0);
|
||||
ASSERT_STREQ(str1, tzStr);
|
||||
}
|
||||
|
||||
void timezone_rz_str_test(const char* tz, time_t t, const char* tzStr) {
|
||||
timezone_t sp = tzalloc(tz);
|
||||
ASSERT(sp);
|
||||
|
||||
char str1[TD_TIMEZONE_LEN] = {0};
|
||||
ASSERT(taosFormatTimezoneStr(t, tz, sp, str1) == 0);
|
||||
ASSERT_STREQ(str1, tzStr);
|
||||
tzfree(sp);
|
||||
}
|
||||
|
||||
TEST(timezoneCase, format_timezone_Test) {
|
||||
for (unsigned int i = 0; i < sizeof (test_tz) / sizeof (test_tz[0]); ++i){
|
||||
timezone_str_test(test_tz[i].name, test_tz[i].t, test_tz[i].timezone);
|
||||
timezone_str_test(test_tz[i].name, test_tz[i].t, test_tz[i].timezone);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(timezoneCase, get_tz_Test) {
|
||||
{
|
||||
char tz[TD_TIMEZONE_LEN] = {0};
|
||||
getTimezoneStr(tz);
|
||||
ASSERT_STREQ(tz, "Asia/Shanghai");
|
||||
|
||||
// getTimezoneStr(tz);
|
||||
// ASSERT_STREQ(tz, "Asia/Shanghai");
|
||||
//
|
||||
// getTimezoneStr(tz);
|
||||
// ASSERT_STREQ(tz, TZ_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
const char * env;
|
||||
time_t expected;
|
||||
} test_mk[] = {
|
||||
{"MST", 832935315},
|
||||
{"", 832910115},
|
||||
{":UTC", 832910115},
|
||||
{"UTC", 832910115},
|
||||
{"UTC0", 832910115}
|
||||
};
|
||||
|
||||
|
||||
TEST(timezoneCase, mktime_Test){
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
|
||||
memset (&tm, 0, sizeof (tm));
|
||||
tm.tm_isdst = 0;
|
||||
tm.tm_year = 96; /* years since 1900 */
|
||||
tm.tm_mon = 4;
|
||||
tm.tm_mday = 24;
|
||||
tm.tm_hour = 3;
|
||||
tm.tm_min = 55;
|
||||
tm.tm_sec = 15;
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (test_mk) / sizeof (test_mk[0]); ++i)
|
||||
{
|
||||
setenv ("TZ", test_mk[i].env, 1);
|
||||
t = taosMktime (&tm, NULL);
|
||||
ASSERT (t == test_mk[i].expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(timezoneCase, mktime_rz_Test){
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
|
||||
memset (&tm, 0, sizeof (tm));
|
||||
tm.tm_isdst = 0;
|
||||
tm.tm_year = 96; /* years since 1900 */
|
||||
tm.tm_mon = 4;
|
||||
tm.tm_mday = 24;
|
||||
tm.tm_hour = 3;
|
||||
tm.tm_min = 55;
|
||||
tm.tm_sec = 15;
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (test_mk) / sizeof (test_mk[0]); ++i)
|
||||
{
|
||||
timezone_t tz = tzalloc(test_mk[i].env);
|
||||
ASSERT(tz);
|
||||
t = taosMktime(&tm, tz);
|
||||
ASSERT (t == test_mk[i].expected);
|
||||
tzfree(tz);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(timezoneCase, localtime_performance_Test) {
|
||||
timezone_t sp = tzalloc("Asia/Shanghai");
|
||||
ASSERT(sp);
|
||||
|
||||
int cnt = 1000000;
|
||||
int times = 10;
|
||||
int64_t time_localtime = 0;
|
||||
int64_t time_localtime_rz = 0;
|
||||
// int cnt = 1000000;
|
||||
for (int i = 0; i < times; ++i) {
|
||||
int64_t t1 = taosGetTimestampNs();
|
||||
for (int j = 0; j < cnt; ++j) {
|
||||
time_t t = time_winter - j;
|
||||
struct tm tm1;
|
||||
ASSERT (taosLocalTime(&t, &tm1, NULL, 0, NULL));
|
||||
}
|
||||
int64_t tmp = taosGetTimestampNs() - t1;
|
||||
printf("localtime cost:%" PRId64 " ns, run %d times", tmp, cnt);
|
||||
time_localtime += tmp/cnt;
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
||||
|
||||
int64_t t2 = taosGetTimestampNs();
|
||||
for (int j = 0; j < cnt; ++j) {
|
||||
time_t t = time_winter - j;
|
||||
struct tm tm1;
|
||||
ASSERT (taosLocalTime(&t, &tm1, NULL, 0, sp));
|
||||
}
|
||||
tmp = taosGetTimestampNs() - t2;
|
||||
printf("localtime_rz cost:%" PRId64 " ns, run %d times", tmp, cnt);
|
||||
time_localtime_rz += tmp/cnt;
|
||||
printf("\n\n");
|
||||
}
|
||||
printf("average: localtime cost:%" PRId64 " ns, localtime_rz cost:%" PRId64 " ns\n", time_localtime/times, time_localtime_rz/times);
|
||||
tzfree(sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
|
@ -303,6 +303,8 @@ static int32_t tSerializeSClientHbReq(SEncoder *pEncoder, const SClientHbReq *pR
|
|||
TAOS_CHECK_RETURN(tEncodeSKv(pEncoder, kv));
|
||||
pIter = taosHashIterate(pReq->info, pIter);
|
||||
}
|
||||
TAOS_CHECK_RETURN(tEncodeU32(pEncoder, pReq->userIp));
|
||||
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pReq->userApp));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -400,6 +402,10 @@ static int32_t tDeserializeSClientHbReq(SDecoder *pDecoder, SClientHbReq *pReq)
|
|||
return terrno = code;
|
||||
}
|
||||
}
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
TAOS_CHECK_RETURN(tDecodeU32(pDecoder, &pReq->userIp));
|
||||
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pReq->userApp));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -516,6 +516,8 @@ static const SSysDbTableSchema connectionsSchema[] = {
|
|||
{.name = "end_point", .bytes = TSDB_EP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
||||
{.name = "login_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||
{.name = "last_access", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||
{.name = "user_app", .bytes = TSDB_APP_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY, .sysInfo = false},
|
||||
{.name = "user_ip", .bytes = TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema consumerSchema[] = {
|
||||
|
@ -557,6 +559,8 @@ static const SSysDbTableSchema querySchema[] = {
|
|||
{.name = "sub_num", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||
{.name = "sub_status", .bytes = TSDB_SHOW_SUBQUERY_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "sql", .bytes = TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "user_app", .bytes = TSDB_APP_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
{.name = "user_ip", .bytes = TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||
};
|
||||
|
||||
static const SSysDbTableSchema appSchema[] = {
|
||||
|
|
|
@ -2494,12 +2494,12 @@ static int32_t formatTimestamp(char* buf, size_t cap, int64_t val, int precision
|
|||
}
|
||||
}
|
||||
struct tm ptm = {0};
|
||||
if (taosLocalTime(&tt, &ptm, buf, cap) == NULL) {
|
||||
if (taosLocalTime(&tt, &ptm, buf, cap, NULL) == NULL) {
|
||||
code = TSDB_CODE_INTERNAL_ERROR;
|
||||
TSDB_CHECK_CODE(code, lino, _end);
|
||||
}
|
||||
|
||||
size_t pos = strftime(buf, cap, "%Y-%m-%d %H:%M:%S", &ptm);
|
||||
size_t pos = taosStrfTime(buf, cap, "%Y-%m-%d %H:%M:%S", &ptm);
|
||||
if (pos == 0) {
|
||||
code = TSDB_CODE_OUT_OF_BUFFER;
|
||||
TSDB_CHECK_CODE(code, lino, _end);
|
||||
|
@ -2641,7 +2641,7 @@ int32_t dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf
|
|||
char* pData = colDataGetVarData(pColInfoData, j);
|
||||
int32_t dataSize = TMIN(sizeof(pBuf), varDataLen(pData));
|
||||
memset(pBuf, 0, sizeof(pBuf));
|
||||
code = taosUcs4ToMbs((TdUcs4*)varDataVal(pData), dataSize, pBuf);
|
||||
code = taosUcs4ToMbs((TdUcs4*)varDataVal(pData), dataSize, pBuf, NULL);
|
||||
if (code < 0) {
|
||||
uError("func %s failed to convert to ucs charset since %s", __func__, tstrerror(code));
|
||||
lino = __LINE__;
|
||||
|
|
|
@ -335,6 +335,7 @@ bool tsExperimental = true;
|
|||
int32_t tsMaxTsmaNum = 3;
|
||||
int32_t tsMaxTsmaCalcDelay = 600;
|
||||
int64_t tsmaDataDeleteMark = 1000 * 60 * 60 * 24; // in ms, default to 1d
|
||||
void* pTimezoneNameMap = NULL;
|
||||
|
||||
#define TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, pName) \
|
||||
if ((pItem = cfgGetItem(pCfg, pName)) == NULL) { \
|
||||
|
@ -1418,34 +1419,6 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
static int32_t taosSetSystemCfg(SConfig *pCfg) {
|
||||
SConfigItem *pItem = NULL;
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "timezone");
|
||||
if (0 == strlen(pItem->str)) {
|
||||
uError("timezone is not set");
|
||||
} else {
|
||||
TAOS_CHECK_RETURN(osSetTimezone(pItem->str));
|
||||
uDebug("timezone format changed from %s to %s", pItem->str, tsTimezoneStr);
|
||||
}
|
||||
TAOS_CHECK_RETURN(cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype, true));
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "locale");
|
||||
const char *locale = pItem->str;
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "charset");
|
||||
const char *charset = pItem->str;
|
||||
|
||||
int32_t code = taosSetSystemLocale(locale, charset);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
uError("failed to set locale:%s, since: %s", locale, tstrerror(code));
|
||||
char curLocale[TD_LOCALE_LEN] = {0};
|
||||
char curCharset[TD_CHARSET_LEN] = {0};
|
||||
taosGetSystemLocale(curLocale, curCharset);
|
||||
if (0 != strlen(curLocale) && 0 != strlen(curCharset)) {
|
||||
uInfo("current locale: %s, charset: %s", curLocale, curCharset);
|
||||
}
|
||||
}
|
||||
|
||||
osSetSystemLocale(locale, charset);
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "enableCoreFile");
|
||||
tsEnableCoreFile = pItem->bval;
|
||||
taosSetCoreDump(tsEnableCoreFile);
|
||||
|
@ -2434,6 +2407,9 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t lino = 0;
|
||||
|
||||
if (strcasecmp("charset", name) == 0 || strcasecmp("timezone", name) == 0) {
|
||||
goto _out;
|
||||
}
|
||||
cfgLock(pCfg);
|
||||
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
|
@ -2525,18 +2501,15 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
|||
case 'l': {
|
||||
if (strcasecmp("locale", name) == 0) {
|
||||
SConfigItem *pLocaleItem = cfgGetItem(pCfg, "locale");
|
||||
SConfigItem *pCharsetItem = cfgGetItem(pCfg, "charset");
|
||||
if (pLocaleItem == NULL || pCharsetItem == NULL) {
|
||||
uError("failed to get locale or charset from cfg");
|
||||
if (pLocaleItem == NULL) {
|
||||
uError("failed to get locale from cfg");
|
||||
code = TSDB_CODE_CFG_NOT_FOUND;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
const char *locale = pLocaleItem->str;
|
||||
const char *charset = pCharsetItem->str;
|
||||
TAOS_CHECK_GOTO(taosSetSystemLocale(locale, charset), &lino, _out);
|
||||
osSetSystemLocale(locale, charset);
|
||||
uInfo("locale set to '%s', charset set to '%s'", locale, charset);
|
||||
TAOS_CHECK_GOTO(taosSetSystemLocale(locale), &lino, _out);
|
||||
uInfo("locale set to '%s'", locale);
|
||||
matched = true;
|
||||
}
|
||||
break;
|
||||
|
@ -2611,13 +2584,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
|||
break;
|
||||
}
|
||||
case 't': {
|
||||
if (strcasecmp("timezone", name) == 0) {
|
||||
TAOS_CHECK_GOTO(osSetTimezone(pItem->str), &lino, _out);
|
||||
uInfo("%s set from %s to %s", name, tsTimezoneStr, pItem->str);
|
||||
|
||||
TAOS_CHECK_GOTO(cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype, false), &lino, _out);
|
||||
matched = true;
|
||||
} else if (strcasecmp("tempDir", name) == 0) {
|
||||
if (strcasecmp("tempDir", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsTempDir, pItem->str);
|
||||
tstrncpy(tsTempDir, pItem->str, PATH_MAX);
|
||||
TAOS_CHECK_GOTO(taosExpandDir(tsTempDir, tsTempDir, PATH_MAX), &lino, _out);
|
||||
|
|
|
@ -299,6 +299,7 @@ int32_t dumpConfToDataBlock(SSDataBlock* pBlock, int32_t startCol) {
|
|||
|
||||
char value[TSDB_CONFIG_PATH_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
int32_t valueLen = 0;
|
||||
|
||||
SDiskCfg* pDiskCfg = NULL;
|
||||
if (strcasecmp(pItem->name, "dataDir") == 0 && exSize > 0) {
|
||||
char* buf = &value[VARSTR_HEADER_SIZE];
|
||||
|
|
|
@ -20,73 +20,6 @@
|
|||
|
||||
#define VALID_NAME_TYPE(x) ((x) == TSDB_DB_NAME_T || (x) == TSDB_TABLE_NAME_T)
|
||||
|
||||
#if 0
|
||||
int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t slidingTime, int64_t intervalTime, char timeUnit, int16_t precision) {
|
||||
if (slidingTime == 0) {
|
||||
return startTime;
|
||||
}
|
||||
int64_t start = startTime;
|
||||
if (timeUnit == 'n' || timeUnit == 'y') {
|
||||
start /= 1000;
|
||||
if (precision == TSDB_TIME_PRECISION_MICRO) {
|
||||
start /= 1000;
|
||||
}
|
||||
struct tm tm;
|
||||
time_t t = (time_t)start;
|
||||
taosLocalTime(&t, &tm, NULL, 0);
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_mday = 1;
|
||||
|
||||
if (timeUnit == 'y') {
|
||||
tm.tm_mon = 0;
|
||||
tm.tm_year = (int)(tm.tm_year / slidingTime * slidingTime);
|
||||
} else {
|
||||
int mon = tm.tm_year * 12 + tm.tm_mon;
|
||||
mon = (int)(mon / slidingTime * slidingTime);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
}
|
||||
|
||||
start = mktime(&tm) * 1000L;
|
||||
if (precision == TSDB_TIME_PRECISION_MICRO) {
|
||||
start *= 1000L;
|
||||
}
|
||||
} else {
|
||||
int64_t delta = startTime - intervalTime;
|
||||
int32_t factor = delta > 0? 1:-1;
|
||||
|
||||
start = (delta / slidingTime + factor) * slidingTime;
|
||||
|
||||
if (timeUnit == 'd' || timeUnit == 'w') {
|
||||
/*
|
||||
* here we revised the start time of day according to the local time zone,
|
||||
* but in case of DST, the start time of one day need to be dynamically decided.
|
||||
*/
|
||||
// todo refactor to extract function that is available for Linux/Windows/Mac platform
|
||||
#if defined(WINDOWS) && _MSC_VER >= 1900
|
||||
// see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
int64_t timezone = _timezone;
|
||||
int32_t daylight = _daylight;
|
||||
char** tzname = _tzname;
|
||||
#endif
|
||||
|
||||
int64_t t = (precision == TSDB_TIME_PRECISION_MILLI) ? MILLISECOND_PER_SECOND : MILLISECOND_PER_SECOND * 1000L;
|
||||
start += timezone * t;
|
||||
}
|
||||
|
||||
int64_t end = start + intervalTime - 1;
|
||||
if (end < startTime) {
|
||||
start += slidingTime;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void toName(int32_t acctId, const char* pDbName, const char* pTableName, SName* pName) {
|
||||
if (pName == NULL){
|
||||
return;
|
||||
|
|
|
@ -25,42 +25,26 @@
|
|||
|
||||
#include "tlog.h"
|
||||
|
||||
// ==== mktime() kernel code =================//
|
||||
static int64_t m_deltaUtc = 0;
|
||||
|
||||
void deltaToUtcInitOnce() {
|
||||
struct tm tm = {0};
|
||||
if (taosStrpTime("1970-01-01 00:00:00", (const char*)("%Y-%m-%d %H:%M:%S"), &tm) == NULL) {
|
||||
uError("failed to parse time string");
|
||||
}
|
||||
m_deltaUtc = (int64_t)taosMktime(&tm);
|
||||
// printf("====delta:%lld\n\n", seconds);
|
||||
}
|
||||
|
||||
static int32_t parseFraction(char* str, char** end, int32_t timePrec, int64_t* pFraction);
|
||||
static int32_t parseTimeWithTz(const char* timestr, int64_t* time, int32_t timePrec, char delim);
|
||||
static int32_t parseLocaltime(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim);
|
||||
static int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim);
|
||||
static int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim, timezone_t tz);
|
||||
static char* forwardToTimeStringEnd(char* str);
|
||||
static bool checkTzPresent(const char* str, int32_t len);
|
||||
static int32_t parseTimezone(char* str, int64_t* tzOffset);
|
||||
|
||||
static int32_t (*parseLocaltimeFp[])(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) = {
|
||||
parseLocaltime, parseLocaltimeDst};
|
||||
|
||||
int32_t taosParseTime(const char* timestr, int64_t* utime, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
int32_t taosParseTime(const char* timestr, int64_t* utime, int32_t len, int32_t timePrec, timezone_t tz) {
|
||||
/* parse datatime string in with tz */
|
||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||
if (checkTzPresent(timestr, len)) {
|
||||
return parseTimeWithTz(timestr, utime, timePrec, 'T');
|
||||
} else {
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 'T');
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 'T', tz);
|
||||
}
|
||||
} else {
|
||||
if (checkTzPresent(timestr, len)) {
|
||||
return parseTimeWithTz(timestr, utime, timePrec, 0);
|
||||
} else {
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 0);
|
||||
return parseLocaltimeDst((char*)timestr, len, utime, timePrec, 0, tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,8 +130,15 @@ int32_t parseFraction(char* str, char** end, int32_t timePrec, int64_t* pFractio
|
|||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
#define PARSE(str,len,result) \
|
||||
if (len != 2) {\
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);\
|
||||
}\
|
||||
result = strnatoi(str, len);
|
||||
|
||||
int32_t parseTimezone(char* str, int64_t* tzOffset) {
|
||||
int64_t hour = 0;
|
||||
int64_t minute = 0;
|
||||
|
||||
int32_t i = 0;
|
||||
if (str[i] != '+' && str[i] != '-') {
|
||||
|
@ -168,27 +159,29 @@ int32_t parseTimezone(char* str, int64_t* tzOffset) {
|
|||
|
||||
char* sep = strchr(&str[i], ':');
|
||||
if (sep != NULL) {
|
||||
int32_t len = (int32_t)(sep - &str[i]);
|
||||
int32_t hourSize = (int32_t)(sep - &str[i]);
|
||||
PARSE(&str[i], hourSize, hour);
|
||||
|
||||
hour = strnatoi(&str[i], len);
|
||||
i += len + 1;
|
||||
i += hourSize + 1;
|
||||
size_t minSize = strlen(&str[i]);
|
||||
PARSE(&str[i], minSize, minute);
|
||||
} else {
|
||||
hour = strnatoi(&str[i], 2);
|
||||
i += 2;
|
||||
size_t hourSize = strlen(&str[i]);
|
||||
if (hourSize > 2){
|
||||
hourSize = 2;
|
||||
}
|
||||
PARSE(&str[i], hourSize, hour)
|
||||
i += hourSize;
|
||||
size_t minSize = strlen(&str[i]);
|
||||
if (minSize > 0){
|
||||
PARSE(&str[i], minSize, minute);
|
||||
}
|
||||
}
|
||||
|
||||
if (hour > 12 || hour < 0) {
|
||||
if (hour > 13 || hour < 0) {
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
|
||||
}
|
||||
|
||||
// return error if there're illegal charaters after min(2 Digits)
|
||||
char* minStr = &str[i];
|
||||
if (minStr[1] != '\0' && minStr[2] != '\0') {
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
|
||||
}
|
||||
|
||||
int64_t minute = strnatoi(&str[i], 2);
|
||||
if (minute > 59 || (hour == 12 && minute > 0)) {
|
||||
if (minute > 59 || minute < 0) {
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
|
||||
}
|
||||
|
||||
|
@ -245,7 +238,10 @@ int32_t parseTimeWithTz(const char* timestr, int64_t* time, int32_t timePrec, ch
|
|||
int64_t seconds = user_mktime64(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
|
||||
// int64_t seconds = gmtime(&tm);
|
||||
#else
|
||||
int64_t seconds = timegm(&tm);
|
||||
int64_t seconds = taosTimeGm(&tm);
|
||||
if (seconds == -1){
|
||||
TAOS_RETURN(TAOS_SYSTEM_ERROR(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
int64_t fraction = 0;
|
||||
|
@ -310,48 +306,7 @@ static FORCE_INLINE bool validateTm(struct tm* pTm) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t parseLocaltime(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) {
|
||||
*utime = 0;
|
||||
struct tm tm = {0};
|
||||
|
||||
char* str;
|
||||
if (delim == 'T') {
|
||||
str = taosStrpTime(timestr, "%Y-%m-%dT%H:%M:%S", &tm);
|
||||
} else if (delim == 0) {
|
||||
str = taosStrpTime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
|
||||
} else {
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
if (str == NULL || (((str - timestr) < len) && (*str != '.')) || !validateTm(&tm)) {
|
||||
// if parse failed, try "%Y-%m-%d" format
|
||||
str = taosStrpTime(timestr, "%Y-%m-%d", &tm);
|
||||
if (str == NULL || (((str - timestr) < len) && (*str != '.')) || !validateTm(&tm)) {
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1900
|
||||
int64_t timezone = _timezone;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int64_t seconds =
|
||||
user_mktime64(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, timezone);
|
||||
|
||||
int64_t fraction = 0;
|
||||
|
||||
if (*str == '.') {
|
||||
/* parse the second fraction part */
|
||||
TAOS_CHECK_RETURN(parseFraction(str + 1, &str, timePrec, &fraction));
|
||||
}
|
||||
|
||||
*utime = TSDB_TICK_PER_SECOND(timePrec) * seconds + fraction;
|
||||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) {
|
||||
int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim, timezone_t tz) {
|
||||
*utime = 0;
|
||||
struct tm tm = {0};
|
||||
tm.tm_isdst = -1;
|
||||
|
@ -373,8 +328,7 @@ int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t ti
|
|||
}
|
||||
}
|
||||
|
||||
/* mktime will be affected by TZ, set by using taos_options */
|
||||
int64_t seconds = taosMktime(&tm);
|
||||
int64_t seconds = taosMktime(&tm, tz);
|
||||
|
||||
int64_t fraction = 0;
|
||||
if (*str == '.') {
|
||||
|
@ -535,7 +489,7 @@ int32_t convertTimeFromPrecisionToUnit(int64_t time, int32_t fromPrecision, char
|
|||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec, int64_t* timeVal) {
|
||||
int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec, int64_t* timeVal, timezone_t tz, void* charsetCxt) {
|
||||
int32_t charLen = varDataLen(inputData);
|
||||
char* newColData;
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_VARBINARY) {
|
||||
|
@ -544,7 +498,7 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
|
|||
TAOS_RETURN(terrno);
|
||||
}
|
||||
(void)memcpy(newColData, varDataVal(inputData), charLen);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, charLen, (int32_t)timePrec, tsDaylight);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, charLen, (int32_t)timePrec, tz);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(newColData);
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_TIMESTAMP);
|
||||
|
@ -555,13 +509,13 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
|
|||
if (NULL == newColData) {
|
||||
TAOS_RETURN(terrno);
|
||||
}
|
||||
int len = taosUcs4ToMbs((TdUcs4*)varDataVal(inputData), charLen, newColData);
|
||||
int len = taosUcs4ToMbs((TdUcs4*)varDataVal(inputData), charLen, newColData, charsetCxt);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newColData);
|
||||
TAOS_RETURN(TSDB_CODE_FAILED);
|
||||
}
|
||||
newColData[len] = 0;
|
||||
int32_t ret = taosParseTime(newColData, timeVal, len, (int32_t)timePrec, tsDaylight);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, len, (int32_t)timePrec, tz);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(newColData);
|
||||
TAOS_RETURN(ret);
|
||||
|
@ -678,7 +632,7 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati
|
|||
|
||||
static bool taosIsLeapYear(int32_t year) { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); }
|
||||
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision, timezone_t tz) {
|
||||
if (duration == 0) {
|
||||
return t;
|
||||
}
|
||||
|
@ -693,7 +647,10 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
|||
|
||||
struct tm tm;
|
||||
time_t tt = (time_t)(t / TSDB_TICK_PER_SECOND(precision));
|
||||
struct tm* ptm = taosLocalTime(&tt, &tm, NULL, 0);
|
||||
if(taosLocalTime(&tt, &tm, NULL, 0, tz) == NULL) {
|
||||
uError("failed to convert time to gm time, code:%d", errno);
|
||||
return t;
|
||||
}
|
||||
int32_t mon = tm.tm_year * 12 + tm.tm_mon + (int32_t)numOfMonth;
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
|
@ -704,7 +661,13 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
|||
if (tm.tm_mday > daysOfMonth[tm.tm_mon]) {
|
||||
tm.tm_mday = daysOfMonth[tm.tm_mon];
|
||||
}
|
||||
return (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision) + fraction);
|
||||
|
||||
tt = taosMktime(&tm, tz);
|
||||
if (tt == -1){
|
||||
uError("failed to convert gm time to time, code:%d", errno);
|
||||
return t;
|
||||
}
|
||||
return (int64_t)(tt * TSDB_TICK_PER_SECOND(precision) + fraction);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -743,7 +706,7 @@ int32_t taosTimeCountIntervalForFill(int64_t skey, int64_t ekey, int64_t interva
|
|||
ekey = skey;
|
||||
skey = tmp;
|
||||
}
|
||||
int32_t ret;
|
||||
int32_t ret = 0;
|
||||
|
||||
if (unit != 'n' && unit != 'y') {
|
||||
ret = (int32_t)((ekey - skey) / interval);
|
||||
|
@ -754,11 +717,17 @@ int32_t taosTimeCountIntervalForFill(int64_t skey, int64_t ekey, int64_t interva
|
|||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)skey;
|
||||
struct tm* ptm = taosLocalTime(&t, &tm, NULL, 0);
|
||||
if (taosLocalTime(&t, &tm, NULL, 0, NULL) == NULL) {
|
||||
uError("%s failed to convert time to local time, code:%d", __FUNCTION__, errno);
|
||||
return ret;
|
||||
}
|
||||
int32_t smon = tm.tm_year * 12 + tm.tm_mon;
|
||||
|
||||
t = (time_t)ekey;
|
||||
ptm = taosLocalTime(&t, &tm, NULL, 0);
|
||||
if (taosLocalTime(&t, &tm, NULL, 0, NULL) == NULL) {
|
||||
uError("%s failed to convert time to local time, code:%d", __FUNCTION__, errno);
|
||||
return ret;
|
||||
}
|
||||
int32_t emon = tm.tm_year * 12 + tm.tm_mon;
|
||||
|
||||
if (unit == 'y') {
|
||||
|
@ -782,7 +751,10 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
start /= (int64_t)(TSDB_TICK_PER_SECOND(precision));
|
||||
struct tm tm;
|
||||
time_t tt = (time_t)start;
|
||||
struct tm* ptm = taosLocalTime(&tt, &tm, NULL, 0);
|
||||
if (taosLocalTime(&tt, &tm, NULL, 0, pInterval->timezone) == NULL){
|
||||
uError("%s failed to convert time to local time, code:%d", __FUNCTION__, errno);
|
||||
return ts;
|
||||
}
|
||||
tm.tm_sec = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_hour = 0;
|
||||
|
@ -798,7 +770,12 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
tm.tm_mon = mon % 12;
|
||||
}
|
||||
|
||||
start = (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision));
|
||||
tt = taosMktime(&tm, pInterval->timezone);
|
||||
if (tt == -1){
|
||||
uError("%s failed to convert local time to time, code:%d", __FUNCTION__, errno);
|
||||
return ts;
|
||||
}
|
||||
start = (int64_t)(tt * TSDB_TICK_PER_SECOND(precision));
|
||||
} else {
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->intervalUnit)) {
|
||||
int64_t news = (ts / pInterval->sliding) * pInterval->sliding;
|
||||
|
@ -812,12 +789,12 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
start = news;
|
||||
if (news <= ts) {
|
||||
int64_t prev = news;
|
||||
int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
|
||||
if (newe < ts) { // move towards the greater endpoint
|
||||
while (newe < ts && news < ts) {
|
||||
news += pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
}
|
||||
|
||||
prev = news;
|
||||
|
@ -825,7 +802,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
while (newe >= ts) {
|
||||
prev = news;
|
||||
news -= pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,8 +824,6 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
// see
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
int64_t timezone = _timezone;
|
||||
int32_t daylight = _daylight;
|
||||
char** tzname = _tzname;
|
||||
#endif
|
||||
|
||||
start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision));
|
||||
|
@ -858,7 +833,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
|
||||
// not enough time range
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
while (end < ts) { // move forward to the correct time window
|
||||
start += pInterval->sliding;
|
||||
|
||||
|
@ -877,15 +852,15 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
|
||||
if (pInterval->offset > 0) {
|
||||
// try to move current window to the left-hande-side, due to the offset effect.
|
||||
int64_t newe = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
int64_t newe = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
int64_t slidingStart = start;
|
||||
while (newe >= ts) {
|
||||
start = slidingStart;
|
||||
slidingStart = taosTimeAdd(slidingStart, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
int64_t news = taosTimeAdd(slidingStart, pInterval->offset, pInterval->offsetUnit, precision);
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
slidingStart = taosTimeAdd(slidingStart, -pInterval->sliding, pInterval->slidingUnit, precision, pInterval->timezone);
|
||||
int64_t news = taosTimeAdd(slidingStart, pInterval->offset, pInterval->offsetUnit, precision, pInterval->timezone);
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision, pInterval->timezone) - 1;
|
||||
}
|
||||
start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision);
|
||||
start = taosTimeAdd(start, pInterval->offset, pInterval->offsetUnit, precision, pInterval->timezone);
|
||||
}
|
||||
|
||||
return start;
|
||||
|
@ -893,7 +868,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
|||
|
||||
// used together with taosTimeTruncate. when offset is great than zero, slide-start/slide-end is the anchor point
|
||||
int64_t taosTimeGetIntervalEnd(int64_t intervalStart, const SInterval* pInterval) {
|
||||
return taosTimeAdd(intervalStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return taosTimeAdd(intervalStart, pInterval->interval, pInterval->intervalUnit, pInterval->precision, pInterval->timezone) - 1;
|
||||
}
|
||||
|
||||
void calcIntervalAutoOffset(SInterval* interval) {
|
||||
|
@ -912,7 +887,7 @@ void calcIntervalAutoOffset(SInterval* interval) {
|
|||
TSKEY news = start;
|
||||
while (news <= skey) {
|
||||
start = news;
|
||||
news = taosTimeAdd(start, interval->sliding, interval->slidingUnit, interval->precision);
|
||||
news = taosTimeAdd(start, interval->sliding, interval->slidingUnit, interval->precision, interval->timezone);
|
||||
if (news < start) {
|
||||
// overflow happens
|
||||
uError("%s failed and skip, skey [%" PRId64 "], inter[%" PRId64 "(%c)], slid[%" PRId64 "(%c)], precision[%d]",
|
||||
|
@ -938,15 +913,15 @@ const char* fmtts(int64_t ts) {
|
|||
|
||||
if (ts > -62135625943 && ts < 32503651200) {
|
||||
time_t t = (time_t)ts;
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf)) == NULL) {
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf), NULL) == NULL) {
|
||||
return buf;
|
||||
}
|
||||
pos += strftime(buf + pos, sizeof(buf), "s=%Y-%m-%d %H:%M:%S", &tm);
|
||||
pos += taosStrfTime(buf + pos, sizeof(buf), "s=%Y-%m-%d %H:%M:%S", &tm);
|
||||
}
|
||||
|
||||
if (ts > -62135625943000 && ts < 32503651200000) {
|
||||
time_t t = (time_t)(ts / 1000);
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf)) == NULL) {
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf), NULL) == NULL) {
|
||||
return buf;
|
||||
}
|
||||
if (pos > 0) {
|
||||
|
@ -954,13 +929,13 @@ const char* fmtts(int64_t ts) {
|
|||
buf[pos++] = '|';
|
||||
buf[pos++] = ' ';
|
||||
}
|
||||
pos += strftime(buf + pos, sizeof(buf), "ms=%Y-%m-%d %H:%M:%S", &tm);
|
||||
pos += taosStrfTime(buf + pos, sizeof(buf), "ms=%Y-%m-%d %H:%M:%S", &tm);
|
||||
pos += sprintf(buf + pos, ".%03d", (int32_t)(ts % 1000));
|
||||
}
|
||||
|
||||
{
|
||||
time_t t = (time_t)(ts / 1000000);
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf)) == NULL) {
|
||||
if (taosLocalTime(&t, &tm, buf, sizeof(buf), NULL) == NULL) {
|
||||
return buf;
|
||||
}
|
||||
if (pos > 0) {
|
||||
|
@ -968,7 +943,7 @@ const char* fmtts(int64_t ts) {
|
|||
buf[pos++] = '|';
|
||||
buf[pos++] = ' ';
|
||||
}
|
||||
pos += strftime(buf + pos, sizeof(buf), "us=%Y-%m-%d %H:%M:%S", &tm);
|
||||
pos += taosStrfTime(buf + pos, sizeof(buf), "us=%Y-%m-%d %H:%M:%S", &tm);
|
||||
pos += sprintf(buf + pos, ".%06d", (int32_t)(ts % 1000000));
|
||||
}
|
||||
|
||||
|
@ -1014,28 +989,28 @@ int32_t taosFormatUtcTime(char* buf, int32_t bufLen, int64_t t, int32_t precisio
|
|||
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
|
||||
}
|
||||
|
||||
if (NULL == taosLocalTime(", &ptm, buf, bufLen)) {
|
||||
if (NULL == taosLocalTime(", &ptm, buf, bufLen, NULL)) {
|
||||
TAOS_RETURN(TAOS_SYSTEM_ERROR(errno));
|
||||
}
|
||||
int32_t length = (int32_t)strftime(ts, 40, "%Y-%m-%dT%H:%M:%S", &ptm);
|
||||
int32_t length = (int32_t)taosStrfTime(ts, 40, "%Y-%m-%dT%H:%M:%S", &ptm);
|
||||
length += tsnprintf(ts + length, fractionLen, format, mod);
|
||||
length += (int32_t)strftime(ts + length, 40 - length, "%z", &ptm);
|
||||
length += (int32_t)taosStrfTime(ts + length, 40 - length, "%z", &ptm);
|
||||
|
||||
tstrncpy(buf, ts, bufLen);
|
||||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
int32_t taosTs2Tm(int64_t ts, int32_t precision, struct STm* tm) {
|
||||
int32_t taosTs2Tm(int64_t ts, int32_t precision, struct STm* tm, timezone_t tz) {
|
||||
tm->fsec = ts % TICK_PER_SECOND[precision] * (TICK_PER_SECOND[TSDB_TIME_PRECISION_NANO] / TICK_PER_SECOND[precision]);
|
||||
time_t t = ts / TICK_PER_SECOND[precision];
|
||||
if (NULL == taosLocalTime(&t, &tm->tm, NULL, 0)) {
|
||||
if (NULL == taosLocalTime(&t, &tm->tm, NULL, 0, tz)) {
|
||||
TAOS_RETURN(TAOS_SYSTEM_ERROR(errno));
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t taosTm2Ts(struct STm* tm, int64_t* ts, int32_t precision) {
|
||||
*ts = taosMktime(&tm->tm);
|
||||
int32_t taosTm2Ts(struct STm* tm, int64_t* ts, int32_t precision, timezone_t tz) {
|
||||
*ts = taosMktime(&tm->tm, tz);
|
||||
*ts *= TICK_PER_SECOND[precision];
|
||||
*ts += tm->fsec / (TICK_PER_SECOND[TSDB_TIME_PRECISION_NANO] / TICK_PER_SECOND[precision]);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1502,10 +1477,17 @@ static int32_t tm2char(const SArray* formats, const struct STm* tm, char* s, int
|
|||
(void)sprintf(s, "%09" PRId64, tm->fsec);
|
||||
s += 9;
|
||||
break;
|
||||
case TSFKW_TZH:
|
||||
(void)sprintf(s, "%s%02d", tsTimezone < 0 ? "-" : "+", tsTimezone);
|
||||
case TSFKW_TZH:{
|
||||
#ifdef WINDOWS
|
||||
int32_t gmtoff = -_timezone;
|
||||
#else
|
||||
int32_t gmtoff = tm->tm.tm_gmtoff;
|
||||
#endif
|
||||
(void)sprintf(s, "%c%02d", (gmtoff >= 0) ? '+' : '-',
|
||||
abs(gmtoff) / 3600);
|
||||
s += strlen(s);
|
||||
break;
|
||||
}
|
||||
case TSFKW_YYYY:
|
||||
(void)sprintf(s, "%04d", tm->tm.tm_year + 1900);
|
||||
s += strlen(s);
|
||||
|
@ -1635,13 +1617,13 @@ static bool needMoreDigits(SArray* formats, int32_t curIdx) {
|
|||
/// @retval -2 if datetime err, like 2023-13-32 25:61:69
|
||||
/// @retval -3 if not supported
|
||||
static int32_t char2ts(const char* s, SArray* formats, int64_t* ts, int32_t precision, const char** sErrPos,
|
||||
int32_t* fErrIdx) {
|
||||
int32_t* fErrIdx, timezone_t tz) {
|
||||
int32_t size = taosArrayGetSize(formats);
|
||||
int32_t pm = 0; // default am
|
||||
int32_t hour12 = 0; // default HH24
|
||||
int32_t year = 0, mon = 0, yd = 0, md = 1, wd = 0;
|
||||
int32_t hour = 0, min = 0, sec = 0, us = 0, ms = 0, ns = 0;
|
||||
int32_t tzSign = 1, tz = tsTimezone;
|
||||
int32_t tzHour = 0;
|
||||
int32_t err = 0;
|
||||
bool withYD = false, withMD = false;
|
||||
|
||||
|
@ -1768,8 +1750,7 @@ static int32_t char2ts(const char* s, SArray* formats, int64_t* ts, int32_t prec
|
|||
}
|
||||
} break;
|
||||
case TSFKW_TZH: {
|
||||
tzSign = *s == '-' ? -1 : 1;
|
||||
const char* newPos = tsFormatStr2Int32(&tz, s, -1, needMoreDigits(formats, i));
|
||||
const char* newPos = tsFormatStr2Int32(&tzHour, s, -1, needMoreDigits(formats, i));
|
||||
if (NULL == newPos)
|
||||
err = -1;
|
||||
else {
|
||||
|
@ -1922,14 +1903,21 @@ static int32_t char2ts(const char* s, SArray* formats, int64_t* ts, int32_t prec
|
|||
tm.tm.tm_min = min;
|
||||
tm.tm.tm_sec = sec;
|
||||
if (!checkTm(&tm.tm)) return -2;
|
||||
if (tz < -12 || tz > 12) return -2;
|
||||
if (tzHour < -13 || tzHour > 13) return -2;
|
||||
tm.fsec = ms * 1000000 + us * 1000 + ns;
|
||||
int32_t ret = taosTm2Ts(&tm, ts, precision);
|
||||
*ts += 60 * 60 * (tsTimezone - tz) * TICK_PER_SECOND[precision];
|
||||
int32_t ret = taosTm2Ts(&tm, ts, precision, tz);
|
||||
if (tzHour != 0) {
|
||||
#ifdef WINDOWS
|
||||
int32_t gmtoff = -_timezone;
|
||||
#else
|
||||
int32_t gmtoff = tm.tm.tm_gmtoff;
|
||||
#endif
|
||||
*ts += (gmtoff - tzHour * 3600) * TICK_PER_SECOND[precision];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t precision, char* out, int32_t outLen) {
|
||||
int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t precision, char* out, int32_t outLen, timezone_t tz) {
|
||||
if (!*formats) {
|
||||
*formats = taosArrayInit(8, sizeof(TSFormatNode));
|
||||
if (!*formats) {
|
||||
|
@ -1938,12 +1926,12 @@ int32_t taosTs2Char(const char* format, SArray** formats, int64_t ts, int32_t pr
|
|||
TAOS_CHECK_RETURN(parseTsFormat(format, *formats));
|
||||
}
|
||||
struct STm tm;
|
||||
TAOS_CHECK_RETURN(taosTs2Tm(ts, precision, &tm));
|
||||
TAOS_CHECK_RETURN(taosTs2Tm(ts, precision, &tm, tz));
|
||||
return tm2char(*formats, &tm, out, outLen);
|
||||
}
|
||||
|
||||
int32_t taosChar2Ts(const char* format, SArray** formats, const char* tsStr, int64_t* ts, int32_t precision,
|
||||
char* errMsg, int32_t errMsgLen) {
|
||||
char* errMsg, int32_t errMsgLen, timezone_t tz) {
|
||||
const char* sErrPos;
|
||||
int32_t fErrIdx;
|
||||
if (!*formats) {
|
||||
|
@ -1953,7 +1941,7 @@ int32_t taosChar2Ts(const char* format, SArray** formats, const char* tsStr, int
|
|||
}
|
||||
TAOS_CHECK_RETURN(parseTsFormat(format, *formats));
|
||||
}
|
||||
int32_t code = char2ts(tsStr, *formats, ts, precision, &sErrPos, &fErrIdx);
|
||||
int32_t code = char2ts(tsStr, *formats, ts, precision, &sErrPos, &fErrIdx, tz);
|
||||
if (code == -1) {
|
||||
TSFormatNode* fNode = (taosArrayGet(*formats, fErrIdx));
|
||||
snprintf(errMsg, errMsgLen, "mismatch format for: %s and %s", sErrPos,
|
||||
|
@ -1978,7 +1966,7 @@ int32_t TEST_ts2char(const char* format, int64_t ts, int32_t precision, char* ou
|
|||
}
|
||||
TAOS_CHECK_RETURN(parseTsFormat(format, formats));
|
||||
struct STm tm;
|
||||
TAOS_CHECK_GOTO(taosTs2Tm(ts, precision, &tm), NULL, _exit);
|
||||
TAOS_CHECK_GOTO(taosTs2Tm(ts, precision, &tm, NULL), NULL, _exit);
|
||||
TAOS_CHECK_GOTO(tm2char(formats, &tm, out, outLen), NULL, _exit);
|
||||
|
||||
_exit:
|
||||
|
@ -1991,7 +1979,7 @@ int32_t TEST_char2ts(const char* format, int64_t* ts, int32_t precision, const c
|
|||
int32_t fErrIdx;
|
||||
SArray* formats = taosArrayInit(4, sizeof(TSFormatNode));
|
||||
TAOS_CHECK_RETURN(parseTsFormat(format, formats));
|
||||
int32_t code = char2ts(tsStr, formats, ts, precision, &sErrPos, &fErrIdx);
|
||||
int32_t code = char2ts(tsStr, formats, ts, precision, &sErrPos, &fErrIdx, NULL);
|
||||
if (code == -1) {
|
||||
(void)printf("failed position: %s\n", sErrPos);
|
||||
(void)printf("failed format: %s\n", ((TSFormatNode*)taosArrayGet(formats, fErrIdx))->key->name);
|
||||
|
@ -2107,3 +2095,30 @@ bool checkRecursiveTsmaInterval(int64_t baseInterval, int8_t baseUnit, int64_t i
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t taosGetTimestampToday(int32_t precision, timezone_t tz) {
|
||||
int64_t factor = (precision == TSDB_TIME_PRECISION_SECONDS) ? 1
|
||||
: (precision == TSDB_TIME_PRECISION_MILLI) ? 1000
|
||||
: (precision == TSDB_TIME_PRECISION_MICRO) ? 1000000
|
||||
: 1000000000;
|
||||
time_t t;
|
||||
int32_t code = taosTime(&t);
|
||||
if (code != 0) {
|
||||
return -1;
|
||||
}
|
||||
struct tm tm;
|
||||
if (taosLocalTime(&t, &tm, NULL, 0, tz) == NULL){
|
||||
uError("%s failed to get local time, code:%d", __FUNCTION__, errno);
|
||||
return t;
|
||||
}
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
|
||||
time_t tmp = taosMktime(&tm, tz);
|
||||
if (tmp == (time_t)-1) {
|
||||
uError("%s failed to get timestamp of today, code:%d", __FUNCTION__, errno);
|
||||
return t;
|
||||
}
|
||||
return (int64_t)tmp * factor;
|
||||
}
|
|
@ -429,9 +429,9 @@ void test_timestamp_tm_conversion(int64_t ts, int32_t precision, int32_t y, int3
|
|||
struct STm tm;
|
||||
taosFormatUtcTime(buf, 128, ts, precision);
|
||||
printf("formated ts of %ld, precision: %d is: %s\n", ts, precision, buf);
|
||||
taosTs2Tm(ts, precision, &tm);
|
||||
taosTs2Tm(ts, precision, &tm, NULL);
|
||||
check_tm(&tm, y, mon, d, h, m, s, fsec);
|
||||
taosTm2Ts(&tm, &ts_tmp, precision);
|
||||
taosTm2Ts(&tm, &ts_tmp, precision, NULL);
|
||||
ASSERT_EQ(ts, ts_tmp);
|
||||
}
|
||||
|
||||
|
@ -442,15 +442,15 @@ TEST(timeTest, timestamp2tm) {
|
|||
int64_t ts, tmp_ts = 0;
|
||||
struct STm tm;
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ns, &ts, strlen(ts_str_ns), TSDB_TIME_PRECISION_NANO, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ns, &ts, strlen(ts_str_ns), TSDB_TIME_PRECISION_NANO, NULL));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_NANO, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775726171L);
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_us, &ts, strlen(ts_str_us), TSDB_TIME_PRECISION_MICRO, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_us, &ts, strlen(ts_str_us), TSDB_TIME_PRECISION_MICRO, NULL));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MICRO, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775726000L);
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ms, &ts, strlen(ts_str_ms), TSDB_TIME_PRECISION_MILLI, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ms, &ts, strlen(ts_str_ms), TSDB_TIME_PRECISION_MILLI, NULL));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MILLI, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775000000L);
|
||||
|
||||
|
@ -477,7 +477,7 @@ void test_ts2char(int64_t ts, const char* format, int32_t precison, const char*
|
|||
|
||||
TEST(timeTest, ts2char) {
|
||||
osDefaultInit();
|
||||
if (tsTimezone != TdEastZone8) GTEST_SKIP();
|
||||
if (taosGetLocalTimezoneOffset() != TdEastZone8) GTEST_SKIP();
|
||||
int64_t ts;
|
||||
const char* format = "YYYY-MM-DD";
|
||||
ts = 0;
|
||||
|
@ -529,7 +529,7 @@ TEST(timeTest, ts2char) {
|
|||
|
||||
TEST(timeTest, char2ts) {
|
||||
osDefaultInit();
|
||||
if (tsTimezone != TdEastZone8) GTEST_SKIP();
|
||||
if (taosGetLocalTimezoneOffset() != TdEastZone8) GTEST_SKIP();
|
||||
int64_t ts;
|
||||
int32_t code =
|
||||
TEST_char2ts("YYYY-DD-MM HH12:MI:SS:MSPM", &ts, TSDB_TIME_PRECISION_MILLI, "2023-10-10 12:00:00.000AM");
|
||||
|
@ -630,7 +630,7 @@ TEST(timeTest, char2ts) {
|
|||
|
||||
// default to 1970-1-1 00:00:00+08 -> 1969-12-31 16:00:00+00
|
||||
ASSERT_EQ(0, TEST_char2ts("YYYY", &ts, TSDB_TIME_PRECISION_SECONDS, "1970"));
|
||||
ASSERT_EQ(ts, -1 * tsTimezone * 60 * 60);
|
||||
ASSERT_EQ(ts, -1 * taosGetLocalTimezoneOffset());
|
||||
|
||||
ASSERT_EQ(0, TEST_char2ts("yyyyMM1/dd ", &ts, TSDB_TIME_PRECISION_MICRO, "210001/2"));
|
||||
ASSERT_EQ(ts, 4102502400000000LL);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "version.h"
|
||||
#include "tconv.h"
|
||||
#ifdef TD_JEMALLOC_ENABLED
|
||||
#include "jemalloc/jemalloc.h"
|
||||
#endif
|
||||
|
@ -477,7 +478,7 @@ int mainWindows(int argc, char **argv) {
|
|||
return code;
|
||||
}
|
||||
|
||||
if ((code = taosConvInit()) != 0) {
|
||||
if ((tsCharsetCxt = taosConvInit(tsCharset)) == NULL) {
|
||||
dError("failed to init conv");
|
||||
taosCloseLog();
|
||||
taosCleanupArgs();
|
||||
|
|
|
@ -198,7 +198,7 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
|||
req.clusterCfg.monitorParas.tsSlowLogThreshold = tsSlowLogThreshold;
|
||||
tstrncpy(req.clusterCfg.monitorParas.tsSlowLogExceptDb, tsSlowLogExceptDb, TSDB_DB_NAME_LEN);
|
||||
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||
if (taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0) != 0) {
|
||||
if (taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, NULL) != 0) {
|
||||
dError("failed to parse time since %s", tstrerror(code));
|
||||
}
|
||||
memcpy(req.clusterCfg.timezone, tsTimezoneStr, TD_TIMEZONE_LEN);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "tglobal.h"
|
||||
#include "tgrant.h"
|
||||
#include "tstream.h"
|
||||
#include "tconv.h"
|
||||
|
||||
static bool dmRequireNode(SDnode *pDnode, SMgmtWrapper *pWrapper) {
|
||||
SMgmtInputOpt input = dmBuildMgmtInputOpt(pWrapper);
|
||||
|
|
|
@ -505,7 +505,7 @@ typedef struct {
|
|||
int64_t dstTbUid;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
int8_t timezone;
|
||||
int8_t timezone; // int8_t is not enough, timezone is unit of second
|
||||
int32_t dstVgId; // for stream
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
|
|
|
@ -714,7 +714,7 @@ SMnode *mndOpen(const char *path, const SMnodeOpt *pOption) {
|
|||
}
|
||||
|
||||
char timestr[24] = "1970-01-01 00:00:00.00";
|
||||
code = taosParseTime(timestr, &pMnode->checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
code = taosParseTime(timestr, &pMnode->checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, NULL);
|
||||
if (code < 0) {
|
||||
mError("failed to parse time since %s", tstrerror(code));
|
||||
(void)taosThreadRwlockDestroy(&pMnode->lock);
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef struct {
|
|||
int32_t numOfQueries;
|
||||
SRWLatch queryLock;
|
||||
SArray *pQueries; // SArray<SQueryDesc>
|
||||
char userApp[TSDB_APP_NAME_LEN];
|
||||
uint32_t userIp;
|
||||
} SConnObj;
|
||||
|
||||
typedef struct {
|
||||
|
@ -135,6 +137,13 @@ void mndCleanupProfile(SMnode *pMnode) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setUserInfo2Conn(SConnObj* connObj, char* userApp, uint32_t userIp){
|
||||
if (connObj == NULL){
|
||||
return;
|
||||
}
|
||||
tstrncpy(connObj->userApp, userApp, sizeof(connObj->userApp));
|
||||
connObj->userIp = userIp;
|
||||
}
|
||||
static SConnObj *mndCreateConn(SMnode *pMnode, const char *user, int8_t connType, uint32_t ip, uint16_t port,
|
||||
int32_t pid, const char *app, int64_t startTime) {
|
||||
SProfileMgmt *pMgmt = &pMnode->profileMgmt;
|
||||
|
@ -232,7 +241,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
SConnObj *pConn = NULL;
|
||||
int32_t code = 0;
|
||||
SConnectReq connReq = {0};
|
||||
char ip[24] = {0};
|
||||
char ip[TD_IP_LEN] = {0};
|
||||
const STraceId *trace = &pReq->info.traceId;
|
||||
|
||||
if ((code = tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq)) != 0) {
|
||||
|
@ -244,7 +253,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
taosIp2String(pReq->info.conn.clientIp, ip);
|
||||
taosInetNtoa(ip, pReq->info.conn.clientIp);
|
||||
if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT)) != 0) {
|
||||
mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, tstrerror(code));
|
||||
goto _OVER;
|
||||
|
@ -513,6 +522,7 @@ static int32_t mndProcessQueryHeartBeat(SMnode *pMnode, SRpcMsg *pMsg, SClientHb
|
|||
}
|
||||
}
|
||||
|
||||
setUserInfo2Conn(pConn, pHbReq->userApp, pHbReq->userIp);
|
||||
SQueryHbRspBasic *rspBasic = taosMemoryCalloc(1, sizeof(SQueryHbRspBasic));
|
||||
if (rspBasic == NULL) {
|
||||
mndReleaseConn(pMnode, pConn, true);
|
||||
|
@ -896,9 +906,10 @@ static int32_t mndRetrieveConns(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
return code;
|
||||
}
|
||||
|
||||
char endpoint[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&endpoint[VARSTR_HEADER_SIZE], "%s:%d", taosIpStr(pConn->ip), pConn->port);
|
||||
varDataLen(endpoint) = strlen(&endpoint[VARSTR_HEADER_SIZE]);
|
||||
char endpoint[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
taosInetNtoa(varDataVal(endpoint), pConn->ip);
|
||||
(void)sprintf(varDataVal(endpoint) + strlen(varDataVal(endpoint)), ":%d", pConn->port);
|
||||
varDataLen(endpoint) = strlen(varDataVal(endpoint));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)endpoint, false);
|
||||
if (code != 0) {
|
||||
|
@ -920,6 +931,27 @@ static int32_t mndRetrieveConns(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
return code;
|
||||
}
|
||||
|
||||
char userApp[TSDB_APP_NAME_LEN + VARSTR_HEADER_SIZE];
|
||||
STR_TO_VARSTR(userApp, pConn->userApp);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)userApp, false);
|
||||
if (code != 0) {
|
||||
mError("failed to set user app since %s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
char userIp[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
if (pConn->userIp != 0 && pConn->userIp != INADDR_NONE){
|
||||
taosInetNtoa(varDataVal(userIp), pConn->userIp);
|
||||
varDataLen(userIp) = strlen(varDataVal(userIp));
|
||||
}
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)userIp, false);
|
||||
if (code != 0) {
|
||||
mError("failed to set user ip since %s", tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
numOfRows++;
|
||||
}
|
||||
|
||||
|
@ -1006,8 +1038,9 @@ static int32_t packQueriesIntoBlock(SShowObj *pShow, SConnObj *pConn, SSDataBloc
|
|||
return code;
|
||||
}
|
||||
|
||||
char endpoint[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&endpoint[VARSTR_HEADER_SIZE], "%s:%d", taosIpStr(pConn->ip), pConn->port);
|
||||
char endpoint[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
taosInetNtoa(varDataVal(endpoint), pConn->ip);
|
||||
(void)sprintf(varDataVal(endpoint) + strlen(varDataVal(endpoint)), ":%d", pConn->port);
|
||||
varDataLen(endpoint) = strlen(&endpoint[VARSTR_HEADER_SIZE]);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, curRowIndex, (const char *)endpoint, false);
|
||||
|
@ -1091,6 +1124,29 @@ static int32_t packQueriesIntoBlock(SShowObj *pShow, SConnObj *pConn, SSDataBloc
|
|||
return code;
|
||||
}
|
||||
|
||||
char userApp[TSDB_APP_NAME_LEN + VARSTR_HEADER_SIZE];
|
||||
STR_TO_VARSTR(userApp, pConn->userApp);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, curRowIndex, (const char *)userApp, false);
|
||||
if (code != 0) {
|
||||
mError("failed to set user app since %s", tstrerror(code));
|
||||
taosRUnLockLatch(&pConn->queryLock);
|
||||
return code;
|
||||
}
|
||||
|
||||
char userIp[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
if (pConn->userIp != 0 && pConn->userIp != INADDR_NONE){
|
||||
taosInetNtoa(varDataVal(userIp), pConn->userIp);
|
||||
varDataLen(userIp) = strlen(varDataVal(userIp));
|
||||
}
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, curRowIndex, (const char *)userIp, false);
|
||||
if (code != 0) {
|
||||
mError("failed to set user ip since %s", tstrerror(code));
|
||||
taosRUnLockLatch(&pConn->queryLock);
|
||||
return code;
|
||||
}
|
||||
|
||||
pBlock->info.rows++;
|
||||
}
|
||||
|
||||
|
@ -1165,9 +1221,9 @@ static int32_t mndRetrieveApps(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
|
|||
return code;
|
||||
}
|
||||
|
||||
char ip[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&ip[VARSTR_HEADER_SIZE], "%s", taosIpStr(pApp->ip));
|
||||
varDataLen(ip) = strlen(&ip[VARSTR_HEADER_SIZE]);
|
||||
char ip[TD_IP_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
taosInetNtoa(varDataVal(ip), pApp->ip);
|
||||
varDataLen(ip) = strlen(varDataVal(ip));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)ip, false);
|
||||
if (code != 0) {
|
||||
|
|
|
@ -316,7 +316,7 @@ static void *mndBuildVCreateSmaReq(SMnode *pMnode, SVgObj *pVgroup, SSmaObj *pSm
|
|||
req.version = 0;
|
||||
req.intervalUnit = pSma->intervalUnit;
|
||||
req.slidingUnit = pSma->slidingUnit;
|
||||
req.timezoneInt = pSma->timezone;
|
||||
// req.timezoneInt = pSma->timezone;
|
||||
tstrncpy(req.indexName, (char *)tNameGetTableName(&name), TSDB_INDEX_NAME_LEN);
|
||||
req.exprLen = pSma->exprLen;
|
||||
req.tagsFilterLen = pSma->tagsFilterLen;
|
||||
|
@ -617,9 +617,9 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea
|
|||
smaObj.intervalUnit = pCreate->intervalUnit;
|
||||
smaObj.slidingUnit = pCreate->slidingUnit;
|
||||
#if 0
|
||||
smaObj.timezone = pCreate->timezone;
|
||||
// smaObj.timezone = pCreate->timezone;
|
||||
#endif
|
||||
smaObj.timezone = tsTimezone; // use timezone of server
|
||||
// smaObj.timezone = taosGetLocalTimezoneOffset(); // use timezone of server
|
||||
smaObj.interval = pCreate->interval;
|
||||
smaObj.offset = pCreate->offset;
|
||||
smaObj.sliding = pCreate->sliding;
|
||||
|
@ -797,7 +797,7 @@ static int32_t mndGetStreamNameFromSmaName(char *streamName, char *smaName) {
|
|||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
sprintf(streamName, "%d.%s", n.acctId, n.tname);
|
||||
snprintf(streamName, TSDB_TABLE_FNAME_LEN,"%d.%s", n.acctId, n.tname);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1222,7 @@ static int32_t mndGetSma(SMnode *pMnode, SUserIndexReq *indexReq, SUserIndexRsp
|
|||
|
||||
memcpy(rsp->dbFName, pSma->db, sizeof(pSma->db));
|
||||
memcpy(rsp->tblFName, pSma->stb, sizeof(pSma->stb));
|
||||
strcpy(rsp->indexType, TSDB_INDEX_TYPE_SMA);
|
||||
tstrncpy(rsp->indexType, TSDB_INDEX_TYPE_SMA, TSDB_INDEX_TYPE_LEN);
|
||||
|
||||
SNodeList *pList = NULL;
|
||||
int32_t extOffset = 0;
|
||||
|
@ -1255,8 +1255,8 @@ int32_t mndGetTableSma(SMnode *pMnode, char *tbFName, STableIndexRsp *rsp, bool
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
strcpy(rsp->dbFName, pStb->db);
|
||||
strcpy(rsp->tbName, pStb->name + strlen(pStb->db) + 1);
|
||||
tstrncpy(rsp->dbFName, pStb->db, TSDB_DB_FNAME_LEN);
|
||||
tstrncpy(rsp->tbName, pStb->name + strlen(pStb->db) + 1, TSDB_TABLE_NAME_LEN);
|
||||
rsp->suid = pStb->uid;
|
||||
rsp->version = pStb->smaVer;
|
||||
mndReleaseStb(pMnode, pStb);
|
||||
|
@ -1554,7 +1554,7 @@ static void initSMAObj(SCreateTSMACxt* pCxt) {
|
|||
pCxt->pSma->dbUid = pCxt->pDb->uid;
|
||||
pCxt->pSma->interval = pCxt->pCreateSmaReq->interval;
|
||||
pCxt->pSma->intervalUnit = pCxt->pCreateSmaReq->intervalUnit;
|
||||
pCxt->pSma->timezone = tsTimezone;
|
||||
// pCxt->pSma->timezone = taosGetLocalTimezoneOffset();
|
||||
pCxt->pSma->version = 1;
|
||||
|
||||
pCxt->pSma->exprLen = pCxt->pCreateSmaReq->exprLen;
|
||||
|
@ -1632,7 +1632,7 @@ static int32_t mndCreateTSMABuildCreateStreamReq(SCreateTSMACxt *pCxt) {
|
|||
f.bytes = pExprNode->resType.bytes;
|
||||
f.type = pExprNode->resType.type;
|
||||
f.flags = COL_SMA_ON;
|
||||
strcpy(f.name, pExprNode->userAlias);
|
||||
tstrncpy(f.name, pExprNode->userAlias, TSDB_COL_NAME_LEN);
|
||||
if (NULL == taosArrayPush(pCxt->pCreateStreamReq->pCols, &f)) {
|
||||
code = terrno;
|
||||
break;
|
||||
|
@ -1735,7 +1735,7 @@ static int32_t mndCreateTSMATxnPrepare(SCreateTSMACxt* pCxt) {
|
|||
}
|
||||
|
||||
dropStbReq.igNotExists = true;
|
||||
strncpy(dropStbReq.name, pCxt->targetStbFullName, TSDB_TABLE_FNAME_LEN);
|
||||
tstrncpy(dropStbReq.name, pCxt->targetStbFullName, TSDB_TABLE_FNAME_LEN);
|
||||
dropStbUndoAction.epSet = createStreamRedoAction.epSet;
|
||||
dropStbUndoAction.acceptableCode = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
dropStbUndoAction.retryCode = TSDB_CODE_MND_STREAM_MUST_BE_DELETED;
|
||||
|
@ -1836,7 +1836,7 @@ static int32_t mndTSMAGenerateOutputName(const char* tsmaName, char* streamName,
|
|||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
sprintf(streamName, "%d.%s", smaName.acctId, smaName.tname);
|
||||
snprintf(streamName, TSDB_TABLE_FNAME_LEN, "%d.%s", smaName.acctId, smaName.tname);
|
||||
snprintf(targetStbName, TSDB_TABLE_FNAME_LEN, "%s"TSMA_RES_STB_POSTFIX, tsmaName);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -2486,7 +2486,7 @@ static int32_t mndGetSomeTsmas(SMnode* pMnode, STableTSMAInfoRsp* pRsp, tsmaFilt
|
|||
mndReleaseStb(pMnode, pStb);
|
||||
TAOS_RETURN(code);
|
||||
}
|
||||
sprintf(streamName, "%d.%s", smaName.acctId, smaName.tname);
|
||||
snprintf(streamName, TSDB_TABLE_FNAME_LEN, "%d.%s", smaName.acctId, smaName.tname);
|
||||
pStream = NULL;
|
||||
|
||||
code = mndAcquireStream(pMnode, streamName, &pStream);
|
||||
|
|
|
@ -1931,11 +1931,6 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
return terrno = code;
|
||||
}
|
||||
|
||||
code = mndStreamRegisterTrans(pTrans, MND_STREAM_TASK_UPDATE_NAME, pStream->uid);
|
||||
if (code) {
|
||||
mError("failed to register trans, transId:%d, and continue", pTrans->id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!includeAllNodes) {
|
||||
|
@ -1951,6 +1946,12 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
mDebug("stream:0x%" PRIx64 " %s involved node changed, create update trans, transId:%d", pStream->uid,
|
||||
pStream->name, pTrans->id);
|
||||
|
||||
// NOTE: for each stream, we register one trans entry for task update
|
||||
code = mndStreamRegisterTrans(pTrans, MND_STREAM_TASK_UPDATE_NAME, pStream->uid);
|
||||
if (code) {
|
||||
mError("failed to register trans, transId:%d, and continue", pTrans->id);
|
||||
}
|
||||
|
||||
code = mndStreamSetUpdateEpsetAction(pMnode, pStream, pChangeInfo, pTrans);
|
||||
|
||||
// todo: not continue, drop all and retry again
|
||||
|
|
|
@ -35,7 +35,11 @@ int32_t mndStreamClearFinishedTrans(SMnode *pMnode, int32_t *pNumOfActiveChkpt)
|
|||
size_t keyLen = 0;
|
||||
void *pIter = NULL;
|
||||
SArray *pList = taosArrayInit(4, sizeof(SKeyInfo));
|
||||
int32_t num = 0;
|
||||
int32_t numOfChkpt = 0;
|
||||
|
||||
if (pNumOfActiveChkpt != NULL) {
|
||||
*pNumOfActiveChkpt = 0;
|
||||
}
|
||||
|
||||
if (pList == NULL) {
|
||||
return terrno;
|
||||
|
@ -50,15 +54,15 @@ int32_t mndStreamClearFinishedTrans(SMnode *pMnode, int32_t *pNumOfActiveChkpt)
|
|||
void *pKey = taosHashGetKey(pEntry, &keyLen);
|
||||
// key is the name of src/dst db name
|
||||
SKeyInfo info = {.pKey = pKey, .keyLen = keyLen};
|
||||
mDebug("transId:%d %s startTs:%" PRId64 " cleared since finished", pEntry->transId, pEntry->name,
|
||||
pEntry->startTime);
|
||||
mDebug("transId:%d stream:0x%" PRIx64 " %s startTs:%" PRId64 " cleared since finished", pEntry->transId,
|
||||
pEntry->streamId, pEntry->name, pEntry->startTime);
|
||||
void* p = taosArrayPush(pList, &info);
|
||||
if (p == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(pEntry->name, MND_STREAM_CHECKPOINT_NAME) == 0) {
|
||||
num++;
|
||||
numOfChkpt++;
|
||||
}
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
}
|
||||
|
@ -78,48 +82,34 @@ int32_t mndStreamClearFinishedTrans(SMnode *pMnode, int32_t *pNumOfActiveChkpt)
|
|||
}
|
||||
}
|
||||
|
||||
mDebug("clear %d finished stream-trans, remained:%d, active checkpoint trans:%d", size,
|
||||
taosHashGetSize(execInfo.transMgmt.pDBTrans), num);
|
||||
mDebug("clear %d finished stream-trans, active trans:%d, active checkpoint trans:%d", size,
|
||||
taosHashGetSize(execInfo.transMgmt.pDBTrans), numOfChkpt);
|
||||
|
||||
taosArrayDestroy(pList);
|
||||
|
||||
if (pNumOfActiveChkpt != NULL) {
|
||||
*pNumOfActiveChkpt = num;
|
||||
*pNumOfActiveChkpt = numOfChkpt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// * Transactions of different streams are not related. Here only check the conflict of transaction for a given stream.
|
||||
// For a given stream:
|
||||
// 1. checkpoint trans is conflict with any other trans except for the drop and reset trans.
|
||||
// 2. create/drop/reset/update trans are conflict with any other trans.
|
||||
int32_t mndStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, const char *pTransName, bool lock) {
|
||||
if (lock) {
|
||||
streamMutexLock(&execInfo.lock);
|
||||
}
|
||||
|
||||
static int32_t doStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, const char *pTransName) {
|
||||
int32_t num = taosHashGetSize(execInfo.transMgmt.pDBTrans);
|
||||
if (num <= 0) {
|
||||
if (lock) {
|
||||
streamMutexUnlock(&execInfo.lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if any task updates exist, any other stream trans are not allowed to be created
|
||||
int32_t code = mndStreamClearFinishedTrans(pMnode, NULL);
|
||||
if (code) {
|
||||
mError("failed to clear finish trans, code:%s", tstrerror(code));
|
||||
mError("failed to clear finish trans, code:%s, and continue", tstrerror(code));
|
||||
}
|
||||
|
||||
SStreamTransInfo *pEntry = taosHashGet(execInfo.transMgmt.pDBTrans, &streamId, sizeof(streamId));
|
||||
if (pEntry != NULL) {
|
||||
SStreamTransInfo tInfo = *pEntry;
|
||||
|
||||
if (lock) {
|
||||
streamMutexUnlock(&execInfo.lock);
|
||||
}
|
||||
|
||||
if (strcmp(tInfo.name, MND_STREAM_CHECKPOINT_NAME) == 0) {
|
||||
if ((strcmp(pTransName, MND_STREAM_DROP_NAME) != 0) && (strcmp(pTransName, MND_STREAM_TASK_RESET_NAME) != 0) &&
|
||||
(strcmp(pTransName, MND_STREAM_RESTART_NAME) != 0)) {
|
||||
|
@ -141,11 +131,25 @@ int32_t mndStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, const char
|
|||
mDebug("stream:0x%" PRIx64 " no conflict trans existed, continue create trans", streamId);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// * Transactions of different streams are not related. Here only check the conflict of transaction for a given stream.
|
||||
// For a given stream:
|
||||
// 1. checkpoint trans is conflict with any other trans except for the drop and reset trans.
|
||||
// 2. create/drop/reset/update trans are conflict with any other trans.
|
||||
int32_t mndStreamTransConflictCheck(SMnode *pMnode, int64_t streamId, const char *pTransName, bool lock) {
|
||||
if (lock) {
|
||||
streamMutexLock(&execInfo.lock);
|
||||
}
|
||||
|
||||
int32_t code = doStreamTransConflictCheck(pMnode, streamId, pTransName);
|
||||
|
||||
if (lock) {
|
||||
streamMutexUnlock(&execInfo.lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndStreamGetRelTrans(SMnode *pMnode, int64_t streamId) {
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndTrans.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndSubscribe.h"
|
||||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
|
||||
#define TRANS_VER1_NUMBER 1
|
||||
|
@ -52,10 +52,17 @@ static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool t
|
|||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
|
||||
static bool mndCannotExecuteTransAction(SMnode *pMnode, bool topHalf) {
|
||||
return (!pMnode->deploy && !mndIsLeader(pMnode)) || !topHalf;
|
||||
static inline bool mndTransIsInSyncContext(bool topHalf) { return !topHalf; }
|
||||
|
||||
static bool mndCannotExecuteTrans(SMnode *pMnode, bool topHalf) {
|
||||
bool isLeader = mndIsLeader(pMnode);
|
||||
bool ret = (!pMnode->deploy && !isLeader) || mndTransIsInSyncContext(topHalf);
|
||||
if (ret) mDebug("cannot execute trans action, deploy:%d, isLeader:%d, topHalf:%d", pMnode->deploy, isLeader, topHalf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *mndStrExecutionContext(bool topHalf) { return topHalf ? "transContext" : "syncContext"; }
|
||||
|
||||
static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndProcessTransTimer(SRpcMsg *pReq);
|
||||
static int32_t mndProcessTtl(SRpcMsg *pReq);
|
||||
|
@ -216,7 +223,7 @@ SSdbRaw *mndTransEncode(STrans *pTrans) {
|
|||
SDB_SET_RESERVE(pRaw, dataPos, TRANS_RESERVE_SIZE, _OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
||||
|
||||
terrno = 0;
|
||||
terrno = 0;
|
||||
|
||||
_OVER:
|
||||
if (terrno != 0) {
|
||||
|
@ -287,8 +294,8 @@ _OVER:
|
|||
|
||||
SSdbRow *mndTransDecode(SSdbRaw *pRaw) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
SSdbRow *pRow = NULL;
|
||||
STrans *pTrans = NULL;
|
||||
char *pData = NULL;
|
||||
|
@ -890,7 +897,7 @@ static bool mndCheckTransConflict(SMnode *pMnode, STrans *pNew) {
|
|||
if (pNew->conflict == TRN_CONFLICT_ARBGROUP) {
|
||||
if (pTrans->conflict == TRN_CONFLICT_GLOBAL) conflict = true;
|
||||
if (pTrans->conflict == TRN_CONFLICT_ARBGROUP) {
|
||||
void* pGidIter = taosHashIterate(pNew->arbGroupIds, NULL);
|
||||
void *pGidIter = taosHashIterate(pNew->arbGroupIds, NULL);
|
||||
while (pGidIter != NULL) {
|
||||
int32_t groupId = *(int32_t *)pGidIter;
|
||||
if (taosHashGet(pTrans->arbGroupIds, &groupId, sizeof(int32_t)) != NULL) {
|
||||
|
@ -1033,7 +1040,7 @@ static int32_t mndTransCheckCommitActions(SMnode *pMnode, STrans *pTrans) {
|
|||
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
||||
int32_t code = 0;
|
||||
if (pTrans == NULL) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
TAOS_CHECK_RETURN(mndTransCheckConflict(pMnode, pTrans));
|
||||
|
@ -1305,6 +1312,14 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
|
|||
TAOS_RETURN(TSDB_CODE_MND_TRANS_CTX_SWITCH);
|
||||
}
|
||||
|
||||
if (pAction->pRaw->type >= SDB_MAX) {
|
||||
pAction->rawWritten = true;
|
||||
pAction->errCode = 0;
|
||||
mndSetTransLastAction(pTrans, pAction);
|
||||
mInfo("skip sdb raw type:%d since it is not supported", pAction->pRaw->type);
|
||||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pAction->pRaw);
|
||||
if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||
pAction->rawWritten = true;
|
||||
|
@ -1327,7 +1342,7 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
|
|||
// execute in trans context
|
||||
static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||
if (pAction->msgSent) return 0;
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) {
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) {
|
||||
TAOS_RETURN(TSDB_CODE_MND_TRANS_CTX_SWITCH);
|
||||
}
|
||||
|
||||
|
@ -1348,10 +1363,10 @@ static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransActio
|
|||
|
||||
char detail[1024] = {0};
|
||||
int32_t len = tsnprintf(detail, sizeof(detail), "msgType:%s numOfEps:%d inUse:%d", TMSG_INFO(pAction->msgType),
|
||||
pAction->epSet.numOfEps, pAction->epSet.inUse);
|
||||
pAction->epSet.numOfEps, pAction->epSet.inUse);
|
||||
for (int32_t i = 0; i < pAction->epSet.numOfEps; ++i) {
|
||||
len += tsnprintf(detail + len, sizeof(detail) - len, " ep:%d-%s:%u", i, pAction->epSet.eps[i].fqdn,
|
||||
pAction->epSet.eps[i].port);
|
||||
pAction->epSet.eps[i].port);
|
||||
}
|
||||
|
||||
int32_t code = tmsgSendReq(&pAction->epSet, &rpcMsg);
|
||||
|
@ -1454,9 +1469,9 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
|
|||
|
||||
for (int32_t action = 0; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pArray, action);
|
||||
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x",
|
||||
pTrans->id, mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived,
|
||||
pAction->errCode, pAction->acceptableCode, pAction->retryCode);
|
||||
mDebug("trans:%d, %s:%d Sent:%d, Received:%d, errCode:0x%x, acceptableCode:0x%x, retryCode:0x%x", pTrans->id,
|
||||
mndTransStr(pAction->stage), pAction->id, pAction->msgSent, pAction->msgReceived, pAction->errCode,
|
||||
pAction->acceptableCode, pAction->retryCode);
|
||||
if (pAction->msgSent) {
|
||||
if (pAction->msgReceived) {
|
||||
if (pAction->errCode != 0 && pAction->errCode != pAction->acceptableCode) {
|
||||
|
@ -1473,8 +1488,8 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
|
|||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->redoActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS && code != TSDB_CODE_MND_TRANS_CTX_SWITCH) {
|
||||
mError("trans:%d, failed to execute redoActions since:%s, code:0x%x, topHalf(TransContext):%d", pTrans->id,
|
||||
terrstr(), terrno, topHalf);
|
||||
mError("trans:%d, failed to execute redoActions since:%s, code:0x%x, in %s", pTrans->id, terrstr(), terrno,
|
||||
mndStrExecutionContext(topHalf));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1482,8 +1497,8 @@ static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans, bool t
|
|||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->undoActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS && code != TSDB_CODE_MND_TRANS_CTX_SWITCH) {
|
||||
mError("trans:%d, failed to execute undoActions since %s. topHalf(TransContext):%d", pTrans->id, terrstr(),
|
||||
topHalf);
|
||||
mError("trans:%d, failed to execute undoActions since %s. in %s", pTrans->id, terrstr(),
|
||||
mndStrExecutionContext(topHalf));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1491,8 +1506,8 @@ static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans, bool t
|
|||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->commitActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS && code != TSDB_CODE_MND_TRANS_CTX_SWITCH) {
|
||||
mError("trans:%d, failed to execute commitActions since %s. topHalf(TransContext):%d", pTrans->id, terrstr(),
|
||||
topHalf);
|
||||
mError("trans:%d, failed to execute commitActions since %s. in %s", pTrans->id, terrstr(),
|
||||
mndStrExecutionContext(topHalf));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1512,7 +1527,7 @@ static int32_t mndTransExecuteActionsSerial(SMnode *pMnode, STrans *pTrans, SArr
|
|||
for (int32_t action = pTrans->actionPos; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pActions, action);
|
||||
|
||||
mInfo("trans:%d, current action:%d, stage:%s, actionType(0:log,1:msg):%d", pTrans->id, pTrans->actionPos,
|
||||
mInfo("trans:%d, current action:%d, stage:%s, actionType(1:msg,2:log):%d", pTrans->id, pTrans->actionPos,
|
||||
mndTransStr(pAction->stage), pAction->actionType);
|
||||
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction, topHalf);
|
||||
|
@ -1543,11 +1558,11 @@ static int32_t mndTransExecuteActionsSerial(SMnode *pMnode, STrans *pTrans, SArr
|
|||
}
|
||||
mndSetTransLastAction(pTrans, pAction);
|
||||
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) {
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) {
|
||||
pTrans->lastErrorNo = code;
|
||||
pTrans->code = code;
|
||||
mInfo("trans:%d, %s:%d, topHalf(TransContext):%d, not execute next action, code:%s", pTrans->id,
|
||||
mndTransStr(pAction->stage), action, topHalf, tstrerror(code));
|
||||
mInfo("trans:%d, %s:%d, cannot execute next action in %s, code:%s", pTrans->id, mndTransStr(pAction->stage),
|
||||
action, mndStrExecutionContext(topHalf), tstrerror(code));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1648,20 +1663,21 @@ static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
|||
code = mndTransExecuteRedoActions(pMnode, pTrans, topHalf);
|
||||
}
|
||||
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) {
|
||||
if (code != 0 && code != TSDB_CODE_MND_TRANS_CTX_SWITCH && mndTransIsInSyncContext(topHalf)) {
|
||||
pTrans->lastErrorNo = code;
|
||||
pTrans->code = code;
|
||||
bool continueExec = true;
|
||||
if (code != 0 && code != TSDB_CODE_MND_TRANS_CTX_SWITCH) {
|
||||
taosMsleep(100);
|
||||
continueExec = true;
|
||||
} else {
|
||||
continueExec = false;
|
||||
mInfo(
|
||||
"trans:%d, failed to execute, will retry redo action stage in 100 ms , in %s, "
|
||||
"continueExec:%d, code:%s",
|
||||
pTrans->id, mndStrExecutionContext(topHalf), continueExec, tstrerror(code));
|
||||
taosMsleep(100);
|
||||
return true;
|
||||
} else {
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) {
|
||||
mInfo("trans:%d, cannot continue to execute redo action stage in %s, continueExec:%d, code:%s", pTrans->id,
|
||||
mndStrExecutionContext(topHalf), continueExec, tstrerror(code));
|
||||
return false;
|
||||
}
|
||||
mInfo("trans:%d, cannot execute redo action stage, topHalf(TransContext):%d, continueExec:%d, code:%s", pTrans->id,
|
||||
topHalf, continueExec, tstrerror(code));
|
||||
|
||||
return continueExec;
|
||||
}
|
||||
terrno = code;
|
||||
|
||||
|
@ -1704,9 +1720,9 @@ static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
// in trans context
|
||||
// execute in trans context
|
||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransCommit(pMnode, pTrans);
|
||||
|
@ -1760,7 +1776,7 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
|||
code = mndTransExecuteUndoActions(pMnode, pTrans, topHalf);
|
||||
}
|
||||
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) return false;
|
||||
terrno = code;
|
||||
|
||||
if (code == 0) {
|
||||
|
@ -1781,7 +1797,7 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
|||
|
||||
// in trans context
|
||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransRollback(pMnode, pTrans);
|
||||
|
@ -1798,8 +1814,9 @@ static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool to
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
// excute in trans context
|
||||
static bool mndTransPerformPreFinishStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
if (mndCannotExecuteTrans(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransPreFinish(pMnode, pTrans);
|
||||
|
@ -1842,8 +1859,8 @@ void mndTransExecuteImp(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
|||
bool continueExec = true;
|
||||
|
||||
while (continueExec) {
|
||||
mInfo("trans:%d, continue to execute, stage:%s createTime:%" PRId64 " topHalf(TransContext):%d", pTrans->id,
|
||||
mndTransStr(pTrans->stage), pTrans->createdTime, topHalf);
|
||||
mInfo("trans:%d, continue to execute stage:%s in %s, createTime:%" PRId64 "", pTrans->id,
|
||||
mndTransStr(pTrans->stage), mndStrExecutionContext(topHalf), pTrans->createdTime);
|
||||
pTrans->lastExecTime = taosGetTimestampMs();
|
||||
switch (pTrans->stage) {
|
||||
case TRN_STAGE_PREPARE:
|
||||
|
@ -2038,11 +2055,11 @@ static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
char lastInfo[TSDB_TRANS_ERROR_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char detail[TSDB_TRANS_ERROR_LEN + 1] = {0};
|
||||
int32_t len = tsnprintf(detail, sizeof(detail), "action:%d code:0x%x(%s) ", pTrans->lastAction,
|
||||
pTrans->lastErrorNo & 0xFFFF, tstrerror(pTrans->lastErrorNo));
|
||||
pTrans->lastErrorNo & 0xFFFF, tstrerror(pTrans->lastErrorNo));
|
||||
SEpSet epset = pTrans->lastEpset;
|
||||
if (epset.numOfEps > 0) {
|
||||
len += tsnprintf(detail + len, sizeof(detail) - len, "msgType:%s numOfEps:%d inUse:%d ",
|
||||
TMSG_INFO(pTrans->lastMsgType), epset.numOfEps, epset.inUse);
|
||||
TMSG_INFO(pTrans->lastMsgType), epset.numOfEps, epset.inUse);
|
||||
for (int32_t i = 0; i < pTrans->lastEpset.numOfEps; ++i) {
|
||||
len += tsnprintf(detail + len, sizeof(detail) - len, "ep:%d-%s:%u ", i, epset.eps[i].fqdn, epset.eps[i].port);
|
||||
}
|
||||
|
|
|
@ -1195,10 +1195,15 @@ int64_t mndGetVgroupMemory(SMnode *pMnode, SDbObj *pDbInput, SVgObj *pVgroup) {
|
|||
|
||||
int64_t vgroupMemroy = 0;
|
||||
if (pDb != NULL) {
|
||||
vgroupMemroy = (int64_t)pDb->cfg.buffer * 1024 * 1024 + (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024;
|
||||
int64_t buffer = (int64_t)pDb->cfg.buffer * 1024 * 1024;
|
||||
int64_t cache = (int64_t)pDb->cfg.pages * pDb->cfg.pageSize * 1024;
|
||||
vgroupMemroy = buffer + cache;
|
||||
int64_t cacheLast = (int64_t)pDb->cfg.cacheLastSize * 1024 * 1024;
|
||||
if (pDb->cfg.cacheLast > 0) {
|
||||
vgroupMemroy += (int64_t)pDb->cfg.cacheLastSize * 1024 * 1024;
|
||||
vgroupMemroy += cacheLast;
|
||||
}
|
||||
mDebug("db:%s, vgroup:%d, buffer:%" PRId64 " cache:%" PRId64 " cacheLast:%" PRId64, pDb->name, pVgroup->vgId,
|
||||
buffer, cache, cacheLast);
|
||||
}
|
||||
|
||||
if (pDbInput == NULL) {
|
||||
|
@ -2712,20 +2717,29 @@ static int32_t mndCheckDnodeMemory(SMnode *pMnode, SDbObj *pOldDb, SDbObj *pNewD
|
|||
for (int32_t i = 0; i < (int32_t)taosArrayGetSize(pArray); ++i) {
|
||||
SDnodeObj *pDnode = taosArrayGet(pArray, i);
|
||||
bool inVgroup = false;
|
||||
int64_t oldMemUsed = 0;
|
||||
int64_t newMemUsed = 0;
|
||||
mDebug("db:%s, vgId:%d, check dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName, pNewVgroup->vgId,
|
||||
pDnode->id, pDnode->memAvail, pDnode->memUsed);
|
||||
for (int32_t j = 0; j < pOldVgroup->replica; ++j) {
|
||||
SVnodeGid *pVgId = &pOldVgroup->vnodeGid[i];
|
||||
SVnodeGid *pVgId = &pOldVgroup->vnodeGid[j];
|
||||
if (pDnode->id == pVgId->dnodeId) {
|
||||
pDnode->memUsed -= mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
|
||||
oldMemUsed = mndGetVgroupMemory(pMnode, pOldDb, pOldVgroup);
|
||||
inVgroup = true;
|
||||
}
|
||||
}
|
||||
for (int32_t j = 0; j < pNewVgroup->replica; ++j) {
|
||||
SVnodeGid *pVgId = &pNewVgroup->vnodeGid[i];
|
||||
SVnodeGid *pVgId = &pNewVgroup->vnodeGid[j];
|
||||
if (pDnode->id == pVgId->dnodeId) {
|
||||
pDnode->memUsed += mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
|
||||
newMemUsed = mndGetVgroupMemory(pMnode, pNewDb, pNewVgroup);
|
||||
inVgroup = true;
|
||||
}
|
||||
}
|
||||
|
||||
mDebug("db:%s, vgId:%d, memory in dnode:%d, oldUsed:%" PRId64 ", newUsed:%" PRId64, pNewVgroup->dbName,
|
||||
pNewVgroup->vgId, pDnode->id, oldMemUsed, newMemUsed);
|
||||
|
||||
pDnode->memUsed = pDnode->memUsed - oldMemUsed + newMemUsed;
|
||||
if (pDnode->memAvail - pDnode->memUsed <= 0) {
|
||||
mError("db:%s, vgId:%d, no enough memory in dnode:%d, avail:%" PRId64 " used:%" PRId64, pNewVgroup->dbName,
|
||||
pNewVgroup->vgId, pDnode->id, pDnode->memAvail, pDnode->memUsed);
|
||||
|
|
|
@ -408,6 +408,11 @@ static int32_t sdbReadFileImp(SSdb *pSdb) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (pRaw->type >= SDB_MAX) {
|
||||
mInfo("skip sdb raw type:%d since it is not supported", pRaw->type);
|
||||
continue;
|
||||
}
|
||||
|
||||
code = sdbWriteWithoutFree(pSdb, pRaw);
|
||||
if (code != 0) {
|
||||
mError("failed to exec sdbWrite while read sdb file:%s since %s", file, terrstr());
|
||||
|
|
|
@ -1328,7 +1328,7 @@ int32_t metaFilterTableIds(void *pVnode, SMetaFltParam *arg, SArray *pUids) {
|
|||
TAOS_CHECK_GOTO(terrno, NULL, END);
|
||||
}
|
||||
|
||||
if (false == taosMbsToUcs4(tagData, nTagData, (TdUcs4 *)buf, maxSize, &maxSize)) {
|
||||
if (false == taosMbsToUcs4(tagData, nTagData, (TdUcs4 *)buf, maxSize, &maxSize, NULL)) {
|
||||
TAOS_CHECK_GOTO(terrno, NULL, END);
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const
|
|||
if (val == NULL) {
|
||||
TAOS_CHECK_GOTO(terrno, NULL, _exception);
|
||||
}
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE, NULL);
|
||||
if (len < 0) {
|
||||
TAOS_CHECK_GOTO(len, NULL, _exception);
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ int metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSche
|
|||
if (val == NULL) {
|
||||
TAOS_CHECK_GOTO(terrno, NULL, _exception);
|
||||
}
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)pTagVal->pData, pTagVal->nData, val + VARSTR_HEADER_SIZE, NULL);
|
||||
if (len < 0) {
|
||||
TAOS_CHECK_GOTO(len, NULL, _exception);
|
||||
}
|
||||
|
|
|
@ -254,11 +254,12 @@ static void tdRSmaTaskInit(SStreamMeta *pMeta, SRSmaInfoItem *pItem, SStreamTask
|
|||
}
|
||||
|
||||
static void tdRSmaTaskRemove(SStreamMeta *pMeta, int64_t streamId, int32_t taskId) {
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
int32_t code = streamMetaUnregisterTask(pMeta, streamId, taskId);
|
||||
if (code != 0) {
|
||||
smaError("vgId:%d, rsma task:%" PRIi64 ",%d drop failed since %s", pMeta->vgId, streamId, taskId, tstrerror(code));
|
||||
}
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
// persist to disk
|
||||
|
|
|
@ -1122,91 +1122,76 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
// always return success to mnode
|
||||
//todo: handle failure of build and send msg to mnode
|
||||
static void doSendChkptSourceRsp(SStreamCheckpointSourceReq* pReq, SRpcHandleInfo* pRpcInfo, int32_t code,
|
||||
int32_t taskId) {
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(pReq, pRpcInfo, &rsp, code);
|
||||
if (ret) { // suppress the error in build checkpoint source rsp
|
||||
tqError("s-task:0x%x failed to build checkpoint-source rsp, code:%s", taskId, tstrerror(ret));
|
||||
}
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
}
|
||||
|
||||
// no matter what kinds of error happened, make sure the mnode will receive the success execution code.
|
||||
int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp) {
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||
int32_t code = 0;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t len = pMsg->contLen - sizeof(SMsgHead);
|
||||
int32_t code = 0;
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
SDecoder decoder = {0};
|
||||
SStreamTask* pTask = NULL;
|
||||
int64_t checkpointId = 0;
|
||||
|
||||
// disable auto rsp to mnode
|
||||
pRsp->info.handle = NULL;
|
||||
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, len);
|
||||
if (tDecodeStreamCheckpointSourceReq(&decoder, &req) < 0) {
|
||||
code = TSDB_CODE_MSG_DECODE_ERROR;
|
||||
tDecoderClear(&decoder);
|
||||
tqError("vgId:%d failed to decode checkpoint-source msg, code:%s", vgId, tstrerror(code));
|
||||
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:0x%x failed to build checkpoint-source rsp, code:%s", req.taskId, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode, todo: handle failure of build and send msg to mnode
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode,
|
||||
}
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
if (!vnodeIsRoleLeader(pTq->pVnode)) {
|
||||
tqDebug("vgId:%d not leader, ignore checkpoint-source msg, s-task:0x%x", vgId, req.taskId);
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:0x%x failed to build checkpoint-source rsp, code:%s", req.taskId, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode, todo: handle failure of build and send msg to mnode
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode
|
||||
}
|
||||
|
||||
if (!pTq->pVnode->restored) {
|
||||
tqDebug("vgId:%d checkpoint-source msg received during restoring, checkpointId:%" PRId64
|
||||
", transId:%d s-task:0x%x ignore it",
|
||||
vgId, req.checkpointId, req.transId, req.taskId);
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:0x%x failed to build checkpoint-source rsp, code:%s", req.taskId, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode, , todo: handle failure of build and send msg to mnode
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS; // always return success to mnode
|
||||
}
|
||||
|
||||
SStreamTask* pTask = NULL;
|
||||
code = streamMetaAcquireTask(pMeta, req.streamId, req.taskId, &pTask);
|
||||
if (pTask == NULL || code != 0) {
|
||||
tqError("vgId:%d failed to find s-task:0x%x, ignore checkpoint msg. checkpointId:%" PRId64
|
||||
" transId:%d it may have been destroyed",
|
||||
vgId, req.taskId, req.checkpointId, req.transId);
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:%s failed to build checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
|
||||
}
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pTask->status.downstreamReady != 1) {
|
||||
streamTaskSetFailedChkptInfo(pTask, req.transId, req.checkpointId); // record the latest failed checkpoint id
|
||||
// record the latest failed checkpoint id
|
||||
streamTaskSetFailedChkptInfo(pTask, req.transId, req.checkpointId);
|
||||
tqError("s-task:%s not ready for checkpoint, since downstream not ready, ignore this checkpointId:%" PRId64
|
||||
", transId:%d set it failed",
|
||||
pTask->id.idStr, req.checkpointId, req.transId);
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:%s failed to build checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS; // todo retry handle error
|
||||
}
|
||||
|
||||
|
@ -1221,14 +1206,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
streamMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:%s failed to build checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
|
@ -1240,7 +1218,6 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
// check if the checkpoint msg already sent or not.
|
||||
if (status == TASK_STATUS__CK) {
|
||||
int64_t checkpointId = 0;
|
||||
streamTaskGetActiveCheckpointInfo(pTask, NULL, &checkpointId);
|
||||
|
||||
tqWarn("s-task:%s repeatly recv checkpoint-source msg checkpointId:%" PRId64
|
||||
|
@ -1249,7 +1226,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
streamMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SYN_PROPOSE_NOT_READY, req.taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else { // checkpoint already finished, and not in checkpoint status
|
||||
if (req.checkpointId <= pTask->chkInfo.checkpointId) {
|
||||
|
@ -1259,15 +1236,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
streamMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:%s failed to build checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
|
||||
}
|
||||
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -1278,7 +1247,9 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
if (code) {
|
||||
qError("s-task:%s (vgId:%d) failed to process checkpoint-source req, code:%s", pTask->id.idStr, vgId,
|
||||
tstrerror(code));
|
||||
return code;
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (req.mndTrigger) {
|
||||
|
@ -1293,13 +1264,8 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
code = streamAddCheckpointSourceRspMsg(&req, &pMsg->info, pTask);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
SRpcMsg rsp = {0};
|
||||
int32_t ret = streamTaskBuildCheckpointSourceRsp(&req, &pMsg->info, &rsp, TSDB_CODE_SUCCESS);
|
||||
if (ret) { // suppress the error in build checkpointsource rsp
|
||||
tqError("s-task:%s failed to build checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
|
||||
}
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return TSDB_CODE_SUCCESS;
|
||||
streamTaskSetCheckpointFailed(pTask); // set the checkpoint failed
|
||||
doSendChkptSourceRsp(&req, &pMsg->info, TSDB_CODE_SUCCESS, req.taskId);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common/tmsg.h>
|
||||
#include "tcommon.h"
|
||||
#include "tmsg.h"
|
||||
#include "tq.h"
|
||||
|
||||
#define IS_NEW_SUBTB_RULE(_t) (((_t)->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER) && ((_t)->subtableWithoutMd5 != 1))
|
||||
|
@ -50,7 +48,7 @@ static int32_t doPutSinkTableInfoIntoCache(SSHashObj* pSinkTableMap, STableSinkI
|
|||
static bool doGetSinkTableInfoFromCache(SSHashObj* pTableInfoMap, uint64_t groupId, STableSinkInfo** pInfo);
|
||||
static int32_t doRemoveSinkTableInfoInCache(SSHashObj* pSinkTableMap, uint64_t groupId, const char* id);
|
||||
static int32_t checkTagSchema(SStreamTask* pTask, SVnode* pVnode);
|
||||
static void reubuildAndSendMultiResBlock(SStreamTask* pTask, const SArray* pBlocks, SVnode* pVnode, int64_t earlyTs);
|
||||
static void rebuildAndSendMultiResBlock(SStreamTask* pTask, const SArray* pBlocks, SVnode* pVnode, int64_t earlyTs);
|
||||
static int32_t handleResultBlockMsg(SStreamTask* pTask, SSDataBlock* pDataBlock, int32_t index, SVnode* pVnode,
|
||||
int64_t earlyTs);
|
||||
static int32_t doWaitForDstTableDropped(SVnode* pVnode, SStreamTask* pTask, const char* dstTableName);
|
||||
|
@ -1187,7 +1185,7 @@ void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data) {
|
|||
return;
|
||||
}
|
||||
|
||||
reubuildAndSendMultiResBlock(pTask, pBlocks, pVnode, earlyTs);
|
||||
rebuildAndSendMultiResBlock(pTask, pBlocks, pVnode, earlyTs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1288,7 @@ int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSDataBlock*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void reubuildAndSendMultiResBlock(SStreamTask* pTask, const SArray* pBlocks, SVnode* pVnode, int64_t earlyTs) {
|
||||
void rebuildAndSendMultiResBlock(SStreamTask* pTask, const SArray* pBlocks, SVnode* pVnode, int64_t earlyTs) {
|
||||
int32_t code = 0;
|
||||
const char* id = pTask->id.idStr;
|
||||
int32_t vgId = pTask->pMeta->vgId;
|
||||
|
|
|
@ -17,19 +17,20 @@
|
|||
#include "vnd.h"
|
||||
|
||||
#define MAX_REPEAT_SCAN_THRESHOLD 3
|
||||
#define SCAN_WAL_IDLE_DURATION 100
|
||||
#define SCAN_WAL_IDLE_DURATION 500 // idle for 500ms to do next wal scan
|
||||
|
||||
typedef struct SBuildScanWalMsgParam {
|
||||
int64_t metaId;
|
||||
int32_t numOfTasks;
|
||||
} SBuildScanWalMsgParam;
|
||||
|
||||
static int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle);
|
||||
static int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta);
|
||||
static int32_t setWalReaderStartOffset(SStreamTask* pTask, int32_t vgId);
|
||||
static bool handleFillhistoryScanComplete(SStreamTask* pTask, int64_t ver);
|
||||
static bool taskReadyForDataFromWal(SStreamTask* pTask);
|
||||
static int32_t doPutDataIntoInputQ(SStreamTask* pTask, int64_t maxVer, int32_t* numOfItems, bool* pSucc);
|
||||
static int32_t tqScanWalInFuture(STQ* pTq, int32_t numOfTasks, int32_t idleDuration);
|
||||
static int32_t doScanWalAsync(STQ* pTq, bool ckPause);
|
||||
|
||||
// extract data blocks(submit/delete) from WAL, and add them into the input queue for all the sources tasks.
|
||||
int32_t tqScanWal(STQ* pTq) {
|
||||
|
@ -37,12 +38,11 @@ int32_t tqScanWal(STQ* pTq) {
|
|||
int32_t vgId = pMeta->vgId;
|
||||
int64_t st = taosGetTimestampMs();
|
||||
int32_t numOfTasks = 0;
|
||||
bool shouldIdle = true;
|
||||
|
||||
tqDebug("vgId:%d continue to check if data in wal are available, scanCounter:%d", vgId, pMeta->scanInfo.scanCounter);
|
||||
|
||||
// check all tasks
|
||||
int32_t code = doScanWalForAllTasks(pMeta, &shouldIdle);
|
||||
int32_t code = doScanWalForAllTasks(pMeta);
|
||||
if (code) {
|
||||
tqError("vgId:%d failed to start all tasks, try next time, code:%s", vgId, tstrerror(code));
|
||||
return code;
|
||||
|
@ -133,10 +133,9 @@ int32_t tqScanWalInFuture(STQ* pTq, int32_t numOfTasks, int32_t idleDuration) {
|
|||
}
|
||||
|
||||
int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
bool alreadyRestored = pTq->pVnode->restored;
|
||||
int32_t numOfTasks = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
// do not launch the stream tasks, if it is a follower or not restored vnode.
|
||||
if (!(vnodeIsRoleLeader(pTq->pVnode) && alreadyRestored)) {
|
||||
|
@ -144,47 +143,8 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
|||
}
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
if (numOfTasks == 0) {
|
||||
tqDebug("vgId:%d no stream tasks existed to run", vgId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pMeta->startInfo.startAllTasks) {
|
||||
tqTrace("vgId:%d in restart procedure, not scan wal", vgId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMeta->scanInfo.scanCounter += 1;
|
||||
if (pMeta->scanInfo.scanCounter > MAX_REPEAT_SCAN_THRESHOLD) {
|
||||
pMeta->scanInfo.scanCounter = MAX_REPEAT_SCAN_THRESHOLD;
|
||||
}
|
||||
|
||||
if (pMeta->scanInfo.scanCounter > 1) {
|
||||
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->scanInfo.scanCounter);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t numOfPauseTasks = pMeta->numOfPausedTasks;
|
||||
if (ckPause && numOfTasks == numOfPauseTasks) {
|
||||
tqDebug("vgId:%d ignore all submit, all streams had been paused, reset the walScanCounter", vgId);
|
||||
|
||||
// reset the counter value, since we do not launch the scan wal operation.
|
||||
pMeta->scanInfo.scanCounter = 0;
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d, vnd restored:%d", vgId,
|
||||
numOfTasks, alreadyRestored);
|
||||
|
||||
int32_t code = streamTaskSchedTask(&pTq->pVnode->msgCb, vgId, 0, 0, STREAM_EXEC_T_EXTRACT_WAL_DATA);
|
||||
code = doScanWalAsync(pTq, ckPause);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -368,11 +328,8 @@ int32_t doPutDataIntoInputQ(SStreamTask* pTask, int64_t maxVer, int32_t* numOfIt
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
||||
*pScanIdle = true;
|
||||
bool noDataInWal = true;
|
||||
int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta) {
|
||||
int32_t vgId = pStreamMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pStreamMeta->pTaskList);
|
||||
if (numOfTasks == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -410,8 +367,6 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
|||
continue;
|
||||
}
|
||||
|
||||
*pScanIdle = false;
|
||||
|
||||
// seek the stored version and extract data from WAL
|
||||
code = setWalReaderStartOffset(pTask, vgId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -437,7 +392,6 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
|||
streamMutexUnlock(&pTask->lock);
|
||||
|
||||
if ((numOfItems > 0) || hasNewData) {
|
||||
noDataInWal = false;
|
||||
code = streamTrySchedExec(pTask);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
streamMetaReleaseTask(pStreamMeta, pTask);
|
||||
|
@ -449,11 +403,47 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
|||
streamMetaReleaseTask(pStreamMeta, pTask);
|
||||
}
|
||||
|
||||
// all wal are checked, and no new data available in wal.
|
||||
if (noDataInWal) {
|
||||
*pScanIdle = true;
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTaskList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t doScanWalAsync(STQ* pTq, bool ckPause) {
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
bool alreadyRestored = pTq->pVnode->restored;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
|
||||
if (numOfTasks == 0) {
|
||||
tqDebug("vgId:%d no stream tasks existed to run", vgId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pMeta->startInfo.startAllTasks) {
|
||||
tqTrace("vgId:%d in restart procedure, not scan wal", vgId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMeta->scanInfo.scanCounter += 1;
|
||||
if (pMeta->scanInfo.scanCounter > MAX_REPEAT_SCAN_THRESHOLD) {
|
||||
pMeta->scanInfo.scanCounter = MAX_REPEAT_SCAN_THRESHOLD;
|
||||
}
|
||||
|
||||
if (pMeta->scanInfo.scanCounter > 1) {
|
||||
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->scanInfo.scanCounter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t numOfPauseTasks = pMeta->numOfPausedTasks;
|
||||
if (ckPause && numOfTasks == numOfPauseTasks) {
|
||||
tqDebug("vgId:%d ignore all submit, all streams had been paused, reset the walScanCounter", vgId);
|
||||
|
||||
// reset the counter value, since we do not launch the scan wal operation.
|
||||
pMeta->scanInfo.scanCounter = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d, vnd restored:%d", vgId,
|
||||
numOfTasks, alreadyRestored);
|
||||
|
||||
return streamTaskSchedTask(&pTq->pVnode->msgCb, vgId, 0, 0, STREAM_EXEC_T_EXTRACT_WAL_DATA);
|
||||
}
|
||||
|
|
|
@ -718,8 +718,6 @@ int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen
|
|||
}
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// drop the related fill-history task firstly
|
||||
if (hTaskId.taskId != 0 && hTaskId.streamId != 0) {
|
||||
tqDebug("s-task:0x%x vgId:%d drop rel fill-history task:0x%x firstly", pReq->taskId, vgId, (int32_t)hTaskId.taskId);
|
||||
|
@ -737,7 +735,6 @@ int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen
|
|||
}
|
||||
|
||||
// commit the update
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
|
||||
tqDebug("vgId:%d task:0x%x dropped, remain tasks:%d", vgId, pReq->taskId, numOfTasks);
|
||||
|
||||
|
|
|
@ -977,6 +977,11 @@ void vnodeUpdateMetaRsp(SVnode *pVnode, STableMetaRsp *pMetaRsp) {
|
|||
extern int32_t vnodeAsyncRetention(SVnode *pVnode, int64_t now);
|
||||
|
||||
static int32_t vnodeProcessTrimReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp) {
|
||||
if (!pVnode->restored) {
|
||||
vInfo("vgId:%d, ignore trim req during restoring. ver:%" PRId64, TD_VID(pVnode), ver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SVTrimDbReq trimReq = {0};
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ int32_t ctgGetTbTag(SCatalog* pCtg, SRequestConnInfo* pConn, SName* pTableName,
|
|||
}
|
||||
|
||||
char* pJson = NULL;
|
||||
parseTagDatatoJson(pTag, &pJson);
|
||||
parseTagDatatoJson(pTag, &pJson, NULL);
|
||||
if(NULL == pJson) {
|
||||
taosArrayDestroy(pTagVals);
|
||||
CTG_ERR_JRET(terrno);
|
||||
|
|
|
@ -2340,7 +2340,7 @@ int32_t ctgHandleGetTbTagRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf*
|
|||
}
|
||||
|
||||
char* pJson = NULL;
|
||||
parseTagDatatoJson(pTag, &pJson);
|
||||
parseTagDatatoJson(pTag, &pJson, NULL);
|
||||
if (NULL == pJson) {
|
||||
taosArrayDestroy(pTagVals);
|
||||
CTG_ERR_JRET(terrno);
|
||||
|
|
|
@ -573,7 +573,7 @@ static void appendTagNameFields(char* buf, int32_t* len, STableCfg* pCfg) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) {
|
||||
static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg, void* charsetCxt) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SArray* pTagVals = NULL;
|
||||
STag* pTag = (STag*)pCfg->pTags;
|
||||
|
@ -585,7 +585,7 @@ static int32_t appendTagValues(char* buf, int32_t* len, STableCfg* pCfg) {
|
|||
|
||||
if (tTagIsJson(pTag)) {
|
||||
char* pJson = NULL;
|
||||
parseTagDatatoJson(pTag, &pJson);
|
||||
parseTagDatatoJson(pTag, &pJson, charsetCxt);
|
||||
if (NULL == pJson) {
|
||||
qError("failed to parse tag to json, pJson is NULL");
|
||||
return terrno;
|
||||
|
@ -726,7 +726,7 @@ static void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STab
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg) {
|
||||
static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg, void* charsetCxt) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
QRY_ERR_RET(blockDataEnsureCapacity(pBlock, 1));
|
||||
pBlock->info.rows = 1;
|
||||
|
@ -760,7 +760,7 @@ static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* p
|
|||
appendTagNameFields(buf2, &len, pCfg);
|
||||
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len),
|
||||
") TAGS (");
|
||||
code = appendTagValues(buf2, &len, pCfg);
|
||||
code = appendTagValues(buf2, &len, pCfg, charsetCxt);
|
||||
TAOS_CHECK_ERRNO(code);
|
||||
len +=
|
||||
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
|
||||
|
@ -817,11 +817,11 @@ static int32_t setCreateViewResultIntoDataBlock(SSDataBlock* pBlock, SShowCreate
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) {
|
||||
static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
|
||||
SSDataBlock* pBlock = NULL;
|
||||
int32_t code = buildCreateTbResultDataBlock(&pBlock);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg);
|
||||
code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg, charsetCxt);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildRetrieveTableRsp(pBlock, SHOW_CREATE_TB_RESULT_COLS, pRsp);
|
||||
|
@ -830,14 +830,14 @@ static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRs
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp) {
|
||||
static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
|
||||
STableCfg* pCfg = (STableCfg*)pStmt->pTableCfg;
|
||||
if (TSDB_SUPER_TABLE != pCfg->tableType) {
|
||||
terrno = TSDB_CODE_TSC_NOT_STABLE_ERROR;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
return execShowCreateTable(pStmt, pRsp);
|
||||
return execShowCreateTable(pStmt, pRsp, charsetCxt);
|
||||
}
|
||||
|
||||
static int32_t execAlterCmd(char* cmd, char* value, bool* processed) {
|
||||
|
@ -909,7 +909,7 @@ static int32_t execAlterLocal(SAlterLocalStmt* pStmt) {
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (cfgSetItem(tsCfg, pStmt->config, pStmt->value, CFG_STYPE_ALTER_CMD, true)) {
|
||||
if (cfgSetItem(tsCfg, pStmt->config, pStmt->value, CFG_STYPE_ALTER_CLIENT_CMD, true)) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
@ -1064,7 +1064,7 @@ static int32_t execShowCreateView(SShowCreateViewStmt* pStmt, SRetrieveTableRsp*
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp** pRsp, int8_t biMode) {
|
||||
int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp** pRsp, int8_t biMode, void* charsetCxt) {
|
||||
switch (nodeType(pStmt)) {
|
||||
case QUERY_NODE_DESCRIBE_STMT:
|
||||
return execDescribe(sysInfoUser, pStmt, pRsp, biMode);
|
||||
|
@ -1073,9 +1073,9 @@ int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieve
|
|||
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
|
||||
return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp);
|
||||
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
|
||||
return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp);
|
||||
return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
|
||||
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
|
||||
return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp);
|
||||
return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
|
||||
case QUERY_NODE_SHOW_CREATE_VIEW_STMT:
|
||||
return execShowCreateView((SShowCreateViewStmt*)pStmt, pRsp);
|
||||
case QUERY_NODE_ALTER_LOCAL_STMT:
|
||||
|
|
|
@ -2418,7 +2418,7 @@ void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, b
|
|||
|
||||
w->skey = key;
|
||||
}
|
||||
w->ekey = taosTimeAdd(w->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
w->ekey = taosTimeAdd(w->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2473,15 +2473,15 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
|
||||
TSKEY getNextTimeWindowStart(const SInterval* pInterval, TSKEY start, int32_t order) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
TSKEY nextStart = taosTimeAdd(start, -1 * pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
nextStart = taosTimeAdd(nextStart, factor * pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
nextStart = taosTimeAdd(nextStart, pInterval->offset, pInterval->offsetUnit, pInterval->precision);
|
||||
TSKEY nextStart = taosTimeAdd(start, -1 * pInterval->offset, pInterval->offsetUnit, pInterval->precision, NULL);
|
||||
nextStart = taosTimeAdd(nextStart, factor * pInterval->sliding, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
nextStart = taosTimeAdd(nextStart, pInterval->offset, pInterval->offsetUnit, pInterval->precision, NULL);
|
||||
return nextStart;
|
||||
}
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
tw->skey = getNextTimeWindowStart(pInterval, tw->skey, order);
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1;
|
||||
}
|
||||
|
||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||
|
|
|
@ -568,7 +568,7 @@ static void reviseFillStartAndEndKey(SFillOperatorInfo* pInfo, int32_t order) {
|
|||
next = ekey;
|
||||
while (next < pInfo->win.ekey) {
|
||||
next = taosTimeAdd(ekey, pInfo->pFillInfo->interval.sliding, pInfo->pFillInfo->interval.slidingUnit,
|
||||
pInfo->pFillInfo->interval.precision);
|
||||
pInfo->pFillInfo->interval.precision, NULL);
|
||||
ekey = next > pInfo->win.ekey ? ekey : next;
|
||||
}
|
||||
pInfo->win.ekey = ekey;
|
||||
|
@ -577,7 +577,7 @@ static void reviseFillStartAndEndKey(SFillOperatorInfo* pInfo, int32_t order) {
|
|||
next = skey;
|
||||
while (next < pInfo->win.skey) {
|
||||
next = taosTimeAdd(skey, pInfo->pFillInfo->interval.sliding, pInfo->pFillInfo->interval.slidingUnit,
|
||||
pInfo->pFillInfo->interval.precision);
|
||||
pInfo->pFillInfo->interval.precision, NULL);
|
||||
skey = next > pInfo->win.skey ? skey : next;
|
||||
}
|
||||
taosFillUpdateStartTimestampInfo(pInfo->pFillInfo, skey);
|
||||
|
|
|
@ -114,7 +114,7 @@ int32_t hJoinLaunchPrimExpr(SSDataBlock* pBlock, SHJoinTableCtx* pTable, int32_t
|
|||
SColumnInfoData* pPrimOut = taosArrayGet(pBlock->pDataBlock, pTable->primCtx.targetSlotId);
|
||||
if (0 != pCtx->timezoneUnit) {
|
||||
for (int32_t i = startIdx; i <= endIdx; ++i) {
|
||||
((int64_t*)pPrimOut->pData)[i] = ((int64_t*)pPrimIn->pData)[i] - (((int64_t*)pPrimIn->pData)[i] - pCtx->timezoneUnit) % pCtx->truncateUnit;
|
||||
((int64_t*)pPrimOut->pData)[i] = ((int64_t*)pPrimIn->pData)[i] - (((int64_t*)pPrimIn->pData)[i] + pCtx->timezoneUnit) % pCtx->truncateUnit;
|
||||
}
|
||||
} else {
|
||||
for (int32_t i = startIdx; i <= endIdx; ++i) {
|
||||
|
|
|
@ -281,12 +281,12 @@ static void calcRowDeltaData(SResultRowData* pEndRow, SArray* pEndPoins, SFillCo
|
|||
}
|
||||
|
||||
static void setFillInfoStart(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) {
|
||||
ts = taosTimeAdd(ts, pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
ts = taosTimeAdd(ts, pInterval->sliding, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
pFillInfo->start = ts;
|
||||
}
|
||||
|
||||
static void setFillInfoEnd(TSKEY ts, SInterval* pInterval, SStreamFillInfo* pFillInfo) {
|
||||
ts = taosTimeAdd(ts, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision);
|
||||
ts = taosTimeAdd(ts, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
pFillInfo->end = ts;
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ void setDeleteFillValueInfo(TSKEY start, TSKEY end, SStreamFillSupporter* pFillS
|
|||
}
|
||||
|
||||
TSKEY realStart = taosTimeAdd(pFillSup->prev.key, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
|
||||
pFillInfo->needFill = true;
|
||||
pFillInfo->start = realStart;
|
||||
|
@ -542,7 +542,7 @@ static void doStreamFillNormal(SStreamFillSupporter* pFillSup, SStreamFillInfo*
|
|||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
}
|
||||
pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
}
|
||||
|
||||
_end:
|
||||
|
@ -564,7 +564,7 @@ static void doStreamFillLinear(SStreamFillSupporter* pFillSup, SStreamFillInfo*
|
|||
|
||||
if ((pFillSup->hasDelete && !ckRes) || !inWinRange(&pFillSup->winRange, &st)) {
|
||||
pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
pFillInfo->pLinearInfo->winIndex++;
|
||||
continue;
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ static void doStreamFillLinear(SStreamFillSupporter* pFillSup, SStreamFillInfo*
|
|||
}
|
||||
}
|
||||
pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
pBlock->info.rows++;
|
||||
}
|
||||
|
||||
|
@ -987,7 +987,14 @@ _end:
|
|||
}
|
||||
|
||||
void resetStreamFillSup(SStreamFillSupporter* pFillSup) {
|
||||
tSimpleHashClear(pFillSup->pResMap);
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
SSHashObj* pNewMap = tSimpleHashInit(16, hashFn);
|
||||
if (pNewMap != NULL) {
|
||||
tSimpleHashCleanup(pFillSup->pResMap);
|
||||
pFillSup->pResMap = pNewMap;
|
||||
} else {
|
||||
tSimpleHashClear(pFillSup->pResMap);
|
||||
}
|
||||
pFillSup->hasDelete = false;
|
||||
}
|
||||
void resetStreamFillInfo(SStreamFillOperatorInfo* pInfo) {
|
||||
|
@ -1336,7 +1343,7 @@ static int32_t doStreamForceFillImpl(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
resTs = taosTimeAdd(resTs, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1406,6 +1413,7 @@ static int32_t doStreamForceFillNext(SOperatorInfo* pOperator, SSDataBlock** ppR
|
|||
}
|
||||
|
||||
pInfo->stateStore.streamStateClearExpiredState(pInfo->pState);
|
||||
resetStreamFillInfo(pInfo);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
(*ppRes) = NULL;
|
||||
goto _end;
|
||||
|
@ -1477,6 +1485,7 @@ static int32_t doStreamForceFillNext(SOperatorInfo* pOperator, SSDataBlock** ppR
|
|||
|
||||
if ((*ppRes) == NULL) {
|
||||
pInfo->stateStore.streamStateClearExpiredState(pInfo->pState);
|
||||
resetStreamFillInfo(pInfo);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,36 @@ void initIntervalSlicePoint(SStreamAggSupporter* pAggSup, STimeWindow* pTWin, in
|
|||
pPoint->pLastRow = POINTER_SHIFT(pPoint->pFinished, sizeof(bool));
|
||||
}
|
||||
|
||||
int32_t getIntervalSlicePrevStateBuf(SStreamAggSupporter* pAggSup, SInterval* pInterval, SWinKey* pCurKey,
|
||||
SInervalSlicePoint* pPrevPoint) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t lino = 0;
|
||||
SWinKey prevKey = {.groupId = pCurKey->groupId};
|
||||
SET_WIN_KEY_INVALID(prevKey.ts);
|
||||
int32_t prevVLen = 0;
|
||||
int32_t prevWinCode = TSDB_CODE_SUCCESS;
|
||||
code = pAggSup->stateStore.streamStateGetPrev(pAggSup->pState, pCurKey, &prevKey, (void**)&pPrevPoint->pResPos,
|
||||
&prevVLen, &prevWinCode);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
|
||||
if (prevWinCode == TSDB_CODE_SUCCESS) {
|
||||
STimeWindow prevSTW = {.skey = prevKey.ts};
|
||||
prevSTW.ekey = taosTimeGetIntervalEnd(prevSTW.skey, pInterval);
|
||||
initIntervalSlicePoint(pAggSup, &prevSTW, pCurKey->groupId, pPrevPoint);
|
||||
qDebug("===stream=== set stream twa prev point buf.ts:%" PRId64 ", groupId:%" PRIu64 ", res:%d",
|
||||
pPrevPoint->winKey.win.skey, pPrevPoint->winKey.groupId, prevWinCode);
|
||||
} else {
|
||||
SET_WIN_KEY_INVALID(pPrevPoint->winKey.win.skey);
|
||||
SET_WIN_KEY_INVALID(pPrevPoint->winKey.win.ekey);
|
||||
}
|
||||
|
||||
_end:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t getIntervalSliceCurStateBuf(SStreamAggSupporter* pAggSup, SInterval* pInterval, bool needPrev, STimeWindow* pTWin, int64_t groupId,
|
||||
SInervalSlicePoint* pCurPoint, SInervalSlicePoint* pPrevPoint, int32_t* pWinCode) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -136,24 +166,8 @@ static int32_t getIntervalSliceCurStateBuf(SStreamAggSupporter* pAggSup, SInterv
|
|||
initIntervalSlicePoint(pAggSup, pTWin, groupId, pCurPoint);
|
||||
|
||||
if (needPrev) {
|
||||
SWinKey prevKey = {.groupId = groupId};
|
||||
SET_WIN_KEY_INVALID(prevKey.ts);
|
||||
int32_t prevVLen = 0;
|
||||
int32_t prevWinCode = TSDB_CODE_SUCCESS;
|
||||
code = pAggSup->stateStore.streamStateGetPrev(pAggSup->pState, &curKey, &prevKey, (void**)&pPrevPoint->pResPos,
|
||||
&prevVLen, &prevWinCode);
|
||||
code = getIntervalSlicePrevStateBuf(pAggSup, pInterval, &curKey, pPrevPoint);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
|
||||
if (prevWinCode == TSDB_CODE_SUCCESS) {
|
||||
STimeWindow prevSTW = {.skey = prevKey.ts};
|
||||
prevSTW.ekey = taosTimeGetIntervalEnd(prevSTW.skey, pInterval);
|
||||
initIntervalSlicePoint(pAggSup, &prevSTW, groupId, pPrevPoint);
|
||||
qDebug("===stream=== set stream twa prev point buf.ts:%" PRId64 ", groupId:%" PRIu64 ", res:%d", pPrevPoint->winKey.win.skey,
|
||||
pPrevPoint->winKey.groupId, prevWinCode);
|
||||
} else {
|
||||
SET_WIN_KEY_INVALID(pPrevPoint->winKey.win.skey);
|
||||
SET_WIN_KEY_INVALID(pPrevPoint->winKey.win.ekey);
|
||||
}
|
||||
}
|
||||
|
||||
_end:
|
||||
|
@ -265,13 +279,15 @@ static int32_t doStreamIntervalSliceAggImpl(SOperatorInfo* pOperator, SSDataBloc
|
|||
STimeWindow curWin =
|
||||
getActiveTimeWindow(NULL, pResultRowInfo, curTs, &pInfo->interval, TSDB_ORDER_ASC);
|
||||
while (1) {
|
||||
if (curTs > pInfo->endTs) {
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t winCode = TSDB_CODE_SUCCESS;
|
||||
code = getIntervalSliceCurStateBuf(&pInfo->streamAggSup, &pInfo->interval, pInfo->hasInterpoFunc, &curWin, groupId, &curPoint, &prevPoint, &winCode);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
if (curTs <= pInfo->endTs) {
|
||||
code = getIntervalSliceCurStateBuf(&pInfo->streamAggSup, &pInfo->interval, pInfo->hasInterpoFunc, &curWin, groupId, &curPoint, &prevPoint, &winCode);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
} else if (pInfo->hasInterpoFunc) {
|
||||
SWinKey curKey = {.ts = curWin.skey, .groupId = groupId};
|
||||
code = getIntervalSlicePrevStateBuf(&pInfo->streamAggSup, &pInfo->interval, &curKey, &prevPoint);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
}
|
||||
|
||||
if (pInfo->hasInterpoFunc && IS_VALID_WIN_KEY(prevPoint.winKey.win.skey) && isInterpoWindowFinished(&prevPoint) == false) {
|
||||
code = setIntervalSliceOutputBuf(&prevPoint, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
|
@ -288,6 +304,12 @@ static int32_t doStreamIntervalSliceAggImpl(SOperatorInfo* pOperator, SSDataBloc
|
|||
code = saveWinResult(&prevKey, prevPoint.pResPos, pInfo->pUpdatedMap);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
setInterpoWindowFinished(&prevPoint);
|
||||
} else if (IS_VALID_WIN_KEY(prevPoint.winKey.win.skey)) {
|
||||
releaseOutputBuf(pInfo->streamAggSup.pState, prevPoint.pResPos, &pInfo->streamAggSup.stateStore);
|
||||
}
|
||||
|
||||
if (curTs > pInfo->endTs) {
|
||||
break;
|
||||
}
|
||||
|
||||
code = setIntervalSliceOutputBuf(&curPoint, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset);
|
||||
|
@ -300,7 +322,7 @@ static int32_t doStreamIntervalSliceAggImpl(SOperatorInfo* pOperator, SSDataBloc
|
|||
forwardRows = getNumOfRowsInTimeWindow(&pBlock->info, tsCols, startPos, curWin.ekey, binarySearchForKey, NULL,
|
||||
TSDB_ORDER_ASC);
|
||||
int32_t prevEndPos = (forwardRows - 1) + startPos;
|
||||
if (pInfo->hasInterpoFunc && winCode != TSDB_CODE_SUCCESS) {
|
||||
if (pInfo->hasInterpoFunc) {
|
||||
int32_t endRowId = getQualifiedRowNumDesc(pSup, pBlock, tsCols, prevEndPos, false);
|
||||
TSKEY endRowTs = tsCols[endRowId];
|
||||
transBlockToSliceResultRow(pBlock, endRowId, endRowTs, curPoint.pLastRow, 0, NULL, NULL, pInfo->pOffsetInfo);
|
||||
|
|
|
@ -467,7 +467,7 @@ static void fillNormalRange(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFi
|
|||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
// }
|
||||
pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
}
|
||||
|
||||
_end:
|
||||
|
@ -527,7 +527,7 @@ static void fillLinearRange(SStreamFillSupporter* pFillSup, SStreamFillInfo* pFi
|
|||
}
|
||||
}
|
||||
pFillInfo->current = taosTimeAdd(pFillInfo->current, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
if (ckRes) {
|
||||
pBlock->info.rows++;
|
||||
}
|
||||
|
@ -547,14 +547,14 @@ static void setFillKeyInfo(TSKEY start, TSKEY end, SInterval* pInterval, SStream
|
|||
|
||||
static TSKEY adustPrevTsKey(TSKEY pointTs, TSKEY rowTs, SInterval* pInterval) {
|
||||
if (rowTs >= pointTs) {
|
||||
pointTs = taosTimeAdd(pointTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
pointTs = taosTimeAdd(pointTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
}
|
||||
return pointTs;
|
||||
}
|
||||
|
||||
static TSKEY adustEndTsKey(TSKEY pointTs, TSKEY rowTs, SInterval* pInterval) {
|
||||
if (rowTs <= pointTs) {
|
||||
pointTs = taosTimeAdd(pointTs, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision);
|
||||
pointTs = taosTimeAdd(pointTs, pInterval->sliding * -1, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
}
|
||||
return pointTs;
|
||||
}
|
||||
|
@ -954,7 +954,7 @@ static int32_t getPointInfoFromState(SStreamAggSupporter* pAggSup, SStreamFillSu
|
|||
}
|
||||
} else {
|
||||
pNextPoint->key.ts = taosTimeAdd(pCurPoint->key.ts, pFillSup->interval.sliding, pFillSup->interval.slidingUnit,
|
||||
pFillSup->interval.precision);
|
||||
pFillSup->interval.precision, NULL);
|
||||
code = pAggSup->stateStore.streamStateFillAddIfNotExist(pState, &pNextPoint->key, (void**)&pNextPoint->pResPos,
|
||||
&nextVLen, &tmpRes);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
|
|
|
@ -358,7 +358,7 @@ static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp
|
|||
void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey));
|
||||
STimeWindow win = {
|
||||
.skey = pWinKey->ts,
|
||||
.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1,
|
||||
.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1,
|
||||
};
|
||||
if (isCloseWindow(&win, pTwSup)) {
|
||||
if (chIds && pPullDataMap) {
|
||||
|
@ -391,7 +391,7 @@ _end:
|
|||
|
||||
STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) {
|
||||
STimeWindow w = {.skey = ts, .ekey = INT64_MAX};
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1;
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -851,7 +851,7 @@ static int32_t processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pF
|
|||
}
|
||||
}
|
||||
}
|
||||
winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision);
|
||||
winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
}
|
||||
}
|
||||
if (pBeOver) {
|
||||
|
|
|
@ -978,7 +978,7 @@ int32_t convertTagDataToStr(char* str, int32_t strBuffLen, int type, void* buf,
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
int32_t length = taosUcs4ToMbs((TdUcs4*)buf, bufSize, str);
|
||||
int32_t length = taosUcs4ToMbs((TdUcs4*)buf, bufSize, str, NULL);
|
||||
if (length <= 0) {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
@ -1129,7 +1129,7 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
|
|||
if (tagData != NULL) {
|
||||
if (tagType == TSDB_DATA_TYPE_JSON) {
|
||||
char* tagJson = NULL;
|
||||
parseTagDatatoJson(tagData, &tagJson);
|
||||
parseTagDatatoJson(tagData, &tagJson, NULL);
|
||||
if (tagJson == NULL) {
|
||||
code = terrno;
|
||||
goto _end;
|
||||
|
|
|
@ -143,7 +143,7 @@ bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnI
|
|||
// TODO: include endpoint
|
||||
SInterval* pInterval = &pFillInfo->interval;
|
||||
int64_t windowEnd =
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
code = colDataSetVal(pDstColInfoData, rowIndex, (const char*)&windowEnd, false);
|
||||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
return true;
|
||||
|
@ -264,7 +264,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
|||
// setTagsValue(pFillInfo, data, index);
|
||||
SInterval* pInterval = &pFillInfo->interval;
|
||||
pFillInfo->currentKey =
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
pBlock->info.rows += 1;
|
||||
pFillInfo->numOfCurrent++;
|
||||
|
||||
|
@ -484,7 +484,7 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t
|
|||
// set the tag value for final result
|
||||
SInterval* pInterval = &pFillInfo->interval;
|
||||
pFillInfo->currentKey =
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision, NULL);
|
||||
|
||||
pBlock->info.rows += 1;
|
||||
pFillInfo->index += 1;
|
||||
|
|
|
@ -901,7 +901,7 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
doKeepLinearInfo(pSliceInfo, pBlock, i);
|
||||
|
||||
pSliceInfo->current =
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
|
||||
if (checkWindowBoundReached(pSliceInfo)) {
|
||||
break;
|
||||
|
@ -927,7 +927,7 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
break;
|
||||
} else {
|
||||
pSliceInfo->current =
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -955,7 +955,7 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
break;
|
||||
} else {
|
||||
pSliceInfo->current =
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -965,7 +965,7 @@ static void doTimesliceImpl(SOperatorInfo* pOperator, STimeSliceOperatorInfo* pS
|
|||
QUERY_CHECK_CODE(code, lino, _end);
|
||||
|
||||
pSliceInfo->current =
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
}
|
||||
doKeepPrevRows(pSliceInfo, pBlock, i);
|
||||
|
||||
|
@ -1003,7 +1003,7 @@ static void genInterpAfterDataBlock(STimeSliceOperatorInfo* pSliceInfo, SOperato
|
|||
while (pSliceInfo->current <= pSliceInfo->win.ekey) {
|
||||
(void)genInterpolationResult(pSliceInfo, &pOperator->exprSupp, pResBlock, NULL, index, false, pOperator->pTaskInfo);
|
||||
pSliceInfo->current =
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision);
|
||||
taosTimeAdd(pSliceInfo->current, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1922,7 +1922,7 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
|
||||
STimeWindow win = {0};
|
||||
win.skey = miaInfo->curTs;
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1;
|
||||
|
||||
int32_t ret = setSingleOutputTupleBuf(pResultRowInfo, &win, &miaInfo->pResultRow, pSup, &iaInfo->aggSup);
|
||||
if (ret != TSDB_CODE_SUCCESS || miaInfo->pResultRow == NULL) {
|
||||
|
@ -1949,7 +1949,7 @@ static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultR
|
|||
miaInfo->curTs = tsCols[currPos];
|
||||
|
||||
currWin.skey = miaInfo->curTs;
|
||||
currWin.ekey = taosTimeAdd(currWin.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
currWin.ekey = taosTimeAdd(currWin.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision, NULL) - 1;
|
||||
|
||||
startPos = currPos;
|
||||
ret = setSingleOutputTupleBuf(pResultRowInfo, &win, &miaInfo->pResultRow, pSup, &iaInfo->aggSup);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue