commit
8cbd216e54
25
.travis.yml
25
.travis.yml
|
@ -34,6 +34,7 @@ matrix:
|
|||
- psmisc
|
||||
- unixodbc
|
||||
- unixodbc-dev
|
||||
- mono-complete
|
||||
|
||||
before_script:
|
||||
- export TZ=Asia/Harbin
|
||||
|
@ -59,6 +60,18 @@ matrix:
|
|||
pip3 install guppy3
|
||||
pip3 install --user ${TRAVIS_BUILD_DIR}/src/connector/python/linux/python3/
|
||||
|
||||
cd ${TRAVIS_BUILD_DIR}/tests/examples/C#/taosdemo
|
||||
mcs -out:taosdemo *.cs || travis_terminate $?
|
||||
pkill -TERM -x taosd
|
||||
fuser -k -n tcp 6030
|
||||
sleep 1
|
||||
${TRAVIS_BUILD_DIR}/debug/build/bin/taosd -c ${TRAVIS_BUILD_DIR}/debug/test/cfg > /dev/null &
|
||||
sleep 5
|
||||
mono taosdemo -Q DEFAULT -y || travis_terminate $?
|
||||
pkill -KILL -x taosd
|
||||
fuser -k -n tcp 6030
|
||||
sleep 1
|
||||
|
||||
cd ${TRAVIS_BUILD_DIR}/tests
|
||||
./test-all.sh smoke || travis_terminate $?
|
||||
sleep 1
|
||||
|
@ -74,6 +87,7 @@ matrix:
|
|||
./valgrind-test.sh 2>&1 > mem-error-out.log
|
||||
sleep 1
|
||||
|
||||
|
||||
# Color setting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
|
@ -146,7 +160,7 @@ matrix:
|
|||
branch_pattern: coverity_scan
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: trusty
|
||||
language: c
|
||||
git:
|
||||
- depth: 1
|
||||
|
@ -156,8 +170,9 @@ matrix:
|
|||
packages:
|
||||
- build-essential
|
||||
- cmake
|
||||
- binutils-2.26
|
||||
env:
|
||||
- DESC="xenial build"
|
||||
- DESC="trusty/gcc-4.8/bintuils-2.26 build"
|
||||
|
||||
before_script:
|
||||
- export TZ=Asia/Harbin
|
||||
|
@ -168,7 +183,7 @@ matrix:
|
|||
|
||||
script:
|
||||
- cmake .. > /dev/null
|
||||
- make
|
||||
- export PATH=/usr/lib/binutils-2.26/bin:$PATH && make
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
|
@ -200,7 +215,7 @@ matrix:
|
|||
dist: bionic
|
||||
language: c
|
||||
compiler: clang
|
||||
env: DESC="linux/clang build"
|
||||
env: DESC="arm64 linux/clang build"
|
||||
git:
|
||||
- depth: 1
|
||||
|
||||
|
@ -238,7 +253,7 @@ matrix:
|
|||
- build-essential
|
||||
- cmake
|
||||
env:
|
||||
- DESC="xenial build"
|
||||
- DESC="arm64 xenial build"
|
||||
|
||||
before_script:
|
||||
- export TZ=Asia/Harbin
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
IF (CMAKE_VERSION VERSION_LESS 3.0)
|
||||
PROJECT(TDengine CXX)
|
||||
SET(PROJECT_VERSION_MAJOR "${LIB_MAJOR_VERSION}")
|
||||
|
|
|
@ -104,6 +104,10 @@ pipeline {
|
|||
find pytest -name '*'sql|xargs rm -rf
|
||||
./test-all.sh p2
|
||||
date'''
|
||||
sh '''
|
||||
cd ${WKC}/tests
|
||||
./test-all.sh b4fq
|
||||
'''
|
||||
}
|
||||
}
|
||||
stage('test_b1') {
|
||||
|
|
|
@ -33,11 +33,17 @@ To build TDengine, use [CMake](https://cmake.org/) 3.5 or higher versions in the
|
|||
|
||||
## Install tools
|
||||
|
||||
### Ubuntu & Debian:
|
||||
### Ubuntu 16.04 and above & Debian:
|
||||
```bash
|
||||
sudo apt-get install -y gcc cmake build-essential git
|
||||
```
|
||||
|
||||
### Ubuntu 14.04:
|
||||
```bash
|
||||
sudo apt-get install -y gcc cmake3 build-essential git binutils-2.26
|
||||
export PATH=/usr/lib/binutils-2.26/bin:$PATH
|
||||
```
|
||||
|
||||
To compile and package the JDBC driver source code, you should have a Java jdk-8 or higher and Apache Maven 2.7 or higher installed.
|
||||
To install openjdk-8:
|
||||
```bash
|
||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.0.13.0")
|
||||
SET(TD_VER_NUMBER "2.0.14.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
ADD_SUBDIRECTORY(zlib-1.2.11)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
|
||||
# MQTT-C build options
|
||||
option(MQTT_C_OpenSSL_SUPPORT "Build MQTT-C with OpenSSL support?" OFF)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_WINDOWS)
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
TDengine采用关系型数据模型,需要建库、建表。因此对于一个具体的应用场景,需要考虑库的设计,超级表和普通表的设计。本节不讨论细致的语法规则,只介绍概念。
|
||||
|
||||
关于数据建模请参考<a href="https://www.taosdata.com/blog/2020/11/11/1945.html">视频教程</a>。
|
||||
|
||||
## 创建库
|
||||
|
||||
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为让各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如:
|
||||
|
@ -60,4 +62,3 @@ TDengine支持多列模型,只要物理量是一个数据采集点同时采集
|
|||
|
||||
TDengine建议尽可能采用多列模型,因为插入效率以及存储效率更高。但对于有些场景,一个采集点的采集量的种类经常变化,这个时候,如果采用多列模型,就需要频繁修改超级表的结构定义,让应用变的复杂,这个时候,采用单列模型会显得简单。
|
||||
|
||||
关于数据建模请参考<a href="https://www.taosdata.com/blog/2020/11/11/1945.html">视频教程</a>。
|
||||
|
|
|
@ -68,7 +68,9 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
2) UPDATE 标志数据库支持更新相同时间戳数据;
|
||||
|
||||
3) 数据库名最大长度为33;
|
||||
|
||||
4) 一条SQL 语句的最大长度为65480个字符;
|
||||
|
||||
5) 数据库还有更多与存储相关的配置参数,请参见系统管理。
|
||||
|
||||
- **显示系统当前参数**
|
||||
|
@ -130,12 +132,37 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]);
|
||||
```
|
||||
说明:
|
||||
|
||||
1) 表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;
|
||||
2) 表名最大长度为193;
|
||||
|
||||
2) 表名最大长度为192;
|
||||
|
||||
3) 表的每行长度不能超过16k个字符;
|
||||
|
||||
4) 子表名只能由字母、数字和下划线组成,且不能以数字开头
|
||||
|
||||
5) 使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节;
|
||||
|
||||
- **以超级表为模板创建数据表**
|
||||
|
||||
```mysql
|
||||
CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
|
||||
```
|
||||
以指定的超级表为模板,指定 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 及以上版本)
|
||||
|
||||
说明:
|
||||
|
||||
1)批量建表方式要求数据表必须以超级表为模板。
|
||||
|
||||
2)在不超出 SQL 语句长度限制的前提下,单条语句中的建表数量建议控制在 1000~3000 之间,将会获得比较理想的建表速度。
|
||||
|
||||
- **删除数据表**
|
||||
|
||||
```mysql
|
||||
|
@ -148,7 +175,11 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
SHOW TABLES [LIKE tb_name_wildcar];
|
||||
```
|
||||
|
||||
显示当前数据库下的所有数据表信息。说明:可在like中使用通配符进行名称的匹配。 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’_’下划线匹配一个字符。
|
||||
显示当前数据库下的所有数据表信息。
|
||||
|
||||
说明:可在like中使用通配符进行名称的匹配,这一通配符字符串最长不能超过24字节。
|
||||
|
||||
通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’\_’下划线匹配一个字符。
|
||||
|
||||
- **在线修改显示字符宽度**
|
||||
|
||||
|
@ -168,8 +199,10 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
ALTER TABLE tb_name ADD COLUMN field_name data_type;
|
||||
```
|
||||
说明:
|
||||
|
||||
1) 列的最大个数为1024,最小个数为2;
|
||||
2) 列名最大长度为65;
|
||||
|
||||
2) 列名最大长度为64;
|
||||
|
||||
- **表删除列**
|
||||
|
||||
|
@ -187,10 +220,14 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
创建STable, 与创建表的SQL语法相似,但需指定TAGS字段的名称和类型
|
||||
|
||||
说明:
|
||||
|
||||
1) TAGS 列的数据类型不能是timestamp类型;
|
||||
|
||||
2) TAGS 列名不能与其他列名相同;
|
||||
|
||||
3) TAGS 列名不能为预留关键字;
|
||||
4) TAGS 最多允许128个,可以0个,总长度不超过16k个字符
|
||||
|
||||
4) TAGS 最多允许128个,至少1个,总长度不超过16k个字符。
|
||||
|
||||
- **删除超级表**
|
||||
|
||||
|
@ -263,33 +300,33 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
|
||||
- **插入一条记录,数据对应到指定的列**
|
||||
```mysql
|
||||
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value, ...)
|
||||
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value, ...)
|
||||
```
|
||||
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
|
||||
|
||||
- **插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...)...;
|
||||
INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
向表tb_name中插入多条记录
|
||||
|
||||
- **按指定的列插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb_name (field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
|
||||
INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
向表tb_name中按指定的列插入多条记录
|
||||
|
||||
- **向多个表插入多条记录**
|
||||
```mysql
|
||||
INSERT INTO tb1_name VALUES (field1_value1, ...)(field1_value2, ...)...
|
||||
tb2_name VALUES (field1_value1, ...)(field1_value2, ...)...;
|
||||
INSERT INTO tb1_name VALUES (field1_value1, ...) (field1_value2, ...) ...
|
||||
tb2_name VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||
```
|
||||
同时向表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, ...);
|
||||
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中按列分别插入多条记录
|
||||
|
||||
|
@ -316,25 +353,27 @@ SELECT select_expr [, select_expr ...]
|
|||
[LIMIT limit_val [, OFFSET offset_val]]
|
||||
[>> export_file]
|
||||
```
|
||||
|
||||
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
|
||||
|
||||
```mysql
|
||||
taos> create table meters(ts timestamp, current float, voltage int, phase float) tags(location binary(30), groupId int);
|
||||
taos> CREATE TABLE meters(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS(location BINARY(30), groupId INT);
|
||||
Query OK, 0 row(s) affected (0.008245s)
|
||||
|
||||
taos> show stables;
|
||||
taos> SHOW STABLES;
|
||||
name | created_time | columns | tags | tables |
|
||||
============================================================================================
|
||||
meters | 2020-08-06 17:50:27.831 | 4 | 2 | 0 |
|
||||
Query OK, 1 row(s) in set (0.001029s)
|
||||
|
||||
taos> show tables;
|
||||
taos> SHOW TABLES;
|
||||
Query OK, 0 row(s) in set (0.000946s)
|
||||
|
||||
taos> insert into d1001 using meters tags('Beijing.Chaoyang', 2);
|
||||
taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2);
|
||||
|
||||
DB error: invalid SQL: keyword VALUES or FILE required
|
||||
|
||||
taos> show tables;
|
||||
taos> SHOW TABLES;
|
||||
table_name | created_time | columns | stable_name |
|
||||
======================================================================================================
|
||||
d1001 | 2020-08-06 17:52:02.097 | 4 | meters |
|
||||
|
@ -397,27 +436,41 @@ Query OK, 1 row(s) in set (0.020443s)
|
|||
在使用SQL函数来进行查询过程中,部分SQL函数支持通配符操作。其中的区别在于:
|
||||
```count(\*)```函数只返回一列。```first```、```last```、```last_row```函数则是返回全部列。
|
||||
|
||||
```
|
||||
taos> select count(*) from d1001;
|
||||
```mysql
|
||||
taos> SELECT COUNT(*) FROM d1001;
|
||||
count(*) |
|
||||
========================
|
||||
3 |
|
||||
Query OK, 1 row(s) in set (0.001035s)
|
||||
```
|
||||
|
||||
```
|
||||
taos> select first(*) from d1001;
|
||||
```mysql
|
||||
taos> SELECT FIRST(*) FROM d1001;
|
||||
first(ts) | first(current) | first(voltage) | first(phase) |
|
||||
=========================================================================================
|
||||
2018-10-03 14:38:05.000 | 10.30000 | 219 | 0.31000 |
|
||||
Query OK, 1 row(s) in set (0.000849s)
|
||||
```
|
||||
|
||||
##### 标签列
|
||||
|
||||
从 2.0.14 版本开始,支持在普通表的查询中指定 _标签列_,且标签列的值会与普通列的数据一起返回。
|
||||
```mysql
|
||||
taos> SELECT location, groupid, current FROM d1001 LIMIT 2;
|
||||
location | groupid | current |
|
||||
======================================================================
|
||||
Beijing.Chaoyang | 2 | 10.30000 |
|
||||
Beijing.Chaoyang | 2 | 12.60000 |
|
||||
Query OK, 2 row(s) in set (0.003112s)
|
||||
```
|
||||
|
||||
注意:普通表的通配符 * 中并不包含 _标签列_。
|
||||
|
||||
#### 结果集列名
|
||||
|
||||
```SELECT```子句中,如果不指定返回结果集合的列名,结果集列名称默认使用```SELECT```子句中的表达式名称作为列名称。此外,用户可使用```AS```来重命名返回结果集合中列的名称。例如:
|
||||
```
|
||||
taos> select ts, ts as primary_key_ts from d1001;
|
||||
```mysql
|
||||
taos> SELECT ts, ts AS primary_key_ts FROM d1001;
|
||||
ts | primary_key_ts |
|
||||
====================================================
|
||||
2018-10-03 14:38:05.000 | 2018-10-03 14:38:05.000 |
|
||||
|
@ -434,53 +487,53 @@ Query OK, 3 row(s) in set (0.001191s)
|
|||
|
||||
FROM关键字后面可以是若干个表(超级表)列表,也可以是子查询的结果。
|
||||
如果没有指定用户的当前数据库,可以在表名称之前使用数据库的名称来指定表所属的数据库。例如:```power.d1001``` 方式来跨库使用表。
|
||||
```
|
||||
```mysql
|
||||
SELECT * FROM power.d1001;
|
||||
------------------------------
|
||||
use power;
|
||||
USE power;
|
||||
SELECT * FROM d1001;
|
||||
```
|
||||
|
||||
#### 特殊功能
|
||||
部分特殊的查询功能可以不使用FROM子句执行。获取当前所在的数据库 database()
|
||||
```
|
||||
taos> SELECT database();
|
||||
```mysql
|
||||
taos> SELECT DATABASE();
|
||||
database() |
|
||||
=================================
|
||||
power |
|
||||
Query OK, 1 row(s) in set (0.000079s)
|
||||
```
|
||||
如果登录的时候没有指定默认数据库,且没有使用```use```命令切换数据,则返回NULL。
|
||||
```
|
||||
taos> SELECT database();
|
||||
```mysql
|
||||
taos> SELECT DATABASE();
|
||||
database() |
|
||||
=================================
|
||||
NULL |
|
||||
Query OK, 1 row(s) in set (0.000184s)
|
||||
```
|
||||
获取服务器和客户端版本号:
|
||||
```
|
||||
taos> SELECT client_version();
|
||||
```mysql
|
||||
taos> SELECT CLIENT_VERSION();
|
||||
client_version() |
|
||||
===================
|
||||
2.0.0.0 |
|
||||
Query OK, 1 row(s) in set (0.000070s)
|
||||
|
||||
taos> SELECT server_version();
|
||||
taos> SELECT SERVER_VERSION();
|
||||
server_version() |
|
||||
===================
|
||||
2.0.0.0 |
|
||||
Query OK, 1 row(s) in set (0.000077s)
|
||||
```
|
||||
服务器状态检测语句。如果服务器正常,返回一个数字(例如 1)。如果服务器异常,返回error code。该SQL语法能兼容连接池对于TDengine状态的检查及第三方工具对于数据库服务器状态的检查。并可以避免出现使用了错误的心跳检测SQL语句导致的连接池连接丢失的问题。
|
||||
```
|
||||
taos> SELECT server_status();
|
||||
```mysql
|
||||
taos> SELECT SERVER_STATUS();
|
||||
server_status() |
|
||||
==================
|
||||
1 |
|
||||
Query OK, 1 row(s) in set (0.000074s)
|
||||
|
||||
taos> SELECT server_status() as status;
|
||||
taos> SELECT SERVER_STATUS() AS status;
|
||||
status |
|
||||
==============
|
||||
1 |
|
||||
|
@ -493,15 +546,15 @@ Query OK, 1 row(s) in set (0.000081s)
|
|||
|
||||
#### 小技巧
|
||||
获取一个超级表所有的子表名及相关的标签信息:
|
||||
```
|
||||
```mysql
|
||||
SELECT TBNAME, location FROM meters;
|
||||
```
|
||||
统计超级表下辖子表数量:
|
||||
```
|
||||
```mysql
|
||||
SELECT COUNT(TBNAME) FROM meters;
|
||||
```
|
||||
以上两个查询均只支持在Where条件子句中添加针对标签(TAGS)的过滤条件。例如:
|
||||
```
|
||||
```mysql
|
||||
taos> SELECT TBNAME, location FROM meters;
|
||||
tbname | location |
|
||||
==================================================================
|
||||
|
@ -511,7 +564,7 @@ taos> SELECT TBNAME, location FROM meters;
|
|||
d1001 | Beijing.Chaoyang |
|
||||
Query OK, 4 row(s) in set (0.000881s)
|
||||
|
||||
taos> SELECT count(tbname) FROM meters WHERE groupId > 2;
|
||||
taos> SELECT COUNT(tbname) FROM meters WHERE groupId > 2;
|
||||
count(tbname) |
|
||||
========================
|
||||
2 |
|
||||
|
@ -537,15 +590,15 @@ Query OK, 1 row(s) in set (0.001091s)
|
|||
| % | 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)) 。
|
||||
1. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
|
||||
2. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用``` OR``` 关键字进行组合条件的查询过滤。例如:((value > 20 and value < 30) OR (value < 12)) 。
|
||||
|
||||
### SQL 示例
|
||||
|
||||
- 对于下面的例子,表tb1用以下语句创建
|
||||
|
||||
```mysql
|
||||
CREATE TABLE tb1 (ts timestamp, col1 int, col2 float, col3 binary(50));
|
||||
CREATE TABLE tb1 (ts TIMESTAMP, col1 INT, col2 FLOAT, col3 BINARY(50));
|
||||
```
|
||||
|
||||
- 查询tb1刚过去的一个小时的所有记录
|
||||
|
@ -563,7 +616,7 @@ Query OK, 1 row(s) in set (0.001091s)
|
|||
- 查询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;
|
||||
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`.
|
||||
|
@ -583,20 +636,30 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中记录行数或某列的非空值个数。
|
||||
|
||||
返回结果数据类型:长整型INT64。
|
||||
|
||||
应用字段:应用全部字段。
|
||||
|
||||
适用于:表、超级表。
|
||||
说明:1)可以使用星号*来替代具体的字段,使用星号(*)返回全部记录数量。2)针对同一表的(不包含NULL值)字段查询结果均相同。3)如果统计对象是具体的列,则返回该列中非NULL值的记录数量。
|
||||
|
||||
说明:
|
||||
|
||||
1)可以使用星号*来替代具体的字段,使用星号(*)返回全部记录数量。
|
||||
|
||||
2)针对同一表的(不包含NULL值)字段查询结果均相同。
|
||||
|
||||
3)如果统计对象是具体的列,则返回该列中非NULL值的记录数量。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
taos> SELECT COUNT(*), COUNT(VOLTAGE) FROM meters;
|
||||
taos> SELECT COUNT(*), COUNT(voltage) FROM meters;
|
||||
count(*) | count(voltage) |
|
||||
================================================
|
||||
9 | 9 |
|
||||
Query OK, 1 row(s) in set (0.004475s)
|
||||
|
||||
taos> SELECT COUNT(*), COUNT(VOLTAGE) FROM d1001;
|
||||
taos> SELECT COUNT(*), COUNT(voltage) FROM d1001;
|
||||
count(*) | count(voltage) |
|
||||
================================================
|
||||
3 | 3 |
|
||||
|
@ -608,8 +671,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT AVG(field_name) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的平均值。
|
||||
|
||||
返回结果数据类型:双精度浮点数Double。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool字段。
|
||||
|
||||
适用于:表、超级表。
|
||||
|
||||
示例:
|
||||
|
@ -620,7 +686,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
11.466666751 | 220.444444444 | 0.293333333 |
|
||||
Query OK, 1 row(s) in set (0.004135s)
|
||||
|
||||
taos> SELECT AVG(current), AVG(voltage), AVG(phase) from d1001;
|
||||
taos> SELECT AVG(current), AVG(voltage), AVG(phase) FROM d1001;
|
||||
avg(current) | avg(voltage) | avg(phase) |
|
||||
====================================================================================
|
||||
11.733333588 | 219.333333333 | 0.316666673 |
|
||||
|
@ -632,9 +698,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT TWA(field_name) FROM tb_name WHERE clause;
|
||||
```
|
||||
功能说明:时间加权平均函数。统计表/超级表中某列在一段时间内的时间加权平均。
|
||||
|
||||
返回结果数据类型:双精度浮点数Double。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
说明:时间加权平均(time weighted average, TWA)查询需要指定查询时间段的 _开始时间_ 和 _结束时间_ 。
|
||||
|
||||
适用于:表、超级表。
|
||||
|
||||
- **SUM**
|
||||
|
@ -642,19 +710,22 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT SUM(field_name) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的和。
|
||||
|
||||
返回结果数据类型:双精度浮点数Double和长整型INT64。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
适用于:表、超级表。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) from meters;
|
||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM meters;
|
||||
sum(current) | sum(voltage) | sum(phase) |
|
||||
================================================================================
|
||||
103.200000763 | 1984 | 2.640000001 |
|
||||
Query OK, 1 row(s) in set (0.001702s)
|
||||
|
||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) from d1001;
|
||||
taos> SELECT SUM(current), SUM(voltage), SUM(phase) FROM d1001;
|
||||
sum(current) | sum(voltage) | sum(phase) |
|
||||
================================================================================
|
||||
35.200000763 | 658 | 0.950000018 |
|
||||
|
@ -666,8 +737,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表中某列的均方差。
|
||||
|
||||
返回结果数据类型:双精度浮点数Double。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
适用于:表。
|
||||
|
||||
示例:
|
||||
|
@ -684,9 +758,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表中某列的值是主键(时间戳)的拟合直线方程。start_val是自变量初始值,step_val是自变量的步长值。
|
||||
|
||||
返回结果数据类型:字符串表达式(斜率, 截距)。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
说明:自变量是时间戳,因变量是该列的值。
|
||||
|
||||
适用于:表。
|
||||
|
||||
示例:
|
||||
|
@ -705,7 +783,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的值最小值。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
示例:
|
||||
|
@ -728,7 +808,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的值最大值。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
示例:
|
||||
|
@ -751,9 +833,18 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的值最先写入的非NULL值。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:所有字段。
|
||||
说明:1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(*);2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;3) 如果结果集中所有列全部为NULL值,则不返回结果。
|
||||
|
||||
说明:
|
||||
|
||||
1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*);
|
||||
|
||||
2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;
|
||||
|
||||
3) 如果结果集中所有列全部为NULL值,则不返回结果。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -775,9 +866,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的值最后写入的非NULL值。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:所有字段。
|
||||
说明:1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(*);2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。
|
||||
|
||||
说明:
|
||||
|
||||
1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(\*);
|
||||
|
||||
2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -799,9 +897,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明: 统计表/超级表中某列的值最大*k*个非NULL值。若多于k个列值并列最大,则返回时间戳小的。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
说明:1)*k*值取值范围1≤*k*≤100;2)系统同时返回该记录关联的时间戳列。
|
||||
|
||||
说明:
|
||||
|
||||
1)*k*值取值范围1≤*k*≤100;
|
||||
|
||||
2)系统同时返回该记录关联的时间戳列。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -826,9 +931,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的值最小*k*个非NULL值。若多于k个列值并列最小,则返回时间戳小的。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
说明:1)*k*值取值范围1≤*k*≤100;2)系统同时返回该记录关联的时间戳列。
|
||||
|
||||
说明:
|
||||
|
||||
1)*k*值取值范围1≤*k*≤100;
|
||||
|
||||
2)系统同时返回该记录关联的时间戳列。
|
||||
|
||||
示例:
|
||||
```mysql
|
||||
|
@ -852,8 +964,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表中某列的值百分比分位数。
|
||||
|
||||
返回结果数据类型: 双精度浮点数Double。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。
|
||||
|
||||
示例:
|
||||
|
@ -870,9 +985,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT APERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表中某列的值百分比分位数,与PERCENTILE函数相似,但是返回近似结果。
|
||||
|
||||
返回结果数据类型: 双精度浮点数Double。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。推荐使用```APERCENTILE```函数,该函数性能远胜于```PERCENTILE```函数
|
||||
|
||||
```mysql
|
||||
taos> SELECT APERCENTILE(current, 20) FROM d1001;
|
||||
apercentile(current, 20) |
|
||||
|
@ -886,8 +1005,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
|
||||
```
|
||||
功能说明:返回表(超级表)的最后一条记录。
|
||||
|
||||
返回结果数据类型:同应用的字段。
|
||||
|
||||
应用字段:所有字段。
|
||||
|
||||
说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。
|
||||
|
||||
示例:
|
||||
|
@ -911,8 +1033,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT DIFF(field_name) FROM tb_name [WHERE clause];
|
||||
```
|
||||
功能说明:统计表中某列的值与前一行对应值的差。
|
||||
|
||||
返回结果数据类型: 同应用字段。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
|
||||
说明:输出结果行数是范围内总行数减一,第一行没有结果输出。
|
||||
|
||||
示例:
|
||||
|
@ -930,8 +1055,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列的最大值和最小值之差。
|
||||
|
||||
返回结果数据类型: 双精度浮点数。
|
||||
|
||||
应用字段:不能应用在binary、nchar、bool类型字段。
|
||||
|
||||
说明:可用于TIMESTAMP字段,此时表示记录的时间覆盖范围。
|
||||
|
||||
示例:
|
||||
|
@ -955,9 +1083,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
|
|||
SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name } [WHERE clause];
|
||||
```
|
||||
功能说明:统计表/超级表中某列或多列间的值加、减、乘、除、取余计算结果。
|
||||
|
||||
返回结果数据类型:双精度浮点数。
|
||||
|
||||
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
|
||||
说明:1)支持两列或多列之间进行计算,可使用括号控制计算优先级;2)NULL字段不参与计算,如果参与计算的某行中包含NULL,该行的计算结果为NULL。
|
||||
|
||||
说明:
|
||||
|
||||
1)支持两列或多列之间进行计算,可使用括号控制计算优先级;
|
||||
|
||||
2)NULL字段不参与计算,如果参与计算的某行中包含NULL,该行的计算结果为NULL。
|
||||
|
||||
```mysql
|
||||
taos> SELECT current + voltage * phase FROM d1001;
|
||||
|
@ -1004,15 +1139,15 @@ SELECT function_list FROM stb_name
|
|||
**示例:** 智能电表的建表语句如下:
|
||||
|
||||
```mysql
|
||||
CREATE TABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);
|
||||
CREATE TABLE meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT);
|
||||
```
|
||||
|
||||
针对智能电表采集的数据,以10分钟为一个阶段,计算过去24小时的电流数据的平均值、最大值、电流的中位数、以及随着时间变化的电流走势拟合直线。如果没有计算值,用前一个非NULL值填充。
|
||||
使用的查询语句如下:
|
||||
|
||||
```mysql
|
||||
SELECT AVG(current),MAX(current),LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters
|
||||
WHERE TS>=NOW-1d
|
||||
SELECT AVG(current), MAX(current), LEASTSQUARES(current, start_val, step_val), PERCENTILE(current, 50) FROM meters
|
||||
WHERE ts>=NOW-1d
|
||||
INTERVAL(10m)
|
||||
FILL(PREV);
|
||||
```
|
||||
|
|
|
@ -105,7 +105,7 @@ taosd -C
|
|||
- queryBufferSize: 为所有并发查询占用保留的内存大小。计算规则可以根据实际应用可能的最大并发数和表的数字相乘,再乘 170 。单位为字节。
|
||||
- ratioOfQueryCores: 设置查询线程的最大数量。最小值0 表示只有1个查询线程;最大值2表示最大建立2倍CPU核数的查询线程。默认为1,表示最大和CPU核数相等的查询线程。该值可以为小数,即0.5表示最大建立CPU核数一半的查询线程。
|
||||
|
||||
**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030都6042共13个端口,而且必须TCP和UDP都打开。
|
||||
**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030到6042共13个端口,而且必须TCP和UDP都打开。
|
||||
|
||||
不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:
|
||||
|
||||
|
@ -255,7 +255,7 @@ taos -C 或 taos --dump-config
|
|||
CREATE USER <user_name> PASS <'password'>;
|
||||
```
|
||||
|
||||
创建用户,并指定用户名和密码,密码需要用单引号引起来,单引号为英文半角
|
||||
创建用户,并指定用户名和密码,密码需要用单引号引起来,单引号为英文半角
|
||||
|
||||
```sql
|
||||
DROP USER <user_name>;
|
||||
|
@ -267,13 +267,15 @@ DROP USER <user_name>;
|
|||
ALTER USER <user_name> PASS <'password'>;
|
||||
```
|
||||
|
||||
修改用户密码, 为避免被转换为小写,密码需要用单引号引用,单引号为英文半角
|
||||
修改用户密码,为避免被转换为小写,密码需要用单引号引用,单引号为英文半角
|
||||
|
||||
```sql
|
||||
ALTER USER <user_name> PRIVILEGE <super|write|read>;
|
||||
ALTER USER <user_name> PRIVILEGE <write|read>;
|
||||
```
|
||||
|
||||
修改用户权限为:super/write/read,不需要添加单引号
|
||||
修改用户权限为:write 或 read,不需要添加单引号
|
||||
|
||||
说明:系统内共有 super/write/read 三种权限级别,但目前不允许通过 alter 指令把 super 权限赋予用户。
|
||||
|
||||
```mysql
|
||||
SHOW USERS;
|
||||
|
@ -432,11 +434,12 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
|||
- 数据库名:不能包含“.”以及特殊字符,不能超过32个字符
|
||||
- 表名:不能包含“.”以及特殊字符,与所属数据库名一起,不能超过192个字符
|
||||
- 表的列名:不能包含特殊字符,不能超过64个字符
|
||||
- 数据库名、表名、列名,都不能以数字开头
|
||||
- 表的列数:不能超过1024列
|
||||
- 记录的最大长度:包括时间戳8 byte,不能超过16KB
|
||||
- 单条SQL语句默认最大字符串长度:65480 byte
|
||||
- 数据库副本数:不能超过3
|
||||
- 用户名:不能超过20个byte
|
||||
- 用户名:不能超过23个byte
|
||||
- 用户密码:不能超过15个byte
|
||||
- 标签(Tags)数量:不能超过128个
|
||||
- 标签的总长度:不能超过16Kbyte
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
|
||||
|
||||
关于集群搭建请参考<a href="https://www.taosdata.com/blog/2020/11/11/1961.html">视频教程</a>。
|
||||
|
||||
## 准备工作
|
||||
|
||||
**第零步**:规划集群所有物理节点的FQDN,将规划好的FQDN分别添加到每个物理节点的/etc/hostname;修改每个物理节点的/etc/hosts,将所有集群物理节点的IP与FQDN的对应添加好。【如部署了DNS,请联系网络管理员在DNS上做好相关配置】
|
||||
|
@ -227,4 +229,3 @@ SHOW MNODES;
|
|||
|
||||
TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
|
||||
|
||||
关于集群搭建请参考<a href="https://www.taosdata.com/blog/2020/11/11/1961.html">视频教程</a>。
|
||||
|
|
|
@ -89,6 +89,8 @@ SHOW DNODES;
|
|||
```
|
||||
它将列出集群中所有的dnode,每个dnode的fqdn:port, 状态(ready, offline等),vnode数目,还未使用的vnode数目等信息。在添加或删除一个节点后,可以使用该命令查看。
|
||||
|
||||
如果集群配置了Arbitrator,那么它也会在这个节点列表中显示出来,其role列的值会是“arb”。
|
||||
|
||||
###查看虚拟节点组
|
||||
|
||||
为充分利用多核技术,并提供scalability,数据需要分片处理。因此TDengine会将一个DB的数据切分成多份,存放在多个vnode里。这些vnode可能分布在多个dnode里,这样就实现了水平扩展。一个vnode仅仅属于一个DB,但一个DB可以有多个vnode。vnode的是mnode根据当前系统资源的情况,自动进行分配的,无需任何人工干预。
|
||||
|
@ -139,4 +141,6 @@ SHOW MNODES;
|
|||
|
||||
如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。
|
||||
|
||||
TDengine安装包里带有一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6030。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。
|
||||
TDengine安装包里带有一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6030。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为Arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的Arbitrator。
|
||||
|
||||
在配置了Arbitrator的情况下,它也会显示在“show dnodes;”指令给出的节点列表中。
|
||||
|
|
|
@ -178,11 +178,11 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
|
||||
获取客户端版本信息。
|
||||
|
||||
- `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port)`
|
||||
- `TAOS *taos_connect(const char *host, const char *user, const char *pass, const char *db, int port)`
|
||||
|
||||
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
|
||||
|
||||
- ip:TDengine管理主节点的IP地址
|
||||
- host:TDengine管理主节点的FQDN
|
||||
- user:用户名
|
||||
- pass:密码
|
||||
- db:数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
|
||||
|
@ -252,7 +252,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
|
||||
- `void taos_free_result(TAOS_RES *res)`
|
||||
|
||||
释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。
|
||||
释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用`taos_consume`等获取查询结果的函数,将导致应用Crash。
|
||||
|
||||
- `char *taos_errstr(TAOS_RES *res)`
|
||||
|
||||
|
@ -262,11 +262,11 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
|
||||
获取最近一次API调用失败的原因,返回值为错误代码。
|
||||
|
||||
**注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
|
||||
**注意**:2.0及以上版本 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池。而不推荐在应用中将该连接 (TAOS\*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性,但 “USE statement” 等状态量有可能在线程之间相互干扰。此外,C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
|
||||
|
||||
### 异步查询API
|
||||
|
||||
同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。
|
||||
同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2\~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。
|
||||
|
||||
异步API都需要应用提供相应的回调函数,回调函数参数设置如下:前两个参数都是一致的,第三个参数依不同的API而定。第一个参数param是应用调用异步API时提供给系统的,用于回调时,应用能够找回具体操作的上下文,依具体实现而定。第二个参数是SQL操作的结果集,如果为空,比如insert操作,表示没有记录返回,如果不为空,比如select操作,表示有记录返回。
|
||||
|
||||
|
@ -425,7 +425,7 @@ cd C:\TDengine\connector\python\windows
|
|||
python -m pip install python3\
|
||||
```
|
||||
|
||||
*如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。
|
||||
* 如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。
|
||||
对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。
|
||||
|
||||
### 使用
|
||||
|
@ -442,7 +442,7 @@ import taos
|
|||
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
|
||||
c1 = conn.cursor()
|
||||
```
|
||||
*<em>host</em> 是TDengine 服务端所有IP, <em>config</em> 为客户端配置文件所在目录
|
||||
* <em>host</em> 是TDengine 服务端所有IP, <em>config</em> 为客户端配置文件所在目录
|
||||
|
||||
* 写入数据
|
||||
```python
|
||||
|
@ -510,17 +510,17 @@ conn.close()
|
|||
|
||||
用户可通过python的帮助信息直接查看模块的使用信息,或者参考tests/examples/python中的示例程序。以下为部分常用类和方法:
|
||||
|
||||
- _TDengineConnection_类
|
||||
- _TDengineConnection_ 类
|
||||
|
||||
参考python中help(taos.TDengineConnection)。
|
||||
这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,这个连接实例可以是每个线程申请一个,也可以多线程共享一个连接。
|
||||
这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,推荐每个线程申请一个独立的连接实例,而不建议多线程共享一个连接。
|
||||
|
||||
- _TDengineCursor_类
|
||||
- _TDengineCursor_ 类
|
||||
|
||||
参考python中help(taos.TDengineCursor)。
|
||||
这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能夸线程共享使用,否则会导致返回结果出现错误。
|
||||
|
||||
- _connect_方法
|
||||
- _connect_ 方法
|
||||
|
||||
用于生成taos.TDengineConnection的实例。
|
||||
|
||||
|
@ -800,7 +800,7 @@ go env -w GOPROXY=https://goproxy.io,direct
|
|||
|
||||
- `sql.Open(DRIVER_NAME string, dataSourceName string) *DB`
|
||||
|
||||
该API用来打开DB,返回一个类型为*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine
|
||||
该API用来打开DB,返回一个类型为\*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine
|
||||
|
||||
**注意**: 该API成功创建的时候,并没有做权限等检查,只有在真正执行Query或者Exec的时候才能真正的去创建连接,并同时检查user/password/host/port是不是合法。 另外,由于整个驱动程序大部分实现都下沉到taosSql所依赖的libtaos中。所以,sql.Open本身特别轻量。
|
||||
|
||||
|
@ -822,7 +822,7 @@ go env -w GOPROXY=https://goproxy.io,direct
|
|||
|
||||
- `func (s *Stmt) Query(args ...interface{}) (*Rows, error)`
|
||||
|
||||
sql.Open内置的方法,Query executes a prepared query statement with the given arguments and returns the query results as a *Rows.
|
||||
sql.Open内置的方法,Query executes a prepared query statement with the given arguments and returns the query results as a \*Rows.
|
||||
|
||||
- `func (s *Stmt) Close() error`
|
||||
|
||||
|
@ -894,7 +894,7 @@ Node-example-raw.js
|
|||
|
||||
验证方法:
|
||||
|
||||
1. 新建安装验证目录,例如:~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。
|
||||
1. 新建安装验证目录,例如:\~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。
|
||||
|
||||
2. 在命令中执行以下命令:
|
||||
|
||||
|
|
|
@ -72,9 +72,6 @@
|
|||
# time interval of heart beat from shell to dnode, seconds
|
||||
# shellActivityTimer 3
|
||||
|
||||
# time of keeping table meta data in cache, seconds
|
||||
# tableMetaKeepTimer 7200
|
||||
|
||||
# minimum sliding window time, milli-second
|
||||
# minSlidingTime 10
|
||||
|
||||
|
@ -162,10 +159,10 @@
|
|||
# stop writing logs when the disk size of the log folder is less than this value
|
||||
# minimalLogDirGB 0.1
|
||||
|
||||
# stop writing temporary files when the disk size of the log folder is less than this value
|
||||
# stop writing temporary files when the disk size of the tmp folder is less than this value
|
||||
# minimalTmpDirGB 0.1
|
||||
|
||||
# stop writing data when the disk size of the log folder is less than this value
|
||||
# if disk free space is less than this value, taosd service exit directly within startup process
|
||||
# minimalDataDirGB 0.1
|
||||
|
||||
# One mnode is equal to the number of vnode consumed
|
||||
|
|
|
@ -348,7 +348,7 @@ function set_ipAsFqdn() {
|
|||
}
|
||||
|
||||
function local_fqdn_check() {
|
||||
#serverFqdn=$(hostname -f)
|
||||
#serverFqdn=$(hostname)
|
||||
echo
|
||||
echo -e -n "System hostname is: ${GREEN}$serverFqdn${NC}"
|
||||
echo
|
||||
|
@ -911,7 +911,7 @@ function install_TDengine() {
|
|||
|
||||
|
||||
## ==============================Main program starts from here============================
|
||||
serverFqdn=$(hostname -f)
|
||||
serverFqdn=$(hostname)
|
||||
if [ "$verType" == "server" ]; then
|
||||
# Install server and client
|
||||
if [ -x ${bin_dir}/taosd ]; then
|
||||
|
|
|
@ -345,7 +345,7 @@ function set_ipAsFqdn() {
|
|||
}
|
||||
|
||||
function local_fqdn_check() {
|
||||
#serverFqdn=$(hostname -f)
|
||||
#serverFqdn=$(hostname)
|
||||
echo
|
||||
echo -e -n "System hostname is: ${GREEN}$serverFqdn${NC}"
|
||||
echo
|
||||
|
@ -881,7 +881,7 @@ function install_PowerDB() {
|
|||
|
||||
|
||||
## ==============================Main program starts from here============================
|
||||
serverFqdn=$(hostname -f)
|
||||
serverFqdn=$(hostname)
|
||||
if [ "$verType" == "server" ]; then
|
||||
# Install server and client
|
||||
if [ -x ${bin_dir}/powerd ]; then
|
||||
|
|
|
@ -228,7 +228,7 @@ function set_ipAsFqdn() {
|
|||
}
|
||||
|
||||
function local_fqdn_check() {
|
||||
#serverFqdn=$(hostname -f)
|
||||
#serverFqdn=$(hostname)
|
||||
echo
|
||||
echo -e -n "System hostname is: ${GREEN}$serverFqdn${NC}"
|
||||
echo
|
||||
|
@ -492,5 +492,5 @@ function install_TDengine() {
|
|||
|
||||
|
||||
## ==============================Main program starts from here============================
|
||||
serverFqdn=$(hostname -f)
|
||||
serverFqdn=$(hostname)
|
||||
install_TDengine
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
version: '2.0.13.0'
|
||||
version: '2.0.14.0'
|
||||
icon: snap/gui/t-dengine.svg
|
||||
summary: an open-source big data platform designed and optimized for IoT.
|
||||
description: |
|
||||
|
@ -72,7 +72,7 @@ parts:
|
|||
- usr/bin/taosd
|
||||
- usr/bin/taos
|
||||
- usr/bin/taosdemo
|
||||
- usr/lib/libtaos.so.2.0.13.0
|
||||
- usr/lib/libtaos.so.2.0.14.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
# Base compile
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc)
|
||||
|
|
|
@ -237,21 +237,21 @@ static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
|||
bool isReady = false;
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SVnodeGid *pVnode = pVgroup->vnodeGid + i;
|
||||
SDnodeObj *pDnode = pVnode->pDnode;
|
||||
if (pVnode == pRmVnode) continue;
|
||||
int32_t vver = mnodeGetVgidVer(pVnode->vver);
|
||||
|
||||
mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d, rmvver:%d" , pVgroup->vgId, i,
|
||||
pVnode->dnodeId, dnodeStatus[pVnode->pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||
if (pVnode->pDnode->status == TAOS_DN_STATUS_DROPPING) continue;
|
||||
if (pVnode->pDnode->status == TAOS_DN_STATUS_OFFLINE) continue;
|
||||
mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d, rmvver:%d", pVgroup->vgId, i,
|
||||
pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING) continue;
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) continue;
|
||||
if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) continue;
|
||||
|
||||
if (rmVnodeVer == 0 || vver >= rmVnodeVer) {
|
||||
mInfo("vgId:%d, is ready for vindex:%d in dnode:%d status:%s role:%s vver:%d larger than rmvver:%d", pVgroup->vgId, i,
|
||||
pVnode->dnodeId, dnodeStatus[pVnode->pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||
mInfo("vgId:%d, is ready for vindex:%d in dnode:%d status:%s role:%s vver:%d larger than rmvver:%d",
|
||||
pVgroup->vgId, i, pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
return isReady;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
|
|
@ -43,6 +43,11 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql);
|
|||
|
||||
char *getArithmeticInputSrc(void *param, const char *name, int32_t colId);
|
||||
|
||||
void tscLockByThread(int64_t *lockedBy);
|
||||
|
||||
void tscUnlockByThread(int64_t *lockedBy);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @date 2018/09/30
|
||||
*/
|
||||
#include "exception.h"
|
||||
#include "os.h"
|
||||
#include "qExtbuffer.h"
|
||||
|
@ -216,7 +213,7 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
|||
SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex);
|
||||
SQueryInfo *tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex);
|
||||
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache);
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
||||
|
||||
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
||||
SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables);
|
||||
|
@ -276,7 +273,7 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex);
|
|||
bool hasMoreVnodesToTry(SSqlObj *pSql);
|
||||
bool hasMoreClauseToTry(SSqlObj* pSql);
|
||||
|
||||
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache);
|
||||
void tscFreeQueryInfo(SSqlCmd* pCmd);
|
||||
|
||||
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
||||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||
|
@ -290,6 +287,14 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
char* serializeTagData(STagData* pTagData, char* pMsg);
|
||||
int32_t copyTagData(STagData* dst, const STagData* src);
|
||||
|
||||
STableMeta* createSuperTableMeta(STableMetaMsg* pChild);
|
||||
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta);
|
||||
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
||||
uint32_t tscGetTableMetaMaxSize();
|
||||
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name);
|
||||
STableMeta* tscTableMetaClone(STableMeta* pTableMeta);
|
||||
|
||||
|
||||
void* malloc_throw(size_t size);
|
||||
void* calloc_throw(size_t nmemb, size_t size);
|
||||
char* strdup_throw(const char* str);
|
||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
|
||||
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
||||
|
||||
//struct SSchema;
|
||||
#define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS)
|
||||
|
||||
/**
|
||||
* get the number of tags of this table
|
||||
|
@ -91,7 +91,7 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
|
|||
* @param numOfCols
|
||||
* @return
|
||||
*/
|
||||
bool isValidSchema(struct SSchema *pSchema, int32_t numOfCols);
|
||||
bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTags);
|
||||
|
||||
/**
|
||||
* get the schema for the "tbname" column. it is a built column
|
||||
|
@ -105,7 +105,10 @@ SSchema tscGetTbnameColumnSchema();
|
|||
* @param size size of the table meta
|
||||
* @return
|
||||
*/
|
||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size);
|
||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg);
|
||||
|
||||
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src);
|
||||
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -56,23 +56,28 @@ typedef struct STableComInfo {
|
|||
int32_t rowSize;
|
||||
} STableComInfo;
|
||||
|
||||
typedef struct SCorVgroupInfo {
|
||||
int32_t version;
|
||||
int8_t inUse;
|
||||
int8_t numOfEps;
|
||||
SEpAddr1 epAddr[TSDB_MAX_REPLICA];
|
||||
} SCorVgroupInfo;
|
||||
typedef struct SNewVgroupInfo {
|
||||
int32_t vgId;
|
||||
int8_t inUse;
|
||||
int8_t numOfEps;
|
||||
SEpAddrMsg ep[TSDB_MAX_REPLICA];
|
||||
} SNewVgroupInfo;
|
||||
|
||||
typedef struct CChildTableMeta {
|
||||
int32_t vgId;
|
||||
STableId id;
|
||||
uint8_t tableType;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||
} CChildTableMeta;
|
||||
|
||||
typedef struct STableMeta {
|
||||
STableComInfo tableInfo;
|
||||
int32_t vgId;
|
||||
STableId id;
|
||||
uint8_t tableType;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||
int16_t sversion;
|
||||
int16_t tversion;
|
||||
char sTableId[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t vgId;
|
||||
SCorVgroupInfo corVgroupInfo;
|
||||
STableId id;
|
||||
// union {int64_t stableUid; SSchema* schema;};
|
||||
STableComInfo tableInfo;
|
||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||
} STableMeta;
|
||||
|
||||
|
@ -171,7 +176,7 @@ typedef struct SParamInfo {
|
|||
} SParamInfo;
|
||||
|
||||
typedef struct STableDataBlocks {
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char tableName[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||
bool ordered; // if current rows are ordered or not
|
||||
int64_t vgId; // virtual group id
|
||||
|
@ -249,7 +254,7 @@ typedef struct {
|
|||
int8_t submitSchema; // submit block is built with table schema
|
||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||
|
||||
STableMeta **pTableMetaList; // all involved tableMeta list of current insert sql statement.
|
||||
char **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||
int32_t numOfTables;
|
||||
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
|
@ -295,8 +300,8 @@ typedef struct STscObj {
|
|||
void * pTimer;
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char acctId[TSDB_ACCT_LEN];
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char acctId[TSDB_ACCT_ID_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
char sversion[TSDB_VERSION_LEN];
|
||||
char writeAuth : 1;
|
||||
char superAuth : 1;
|
||||
|
@ -342,6 +347,11 @@ typedef struct SSqlObj {
|
|||
SSubqueryState subState;
|
||||
struct SSqlObj **pSubs;
|
||||
|
||||
int64_t metaRid;
|
||||
int64_t svgroupRid;
|
||||
|
||||
int64_t squeryLock;
|
||||
|
||||
struct SSqlObj *prev, *next;
|
||||
int64_t self;
|
||||
} SSqlObj;
|
||||
|
@ -386,7 +396,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet);
|
|||
int tscProcessSql(SSqlObj *pSql);
|
||||
|
||||
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex);
|
||||
void tscQueueAsyncRes(SSqlObj *pSql);
|
||||
void tscAsyncResultOnError(SSqlObj *pSql);
|
||||
|
||||
void tscQueueAsyncError(void(*fp), void *param, int32_t code);
|
||||
|
||||
|
@ -400,7 +410,7 @@ void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
|
|||
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||
|
||||
void tscResetSqlCmdObj(SSqlCmd *pCmd, bool removeFromCache);
|
||||
void tscResetSqlCmdObj(SSqlCmd *pCmd);
|
||||
|
||||
/**
|
||||
* free query result of the sql object
|
||||
|
@ -414,7 +424,6 @@ void tscFreeSqlResult(SSqlObj *pSql);
|
|||
*/
|
||||
void tscFreeSqlObj(SSqlObj *pSql);
|
||||
void tscFreeRegisteredSqlObj(void *pSql);
|
||||
void tscFreeTableMetaHelper(void *pTableMeta);
|
||||
|
||||
void tscCloseTscObj(void *pObj);
|
||||
|
||||
|
@ -456,7 +465,7 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
|||
} else {
|
||||
assert(bytes == tDataTypeDesc[type].nSize);
|
||||
|
||||
pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)&pInfo->pSqlExpr->param[1].i64Key;
|
||||
pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)&pInfo->pSqlExpr->param[1].i64;
|
||||
pRes->length[columnIndex] = bytes;
|
||||
}
|
||||
} else {
|
||||
|
@ -479,7 +488,9 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
|||
}
|
||||
}
|
||||
|
||||
extern SCacheObj *tscMetaCache;
|
||||
extern int32_t sentinel;
|
||||
extern SHashObj *tscVgroupMap;
|
||||
extern SHashObj *tscTableMetaInfo;
|
||||
|
||||
extern int tscObjRef;
|
||||
extern void *tscTmr;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "tnote.h"
|
||||
#include "trpc.h"
|
||||
#include "tcache.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscSubquery.h"
|
||||
#include "tscLocalMerge.h"
|
||||
|
@ -57,7 +56,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
if (pSql->sqlstr == NULL) {
|
||||
tscError("%p failed to malloc sql string buffer", pSql);
|
||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,7 +70,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pSql->res.code = code;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -96,7 +95,7 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa
|
|||
return;
|
||||
}
|
||||
|
||||
nPrintTsc(sqlstr);
|
||||
nPrintTsc("%s", sqlstr);
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
|
@ -166,7 +165,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
|
|||
pRes->code = numOfRows;
|
||||
}
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -217,7 +216,7 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) {
|
|||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||
pSql->param = param;
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -280,7 +279,7 @@ void taos_fetch_row_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, TAOS_ROW),
|
|||
pSql->param = param;
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -366,7 +365,7 @@ static void tscProcessAsyncError(SSchedMsg *pMsg) {
|
|||
void (*fp)() = pMsg->ahandle;
|
||||
terrno = *(int32_t*) pMsg->msg;
|
||||
tfree(pMsg->msg);
|
||||
(*fp)(pMsg->thandle, NULL, *(int32_t*)pMsg->msg);
|
||||
(*fp)(pMsg->thandle, NULL, terrno);
|
||||
}
|
||||
|
||||
void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
|
||||
|
@ -382,14 +381,14 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
|
|||
}
|
||||
|
||||
|
||||
void tscQueueAsyncRes(SSqlObj *pSql) {
|
||||
void tscAsyncResultOnError(SSqlObj *pSql) {
|
||||
if (pSql == NULL || pSql->signature != pSql) {
|
||||
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pSql->res.code != TSDB_CODE_SUCCESS);
|
||||
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
||||
tscError("%p invoke user specified function due to error occured, code:%s", pSql, tstrerror(pSql->res.code));
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
if (pSql->fp == NULL || pSql->fetchFp == NULL){
|
||||
|
@ -403,8 +402,10 @@ void tscQueueAsyncRes(SSqlObj *pSql) {
|
|||
int tscSendMsgToServer(SSqlObj *pSql);
|
||||
|
||||
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||
SSqlObj *pSql = (SSqlObj *)param;
|
||||
if (pSql == NULL || pSql->signature != pSql) return;
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
|
||||
if (pSql == NULL) return;
|
||||
|
||||
assert(pSql->signature == pSql && (int64_t)param == pSql->self);
|
||||
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
@ -422,14 +423,15 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
// 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_TAG_FILTER_QUERY))) {
|
||||
tscDebug("%p update table meta in local cache, continue to process sql and send the corresponding query", pSql);
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 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) {
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -437,16 +439,18 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
// tscProcessSql can add error into async res
|
||||
tscProcessSql(pSql);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else { // continue to process normal async query
|
||||
if (pCmd->parseFinished) {
|
||||
tscDebug("%p update table meta in local cache, continue to process sql and send corresponding query", pSql);
|
||||
tscDebug("%p update local table meta, continue to process sql and send corresponding query", pSql);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -455,10 +459,11 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
if (pCmd->command == TSDB_SQL_SELECT) {
|
||||
tscDebug("%p redo parse sql string and proceed", pSql);
|
||||
pCmd->parseFinished = false;
|
||||
tscResetSqlCmdObj(pCmd, false);
|
||||
tscResetSqlCmdObj(pCmd);
|
||||
|
||||
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;
|
||||
|
@ -469,12 +474,14 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
tscProcessSql(pSql);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else {
|
||||
tscDebug("%p continue parse sql after get table meta", pSql);
|
||||
|
||||
code = tsParseSql(pSql, false);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
|
@ -484,12 +491,14 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
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 {
|
||||
assert(code == TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -502,6 +511,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
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;
|
||||
|
@ -510,6 +520,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
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;
|
||||
|
@ -522,16 +533,23 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
tscDoQuery(pSql);
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
return;
|
||||
|
||||
_error:
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pSql->res.code = code;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "taosmsg.h"
|
||||
|
||||
#include "taosdef.h"
|
||||
#include "tcache.h"
|
||||
#include "tname.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscUtil.h"
|
||||
|
@ -205,7 +204,7 @@ static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
|||
assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
|
||||
|
||||
const int32_t NUM_OF_DESC_TABLE_COLUMNS = 4;
|
||||
const int32_t TYPE_COLUMN_LENGTH = 16;
|
||||
const int32_t TYPE_COLUMN_LENGTH = 20;
|
||||
const int32_t NOTE_COLUMN_MIN_LENGTH = 8;
|
||||
|
||||
int32_t noteFieldLen = NOTE_COLUMN_MIN_LENGTH;
|
||||
|
@ -273,7 +272,7 @@ void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
|
|||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
taos_free_result(pSql);
|
||||
free(builder);
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -291,7 +290,7 @@ void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
|
|||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
(*pParentSql->fp)(pParentSql->param, pParentSql, code);
|
||||
} else {
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -571,7 +570,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch
|
|||
|
||||
char fullName[TSDB_TABLE_FNAME_LEN * 2] = {0};
|
||||
extractDBName(pTableMetaInfo->name, fullName);
|
||||
extractTableName(pMeta->sTableId, param->sTableName);
|
||||
extractTableName(pMeta->sTableName, param->sTableName);
|
||||
snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName), ".%s", param->sTableName);
|
||||
extractTableName(pTableMetaInfo->name, param->buf);
|
||||
|
||||
|
@ -901,7 +900,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
||||
pRes->code = tscProcessShowCreateDatabase(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
||||
taosCacheEmpty(tscMetaCache);
|
||||
taosHashEmpty(tscTableMetaInfo);
|
||||
pRes->code = TSDB_CODE_SUCCESS;
|
||||
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
||||
pRes->code = tscProcessServerVer(pSql);
|
||||
|
@ -925,7 +924,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -89,17 +89,17 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
|
|||
pCtx->startOffset = 0;
|
||||
pCtx->size = 1;
|
||||
pCtx->hasNull = true;
|
||||
pCtx->currentStage = SECONDARY_STAGE_MERGE;
|
||||
pCtx->currentStage = MERGE_STAGE;
|
||||
|
||||
// for top/bottom function, the output of timestamp is the first column
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
||||
pCtx->ptsOutputBuf = pReducer->pCtx[0].aOutputBuf;
|
||||
pCtx->param[2].i64Key = pQueryInfo->order.order;
|
||||
pCtx->param[2].i64 = pQueryInfo->order.order;
|
||||
pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
||||
pCtx->param[1].i64Key = pQueryInfo->order.orderColId;
|
||||
pCtx->param[1].i64 = pQueryInfo->order.orderColId;
|
||||
} else if (functionId == TSDB_FUNC_APERCT) {
|
||||
pCtx->param[0].i64Key = pExpr->param[0].i64Key;
|
||||
pCtx->param[0].i64 = pExpr->param[0].i64;
|
||||
pCtx->param[0].nType = pExpr->param[0].nType;
|
||||
}
|
||||
|
||||
|
@ -1064,10 +1064,10 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
|
|||
}
|
||||
} else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j);
|
||||
pCtx->param[0].i64Key = pExpr->param[0].i64Key;
|
||||
pCtx->param[0].i64 = pExpr->param[0].i64;
|
||||
}
|
||||
|
||||
pCtx->currentStage = SECONDARY_STAGE_MERGE;
|
||||
pCtx->currentStage = MERGE_STAGE;
|
||||
|
||||
if (needInit) {
|
||||
aAggs[pCtx->functionId].init(pCtx);
|
||||
|
@ -1080,7 +1080,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
|
|||
continue;
|
||||
}
|
||||
|
||||
aAggs[functionId].distSecondaryMergeFunc(&pLocalReducer->pCtx[j]);
|
||||
aAggs[functionId].mergeFunc(&pLocalReducer->pCtx[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1647,7 +1647,7 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
// calculate the result from several other columns
|
||||
if (pSup->pArithExprInfo != NULL) {
|
||||
arithSup.pArithExpr = pSup->pArithExprInfo;
|
||||
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
||||
arithmeticTreeTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
||||
} else {
|
||||
SSqlExpr* pExpr = pSup->pSqlExpr;
|
||||
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num));
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "os.h"
|
||||
|
||||
#include "ttype.h"
|
||||
#include "hash.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
|
@ -40,46 +41,9 @@ enum {
|
|||
|
||||
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int32_t * numOfRows);
|
||||
|
||||
static int32_t tscToInteger(SStrToken *pToken, int64_t *value, char **endPtr) {
|
||||
if (pToken->n == 0) {
|
||||
return TK_ILLEGAL;
|
||||
}
|
||||
|
||||
|
||||
int32_t radix = 10;
|
||||
if (pToken->type == TK_HEX) {
|
||||
radix = 16;
|
||||
} else if (pToken->type == TK_BIN) {
|
||||
radix = 2;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
*value = strtoll(pToken->z, endPtr, radix);
|
||||
if (**endPtr == 'e' || **endPtr == 'E' || **endPtr == '.') {
|
||||
errno = 0;
|
||||
double v = round(strtod(pToken->z, endPtr));
|
||||
if (v > INT64_MAX || v <= INT64_MIN) {
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
*value = (int64_t)v;
|
||||
}
|
||||
}
|
||||
|
||||
// not a valid integer number, return error
|
||||
if (*endPtr - pToken->z != pToken->n) {
|
||||
return TK_ILLEGAL;
|
||||
}
|
||||
|
||||
return pToken->type;
|
||||
}
|
||||
|
||||
static int32_t tscToDouble(SStrToken *pToken, double *value, char **endPtr) {
|
||||
if (pToken->n == 0) {
|
||||
return TK_ILLEGAL;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
*value = strtod(pToken->z, endPtr);
|
||||
*value = strtold(pToken->z, endPtr);
|
||||
|
||||
// not a valid integer number, return error
|
||||
if ((*endPtr - pToken->z) != pToken->n) {
|
||||
|
@ -163,86 +127,119 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// todo extract the null value check
|
||||
static bool isNullStr(SStrToken* pToken) {
|
||||
return (pToken->type == TK_NULL) || ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0));
|
||||
}
|
||||
int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload, char *msg, char **str, bool primaryKey,
|
||||
int16_t timePrec) {
|
||||
int64_t iv;
|
||||
int32_t numType;
|
||||
char * endptr = NULL;
|
||||
errno = 0; // clear the previous existed error information
|
||||
int32_t ret;
|
||||
char *endptr = NULL;
|
||||
|
||||
if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid numeric data", pToken->z);
|
||||
}
|
||||
|
||||
switch (pSchema->type) {
|
||||
case TSDB_DATA_TYPE_BOOL: { // bool
|
||||
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
|
||||
if (strncmp(pToken->z, "true", pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_TRUE;
|
||||
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_FALSE;
|
||||
} else if (strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_DATA_BOOL_NULL;
|
||||
} else {
|
||||
return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z);
|
||||
}
|
||||
} else if (pToken->type == TK_INTEGER) {
|
||||
iv = strtoll(pToken->z, NULL, 10);
|
||||
*(uint8_t *)payload = (int8_t)((iv == 0) ? TSDB_FALSE : TSDB_TRUE);
|
||||
} else if (pToken->type == TK_FLOAT) {
|
||||
double dv = strtod(pToken->z, NULL);
|
||||
*(uint8_t *)payload = (int8_t)((dv == 0) ? TSDB_FALSE : TSDB_TRUE);
|
||||
} else if (pToken->type == TK_NULL) {
|
||||
*(uint8_t *)payload = TSDB_DATA_BOOL_NULL;
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint8_t *)payload) = TSDB_DATA_BOOL_NULL;
|
||||
} else {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bool data", pToken->z);
|
||||
if ((pToken->type == TK_BOOL || pToken->type == TK_STRING) && (pToken->n != 0)) {
|
||||
if (strncmp(pToken->z, "true", pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_TRUE;
|
||||
} else if (strncmp(pToken->z, "false", pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_FALSE;
|
||||
} else {
|
||||
return tscSQLSyntaxErrMsg(msg, "invalid bool data", pToken->z);
|
||||
}
|
||||
} else if (pToken->type == TK_INTEGER) {
|
||||
iv = strtoll(pToken->z, NULL, 10);
|
||||
*(uint8_t *)payload = (int8_t)((iv == 0) ? TSDB_FALSE : TSDB_TRUE);
|
||||
} else if (pToken->type == TK_FLOAT) {
|
||||
double dv = strtod(pToken->z, NULL);
|
||||
*(uint8_t *)payload = (int8_t)((dv == 0) ? TSDB_FALSE : TSDB_TRUE);
|
||||
} else {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bool data", pToken->z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int8_t *)payload) = TSDB_DATA_TINYINT_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
*((int8_t *)payload) = TSDB_DATA_TINYINT_NULL;
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint8_t *)payload) = TSDB_DATA_TINYINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (TK_ILLEGAL == numType) {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid tinyint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT8_MAX || iv <= INT8_MIN) {
|
||||
return tscInvalidSQLErrMsg(msg, "tinyint data overflow", pToken->z);
|
||||
} else if (!IS_VALID_TINYINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int8_t *)payload) = (int8_t)iv;
|
||||
*((uint8_t *)payload) = (uint8_t)iv;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint8_t *)payload) = TSDB_DATA_UTINYINT_NULL;
|
||||
} else {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid unsigned tinyint data", pToken->z);
|
||||
} else if (!IS_VALID_UTINYINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "unsigned tinyint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((uint8_t *)payload) = (uint8_t)iv;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int16_t *)payload) = TSDB_DATA_SMALLINT_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
if (isNullStr(pToken)) {
|
||||
*((int16_t *)payload) = TSDB_DATA_SMALLINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (TK_ILLEGAL == numType) {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid smallint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT16_MAX || iv <= INT16_MIN) {
|
||||
} else if (!IS_VALID_SMALLINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "smallint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int16_t *)payload) = (int16_t)iv;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint16_t *)payload) = TSDB_DATA_USMALLINT_NULL;
|
||||
} else {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid unsigned smallint data", pToken->z);
|
||||
} else if (!IS_VALID_USMALLINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "unsigned smallint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((uint16_t *)payload) = (uint16_t)iv;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int32_t *)payload) = TSDB_DATA_INT_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
if (isNullStr(pToken)) {
|
||||
*((int32_t *)payload) = TSDB_DATA_INT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (TK_ILLEGAL == numType) {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid int data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT32_MAX || iv <= INT32_MIN) {
|
||||
} else if (!IS_VALID_INT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "int data overflow", pToken->z);
|
||||
}
|
||||
|
||||
|
@ -251,17 +248,30 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
|
|||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint32_t *)payload) = TSDB_DATA_UINT_NULL;
|
||||
} else {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid unsigned int data", pToken->z);
|
||||
} else if (!IS_VALID_UINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "unsigned int data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((uint32_t *)payload) = (uint32_t)iv;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int64_t *)payload) = TSDB_DATA_BIGINT_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
if (isNullStr(pToken)) {
|
||||
*((int64_t *)payload) = TSDB_DATA_BIGINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (TK_ILLEGAL == numType) {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, true);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bigint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv == INT64_MIN) {
|
||||
} else if (!IS_VALID_BIGINT(iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "bigint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
|
@ -269,11 +279,23 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
|
|||
}
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
if (isNullStr(pToken)) {
|
||||
*((uint64_t *)payload) = TSDB_DATA_UBIGINT_NULL;
|
||||
} else {
|
||||
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid unsigned bigint data", pToken->z);
|
||||
} else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "unsigned bigint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((uint64_t *)payload) = iv;
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int32_t *)payload) = TSDB_DATA_FLOAT_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
if (isNullStr(pToken)) {
|
||||
*((int32_t *)payload) = TSDB_DATA_FLOAT_NULL;
|
||||
} else {
|
||||
double dv;
|
||||
|
@ -281,24 +303,16 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
|
|||
return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z);
|
||||
}
|
||||
|
||||
float fv = (float)dv;
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || (fv > FLT_MAX || fv < -FLT_MAX)) {
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z);
|
||||
}
|
||||
|
||||
if (isinf(fv) || isnan(fv)) {
|
||||
*((int32_t *)payload) = TSDB_DATA_FLOAT_NULL;
|
||||
}
|
||||
|
||||
*((float *)payload) = fv;
|
||||
*((float *)payload) = (float)dv;
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
if (pToken->type == TK_NULL) {
|
||||
*((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL;
|
||||
} else if ((pToken->type == TK_STRING) && (pToken->n != 0) &&
|
||||
(strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0)) {
|
||||
if (isNullStr(pToken)) {
|
||||
*((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL;
|
||||
} else {
|
||||
double dv;
|
||||
|
@ -306,15 +320,11 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
|
|||
return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z);
|
||||
}
|
||||
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || (dv > DBL_MAX || dv < -DBL_MAX)) {
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
||||
return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z);
|
||||
}
|
||||
|
||||
if (isinf(dv) || isnan(dv)) {
|
||||
*((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL;
|
||||
} else {
|
||||
*((double *)payload) = dv;
|
||||
}
|
||||
*((double *)payload) = dv;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -337,7 +347,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SStrToken *pToken, char *payload,
|
|||
setVardataNull(payload, TSDB_DATA_TYPE_NCHAR);
|
||||
} else {
|
||||
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
||||
size_t output = 0;
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(pToken->z, pToken->n, varDataVal(payload), pSchema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||
char buf[512] = {0};
|
||||
snprintf(buf, tListLen(buf), "%s", strerror(errno));
|
||||
|
@ -752,6 +762,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
|
||||
char *sql = *sqlstr;
|
||||
|
||||
pSql->cmd.autoCreated = false;
|
||||
|
||||
// get the token of specified table
|
||||
index = 0;
|
||||
tableToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
|
@ -935,11 +947,15 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
|
||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||
if (row == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL);
|
||||
}
|
||||
tdSortKVRowByColIdx(row);
|
||||
|
||||
pCmd->tagData.dataLen = kvRowLen(row);
|
||||
if (pCmd->tagData.dataLen <= 0){
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL);
|
||||
}
|
||||
|
||||
char* pTag = realloc(pCmd->tagData.data, pCmd->tagData.dataLen);
|
||||
if (pTag == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1339,7 +1355,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
if (sqlstr == NULL || pSql->parseRetry >= 1 || ret != TSDB_CODE_TSC_INVALID_SQL) {
|
||||
free(sqlstr);
|
||||
} else {
|
||||
tscResetSqlCmdObj(pCmd, true);
|
||||
tscResetSqlCmdObj(pCmd);
|
||||
free(pSql->sqlstr);
|
||||
pSql->sqlstr = sqlstr;
|
||||
pSql->parseRetry++;
|
||||
|
@ -1351,7 +1367,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
|||
SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr);
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
|
||||
tscResetSqlCmdObj(pCmd, true);
|
||||
tscResetSqlCmdObj(pCmd);
|
||||
pSql->parseRetry++;
|
||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||
}
|
||||
|
@ -1429,7 +1445,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
|||
fclose(fp);
|
||||
|
||||
pParentSql->res.code = code;
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
|
@ -1451,7 +1467,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
|||
int32_t count = 0;
|
||||
int32_t maxRows = 0;
|
||||
|
||||
tfree(pCmd->pTableMetaList);
|
||||
tfree(pCmd->pTableNameList);
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
if (pCmd->pTableBlockHashList == NULL) {
|
||||
|
@ -1500,7 +1516,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
|||
code = doPackSendDataBlock(pSql, count, pTableDataBlock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = code;
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1535,7 +1551,7 @@ void tscProcessMultiVnodesImportFromFile(SSqlObj *pSql) {
|
|||
tscError("%p failed to open file %s to load data from file, code:%s", pSql, pCmd->payload, tstrerror(pSql->res.code));
|
||||
|
||||
tfree(pSupporter);
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -84,35 +84,35 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
|||
var->nLen = 0;
|
||||
if (tb->is_null != NULL && *(tb->is_null)) {
|
||||
var->nType = TSDB_DATA_TYPE_NULL;
|
||||
var->i64Key = 0;
|
||||
var->i64 = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
var->nType = tb->buffer_type;
|
||||
switch (tb->buffer_type) {
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
var->i64Key = 0;
|
||||
var->i64 = 0;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
var->i64Key = (*(int8_t*)tb->buffer) ? 1 : 0;
|
||||
var->i64 = (*(int8_t*)tb->buffer) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
var->i64Key = *(int8_t*)tb->buffer;
|
||||
var->i64 = *(int8_t*)tb->buffer;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
var->i64Key = *(int16_t*)tb->buffer;
|
||||
var->i64 = *(int16_t*)tb->buffer;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
var->i64Key = *(int32_t*)tb->buffer;
|
||||
var->i64 = *(int32_t*)tb->buffer;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
var->i64Key = *(int64_t*)tb->buffer;
|
||||
var->i64 = *(int64_t*)tb->buffer;
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
|
@ -219,7 +219,7 @@ static char* normalStmtBuildSql(STscStmt* stmt) {
|
|||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
taosStringBuilderAppendInteger(&sb, var->i64Key);
|
||||
taosStringBuilderAppendInteger(&sb, var->i64);
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
|
@ -616,7 +616,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
size_t output = 0;
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
@ -678,7 +678,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
size_t output = 0;
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(bind->buffer, *bind->length, varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define _GNU_SOURCE
|
||||
|
||||
#include "os.h"
|
||||
#include "ttype.h"
|
||||
#include "qAst.h"
|
||||
#include "taos.h"
|
||||
#include "taosmsg.h"
|
||||
|
@ -75,11 +76,11 @@ static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SC
|
|||
static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
|
||||
static uint8_t convertOptr(SStrToken *pToken);
|
||||
|
||||
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery);
|
||||
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery);
|
||||
|
||||
static bool validateIpAddress(const char* ip, size_t size);
|
||||
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery);
|
||||
|
||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
||||
|
||||
|
@ -220,7 +221,7 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) {
|
|||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if (pPwd->n >= TSDB_PASSWORD_LEN) {
|
||||
if (pPwd->n >= TSDB_KEY_LEN) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
|
@ -484,10 +485,10 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
|
||||
case TSDB_SQL_CREATE_USER:
|
||||
case TSDB_SQL_ALTER_USER: {
|
||||
const char* msg5 = "invalid user rights";
|
||||
const char* msg7 = "not support options";
|
||||
const char* msg2 = "invalid user/account name";
|
||||
const char* msg3 = "name too long";
|
||||
const char* msg5 = "invalid user rights";
|
||||
const char* msg7 = "not support options";
|
||||
|
||||
pCmd->command = pInfo->type;
|
||||
|
||||
|
@ -910,7 +911,7 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableNa
|
|||
* that are corresponding to the old name for the new table name.
|
||||
*/
|
||||
if (strlen(oldName) > 0 && strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
|
||||
tscClearTableMetaInfo(pTableMetaInfo, false);
|
||||
tscClearTableMetaInfo(pTableMetaInfo);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -950,7 +951,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (pField->type < TSDB_DATA_TYPE_BOOL || pField->type > TSDB_DATA_TYPE_NCHAR) {
|
||||
if (!isValidDataType(pField->type)) {
|
||||
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
return false;
|
||||
}
|
||||
|
@ -1011,7 +1012,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC
|
|||
return false;
|
||||
}
|
||||
|
||||
if (p->type < TSDB_DATA_TYPE_BOOL || p->type > TSDB_DATA_TYPE_NCHAR) {
|
||||
if (!isValidDataType(p->type)) {
|
||||
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||
return false;
|
||||
}
|
||||
|
@ -1241,7 +1242,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr
|
|||
|
||||
/* db name is not specified, the tableName dose not include db name */
|
||||
if (pDB != NULL) {
|
||||
if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
|
||||
if (pDB->n >= TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1476,7 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) {
|
|||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||
}
|
||||
|
||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery) {
|
||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery) {
|
||||
assert(pSelection != NULL && pCmd != NULL);
|
||||
|
||||
const char* msg2 = "functions can not be mixed up";
|
||||
|
@ -1531,7 +1532,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
|||
addPrimaryTsColIntoResult(pQueryInfo);
|
||||
}
|
||||
|
||||
if (!functionCompatibleCheck(pQueryInfo, joinQuery)) {
|
||||
if (!functionCompatibleCheck(pQueryInfo, joinQuery, intervalQuery)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
|
@ -1754,7 +1755,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
|
|||
// set reverse order scan data blocks for last query
|
||||
if (functionID == TSDB_FUNC_LAST) {
|
||||
pExpr->numOfParams = 1;
|
||||
pExpr->param[0].i64Key = TSDB_ORDER_DESC;
|
||||
pExpr->param[0].i64 = TSDB_ORDER_DESC;
|
||||
pExpr->param[0].nType = TSDB_DATA_TYPE_INT;
|
||||
}
|
||||
|
||||
|
@ -1945,7 +1946,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
int16_t colType = pSchema->type;
|
||||
|
||||
if (colType <= TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
|
@ -2105,7 +2106,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { // group by normal columns
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, colIndex + i);
|
||||
pExpr->numOfParams = 1;
|
||||
pExpr->param->i64Key = TSDB_ORDER_ASC;
|
||||
pExpr->param->i64 = TSDB_ORDER_ASC;
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -2182,7 +2183,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
|
||||
// 2. valid the column type
|
||||
int16_t colType = pSchema[index.columnIndex].type;
|
||||
if (colType == TSDB_DATA_TYPE_BOOL || colType >= TSDB_DATA_TYPE_BINARY) {
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
|
@ -2727,7 +2728,7 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo* pQueryInfo) {
|
|||
if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
|
||||
(functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_LAST_DST) ||
|
||||
(functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) {
|
||||
if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64Key, &type, &bytes,
|
||||
if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64, &type, &bytes,
|
||||
&interBytes, 0, true) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
@ -2810,7 +2811,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery) {
|
||||
int32_t startIdx = 0;
|
||||
|
||||
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
@ -2826,6 +2827,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
|||
|
||||
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
|
||||
|
||||
if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// diff function cannot be executed with other function
|
||||
// arithmetic function can be executed with other arithmetic functions
|
||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
@ -2850,7 +2855,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
|||
}
|
||||
}
|
||||
|
||||
if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
|
||||
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -4019,6 +4024,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
|||
if (pExpr->nSQLOptr == TK_LIKE) {
|
||||
char* str = taosStringBuilderGetResult(sb, NULL);
|
||||
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
||||
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4068,6 +4074,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
|||
|
||||
char* str = taosStringBuilderGetResult(&sb1, NULL);
|
||||
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
||||
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
|
||||
|
||||
taosStringBuilderDestroy(&sb1);
|
||||
tfree(segments);
|
||||
|
@ -4390,8 +4397,8 @@ int32_t getTimeRange(STimeWindow* win, tSQLExpr* pRight, int32_t optr, int16_t t
|
|||
*
|
||||
* Additional check to avoid data overflow
|
||||
*/
|
||||
if (pRight->val.i64Key <= INT64_MAX / 1000) {
|
||||
pRight->val.i64Key *= 1000;
|
||||
if (pRight->val.i64 <= INT64_MAX / 1000) {
|
||||
pRight->val.i64 *= 1000;
|
||||
}
|
||||
} else if (pRight->nSQLOptr == TK_FLOAT && timePrecision == TSDB_TIME_PRECISION_MILLI) {
|
||||
pRight->val.dKey *= 1000;
|
||||
|
@ -4592,8 +4599,8 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
|
|||
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
|
||||
const char* msg0 = "only support order by primary timestamp";
|
||||
const char* msg1 = "invalid column name";
|
||||
const char* msg2 = "only support order by primary timestamp or queried column";
|
||||
const char* msg3 = "only support order by primary timestamp or first tag in groupby clause";
|
||||
const char* msg2 = "only support order by primary timestamp or first tag in groupby clause allowed";
|
||||
const char* msg3 = "invalid column in order by clause, only primary timestamp or first tag in groupby clause allowed";
|
||||
|
||||
setDefaultOrderInfo(pQueryInfo);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
@ -5273,8 +5280,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
|||
|
||||
const char* msg0 = "soffset/offset can not be less than 0";
|
||||
const char* msg1 = "slimit/soffset only available for STable query";
|
||||
const char* msg2 = "functions mixed up in table query";
|
||||
const char* msg3 = "slimit/soffset can not apply to projection query";
|
||||
const char* msg2 = "slimit/soffset can not apply to projection query";
|
||||
|
||||
// handle the limit offset value, validate the limit
|
||||
pQueryInfo->limit = pQuerySql->limit;
|
||||
|
@ -5299,7 +5305,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
|||
if (!tscQueryTags(pQueryInfo)) { // local handle the super table tag query
|
||||
if (tscIsProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
if (pQueryInfo->slimit.limit > 0 || pQueryInfo->slimit.offset > 0) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
// for projection query on super table, all queries are subqueries
|
||||
|
@ -5357,24 +5363,6 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
|||
if (pQueryInfo->slimit.limit != -1 || pQueryInfo->slimit.offset != 0) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
size_t size = taosArrayGetSize(pQueryInfo->exprList);
|
||||
|
||||
bool hasTags = false;
|
||||
bool hasOtherFunc = false;
|
||||
// filter the query functions operating on "tbname" column that are not supported by normal columns.
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||
hasTags = true;
|
||||
} else {
|
||||
hasOtherFunc = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTags && hasOtherFunc) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -5393,22 +5381,22 @@ static int32_t setKeepOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* p
|
|||
tVariantListItem* p0 = taosArrayGet(pKeep, 0);
|
||||
switch (s) {
|
||||
case 1: {
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64);
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
tVariantListItem* p1 = taosArrayGet(pKeep, 1);
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
|
||||
pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64Key);
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64);
|
||||
pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
tVariantListItem* p1 = taosArrayGet(pKeep, 1);
|
||||
tVariantListItem* p2 = taosArrayGet(pKeep, 2);
|
||||
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64Key);
|
||||
pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64Key);
|
||||
pMsg->daysToKeep2 = htonl((int32_t)p2->pVar.i64Key);
|
||||
pMsg->daysToKeep = htonl((int32_t)p0->pVar.i64);
|
||||
pMsg->daysToKeep1 = htonl((int32_t)p1->pVar.i64);
|
||||
pMsg->daysToKeep2 = htonl((int32_t)p2->pVar.i64);
|
||||
break;
|
||||
}
|
||||
default: { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); }
|
||||
|
@ -5574,7 +5562,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
|
|||
if ((pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) &&
|
||||
!(pExpr->functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->colInfo.flag))) {
|
||||
SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
|
||||
getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64Key, &pExpr->resType,
|
||||
getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64, &pExpr->resType,
|
||||
&pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable);
|
||||
}
|
||||
}
|
||||
|
@ -5846,14 +5834,43 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) {
|
||||
bool tagProjection = false;
|
||||
bool tableCounting = false;
|
||||
|
||||
int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
int32_t functionId = pExpr->functionId;
|
||||
|
||||
if (functionId == TSDB_FUNC_TAGPRJ) {
|
||||
tagProjection = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (functionId == TSDB_FUNC_COUNT) {
|
||||
assert(pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX);
|
||||
tableCounting = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (tableCounting && tagProjection)? -1:0;
|
||||
}
|
||||
|
||||
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||
const char* msg1 = "functions/columns not allowed in group by query";
|
||||
const char* msg2 = "projection query on columns not allowed";
|
||||
const char* msg3 = "group by not allowed on projection query";
|
||||
const char* msg4 = "retrieve tags not compatible with group by or interval query";
|
||||
const char* msg5 = "functions can not be mixed up";
|
||||
|
||||
// only retrieve tags, group by is not supportted
|
||||
if (tscQueryTags(pQueryInfo)) {
|
||||
if (doTagFunctionCheck(pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||
}
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
} else {
|
||||
|
@ -6005,9 +6022,9 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
|
|||
}
|
||||
|
||||
if (pCreate->quorum != -1 &&
|
||||
(pCreate->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCreate->quorum > TSDB_MAX_DB_REPLICA_OPTION)) {
|
||||
(pCreate->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCreate->quorum > TSDB_MAX_DB_QUORUM_OPTION)) {
|
||||
snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum,
|
||||
TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION);
|
||||
TSDB_MIN_DB_QUORUM_OPTION, TSDB_MAX_DB_QUORUM_OPTION);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg);
|
||||
}
|
||||
|
||||
|
@ -6084,7 +6101,9 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
|
|||
int32_t tmpLen = 0;
|
||||
tmpLen =
|
||||
sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId);
|
||||
if (tmpLen + offset > totalBufSize) break;
|
||||
|
||||
if (tmpLen + offset >= totalBufSize - 1) break;
|
||||
|
||||
|
||||
offset += sprintf(str + offset, "%s", tmpBuf);
|
||||
|
||||
|
@ -6093,7 +6112,9 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
assert(offset < totalBufSize);
|
||||
str[offset] = ']';
|
||||
assert(offset < totalBufSize);
|
||||
tscDebug("%p select clause:%s", pSql, str);
|
||||
}
|
||||
|
||||
|
@ -6276,10 +6297,12 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
|
||||
int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||
const char* msg1 = "invalid table name";
|
||||
const char* msg2 = "functions not allowed in CQ";
|
||||
const char* msg3 = "fill only available for interval query";
|
||||
const char* msg4 = "fill option not supported in stream computing";
|
||||
const char* msg5 = "sql too long"; // todo ADD support
|
||||
const char* msg6 = "from missing in subclause";
|
||||
const char* msg7 = "time interval is required";
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
|
@ -6289,10 +6312,10 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
// if sql specifies db, use it, otherwise use default db
|
||||
SStrToken* pzTableName = &(pCreateTable->name);
|
||||
SStrToken* pName = &(pCreateTable->name);
|
||||
SQuerySQL* pQuerySql = pCreateTable->pSelect;
|
||||
|
||||
if (tscValidateName(pzTableName) != TSDB_CODE_SUCCESS) {
|
||||
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
|
@ -6318,7 +6341,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
}
|
||||
|
||||
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||
if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false) != TSDB_CODE_SUCCESS) {
|
||||
if (parseSelectClause(&pSql->cmd, 0, pQuerySql->pSelection, isSTable, false, false) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -6331,15 +6354,19 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
// set interval value
|
||||
if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
} else {
|
||||
if ((pQueryInfo->interval.interval > 0) &&
|
||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pQueryInfo->interval.interval > 0) &&
|
||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
if (!tscIsProjectionQuery(pQueryInfo) && pQueryInfo->interval.interval == 0) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||
}
|
||||
|
||||
// set the created table[stream] name
|
||||
code = tscSetTableFullName(pTableMetaInfo, pzTableName, pSql);
|
||||
code = tscSetTableFullName(pTableMetaInfo, pName, pSql);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -6381,6 +6408,41 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||
const char* msg3 = "start(end) time of query range required or time range too large";
|
||||
|
||||
if (pQueryInfo->interval.interval == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
|
||||
if (initialWindows) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
|
||||
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
||||
|
||||
int64_t intervalRange = 0;
|
||||
if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') {
|
||||
int64_t f = 1;
|
||||
if (pQueryInfo->interval.intervalUnit == 'n') {
|
||||
f = 30L * MILLISECOND_PER_DAY;
|
||||
} else if (pQueryInfo->interval.intervalUnit == 'y') {
|
||||
f = 365L * MILLISECOND_PER_DAY;
|
||||
}
|
||||
|
||||
intervalRange = pQueryInfo->interval.interval * f;
|
||||
} else {
|
||||
intervalRange = pQueryInfo->interval.interval;
|
||||
}
|
||||
// number of result is not greater than 10,000,000
|
||||
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||
assert(pQuerySql != NULL && (pQuerySql->from == NULL || taosArrayGetSize(pQuerySql->from) > 0));
|
||||
|
||||
|
@ -6528,7 +6590,9 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
|
||||
int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
|
||||
|
||||
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery) != TSDB_CODE_SUCCESS) {
|
||||
int32_t intervalQuery = !(pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0);
|
||||
|
||||
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery, intervalQuery) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -6576,31 +6640,21 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
||||
/*
|
||||
* fill options are set at the end position, when all columns are set properly
|
||||
* the columns may be increased due to group by operation
|
||||
*/
|
||||
if (pQuerySql->fillType != NULL) {
|
||||
if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
if (pQueryInfo->interval.interval > 0) {
|
||||
bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
|
||||
if (initialWindows) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
|
||||
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
||||
// number of result is not greater than 10,000,000
|
||||
if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
/*
|
||||
* fill options are set at the end position, when all columns are set properly
|
||||
* the columns may be increased due to group by operation
|
||||
*/
|
||||
if ((code = checkQueryRangeForFill(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySql)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6711,7 +6765,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
// check for dividing by 0
|
||||
if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
|
||||
if (pRight->nodeType == TSQL_NODE_VALUE) {
|
||||
if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64Key == 0) {
|
||||
if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
} else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->dKey == 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
|
|
@ -66,30 +66,24 @@ STableComInfo tscGetTableInfo(const STableMeta* pTableMeta) {
|
|||
return pTableMeta->tableInfo;
|
||||
}
|
||||
|
||||
bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols) {
|
||||
if (!VALIDNUMOFCOLS(numOfCols)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* first column must be the timestamp, which is a primary key */
|
||||
if (pSchema[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* type is valid, length is valid */
|
||||
static bool doValidateSchema(SSchema* pSchema, int32_t numOfCols, int32_t maxLen) {
|
||||
int32_t rowLen = 0;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
// 1. valid types
|
||||
if (pSchema[i].type > TSDB_DATA_TYPE_TIMESTAMP || pSchema[i].type < TSDB_DATA_TYPE_BOOL) {
|
||||
if (!isValidDataType(pSchema[i].type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. valid length for each type
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||
if (pSchema[i].bytes > TSDB_MAX_BINARY_LEN) {
|
||||
return false;
|
||||
}
|
||||
} else if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
||||
if (pSchema[i].bytes > TSDB_MAX_NCHAR_LEN) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (pSchema[i].bytes != tDataTypeDesc[pSchema[i].type].nSize) {
|
||||
return false;
|
||||
|
@ -106,8 +100,32 @@ bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols) {
|
|||
rowLen += pSchema[i].bytes;
|
||||
}
|
||||
|
||||
// valid total length
|
||||
return (rowLen <= TSDB_MAX_BYTES_PER_ROW);
|
||||
return rowLen <= maxLen;
|
||||
}
|
||||
|
||||
bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTags) {
|
||||
if (!VALIDNUMOFCOLS(numOfCols)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VALIDNUMOFTAGS(numOfTags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* first column must be the timestamp, which is a primary key */
|
||||
if (pSchema[0].type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doValidateSchema(pSchema, numOfCols, TSDB_MAX_BYTES_PER_ROW)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doValidateSchema(&pSchema[numOfCols], numOfTags, TSDB_MAX_TAGS_LEN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SSchema* tscGetTableColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) {
|
||||
|
@ -130,19 +148,8 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupMsg *pVgroupMsg) {
|
||||
corVgroupInfo->version = 0;
|
||||
corVgroupInfo->inUse = 0;
|
||||
corVgroupInfo->numOfEps = pVgroupMsg->numOfEps;
|
||||
|
||||
for (int32_t i = 0; i < pVgroupMsg->numOfEps; i++) {
|
||||
corVgroupInfo->epAddr[i].fqdn = strndup(pVgroupMsg->epAddr[i].fqdn, tListLen(pVgroupMsg->epAddr[0].fqdn));
|
||||
corVgroupInfo->epAddr[i].port = pVgroupMsg->epAddr[i].port;
|
||||
}
|
||||
}
|
||||
|
||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size) {
|
||||
assert(pTableMetaMsg != NULL);
|
||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
||||
assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2 && pTableMetaMsg->numOfTags >= 0);
|
||||
|
||||
int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
||||
|
@ -159,11 +166,9 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
|||
pTableMeta->id.tid = pTableMetaMsg->tid;
|
||||
pTableMeta->id.uid = pTableMetaMsg->uid;
|
||||
|
||||
tscInitCorVgroupInfo(&pTableMeta->corVgroupInfo, &pTableMetaMsg->vgroup);
|
||||
|
||||
pTableMeta->sversion = pTableMetaMsg->sversion;
|
||||
pTableMeta->tversion = pTableMetaMsg->tversion;
|
||||
tstrncpy(pTableMeta->sTableId, pTableMetaMsg->sTableId, TSDB_TABLE_FNAME_LEN);
|
||||
tstrncpy(pTableMeta->sTableName, pTableMetaMsg->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
memcpy(pTableMeta->schema, pTableMetaMsg->schema, schemaSize);
|
||||
|
||||
|
@ -172,13 +177,44 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
|||
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||
}
|
||||
|
||||
if (size != NULL) {
|
||||
*size = sizeof(STableMeta) + schemaSize;
|
||||
}
|
||||
|
||||
return pTableMeta;
|
||||
}
|
||||
|
||||
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src) {
|
||||
assert(pExisted != NULL && src != NULL);
|
||||
if (pExisted->numOfEps != src->numOfEps) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pExisted->numOfEps; ++i) {
|
||||
if (pExisted->ep[i].port != src->epAddr[i].port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp(pExisted->ep[i].fqdn, src->epAddr[i].fqdn, tListLen(pExisted->ep[i].fqdn)) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) {
|
||||
assert(pVgroupMsg != NULL);
|
||||
|
||||
SNewVgroupInfo info = {0};
|
||||
info.numOfEps = pVgroupMsg->numOfEps;
|
||||
info.vgId = pVgroupMsg->vgId;
|
||||
info.inUse = 0;
|
||||
|
||||
for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) {
|
||||
tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
||||
info.ep[i].port = pVgroupMsg->epAddr[i].port;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// todo refactor
|
||||
UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tcmdtype.h"
|
||||
#include "trpc.h"
|
||||
#include "tscLocalMerge.h"
|
||||
|
@ -85,7 +84,8 @@ static void tscEpSetHtons(SRpcEpSet *s) {
|
|||
bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
||||
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < s1->numOfEps; i++) {
|
||||
if (s1->port[i] != s2->port[i]
|
||||
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
|
||||
|
@ -93,6 +93,7 @@ bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
||||
// no need to update if equal
|
||||
SRpcCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
|
||||
|
@ -101,37 +102,44 @@ void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
|||
taosCorEndWrite(&pCorEpSet->version);
|
||||
}
|
||||
|
||||
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SCorVgroupInfo *pVgroupInfo) {
|
||||
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SNewVgroupInfo *pVgroupInfo) {
|
||||
if (pVgroupInfo == NULL) { return;}
|
||||
taosCorBeginRead(&pVgroupInfo->version);
|
||||
int8_t inUse = pVgroupInfo->inUse;
|
||||
pEpSet->inUse = (inUse >= 0 && inUse < TSDB_MAX_REPLICA) ? inUse: 0;
|
||||
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||
for (int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, sizeof(pEpSet->fqdn[i]));
|
||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->ep[i].fqdn, sizeof(pEpSet->fqdn[i]));
|
||||
pEpSet->port[i] = pVgroupInfo->ep[i].port;
|
||||
}
|
||||
taosCorEndRead(&pVgroupInfo->version);
|
||||
}
|
||||
|
||||
static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
|
||||
SSqlCmd *pCmd = &pObj->cmd;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return;}
|
||||
SCorVgroupInfo *pVgroupInfo = &pTableMetaInfo->pTableMeta->corVgroupInfo;
|
||||
|
||||
taosCorBeginWrite(&pVgroupInfo->version);
|
||||
tscDebug("before: Endpoint in use: %d", pVgroupInfo->inUse);
|
||||
pVgroupInfo->inUse = pEpSet->inUse;
|
||||
pVgroupInfo->numOfEps = pEpSet->numOfEps;
|
||||
for (int32_t i = 0; i < pVgroupInfo->numOfEps; i++) {
|
||||
tfree(pVgroupInfo->epAddr[i].fqdn);
|
||||
pVgroupInfo->epAddr[i].fqdn = strndup(pEpSet->fqdn[i], tListLen(pEpSet->fqdn[i]));
|
||||
pVgroupInfo->epAddr[i].port = pEpSet->port[i];
|
||||
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tscDebug("after: EndPoint in use: %d", pVgroupInfo->inUse);
|
||||
taosCorEndWrite(&pVgroupInfo->version);
|
||||
int32_t vgId = pTableMetaInfo->pTableMeta->vgId;
|
||||
if (pTableMetaInfo->pTableMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
assert(vgId == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
assert(vgroupInfo.numOfEps > 0 && vgroupInfo.vgId > 0);
|
||||
|
||||
tscDebug("before: Endpoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
|
||||
vgroupInfo.inUse = pEpSet->inUse;
|
||||
vgroupInfo.numOfEps = pEpSet->numOfEps;
|
||||
for (int32_t i = 0; i < vgroupInfo.numOfEps; i++) {
|
||||
strncpy(vgroupInfo.ep[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
|
||||
vgroupInfo.ep[i].port = pEpSet->port[i];
|
||||
}
|
||||
|
||||
tscDebug("after: EndPoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
|
||||
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
}
|
||||
|
||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||
|
@ -303,7 +311,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pEpSet) {
|
||||
if (pEpSet) { // todo update this
|
||||
if (!tscEpSetIsEqual(&pSql->epSet, pEpSet)) {
|
||||
if (pCmd->command < TSDB_SQL_MGMT) {
|
||||
tscUpdateVgroupInfo(pSql, pEpSet);
|
||||
|
@ -415,7 +423,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
|
||||
if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it
|
||||
taosRemoveRef(tscObjRef, pSql->self);
|
||||
tscDebug("%p sqlObj is automatically freed", pSql);
|
||||
tscDebug("%p sqlObj is automatically freed", pSql);
|
||||
}
|
||||
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
|
@ -437,7 +445,7 @@ int doProcessSql(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
|
@ -446,7 +454,7 @@ int doProcessSql(SSqlObj *pSql) {
|
|||
// NOTE: if code is TSDB_CODE_SUCCESS, pSql may have been released here already by other threads.
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pRes->code = code;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -549,7 +557,10 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
// pSql->cmd.payloadLen is set during copying data into payload
|
||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {0};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
|
||||
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit,
|
||||
pSql->epSet.numOfEps);
|
||||
|
@ -559,9 +570,11 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
/*
|
||||
* for table query, simply return the size <= 1k
|
||||
*/
|
||||
static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
||||
static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) {
|
||||
const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5;
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||
|
||||
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
|
||||
|
||||
|
@ -569,6 +582,8 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
|||
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2);
|
||||
|
||||
int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
|
||||
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr) + 1;
|
||||
|
||||
|
||||
int32_t tableSerialize = 0;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
@ -585,7 +600,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
|||
}
|
||||
|
||||
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + tsBufSize +
|
||||
tableSerialize + 4096;
|
||||
tableSerialize + sqlLen + 4096;
|
||||
}
|
||||
|
||||
static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg) {
|
||||
|
@ -611,7 +626,10 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
} else {
|
||||
vgId = pTableMeta->vgId;
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {0};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
}
|
||||
|
||||
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
||||
|
@ -662,7 +680,7 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
int32_t size = tscEstimateQueryMsgSize(pCmd, pCmd->clauseIndex);
|
||||
int32_t size = tscEstimateQueryMsgSize(pSql, pCmd->clauseIndex);
|
||||
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
|
||||
tscError("%p failed to malloc for query msg", pSql);
|
||||
|
@ -695,7 +713,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
|
||||
|
||||
int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList);
|
||||
|
||||
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr);
|
||||
|
||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
||||
pQueryMsg->window.skey = htobe64(pQueryInfo->window.skey);
|
||||
pQueryMsg->window.ekey = htobe64(pQueryInfo->window.ekey);
|
||||
|
@ -718,10 +737,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit;
|
||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||
pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
||||
|
||||
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
||||
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
||||
|
||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||
|
||||
|
@ -734,12 +755,10 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i);
|
||||
SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex];
|
||||
|
||||
if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || pColSchema->type < TSDB_DATA_TYPE_BOOL ||
|
||||
pColSchema->type > TSDB_DATA_TYPE_NCHAR) {
|
||||
if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || !isValidDataType(pColSchema->type)) {
|
||||
tscError("%p tid:%d uid:%" PRIu64" id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s",
|
||||
pSql, pTableMeta->id.tid, pTableMeta->id.uid, pTableMetaInfo->name, tscGetNumOfColumns(pTableMeta), pCol->colIndex.columnIndex,
|
||||
pColSchema->name);
|
||||
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -805,7 +824,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
memcpy(pMsg, pExpr->param[j].pz, pExpr->param[j].nLen);
|
||||
pMsg += pExpr->param[j].nLen;
|
||||
} else {
|
||||
pSqlFuncExpr->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64Key);
|
||||
pSqlFuncExpr->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,7 +864,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
memcpy(pMsg, pExpr->param[j].pz, pExpr->param[j].nLen);
|
||||
pMsg += pExpr->param[j].nLen;
|
||||
} else {
|
||||
pSqlFuncExpr1->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64Key);
|
||||
pSqlFuncExpr1->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,7 +942,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex];
|
||||
|
||||
if ((pCol->colIndex.columnIndex >= numOfTagColumns || pCol->colIndex.columnIndex < -1) ||
|
||||
(pColSchema->type < TSDB_DATA_TYPE_BOOL || pColSchema->type > TSDB_DATA_TYPE_NCHAR)) {
|
||||
(!isValidDataType(pColSchema->type))) {
|
||||
tscError("%p tid:%d uid:%" PRIu64 " id:%s, tag index out of range, totalCols:%d, numOfTags:%d, index:%d, column name:%s",
|
||||
pSql, pTableMeta->id.tid, pTableMeta->id.uid, pTableMetaInfo->name, total, numOfTagColumns,
|
||||
pCol->colIndex.columnIndex, pColSchema->name);
|
||||
|
@ -954,13 +973,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pMsg += pCond->len;
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
|
||||
*pMsg = 0;
|
||||
pMsg++;
|
||||
} else {
|
||||
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
|
||||
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
|
||||
|
||||
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
|
||||
if (pCond->len > 0) {
|
||||
strncpy(pMsg, pCond->cond, pCond->len);
|
||||
pMsg += pCond->len;
|
||||
}
|
||||
|
||||
// compressed ts block
|
||||
|
@ -981,6 +998,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
|
||||
}
|
||||
|
||||
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
||||
pMsg += sqlLen;
|
||||
|
||||
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
|
||||
|
||||
tscDebug("%p msg built success, len:%d bytes", pSql, msgLen);
|
||||
|
@ -1447,10 +1467,14 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
|
|||
SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
|
||||
pCmd->payloadLen = htonl(pUpdateMsg->head.contLen);
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMetaInfo->pTableMeta->corVgroupInfo);
|
||||
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
assert(vgroupInfo.vgId > 0);
|
||||
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1516,7 +1540,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) {
|
|||
if (code == TSDB_CODE_SUCCESS) {
|
||||
(*pSql->fp)(pSql->param, pSql, pSql->res.numOfRows);
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1545,7 +1569,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
|||
|
||||
int32_t code = pRes->code;
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1564,7 +1588,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
|||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -1804,23 +1828,50 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
assert(i == 0);
|
||||
}
|
||||
|
||||
assert(pSchema->type >= TSDB_DATA_TYPE_BOOL && pSchema->type <= TSDB_DATA_TYPE_NCHAR);
|
||||
assert(isValidDataType(pSchema->type));
|
||||
pSchema++;
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg, &size);
|
||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||
|
||||
// todo add one more function: taosAddDataIfNotExists();
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||
|
||||
pTableMetaInfo->pTableMeta = (STableMeta *) taosCachePut(tscMetaCache, pTableMetaInfo->name,
|
||||
strlen(pTableMetaInfo->name), pTableMeta, size, tsTableMetaKeepTimer * 1000);
|
||||
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||
// check if super table hashmap or not
|
||||
int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
if (pTableMetaInfo->pTableMeta == NULL) {
|
||||
free(pTableMeta);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
// super tableMeta data alreay exists, create it according to tableMeta and add it to hash map
|
||||
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
|
||||
|
||||
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
|
||||
int32_t code = taosHashPut(tscTableMetaInfo, pTableMeta->sTableName, len, pSupTableMeta, size);
|
||||
assert(code == TSDB_CODE_SUCCESS);
|
||||
|
||||
tfree(pSupTableMeta);
|
||||
|
||||
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
|
||||
taosHashPut(tscTableMetaInfo, pTableMetaInfo->name, strlen(pTableMetaInfo->name), cMeta, sizeof(CChildTableMeta));
|
||||
tfree(cMeta);
|
||||
} else {
|
||||
uint32_t s = tscGetTableMetaSize(pTableMeta);
|
||||
taosHashPut(tscTableMetaInfo, pTableMetaInfo->name, strlen(pTableMetaInfo->name), pTableMeta, s);
|
||||
}
|
||||
|
||||
// update the vgroupInfo if needed
|
||||
if (pTableMeta->vgId > 0) {
|
||||
int32_t vgId = pTableMeta->vgId;
|
||||
assert(pTableMeta->tableType != TSDB_SUPER_TABLE);
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {.inUse = -1};
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
|
||||
if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, &pMetaMsg->vgroup)) ||
|
||||
(vgroupInfo.inUse < 0)) { // vgroup info exists, compare with it
|
||||
vgroupInfo = createNewVgroupInfo(&pMetaMsg->vgroup);
|
||||
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo));
|
||||
tscDebug("add new VgroupInfo, vgId:%d, total:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap));
|
||||
}
|
||||
}
|
||||
|
||||
tscDebug("%p recv table meta, uid:%"PRId64 ", tid:%d, name:%s", pSql, pTableMeta->id.uid, pTableMeta->id.tid, pTableMetaInfo->name);
|
||||
|
@ -1831,8 +1882,8 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
|
||||
/**
|
||||
* multi table meta rsp pkg format:
|
||||
* | STaosRsp | ieType | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
|
||||
* |...... 1B 1B 4B
|
||||
* | STaosRsp | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
|
||||
* |...... 1B 4B
|
||||
**/
|
||||
int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
||||
#if 0
|
||||
|
@ -1924,9 +1975,6 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
|||
//
|
||||
// rsp += tagLen;
|
||||
// int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache
|
||||
//
|
||||
// pMeta->index = 0;
|
||||
// (void)taosCachePut(tscMetaCache, pMeta->tableId, (char *)pMeta, size, tsTableMetaKeepTimer);
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -1939,16 +1987,20 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
||||
// master sqlObj locates in param
|
||||
SSqlObj* parent = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param);
|
||||
if(parent == NULL) {
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
||||
assert(parent->signature == parent && (int64_t)pSql->param == parent->self);
|
||||
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
// NOTE: the order of several table must be preserved.
|
||||
SSTableVgroupRspMsg *pStableVgroup = (SSTableVgroupRspMsg *)pRes->pRsp;
|
||||
pStableVgroup->numOfTables = htonl(pStableVgroup->numOfTables);
|
||||
char *pMsg = pRes->pRsp + sizeof(SSTableVgroupRspMsg);
|
||||
|
||||
// master sqlObj locates in param
|
||||
SSqlObj* parent = pSql->param;
|
||||
assert(parent != NULL);
|
||||
|
||||
SSqlCmd* pCmd = &parent->cmd;
|
||||
for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) {
|
||||
|
@ -1982,18 +2034,16 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
|||
|
||||
pMsg += size;
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, parent->self);
|
||||
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
||||
/*
|
||||
* current process do not use the cache at all
|
||||
*/
|
||||
int tscProcessShowRsp(SSqlObj *pSql) {
|
||||
STableMetaMsg *pMetaMsg;
|
||||
SShowRsp * pShow;
|
||||
SSchema * pSchema;
|
||||
char key[20];
|
||||
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
@ -2018,20 +2068,10 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
pSchema++;
|
||||
}
|
||||
|
||||
key[0] = pCmd->msgType + 'a';
|
||||
strcpy(key + 1, "showlist");
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
pTableMetaInfo->pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
taosCacheRelease(tscMetaCache, (void *)&(pTableMetaInfo->pTableMeta), false);
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg, &size);
|
||||
|
||||
pTableMetaInfo->pTableMeta = taosCachePut(tscMetaCache, key, strlen(key), (char *)pTableMeta, size,
|
||||
tsTableMetaKeepTimer * 1000);
|
||||
SSchema *pTableSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
if (pQueryInfo->colList == NULL) {
|
||||
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
@ -2054,12 +2094,9 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
|
||||
pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
||||
tfree(pTableMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO multithread problem
|
||||
static void createHBObj(STscObj* pObj) {
|
||||
if (pObj->hbrid != 0) {
|
||||
return;
|
||||
|
@ -2141,51 +2178,34 @@ int tscProcessUseDbRsp(SSqlObj *pSql) {
|
|||
|
||||
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
||||
pSql->pTscObj->db[0] = 0;
|
||||
taosCacheEmpty(tscMetaCache);
|
||||
taosHashEmpty(tscTableMetaInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessDropTableRsp(SSqlObj *pSql) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
|
||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
||||
return 0;
|
||||
}
|
||||
//The cached tableMeta is expired in this case, so clean it in hash table
|
||||
taosHashRemove(tscTableMetaInfo, pTableMetaInfo->name, strnlen(pTableMetaInfo->name, TSDB_TABLE_FNAME_LEN));
|
||||
tscDebug("%p remove table meta after drop table:%s, numOfRemain:%d", pSql, pTableMetaInfo->name,
|
||||
(int32_t) taosHashGetSize(tscTableMetaInfo));
|
||||
|
||||
/*
|
||||
* 1. if a user drops one table, which is the only table in a vnode, remove operation will incur vnode to be removed.
|
||||
* 2. Then, a user creates a new metric followed by a table with identical name of removed table but different schema,
|
||||
* here the table will reside in a new vnode.
|
||||
* The cached information is expired, however, we may have lost the ref of original meter. So, clear whole cache
|
||||
* instead.
|
||||
*/
|
||||
tscDebug("%p force release table meta after drop table:%s", pSql, pTableMetaInfo->name);
|
||||
taosCacheRelease(tscMetaCache, (void **)&pTableMeta, true);
|
||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
|
||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
||||
return 0;
|
||||
}
|
||||
char* name = pTableMetaInfo->name;
|
||||
tscDebug("%p remove tableMeta in hashMap after alter-table: %s", pSql, name);
|
||||
|
||||
tscDebug("%p force release metermeta in cache after alter-table: %s", pSql, pTableMetaInfo->name);
|
||||
taosCacheRelease(tscMetaCache, (void **)&pTableMeta, true);
|
||||
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), true);
|
||||
|
||||
if (isSuperTable) { // if it is a super table, reset whole query cache
|
||||
tscDebug("%p reset query cache since table:%s is stable", pSql, pTableMetaInfo->name);
|
||||
taosCacheEmpty(tscMetaCache);
|
||||
}
|
||||
if (isSuperTable) { // if it is a super table, iterate the hashTable and remove all the childTableMeta
|
||||
taosHashEmpty(tscTableMetaInfo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2195,6 +2215,7 @@ int tscProcessAlterDbMsgRsp(SSqlObj *pSql) {
|
|||
UNUSED(pSql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessShowCreateRsp(SSqlObj *pSql) {
|
||||
return tscLocalResultCommonBuilder(pSql, 1);
|
||||
}
|
||||
|
@ -2308,14 +2329,18 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn
|
|||
|
||||
tscDebug("%p new pSqlObj:%p to get tableMeta, auto create:%d", pSql, pNew, pNew->cmd.autoCreated);
|
||||
|
||||
pNew->fp = tscTableMetaCallBack;
|
||||
pNew->param = pSql;
|
||||
|
||||
registerSqlObj(pNew);
|
||||
|
||||
pNew->fp = tscTableMetaCallBack;
|
||||
pNew->param = (void *)pSql->self;
|
||||
|
||||
tscDebug("%p metaRid from %" PRId64 " to %" PRId64 , pSql, pSql->metaRid, pNew->self);
|
||||
|
||||
pSql->metaRid = pNew->self;
|
||||
|
||||
int32_t code = tscProcessSql(pNew);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify upper application that current process need to be terminated
|
||||
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -2323,21 +2348,30 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn
|
|||
|
||||
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||
assert(strlen(pTableMetaInfo->name) != 0);
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
// If this STableMetaInfo owns a table meta, release it first
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), false);
|
||||
}
|
||||
|
||||
pTableMetaInfo->pTableMeta = (STableMeta *)taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
tscDebug("%p retrieve table Meta from cache, the number of columns:%d, numOfTags:%d, %p", pSql, tinfo.numOfColumns,
|
||||
tinfo.numOfTags, pTableMetaInfo->pTableMeta);
|
||||
uint32_t size = tscGetTableMetaMaxSize();
|
||||
pTableMetaInfo->pTableMeta = calloc(1, size);
|
||||
|
||||
pTableMetaInfo->pTableMeta->tableType = -1;
|
||||
pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1;
|
||||
int32_t len = (int32_t) strlen(pTableMetaInfo->name);
|
||||
|
||||
taosHashGetClone(tscTableMetaInfo, pTableMetaInfo->name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
||||
|
||||
// TODO resize the tableMeta
|
||||
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pMeta->id.uid > 0) {
|
||||
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
||||
int32_t code = tscCreateTableMetaFromCChildMeta(pTableMetaInfo->pTableMeta, pTableMetaInfo->name);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||
}
|
||||
|
||||
|
@ -2347,7 +2381,7 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create
|
|||
}
|
||||
|
||||
/**
|
||||
* retrieve table meta from mnode, and update the local table meta cache.
|
||||
* retrieve table meta from mnode, and update the local table meta hashmap.
|
||||
* @param pSql sql object
|
||||
* @param tableIndex table index
|
||||
* @return status code
|
||||
|
@ -2355,16 +2389,18 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create
|
|||
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||
const char* name = pTableMetaInfo->name;
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
tscDebug("%p update table meta, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
||||
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid, pTableMeta);
|
||||
if (pTableMeta) {
|
||||
tscDebug("%p update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64, pSql, name,
|
||||
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid);
|
||||
}
|
||||
|
||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), true);
|
||||
// remove stored tableMeta info in hash table
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||
}
|
||||
|
||||
|
@ -2405,7 +2441,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||
STableMeta *pTableMeta = taosCacheAcquireByData(tscMetaCache, pMInfo->pTableMeta);
|
||||
STableMeta* pTableMeta = tscTableMetaClone(pMInfo->pTableMeta);
|
||||
tscAddTableMetaInfo(pNewQueryInfo, pMInfo->name, pTableMeta, NULL, pMInfo->tagColList, pMInfo->pVgroupTables);
|
||||
}
|
||||
|
||||
|
@ -2417,10 +2453,15 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
|||
pNewQueryInfo->numOfTables = pQueryInfo->numOfTables;
|
||||
registerSqlObj(pNew);
|
||||
|
||||
tscDebug("%p svgroupRid from %" PRId64 " to %" PRId64 , pSql, pSql->svgroupRid, pNew->self);
|
||||
|
||||
pSql->svgroupRid = pNew->self;
|
||||
|
||||
|
||||
tscDebug("%p new sqlObj:%p to get vgroupInfo, numOfTables:%d", pSql, pNew, pNewQueryInfo->numOfTables);
|
||||
|
||||
pNew->fp = tscTableMetaCallBack;
|
||||
pNew->param = pSql;
|
||||
pNew->param = (void *)pSql->self;
|
||||
code = tscProcessSql(pNew);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
||||
|
|
|
@ -47,7 +47,7 @@ static bool validUserName(const char* user) {
|
|||
}
|
||||
|
||||
static bool validPassword(const char* passwd) {
|
||||
return validImpl(passwd, TSDB_PASSWORD_LEN - 1);
|
||||
return validImpl(passwd, TSDB_KEY_LEN - 1);
|
||||
}
|
||||
|
||||
static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, const char *auth, const char *db,
|
||||
|
@ -238,11 +238,11 @@ TAOS *taos_connect_c(const char *ip, uint8_t ipLen, const char *user, uint8_t us
|
|||
uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port) {
|
||||
char ipBuf[TSDB_EP_LEN] = {0};
|
||||
char userBuf[TSDB_USER_LEN] = {0};
|
||||
char passBuf[TSDB_PASSWORD_LEN] = {0};
|
||||
char passBuf[TSDB_KEY_LEN] = {0};
|
||||
char dbBuf[TSDB_DB_NAME_LEN] = {0};
|
||||
strncpy(ipBuf, ip, MIN(TSDB_EP_LEN - 1, ipLen));
|
||||
strncpy(userBuf, user, MIN(TSDB_USER_LEN - 1, userLen));
|
||||
strncpy(passBuf, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen));
|
||||
strncpy(passBuf, pass, MIN(TSDB_KEY_LEN - 1, passLen));
|
||||
strncpy(dbBuf, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen));
|
||||
return taos_connect(ipBuf, userBuf, passBuf, dbBuf, port);
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, int64_t*
|
|||
return NULL;
|
||||
}
|
||||
|
||||
nPrintTsc(sqlstr);
|
||||
nPrintTsc("%s", sqlstr);
|
||||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
|
@ -694,6 +694,8 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
|||
// set the master sqlObj flag to cancel query
|
||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
|
||||
tscLockByThread(&pSql->squeryLock);
|
||||
|
||||
for (int i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||
// NOTE: pSub may have been released already here
|
||||
SSqlObj *pSub = pSql->pSubs[i];
|
||||
|
@ -709,10 +711,16 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
|||
pSubObj->rpcRid = -1;
|
||||
}
|
||||
|
||||
tscQueueAsyncRes(pSubObj);
|
||||
tscAsyncResultOnError(pSubObj);
|
||||
taosReleaseRef(tscObjRef, pSubObj->self);
|
||||
}
|
||||
|
||||
if (pSql->subState.numOfSub <= 0) {
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
tscUnlockByThread(&pSql->squeryLock);
|
||||
|
||||
tscDebug("%p super table query cancelled", pSql);
|
||||
}
|
||||
|
||||
|
@ -745,7 +753,7 @@ void taos_stop_query(TAOS_RES *res) {
|
|||
pSql->rpcRid = -1;
|
||||
}
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,18 +796,34 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
len += sprintf(str + len, "%d", *((int8_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
len += sprintf(str + len, "%u", *((uint8_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
len += sprintf(str + len, "%d", *((int16_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
len += sprintf(str + len, "%u", *((uint16_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
len += sprintf(str + len, "%d", *((int32_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
len += sprintf(str + len, "%u", *((uint32_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
len += sprintf(str + len, "%" PRIu64, *((uint64_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float fv = 0;
|
||||
fv = GET_FLOAT_VAL(row[i]);
|
||||
|
@ -909,7 +933,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
||||
// must before clean the sqlcmd object
|
||||
tscResetSqlCmdObj(&pSql->cmd, false);
|
||||
tscResetSqlCmdObj(&pSql->cmd);
|
||||
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
|
@ -962,7 +986,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t
|
|||
return code;
|
||||
}
|
||||
|
||||
if (++pCmd->count > TSDB_MULTI_METERMETA_MAX_NUM) {
|
||||
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;
|
||||
|
|
|
@ -65,44 +65,67 @@ static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, in
|
|||
return retryDelta;
|
||||
}
|
||||
|
||||
static void tscProcessStreamLaunchQuery(SSchedMsg *pMsg) {
|
||||
SSqlStream *pStream = (SSqlStream *)pMsg->ahandle;
|
||||
SSqlObj * pSql = pStream->pSql;
|
||||
static void setRetryInfo(SSqlStream* pStream, int32_t code) {
|
||||
SSqlObj* pSql = pStream->pSql;
|
||||
|
||||
pSql->fp = tscProcessStreamQueryCallback;
|
||||
pSql->fetchFp = tscProcessStreamQueryCallback;
|
||||
pSql->param = pStream;
|
||||
pSql->res.code = code;
|
||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision);
|
||||
tscDebug("%p stream:%p, get table Meta failed, retry in %" PRId64 "ms", pSql, pStream, retryDelayTime);
|
||||
tscSetRetryTimer(pStream, pSql, retryDelayTime);
|
||||
}
|
||||
|
||||
static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
||||
SSqlStream *pStream = (SSqlStream *)param;
|
||||
assert(pStream->pSql == tres);
|
||||
|
||||
SSqlObj* pSql = (SSqlObj*) tres;
|
||||
|
||||
pSql->fp = doLaunchQuery;
|
||||
pSql->fetchFp = doLaunchQuery;
|
||||
pSql->res.completed = false;
|
||||
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
setRetryInfo(pStream, code);
|
||||
return;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
int code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
pSql->res.code = code;
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
code = tscGetSTableVgroupInfo(pSql, 0);
|
||||
pSql->res.code = code;
|
||||
}
|
||||
|
||||
// failed to get meter/metric meta, retry in 10sec.
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision);
|
||||
tscDebug("%p stream:%p,get metermeta failed, retry in %" PRId64 "ms", pStream->pSql, pStream, retryDelayTime);
|
||||
tscSetRetryTimer(pStream, pSql, retryDelayTime);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
// failed to get table Meta or vgroup list, retry in 10sec.
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
tscTansformSQLFuncForSTableQuery(pQueryInfo);
|
||||
tscDebug("%p stream:%p start stream query on:%s", pSql, pStream, pTableMetaInfo->name);
|
||||
tscDoQuery(pStream->pSql);
|
||||
tscDebug("%p stream:%p, start stream query on:%s", pSql, pStream, pTableMetaInfo->name);
|
||||
|
||||
pSql->fp = tscProcessStreamQueryCallback;
|
||||
pSql->fetchFp = tscProcessStreamQueryCallback;
|
||||
tscDoQuery(pSql);
|
||||
tscIncStreamExecutionCount(pStream);
|
||||
} else {
|
||||
setRetryInfo(pStream, code);
|
||||
}
|
||||
}
|
||||
|
||||
static void tscProcessStreamLaunchQuery(SSchedMsg *pMsg) {
|
||||
SSqlStream *pStream = (SSqlStream *)pMsg->ahandle;
|
||||
doLaunchQuery(pStream, pStream->pSql, 0);
|
||||
}
|
||||
|
||||
static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||
SSqlStream *pStream = (SSqlStream *)handle;
|
||||
if (pStream == NULL) return;
|
||||
if (pStream->pTimer != tmrId) return;
|
||||
if (pStream == NULL || pStream->pTimer != tmrId) {
|
||||
return;
|
||||
}
|
||||
|
||||
pStream->pTimer = NULL;
|
||||
|
||||
pStream->numOfRes = 0; // reset the numOfRes.
|
||||
|
@ -167,7 +190,9 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
retryDelay);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), true);
|
||||
|
||||
char* name = pTableMetaInfo->name;
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
||||
|
||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
|
||||
|
@ -269,9 +294,8 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
tscDebug("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, pTableMetaInfo->name,
|
||||
pStream->numOfRes);
|
||||
|
||||
// release the metric/meter meta information reference, so data in cache can be updated
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
||||
tscFreeSqlResult(pSql);
|
||||
tfree(pSql->pSubs);
|
||||
pSql->subState.numOfSub = 0;
|
||||
|
@ -391,11 +415,16 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) {
|
|||
tscSetRetryTimer(pStream, pSql, timer);
|
||||
}
|
||||
|
||||
static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||
static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||
int64_t minIntervalTime =
|
||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
|
||||
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
||||
sprintf(pSql->cmd.payload, "the interval value is 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit!= 'y' && pQueryInfo->interval.interval < minIntervalTime) {
|
||||
tscWarn("%p stream:%p, original sample interval:%" PRId64 " too small, reset to:%" PRId64, pSql, pStream,
|
||||
|
@ -435,6 +464,8 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
pQueryInfo->interval.interval = 0; // clear the interval value to avoid the force time window split by query processor
|
||||
pQueryInfo->interval.sliding = 0;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||
|
@ -484,34 +515,19 @@ static int64_t tscGetLaunchTimestamp(const SSqlStream *pStream) {
|
|||
return (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? timer / 1000L : timer;
|
||||
}
|
||||
|
||||
static void setErrorInfo(SSqlObj* pSql, int32_t code, char* info) {
|
||||
if (pSql == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
pSql->res.code = code;
|
||||
|
||||
if (info != NULL) {
|
||||
strncpy(pCmd->payload, info, pCmd->payloadLen);
|
||||
}
|
||||
}
|
||||
|
||||
static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||
SSqlStream* pStream = (SSqlStream*)param;
|
||||
SSqlObj* pSql = pStream->pSql;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
setErrorInfo(pSql, code, pCmd->payload);
|
||||
tscError("%p open stream failed, sql:%s, reason:%s, code:0x%08x", pSql, pSql->sqlstr, pCmd->payload, code);
|
||||
pSql->res.code = code;
|
||||
tscError("%p open stream failed, sql:%s, reason:%s, code:%s", pSql, pSql->sqlstr, pCmd->payload, tstrerror(code));
|
||||
|
||||
pStream->fp(pStream->param, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
@ -522,13 +538,21 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
|||
pStream->ctime = taosGetTimestamp(pStream->precision);
|
||||
pStream->etime = pQueryInfo->window.ekey;
|
||||
|
||||
tscAddIntoStreamList(pStream);
|
||||
if (tscSetSlidingWindowInfo(pSql, pStream) != TSDB_CODE_SUCCESS) {
|
||||
pSql->res.code = code;
|
||||
|
||||
tscError("%p stream %p open failed, since the interval value is incorrect", pSql, pStream);
|
||||
pStream->fp(pStream->param, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
tscSetSlidingWindowInfo(pSql, pStream);
|
||||
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
||||
|
||||
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
||||
pCmd->command = TSDB_SQL_SELECT;
|
||||
|
||||
tscAddIntoStreamList(pStream);
|
||||
|
||||
taosTmrReset(tscProcessStreamTimer, (int32_t)starttime, pStream, tscTmr, &pStream->pTimer);
|
||||
|
||||
tscDebug("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql,
|
||||
|
@ -585,12 +609,15 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
|
||||
pSql->fp = tscCreateStream;
|
||||
pSql->fetchFp = tscCreateStream;
|
||||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
tscCreateStream(pStream, pSql, code);
|
||||
} else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
tscError("%p open stream failed, sql:%s, code:%s", pSql, sqlstr, tstrerror(pRes->code));
|
||||
tscFreeSqlObj(pSql);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
free(pStream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -188,8 +188,10 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
|
|||
tsBufFlush(output2);
|
||||
|
||||
tsBufDestroy(pSupporter1->pTSBuf);
|
||||
pSupporter1->pTSBuf = NULL;
|
||||
tsBufDestroy(pSupporter2->pTSBuf);
|
||||
|
||||
pSupporter2->pTSBuf = NULL;
|
||||
|
||||
TSKEY et = taosGetTimestampUs();
|
||||
tscDebug("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks "
|
||||
"intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us",
|
||||
|
@ -219,12 +221,9 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) {
|
|||
assert (pSupporter->uid != 0);
|
||||
|
||||
taosGetTmpfilePath("join-", pSupporter->path);
|
||||
pSupporter->f = fopen(pSupporter->path, "w");
|
||||
|
||||
// todo handle error
|
||||
if (pSupporter->f == NULL) {
|
||||
tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno));
|
||||
}
|
||||
// do NOT create file here to reduce crash generated file left issue
|
||||
pSupporter->f = NULL;
|
||||
|
||||
return pSupporter;
|
||||
}
|
||||
|
@ -244,12 +243,19 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) {
|
|||
|
||||
tscFieldInfoClear(&pSupporter->fieldsInfo);
|
||||
|
||||
if (pSupporter->pTSBuf != NULL) {
|
||||
tsBufDestroy(pSupporter->pTSBuf);
|
||||
pSupporter->pTSBuf = NULL;
|
||||
}
|
||||
|
||||
unlink(pSupporter->path);
|
||||
|
||||
if (pSupporter->f != NULL) {
|
||||
fclose(pSupporter->f);
|
||||
unlink(pSupporter->path);
|
||||
pSupporter->f = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (pSupporter->pVgroupTables != NULL) {
|
||||
taosArrayDestroy(pSupporter->pVgroupTables);
|
||||
pSupporter->pVgroupTables = NULL;
|
||||
|
@ -459,7 +465,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
|||
int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
|
||||
|
||||
// set the tag column id for executor to extract correct tag value
|
||||
pExpr->param[0] = (tVariant) {.i64Key = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)};
|
||||
pExpr->param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)};
|
||||
pExpr->numOfParams = 1;
|
||||
}
|
||||
|
||||
|
@ -526,6 +532,8 @@ static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) {
|
|||
tscError("%p all subquery return and query failed, global code:%s", pSqlObj, tstrerror(pSqlObj->res.code));
|
||||
freeJoinSubqueryObj(pSqlObj);
|
||||
}
|
||||
|
||||
//tscDestroyJoinSupporter(pSupporter);
|
||||
}
|
||||
|
||||
// update the query time range according to the join results on timestamp
|
||||
|
@ -642,7 +650,7 @@ static void issueTSCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj*
|
|||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, 0);
|
||||
int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid);
|
||||
pExpr->param->i64Key = tagColId;
|
||||
pExpr->param->i64 = tagColId;
|
||||
pExpr->numOfParams = 1;
|
||||
}
|
||||
|
||||
|
@ -779,7 +787,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
pParentSql->res.code = numOfRows;
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -796,7 +804,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -845,7 +853,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
freeJoinSubqueryObj(pParentSql);
|
||||
pParentSql->res.code = code;
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
||||
taosArrayDestroy(s1);
|
||||
taosArrayDestroy(s2);
|
||||
|
@ -916,11 +924,27 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
pParentSql->res.code = numOfRows;
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numOfRows > 0) { // write the compressed timestamp to disk file
|
||||
if(pSupporter->f == NULL) {
|
||||
pSupporter->f = fopen(pSupporter->path, "w");
|
||||
|
||||
if (pSupporter->f == NULL) {
|
||||
tscError("%p failed to create tmp file:%s, reason:%s", pSql, pSupporter->path, strerror(errno));
|
||||
|
||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(pRes->data, (size_t)pRes->numOfRows, 1, pSupporter->f);
|
||||
fclose(pSupporter->f);
|
||||
pSupporter->f = NULL;
|
||||
|
@ -930,7 +954,10 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
|||
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
||||
|
||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1028,7 +1055,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
|||
pParentSql->res.code = numOfRows;
|
||||
tscError("%p retrieve failed, index:%d, code:%s", pSql, pSupporter->subqueryIndex, tstrerror(numOfRows));
|
||||
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1155,7 +1182,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) {
|
|||
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
||||
(*pSql->fp)(pSql->param, pSql, 0);
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1233,7 +1260,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) {
|
|||
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
||||
(*pSql->fp)(pSql->param, pSql, 0);
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -1335,16 +1362,18 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
|
||||
SJoinSupporter* pSupporter = (SJoinSupporter*)param;
|
||||
SSqlObj* pParentSql = pSupporter->pObj;
|
||||
|
||||
|
||||
// There is only one subquery and table for each subquery.
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
assert(pQueryInfo->numOfTables == 1 && pSql->cmd.numOfClause == 1);
|
||||
|
||||
// retrieve actual query results from vnode during the second stage join subquery
|
||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p abort query due to other subquery failure. code:%d, global code:%d", pSql, code, pParentSql->res.code);
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1355,9 +1384,8 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
|
||||
tscError("%p abort query, code:%s, global code:%s", pSql, tstrerror(code), tstrerror(pParentSql->res.code));
|
||||
pParentSql->res.code = code;
|
||||
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1378,9 +1406,6 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
// In case of consequence query from other vnode, do not wait for other query response here.
|
||||
if (!(pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0))) {
|
||||
if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
|
||||
|
@ -1403,7 +1428,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
||||
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
||||
} else {
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1520,7 +1545,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
|||
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid);
|
||||
pExpr->param->i64Key = tagColId;
|
||||
pExpr->param->i64 = tagColId;
|
||||
pExpr->numOfParams = 1;
|
||||
}
|
||||
|
||||
|
@ -1612,7 +1637,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
|
|||
|
||||
_error:
|
||||
pRes->code = code;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
|
||||
|
@ -1631,6 +1656,25 @@ static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
|
|||
}
|
||||
}
|
||||
|
||||
void tscLockByThread(int64_t *lockedBy) {
|
||||
int64_t tid = taosGetSelfPthreadId();
|
||||
int i = 0;
|
||||
while (atomic_val_compare_exchange_64(lockedBy, 0, tid) != 0) {
|
||||
if (++i % 100 == 0) {
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tscUnlockByThread(int64_t *lockedBy) {
|
||||
int64_t tid = taosGetSelfPthreadId();
|
||||
if (atomic_val_compare_exchange_64(lockedBy, tid, 0) != tid) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
@ -1666,7 +1710,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize);
|
||||
if (ret != 0) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
tfree(pMemoryBuf);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1680,7 +1724,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub);
|
||||
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1890,7 +1934,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
|||
(*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code);
|
||||
} else { // regular super table query
|
||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1968,7 +2012,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
|||
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
||||
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
||||
} else {
|
||||
tscQueueAsyncRes(pParentSql);
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2093,7 +2137,15 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo
|
|||
return pNew;
|
||||
}
|
||||
|
||||
// todo there is are race condition in this function, while cancel is called by user.
|
||||
void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
||||
// the param may be null, since it may be done by other query threads. and the asyncOnError may enter in this
|
||||
// function while kill query by a user.
|
||||
if (param == NULL) {
|
||||
assert(code != TSDB_CODE_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
SRetrieveSupport *trsupport = (SRetrieveSupport *) param;
|
||||
|
||||
SSqlObj* pParentSql = trsupport->pParentSql;
|
||||
|
@ -2220,7 +2272,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
(*pParentObj->fp)(pParentObj->param, pParentObj, v);
|
||||
} else {
|
||||
if (!needRetryInsert(pParentObj, numOfSub)) {
|
||||
tscQueueAsyncRes(pParentObj);
|
||||
tscAsyncResultOnError(pParentObj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2231,7 +2283,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
numOfFailed += 1;
|
||||
|
||||
// clean up tableMeta in cache
|
||||
tscFreeQueryInfo(&pSql->cmd, true);
|
||||
tscFreeQueryInfo(&pSql->cmd);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0);
|
||||
STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0);
|
||||
tscAddTableMetaInfo(pQueryInfo, pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL);
|
||||
|
@ -2243,15 +2295,16 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
tscError("%p Async insertion completed, total inserted:%d rows, numOfFailed:%d, numOfTotal:%d", pParentObj,
|
||||
pParentObj->res.numOfRows, numOfFailed, numOfSub);
|
||||
|
||||
tscDebug("%p cleanup %d tableMeta in cache", pParentObj, pParentObj->cmd.numOfTables);
|
||||
tscDebug("%p cleanup %d tableMeta in hashTable", pParentObj, pParentObj->cmd.numOfTables);
|
||||
for(int32_t i = 0; i < pParentObj->cmd.numOfTables; ++i) {
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pParentObj->cmd.pTableMetaList[i]), true);
|
||||
char* name = pParentObj->cmd.pTableNameList[i];
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
}
|
||||
|
||||
pParentObj->cmd.parseFinished = false;
|
||||
pParentObj->subState.numOfRemain = numOfFailed;
|
||||
|
||||
tscResetSqlCmdObj(&pParentObj->cmd, false);
|
||||
tscResetSqlCmdObj(&pParentObj->cmd);
|
||||
|
||||
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
|
||||
// 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly.
|
||||
|
@ -2264,7 +2317,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pParentObj->res.code = code;
|
||||
tscQueueAsyncRes(pParentObj);
|
||||
tscAsyncResultOnError(pParentObj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2288,7 +2341,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) {
|
|||
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
||||
|
||||
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return code; // here the pSql may have been released already.
|
||||
}
|
||||
|
||||
|
@ -2481,7 +2534,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2496,7 +2549,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
|
||||
if (pRes->tsrow == NULL || pRes->buffer == NULL || pRes->length == NULL) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2508,7 +2561,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
||||
} else {
|
||||
tscQueueAsyncRes(pSql);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,15 +31,20 @@
|
|||
#include "tlocale.h"
|
||||
|
||||
// global, not configurable
|
||||
SCacheObj *tscMetaCache; // table meta cache
|
||||
SHashObj *tscHashMap; // hash map to keep the global vgroup info
|
||||
int tscObjRef = -1;
|
||||
void *tscTmr;
|
||||
void *tscQhandle;
|
||||
void *tscCheckDiskUsageTmr;
|
||||
int tscRefId = -1;
|
||||
int tscNumOfObj = 0; // number of sqlObj in current process.
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
#define TSC_VAR_RELEASED 0
|
||||
|
||||
int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
||||
|
||||
SHashObj *tscVgroupMap; // hash map to keep the global vgroup info
|
||||
SHashObj *tscTableMetaInfo; // table meta info
|
||||
int32_t tscObjRef = -1;
|
||||
void *tscTmr;
|
||||
void *tscQhandle;
|
||||
int32_t tscRefId = -1;
|
||||
int32_t tscNumOfObj = 0; // number of sqlObj in current process.
|
||||
|
||||
static void *tscCheckDiskUsageTmr;
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
|
||||
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
||||
|
@ -129,11 +134,11 @@ void taos_init_imp(void) {
|
|||
taosTmrReset(tscCheckDiskUsage, 10, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||
}
|
||||
|
||||
int64_t refreshTime = 10; // 10 seconds by default
|
||||
if (tscMetaCache == NULL) {
|
||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
||||
if (tscTableMetaInfo == NULL) {
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
tscHashMap = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
tscVgroupMap = taosHashInit(256, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
tscTableMetaInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
tscDebug("TableMeta:%p", tscTableMetaInfo);
|
||||
}
|
||||
|
||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||
|
@ -151,30 +156,38 @@ void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
|||
void taos_cleanup(void) {
|
||||
tscDebug("start to cleanup client environment");
|
||||
|
||||
void* m = tscMetaCache;
|
||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscMetaCache, m, 0) == m) {
|
||||
taosCacheCleanup(m);
|
||||
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int refId = atomic_exchange_32(&tscObjRef, -1);
|
||||
if (refId != -1) {
|
||||
taosCloseRef(refId);
|
||||
}
|
||||
taosHashCleanup(tscTableMetaInfo);
|
||||
tscTableMetaInfo = NULL;
|
||||
|
||||
m = tscQhandle;
|
||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscQhandle, m, 0) == m) {
|
||||
taosCleanUpScheduler(m);
|
||||
}
|
||||
taosHashCleanup(tscVgroupMap);
|
||||
tscVgroupMap = NULL;
|
||||
|
||||
int32_t id = tscObjRef;
|
||||
tscObjRef = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
void* p = tscQhandle;
|
||||
tscQhandle = NULL;
|
||||
taosCleanUpScheduler(p);
|
||||
|
||||
id = tscRefId;
|
||||
tscRefId = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
taosCloseRef(tscRefId);
|
||||
taosCleanupKeywordsTable();
|
||||
taosCloseLog();
|
||||
if (tscEmbedded == 0) rpcCleanup();
|
||||
|
||||
m = tscTmr;
|
||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscTmr, m, 0) == m) {
|
||||
taosTmrCleanUp(m);
|
||||
if (tscEmbedded == 0) {
|
||||
rpcCleanup();
|
||||
}
|
||||
|
||||
p = tscTmr;
|
||||
tscTmr = NULL;
|
||||
taosTmrCleanUp(p);
|
||||
}
|
||||
|
||||
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "os.h"
|
||||
#include "qAst.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
#include "tkey.h"
|
||||
#include "tmd5.h"
|
||||
#include "tscLocalMerge.h"
|
||||
|
@ -31,7 +30,7 @@
|
|||
#include "ttokendef.h"
|
||||
|
||||
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
|
||||
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache);
|
||||
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo);
|
||||
|
||||
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
||||
if (pTagCond->pCond == NULL) {
|
||||
|
@ -72,6 +71,7 @@ void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBufferWriter* bw) {
|
|||
|
||||
bool tscQueryTags(SQueryInfo* pQueryInfo) {
|
||||
int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
int32_t functId = pExpr->functionId;
|
||||
|
@ -315,7 +315,7 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
|||
} else {
|
||||
for (int32_t k = 0; k < pRes->numOfRows; ++k) {
|
||||
char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes;
|
||||
memcpy(p, &pInfo->pSqlExpr->param[1].i64Key, pInfo->field.bytes);
|
||||
memcpy(p, &pInfo->pSqlExpr->param[1].i64, pInfo->field.bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -379,17 +379,16 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
|||
pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free
|
||||
}
|
||||
|
||||
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache) {
|
||||
void tscFreeQueryInfo(SSqlCmd* pCmd) {
|
||||
if (pCmd == NULL || pCmd->numOfClause == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
|
||||
char* addr = (char*)pCmd - offsetof(SSqlObj, cmd);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
||||
|
||||
freeQueryInfoImpl(pQueryInfo);
|
||||
clearAllTableMetaInfo(pQueryInfo, (const char*)addr, removeFromCache);
|
||||
clearAllTableMetaInfo(pQueryInfo);
|
||||
tfree(pQueryInfo);
|
||||
}
|
||||
|
||||
|
@ -397,7 +396,7 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache) {
|
|||
tfree(pCmd->pQueryInfo);
|
||||
}
|
||||
|
||||
void tscResetSqlCmdObj(SSqlCmd* pCmd, bool removeFromCache) {
|
||||
void tscResetSqlCmdObj(SSqlCmd* pCmd) {
|
||||
pCmd->command = 0;
|
||||
pCmd->numOfCols = 0;
|
||||
pCmd->count = 0;
|
||||
|
@ -407,17 +406,17 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd, bool removeFromCache) {
|
|||
pCmd->autoCreated = 0;
|
||||
|
||||
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
||||
if (pCmd->pTableMetaList && pCmd->pTableMetaList[i]) {
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pCmd->pTableMetaList[i]), false);
|
||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||
tfree(pCmd->pTableNameList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pCmd->numOfTables = 0;
|
||||
tfree(pCmd->pTableMetaList);
|
||||
tfree(pCmd->pTableNameList);
|
||||
|
||||
pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList);
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
tscFreeQueryInfo(pCmd, removeFromCache);
|
||||
tscFreeQueryInfo(pCmd);
|
||||
}
|
||||
|
||||
void tscFreeSqlResult(SSqlObj* pSql) {
|
||||
|
@ -460,22 +459,24 @@ void tscFreeRegisteredSqlObj(void *pSql) {
|
|||
|
||||
assert(RID_VALID(p->self));
|
||||
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfObj, 1);
|
||||
int32_t total = atomic_sub_fetch_32(&tscNumOfObj, 1);
|
||||
|
||||
tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total);
|
||||
tscFreeSqlObj(p);
|
||||
taosReleaseRef(tscRefId, pTscObj->rid);
|
||||
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfObj, 1);
|
||||
int32_t total = atomic_sub_fetch_32(&tscNumOfObj, 1);
|
||||
tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total);
|
||||
}
|
||||
|
||||
void tscFreeTableMetaHelper(void *pTableMeta) {
|
||||
STableMeta* p = (STableMeta*) pTableMeta;
|
||||
void tscFreeMetaSqlObj(int64_t *rid){
|
||||
if (RID_VALID(*rid)) {
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, *rid);
|
||||
if (pSql) {
|
||||
taosRemoveRef(tscObjRef, *rid);
|
||||
taosReleaseRef(tscObjRef, *rid);
|
||||
}
|
||||
|
||||
int32_t numOfEps1 = p->corVgroupInfo.numOfEps;
|
||||
assert(numOfEps1 >= 0 && numOfEps1 <= TSDB_MAX_REPLICA);
|
||||
|
||||
for(int32_t i = 0; i < numOfEps1; ++i) {
|
||||
tfree(p->corVgroupInfo.epAddr[i].fqdn);
|
||||
*rid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,6 +489,9 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
|
||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
|
||||
tscFreeMetaSqlObj(&pSql->metaRid);
|
||||
tscFreeMetaSqlObj(&pSql->svgroupRid);
|
||||
|
||||
tscFreeSubobj(pSql);
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
@ -506,7 +510,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
pSql->self = 0;
|
||||
|
||||
tscFreeSqlResult(pSql);
|
||||
tscResetSqlCmdObj(pCmd, false);
|
||||
tscResetSqlCmdObj(pCmd);
|
||||
|
||||
tfree(pCmd->tagData.data);
|
||||
pCmd->tagData.dataLen = 0;
|
||||
|
@ -516,6 +520,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
pCmd->allocSize = 0;
|
||||
|
||||
tsem_destroy(&pSql->rspSem);
|
||||
memset(pSql, 0, sizeof(*pSql));
|
||||
free(pSql);
|
||||
}
|
||||
|
||||
|
@ -529,7 +534,7 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
|
|||
|
||||
// free the refcount for metermeta
|
||||
if (pDataBlock->pTableMeta != NULL) {
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pDataBlock->pTableMeta), false);
|
||||
tfree(pDataBlock->pTableMeta);
|
||||
}
|
||||
|
||||
tfree(pDataBlock);
|
||||
|
@ -600,15 +605,15 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
|||
|
||||
// set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache
|
||||
if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) {
|
||||
tstrncpy(pTableMetaInfo->name, pDataBlock->tableId, sizeof(pTableMetaInfo->name));
|
||||
tstrncpy(pTableMetaInfo->name, pDataBlock->tableName, sizeof(pTableMetaInfo->name));
|
||||
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
}
|
||||
|
||||
pTableMetaInfo->pTableMeta = taosCacheTransfer(tscMetaCache, (void**)&pDataBlock->pTableMeta);
|
||||
pTableMetaInfo->pTableMeta = tscTableMetaClone(pDataBlock->pTableMeta);
|
||||
} else {
|
||||
assert(strncmp(pTableMetaInfo->name, pDataBlock->tableId, tListLen(pDataBlock->tableId)) == 0);
|
||||
assert(strncmp(pTableMetaInfo->name, pDataBlock->tableName, tListLen(pDataBlock->tableName)) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -671,14 +676,10 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff
|
|||
dataBuf->size = startOffset;
|
||||
dataBuf->tsSource = -1;
|
||||
|
||||
tstrncpy(dataBuf->tableId, name, sizeof(dataBuf->tableId));
|
||||
tstrncpy(dataBuf->tableName, name, sizeof(dataBuf->tableName));
|
||||
|
||||
/*
|
||||
* The table meta may be released since the table meta cache are completed clean by other thread
|
||||
* due to operation such as drop database. So here we add the reference count directly instead of invoke
|
||||
* taosGetDataFromCache, which may return NULL value.
|
||||
*/
|
||||
dataBuf->pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMeta);
|
||||
//Here we keep the tableMeta to avoid it to be remove by other threads.
|
||||
dataBuf->pTableMeta = tscTableMetaClone(pTableMeta);
|
||||
assert(initialSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
|
||||
|
||||
*dataBlocks = dataBuf;
|
||||
|
@ -784,15 +785,15 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static void extractTableMeta(SSqlCmd* pCmd) {
|
||||
static void extractTableNameList(SSqlCmd* pCmd) {
|
||||
pCmd->numOfTables = (int32_t) taosHashGetSize(pCmd->pTableBlockHashList);
|
||||
pCmd->pTableMetaList = calloc(pCmd->numOfTables, POINTER_BYTES);
|
||||
pCmd->pTableNameList = calloc(pCmd->numOfTables, POINTER_BYTES);
|
||||
|
||||
STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||
int32_t i = 0;
|
||||
while(p1) {
|
||||
STableDataBlocks* pBlocks = *p1;
|
||||
pCmd->pTableMetaList[i++] = taosCacheTransfer(tscMetaCache, (void**) &pBlocks->pTableMeta);
|
||||
pCmd->pTableNameList[i++] = strndup(pBlocks->tableName, TSDB_TABLE_FNAME_LEN);
|
||||
p1 = taosHashIterate(pCmd->pTableBlockHashList, p1);
|
||||
}
|
||||
|
||||
|
@ -815,7 +816,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
|||
STableDataBlocks* dataBuf = NULL;
|
||||
|
||||
int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
||||
INSERT_HEAD_SIZE, 0, pOneTableBlock->tableId, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList);
|
||||
INSERT_HEAD_SIZE, 0, pOneTableBlock->tableName, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
|
||||
taosHashCleanup(pVnodeDataBlockHashList);
|
||||
|
@ -849,7 +850,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
|||
tscSortRemoveDataBlockDupRows(pOneTableBlock);
|
||||
char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
||||
|
||||
tscDebug("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId,
|
||||
tscDebug("%p name:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableName,
|
||||
pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey));
|
||||
|
||||
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||
|
@ -879,7 +880,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
|||
pOneTableBlock = *p;
|
||||
}
|
||||
|
||||
extractTableMeta(pCmd);
|
||||
extractTableNameList(pCmd);
|
||||
|
||||
// free the table data blocks;
|
||||
pCmd->pDataBlocks = pVnodeDataBlockList;
|
||||
|
@ -900,6 +901,7 @@ void tscCloseTscObj(void *param) {
|
|||
rpcClose(pObj->pDnodeConn);
|
||||
pObj->pDnodeConn = NULL;
|
||||
}
|
||||
|
||||
tfree(pObj->tscCorMgmtEpSet);
|
||||
pthread_mutex_destroy(&pObj->mutex);
|
||||
|
||||
|
@ -1528,6 +1530,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
|
|||
}
|
||||
|
||||
dest->tbnameCond.uid = src->tbnameCond.uid;
|
||||
dest->tbnameCond.len = src->tbnameCond.len;
|
||||
|
||||
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
|
||||
dest->relType = src->relType;
|
||||
|
@ -1823,14 +1826,12 @@ SArray* tscVgroupTableInfoClone(SArray* pVgroupTables) {
|
|||
return pa;
|
||||
}
|
||||
|
||||
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) {
|
||||
tscDebug("%p unref %d tables in the tableMeta cache", address, pQueryInfo->numOfTables);
|
||||
|
||||
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo) {
|
||||
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||
|
||||
tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables);
|
||||
tscClearTableMetaInfo(pTableMetaInfo, removeFromCache);
|
||||
tscClearTableMetaInfo(pTableMetaInfo);
|
||||
free(pTableMetaInfo);
|
||||
}
|
||||
|
||||
|
@ -1884,14 +1885,12 @@ STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo* pQueryInfo) {
|
|||
return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache) {
|
||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo) {
|
||||
if (pTableMetaInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), removeFromCache);
|
||||
}
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
||||
tscColumnListDestroy(pTableMetaInfo->tagColList);
|
||||
|
@ -2015,7 +2014,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
|
||||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->signature = pNew;
|
||||
pNew->sqlstr = NULL;
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
|
||||
SSqlCmd* pnCmd = &pNew->cmd;
|
||||
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
|
||||
|
@ -2031,7 +2030,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
|
||||
pnCmd->numOfTables = 0;
|
||||
pnCmd->parseFinished = 1;
|
||||
pnCmd->pTableMetaList = NULL;
|
||||
pnCmd->pTableNameList = NULL;
|
||||
pnCmd->pTableBlockHashList = NULL;
|
||||
|
||||
if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -2113,8 +2112,8 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
char* name = pTableMetaInfo->name;
|
||||
STableMetaInfo* pFinalInfo = NULL;
|
||||
|
||||
if (pPrevSql == NULL) { // get by name may failed due to the cache cleanup
|
||||
STableMeta* pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMetaInfo->pTableMeta);
|
||||
if (pPrevSql == NULL) {
|
||||
STableMeta* pTableMeta = tscTableMetaClone(pTableMetaInfo->pTableMeta);
|
||||
assert(pTableMeta != NULL);
|
||||
|
||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupList,
|
||||
|
@ -2122,15 +2121,15 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
||||
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
|
||||
|
||||
STableMeta* pPrevTableMeta = taosCacheTransfer(tscMetaCache, (void**)&pPrevInfo->pTableMeta);
|
||||
|
||||
STableMeta* pPrevTableMeta = tscTableMetaClone(pPrevInfo->pTableMeta);
|
||||
SVgroupsInfo* pVgroupsInfo = pPrevInfo->vgroupList;
|
||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pPrevTableMeta, pVgroupsInfo, pTableMetaInfo->tagColList,
|
||||
pTableMetaInfo->pVgroupTables);
|
||||
}
|
||||
|
||||
// this case cannot be happened
|
||||
if (pFinalInfo->pTableMeta == NULL) {
|
||||
tscError("%p new subquery failed since no tableMeta in cache, name:%s", pSql, name);
|
||||
tscError("%p new subquery failed since no tableMeta, name:%s", pSql, name);
|
||||
|
||||
if (pPrevSql != NULL) { // pass the previous error to client
|
||||
assert(pPrevSql->res.code != TSDB_CODE_SUCCESS);
|
||||
|
@ -2210,7 +2209,9 @@ void tscDoQuery(SSqlObj* pSql) {
|
|||
tscProcessSql(pSql);
|
||||
} else { // secondary stage join query.
|
||||
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
|
||||
tscLockByThread(&pSql->squeryLock);
|
||||
tscHandleMasterSTableQuery(pSql);
|
||||
tscUnlockByThread(&pSql->squeryLock);
|
||||
} else {
|
||||
tscProcessSql(pSql);
|
||||
}
|
||||
|
@ -2219,7 +2220,9 @@ void tscDoQuery(SSqlObj* pSql) {
|
|||
|
||||
return;
|
||||
} else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
|
||||
tscLockByThread(&pSql->squeryLock);
|
||||
tscHandleMasterSTableQuery(pSql);
|
||||
tscUnlockByThread(&pSql->squeryLock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2557,6 +2560,7 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) {
|
|||
for(int32_t j = 0; j < pVgroupInfo->numOfEps; ++j) {
|
||||
tfree(pVgroupInfo->epAddr[j].fqdn);
|
||||
}
|
||||
|
||||
for(int32_t j = pVgroupInfo->numOfEps; j < TSDB_MAX_REPLICA; j++) {
|
||||
assert( pVgroupInfo->epAddr[j].fqdn == NULL );
|
||||
}
|
||||
|
@ -2610,3 +2614,87 @@ int32_t copyTagData(STagData* dst, const STagData* src) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STableMeta* createSuperTableMeta(STableMetaMsg* pChild) {
|
||||
assert(pChild != NULL);
|
||||
int32_t total = pChild->numOfColumns + pChild->numOfTags;
|
||||
|
||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * total);
|
||||
pTableMeta->tableType = TSDB_SUPER_TABLE;
|
||||
pTableMeta->tableInfo.numOfTags = pChild->numOfTags;
|
||||
pTableMeta->tableInfo.numOfColumns = pChild->numOfColumns;
|
||||
pTableMeta->tableInfo.precision = pChild->precision;
|
||||
|
||||
pTableMeta->id.tid = 0;
|
||||
pTableMeta->id.uid = pChild->suid;
|
||||
pTableMeta->tversion = pChild->tversion;
|
||||
pTableMeta->sversion = pChild->sversion;
|
||||
|
||||
memcpy(pTableMeta->schema, pChild->schema, sizeof(SSchema) * total);
|
||||
|
||||
int32_t num = pTableMeta->tableInfo.numOfColumns;
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||
}
|
||||
|
||||
return pTableMeta;
|
||||
}
|
||||
|
||||
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta) {
|
||||
assert(pTableMeta != NULL);
|
||||
|
||||
int32_t totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags;
|
||||
return sizeof(STableMeta) + totalCols * sizeof(SSchema);
|
||||
}
|
||||
|
||||
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta) {
|
||||
assert(pTableMeta != NULL);
|
||||
|
||||
CChildTableMeta* cMeta = calloc(1, sizeof(CChildTableMeta));
|
||||
cMeta->tableType = TSDB_CHILD_TABLE;
|
||||
cMeta->vgId = pTableMeta->vgId;
|
||||
cMeta->id = pTableMeta->id;
|
||||
tstrncpy(cMeta->sTableName, pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
return cMeta;
|
||||
}
|
||||
|
||||
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) {
|
||||
assert(pChild != NULL);
|
||||
|
||||
uint32_t size = tscGetTableMetaMaxSize();
|
||||
STableMeta* p = calloc(1, size);
|
||||
|
||||
taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1);
|
||||
if (p->id.uid > 0) { // tableMeta exists, build child table meta and return
|
||||
pChild->sversion = p->sversion;
|
||||
pChild->tversion = p->tversion;
|
||||
|
||||
memcpy(&pChild->tableInfo, &p->tableInfo, sizeof(STableInfo));
|
||||
int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags;
|
||||
|
||||
memcpy(pChild->schema, p->schema, sizeof(SSchema) *total);
|
||||
|
||||
tfree(p);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else { // super table has been removed, current tableMeta is also expired. remove it here
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
|
||||
tfree(p);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t tscGetTableMetaMaxSize() {
|
||||
return sizeof(STableMeta) + TSDB_MAX_COLUMNS * sizeof(SSchema);
|
||||
}
|
||||
|
||||
STableMeta* tscTableMetaClone(STableMeta* pTableMeta) {
|
||||
assert(pTableMeta != NULL);
|
||||
uint32_t size = tscGetTableMetaSize(pTableMeta);
|
||||
STableMeta* p = calloc(1, size);
|
||||
memcpy(p, pTableMeta, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest)
|
||||
|
|
|
@ -162,6 +162,10 @@ TEST(testCase, parse_time) {
|
|||
|
||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
||||
|
||||
char* t = "2021-01-08T02:11:40.000+00:00";
|
||||
taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
printf("%ld\n", time);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
|
|
@ -36,6 +36,7 @@ extern int8_t tsEnableVnodeBak;
|
|||
extern int8_t tsEnableTelemetryReporting;
|
||||
extern char tsEmail[];
|
||||
extern char tsArbitrator[];
|
||||
extern int8_t tsArbOnline;
|
||||
|
||||
// common
|
||||
extern int tsRpcTimer;
|
||||
|
@ -62,7 +63,6 @@ extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked
|
|||
extern int8_t tsKeepOriginalColumnName;
|
||||
|
||||
// client
|
||||
extern int32_t tsTableMetaKeepTimer;
|
||||
extern int32_t tsMaxSQLStringLen;
|
||||
extern int8_t tsTscEnableRecordSql;
|
||||
extern int32_t tsMaxNumOfOrderedResults;
|
||||
|
@ -190,7 +190,7 @@ extern int32_t monDebugFlag;
|
|||
extern int32_t uDebugFlag;
|
||||
extern int32_t rpcDebugFlag;
|
||||
extern int32_t odbcDebugFlag;
|
||||
extern int32_t qDebugFlag;
|
||||
extern uint32_t qDebugFlag;
|
||||
extern int32_t wDebugFlag;
|
||||
extern int32_t cqDebugFlag;
|
||||
extern int32_t debugFlag;
|
||||
|
|
|
@ -28,7 +28,8 @@ typedef struct tVariant {
|
|||
uint32_t nType;
|
||||
int32_t nLen; // only used for string, for number, it is useless
|
||||
union {
|
||||
int64_t i64Key;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
double dKey;
|
||||
char * pz;
|
||||
wchar_t *wpz;
|
||||
|
@ -36,9 +37,9 @@ typedef struct tVariant {
|
|||
};
|
||||
} tVariant;
|
||||
|
||||
void tVariantCreate(tVariant *pVar, SStrToken *token);
|
||||
bool tVariantIsValid(tVariant *pVar);
|
||||
|
||||
void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type);
|
||||
void tVariantCreate(tVariant *pVar, SStrToken *token);
|
||||
|
||||
void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32_t type);
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ int32_t tsStatusInterval = 1; // second
|
|||
int32_t tsNumOfMnodes = 3;
|
||||
int8_t tsEnableVnodeBak = 1;
|
||||
int8_t tsEnableTelemetryReporting = 1;
|
||||
int8_t tsArbOnline = 0;
|
||||
char tsEmail[TSDB_FQDN_LEN] = {0};
|
||||
|
||||
// common
|
||||
|
@ -71,7 +72,6 @@ char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
|
|||
int32_t tsCompressMsgSize = -1;
|
||||
|
||||
// client
|
||||
int32_t tsTableMetaKeepTimer = 7200; // second
|
||||
int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN;
|
||||
int8_t tsTscEnableRecordSql = 0;
|
||||
|
||||
|
@ -218,7 +218,7 @@ int32_t odbcDebugFlag = 131;
|
|||
int32_t httpDebugFlag = 131;
|
||||
int32_t mqttDebugFlag = 131;
|
||||
int32_t monDebugFlag = 131;
|
||||
int32_t qDebugFlag = 131;
|
||||
uint32_t qDebugFlag = 131;
|
||||
int32_t rpcDebugFlag = 131;
|
||||
int32_t uDebugFlag = 131;
|
||||
int32_t debugFlag = 0;
|
||||
|
@ -595,16 +595,6 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "tableMetaKeepTimer";
|
||||
cfg.ptr = &tsTableMetaKeepTimer;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
|
||||
cfg.minValue = 1;
|
||||
cfg.maxValue = 8640000;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_SECOND;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "minSlidingTime";
|
||||
cfg.ptr = &tsMinSlidingTime;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
|
@ -810,8 +800,8 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.ptr = &tsQuorum;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = TSDB_MIN_DB_REPLICA_OPTION;
|
||||
cfg.maxValue = TSDB_MAX_DB_REPLICA_OPTION;
|
||||
cfg.minValue = TSDB_MIN_DB_QUORUM_OPTION;
|
||||
cfg.maxValue = TSDB_MAX_DB_QUORUM_OPTION;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "ttokendef.h"
|
||||
#include "tscompression.h"
|
||||
|
||||
const int32_t TYPE_BYTES[11] = {
|
||||
const int32_t TYPE_BYTES[15] = {
|
||||
-1, // TSDB_DATA_TYPE_NULL
|
||||
sizeof(int8_t), // TSDB_DATA_TYPE_BOOL
|
||||
sizeof(int8_t), // TSDB_DATA_TYPE_TINYINT
|
||||
|
@ -29,10 +29,28 @@ const int32_t TYPE_BYTES[11] = {
|
|||
sizeof(double), // TSDB_DATA_TYPE_DOUBLE
|
||||
sizeof(VarDataOffsetT), // TSDB_DATA_TYPE_BINARY
|
||||
sizeof(TSKEY), // TSDB_DATA_TYPE_TIMESTAMP
|
||||
sizeof(VarDataOffsetT) // TSDB_DATA_TYPE_NCHAR
|
||||
sizeof(VarDataOffsetT), // TSDB_DATA_TYPE_NCHAR
|
||||
sizeof(uint8_t), // TSDB_DATA_TYPE_UTINYINT
|
||||
sizeof(uint16_t), // TSDB_DATA_TYPE_USMALLINT
|
||||
sizeof(uint32_t), // TSDB_DATA_TYPE_UINT
|
||||
sizeof(uint64_t), // TSDB_DATA_TYPE_UBIGINT
|
||||
};
|
||||
|
||||
static void getStatics_bool(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
#define DO_STATICS(__sum, __min, __max, __minIndex, __maxIndex, _list, _index) \
|
||||
do { \
|
||||
(__sum) += (_list)[(_index)]; \
|
||||
if ((__min) > (_list)[(_index)]) { \
|
||||
(__min) = (_list)[(_index)]; \
|
||||
(__minIndex) = (_index); \
|
||||
} \
|
||||
\
|
||||
if ((__max) < (_list)[(_index)]) { \
|
||||
(__max) = (_list)[(_index)]; \
|
||||
(__maxIndex) = (_index); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void getStatics_bool(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
int8_t *data = (int8_t *)pData;
|
||||
*min = INT64_MAX;
|
||||
|
@ -43,26 +61,17 @@ static void getStatics_bool(const TSKEY *primaryKey, const void *pData, int32_t
|
|||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((char *)&data[i], TSDB_DATA_TYPE_BOOL)) {
|
||||
if (data[i] == TSDB_DATA_BOOL_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*sum += data[i];
|
||||
if (*min > data[i]) {
|
||||
*min = data[i];
|
||||
*minIndex = i;
|
||||
}
|
||||
|
||||
if (*max < data[i]) {
|
||||
*max = data[i];
|
||||
*maxIndex = i;
|
||||
}
|
||||
|
||||
DO_STATICS(*sum, *min, *max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void getStatics_i8(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
static void getStatics_i8(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
int8_t *data = (int8_t *)pData;
|
||||
*min = INT64_MAX;
|
||||
*max = INT64_MIN;
|
||||
|
@ -72,26 +81,43 @@ static void getStatics_i8(const TSKEY *primaryKey, const void *pData, int32_t nu
|
|||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((char *)&data[i], TSDB_DATA_TYPE_TINYINT)) {
|
||||
if (((uint8_t)data[i]) == TSDB_DATA_TINYINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*sum += data[i];
|
||||
if (*min > data[i]) {
|
||||
*min = data[i];
|
||||
*minIndex = i;
|
||||
}
|
||||
|
||||
if (*max < data[i]) {
|
||||
*max = data[i];
|
||||
*maxIndex = i;
|
||||
}
|
||||
|
||||
DO_STATICS(*sum, *min, *max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void getStatics_i16(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
static void getStatics_u8(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
uint8_t *data = (uint8_t *)pData;
|
||||
uint64_t _min = UINT64_MAX;
|
||||
uint64_t _max = 0;
|
||||
uint64_t _sum = 0;
|
||||
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (((uint8_t)data[i]) == TSDB_DATA_UTINYINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
DO_STATICS(_sum, _min, _max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
|
||||
*min = _min;
|
||||
*max = _max;
|
||||
*sum = _sum;
|
||||
}
|
||||
|
||||
static void getStatics_i16(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
int16_t *data = (int16_t *)pData;
|
||||
*min = INT64_MAX;
|
||||
*max = INT64_MIN;
|
||||
|
@ -100,39 +126,45 @@ static void getStatics_i16(const TSKEY *primaryKey, const void *pData, int32_t n
|
|||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
// int64_t lastKey = 0;
|
||||
// int16_t lastVal = TSDB_DATA_SMALLINT_NULL;
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((const char*) &data[i], TSDB_DATA_TYPE_SMALLINT)) {
|
||||
if (((uint16_t)data[i]) == TSDB_DATA_SMALLINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*sum += data[i];
|
||||
if (*min > data[i]) {
|
||||
*min = data[i];
|
||||
*minIndex = i;
|
||||
}
|
||||
|
||||
if (*max < data[i]) {
|
||||
*max = data[i];
|
||||
*maxIndex = i;
|
||||
}
|
||||
|
||||
// if (isNull(&lastVal, TSDB_DATA_TYPE_SMALLINT)) {
|
||||
// lastKey = primaryKey[i];
|
||||
// lastVal = data[i];
|
||||
// } else {
|
||||
// *wsum = lastVal * (primaryKey[i] - lastKey);
|
||||
// lastKey = primaryKey[i];
|
||||
// lastVal = data[i];
|
||||
// }
|
||||
|
||||
DO_STATICS(*sum, *min, *max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void getStatics_i32(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
static void getStatics_u16(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
uint16_t *data = (uint16_t *)pData;
|
||||
uint64_t _min = UINT64_MAX;
|
||||
uint64_t _max = 0;
|
||||
uint64_t _sum = 0;
|
||||
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (((uint16_t)data[i]) == TSDB_DATA_USMALLINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
DO_STATICS(_sum, _min, _max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
|
||||
*min = _min;
|
||||
*max = _max;
|
||||
*sum = _sum;
|
||||
}
|
||||
|
||||
static void getStatics_i32(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
int32_t *data = (int32_t *)pData;
|
||||
*min = INT64_MAX;
|
||||
*max = INT64_MIN;
|
||||
|
@ -141,29 +173,43 @@ static void getStatics_i32(const TSKEY *primaryKey, const void *pData, int32_t n
|
|||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
// int64_t lastKey = 0;
|
||||
// int32_t lastVal = TSDB_DATA_INT_NULL;
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((const char*) &data[i], TSDB_DATA_TYPE_INT)) {
|
||||
if (((uint32_t)data[i]) == TSDB_DATA_INT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*sum += data[i];
|
||||
if (*min > data[i]) {
|
||||
*min = data[i];
|
||||
*minIndex = i;
|
||||
}
|
||||
|
||||
if (*max < data[i]) {
|
||||
*max = data[i];
|
||||
*maxIndex = i;
|
||||
}
|
||||
|
||||
DO_STATICS(*sum, *min, *max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void getStatics_i64(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
static void getStatics_u32(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
uint32_t *data = (uint32_t *)pData;
|
||||
uint64_t _min = UINT64_MAX;
|
||||
uint64_t _max = 0;
|
||||
uint64_t _sum = 0;
|
||||
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (((uint32_t)data[i]) == TSDB_DATA_UINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
DO_STATICS(_sum, _min, _max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
|
||||
*min = _min;
|
||||
*max = _max;
|
||||
*sum = _sum;
|
||||
}
|
||||
|
||||
static void getStatics_i64(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
int64_t *data = (int64_t *)pData;
|
||||
*min = INT64_MAX;
|
||||
|
@ -174,52 +220,60 @@ static void getStatics_i64(const TSKEY *primaryKey, const void *pData, int32_t n
|
|||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((const char*) &data[i], TSDB_DATA_TYPE_BIGINT)) {
|
||||
if (((uint64_t)data[i]) == TSDB_DATA_BIGINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*sum += data[i];
|
||||
if (*min > data[i]) {
|
||||
*min = data[i];
|
||||
*minIndex = i;
|
||||
}
|
||||
|
||||
if (*max < data[i]) {
|
||||
*max = data[i];
|
||||
*maxIndex = i;
|
||||
}
|
||||
|
||||
// if (isNull(&lastVal, TSDB_DATA_TYPE_BIGINT)) {
|
||||
// lastKey = primaryKey[i];
|
||||
// lastVal = data[i];
|
||||
// } else {
|
||||
// *wsum = lastVal * (primaryKey[i] - lastKey);
|
||||
// lastKey = primaryKey[i];
|
||||
// lastVal = data[i];
|
||||
// }
|
||||
|
||||
DO_STATICS(*sum, *min, *max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void getStatics_f(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
static void getStatics_u64(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
uint64_t *data = (uint64_t *)pData;
|
||||
uint64_t _min = UINT64_MAX;
|
||||
uint64_t _max = 0;
|
||||
uint64_t _sum = 0;
|
||||
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (((uint64_t)data[i]) == TSDB_DATA_UBIGINT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
DO_STATICS(_sum, _min, _max, *minIndex, *maxIndex, data, i);
|
||||
}
|
||||
|
||||
*min = _min;
|
||||
*max = _max;
|
||||
*sum = _sum;
|
||||
}
|
||||
|
||||
static void getStatics_f(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
float *data = (float *)pData;
|
||||
float fmin = FLT_MAX;
|
||||
float fmax = -FLT_MAX;
|
||||
double dsum = 0;
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
float *data = (float *)pData;
|
||||
float fmin = FLT_MAX;
|
||||
float fmax = -FLT_MAX;
|
||||
double dsum = 0;
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((const char*) &data[i], TSDB_DATA_TYPE_FLOAT)) {
|
||||
if ((*(uint32_t*)&(data[i])) == TSDB_DATA_FLOAT_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
float fv = 0;
|
||||
fv = GET_FLOAT_VAL((const char*)&(data[i]));
|
||||
|
||||
float fv = GET_FLOAT_VAL((const char*)&(data[i]));
|
||||
|
||||
dsum += fv;
|
||||
if (fmin > fv) {
|
||||
fmin = fv;
|
||||
|
@ -232,28 +286,24 @@ static void getStatics_f(const TSKEY *primaryKey, const void *pData, int32_t num
|
|||
}
|
||||
}
|
||||
|
||||
double csum = 0;
|
||||
csum = GET_DOUBLE_VAL((const char *)sum);
|
||||
csum += dsum;
|
||||
|
||||
SET_DOUBLE_VAL(sum, csum);
|
||||
SET_DOUBLE_VAL(sum, dsum);
|
||||
SET_DOUBLE_VAL(max, fmax);
|
||||
SET_DOUBLE_VAL(min, fmin);
|
||||
}
|
||||
|
||||
static void getStatics_d(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
static void getStatics_d(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
double *data = (double *)pData;
|
||||
double dmin = DBL_MAX;
|
||||
double dmax = -DBL_MAX;
|
||||
double dsum = 0;
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
double dmin = DBL_MAX;
|
||||
double dmax = -DBL_MAX;
|
||||
double dsum = 0;
|
||||
*minIndex = 0;
|
||||
*maxIndex = 0;
|
||||
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
||||
for (int32_t i = 0; i < numOfRow; ++i) {
|
||||
if (isNull((const char*) &data[i], TSDB_DATA_TYPE_DOUBLE)) {
|
||||
if ((*(uint64_t*)&(data[i])) == TSDB_DATA_DOUBLE_NULL) {
|
||||
(*numOfNull) += 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -272,16 +322,12 @@ static void getStatics_d(const TSKEY *primaryKey, const void *pData, int32_t num
|
|||
}
|
||||
}
|
||||
|
||||
double csum = 0;
|
||||
csum = GET_DOUBLE_VAL((const char *)sum);
|
||||
csum += dsum;
|
||||
|
||||
SET_DOUBLE_PTR(sum, &csum);
|
||||
SET_DOUBLE_PTR(sum, &dsum);
|
||||
SET_DOUBLE_PTR(max, &dmax);
|
||||
SET_DOUBLE_PTR(min, &dmin);
|
||||
}
|
||||
|
||||
static void getStatics_bin(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
static void getStatics_bin(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
const char* data = pData;
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
@ -301,7 +347,7 @@ static void getStatics_bin(const TSKEY *primaryKey, const void *pData, int32_t n
|
|||
*maxIndex = 0;
|
||||
}
|
||||
|
||||
static void getStatics_nchr(const TSKEY *primaryKey, const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
static void getStatics_nchr(const void *pData, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int16_t *numOfNull) {
|
||||
const char* data = pData;
|
||||
ASSERT(numOfRow <= INT16_MAX);
|
||||
|
@ -321,18 +367,22 @@ static void getStatics_nchr(const TSKEY *primaryKey, const void *pData, int32_t
|
|||
*maxIndex = 0;
|
||||
}
|
||||
|
||||
tDataTypeDescriptor tDataTypeDesc[11] = {
|
||||
{TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE", NULL, NULL, NULL},
|
||||
{TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", tsCompressBool, tsDecompressBool, getStatics_bool},
|
||||
{TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", tsCompressTinyint, tsDecompressTinyint, getStatics_i8},
|
||||
{TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", tsCompressSmallint, tsDecompressSmallint, getStatics_i16},
|
||||
{TSDB_DATA_TYPE_INT, 3, INT_BYTES, "INT", tsCompressInt, tsDecompressInt, getStatics_i32},
|
||||
{TSDB_DATA_TYPE_BIGINT, 6, LONG_BYTES, "BIGINT", tsCompressBigint, tsDecompressBigint, getStatics_i64},
|
||||
{TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", tsCompressFloat, tsDecompressFloat, getStatics_f},
|
||||
{TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", tsCompressDouble, tsDecompressDouble, getStatics_d},
|
||||
{TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", tsCompressString, tsDecompressString, getStatics_bin},
|
||||
{TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", tsCompressTimestamp, tsDecompressTimestamp, getStatics_i64},
|
||||
{TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", tsCompressString, tsDecompressString, getStatics_nchr},
|
||||
tDataTypeDescriptor tDataTypeDesc[15] = {
|
||||
{TSDB_DATA_TYPE_NULL, 6,1, "NOTYPE", NULL, NULL, NULL},
|
||||
{TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", tsCompressBool, tsDecompressBool, getStatics_bool},
|
||||
{TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", tsCompressTinyint, tsDecompressTinyint, getStatics_i8},
|
||||
{TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", tsCompressSmallint, tsDecompressSmallint, getStatics_i16},
|
||||
{TSDB_DATA_TYPE_INT, 3, INT_BYTES, "INT", tsCompressInt, tsDecompressInt, getStatics_i32},
|
||||
{TSDB_DATA_TYPE_BIGINT, 6, LONG_BYTES, "BIGINT", tsCompressBigint, tsDecompressBigint, getStatics_i64},
|
||||
{TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", tsCompressFloat, tsDecompressFloat, getStatics_f},
|
||||
{TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", tsCompressDouble, tsDecompressDouble, getStatics_d},
|
||||
{TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", tsCompressString, tsDecompressString, getStatics_bin},
|
||||
{TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", tsCompressTimestamp, tsDecompressTimestamp, getStatics_i64},
|
||||
{TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", tsCompressString, tsDecompressString, getStatics_nchr},
|
||||
{TSDB_DATA_TYPE_UTINYINT, 16, CHAR_BYTES, "TINYINT UNSIGNED", tsCompressTinyint, tsDecompressTinyint, getStatics_u8},
|
||||
{TSDB_DATA_TYPE_USMALLINT, 17, SHORT_BYTES, "SMALLINT UNSIGNED", tsCompressSmallint, tsDecompressSmallint, getStatics_u16},
|
||||
{TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", tsCompressInt, tsDecompressInt, getStatics_u32},
|
||||
{TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", tsCompressBigint, tsDecompressBigint, getStatics_u64},
|
||||
};
|
||||
|
||||
char tTokenTypeSwitcher[13] = {
|
||||
|
@ -352,7 +402,7 @@ char tTokenTypeSwitcher[13] = {
|
|||
};
|
||||
|
||||
bool isValidDataType(int32_t type) {
|
||||
return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_NCHAR;
|
||||
return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_UBIGINT;
|
||||
}
|
||||
|
||||
void setVardataNull(char* val, int32_t type) {
|
||||
|
@ -397,6 +447,26 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) {
|
|||
*(uint64_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_BIGINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint8_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_UTINYINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint16_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_USMALLINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_UINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint64_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_UBIGINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_FLOAT_NULL;
|
||||
|
@ -422,13 +492,17 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) {
|
|||
}
|
||||
}
|
||||
|
||||
static uint8_t nullBool = TSDB_DATA_BOOL_NULL;
|
||||
static uint8_t nullTinyInt = TSDB_DATA_TINYINT_NULL;
|
||||
static uint16_t nullSmallInt = TSDB_DATA_SMALLINT_NULL;
|
||||
static uint32_t nullInt = TSDB_DATA_INT_NULL;
|
||||
static uint64_t nullBigInt = TSDB_DATA_BIGINT_NULL;
|
||||
static uint32_t nullFloat = TSDB_DATA_FLOAT_NULL;
|
||||
static uint64_t nullDouble = TSDB_DATA_DOUBLE_NULL;
|
||||
static uint8_t nullBool = TSDB_DATA_BOOL_NULL;
|
||||
static uint8_t nullTinyInt = TSDB_DATA_TINYINT_NULL;
|
||||
static uint16_t nullSmallInt = TSDB_DATA_SMALLINT_NULL;
|
||||
static uint32_t nullInt = TSDB_DATA_INT_NULL;
|
||||
static uint64_t nullBigInt = TSDB_DATA_BIGINT_NULL;
|
||||
static uint32_t nullFloat = TSDB_DATA_FLOAT_NULL;
|
||||
static uint64_t nullDouble = TSDB_DATA_DOUBLE_NULL;
|
||||
static uint8_t nullTinyIntu = TSDB_DATA_UTINYINT_NULL;
|
||||
static uint16_t nullSmallIntu = TSDB_DATA_USMALLINT_NULL;
|
||||
static uint32_t nullIntu = TSDB_DATA_UINT_NULL;
|
||||
static uint64_t nullBigIntu = TSDB_DATA_UBIGINT_NULL;
|
||||
|
||||
static union {
|
||||
tstr str;
|
||||
|
@ -436,17 +510,25 @@ static union {
|
|||
} nullBinary = {.str = {.len = 1}}, nullNchar = {.str = {.len = 4}};
|
||||
|
||||
static void *nullValues[] = {
|
||||
&nullBool, &nullTinyInt, &nullSmallInt, &nullInt, &nullBigInt,
|
||||
&nullFloat, &nullDouble, &nullBinary, &nullBigInt, &nullNchar,
|
||||
&nullBool, &nullTinyInt, &nullSmallInt, &nullInt, &nullBigInt,
|
||||
&nullFloat, &nullDouble, &nullBinary, &nullBigInt, &nullNchar,
|
||||
&nullTinyIntu, &nullSmallIntu, &nullIntu, &nullBigIntu,
|
||||
};
|
||||
|
||||
void *getNullValue(int32_t type) {
|
||||
assert(type >= TSDB_DATA_TYPE_BOOL && type <= TSDB_DATA_TYPE_NCHAR);
|
||||
assert(type >= TSDB_DATA_TYPE_BOOL && type <= TSDB_DATA_TYPE_UBIGINT);
|
||||
return nullValues[type - 1];
|
||||
}
|
||||
|
||||
void assignVal(char *val, const char *src, int32_t len, int32_t type) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
*((int8_t *)val) = GET_INT8_VAL(src);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
*((int16_t *)val) = GET_INT16_VAL(src);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
*((int32_t *)val) = GET_INT32_VAL(src);
|
||||
break;
|
||||
|
@ -457,17 +539,10 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) {
|
|||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
SET_DOUBLE_VAL(val, GET_DOUBLE_VAL(src));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
*((int64_t *)val) = GET_INT64_VAL(src);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
*((int16_t *)val) = GET_INT16_VAL(src);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
*((int8_t *)val) = GET_INT8_VAL(src);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
varDataCopy(val, src);
|
||||
break;
|
||||
|
@ -483,12 +558,14 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) {
|
|||
|
||||
void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
SWAP(*(int32_t *)(pLeft), *(int32_t *)(pRight), int32_t);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
SWAP(*(int64_t *)(pLeft), *(int64_t *)(pRight), int64_t);
|
||||
break;
|
||||
|
@ -497,7 +574,8 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
SWAP(*(double *)(pLeft), *(double *)(pRight), double);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
SWAP(*(int16_t *)(pLeft), *(int16_t *)(pRight), int16_t);
|
||||
break;
|
||||
}
|
||||
|
@ -508,7 +586,8 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
SWAP(*(int8_t *)(pLeft), *(int8_t *)(pRight), int8_t);
|
||||
break;
|
||||
}
|
||||
|
@ -521,3 +600,41 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bool issigned) {
|
||||
errno = 0;
|
||||
int32_t ret = 0;
|
||||
|
||||
char* endPtr = NULL;
|
||||
if (type == TK_FLOAT) {
|
||||
double v = strtod(z, &endPtr);
|
||||
if ((errno == ERANGE && v == HUGE_VALF) || isinf(v) || isnan(v)) {
|
||||
ret = -1;
|
||||
} else if ((issigned && (v < INT64_MIN || v > INT64_MAX)) || ((!issigned) && (v < 0 || v > UINT64_MAX))) {
|
||||
ret = -1;
|
||||
} else {
|
||||
*value = (int64_t) round(v);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t radix = 10;
|
||||
if (type == TK_HEX) {
|
||||
radix = 16;
|
||||
} else if (type == TK_BIN) {
|
||||
radix = 2;
|
||||
}
|
||||
|
||||
// the string may be overflow according to errno
|
||||
*value = issigned? strtoll(z, &endPtr, radix):strtoul(z, &endPtr, radix);
|
||||
|
||||
// not a valid integer number, return error
|
||||
if (endPtr - z != n || errno == ERANGE) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -21,36 +21,48 @@
|
|||
#include "tstoken.h"
|
||||
#include "ttokendef.h"
|
||||
#include "tutil.h"
|
||||
#include "ttype.h"
|
||||
|
||||
// todo support scientific expression number and oct number
|
||||
void tVariantCreate(tVariant *pVar, SStrToken *token) { tVariantCreateFromString(pVar, token->z, token->n, token->type); }
|
||||
void tVariantCreate(tVariant *pVar, SStrToken *token) {
|
||||
int32_t ret = 0;
|
||||
int32_t type = token->type;
|
||||
|
||||
void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type) {
|
||||
memset(pVar, 0, sizeof(tVariant));
|
||||
|
||||
switch (type) {
|
||||
|
||||
switch (token->type) {
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
int32_t k = strncasecmp(pz, "true", 4);
|
||||
int32_t k = strncasecmp(token->z, "true", 4);
|
||||
if (k == 0) {
|
||||
pVar->i64Key = TSDB_TRUE;
|
||||
pVar->i64 = TSDB_TRUE;
|
||||
} else {
|
||||
assert(strncasecmp(pz, "false", 5) == 0);
|
||||
pVar->i64Key = TSDB_FALSE;
|
||||
assert(strncasecmp(token->z, "false", 5) == 0);
|
||||
pVar->i64 = TSDB_FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
pVar->i64Key = strtoll(pz, NULL, 10);
|
||||
case TSDB_DATA_TYPE_INT:{
|
||||
ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true);
|
||||
if (ret != 0) {
|
||||
pVar->nType = -1; // -1 means error type
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
pVar->dKey = strtod(pz, NULL);
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
pVar->dKey = strtod(token->z, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
pVar->pz = strndup(pz, len);
|
||||
pVar->pz = strndup(token->z, token->n);
|
||||
pVar->nLen = strdequote(pVar->pz);
|
||||
break;
|
||||
}
|
||||
|
@ -74,20 +86,36 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
|
|||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
pVar->i64Key = GET_INT8_VAL(pz);
|
||||
pVar->i64 = GET_INT8_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
pVar->u64 = GET_UINT8_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
pVar->i64Key = GET_INT16_VAL(pz);
|
||||
pVar->i64 = GET_INT16_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
pVar->u64 = GET_UINT16_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
pVar->i64Key = GET_INT32_VAL(pz);
|
||||
pVar->i64 = GET_INT32_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
pVar->u64 = GET_UINT32_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
pVar->i64Key = GET_INT64_VAL(pz);
|
||||
pVar->i64 = GET_INT64_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
pVar->u64 = GET_UINT64_VAL(pz);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
|
@ -115,7 +143,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
|
|||
}
|
||||
|
||||
default:
|
||||
pVar->i64Key = GET_INT32_VAL(pVar);
|
||||
pVar->i64 = GET_INT32_VAL(pz);
|
||||
}
|
||||
|
||||
pVar->nType = type;
|
||||
|
@ -141,6 +169,11 @@ void tVariantDestroy(tVariant *pVar) {
|
|||
}
|
||||
}
|
||||
|
||||
bool tVariantIsValid(tVariant *pVar) {
|
||||
assert(pVar != NULL);
|
||||
return isValidDataType(pVar->nType);
|
||||
}
|
||||
|
||||
void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
||||
if (pSrc == NULL || pDst == NULL) return;
|
||||
|
||||
|
@ -159,8 +192,8 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
|||
|
||||
}
|
||||
|
||||
if (pSrc->nType >= TSDB_DATA_TYPE_BOOL && pSrc->nType <= TSDB_DATA_TYPE_DOUBLE) {
|
||||
pDst->i64Key = pSrc->i64Key;
|
||||
if (IS_NUMERIC_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) {
|
||||
pDst->i64 = pSrc->i64;
|
||||
} else if (pSrc->nType == TSDB_DATA_TYPE_ARRAY) { // this is only for string array
|
||||
size_t num = taosArrayGetSize(pSrc->arr);
|
||||
pDst->arr = taosArrayInit(num, sizeof(char*));
|
||||
|
@ -189,30 +222,30 @@ int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
switch (p1->nType) {
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
if (p1->nLen == p2->nLen) {
|
||||
return memcmp(p1->pz, p2->pz, p1->nLen);
|
||||
} else {
|
||||
return p1->nLen > p2->nLen? 1:-1;
|
||||
}
|
||||
};
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
if (p1->dKey == p2->dKey) {
|
||||
return 0;
|
||||
} else {
|
||||
return p1->dKey > p2->dKey? 1:-1;
|
||||
}
|
||||
|
||||
default:
|
||||
if (p1->i64Key == p2->i64Key) {
|
||||
return 0;
|
||||
} else {
|
||||
return p1->i64Key > p2->i64Key? 1:-1;
|
||||
}
|
||||
if (p1->nType == TSDB_DATA_TYPE_BINARY || p1->nType == TSDB_DATA_TYPE_NCHAR) {
|
||||
if (p1->nLen == p2->nLen) {
|
||||
return memcmp(p1->pz, p2->pz, p1->nLen);
|
||||
} else {
|
||||
return p1->nLen > p2->nLen? 1:-1;
|
||||
}
|
||||
} else if (p1->nType == TSDB_DATA_TYPE_FLOAT || p1->nType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
if (p1->dKey == p2->dKey) {
|
||||
return 0;
|
||||
} else {
|
||||
return p1->dKey > p2->dKey? 1:-1;
|
||||
}
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(p1->nType)) {
|
||||
if (p1->u64 == p2->u64) {
|
||||
return 0;
|
||||
} else {
|
||||
return p1->u64 > p2->u64? 1:-1;
|
||||
}
|
||||
} else {
|
||||
if (p1->i64 == p2->i64) {
|
||||
return 0;
|
||||
} else {
|
||||
return p1->i64 > p2->i64? 1:-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,11 +272,15 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
|
|||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
return sprintf(dst, "%d", (int32_t)pVar->i64Key);
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
return sprintf(dst, "%d", (int32_t)pVar->i64);
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
return sprintf(dst, "%" PRId64, pVar->i64Key);
|
||||
|
||||
return sprintf(dst, "%" PRId64, pVar->i64);
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
return sprintf(dst, "%" PRIu64, pVar->u64);
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
return sprintf(dst, "%.9lf", pVar->dKey);
|
||||
|
@ -253,121 +290,6 @@ int32_t tVariantToString(tVariant *pVar, char *dst) {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int32_t doConvertToInteger(tVariant *pVariant, char *pDest, int32_t type, bool releaseVariantPtr) {
|
||||
if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
|
||||
setNull(pDest, type, tDataTypeDesc[type].nSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
*((int64_t *)pDest) = pVariant->i64Key;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
if ((pVariant->dKey < INT64_MIN) || (pVariant->dKey > INT64_MAX)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int64_t *)pDest) = (int64_t)pVariant->dKey;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
|
||||
SStrToken token = {0};
|
||||
token.n = tSQLGetToken(pVariant->pz, &token.type);
|
||||
|
||||
if (token.type == TK_MINUS || token.type == TK_PLUS) {
|
||||
token.n = tSQLGetToken(pVariant->pz + token.n, &token.type);
|
||||
}
|
||||
|
||||
if (token.type == TK_FLOAT) {
|
||||
double v = strtod(pVariant->pz, &endPtr);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((v < INT64_MIN) || (v > INT64_MAX)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int64_t *)pDest) = (int64_t)v;
|
||||
} else if (token.type == TK_INTEGER) {
|
||||
int64_t val = strtoll(pVariant->pz, &endPtr, 10);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if (errno == ERANGE) {
|
||||
return -1; // data overflow
|
||||
}
|
||||
|
||||
*((int64_t *)pDest) = val;
|
||||
} else if (token.type == TK_NULL) {
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
setNull(pDest, type, tDataTypeDesc[type].nSize);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) {
|
||||
errno = 0;
|
||||
wchar_t *endPtr = NULL;
|
||||
|
||||
SStrToken token = {0};
|
||||
token.n = tSQLGetToken(pVariant->pz, &token.type);
|
||||
|
||||
if (token.type == TK_MINUS || token.type == TK_PLUS) {
|
||||
token.n = tSQLGetToken(pVariant->pz + token.n, &token.type);
|
||||
}
|
||||
|
||||
if (token.type == TK_FLOAT) {
|
||||
double v = wcstod(pVariant->wpz, &endPtr);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((v < INT64_MIN) || (v > INT64_MAX)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int64_t *)pDest) = (int64_t)v;
|
||||
} else if (token.type == TK_NULL) {
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
setNull(pDest, type, tDataTypeDesc[type].nSize);
|
||||
} else {
|
||||
int64_t val = wcstoll(pVariant->wpz, &endPtr, 10);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if (errno == ERANGE) {
|
||||
return -1; // data overflow
|
||||
}
|
||||
|
||||
*((int64_t *)pDest) = val;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static FORCE_INLINE int32_t convertToBoolImpl(char *pStr, int32_t len) {
|
||||
if ((strncasecmp(pStr, "true", len) == 0) && (len == 4)) {
|
||||
return TSDB_TRUE;
|
||||
|
@ -385,15 +307,18 @@ static FORCE_INLINE int32_t wcsconvertToBoolImpl(wchar_t *pstr, int32_t len) {
|
|||
return TSDB_TRUE;
|
||||
} else if (wcsncasecmp(pstr, L"false", len) == 0 && (len == 5)) {
|
||||
return TSDB_FALSE;
|
||||
} else if (memcmp(pstr, L"null", wcslen(L"null")) == 0) {
|
||||
return TSDB_DATA_BOOL_NULL;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
||||
const int32_t INITIAL_ALLOC_SIZE = 20;
|
||||
const int32_t INITIAL_ALLOC_SIZE = 40;
|
||||
char * pBuf = NULL;
|
||||
|
||||
|
||||
// it is a in-place convert type for tVariant, local buffer is needed
|
||||
if (*pDest == pVariant->pz) {
|
||||
pBuf = calloc(1, INITIAL_ALLOC_SIZE);
|
||||
}
|
||||
|
@ -413,12 +338,12 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
}
|
||||
|
||||
} else {
|
||||
if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64Key);
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
sprintf(pBuf == NULL ? *pDest : pBuf, "%lf", pVariant->dKey);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) {
|
||||
sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE");
|
||||
sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i64 == TSDB_TRUE) ? "TRUE" : "FALSE");
|
||||
} else if (pVariant->nType == 0) { // null data
|
||||
setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0);
|
||||
}
|
||||
|
@ -432,28 +357,33 @@ static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// todo handle the error
|
||||
static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
||||
char tmpBuf[40] = {0};
|
||||
|
||||
char * pDst = tmpBuf;
|
||||
int32_t nLen = 0;
|
||||
|
||||
if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
nLen = sprintf(pDst, "%" PRId64, pVariant->i64Key);
|
||||
|
||||
// convert the number to string, than convert it to wchar string.
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
nLen = sprintf(pDst, "%" PRId64, pVariant->i64);
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
nLen = sprintf(pDst, "%"PRIu64, pVariant->u64);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
nLen = sprintf(pDst, "%lf", pVariant->dKey);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
pDst = pVariant->pz;
|
||||
nLen = pVariant->nLen;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) {
|
||||
nLen = sprintf(pDst, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE");
|
||||
nLen = sprintf(pDst, "%s", (pVariant->i64 == TSDB_TRUE) ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
if (*pDest == pVariant->pz) {
|
||||
wchar_t *pWStr = calloc(1, (nLen + 1) * TSDB_NCHAR_SIZE);
|
||||
taosMbsToUcs4(pDst, nLen, (char *)pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL);
|
||||
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, (char *)pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL);
|
||||
if (!ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// free the binary buffer in the first place
|
||||
if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
free(pVariant->wpz);
|
||||
|
@ -468,11 +398,15 @@ static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
|
||||
pVariant->wpz = (wchar_t *)tmp;
|
||||
} else {
|
||||
size_t output = -1;
|
||||
taosMbsToUcs4(pDst, nLen, *pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output);
|
||||
|
||||
int32_t output = 0;
|
||||
|
||||
bool ret = taosMbsToUcs4(pDst, nLen, *pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output);
|
||||
if (!ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pDestSize != NULL) {
|
||||
*pDestSize = (int32_t)output;
|
||||
*pDestSize = output;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,38 +415,31 @@ static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) {
|
|||
|
||||
static FORCE_INLINE int32_t convertToDouble(char *pStr, int32_t len, double *value) {
|
||||
SStrToken stoken = {.z = pStr, .n = len};
|
||||
|
||||
if (TK_ILLEGAL == isValidNumber(&stoken)) {
|
||||
if (TK_ILLEGAL == tGetNumericStringType(&stoken)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*value = strtod(pStr, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result, int32_t type, int64_t lowBnd,
|
||||
int64_t upperBnd, bool releaseVariantPtr) {
|
||||
static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result, int32_t type, bool issigned, bool releaseVariantPtr) {
|
||||
if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
|
||||
setNull((char *)result, type, tDataTypeDesc[type].nSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
*result = pVariant->i64Key;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
*result = (int64_t)pVariant->dKey;
|
||||
|
||||
errno = 0;
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
*result = pVariant->i64;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
*result = pVariant->u64;
|
||||
} else if (IS_FLOAT_TYPE(pVariant->nType)) {
|
||||
*result = (int64_t) pVariant->dKey;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
errno = 0;
|
||||
char *endPtr = NULL;
|
||||
|
||||
SStrToken token = {0};
|
||||
token.n = tSQLGetToken(pVariant->pz, &token.type);
|
||||
|
||||
if (token.type == TK_MINUS || token.type == TK_PLUS) {
|
||||
token.n = tSQLGetToken(pVariant->pz + token.n, &token.type);
|
||||
}
|
||||
|
||||
SStrToken token = {.z = pVariant->pz, .n = pVariant->nLen};
|
||||
/*int32_t n = */tSQLGetToken(pVariant->pz, &token.type);
|
||||
|
||||
if (token.type == TK_NULL) {
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
|
@ -522,39 +449,25 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
|
|||
setNull((char *)result, type, tDataTypeDesc[type].nSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStrToken sToken = {.z = pVariant->pz, .n = pVariant->nLen};
|
||||
if (TK_ILLEGAL == isValidNumber(&sToken)) {
|
||||
|
||||
// decide if it is a valid number
|
||||
token.type = tGetNumericStringType(&token);
|
||||
if (token.type == TK_ILLEGAL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (token.type == TK_FLOAT) {
|
||||
double v = strtod(pVariant->pz, &endPtr);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*result = (int64_t)v;
|
||||
} else if (token.type == TK_INTEGER) {
|
||||
int64_t val = strtoll(pVariant->pz, &endPtr, 10);
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
if (errno == ERANGE) {
|
||||
return -1; // data overflow
|
||||
}
|
||||
|
||||
*result = val;
|
||||
} else {
|
||||
|
||||
int64_t res = 0;
|
||||
int32_t t = tStrToInteger(token.z, token.type, token.n, &res, issigned);
|
||||
if (t != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (releaseVariantPtr) {
|
||||
free(pVariant->pz);
|
||||
pVariant->nLen = 0;
|
||||
}
|
||||
|
||||
*result = res;
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) {
|
||||
errno = 0;
|
||||
wchar_t *endPtr = NULL;
|
||||
|
@ -599,19 +512,35 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
|
|||
*result = val;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*result <= lowBnd) || (*result > upperBnd)) {
|
||||
return -1;
|
||||
|
||||
bool code = false;
|
||||
switch(type) {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
code = IS_VALID_TINYINT(*result); break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
code = IS_VALID_SMALLINT(*result); break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
code = IS_VALID_INT(*result); break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
code = IS_VALID_BIGINT(*result); break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
code = IS_VALID_UTINYINT(*result); break;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
code = IS_VALID_USMALLINT(*result); break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
code = IS_VALID_UINT(*result); break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
code = IS_VALID_UBIGINT(*result); break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return code? 0:-1;
|
||||
}
|
||||
|
||||
static int32_t convertToBool(tVariant *pVariant, int64_t *pDest) {
|
||||
if (pVariant->nType == TSDB_DATA_TYPE_BOOL) {
|
||||
*pDest = pVariant->i64Key; // in order to be compatible to null of bool
|
||||
} else if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
*pDest = ((pVariant->i64Key != 0) ? TSDB_TRUE : TSDB_FALSE);
|
||||
*pDest = pVariant->i64; // in order to be compatible to null of bool
|
||||
} else if (IS_NUMERIC_TYPE(pVariant->nType)) {
|
||||
*pDest = ((pVariant->i64 != 0) ? TSDB_TRUE : TSDB_FALSE);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_FLOAT || pVariant->nType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
*pDest = ((pVariant->dKey != 0) ? TSDB_TRUE : TSDB_FALSE);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
|
@ -638,8 +567,6 @@ static int32_t convertToBool(tVariant *pVariant, int64_t *pDest) {
|
|||
/*
|
||||
* transfer data from variant serve as the implicit data conversion: from input sql string pVariant->nType
|
||||
* to column type defined in schema
|
||||
*
|
||||
* todo handle the return value
|
||||
*/
|
||||
int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool includeLengthPrefix) {
|
||||
if (pVariant == NULL || (pVariant->nType != 0 && !isValidDataType(pVariant->nType))) {
|
||||
|
@ -647,57 +574,82 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
}
|
||||
|
||||
errno = 0; // reset global error code
|
||||
|
||||
int64_t result;
|
||||
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
int64_t dst = 0;
|
||||
if (convertToBool(pVariant, &dst) < 0) {
|
||||
if (convertToBool(pVariant, &result) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*(int8_t *)payload = (int8_t)dst;
|
||||
|
||||
*(int8_t *)payload = (int8_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int64_t result = 0;
|
||||
if (convertToInteger(pVariant, &result, type, INT8_MIN, INT8_MAX, false) < 0) {
|
||||
if (convertToInteger(pVariant, &result, type, true, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int8_t *)payload) = (int8_t)result;
|
||||
*((int8_t *)payload) = (int8_t) result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
if (convertToInteger(pVariant, &result, type, false, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*((uint8_t *)payload) = (uint8_t) result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int64_t result = 0;
|
||||
if (convertToInteger(pVariant, &result, type, INT16_MIN, INT16_MAX, false) < 0) {
|
||||
if (convertToInteger(pVariant, &result, type, true, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int16_t *)payload) = (int16_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
if (convertToInteger(pVariant, &result, type, false, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*((uint16_t *)payload) = (uint16_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int64_t result = 0;
|
||||
if (convertToInteger(pVariant, &result, type, INT32_MIN, INT32_MAX, false) < 0) {
|
||||
if (convertToInteger(pVariant, &result, type, true, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int32_t *)payload) = (int32_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
if (convertToInteger(pVariant, &result, type, false, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*((uint32_t *)payload) = (uint32_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t result = 0;
|
||||
if (convertToInteger(pVariant, &result, type, INT64_MIN, INT64_MAX, false) < 0) {
|
||||
if (convertToInteger(pVariant, &result, type, true, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*((int64_t *)payload) = (int64_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
if (convertToInteger(pVariant, &result, type, false, false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
*((uint64_t *)payload) = (uint64_t)result;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
if (pVariant->nType == TSDB_DATA_TYPE_BINARY) {
|
||||
if (strncasecmp(TSDB_DATA_NULL_STR_L, pVariant->pz, pVariant->nLen) == 0 &&
|
||||
|
@ -706,20 +658,19 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
return 0;
|
||||
} else {
|
||||
double value = -1;
|
||||
int32_t ret;
|
||||
ret = convertToDouble(pVariant->pz, pVariant->nLen, &value);
|
||||
int32_t ret = convertToDouble(pVariant->pz, pVariant->nLen, &value);
|
||||
if ((errno == ERANGE && (float)value == -1) || (ret != 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SET_FLOAT_VAL(payload, value);
|
||||
}
|
||||
} else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
SET_FLOAT_VAL(payload, pVariant->i64Key);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BOOL || IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
SET_FLOAT_VAL(payload, pVariant->i64);
|
||||
} else if (IS_FLOAT_TYPE(pVariant->nType)) {
|
||||
SET_FLOAT_VAL(payload, pVariant->dKey);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
|
||||
*((int32_t *)payload) = TSDB_DATA_FLOAT_NULL;
|
||||
*((uint32_t *)payload) = TSDB_DATA_FLOAT_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -745,9 +696,9 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
|
||||
SET_DOUBLE_VAL(payload, value);
|
||||
}
|
||||
} else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
SET_DOUBLE_VAL(payload, pVariant->i64Key);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) {
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_BOOL || IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
|
||||
SET_DOUBLE_VAL(payload, pVariant->i64);
|
||||
} else if (IS_FLOAT_TYPE(pVariant->nType)) {
|
||||
SET_DOUBLE_VAL(payload, pVariant->dKey);
|
||||
} else if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
|
||||
*((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL;
|
||||
|
@ -755,9 +706,10 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
}
|
||||
|
||||
double dv = GET_DOUBLE_VAL(payload);
|
||||
if (isinf(dv) || isnan(dv) || dv > DBL_MAX || dv < -DBL_MAX) {
|
||||
if (errno == ERANGE || isinf(dv) || isnan(dv)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -794,7 +746,7 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
if (pVariant->nType == TSDB_DATA_TYPE_NULL) {
|
||||
*((int64_t *)payload) = TSDB_DATA_BIGINT_NULL;
|
||||
} else {
|
||||
*((int64_t *)payload) = pVariant->i64Key;
|
||||
*((int64_t *)payload) = pVariant->i64;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -805,7 +757,9 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
*(uint32_t *)payload = TSDB_DATA_NCHAR_NULL;
|
||||
} else {
|
||||
if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) {
|
||||
toNchar(pVariant, &payload, &newlen);
|
||||
if (toNchar(pVariant, &payload, &newlen) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
wcsncpy((wchar_t *)payload, pVariant->wpz, pVariant->nLen);
|
||||
}
|
||||
|
@ -817,7 +771,9 @@ int32_t tVariantDump(tVariant *pVariant, char *payload, int16_t type, bool inclu
|
|||
char *p = varDataVal(payload);
|
||||
|
||||
if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) {
|
||||
toNchar(pVariant, &p, &newlen);
|
||||
if (toNchar(pVariant, &p, &newlen) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
wcsncpy((wchar_t *)p, pVariant->wpz, pVariant->nLen);
|
||||
newlen = pVariant->nLen;
|
||||
|
@ -848,7 +804,7 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
|
|||
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL: { // bool
|
||||
if (convertToBool(pVariant, &pVariant->i64Key) < 0) {
|
||||
if (convertToBool(pVariant, &pVariant->i64) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -859,7 +815,7 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
|
|||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
convertToInteger(pVariant, &(pVariant->i64Key), type, INT64_MIN, INT64_MAX, true);
|
||||
convertToInteger(pVariant, &(pVariant->i64), type, true, true);
|
||||
pVariant->nType = TSDB_DATA_TYPE_BIGINT;
|
||||
break;
|
||||
}
|
||||
|
@ -886,7 +842,7 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
|
|||
free(pVariant->pz);
|
||||
pVariant->dKey = v;
|
||||
} else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
pVariant->dKey = (double)(pVariant->i64Key);
|
||||
pVariant->dKey = (double)(pVariant->i64);
|
||||
}
|
||||
|
||||
pVariant->nType = TSDB_DATA_TYPE_DOUBLE;
|
||||
|
@ -901,7 +857,9 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
|
|||
}
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) {
|
||||
toNchar(pVariant, &pVariant->pz, &pVariant->nLen);
|
||||
if (toNchar(pVariant, &pVariant->pz, &pVariant->nLen) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
pVariant->nType = type;
|
||||
break;
|
||||
|
@ -909,6 +867,4 @@ int32_t tVariantTypeSetType(tVariant *pVariant, char type) {
|
|||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -19,136 +19,137 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
enum TDengineDataType {
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
||||
}
|
||||
|
||||
enum TDengineInitOption
|
||||
{
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
enum TDengineDataType
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOLEAN";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "BYTE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SHORT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "LONG";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
||||
}
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
enum TDengineInitOption
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOLEAN";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "BYTE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SHORT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "LONG";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
}
|
||||
}
|
||||
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
|
||||
PROJECT(TDengine)
|
||||
|
||||
|
|
|
@ -56,6 +56,12 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
|
||||
<!-- for restful -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
|
@ -73,7 +79,14 @@
|
|||
<version>1.2.58</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.49</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -0,0 +1,808 @@
|
|||
/***************************************************************************
|
||||
* 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/>.
|
||||
*****************************************************************************/
|
||||
package com.taosdata.jdbc;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
|
||||
|
||||
private final static String PRODUCT_NAME = "TDengine";
|
||||
private final static String PRODUCT_VESION = "2.0.x.x";
|
||||
private final static String DRIVER_NAME = "taos-jdbcdriver";
|
||||
private final static String DRIVER_VERSION = "2.0.x";
|
||||
private final static int DRIVER_MAJAR_VERSION = 2;
|
||||
private final static int DRIVER_MINOR_VERSION = 0;
|
||||
|
||||
public boolean allProceduresAreCallable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean allTablesAreSelectable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract String getURL() throws SQLException;
|
||||
|
||||
public abstract String getUserName() throws SQLException;
|
||||
|
||||
public boolean isReadOnly() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean nullsAreSortedHigh() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean nullsAreSortedLow() throws SQLException {
|
||||
return !nullsAreSortedHigh();
|
||||
}
|
||||
|
||||
public boolean nullsAreSortedAtStart() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean nullsAreSortedAtEnd() throws SQLException {
|
||||
return !nullsAreSortedAtStart();
|
||||
}
|
||||
|
||||
public String getDatabaseProductName() throws SQLException {
|
||||
return PRODUCT_NAME;
|
||||
}
|
||||
|
||||
public String getDatabaseProductVersion() throws SQLException {
|
||||
return PRODUCT_VESION;
|
||||
}
|
||||
|
||||
public String getDriverName() throws SQLException {
|
||||
return DRIVER_NAME;
|
||||
}
|
||||
|
||||
public String getDriverVersion() throws SQLException {
|
||||
return DRIVER_VERSION;
|
||||
}
|
||||
|
||||
public int getDriverMajorVersion() {
|
||||
return DRIVER_MAJAR_VERSION;
|
||||
}
|
||||
|
||||
public int getDriverMinorVersion() {
|
||||
return DRIVER_MINOR_VERSION;
|
||||
}
|
||||
|
||||
public boolean usesLocalFiles() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean usesLocalFilePerTable() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMixedCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesUpperCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesLowerCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesMixedCaseIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getIdentifierQuoteString() throws SQLException {
|
||||
return " ";
|
||||
}
|
||||
|
||||
public String getSQLKeywords() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getNumericFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getStringFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSystemFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTimeDateFunctions() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSearchStringEscape() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getExtraNameCharacters() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsAlterTableWithAddColumn() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsAlterTableWithDropColumn() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsColumnAliasing() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean nullPlusNonNullIsNull() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsConvert() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsConvert(int fromType, int toType) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsTableCorrelationNames() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsExpressionsInOrderBy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOrderByUnrelated() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsGroupBy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsGroupByUnrelated() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsGroupByBeyondSelect() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsLikeEscapeClause() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMultipleResultSets() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMultipleTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsNonNullableColumns() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMinimumSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCoreSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsExtendedSQLGrammar() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsANSI92IntermediateSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsANSI92FullSQL() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsFullOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsLimitedOuterJoins() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getSchemaTerm() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getProcedureTerm() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCatalogTerm() throws SQLException {
|
||||
return "database";
|
||||
}
|
||||
|
||||
public boolean isCatalogAtStart() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getCatalogSeparator() throws SQLException {
|
||||
return ".";
|
||||
}
|
||||
|
||||
public boolean supportsSchemasInDataManipulation() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSchemasInProcedureCalls() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSchemasInTableDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCatalogsInDataManipulation() throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsPositionedDelete() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsPositionedUpdate() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSelectForUpdate() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsStoredProcedures() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSubqueriesInComparisons() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSubqueriesInExists() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSubqueriesInIns() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsCorrelatedSubqueries() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsUnion() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsUnionAll() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getMaxBinaryLiteralLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxCharLiteralLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnsInGroupBy() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnsInIndex() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnsInOrderBy() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnsInSelect() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxColumnsInTable() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxConnections() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxCursorNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxIndexLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxSchemaNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxProcedureNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxCatalogNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxRowSize() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getMaxStatementLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxStatements() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxTableNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxTablesInSelect() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMaxUserNameLength() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getDefaultTransactionIsolation() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean supportsTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
|
||||
throws SQLException {
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
|
||||
String columnNamePattern) throws SQLException {
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
|
||||
throws SQLException;
|
||||
|
||||
public ResultSet getSchemas() throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public abstract ResultSet getCatalogs() throws SQLException;
|
||||
|
||||
public ResultSet getTableTypes() throws SQLException {
|
||||
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
|
||||
|
||||
// set up ColumnMetaDataList
|
||||
List<ColumnMetaData> columnMetaDataList = new ArrayList<ColumnMetaData>(1);
|
||||
ColumnMetaData colMetaData = new ColumnMetaData();
|
||||
colMetaData.setColIndex(0);
|
||||
colMetaData.setColName("TABLE_TYPE");
|
||||
colMetaData.setColSize(10);
|
||||
colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
|
||||
columnMetaDataList.add(colMetaData);
|
||||
|
||||
// set up rowDataList
|
||||
List<TSDBResultSetRowData> rowDataList = new ArrayList<TSDBResultSetRowData>(2);
|
||||
TSDBResultSetRowData rowData = new TSDBResultSetRowData();
|
||||
rowData.setString(0, "TABLE");
|
||||
rowDataList.add(rowData);
|
||||
rowData = new TSDBResultSetRowData();
|
||||
rowData.setString(0, "STABLE");
|
||||
rowDataList.add(rowData);
|
||||
|
||||
resultSet.setColumnMetaDataList(columnMetaDataList);
|
||||
resultSet.setRowDataList(rowDataList);
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;
|
||||
|
||||
protected int getNullable(int index, String typeName) {
|
||||
if (index == 0 && "TIMESTAMP".equals(typeName))
|
||||
return DatabaseMetaData.columnNoNulls;
|
||||
return DatabaseMetaData.columnNullable;
|
||||
}
|
||||
|
||||
protected int getColumnSize(String typeName, int length) {
|
||||
switch (typeName) {
|
||||
case "TIMESTAMP":
|
||||
return 23;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getDecimalDigits(String typeName) {
|
||||
switch (typeName) {
|
||||
case "FLOAT":
|
||||
return 5;
|
||||
case "DOUBLE":
|
||||
return 9;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getDataType(String typeName) {
|
||||
switch (typeName) {
|
||||
case "TIMESTAMP":
|
||||
return Types.TIMESTAMP;
|
||||
case "INT":
|
||||
return Types.INTEGER;
|
||||
case "BIGINT":
|
||||
return Types.BIGINT;
|
||||
case "FLOAT":
|
||||
return Types.FLOAT;
|
||||
case "DOUBLE":
|
||||
return Types.DOUBLE;
|
||||
case "BINARY":
|
||||
return Types.BINARY;
|
||||
case "SMALLINT":
|
||||
return Types.SMALLINT;
|
||||
case "TINYINT":
|
||||
return Types.TINYINT;
|
||||
case "BOOL":
|
||||
return Types.BOOLEAN;
|
||||
case "NCHAR":
|
||||
return Types.NCHAR;
|
||||
default:
|
||||
return Types.NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable,
|
||||
String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getTypeInfo() throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public boolean supportsResultSetType(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ownUpdatesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ownDeletesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ownInsertsAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean othersUpdatesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean othersDeletesAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean othersInsertsAreVisible(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updatesAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean deletesAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean insertsAreDetected(int type) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsBatchUpdates() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsSavepoints() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsNamedParameters() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsMultipleOpenResults() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsGetGeneratedKeys() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
|
||||
String attributeNamePattern) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getDatabaseMajorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getDatabaseMinorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getJDBCMajorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getJDBCMinorVersion() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getSQLStateType() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean locatorsUpdateCopy() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsStatementPooling() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public RowIdLifetime getRowIdLifetime() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ResultSet getClientInfoProperties() throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
|
||||
throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern,
|
||||
String columnNamePattern) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern,
|
||||
String columnNamePattern) throws SQLException {
|
||||
return getEmptyResultSet();
|
||||
}
|
||||
|
||||
public boolean generatedKeyAlwaysReturned() throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
private ResultSet getEmptyResultSet() {
|
||||
return new EmptyResultSet();
|
||||
}
|
||||
}
|
|
@ -19,68 +19,71 @@ import java.util.Map;
|
|||
|
||||
public abstract class TSDBConstants {
|
||||
|
||||
public static final String DEFAULT_PORT = "6200";
|
||||
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
||||
public static final String INVALID_VARIABLES = "invalid variables";
|
||||
public static Map<Integer, String> DATATYPE_MAP = null;
|
||||
public static final String DEFAULT_PORT = "6200";
|
||||
public static final String UNSUPPORT_METHOD_EXCEPTIONZ_MSG = "this operation is NOT supported currently!";
|
||||
public static final String INVALID_VARIABLES = "invalid variables";
|
||||
public static Map<Integer, String> DATATYPE_MAP = null;
|
||||
|
||||
public static final long JNI_NULL_POINTER = 0L;
|
||||
public static final long JNI_NULL_POINTER = 0L;
|
||||
|
||||
public static final int JNI_SUCCESS = 0;
|
||||
public static final int JNI_TDENGINE_ERROR = -1;
|
||||
public static final int JNI_CONNECTION_NULL = -2;
|
||||
public static final int JNI_RESULT_SET_NULL = -3;
|
||||
public static final int JNI_NUM_OF_FIELDS_0 = -4;
|
||||
public static final int JNI_SQL_NULL = -5;
|
||||
public static final int JNI_FETCH_END = -6;
|
||||
|
||||
public static final int TSDB_DATA_TYPE_NULL = 0;
|
||||
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
||||
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
||||
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
||||
public static final int TSDB_DATA_TYPE_INT = 4;
|
||||
public static final int TSDB_DATA_TYPE_BIGINT = 5;
|
||||
public static final int TSDB_DATA_TYPE_FLOAT = 6;
|
||||
public static final int TSDB_DATA_TYPE_DOUBLE = 7;
|
||||
public static final int TSDB_DATA_TYPE_BINARY = 8;
|
||||
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
|
||||
public static final int TSDB_DATA_TYPE_NCHAR = 10;
|
||||
|
||||
public static String WrapErrMsg(String msg) {
|
||||
return "TDengine Error: " + msg;
|
||||
}
|
||||
public static final int JNI_SUCCESS = 0;
|
||||
public static final int JNI_TDENGINE_ERROR = -1;
|
||||
public static final int JNI_CONNECTION_NULL = -2;
|
||||
public static final int JNI_RESULT_SET_NULL = -3;
|
||||
public static final int JNI_NUM_OF_FIELDS_0 = -4;
|
||||
public static final int JNI_SQL_NULL = -5;
|
||||
public static final int JNI_FETCH_END = -6;
|
||||
|
||||
public static String FixErrMsg(int code) {
|
||||
switch (code) {
|
||||
case JNI_TDENGINE_ERROR:
|
||||
return WrapErrMsg("internal error of database!");
|
||||
case JNI_CONNECTION_NULL:
|
||||
return WrapErrMsg("invalid tdengine connection!");
|
||||
case JNI_RESULT_SET_NULL:
|
||||
return WrapErrMsg("invalid resultset pointer!");
|
||||
case JNI_NUM_OF_FIELDS_0:
|
||||
return WrapErrMsg("invalid num of fields!");
|
||||
case JNI_SQL_NULL:
|
||||
return WrapErrMsg("can't execute empty sql!");
|
||||
case JNI_FETCH_END:
|
||||
return WrapErrMsg("fetch to the end of resultset");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return WrapErrMsg("unkown error!");
|
||||
}
|
||||
public static final int TSDB_DATA_TYPE_NULL = 0;
|
||||
public static final int TSDB_DATA_TYPE_BOOL = 1;
|
||||
public static final int TSDB_DATA_TYPE_TINYINT = 2;
|
||||
public static final int TSDB_DATA_TYPE_SMALLINT = 3;
|
||||
public static final int TSDB_DATA_TYPE_INT = 4;
|
||||
public static final int TSDB_DATA_TYPE_BIGINT = 5;
|
||||
public static final int TSDB_DATA_TYPE_FLOAT = 6;
|
||||
public static final int TSDB_DATA_TYPE_DOUBLE = 7;
|
||||
public static final int TSDB_DATA_TYPE_BINARY = 8;
|
||||
public static final int TSDB_DATA_TYPE_TIMESTAMP = 9;
|
||||
public static final int TSDB_DATA_TYPE_NCHAR = 10;
|
||||
|
||||
static {
|
||||
DATATYPE_MAP = new HashMap<Integer, String>();
|
||||
DATATYPE_MAP.put(1, "BOOL");
|
||||
DATATYPE_MAP.put(2, "TINYINT");
|
||||
DATATYPE_MAP.put(3, "SMALLINT");
|
||||
DATATYPE_MAP.put(4, "INT");
|
||||
DATATYPE_MAP.put(5, "BIGINT");
|
||||
DATATYPE_MAP.put(6, "FLOAT");
|
||||
DATATYPE_MAP.put(7, "DOUBLE");
|
||||
DATATYPE_MAP.put(8, "BINARY");
|
||||
DATATYPE_MAP.put(9, "TIMESTAMP");
|
||||
DATATYPE_MAP.put(10, "NCHAR");
|
||||
}
|
||||
// nchar field's max length
|
||||
public static final int maxFieldSize = 16 * 1024;
|
||||
|
||||
public static String WrapErrMsg(String msg) {
|
||||
return "TDengine Error: " + msg;
|
||||
}
|
||||
|
||||
public static String FixErrMsg(int code) {
|
||||
switch (code) {
|
||||
case JNI_TDENGINE_ERROR:
|
||||
return WrapErrMsg("internal error of database!");
|
||||
case JNI_CONNECTION_NULL:
|
||||
return WrapErrMsg("invalid tdengine connection!");
|
||||
case JNI_RESULT_SET_NULL:
|
||||
return WrapErrMsg("invalid resultset pointer!");
|
||||
case JNI_NUM_OF_FIELDS_0:
|
||||
return WrapErrMsg("invalid num of fields!");
|
||||
case JNI_SQL_NULL:
|
||||
return WrapErrMsg("can't execute empty sql!");
|
||||
case JNI_FETCH_END:
|
||||
return WrapErrMsg("fetch to the end of resultset");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return WrapErrMsg("unkown error!");
|
||||
}
|
||||
|
||||
static {
|
||||
DATATYPE_MAP = new HashMap<Integer, String>();
|
||||
DATATYPE_MAP.put(1, "BOOL");
|
||||
DATATYPE_MAP.put(2, "TINYINT");
|
||||
DATATYPE_MAP.put(3, "SMALLINT");
|
||||
DATATYPE_MAP.put(4, "INT");
|
||||
DATATYPE_MAP.put(5, "BIGINT");
|
||||
DATATYPE_MAP.put(6, "FLOAT");
|
||||
DATATYPE_MAP.put(7, "DOUBLE");
|
||||
DATATYPE_MAP.put(8, "BINARY");
|
||||
DATATYPE_MAP.put(9, "TIMESTAMP");
|
||||
DATATYPE_MAP.put(10, "NCHAR");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class RestfulConnection implements Connection {
|
||||
|
||||
private static final String CONNECTION_IS_CLOSED = "connection is closed.";
|
||||
private static final String AUTO_COMMIT_IS_TRUE = "auto commit is true";
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final Properties props;
|
||||
private final String database;
|
||||
private volatile String database;
|
||||
private final String url;
|
||||
/******************************************************/
|
||||
private boolean isClosed;
|
||||
private DatabaseMetaData metadata;
|
||||
private Map<String, Class<?>> typeMap;
|
||||
private Properties clientInfoProps = new Properties();
|
||||
|
||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||
this.host = host;
|
||||
|
@ -21,280 +31,424 @@ public class RestfulConnection implements Connection {
|
|||
this.props = props;
|
||||
this.database = database;
|
||||
this.url = url;
|
||||
this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed."));
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
return new RestfulStatement(this, database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
//TODO: prepareStatement
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nativeSQL(String sql) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
//nothing did
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (!autoCommit)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoCommit() throws SQLException {
|
||||
return false;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (getAutoCommit())
|
||||
throw new SQLException(AUTO_COMMIT_IS_TRUE);
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (getAutoCommit())
|
||||
throw new SQLException(AUTO_COMMIT_IS_TRUE);
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
|
||||
if (isClosed)
|
||||
return;
|
||||
//TODO: release all resources
|
||||
isClosed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return false;
|
||||
return isClosed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseMetaData getMetaData() throws SQLException {
|
||||
//TODO: RestfulDatabaseMetaData is not implemented
|
||||
return new RestfulDatabaseMetaData();
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadOnly(boolean readOnly) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() throws SQLException {
|
||||
return false;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatalog(String catalog) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
synchronized (RestfulConnection.class) {
|
||||
this.database = catalog;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalog() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return this.database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransactionIsolation(int level) throws SQLException {
|
||||
//transaction is not supported
|
||||
throw new SQLFeatureNotSupportedException("transactions are not supported");
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
switch (level) {
|
||||
case Connection.TRANSACTION_NONE:
|
||||
break;
|
||||
case Connection.TRANSACTION_READ_UNCOMMITTED:
|
||||
case Connection.TRANSACTION_READ_COMMITTED:
|
||||
case Connection.TRANSACTION_REPEATABLE_READ:
|
||||
case Connection.TRANSACTION_SERIALIZABLE:
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
default:
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public int getTransactionIsolation() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
|
||||
return Connection.TRANSACTION_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
//TODO: getWarnings not implemented
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("clearWarnings not supported.");
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
return createStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
|
||||
|
||||
return this.prepareStatement(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.INVALID_VARIABLES);
|
||||
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Class<?>> getTypeMap() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
synchronized (RestfulConnection.class) {
|
||||
if (this.typeMap == null) {
|
||||
this.typeMap = new HashMap<>();
|
||||
}
|
||||
return this.typeMap;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
|
||||
synchronized (RestfulConnection.class) {
|
||||
this.typeMap = map;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHoldability(int holdability) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHoldability() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Savepoint setSavepoint() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (getAutoCommit())
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
//nothing to do
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Savepoint setSavepoint(String name) throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (getAutoCommit())
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
//nothing to do
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(Savepoint savepoint) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
if (getAutoCommit())
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
//nothing to do
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
return createStatement(resultSetType, resultSetConcurrency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
return prepareStatement(sql, resultSetType, resultSetConcurrency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return null;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return null;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||
return null;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||
return null;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob createClob() throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob createBlob() throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob createNClob() throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML createSQLXML() throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(int timeout) throws SQLException {
|
||||
return false;
|
||||
if (timeout < 0)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
// TODO:
|
||||
/* The driver shall submit a query on the connection or use some other mechanism that positively verifies
|
||||
the connection is still valid when this method is called.*/
|
||||
return !isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientInfo(String name, String value) throws SQLClientInfoException {
|
||||
|
||||
if (isClosed)
|
||||
throw new SQLClientInfoException();
|
||||
clientInfoProps.setProperty(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientInfo(Properties properties) throws SQLClientInfoException {
|
||||
if (isClosed)
|
||||
throw new SQLClientInfoException();
|
||||
|
||||
for (Enumeration<Object> enumer = properties.keys(); enumer.hasMoreElements(); ) {
|
||||
String name = (String) enumer.nextElement();
|
||||
clientInfoProps.put(name, properties.getProperty(name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientInfo(String name) throws SQLException {
|
||||
return null;
|
||||
if (isClosed)
|
||||
throw new SQLClientInfoException();
|
||||
|
||||
return clientInfoProps.getProperty(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getClientInfo() throws SQLException {
|
||||
return null;
|
||||
if (isClosed)
|
||||
throw new SQLClientInfoException();
|
||||
|
||||
return clientInfoProps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSchema(String schema) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
synchronized (RestfulConnection.class) {
|
||||
this.database = schema;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchema() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return this.database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(Executor executor) throws SQLException {
|
||||
if (executor == null) {
|
||||
throw new SQLException("Executor can not be null");
|
||||
}
|
||||
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNetworkTimeout() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(CONNECTION_IS_CLOSED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,7 @@ public class RestfulDriver extends AbstractTaosDriver {
|
|||
return null;
|
||||
|
||||
Properties props = parseURL(url, info);
|
||||
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost");
|
||||
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST);
|
||||
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
|
||||
String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,13 +2,15 @@ package com.taosdata.jdbc.rs;
|
|||
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RestfulResultSetMetaData implements ResultSetMetaData {
|
||||
|
||||
private List<String> fields;
|
||||
private final String database;
|
||||
private ArrayList<RestfulResultSet.Field> fields;
|
||||
|
||||
public RestfulResultSetMetaData(List<String> fields) {
|
||||
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields) {
|
||||
this.database = database;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
@ -24,6 +26,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
|||
|
||||
@Override
|
||||
public boolean isCaseSensitive(int column) throws SQLException {
|
||||
//TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -39,7 +42,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
|||
|
||||
@Override
|
||||
public int isNullable(int column) throws SQLException {
|
||||
return 0;
|
||||
return ResultSetMetaData.columnNullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,7 +57,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
|||
|
||||
@Override
|
||||
public String getColumnLabel(int column) throws SQLException {
|
||||
return fields.get(column - 1);
|
||||
return fields.get(column - 1).name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +67,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
|||
|
||||
@Override
|
||||
public String getSchemaName(int column) throws SQLException {
|
||||
return null;
|
||||
return this.database;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,7 +87,7 @@ public class RestfulResultSetMetaData implements ResultSetMetaData {
|
|||
|
||||
@Override
|
||||
public String getCatalogName(int column) throws SQLException {
|
||||
return null;
|
||||
return this.database;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,20 +7,60 @@ import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
|
|||
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RestfulStatement implements Statement {
|
||||
|
||||
private static final String STATEMENT_CLOSED = "Statement already closed.";
|
||||
private boolean closed;
|
||||
private String database;
|
||||
private final RestfulConnection conn;
|
||||
|
||||
public RestfulStatement(RestfulConnection c, String database) {
|
||||
this.conn = c;
|
||||
private volatile RestfulResultSet resultSet;
|
||||
private volatile int affectedRows;
|
||||
private volatile boolean closeOnCompletion;
|
||||
|
||||
public RestfulStatement(RestfulConnection conn, String database) {
|
||||
this.conn = conn;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
private String[] parseTableIdentifier(String sql) {
|
||||
sql = sql.trim().toLowerCase();
|
||||
String[] ret = null;
|
||||
if (sql.contains("where"))
|
||||
sql = sql.substring(0, sql.indexOf("where"));
|
||||
if (sql.contains("interval"))
|
||||
sql = sql.substring(0, sql.indexOf("interval"));
|
||||
if (sql.contains("fill"))
|
||||
sql = sql.substring(0, sql.indexOf("fill"));
|
||||
if (sql.contains("sliding"))
|
||||
sql = sql.substring(0, sql.indexOf("sliding"));
|
||||
if (sql.contains("group by"))
|
||||
sql = sql.substring(0, sql.indexOf("group by"));
|
||||
if (sql.contains("order by"))
|
||||
sql = sql.substring(0, sql.indexOf("order by"));
|
||||
if (sql.contains("slimit"))
|
||||
sql = sql.substring(0, sql.indexOf("slimit"));
|
||||
if (sql.contains("limit"))
|
||||
sql = sql.substring(0, sql.indexOf("limit"));
|
||||
// parse
|
||||
if (sql.contains("from")) {
|
||||
sql = sql.substring(sql.indexOf("from") + 4).trim();
|
||||
return Arrays.asList(sql.split(",")).stream()
|
||||
.map(tableIdentifier -> {
|
||||
tableIdentifier = tableIdentifier.trim();
|
||||
if (tableIdentifier.contains(" "))
|
||||
tableIdentifier = tableIdentifier.substring(0, tableIdentifier.indexOf(" "));
|
||||
return tableIdentifier;
|
||||
}).collect(Collectors.joining(",")).split(",");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
if (isClosed())
|
||||
|
@ -29,43 +69,33 @@ public class RestfulStatement implements Statement {
|
|||
throw new SQLException("not a select sql for executeQuery: " + sql);
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
// row data
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
String fields = "";
|
||||
List<String> words = Arrays.asList(sql.split(" "));
|
||||
if (words.get(0).equalsIgnoreCase("select")) {
|
||||
int index = 0;
|
||||
if (words.contains("from")) {
|
||||
index = words.indexOf("from");
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
if (resultJson.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
||||
}
|
||||
|
||||
// parse table name from sql
|
||||
String[] tableIdentifiers = parseTableIdentifier(sql);
|
||||
if (tableIdentifiers != null) {
|
||||
List<JSONObject> fieldJsonList = new ArrayList<>();
|
||||
for (String tableIdentifier : tableIdentifiers) {
|
||||
// field meta
|
||||
String fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + tableIdentifier);
|
||||
JSONObject fieldJson = JSON.parseObject(fields);
|
||||
if (fieldJson.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + fieldJson.getString("desc") + "\n" + "error code: " + fieldJson.getString("code")));
|
||||
}
|
||||
fieldJsonList.add(fieldJson);
|
||||
}
|
||||
if (words.contains("FROM")) {
|
||||
index = words.indexOf("FROM");
|
||||
}
|
||||
fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + words.get(index + 1));
|
||||
this.resultSet = new RestfulResultSet(database, this, resultJson, fieldJsonList);
|
||||
} else {
|
||||
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
||||
}
|
||||
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
}
|
||||
String dataStr = jsonObject.getString("data");
|
||||
if ("use".equalsIgnoreCase(fields.split(" ")[0])) {
|
||||
return new RestfulResultSet(dataStr, "");
|
||||
}
|
||||
|
||||
JSONObject jsonField = JSON.parseObject(fields);
|
||||
if (jsonField == null) {
|
||||
return new RestfulResultSet(dataStr, "");
|
||||
}
|
||||
if (jsonField.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonField.getString("desc") + "\n" +
|
||||
"error code: " + jsonField.getString("code")));
|
||||
}
|
||||
String fieldData = jsonField.getString("data");
|
||||
|
||||
return new RestfulResultSet(dataStr, fieldData);
|
||||
this.affectedRows = 0;
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,77 +108,103 @@ public class RestfulStatement implements Statement {
|
|||
if (this.database == null)
|
||||
throw new SQLException("Database not specified or available");
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
||||
// HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + jsonObject.getString("desc") + "\n" + "error code: " + jsonObject.getString("code")));
|
||||
}
|
||||
return Integer.parseInt(jsonObject.getString("rows"));
|
||||
this.resultSet = null;
|
||||
this.affectedRows = Integer.parseInt(jsonObject.getString("rows"));
|
||||
return this.affectedRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
this.closed = true;
|
||||
synchronized (RestfulStatement.class) {
|
||||
if (!isClosed())
|
||||
this.closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxFieldSize() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return TSDBConstants.maxFieldSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxFieldSize(int max) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
if (max < 0)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRows() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
if (max < 0)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQueryTimeout() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQueryTimeout(int seconds) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
if (seconds < 0)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() throws SQLException {
|
||||
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
//TODO: getWarnings not Implemented
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
|
||||
// nothing to do
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorName(String name) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(RestfulStatement.STATEMENT_CLOSED);
|
||||
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -159,133 +215,181 @@ public class RestfulStatement implements Statement {
|
|||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||
this.database = sql.trim().replace("use", "").trim();
|
||||
this.conn.setCatalog(this.database);
|
||||
}
|
||||
if (this.database == null)
|
||||
throw new SQLException("Database not specified or available");
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
// use database
|
||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
// execute sql
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
// parse result
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
if (SqlSyntaxValidator.isSelectSql(sql)) {
|
||||
executeQuery(sql);
|
||||
} else if (SqlSyntaxValidator.isShowSql(sql) || SqlSyntaxValidator.isDescribeSql(sql)) {
|
||||
final String url = "http://" + conn.getHost().trim() + ":" + conn.getPort() + "/rest/sql";
|
||||
if (!SqlSyntaxValidator.isShowDatabaseSql(sql)) {
|
||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
}
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
JSONObject resultJson = JSON.parseObject(result);
|
||||
if (resultJson.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + resultJson.getString("desc") + "\n" + "error code: " + resultJson.getString("code")));
|
||||
}
|
||||
this.resultSet = new RestfulResultSet(database, this, resultJson);
|
||||
} else {
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUpdateCount() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed()) {
|
||||
throw new SQLException("Invalid method call on a closed statement.");
|
||||
}
|
||||
return this.affectedRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults() throws SQLException {
|
||||
return false;
|
||||
return getMoreResults(CLOSE_CURRENT_RESULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
|
||||
if (direction != ResultSet.FETCH_FORWARD && direction != ResultSet.FETCH_REVERSE && direction != ResultSet.FETCH_UNKNOWN)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
this.resultSet.setFetchDirection(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return 0;
|
||||
return this.resultSet.getFetchDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
if (rows < 0)
|
||||
throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchSize() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return this.resultSet.getConcurrency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetType() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return this.resultSet.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBatch(String sql) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
//TODO:
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBatch() throws SQLException {
|
||||
|
||||
//TODO:
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] executeBatch() throws SQLException {
|
||||
//TODO:
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return null;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return this.conn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults(int current) throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
if (resultSet == null)
|
||||
return false;
|
||||
|
||||
// switch (current) {
|
||||
// case CLOSE_CURRENT_RESULT:
|
||||
// resultSet.close();
|
||||
// break;
|
||||
// case KEEP_CURRENT_RESULT:
|
||||
// break;
|
||||
// case CLOSE_ALL_RESULTS:
|
||||
// resultSet.close();
|
||||
// break;
|
||||
// default:
|
||||
// throw new SQLException(TSDBConstants.INVALID_VARIABLES);
|
||||
// }
|
||||
// return next;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return null;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return 0;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||
return 0;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||
return 0;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return false;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||
return false;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||
return false;
|
||||
throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return this.resultSet.getHoldability();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -295,22 +399,30 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public void setPoolable(boolean poolable) throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPoolable() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeOnCompletion() throws SQLException {
|
||||
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
this.closeOnCompletion = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCloseOnCompletion() throws SQLException {
|
||||
return false;
|
||||
if (isClosed())
|
||||
throw new SQLException(STATEMENT_CLOSED);
|
||||
return this.closeOnCompletion;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,8 @@ import org.apache.http.protocol.HTTP;
|
|||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
|
||||
public class HttpClientPoolUtil {
|
||||
public static PoolingHttpClientConnectionManager cm = null;
|
||||
|
@ -94,7 +96,9 @@ public class HttpClientPoolUtil {
|
|||
initPools();
|
||||
}
|
||||
method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||
method.setEntity(new StringEntity(data));
|
||||
method.setHeader("Authorization", "Basic cm9vdDp0YW9zZGF0YQ==");
|
||||
method.setHeader("Content-Type", "text/plain");
|
||||
method.setEntity(new StringEntity(data, Charset.forName("UTF-8")));
|
||||
HttpContext context = HttpClientContext.create();
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
|
@ -105,26 +109,13 @@ public class HttpClientPoolUtil {
|
|||
if (method != null) {
|
||||
method.abort();
|
||||
}
|
||||
// e.printStackTrace();
|
||||
// logger.error("execute post request exception, url:" + uri + ", exception:" + e.toString()
|
||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
||||
new Exception("execute post request exception, url:"
|
||||
+ uri + ", exception:" + e.toString() +
|
||||
", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
||||
.printStackTrace();
|
||||
new Exception("execute post request exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
try {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
|
||||
// + ", cost time(ms):" + (System.currentTimeMillis() - startTime));
|
||||
new Exception(
|
||||
"close response exception, url:" + uri +
|
||||
", exception:" + e.toString()
|
||||
+ ", cost time(ms):" + (System.currentTimeMillis() - startTime))
|
||||
.printStackTrace();
|
||||
new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,12 @@
|
|||
package com.taosdata.jdbc.utils;
|
||||
|
||||
import com.taosdata.jdbc.TSDBConnection;
|
||||
import com.taosdata.jdbc.TSDBJNIConnector;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SqlSyntaxValidator {
|
||||
|
||||
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use"};
|
||||
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use", "import"};
|
||||
private static final String[] querySQL = {"select"};
|
||||
|
||||
private TSDBConnection tsdbConnection;
|
||||
|
@ -31,22 +29,6 @@ public class SqlSyntaxValidator {
|
|||
this.tsdbConnection = (TSDBConnection) connection;
|
||||
}
|
||||
|
||||
public boolean validateSqlSyntax(String sql) throws SQLException {
|
||||
|
||||
boolean res = false;
|
||||
if (tsdbConnection == null || tsdbConnection.isClosed()) {
|
||||
throw new SQLException("invalid connection");
|
||||
} else {
|
||||
TSDBJNIConnector jniConnector = tsdbConnection.getConnection();
|
||||
if (jniConnector == null) {
|
||||
throw new SQLException("jniConnector is null");
|
||||
} else {
|
||||
res = jniConnector.validateCreateTableSql(sql);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static boolean isValidForExecuteUpdate(String sql) {
|
||||
for (String prefix : updateSQL) {
|
||||
if (sql.trim().toLowerCase().startsWith(prefix))
|
||||
|
@ -56,18 +38,28 @@ public class SqlSyntaxValidator {
|
|||
}
|
||||
|
||||
public static boolean isUseSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[8]) || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
||||
return sql.trim().toLowerCase().startsWith("use") || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
||||
}
|
||||
|
||||
public static boolean isUpdateSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[1]);
|
||||
public static boolean isShowSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith("show");
|
||||
}
|
||||
|
||||
public static boolean isDescribeSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith("describe");
|
||||
}
|
||||
|
||||
|
||||
public static boolean isInsertSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[0]);
|
||||
return sql.trim().toLowerCase().startsWith("insert") || sql.trim().toLowerCase().startsWith("import");
|
||||
}
|
||||
|
||||
public static boolean isSelectSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(querySQL[0]);
|
||||
return sql.trim().toLowerCase().startsWith("select");
|
||||
}
|
||||
|
||||
|
||||
public static boolean isShowDatabaseSql(String sql) {
|
||||
return sql.trim().toLowerCase().matches("show\\s*databases");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.junit.Test;
|
|||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class DatabaseMetaDataTest extends BaseTest {
|
||||
public class DatabaseMetaDataTest {
|
||||
static Connection connection = null;
|
||||
static PreparedStatement statement = null;
|
||||
static String dbName = "test";
|
||||
|
@ -23,20 +23,21 @@ public class DatabaseMetaDataTest extends BaseTest {
|
|||
}
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
|
||||
|
||||
String sql = "drop database if exists " + dbName;
|
||||
statement = (TSDBPreparedStatement) connection.prepareStatement(sql);
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.executeUpdate("create database if not exists " + dbName);
|
||||
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaDataTest() throws SQLException {
|
||||
|
||||
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"});
|
||||
while (resultSet.next()) {
|
||||
|
@ -180,7 +181,7 @@ public class DatabaseMetaDataTest extends BaseTest {
|
|||
databaseMetaData.getCatalogs();
|
||||
// databaseMetaData.getTableTypes();
|
||||
|
||||
databaseMetaData.getColumns("", "", "", "");
|
||||
databaseMetaData.getColumns(dbName, "", tName, "");
|
||||
databaseMetaData.getColumnPrivileges("", "", "", "");
|
||||
databaseMetaData.getTablePrivileges("", "", "");
|
||||
databaseMetaData.getBestRowIdentifier("", "", "", 0, false);
|
||||
|
|
|
@ -19,7 +19,7 @@ public class AppMemoryLeakTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = Exception.class)
|
||||
public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
int stmtCnt = 0;
|
||||
|
@ -30,15 +30,4 @@ public class AppMemoryLeakTest {
|
|||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
int stmtCnt = 0;
|
||||
Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
|
||||
while (true) {
|
||||
Statement stmt = conn.createStatement();
|
||||
System.out.println(++stmtCnt + " : " + stmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class ConnectWrongDatabaseTest {
|
||||
|
||||
@Test
|
||||
public void connect() {
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
DriverManager.getConnection("jdbc:TAOS://localhost:6030/wrong_db?user=root&password=taosdata");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
Assert.assertEquals("TDengine Error: Invalid database name", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
|
||||
import org.junit.*;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class SQLTest {
|
||||
private static final String host = "master";
|
||||
|
||||
private static Connection connection;
|
||||
|
||||
@Test
|
||||
public void testCase001() {
|
||||
String sql = "create database if not exists restful_test";
|
||||
execute(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase002() {
|
||||
String sql = "use restful_test";
|
||||
execute(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase003() {
|
||||
String sql = "show databases";
|
||||
executeWithResult(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase004() {
|
||||
String sql = "show tables";
|
||||
executeWithResult(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase005() {
|
||||
String sql = "show stables";
|
||||
executeWithResult(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase006() {
|
||||
String sql = "show dnodes";
|
||||
executeWithResult(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase007() {
|
||||
String sql = "show vgroups";
|
||||
executeWithResult(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase008() {
|
||||
String sql = "drop table if exists restful_test.weather";
|
||||
execute(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase009() {
|
||||
String sql = "create table if not exists restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))";
|
||||
execute(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase010() {
|
||||
String sql = "create table t1 using restful_test.weather tags('北京')";
|
||||
execute(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase011() {
|
||||
String sql = "insert into restful_test.t1 values(now, 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase012() {
|
||||
String sql = "insert into restful_test.t1 values('2020-01-01 00:00:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase013() {
|
||||
String sql = "insert into restful_test.t1 values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase014() {
|
||||
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:03:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase015() {
|
||||
String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase016() {
|
||||
String sql = "insert into t1 values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t2 values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase017() {
|
||||
String sql = "Insert into t3 using weather tags('广东') values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t4 using weather tags('天津') values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase018() {
|
||||
String sql = "select * from restful_test.t1";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase019() {
|
||||
String sql = "select * from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase020() {
|
||||
String sql = "select ts, temperature from restful_test.t1";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase021() {
|
||||
String sql = "select ts, temperature from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase022() {
|
||||
String sql = "select temperature, ts from restful_test.t1";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase023() {
|
||||
String sql = "select temperature, ts from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase024() {
|
||||
String sql = "import into restful_test.t5 using weather tags('石家庄') values('2020-01-01 00:01:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase025() {
|
||||
String sql = "import into restful_test.t6 using weather tags('沈阳') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase026() {
|
||||
String sql = "import into restful_test.t7 using weather tags('长沙') values('2020-01-01 00:01:00.000', 22.22) restful_test.t8 using weather tags('吉林') values('2020-01-01 00:01:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase027() {
|
||||
String sql = "import into restful_test.t9 using weather tags('武汉') values('2020-01-01 00:01:00.000', 22.22) ,('2020-01-02 00:01:00.000', 22.22) restful_test.t10 using weather tags('哈尔滨') values('2020-01-01 00:01:00.000', 22.22),('2020-01-02 00:01:00.000', 22.22)";
|
||||
executeUpdate(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase028() {
|
||||
String sql = "select location, temperature, ts from restful_test.weather where temperature > 1";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase029() {
|
||||
String sql = "select location, temperature, ts from restful_test.weather where temperature < 1";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase030() {
|
||||
String sql = "select location, temperature, ts from restful_test.weather where ts > now";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase031() {
|
||||
String sql = "select location, temperature, ts from restful_test.weather where ts < now";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase032() {
|
||||
String sql = "select count(*) from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase033() {
|
||||
String sql = "select first(*) from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase034() {
|
||||
String sql = "select last(*) from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase035() {
|
||||
String sql = "select last_row(*) from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase036() {
|
||||
String sql = "select ts, ts as primary_key from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCase037() {
|
||||
String sql = "select database()";
|
||||
execute("use restful_test");
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase038() {
|
||||
String sql = "select client_version()";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase039() {
|
||||
String sql = "select server_status()";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase040() {
|
||||
String sql = "select server_status() as status";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase041() {
|
||||
String sql = "select tbname, location from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase042() {
|
||||
String sql = "select count(tbname) from restful_test.weather";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase043() {
|
||||
String sql = "select * from restful_test.weather where ts < now - 1h";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase044() {
|
||||
String sql = "select * from restful_test.weather where ts < now - 1h and location like '%'";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase045() {
|
||||
String sql = "select * from restful_test.weather where ts < now - 1h order by ts";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase046() {
|
||||
String sql = "select last(*) from restful_test.weather where ts < now - 1h group by tbname order by tbname";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase047() {
|
||||
String sql = "select * from restful_test.weather limit 2";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase048() {
|
||||
String sql = "select * from restful_test.weather limit 2 offset 5";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase049() {
|
||||
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts ";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase050() {
|
||||
String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts and t1.location = t3.location";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase051() {
|
||||
String sql = "select * from restful_test.t1 tt, restful_test.t3 yy where tt.ts = yy.ts";
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
private void executeUpdate(String sql) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
long start = System.currentTimeMillis();
|
||||
int affectedRows = statement.executeUpdate(sql);
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("[ affected rows : " + affectedRows + " ] time cost: " + (end - start) + " ms, execute statement ====> " + sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void executeWithResult(String sql) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(sql);
|
||||
ResultSet resultSet = statement.getResultSet();
|
||||
printResult(resultSet);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(String sql) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
long start = System.currentTimeMillis();
|
||||
boolean execute = statement.execute(sql);
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, execute, (end - start));
|
||||
} catch (SQLException e) {
|
||||
System.out.println("ERROR execute SQL ===> " + sql);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printSql(String sql, boolean succeed, long cost) {
|
||||
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||
}
|
||||
|
||||
private void executeQuery(String sql) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
long start = System.currentTimeMillis();
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, true, (end - start));
|
||||
printResult(resultSet);
|
||||
} catch (SQLException e) {
|
||||
System.out.println("ERROR execute SQL ===> " + sql);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printResult(ResultSet resultSet) throws SQLException {
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
String columnLabel = metaData.getColumnLabel(i);
|
||||
String value = resultSet.getString(i);
|
||||
sb.append(columnLabel + ": " + value + "\t");
|
||||
}
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void before() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() throws SQLException {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -5,10 +5,6 @@ import org.junit.Test;
|
|||
|
||||
public class SqlSyntaxValidatorTest {
|
||||
|
||||
@Test
|
||||
public void validateSqlSyntax() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSelectSQL() {
|
||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather"));
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
const ref = require('ref');
|
||||
const os = require('os');
|
||||
const ffi = require('ffi');
|
||||
const ArrayType = require('ref-array');
|
||||
const Struct = require('ref-struct');
|
||||
|
@ -188,7 +189,13 @@ function CTaosInterface (config = null, pass = false) {
|
|||
ref.types.void_ptr2 = ref.refType(ref.types.void_ptr);
|
||||
/*Declare a bunch of functions first*/
|
||||
/* Note, pointers to TAOS_RES, TAOS, are ref.types.void_ptr. The connection._conn buffer is supplied for pointers to TAOS * */
|
||||
this.libtaos = ffi.Library('libtaos', {
|
||||
|
||||
if ('win32' == os.platform()) {
|
||||
taoslibname = 'taos';
|
||||
} else {
|
||||
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 *taos_connect(char *ip, char *user, char *pass, char *db, int port)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "td2.0-connector",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.5",
|
||||
"description": "A Node.js connector for TDengine.",
|
||||
"main": "tdengine.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct {
|
|||
int32_t master;
|
||||
int32_t num; // number of continuous streams
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
FCqWrite cqWrite;
|
||||
struct SCqObj *pHead;
|
||||
|
@ -295,6 +295,8 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
|||
|
||||
if (pObj->pStream == NULL) {
|
||||
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, pObj, NULL);
|
||||
|
||||
// TODO the pObj->pStream may be released if error happens
|
||||
if (pObj->pStream) {
|
||||
tscSetStreamDestTable(pObj->pStream, pObj->dstTable);
|
||||
pContext->num++;
|
||||
|
@ -306,11 +308,14 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
|||
}
|
||||
|
||||
static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||
SCqObj *pObj = (SCqObj *)param;
|
||||
SCqObj *pObj = (SCqObj *)param;
|
||||
if (tres == NULL && row == NULL) {
|
||||
taos_close_stream(pObj->pStream);
|
||||
|
||||
pObj->pStream = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
SCqContext *pContext = pObj->pContext;
|
||||
STSchema *pSchema = pObj->pSchema;
|
||||
if (pObj->pStream == NULL) return;
|
||||
|
@ -336,7 +341,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
|||
val = ((char*)val) - sizeof(VarDataLenT);
|
||||
} else if (c->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
char buf[TSDB_MAX_NCHAR_LEN];
|
||||
size_t len = taos_fetch_lengths(tres)[i];
|
||||
int32_t len = taos_fetch_lengths(tres)[i];
|
||||
taosMbsToUcs4(val, len, buf, sizeof(buf), &len);
|
||||
memcpy(val + sizeof(VarDataLenT), buf, len);
|
||||
varDataLen(val) = len;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
LIST(APPEND CQTEST_SRC ./cqtest.c)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
|
||||
|
|
|
@ -23,8 +23,7 @@ extern "C" {
|
|||
|
||||
int32_t dnodeInitModules();
|
||||
void dnodeCleanupModules();
|
||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
||||
void dnodeProcessModuleStatus(uint32_t moduleStatus);
|
||||
int32_t dnodeStartMnode(SMInfos *pMinfos);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -184,7 +184,19 @@ void dnodeReprocessMWriteMsg(void *pMsg) {
|
|||
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||
|
||||
dnodeSendRedirectMsg(pMsg, true);
|
||||
if (pWrite->pBatchMasterMsg) {
|
||||
++pWrite->pBatchMasterMsg->received;
|
||||
if (pWrite->pBatchMasterMsg->successed + pWrite->pBatchMasterMsg->received
|
||||
>= pWrite->pBatchMasterMsg->expected) {
|
||||
dnodeSendRedirectMsg(&pWrite->pBatchMasterMsg->rpcMsg, true);
|
||||
dnodeFreeMWriteMsg(pWrite->pBatchMasterMsg);
|
||||
}
|
||||
|
||||
mnodeDestroySubMsg(pWrite);
|
||||
|
||||
return;
|
||||
}
|
||||
dnodeSendRedirectMsg(&pWrite->rpcMsg, true);
|
||||
dnodeFreeMWriteMsg(pWrite);
|
||||
} else {
|
||||
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||
|
|
|
@ -127,14 +127,16 @@ int32_t dnodeInitModules() {
|
|||
return dnodeStartModules();
|
||||
}
|
||||
|
||||
void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||
int32_t dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
||||
int32_t code = 0;
|
||||
|
||||
for (int32_t module = TSDB_MOD_MNODE; module < TSDB_MOD_HTTP; ++module) {
|
||||
bool enableModule = moduleStatus & (1 << module);
|
||||
if (!tsModule[module].enable && enableModule) {
|
||||
dInfo("module status:%u is set, start %s module", moduleStatus, tsModule[module].name);
|
||||
tsModule[module].enable = true;
|
||||
dnodeSetModuleStatus(module);
|
||||
(*tsModule[module].startFp)();
|
||||
code = (*tsModule[module].startFp)();
|
||||
}
|
||||
|
||||
if (tsModule[module].enable && !enableModule) {
|
||||
|
@ -144,21 +146,29 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
|||
(*tsModule[module].stopFp)();
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
bool dnodeStartMnode(SMInfos *pMinfos) {
|
||||
SMInfos *pMnodes = pMinfos;
|
||||
|
||||
int32_t dnodeStartMnode(SMInfos *pMinfos) {
|
||||
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
|
||||
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t moduleStatus = tsModuleStatus | (1 << TSDB_MOD_MNODE);
|
||||
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
||||
dnodeProcessModuleStatus(moduleStatus);
|
||||
|
||||
sdbUpdateSync(pMnodes);
|
||||
int32_t code = dnodeProcessModuleStatus(moduleStatus);
|
||||
if (code == 0) {
|
||||
code = sdbUpdateSync(pMinfos);
|
||||
}
|
||||
|
||||
return true;
|
||||
if (code != 0) {
|
||||
dError("failed to start mnode module since %s", tstrerror(code));
|
||||
moduleStatus = tsModuleStatus & ~(1 << TSDB_MOD_MNODE);
|
||||
dnodeProcessModuleStatus(moduleStatus);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ int32_t dnodeInitServer() {
|
|||
rpcInit.label = "DND-S";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = dnodeProcessReqMsgFromDnode;
|
||||
rpcInit.sessions = TSDB_MAX_VNODES;
|
||||
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
||||
rpcInit.connType = TAOS_CONN_SERVER;
|
||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||
|
||||
|
@ -123,7 +123,7 @@ int32_t dnodeInitClient() {
|
|||
rpcInit.label = "DND-C";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = dnodeProcessRspFromDnode;
|
||||
rpcInit.sessions = TSDB_MAX_VNODES;
|
||||
rpcInit.sessions = TSDB_MAX_VNODES << 4;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||
rpcInit.user = "t";
|
||||
|
|
|
@ -160,7 +160,7 @@ static void signal_handler(int32_t signum, siginfo_t *sigInfo, void *context) {
|
|||
syslog(LOG_INFO, "Shut down signal is %d", signum);
|
||||
syslog(LOG_INFO, "Shutting down TDengine service...");
|
||||
// clean the system.
|
||||
dInfo("shut down signal is %d, sender PID:%d", signum, sigInfo->si_pid);
|
||||
dInfo("shut down signal is %d, sender PID:%d cmdline:%s", signum, sigInfo->si_pid, taosGetCmdlineByPID(sigInfo->si_pid));
|
||||
|
||||
// protect the application from receive another signal
|
||||
struct sigaction act = {{0}};
|
||||
|
|
|
@ -214,7 +214,5 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
|
|||
dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
|
||||
}
|
||||
|
||||
dnodeStartMnode(&pCfg->mnodes);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return dnodeStartMnode(&pCfg->mnodes);
|
||||
}
|
||||
|
|
|
@ -202,13 +202,14 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
|||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite);
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite,
|
||||
pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version);
|
||||
pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead.msgType], qtypeStr[qtype], pWrite->pHead.version);
|
||||
|
||||
pWrite->code = vnodeProcessWrite(pVnode, pWrite->pHead, qtype, &pWrite->rspRet);
|
||||
pWrite->code = vnodeProcessWrite(pVnode, &pWrite->pHead, qtype, pWrite);
|
||||
if (pWrite->code <= 0) pWrite->processedCount = 1;
|
||||
if (pWrite->code == 0 && pWrite->pHead->msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true;
|
||||
if (pWrite->code > 0) pWrite->code = 0;
|
||||
if (pWrite->code == 0 && pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true;
|
||||
|
||||
dTrace("msg:%p is processed in vwrite queue, result:%s", pWrite, tstrerror(pWrite->code));
|
||||
dTrace("msg:%p is processed in vwrite queue, code:0x%x", pWrite, pWrite->code);
|
||||
}
|
||||
|
||||
walFsync(vnodeGetWal(pVnode), forceFsync);
|
||||
|
@ -221,7 +222,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
|||
dnodeSendRpcVWriteRsp(pVnode, pWrite, pWrite->code);
|
||||
} else {
|
||||
if (qtype == TAOS_QTYPE_FWD) {
|
||||
vnodeConfirmForward(pVnode, pWrite->pHead->version, 0);
|
||||
vnodeConfirmForward(pVnode, pWrite->pHead.version, 0);
|
||||
}
|
||||
if (pWrite->rspRet.rsp) {
|
||||
rpcFreeCont(pWrite->rspRet.rsp);
|
||||
|
|
|
@ -73,7 +73,8 @@ static int32_t dnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
|
|||
|
||||
if (*numOfVnodes >= TSDB_MAX_VNODES) {
|
||||
dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
|
||||
continue;
|
||||
closedir(dir);
|
||||
return TSDB_CODE_DND_TOO_MANY_VNODES;
|
||||
} else {
|
||||
vnodeList[*numOfVnodes - 1] = vnode;
|
||||
}
|
||||
|
@ -288,4 +289,4 @@ void dnodeSendStatusMsgToMnode() {
|
|||
dInfo("force send status msg to mnode");
|
||||
taosTmrReset(dnodeSendStatusMsg, 3, NULL, tsDnodeTmr, &tsStatusTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ void dnodeGetClusterId(char *clusterId);
|
|||
|
||||
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
|
||||
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
|
||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
||||
int32_t dnodeStartMnode(SMInfos *pMinfos);
|
||||
|
||||
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
||||
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
||||
|
|
|
@ -42,11 +42,12 @@ typedef struct SMnodeMsg {
|
|||
struct SVgObj * pVgroup;
|
||||
struct STableObj *pTable;
|
||||
struct SSTableObj*pSTable;
|
||||
struct SMnodeMsg *pBatchMasterMsg;
|
||||
SMnodeRsp rpcRsp;
|
||||
int8_t received;
|
||||
int8_t successed;
|
||||
int8_t expected;
|
||||
int8_t retry;
|
||||
int16_t received;
|
||||
int16_t successed;
|
||||
int16_t expected;
|
||||
int16_t retry;
|
||||
int32_t incomingTs;
|
||||
int32_t code;
|
||||
void * pObj;
|
||||
|
@ -57,13 +58,14 @@ typedef struct SMnodeMsg {
|
|||
void * mnodeCreateMsg(SRpcMsg *pRpcMsg);
|
||||
int32_t mnodeInitMsg(SMnodeMsg *pMsg);
|
||||
void mnodeCleanupMsg(SMnodeMsg *pMsg);
|
||||
void mnodeDestroySubMsg(SMnodeMsg *pSubMsg);
|
||||
|
||||
int32_t mnodeInitSystem();
|
||||
int32_t mnodeStartSystem();
|
||||
void mnodeCleanupSystem();
|
||||
void mnodeStopSystem();
|
||||
void sdbUpdateAsync();
|
||||
void sdbUpdateSync(void *pMnodes);
|
||||
int32_t sdbUpdateSync(void *pMnodes);
|
||||
bool mnodeIsRunning();
|
||||
int32_t mnodeProcessRead(SMnodeMsg *pMsg);
|
||||
int32_t mnodeProcessWrite(SMnodeMsg *pMsg);
|
||||
|
|
|
@ -86,6 +86,7 @@ void qDestroyQueryInfo(qinfo_t qHandle);
|
|||
|
||||
void* qOpenQueryMgmt(int32_t vgId);
|
||||
void qQueryMgmtNotifyClosed(void* pExecutor);
|
||||
void qQueryMgmtReOpen(void *pExecutor);
|
||||
void qCleanupQueryMgmt(void* pExecutor);
|
||||
void** qRegisterQInfo(void* pMgmt, uint64_t qInfo);
|
||||
void** qAcquireQInfo(void* pMgmt, uint64_t key);
|
||||
|
|
|
@ -42,6 +42,10 @@ typedef void **TAOS_ROW;
|
|||
#define TSDB_DATA_TYPE_BINARY 8 // string
|
||||
#define TSDB_DATA_TYPE_TIMESTAMP 9 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_NCHAR 10 // unicode string
|
||||
#define TSDB_DATA_TYPE_UTINYINT 11 // 1 byte
|
||||
#define TSDB_DATA_TYPE_USMALLINT 12 // 2 bytes
|
||||
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
|
||||
|
||||
typedef enum {
|
||||
TSDB_OPTION_LOCALE,
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef struct tstr {
|
|||
|
||||
|
||||
// Bytes for each type.
|
||||
extern const int32_t TYPE_BYTES[11];
|
||||
extern const int32_t TYPE_BYTES[15];
|
||||
|
||||
// TODO: replace and remove code below
|
||||
#define CHAR_BYTES sizeof(char)
|
||||
|
@ -92,6 +92,11 @@ extern const int32_t TYPE_BYTES[11];
|
|||
#define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF
|
||||
#define TSDB_DATA_BINARY_NULL 0xFF
|
||||
|
||||
#define TSDB_DATA_UTINYINT_NULL 0xFF
|
||||
#define TSDB_DATA_USMALLINT_NULL 0xFFFF
|
||||
#define TSDB_DATA_UINT_NULL 0xFFFFFFFF
|
||||
#define TSDB_DATA_UBIGINT_NULL 0xFFFFFFFFFFFFFFFFL
|
||||
|
||||
#define TSDB_DATA_NULL_STR "NULL"
|
||||
#define TSDB_DATA_NULL_STR_L "null"
|
||||
|
||||
|
@ -131,19 +136,16 @@ do { \
|
|||
(src) = (void *)((char *)src + sizeof(type));\
|
||||
} while(0)
|
||||
|
||||
#define GET_INT8_VAL(x) (*(int8_t *)(x))
|
||||
#define GET_INT16_VAL(x) (*(int16_t *)(x))
|
||||
#define GET_INT32_VAL(x) (*(int32_t *)(x))
|
||||
#define GET_INT64_VAL(x) (*(int64_t *)(x))
|
||||
#define GET_INT8_VAL(x) (*(int8_t *)(x))
|
||||
#define GET_INT16_VAL(x) (*(int16_t *)(x))
|
||||
#define GET_INT32_VAL(x) (*(int32_t *)(x))
|
||||
#define GET_INT64_VAL(x) (*(int64_t *)(x))
|
||||
#define GET_UINT8_VAL(x) (*(uint8_t*) (x))
|
||||
#define GET_UINT16_VAL(x) (*(uint16_t *)(x))
|
||||
#define GET_UINT32_VAL(x) (*(uint32_t *)(x))
|
||||
#define GET_UINT64_VAL(x) (*(uint64_t *)(x))
|
||||
|
||||
#ifdef _TD_ARM_32
|
||||
|
||||
//#define __float_align_declear() float __underlyFloat = 0.0;
|
||||
//#define __float_align_declear()
|
||||
//#define GET_FLOAT_VAL_ALIGN(x) (*(int32_t*)&(__underlyFloat) = *(int32_t*)(x); __underlyFloat);
|
||||
// notes: src must be float or double type variable !!!
|
||||
//#define SET_FLOAT_VAL_ALIGN(dst, src) (*(int32_t*) dst = *(int32_t*)src);
|
||||
//#define SET_DOUBLE_VAL_ALIGN(dst, src) (*(int64_t*) dst = *(int64_t*)src);
|
||||
|
||||
float taos_align_get_float(const char* pBuf);
|
||||
double taos_align_get_double(const char* pBuf);
|
||||
|
||||
|
@ -171,14 +173,14 @@ typedef struct tDataTypeDescriptor {
|
|||
char algorithm, char *const buffer, int bufferSize);
|
||||
int (*decompFunc)(const char *const input, int compressedSize, const int nelements, char *const output,
|
||||
int outputSize, char algorithm, char *const buffer, int bufferSize);
|
||||
void (*getStatisFunc)(const TSKEY *primaryKey, const void *pData, int32_t numofrow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minindex, int16_t *maxindex, int16_t *numofnull);
|
||||
void (*getStatisFunc)(const void *pData, int32_t numofrow, int64_t *min, int64_t *max, int64_t *sum,
|
||||
int16_t *minindex, int16_t *maxindex, int16_t *numofnull);
|
||||
} tDataTypeDescriptor;
|
||||
|
||||
extern tDataTypeDescriptor tDataTypeDesc[11];
|
||||
extern tDataTypeDescriptor tDataTypeDesc[15];
|
||||
|
||||
bool isValidDataType(int32_t type);
|
||||
//bool isNull(const char *val, int32_t type);
|
||||
|
||||
static FORCE_INLINE bool isNull(const char *val, int32_t type) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -200,6 +202,15 @@ static FORCE_INLINE bool isNull(const char *val, int32_t type) {
|
|||
return varDataLen(val) == sizeof(int32_t) && *(uint32_t*) varDataVal(val) == TSDB_DATA_NCHAR_NULL;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
return varDataLen(val) == sizeof(int8_t) && *(uint8_t *) varDataVal(val) == TSDB_DATA_BINARY_NULL;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
return *(uint8_t*) val == TSDB_DATA_UTINYINT_NULL;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
return *(uint16_t*) val == TSDB_DATA_USMALLINT_NULL;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
return *(uint32_t*) val == TSDB_DATA_UINT_NULL;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
return *(uint64_t*) val == TSDB_DATA_UBIGINT_NULL;
|
||||
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
|
@ -213,6 +224,10 @@ void* getNullValue(int32_t type);
|
|||
void assignVal(char *val, const char *src, int32_t len, int32_t type);
|
||||
void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf);
|
||||
|
||||
int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bool issigned);
|
||||
|
||||
#define SET_DOUBLE_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_DOUBLE_NULL)
|
||||
|
||||
// TODO: check if below is necessary
|
||||
#define TSDB_RELATION_INVALID 0
|
||||
#define TSDB_RELATION_LESS 1
|
||||
|
@ -241,10 +256,8 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_USER_LEN TSDB_UNI_LEN
|
||||
|
||||
// ACCOUNT is a 32 bit positive integer
|
||||
// this is the length of its string representation
|
||||
// including the terminator zero
|
||||
#define TSDB_ACCT_LEN 11
|
||||
#define TSDB_PASSWORD_LEN TSDB_UNI_LEN
|
||||
// this is the length of its string representation, including the terminator zero
|
||||
#define TSDB_ACCT_ID_LEN 11
|
||||
|
||||
#define TSDB_MAX_COLUMNS 1024
|
||||
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
||||
|
@ -252,7 +265,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_NODE_NAME_LEN 64
|
||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||
#define TSDB_DB_NAME_LEN 33
|
||||
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_COL_NAME_LEN 65
|
||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||
|
@ -278,11 +291,6 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_EP_LEN (TSDB_FQDN_LEN+6)
|
||||
#define TSDB_IPv4ADDR_LEN 16
|
||||
#define TSDB_FILENAME_LEN 128
|
||||
#define TSDB_METER_VNODE_BITS 20
|
||||
#define TSDB_METER_SID_MASK 0xFFFFF
|
||||
#define TSDB_SHELL_VNODE_BITS 24
|
||||
#define TSDB_SHELL_SID_MASK 0xFF
|
||||
#define TSDB_HTTP_TOKEN_LEN 20
|
||||
#define TSDB_SHOW_SQL_LEN 512
|
||||
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
||||
|
||||
|
@ -296,9 +304,6 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_MQTT_TOPIC_LEN 64
|
||||
#define TSDB_MQTT_CLIENT_ID_LEN 32
|
||||
|
||||
#define TSDB_METER_STATE_OFFLINE 0
|
||||
#define TSDB_METER_STATE_ONLLINE 1
|
||||
|
||||
#define TSDB_DEFAULT_PKT_SIZE 65480 //same as RPC_MAX_UDP_SIZE
|
||||
|
||||
#define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE
|
||||
|
@ -318,7 +323,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
|
||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||
#define TSDB_UD_COLUMN_INDEX (-100)
|
||||
#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta
|
||||
#define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta
|
||||
|
||||
#define TSDB_MIN_CACHE_BLOCK_SIZE 1
|
||||
#define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode
|
||||
|
@ -380,6 +385,9 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_MIN_DB_REPLICA_OPTION 1
|
||||
#define TSDB_MAX_DB_REPLICA_OPTION 3
|
||||
#define TSDB_DEFAULT_DB_REPLICA_OPTION 1
|
||||
|
||||
#define TSDB_MIN_DB_QUORUM_OPTION 1
|
||||
#define TSDB_MAX_DB_QUORUM_OPTION 2
|
||||
#define TSDB_DEFAULT_DB_QUORUM_OPTION 1
|
||||
|
||||
#define TSDB_MAX_JOIN_TABLE_NUM 5
|
||||
|
@ -436,7 +444,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_PORT_HTTP 11
|
||||
#define TSDB_PORT_ARBITRATOR 12
|
||||
|
||||
#define TSDB_MAX_WAL_SIZE (1024*1024*2)
|
||||
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
|
||||
|
||||
typedef enum {
|
||||
TAOS_QTYPE_RPC = 0,
|
||||
|
|
|
@ -126,6 +126,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, 0, 0x030B, "Data expir
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "Invalid query id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "Invalid stream id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "Invalid connection id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_IS_RUNNING, 0, 0x0310, "mnode is alreay running")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_CONFIG_SYNC, 0, 0x0311, "failed to config sync")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_START_SYNC, 0, 0x0312, "failed to start sync")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_CREATE_DIR, 0, 0x0313, "failed to create mnode dir")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_INIT_STEP, 0, 0x0314, "failed to init components")
|
||||
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "Object already there")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "Unexpected generic error in sdb")
|
||||
|
@ -175,6 +180,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_TAG_NOT_EXIST, 0, 0x036A, "Tag does n
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_ALREAY_EXIST, 0, 0x036B, "Field already exists")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_NOT_EXIST, 0, 0x036C, "Field does not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STABLE_NAME, 0, 0x036D, "Super table does not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CREATE_TABLE_MSG, 0, 0x036E, "Invalid create table message")
|
||||
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_SELECTED, 0, 0x0380, "Database not specified or available")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ALREADY_EXIST, 0, 0x0381, "Database already exists")
|
||||
|
@ -194,6 +200,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_NO_WRITE_ACCESS, 0, 0x0402, "No permission for disk files in dnode")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, 0, 0x0403, "Invalid message length")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, 0, 0x0404, "Action in progress")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_TOO_MANY_VNODES, 0, 0x0405, "Too many vnode directories")
|
||||
|
||||
// vnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, 0, 0x0500, "Action in progress")
|
||||
|
|
|
@ -268,7 +268,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
int32_t len; // one create table message
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
int8_t igExists;
|
||||
int8_t getMeta;
|
||||
int16_t numOfTags;
|
||||
|
@ -290,7 +290,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
int16_t type; /* operation type */
|
||||
int16_t numOfCols; /* number of schema */
|
||||
int32_t tagValLen;
|
||||
|
@ -322,7 +322,7 @@ typedef struct {
|
|||
} SConnectMsg;
|
||||
|
||||
typedef struct {
|
||||
char acctId[TSDB_ACCT_LEN];
|
||||
char acctId[TSDB_ACCT_ID_LEN];
|
||||
char serverVersion[TSDB_VERSION_LEN];
|
||||
char clusterId[TSDB_CLUSTER_ID_LEN];
|
||||
int8_t writeAuth;
|
||||
|
@ -476,6 +476,7 @@ typedef struct {
|
|||
int16_t numOfCols; // the number of columns will be load from vnode
|
||||
SInterval interval;
|
||||
uint16_t tagCondLen; // tag length in current query
|
||||
uint32_t tbnameCondLen; // table name filter condition string length
|
||||
int16_t numOfGroupCols; // num of group by columns
|
||||
int16_t orderByIdx;
|
||||
int16_t orderType; // used in group by xx order by xxx
|
||||
|
@ -494,6 +495,7 @@ typedef struct {
|
|||
int32_t tsNumOfBlocks; // ts comp block numbers
|
||||
int32_t tsOrder; // ts comp block order
|
||||
int32_t numOfTags; // number of tags columns involved
|
||||
int32_t sqlstrLen; // sql query string
|
||||
SColumnInfo colList[];
|
||||
} SQueryTableMsg;
|
||||
|
||||
|
@ -532,7 +534,7 @@ typedef struct {
|
|||
} SVnodeLoad;
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
int32_t cacheBlockSize; //MB
|
||||
int32_t totalBlocks;
|
||||
int32_t maxTables;
|
||||
|
@ -680,7 +682,7 @@ typedef struct {
|
|||
} SVnodeDesc;
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
SVnodeCfg cfg;
|
||||
SVnodeDesc nodes[TSDB_MAX_REPLICA];
|
||||
} SCreateVnodeMsg, SAlterVnodeMsg;
|
||||
|
@ -725,7 +727,6 @@ typedef struct {
|
|||
typedef struct STableMetaMsg {
|
||||
int32_t contLen;
|
||||
char tableId[TSDB_TABLE_FNAME_LEN]; // table id
|
||||
char sTableId[TSDB_TABLE_FNAME_LEN];
|
||||
uint8_t numOfTags;
|
||||
uint8_t precision;
|
||||
uint8_t tableType;
|
||||
|
@ -735,6 +736,9 @@ typedef struct STableMetaMsg {
|
|||
int32_t tid;
|
||||
uint64_t uid;
|
||||
SVgroupMsg vgroup;
|
||||
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||
uint64_t suid;
|
||||
SSchema schema[];
|
||||
} STableMetaMsg;
|
||||
|
||||
|
@ -757,7 +761,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
int8_t type;
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
uint16_t payloadLen;
|
||||
char payload[];
|
||||
} SShowMsg;
|
||||
|
|
|
@ -26,7 +26,7 @@ typedef int32_t (*FCqWrite)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg
|
|||
typedef struct {
|
||||
int32_t vgId;
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
FCqWrite cqWrite;
|
||||
} SCqCfg;
|
||||
|
|
|
@ -117,112 +117,114 @@
|
|||
#define TK_CACHELAST 99
|
||||
#define TK_LP 100
|
||||
#define TK_RP 101
|
||||
#define TK_TAGS 102
|
||||
#define TK_USING 103
|
||||
#define TK_AS 104
|
||||
#define TK_COMMA 105
|
||||
#define TK_NULL 106
|
||||
#define TK_SELECT 107
|
||||
#define TK_UNION 108
|
||||
#define TK_ALL 109
|
||||
#define TK_FROM 110
|
||||
#define TK_VARIABLE 111
|
||||
#define TK_INTERVAL 112
|
||||
#define TK_FILL 113
|
||||
#define TK_SLIDING 114
|
||||
#define TK_ORDER 115
|
||||
#define TK_BY 116
|
||||
#define TK_ASC 117
|
||||
#define TK_DESC 118
|
||||
#define TK_GROUP 119
|
||||
#define TK_HAVING 120
|
||||
#define TK_LIMIT 121
|
||||
#define TK_OFFSET 122
|
||||
#define TK_SLIMIT 123
|
||||
#define TK_SOFFSET 124
|
||||
#define TK_WHERE 125
|
||||
#define TK_NOW 126
|
||||
#define TK_RESET 127
|
||||
#define TK_QUERY 128
|
||||
#define TK_ADD 129
|
||||
#define TK_COLUMN 130
|
||||
#define TK_TAG 131
|
||||
#define TK_CHANGE 132
|
||||
#define TK_SET 133
|
||||
#define TK_KILL 134
|
||||
#define TK_CONNECTION 135
|
||||
#define TK_STREAM 136
|
||||
#define TK_COLON 137
|
||||
#define TK_ABORT 138
|
||||
#define TK_AFTER 139
|
||||
#define TK_ATTACH 140
|
||||
#define TK_BEFORE 141
|
||||
#define TK_BEGIN 142
|
||||
#define TK_CASCADE 143
|
||||
#define TK_CLUSTER 144
|
||||
#define TK_CONFLICT 145
|
||||
#define TK_COPY 146
|
||||
#define TK_DEFERRED 147
|
||||
#define TK_DELIMITERS 148
|
||||
#define TK_DETACH 149
|
||||
#define TK_EACH 150
|
||||
#define TK_END 151
|
||||
#define TK_EXPLAIN 152
|
||||
#define TK_FAIL 153
|
||||
#define TK_FOR 154
|
||||
#define TK_IGNORE 155
|
||||
#define TK_IMMEDIATE 156
|
||||
#define TK_INITIALLY 157
|
||||
#define TK_INSTEAD 158
|
||||
#define TK_MATCH 159
|
||||
#define TK_KEY 160
|
||||
#define TK_OF 161
|
||||
#define TK_RAISE 162
|
||||
#define TK_REPLACE 163
|
||||
#define TK_RESTRICT 164
|
||||
#define TK_ROW 165
|
||||
#define TK_STATEMENT 166
|
||||
#define TK_TRIGGER 167
|
||||
#define TK_VIEW 168
|
||||
#define TK_COUNT 169
|
||||
#define TK_SUM 170
|
||||
#define TK_AVG 171
|
||||
#define TK_MIN 172
|
||||
#define TK_MAX 173
|
||||
#define TK_FIRST 174
|
||||
#define TK_LAST 175
|
||||
#define TK_TOP 176
|
||||
#define TK_BOTTOM 177
|
||||
#define TK_STDDEV 178
|
||||
#define TK_PERCENTILE 179
|
||||
#define TK_APERCENTILE 180
|
||||
#define TK_LEASTSQUARES 181
|
||||
#define TK_HISTOGRAM 182
|
||||
#define TK_DIFF 183
|
||||
#define TK_SPREAD 184
|
||||
#define TK_TWA 185
|
||||
#define TK_INTERP 186
|
||||
#define TK_LAST_ROW 187
|
||||
#define TK_RATE 188
|
||||
#define TK_IRATE 189
|
||||
#define TK_SUM_RATE 190
|
||||
#define TK_SUM_IRATE 191
|
||||
#define TK_AVG_RATE 192
|
||||
#define TK_AVG_IRATE 193
|
||||
#define TK_TBID 194
|
||||
#define TK_SEMI 195
|
||||
#define TK_NONE 196
|
||||
#define TK_PREV 197
|
||||
#define TK_LINEAR 198
|
||||
#define TK_IMPORT 199
|
||||
#define TK_METRIC 200
|
||||
#define TK_TBNAME 201
|
||||
#define TK_JOIN 202
|
||||
#define TK_METRICS 203
|
||||
#define TK_STABLE 204
|
||||
#define TK_INSERT 205
|
||||
#define TK_INTO 206
|
||||
#define TK_VALUES 207
|
||||
#define TK_UNSIGNED 102
|
||||
#define TK_TAGS 103
|
||||
#define TK_USING 104
|
||||
#define TK_AS 105
|
||||
#define TK_COMMA 106
|
||||
#define TK_NULL 107
|
||||
#define TK_SELECT 108
|
||||
#define TK_UNION 109
|
||||
#define TK_ALL 110
|
||||
#define TK_FROM 111
|
||||
#define TK_VARIABLE 112
|
||||
#define TK_INTERVAL 113
|
||||
#define TK_FILL 114
|
||||
#define TK_SLIDING 115
|
||||
#define TK_ORDER 116
|
||||
#define TK_BY 117
|
||||
#define TK_ASC 118
|
||||
#define TK_DESC 119
|
||||
#define TK_GROUP 120
|
||||
#define TK_HAVING 121
|
||||
#define TK_LIMIT 122
|
||||
#define TK_OFFSET 123
|
||||
#define TK_SLIMIT 124
|
||||
#define TK_SOFFSET 125
|
||||
#define TK_WHERE 126
|
||||
#define TK_NOW 127
|
||||
#define TK_RESET 128
|
||||
#define TK_QUERY 129
|
||||
#define TK_ADD 130
|
||||
#define TK_COLUMN 131
|
||||
#define TK_TAG 132
|
||||
#define TK_CHANGE 133
|
||||
#define TK_SET 134
|
||||
#define TK_KILL 135
|
||||
#define TK_CONNECTION 136
|
||||
#define TK_STREAM 137
|
||||
#define TK_COLON 138
|
||||
#define TK_ABORT 139
|
||||
#define TK_AFTER 140
|
||||
#define TK_ATTACH 141
|
||||
#define TK_BEFORE 142
|
||||
#define TK_BEGIN 143
|
||||
#define TK_CASCADE 144
|
||||
#define TK_CLUSTER 145
|
||||
#define TK_CONFLICT 146
|
||||
#define TK_COPY 147
|
||||
#define TK_DEFERRED 148
|
||||
#define TK_DELIMITERS 149
|
||||
#define TK_DETACH 150
|
||||
#define TK_EACH 151
|
||||
#define TK_END 152
|
||||
#define TK_EXPLAIN 153
|
||||
#define TK_FAIL 154
|
||||
#define TK_FOR 155
|
||||
#define TK_IGNORE 156
|
||||
#define TK_IMMEDIATE 157
|
||||
#define TK_INITIALLY 158
|
||||
#define TK_INSTEAD 159
|
||||
#define TK_MATCH 160
|
||||
#define TK_KEY 161
|
||||
#define TK_OF 162
|
||||
#define TK_RAISE 163
|
||||
#define TK_REPLACE 164
|
||||
#define TK_RESTRICT 165
|
||||
#define TK_ROW 166
|
||||
#define TK_STATEMENT 167
|
||||
#define TK_TRIGGER 168
|
||||
#define TK_VIEW 169
|
||||
#define TK_COUNT 170
|
||||
#define TK_SUM 171
|
||||
#define TK_AVG 172
|
||||
#define TK_MIN 173
|
||||
#define TK_MAX 174
|
||||
#define TK_FIRST 175
|
||||
#define TK_LAST 176
|
||||
#define TK_TOP 177
|
||||
#define TK_BOTTOM 178
|
||||
#define TK_STDDEV 179
|
||||
#define TK_PERCENTILE 180
|
||||
#define TK_APERCENTILE 181
|
||||
#define TK_LEASTSQUARES 182
|
||||
#define TK_HISTOGRAM 183
|
||||
#define TK_DIFF 184
|
||||
#define TK_SPREAD 185
|
||||
#define TK_TWA 186
|
||||
#define TK_INTERP 187
|
||||
#define TK_LAST_ROW 188
|
||||
#define TK_RATE 189
|
||||
#define TK_IRATE 190
|
||||
#define TK_SUM_RATE 191
|
||||
#define TK_SUM_IRATE 192
|
||||
#define TK_AVG_RATE 193
|
||||
#define TK_AVG_IRATE 194
|
||||
#define TK_TBID 195
|
||||
#define TK_SEMI 196
|
||||
#define TK_NONE 197
|
||||
#define TK_PREV 198
|
||||
#define TK_LINEAR 199
|
||||
#define TK_IMPORT 200
|
||||
#define TK_METRIC 201
|
||||
#define TK_TBNAME 202
|
||||
#define TK_JOIN 203
|
||||
#define TK_METRICS 204
|
||||
#define TK_STABLE 205
|
||||
#define TK_INSERT 206
|
||||
#define TK_INTO 207
|
||||
#define TK_VALUES 208
|
||||
|
||||
|
||||
|
||||
#define TK_SPACE 300
|
||||
|
|
|
@ -8,27 +8,56 @@ extern "C" {
|
|||
#include "taosdef.h"
|
||||
|
||||
#define GET_TYPED_DATA(_v, _finalType, _type, _data) \
|
||||
switch (_type) { \
|
||||
case TSDB_DATA_TYPE_BOOL: \
|
||||
case TSDB_DATA_TYPE_TINYINT: \
|
||||
(_v) = (_finalType)GET_INT8_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_SMALLINT: \
|
||||
(_v) = (_finalType)GET_INT16_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_BIGINT: \
|
||||
(_v) = (_finalType)(GET_INT64_VAL(_data)); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_FLOAT: \
|
||||
(_v) = (_finalType)GET_FLOAT_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_DOUBLE: \
|
||||
(_v) = (_finalType)GET_DOUBLE_VAL(_data); \
|
||||
break; \
|
||||
default: \
|
||||
(_v) = (_finalType)GET_INT32_VAL(_data); \
|
||||
break; \
|
||||
}
|
||||
do { \
|
||||
switch (_type) { \
|
||||
case TSDB_DATA_TYPE_BOOL: \
|
||||
case TSDB_DATA_TYPE_TINYINT: \
|
||||
(_v) = (_finalType)GET_INT8_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_UTINYINT: \
|
||||
(_v) = (_finalType)GET_UINT8_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_SMALLINT: \
|
||||
(_v) = (_finalType)GET_INT16_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_USMALLINT: \
|
||||
(_v) = (_finalType)GET_UINT16_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_BIGINT: \
|
||||
(_v) = (_finalType)(GET_INT64_VAL(_data)); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_UBIGINT: \
|
||||
(_v) = (_finalType)(GET_UINT64_VAL(_data)); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_FLOAT: \
|
||||
(_v) = (_finalType)GET_FLOAT_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_DOUBLE: \
|
||||
(_v) = (_finalType)GET_DOUBLE_VAL(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_UINT: \
|
||||
(_v) = (_finalType)GET_UINT32_VAL(_data); \
|
||||
break; \
|
||||
default: \
|
||||
(_v) = (_finalType)GET_INT32_VAL(_data); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
|
||||
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
|
||||
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
|
||||
|
||||
#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t)))
|
||||
|
||||
#define IS_VALID_TINYINT(_t) ((_t) > INT8_MIN && (_t) <= INT8_MAX)
|
||||
#define IS_VALID_SMALLINT(_t) ((_t) > INT16_MIN && (_t) <= INT16_MAX)
|
||||
#define IS_VALID_INT(_t) ((_t) > INT32_MIN && (_t) <= INT32_MAX)
|
||||
#define IS_VALID_BIGINT(_t) ((_t) > INT64_MIN && (_t) <= INT64_MAX)
|
||||
#define IS_VALID_UTINYINT(_t) ((_t) >= 0 && (_t) < UINT8_MAX)
|
||||
#define IS_VALID_USMALLINT(_t) ((_t) >= 0 && (_t) < UINT16_MAX)
|
||||
#define IS_VALID_UINT(_t) ((_t) >= 0 && (_t) < UINT32_MAX)
|
||||
#define IS_VALID_UBIGINT(_t) ((_t) >= 0 && (_t) < UINT64_MAX)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ typedef struct {
|
|||
SRpcMsg rpcMsg;
|
||||
SRspRet rspRet;
|
||||
char reserveForSync[24];
|
||||
SWalHead pHead[];
|
||||
SWalHead pHead;
|
||||
} SVWriteMsg;
|
||||
|
||||
// vnodeStatus
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
PROJECT(TDengine)
|
||||
|
||||
ADD_SUBDIRECTORY(shell)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue