[td-255]merge develop
This commit is contained in:
commit
691eba4782
|
@ -0,0 +1,13 @@
|
|||
# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference
|
||||
version: 2.1
|
||||
# Use a package of configuration called an orb.
|
||||
orbs:
|
||||
# Declare a dependency on the welcome-orb
|
||||
welcome: circleci/welcome-orb@0.4.1
|
||||
# Orchestrate or schedule a set of jobs
|
||||
workflows:
|
||||
# Name the workflow "welcome"
|
||||
welcome:
|
||||
# Run the welcome/run job in its own container
|
||||
jobs:
|
||||
- welcome/run
|
|
@ -1,12 +1,12 @@
|
|||
[submodule "src/connector/go"]
|
||||
path = src/connector/go
|
||||
url = https://github.com/taosdata/driver-go
|
||||
url = git@github.com:taosdata/driver-go.git
|
||||
[submodule "src/connector/grafanaplugin"]
|
||||
path = src/connector/grafanaplugin
|
||||
url = https://github.com/taosdata/grafanaplugin
|
||||
url = git@github.com:taosdata/grafanaplugin.git
|
||||
[submodule "src/connector/hivemq-tdengine-extension"]
|
||||
path = src/connector/hivemq-tdengine-extension
|
||||
url = https://github.com/huskar-t/hivemq-tdengine-extension.git
|
||||
url = git@github.com:taosdata/hivemq-tdengine-extension.git
|
||||
[submodule "tests/examples/rust"]
|
||||
path = tests/examples/rust
|
||||
url = https://github.com/songtianyi/tdengine-rust-bindings.git
|
||||
|
|
|
@ -116,7 +116,7 @@ mkdir debug && cd debug
|
|||
cmake .. && cmake --build .
|
||||
```
|
||||
|
||||
在X86-64、X86、arm64 和 arm32 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。
|
||||
在X86-64、X86、arm64、arm32 和 mips64 平台上,TDengine 生成脚本可以自动检测机器架构。也可以手动配置 CPUTYPE 参数来指定 CPU 类型,如 aarch64 或 aarch32 等。
|
||||
|
||||
aarch64:
|
||||
|
||||
|
@ -130,6 +130,12 @@ aarch32:
|
|||
cmake .. -DCPUTYPE=aarch32 && cmake --build .
|
||||
```
|
||||
|
||||
mips64:
|
||||
|
||||
```bash
|
||||
cmake .. -DCPUTYPE=mips64 && cmake --build .
|
||||
```
|
||||
|
||||
### Windows 系统
|
||||
|
||||
如果你使用的是 Visual Studio 2013 版本:
|
||||
|
|
|
@ -110,7 +110,7 @@ mkdir debug && cd debug
|
|||
cmake .. && cmake --build .
|
||||
```
|
||||
|
||||
TDengine build script can detect the host machine's architecture on X86-64, X86, arm64 and arm32 platform.
|
||||
TDengine build script can detect the host machine's architecture on X86-64, X86, arm64, arm32 and mips64 platform.
|
||||
You can also specify CPUTYPE option like aarch64 or aarch32 too if the detection result is not correct:
|
||||
|
||||
aarch64:
|
||||
|
@ -123,6 +123,11 @@ aarch32:
|
|||
cmake .. -DCPUTYPE=aarch32 && cmake --build .
|
||||
```
|
||||
|
||||
mips64:
|
||||
```bash
|
||||
cmake .. -DCPUTYPE=mips64 && cmake --build .
|
||||
```
|
||||
|
||||
### On Windows platform
|
||||
|
||||
If you use the Visual Studio 2013, please open a command window by executing "cmd.exe".
|
||||
|
|
|
@ -102,6 +102,12 @@ IF ("${CPUTYPE}" STREQUAL "")
|
|||
SET(TD_LINUX TRUE)
|
||||
SET(TD_LINUX_64 FALSE)
|
||||
SET(TD_ARM_64 TRUE)
|
||||
ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "mips64")
|
||||
SET(CPUTYPE "mips64")
|
||||
MESSAGE(STATUS "Set CPUTYPE to mips64")
|
||||
SET(TD_LINUX TRUE)
|
||||
SET(TD_LINUX_64 FALSE)
|
||||
SET(TD_MIPS_64 TRUE)
|
||||
ENDIF ()
|
||||
|
||||
ELSE ()
|
||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.1.0.0")
|
||||
SET(TD_VER_NUMBER "2.1.1.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -24,7 +24,7 @@ TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。
|
|||
|
||||
## <a class="anchor" id="start"></a>轻松启动
|
||||
|
||||
安装成功后,用户可使用`systemctl`命令来启动TDengine的服务进程。
|
||||
安装成功后,用户可使用 `systemctl` 命令来启动 TDengine 的服务进程。
|
||||
|
||||
```bash
|
||||
$ systemctl start taosd
|
||||
|
@ -35,21 +35,22 @@ $ systemctl start taosd
|
|||
$ systemctl status taosd
|
||||
```
|
||||
|
||||
如果TDengine服务正常工作,那么您可以通过TDengine的命令行程序`taos`来访问并体验TDengine。
|
||||
如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。
|
||||
|
||||
**注意:**
|
||||
|
||||
- systemctl命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo
|
||||
- 为更好的获得产品反馈,改善产品,TDengine会采集基本的使用信息,但您可以修改系统配置文件taos.cfg里的配置参数telemetryReporting, 将其设为0,就可将其关闭。
|
||||
- TDengine采用FQDN(一般就是hostname)作为节点的ID,为保证正常运行,需要给运行taosd的服务器配置好hostname,在客户端应用运行的机器配置好DNS服务或hosts文件,保证FQDN能够解析。
|
||||
- systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。
|
||||
- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting, 将其设为 0,就可将其关闭。
|
||||
- TDengine 采用 FQDN (一般就是 hostname )作为节点的 ID,为保证正常运行,需要给运行 taosd 的服务器配置好 hostname,在客户端应用运行的机器配置好 DNS 服务或 hosts 文件,保证 FQDN 能够解析。
|
||||
- `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。
|
||||
|
||||
* TDengine 支持在使用[`systemd`](https://en.wikipedia.org/wiki/Systemd)做进程服务管理的linux系统上安装,用`which systemctl`命令来检测系统中是否存在`systemd`包:
|
||||
* TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd` 包:
|
||||
|
||||
```bash
|
||||
$ which systemctl
|
||||
```
|
||||
|
||||
如果系统中不支持systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。
|
||||
如果系统中不支持 systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。
|
||||
|
||||
|
||||
## <a class="anchor" id="console"></a>TDengine命令行程序
|
||||
|
|
|
@ -129,7 +129,7 @@ taosd -C
|
|||
- blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。(可通过 alter database 修改)
|
||||
- replica:副本个数,取值范围:1-3。单位为个,默认值:1。(可通过 alter database 修改)
|
||||
- precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms。
|
||||
- cacheLast:是否在内存中缓存子表 last_row,0:关闭;1:开启。默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
|
||||
- cacheLast:是否在内存中缓存子表的最近数据,0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值,3:同时打开缓存最近行和列功能,默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
|
||||
|
||||
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
|
||||
|
||||
|
|
|
@ -1,172 +1,172 @@
|
|||
# TDengine 2.0 错误码以及对应的十进制码
|
||||
|
||||
| 状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制) |
|
||||
|-----------------------| :---: | :---------: | :------------------------ | ---------------- |
|
||||
|TSDB_CODE_RPC_ACTION_IN_PROGRESS| 0 | 0x0001| "Action in progress"| -2147483647|
|
||||
|TSDB_CODE_RPC_AUTH_REQUIRED| 0 | 0x0002 | "Authentication required"| -2147483646|
|
||||
|TSDB_CODE_RPC_AUTH_FAILURE| 0| 0x0003 | "Authentication failure"| -2147483645|
|
||||
|TSDB_CODE_RPC_REDIRECT |0 | 0x0004| "Redirect"| -2147483644|
|
||||
|TSDB_CODE_RPC_NOT_READY| 0 | 0x0005 | "System not ready"| -2147483643|
|
||||
|TSDB_CODE_RPC_ALREADY_PROCESSED| 0 | 0x0006 |"Message already processed"| -2147483642|
|
||||
|TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED| 0 |0x0007| "Last session not finished"| -2147483641|
|
||||
|TSDB_CODE_RPC_MISMATCHED_LINK_ID| 0| 0x0008 | "Mismatched meter id"| -2147483640|
|
||||
|TSDB_CODE_RPC_TOO_SLOW| 0 | 0x0009 | "Processing of request timed out"| -2147483639|
|
||||
|TSDB_CODE_RPC_MAX_SESSIONS| 0 | 0x000A | "Number of sessions reached limit"| -2147483638|
|
||||
|TSDB_CODE_RPC_NETWORK_UNAVAIL| 0 |0x000B | "Unable to establish connection" |-2147483637|
|
||||
|TSDB_CODE_RPC_APP_ERROR| 0| 0x000C | "Unexpected generic error in RPC"| -2147483636|
|
||||
|TSDB_CODE_RPC_UNEXPECTED_RESPONSE| 0 |0x000D | "Unexpected response"| -2147483635|
|
||||
|TSDB_CODE_RPC_INVALID_VALUE| 0 | 0x000E | "Invalid value"| -2147483634|
|
||||
|TSDB_CODE_RPC_INVALID_TRAN_ID| 0 | 0x000F | "Invalid transaction id"| -2147483633|
|
||||
|TSDB_CODE_RPC_INVALID_SESSION_ID| 0| 0x0010 | "Invalid session id"| -2147483632|
|
||||
|TSDB_CODE_RPC_INVALID_MSG_TYPE| 0| 0x0011| "Invalid message type"| -2147483631|
|
||||
|TSDB_CODE_RPC_INVALID_RESPONSE_TYPE| 0 | 0x0012| "Invalid response type"| -2147483630|
|
||||
|TSDB_CODE_RPC_INVALID_TIME_STAMP| 0| 0x0013| "Invalid timestamp"| -2147483629|
|
||||
|TSDB_CODE_COM_OPS_NOT_SUPPORT| 0 | 0x0100| "Operation not supported"| -2147483392|
|
||||
|TSDB_CODE_COM_MEMORY_CORRUPTED |0| 0x0101 | "Memory corrupted"| -2147483391|
|
||||
|TSDB_CODE_COM_OUT_OF_MEMORY| 0| 0x0102| "Out of memory"| -2147483390|
|
||||
|TSDB_CODE_COM_INVALID_CFG_MSG| 0 | 0x0103| "Invalid config message"| -2147483389|
|
||||
|TSDB_CODE_COM_FILE_CORRUPTED| 0| 0x0104| "Data file corrupted" |-2147483388|
|
||||
|TSDB_CODE_TSC_INVALID_SQL| 0| 0x0200 | "Invalid SQL statement"| -2147483136|
|
||||
|TSDB_CODE_TSC_INVALID_QHANDLE| 0 | 0x0201 | "Invalid qhandle"| -2147483135|
|
||||
|TSDB_CODE_TSC_INVALID_TIME_STAMP| 0 | 0x0202 | "Invalid combination of client/service time"| -2147483134|
|
||||
|TSDB_CODE_TSC_INVALID_VALUE| 0 | 0x0203| "Invalid value in client"| -2147483133|
|
||||
|TSDB_CODE_TSC_INVALID_VERSION| 0 | 0x0204 | "Invalid client version" |-2147483132|
|
||||
|TSDB_CODE_TSC_INVALID_IE| 0 | 0x0205 | "Invalid client ie" |-2147483131|
|
||||
|TSDB_CODE_TSC_INVALID_FQDN| 0 | 0x0206| "Invalid host name"| -2147483130|
|
||||
|TSDB_CODE_TSC_INVALID_USER_LENGTH| 0 | 0x0207| "Invalid user name"| -2147483129|
|
||||
|TSDB_CODE_TSC_INVALID_PASS_LENGTH| 0 | 0x0208 | "Invalid password"| -2147483128|
|
||||
|TSDB_CODE_TSC_INVALID_DB_LENGTH| 0 | 0x0209| "Database name too long"| -2147483127|
|
||||
|TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH| 0 | 0x020A | "Table name too long"| -2147483126|
|
||||
|TSDB_CODE_TSC_INVALID_CONNECTION| 0 | 0x020B| "Invalid connection"| -2147483125|
|
||||
|TSDB_CODE_TSC_OUT_OF_MEMORY| 0 | 0x020C | "System out of memory" |-2147483124|
|
||||
|TSDB_CODE_TSC_NO_DISKSPACE| 0 | 0x020D | "System out of disk space"| -2147483123|
|
||||
|TSDB_CODE_TSC_QUERY_CACHE_ERASED| 0 | 0x020E| "Query cache erased"| -2147483122|
|
||||
|TSDB_CODE_TSC_QUERY_CANCELLED| 0 | 0x020F |"Query terminated"| -2147483121|
|
||||
|TSDB_CODE_TSC_SORTED_RES_TOO_MANY| 0 |0x0210 | "Result set too large to be sorted"| -2147483120|
|
||||
|TSDB_CODE_TSC_APP_ERROR| 0 | 0x0211 | "Application error"| -2147483119|
|
||||
|TSDB_CODE_TSC_ACTION_IN_PROGRESS| 0 |0x0212 | "Action in progress"| -2147483118|
|
||||
|TSDB_CODE_TSC_DISCONNECTED| 0 | 0x0213 |"Disconnected from service" |-2147483117|
|
||||
|TSDB_CODE_TSC_NO_WRITE_AUTH| 0 | 0x0214 | "No write permission" |-2147483116|
|
||||
|TSDB_CODE_MND_MSG_NOT_PROCESSED| 0| 0x0300| "Message not processed"| -2147482880|
|
||||
|TSDB_CODE_MND_ACTION_IN_PROGRESS| 0 | 0x0301 |"Message is progressing"| -2147482879|
|
||||
|TSDB_CODE_MND_ACTION_NEED_REPROCESSED| 0 | 0x0302 |"Messag need to be reprocessed"| -2147482878|
|
||||
|TSDB_CODE_MND_NO_RIGHTS| 0 | 0x0303| "Insufficient privilege for operation"| -2147482877|
|
||||
|TSDB_CODE_MND_APP_ERROR| 0 | 0x0304 | "Unexpected generic error in mnode"| -2147482876|
|
||||
|TSDB_CODE_MND_INVALID_CONNECTION| 0 | 0x0305 | "Invalid message connection"| -2147482875|
|
||||
|TSDB_CODE_MND_INVALID_MSG_VERSION| 0 | 0x0306 | "Incompatible protocol version"| -2147482874|
|
||||
|TSDB_CODE_MND_INVALID_MSG_LEN| 0| 0x0307 | "Invalid message length"| -2147482873|
|
||||
|TSDB_CODE_MND_INVALID_MSG_TYPE| 0 | 0x0308 | "Invalid message type" |-2147482872|
|
||||
|TSDB_CODE_MND_TOO_MANY_SHELL_CONNS| 0 |0x0309 | "Too many connections"| -2147482871|
|
||||
|TSDB_CODE_MND_OUT_OF_MEMORY| 0 |0x030A | "Out of memory in mnode"| -2147482870|
|
||||
|TSDB_CODE_MND_INVALID_SHOWOBJ| 0 | 0x030B |"Data expired"| -2147482869|
|
||||
|TSDB_CODE_MND_INVALID_QUERY_ID |0 | 0x030C |"Invalid query id" |-2147482868|
|
||||
|TSDB_CODE_MND_INVALID_STREAM_ID| 0 |0x030D | "Invalid stream id"| -2147482867|
|
||||
|TSDB_CODE_MND_INVALID_CONN_ID| 0| 0x030E | "Invalid connection id" |-2147482866|
|
||||
|TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE| 0 | 0x0320| "Object already there"| -2147482848|
|
||||
|TSDB_CODE_MND_SDB_ERROR| 0 |0x0321 | "Unexpected generic error in sdb" |-2147482847|
|
||||
|TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE| 0 | 0x0322| "Invalid table type" |-2147482846|
|
||||
|TSDB_CODE_MND_SDB_OBJ_NOT_THERE| 0 | 0x0323 |"Object not there" |-2147482845|
|
||||
|TSDB_CODE_MND_SDB_INVAID_META_ROW| 0 | 0x0324| "Invalid meta row" |-2147482844|
|
||||
|TSDB_CODE_MND_SDB_INVAID_KEY_TYPE| 0 | 0x0325 |"Invalid key type" |-2147482843|
|
||||
|TSDB_CODE_MND_DNODE_ALREADY_EXIST| 0 | 0x0330 | "DNode already exists"| -2147482832|
|
||||
|TSDB_CODE_MND_DNODE_NOT_EXIST| 0 | 0x0331| "DNode does not exist" |-2147482831|
|
||||
|TSDB_CODE_MND_VGROUP_NOT_EXIST| 0 | 0x0332 |"VGroup does not exist"| -2147482830|
|
||||
|TSDB_CODE_MND_NO_REMOVE_MASTER |0 | 0x0333 | "Master DNode cannot be removed"| -2147482829|
|
||||
|TSDB_CODE_MND_NO_ENOUGH_DNODES |0 | 0x0334| "Out of DNodes"| -2147482828|
|
||||
|TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT |0 | 0x0335 | "Cluster cfg inconsistent"| -2147482827|
|
||||
|TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION| 0 | 0x0336 | "Invalid dnode cfg option"| -2147482826|
|
||||
|TSDB_CODE_MND_BALANCE_ENABLED| 0 | 0x0337 | "Balance already enabled" |-2147482825|
|
||||
|TSDB_CODE_MND_VGROUP_NOT_IN_DNODE| 0 |0x0338 | "Vgroup not in dnode"| -2147482824|
|
||||
|TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE| 0 | 0x0339 | "Vgroup already in dnode"| -2147482823|
|
||||
|TSDB_CODE_MND_DNODE_NOT_FREE |0 | 0x033A |"Dnode not avaliable"| -2147482822|
|
||||
|TSDB_CODE_MND_INVALID_CLUSTER_ID |0 |0x033B | "Cluster id not match"| -2147482821|
|
||||
|TSDB_CODE_MND_NOT_READY| 0 | 0x033C |"Cluster not ready"| -2147482820|
|
||||
|TSDB_CODE_MND_ACCT_ALREADY_EXIST| 0 | 0x0340 | "Account already exists" |-2147482816|
|
||||
|TSDB_CODE_MND_INVALID_ACCT| 0 | 0x0341| "Invalid account"| -2147482815|
|
||||
|TSDB_CODE_MND_INVALID_ACCT_OPTION| 0 | 0x0342 | "Invalid account options"| -2147482814|
|
||||
|TSDB_CODE_MND_USER_ALREADY_EXIST| 0 | 0x0350 | "User already exists"| -2147482800|
|
||||
|TSDB_CODE_MND_INVALID_USER |0 | 0x0351 | "Invalid user" |-2147482799|
|
||||
|TSDB_CODE_MND_INVALID_USER_FORMAT| 0 |0x0352 |"Invalid user format" |-2147482798|
|
||||
|TSDB_CODE_MND_INVALID_PASS_FORMAT| 0| 0x0353 | "Invalid password format"| -2147482797|
|
||||
|TSDB_CODE_MND_NO_USER_FROM_CONN| 0 | 0x0354 | "Can not get user from conn"| -2147482796|
|
||||
|TSDB_CODE_MND_TOO_MANY_USERS| 0 | 0x0355| "Too many users"| -2147482795|
|
||||
|TSDB_CODE_MND_TABLE_ALREADY_EXIST| 0| 0x0360| "Table already exists"| -2147482784|
|
||||
|TSDB_CODE_MND_INVALID_TABLE_ID| 0| 0x0361| "Table name too long"| -2147482783|
|
||||
|TSDB_CODE_MND_INVALID_TABLE_NAME| 0| 0x0362 | "Table does not exist"| -2147482782|
|
||||
|TSDB_CODE_MND_INVALID_TABLE_TYPE| 0| 0x0363 | "Invalid table type in tsdb"| -2147482781|
|
||||
|TSDB_CODE_MND_TOO_MANY_TAGS| 0 | 0x0364| "Too many tags"| -2147482780|
|
||||
|TSDB_CODE_MND_TOO_MANY_TIMESERIES| 0| 0x0366| "Too many time series"| -2147482778|
|
||||
|TSDB_CODE_MND_NOT_SUPER_TABLE| 0 |0x0367| "Not super table"| -2147482777|
|
||||
|TSDB_CODE_MND_COL_NAME_TOO_LONG| 0| 0x0368| "Tag name too long"| -2147482776|
|
||||
|TSDB_CODE_MND_TAG_ALREAY_EXIST| 0| 0x0369| "Tag already exists"| -2147482775|
|
||||
|TSDB_CODE_MND_TAG_NOT_EXIST| 0 |0x036A | "Tag does not exist" |-2147482774|
|
||||
|TSDB_CODE_MND_FIELD_ALREAY_EXIST| 0 | 0x036B| "Field already exists"| -2147482773|
|
||||
|TSDB_CODE_MND_FIELD_NOT_EXIST| 0 | 0x036C | "Field does not exist"| -2147482772|
|
||||
|TSDB_CODE_MND_INVALID_STABLE_NAME |0 | 0x036D |"Super table does not exist" |-2147482771|
|
||||
|TSDB_CODE_MND_DB_NOT_SELECTED| 0 | 0x0380 | "Database not specified or available"| -2147482752|
|
||||
|TSDB_CODE_MND_DB_ALREADY_EXIST| 0 | 0x0381 | "Database already exists"| -2147482751|
|
||||
|TSDB_CODE_MND_INVALID_DB_OPTION| 0 | 0x0382 | "Invalid database options"| -2147482750|
|
||||
|TSDB_CODE_MND_INVALID_DB| 0 | 0x0383 | "Invalid database name"| -2147482749|
|
||||
|TSDB_CODE_MND_MONITOR_DB_FORBIDDEN| 0 | 0x0384 | "Cannot delete monitor database"| -2147482748|
|
||||
|TSDB_CODE_MND_TOO_MANY_DATABASES| 0| 0x0385 | "Too many databases for account"| -2147482747|
|
||||
|TSDB_CODE_MND_DB_IN_DROPPING| 0 | 0x0386| "Database not available" |-2147482746|
|
||||
|TSDB_CODE_DND_MSG_NOT_PROCESSED| 0| 0x0400 | "Message not processed"| -2147482624|
|
||||
|TSDB_CODE_DND_OUT_OF_MEMORY |0 | 0x0401 | "Dnode out of memory"| -2147482623|
|
||||
|TSDB_CODE_DND_NO_WRITE_ACCESS| 0 | 0x0402 | "No permission for disk files in dnode"| -2147482622|
|
||||
|TSDB_CODE_DND_INVALID_MSG_LEN| 0 | 0x0403 | "Invalid message length"| -2147482621|
|
||||
|TSDB_CODE_VND_ACTION_IN_PROGRESS |0 |0x0500| "Action in progress" |-2147482368|
|
||||
|TSDB_CODE_VND_MSG_NOT_PROCESSED| 0 |0x0501 | "Message not processed" |-2147482367|
|
||||
|TSDB_CODE_VND_ACTION_NEED_REPROCESSED |0 |0x0502| "Action need to be reprocessed"| -2147482366|
|
||||
|TSDB_CODE_VND_INVALID_VGROUP_ID |0 | 0x0503| "Invalid Vgroup ID"| -2147482365|
|
||||
|TSDB_CODE_VND_INIT_FAILED| 0 | 0x0504 | "Vnode initialization failed"| -2147482364|
|
||||
|TSDB_CODE_VND_NO_DISKSPACE| 0 |0x0505| "System out of disk space" |-2147482363|
|
||||
|TSDB_CODE_VND_NO_DISK_PERMISSIONS| 0 | 0x0506| "No write permission for disk files" |-2147482362|
|
||||
|TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR| 0 | 0x0507 | "Missing data file"| -2147482361|
|
||||
|TSDB_CODE_VND_OUT_OF_MEMORY |0| 0x0508 | "Out of memory"| -2147482360|
|
||||
|TSDB_CODE_VND_APP_ERROR| 0| 0x0509 | "Unexpected generic error in vnode"| -2147482359|
|
||||
|TSDB_CODE_VND_INVALID_STATUS |0| 0x0510 | "Database not ready"| -2147482352|
|
||||
|TSDB_CODE_VND_NOT_SYNCED| 0 | 0x0511 | "Database suspended"| -2147482351|
|
||||
|TSDB_CODE_VND_NO_WRITE_AUTH| 0 | 0x0512| "Write operation denied" |-2147482350|
|
||||
|TSDB_CODE_TDB_INVALID_TABLE_ID |0 | 0x0600 | "Invalid table ID"| -2147482112|
|
||||
|TSDB_CODE_TDB_INVALID_TABLE_TYPE| 0| 0x0601 |"Invalid table type"| -2147482111|
|
||||
|TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION| 0| 0x0602| "Invalid table schema version"| -2147482110|
|
||||
|TSDB_CODE_TDB_TABLE_ALREADY_EXIST| 0 | 0x0603| "Table already exists"| -2147482109|
|
||||
|TSDB_CODE_TDB_INVALID_CONFIG| 0 | 0x0604| "Invalid configuration"| -2147482108|
|
||||
|TSDB_CODE_TDB_INIT_FAILED| 0 | 0x0605| "Tsdb init failed"| -2147482107|
|
||||
|TSDB_CODE_TDB_NO_DISKSPACE| 0 | 0x0606| "No diskspace for tsdb"| -2147482106|
|
||||
|TSDB_CODE_TDB_NO_DISK_PERMISSIONS| 0 | 0x0607| "No permission for disk files"| -2147482105|
|
||||
|TSDB_CODE_TDB_FILE_CORRUPTED| 0 | 0x0608| "Data file(s) corrupted"| -2147482104|
|
||||
|TSDB_CODE_TDB_OUT_OF_MEMORY| 0 | 0x0609| "Out of memory"| -2147482103|
|
||||
|TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE| 0 | 0x060A| "Tag too old"| -2147482102|
|
||||
|TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE |0| 0x060B | "Timestamp data out of range"| -2147482101|
|
||||
|TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP| 0| 0x060C| "Submit message is messed up"| -2147482100|
|
||||
|TSDB_CODE_TDB_INVALID_ACTION| 0 | 0x060D | "Invalid operation"| -2147482099|
|
||||
|TSDB_CODE_TDB_INVALID_CREATE_TB_MSG| 0 | 0x060E| "Invalid creation of table"| -2147482098|
|
||||
|TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM| 0 | 0x060F| "No table data in memory skiplist" |-2147482097|
|
||||
|TSDB_CODE_TDB_FILE_ALREADY_EXISTS| 0 | 0x0610| "File already exists"| -2147482096|
|
||||
|TSDB_CODE_TDB_TABLE_RECONFIGURE| 0 | 0x0611| "Need to reconfigure table"| -2147482095|
|
||||
|TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO| 0 | 0x0612| "Invalid information to create table"| -2147482094|
|
||||
|TSDB_CODE_QRY_INVALID_QHANDLE| 0 | 0x0700| "Invalid handle"| -2147481856|
|
||||
|TSDB_CODE_QRY_INVALID_MSG| 0 | 0x0701| "Invalid message"| -2147481855|
|
||||
|TSDB_CODE_QRY_NO_DISKSPACE| 0 | 0x0702 | "No diskspace for query"| -2147481854|
|
||||
|TSDB_CODE_QRY_OUT_OF_MEMORY| 0 | 0x0703 | "System out of memory"| -2147481853|
|
||||
|TSDB_CODE_QRY_APP_ERROR| 0 | 0x0704 | "Unexpected generic error in query"| -2147481852|
|
||||
|TSDB_CODE_QRY_DUP_JOIN_KEY| 0 | 0x0705| "Duplicated join key"| -2147481851|
|
||||
|TSDB_CODE_QRY_EXCEED_TAGS_LIMIT| 0 | 0x0706 | "Tag conditon too many"| -2147481850|
|
||||
|TSDB_CODE_QRY_NOT_READY |0| 0x0707 | "Query not ready" |-2147481849|
|
||||
|TSDB_CODE_QRY_HAS_RSP| 0 | 0x0708| "Query should response"| -2147481848|
|
||||
|TSDB_CODE_GRANT_EXPIRED| 0 | 0x0800| "License expired"| -2147481600|
|
||||
|TSDB_CODE_GRANT_DNODE_LIMITED| 0 | 0x0801 | "DNode creation limited by licence"| -2147481599|
|
||||
|TSDB_CODE_GRANT_ACCT_LIMITED |0| 0x0802 |"Account creation limited by license"| -2147481598|
|
||||
|TSDB_CODE_GRANT_TIMESERIES_LIMITED| 0 | 0x0803 | "Table creation limited by license"| -2147481597|
|
||||
|TSDB_CODE_GRANT_DB_LIMITED| 0 | 0x0804 | "DB creation limited by license"| -2147481596|
|
||||
|TSDB_CODE_GRANT_USER_LIMITED| 0 | 0x0805 | "User creation limited by license"| -2147481595|
|
||||
|TSDB_CODE_GRANT_CONN_LIMITED| 0| 0x0806 | "Conn creation limited by license" |-2147481594|
|
||||
|TSDB_CODE_GRANT_STREAM_LIMITED| 0 | 0x0807 | "Stream creation limited by license"| -2147481593|
|
||||
|TSDB_CODE_GRANT_SPEED_LIMITED| 0 | 0x0808 | "Write speed limited by license" |-2147481592|
|
||||
|TSDB_CODE_GRANT_STORAGE_LIMITED| 0 |0x0809 | "Storage capacity limited by license"| -2147481591|
|
||||
|TSDB_CODE_GRANT_QUERYTIME_LIMITED| 0 | 0x080A | "Query time limited by license" |-2147481590|
|
||||
|TSDB_CODE_GRANT_CPU_LIMITED| 0 |0x080B |"CPU cores limited by license"| -2147481589|
|
||||
|TSDB_CODE_SYN_INVALID_CONFIG| 0 | 0x0900| "Invalid Sync Configuration"| -2147481344|
|
||||
|TSDB_CODE_SYN_NOT_ENABLED| 0 | 0x0901 | "Sync module not enabled" |-2147481343|
|
||||
|TSDB_CODE_WAL_APP_ERROR| 0| 0x1000 | "Unexpected generic error in wal" |-2147479552|
|
||||
| 状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制) |
|
||||
| :-------------------------------------- | :--: | :----------------: | :------------------------------------------- | :--------------- |
|
||||
| TSDB_CODE_RPC_ACTION_IN_PROGRESS | 0 | 0x0001 | "Action in progress" | -2147483647 |
|
||||
| TSDB_CODE_RPC_AUTH_REQUIRED | 0 | 0x0002 | "Authentication required" | -2147483646 |
|
||||
| TSDB_CODE_RPC_AUTH_FAILURE | 0 | 0x0003 | "Authentication failure" | -2147483645 |
|
||||
| TSDB_CODE_RPC_REDIRECT | 0 | 0x0004 | "Redirect" | -2147483644 |
|
||||
| TSDB_CODE_RPC_NOT_READY | 0 | 0x0005 | "System not ready" | -2147483643 |
|
||||
| TSDB_CODE_RPC_ALREADY_PROCESSED | 0 | 0x0006 | "Message already processed" | -2147483642 |
|
||||
| TSDB_CODE_RPC_LAST_SESSION_NOT_FINISHED | 0 | 0x0007 | "Last session not finished" | -2147483641 |
|
||||
| TSDB_CODE_RPC_MISMATCHED_LINK_ID | 0 | 0x0008 | "Mismatched meter id" | -2147483640 |
|
||||
| TSDB_CODE_RPC_TOO_SLOW | 0 | 0x0009 | "Processing of request timed out" | -2147483639 |
|
||||
| TSDB_CODE_RPC_MAX_SESSIONS | 0 | 0x000A | "Number of sessions reached limit" | -2147483638 |
|
||||
| TSDB_CODE_RPC_NETWORK_UNAVAIL | 0 | 0x000B | "Unable to establish connection" | -2147483637 |
|
||||
| TSDB_CODE_RPC_APP_ERROR | 0 | 0x000C | "Unexpected generic error in RPC" | -2147483636 |
|
||||
| TSDB_CODE_RPC_UNEXPECTED_RESPONSE | 0 | 0x000D | "Unexpected response" | -2147483635 |
|
||||
| TSDB_CODE_RPC_INVALID_VALUE | 0 | 0x000E | "Invalid value" | -2147483634 |
|
||||
| TSDB_CODE_RPC_INVALID_TRAN_ID | 0 | 0x000F | "Invalid transaction id" | -2147483633 |
|
||||
| TSDB_CODE_RPC_INVALID_SESSION_ID | 0 | 0x0010 | "Invalid session id" | -2147483632 |
|
||||
| TSDB_CODE_RPC_INVALID_MSG_TYPE | 0 | 0x0011 | "Invalid message type" | -2147483631 |
|
||||
| TSDB_CODE_RPC_INVALID_RESPONSE_TYPE | 0 | 0x0012 | "Invalid response type" | -2147483630 |
|
||||
| TSDB_CODE_RPC_INVALID_TIME_STAMP | 0 | 0x0013 | "Invalid timestamp" | -2147483629 |
|
||||
| TSDB_CODE_COM_OPS_NOT_SUPPORT | 0 | 0x0100 | "Operation not supported" | -2147483392 |
|
||||
| TSDB_CODE_COM_MEMORY_CORRUPTED | 0 | 0x0101 | "Memory corrupted" | -2147483391 |
|
||||
| TSDB_CODE_COM_OUT_OF_MEMORY | 0 | 0x0102 | "Out of memory" | -2147483390 |
|
||||
| TSDB_CODE_COM_INVALID_CFG_MSG | 0 | 0x0103 | "Invalid config message" | -2147483389 |
|
||||
| TSDB_CODE_COM_FILE_CORRUPTED | 0 | 0x0104 | "Data file corrupted" | -2147483388 |
|
||||
| TSDB_CODE_TSC_INVALID_OPERATION | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 |
|
||||
| TSDB_CODE_TSC_INVALID_QHANDLE | 0 | 0x0201 | "Invalid qhandle" | -2147483135 |
|
||||
| TSDB_CODE_TSC_INVALID_TIME_STAMP | 0 | 0x0202 | "Invalid combination of client/service time" | -2147483134 |
|
||||
| TSDB_CODE_TSC_INVALID_VALUE | 0 | 0x0203 | "Invalid value in client" | -2147483133 |
|
||||
| TSDB_CODE_TSC_INVALID_VERSION | 0 | 0x0204 | "Invalid client version" | -2147483132 |
|
||||
| TSDB_CODE_TSC_INVALID_IE | 0 | 0x0205 | "Invalid client ie" | -2147483131 |
|
||||
| TSDB_CODE_TSC_INVALID_FQDN | 0 | 0x0206 | "Invalid host name" | -2147483130 |
|
||||
| TSDB_CODE_TSC_INVALID_USER_LENGTH | 0 | 0x0207 | "Invalid user name" | -2147483129 |
|
||||
| TSDB_CODE_TSC_INVALID_PASS_LENGTH | 0 | 0x0208 | "Invalid password" | -2147483128 |
|
||||
| TSDB_CODE_TSC_INVALID_DB_LENGTH | 0 | 0x0209 | "Database name too long" | -2147483127 |
|
||||
| TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH | 0 | 0x020A | "Table name too long" | -2147483126 |
|
||||
| TSDB_CODE_TSC_INVALID_CONNECTION | 0 | 0x020B | "Invalid connection" | -2147483125 |
|
||||
| TSDB_CODE_TSC_OUT_OF_MEMORY | 0 | 0x020C | "System out of memory" | -2147483124 |
|
||||
| TSDB_CODE_TSC_NO_DISKSPACE | 0 | 0x020D | "System out of disk space" | -2147483123 |
|
||||
| TSDB_CODE_TSC_QUERY_CACHE_ERASED | 0 | 0x020E | "Query cache erased" | -2147483122 |
|
||||
| TSDB_CODE_TSC_QUERY_CANCELLED | 0 | 0x020F | "Query terminated" | -2147483121 |
|
||||
| TSDB_CODE_TSC_SORTED_RES_TOO_MANY | 0 | 0x0210 | "Result set too large to be sorted" | -2147483120 |
|
||||
| TSDB_CODE_TSC_APP_ERROR | 0 | 0x0211 | "Application error" | -2147483119 |
|
||||
| TSDB_CODE_TSC_ACTION_IN_PROGRESS | 0 | 0x0212 | "Action in progress" | -2147483118 |
|
||||
| TSDB_CODE_TSC_DISCONNECTED | 0 | 0x0213 | "Disconnected from service" | -2147483117 |
|
||||
| TSDB_CODE_TSC_NO_WRITE_AUTH | 0 | 0x0214 | "No write permission" | -2147483116 |
|
||||
| TSDB_CODE_MND_MSG_NOT_PROCESSED | 0 | 0x0300 | "Message not processed" | -2147482880 |
|
||||
| TSDB_CODE_MND_ACTION_IN_PROGRESS | 0 | 0x0301 | "Message is progressing" | -2147482879 |
|
||||
| TSDB_CODE_MND_ACTION_NEED_REPROCESSED | 0 | 0x0302 | "Messag need to be reprocessed" | -2147482878 |
|
||||
| TSDB_CODE_MND_NO_RIGHTS | 0 | 0x0303 | "Insufficient privilege for operation" | -2147482877 |
|
||||
| TSDB_CODE_MND_APP_ERROR | 0 | 0x0304 | "Unexpected generic error in mnode" | -2147482876 |
|
||||
| TSDB_CODE_MND_INVALID_CONNECTION | 0 | 0x0305 | "Invalid message connection" | -2147482875 |
|
||||
| TSDB_CODE_MND_INVALID_MSG_VERSION | 0 | 0x0306 | "Incompatible protocol version" | -2147482874 |
|
||||
| TSDB_CODE_MND_INVALID_MSG_LEN | 0 | 0x0307 | "Invalid message length" | -2147482873 |
|
||||
| TSDB_CODE_MND_INVALID_MSG_TYPE | 0 | 0x0308 | "Invalid message type" | -2147482872 |
|
||||
| TSDB_CODE_MND_TOO_MANY_SHELL_CONNS | 0 | 0x0309 | "Too many connections" | -2147482871 |
|
||||
| TSDB_CODE_MND_OUT_OF_MEMORY | 0 | 0x030A | "Out of memory in mnode" | -2147482870 |
|
||||
| TSDB_CODE_MND_INVALID_SHOWOBJ | 0 | 0x030B | "Data expired" | -2147482869 |
|
||||
| TSDB_CODE_MND_INVALID_QUERY_ID | 0 | 0x030C | "Invalid query id" | -2147482868 |
|
||||
| TSDB_CODE_MND_INVALID_STREAM_ID | 0 | 0x030D | "Invalid stream id" | -2147482867 |
|
||||
| TSDB_CODE_MND_INVALID_CONN_ID | 0 | 0x030E | "Invalid connection id" | -2147482866 |
|
||||
| TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE | 0 | 0x0320 | "Object already there" | -2147482848 |
|
||||
| TSDB_CODE_MND_SDB_ERROR | 0 | 0x0321 | "Unexpected generic error in sdb" | -2147482847 |
|
||||
| TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE | 0 | 0x0322 | "Invalid table type" | -2147482846 |
|
||||
| TSDB_CODE_MND_SDB_OBJ_NOT_THERE | 0 | 0x0323 | "Object not there" | -2147482845 |
|
||||
| TSDB_CODE_MND_SDB_INVAID_META_ROW | 0 | 0x0324 | "Invalid meta row" | -2147482844 |
|
||||
| TSDB_CODE_MND_SDB_INVAID_KEY_TYPE | 0 | 0x0325 | "Invalid key type" | -2147482843 |
|
||||
| TSDB_CODE_MND_DNODE_ALREADY_EXIST | 0 | 0x0330 | "DNode already exists" | -2147482832 |
|
||||
| TSDB_CODE_MND_DNODE_NOT_EXIST | 0 | 0x0331 | "DNode does not exist" | -2147482831 |
|
||||
| TSDB_CODE_MND_VGROUP_NOT_EXIST | 0 | 0x0332 | "VGroup does not exist" | -2147482830 |
|
||||
| TSDB_CODE_MND_NO_REMOVE_MASTER | 0 | 0x0333 | "Master DNode cannot be removed" | -2147482829 |
|
||||
| TSDB_CODE_MND_NO_ENOUGH_DNODES | 0 | 0x0334 | "Out of DNodes" | -2147482828 |
|
||||
| TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT | 0 | 0x0335 | "Cluster cfg inconsistent" | -2147482827 |
|
||||
| TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION | 0 | 0x0336 | "Invalid dnode cfg option" | -2147482826 |
|
||||
| TSDB_CODE_MND_BALANCE_ENABLED | 0 | 0x0337 | "Balance already enabled" | -2147482825 |
|
||||
| TSDB_CODE_MND_VGROUP_NOT_IN_DNODE | 0 | 0x0338 | "Vgroup not in dnode" | -2147482824 |
|
||||
| TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE | 0 | 0x0339 | "Vgroup already in dnode" | -2147482823 |
|
||||
| TSDB_CODE_MND_DNODE_NOT_FREE | 0 | 0x033A | "Dnode not avaliable" | -2147482822 |
|
||||
| TSDB_CODE_MND_INVALID_CLUSTER_ID | 0 | 0x033B | "Cluster id not match" | -2147482821 |
|
||||
| TSDB_CODE_MND_NOT_READY | 0 | 0x033C | "Cluster not ready" | -2147482820 |
|
||||
| TSDB_CODE_MND_ACCT_ALREADY_EXIST | 0 | 0x0340 | "Account already exists" | -2147482816 |
|
||||
| TSDB_CODE_MND_INVALID_ACCT | 0 | 0x0341 | "Invalid account" | -2147482815 |
|
||||
| TSDB_CODE_MND_INVALID_ACCT_OPTION | 0 | 0x0342 | "Invalid account options" | -2147482814 |
|
||||
| TSDB_CODE_MND_USER_ALREADY_EXIST | 0 | 0x0350 | "User already exists" | -2147482800 |
|
||||
| TSDB_CODE_MND_INVALID_USER | 0 | 0x0351 | "Invalid user" | -2147482799 |
|
||||
| TSDB_CODE_MND_INVALID_USER_FORMAT | 0 | 0x0352 | "Invalid user format" | -2147482798 |
|
||||
| TSDB_CODE_MND_INVALID_PASS_FORMAT | 0 | 0x0353 | "Invalid password format" | -2147482797 |
|
||||
| TSDB_CODE_MND_NO_USER_FROM_CONN | 0 | 0x0354 | "Can not get user from conn" | -2147482796 |
|
||||
| TSDB_CODE_MND_TOO_MANY_USERS | 0 | 0x0355 | "Too many users" | -2147482795 |
|
||||
| TSDB_CODE_MND_TABLE_ALREADY_EXIST | 0 | 0x0360 | "Table already exists" | -2147482784 |
|
||||
| TSDB_CODE_MND_INVALID_TABLE_ID | 0 | 0x0361 | "Table name too long" | -2147482783 |
|
||||
| TSDB_CODE_MND_INVALID_TABLE_NAME | 0 | 0x0362 | "Table does not exist" | -2147482782 |
|
||||
| TSDB_CODE_MND_INVALID_TABLE_TYPE | 0 | 0x0363 | "Invalid table type in tsdb" | -2147482781 |
|
||||
| TSDB_CODE_MND_TOO_MANY_TAGS | 0 | 0x0364 | "Too many tags" | -2147482780 |
|
||||
| TSDB_CODE_MND_TOO_MANY_TIMESERIES | 0 | 0x0366 | "Too many time series" | -2147482778 |
|
||||
| TSDB_CODE_MND_NOT_SUPER_TABLE | 0 | 0x0367 | "Not super table" | -2147482777 |
|
||||
| TSDB_CODE_MND_COL_NAME_TOO_LONG | 0 | 0x0368 | "Tag name too long" | -2147482776 |
|
||||
| TSDB_CODE_MND_TAG_ALREAY_EXIST | 0 | 0x0369 | "Tag already exists" | -2147482775 |
|
||||
| TSDB_CODE_MND_TAG_NOT_EXIST | 0 | 0x036A | "Tag does not exist" | -2147482774 |
|
||||
| TSDB_CODE_MND_FIELD_ALREAY_EXIST | 0 | 0x036B | "Field already exists" | -2147482773 |
|
||||
| TSDB_CODE_MND_FIELD_NOT_EXIST | 0 | 0x036C | "Field does not exist" | -2147482772 |
|
||||
| TSDB_CODE_MND_INVALID_STABLE_NAME | 0 | 0x036D | "Super table does not exist" | -2147482771 |
|
||||
| TSDB_CODE_MND_DB_NOT_SELECTED | 0 | 0x0380 | "Database not specified or available" | -2147482752 |
|
||||
| TSDB_CODE_MND_DB_ALREADY_EXIST | 0 | 0x0381 | "Database already exists" | -2147482751 |
|
||||
| TSDB_CODE_MND_INVALID_DB_OPTION | 0 | 0x0382 | "Invalid database options" | -2147482750 |
|
||||
| TSDB_CODE_MND_INVALID_DB | 0 | 0x0383 | "Invalid database name" | -2147482749 |
|
||||
| TSDB_CODE_MND_MONITOR_DB_FORBIDDEN | 0 | 0x0384 | "Cannot delete monitor database" | -2147482748 |
|
||||
| TSDB_CODE_MND_TOO_MANY_DATABASES | 0 | 0x0385 | "Too many databases for account" | -2147482747 |
|
||||
| TSDB_CODE_MND_DB_IN_DROPPING | 0 | 0x0386 | "Database not available" | -2147482746 |
|
||||
| TSDB_CODE_DND_MSG_NOT_PROCESSED | 0 | 0x0400 | "Message not processed" | -2147482624 |
|
||||
| TSDB_CODE_DND_OUT_OF_MEMORY | 0 | 0x0401 | "Dnode out of memory" | -2147482623 |
|
||||
| TSDB_CODE_DND_NO_WRITE_ACCESS | 0 | 0x0402 | "No permission for disk files in dnode" | -2147482622 |
|
||||
| TSDB_CODE_DND_INVALID_MSG_LEN | 0 | 0x0403 | "Invalid message length" | -2147482621 |
|
||||
| TSDB_CODE_VND_ACTION_IN_PROGRESS | 0 | 0x0500 | "Action in progress" | -2147482368 |
|
||||
| TSDB_CODE_VND_MSG_NOT_PROCESSED | 0 | 0x0501 | "Message not processed" | -2147482367 |
|
||||
| TSDB_CODE_VND_ACTION_NEED_REPROCESSED | 0 | 0x0502 | "Action need to be reprocessed" | -2147482366 |
|
||||
| TSDB_CODE_VND_INVALID_VGROUP_ID | 0 | 0x0503 | "Invalid Vgroup ID" | -2147482365 |
|
||||
| TSDB_CODE_VND_INIT_FAILED | 0 | 0x0504 | "Vnode initialization failed" | -2147482364 |
|
||||
| TSDB_CODE_VND_NO_DISKSPACE | 0 | 0x0505 | "System out of disk space" | -2147482363 |
|
||||
| TSDB_CODE_VND_NO_DISK_PERMISSIONS | 0 | 0x0506 | "No write permission for disk files" | -2147482362 |
|
||||
| TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR | 0 | 0x0507 | "Missing data file" | -2147482361 |
|
||||
| TSDB_CODE_VND_OUT_OF_MEMORY | 0 | 0x0508 | "Out of memory" | -2147482360 |
|
||||
| TSDB_CODE_VND_APP_ERROR | 0 | 0x0509 | "Unexpected generic error in vnode" | -2147482359 |
|
||||
| TSDB_CODE_VND_INVALID_STATUS | 0 | 0x0510 | "Database not ready" | -2147482352 |
|
||||
| TSDB_CODE_VND_NOT_SYNCED | 0 | 0x0511 | "Database suspended" | -2147482351 |
|
||||
| TSDB_CODE_VND_NO_WRITE_AUTH | 0 | 0x0512 | "Write operation denied" | -2147482350 |
|
||||
| TSDB_CODE_TDB_INVALID_TABLE_ID | 0 | 0x0600 | "Invalid table ID" | -2147482112 |
|
||||
| TSDB_CODE_TDB_INVALID_TABLE_TYPE | 0 | 0x0601 | "Invalid table type" | -2147482111 |
|
||||
| TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION | 0 | 0x0602 | "Invalid table schema version" | -2147482110 |
|
||||
| TSDB_CODE_TDB_TABLE_ALREADY_EXIST | 0 | 0x0603 | "Table already exists" | -2147482109 |
|
||||
| TSDB_CODE_TDB_INVALID_CONFIG | 0 | 0x0604 | "Invalid configuration" | -2147482108 |
|
||||
| TSDB_CODE_TDB_INIT_FAILED | 0 | 0x0605 | "Tsdb init failed" | -2147482107 |
|
||||
| TSDB_CODE_TDB_NO_DISKSPACE | 0 | 0x0606 | "No diskspace for tsdb" | -2147482106 |
|
||||
| TSDB_CODE_TDB_NO_DISK_PERMISSIONS | 0 | 0x0607 | "No permission for disk files" | -2147482105 |
|
||||
| TSDB_CODE_TDB_FILE_CORRUPTED | 0 | 0x0608 | "Data file(s) corrupted" | -2147482104 |
|
||||
| TSDB_CODE_TDB_OUT_OF_MEMORY | 0 | 0x0609 | "Out of memory" | -2147482103 |
|
||||
| TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE | 0 | 0x060A | "Tag too old" | -2147482102 |
|
||||
| TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE | 0 | 0x060B | "Timestamp data out of range" | -2147482101 |
|
||||
| TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP | 0 | 0x060C | "Submit message is messed up" | -2147482100 |
|
||||
| TSDB_CODE_TDB_INVALID_ACTION | 0 | 0x060D | "Invalid operation" | -2147482099 |
|
||||
| TSDB_CODE_TDB_INVALID_CREATE_TB_MSG | 0 | 0x060E | "Invalid creation of table" | -2147482098 |
|
||||
| TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM | 0 | 0x060F | "No table data in memory skiplist" | -2147482097 |
|
||||
| TSDB_CODE_TDB_FILE_ALREADY_EXISTS | 0 | 0x0610 | "File already exists" | -2147482096 |
|
||||
| TSDB_CODE_TDB_TABLE_RECONFIGURE | 0 | 0x0611 | "Need to reconfigure table" | -2147482095 |
|
||||
| TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO | 0 | 0x0612 | "Invalid information to create table" | -2147482094 |
|
||||
| TSDB_CODE_QRY_INVALID_QHANDLE | 0 | 0x0700 | "Invalid handle" | -2147481856 |
|
||||
| TSDB_CODE_QRY_INVALID_MSG | 0 | 0x0701 | "Invalid message" | -2147481855 |
|
||||
| TSDB_CODE_QRY_NO_DISKSPACE | 0 | 0x0702 | "No diskspace for query" | -2147481854 |
|
||||
| TSDB_CODE_QRY_OUT_OF_MEMORY | 0 | 0x0703 | "System out of memory" | -2147481853 |
|
||||
| TSDB_CODE_QRY_APP_ERROR | 0 | 0x0704 | "Unexpected generic error in query" | -2147481852 |
|
||||
| TSDB_CODE_QRY_DUP_JOIN_KEY | 0 | 0x0705 | "Duplicated join key" | -2147481851 |
|
||||
| TSDB_CODE_QRY_EXCEED_TAGS_LIMIT | 0 | 0x0706 | "Tag conditon too many" | -2147481850 |
|
||||
| TSDB_CODE_QRY_NOT_READY | 0 | 0x0707 | "Query not ready" | -2147481849 |
|
||||
| TSDB_CODE_QRY_HAS_RSP | 0 | 0x0708 | "Query should response" | -2147481848 |
|
||||
| TSDB_CODE_GRANT_EXPIRED | 0 | 0x0800 | "License expired" | -2147481600 |
|
||||
| TSDB_CODE_GRANT_DNODE_LIMITED | 0 | 0x0801 | "DNode creation limited by licence" | -2147481599 |
|
||||
| TSDB_CODE_GRANT_ACCT_LIMITED | 0 | 0x0802 | "Account creation limited by license" | -2147481598 |
|
||||
| TSDB_CODE_GRANT_TIMESERIES_LIMITED | 0 | 0x0803 | "Table creation limited by license" | -2147481597 |
|
||||
| TSDB_CODE_GRANT_DB_LIMITED | 0 | 0x0804 | "DB creation limited by license" | -2147481596 |
|
||||
| TSDB_CODE_GRANT_USER_LIMITED | 0 | 0x0805 | "User creation limited by license" | -2147481595 |
|
||||
| TSDB_CODE_GRANT_CONN_LIMITED | 0 | 0x0806 | "Conn creation limited by license" | -2147481594 |
|
||||
| TSDB_CODE_GRANT_STREAM_LIMITED | 0 | 0x0807 | "Stream creation limited by license" | -2147481593 |
|
||||
| TSDB_CODE_GRANT_SPEED_LIMITED | 0 | 0x0808 | "Write speed limited by license" | -2147481592 |
|
||||
| TSDB_CODE_GRANT_STORAGE_LIMITED | 0 | 0x0809 | "Storage capacity limited by license" | -2147481591 |
|
||||
| TSDB_CODE_GRANT_QUERYTIME_LIMITED | 0 | 0x080A | "Query time limited by license" | -2147481590 |
|
||||
| TSDB_CODE_GRANT_CPU_LIMITED | 0 | 0x080B | "CPU cores limited by license" | -2147481589 |
|
||||
| TSDB_CODE_SYN_INVALID_CONFIG | 0 | 0x0900 | "Invalid Sync Configuration" | -2147481344 |
|
||||
| TSDB_CODE_SYN_NOT_ENABLED | 0 | 0x0901 | "Sync module not enabled" | -2147481343 |
|
||||
| TSDB_CODE_WAL_APP_ERROR | 0 | 0x1000 | "Unexpected generic error in wal" | -2147479552 |
|
||||
|
|
|
@ -41,9 +41,9 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
|
||||
在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。
|
||||
|
||||
| | 类型 | Bytes | 说明 |
|
||||
| # | **类型** | **Bytes** | **说明** |
|
||||
| ---- | :-------: | ------ | ------------------------------------------------------------ |
|
||||
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18 版本开始,已经去除了这一时间范围限制) |
|
||||
| 1 | TIMESTAMP | 8 | 时间戳。缺省精度毫秒,可支持微秒。从格林威治时间 1970-01-01 00:00:00.000 (UTC/GMT) 开始,计时不能早于该时间。(从 2.0.18.0 版本开始,已经去除了这一时间范围限制) |
|
||||
| 2 | INT | 4 | 整型,范围 [-2^31+1, 2^31-1], -2^31 用作 NULL |
|
||||
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL |
|
||||
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
|
||||
|
@ -53,6 +53,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用于 NULL |
|
||||
| 9 | BOOL | 1 | 布尔型,{true, false} |
|
||||
| 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 |
|
||||
<!-- REPLACE_OPEN_TO_ENTERPRISE__COLUMN_TYPE_ADDONS -->
|
||||
|
||||
**Tips**:
|
||||
1. TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。
|
||||
|
@ -63,11 +64,11 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
- **创建数据库**
|
||||
|
||||
```mysql
|
||||
CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [UPDATE 1];
|
||||
CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1];
|
||||
```
|
||||
说明:
|
||||
说明:<!-- 注意:上一行中的 SQL 语句在企业版文档中会被替换,因此修改此语句的话,需要修改企业版文档的替换字典键值!! -->
|
||||
|
||||
1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;
|
||||
1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;<!-- REPLACE_OPEN_TO_ENTERPRISE__KEEP_PARAM_DESCRIPTION -->
|
||||
|
||||
2) UPDATE 标志数据库支持更新相同时间戳数据;
|
||||
|
||||
|
@ -75,7 +76,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
|
||||
4) 一条SQL 语句的最大长度为65480个字符;
|
||||
|
||||
5) 数据库还有更多与存储相关的配置参数,请参见系统管理。
|
||||
5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/administrator#config) 章节。
|
||||
|
||||
- **显示系统当前参数**
|
||||
|
||||
|
@ -125,7 +126,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
ALTER DATABASE db_name CACHELAST 0;
|
||||
```
|
||||
CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持,修改后需要重启服务器生效。)
|
||||
CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11.0 版本开始支持。从 2.1.1.0 版本开始,修改此参数后无需重启服务器即可生效。)
|
||||
|
||||
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
|
||||
|
||||
|
@ -167,22 +168,22 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
|
||||
```
|
||||
以指定的超级表为模板,指定 tags 的值来创建数据表。
|
||||
以指定的超级表为模板,指定 TAGS 的值来创建数据表。
|
||||
|
||||
- **以超级表为模板创建数据表,并指定具体的 tags 列**
|
||||
- **以超级表为模板创建数据表,并指定具体的 TAGS 列**
|
||||
|
||||
```mysql
|
||||
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
|
||||
```
|
||||
以指定的超级表为模板,指定一部分 tags 列的值来创建数据表。(没被指定的 tags 列会设为空值。)
|
||||
说明:从 2.0.17 版本开始支持这种方式。在之前的版本中,不允许指定 tags 列,而必须显式给出所有 tags 列的取值。
|
||||
以指定的超级表为模板,指定一部分 TAGS 列的值来创建数据表(没被指定的 TAGS 列会设为空值)。
|
||||
说明:从 2.0.17.0 版本开始支持这种方式。在之前的版本中,不允许指定 TAGS 列,而必须显式给出所有 TAGS 列的取值。
|
||||
|
||||
- **批量创建数据表**
|
||||
|
||||
```mysql
|
||||
CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) tb_name2 USING stb_name TAGS (tag_value2, ...) ...;
|
||||
```
|
||||
以更快的速度批量创建大量数据表。(服务器端 2.0.14 及以上版本)
|
||||
以更快的速度批量创建大量数据表(服务器端 2.0.14 及以上版本)。
|
||||
|
||||
说明:
|
||||
|
||||
|
@ -220,6 +221,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
SET MAX_BINARY_DISPLAY_WIDTH <nn>;
|
||||
```
|
||||
如显示的内容后面以...结尾时,表示该内容已被截断,可通过本命令修改显示字符宽度以显示完整的内容。
|
||||
|
||||
- **获取表的结构信息**
|
||||
|
||||
|
@ -236,14 +238,14 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
|
||||
1) 列的最大个数为1024,最小个数为2;
|
||||
|
||||
2) 列名最大长度为64;
|
||||
2) 列名最大长度为64。
|
||||
|
||||
- **表删除列**
|
||||
|
||||
```mysql
|
||||
ALTER TABLE tb_name DROP COLUMN field_name;
|
||||
```
|
||||
如果表是通过[超级表](../super-table/)创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构
|
||||
如果表是通过超级表创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构。
|
||||
|
||||
## <a class="anchor" id="super-table"></a>超级表STable管理
|
||||
|
||||
|
@ -254,7 +256,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
CREATE STABLE [IF NOT EXISTS] stb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]) TAGS (tag1_name tag_type1, tag2_name tag_type2 [, tag3_name tag_type3]);
|
||||
```
|
||||
创建 STable,与创建表的 SQL 语法相似,但需指定 TAGS 字段的名称和类型
|
||||
创建 STable,与创建表的 SQL 语法相似,但需要指定 TAGS 字段的名称和类型
|
||||
|
||||
说明:
|
||||
|
||||
|
@ -276,7 +278,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
- **显示当前数据库下的所有超级表信息**
|
||||
|
||||
```mysql
|
||||
SHOW STABLES [LIKE tb_name_wildcar];
|
||||
SHOW STABLES [LIKE tb_name_wildcard];
|
||||
```
|
||||
查看数据库内全部 STable,及其相关信息,包括 STable 的名称、创建时间、列数量、标签(TAG)数量、通过该 STable 建表的数量。
|
||||
|
||||
|
@ -341,7 +343,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
INSERT INTO tb_name VALUES (field_value, ...);
|
||||
```
|
||||
向表tb_name中插入一条记录
|
||||
向表tb_name中插入一条记录。
|
||||
|
||||
- **插入一条记录,数据对应到指定的列**
|
||||
```mysql
|
||||
|
@ -353,42 +355,56 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
|||
```mysql
|
||||
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
向表tb_name中插入多条记录
|
||||
向表tb_name中插入多条记录。
|
||||
**注意**:在使用“插入多条记录”方式写入数据时,不能把第一列的时间戳取值都设为now,否则会导致语句中的多条记录使用相同的时间戳,于是就可能出现相互覆盖以致这些数据行无法全部被正确保存。
|
||||
|
||||
- **按指定的列插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
向表tb_name中按指定的列插入多条记录
|
||||
向表tb_name中按指定的列插入多条记录。
|
||||
|
||||
- **向多个表插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb1_name VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||
tb2_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
同时向表tb1_name和tb2_name中分别插入多条记录
|
||||
同时向表tb1_name和tb2_name中分别插入多条记录。
|
||||
|
||||
- **同时向多个表按列插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||
tb2_name (tb2_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
同时向表tb1_name和tb2_name中按列分别插入多条记录
|
||||
同时向表tb1_name和tb2_name中按列分别插入多条记录。
|
||||
|
||||
注意:允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。
|
||||
注意:
|
||||
1) 如果时间戳为now,系统将自动使用客户端当前时间作为该记录的时间戳;
|
||||
2) 允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。
|
||||
|
||||
- <a class="anchor" id="auto_create_table"></a>**插入记录时自动建表**
|
||||
```mysql
|
||||
INSERT INTO tb_name USING stb_name TAGS (tag_value1, ...) VALUES (field_value1, ...);
|
||||
```
|
||||
如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 tags 取值。
|
||||
如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 TAGS 取值。
|
||||
|
||||
- **插入记录时自动建表,并指定具体的 tags 列**
|
||||
- **插入记录时自动建表,并指定具体的 TAGS 列**
|
||||
```mysql
|
||||
INSERT INTO tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...) VALUES (field_value1, ...);
|
||||
```
|
||||
在自动建表时,可以只是指定部分 tags 列的取值,未被指定的 tags 列将取为空值。
|
||||
在自动建表时,可以只是指定部分 TAGS 列的取值,未被指定的 TAGS 列将取为空值。
|
||||
|
||||
- **同时向多个表按列插入多条记录,自动建表**
|
||||
```mysql
|
||||
INSERT INTO tb1_name (tb1_field1_name, ...) [USING stb1_name TAGS (tag_value1, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||
tb2_name (tb2_field1_name, ...) [USING stb2_name TAGS (tag_value2, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
以自动建表的方式,同时向表tb1_name和tb2_name中按列分别插入多条记录。
|
||||
从 2.0.20.5 版本开始,子表的列名可以不跟在子表名称后面,而是可以放在 TAGS 和 VALUES 之间,例如像下面这样写:
|
||||
```mysql
|
||||
INSERT INTO tb1_name [USING stb1_name TAGS (tag_value1, ...)] (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
注意:虽然两种写法都可以,但并不能在一条 SQL 语句中混用,否则会报语法错误。
|
||||
|
||||
**历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。
|
||||
|
||||
|
@ -471,7 +487,7 @@ Query OK, 9 row(s) in set (0.002022s)
|
|||
SELECT * FROM d1001;
|
||||
SELECT d1001.* FROM d1001;
|
||||
```
|
||||
在Join查询中,带前缀的\*和不带前缀\*返回的结果有差别, \*返回全部表的所有列数据(不包含标签),带前缀的通配符,则只返回该表的列数据。
|
||||
在JOIN查询中,带前缀的\*和不带前缀\*返回的结果有差别, \*返回全部表的所有列数据(不包含标签),带前缀的通配符,则只返回该表的列数据。
|
||||
```mysql
|
||||
taos> SELECT * FROM d1001, d1003 WHERE d1001.ts=d1003.ts;
|
||||
ts | current | voltage | phase | ts | current | voltage | phase |
|
||||
|
@ -487,7 +503,7 @@ taos> SELECT d1001.* FROM d1001,d1003 WHERE d1001.ts = d1003.ts;
|
|||
Query OK, 1 row(s) in set (0.020443s)
|
||||
```
|
||||
|
||||
在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于:
|
||||
在使用SQL函数来进行查询的过程中,部分SQL函数支持通配符操作。其中的区别在于:
|
||||
```count(*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。
|
||||
|
||||
```mysql
|
||||
|
@ -522,12 +538,12 @@ Query OK, 2 row(s) in set (0.003112s)
|
|||
|
||||
##### 获取标签列的去重取值
|
||||
|
||||
从 2.0.15 版本开始,支持在超级表查询标签列时,指定 distinct 关键字,这样将返回指定标签列的所有不重复取值。
|
||||
从 2.0.15 版本开始,支持在超级表查询标签列时,指定 DISTINCT 关键字,这样将返回指定标签列的所有不重复取值。
|
||||
```mysql
|
||||
SELECT DISTINCT tag_name FROM stb_name;
|
||||
```
|
||||
|
||||
注意:目前 distinct 关键字只支持对超级表的标签列进行去重,而不能用于普通列。
|
||||
注意:目前 DISTINCT 关键字只支持对超级表的标签列进行去重,而不能用于普通列。
|
||||
|
||||
|
||||
|
||||
|
@ -562,7 +578,7 @@ SELECT * FROM d1001;
|
|||
|
||||
#### 特殊功能
|
||||
|
||||
部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database()
|
||||
部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database():
|
||||
```mysql
|
||||
taos> SELECT DATABASE();
|
||||
database() |
|
||||
|
@ -570,7 +586,7 @@ taos> SELECT DATABASE();
|
|||
power |
|
||||
Query OK, 1 row(s) in set (0.000079s)
|
||||
```
|
||||
如果登录的时候没有指定默认数据库,且没有使用```use```命令切换数据,则返回NULL。
|
||||
如果登录的时候没有指定默认数据库,且没有使用```USE```命令切换数据,则返回NULL。
|
||||
```mysql
|
||||
taos> SELECT DATABASE();
|
||||
database() |
|
||||
|
@ -578,7 +594,7 @@ taos> SELECT DATABASE();
|
|||
NULL |
|
||||
Query OK, 1 row(s) in set (0.000184s)
|
||||
```
|
||||
获取服务器和客户端版本号:
|
||||
获取服务器和客户端版本号:
|
||||
```mysql
|
||||
taos> SELECT CLIENT_VERSION();
|
||||
client_version() |
|
||||
|
@ -622,7 +638,7 @@ SELECT TBNAME, location FROM meters;
|
|||
```mysql
|
||||
SELECT COUNT(TBNAME) FROM meters;
|
||||
```
|
||||
以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
||||
以上两个查询均只支持在WHERE条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
||||
```mysql
|
||||
taos> SELECT TBNAME, location FROM meters;
|
||||
tbname | location |
|
||||
|
@ -648,30 +664,31 @@ Query OK, 1 row(s) in set (0.001091s)
|
|||
- 参数 LIMIT 控制输出条数,OFFSET 指定从第几条开始输出。LIMIT/OFFSET 对结果集的执行顺序在 ORDER BY 之后。
|
||||
* 在有 GROUP BY 子句的情况下,LIMIT 参数控制的是每个分组中至多允许输出的条数。
|
||||
- 参数 SLIMIT 控制由 GROUP BY 指令划分的分组中,至多允许输出几个分组的数据。
|
||||
- 通过 ">>" 输出结果可以导出到指定文件。
|
||||
- 通过 “>>” 输出结果可以导出到指定文件。
|
||||
|
||||
### 支持的条件过滤操作
|
||||
|
||||
| Operation | Note | Applicable Data Types |
|
||||
| ----------- | ----------------------------- | ------------------------------------- |
|
||||
| > | larger than | **`timestamp`** and all numeric types |
|
||||
| < | smaller than | **`timestamp`** and all numeric types |
|
||||
| >= | larger than or equal to | **`timestamp`** and all numeric types |
|
||||
| <= | smaller than or equal to | **`timestamp`** and all numeric types |
|
||||
| = | equal to | all types |
|
||||
| <> | not equal to | all types |
|
||||
| between and | within a certain range | **`timestamp`** and all numeric types |
|
||||
| % | match with any char sequences | **`binary`** **`nchar`** |
|
||||
| _ | match with a single char | **`binary`** **`nchar`** |
|
||||
| **Operation** | **Note** | **Applicable Data Types** |
|
||||
| --------------- | ----------------------------- | ------------------------------------- |
|
||||
| > | larger than | **`timestamp`** and all numeric types |
|
||||
| < | smaller than | **`timestamp`** and all numeric types |
|
||||
| >= | larger than or equal to | **`timestamp`** and all numeric types |
|
||||
| <= | smaller than or equal to | **`timestamp`** and all numeric types |
|
||||
| = | equal to | all types |
|
||||
| <> | not equal to | all types |
|
||||
| between and | within a certain range | **`timestamp`** and all numeric types |
|
||||
| % | match with any char sequences | **`binary`** **`nchar`** |
|
||||
| _ | match with a single char | **`binary`** **`nchar`** |
|
||||
|
||||
1. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
|
||||
2. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如:((value > 20 AND value < 30) OR (value < 12)) 。
|
||||
3. 从 2.0.17 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。
|
||||
|
||||
<!--
|
||||
### <a class="anchor" id="having"></a>GROUP BY 之后的 HAVING 过滤
|
||||
<a class="anchor" id="having"></a>
|
||||
### GROUP BY 之后的 HAVING 过滤
|
||||
|
||||
从 2.0.20 版本开始,GROUP BY 之后允许再跟一个 HAVING 子句,对成组后的各组数据再做筛选。HAVING 子句可以使用聚合函数和选择函数作为过滤条件(但暂时不支持 LEASTSQUARES、TOP、BOTTOM、LAST_ROW)。
|
||||
从 2.0.20.0 版本开始,GROUP BY 之后允许再跟一个 HAVING 子句,对成组后的各组数据再做筛选。HAVING 子句可以使用聚合函数和选择函数作为过滤条件(但暂时不支持 LEASTSQUARES、TOP、BOTTOM、LAST_ROW)。
|
||||
|
||||
例如,如下语句只会输出 `AVG(f1) > 0` 的分组:
|
||||
```mysql
|
||||
|
@ -679,7 +696,8 @@ SELECT AVG(f1), SPREAD(f1, f2, st2.f1) FROM st2 WHERE f1 > 0 GROUP BY f1 HAVING
|
|||
```
|
||||
-->
|
||||
|
||||
### <a class="anchor" id="union"></a>UNION ALL 操作符
|
||||
<a class="anchor" id="union"></a>
|
||||
### UNION ALL 操作符
|
||||
|
||||
```mysql
|
||||
SELECT ...
|
||||
|
@ -691,37 +709,38 @@ TDengine 支持 UNION ALL 操作符。也就是说,如果多个 SELECT 子句
|
|||
|
||||
### SQL 示例
|
||||
|
||||
- 对于下面的例子,表tb1用以下语句创建
|
||||
- 对于下面的例子,表tb1用以下语句创建:
|
||||
|
||||
```mysql
|
||||
CREATE TABLE tb1 (ts TIMESTAMP, col1 INT, col2 FLOAT, col3 BINARY(50));
|
||||
```
|
||||
|
||||
- 查询tb1刚过去的一个小时的所有记录
|
||||
- 查询tb1刚过去的一个小时的所有记录:
|
||||
|
||||
```mysql
|
||||
SELECT * FROM tb1 WHERE ts >= NOW - 1h;
|
||||
```
|
||||
|
||||
- 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且col3的字符串是'nny'结尾的记录,结果按照时间戳降序
|
||||
- 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且col3的字符串是'nny'结尾的记录,结果按照时间戳降序:
|
||||
|
||||
```mysql
|
||||
SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE '%nny' ORDER BY ts DESC;
|
||||
```
|
||||
|
||||
- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始
|
||||
- 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始:
|
||||
|
||||
```mysql
|
||||
SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND col2 > 1.2 LIMIT 10 OFFSET 5;
|
||||
```
|
||||
|
||||
- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`.
|
||||
- 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 `/home/testoutpu.csv`:
|
||||
|
||||
```mysql
|
||||
SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv;
|
||||
```
|
||||
|
||||
## <a class="anchor" id="functions"></a>SQL 函数
|
||||
<a class="anchor" id="functions"></a>
|
||||
## SQL 函数
|
||||
|
||||
### 聚合函数
|
||||
|
||||
|
@ -741,7 +760,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
|
||||
说明:
|
||||
|
||||
1)可以使用星号\*来替代具体的字段,使用星号(\*)返回全部记录数量。
|
||||
1)可以使用星号(\*)来替代具体的字段,使用星号(\*)返回全部记录数量。
|
||||
|
||||
2)针对同一表的(不包含NULL值)字段查询结果均相同。
|
||||
|
||||
|
@ -1012,7 +1031,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
|
||||
1)*k*值取值范围1≤*k*≤100;
|
||||
|
||||
2)系统同时返回该记录关联的时间戳列。
|
||||
2)系统同时返回该记录关联的时间戳列;
|
||||
|
||||
3)限制:TOP函数不支持FILL子句。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -1048,7 +1069,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
|
||||
1)*k*值取值范围1≤*k*≤100;
|
||||
|
||||
2)系统同时返回该记录关联的时间戳列。
|
||||
2)系统同时返回该记录关联的时间戳列;
|
||||
|
||||
3)限制:BOTTOM函数不支持FILL子句。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -1124,7 +1147,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
|
||||
适用于:**表、超级表**。
|
||||
|
||||
说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。
|
||||
说明:与LAST函数不同,LAST_ROW不支持时间范围限制,强制返回最后一条记录。
|
||||
|
||||
限制:LAST_ROW()不能与INTERVAL一起使用。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -1233,40 +1258,40 @@ SELECT function_list FROM tb_name
|
|||
[WHERE where_condition]
|
||||
INTERVAL (interval [, offset])
|
||||
[SLIDING sliding]
|
||||
[FILL ({NONE | VALUE | PREV | NULL | LINEAR})]
|
||||
[FILL ({NONE | VALUE | PREV | NULL | LINEAR | NEXT})]
|
||||
|
||||
SELECT function_list FROM stb_name
|
||||
[WHERE where_condition]
|
||||
INTERVAL (interval [, offset])
|
||||
[SLIDING sliding]
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR})]
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR | NEXT})]
|
||||
[GROUP BY tags]
|
||||
```
|
||||
|
||||
- 聚合时间段的长度由关键词INTERVAL指定,最短时间间隔10毫秒(10a),并且支持偏移(偏移必须小于间隔)。聚合查询中,能够同时执行的聚合和选择函数仅限于单个输出的函数:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last,不能使用具有多行输出结果的函数(例如:top、bottom、diff以及四则运算)。
|
||||
- WHERE语句可以指定查询的起止时间和其他过滤条件
|
||||
- SLIDING语句用于指定聚合时间段的前向增量
|
||||
- WHERE语句可以指定查询的起止时间和其他过滤条件。
|
||||
- SLIDING语句用于指定聚合时间段的前向增量。
|
||||
- FILL语句指定某一时间区间数据缺失的情况下的填充模式。填充模式包括以下几种:
|
||||
* 不进行填充:NONE(默认填充模式)。
|
||||
* VALUE填充:固定值填充,此时需要指定填充的数值。例如:fill(value, 1.23)。
|
||||
* NULL填充:使用NULL填充数据。例如:fill(null)。
|
||||
* PREV填充:使用前一个非NULL值填充数据。例如:fill(prev)。
|
||||
1. 不进行填充:NONE(默认填充模式)。
|
||||
2. VALUE填充:固定值填充,此时需要指定填充的数值。例如:FILL(VALUE, 1.23)。
|
||||
3. NULL填充:使用NULL填充数据。例如:FILL(NULL)。
|
||||
4. PREV填充:使用前一个非NULL值填充数据。例如:FILL(PREV)。
|
||||
5. NEXT填充:使用下一个非NULL值填充数据。例如:FILL(NEXT)。
|
||||
|
||||
说明:
|
||||
1. 使用FILL语句的时候可能生成大量的填充输出,务必指定查询的时间区间。针对每次查询,系统可返回不超过1千万条具有插值的结果。
|
||||
2. 在时间维度聚合中,返回的结果中时间序列严格单调递增。
|
||||
3. 如果查询对象是超级表,则聚合函数会作用于该超级表下满足值过滤条件的所有表的数据。如果查询中没有使用group by语句,则返回的结果按照时间序列严格单调递增;如果查询中使用了group by语句分组,则返回结果中每个group内不按照时间序列严格单调递增。
|
||||
3. 如果查询对象是超级表,则聚合函数会作用于该超级表下满足值过滤条件的所有表的数据。如果查询中没有使用GROUP BY语句,则返回的结果按照时间序列严格单调递增;如果查询中使用了GROUP BY语句分组,则返回结果中每个GROUP内不按照时间序列严格单调递增。
|
||||
|
||||
时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](https://www.taosdata.com/cn/documentation/advanced-features#continuous-query)。
|
||||
|
||||
**示例:** 智能电表的建表语句如下:
|
||||
**示例**: 智能电表的建表语句如下:
|
||||
|
||||
```mysql
|
||||
CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT);
|
||||
```
|
||||
|
||||
针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。
|
||||
使用的查询语句如下:
|
||||
针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。使用的查询语句如下:
|
||||
|
||||
```mysql
|
||||
SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters
|
||||
|
@ -1287,15 +1312,15 @@ SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), P
|
|||
|
||||
## TAOS SQL其他约定
|
||||
|
||||
**group by的限制**
|
||||
**GROUP BY的限制**
|
||||
|
||||
TAOS SQL支持对标签、tbname进行group by操作,也支持普通列进行group by,前提是:仅限一列且该列的唯一值小于10万个。
|
||||
TAOS SQL支持对标签、TBNAME进行GROUP BY操作,也支持普通列进行GROUP BY,前提是:仅限一列且该列的唯一值小于10万个。
|
||||
|
||||
**join操作的限制**
|
||||
**JOIN操作的限制**
|
||||
|
||||
TAOS SQL支持表之间按主键时间戳来join两张表的列,暂不支持两个表之间聚合后的四则运算。
|
||||
|
||||
**is not null与不为空的表达式适用范围**
|
||||
**IS NOT NULL与不为空的表达式适用范围**
|
||||
|
||||
is not null支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。
|
||||
IS NOT NULL支持所有类型的列。不为空的表达式为 <>"",仅对非数值类型的列适用。
|
||||
|
||||
|
|
|
@ -26,17 +26,17 @@
|
|||
|
||||
## 2. Windows平台下JDBCDriver找不到动态链接库,怎么办?
|
||||
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/jdbcdriver找不到动态链接库/)
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/950.html)
|
||||
|
||||
## 3. 创建数据表时提示more dnodes are needed
|
||||
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/创建数据表时提示more-dnodes-are-needed/)
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/03/965.html)
|
||||
|
||||
## 4. 如何让TDengine crash时生成core文件?
|
||||
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/tdengine-crash时生成core文件的方法/)
|
||||
请看为此问题撰写的[技术博客](https://www.taosdata.com/blog/2019/12/06/974.html)
|
||||
|
||||
## 5. 遇到错误"Unable to establish connection", 我怎么办?
|
||||
## 5. 遇到错误“Unable to establish connection”, 我怎么办?
|
||||
|
||||
客户端遇到连接故障,请按照下面的步骤进行检查:
|
||||
|
||||
|
@ -51,13 +51,13 @@
|
|||
|
||||
4. 确认客户端连接时指定了正确的服务器FQDN (Fully Qualified Domain Name(可在服务器上执行Linux命令hostname -f获得)),FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。
|
||||
|
||||
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
|
||||
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件。如果部署的是TDengine集群,客户端需要能ping通所有集群节点的FQDN。
|
||||
|
||||
6. 检查防火墙设置(Ubuntu 使用 ufw status,CentOS 使用 firewall-cmd --list-port),确认TCP/UDP 端口6030-6042 是打开的
|
||||
|
||||
7. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保*libtaos.so*在目录*/usr/local/taos/driver*里, 并且*/usr/local/taos/driver*在系统库函数搜索路径*LD_LIBRARY_PATH*里
|
||||
|
||||
8. 对于windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
|
||||
8. 对于Windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
|
||||
|
||||
9. 如果仍不能排除连接故障
|
||||
|
||||
|
@ -70,7 +70,8 @@
|
|||
|
||||
10. 也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):[TDengine 内嵌网络检测工具使用指南](https://www.taosdata.com/blog/2020/09/08/1816.html)。
|
||||
|
||||
## 6. 遇到错误“Unexpected generic error in RPC”或者"TDengine Error: Unable to resolve FQDN", 我怎么办?
|
||||
## 6. 遇到错误“Unexpected generic error in RPC”或者“Unable to resolve FQDN”,我怎么办?
|
||||
|
||||
产生这个错误,是由于客户端或数据节点无法解析FQDN(Fully Qualified Domain Name)导致。对于TAOS Shell或客户端应用,请做如下检查:
|
||||
|
||||
1. 请检查连接的服务器的FQDN是否正确,FQDN配置参考:[一篇文章说清楚TDengine的FQDN](https://www.taosdata.com/blog/2020/09/11/1824.html)。
|
||||
|
@ -102,7 +103,7 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支
|
|||
|
||||
批量插入。每条写入语句可以一张表同时插入多条记录,也可以同时插入多张表的多条记录。
|
||||
|
||||
## 12. windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决?
|
||||
## 12. Windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决?
|
||||
|
||||
Windows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的`taos`客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下:
|
||||
```JAVA
|
||||
|
@ -115,15 +116,15 @@ Connection = DriverManager.getConnection(url, properties);
|
|||
## 13.JDBC报错: the excuted SQL is not a DML or a DDL?
|
||||
|
||||
请更新至最新的JDBC驱动
|
||||
```JAVA
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.4</version>
|
||||
<version>2.0.27</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## 14. taos connect failed, reason: invalid timestamp
|
||||
## 14. taos connect failed, reason: invalid timestamp
|
||||
|
||||
常见原因是服务器和客户端时间没有校准,可以通过和时间服务器同步的方式(Linux 下使用 ntpdate 命令,Windows 在系统时间设置中选择自动同步)校准。
|
||||
|
||||
|
@ -157,7 +158,8 @@ ALTER LOCAL RESETLOG;
|
|||
|
||||
其含义是,清空本机所有由客户端生成的日志文件。
|
||||
|
||||
## <a class="anchor" id="timezone"></a>18. 时间戳的时区信息是怎样处理的?
|
||||
<a class="anchor" id="timezone"></a>
|
||||
## 18. 时间戳的时区信息是怎样处理的?
|
||||
|
||||
TDengine 中时间戳的时区总是由客户端进行处理,而与服务端无关。具体来说,客户端会对 SQL 语句中的时间戳进行时区转换,转为 UTC 时区(即 Unix 时间戳——Unix Timestamp)再交由服务端进行写入和查询;在读取数据时,服务端也是采用 UTC 时区提供原始数据,客户端收到后再根据本地设置,把时间戳转换为本地系统所要求的时区进行显示。
|
||||
|
||||
|
@ -167,12 +169,13 @@ TDengine 中时间戳的时区总是由客户端进行处理,而与服务端
|
|||
3. 如果在 C/C++/Java/Python 等各种编程语言的 Connector Driver 中,在建立数据库连接时显式指定了 timezone,那么会以这个指定的时区设置为准。例如 Java Connector 的 JDBC URL 中就有 timezone 参数。
|
||||
4. 在书写 SQL 语句时,也可以直接使用 Unix 时间戳(例如 `1554984068000`)或带有时区的时间戳字符串,也即以 RFC 3339 格式(例如 `2013-04-12T15:52:01.123+08:00`)或 ISO-8601 格式(例如 `2013-04-12T15:52:01.123+0800`)来书写时间戳,此时这些时间戳的取值将不再受其他时区设置的影响。
|
||||
|
||||
## <a class="anchor" id="port"></a>19. TDengine 都会用到哪些网络端口?
|
||||
<a class="anchor" id="port"></a>
|
||||
## 19. TDengine 都会用到哪些网络端口?
|
||||
|
||||
在 TDengine 2.0 版本中,会用到以下这些网络端口(以默认端口 6030 为前提进行说明,如果修改了配置文件中的设置,那么这里列举的端口都会出现变化),管理员可以参考这里的信息调整防火墙设置:
|
||||
|
||||
| 协议 | 默认端口 | 用途说明 | 修改方法 |
|
||||
| --- | --------- | ------------------------------- | ------------------------------ |
|
||||
| :--- | :-------- | :---------------------------------- | :------------------------------- |
|
||||
| TCP | 6030 | 客户端与服务端之间通讯。 | 由配置文件设置 serverPort 决定。 |
|
||||
| TCP | 6035 | 多节点集群的节点间通讯。 | 随 serverPort 端口变化。 |
|
||||
| TCP | 6040 | 多节点集群的节点间数据同步。 | 随 serverPort 端口变化。 |
|
||||
|
|
|
@ -58,7 +58,12 @@ cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_pat
|
|||
cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include
|
||||
cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples
|
||||
cp -r ${top_dir}/src/connector/grafanaplugin/dist ${pkg_dir}${install_home_path}/connector/grafanaplugin
|
||||
if [ -d "${top_dir}/src/connector/grafanaplugin/dist" ]; then
|
||||
cp -r ${top_dir}/src/connector/grafanaplugin/dist ${pkg_dir}${install_home_path}/connector/grafanaplugin
|
||||
else
|
||||
echo "grafanaplugin bundled directory not found!"
|
||||
exit 1
|
||||
fi
|
||||
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
||||
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
||||
|
|
|
@ -66,7 +66,12 @@ cp %{_compiledir}/build/bin/taosdump %{buildroot}%{homepath}/bin
|
|||
cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver
|
||||
cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include
|
||||
cp -r %{_compiledir}/../src/connector/grafanaplugin/dist %{buildroot}%{homepath}/connector/grafanaplugin
|
||||
if [ -d %{_compiledir}/../src/connector/grafanaplugin/dist ]; then
|
||||
cp -r %{_compiledir}/../src/connector/grafanaplugin/dist %{buildroot}%{homepath}/connector/grafanaplugin
|
||||
else
|
||||
echo grafanaplugin bundled directory not found!
|
||||
exit 1
|
||||
fi
|
||||
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
||||
|
|
|
@ -243,9 +243,17 @@ function install_data() {
|
|||
}
|
||||
|
||||
function install_connector() {
|
||||
${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin/dist ${install_main_dir}/connector/grafanaplugin
|
||||
if [ -d "${source_dir}/src/connector/grafanaplugin/dist" ]; then
|
||||
${csudo} cp -rf ${source_dir}/src/connector/grafanaplugin/dist ${install_main_dir}/connector/grafanaplugin
|
||||
else
|
||||
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||
fi
|
||||
if find ${source_dir}/src/connector/go -mindepth 1 -maxdepth 1 | read; then
|
||||
${csudo} cp -r ${source_dir}/src/connector/go ${install_main_dir}/connector
|
||||
else
|
||||
echo "WARNING: go connector not found, please check if want to use it!"
|
||||
fi
|
||||
${csudo} cp -rf ${source_dir}/src/connector/python ${install_main_dir}/connector
|
||||
${csudo} cp -rf ${source_dir}/src/connector/go ${install_main_dir}/connector
|
||||
|
||||
${csudo} cp ${binary_dir}/build/lib/*.jar ${install_main_dir}/connector &> /dev/null && ${csudo} chmod 777 ${install_main_dir}/connector/*.jar || echo &> /dev/null
|
||||
}
|
||||
|
|
|
@ -117,9 +117,17 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
|||
if [ "$osType" != "Darwin" ]; then
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||
fi
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
else
|
||||
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||
fi
|
||||
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
else
|
||||
echo "WARNING: go connector not found, please check if want to use it!"
|
||||
fi
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
||||
fi
|
||||
# Copy release note
|
||||
|
|
|
@ -144,9 +144,17 @@ if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
|||
if [ "$osType" != "Darwin" ]; then
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||
fi
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
else
|
||||
echo "WARNING: grafanaplugin bunlded dir not found, please check if want to use it!"
|
||||
fi
|
||||
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
else
|
||||
echo "WARNING: go connector not found, please check if want to use it!"
|
||||
fi
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||
|
||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py
|
||||
|
||||
|
|
|
@ -114,6 +114,25 @@ mkdir -p ${install_dir}/examples
|
|||
examples_dir="${top_dir}/tests/examples"
|
||||
cp -r ${examples_dir}/c ${install_dir}/examples
|
||||
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||
if [ -d ${examples_dir}/JDBC/connectionPools/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/connectionPools/target
|
||||
fi
|
||||
if [ -d ${examples_dir}/JDBC/JDBCDemo/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/JDBCDemo/target
|
||||
fi
|
||||
if [ -d ${examples_dir}/JDBC/mybatisplus-demo/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/mybatisplus-demo/target
|
||||
fi
|
||||
if [ -d ${examples_dir}/JDBC/springbootdemo/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/springbootdemo/target
|
||||
fi
|
||||
if [ -d ${examples_dir}/JDBC/SpringJdbcTemplate/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/SpringJdbcTemplate/target
|
||||
fi
|
||||
if [ -d ${examples_dir}/JDBC/taosdemo/target ]; then
|
||||
rm -rf ${examples_dir}/JDBC/taosdemo/target
|
||||
fi
|
||||
|
||||
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
||||
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
||||
cp -r ${examples_dir}/python ${install_dir}/examples
|
||||
|
@ -131,9 +150,17 @@ connector_dir="${code_dir}/connector"
|
|||
mkdir -p ${install_dir}/connector
|
||||
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
else
|
||||
echo "WARNING: grafanaplugin bundled dir not found, please check if you want to use it!"
|
||||
fi
|
||||
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
else
|
||||
echo "WARNING: go connector not found, please check if want to use it!"
|
||||
fi
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector
|
||||
cp -r ${connector_dir}/nodejs ${install_dir}/connector
|
||||
fi
|
||||
# Copy release note
|
||||
|
|
|
@ -166,9 +166,18 @@ connector_dir="${code_dir}/connector"
|
|||
mkdir -p ${install_dir}/connector
|
||||
if [[ "$pagMode" != "lite" ]] && [[ "$cpuType" != "aarch32" ]]; then
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector ||:
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
|
||||
if [ -d "${connector_dir}/grafanaplugin/dist" ]; then
|
||||
cp -r ${connector_dir}/grafanaplugin/dist ${install_dir}/connector/grafanaplugin
|
||||
else
|
||||
echo "WARNING: grafanaplugin bundled dir not found, please check if want to use it!"
|
||||
fi
|
||||
if find ${connector_dir}/go -mindepth 1 -maxdepth 1 | read; then
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
else
|
||||
echo "WARNING: go connector not found, please check if want to use it!"
|
||||
fi
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
|
||||
sed -i '/password/ {s/taosdata/powerdb/g}' ${install_dir}/connector/python/taos/cinterface.py
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
|
||||
version: '2.1.0.0'
|
||||
version: '2.1.1.0'
|
||||
icon: snap/gui/t-dengine.svg
|
||||
summary: an open-source big data platform designed and optimized for IoT.
|
||||
description: |
|
||||
|
@ -73,7 +72,7 @@ parts:
|
|||
- usr/bin/taosd
|
||||
- usr/bin/taos
|
||||
- usr/bin/taosdemo
|
||||
- usr/lib/libtaos.so.2.1.0.0
|
||||
- usr/lib/libtaos.so.2.1.1.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -39,38 +39,29 @@ typedef struct SLocalDataSource {
|
|||
} SLocalDataSource;
|
||||
|
||||
typedef struct SLocalMerger {
|
||||
SLocalDataSource ** pLocalDataSrc;
|
||||
SLocalDataSource **pLocalDataSrc;
|
||||
int32_t numOfBuffer;
|
||||
int32_t numOfCompleted;
|
||||
int32_t numOfVnode;
|
||||
SLoserTreeInfo * pLoserTree;
|
||||
tFilePage * pResultBuf;
|
||||
int32_t nResultBufSize;
|
||||
tFilePage * pTempBuffer;
|
||||
struct SQLFunctionCtx *pCtx;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
tOrderDescriptor * pDesc;
|
||||
SColumnModel * resColModel;
|
||||
SColumnModel* finalModel;
|
||||
tExtMemBuffer ** pExtMemBuffer; // disk-based buffer
|
||||
SLoserTreeInfo *pLoserTree;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
tOrderDescriptor *pDesc;
|
||||
tExtMemBuffer **pExtMemBuffer; // disk-based buffer
|
||||
char *buf; // temp buffer
|
||||
} SLocalMerger;
|
||||
|
||||
typedef struct SRetrieveSupport {
|
||||
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
||||
tOrderDescriptor *pOrderDescriptor;
|
||||
SColumnModel* pFinalColModel; // colModel for final result
|
||||
SColumnModel* pFFColModel;
|
||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||
SSqlObj * pParentSql;
|
||||
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
||||
uint32_t numOfRetry; // record the number of retry times
|
||||
} SRetrieveSupport;
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize);
|
||||
int32_t tscLocalReducerEnvCreate(SQueryInfo* pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub, tOrderDescriptor **pDesc, uint32_t nBufferSize, int64_t id);
|
||||
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel,
|
||||
int32_t numOfVnodes);
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes);
|
||||
|
||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||
int32_t numOfRows, int32_t orderType);
|
||||
|
@ -80,12 +71,10 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
|||
/*
|
||||
* create local reducer to launch the second-stage reduce process at client site
|
||||
*/
|
||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SColumnModel *finalModel, SColumnModel *pFFModel, SSqlObj* pSql);
|
||||
int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SQueryInfo *pQueryInfo, SLocalMerger **pMerger, int64_t id);
|
||||
|
||||
void tscDestroyLocalMerger(SSqlObj *pSql);
|
||||
|
||||
//int32_t tscDoLocalMerge(SSqlObj *pSql);
|
||||
void tscDestroyLocalMerger(SLocalMerger* pLocalMerger);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tsched.h"
|
||||
#include "exception.h"
|
||||
#include "os.h"
|
||||
#include "qExtbuffer.h"
|
||||
|
@ -36,6 +37,9 @@ extern "C" {
|
|||
#define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo)\
|
||||
(!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo)))
|
||||
|
||||
#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \
|
||||
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
||||
|
||||
#pragma pack(push,1)
|
||||
// this struct is transfered as binary, padding two bytes to avoid
|
||||
// an 'uid' whose low bytes is 0xff being recoginized as NULL,
|
||||
|
@ -59,7 +63,7 @@ typedef struct SJoinSupporter {
|
|||
SArray* exprList;
|
||||
SFieldInfo fieldsInfo;
|
||||
STagCond tagCond;
|
||||
SSqlGroupbyExpr groupInfo; // group by info
|
||||
SGroupbyExpr groupInfo; // group by info
|
||||
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
|
||||
FILE* f; // temporary file in order to create TSBuf
|
||||
char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory
|
||||
|
@ -90,22 +94,14 @@ typedef struct SVgroupTableInfo {
|
|||
SArray *itemList; // SArray<STableIdInfo>
|
||||
} SVgroupTableInfo;
|
||||
|
||||
static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) {
|
||||
assert(pCmd != NULL && subClauseIndex >= 0);
|
||||
if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pCmd->pQueryInfo[subClauseIndex];
|
||||
}
|
||||
|
||||
SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd);
|
||||
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
||||
|
||||
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
||||
void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf);
|
||||
|
||||
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
||||
void doRetrieveSubqueryData(SSchedMsg *pMsg);
|
||||
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, int16_t bytes,
|
||||
uint32_t offset);
|
||||
|
@ -128,7 +124,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
|||
*/
|
||||
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscIsSecondStageQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
|
||||
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
||||
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
||||
bool hasTagValOutput(SQueryInfo* pQueryInfo);
|
||||
|
@ -137,13 +133,14 @@ bool isStabledev(SQueryInfo* pQueryInfo);
|
|||
bool isTsCompQuery(SQueryInfo* pQueryInfo);
|
||||
bool isSimpleAggregate(SQueryInfo* pQueryInfo);
|
||||
bool isBlockDistQuery(SQueryInfo* pQueryInfo);
|
||||
int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo);
|
||||
bool isSimpleAggregateRv(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
|
||||
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
|
||||
bool tscHasColumnFilter(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscIsTwoStageSTableQuery(SSqlCmd *pCmd, SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
||||
|
@ -151,9 +148,9 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
|||
bool tscQueryBlockInfo(SQueryInfo* pQueryInfo);
|
||||
|
||||
SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType);
|
||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType, int16_t colId);
|
||||
|
||||
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql);
|
||||
int32_t tscSetTableFullName(SName* pName, SStrToken* pzTableName, SSqlObj* pSql);
|
||||
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
||||
|
||||
bool tscIsInsertData(char* sqlstr);
|
||||
|
@ -172,36 +169,49 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
|||
|
||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
||||
void tscFieldInfoClear(SFieldInfo* pFieldInfo);
|
||||
void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList);
|
||||
|
||||
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
||||
|
||||
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize);
|
||||
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||
|
||||
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||
|
||||
int32_t tscGetResRowLength(SArray* pExprList);
|
||||
|
||||
SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||
|
||||
SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
SExprInfo* tscExprCreate(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, int32_t colType);
|
||||
|
||||
void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||
|
||||
SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||
|
||||
SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
int16_t size);
|
||||
size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo);
|
||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||
|
||||
SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||
int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src);
|
||||
void tscSqlExprInfoDestroy(SArray* pExprInfo);
|
||||
size_t tscNumOfExprs(SQueryInfo* pQueryInfo);
|
||||
SExprInfo *tscExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||
int32_t tscExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
int32_t tscExprCopyAll(SArray* dst, const SArray* src, bool deepcopy);
|
||||
void tscExprAssign(SExprInfo* dst, const SExprInfo* src);
|
||||
void tscExprDestroy(SArray* pExprInfo);
|
||||
|
||||
int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||
|
||||
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta);
|
||||
|
||||
SColumn* tscColumnClone(const SColumn* src);
|
||||
bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid);
|
||||
SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
||||
void tscColumnListDestroy(SArray* pColList);
|
||||
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
|
||||
void tscColumnListCopyAll(SArray* dst, const SArray* src);
|
||||
|
||||
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
|
||||
|
@ -223,14 +233,14 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
|||
|
||||
bool tscShouldBeFreed(SSqlObj* pSql);
|
||||
|
||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t tableIndex);
|
||||
STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||
|
||||
void tscInitQueryInfo(SQueryInfo* pQueryInfo);
|
||||
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
||||
int32_t tscAddQueryInfo(SSqlCmd *pCmd);
|
||||
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex);
|
||||
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd, int32_t subClauseIndex);
|
||||
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd);
|
||||
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd);
|
||||
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
||||
|
||||
|
@ -244,13 +254,12 @@ SArray* tscVgroupTableInfoDup(SArray* pVgroupTables);
|
|||
void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index);
|
||||
void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
||||
|
||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
|
||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
||||
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
||||
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo);
|
||||
|
||||
void tscResetForNextRetrieve(SSqlRes* pRes);
|
||||
void tscDoQuery(SSqlObj* pSql);
|
||||
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
|
||||
|
@ -281,7 +290,7 @@ void registerSqlObj(SSqlObj* pSql);
|
|||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t fp, void* param, int32_t cmd, SSqlObj* pPrevSql);
|
||||
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex);
|
||||
|
||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
|
||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlCmd* pCmd);
|
||||
|
||||
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
|
||||
int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId);
|
||||
|
@ -297,6 +306,11 @@ void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
|||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
||||
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp);
|
||||
|
||||
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray);
|
||||
|
||||
bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx);
|
||||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||
void tscClearSqlOwner(SSqlObj* pSql);
|
||||
|
@ -309,12 +323,14 @@ STableMeta* createSuperTableMeta(STableMetaMsg* pChild);
|
|||
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta);
|
||||
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
||||
uint32_t tscGetTableMetaMaxSize();
|
||||
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name, void* buf);
|
||||
int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf);
|
||||
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
||||
SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo);
|
||||
|
||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
||||
|
||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema);
|
||||
void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
||||
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
||||
|
||||
void* malloc_throw(size_t size);
|
||||
void* calloc_throw(size_t nmemb, size_t size);
|
||||
|
|
|
@ -42,12 +42,6 @@ extern "C" {
|
|||
struct SSqlInfo;
|
||||
struct SLocalMerger;
|
||||
|
||||
// data source from sql string or from file
|
||||
enum {
|
||||
DATA_FROM_SQL_STRING = 1,
|
||||
DATA_FROM_DATA_FILE = 2,
|
||||
};
|
||||
|
||||
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
|
||||
|
||||
typedef struct STableComInfo {
|
||||
|
@ -68,14 +62,16 @@ typedef struct CChildTableMeta {
|
|||
int32_t vgId;
|
||||
STableId id;
|
||||
uint8_t tableType;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN]; //super table name, not full name
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN]; // TODO: refactor super table name, not full name
|
||||
uint64_t suid; // super table id
|
||||
} CChildTableMeta;
|
||||
|
||||
typedef struct STableMeta {
|
||||
int32_t vgId;
|
||||
STableId id;
|
||||
uint8_t tableType;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name
|
||||
uint64_t suid; // super table id
|
||||
int16_t sversion;
|
||||
int16_t tversion;
|
||||
STableComInfo tableInfo;
|
||||
|
@ -83,10 +79,10 @@ typedef struct STableMeta {
|
|||
} STableMeta;
|
||||
|
||||
typedef struct STableMetaInfo {
|
||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||
uint32_t tableMetaSize;
|
||||
SVgroupsInfo *vgroupList;
|
||||
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
||||
SVgroupsInfo *vgroupList;
|
||||
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
||||
|
||||
/*
|
||||
* 1. keep the vgroup index during the multi-vnode super table projection query
|
||||
|
@ -135,8 +131,8 @@ typedef struct SJoinNode {
|
|||
} SJoinNode;
|
||||
|
||||
typedef struct SJoinInfo {
|
||||
bool hasJoin;
|
||||
SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM];
|
||||
bool hasJoin;
|
||||
SJoinNode *joinTables[TSDB_MAX_JOIN_TABLE_NUM];
|
||||
} SJoinInfo;
|
||||
|
||||
typedef struct STagCond {
|
||||
|
@ -203,10 +199,11 @@ typedef struct SQueryInfo {
|
|||
SInterval interval; // tumble time window
|
||||
SSessionWindow sessionWindow; // session time window
|
||||
|
||||
SSqlGroupbyExpr groupbyExpr; // groupby tags info
|
||||
SGroupbyExpr groupbyExpr; // groupby tags info
|
||||
SArray * colList; // SArray<SColumn*>
|
||||
SFieldInfo fieldsInfo;
|
||||
SArray * exprList; // SArray<SExprInfo*>
|
||||
SArray * exprList1; // final exprlist in case of arithmetic expression exists
|
||||
SLimitVal limit;
|
||||
SLimitVal slimit;
|
||||
STagCond tagCond;
|
||||
|
@ -229,35 +226,55 @@ typedef struct SQueryInfo {
|
|||
int32_t round; // 0/1/....
|
||||
int32_t bufLen;
|
||||
char* buf;
|
||||
SQInfo* pQInfo; // global merge operator
|
||||
SArray* pDSOperator; // data source operator
|
||||
SArray* pPhyOperator; // physical query execution plan
|
||||
SQInfo* pQInfo; // global merge operator
|
||||
SQueryAttr* pQueryAttr; // query object
|
||||
|
||||
struct SQueryInfo *sibling; // sibling
|
||||
SArray *pUpstream; // SArray<struct SQueryInfo>
|
||||
struct SQueryInfo *pDownstream;
|
||||
int32_t havingFieldNum;
|
||||
bool stableQuery;
|
||||
bool groupbyColumn;
|
||||
bool simpleAgg;
|
||||
bool arithmeticOnAgg;
|
||||
bool projectionQuery;
|
||||
bool hasFilter;
|
||||
bool onlyTagQuery;
|
||||
bool globalMerge; // need global merge
|
||||
bool arithmCalOnAgg; // arithmetic calculation on aggregate result.
|
||||
SArray *pUdfInfo; // user defined function information SArray<SUdfInfo>
|
||||
SArray *pUdfInfo; // user defined function information SArray<SUdfInfo>
|
||||
} SQueryInfo;
|
||||
|
||||
typedef struct {
|
||||
STableMeta *pTableMeta;
|
||||
SVgroupsInfo *pVgroupInfo;
|
||||
} STableMetaVgroupInfo;
|
||||
|
||||
typedef struct SInsertStatementParam {
|
||||
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||
int32_t numOfTables; // number of tables in table name list
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
int8_t schemaAttached; // denote if submit block is built with table schema or not
|
||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||
|
||||
char msg[512]; // error message
|
||||
char *sql; // current sql statement position
|
||||
uint32_t insertType; // insert data from [file|sql statement| bound statement]
|
||||
} SInsertStatementParam;
|
||||
|
||||
// TODO extract sql parser supporter
|
||||
typedef struct {
|
||||
int command;
|
||||
uint8_t msgType;
|
||||
SInsertStatementParam insertParam;
|
||||
char reserve1[3]; // fix bus error on arm32
|
||||
bool autoCreated; // create table if it is not existed during retrieve table meta in mnode
|
||||
bool subCmd;
|
||||
|
||||
union {
|
||||
int32_t count;
|
||||
int32_t numOfTablesInSubmit;
|
||||
};
|
||||
|
||||
uint32_t insertType; // TODO remove it
|
||||
char * curSql; // current sql, resume position of sql after parsing paused
|
||||
int8_t parseFinished;
|
||||
char reserve2[3]; // fix bus error on arm32
|
||||
|
||||
int16_t numOfCols;
|
||||
|
@ -266,25 +283,13 @@ typedef struct {
|
|||
char * payload;
|
||||
int32_t payloadLen;
|
||||
|
||||
SQueryInfo **pQueryInfo;
|
||||
int32_t numOfClause;
|
||||
int32_t clauseIndex; // index of multiple subclause query
|
||||
SQueryInfo *active; // current active query info
|
||||
|
||||
int32_t batchSize; // for parameter ('?') binding and batch processing
|
||||
SHashObj *pTableMetaMap; // local buffer to keep the queried table meta, before validating the AST
|
||||
SQueryInfo *pQueryInfo;
|
||||
SQueryInfo *active; // current active query info
|
||||
int32_t batchSize; // for parameter ('?') binding and batch processing
|
||||
int32_t numOfParams;
|
||||
|
||||
int8_t dataSourceType; // load data from file or not
|
||||
char reserve4[3]; // fix bus error on arm32
|
||||
int8_t submitSchema; // submit block is built with table schema
|
||||
char reserve5[3]; // fix bus error on arm32
|
||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||
|
||||
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||
int32_t numOfTables;
|
||||
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
int32_t resColumnId;
|
||||
} SSqlCmd;
|
||||
|
||||
typedef struct SResRec {
|
||||
|
@ -445,7 +450,7 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
|||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock);
|
||||
|
||||
void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput);
|
||||
void destroyTableNameList(SSqlCmd* pCmd);
|
||||
|
||||
void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
|
||||
|
@ -491,7 +496,7 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
|||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql);
|
||||
|
||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
|
||||
extern int32_t sentinel;
|
||||
extern SHashObj *tscVgroupMap;
|
||||
|
@ -507,7 +512,7 @@ extern int tscNumOfObj; // number of existed sqlObj in current process.
|
|||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||
|
||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||
int16_t getNewResColId(SQueryInfo* pQueryInfo);
|
||||
int16_t getNewResColId(SSqlCmd* pCmd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -218,11 +218,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J
|
|||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: executeBatchImp
|
||||
* Method: closeStmt
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
||||
|
||||
/**
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: setTableNameTagsImp
|
||||
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
|
||||
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -749,7 +749,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
|
|||
}
|
||||
|
||||
jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jname, name);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
@ -762,7 +761,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
|||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||
TAOS_STMT *pStmt = (TAOS_STMT *)stmt;
|
||||
if (pStmt == NULL) {
|
||||
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
||||
return JNI_SQL_NULL;
|
||||
|
@ -777,14 +776,14 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
|||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, lengthList);
|
||||
char *lengthArray = (char*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
||||
char *lengthArray = (char *)calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte *)lengthArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, nullList);
|
||||
char *nullArray = (char*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
||||
char *nullArray = (char *)calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
|
@ -799,22 +798,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
|||
b->length = (int32_t*)lengthArray;
|
||||
|
||||
// set the length and is_null array
|
||||
switch(dataType) {
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int32_t bytes = tDataTypes[dataType].bytes;
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
b->length[i] = bytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
// do nothing
|
||||
if (!IS_VAR_DATA_TYPE(dataType)) {
|
||||
int32_t bytes = tDataTypes[dataType].bytes;
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
b->length[i] = bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,3 +865,74 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv
|
|||
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(JNIEnv *env, jobject jobj,
|
||||
jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList, jbyteArray lengthList, jbyteArray nullList, jlong conn) {
|
||||
TAOS *tsconn = (TAOS *)conn;
|
||||
if (tsconn == NULL) {
|
||||
jniError("jobj:%p, connection already closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||
if (pStmt == NULL) {
|
||||
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
|
||||
return JNI_SQL_NULL;
|
||||
}
|
||||
|
||||
jsize len = (*env)->GetArrayLength(env, tags);
|
||||
char *tagsData = (char *)calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// todo handle error
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, lengthList);
|
||||
int64_t *lengthArray = (int64_t*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, typeList);
|
||||
char *typeArray = (char*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte*) typeArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
len = (*env)->GetArrayLength(env, nullList);
|
||||
int32_t *nullArray = (int32_t*) calloc(1, len);
|
||||
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
}
|
||||
|
||||
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
|
||||
char* curTags = tagsData;
|
||||
|
||||
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
|
||||
for(int32_t i = 0; i < numOfTags; ++i) {
|
||||
tagsBind[i].buffer_type = typeArray[i];
|
||||
tagsBind[i].buffer = curTags;
|
||||
tagsBind[i].is_null = &nullArray[i];
|
||||
tagsBind[i].length = (uintptr_t*) &lengthArray[i];
|
||||
|
||||
curTags += lengthArray[i];
|
||||
}
|
||||
|
||||
int32_t code = taos_stmt_set_tbname_tags((void*)stmt, name, tagsBind);
|
||||
|
||||
int32_t nTags = (int32_t) numOfTags;
|
||||
jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags);
|
||||
|
||||
tfree(tagsData);
|
||||
tfree(lengthArray);
|
||||
tfree(typeArray);
|
||||
tfree(nullArray);
|
||||
(*env)->ReleaseStringUTFChars(env, tableName, name);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
|
||||
return JNI_TDENGINE_ERROR;
|
||||
}
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
pCmd->curSql = pSql->sqlstr;
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return;
|
||||
|
@ -69,7 +70,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
executeQuery(pSql, pQueryInfo);
|
||||
}
|
||||
|
||||
|
@ -127,7 +128,8 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
* all available virtual node has been checked already, now we need to check
|
||||
* for the next subclause queries
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
if (pCmd->active->sibling != NULL) {
|
||||
pCmd->active = pCmd->active->sibling;
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
@ -220,6 +222,17 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
tscResetForNextRetrieve(pRes);
|
||||
|
||||
// handle the sub queries of join query
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) {
|
||||
SSchedMsg schedMsg = {0};
|
||||
schedMsg.fp = doRetrieveSubqueryData;
|
||||
schedMsg.ahandle = (void *)pSql;
|
||||
schedMsg.thandle = (void *)1;
|
||||
schedMsg.msg = 0;
|
||||
taosScheduleTask(tscQhandle, &schedMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockForSubquery(pSql);
|
||||
} else if (pRes->completed) {
|
||||
|
@ -231,7 +244,8 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
* all available virtual nodes in current clause has been checked already, now try the
|
||||
* next one in the following union subclause
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
if (pCmd->active->sibling != NULL) {
|
||||
pCmd->active = pCmd->active->sibling; // todo refactor
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
@ -255,7 +269,7 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd);
|
||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(&pSql->cmd);
|
||||
tscBuildAndSendRequest(pSql, pQueryInfo1);
|
||||
}
|
||||
}
|
||||
|
@ -317,26 +331,38 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM
|
|||
// update the pExpr info, colList info, number of table columns
|
||||
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
|
||||
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
|
||||
int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
||||
|
||||
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||
SSchema *pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base);
|
||||
SSqlExpr *pExpr = &(tscExprGet(pQueryInfo, i)->base);
|
||||
|
||||
// update the table uid
|
||||
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||
|
||||
if (pExpr->colInfo.colIndex >= 0) {
|
||||
int32_t index = pExpr->colInfo.colIndex;
|
||||
|
||||
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
|
||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) {
|
||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < 0 || index >= numOfTags))) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
|
||||
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||
if ((pTagSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pTagSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else if (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag)) {
|
||||
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else { // do nothing for udc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,12 +400,12 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg);
|
||||
if (pSql->pStream == NULL) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send the corresponding query", pSql->self);
|
||||
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
|
||||
TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, continue to process sql and send the corresponding query", pSql->self);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
|
@ -401,42 +427,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else { // continue to process normal async query
|
||||
if (pCmd->parseFinished) {
|
||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send corresponding query", pSql->self);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
|
||||
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pCmd->command != TSDB_SQL_INSERT);
|
||||
|
||||
if (pCmd->command == TSDB_SQL_SELECT) {
|
||||
tscDebug("0x%"PRIx64" redo parse sql string and proceed", pSql->self);
|
||||
pCmd->parseFinished = false;
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
tscBuildAndSendRequest(pSql, NULL);
|
||||
} else { // in all other cases, simple retry
|
||||
tscBuildAndSendRequest(pSql, NULL);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else {
|
||||
tscDebug("0x%"PRIx64" continue parse sql after get table meta", pSql->self);
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||
tscDebug("0x%" PRIx64 " continue parse sql after get table-meta", pSql->self);
|
||||
|
||||
code = tsParseSql(pSql, false);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
|
@ -446,8 +438,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
goto _error;
|
||||
}
|
||||
|
||||
if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
@ -457,59 +449,52 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
} else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
||||
} else {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||
tscImportDataFromFile(pSql);
|
||||
} else {
|
||||
tscHandleMultivnodeInsert(pSql);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pSql->retryReason != TSDB_CODE_SUCCESS) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again",
|
||||
pSql->self);
|
||||
tscResetSqlCmd(pCmd, false);
|
||||
pSql->retryReason = TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
executeQuery(pSql, pQueryInfo1);
|
||||
tscDebug("0x%" PRIx64 " cached table-meta, continue validate sql statement and send query", pSql->self);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd);
|
||||
executeQuery(pSql, pQueryInfo1);
|
||||
}
|
||||
}
|
||||
|
||||
} else { // stream computing
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
} else { // stream computing
|
||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pCmd->command);
|
||||
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
code = tscGetSTableVgroupInfo(pSql, pCmd->clauseIndex);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
}
|
||||
|
||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pSql->cmd.command);
|
||||
if (!pSql->cmd.parseFinished) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (tscNumOfExprs(pQueryInfo) == 0) {
|
||||
tsParseSql(pSql, false);
|
||||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// tscDoQuery(pSql);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
|
||||
_error:
|
||||
|
|
|
@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
// one column for each row
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
@ -154,14 +154,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
|
||||
pSql->cmd.numOfCols = numOfCols;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE};
|
||||
tstrncpy(f.name, "Field", sizeof(f.name));
|
||||
|
||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
(TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false);
|
||||
|
||||
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
||||
|
@ -171,7 +171,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Type", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
||||
-1000, typeColLength, false);
|
||||
|
||||
rowLen += typeColLength + VARSTR_HEADER_SIZE;
|
||||
|
@ -181,7 +181,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Length", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
||||
-1000, sizeof(int32_t), false);
|
||||
|
||||
rowLen += sizeof(int32_t);
|
||||
|
@ -191,7 +191,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
tstrncpy(f.name, "Note", sizeof(f.name));
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
||||
-1000, noteColLength, false);
|
||||
|
||||
rowLen += noteColLength + VARSTR_HEADER_SIZE;
|
||||
|
@ -199,7 +199,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
}
|
||||
|
||||
static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
|
||||
|
||||
|
@ -390,7 +390,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
SColumnIndex index = {0};
|
||||
pSql->cmd.numOfCols = 2;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
TAOS_FIELD f;
|
||||
|
@ -405,7 +405,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
}
|
||||
|
||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
||||
|
||||
rowLen += f.bytes;
|
||||
|
||||
|
@ -418,7 +418,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
}
|
||||
|
||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||
(int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false);
|
||||
|
||||
rowLen += ddlLen + VARSTR_HEADER_SIZE;
|
||||
|
@ -428,7 +428,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
|||
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
int32_t numOfRows = 1;
|
||||
if (strlen(ddl) == 0) {
|
||||
|
||||
|
@ -445,7 +445,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c
|
|||
return 0;
|
||||
}
|
||||
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);
|
||||
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
@ -532,7 +532,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
|||
}
|
||||
buf[0] = 0;
|
||||
|
||||
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
|
||||
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0)->pTableMeta;
|
||||
if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
|
||||
pMeta->tableType == TSDB_STREAM_TABLE) {
|
||||
free(buf);
|
||||
|
@ -553,7 +553,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
@ -607,7 +607,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch
|
|||
}
|
||||
|
||||
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
|
@ -634,7 +634,7 @@ static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName,
|
|||
}
|
||||
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||
char *result = ddl;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
|
@ -675,7 +675,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName,
|
|||
}
|
||||
|
||||
static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
assert(pTableMetaInfo->pTableMeta != NULL);
|
||||
|
||||
|
@ -704,7 +704,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
|
@ -730,7 +730,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
|||
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
||||
}
|
||||
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -757,7 +757,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
extractDBName(pSql->pTscObj->db, db);
|
||||
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -784,7 +784,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
|
||||
static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
||||
const char* v = pSql->pTscObj->sversion;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -807,7 +807,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -859,7 +859,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
|||
return pSql->res.code;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
|
||||
int32_t val = 1;
|
||||
|
@ -873,7 +873,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
|||
|
||||
pCmd->numOfCols = 1;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
||||
|
@ -928,7 +928,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
} else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
|
||||
pRes->code = tscProcessServStatus(pSql);
|
||||
} else {
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "texpr.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
#include "tsclient.h"
|
||||
#include "qUtil.h"
|
||||
|
||||
|
@ -59,77 +57,25 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo merge with vnode side function
|
||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema) {
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pCtx[i].order = pQueryInfo->order.order;
|
||||
pCtx[i].functionId = pExpr->base.functionId;
|
||||
|
||||
pCtx[i].order = pQueryInfo->order.order;
|
||||
pCtx[i].functionId = pExpr->base.functionId;
|
||||
|
||||
// input data format comes from pModel
|
||||
pCtx[i].inputType = pSchema[i].type;
|
||||
pCtx[i].inputBytes = pSchema[i].bytes;
|
||||
|
||||
pCtx[i].outputBytes = pExpr->base.resBytes;
|
||||
pCtx[i].outputType = pExpr->base.resType;
|
||||
|
||||
// input buffer hold only one point data
|
||||
pCtx[i].size = 1;
|
||||
pCtx[i].hasNull = true;
|
||||
pCtx[i].currentStage = MERGE_STAGE;
|
||||
|
||||
// for top/bottom function, the output of timestamp is the first column
|
||||
int32_t functionId = pExpr->base.functionId;
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
||||
pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
|
||||
pCtx[i].param[2].i64 = pQueryInfo->order.order;
|
||||
pCtx[i].param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
pCtx[i].param[1].i64 = pQueryInfo->order.orderColId;
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64; // top/bot parameter
|
||||
} else if (functionId == TSDB_FUNC_APERCT) {
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
||||
} else if (functionId == TSDB_FUNC_BLKINFO) {
|
||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
||||
pCtx[i].numOfParams = 1;
|
||||
}
|
||||
|
||||
pCtx[i].interBufBytes = pExpr->base.interBytes;
|
||||
pCtx[i].stableQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
int32_t tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||
SQueryInfo* pQueryInfo, SLocalMerger **pMerger, int64_t id) {
|
||||
if (pMemBuffer == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("pMemBuffer:%p is NULL", pMemBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscError("0x%"PRIx64" %p pMemBuffer is NULL", id, pMemBuffer);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
if (pDesc->pColumnModel == NULL) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
tscError("0x%"PRIx64" no local buffer or intermediate result format model", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscError("0x%"PRIx64" no local buffer or intermediate result format model", id);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
int32_t numOfFlush = 0;
|
||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||
int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
||||
if (len == 0) {
|
||||
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", pSql->self, i + 1);
|
||||
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", id, i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -137,41 +83,36 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
}
|
||||
|
||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
|
||||
tscDebug("0x%"PRIx64" retrieved no data", pSql->self);
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
tscDebug("0x%"PRIx64" no data to retrieve", id);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) {
|
||||
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", pSql->self, pDesc->pColumnModel->capacity,
|
||||
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", id, pDesc->pColumnModel->capacity,
|
||||
pMemBuffer[0]->pageSize);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush;
|
||||
|
||||
SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size);
|
||||
if (pMerger == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", pSql->self);
|
||||
*pMerger = (SLocalMerger *) calloc(1, sizeof(SLocalMerger));
|
||||
if ((*pMerger) == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", id);
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pExtMemBuffer = pMemBuffer;
|
||||
pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1];
|
||||
assert(pMerger->pLocalDataSrc != NULL);
|
||||
(*pMerger)->pExtMemBuffer = pMemBuffer;
|
||||
(*pMerger)->pLocalDataSrc = calloc(numOfFlush, POINTER_BYTES);
|
||||
assert((*pMerger)->pLocalDataSrc != NULL);
|
||||
|
||||
pMerger->numOfBuffer = numOfFlush;
|
||||
pMerger->numOfVnode = numOfBuffer;
|
||||
(*pMerger)->numOfBuffer = numOfFlush;
|
||||
(*pMerger)->numOfVnode = numOfBuffer;
|
||||
|
||||
pMerger->pDesc = pDesc;
|
||||
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer);
|
||||
(*pMerger)->pDesc = pDesc;
|
||||
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", id, (*pMerger)->numOfBuffer);
|
||||
|
||||
int32_t idx = 0;
|
||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||
|
@ -180,13 +121,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
||||
SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
||||
if (ds == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create merge structure", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscError("0x%"PRIx64" failed to create merge structure", id);
|
||||
tfree(pMerger);
|
||||
return;
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pLocalDataSrc[idx] = ds;
|
||||
(*pMerger)->pLocalDataSrc[idx] = ds;
|
||||
|
||||
ds->pMemBuffer = pMemBuffer[i];
|
||||
ds->flushoutIdx = j;
|
||||
|
@ -194,12 +134,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
ds->pageId = 0;
|
||||
ds->rowIdx = 0;
|
||||
|
||||
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", pSql->self, i + 1, idx + 1);
|
||||
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", id, i + 1, idx + 1);
|
||||
tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0);
|
||||
#ifdef _DEBUG_VIEW
|
||||
printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num);
|
||||
SSrcColumnInfo colInfo[256] = {0};
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||
|
||||
|
@ -208,7 +148,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
#endif
|
||||
|
||||
if (ds->filePage.num == 0) { // no data in this flush, the index does not increase
|
||||
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", pSql->self, idx);
|
||||
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", id, idx);
|
||||
tfree(ds);
|
||||
continue;
|
||||
}
|
||||
|
@ -219,91 +159,43 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
|
||||
// no data actually, no need to merge result.
|
||||
if (idx == 0) {
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tscDebug("0x%"PRIx64" retrieved no data", id);
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, numOfBuffer);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pMerger->numOfBuffer = idx;
|
||||
(*pMerger)->numOfBuffer = idx;
|
||||
|
||||
SCompareParam *param = malloc(sizeof(SCompareParam));
|
||||
if (param == NULL) {
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
param->pLocalData = pMerger->pLocalDataSrc;
|
||||
param->pDesc = pMerger->pDesc;
|
||||
param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
param->pLocalData = (*pMerger)->pLocalDataSrc;
|
||||
param->pDesc = (*pMerger)->pDesc;
|
||||
param->num = (*pMerger)->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||
|
||||
param->groupOrderType = pQueryInfo->groupbyExpr.orderType;
|
||||
|
||||
pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator);
|
||||
if (pMerger->pLoserTree == NULL || pRes->code != 0) {
|
||||
int32_t code = tLoserTreeCreate(&(*pMerger)->pLoserTree, (*pMerger)->numOfBuffer, param, treeComparator);
|
||||
if ((*pMerger)->pLoserTree == NULL || code != TSDB_CODE_SUCCESS) {
|
||||
tfree(param);
|
||||
tfree(pMerger);
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return code;
|
||||
}
|
||||
|
||||
// the input data format follows the old format, but output in a new format.
|
||||
// so, all the input must be parsed as old format
|
||||
pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx));
|
||||
pMerger->rowSize = pMemBuffer[0]->nElemSize;
|
||||
(*pMerger)->rowSize = pMemBuffer[0]->nElemSize;
|
||||
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
// todo fixed row size is larger than the minimum page size;
|
||||
assert((*pMerger)->rowSize <= pMemBuffer[0]->pageSize);
|
||||
|
||||
if (pMerger->rowSize > pMemBuffer[0]->pageSize) {
|
||||
assert(false); // todo fixed row size is larger than the minimum page size;
|
||||
}
|
||||
|
||||
// used to keep the latest input row
|
||||
pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage));
|
||||
|
||||
pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||
pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage));
|
||||
|
||||
pMerger->resColModel = finalmodel;
|
||||
pMerger->resColModel->capacity = pMerger->nResultBufSize;
|
||||
pMerger->finalModel = pFFModel;
|
||||
|
||||
if (finalmodel->rowSize > 0) {
|
||||
pMerger->resColModel->capacity /= finalmodel->rowSize;
|
||||
}
|
||||
|
||||
assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize);
|
||||
|
||||
if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) {
|
||||
tfree(pMerger->pTempBuffer);
|
||||
tfree(pMerger->pLoserTree);
|
||||
if ((*pMerger)->pLoserTree == NULL) {
|
||||
tfree((*pMerger)->pLoserTree);
|
||||
tfree(param);
|
||||
tfree(pMerger);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return;
|
||||
tfree((*pMerger));
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMerger->pTempBuffer->num = 0;
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
|
||||
SSchema* pschema = calloc(pDesc->pColumnModel->numOfCols, sizeof(SSchema));
|
||||
for(int32_t i = 0; i < pDesc->pColumnModel->numOfCols; ++i) {
|
||||
pschema[i] = pDesc->pColumnModel->pFields[i].field;
|
||||
}
|
||||
|
||||
tsCreateSQLFunctionCtx(pQueryInfo, pMerger->pCtx, pschema);
|
||||
// setCtxInputOutputBuffer(pQueryInfo, pMerger->pCtx, pMerger, pDesc);
|
||||
|
||||
tfree(pschema);
|
||||
|
||||
int32_t maxBufSize = 0;
|
||||
for (int32_t k = 0; k < tscSqlExprNumOfExprs(pQueryInfo); ++k) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
if (maxBufSize < pExpr->base.resBytes && pExpr->base.functionId == TSDB_FUNC_TAG) {
|
||||
maxBufSize = pExpr->base.resBytes;
|
||||
}
|
||||
}
|
||||
|
||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||
pMerger->pDesc->pColumnModel->capacity = 1;
|
||||
|
||||
// restore the limitation value at the last stage
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
|
@ -311,22 +203,10 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
|||
pQueryInfo->limit.offset = pQueryInfo->prjOffset;
|
||||
}
|
||||
|
||||
pRes->pLocalMerger = pMerger;
|
||||
pRes->numOfGroups = 0;
|
||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||
(*pMerger)->pDesc->pColumnModel->capacity = 1;
|
||||
|
||||
// STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
// STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
||||
// TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey;
|
||||
// int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision);
|
||||
|
||||
// if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
// SFillColInfo* pFillCol = createFillColInfo(pQueryInfo);
|
||||
// pMerger->pFillInfo =
|
||||
// taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, 4096,
|
||||
// (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding,
|
||||
// pQueryInfo->interval.slidingUnit, tinfo.precision, pQueryInfo->fillType, pFillCol, pSql);
|
||||
// }
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage,
|
||||
|
@ -417,44 +297,32 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tscDestroyLocalMerger(SSqlObj *pSql) {
|
||||
if (pSql == NULL) {
|
||||
void tscDestroyLocalMerger(SLocalMerger* pLocalMerger) {
|
||||
if (pLocalMerger == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlRes *pRes = &(pSql->res);
|
||||
if (pRes->pLocalMerger == NULL) {
|
||||
return;
|
||||
for (int32_t i = 0; i < pLocalMerger->numOfBuffer; ++i) {
|
||||
tfree(pLocalMerger->pLocalDataSrc[i]);
|
||||
}
|
||||
|
||||
// there is no more result, so we release all allocated resource
|
||||
SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL);
|
||||
tfree(pLocalMerge->pResultBuf);
|
||||
tfree(pLocalMerge->pCtx);
|
||||
pLocalMerger->numOfBuffer = 0;
|
||||
tscLocalReducerEnvDestroy(pLocalMerger->pExtMemBuffer, pLocalMerger->pDesc, pLocalMerger->numOfVnode);
|
||||
|
||||
if (pLocalMerge->pLoserTree) {
|
||||
tfree(pLocalMerge->pLoserTree->param);
|
||||
tfree(pLocalMerge->pLoserTree);
|
||||
pLocalMerger->numOfCompleted = 0;
|
||||
|
||||
if (pLocalMerger->pLoserTree) {
|
||||
tfree(pLocalMerger->pLoserTree->param);
|
||||
tfree(pLocalMerger->pLoserTree);
|
||||
}
|
||||
|
||||
tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel,
|
||||
pLocalMerge->finalModel, pLocalMerge->numOfVnode);
|
||||
for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) {
|
||||
tfree(pLocalMerge->pLocalDataSrc[i]);
|
||||
}
|
||||
|
||||
pLocalMerge->numOfBuffer = 0;
|
||||
pLocalMerge->numOfCompleted = 0;
|
||||
tfree(pLocalMerge->pTempBuffer);
|
||||
|
||||
free(pLocalMerge);
|
||||
|
||||
tscDebug("0x%"PRIx64" free local reducer finished", pSql->self);
|
||||
tfree(pLocalMerger->buf);
|
||||
tfree(pLocalMerger->pLocalDataSrc);
|
||||
free(pLocalMerger);
|
||||
}
|
||||
|
||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) {
|
||||
int32_t numOfGroupByCols = 0;
|
||||
SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SQueryInfo* pQueryInfo, SColumnModel *pModel) {
|
||||
int32_t numOfGroupByCols = 0;
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
|
@ -473,13 +341,13 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
if (numOfGroupByCols > 0) {
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
int32_t numOfInternalOutput = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
|
||||
// the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
||||
for(int32_t j = 0; j < numOfInternalOutput; ++j) {
|
||||
SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j);
|
||||
SExprInfo* pExprInfo = tscExprGet(pQueryInfo, j);
|
||||
|
||||
int32_t functionId = pExprInfo->base.functionId;
|
||||
if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) {
|
||||
|
@ -501,9 +369,9 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
if (pQueryInfo->interval.interval != 0) {
|
||||
orderColIndexList[0] = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||
} else {
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
size_t size = tscNumOfExprs(pQueryInfo);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
orderColIndexList[0] = i;
|
||||
}
|
||||
|
@ -524,37 +392,30 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
}
|
||||
}
|
||||
|
||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SSchema * pSchema = NULL;
|
||||
int32_t tscLocalReducerEnvCreate(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub,
|
||||
tOrderDescriptor **pOrderDesc, uint32_t nBufferSizes, int64_t id) {
|
||||
SSchema *pSchema = NULL;
|
||||
SColumnModel *pModel = NULL;
|
||||
*pFinalModel = NULL;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub);
|
||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * numOfSub);
|
||||
if (*pMemBuffer == NULL) {
|
||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
size_t size = tscNumOfExprs(pQueryInfo);
|
||||
|
||||
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * size);
|
||||
if (pSchema == NULL) {
|
||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t rlen = 0;
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
|
||||
pSchema[i].bytes = pExpr->base.resBytes;
|
||||
pSchema[i].type = (int8_t)pExpr->base.resType;
|
||||
|
@ -569,6 +430,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
}
|
||||
|
||||
pModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
tfree(pSchema);
|
||||
|
||||
int32_t pg = DEFAULT_PAGE_SIZE;
|
||||
int32_t overhead = sizeof(tFilePage);
|
||||
|
@ -576,100 +438,26 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
pg *= 2;
|
||||
}
|
||||
|
||||
size_t numOfSubs = pSql->subState.numOfSub;
|
||||
assert(numOfSubs <= pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
for (int32_t i = 0; i < numOfSubs; ++i) {
|
||||
assert(numOfSub <= pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
for (int32_t i = 0; i < numOfSub; ++i) {
|
||||
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pg, pModel);
|
||||
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
||||
}
|
||||
|
||||
if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSchema);
|
||||
return pRes->code;
|
||||
if (createOrderDescriptor(pOrderDesc, pQueryInfo, pModel) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// final result depends on the fields number
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
SSchema p1 = {0};
|
||||
if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
p1 = *tGetTbnameColumnSchema();
|
||||
} else if (TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag)) {
|
||||
p1.bytes = pExpr->base.resBytes;
|
||||
p1.type = (uint8_t) pExpr->base.resType;
|
||||
tstrncpy(p1.name, pExpr->base.aliasName, tListLen(p1.name));
|
||||
} else {
|
||||
p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex);
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t type = -1;
|
||||
int16_t bytes = 0;
|
||||
|
||||
// the final result size and type in the same as query on single table.
|
||||
// so here, set the flag to be false;
|
||||
int32_t functionId = pExpr->base.functionId;
|
||||
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
||||
type = pModel->pFields[i].field.type;
|
||||
bytes = pModel->pFields[i].field.bytes;
|
||||
} else if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false, pUdfInfo);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
|
||||
} else {
|
||||
if (functionId == TSDB_FUNC_FIRST_DST) {
|
||||
functionId = TSDB_FUNC_FIRST;
|
||||
} else if (functionId == TSDB_FUNC_LAST_DST) {
|
||||
functionId = TSDB_FUNC_LAST;
|
||||
} else if (functionId == TSDB_FUNC_STDDEV_DST) {
|
||||
functionId = TSDB_FUNC_STDDEV;
|
||||
}
|
||||
|
||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false, NULL);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
pSchema[i].type = (uint8_t)type;
|
||||
pSchema[i].bytes = bytes;
|
||||
strcpy(pSchema[i].name, pModel->pFields[i].field.name);
|
||||
}
|
||||
|
||||
*pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
size = tscNumOfFields(pQueryInfo);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
||||
pSchema[i].bytes = pField->field.bytes;
|
||||
pSchema[i].type = pField->field.type;
|
||||
tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name));
|
||||
}
|
||||
|
||||
*pFFModel = createColumnModel(pSchema, (int32_t) size, capacity);
|
||||
|
||||
tfree(pSchema);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pMemBuffer
|
||||
* @param pDesc
|
||||
* @param pFinalModel
|
||||
* @param numOfVnodes
|
||||
*/
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel,
|
||||
int32_t numOfVnodes) {
|
||||
destroyColumnModel(pFinalModel);
|
||||
destroyColumnModel(pFFModel);
|
||||
|
||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes) {
|
||||
tOrderDescDestroy(pDesc);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
||||
}
|
||||
|
@ -804,12 +592,12 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
|||
|
||||
if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||
|
||||
|
||||
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||
}
|
||||
} else {
|
||||
|
@ -821,12 +609,12 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
|||
|
||||
if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||
|
||||
|
||||
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[functionId].xFinalize(&pCtx[j]);
|
||||
}
|
||||
|
||||
|
@ -846,7 +634,7 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
|||
if (pCtx[j].functionId < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[pCtx[j].functionId].init(&pCtx[j], pCtx[j].resultInfo);
|
||||
}
|
||||
|
||||
|
@ -862,12 +650,12 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
|||
|
||||
if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||
|
||||
|
||||
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||
}
|
||||
}
|
||||
|
@ -884,12 +672,12 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
|||
|
||||
if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pInfo->udfInfo, -1 * functionId - 1);
|
||||
|
||||
|
||||
doInvokeUdf(pUdfInfo, &pCtx[j], 0, TSDB_UDF_FUNC_MERGE);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[functionId].mergeFunc(&pCtx[j]);
|
||||
}
|
||||
}
|
||||
|
@ -921,10 +709,12 @@ static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) {
|
|||
return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted);
|
||||
}
|
||||
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) {
|
||||
SSqlRes *pRes = &pObj->res;
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pSql, int32_t numOfRes, int32_t rowLen) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
if (pRes->pLocalMerger != NULL) {
|
||||
tscDestroyLocalMerger(pObj);
|
||||
tscDestroyLocalMerger(pRes->pLocalMerger);
|
||||
pRes->pLocalMerger = NULL;
|
||||
tscDebug("0x%"PRIx64" free local reducer finished", pSql->self);
|
||||
}
|
||||
|
||||
pRes->qId = 1; // hack to pass the safety check in fetch_row function
|
||||
|
@ -935,14 +725,12 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
|
|||
pRes->pLocalMerger = (SLocalMerger *)calloc(1, sizeof(SLocalMerger));
|
||||
|
||||
/*
|
||||
* we need one additional byte space
|
||||
* the sprintf function needs one additional space to put '\0' at the end of string
|
||||
* One more byte space is required, since the sprintf function needs one additional space to put '\0' at
|
||||
* the end of string
|
||||
*/
|
||||
size_t allocSize = numOfRes * rowLen + sizeof(tFilePage) + 1;
|
||||
pRes->pLocalMerger->pResultBuf = (tFilePage *)calloc(1, allocSize);
|
||||
|
||||
pRes->pLocalMerger->pResultBuf->num = numOfRes;
|
||||
pRes->data = pRes->pLocalMerger->pResultBuf->data;
|
||||
size_t size = numOfRes * rowLen + 1;
|
||||
pRes->pLocalMerger->buf = calloc(1, size);
|
||||
pRes->data = pRes->pLocalMerger->buf;
|
||||
}
|
||||
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
|
@ -954,12 +742,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
|
||||
// todo refactor
|
||||
arithSup.offset = 0;
|
||||
arithSup.numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
arithSup.numOfCols = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
arithSup.exprList = pQueryInfo->exprList;
|
||||
arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES);
|
||||
|
||||
for(int32_t k = 0; k < arithSup.numOfCols; ++k) {
|
||||
SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
SExprInfo* pExpr = tscExprGet(pQueryInfo, k);
|
||||
arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset);
|
||||
}
|
||||
|
||||
|
@ -988,8 +776,8 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
return offset;
|
||||
}
|
||||
|
||||
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
|
||||
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
|
||||
#define COLMODEL_GET_VAL(data, schema, rowId, colId) \
|
||||
(data + (schema)->pFields[colId].offset * ((schema)->capacity) + (rowId) * (schema)->pFields[colId].field.bytes)
|
||||
|
||||
static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex,
|
||||
int32_t maxRows) {
|
||||
|
@ -997,7 +785,7 @@ static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel
|
|||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||
char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes;
|
||||
|
||||
char *src = COLMODEL_GET_VAL(buf, pModel, maxRows, rowIndex, i);
|
||||
char *src = COLMODEL_GET_VAL(buf, pModel, rowIndex, i);
|
||||
memmove(p, src, pColInfo->info.bytes);
|
||||
}
|
||||
|
||||
|
@ -1014,8 +802,6 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
|
||||
SLocalMerger *pMerger = pInfo->pMerge;
|
||||
SLoserTreeInfo *pTree = pMerger->pLoserTree;
|
||||
SColumnModel *pModel = pMerger->pDesc->pColumnModel;
|
||||
tFilePage *tmpBuffer = pMerger->pTempBuffer;
|
||||
|
||||
pInfo->binfo.pRes->info.rows = 0;
|
||||
|
||||
|
@ -1028,7 +814,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index);
|
||||
#endif
|
||||
|
||||
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0);
|
||||
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0));
|
||||
|
||||
// chosen from loser tree
|
||||
SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index];
|
||||
|
@ -1041,11 +827,10 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||
|
||||
char *newRow =
|
||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
char *newRow = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
|
||||
char * data = pInfo->prevRow[i];
|
||||
char *data = pInfo->prevRow[i];
|
||||
int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes);
|
||||
if (ret == 0) {
|
||||
continue;
|
||||
|
@ -1064,9 +849,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||
|
||||
char *curCol =
|
||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
char *curCol = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||
memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes);
|
||||
}
|
||||
|
||||
|
@ -1077,7 +861,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
|||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||
pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||
|
||||
#if defined(_DEBUG_VIEW)
|
||||
printf("chosen row:\t");
|
||||
|
@ -1126,7 +911,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
}
|
||||
|
||||
SMultiwayMergeInfo *pAggInfo = pOperator->info;
|
||||
SOperatorInfo *upstream = pOperator->upstream;
|
||||
SOperatorInfo *upstream = pOperator->upstream[0];
|
||||
|
||||
*newgroup = false;
|
||||
bool handleData = false;
|
||||
|
@ -1147,7 +932,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
clearOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
aAggs[pCtx->functionId].init(pCtx, pCtx->resultInfo);
|
||||
}
|
||||
}
|
||||
|
@ -1201,9 +986,9 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
|
||||
if (functionId < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pAggInfo->udfInfo, -1 * functionId - 1);
|
||||
|
||||
|
||||
doInvokeUdf(pUdfInfo, &pAggInfo->binfo.pCtx[j], 0, TSDB_UDF_FUNC_FINALIZE);
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1223,7 +1008,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
|||
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) {
|
||||
STimeWindow* w = &pRes->info.window;
|
||||
|
||||
// TODO in case of desc order, swap it
|
||||
w->skey = *(int64_t*)pInfoData->pData;
|
||||
w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1));
|
||||
|
||||
|
@ -1243,7 +1027,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (pInfo->currentGroupOffset == 0) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1251,7 +1035,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) {
|
||||
while ((*newgroup) == false) { // ignore the remain blocks
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1263,7 +1047,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
@ -1277,7 +1061,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
}
|
||||
|
||||
while ((*newgroup) == false) {
|
||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
||||
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
|
|
|
@ -107,7 +107,7 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
|
|||
}
|
||||
|
||||
if (parseAbsoluteDuration(valueToken.z, valueToken.n, &interval) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (timePrec == TSDB_TIME_PRECISION_MILLI) {
|
||||
|
@ -441,7 +441,7 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1
|
|||
*str += index;
|
||||
|
||||
if (sToken.type == TK_QUESTION) {
|
||||
if (pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
if (pCmd->insertParam.insertType != TSDB_QUERY_TYPE_STMT_INSERT) {
|
||||
return tscSQLSyntaxErrMsg(pCmd->payload, "? only allowed in binding insertion", *str);
|
||||
}
|
||||
|
||||
|
@ -647,7 +647,7 @@ static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta,
|
|||
pBlocks->sversion = pTableMeta->sversion;
|
||||
|
||||
if (pBlocks->numOfRows + numOfRows >= INT16_MAX) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
} else {
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -708,7 +708,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock
|
|||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
char tmpTokenBuf[16*1024] = {0}; // used for deleting Escape character: \\, \', \"
|
||||
|
||||
int32_t numOfRows = 0;
|
||||
|
@ -747,12 +747,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
const int32_t STABLE_INDEX = 1;
|
||||
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
char *sql = *sqlstr;
|
||||
|
||||
pSql->cmd.autoCreated = false;
|
||||
|
||||
// get the token of specified table
|
||||
index = 0;
|
||||
tableToken = tStrGetToken(sql, &index, false);
|
||||
|
@ -786,7 +784,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
if (numOfColList == 0 && (*boundColumn) != NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, TABLE_INDEX);
|
||||
|
@ -802,7 +800,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
STableMetaInfo *pSTableMetaInfo = tscGetMetaInfo(pQueryInfo, STABLE_INDEX);
|
||||
code = tscSetTableFullName(pSTableMetaInfo, &sToken, pSql);
|
||||
code = tscSetTableFullName(&pSTableMetaInfo->name, &sToken, pSql);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -879,7 +877,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
if (TK_ILLEGAL == sToken.type) {
|
||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||
tscDestroyBoundColumnInfo(&spd);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (sToken.n == 0 || sToken.type == TK_RP) {
|
||||
|
@ -961,7 +959,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
if (numOfColsAfterTags == 0 && (*boundColumn) != NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(sql, &index, false);
|
||||
|
@ -973,13 +971,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
||||
}
|
||||
|
||||
int32_t ret = tscSetTableFullName(pTableMetaInfo, &tableToken, pSql);
|
||||
int32_t ret = tscSetTableFullName(&pTableMetaInfo->name, &tableToken, pSql);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sql == NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, true);
|
||||
|
@ -991,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
sql = sToken.z;
|
||||
|
||||
if (sql == NULL) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, false);
|
||||
|
@ -1015,12 +1013,17 @@ int validateTableName(char *tblName, int len, SStrToken* psTblToken) {
|
|||
return tscValidateName(psTblToken);
|
||||
}
|
||||
|
||||
static int32_t validateDataSource(SSqlCmd *pCmd, int8_t type, const char *sql) {
|
||||
if (pCmd->dataSourceType != 0 && pCmd->dataSourceType != type) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sql);
|
||||
static int32_t validateDataSource(SSqlCmd *pCmd, int32_t type, const char *sql) {
|
||||
uint32_t *insertType = &pCmd->insertParam.insertType;
|
||||
if (*insertType == TSDB_QUERY_TYPE_STMT_INSERT && type == TSDB_QUERY_TYPE_INSERT) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pCmd->dataSourceType = type;
|
||||
if ((*insertType) != 0 && (*insertType) != type) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mixed up", sql);
|
||||
}
|
||||
|
||||
*insertType = type;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1093,6 @@ static int32_t parseBoundColumns(SSqlCmd* pCmd, SParsedDataColInfo* pColInfo, SS
|
|||
|
||||
_clean:
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->parseFinished = 1;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1106,7 +1108,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
int32_t totalNum = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
assert(pQueryInfo != NULL);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo):tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
@ -1120,9 +1122,9 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
if (NULL == pCmd->pTableBlockHashList) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (NULL == pCmd->pTableBlockHashList) {
|
||||
if (NULL == pCmd->insertParam.pTableBlockHashList) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (NULL == pCmd->insertParam.pTableBlockHashList) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _clean;
|
||||
}
|
||||
|
@ -1130,7 +1132,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
str = pCmd->curSql;
|
||||
}
|
||||
|
||||
tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->pTableBlockHashList);
|
||||
tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->insertParam.pTableBlockHashList);
|
||||
|
||||
while (1) {
|
||||
int32_t index = 0;
|
||||
|
@ -1142,7 +1144,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
* if the data is from the data file, no data has been generated yet. So, there no data to
|
||||
* merge or submit, save the file path and parse the file in other routines.
|
||||
*/
|
||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1153,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
* Otherwise, create the first submit block and submit to virtual node.
|
||||
*/
|
||||
if (totalNum == 0) {
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
goto _clean;
|
||||
} else {
|
||||
break;
|
||||
|
@ -1168,7 +1170,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
goto _clean;
|
||||
}
|
||||
|
||||
if ((code = tscSetTableFullName(pTableMetaInfo, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
if ((code = tscSetTableFullName(&pTableMetaInfo->name, &sTblToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1203,7 +1205,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
if (sToken.type == TK_FILE) {
|
||||
if (validateDataSource(pCmd, DATA_FROM_DATA_FILE, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_FILE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
|
@ -1236,12 +1238,12 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
if (bindedColumns == NULL) {
|
||||
STableMeta *pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
STableDataBlocks *dataBuf = NULL;
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta,
|
||||
&dataBuf, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1254,14 +1256,14 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
}
|
||||
} else { // bindedColumns != NULL
|
||||
// insert into tablename(col1, col2,..., coln) values(v1, v2,... vn);
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta;
|
||||
|
||||
if (validateDataSource(pCmd, DATA_FROM_SQL_STRING, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
if (validateDataSource(pCmd, TSDB_QUERY_TYPE_INSERT, sToken.z) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
||||
STableDataBlocks *dataBuf = NULL;
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
int32_t ret = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), tinfo.rowSize, &pTableMetaInfo->name, pTableMeta,
|
||||
&dataBuf, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1297,7 +1299,8 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
goto _clean;
|
||||
}
|
||||
|
||||
if ((pCmd->insertType != TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->pTableBlockHashList) > 0) { // merge according to vgId
|
||||
// merge according to vgId
|
||||
if (!TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT) && taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) {
|
||||
if ((code = tscMergeTableDataBlocks(pSql, true)) != TSDB_CODE_SUCCESS) {
|
||||
goto _clean;
|
||||
}
|
||||
|
@ -1308,7 +1311,6 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
|
||||
_clean:
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->parseFinished = 1;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1326,9 +1328,8 @@ int tsInsertInitialCheck(SSqlObj *pSql) {
|
|||
pCmd->count = 0;
|
||||
pCmd->command = TSDB_SQL_INSERT;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex);
|
||||
|
||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd);
|
||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT);
|
||||
|
||||
sToken = tStrGetToken(pSql->sqlstr, &index, false);
|
||||
if (sToken.type != TK_INTO) {
|
||||
|
@ -1343,11 +1344,11 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
if ((!pCmd->parseFinished) && (!initial)) {
|
||||
if (!initial) {
|
||||
tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->curSql);
|
||||
}
|
||||
|
||||
ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
ret = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (TSDB_CODE_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1357,31 +1358,32 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// make a backup as tsParseInsertSql may modify the string
|
||||
char* sqlstr = strdup(pSql->sqlstr);
|
||||
ret = tsParseInsertSql(pSql);
|
||||
if ((sqlstr == NULL) || (pSql->parseRetry >= 1) ||
|
||||
(ret != TSDB_CODE_TSC_SQL_SYNTAX_ERROR && ret != TSDB_CODE_TSC_INVALID_SQL)) {
|
||||
free(sqlstr);
|
||||
} else {
|
||||
assert(ret == TSDB_CODE_SUCCESS || ret == TSDB_CODE_TSC_ACTION_IN_PROGRESS || ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
|
||||
if (pSql->parseRetry < 1 && (ret == TSDB_CODE_TSC_SQL_SYNTAX_ERROR || ret == TSDB_CODE_TSC_INVALID_OPERATION)) {
|
||||
tscDebug("0x%"PRIx64 " parse insert sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret));
|
||||
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
free(pSql->sqlstr);
|
||||
pSql->sqlstr = sqlstr;
|
||||
pSql->parseRetry++;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) == TSDB_CODE_SUCCESS) {
|
||||
ret = tsParseInsertSql(pSql);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SSqlInfo SQLInfo = qSqlParse(pSql->sqlstr);
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
|
||||
SSqlInfo sqlInfo = qSqlParse(pSql->sqlstr);
|
||||
ret = tscValidateSqlInfo(pSql, &sqlInfo);
|
||||
if (ret == TSDB_CODE_TSC_INVALID_OPERATION && pSql->parseRetry < 1 && sqlInfo.type == TSDB_SQL_SELECT) {
|
||||
tscDebug("0x%"PRIx64 " parse query sql statement failed, code:%s, clear meta cache and retry ", pSql->self, tstrerror(ret));
|
||||
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
pSql->parseRetry++;
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
|
||||
ret = tscValidateSqlInfo(pSql, &sqlInfo);
|
||||
}
|
||||
|
||||
SqlInfoDestroy(&SQLInfo);
|
||||
SqlInfoDestroy(&sqlInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1398,8 +1400,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
pSql->res.numOfRows = 0;
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, 0)->pTableMeta;
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
|
@ -1411,7 +1412,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
return code;
|
||||
}
|
||||
|
||||
STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
|
||||
STableDataBlocks *pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0);
|
||||
if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1461,17 +1462,17 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
|||
// accumulate the total submit records
|
||||
pParentSql->res.numOfRows += pSql->res.numOfRows;
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||
|
||||
destroyTableNameList(pCmd);
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
@ -1479,7 +1480,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
|||
|
||||
STableDataBlocks *pTableDataBlock = NULL;
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tinfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pTableDataBlock, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1561,8 +1562,8 @@ void tscImportDataFromFile(SSqlObj *pSql) {
|
|||
return;
|
||||
}
|
||||
|
||||
assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0);
|
||||
pCmd->active = pCmd->pQueryInfo[0];
|
||||
assert(TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT) && strlen(pCmd->payload) != 0);
|
||||
pCmd->active = pCmd->pQueryInfo;
|
||||
|
||||
SImportFileSupport *pSupporter = calloc(1, sizeof(SImportFileSupport));
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, 0, parseFileSendDataBlock, pSupporter, TSDB_SQL_INSERT, NULL);
|
||||
|
|
|
@ -46,10 +46,14 @@ typedef struct SNormalStmt {
|
|||
|
||||
typedef struct SMultiTbStmt {
|
||||
bool nameSet;
|
||||
bool tagSet;
|
||||
uint64_t currentUid;
|
||||
uint32_t tbNum;
|
||||
SStrToken tbname;
|
||||
SHashObj *pTableHash;
|
||||
SStrToken stbname;
|
||||
SStrToken values;
|
||||
SArray *tags;
|
||||
SHashObj *pTableHash;
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
} SMultiTbStmt;
|
||||
|
||||
|
@ -283,9 +287,9 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
|||
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (!spd->cols[i].hasVal) { // current column do not have any value to insert, set it to null
|
||||
for (int32_t n = 0; n < rowNum; ++n) {
|
||||
for (int32_t n = 0; n < rowNum; ++n) {
|
||||
char *ptr = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * n + offset;
|
||||
|
||||
|
||||
if (schema[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||
varDataSetLen(ptr, sizeof(int8_t));
|
||||
*(uint8_t*) varDataVal(ptr) = TSDB_DATA_BINARY_NULL;
|
||||
|
@ -297,7 +301,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
offset += schema[i].bytes;
|
||||
}
|
||||
|
||||
|
@ -308,7 +312,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
|||
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||
|
||||
STableDataBlocks* pOneTableBlock = *p;
|
||||
while(pOneTableBlock) {
|
||||
|
@ -316,8 +320,8 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
|||
if (pBlocks->numOfRows > 0 && pOneTableBlock->boundColumnInfo.numOfBound < pOneTableBlock->boundColumnInfo.numOfCols) {
|
||||
fillColumnsNull(pOneTableBlock, pBlocks->numOfRows);
|
||||
}
|
||||
|
||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||
|
||||
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -775,7 +779,7 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -800,7 +804,7 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
|
|||
|
||||
if (!IS_VAR_DATA_TYPE(param->type)) {
|
||||
memcpy(data + param->offset, (char *)bind->buffer + bind->buffer_length * i, tDataTypes[param->type].bytes);
|
||||
|
||||
|
||||
if (param->offset == 0) {
|
||||
if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) {
|
||||
tscError("invalid timestamp");
|
||||
|
@ -829,23 +833,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
|
|||
varDataSetLen(data + param->offset, output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -853,15 +857,15 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
|||
|
||||
pBlock = *t1;
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -900,16 +904,16 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
int rowNum = bind->num;
|
||||
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -917,15 +921,15 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
|
||||
pBlock = *t1;
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -954,7 +958,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
tscError("0x%"PRIx64" param %d: num[%d:%d] not match", pStmt->pSql->self, param->idx, rowNum, bind[param->idx].num);
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
|
||||
|
@ -965,7 +969,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
|||
pCmd->batchSize += rowNum - 1;
|
||||
} else {
|
||||
SParamInfo* param = &pBlock->params[colIdx];
|
||||
|
||||
|
||||
int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
|
||||
|
@ -990,13 +994,12 @@ static int insertStmtUpdateBatch(STscStmt* stmt) {
|
|||
tscError("too many record:%d", pCmd->batchSize);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
||||
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||
if (t1 == NULL) {
|
||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -1019,11 +1022,11 @@ static int insertStmtUpdateBatch(STscStmt* stmt) {
|
|||
static int insertStmtAddBatch(STscStmt* stmt) {
|
||||
SSqlCmd* pCmd = &stmt->pSql->cmd;
|
||||
++pCmd->batchSize;
|
||||
|
||||
|
||||
if (stmt->multiTbInsert) {
|
||||
return insertStmtUpdateBatch(stmt);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1032,9 +1035,9 @@ static int insertStmtReset(STscStmt* pStmt) {
|
|||
if (pCmd->batchSize > 2) {
|
||||
int32_t alloced = (pCmd->batchSize + 1) / 2;
|
||||
|
||||
size_t size = taosArrayGetSize(pCmd->pDataBlocks);
|
||||
size_t size = taosArrayGetSize(pCmd->insertParam.pDataBlocks);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i);
|
||||
STableDataBlocks* pBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, i);
|
||||
|
||||
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||
pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced;
|
||||
|
@ -1045,7 +1048,7 @@ static int insertStmtReset(STscStmt* pStmt) {
|
|||
}
|
||||
pCmd->batchSize = 0;
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
pTableMetaInfo->vgroupIndex = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1056,22 +1059,21 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
assert(pCmd->numOfClause == 1);
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
assert(ret == 0);
|
||||
pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
||||
|
@ -1088,7 +1090,7 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
return code;
|
||||
}
|
||||
|
||||
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
|
||||
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0);
|
||||
code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -1106,15 +1108,15 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
|
||||
// data block reset
|
||||
pCmd->batchSize = 0;
|
||||
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||
tfree(pCmd->pTableNameList[i]);
|
||||
for(int32_t i = 0; i < pCmd->insertParam.numOfTables; ++i) {
|
||||
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pCmd->numOfTables = 0;
|
||||
tfree(pCmd->pTableNameList);
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->insertParam.numOfTables = 0;
|
||||
tfree(pCmd->insertParam.pTableNameList);
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
@ -1122,32 +1124,32 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
static void insertBatchClean(STscStmt* pStmt) {
|
||||
SSqlCmd *pCmd = &pStmt->pSql->cmd;
|
||||
SSqlObj *pSql = pStmt->pSql;
|
||||
int32_t size = taosHashGetSize(pCmd->pTableBlockHashList);
|
||||
|
||||
int32_t size = taosHashGetSize(pCmd->insertParam.pTableBlockHashList);
|
||||
|
||||
// data block reset
|
||||
pCmd->batchSize = 0;
|
||||
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||
tfree(pCmd->pTableNameList[i]);
|
||||
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pCmd->pTableNameList);
|
||||
tfree(pCmd->insertParam.pTableNameList);
|
||||
|
||||
/*
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||
|
||||
STableDataBlocks* pOneTableBlock = *p;
|
||||
|
||||
while (1) {
|
||||
while (1) {
|
||||
SSubmitBlk* pBlocks = (SSubmitBlk*) pOneTableBlock->pData;
|
||||
|
||||
|
||||
pOneTableBlock->size = sizeof(SSubmitBlk);
|
||||
|
||||
pBlocks->numOfRows = 0;
|
||||
|
||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
||||
|
||||
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||
if (p == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -1156,27 +1158,27 @@ static void insertBatchClean(STscStmt* pStmt) {
|
|||
}
|
||||
*/
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
pCmd->numOfTables = 0;
|
||||
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||
pCmd->insertParam.numOfTables = 0;
|
||||
|
||||
taosHashEmpty(pCmd->pTableBlockHashList);
|
||||
taosHashEmpty(pCmd->insertParam.pTableBlockHashList);
|
||||
tscFreeSqlResult(pSql);
|
||||
tscFreeSubobj(pSql);
|
||||
tfree(pSql->pSubs);
|
||||
pSql->subState.numOfSub = 0;
|
||||
pSql->subState.numOfSub = 0;
|
||||
}
|
||||
|
||||
static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
if(pStmt->mtb.nameSet == false) {
|
||||
tscError("0x%"PRIx64" no table name set", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
|
||||
|
||||
if (taosHashGetSize(pStmt->pSql->cmd.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||
if (taosHashGetSize(pStmt->pSql->cmd.insertParam.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||
tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
@ -1192,15 +1194,193 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
// wait for the callback function to post the semaphore
|
||||
tsem_wait(&pStmt->pSql->rspSem);
|
||||
|
||||
insertBatchClean(pStmt);
|
||||
|
||||
|
||||
return pStmt->pSql->res.code;
|
||||
}
|
||||
|
||||
|
||||
int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t index = 0;
|
||||
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||
pStmt->multiTbInsert = true;
|
||||
pStmt->mtb.tbname = sToken;
|
||||
pStmt->mtb.nameSet = false;
|
||||
if (pStmt->mtb.pTableHash == NULL) {
|
||||
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||
}
|
||||
|
||||
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
pStmt->mtb.tagSet = true;
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n > 0 && sToken.type == TK_VALUES) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (sToken.n <= 0 || sToken.type != TK_USING) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
pStmt->mtb.stbname = sToken;
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_TAGS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_LP) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
|
||||
|
||||
int32_t loopCont = 1;
|
||||
|
||||
while (loopCont) {
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
switch (sToken.type) {
|
||||
case TK_RP:
|
||||
loopCont = 0;
|
||||
break;
|
||||
case TK_VALUES:
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
case TK_QUESTION:
|
||||
pStmt->mtb.tagSet = false; //continue
|
||||
default:
|
||||
taosArrayPush(pStmt->mtb.tags, &sToken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pStmt->mtb.tags) <= 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
if (sToken.n <= 0 || sToken.type != TK_VALUES) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pStmt->mtb.values = sToken;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) {
|
||||
size_t tagNum = taosArrayGetSize(pStmt->mtb.tags);
|
||||
size_t size = 1048576;
|
||||
char *str = calloc(1, size);
|
||||
size_t len = 0;
|
||||
int32_t ret = 0;
|
||||
int32_t j = 0;
|
||||
|
||||
while (1) {
|
||||
len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z);
|
||||
if (len >= (size -1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
for (size_t i = 0; i < tagNum && len < (size - 1); ++i) {
|
||||
SStrToken *t = taosArrayGet(pStmt->mtb.tags, i);
|
||||
if (t->type == TK_QUESTION) {
|
||||
int32_t l = 0;
|
||||
if (i > 0) {
|
||||
str[len++] = ',';
|
||||
}
|
||||
|
||||
if (tags[j].is_null && (*tags[j].is_null)) {
|
||||
ret = converToStr(str + len, TSDB_DATA_TYPE_NULL, NULL, -1, &l);
|
||||
} else {
|
||||
if (tags[j].buffer == NULL) {
|
||||
free(str);
|
||||
tscError("empty");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l);
|
||||
}
|
||||
|
||||
++j;
|
||||
|
||||
if (ret) {
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
len += l;
|
||||
} else {
|
||||
len += (size_t)snprintf(str + len, size - len - 1, i > 0 ? ",%.*s" : "%.*s", t->n, t->z);
|
||||
}
|
||||
}
|
||||
|
||||
if (len >= (size - 1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(str, ") ");
|
||||
len += 2;
|
||||
|
||||
if ((len + strlen(pStmt->mtb.values.z)) >= (size - 1)) {
|
||||
size *= 2;
|
||||
free(str);
|
||||
str = calloc(1, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat(str, pStmt->mtb.values.z);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
free(pSql->sqlstr);
|
||||
pSql->sqlstr = str;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// interface functions
|
||||
|
||||
|
@ -1221,6 +1401,7 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) {
|
|||
pStmt->taos = pObj;
|
||||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
|
||||
if (pSql == NULL) {
|
||||
free(pStmt);
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1253,7 +1434,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
}
|
||||
|
||||
pStmt->last = STMT_PREPARE;
|
||||
|
||||
|
||||
SSqlObj* pSql = pStmt->pSql;
|
||||
size_t sqlLen = strlen(sql);
|
||||
|
||||
|
@ -1263,7 +1444,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
pSql->fp = waitForQueryRsp;
|
||||
pSql->fetchFp = waitForQueryRsp;
|
||||
|
||||
pCmd->insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
tscError("%p failed to malloc payload buffer", pSql);
|
||||
|
@ -1292,34 +1473,15 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
|
||||
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||
int32_t ret = stmtParseInsertTbTags(pSql, pStmt);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t index = 0;
|
||||
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
||||
|
||||
if (sToken.n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
if (pStmt->multiTbInsert) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||
pStmt->multiTbInsert = true;
|
||||
pStmt->mtb.tbname = sToken;
|
||||
pStmt->mtb.nameSet = false;
|
||||
if (pStmt->mtb.pTableHash == NULL) {
|
||||
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||
}
|
||||
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pStmt->multiTbInsert = false;
|
||||
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
|
@ -1336,8 +1498,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
return normalStmtPrepare(pStmt);
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
SSqlObj* pSql = pStmt->pSql;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
@ -1376,44 +1537,58 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
||||
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
||||
pCmd->batchSize = pBlk->numOfRows;
|
||||
|
||||
taosHashPut(pCmd->pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||
|
||||
taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||
|
||||
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
||||
|
||||
if (pStmt->mtb.tagSet) {
|
||||
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
||||
} else {
|
||||
if (tags == NULL) {
|
||||
tscError("No tags set");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
pStmt->mtb.nameSet = true;
|
||||
pStmt->mtb.tagSet = true;
|
||||
|
||||
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
|
||||
pSql->cmd.parseFinished = 0;
|
||||
pSql->cmd.numOfParams = 0;
|
||||
pSql->cmd.batchSize = 0;
|
||||
|
||||
if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) {
|
||||
SHashObj* hashList = pCmd->pTableBlockHashList;
|
||||
pCmd->pTableBlockHashList = NULL;
|
||||
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) {
|
||||
SHashObj* hashList = pCmd->insertParam.pTableBlockHashList;
|
||||
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||
tscResetSqlCmd(pCmd, true);
|
||||
pCmd->pTableBlockHashList = hashList;
|
||||
pCmd->insertParam.pTableBlockHashList = hashList;
|
||||
}
|
||||
|
||||
|
||||
int32_t code = tsParseSql(pStmt->pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
// wait for the callback function to post the semaphore
|
||||
tsem_wait(&pStmt->pSql->rspSem);
|
||||
|
||||
|
||||
code = pStmt->pSql->res.code;
|
||||
}
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
code = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -1426,15 +1601,20 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|||
pStmt->mtb.tbNum++;
|
||||
|
||||
taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES);
|
||||
|
||||
taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid));
|
||||
|
||||
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
|
||||
}
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||
return taos_stmt_set_tbname_tags(stmt, name, NULL);
|
||||
}
|
||||
|
||||
|
||||
int taos_stmt_close(TAOS_STMT* stmt) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
if (!pStmt->isInsert) {
|
||||
|
@ -1451,8 +1631,9 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
|||
if (pStmt->multiTbInsert) {
|
||||
taosHashCleanup(pStmt->mtb.pTableHash);
|
||||
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true);
|
||||
taosHashCleanup(pStmt->pSql->cmd.pTableBlockHashList);
|
||||
pStmt->pSql->cmd.pTableBlockHashList = NULL;
|
||||
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
||||
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
||||
taosArrayDestroy(pStmt->mtb.tags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1467,7 +1648,7 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
|
|||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return TSDB_CODE_TSC_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
if (pStmt->isInsert) {
|
||||
if (pStmt->multiTbInsert) {
|
||||
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
|
||||
|
@ -1482,7 +1663,7 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
|
|||
}
|
||||
|
||||
pStmt->last = STMT_BIND;
|
||||
|
||||
|
||||
return insertStmtBindParam(pStmt, bind);
|
||||
} else {
|
||||
return normalStmtBindParam(pStmt, bind);
|
||||
|
@ -1502,7 +1683,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
|
|||
tscError("0x%"PRIx64" invalid parameter", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (!pStmt->isInsert) {
|
||||
tscError("0x%"PRIx64" not or invalid batch insert", pStmt->pSql->self);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
|
@ -1512,7 +1693,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
|
|||
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH) {
|
||||
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_EXECUTE) {
|
||||
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
|
@ -1521,7 +1702,7 @@ int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
|
|||
}
|
||||
|
||||
pStmt->last = STMT_BIND;
|
||||
|
||||
|
||||
return insertStmtBindParamBatch(pStmt, bind, -1);
|
||||
}
|
||||
|
||||
|
@ -1546,7 +1727,7 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in
|
|||
if (pStmt->last != STMT_SETTBNAME && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL) {
|
||||
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pStmt->last != STMT_PREPARE && pStmt->last != STMT_ADD_BATCH && pStmt->last != STMT_BIND_COL && pStmt->last != STMT_EXECUTE) {
|
||||
tscError("0x%"PRIx64" bind param status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
|
@ -1567,7 +1748,7 @@ int taos_stmt_add_batch(TAOS_STMT* stmt) {
|
|||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return TSDB_CODE_TSC_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
if (pStmt->isInsert) {
|
||||
if (pStmt->last != STMT_BIND && pStmt->last != STMT_BIND_COL) {
|
||||
tscError("0x%"PRIx64" add batch status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
|
@ -1575,10 +1756,10 @@ int taos_stmt_add_batch(TAOS_STMT* stmt) {
|
|||
}
|
||||
|
||||
pStmt->last = STMT_ADD_BATCH;
|
||||
|
||||
|
||||
return insertStmtAddBatch(pStmt);
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_COM_OPS_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
|
@ -1597,7 +1778,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
|||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return TSDB_CODE_TSC_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
if (pStmt->isInsert) {
|
||||
if (pStmt->last != STMT_ADD_BATCH) {
|
||||
tscError("0x%"PRIx64" exec status error, last:%d", pStmt->pSql->self, pStmt->last);
|
||||
|
@ -1605,7 +1786,7 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
|||
}
|
||||
|
||||
pStmt->last = STMT_EXECUTE;
|
||||
|
||||
|
||||
if (pStmt->multiTbInsert) {
|
||||
ret = insertBatchStmtExecute(pStmt);
|
||||
} else {
|
||||
|
@ -1617,9 +1798,10 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
|||
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
} else {
|
||||
if (pStmt->pSql != NULL) {
|
||||
taos_free_result(pStmt->pSql);
|
||||
tscFreeSqlObj(pStmt->pSql);
|
||||
pStmt->pSql = NULL;
|
||||
}
|
||||
|
||||
pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql);
|
||||
ret = taos_errno(pStmt->pSql);
|
||||
free(sql);
|
||||
|
@ -1689,16 +1871,16 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
|
|||
|
||||
if (pStmt->isInsert) {
|
||||
SSqlCmd* pCmd = &pStmt->pSql->cmd;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
}
|
||||
|
||||
STableDataBlocks* pBlock = NULL;
|
||||
|
||||
int32_t ret =
|
||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||
if (ret != 0) {
|
||||
// todo handle error
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -94,6 +94,7 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
|||
|
||||
pTableMeta->tableType = pTableMetaMsg->tableType;
|
||||
pTableMeta->vgId = pTableMetaMsg->vgroup.vgId;
|
||||
pTableMeta->suid = pTableMetaMsg->suid;
|
||||
|
||||
pTableMeta->tableInfo = (STableComInfo) {
|
||||
.numOfTags = pTableMetaMsg->numOfTags,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -373,11 +373,15 @@ int taos_num_fields(TAOS_RES *res) {
|
|||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
int32_t num = 0;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return num;
|
||||
}
|
||||
|
||||
while(pQueryInfo->pDownstream != NULL) {
|
||||
pQueryInfo = pQueryInfo->pDownstream;
|
||||
}
|
||||
|
||||
size_t numOfCols = tscNumOfFields(pQueryInfo);
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SInternalField* pInfo = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i);
|
||||
|
@ -408,7 +412,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -560,7 +564,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if ((pQueryInfo == NULL) || pQueryInfo->globalMerge) {
|
||||
return true;
|
||||
|
@ -614,7 +618,7 @@ int taos_errno(TAOS_RES *tres) {
|
|||
* why the sql is invalid
|
||||
*/
|
||||
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||
if (code != TSDB_CODE_TSC_INVALID_SQL
|
||||
if (code != TSDB_CODE_TSC_INVALID_OPERATION
|
||||
&& code != TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
@ -673,7 +677,7 @@ char *taos_get_client_info() { return version; }
|
|||
static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if (!pQueryInfo->globalMerge) {
|
||||
return;
|
||||
|
@ -724,7 +728,7 @@ void taos_stop_query(TAOS_RES *res) {
|
|||
// set the error code for master pSqlObj firstly
|
||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
if (pQueryInfo->globalMerge) {
|
||||
assert(pSql->rpcRid <= 0);
|
||||
|
@ -754,7 +758,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
if (pQueryInfo == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
@ -829,9 +833,9 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int32_t charLen = varDataLen((char*)row[i] - VARSTR_HEADER_SIZE);
|
||||
if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||
assert(charLen <= fields[i].bytes);
|
||||
assert(charLen <= fields[i].bytes && charLen >= 0);
|
||||
} else {
|
||||
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE);
|
||||
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0);
|
||||
}
|
||||
|
||||
memcpy(str + len, row[i], charLen);
|
||||
|
@ -868,15 +872,11 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
|
||||
pSql->pTscObj = taos;
|
||||
pSql->pTscObj = taos;
|
||||
pSql->signature = pSql;
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pRes->numOfTotal = 0;
|
||||
pRes->numOfClauseTotal = 0;
|
||||
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj);
|
||||
|
||||
|
@ -896,10 +896,10 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
strtolower(pSql->sqlstr, sql);
|
||||
|
||||
pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->pTableBlockHashList) {
|
||||
taosHashCleanup(pCmd->pTableBlockHashList);
|
||||
pCmd->pTableBlockHashList = NULL;
|
||||
// pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->insertParam.pTableBlockHashList) {
|
||||
taosHashCleanup(pCmd->insertParam.pTableBlockHashList);
|
||||
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||
}
|
||||
|
||||
pSql->fp = asyncCallback;
|
||||
|
@ -921,90 +921,19 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
||||
// must before clean the sqlcmd object
|
||||
tscResetSqlCmd(&pSql->cmd, false);
|
||||
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pCmd->command = TSDB_SQL_MULTI_META;
|
||||
pCmd->count = 0;
|
||||
|
||||
int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
char *str = (char *)tblNameList;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex);
|
||||
if (pQueryInfo == NULL) {
|
||||
pSql->res.code = terrno;
|
||||
return terrno;
|
||||
void loadMultiTableMetaCallback(void *param, TAOS_RES *res, int code) {
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
|
||||
if (pSql == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
pSql->res.code = code;
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
if ((code = tscAllocPayload(pCmd, tblListLen + 16)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
char *nextStr;
|
||||
char tblName[TSDB_TABLE_FNAME_LEN];
|
||||
int payloadLen = 0;
|
||||
char *pMsg = pCmd->payload;
|
||||
while (1) {
|
||||
nextStr = strchr(str, ',');
|
||||
if (nextStr == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(tblName, str, nextStr - str);
|
||||
int32_t len = (int32_t)(nextStr - str);
|
||||
tblName[len] = '\0';
|
||||
|
||||
str = nextStr + 1;
|
||||
len = (int32_t)strtrim(tblName);
|
||||
|
||||
SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName};
|
||||
tGetToken(tblName, &sToken.type);
|
||||
|
||||
// Check if the table name available or not
|
||||
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
sprintf(pCmd->payload, "table name is invalid");
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((code = tscSetTableFullName(pTableMetaInfo, &sToken, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
||||
sprintf(pCmd->payload, "tables over the max number");
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t xlen = tNameLen(&pTableMetaInfo->name);
|
||||
if (payloadLen + xlen + 128 >= pCmd->allocSize) {
|
||||
char *pNewMem = realloc(pCmd->payload, pCmd->allocSize + tblListLen);
|
||||
if (pNewMem == NULL) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
sprintf(pCmd->payload, "failed to allocate memory");
|
||||
return code;
|
||||
}
|
||||
|
||||
pCmd->payload = pNewMem;
|
||||
pCmd->allocSize = pCmd->allocSize + tblListLen;
|
||||
pMsg = pCmd->payload;
|
||||
}
|
||||
|
||||
char n[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, n);
|
||||
payloadLen += sprintf(pMsg + payloadLen, "%s,", n);
|
||||
}
|
||||
|
||||
*(pMsg + payloadLen) = '\0';
|
||||
pCmd->payloadLen = payloadLen + 1;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
static void freeElem(void* p) {
|
||||
tfree(*(char**)p);
|
||||
}
|
||||
|
||||
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||
|
@ -1020,38 +949,28 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
pSql->pTscObj = taos;
|
||||
pSql->signature = pSql;
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
pSql->fp = NULL; // todo set the correct callback function pointer
|
||||
pSql->cmd.pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
pRes->code = 0;
|
||||
pRes->numOfTotal = 0; // the number of getting table meta from server
|
||||
pRes->numOfClauseTotal = 0;
|
||||
|
||||
assert(pSql->fp == NULL);
|
||||
tscDebug("0x%"PRIx64" tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||
|
||||
int32_t tblListLen = (int32_t)strlen(tableNameList);
|
||||
if (tblListLen > MAX_TABLE_NAME_LENGTH) {
|
||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, tblListLen, MAX_TABLE_NAME_LENGTH);
|
||||
int32_t length = (int32_t)strlen(tableNameList);
|
||||
if (length > MAX_TABLE_NAME_LENGTH) {
|
||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, length, MAX_TABLE_NAME_LENGTH);
|
||||
tscFreeSqlObj(pSql);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
char *str = calloc(1, tblListLen + 1);
|
||||
char *str = calloc(1, length + 1);
|
||||
if (str == NULL) {
|
||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||
tscError("0x%"PRIx64" failed to allocate sql string buffer", pSql->self);
|
||||
tscFreeSqlObj(pSql);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
strtolower(str, tableNameList);
|
||||
int32_t code = (uint8_t) tscParseTblNameList(pSql, str, tblListLen);
|
||||
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
||||
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
/*
|
||||
* set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query.
|
||||
* If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscBuildAndSendRequest()
|
||||
* to free connection, which may cause segment fault, when the parse phrase is not even successfully executed.
|
||||
*/
|
||||
pRes->qId = 0;
|
||||
int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist);
|
||||
free(str);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1059,12 +978,23 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
return code;
|
||||
}
|
||||
|
||||
tscDoQuery(pSql);
|
||||
registerSqlObj(pSql);
|
||||
tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||
|
||||
tscDebug("0x%"PRIx64" load multi-table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj);
|
||||
if ((code = pRes->code) != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pSql);
|
||||
code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, loadMultiTableMetaCallback);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
taosArrayDestroyEx(plist, freeElem);
|
||||
taosArrayDestroyEx(vgroupList, freeElem);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeRegisteredSqlObj(pSql);
|
||||
return code;
|
||||
}
|
||||
|
||||
tsem_wait(&pSql->rspSem);
|
||||
tscFreeRegisteredSqlObj(pSql);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l
|
|||
|
||||
static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||
if (pExpr->base.functionId != TSDB_FUNC_PRJ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
code = tscGetSTableVgroupInfo(pSql, 0);
|
||||
code = tscGetSTableVgroupInfo(pSql, pQueryInfo);
|
||||
}
|
||||
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
|
@ -138,7 +138,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
|||
|
||||
pStream->numOfRes = 0; // reset the numOfRes.
|
||||
SSqlObj *pSql = pStream->pSql;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
tscDebug("0x%"PRIx64" timer launch query", pSql->self);
|
||||
|
||||
if (pStream->isProject) {
|
||||
|
@ -197,7 +197,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self,
|
||||
pStream, numOfRows, retryDelay);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0);
|
||||
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
@ -224,7 +224,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) {
|
||||
#if 0
|
||||
SSqlObj * pSql = pStream->pSql;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) {
|
||||
return;
|
||||
|
@ -273,7 +273,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
|
||||
if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful.
|
||||
|
@ -444,7 +444,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
int64_t minIntervalTime =
|
||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
||||
sprintf(pSql->cmd.payload, "the interval value is 0");
|
||||
|
@ -494,7 +494,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
}
|
||||
|
||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
if (pStream->isProject) {
|
||||
// no data in table, flush all data till now to destination meter, 10sec delay
|
||||
|
@ -556,7 +556,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
|||
return;
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
||||
|
@ -614,31 +614,32 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pStream->stime = stime;
|
||||
pStream->fp = fp;
|
||||
pStream->stime = stime;
|
||||
pStream->fp = fp;
|
||||
pStream->callback = callback;
|
||||
pStream->param = param;
|
||||
pStream->pSql = pSql;
|
||||
pSql->pStream = pStream;
|
||||
pSql->param = pStream;
|
||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||
pStream->param = param;
|
||||
pStream->pSql = pSql;
|
||||
|
||||
pSql->sqlstr = calloc(1, strlen(sqlstr) + 1);
|
||||
pSql->pStream = pStream;
|
||||
pSql->param = pStream;
|
||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||
pSql->sqlstr = calloc(1, strlen(sqlstr) + 1);
|
||||
if (pSql->sqlstr == NULL) {
|
||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||
tscFreeSqlObj(pSql);
|
||||
free(pStream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strtolower(pSql->sqlstr, sqlstr);
|
||||
pSql->fp = tscCreateStream;
|
||||
pSql->fetchFp = tscCreateStream;
|
||||
pSql->cmd.resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
tsem_init(&pSql->rspSem, 0, 0);
|
||||
registerSqlObj(pSql);
|
||||
|
||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||
tsem_init(&pSql->rspSem, 0, 0);
|
||||
|
||||
pSql->fp = tscCreateStream;
|
||||
pSql->fetchFp = tscCreateStream;
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
|
|
|
@ -151,6 +151,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
strtolower(pSql->sqlstr, pSql->sqlstr);
|
||||
pRes->qId = 0;
|
||||
pRes->numOfRows = 1;
|
||||
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||
|
||||
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -173,7 +174,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
line = __LINE__;
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -215,7 +216,7 @@ static void tscProcessSubscriptionTimer(void *handle, void *tmrId) {
|
|||
taosTmrReset(tscProcessSubscriptionTimer, pSub->interval, pSub, tscTmr, &pSub->pTimer);
|
||||
}
|
||||
|
||||
|
||||
//TODO refactor: extract table list name not simply from the sql
|
||||
static SArray* getTableList( SSqlObj* pSql ) {
|
||||
const char* p = strstr( pSql->sqlstr, " from " );
|
||||
assert(p != NULL); // we are sure this is a 'select' statement
|
||||
|
@ -224,11 +225,11 @@ static SArray* getTableList( SSqlObj* pSql ) {
|
|||
|
||||
SSqlObj* pNew = taos_query(pSql->pTscObj, sql);
|
||||
if (pNew == NULL) {
|
||||
tscError("0x%"PRIx64"failed to retrieve table id: cannot create new sql object.", pSql->self);
|
||||
tscError("0x%"PRIx64" failed to retrieve table id: cannot create new sql object.", pSql->self);
|
||||
return NULL;
|
||||
|
||||
} else if (taos_errno(pNew) != TSDB_CODE_SUCCESS) {
|
||||
tscError("0x%"PRIx64"failed to retrieve table id,error: %s", pSql->self, tstrerror(taos_errno(pNew)));
|
||||
tscError("0x%"PRIx64" failed to retrieve table id,error: %s", pSql->self, tstrerror(taos_errno(pNew)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -266,7 +267,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
|
||||
pSub->lastSyncTime = taosGetTimestampMs();
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0};
|
||||
|
@ -284,7 +285,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
}
|
||||
size_t numOfTables = taosArrayGetSize(tables);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress));
|
||||
for( size_t i = 0; i < numOfTables; i++ ) {
|
||||
STidTags* tt = taosArrayGet( tables, i );
|
||||
|
@ -304,7 +305,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
|||
}
|
||||
taosArrayDestroy(tables);
|
||||
|
||||
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
||||
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -503,8 +504,8 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
SSqlObj *pSql = pSub->pSql;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription
|
||||
|
||||
size_t size = taosArrayGetSize(pSub->progress);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -242,6 +242,7 @@ typedef struct SDataCol {
|
|||
int len; // column data length
|
||||
VarDataOffsetT *dataOff; // For binary and nchar data, the offset in the data column
|
||||
void * pData; // Actual data pointer
|
||||
TSKEY ts; // only used in last NULL column
|
||||
} SDataCol;
|
||||
|
||||
static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
||||
|
|
|
@ -142,12 +142,15 @@ extern int32_t tsMonitorInterval;
|
|||
extern int8_t tsEnableStream;
|
||||
|
||||
// internal
|
||||
extern int8_t tsCompactMnodeWal;
|
||||
extern int8_t tsPrintAuth;
|
||||
extern int8_t tscEmbedded;
|
||||
extern char configDir[];
|
||||
extern char tsVnodeDir[];
|
||||
extern char tsDnodeDir[];
|
||||
extern char tsMnodeDir[];
|
||||
extern char tsMnodeBakDir[];
|
||||
extern char tsMnodeTmpDir[];
|
||||
extern char tsDataDir[];
|
||||
extern char tsLogDir[];
|
||||
extern char tsScriptDir[];
|
||||
|
|
|
@ -44,8 +44,8 @@ typedef struct SResPair {
|
|||
// the structure for sql function in select clause
|
||||
typedef struct SSqlExpr {
|
||||
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
|
||||
char token[TSDB_COL_NAME_LEN]; // original token
|
||||
SColIndex colInfo;
|
||||
|
||||
uint64_t uid; // refactor use the pointer
|
||||
|
||||
int16_t functionId; // function id in aAgg array
|
||||
|
@ -92,10 +92,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len);
|
|||
|
||||
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
|
||||
|
||||
//SSchema tGetTbnameColumnSchema();
|
||||
|
||||
SSchema tGetBlockDistColumnSchema();
|
||||
|
||||
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name);
|
||||
|
||||
bool tscValidateTableNameLength(size_t len);
|
||||
|
|
|
@ -2569,6 +2569,7 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
|
|||
case TSDB_BINARY_OP_REMAINDER:
|
||||
return vectorRemainder;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <texpr.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "texpr.h"
|
||||
|
@ -465,27 +466,29 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
tExprNode* exprdup(tExprNode* pTree) {
|
||||
if (pTree == NULL) {
|
||||
tExprNode* exprdup(tExprNode* pNode) {
|
||||
if (pNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
||||
if (pTree->nodeType == TSQL_NODE_EXPR) {
|
||||
tExprNode* pLeft = exprdup(pTree->_node.pLeft);
|
||||
tExprNode* pRight = exprdup(pTree->_node.pRight);
|
||||
tExprNode* pCloned = calloc(1, sizeof(tExprNode));
|
||||
if (pNode->nodeType == TSQL_NODE_EXPR) {
|
||||
tExprNode* pLeft = exprdup(pNode->_node.pLeft);
|
||||
tExprNode* pRight = exprdup(pNode->_node.pRight);
|
||||
|
||||
pNode->nodeType = TSQL_NODE_EXPR;
|
||||
pNode->_node.pLeft = pLeft;
|
||||
pNode->_node.pRight = pRight;
|
||||
} else if (pTree->nodeType == TSQL_NODE_VALUE) {
|
||||
pNode->pVal = calloc(1, sizeof(tVariant));
|
||||
tVariantAssign(pNode->pVal, pTree->pVal);
|
||||
} else if (pTree->nodeType == TSQL_NODE_COL) {
|
||||
pNode->pSchema = calloc(1, sizeof(SSchema));
|
||||
*pNode->pSchema = *pTree->pSchema;
|
||||
pCloned->_node.pLeft = pLeft;
|
||||
pCloned->_node.pRight = pRight;
|
||||
pCloned->_node.optr = pNode->_node.optr;
|
||||
pCloned->_node.hasPK = pNode->_node.hasPK;
|
||||
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
|
||||
pCloned->pVal = calloc(1, sizeof(tVariant));
|
||||
tVariantAssign(pCloned->pVal, pNode->pVal);
|
||||
} else if (pNode->nodeType == TSQL_NODE_COL) {
|
||||
pCloned->pSchema = calloc(1, sizeof(SSchema));
|
||||
*pCloned->pSchema = *pNode->pSchema;
|
||||
}
|
||||
|
||||
return pNode;
|
||||
pCloned->nodeType = pNode->nodeType;
|
||||
return pCloned;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,12 +176,15 @@ int32_t tsMonitorInterval = 30; // seconds
|
|||
int8_t tsEnableStream = 1;
|
||||
|
||||
// internal
|
||||
int8_t tsCompactMnodeWal = 0;
|
||||
int8_t tsPrintAuth = 0;
|
||||
int8_t tscEmbedded = 0;
|
||||
char configDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsVnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsMnodeDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsMnodeTmpDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsMnodeBakDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsDataDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsScriptDir[TSDB_FILENAME_LEN] = {0};
|
||||
char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
|
||||
|
|
|
@ -33,15 +33,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len) {
|
|||
return strlen(prefix);
|
||||
}
|
||||
|
||||
SSchema tGetBlockDistColumnSchema() {
|
||||
SSchema s = {0};
|
||||
s.bytes = TSDB_MAX_BINARY_LEN;;
|
||||
s.type = TSDB_DATA_TYPE_BINARY;
|
||||
s.colId = TSDB_BLOCK_DIST_COLUMN_INDEX;
|
||||
tstrncpy(s.name, TSQL_BLOCK_DIST_L, TSDB_COL_NAME_LEN);
|
||||
return s;
|
||||
}
|
||||
|
||||
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name) {
|
||||
SSchema s = {0};
|
||||
|
||||
|
|
|
@ -310,6 +310,16 @@ public class TSDBJNIConnector {
|
|||
|
||||
private native int setBindTableNameImp(long stmt, String name, long conn);
|
||||
|
||||
public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException {
|
||||
int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(),
|
||||
nullList.array(), this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags");
|
||||
}
|
||||
}
|
||||
|
||||
private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn);
|
||||
|
||||
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException {
|
||||
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||
|
|
|
@ -41,6 +41,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
private boolean isPrepared;
|
||||
|
||||
private ArrayList<ColumnInfo> colData;
|
||||
private ArrayList<TableTagInfo> tableTags;
|
||||
private int tagValueLength;
|
||||
|
||||
private String tableName;
|
||||
private long nativeStmtHandle = 0;
|
||||
|
||||
|
@ -63,8 +66,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
if (parameterCnt > 1) {
|
||||
// the table name is also a parameter, so ignore it.
|
||||
this.colData = new ArrayList<ColumnInfo>(parameterCnt - 1);
|
||||
this.colData.addAll(Collections.nCopies(parameterCnt - 1, null));
|
||||
this.colData = new ArrayList<ColumnInfo>();
|
||||
this.tableTags = new ArrayList<TableTagInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,11 +565,109 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
}
|
||||
};
|
||||
|
||||
private static class TableTagInfo {
|
||||
private boolean isNull;
|
||||
private Object value;
|
||||
private int type;
|
||||
public TableTagInfo(Object value, int type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static TableTagInfo createNullTag(int type) {
|
||||
TableTagInfo info = new TableTagInfo(null, type);
|
||||
info.isNull = true;
|
||||
return info;
|
||||
}
|
||||
};
|
||||
|
||||
public void setTableName(String name) {
|
||||
this.tableName = name;
|
||||
}
|
||||
|
||||
private void ensureTagCapacity(int index) {
|
||||
if (this.tableTags.size() < index + 1) {
|
||||
int delta = index + 1 - this.tableTags.size();
|
||||
this.tableTags.addAll(Collections.nCopies(delta, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void setTagNull(int index, int type) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, TableTagInfo.createNullTag(type));
|
||||
}
|
||||
|
||||
public void setTagBoolean(int index, boolean value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagInt(int index, int value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT));
|
||||
this.tagValueLength += Integer.BYTES;
|
||||
}
|
||||
|
||||
public void setTagByte(int index, byte value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT));
|
||||
this.tagValueLength += Byte.BYTES;
|
||||
}
|
||||
|
||||
public void setTagShort(int index, short value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT));
|
||||
this.tagValueLength += Short.BYTES;
|
||||
}
|
||||
|
||||
public void setTagLong(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagTimestamp(int index, long value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP));
|
||||
this.tagValueLength += Long.BYTES;
|
||||
}
|
||||
|
||||
public void setTagFloat(int index, float value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT));
|
||||
this.tagValueLength += Float.BYTES;
|
||||
}
|
||||
|
||||
public void setTagDouble(int index, double value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE));
|
||||
this.tagValueLength += Double.BYTES;
|
||||
}
|
||||
|
||||
public void setTagString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY));
|
||||
this.tagValueLength += value.getBytes().length;
|
||||
}
|
||||
|
||||
public void setTagNString(int index, String value) {
|
||||
ensureTagCapacity(index);
|
||||
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR));
|
||||
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
try {
|
||||
this.tagValueLength += value.getBytes(charset).length;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
||||
if (this.colData.size() == 0) {
|
||||
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
|
||||
|
||||
}
|
||||
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
||||
if (col == null) {
|
||||
ColumnInfo p = new ColumnInfo();
|
||||
|
@ -641,7 +742,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
|||
|
||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
||||
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||
|
||||
if (this.tableTags == null) {
|
||||
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||
} else {
|
||||
int num = this.tableTags.size();
|
||||
ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength);
|
||||
tagDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer typeList = ByteBuffer.allocate(num);
|
||||
typeList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES);
|
||||
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
|
||||
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
for (int i = 0; i < num; ++i) {
|
||||
TableTagInfo tag = this.tableTags.get(i);
|
||||
if (tag.isNull) {
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(1);
|
||||
lengthList.putLong(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (tag.type) {
|
||||
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||
Integer val = (Integer) tag.value;
|
||||
tagDataList.putInt(val);
|
||||
lengthList.putLong(Integer.BYTES);
|
||||
break;
|
||||
}
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||
Byte val = (Byte) tag.value;
|
||||
tagDataList.put(val);
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||
Boolean val = (Boolean) tag.value;
|
||||
tagDataList.put((byte) (val ? 1 : 0));
|
||||
lengthList.putLong(Byte.BYTES);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||
Short val = (Short) tag.value;
|
||||
tagDataList.putShort(val);
|
||||
lengthList.putLong(Short.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||
Long val = (Long) tag.value;
|
||||
tagDataList.putLong(val == null ? 0 : val);
|
||||
lengthList.putLong(Long.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||
Float val = (Float) tag.value;
|
||||
tagDataList.putFloat(val == null ? 0 : val);
|
||||
lengthList.putLong(Float.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||
Double val = (Double) tag.value;
|
||||
tagDataList.putDouble(val == null ? 0 : val);
|
||||
lengthList.putLong(Double.BYTES);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||
String charset = TaosGlobalConfig.getCharset();
|
||||
String val = (String) tag.value;
|
||||
|
||||
byte[] b = null;
|
||||
try {
|
||||
if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||
b = val.getBytes();
|
||||
} else {
|
||||
b = val.getBytes(charset);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
tagDataList.put(b);
|
||||
lengthList.putLong(b.length);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||
}
|
||||
}
|
||||
|
||||
typeList.put((byte) tag.type);
|
||||
isNullList.putInt(tag.isNull? 1 : 0);
|
||||
}
|
||||
|
||||
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
|
||||
typeList, lengthList, isNullList);
|
||||
}
|
||||
|
||||
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
||||
if (colInfo == null) {
|
||||
|
|
|
@ -207,10 +207,69 @@ public class TSDBPreparedStatementTest {
|
|||
while(rs.next()) {
|
||||
rows++;
|
||||
}
|
||||
Assert.assertEquals(numOfRows, rows);
|
||||
Assert.assertEquals(numOfRows, rows);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindDataSelectColumnTest() throws SQLException {
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
int numOfRows = 1000;
|
||||
|
||||
for (int loop = 0; loop < 10; loop++){
|
||||
stmt.execute("drop table if exists weather_test");
|
||||
stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))");
|
||||
|
||||
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? (ts, f1, f7) values(?, ?, ?)");
|
||||
Random r = new Random();
|
||||
s.setTableName("weather_test");
|
||||
|
||||
ArrayList<Long> ts = new ArrayList<Long>();
|
||||
for(int i = 0; i < numOfRows; i++) {
|
||||
ts.add(System.currentTimeMillis() + i);
|
||||
}
|
||||
s.setTimestamp(0, ts);
|
||||
|
||||
int random = 10 + r.nextInt(5);
|
||||
ArrayList<String> s2 = new ArrayList<String>();
|
||||
for(int i = 0; i < numOfRows; i++) {
|
||||
if(i % random == 0) {
|
||||
s2.add(null);
|
||||
}else{
|
||||
s2.add("分支" + i % 4);
|
||||
}
|
||||
}
|
||||
s.setNString(1, s2, 4);
|
||||
|
||||
random = 10 + r.nextInt(5);
|
||||
ArrayList<String> s5 = new ArrayList<String>();
|
||||
for(int i = 0; i < numOfRows; i++) {
|
||||
if(i % random == 0) {
|
||||
s5.add(null);
|
||||
}else{
|
||||
s5.add("test" + i % 10);
|
||||
}
|
||||
}
|
||||
s.setString(2, s5, 10);
|
||||
|
||||
s.columnDataAddBatch();
|
||||
s.columnDataExecuteBatch();
|
||||
s.columnDataCloseBatch();
|
||||
|
||||
String sql = "select * from weather_test";
|
||||
PreparedStatement statement = conn.prepareStatement(sql);
|
||||
ResultSet rs = statement.executeQuery();
|
||||
int rows = 0;
|
||||
while(rs.next()) {
|
||||
rows++;
|
||||
}
|
||||
Assert.assertEquals(numOfRows, rows);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void setBoolean() throws SQLException {
|
||||
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
|
||||
|
|
|
@ -9,7 +9,7 @@ const ffi = require('ffi-napi');
|
|||
const ArrayType = require('ref-array-napi');
|
||||
const Struct = require('ref-struct-napi');
|
||||
const FieldTypes = require('./constants');
|
||||
const errors = require ('./error');
|
||||
const errors = require('./error');
|
||||
const TaosObjects = require('./taosobjects');
|
||||
const { NULL_POINTER } = require('ref-napi');
|
||||
|
||||
|
@ -22,7 +22,7 @@ function convertMicrosecondsToDatetime(time) {
|
|||
return new TaosObjects.TaosTimestamp(time * 0.001, true);
|
||||
}
|
||||
|
||||
function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
timestampConverter = convertMillisecondsToDatetime;
|
||||
if (micro == true) {
|
||||
timestampConverter = convertMicrosecondsToDatetime;
|
||||
|
@ -44,14 +44,14 @@ function convertTimestamp(data, num_of_rows, nbytes = 0, offset = 0, micro=false
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = new Array(data.length);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i] == 0) {
|
||||
res[i] = false;
|
||||
}
|
||||
else if (data[i] == 1){
|
||||
else if (data[i] == 1) {
|
||||
res[i] = true;
|
||||
}
|
||||
else if (data[i] == FieldTypes.C_BOOL_NULL) {
|
||||
|
@ -60,29 +60,29 @@ function convertBool(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertTinyint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertTinyint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
while (currOffset < data.length) {
|
||||
let d = data.readIntLE(currOffset,1);
|
||||
let d = data.readIntLE(currOffset, 1);
|
||||
res.push(d == FieldTypes.C_TINYINT_NULL ? null : d);
|
||||
currOffset += nbytes;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function convertSmallint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertSmallint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
while (currOffset < data.length) {
|
||||
let d = data.readIntLE(currOffset,2);
|
||||
let d = data.readIntLE(currOffset, 2);
|
||||
res.push(d == FieldTypes.C_SMALLINT_NULL ? null : d);
|
||||
currOffset += nbytes;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
|
@ -93,7 +93,7 @@ function convertInt(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
|
@ -104,7 +104,7 @@ function convertBigint(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
|
@ -115,7 +115,7 @@ function convertFloat(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
|
@ -126,7 +126,7 @@ function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let currOffset = 0;
|
||||
|
@ -142,7 +142,7 @@ function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
||||
function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro = false) {
|
||||
data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset);
|
||||
let res = [];
|
||||
let dataEntry = data.slice(0, nbytes); //one entry in a row under a column;
|
||||
|
@ -153,23 +153,23 @@ function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro=false) {
|
|||
|
||||
// Object with all the relevant converters from pblock data to javascript readable data
|
||||
let convertFunctions = {
|
||||
[FieldTypes.C_BOOL] : convertBool,
|
||||
[FieldTypes.C_TINYINT] : convertTinyint,
|
||||
[FieldTypes.C_SMALLINT] : convertSmallint,
|
||||
[FieldTypes.C_INT] : convertInt,
|
||||
[FieldTypes.C_BIGINT] : convertBigint,
|
||||
[FieldTypes.C_FLOAT] : convertFloat,
|
||||
[FieldTypes.C_DOUBLE] : convertDouble,
|
||||
[FieldTypes.C_BINARY] : convertBinary,
|
||||
[FieldTypes.C_TIMESTAMP] : convertTimestamp,
|
||||
[FieldTypes.C_NCHAR] : convertNchar
|
||||
[FieldTypes.C_BOOL]: convertBool,
|
||||
[FieldTypes.C_TINYINT]: convertTinyint,
|
||||
[FieldTypes.C_SMALLINT]: convertSmallint,
|
||||
[FieldTypes.C_INT]: convertInt,
|
||||
[FieldTypes.C_BIGINT]: convertBigint,
|
||||
[FieldTypes.C_FLOAT]: convertFloat,
|
||||
[FieldTypes.C_DOUBLE]: convertDouble,
|
||||
[FieldTypes.C_BINARY]: convertBinary,
|
||||
[FieldTypes.C_TIMESTAMP]: convertTimestamp,
|
||||
[FieldTypes.C_NCHAR]: convertNchar
|
||||
}
|
||||
|
||||
// Define TaosField structure
|
||||
var char_arr = ArrayType(ref.types.char);
|
||||
var TaosField = Struct({
|
||||
'name': char_arr,
|
||||
});
|
||||
'name': char_arr,
|
||||
});
|
||||
TaosField.fields.name.type.size = 65;
|
||||
TaosField.defineProperty('type', ref.types.char);
|
||||
TaosField.defineProperty('bytes', ref.types.short);
|
||||
|
@ -183,7 +183,7 @@ TaosField.defineProperty('bytes', ref.types.short);
|
|||
* @classdesc The CTaosInterface is the interface through which Node.JS communicates data back and forth with TDengine. It is not advised to
|
||||
* access this class directly and use it unless you understand what these functions do.
|
||||
*/
|
||||
function CTaosInterface (config = null, pass = false) {
|
||||
function CTaosInterface(config = null, pass = false) {
|
||||
ref.types.char_ptr = ref.refType(ref.types.char);
|
||||
ref.types.void_ptr = ref.refType(ref.types.void);
|
||||
ref.types.void_ptr2 = ref.refType(ref.types.void_ptr);
|
||||
|
@ -196,64 +196,65 @@ function CTaosInterface (config = null, pass = false) {
|
|||
taoslibname = 'libtaos';
|
||||
}
|
||||
this.libtaos = ffi.Library(taoslibname, {
|
||||
'taos_options': [ ref.types.int, [ ref.types.int , ref.types.void_ptr ] ],
|
||||
'taos_init': [ ref.types.void, [ ] ],
|
||||
'taos_options': [ref.types.int, [ref.types.int, ref.types.void_ptr]],
|
||||
'taos_init': [ref.types.void, []],
|
||||
//TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)
|
||||
'taos_connect': [ ref.types.void_ptr, [ ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int ] ],
|
||||
'taos_connect': [ref.types.void_ptr, [ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.char_ptr, ref.types.int]],
|
||||
//void taos_close(TAOS *taos)
|
||||
'taos_close': [ ref.types.void, [ ref.types.void_ptr ] ],
|
||||
//int *taos_fetch_lengths(TAOS_RES *taos);
|
||||
'taos_fetch_lengths': [ ref.types.void_ptr, [ ref.types.void_ptr ] ],
|
||||
'taos_close': [ref.types.void, [ref.types.void_ptr]],
|
||||
//int *taos_fetch_lengths(TAOS_RES *res);
|
||||
'taos_fetch_lengths': [ref.types.void_ptr, [ref.types.void_ptr]],
|
||||
//int taos_query(TAOS *taos, char *sqlstr)
|
||||
'taos_query': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.char_ptr ] ],
|
||||
//int taos_affected_rows(TAOS *taos)
|
||||
'taos_affected_rows': [ ref.types.int, [ ref.types.void_ptr] ],
|
||||
'taos_query': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr]],
|
||||
//int taos_affected_rows(TAOS_RES *res)
|
||||
'taos_affected_rows': [ref.types.int, [ref.types.void_ptr]],
|
||||
//int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)
|
||||
'taos_fetch_block': [ ref.types.int, [ ref.types.void_ptr, ref.types.void_ptr] ],
|
||||
'taos_fetch_block': [ref.types.int, [ref.types.void_ptr, ref.types.void_ptr]],
|
||||
//int taos_num_fields(TAOS_RES *res);
|
||||
'taos_num_fields': [ ref.types.int, [ ref.types.void_ptr] ],
|
||||
'taos_num_fields': [ref.types.int, [ref.types.void_ptr]],
|
||||
//TAOS_ROW taos_fetch_row(TAOS_RES *res)
|
||||
//TAOS_ROW is void **, but we set the return type as a reference instead to get the row
|
||||
'taos_fetch_row': [ ref.refType(ref.types.void_ptr2), [ ref.types.void_ptr ] ],
|
||||
'taos_fetch_row': [ref.refType(ref.types.void_ptr2), [ref.types.void_ptr]],
|
||||
'taos_print_row': [ref.types.int, [ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]],
|
||||
//int taos_result_precision(TAOS_RES *res)
|
||||
'taos_result_precision': [ ref.types.int, [ ref.types.void_ptr ] ],
|
||||
'taos_result_precision': [ref.types.int, [ref.types.void_ptr]],
|
||||
//void taos_free_result(TAOS_RES *res)
|
||||
'taos_free_result': [ ref.types.void, [ ref.types.void_ptr] ],
|
||||
'taos_free_result': [ref.types.void, [ref.types.void_ptr]],
|
||||
//int taos_field_count(TAOS *taos)
|
||||
'taos_field_count': [ ref.types.int, [ ref.types.void_ptr ] ],
|
||||
'taos_field_count': [ref.types.int, [ref.types.void_ptr]],
|
||||
//TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)
|
||||
'taos_fetch_fields': [ ref.refType(TaosField), [ ref.types.void_ptr ] ],
|
||||
'taos_fetch_fields': [ref.refType(TaosField), [ref.types.void_ptr]],
|
||||
//int taos_errno(TAOS *taos)
|
||||
'taos_errno': [ ref.types.int, [ ref.types.void_ptr] ],
|
||||
'taos_errno': [ref.types.int, [ref.types.void_ptr]],
|
||||
//char *taos_errstr(TAOS *taos)
|
||||
'taos_errstr': [ ref.types.char_ptr, [ ref.types.void_ptr] ],
|
||||
'taos_errstr': [ref.types.char_ptr, [ref.types.void_ptr]],
|
||||
//void taos_stop_query(TAOS_RES *res);
|
||||
'taos_stop_query': [ ref.types.void, [ ref.types.void_ptr] ],
|
||||
'taos_stop_query': [ref.types.void, [ref.types.void_ptr]],
|
||||
//char *taos_get_server_info(TAOS *taos);
|
||||
'taos_get_server_info': [ ref.types.char_ptr, [ ref.types.void_ptr ] ],
|
||||
'taos_get_server_info': [ref.types.char_ptr, [ref.types.void_ptr]],
|
||||
//char *taos_get_client_info();
|
||||
'taos_get_client_info': [ ref.types.char_ptr, [ ] ],
|
||||
'taos_get_client_info': [ref.types.char_ptr, []],
|
||||
|
||||
// ASYNC
|
||||
// void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param)
|
||||
'taos_query_a': [ ref.types.void, [ ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr ] ],
|
||||
'taos_query_a': [ref.types.void, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr]],
|
||||
// void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);
|
||||
'taos_fetch_rows_a': [ ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.void_ptr ]],
|
||||
'taos_fetch_rows_a': [ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.void_ptr]],
|
||||
|
||||
// Subscription
|
||||
//TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval)
|
||||
'taos_subscribe': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.int, ref.types.char_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int] ],
|
||||
'taos_subscribe': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.int, ref.types.char_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.void_ptr, ref.types.int]],
|
||||
// TAOS_RES *taos_consume(TAOS_SUB *tsub)
|
||||
'taos_consume': [ ref.types.void_ptr, [ref.types.void_ptr] ],
|
||||
'taos_consume': [ref.types.void_ptr, [ref.types.void_ptr]],
|
||||
//void taos_unsubscribe(TAOS_SUB *tsub);
|
||||
'taos_unsubscribe': [ ref.types.void, [ ref.types.void_ptr ] ],
|
||||
'taos_unsubscribe': [ref.types.void, [ref.types.void_ptr]],
|
||||
|
||||
// Continuous Query
|
||||
//TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||
// int64_t stime, void *param, void (*callback)(void *));
|
||||
'taos_open_stream': [ ref.types.void_ptr, [ ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.int64, ref.types.void_ptr, ref.types.void_ptr ] ],
|
||||
'taos_open_stream': [ref.types.void_ptr, [ref.types.void_ptr, ref.types.char_ptr, ref.types.void_ptr, ref.types.int64, ref.types.void_ptr, ref.types.void_ptr]],
|
||||
//void taos_close_stream(TAOS_STREAM *tstr);
|
||||
'taos_close_stream': [ ref.types.void, [ ref.types.void_ptr ] ]
|
||||
'taos_close_stream': [ref.types.void, [ref.types.void_ptr]]
|
||||
|
||||
});
|
||||
if (pass == false) {
|
||||
|
@ -264,7 +265,7 @@ function CTaosInterface (config = null, pass = false) {
|
|||
try {
|
||||
this._config = ref.allocCString(config);
|
||||
}
|
||||
catch(err){
|
||||
catch (err) {
|
||||
throw "Attribute Error: config is expected as a str";
|
||||
}
|
||||
}
|
||||
|
@ -276,38 +277,38 @@ function CTaosInterface (config = null, pass = false) {
|
|||
return this;
|
||||
}
|
||||
CTaosInterface.prototype.config = function config() {
|
||||
return this._config;
|
||||
}
|
||||
CTaosInterface.prototype.connect = function connect(host=null, user="root", password="taosdata", db=null, port=0) {
|
||||
let _host,_user,_password,_db,_port;
|
||||
try {
|
||||
return this._config;
|
||||
}
|
||||
CTaosInterface.prototype.connect = function connect(host = null, user = "root", password = "taosdata", db = null, port = 0) {
|
||||
let _host, _user, _password, _db, _port;
|
||||
try {
|
||||
_host = host != null ? ref.allocCString(host) : ref.alloc(ref.types.char_ptr, ref.NULL);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: host is expected as a str";
|
||||
}
|
||||
try {
|
||||
_user = ref.allocCString(user)
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: user is expected as a str";
|
||||
}
|
||||
try {
|
||||
_password = ref.allocCString(password);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: password is expected as a str";
|
||||
}
|
||||
try {
|
||||
_db = db != null ? ref.allocCString(db) : ref.alloc(ref.types.char_ptr, ref.NULL);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: db is expected as a str";
|
||||
}
|
||||
try {
|
||||
_port = ref.alloc(ref.types.int, port);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw TypeError("port is expected as an int")
|
||||
}
|
||||
let connection = this.libtaos.taos_connect(_host, _user, _password, _db, _port);
|
||||
|
@ -324,10 +325,10 @@ CTaosInterface.prototype.close = function close(connection) {
|
|||
console.log("Connection is closed");
|
||||
}
|
||||
CTaosInterface.prototype.query = function query(connection, sql) {
|
||||
return this.libtaos.taos_query(connection, ref.allocCString(sql));
|
||||
return this.libtaos.taos_query(connection, ref.allocCString(sql));
|
||||
}
|
||||
CTaosInterface.prototype.affectedRows = function affectedRows(connection) {
|
||||
return this.libtaos.taos_affected_rows(connection);
|
||||
CTaosInterface.prototype.affectedRows = function affectedRows(result) {
|
||||
return this.libtaos.taos_affected_rows(result);
|
||||
}
|
||||
CTaosInterface.prototype.useResult = function useResult(result) {
|
||||
|
||||
|
@ -337,8 +338,8 @@ CTaosInterface.prototype.useResult = function useResult(result) {
|
|||
pfields = ref.reinterpret(pfields, this.fieldsCount(result) * 68, 0);
|
||||
for (let i = 0; i < pfields.length; i += 68) {
|
||||
//0 - 63 = name //64 - 65 = bytes, 66 - 67 = type
|
||||
fields.push( {
|
||||
name: ref.readCString(ref.reinterpret(pfields,65,i)),
|
||||
fields.push({
|
||||
name: ref.readCString(ref.reinterpret(pfields, 65, i)),
|
||||
type: pfields[i + 65],
|
||||
bytes: pfields[i + 66]
|
||||
})
|
||||
|
@ -347,11 +348,10 @@ CTaosInterface.prototype.useResult = function useResult(result) {
|
|||
return fields;
|
||||
}
|
||||
CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
||||
//let pblock = ref.ref(ref.ref(ref.NULL)); // equal to our raw data
|
||||
let pblock = this.libtaos.taos_fetch_row(result);
|
||||
let num_of_rows = 1;
|
||||
if (ref.isNull(pblock) == true) {
|
||||
return {block:null, num_of_rows:0};
|
||||
let pblock = ref.NULL_POINTER;
|
||||
let num_of_rows = this.libtaos.taos_fetch_block(result, pblock);
|
||||
if (ref.isNull(pblock.deref()) == true) {
|
||||
return { block: null, num_of_rows: 0 };
|
||||
}
|
||||
|
||||
var fieldL = this.libtaos.taos_fetch_lengths(result);
|
||||
|
@ -359,10 +359,10 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
|||
let isMicro = (this.libtaos.taos_result_precision(result) == FieldTypes.C_TIMESTAMP_MICRO);
|
||||
|
||||
var fieldlens = [];
|
||||
|
||||
|
||||
if (ref.isNull(fieldL) == false) {
|
||||
for (let i = 0; i < fields.length; i ++) {
|
||||
let plen = ref.reinterpret(fieldL, 4, i*4);
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
let plen = ref.reinterpret(fieldL, 4, i * 4);
|
||||
let len = plen.readInt32LE(0);
|
||||
fieldlens.push(len);
|
||||
}
|
||||
|
@ -370,21 +370,23 @@ CTaosInterface.prototype.fetchBlock = function fetchBlock(result, fields) {
|
|||
|
||||
let blocks = new Array(fields.length);
|
||||
blocks.fill(null);
|
||||
//num_of_rows = Math.abs(num_of_rows);
|
||||
num_of_rows = Math.abs(num_of_rows);
|
||||
let offset = 0;
|
||||
let ptr = pblock.deref();
|
||||
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
pdata = ref.reinterpret(pblock,8,i*8);
|
||||
if(ref.isNull(pdata.readPointer())){
|
||||
blocks[i] = new Array();
|
||||
}else{
|
||||
pdata = ref.ref(pdata.readPointer());
|
||||
if (!convertFunctions[fields[i]['type']] ) {
|
||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||
}
|
||||
blocks[i] = convertFunctions[fields[i]['type']](pdata, 1, fieldlens[i], offset, isMicro);
|
||||
}
|
||||
pdata = ref.reinterpret(ptr, 8, i * 8);
|
||||
if (ref.isNull(pdata.readPointer())) {
|
||||
blocks[i] = new Array();
|
||||
} else {
|
||||
pdata = ref.ref(pdata.readPointer());
|
||||
if (!convertFunctions[fields[i]['type']]) {
|
||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||
}
|
||||
blocks[i] = convertFunctions[fields[i]['type']](pdata, num_of_rows, fieldlens[i], offset, isMicro);
|
||||
}
|
||||
}
|
||||
return {blocks: blocks, num_of_rows:Math.abs(num_of_rows)}
|
||||
return { blocks: blocks, num_of_rows }
|
||||
}
|
||||
CTaosInterface.prototype.fetchRow = function fetchRow(result, fields) {
|
||||
let row = this.libtaos.taos_fetch_row(result);
|
||||
|
@ -414,7 +416,7 @@ CTaosInterface.prototype.errStr = function errStr(result) {
|
|||
// Async
|
||||
CTaosInterface.prototype.query_a = function query_a(connection, sql, callback, param = ref.ref(ref.NULL)) {
|
||||
// void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int), void *param)
|
||||
callback = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.int ], callback);
|
||||
callback = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], callback);
|
||||
this.libtaos.taos_query_a(connection, ref.allocCString(sql), callback, param);
|
||||
return param;
|
||||
}
|
||||
|
@ -439,46 +441,46 @@ CTaosInterface.prototype.fetch_rows_a = function fetch_rows_a(result, callback,
|
|||
var fieldL = cti.libtaos.taos_fetch_lengths(result);
|
||||
var fieldlens = [];
|
||||
if (ref.isNull(fieldL) == false) {
|
||||
|
||||
for (let i = 0; i < fields.length; i ++) {
|
||||
let plen = ref.reinterpret(fieldL, 8, i*8);
|
||||
let len = ref.get(plen,0,ref.types.int32);
|
||||
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
let plen = ref.reinterpret(fieldL, 8, i * 8);
|
||||
let len = ref.get(plen, 0, ref.types.int32);
|
||||
fieldlens.push(len);
|
||||
}
|
||||
}
|
||||
if (numOfRows2 > 0){
|
||||
if (numOfRows2 > 0) {
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
if(ref.isNull(pdata.readPointer())){
|
||||
blocks[i] = new Array();
|
||||
}else{
|
||||
if (!convertFunctions[fields[i]['type']] ) {
|
||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||
}
|
||||
let prow = ref.reinterpret(row,8,i*8);
|
||||
prow = prow.readPointer();
|
||||
prow = ref.ref(prow);
|
||||
blocks[i] = convertFunctions[fields[i]['type']](prow, 1, fieldlens[i], offset, isMicro);
|
||||
//offset += fields[i]['bytes'] * numOfRows2;
|
||||
}
|
||||
if (ref.isNull(pdata.readPointer())) {
|
||||
blocks[i] = new Array();
|
||||
} else {
|
||||
if (!convertFunctions[fields[i]['type']]) {
|
||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||
}
|
||||
let prow = ref.reinterpret(row, 8, i * 8);
|
||||
prow = prow.readPointer();
|
||||
prow = ref.ref(prow);
|
||||
blocks[i] = convertFunctions[fields[i]['type']](prow, 1, fieldlens[i], offset, isMicro);
|
||||
//offset += fields[i]['bytes'] * numOfRows2;
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(param2, result2, numOfRows2, blocks);
|
||||
}
|
||||
asyncCallbackWrapper = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.types.int ], asyncCallbackWrapper);
|
||||
asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.types.int], asyncCallbackWrapper);
|
||||
this.libtaos.taos_fetch_rows_a(result, asyncCallbackWrapper, param);
|
||||
return param;
|
||||
}
|
||||
// Fetch field meta data by result handle
|
||||
CTaosInterface.prototype.fetchFields_a = function fetchFields_a (result) {
|
||||
CTaosInterface.prototype.fetchFields_a = function fetchFields_a(result) {
|
||||
let pfields = this.fetchFields(result);
|
||||
let pfieldscount = this.numFields(result);
|
||||
let fields = [];
|
||||
if (ref.isNull(pfields) == false) {
|
||||
pfields = ref.reinterpret(pfields, 68 * pfieldscount , 0);
|
||||
pfields = ref.reinterpret(pfields, 68 * pfieldscount, 0);
|
||||
for (let i = 0; i < pfields.length; i += 68) {
|
||||
//0 - 64 = name //65 = type, 66 - 67 = bytes
|
||||
fields.push( {
|
||||
name: ref.readCString(ref.reinterpret(pfields,65,i)),
|
||||
fields.push({
|
||||
name: ref.readCString(ref.reinterpret(pfields, 65, i)),
|
||||
type: pfields[i + 65],
|
||||
bytes: pfields[i + 66]
|
||||
})
|
||||
|
@ -488,7 +490,7 @@ CTaosInterface.prototype.fetchFields_a = function fetchFields_a (result) {
|
|||
}
|
||||
// Stop a query by result handle
|
||||
CTaosInterface.prototype.stopQuery = function stopQuery(result) {
|
||||
if (result != null){
|
||||
if (result != null) {
|
||||
this.libtaos.taos_stop_query(result);
|
||||
}
|
||||
else {
|
||||
|
@ -509,13 +511,13 @@ CTaosInterface.prototype.subscribe = function subscribe(connection, restart, top
|
|||
try {
|
||||
sql = sql != null ? ref.allocCString(sql) : ref.alloc(ref.types.char_ptr, ref.NULL);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: sql is expected as a str";
|
||||
}
|
||||
try {
|
||||
topic = topic != null ? ref.allocCString(topic) : ref.alloc(ref.types.char_ptr, ref.NULL);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw TypeError("topic is expected as a str");
|
||||
}
|
||||
|
||||
|
@ -539,8 +541,8 @@ CTaosInterface.prototype.consume = function consume(subscription) {
|
|||
pfields = ref.reinterpret(pfields, this.numFields(result) * 68, 0);
|
||||
for (let i = 0; i < pfields.length; i += 68) {
|
||||
//0 - 63 = name //64 - 65 = bytes, 66 - 67 = type
|
||||
fields.push( {
|
||||
name: ref.readCString(ref.reinterpret(pfields,64,i)),
|
||||
fields.push({
|
||||
name: ref.readCString(ref.reinterpret(pfields, 64, i)),
|
||||
bytes: pfields[i + 64],
|
||||
type: pfields[i + 66]
|
||||
})
|
||||
|
@ -548,7 +550,7 @@ CTaosInterface.prototype.consume = function consume(subscription) {
|
|||
}
|
||||
|
||||
let data = [];
|
||||
while(true) {
|
||||
while (true) {
|
||||
let { blocks, num_of_rows } = this.fetchBlock(result, fields);
|
||||
if (num_of_rows == 0) {
|
||||
break;
|
||||
|
@ -559,7 +561,7 @@ CTaosInterface.prototype.consume = function consume(subscription) {
|
|||
for (let j = 0; j < fields.length; j++) {
|
||||
rowBlock[j] = blocks[j][i];
|
||||
}
|
||||
data[data.length-1] = (rowBlock);
|
||||
data[data.length - 1] = (rowBlock);
|
||||
}
|
||||
}
|
||||
return { data: data, fields: fields, result: result };
|
||||
|
@ -570,11 +572,11 @@ CTaosInterface.prototype.unsubscribe = function unsubscribe(subscription) {
|
|||
}
|
||||
|
||||
// Continuous Query
|
||||
CTaosInterface.prototype.openStream = function openStream(connection, sql, callback, stime,stoppingCallback, param = ref.ref(ref.NULL)) {
|
||||
CTaosInterface.prototype.openStream = function openStream(connection, sql, callback, stime, stoppingCallback, param = ref.ref(ref.NULL)) {
|
||||
try {
|
||||
sql = ref.allocCString(sql);
|
||||
}
|
||||
catch(err) {
|
||||
catch (err) {
|
||||
throw "Attribute Error: sql string is expected as a str";
|
||||
}
|
||||
var cti = this;
|
||||
|
@ -587,7 +589,7 @@ CTaosInterface.prototype.openStream = function openStream(connection, sql, callb
|
|||
let offset = 0;
|
||||
if (numOfRows2 > 0) {
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
if (!convertFunctions[fields[i]['type']] ) {
|
||||
if (!convertFunctions[fields[i]['type']]) {
|
||||
throw new errors.DatabaseError("Invalid data type returned from database");
|
||||
}
|
||||
blocks[i] = convertFunctions[fields[i]['type']](row, numOfRows2, fields[i]['bytes'], offset, isMicro);
|
||||
|
@ -596,8 +598,8 @@ CTaosInterface.prototype.openStream = function openStream(connection, sql, callb
|
|||
}
|
||||
callback(param2, result2, blocks, fields);
|
||||
}
|
||||
asyncCallbackWrapper = ffi.Callback(ref.types.void, [ ref.types.void_ptr, ref.types.void_ptr, ref.refType(ref.types.void_ptr2) ], asyncCallbackWrapper);
|
||||
asyncStoppingCallbackWrapper = ffi.Callback( ref.types.void, [ ref.types.void_ptr ], stoppingCallback);
|
||||
asyncCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr, ref.types.void_ptr, ref.refType(ref.types.void_ptr2)], asyncCallbackWrapper);
|
||||
asyncStoppingCallbackWrapper = ffi.Callback(ref.types.void, [ref.types.void_ptr], stoppingCallback);
|
||||
let streamHandle = this.libtaos.taos_open_stream(connection, sql, asyncCallbackWrapper, stime, param, asyncStoppingCallbackWrapper);
|
||||
if (ref.isNull(streamHandle)) {
|
||||
throw new errors.TDError('Failed to open a stream with TDengine');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const ref = require('ref-napi');
|
||||
require('./globalfunc.js')
|
||||
const CTaosInterface = require('./cinterface')
|
||||
const errors = require ('./error')
|
||||
const errors = require('./error')
|
||||
const TaosQuery = require('./taosquery')
|
||||
const { PerformanceObserver, performance } = require('perf_hooks');
|
||||
module.exports = TDengineCursor;
|
||||
|
@ -22,7 +22,7 @@ module.exports = TDengineCursor;
|
|||
* @property {fields} - Array of the field objects in order from left to right of the latest data retrieved
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function TDengineCursor(connection=null) {
|
||||
function TDengineCursor(connection = null) {
|
||||
//All parameters are store for sync queries only.
|
||||
this._rowcount = -1;
|
||||
this._connection = null;
|
||||
|
@ -91,7 +91,7 @@ TDengineCursor.prototype.execute = function execute(operation, options, callback
|
|||
return null;
|
||||
}
|
||||
|
||||
if (typeof options == 'function') {
|
||||
if (typeof options == 'function') {
|
||||
callback = options;
|
||||
}
|
||||
if (typeof options != 'object') options = {}
|
||||
|
@ -144,10 +144,10 @@ TDengineCursor.prototype.execute = function execute(operation, options, callback
|
|||
|
||||
}
|
||||
TDengineCursor.prototype._createAffectedResponse = function (num, time) {
|
||||
return "Query OK, " + num + " row(s) affected (" + (time * 0.001).toFixed(8) + "s)";
|
||||
return "Query OK, " + num + " row(s) affected (" + (time * 0.001).toFixed(8) + "s)";
|
||||
}
|
||||
TDengineCursor.prototype._createSetResponse = function (num, time) {
|
||||
return "Query OK, " + num + " row(s) in set (" + (time * 0.001).toFixed(8) + "s)";
|
||||
return "Query OK, " + num + " row(s) in set (" + (time * 0.001).toFixed(8) + "s)";
|
||||
}
|
||||
TDengineCursor.prototype.executemany = function executemany() {
|
||||
|
||||
|
@ -176,27 +176,22 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) {
|
|||
throw new errors.OperationalError("Invalid use of fetchall, either result or fields from query are null. First execute a query first");
|
||||
}
|
||||
|
||||
let data = [];
|
||||
let num_of_rows = this._chandle.affectedRows(this._result);
|
||||
let data = new Array(num_of_rows);
|
||||
|
||||
this._rowcount = 0;
|
||||
//let nodetime = 0;
|
||||
|
||||
let time = 0;
|
||||
const obs = new PerformanceObserver((items) => {
|
||||
time += items.getEntries()[0].duration;
|
||||
performance.clearMarks();
|
||||
});
|
||||
/*
|
||||
const obs2 = new PerformanceObserver((items) => {
|
||||
nodetime += items.getEntries()[0].duration;
|
||||
performance.clearMarks();
|
||||
});
|
||||
obs2.observe({ entryTypes: ['measure'] });
|
||||
performance.mark('nodea');
|
||||
*/
|
||||
obs.observe({ entryTypes: ['measure'] });
|
||||
performance.mark('A');
|
||||
while(true) {
|
||||
|
||||
while (true) {
|
||||
let blockAndRows = this._chandle.fetchBlock(this._result, this._fields);
|
||||
// console.log(blockAndRows);
|
||||
// break;
|
||||
let block = blockAndRows.blocks;
|
||||
let num_of_rows = blockAndRows.num_of_rows;
|
||||
if (num_of_rows == 0) {
|
||||
|
@ -205,22 +200,24 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) {
|
|||
this._rowcount += num_of_rows;
|
||||
let numoffields = this._fields.length;
|
||||
for (let i = 0; i < num_of_rows; i++) {
|
||||
data.push([]);
|
||||
|
||||
// data.push([]);
|
||||
|
||||
let rowBlock = new Array(numoffields);
|
||||
for (let j = 0; j < numoffields; j++) {
|
||||
rowBlock[j] = block[j][i];
|
||||
}
|
||||
data[data.length-1] = (rowBlock);
|
||||
data[this._rowcount - num_of_rows + i] = (rowBlock);
|
||||
// data.push(rowBlock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
performance.mark('B');
|
||||
performance.measure('query', 'A', 'B');
|
||||
let response = this._createSetResponse(this._rowcount, time)
|
||||
console.log(response);
|
||||
|
||||
// this._connection._clearResultSet();
|
||||
// this._connection._clearResultSet();
|
||||
let fields = this.fields;
|
||||
this._reset_result();
|
||||
this.data = data;
|
||||
|
@ -239,12 +236,12 @@ TDengineCursor.prototype.fetchall = function fetchall(options, callback) {
|
|||
* @return {number | Buffer} Number of affected rows or a Buffer that points to the results of the query
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TDengineCursor.prototype.execute_a = function execute_a (operation, options, callback, param) {
|
||||
TDengineCursor.prototype.execute_a = function execute_a(operation, options, callback, param) {
|
||||
if (operation == undefined) {
|
||||
throw new errors.ProgrammingError('No operation passed as argument');
|
||||
return null;
|
||||
}
|
||||
if (typeof options == 'function') {
|
||||
if (typeof options == 'function') {
|
||||
//we expect the parameter after callback to be param
|
||||
param = callback;
|
||||
callback = options;
|
||||
|
@ -265,14 +262,14 @@ TDengineCursor.prototype.execute_a = function execute_a (operation, options, cal
|
|||
}
|
||||
|
||||
if (resCode >= 0) {
|
||||
// let fieldCount = cr._chandle.numFields(res2);
|
||||
// if (fieldCount == 0) {
|
||||
// //cr._chandle.freeResult(res2);
|
||||
// return res2;
|
||||
// }
|
||||
// else {
|
||||
// return res2;
|
||||
// }
|
||||
// let fieldCount = cr._chandle.numFields(res2);
|
||||
// if (fieldCount == 0) {
|
||||
// //cr._chandle.freeResult(res2);
|
||||
// return res2;
|
||||
// }
|
||||
// else {
|
||||
// return res2;
|
||||
// }
|
||||
return res2;
|
||||
|
||||
}
|
||||
|
@ -317,7 +314,7 @@ TDengineCursor.prototype.execute_a = function execute_a (operation, options, cal
|
|||
* })
|
||||
*/
|
||||
TDengineCursor.prototype.fetchall_a = function fetchall_a(result, options, callback, param = {}) {
|
||||
if (typeof options == 'function') {
|
||||
if (typeof options == 'function') {
|
||||
//we expect the parameter after callback to be param
|
||||
param = callback;
|
||||
callback = options;
|
||||
|
@ -360,17 +357,17 @@ TDengineCursor.prototype.fetchall_a = function fetchall_a(result, options, callb
|
|||
for (let k = 0; k < fields.length; k++) {
|
||||
rowBlock[k] = block[k][j];
|
||||
}
|
||||
data[data.length-1] = rowBlock;
|
||||
data[data.length - 1] = rowBlock;
|
||||
}
|
||||
}
|
||||
cr._chandle.freeResult(result2); // free result, avoid seg faults and mem leaks!
|
||||
callback(param2, result2, numOfRows2, {data:data,fields:fields});
|
||||
callback(param2, result2, numOfRows2, { data: data, fields: fields });
|
||||
|
||||
}
|
||||
}
|
||||
ref.writeObject(buf, 0, param);
|
||||
param = this._chandle.fetch_rows_a(result, asyncCallbackWrapper, buf); //returned param
|
||||
return {param:param,result:result};
|
||||
return { param: param, result: result };
|
||||
}
|
||||
/**
|
||||
* Stop a query given the result handle.
|
||||
|
@ -428,7 +425,7 @@ TDengineCursor.prototype.subscribe = function subscribe(config) {
|
|||
*/
|
||||
TDengineCursor.prototype.consumeData = async function consumeData(subscription, callback) {
|
||||
while (true) {
|
||||
let { data, fields, result} = this._chandle.consume(subscription);
|
||||
let { data, fields, result } = this._chandle.consume(subscription);
|
||||
callback(data, fields, result);
|
||||
}
|
||||
}
|
||||
|
@ -450,30 +447,30 @@ TDengineCursor.prototype.unsubscribe = function unsubscribe(subscription) {
|
|||
* @return {Buffer} A buffer pointing to the stream handle
|
||||
* @since 1.3.0
|
||||
*/
|
||||
TDengineCursor.prototype.openStream = function openStream(sql, callback, stime = 0, stoppingCallback, param = {}) {
|
||||
let buf = ref.alloc('Object');
|
||||
ref.writeObject(buf, 0, param);
|
||||
TDengineCursor.prototype.openStream = function openStream(sql, callback, stime = 0, stoppingCallback, param = {}) {
|
||||
let buf = ref.alloc('Object');
|
||||
ref.writeObject(buf, 0, param);
|
||||
|
||||
let asyncCallbackWrapper = function (param2, result2, blocks, fields) {
|
||||
let data = [];
|
||||
let num_of_rows = blocks[0].length;
|
||||
for (let j = 0; j < num_of_rows; j++) {
|
||||
data.push([]);
|
||||
let rowBlock = new Array(fields.length);
|
||||
for (let k = 0; k < fields.length; k++) {
|
||||
rowBlock[k] = blocks[k][j];
|
||||
}
|
||||
data[data.length-1] = rowBlock;
|
||||
}
|
||||
callback(param2, result2, blocks, fields);
|
||||
}
|
||||
return this._chandle.openStream(this._connection._conn, sql, asyncCallbackWrapper, stime, stoppingCallback, buf);
|
||||
}
|
||||
/**
|
||||
* Close a stream
|
||||
* @param {Buffer} - A buffer pointing to the handle of the stream to be closed
|
||||
* @since 1.3.0
|
||||
*/
|
||||
TDengineCursor.prototype.closeStream = function closeStream(stream) {
|
||||
this._chandle.closeStream(stream);
|
||||
}
|
||||
let asyncCallbackWrapper = function (param2, result2, blocks, fields) {
|
||||
let data = [];
|
||||
let num_of_rows = blocks[0].length;
|
||||
for (let j = 0; j < num_of_rows; j++) {
|
||||
data.push([]);
|
||||
let rowBlock = new Array(fields.length);
|
||||
for (let k = 0; k < fields.length; k++) {
|
||||
rowBlock[k] = blocks[k][j];
|
||||
}
|
||||
data[data.length - 1] = rowBlock;
|
||||
}
|
||||
callback(param2, result2, blocks, fields);
|
||||
}
|
||||
return this._chandle.openStream(this._connection._conn, sql, asyncCallbackWrapper, stime, stoppingCallback, buf);
|
||||
}
|
||||
/**
|
||||
* Close a stream
|
||||
* @param {Buffer} - A buffer pointing to the handle of the stream to be closed
|
||||
* @since 1.3.0
|
||||
*/
|
||||
TDengineCursor.prototype.closeStream = function closeStream(stream) {
|
||||
this._chandle.closeStream(stream);
|
||||
}
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
{
|
||||
"name": "td2.0-connector",
|
||||
"version": "2.0.6",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"array-index": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz",
|
||||
"integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=",
|
||||
"requires": {
|
||||
"debug": "^2.2.0",
|
||||
"es6-symbol": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"d": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
|
||||
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
|
||||
"requires": {
|
||||
"es5-ext": "^0.10.50",
|
||||
"type": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.53",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
|
||||
"integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
|
||||
"requires": {
|
||||
"es6-iterator": "~2.0.3",
|
||||
"es6-symbol": "~3.1.3",
|
||||
"next-tick": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
||||
"integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.35",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
||||
"requires": {
|
||||
"d": "^1.0.1",
|
||||
"ext": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
|
||||
"integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
|
||||
"requires": {
|
||||
"type": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
|
||||
"integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ffi-napi": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-3.1.0.tgz",
|
||||
"integrity": "sha512-EsHO+sP2p/nUC/3l/l8m9niee1BLm4asUFDzkkBGR4kYVgp2KqdAYUomZhkKtzim4Fq7mcYHjpUaIHsMqs+E1g==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"get-uv-event-loop-napi-h": "^1.0.5",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.1",
|
||||
"ref-napi": "^2.0.1",
|
||||
"ref-struct-di": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ref-napi": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.1.2.tgz",
|
||||
"integrity": "sha512-aFl+vrIuLWUXMUTQGAwGAuSNLX3Ub5W3iVP8b7KyFFZUdn4+i4U1TXXTop0kCTUfGNu8glBGVz4lowkwMcPVVA==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"get-symbol-from-current-process-h": "^1.0.2",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get-symbol-from-current-process-h": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz",
|
||||
"integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw=="
|
||||
},
|
||||
"get-uv-event-loop-napi-h": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz",
|
||||
"integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==",
|
||||
"requires": {
|
||||
"get-symbol-from-current-process-h": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"next-tick": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
||||
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
|
||||
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
|
||||
},
|
||||
"node-gyp-build": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
|
||||
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
|
||||
},
|
||||
"ref-array-napi": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ref-array-napi/-/ref-array-napi-1.2.1.tgz",
|
||||
"integrity": "sha512-jQp2WWSucmxkqVfoNfm7yDlDeGu3liAbzqfwjNybL80ooLOCnCZpAK2woDInY+lxNOK/VlIVSqeDEYb4gVPuNQ==",
|
||||
"requires": {
|
||||
"array-index": "1",
|
||||
"debug": "2",
|
||||
"ref-napi": "^1.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"ref-napi": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz",
|
||||
"integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==",
|
||||
"requires": {
|
||||
"debug": "^3.1.0",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ref-napi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-3.0.1.tgz",
|
||||
"integrity": "sha512-W3rcb0E+tlO9u9ySFnX5vifInwwPGToOfFgTZUHJBNiOBsW0NNvgHz2zJN7ctABo/2yIlgdPQUvuqqfORIF4LA==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"get-symbol-from-current-process-h": "^1.0.2",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.1"
|
||||
}
|
||||
},
|
||||
"ref-struct-di": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ref-struct-di/-/ref-struct-di-1.1.1.tgz",
|
||||
"integrity": "sha512-2Xyn/0Qgz89VT+++WP0sTosdm9oeowLP23wRJYhG4BFdMUrLj3jhwHZNEytYNYgtPKLNTP3KJX4HEgBvM1/Y2g==",
|
||||
"requires": {
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ref-struct-napi": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ref-struct-napi/-/ref-struct-napi-1.1.1.tgz",
|
||||
"integrity": "sha512-YgS5/d7+kT5zgtySYI5ieH0hREdv+DabgDvoczxsui0f9VLm0rrDcWEj4DHKehsH+tJnVMsLwuyctWgvdEcVRw==",
|
||||
"requires": {
|
||||
"debug": "2",
|
||||
"ref-napi": "^1.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"ref-napi": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-1.5.2.tgz",
|
||||
"integrity": "sha512-hwyNmWpUkt1bDWDW4aiwCoC+SJfJO69UIdjqssNqdaS0sYJpgqzosGg/rLtk69UoQ8drZdI9yyQefM7eEMM3Gw==",
|
||||
"requires": {
|
||||
"debug": "^3.1.0",
|
||||
"node-addon-api": "^2.0.0",
|
||||
"node-gyp-build": "^4.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "td2.0-connector",
|
||||
"version": "2.0.6",
|
||||
"version": "2.0.7",
|
||||
"description": "A Node.js connector for TDengine.",
|
||||
"main": "tdengine.js",
|
||||
"directories": {
|
||||
|
|
|
@ -312,11 +312,7 @@ static int test_sqls_in_stmt(SQLHENV env, SQLHDBC conn, SQLHSTMT stmt, const cha
|
|||
size_t len = 0;
|
||||
|
||||
ssize_t n = 0;
|
||||
#ifdef _MSC_VER
|
||||
n = taosGetlineImp(&line, &len, f);
|
||||
#else
|
||||
n = getline(&line, &len, f);
|
||||
#endif
|
||||
n = tgetline(&line, &len, f);
|
||||
if (n==-1) break;
|
||||
|
||||
const char *p = NULL;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "dnodeTelemetry.h"
|
||||
#include "module.h"
|
||||
#include "qScript.h"
|
||||
#include "mnode.h"
|
||||
|
||||
#if !defined(_MODULE) || !defined(_TD_LINUX)
|
||||
int32_t moduleStart() { return 0; }
|
||||
|
@ -84,7 +85,18 @@ static SStep tsDnodeSteps[] = {
|
|||
{"dnode-shell", dnodeInitShell, dnodeCleanupShell},
|
||||
{"dnode-statustmr", dnodeInitStatusTimer,dnodeCleanupStatusTimer},
|
||||
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||
{"dnode-script", scriptEnvPoolInit, scriptEnvPoolCleanup},
|
||||
{"dnode-script", scriptEnvPoolInit, scriptEnvPoolCleanup},
|
||||
};
|
||||
|
||||
static SStep tsDnodeCompactSteps[] = {
|
||||
{"dnode-tfile", tfInit, tfCleanup},
|
||||
{"dnode-storage", dnodeInitStorage, dnodeCleanupStorage},
|
||||
{"dnode-eps", dnodeInitEps, dnodeCleanupEps},
|
||||
{"dnode-wal", walInit, walCleanUp},
|
||||
{"dnode-mread", dnodeInitMRead, NULL},
|
||||
{"dnode-mwrite", dnodeInitMWrite, NULL},
|
||||
{"dnode-mpeer", dnodeInitMPeer, NULL},
|
||||
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
|
||||
};
|
||||
|
||||
static int dnodeCreateDir(const char *dir) {
|
||||
|
@ -96,13 +108,23 @@ static int dnodeCreateDir(const char *dir) {
|
|||
}
|
||||
|
||||
static void dnodeCleanupComponents() {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
dnodeStepCleanup(tsDnodeSteps, stepSize);
|
||||
if (!tsCompactMnodeWal) {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
dnodeStepCleanup(tsDnodeSteps, stepSize);
|
||||
} else {
|
||||
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||
dnodeStepCleanup(tsDnodeCompactSteps, stepSize);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t dnodeInitComponents() {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsDnodeSteps, stepSize);
|
||||
if (!tsCompactMnodeWal) {
|
||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsDnodeSteps, stepSize);
|
||||
} else {
|
||||
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsDnodeCompactSteps, stepSize);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t dnodeInitTmr() {
|
||||
|
@ -218,7 +240,24 @@ static int32_t dnodeInitStorage() {
|
|||
sprintf(tsDnodeDir, "%s/dnode", tsDataDir);
|
||||
// sprintf(tsVnodeBakDir, "%s/vnode_bak", tsDataDir);
|
||||
|
||||
//TODO(dengyihao): no need to init here
|
||||
if (tsCompactMnodeWal == 1) {
|
||||
sprintf(tsMnodeTmpDir, "%s/mnode_tmp", tsDataDir);
|
||||
if (taosDirExist(tsMnodeTmpDir)) {
|
||||
dError("mnode_tmp dir already exist in %s,quit compact job", tsMnodeTmpDir);
|
||||
return -1;
|
||||
}
|
||||
if (dnodeCreateDir(tsMnodeTmpDir) < 0) {
|
||||
dError("failed to create dir: %s, reason: %s", tsMnodeTmpDir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(tsMnodeBakDir, "%s/mnode_bak", tsDataDir);
|
||||
if (taosDirExist(tsMnodeBakDir)) {
|
||||
dError("mnode_bak dir already exist in %s,quit compact job", tsMnodeBakDir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//TODO(dengyihao): no need to init here
|
||||
if (dnodeCreateDir(tsMnodeDir) < 0) {
|
||||
dError("failed to create dir: %s, reason: %s", tsMnodeDir, strerror(errno));
|
||||
return -1;
|
||||
|
|
|
@ -42,6 +42,8 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
}
|
||||
} else if (strcmp(argv[i], "-C") == 0) {
|
||||
dump_config = 1;
|
||||
} else if (strcmp(argv[i], "--compact-mnode-wal") == 0) {
|
||||
tsCompactMnodeWal = 1;
|
||||
} else if (strcmp(argv[i], "-V") == 0) {
|
||||
#ifdef _ACCT
|
||||
char *versionStr = "enterprise";
|
||||
|
|
|
@ -73,6 +73,9 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg);
|
|||
void mnodeProcessPeerRsp(SRpcMsg *pMsg);
|
||||
int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
|
||||
int32_t mnodeCompactWal();
|
||||
int32_t mnodeCompactComponents();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -54,7 +54,8 @@ void monCleanupSystem();
|
|||
void monSaveAcctLog(SAcctMonitorObj *pMonObj);
|
||||
void monSaveLog(int32_t level, const char *const format, ...);
|
||||
void monExecuteSQL(char *sql);
|
||||
|
||||
typedef void (*MonExecuteSQLCbFP)(void *param, TAOS_RES *, int code);
|
||||
void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -112,6 +112,7 @@ typedef struct TAOS_MULTI_BIND {
|
|||
|
||||
TAOS_STMT *taos_stmt_init(TAOS *taos);
|
||||
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
||||
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags);
|
||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name);
|
||||
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||
|
|
|
@ -33,6 +33,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define TSWINDOW_INITIALIZER ((STimeWindow) {INT64_MIN, INT64_MAX})
|
||||
#define TSWINDOW_DESC_INITIALIZER ((STimeWindow) {INT64_MAX, INT64_MIN})
|
||||
|
||||
#define TSKEY_INITIAL_VAL INT64_MIN
|
||||
|
||||
// Bytes for each type.
|
||||
|
@ -246,7 +248,6 @@ do { \
|
|||
#define TSDB_MAX_REPLICA 5
|
||||
|
||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||
#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2)
|
||||
#define TSDB_UD_COLUMN_INDEX (-1000)
|
||||
#define TSDB_RES_COL_ID (-5000)
|
||||
|
||||
|
@ -302,7 +303,7 @@ do { \
|
|||
#define TSDB_DEFAULT_DB_UPDATE_OPTION 0
|
||||
|
||||
#define TSDB_MIN_DB_CACHE_LAST_ROW 0
|
||||
#define TSDB_MAX_DB_CACHE_LAST_ROW 1
|
||||
#define TSDB_MAX_DB_CACHE_LAST_ROW 3
|
||||
#define TSDB_DEFAULT_CACHE_LAST_ROW 0
|
||||
|
||||
#define TSDB_MIN_FSYNC_PERIOD 0
|
||||
|
@ -353,6 +354,7 @@ do { \
|
|||
#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u
|
||||
#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type
|
||||
#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u
|
||||
#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file
|
||||
#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type
|
||||
|
||||
#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0)
|
||||
|
|
|
@ -74,7 +74,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010A) //"Ref is not there")
|
||||
|
||||
//client
|
||||
#define TSDB_CODE_TSC_INVALID_SQL TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid SQL statement")
|
||||
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation")
|
||||
#define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle")
|
||||
#define TSDB_CODE_TSC_INVALID_TIME_STAMP TAOS_DEF_ERROR_CODE(0, 0x0202) //"Invalid combination of client/service time")
|
||||
#define TSDB_CODE_TSC_INVALID_VALUE TAOS_DEF_ERROR_CODE(0, 0x0203) //"Invalid value in client")
|
||||
|
@ -227,6 +227,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
|
||||
#define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing")
|
||||
#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state")
|
||||
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0515) //"Database is closing")
|
||||
|
||||
// tsdb
|
||||
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID")
|
||||
|
@ -436,6 +437,9 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_FS_INVLD_LEVEL TAOS_DEF_ERROR_CODE(0, 0x2207) //"tfs invalid level")
|
||||
#define TSDB_CODE_FS_NO_VALID_DISK TAOS_DEF_ERROR_CODE(0, 0x2208) //"tfs no valid disk")
|
||||
|
||||
// monitor
|
||||
#define TSDB_CODE_MON_CONNECTION_INVALID TAOS_DEF_ERROR_CODE(0, 0x2300) //"monitor invalid monitor db connection")
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -86,7 +86,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_TABLE, "drop-table" )
|
|||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TABLE, "alter-table" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLE_META, "table-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_STABLE_VGROUP, "stable-vgroup" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "tables-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "multiTable-meta" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_STREAM, "alter-stream" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SHOW, "show" )
|
||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE, "retrieve" )
|
||||
|
@ -297,6 +297,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
// if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table
|
||||
int8_t supertable;
|
||||
int8_t igNotExists;
|
||||
} SCMDropTableMsg;
|
||||
|
||||
|
@ -744,8 +746,9 @@ typedef struct {
|
|||
} STableInfoMsg;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfVgroups;
|
||||
int32_t numOfTables;
|
||||
char tableIds[];
|
||||
char tableNames[];
|
||||
} SMultiTableInfoMsg;
|
||||
|
||||
typedef struct SSTableVgroupMsg {
|
||||
|
@ -794,8 +797,9 @@ typedef struct STableMetaMsg {
|
|||
|
||||
typedef struct SMultiTableMeta {
|
||||
int32_t numOfTables;
|
||||
int32_t numOfVgroup;
|
||||
int32_t contLen;
|
||||
char metas[];
|
||||
char meta[];
|
||||
} SMultiTableMeta;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -69,9 +69,13 @@ typedef struct {
|
|||
int8_t precision;
|
||||
int8_t compression;
|
||||
int8_t update;
|
||||
int8_t cacheLastRow;
|
||||
int8_t cacheLastRow; // 0:no cache, 1: cache last row, 2: cache last NULL column 3: 1&2
|
||||
} STsdbCfg;
|
||||
|
||||
#define CACHE_NO_LAST(c) ((c)->cacheLastRow == 0)
|
||||
#define CACHE_LAST_ROW(c) (((c)->cacheLastRow & 1) > 0)
|
||||
#define CACHE_LAST_NULL_COLUMN(c) (((c)->cacheLastRow & 2) > 0)
|
||||
|
||||
// --------- TSDB REPOSITORY USAGE STATISTICS
|
||||
typedef struct {
|
||||
int64_t totalStorage; // total bytes occupie
|
||||
|
@ -211,7 +215,7 @@ typedef struct SDataBlockInfo {
|
|||
} SDataBlockInfo;
|
||||
|
||||
typedef struct SFileBlockInfo {
|
||||
int32_t numOfRows;
|
||||
int32_t numBlocksOfStep;
|
||||
} SFileBlockInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -225,11 +229,15 @@ typedef struct {
|
|||
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
||||
} STableGroupInfo;
|
||||
|
||||
#define TSDB_BLOCK_DIST_STEP_ROWS 16
|
||||
typedef struct {
|
||||
uint16_t rowSize;
|
||||
uint16_t numOfFiles;
|
||||
uint32_t numOfTables;
|
||||
uint64_t totalSize;
|
||||
uint64_t totalRows;
|
||||
int32_t maxRows;
|
||||
int32_t minRows;
|
||||
int32_t firstSeekTimeUs;
|
||||
uint32_t numOfRowsInMemTable;
|
||||
SArray *dataBlockInfos;
|
||||
|
@ -261,6 +269,12 @@ TsdbQueryHandleT *tsdbQueryTables(STsdbRepo *tsdb, STsdbQueryCond *pCond, STable
|
|||
TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, uint64_t qId,
|
||||
SMemRef *pRef);
|
||||
|
||||
|
||||
TsdbQueryHandleT tsdbQueryCacheLast(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, SMemRef* pMemRef);
|
||||
|
||||
bool isTsdbCacheLastRow(TsdbQueryHandleT* pQueryHandle);
|
||||
|
||||
|
||||
/**
|
||||
* get the queried table object list
|
||||
* @param pHandle
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"filetype": "subscribe",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"databases": "test",
|
||||
"specified_table_query": {
|
||||
"concurrent": 1,
|
||||
"mode": "async",
|
||||
"interval": 1000,
|
||||
"restart": "yes",
|
||||
"keepProgress": "yes",
|
||||
"resubAfterConsume": 10,
|
||||
"sqls": [
|
||||
{
|
||||
"sql": "select col1 from meters where col1 > 1;",
|
||||
"result": "./subscribe_res0.txt"
|
||||
},
|
||||
{
|
||||
"sql": "select col2 from meters where col2 > 1;",
|
||||
"result": "./subscribe_res2.txt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"super_table_query": {
|
||||
"stblname": "meters",
|
||||
"threads": 1,
|
||||
"mode": "sync",
|
||||
"interval": 1000,
|
||||
"restart": "yes",
|
||||
"keepProgress": "yes",
|
||||
"sqls": [
|
||||
{
|
||||
"sql": "select col1 from xxxx where col1 > 10;",
|
||||
"result": "./subscribe_res1.txt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,17 +1,37 @@
|
|||
{
|
||||
"filetype":"subscribe",
|
||||
"filetype": "subscribe",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"databases": "dbx",
|
||||
"specified_table_query":
|
||||
{"concurrent":1, "mode":"sync", "interval":5000, "restart":"yes", "keepProgress":"yes",
|
||||
"sqls": [{"sql": "select avg(col1) from stb01 where col1 > 1;", "result": "./subscribe_res0.txt"}]
|
||||
},
|
||||
"super_table_query":
|
||||
{"stblname": "stb", "threads":1, "mode":"sync", "interval":10000, "restart":"yes", "keepProgress":"yes",
|
||||
"sqls": [{"sql": "select col1 from xxxx where col1 > 10;", "result": "./subscribe_res1.txt"}]
|
||||
}
|
||||
"databases": "test",
|
||||
"specified_table_query": {
|
||||
"concurrent": 1,
|
||||
"mode": "sync",
|
||||
"interval": 1000,
|
||||
"restart": "yes",
|
||||
"keepProgress": "yes",
|
||||
"resubAfterConsume": 10,
|
||||
"sqls": [
|
||||
{
|
||||
"sql": "select avg(col1) from meters where col1 > 1;",
|
||||
"result": "./subscribe_res0.txt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"super_table_query": {
|
||||
"stblname": "meters",
|
||||
"threads": 1,
|
||||
"mode": "sync",
|
||||
"interval": 1000,
|
||||
"restart": "yes",
|
||||
"keepProgress": "yes",
|
||||
"sqls": [
|
||||
{
|
||||
"sql": "select col1 from xxxx where col1 > 10;",
|
||||
"result": "./subscribe_res1.txt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,8 @@ void mnodeDropDbFromAcct(SAcctObj *pAcct, SDbObj *pDb);
|
|||
void mnodeAddUserToAcct(SAcctObj *pAcct, SUserObj *pUser);
|
||||
void mnodeDropUserFromAcct(SAcctObj *pAcct, SUserObj *pUser);
|
||||
|
||||
int32_t mnodeCompactAccts();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,8 @@ void mnodeCleanupCluster();
|
|||
void mnodeUpdateClusterId();
|
||||
const char* mnodeGetClusterId();
|
||||
|
||||
int32_t mnodeCompactCluster();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,8 @@ void mnodeDecDbRef(SDbObj *pDb);
|
|||
bool mnodeCheckIsMonitorDB(char *db, char *monitordb);
|
||||
void mnodeDropAllDbs(SAcctObj *pAcct);
|
||||
|
||||
int32_t mnodeCompactDbs();
|
||||
|
||||
// util func
|
||||
void mnodeAddSuperTableIntoDb(SDbObj *pDb);
|
||||
void mnodeRemoveSuperTableFromDb(SDbObj *pDb);
|
||||
|
|
|
@ -77,6 +77,7 @@ void * mnodeGetDnodeByEp(char *ep);
|
|||
void mnodeUpdateDnode(SDnodeObj *pDnode);
|
||||
int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg);
|
||||
|
||||
int32_t mnodeCompactDnodes();
|
||||
extern int32_t tsAccessSquence;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -50,6 +50,7 @@ char* mnodeGetMnodeMasterEp();
|
|||
void mnodeGetMnodeInfos(void *mnodes);
|
||||
void mnodeUpdateMnodeEpSet(SMInfos *pMnodes);
|
||||
|
||||
int32_t mnodeCompactMnodes();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -93,6 +93,7 @@ void sdbUpdateMnodeRoles();
|
|||
int32_t sdbGetReplicaNum();
|
||||
|
||||
int32_t sdbInsertRow(SSdbRow *pRow);
|
||||
int32_t sdbInsertCompactRow(SSdbRow *pRow);
|
||||
int32_t sdbDeleteRow(SSdbRow *pRow);
|
||||
int32_t sdbUpdateRow(SSdbRow *pRow);
|
||||
int32_t sdbInsertRowToQueue(SSdbRow *pRow);
|
||||
|
@ -107,6 +108,7 @@ int32_t sdbGetId(void *pTable);
|
|||
uint64_t sdbGetVersion();
|
||||
bool sdbCheckRowDeleted(void *pTable, void *pRow);
|
||||
|
||||
int32_t mnodeCompactWal();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@ void mnodeCancelGetNextSuperTable(void *pIter);
|
|||
void mnodeDropAllChildTables(SDbObj *pDropDb);
|
||||
void mnodeDropAllSuperTables(SDbObj *pDropDb);
|
||||
void mnodeDropAllChildTablesInVgroups(SVgObj *pVgroup);
|
||||
int32_t mnodeCompactTables();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ char * mnodeGetUserFromMsg(void *pMnodeMsg);
|
|||
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg);
|
||||
void mnodeDropAllUsers(SAcctObj *pAcct);
|
||||
|
||||
int32_t mnodeCompactUsers();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ void mnodeDropAllDbVgroups(SDbObj *pDropDb);
|
|||
void mnodeSendDropAllDbVgroupsMsg(SDbObj *pDropDb);
|
||||
void mnodeDropAllDnodeVgroups(SDnodeObj *pDropDnode);
|
||||
//void mnodeUpdateAllDbVgroups(SDbObj *pAlterDb);
|
||||
int32_t mnodeCompactVgroups();
|
||||
|
||||
void * mnodeGetNextVgroup(void *pIter, SVgObj **pVgroup);
|
||||
void mnodeCancelGetNextVgroup(void *pIter);
|
||||
|
|
|
@ -238,6 +238,32 @@ static int32_t mnodeCreateRootAcct() {
|
|||
return sdbInsertRow(&row);
|
||||
}
|
||||
|
||||
int32_t mnodeCompactAccts() {
|
||||
void *pIter = NULL;
|
||||
SAcctObj *pAcct = NULL;
|
||||
|
||||
mInfo("start to compact accts table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextAcct(pIter, &pAcct);
|
||||
if (pAcct == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsAcctSdb,
|
||||
.pObj = pAcct,
|
||||
};
|
||||
|
||||
mInfo("compact accts %s", pAcct->user);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact accts table...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _ACCT
|
||||
|
||||
int32_t acctInit() { return TSDB_CODE_SUCCESS; }
|
||||
|
|
|
@ -237,3 +237,27 @@ static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows,
|
|||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
int32_t mnodeCompactCluster() {
|
||||
SClusterObj *pCluster = NULL;
|
||||
void *pIter;
|
||||
|
||||
mInfo("start to compact cluster table...");
|
||||
|
||||
pIter = mnodeGetNextCluster(NULL, &pCluster);
|
||||
while (pCluster) {
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsClusterSdb,
|
||||
.pObj = pCluster,
|
||||
};
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
|
||||
pIter = mnodeGetNextCluster(pIter, &pCluster);
|
||||
}
|
||||
|
||||
mInfo("end to compact cluster table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -389,7 +389,7 @@ static void mnodeSetDefaultDbCfg(SDbCfg *pCfg) {
|
|||
if (pCfg->compression < 0) pCfg->compression = tsCompression;
|
||||
if (pCfg->walLevel < 0) pCfg->walLevel = tsWAL;
|
||||
if (pCfg->replications < 0) pCfg->replications = tsReplications;
|
||||
if (pCfg->quorum < 0) pCfg->quorum = tsQuorum;
|
||||
if (pCfg->quorum < 0) pCfg->quorum = MIN(tsQuorum, pCfg->replications);
|
||||
if (pCfg->update < 0) pCfg->update = tsUpdate;
|
||||
if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = tsCacheLastRow;
|
||||
if (pCfg->dbType < 0) pCfg->dbType = 0;
|
||||
|
@ -1274,3 +1274,30 @@ void mnodeDropAllDbs(SAcctObj *pAcct) {
|
|||
|
||||
mInfo("acct:%s, all dbs:%d is dropped from sdb", pAcct->user, numOfDbs);
|
||||
}
|
||||
|
||||
int32_t mnodeCompactDbs() {
|
||||
void *pIter = NULL;
|
||||
SDbObj *pDb = NULL;
|
||||
|
||||
mInfo("start to compact dbs table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextDb(pIter, &pDb);
|
||||
if (pDb == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = sizeof(SDbObj),
|
||||
};
|
||||
|
||||
mInfo("compact dbs %s", pDb->name);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact dbs table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1270,3 +1270,30 @@ char* dnodeRoles[] = {
|
|||
"vnode",
|
||||
"any"
|
||||
};
|
||||
|
||||
int32_t mnodeCompactDnodes() {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
void * pIter = NULL;
|
||||
|
||||
mInfo("start to compact dnodes table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsDnodeSdb,
|
||||
.pObj = pDnode,
|
||||
.rowSize = sizeof(SDnodeObj),
|
||||
};
|
||||
|
||||
mInfo("compact dnode %d", pDnode->dnodeId);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact dnodes table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -59,6 +59,18 @@ static SStep tsMnodeSteps[] = {
|
|||
{"show", mnodeInitShow, mnodeCleanUpShow}
|
||||
};
|
||||
|
||||
static SStep tsMnodeCompactSteps[] = {
|
||||
{"cluster", mnodeCompactCluster, NULL},
|
||||
{"dnodes", mnodeCompactDnodes, NULL},
|
||||
{"mnodes", mnodeCompactMnodes, NULL},
|
||||
{"accts", mnodeCompactAccts, NULL},
|
||||
{"users", mnodeCompactUsers, NULL},
|
||||
{"dbs", mnodeCompactDbs, NULL},
|
||||
{"vgroups", mnodeCompactVgroups, NULL},
|
||||
{"tables", mnodeCompactTables, NULL},
|
||||
|
||||
};
|
||||
|
||||
static void mnodeInitTimer();
|
||||
static void mnodeCleanupTimer();
|
||||
static bool mnodeNeedStart() ;
|
||||
|
@ -73,6 +85,11 @@ static int32_t mnodeInitComponents() {
|
|||
return dnodeStepInit(tsMnodeSteps, stepSize);
|
||||
}
|
||||
|
||||
int32_t mnodeCompactComponents() {
|
||||
int32_t stepSize = sizeof(tsMnodeCompactSteps) / sizeof(SStep);
|
||||
return dnodeStepInit(tsMnodeCompactSteps, stepSize);
|
||||
}
|
||||
|
||||
int32_t mnodeStartSystem() {
|
||||
if (tsMgmtIsRunning) {
|
||||
mInfo("mnode module already started...");
|
||||
|
@ -106,7 +123,7 @@ int32_t mnodeStartSystem() {
|
|||
|
||||
int32_t mnodeInitSystem() {
|
||||
mnodeInitTimer();
|
||||
if (mnodeNeedStart()) {
|
||||
if (mnodeNeedStart() || tsCompactMnodeWal) {
|
||||
return mnodeStartSystem();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -566,3 +566,30 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
|||
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
int32_t mnodeCompactMnodes() {
|
||||
void *pIter = NULL;
|
||||
SMnodeObj *pMnode = NULL;
|
||||
|
||||
mInfo("start to compact mnodes table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextMnode(pIter, &pMnode);
|
||||
if (pMnode == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsMnodeSdb,
|
||||
.pObj = pMnode,
|
||||
.rowSize = sizeof(SMnodeObj),
|
||||
};
|
||||
|
||||
mInfo("compact mnode %d", pMnode->mnodeId);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact mnodes table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include "tutil.h"
|
||||
#include "tref.h"
|
||||
#include "tbn.h"
|
||||
#include "tfs.h"
|
||||
#include "tqueue.h"
|
||||
#include "twal.h"
|
||||
#include "tsync.h"
|
||||
|
@ -450,6 +451,12 @@ int32_t sdbInit() {
|
|||
}
|
||||
|
||||
tsSdbMgmt.status = SDB_STATUS_SERVING;
|
||||
|
||||
if (tsCompactMnodeWal) {
|
||||
mnodeCompactWal();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -683,7 +690,7 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
|||
pthread_mutex_unlock(&tsSdbMgmt.mutex);
|
||||
|
||||
// from app, row is created
|
||||
if (pRow != NULL) {
|
||||
if (pRow != NULL && tsCompactMnodeWal != 1) {
|
||||
// forward to peers
|
||||
pRow->processedCount = 0;
|
||||
int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||
|
@ -706,19 +713,21 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
|||
actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version);
|
||||
|
||||
// even it is WAL/FWD, it shall be called to update version in sync
|
||||
syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||
if (tsCompactMnodeWal != 1) {
|
||||
syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||
}
|
||||
|
||||
// from wal or forward msg, row not created, should add into hash
|
||||
if (action == SDB_ACTION_INSERT) {
|
||||
return sdbPerformInsertAction(pHead, pTable);
|
||||
} else if (action == SDB_ACTION_DELETE) {
|
||||
if (qtype == TAOS_QTYPE_FWD) {
|
||||
//if (qtype == TAOS_QTYPE_FWD) {
|
||||
// Drop database/stable may take a long time and cause a timeout, so we confirm first then reput it into queue
|
||||
sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
// sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused);
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
//} else {
|
||||
return sdbPerformDeleteAction(pHead, pTable);
|
||||
}
|
||||
//}
|
||||
} else if (action == SDB_ACTION_UPDATE) {
|
||||
return sdbPerformUpdateAction(pHead, pTable);
|
||||
} else {
|
||||
|
@ -726,6 +735,12 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
|||
}
|
||||
}
|
||||
|
||||
int32_t sdbInsertCompactRow(SSdbRow *pRow) {
|
||||
SSdbTable *pTable = pRow->pTable;
|
||||
if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE;
|
||||
return sdbWriteRowToQueue(pRow, SDB_ACTION_INSERT);
|
||||
}
|
||||
|
||||
int32_t sdbInsertRow(SSdbRow *pRow) {
|
||||
SSdbTable *pTable = pRow->pTable;
|
||||
if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE;
|
||||
|
@ -1138,3 +1153,46 @@ static void *sdbWorkerFp(void *pWorker) {
|
|||
int32_t sdbGetReplicaNum() {
|
||||
return tsSdbMgmt.cfg.replica;
|
||||
}
|
||||
|
||||
int32_t mnodeCompactWal() {
|
||||
sdbInfo("vgId:1, start compact mnode wal...");
|
||||
|
||||
// close old wal
|
||||
walFsync(tsSdbMgmt.wal, true);
|
||||
walClose(tsSdbMgmt.wal);
|
||||
|
||||
// reset version,then compacted wal log can start from version 1
|
||||
tsSdbMgmt.version = 0;
|
||||
|
||||
// change wal to wal_tmp dir
|
||||
SWalCfg walCfg = {.vgId = 1, .walLevel = TAOS_WAL_FSYNC, .keep = TAOS_WAL_KEEP, .fsyncPeriod = 0};
|
||||
char temp[TSDB_FILENAME_LEN] = {0};
|
||||
sprintf(temp, "%s/wal", tsMnodeTmpDir);
|
||||
tsSdbMgmt.wal = walOpen(temp, &walCfg);
|
||||
walRenew(tsSdbMgmt.wal);
|
||||
|
||||
// compact memory tables info to wal tmp dir
|
||||
if (mnodeCompactComponents() != 0) {
|
||||
tfsRmdir(tsMnodeTmpDir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// close wal
|
||||
walFsync(tsSdbMgmt.wal, true);
|
||||
walClose(tsSdbMgmt.wal);
|
||||
|
||||
// rename old wal to wal_bak
|
||||
if (taosRename(tsMnodeDir, tsMnodeBakDir) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// rename wal_tmp to wal
|
||||
if (taosRename(tsMnodeTmpDir, tsMnodeDir) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// del wal_tmp dir
|
||||
sdbInfo("vgId:1, compact mnode wal success");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -966,6 +966,11 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
|
|||
pMsg->rpcMsg.ahandle, pDrop->name, pSTable->uid, pSTable->numOfTables, taosHashGetSize(pSTable->vgHash));
|
||||
return mnodeProcessDropSuperTableMsg(pMsg);
|
||||
} else {
|
||||
// user specify the "DROP STABLE" sql statement, but it is actually a normal table, return error msg.
|
||||
if (pDrop->supertable) {
|
||||
return TSDB_CODE_MND_INVALID_TABLE_TYPE;
|
||||
}
|
||||
|
||||
SCTableObj *pCTable = (SCTableObj *)pMsg->pTable;
|
||||
mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle,
|
||||
pDrop->name, pCTable->vgId, pCTable->tid, pCTable->uid);
|
||||
|
@ -1189,8 +1194,8 @@ static int32_t mnodeFindSuperTableTagIndex(SSTableObj *pStable, const char *tagN
|
|||
|
||||
static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) {
|
||||
SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
|
||||
mLInfo("msg:%p, app:%p stable %s, add tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId,
|
||||
tstrerror(code));
|
||||
mLInfo("msg:%p, app:%p stable %s, add tag result:%s, numOfTags:%d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId,
|
||||
tstrerror(code), pStable->numOfTags);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1674,12 +1679,9 @@ static int32_t mnodeSetSchemaFromSuperTable(SSchema *pSchema, SSTableObj *pTable
|
|||
return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
|
||||
}
|
||||
|
||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||
static int32_t mnodeDoGetSuperTableMeta(SMnodeMsg *pMsg, STableMetaMsg* pMeta) {
|
||||
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
||||
if (pMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMeta->uid = htobe64(pTable->uid);
|
||||
pMeta->sversion = htons(pTable->sversion);
|
||||
pMeta->tversion = htons(pTable->tversion);
|
||||
|
@ -1690,6 +1692,18 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
|||
pMeta->contLen = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable);
|
||||
tstrncpy(pMeta->tableFname, pTable->info.tableId, sizeof(pMeta->tableFname));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
||||
if (pMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||
|
||||
pMsg->rpcRsp.len = pMeta->contLen;
|
||||
pMeta->contLen = htons(pMeta->contLen);
|
||||
|
||||
|
@ -1700,11 +1714,7 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
int32_t numOfTable = htonl(pInfo->numOfTables);
|
||||
|
||||
// reserve space
|
||||
static int32_t calculateVgroupMsgLength(SSTableVgroupMsg* pInfo, int32_t numOfTable) {
|
||||
int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg);
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
|
@ -1716,6 +1726,75 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
mnodeDecTableRef(pTable);
|
||||
}
|
||||
|
||||
return contLen;
|
||||
}
|
||||
|
||||
static char* serializeVgroupInfo(SSTableObj *pTable, char* name, char* msg, SMnodeMsg* pMsgBody, void* handle) {
|
||||
SName sn = {0};
|
||||
tNameFromString(&sn, name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
const char* tableName = tNameGetTableName(&sn);
|
||||
|
||||
strncpy(msg, tableName, TSDB_TABLE_NAME_LEN);
|
||||
msg += TSDB_TABLE_NAME_LEN;
|
||||
|
||||
if (pTable->vgHash == NULL) {
|
||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsgBody, handle, name);
|
||||
mnodeDecTableRef(pTable);
|
||||
|
||||
// even this super table has no corresponding table, still return
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
pVgroupMsg->numOfVgroups = 0;
|
||||
|
||||
msg += sizeof(SVgroupsMsg);
|
||||
} else {
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsgBody, handle,
|
||||
pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash));
|
||||
|
||||
int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL);
|
||||
int32_t vgSize = 0;
|
||||
while (pVgId) {
|
||||
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
|
||||
pVgId = taosHashIterate(pTable->vgHash, pVgId);
|
||||
if (pVgroup == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
|
||||
pVgroupMsg->vgroups[vgSize].numOfEps = 0;
|
||||
|
||||
for (int32_t vn = 0; vn < pVgroup->numOfVnodes; ++vn) {
|
||||
SDnodeObj *pDnode = pVgroup->vnodeGid[vn].pDnode;
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
tstrncpy(pVgroupMsg->vgroups[vgSize].epAddr[vn].fqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN);
|
||||
pVgroupMsg->vgroups[vgSize].epAddr[vn].port = htons(pDnode->dnodePort);
|
||||
|
||||
pVgroupMsg->vgroups[vgSize].numOfEps++;
|
||||
}
|
||||
|
||||
vgSize++;
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
taosHashCancelIterate(pTable->vgHash, pVgId);
|
||||
mnodeDecTableRef(pTable);
|
||||
|
||||
pVgroupMsg->numOfVgroups = htonl(vgSize);
|
||||
|
||||
// one table is done, try the next table
|
||||
msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
int32_t numOfTable = htonl(pInfo->numOfTables);
|
||||
|
||||
// calculate the required space.
|
||||
int32_t contLen = calculateVgroupMsgLength(pInfo, numOfTable);
|
||||
SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
@ -1726,62 +1805,16 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
|
||||
SSTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||
if (pTable == NULL) {
|
||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName);
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
}
|
||||
if (pTable->vgHash == NULL) {
|
||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle,
|
||||
stableName);
|
||||
mnodeDecTableRef(pTable);
|
||||
|
||||
// even this super table has no corresponding table, still return
|
||||
pRsp->numOfTables++;
|
||||
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
pVgroupMsg->numOfVgroups = 0;
|
||||
|
||||
msg += sizeof(SVgroupsMsg);
|
||||
} else {
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsg, pMsg->rpcMsg.ahandle,
|
||||
pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash));
|
||||
|
||||
int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL);
|
||||
int32_t vgSize = 0;
|
||||
while (pVgId) {
|
||||
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
|
||||
pVgId = taosHashIterate(pTable->vgHash, pVgId);
|
||||
if (pVgroup == NULL) continue;
|
||||
|
||||
pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
|
||||
pVgroupMsg->vgroups[vgSize].numOfEps = 0;
|
||||
|
||||
for (int32_t vn = 0; vn < pVgroup->numOfVnodes; ++vn) {
|
||||
SDnodeObj *pDnode = pVgroup->vnodeGid[vn].pDnode;
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
tstrncpy(pVgroupMsg->vgroups[vgSize].epAddr[vn].fqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN);
|
||||
pVgroupMsg->vgroups[vgSize].epAddr[vn].port = htons(pDnode->dnodePort);
|
||||
|
||||
pVgroupMsg->vgroups[vgSize].numOfEps++;
|
||||
}
|
||||
|
||||
vgSize++;
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
taosHashCancelIterate(pTable->vgHash, pVgId);
|
||||
mnodeDecTableRef(pTable);
|
||||
|
||||
pVgroupMsg->numOfVgroups = htonl(vgSize);
|
||||
|
||||
// one table is done, try the next table
|
||||
msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
|
||||
pRsp->numOfTables++;
|
||||
}
|
||||
msg = serializeVgroupInfo(pTable, stableName, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||
pRsp->numOfTables++;
|
||||
}
|
||||
|
||||
if (pRsp->numOfTables != numOfTable) {
|
||||
|
@ -2415,9 +2448,9 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
|
|||
pMeta->vgroup.numOfEps++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
||||
|
||||
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
||||
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d tid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||
pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2811,56 +2844,137 @@ static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) {
|
|||
|
||||
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||
SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||
|
||||
int32_t totalMallocLen = 4 * 1024 * 1024; // first malloc 4 MB, subsequent reallocation as twice
|
||||
SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen);
|
||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||
pInfo->numOfVgroups = htonl(pInfo->numOfVgroups);
|
||||
|
||||
int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg);
|
||||
|
||||
int32_t num = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
char* str = strndup(pInfo->tableNames, contLen);
|
||||
char** nameList = strsplit(str, ",", &num);
|
||||
SArray* pList = taosArrayInit(4, POINTER_BYTES);
|
||||
SMultiTableMeta *pMultiMeta = NULL;
|
||||
|
||||
if (num != pInfo->numOfTables + pInfo->numOfVgroups) {
|
||||
mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
// first malloc 80KB, subsequent reallocation will expand the size as twice of the original size
|
||||
int32_t totalMallocLen = sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16);
|
||||
pMultiMeta = rpcMallocCont(totalMallocLen);
|
||||
if (pMultiMeta == NULL) {
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
pMultiMeta->contLen = sizeof(SMultiTableMeta);
|
||||
pMultiMeta->numOfTables = 0;
|
||||
|
||||
for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
|
||||
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN);
|
||||
SCTableObj *pTable = mnodeGetChildTable(tableId);
|
||||
if (pTable == NULL) continue;
|
||||
int32_t t = 0;
|
||||
for (; t < pInfo->numOfTables; ++t) {
|
||||
char *fullName = nameList[t];
|
||||
|
||||
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableName(tableId);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
pMsg->pTable = mnodeGetTable(fullName);
|
||||
if (pMsg->pTable == NULL) {
|
||||
mError("msg:%p, app:%p table:%s, failed to get table meta, table not exist", pMsg, pMsg->rpcMsg.ahandle, fullName);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
int availLen = totalMallocLen - pMultiMeta->contLen;
|
||||
if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
||||
if (pMsg->pDb == NULL) {
|
||||
pMsg->pDb = mnodeGetDbByTableName(fullName);
|
||||
}
|
||||
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
code = TSDB_CODE_APP_NOT_READY;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
int remain = totalMallocLen - pMultiMeta->contLen;
|
||||
if (remain <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
||||
totalMallocLen *= 2;
|
||||
pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen);
|
||||
if (pMultiMeta == NULL) {
|
||||
mnodeDecTableRef(pTable);
|
||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
} else {
|
||||
t--;
|
||||
mnodeDecTableRef(pTable);
|
||||
continue;
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen);
|
||||
int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
pMultiMeta->numOfTables ++;
|
||||
pMultiMeta->contLen += pMeta->contLen;
|
||||
STableMetaMsg *pMeta = (STableMetaMsg *)((char*) pMultiMeta + pMultiMeta->contLen);
|
||||
|
||||
if (pMsg->pTable->type == TSDB_SUPER_TABLE) {
|
||||
code = mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||
taosArrayPush(pList, &fullName); // keep the full name for each super table for retrieve vgroup list
|
||||
} else {
|
||||
code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
||||
if (pMsg->pVgroup != NULL) {
|
||||
mnodeDecVgroupRef(pMsg->pVgroup);
|
||||
pMsg->pVgroup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mnodeDecTableRef(pTable);
|
||||
mnodeDecTableRef(pMsg->pTable);
|
||||
pMsg->pTable = NULL;
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
pMultiMeta->numOfTables++;
|
||||
pMultiMeta->contLen += pMeta->contLen;
|
||||
} else {
|
||||
// ignore error and continue.
|
||||
// Otherwise the client may found that the responding message is inconsistent.
|
||||
// goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
char* msg = (char*) pMultiMeta + pMultiMeta->contLen;
|
||||
|
||||
// add the additional super table names that needs the vgroup info
|
||||
for(;t < num; ++t) {
|
||||
taosArrayPush(pList, &nameList[t]);
|
||||
}
|
||||
|
||||
// add the pVgroupList into the pList
|
||||
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pList);
|
||||
pMultiMeta->numOfVgroup = htonl(numOfVgroupList);
|
||||
|
||||
for(int32_t i = 0; i < numOfVgroupList; ++i) {
|
||||
char* name = taosArrayGetP(pList, i);
|
||||
|
||||
SSTableObj *pTable = mnodeGetSuperTable(name);
|
||||
if (pTable == NULL) {
|
||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, name);
|
||||
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||
goto _end;
|
||||
}
|
||||
|
||||
msg = serializeVgroupInfo(pTable, name, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||
}
|
||||
|
||||
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
||||
|
||||
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
||||
pMsg->rpcRsp.rsp = pMultiMeta;
|
||||
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_end:
|
||||
tfree(str);
|
||||
tfree(nameList);
|
||||
taosArrayDestroy(pList);
|
||||
pMsg->pTable = NULL;
|
||||
pMsg->pVgroup = NULL;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
rpcFreeCont(pMultiMeta);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
|
@ -3242,3 +3356,65 @@ static int32_t mnodeRetrieveStreamTables(SShowObj *pShow, char *data, int32_t ro
|
|||
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static int32_t mnodeCompactSuperTables() {
|
||||
void *pIter = NULL;
|
||||
SSTableObj *pTable = NULL;
|
||||
|
||||
mInfo("start to compact super table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextSuperTable(pIter, &pTable);
|
||||
if (pTable == NULL) break;
|
||||
|
||||
int32_t schemaSize = (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsSuperTableSdb,
|
||||
.pObj = pTable,
|
||||
.rowSize = sizeof(SSTableObj) + schemaSize,
|
||||
};
|
||||
|
||||
//mInfo("compact super %" PRIu64, pTable->uid);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact super table...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mnodeCompactChildTables() {
|
||||
void *pIter = NULL;
|
||||
SCTableObj *pTable = NULL;
|
||||
|
||||
mInfo("start to compact child table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextChildTable(pIter, &pTable);
|
||||
if (pTable == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pObj = pTable,
|
||||
.pTable = tsChildTableSdb,
|
||||
};
|
||||
|
||||
//mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact child table...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mnodeCompactTables() {
|
||||
mnodeCompactSuperTables();
|
||||
|
||||
mnodeCompactChildTables();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -617,3 +617,30 @@ static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey);
|
||||
}
|
||||
|
||||
int32_t mnodeCompactUsers() {
|
||||
void *pIter = NULL;
|
||||
SUserObj *pUser = NULL;
|
||||
|
||||
mInfo("start to compact users table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextUser(pIter, &pUser);
|
||||
if (pUser == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.rowSize = sizeof(SUserObj),
|
||||
};
|
||||
|
||||
mInfo("compact users %s", pUser->user);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact users table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -121,7 +121,7 @@ static int32_t mnodeVgroupActionDelete(SSdbRow *pRow) {
|
|||
SVgObj *pVgroup = pRow->pObj;
|
||||
|
||||
if (pVgroup->pDb == NULL) {
|
||||
mError("vgId:%d, db:%s is not exist while insert into hash", pVgroup->vgId, pVgroup->dbName);
|
||||
mError("vgId:%d, db:%s is not exist while delete from hash", pVgroup->vgId, pVgroup->dbName);
|
||||
return TSDB_CODE_MND_VGROUP_NOT_EXIST;
|
||||
}
|
||||
|
||||
|
@ -1302,3 +1302,30 @@ void mnodeSetVgidVer(int8_t *cver, uint64_t iver) {
|
|||
cver[1] = (int8_t)((int32_t)(iver % 100000) / 100);
|
||||
cver[2] = (int8_t)(iver % 100);
|
||||
}
|
||||
|
||||
int32_t mnodeCompactVgroups() {
|
||||
void *pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
|
||||
mInfo("start to compact vgroups table...");
|
||||
|
||||
while (1) {
|
||||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
SSdbRow row = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.pTable = tsVgroupSdb,
|
||||
.pObj = pVgroup,
|
||||
.rowSize = sizeof(SVgObj),
|
||||
};
|
||||
|
||||
mInfo("compact vgroups %d", pVgroup->vgId);
|
||||
|
||||
sdbInsertCompactRow(&row);
|
||||
}
|
||||
|
||||
mInfo("end to compact vgroups table...");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
void taosRemoveDir(char *rootDir);
|
||||
bool taosDirExist(const char* dirname);
|
||||
int32_t taosMkDir(const char *pathname, mode_t mode);
|
||||
void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays);
|
||||
int32_t taosRename(char *oldName, char *newName);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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_OS_MIPS64_H
|
||||
#define TDENGINE_OS_MIPS64_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <argp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <regex.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wordexp.h>
|
||||
#include <wctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/resource.h>
|
||||
#include <error.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <math.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -45,6 +45,10 @@ void taosRemoveDir(char *rootDir) {
|
|||
uInfo("dir:%s is removed", rootDir);
|
||||
}
|
||||
|
||||
bool taosDirExist(const char* dirname) {
|
||||
return access(dirname, F_OK) == 0;
|
||||
}
|
||||
|
||||
int taosMkDir(const char *path, mode_t mode) {
|
||||
int code = mkdir(path, 0755);
|
||||
if (code < 0 && errno == EEXIST) code = 0;
|
||||
|
|
|
@ -62,7 +62,7 @@ static void* taosRandomRealloc(void* ptr, size_t size, const char* file, uint32_
|
|||
|
||||
static char* taosRandomStrdup(const char* str, const char* file, uint32_t line) {
|
||||
size_t len = strlen(str);
|
||||
return taosRandomAllocFail(len + 1, file, line) ? NULL : taosStrdupImp(str);
|
||||
return taosRandomAllocFail(len + 1, file, line) ? NULL : tstrdup(str);
|
||||
}
|
||||
|
||||
static char* taosRandomStrndup(const char* str, size_t size, const char* file, uint32_t line) {
|
||||
|
@ -70,11 +70,11 @@ static char* taosRandomStrndup(const char* str, size_t size, const char* file, u
|
|||
if (len > size) {
|
||||
len = size;
|
||||
}
|
||||
return taosRandomAllocFail(len + 1, file, line) ? NULL : taosStrndupImp(str, len);
|
||||
return taosRandomAllocFail(len + 1, file, line) ? NULL : tstrndup(str, len);
|
||||
}
|
||||
|
||||
static ssize_t taosRandomGetline(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) {
|
||||
return taosRandomAllocFail(*n, file, line) ? -1 : taosGetlineImp(lineptr, n, stream);
|
||||
return taosRandomAllocFail(*n, file, line) ? -1 : tgetline(lineptr, n, stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -242,7 +242,7 @@ static char* taosStrndupDetectLeak(const char* str, size_t size, const char* fil
|
|||
static ssize_t taosGetlineDetectLeak(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) {
|
||||
char* buf = NULL;
|
||||
size_t bufSize = 0;
|
||||
ssize_t size = taosGetlineImp(&buf, &bufSize, stream);
|
||||
ssize_t size = tgetline(&buf, &bufSize, stream);
|
||||
if (size != -1) {
|
||||
if (*n < size + 1) {
|
||||
void* p = taosReallocDetectLeak(*lineptr, size + 1, file, line);
|
||||
|
@ -372,7 +372,7 @@ void taosFreeMem(void* ptr, const char* file, uint32_t line) {
|
|||
char* taosStrdupMem(const char* str, const char* file, uint32_t line) {
|
||||
switch (allocMode) {
|
||||
case TAOS_ALLOC_MODE_DEFAULT:
|
||||
return taosStrdupImp(str);
|
||||
return tstrdup(str);
|
||||
|
||||
case TAOS_ALLOC_MODE_RANDOM_FAIL:
|
||||
return taosRandomStrdup(str, file, line);
|
||||
|
@ -380,13 +380,13 @@ char* taosStrdupMem(const char* str, const char* file, uint32_t line) {
|
|||
case TAOS_ALLOC_MODE_DETECT_LEAK:
|
||||
return taosStrdupDetectLeak(str, file, line);
|
||||
}
|
||||
return taosStrdupImp(str);
|
||||
return tstrdup(str);
|
||||
}
|
||||
|
||||
char* taosStrndupMem(const char* str, size_t size, const char* file, uint32_t line) {
|
||||
switch (allocMode) {
|
||||
case TAOS_ALLOC_MODE_DEFAULT:
|
||||
return taosStrndupImp(str, size);
|
||||
return tstrndup(str, size);
|
||||
|
||||
case TAOS_ALLOC_MODE_RANDOM_FAIL:
|
||||
return taosRandomStrndup(str, size, file, line);
|
||||
|
@ -394,13 +394,13 @@ char* taosStrndupMem(const char* str, size_t size, const char* file, uint32_t li
|
|||
case TAOS_ALLOC_MODE_DETECT_LEAK:
|
||||
return taosStrndupDetectLeak(str, size, file, line);
|
||||
}
|
||||
return taosStrndupImp(str, size);
|
||||
return tstrndup(str, size);
|
||||
}
|
||||
|
||||
ssize_t taosGetlineMem(char **lineptr, size_t *n, FILE *stream, const char* file, uint32_t line) {
|
||||
switch (allocMode) {
|
||||
case TAOS_ALLOC_MODE_DEFAULT:
|
||||
return taosGetlineImp(lineptr, n, stream);
|
||||
return tgetline(lineptr, n, stream);
|
||||
|
||||
case TAOS_ALLOC_MODE_RANDOM_FAIL:
|
||||
return taosRandomGetline(lineptr, n, stream, file, line);
|
||||
|
@ -408,7 +408,7 @@ ssize_t taosGetlineMem(char **lineptr, size_t *n, FILE *stream, const char* file
|
|||
case TAOS_ALLOC_MODE_DETECT_LEAK:
|
||||
return taosGetlineDetectLeak(lineptr, n, stream, file, line);
|
||||
}
|
||||
return taosGetlineImp(lineptr, n, stream);
|
||||
return tgetline(lineptr, n, stream);
|
||||
}
|
||||
|
||||
static void taosCloseAllocLog() {
|
||||
|
@ -517,4 +517,4 @@ void* taosTZfree(void* ptr) {
|
|||
free((void*)((char*)ptr - sizeof(size_t)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
typedef void (*FLinuxSignalHandler)(int32_t signum, siginfo_t *sigInfo, void *context);
|
||||
|
||||
void taosSetSignal(int32_t signum, FSignalHandler sigfp) {
|
||||
struct sigaction act = {{0}};
|
||||
struct sigaction act; memset(&act, 0, sizeof(act));
|
||||
#if 1
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction = (FLinuxSignalHandler)sigfp;
|
||||
#else
|
||||
act.sa_handler = sigfp;
|
||||
#endif
|
||||
sigaction(signum, &act, NULL);
|
||||
#else
|
||||
act.sa_handler = sigfp;
|
||||
#endif
|
||||
sigaction(signum, &act, NULL);
|
||||
}
|
||||
|
||||
void taosIgnSignal(int32_t signum) {
|
||||
|
|
|
@ -87,12 +87,12 @@ static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t time
|
|||
|
||||
int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
|
||||
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t daylight) {
|
||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
/* parse datatime string in with tz */
|
||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||
return parseTimeWithTz(timestr, time, timePrec);
|
||||
} else {
|
||||
return (*parseLocaltimeFp[daylight])(timestr, time, timePrec);
|
||||
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tglobal.h"
|
||||
|
@ -24,7 +25,7 @@
|
|||
|
||||
bool taosCheckPthreadValid(pthread_t thread) { return thread.p != NULL; }
|
||||
|
||||
void taosResetPthread(pthread_t *thread) { thread->p = 0; }
|
||||
void taosResetPthread(pthread_t* thread) { thread->p = 0; }
|
||||
|
||||
int64_t taosGetPthreadId(pthread_t thread) {
|
||||
#ifdef PTW32_VERSION
|
||||
|
@ -34,27 +35,24 @@ int64_t taosGetPthreadId(pthread_t thread) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int64_t taosGetSelfPthreadId() {
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
int64_t taosGetSelfPthreadId() { return GetCurrentThreadId(); }
|
||||
|
||||
bool taosComparePthread(pthread_t first, pthread_t second) {
|
||||
return first.p == second.p;
|
||||
}
|
||||
bool taosComparePthread(pthread_t first, pthread_t second) { return first.p == second.p; }
|
||||
|
||||
int32_t taosGetPId() {
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
int32_t taosGetPId() { return GetCurrentProcessId(); }
|
||||
|
||||
int32_t taosGetCurrentAPPName(char *name, int32_t* len) {
|
||||
int32_t taosGetCurrentAPPName(char* name, int32_t* len) {
|
||||
char filepath[1024] = {0};
|
||||
|
||||
GetModuleFileName(NULL, filepath, MAX_PATH);
|
||||
*strrchr(filepath,'.') = '\0';
|
||||
char* sub = strrchr(filepath, '.');
|
||||
if (sub != NULL) {
|
||||
*sub = '\0';
|
||||
}
|
||||
strcpy(name, filepath);
|
||||
|
||||
if (len != NULL) {
|
||||
*len = (int32_t) strlen(filepath);
|
||||
*len = (int32_t)strlen(filepath);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -165,7 +165,7 @@ void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char *errMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_SQL & 0XFFFF, temp);
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_OPERATION & 0XFFFF, temp);
|
||||
}
|
||||
|
||||
void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
||||
|
|
|
@ -263,7 +263,7 @@ void httpProcessSingleSqlCallBackImp(void *param, TAOS_RES *result, int32_t code
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
SSqlObj *pObj = (SSqlObj *)result;
|
||||
if (code == TSDB_CODE_TSC_INVALID_SQL) {
|
||||
if (code == TSDB_CODE_TSC_INVALID_OPERATION) {
|
||||
terrno = code;
|
||||
httpError("context:%p, fd:%d, user:%s, query error, code:%s, sqlObj:%p, error:%s", pContext, pContext->fd,
|
||||
pContext->user, tstrerror(code), pObj, taos_errstr(pObj));
|
||||
|
|
|
@ -237,6 +237,11 @@ void httpFreeMultiCmds(HttpContext *pContext) {
|
|||
JsonBuf *httpMallocJsonBuf(HttpContext *pContext) {
|
||||
if (pContext->jsonBuf == NULL) {
|
||||
pContext->jsonBuf = (JsonBuf *)malloc(sizeof(JsonBuf));
|
||||
if (pContext->jsonBuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pContext->jsonBuf, 0, sizeof(JsonBuf));
|
||||
}
|
||||
|
||||
if (!pContext->jsonBuf->pContext) {
|
||||
|
|
|
@ -417,3 +417,13 @@ void monExecuteSQL(char *sql) {
|
|||
monDebug("execute sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "sql");
|
||||
}
|
||||
|
||||
void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param) {
|
||||
if (tsMonitor.conn == NULL) {
|
||||
callback(param, NULL, TSDB_CODE_MON_CONNECTION_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
monDebug("execute sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, callback, param);
|
||||
}
|
||||
|
|
|
@ -71,13 +71,13 @@ typedef struct SResultRowPool {
|
|||
SArray* pData; // SArray<void*>
|
||||
} SResultRowPool;
|
||||
|
||||
typedef struct SSqlGroupbyExpr {
|
||||
typedef struct SGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||
int16_t numOfGroupCols;
|
||||
int16_t numOfGroupCols; // todo remove it
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SSqlGroupbyExpr;
|
||||
} SGroupbyExpr;
|
||||
|
||||
typedef struct SResultRow {
|
||||
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||
|
@ -217,7 +217,7 @@ typedef struct SQueryAttr {
|
|||
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
||||
int32_t maxTableColumnWidth;
|
||||
int32_t tagLen; // tag value length of current query
|
||||
SSqlGroupbyExpr* pGroupbyExpr;
|
||||
SGroupbyExpr* pGroupbyExpr;
|
||||
|
||||
SExprInfo* pExpr1;
|
||||
SExprInfo* pExpr2;
|
||||
|
@ -305,6 +305,7 @@ enum OPERATOR_TYPE_E {
|
|||
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||
OP_Filter = 19,
|
||||
OP_Distinct = 20,
|
||||
OP_Join = 21,
|
||||
};
|
||||
|
||||
typedef struct SOperatorInfo {
|
||||
|
@ -317,7 +318,8 @@ typedef struct SOperatorInfo {
|
|||
SExprInfo *pExpr;
|
||||
SQueryRuntimeEnv *pRuntimeEnv;
|
||||
|
||||
struct SOperatorInfo *upstream;
|
||||
struct SOperatorInfo **upstream; // upstream pointer list
|
||||
int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator
|
||||
__operator_fn_t exec;
|
||||
__optr_cleanup_fn_t cleanup;
|
||||
} SOperatorInfo;
|
||||
|
@ -365,7 +367,7 @@ typedef struct SQueryParam {
|
|||
|
||||
SColIndex *pGroupColIndex;
|
||||
SColumnInfo *pTagColumnInfo;
|
||||
SSqlGroupbyExpr *pGroupbyExpr;
|
||||
SGroupbyExpr *pGroupbyExpr;
|
||||
int32_t tableScanOperator;
|
||||
SArray *pOperator;
|
||||
SUdfInfo *pUdfInfo;
|
||||
|
@ -496,9 +498,11 @@ typedef struct SMultiwayMergeInfo {
|
|||
|
||||
bool hasPrev;
|
||||
bool groupMix;
|
||||
SArray *udfInfo;
|
||||
SArray *udfInfo;
|
||||
} SMultiwayMergeInfo;
|
||||
|
||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||
|
||||
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
||||
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
||||
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
|
@ -519,12 +523,20 @@ SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SEx
|
|||
int32_t numOfRows, void* merger, bool groupMix);
|
||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo);
|
||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||
|
||||
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput);
|
||||
|
||||
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
||||
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
||||
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
||||
|
||||
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock);
|
||||
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p);
|
||||
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p);
|
||||
|
||||
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
||||
void* destroyOutputBuf(SSDataBlock* pBlock);
|
||||
|
||||
|
@ -542,13 +554,14 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
|||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||
SSqlExpr **pExpr, SExprInfo *prevExpr, SUdfInfo *pUdfInfo);
|
||||
|
||||
SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, bool stableQuery, char* sql, uint64_t *qId, int32_t vgId, SUdfInfo* pUdfInfo);
|
||||
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId, SUdfInfo* pUdfInfo);
|
||||
|
||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||
int32_t prevResultLen, void* merger);
|
||||
|
||||
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId);
|
||||
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||
|
||||
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef struct SFillInfo {
|
|||
|
||||
SFillColInfo* pFillCol; // column info for fill operations
|
||||
SFillTagColInfo* pTags; // tags value for filling gap
|
||||
void* handle; // for dubug purpose
|
||||
void* handle; // for debug purpose
|
||||
} SFillInfo;
|
||||
|
||||
typedef struct SPoint {
|
||||
|
@ -82,8 +82,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
|||
|
||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
|
||||
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput);
|
||||
|
||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo);
|
||||
|
||||
int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct SHeapEntry {
|
|||
} SHeapEntry;
|
||||
|
||||
typedef struct SHistogramInfo {
|
||||
int32_t numOfElems;
|
||||
int64_t numOfElems;
|
||||
int32_t numOfEntries;
|
||||
int32_t maxEntries;
|
||||
double min;
|
||||
|
|
|
@ -16,7 +16,38 @@
|
|||
#ifndef TDENGINE_QPLAN_H
|
||||
#define TDENGINE_QPLAN_H
|
||||
|
||||
//TODO refactor
|
||||
struct SQueryInfo;
|
||||
|
||||
typedef struct SQueryNodeBasicInfo {
|
||||
int32_t type;
|
||||
char *name;
|
||||
} SQueryNodeBasicInfo;
|
||||
|
||||
typedef struct SQueryTableInfo {
|
||||
char *tableName;
|
||||
STableId id;
|
||||
} SQueryTableInfo;
|
||||
|
||||
typedef struct SQueryNode {
|
||||
SQueryNodeBasicInfo info;
|
||||
SQueryTableInfo tableInfo;
|
||||
SSchema *pSchema; // the schema of the input SSDatablock
|
||||
int32_t numOfCols; // number of input columns
|
||||
SExprInfo *pExpr; // the query functions or sql aggregations
|
||||
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
||||
|
||||
void *pExtInfo; // additional information
|
||||
// previous operator to generated result for current node to process
|
||||
// in case of join, multiple prev nodes exist.
|
||||
SArray *pPrevNodes;// upstream nodes
|
||||
struct SQueryNode *nextNode;
|
||||
} SQueryNode;
|
||||
|
||||
SQueryNode* qCreateQueryPlan(struct SQueryInfo* pQueryInfo);
|
||||
void* qDestroyQueryPlan(SQueryNode* pQueryNode);
|
||||
|
||||
char* queryPlanToString(SQueryNode* pQueryNode);
|
||||
|
||||
SArray* createTableScanPlan(SQueryAttr* pQueryAttr);
|
||||
SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr);
|
||||
SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr);
|
||||
|
|
|
@ -107,14 +107,18 @@ typedef struct SSqlNode {
|
|||
struct tSqlExpr *pHaving; // having clause [optional]
|
||||
} SSqlNode;
|
||||
|
||||
typedef struct STableNamePair {
|
||||
SStrToken name;
|
||||
typedef struct SRelElementPair {
|
||||
union {
|
||||
SStrToken tableName;
|
||||
SArray *pSubquery;
|
||||
};
|
||||
|
||||
SStrToken aliasName;
|
||||
} STableNamePair;
|
||||
} SRelElementPair;
|
||||
|
||||
typedef struct SRelationInfo {
|
||||
int32_t type; // nested query|table name list
|
||||
SArray *list; // SArray<STableNamePair>|SArray<SSqlNode*>
|
||||
SArray *list; // SArray<SRelElementPair>
|
||||
} SRelationInfo;
|
||||
|
||||
typedef struct SCreatedTableInfo {
|
||||
|
@ -264,8 +268,9 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
|||
SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder);
|
||||
|
||||
SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias);
|
||||
SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode);
|
||||
//SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SRelElementPair* p);
|
||||
void *destroyRelationInfo(SRelationInfo* pFromInfo);
|
||||
SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias);
|
||||
|
||||
// sql expr leaf node
|
||||
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
||||
|
|
|
@ -47,6 +47,9 @@ void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, in
|
|||
|
||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||
|
||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||
return pResultRowInfo->pResult[slot];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue