提交 6136051a 编写于 作者: W wenzhouwww

Merge branch 'develop' of github.com:taosdata/TDengine into develop

...@@ -86,7 +86,6 @@ tests/script/api/batchprepare ...@@ -86,7 +86,6 @@ tests/script/api/batchprepare
tests/script/api/stmt tests/script/api/stmt
tests/script/api/stmtBatchTest tests/script/api/stmtBatchTest
tests/script/api/stmtTest tests/script/api/stmtTest
# Emacs # Emacs
# -*- mode: gitignore; -*- # -*- mode: gitignore; -*-
*~ *~
......
...@@ -450,7 +450,7 @@ pipeline { ...@@ -450,7 +450,7 @@ pipeline {
stage('test_b1_s2') { stage('test_b1_s2') {
agent{label " slave2 || slave12 "} agent{label " slave2 || slave12 "}
steps { steps {
timeout(time: 55, unit: 'MINUTES'){ timeout(time: 105, unit: 'MINUTES'){
pre_test() pre_test()
sh ''' sh '''
rm -rf /var/lib/taos/* rm -rf /var/lib/taos/*
......
...@@ -265,7 +265,7 @@ IF (TD_WINDOWS) ...@@ -265,7 +265,7 @@ IF (TD_WINDOWS)
ADD_DEFINITIONS(-D_MBCS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) ADD_DEFINITIONS(-D_MBCS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
SET(CMAKE_GENERATOR "NMake Makefiles" CACHE INTERNAL "" FORCE) SET(CMAKE_GENERATOR "NMake Makefiles" CACHE INTERNAL "" FORCE)
IF (NOT TD_GODLL) IF (NOT TD_GODLL)
SET(COMMON_FLAGS "/nologo /WX /wd4018 /wd5999 /Oi /Oy- /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Gd /errorReport:prompt /analyze-") SET(COMMON_FLAGS "/nologo /WX /wd4018 /wd4999 /Oi /Oy- /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Gd /errorReport:prompt /analyze-")
IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900)) IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18") SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
ENDIF () ENDIF ()
......
...@@ -55,7 +55,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、 ...@@ -55,7 +55,7 @@ TDengine提供了丰富的应用程序开发接口,其中包括C/C++、Java、
*install_client.sh*:安装脚本,用于应用驱动程序 *install_client.sh*:安装脚本,用于应用驱动程序
*taos.tar.gz*:应用驱动安装包 *taos.tar.gz*:应用驱动安装包
*driver*:TDengine应用驱动driver *driver*:TDengine应用驱动driver
*connector*: 各种编程语言连接器(go/grafanaplugin/nodejs/python/JDBC) *connector*: 各种编程语言连接器(go/nodejs/python/JDBC)
*examples*: 各种编程语言的示例程序(c/C#/go/JDBC/MATLAB/python/R) *examples*: 各种编程语言的示例程序(c/C#/go/JDBC/MATLAB/python/R)
运行install_client.sh进行安装。 运行install_client.sh进行安装。
...@@ -541,9 +541,8 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 ...@@ -541,9 +541,8 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
Python连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1963.html) Python连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1963.html)
**安装**:参见下面具体步骤 * **安装**:参见下面具体步骤
* **示例程序**:位于install_directory/examples/python
**示例程序**:位于install_directory/examples/python
### 安装 ### 安装
...@@ -557,47 +556,36 @@ Python连接器支持的系统有:Linux 64/Windows x64 ...@@ -557,47 +556,36 @@ Python连接器支持的系统有:Linux 64/Windows x64
### Python连接器安装 ### Python连接器安装
**Linux** Python 连接器可以通过 `pip` 从 PyPI 下载安装。注意 TDengine Python 连接器的包名为 `taospy` 而不是 `taos`(这是一个与 TDengine 无关的另一个程序)。但为保持向后兼容性,仍然使用 `import taos` 导入。
用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到connector安装包。用户可以通过pip命令安装:
`pip install src/connector/python/`
`pip3 install src/connector/python/`
**Windows**
在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\Windows\system32" 目录下, 然后进入Windows *cmd* 命令行界面
```bash ```bash
cd C:\TDengine\connector\python pip install taospy
python -m pip install .
``` ```
**PyPI** 如果不使用系统默认的 `python``pip`,则需要指定 `pip` 的版本或路径:
从2.1.1版本开始,用户可以从[PyPI](https://pypi.org/project/taospy/)安装: ```bash
pip2 install taospy
```sh pip3 install taospy
pip install taospy
``` ```
* 如果机器上没有pip命令,用户可将src/connector/python下的taos文件夹拷贝到应用程序的目录使用。 Python 命令行依赖 taos 动态库 `libtaos.so``taos.dll`, 对于 Windows 客户端,安装TDengine windows 客户端后,如果不能正常 `import taos`,可以将 `C:\TDengine\driver\taos.dll` 拷贝到 `C:\windows\system32` 目录后重新尝试。
对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。
对于无法联网用户,可以将TDengine客户端中的 `connector/python` 路径(Linux 下其安装路径为 `/usr/local/taos/connector/python/`,Windows 下默认安装路径为 `C:\TDengine\connector\python`)添加到 `PYTHONPATH` 环境变量中使用。
### 示例程序 ### 示例程序
示例程序源码位于install_directory/examples/Python,有: 示例程序源码位于 `<install_directory>/examples/python`,有:
**read_example.py Python示例源程序**
* **read_example.py** Python示例源程序
用户可以参考read_example.py这个程序来设计用户自己的写入、查询程序。 用户可以参考`read_example.py`这个程序来设计用户自己的写入、查询程序。
在安装了对应的应用驱动后,通过import taos引入taos类。主要步骤如下: 在安装了对应的应用驱动后,通过`import taos`引入taos类。主要步骤如下:
- 通过taos.connect获取TDengineConnection对象,这个对象可以一个程序只申请一个,在多线程中共享。 - 通过taos.connect获取TaosConnection对象,这个对象可以一个程序只申请一个,在多线程中共享。
- 通过TDengineConnection对象的 .cursor()方法获取一个新的游标对象,这个游标对象必须保证每个线程独享。 - 通过TaosConnection对象的 `.cursor()` 方法获取一个新的游标对象,这个游标对象必须保证每个线程独享。
- 通过游标对象的execute()方法,执行写入或查询的SQL语句。 - 通过游标对象的execute()方法,执行写入或查询的SQL语句。
...@@ -634,127 +622,132 @@ for row in results: ...@@ -634,127 +622,132 @@ for row in results:
print(row) print(row)
``` ```
#### 代码示例 ##### 代码示例
* 导入TDengine客户端模块 1. 导入TDengine客户端模块
```python ```python
import taos import taos
``` ```
* 获取连接并获取游标对象
```python 2. 获取连接并获取游标对象
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
c1 = conn.cursor()
```
* *host* 是TDengine 服务端所有IP, *config* 为客户端配置文件所在目录
* 写入数据 ```python
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
c1 = conn.cursor()
```
```python *host* 是TDengine 服务端所在IP, *config* 为客户端配置文件所在目录。
import datetime
# 创建数据库
c1.execute('create database db')
c1.execute('use db')
# 建表
c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
# 插入数据
start_time = datetime.datetime(2019, 11, 1)
affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
# 批量插入数据
time_interval = datetime.timedelta(seconds=60)
sqlcmd = ['insert into tb values']
for irow in range(1,11):
start_time += time_interval
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
affected_rows = c1.execute(' '.join(sqlcmd))
```
* 查询数据 3. 写入数据
```python ```python
c1.execute('select * from tb') import datetime
# 拉取查询结果
data = c1.fetchall() # 创建数据库
# 返回的结果是一个列表,每一行构成列表的一个元素 c1.execute('create database db')
numOfRows = c1.rowcount c1.execute('use db')
numOfCols = len(c1.description) # 建表
for irow in range(numOfRows): c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])) # 插入数据
start_time = datetime.datetime(2019, 11, 1)
# 直接使用cursor 循环拉取查询结果 affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
c1.execute('select * from tb') # 批量插入数据
for data in c1: time_interval = datetime.timedelta(seconds=60)
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) sqlcmd = ['insert into tb values']
``` for irow in range(1,11):
start_time += time_interval
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
affected_rows = c1.execute(' '.join(sqlcmd))
```
* 从v2.1.0版本开始, 我们提供另外一种API:`connection.query` 4. 查询数据
```python ```python
import taos c1.execute('select * from tb')
# 拉取查询结果
data = c1.fetchall()
# 返回的结果是一个列表,每一行构成列表的一个元素
numOfRows = c1.rowcount
numOfCols = len(c1.description)
for irow in range(numOfRows):
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1], data[irow][2]))
# 直接使用cursor 循环拉取查询结果
c1.execute('select * from tb')
for data in c1:
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1], data[2]))
```
conn = taos.connect() #### Query API
conn.execute("create database if not exists pytest")
result = conn.query("show databases") 从v2.1.0版本开始, 我们提供另外一种方法:`connection.query` 来操作数据库。
num_of_fields = result.field_count
for field in result.fields:
print(field)
for row in result:
print(row)
conn.execute("drop database pytest")
```
`query` 方法会返回一个 `TaosResult` 类对象,并提供了以下有用的属性或方法: ```python
import taos
属性: conn = taos.connect()
conn.execute("create database if not exists pytest")
- `fields`: `TaosFields` 集合类,提供返回数据的列信息。 result = conn.query("show databases")
- `field_count`: 返回数据的列数. num_of_fields = result.field_count
- `affected_rows`: 插入数据的行数. for field in result.fields:
- `row_count`: 查询数据结果数. print(field)
- `precision`: 当前数据库的时间精度. for row in result:
print(row)
conn.execute("drop database pytest")
```
方法: `query` 方法会返回一个 `TaosResult` 对象,并提供了以下属性或方法:
- `fetch_all()`: 类似于 `cursor.fetchall()` 返回同样的集合数据 属性:
- `fetch_all_into_dict()`: v2.1.1 新添加的API,将上面的数据转换成字典类型返回
- `blocks_iter()` `rows_iter()`: 根据底层API提供的两种不同迭代器。
- `fetch_rows_a`: 异步API
- `errno`: 错误码
- `errstr`: 错误信息
- `close`: 关闭结果对象,一般不需要直接调用
- `fields`: `TaosFields` 集合类,提供返回数据的列信息。
- `field_count`: 返回数据的列数.
- `affected_rows`: 插入数据的行数.
- `row_count`: 查询数据结果数.
- `precision`: 当前数据库的时间精度.
* 创建订阅 方法:
```python - `fetch_all()`: 类似于 `cursor.fetchall()` 返回同样的集合数据
# 创建一个主题为 'test' 消费周期为1000毫秒的订阅 - `fetch_all_into_dict()`: v2.1.1 新添加的API,将上面的数据转换成字典类型返回
# 第一个参数为 True 表示重新开始订阅,如为 False 且之前创建过主题为 'test' 的订阅,则表示继续消费此订阅的数据,而不是重新开始消费所有数据 - `blocks_iter()` `rows_iter()`: 根据底层API提供的两种不同迭代器。
sub = conn.subscribe(True, "test", "select * from tb;", 1000) - `fetch_rows_a`: 异步API
``` - `errno`: 错误码
- `errstr`: 错误信息
- `close`: 关闭结果对象,一般不需要直接调用
* 消费订阅的数据 #### 订阅 API
```python 1. 创建一个同步订阅队列:
data = sub.consume()
for d in data:
print(d)
```
* 取消订阅 ```python
# 创建一个主题为 'test' 消费周期为1000毫秒的订阅
# 第一个参数为 True 表示重新开始订阅,如为 False 且之前创建过主题为 'test' 的订阅,
# 则表示继续消费此订阅的数据,而不是重新开始消费所有数据
sub = conn.subscribe(True, "test", "select * from tb;", 1000)
```
```python 2. 消费订阅的数据
sub.close()
```
* 关闭连接 ```python
data = sub.consume()
for d in data:
print(d)
```
```python 3. 取消订阅
c1.close()
conn.close() ```python
``` sub.close()
```
4. 关闭连接
```python
conn.close()
```
#### 关于纳秒 (nanosecond) 在 Python 连接器中的说明 #### 关于纳秒 (nanosecond) 在 Python 连接器中的说明
...@@ -767,30 +760,20 @@ conn.close() ...@@ -767,30 +760,20 @@ conn.close()
用户可通过python的帮助信息直接查看模块的使用信息,或者参考tests/examples/python中的示例程序。以下为部分常用类和方法: 用户可通过python的帮助信息直接查看模块的使用信息,或者参考tests/examples/python中的示例程序。以下为部分常用类和方法:
- _TDengineConnection_ 类 - _TaosConnection_ 类
参考python中help(taos.TDengineConnection)。 参考python中help(taos.TaosConnection)。
这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,推荐每个线程申请一个独立的连接实例,而不建议多线程共享一个连接。 这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,推荐每个线程申请一个独立的连接实例,而不建议多线程共享一个连接。
- _TDengineCursor_ 类 - _TaosCursor_ 类
参考python中help(taos.TDengineCursor)。 参考python中help(taos.TaosCursor)。
这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。 这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。
- _connect_ 方法 - _connect_ 方法
用于生成taos.TDengineConnection的实例。 用于生成taos.TaosConnection的实例。
### Python客户端使用示例代码
在tests/examples/python中,我们提供了一个示例Python程序read_example.py,可以参考这个程序来设计用户自己的写入、查询程序。在安装了对应的客户端后,通过import taos引入taos类。主要步骤如下
- 通过taos.connect获取TDengineConnection对象,这个对象可以一个程序只申请一个,在多线程中共享。
- 通过TDengineConnection对象的 .cursor()方法获取一个新的游标对象,这个游标对象必须保证每个线程独享。
- 通过游标对象的execute()方法,执行写入或查询的SQL语句。
- 如果执行的是写入语句,execute返回的是成功写入的行数信息affected rows。
- 如果执行的是查询语句,则execute执行成功后,需要通过fetchall方法去拉取结果集。
具体方法可以参考示例代码。
## <a class="anchor" id="restful"></a>RESTful Connector ## <a class="anchor" id="restful"></a>RESTful Connector
......
...@@ -411,38 +411,22 @@ See [video tutorials](https://www.taosdata.com/blog/2020/11/11/1963.html) for th ...@@ -411,38 +411,22 @@ See [video tutorials](https://www.taosdata.com/blog/2020/11/11/1963.html) for th
### Python connector installation ### Python connector installation
#### Linux From TDengine 2.4, users can install python connector for TDengine with `pip`. Note that the package name is **taospy** (not `taos` - a fully unrelated package). For backward compatibility, we still use `import taos` to import connector package.
Users can find the connector package for python2 and python3 in the source code src/connector/python (or tar.gz/connector/python) folder. Users can install it through `pip` command: ```bash
`pip install src/connector/python/`
or
`pip3 install src/connector/python/`
You can install the `taospy` connector from [PyPI](https://pypi.org/project/taospy/):
```sh
pip install taospy pip install taospy
``` ```
#### Windows Use your version-specific `pip` command as if you need.
With Windows TDengine client installed, copy the file "C:\TDengine\driver\taos.dll" to the "C:\Windows\system32" directory and enter the Windows *cmd* command line interface: ```bash
pip2 install taospy
```cmd pip3 install taospy
cd C:\TDengine\connector\python
python -m pip install .
``` ```
Or install from PyPI: The python connector requires `libtaos` library (`libtaos.so` in Linux, or `taos.dll` in Windows). For Windows client, if `import taos` failed, you could copy the dll `C:\TDengine\driver\taos.dll` to `C:\windows\system32` and try it again.
```cmd
pip install taospy
```
- If there is no `pip` command on the machine, the user can copy the taos folder under src/connector/python to the application directory for use. For Windows client, after installing the TDengine Windows client, copy C:\ TDengine\driver\taos.dll to the C:\ windows\ system32 directory. For users that has a limited network environment, just add the `connector/python` of installed directory(commonly `/usr/local/taos/connector/python/` in Linux, `C:\TDengine\connector\python` in Windows) to `PYTHONPATH` environment variable.
### How to use ### How to use
...@@ -462,63 +446,66 @@ for row in results: ...@@ -462,63 +446,66 @@ for row in results:
print(row) print(row)
``` ```
#### Code sample ##### Code sample
- Import the TDengine client module - Import the TDengine client module
```python ```python
import taos import taos
``` ```
- Get the connection and cursor object - Get the connection and cursor object
```python ```python
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos") conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
c1 = conn.cursor() c1 = conn.cursor()
``` ```
*host* covers all IPs of TDengine server-side, and *config* is the directory where the client configuration files is located
- *host* covers all IPs of TDengine server-side, and *config* is the directory where the client configuration files is located
- Write data - Write data
```python ```python
import datetime import datetime
# Create a database # Create a database
c1.execute('create database db') c1.execute('create database db')
c1.execute('use db') c1.execute('use db')
# Create a table # Create a table
c1.execute('create table tb (ts timestamp, temperature int, humidity float)') c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
# Insert data # Insert data
start_time = datetime.datetime(2019, 11, 1) start_time = datetime.datetime(2019, 11, 1)
affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time) affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
# Insert data in batch # Insert data in batch
time_interval = datetime.timedelta(seconds=60) time_interval = datetime.timedelta(seconds=60)
sqlcmd = ['insert into tb values'] sqlcmd = ['insert into tb values']
for irow in range(1,11): for irow in range(1,11):
start_time += time_interval start_time += time_interval
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2)) sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
affected_rows = c1.execute(' '.join(sqlcmd)) affected_rows = c1.execute(' '.join(sqlcmd))
``` ```
- Query data - Query data
```python ```python
c1.execute('select * from tb') c1.execute('select * from tb')
# pull query result # pull query result
data = c1.fetchall() data = c1.fetchall()
# The result is a list, with each row as an element # The result is a list, with each row as an element
numOfRows = c1.rowcount numOfRows = c1.rowcount
numOfCols = len(c1.description) numOfCols = len(c1.description)
for irow in range(numOfRows): for irow in range(numOfRows):
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])) print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2]))
# Use cursor loop directly to pull query result # Use cursor loop directly to pull query result
c1.execute('select * from tb') c1.execute('select * from tb')
for data in c1: for data in c1:
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])) print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2]))
``` ```
- Since v2.1.0, python connector provides a new API for query: #### Query API
Since v2.1.0, python connector provides a new API for query:
```python ```python
import taos import taos
...@@ -556,15 +543,19 @@ Functions: ...@@ -556,15 +543,19 @@ Functions:
- `errstr`: error string if failed. - `errstr`: error string if failed.
- `close`: close result, you do not need to call it directly, result will auto closed out of scope. - `close`: close result, you do not need to call it directly, result will auto closed out of scope.
- Create subscription #### Subscription API
Create subscription
```python ```python
# Create a subscription with the topic ‘test’ and a consumption cycle of 1000 milliseconds # Create a subscription with the topic ‘test’ and a consumption cycle of 1000 milliseconds
# If the first parameter is True, it means restarting the subscription. If it is False and a subscription with the topic 'test 'has been created before, it means continuing to consume the data of this subscription instead of restarting to consume all the data # If the first parameter is True, it means restarting the subscription.
# If it is False and a subscription with the topic 'test 'has been created before,
# it means continuing to consume the data of this subscription instead of restarting to consume all the data
sub = conn.subscribe(True, "test", "select * from tb;", 1000) sub = conn.subscribe(True, "test", "select * from tb;", 1000)
``` ```
- Consume subscription data Consume subscription data.
```python ```python
data = sub.consume() data = sub.consume()
...@@ -572,17 +563,15 @@ for d in data: ...@@ -572,17 +563,15 @@ for d in data:
print(d) print(d)
``` ```
- Unsubscription Unsubscribe.
```python ```python
sub.close() sub.close()
``` ```
Close connection.
- Close connection
```python ```python
c1.close()
conn.close() conn.close()
``` ```
......
...@@ -1092,7 +1092,7 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql ...@@ -1092,7 +1092,7 @@ static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo, SSql
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name)); tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, getNewResColId(pCmd)); tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL, 0);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -2191,7 +2191,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS ...@@ -2191,7 +2191,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11);
} }
if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){ if(pItem->aliasName != NULL && strcasecmp(pItem->aliasName, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME) == 0){
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11);
} }
...@@ -2774,12 +2774,17 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2774,12 +2774,17 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
} }
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pColumnSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
// elapsed only can be applied to primary key // elapsed only can be applied to primary key
if (functionId == TSDB_FUNC_ELAPSED && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { if (functionId == TSDB_FUNC_ELAPSED) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "elapsed only can be applied to primary key"); if ( index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX || pColumnSchema->colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "elapsed only can be applied to primary key");
}
} }
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta); STableComInfo info = tscGetTableInfo(pTableMetaInfo->pTableMeta);
// functions can not be applied to tags // functions can not be applied to tags
...@@ -2809,7 +2814,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2809,7 +2814,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || functionId == TSDB_FUNC_CSUM) { if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || functionId == TSDB_FUNC_CSUM) {
SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP,
TSDB_KEYSIZE, getNewResColId(pCmd), TSDB_KEYSIZE, false); TSDB_KEYSIZE, 0, TSDB_KEYSIZE, false);
tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName)); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS_DUMMY].name, sizeof(pExpr->base.aliasName));
SColumnList ids = createColumnList(1, 0, 0); SColumnList ids = createColumnList(1, 0, 0);
...@@ -3130,7 +3135,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -3130,7 +3135,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
// set the first column ts for top/bottom query // set the first column ts for top/bottom query
int32_t tsFuncId = (functionId == TSDB_FUNC_MAVG) ? TSDB_FUNC_TS_DUMMY : TSDB_FUNC_TS; int32_t tsFuncId = (functionId == TSDB_FUNC_MAVG) ? TSDB_FUNC_TS_DUMMY : TSDB_FUNC_TS;
SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
pExpr = tscExprAppend(pQueryInfo, tsFuncId, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pCmd), pExpr = tscExprAppend(pQueryInfo, tsFuncId, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0,
0, false); 0, false);
tstrncpy(pExpr->base.aliasName, aAggs[tsFuncId].name, sizeof(pExpr->base.aliasName)); tstrncpy(pExpr->base.aliasName, aAggs[tsFuncId].name, sizeof(pExpr->base.aliasName));
...@@ -3156,7 +3161,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -3156,7 +3161,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
// todo REFACTOR // todo REFACTOR
// set the first column ts for top/bottom query // set the first column ts for top/bottom query
SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pCmd), pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, 0,
0, false); 0, false);
tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName));
......
...@@ -837,7 +837,7 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, ...@@ -837,7 +837,7 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo,
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (pExpr->resColId >= 0) { if (pExpr->resColId > 0) {
tscError("result column id underflowed: %d", pExpr->resColId); tscError("result column id underflowed: %d", pExpr->resColId);
return TSDB_CODE_TSC_RES_TOO_MANY; return TSDB_CODE_TSC_RES_TOO_MANY;
} }
......
src/TDengineDriver/bin/
src/TDengineDriver/obj/
src/test/Cases/bin/
src/test/Cases/obj/
src/test/XUnitTest/bin/
src/test/XUnitTest/obj/
...@@ -35,7 +35,8 @@ namespace TDengineDriver ...@@ -35,7 +35,8 @@ namespace TDengineDriver
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
TSDB_DATA_TYPE_USMALLINT = 12,// 2 bytes TSDB_DATA_TYPE_USMALLINT = 12,// 2 bytes
TSDB_DATA_TYPE_UINT = 13, // 4 bytes TSDB_DATA_TYPE_UINT = 13, // 4 bytes
TSDB_DATA_TYPE_UBIGINT = 14 // 8 bytes TSDB_DATA_TYPE_UBIGINT = 14, // 8 bytes
TSDB_DATA_TYPE_JSONTAG = 15 //4096 bytes
} }
public enum TDengineInitOption public enum TDengineInitOption
...@@ -46,7 +47,6 @@ namespace TDengineDriver ...@@ -46,7 +47,6 @@ namespace TDengineDriver
TDDB_OPTION_CONFIGDIR = 3, TDDB_OPTION_CONFIGDIR = 3,
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
} }
enum TaosField enum TaosField
{ {
STRUCT_SIZE = 68, STRUCT_SIZE = 68,
...@@ -92,6 +92,8 @@ namespace TDengineDriver ...@@ -92,6 +92,8 @@ namespace TDengineDriver
return "TIMESTAMP"; return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR: case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
return "NCHAR"; return "NCHAR";
case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
return "JSON";
default: default:
return "undefine"; return "undefine";
} }
...@@ -204,6 +206,7 @@ namespace TDengineDriver ...@@ -204,6 +206,7 @@ namespace TDengineDriver
metas.Add(meta); metas.Add(meta);
} }
return metas; return metas;
} }
......
using System;
using Test.UtilsTools;
namespace Cases
{
public class JsonTagTest
{
public void Test(IntPtr conn)
{
Console.WriteLine("STEP 1 prepare data & validate json string===== ");
UtilsTools.ExecuteQuery(conn, "create table if not exists jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_1 using jsons1 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 1, false, 'json1', '涛思数据') (1591060608000, 23, true, '涛思数据', 'json')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_2 using jsons1 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060628000, 2, true, 'json2', 'sss')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_3 using jsons1 tags('{\"tag1\":false,\"tag2\":\"beijing\"}') values (1591060668000, 3, false, 'json3', 'efwe')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_4 using jsons1 tags('{\"tag1\":null,\"tag2\":\"shanghai\",\"tag3\":\"hello\"}') values (1591060728000, 4, true, 'json4', '323sd')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_5 using jsons1 tags('{\"tag1\":1.232, \"tag2\":null}') values(1591060928000, 1, false, '涛思数据', 'ewe')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_6 using jsons1 tags('{\"tag1\":11,\"tag2\":\"\",\"tag2\":null}') values(1591061628000, 11, false, '涛思数据','')");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_7 using jsons1 tags('{\"tag1\":\"涛思数据\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '涛思数据', 'dws')");
Console.WriteLine("");
Console.WriteLine("test duplicate key using the first one. elimate empty key======== ");
UtilsTools.ExecuteQuery(conn, "CREATE TABLE if not exists jsons1_8 using jsons1 tags('{\"tag1\":null, \"tag1\":true, \"tag1\":45, \"1tag$\":2, \" \":90}')");
Console.WriteLine("");
Console.WriteLine("test empty json string, save as jtag is NULL========== ");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_9 using jsons1 tags('\t') values (1591062328000, 24, NULL, '涛思数据', '2sdw')");
UtilsTools.ExecuteQuery(conn, "CREATE TABLE if not exists jsons1_10 using jsons1 tags('')");
UtilsTools.ExecuteQuery(conn, "CREATE TABLE if not exists jsons1_11 using jsons1 tags(' ')");
UtilsTools.ExecuteQuery(conn, "CREATE TABLE if not exists jsons1_12 using jsons1 tags('{}')");
UtilsTools.ExecuteQuery(conn, "CREATE TABLE if not exists jsons1_13 using jsons1 tags('null')");
Console.WriteLine("");
Console.WriteLine("test invalidate json==================== ");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('\"efwewf\"')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('3333')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('33.33')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('false')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('[1,true]')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{222}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"fe\"}')");
Console.WriteLine("");
Console.WriteLine("test invalidate json key, key must can be printed assic char========== ");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":[1,true]}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":{}}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"。loc\":\"fff\"}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"\":\"fff\"}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"\t\":\"fff\"}')");
UtilsTools.ExecuteErrorQuery(conn, "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"试试\":\"fff\"}')");
Console.WriteLine("");
Console.WriteLine("STEP 2 alter table json tag============");
UtilsTools.ExecuteErrorQuery(conn, "ALTER STABLE jsons1 add tag tag2 nchar(20)");
UtilsTools.ExecuteErrorQuery(conn, "ALTER STABLE jsons1 drop tag jtag");
UtilsTools.ExecuteErrorQuery(conn, "ALTER TABLE jsons1_1 SET TAG jtag=4");
UtilsTools.ExecuteQuery(conn, "ALTER TABLE jsons1_1 SET TAG jtag='{\"tag1\":\"femail\",\"tag2\":35,\"tag3\":true}'");
Console.WriteLine("");
Console.WriteLine("STEP 3 query table============");
Console.WriteLine("test error syntax============");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->tag1='beijing'");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'location'");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->''");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->''=9");
UtilsTools.ExecuteErrorQuery(conn, "select -> from jsons1");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where contains");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->");
UtilsTools.ExecuteErrorQuery(conn, "select jtag->location from jsons1");
UtilsTools.ExecuteErrorQuery(conn, "select jtag contains location from jsons1");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag contains location");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag contains''");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag contains 'location'='beijing'");
Console.WriteLine("");
Console.WriteLine("test select normal column===========");
IntPtr res = IntPtr.Zero;
res = UtilsTools.ExecuteQuery(conn, "select dataint from jsons1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1 where jtag is null");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1 where jtag is not null");
UtilsTools.DisplayRes(res);
Console.WriteLine("test #line 41===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1_8");
UtilsTools.DisplayRes(res);
Console.WriteLine("test #line 72===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1_1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test jtag is NULL===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag from jsons1_9");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', value is string ===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from jsons1_1");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag2' from jsons1_6");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', value is int===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag2' from jsons1_1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', value is bool===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag3' from jsons1_1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', value is null===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from jsons1_4");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', value is double===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from jsons1_5");
UtilsTools.DisplayRes(res);
Console.WriteLine("test select json tag->'key', key is not exist===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag10' from jsons1_4");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from jsons1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test header name===========");
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from jsons1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test where with json tag===========");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1_1 where jtag is not null");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag='{\"tag1\":11,\"tag2\":\"\"}'");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'tag1'={}");
Console.WriteLine("where json value is string===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select dataint,tbname,jtag->'tag1',jtag from jsons1 where jtag->'tag2'='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'='涛思数据'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'>'beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'>='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'<'beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'<='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'!='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2'=''");
UtilsTools.DisplayRes(res);
Console.WriteLine("where json value is int===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=5");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=10");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'<54");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'<=11");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'>4");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'>=5");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'!=5");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'!=55");
UtilsTools.DisplayRes(res);
Console.WriteLine("where json value is double===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=1.232");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'<1.232");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'<=1.232");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'>1.23");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'>=1.232");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'!=1.232");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'!=3.232");
UtilsTools.DisplayRes(res);
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'tag1'/0=3");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'tag1'/5=1");
Console.WriteLine("where json value is bool===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=true");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=false");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'!=false");
UtilsTools.DisplayRes(res);
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'tag1'>false");
Console.WriteLine("where json value is null===========");
Console.WriteLine("only json suport =null. This synatx will change later.===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=null");
UtilsTools.DisplayRes(res);
Console.WriteLine("where json is null===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag is null");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag is not null");
UtilsTools.DisplayRes(res);
Console.WriteLine("where json key is null===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag_no_exist'=3");
UtilsTools.DisplayRes(res);
Console.WriteLine("where json value is not exist===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1' is null");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag4' is null");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag3' is not null");
UtilsTools.DisplayRes(res);
Console.WriteLine("test contains===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag contains 'tag1'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag contains 'tag3'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag contains 'tag_no_exist'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test json tag in where condition with and/or===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=false or jtag->'tag2'='beijing'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1' is not null and jtag contains 'tag3'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1'='femail' and jtag contains 'tag3'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test with tbname/normal column===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where tbname = 'jsons1_1'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=3");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=23");
UtilsTools.DisplayRes(res);
Console.WriteLine("test where condition like===========");
res = UtilsTools.ExecuteQuery(conn, "select *,tbname from jsons1 where jtag->'tag2' like 'bei%'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select *,tbname from jsons1 where jtag->'tag1' like 'fe%' and jtag->'tag2' is not null");
UtilsTools.DisplayRes(res);
Console.WriteLine("test where condition in no support in===========");
UtilsTools.ExecuteErrorQuery(conn, "select * from jsons1 where jtag->'tag1' in ('beijing')");
Console.WriteLine("test where condition match===========");
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1' match 'ma'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1' match 'ma$'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag2' match 'jing$'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select * from jsons1 where jtag->'tag1' match '收到'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test distinct===========");
UtilsTools.ExecuteQuery(conn, "insert into jsons1_14 using jsons1 tags('{\"tag1\":\"涛思数据\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '涛思数据', 'dws')");
res = UtilsTools.ExecuteQuery(conn, "select distinct jtag->'tag1' from jsons1");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select distinct jtag from jsons1");
UtilsTools.DisplayRes(res);
Console.WriteLine("test dumplicate key with normal colomn===========");
UtilsTools.ExecuteQuery(conn, "INSERT INTO jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"涛思数据\"}') values(1591060828000, 4, false, 'jjsf', \"你就会\")");
res = UtilsTools.ExecuteQuery(conn, "select *,tbname,jtag from jsons1 where jtag->'datastr' match '涛思数据' and datastr match 'js'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_14'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test join===========");
UtilsTools.ExecuteQuery(conn, "create table if not exists jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)");
UtilsTools.ExecuteQuery(conn, "insert into jsons2_1 using jsons2 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 2, false, 'json2', '涛思数据2')");
UtilsTools.ExecuteQuery(conn, "insert into jsons2_2 using jsons2 tags('{\"tag1\":5,\"tag2\":null}') values (1591060628000, 2, true, 'json2', 'sss')");
UtilsTools.ExecuteQuery(conn, "create table if not exists jsons3(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)");
UtilsTools.ExecuteQuery(conn, "insert into jsons3_1 using jsons3 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 3, false, 'json3', '涛思数据3')");
UtilsTools.ExecuteQuery(conn, "insert into jsons3_2 using jsons3 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060638000, 2, true, 'json3', 'sss')");
res = UtilsTools.ExecuteQuery(conn, "select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test group by & order by json tag===========");
res = UtilsTools.ExecuteQuery(conn, "select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' desc");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' asc");
UtilsTools.DisplayRes(res);
Console.WriteLine("test stddev with group by json tag===========");
res = UtilsTools.ExecuteQuery(conn, "select stddev(dataint) from jsons1 group by jtag->'tag1'");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select stddev(dataint) from jsons1 group by jsons1.jtag->'tag1'");
UtilsTools.DisplayRes(res);
Console.WriteLine("test top/bottom with group by json tag===========");
res = UtilsTools.ExecuteQuery(conn, "select top(dataint,100) from jsons1 group by jtag->'tag1'");
UtilsTools.DisplayRes(res);
Console.WriteLine("subquery with json tag===========");
res = UtilsTools.ExecuteQuery(conn, "select * from (select jtag, dataint from jsons1)");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)");
UtilsTools.DisplayRes(res);
res = UtilsTools.ExecuteQuery(conn, "select ts,tbname,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts)");
UtilsTools.DisplayRes(res);
Console.WriteLine("");
}
}
}
\ No newline at end of file
using System; using System;
using Test.UtilsTools; using Test.UtilsTools;
using Cases; using Cases;
namespace Cases.EntryPoint namespace Cases.EntryPoint
{ {
class Program class Program
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
IntPtr conn = IntPtr.Zero; IntPtr conn = IntPtr.Zero;
IntPtr stmt = IntPtr.Zero; IntPtr stmt = IntPtr.Zero;
IntPtr res = IntPtr.Zero; IntPtr res = IntPtr.Zero;
conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0); conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0);
UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650"); UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650");
UtilsTools.ExecuteQuery(conn, "use csharp"); UtilsTools.ExecuteQuery(conn, "use csharp");
Console.WriteLine("====================StableColumnByColumn==================="); Console.WriteLine("====================StableColumnByColumn===================");
StableColumnByColumn columnByColumn = new StableColumnByColumn(); StableColumnByColumn columnByColumn = new StableColumnByColumn();
columnByColumn.Test(conn, "stablecolumnbycolumn"); columnByColumn.Test(conn, "stablecolumnbycolumn");
Console.WriteLine("====================StmtStableQuery==================="); Console.WriteLine("====================StmtStableQuery===================");
StmtStableQuery stmtStableQuery = new StmtStableQuery(); StmtStableQuery stmtStableQuery = new StmtStableQuery();
stmtStableQuery.Test(conn, "stablecolumnbycolumn"); stmtStableQuery.Test(conn, "stablecolumnbycolumn");
Console.WriteLine("====================StableMutipleLine==================="); Console.WriteLine("====================StableMutipleLine===================");
StableMutipleLine mutipleLine = new StableMutipleLine(); StableMutipleLine mutipleLine = new StableMutipleLine();
mutipleLine.Test(conn, "stablemutipleline"); mutipleLine.Test(conn, "stablemutipleline");
//================================================================================ //================================================================================
Console.WriteLine("====================NtableSingleLine==================="); Console.WriteLine("====================NtableSingleLine===================");
NtableSingleLine ntableSingleLine = new NtableSingleLine(); NtableSingleLine ntableSingleLine = new NtableSingleLine();
ntableSingleLine.Test(conn, "stablesingleline"); ntableSingleLine.Test(conn, "stablesingleline");
Console.WriteLine("====================NtableMutipleLine==================="); Console.WriteLine("====================NtableMutipleLine===================");
NtableMutipleLine ntableMutipleLine = new NtableMutipleLine(); NtableMutipleLine ntableMutipleLine = new NtableMutipleLine();
ntableMutipleLine.Test(conn, "ntablemutipleline"); ntableMutipleLine.Test(conn, "ntablemutipleline");
Console.WriteLine("====================StmtNtableQuery==================="); Console.WriteLine("====================StmtNtableQuery===================");
StmtNtableQuery stmtNtableQuery = new StmtNtableQuery(); StmtNtableQuery stmtNtableQuery = new StmtNtableQuery();
stmtNtableQuery.Test(conn, "ntablemutipleline"); stmtNtableQuery.Test(conn, "ntablemutipleline");
Console.WriteLine("====================NtableColumnByColumn==================="); Console.WriteLine("====================NtableColumnByColumn===================");
NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn(); NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn();
ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn"); ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn");
Console.WriteLine("====================fetchfeilds==================="); Console.WriteLine("====================fetchfeilds===================");
FetchFields fetchFields = new FetchFields(); FetchFields fetchFields = new FetchFields();
fetchFields.Test(conn, "fetchfeilds"); fetchFields.Test(conn,"fetchfeilds");
UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); Console.WriteLine("===================JsonTagTest====================");
UtilsTools.CloseConnection(conn); JsonTagTest jsonTagTest = new JsonTagTest();
UtilsTools.ExitProgram(); jsonTagTest.Test(conn);
} // UtilsTools.ExecuteQuery(conn, "drop database if exists csharp");
} UtilsTools.CloseConnection(conn);
} UtilsTools.ExitProgram();
}
}
}
using System; using System;
using Test.UtilsTools; using Test.UtilsTools;
using TDengineDriver; using TDengineDriver;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Cases namespace Cases
{ {
public class FetchFields public class FetchFields
{ {
public void Test(IntPtr conn, string tableName) public void Test(IntPtr conn, string tableName)
{ {
IntPtr res = IntPtr.Zero; IntPtr res = IntPtr.Zero;
String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(id int);"; String createTb = "create stable " + tableName + " (ts timestamp ,b bool,v1 tinyint,v2 smallint,v4 int,v8 bigint,f4 float,f8 double,u1 tinyint unsigned,u2 smallint unsigned,u4 int unsigned,u8 bigint unsigned,bin binary(200),blob nchar(200))tags(jsontag json);";
String insertSql = "insert into " + tableName + "_t1 using " + tableName + " tags(1) values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')"; String insertSql = "insert into " + tableName + "_t1 using " + tableName + " tags('{\"k1\": \"v1\"}') values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')";
String selectSql = "select * from " + tableName; String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName; String dropSql = "drop table " + tableName;
UtilsTools.ExecuteQuery(conn, createTb); UtilsTools.ExecuteQuery(conn, createTb);
UtilsTools.ExecuteQuery(conn, insertSql); UtilsTools.ExecuteQuery(conn, insertSql);
res = UtilsTools.ExecuteQuery(conn, selectSql); res = UtilsTools.ExecuteQuery(conn, selectSql);
UtilsTools.ExecuteQuery(conn, dropSql); UtilsTools.ExecuteQuery(conn, dropSql);
List<TDengineMeta> metas = new List<TDengineMeta>(); List<TDengineMeta> metas = new List<TDengineMeta>();
metas = TDengine.FetchFields(res); metas = TDengine.FetchFields(res);
if (metas.Capacity == 0) if (metas.Capacity == 0)
{ {
Console.WriteLine("empty result"); Console.WriteLine("empty result");
} }
else else
{ {
foreach(TDengineMeta meta in metas){ foreach(TDengineMeta meta in metas){
Console.WriteLine("col_name:{0},col_type_code:{1},col_type:{2}({3})",meta.name,meta.type,meta.TypeName(),meta.size); Console.WriteLine("col_name:{0},col_type_code:{1},col_type:{2}({3})",meta.name,meta.type,meta.TypeName(),meta.size);
} }
} }
} }
} }
} }
\ No newline at end of file
...@@ -39,6 +39,28 @@ namespace Test.UtilsTools ...@@ -39,6 +39,28 @@ namespace Test.UtilsTools
} }
return res; return res;
} }
public static IntPtr ExecuteErrorQuery(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero)
{
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
return res;
}
public static void DisplayRes(IntPtr res) public static void DisplayRes(IntPtr res)
{ {
long queryRows = 0; long queryRows = 0;
...@@ -120,6 +142,10 @@ namespace Test.UtilsTools ...@@ -120,6 +142,10 @@ namespace Test.UtilsTools
string v10 = Marshal.PtrToStringAnsi(data); string v10 = Marshal.PtrToStringAnsi(data);
builder.Append(v10); builder.Append(v10);
break; break;
case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
string v11 = Marshal.PtrToStringAnsi(data);
builder.Append(v11);
break;
} }
} }
builder.Append("---"); builder.Append("---");
......
Subproject commit dca4059d87c3f5c678a5e946978d40daec204e27 Subproject commit beca4813316f254624d8dbecf54d45a5a232c61d
...@@ -36,7 +36,11 @@ extern "C" { ...@@ -36,7 +36,11 @@ extern "C" {
#define atomic_exchange_8(ptr, val) _InterlockedExchange8((char volatile*)(ptr), (char)(val)) #define atomic_exchange_8(ptr, val) _InterlockedExchange8((char volatile*)(ptr), (char)(val))
#define atomic_exchange_16(ptr, val) _InterlockedExchange16((short volatile*)(ptr), (short)(val)) #define atomic_exchange_16(ptr, val) _InterlockedExchange16((short volatile*)(ptr), (short)(val))
#define atomic_exchange_32(ptr, val) _InterlockedExchange((long volatile*)(ptr), (long)(val)) #define atomic_exchange_32(ptr, val) _InterlockedExchange((long volatile*)(ptr), (long)(val))
#if _MSC_VER >= 1930
#define atomic_exchange_64(ptr, val) InterlockedExchange64((__int64 volatile*)(ptr), (__int64)(val))
#else
#define atomic_exchange_64(ptr, val) _InterlockedExchange64((__int64 volatile*)(ptr), (__int64)(val)) #define atomic_exchange_64(ptr, val) _InterlockedExchange64((__int64 volatile*)(ptr), (__int64)(val))
#endif
#ifdef _WIN64 #ifdef _WIN64
#define atomic_exchange_ptr(ptr, val) _InterlockedExchangePointer((void* volatile*)(ptr), (void*)(val)) #define atomic_exchange_ptr(ptr, val) _InterlockedExchangePointer((void* volatile*)(ptr), (void*)(val))
#else #else
...@@ -91,7 +95,12 @@ extern "C" { ...@@ -91,7 +95,12 @@ extern "C" {
#define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val)) #define atomic_fetch_add_8(ptr, val) _InterlockedExchangeAdd8((char volatile*)(ptr), (char)(val))
#define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val)) #define atomic_fetch_add_16(ptr, val) _InterlockedExchangeAdd16((short volatile*)(ptr), (short)(val))
#define atomic_fetch_add_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), (long)(val)) #define atomic_fetch_add_32(ptr, val) _InterlockedExchangeAdd((long volatile*)(ptr), (long)(val))
#if _MSC_VER >= 1930
#define atomic_fetch_add_64(ptr, val) InterlockedExchangeAdd64((__int64 volatile*)(ptr), (__int64)(val))
#else
#define atomic_fetch_add_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), (__int64)(val)) #define atomic_fetch_add_64(ptr, val) _InterlockedExchangeAdd64((__int64 volatile*)(ptr), (__int64)(val))
#endif
#define atomic_sub_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), -(char)(val)) #define atomic_sub_fetch_8(ptr, val) interlocked_add_fetch_8((char volatile*)(ptr), -(char)(val))
#define atomic_sub_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), -(short)(val)) #define atomic_sub_fetch_16(ptr, val) interlocked_add_fetch_16((short volatile*)(ptr), -(short)(val))
......
...@@ -121,7 +121,7 @@ bool checkTzPresent(char *str, int32_t len) { ...@@ -121,7 +121,7 @@ bool checkTzPresent(char *str, int32_t len) {
} }
inline int32_t taos_parse_time(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { FORCE_INLINE int32_t taos_parse_time(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
return taosParseTime(timestr, time, len, timePrec, day_light); return taosParseTime(timestr, time, len, timePrec, day_light);
} }
......
...@@ -590,7 +590,8 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { ...@@ -590,7 +590,8 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
} }
// outer query order by support // outer query order by support
int32_t orderColId = pQueryAttr->order.orderColId; int32_t orderColId = pQueryAttr->order.orderColId;
if (pQueryAttr->vgId == 0 && orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX && orderColId != INT32_MIN) {
if (pQueryAttr->vgId == 0 && orderColId != INT32_MIN) {
op = OP_Order; op = OP_Order;
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
} }
...@@ -664,7 +665,7 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { ...@@ -664,7 +665,7 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
// outer query order by support // outer query order by support
int32_t orderColId = pQueryAttr->order.orderColId; int32_t orderColId = pQueryAttr->order.orderColId;
if (pQueryAttr->vgId == 0 && orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX && orderColId != INT32_MIN) { if (pQueryAttr->vgId == 0 && orderColId != INT32_MIN) {
op = OP_Order; op = OP_Order;
taosArrayPush(plan, &op); taosArrayPush(plan, &op);
} }
......
###################################################################
# Copyright (c) 2021 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
from util.log import *
from util.cases import *
from util.sql import *
class TDTestCase:
def caseDescription(self):
'''
case1<shenglian zhou>: [TD-12145]function/clause program inserted column will be use as ts in outerquery
case2<shenglian zhou>: [TD-12164]elapsed function can only take primary timestamp as first parameter
case3<shenglian zhou>: [TD-12165]_c0 can not be alias name
'''
return
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
self._conn = conn
def run(self):
print("running {}".format(__file__))
tdSql.execute("drop database if exists td12145")
tdSql.execute("create database if not exists td12145")
tdSql.execute('use td12145')
tdSql.execute('create stable st(ts timestamp , value int ) tags (ind int)')
tdSql.execute('insert into tb1 using st tags(1) values(now ,1)')
tdSql.execute('insert into tb1 using st tags(1) values(now+1s ,2)')
tdSql.execute('insert into tb1 using st tags(1) values(now+2s ,3)')
tdSql.error('select elapsed(ts00 ,1s) from (select elapsed(ts,1s) ts00 from tb1)')
tdSql.error('select elapsed(ts00 ,1s) from (select value ts00 from tb1)')
tdSql.error('select _c0 from (select value as _c0 , _c0 from st)')
tdSql.error('select ts from (select value as _c0 , ts from st)')
tdSql.query('select ts, max(nestvalue) from (select csum(value) nestvalue from tb1)')
tdSql.checkRows(1)
tdSql.checkData(0, 1, 6)
tdSql.execute('drop database td12145')
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
python3 test.py -f 0-management/3-tag/json_tag.py python3 test.py -f 0-management/3-tag/json_tag.py
python3 test.py -f 1-insert/0-sql/batchInsert.py python3 test.py -f 1-insert/0-sql/batchInsert.py
python3 test.py -f 2-query/7-nest/ts_hidden_column.py
C#checker/bin/
C#checker/obj/
TDengineTest/bin/
TDengineTest/obj/
schemaless/bin/
schemaless/obj/
stmt/TDengineDriver.cs
stmt/TaosBind.cs
stmt/TaosMultiBind.cs
stmt/bin/
stmt/obj/
taosdemo/bin/
taosdemo/obj/
...@@ -7,6 +7,8 @@ IF (TD_LINUX) ...@@ -7,6 +7,8 @@ IF (TD_LINUX)
TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread ) TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
ADD_EXECUTABLE(sml schemaless.c) ADD_EXECUTABLE(sml schemaless.c)
TARGET_LINK_LIBRARIES(sml taos_static trpc tutil pthread ) TARGET_LINK_LIBRARIES(sml taos_static trpc tutil pthread )
ADD_EXECUTABLE(sqlperf sqlperf.c)
TARGET_LINK_LIBRARIES(sqlperf taos_static trpc tutil pthread )
ADD_EXECUTABLE(subscribe subscribe.c) ADD_EXECUTABLE(subscribe subscribe.c)
TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread ) TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
ADD_EXECUTABLE(epoll epoll.c) ADD_EXECUTABLE(epoll epoll.c)
......
...@@ -105,6 +105,35 @@ int32_t generateLine(char* line, int lineLen, char* lineTemplate, int protocol, ...@@ -105,6 +105,35 @@ int32_t generateLine(char* line, int lineLen, char* lineTemplate, int protocol,
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t setupSuperTables(TAOS* taos, char* lineTemplate, int protocol,
int numSuperTables, int numChildTables, int numRowsPerChildTable,
int maxBatchesPerThread, int64_t ts) {
printf("setup supertables...");
{
char** linesStb = calloc(numSuperTables, sizeof(char*));
for (int i = 0; i < numSuperTables; i++) {
char* lineStb = calloc(strlen(lineTemplate)+128, 1);
generateLine(lineStb, strlen(lineTemplate)+128, lineTemplate, protocol, i,
numSuperTables * numChildTables,
ts + numSuperTables * numChildTables * numRowsPerChildTable);
linesStb[i] = lineStb;
}
SThreadInsertArgs args = {0};
args.protocol = protocol;
args.batches = calloc(maxBatchesPerThread, sizeof(maxBatchesPerThread));
args.taos = taos;
args.batches[0].lines = linesStb;
args.batches[0].numLines = numSuperTables;
insertLines(&args);
free(args.batches);
for (int i = 0; i < numSuperTables; ++i) {
free(linesStb[i]);
}
free(linesStb);
}
return TSDB_CODE_SUCCESS;
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
int numThreads = 8; int numThreads = 8;
int maxBatchesPerThread = 1024; int maxBatchesPerThread = 1024;
...@@ -117,9 +146,10 @@ int main(int argc, char* argv[]) { ...@@ -117,9 +146,10 @@ int main(int argc, char* argv[]) {
int maxLinesPerBatch = 16384; int maxLinesPerBatch = 16384;
int protocol = TSDB_SML_TELNET_PROTOCOL; int protocol = TSDB_SML_TELNET_PROTOCOL;
int assembleSTables = 0;
int opt; int opt;
while ((opt = getopt(argc, argv, "s:c:r:f:t:b:p:hv")) != -1) { while ((opt = getopt(argc, argv, "s:c:r:f:t:b:p:w:hv")) != -1) {
switch (opt) { switch (opt) {
case 's': case 's':
numSuperTables = atoi(optarg); numSuperTables = atoi(optarg);
...@@ -142,6 +172,9 @@ int main(int argc, char* argv[]) { ...@@ -142,6 +172,9 @@ int main(int argc, char* argv[]) {
case 'v': case 'v':
verbose = true; verbose = true;
break; break;
case 'a':
assembleSTables = atoi(optarg);
break;
case 'p': case 'p':
if (optarg[0] == 't') { if (optarg[0] == 't') {
protocol = TSDB_SML_TELNET_PROTOCOL; protocol = TSDB_SML_TELNET_PROTOCOL;
...@@ -152,11 +185,11 @@ int main(int argc, char* argv[]) { ...@@ -152,11 +185,11 @@ int main(int argc, char* argv[]) {
} }
break; break;
case 'h': case 'h':
fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -b maxlines_per_batch -p [t|l|j] -v\n", fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -b maxlines_per_batch -p [t|l|j] -a assemble-stables -v\n",
argv[0]); argv[0]);
exit(0); exit(0);
default: /* '?' */ default: /* '?' */
fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -b maxlines_per_batch -p [t|l|j] -v\n", fprintf(stderr, "Usage: %s -s supertable -c childtable -r rows -f fields -t threads -b maxlines_per_batch -p [t|l|j] -a assemble-stables -v\n",
argv[0]); argv[0]);
exit(-1); exit(-1);
} }
...@@ -200,28 +233,9 @@ int main(int argc, char* argv[]) { ...@@ -200,28 +233,9 @@ int main(int argc, char* argv[]) {
getTelenetTemplate(lineTemplate, 65535); getTelenetTemplate(lineTemplate, 65535);
} }
printf("setup supertables..."); if (assembleSTables) {
{ setupSuperTables(taos, lineTemplate, protocol,
char** linesStb = calloc(numSuperTables, sizeof(char*)); numSuperTables, numChildTables, numRowsPerChildTable, maxBatchesPerThread, ts);
for (int i = 0; i < numSuperTables; i++) {
char* lineStb = calloc(strlen(lineTemplate)+128, 1);
generateLine(lineStb, strlen(lineTemplate)+128, lineTemplate, protocol, i,
numSuperTables * numChildTables,
ts + numSuperTables * numChildTables * numRowsPerChildTable);
linesStb[i] = lineStb;
}
SThreadInsertArgs args = {0};
args.protocol = protocol;
args.batches = calloc(maxBatchesPerThread, sizeof(maxBatchesPerThread));
args.taos = taos;
args.batches[0].lines = linesStb;
args.batches[0].numLines = numSuperTables;
insertLines(&args);
free(args.batches);
for (int i = 0; i < numSuperTables; ++i) {
free(linesStb[i]);
}
free(linesStb);
} }
printf("generate lines...\n"); printf("generate lines...\n");
......
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h" // TAOS header file
#include "taoserror.h"
#include "os.h"
bool verbose = false;
bool describeTableFirst = false;
typedef struct{
TAOS* taos;
int numThreads;
int threadId;
int numSTables;
} SThreadArgs;
static int executeSql(TAOS *taos, char *command) {
if (verbose) {
printf("sql: %s\n", command);
}
TAOS_RES *pSql = NULL;
int32_t code = TSDB_CODE_SUCCESS;
pSql = taos_query(taos, command);
code = taos_errno(pSql);
if (code != 0) {
if (verbose) fprintf(stderr, "Failed to run %s, reason: %s\n", command, taos_errstr(pSql));
taos_free_result(pSql);
return code;
}
taos_free_result(pSql);
return 0;
}
void* threadFunc(void* args) {
char* sqlDescribeSTable = "describe st%d";
char* sqlCreateSTable = "create table st%d (ts timestamp, value double) "
"tags(t0 nchar(20), t1 nchar(20), t2 nchar(20), t3 nchar(20), t4 nchar(20), "
"t5 nchar(20), t6 nchar(20), t7 nchar(20), t8 nchar(20), t9 nchar(20))";
char* sqlInsertData = "insert into t%d using st%d tags('t%d', 't%d', 't%d', 't%d', 't%d', 't%d', 't%d', 't%d', 't%d', 't%d') values(%lld, %d.%d)";
SThreadArgs* param = args;
int interval = param->numSTables/param->numThreads;
if (param->numSTables % param->numThreads != 0) {
++interval;
}
int start = param->threadId*interval;
int end = (param->threadId+1)*interval > param->numSTables ? param->numSTables : (param->threadId+1)*interval;
int r = rand();
for (int i = start; i < end; ++i) {
int tableId = i;
char sql0[1024] = {0};
char sql1[1024] = {0};
char sql2[1024] = {0};
sprintf(sql0, sqlDescribeSTable, tableId);
sprintf(sql1, sqlCreateSTable, tableId);
time_t ct = time(0);
int64_t ts = ct * 1000;
sprintf(sql2, sqlInsertData, tableId, tableId, r, r, r, r, r, r, r, r, r, r, ts + tableId, r, r);
if (describeTableFirst) {
executeSql(param->taos, sql0);
}
executeSql(param->taos, sql1);
executeSql(param->taos, sql2);
}
return NULL;
}
int main(int argc, char *argv[]) {
int numSTables = 20000;
int numThreads = 32;
int opt;
while ((opt = getopt(argc, argv, "s:t:fvh")) != -1) {
switch (opt) {
case 's':
numSTables = atoi(optarg);
break;
case 't':
numThreads = atoi(optarg);
break;
case 'f':
describeTableFirst = true;
break;
case 'v':
verbose = true;
break;
case 'h':
fprintf(stderr, "Usage: %s -s supertable -t thread -FirstDescribeSTable -Verbose\n", argv[0]);
exit(0);
default:
fprintf(stderr, "Usage: %s -s supertable -t thread -FirstDescribeSTable -Verbose\n", argv[0]);
exit(-1);
}
}
// connect to server
TAOS *taos = taos_connect(NULL, "root", "taosdata", NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/);
exit(1);
}
executeSql(taos, "drop database if exists sqlsml");
executeSql(taos, "create database sqlsml");
executeSql(taos, "use sqlsml");
pthread_t* tids = calloc(numThreads, sizeof(pthread_t));
SThreadArgs* threadArgs = calloc(numThreads, sizeof(SThreadArgs));
for (int i = 0; i < numThreads; ++i) {
threadArgs[i].numSTables = numSTables;
threadArgs[i].numThreads = numThreads;
threadArgs[i].threadId = i;
threadArgs[i].taos = taos;
}
int64_t begin = taosGetTimestampUs();
for (int i = 0; i < numThreads; ++i) {
pthread_create(tids+i, NULL, threadFunc, threadArgs+i);
}
for (int i = 0; i < numThreads; ++i) {
pthread_join(tids[i], NULL);
}
int64_t end = taosGetTimestampUs();
printf("TIME: %d(ms)\n", (int)((end-begin)/1000));
printf("THROUGHPUT: %d\n", (int)((numSTables * 1e6) / (end-begin)));
free(threadArgs);
free(tids);
taos_close(taos);
taos_cleanup();
}
...@@ -167,6 +167,7 @@ python3 ./test.py -f update/merge_commit_data.py ...@@ -167,6 +167,7 @@ python3 ./test.py -f update/merge_commit_data.py
# tools # tools
python3 test.py -f tools/taosdumpTest.py python3 test.py -f tools/taosdumpTest.py
python3 test.py -f tools/taosdumpTest2.py python3 test.py -f tools/taosdumpTest2.py
python3 test.py -f tools/taosdumpTest3.py
python3 test.py -f tools/taosdemoTest.py python3 test.py -f tools/taosdemoTest.py
python3 test.py -f tools/taosdemoTestWithoutMetric.py python3 test.py -f tools/taosdemoTestWithoutMetric.py
......
...@@ -259,7 +259,7 @@ class ElapsedCase: ...@@ -259,7 +259,7 @@ class ElapsedCase:
self.limitCheck("select elapsed(ts) from st1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00' interval(40s) group by tbname", 1) self.limitCheck("select elapsed(ts) from st1 where ts > '2021-11-22 00:00:00' and ts < '2021-11-23 00:00:00' interval(40s) group by tbname", 1)
def fromCheck(self, sqlTemplate, table): def fromCheck(self, sqlTemplate, table):
tdSql.checkEqual(tdSql.getResult(sqlTemplate % table), tdSql.getResult(sqlTemplate % ("(select * from %s)" % table))) #tdSql.checkEqual(tdSql.getResult(sqlTemplate % table), tdSql.getResult(sqlTemplate % ("(select * from %s)" % table)))
tdSql.query(sqlTemplate % ("(select last(ts) from %s interval(10s))" % table)) tdSql.query(sqlTemplate % ("(select last(ts) from %s interval(10s))" % table))
tdSql.query(sqlTemplate % ("(select elapsed(ts) from %s interval(10s))" % table)) tdSql.query(sqlTemplate % ("(select elapsed(ts) from %s interval(10s))" % table))
......
...@@ -251,7 +251,7 @@ class TDDnode: ...@@ -251,7 +251,7 @@ class TDDnode:
"dnode:%d is deployed and configured by %s" % "dnode:%d is deployed and configured by %s" %
(self.index, self.cfgPath)) (self.index, self.cfgPath))
def getBuildPath(self): def getBuildPath(self, tool="taosd"):
buildPath = "" buildPath = ""
selfPath = os.path.dirname(os.path.realpath(__file__)) selfPath = os.path.dirname(os.path.realpath(__file__))
...@@ -261,7 +261,7 @@ class TDDnode: ...@@ -261,7 +261,7 @@ class TDDnode:
projPath = selfPath[:selfPath.find("tests")] projPath = selfPath[:selfPath.find("tests")]
for root, dirs, files in os.walk(projPath): for root, dirs, files in os.walk(projPath):
if (("taosd") in files): if ((tool) in files):
rootRealPath = os.path.dirname(os.path.realpath(root)) rootRealPath = os.path.dirname(os.path.realpath(root))
if ("packaging" not in rootRealPath): if ("packaging" not in rootRealPath):
buildPath = root[:len(root)-len("/build/bin")] buildPath = root[:len(root)-len("/build/bin")]
......
###################################################################
# Copyright (c) 2020 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import taos
import time
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
class TDTestCase:
def __init__(self):
self.err_case = 0
self.curret_case = 0
def caseDescription(self):
'''
case1 <cpwu>: [TD-12340] : group by ts should resturn two column ;\n
case2 <cpwu>: [TD-12342] : "group by ts order by first-tag" should return error
'''
return
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def create_stb(self):
basetime = int(round(time.time() * 1000))
tdSql.prepare()
tdSql.execute(f"create stable stb1(ts timestamp, c1 int) tags (tag1 int)")
for i in range(10):
tdSql.execute(f"create table t{i} using stb1 tags({i})")
tdSql.execute(f"insert into t{i} values ({basetime}, {i})")
pass
def check_td12340(self):
# this case expect return two column when using "group by ts"
tdSql.query("select count(*) from stb1 group by ts")
try:
tdSql.checkCols(2)
self.curret_case += 1
tdLog.printNoPrefix("the case1: td-12340 run passed")
except:
self.err_case += 1
tdLog.printNoPrefix("the case1: td-12340 run failed")
pass
def check_td12342(self):
# this case expect return err when using "group by ts order by first-tag"
try:
tdSql.error("select count(*) from stb1 group by ts order by tag1")
self.curret_case += 1
tdLog.printNoPrefix("the case2: td-12342 run passed")
except:
self.err_case += 1
tdLog.printNoPrefix("the case2: td-12342 run failed")
pass
def run(self):
self.create_stb()
self.check_td12340()
self.check_td12342()
if self.err_case > 0:
tdLog.exit(f"{self.err_case} is failed")
else:
tdLog.success("2 case is all passed")
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import os
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import *
import subprocess
class TDTestCase:
def caseDescription(self):
'''
case1<pxiao>: [TD-11977] start taosdump without taosd
case1<pxiao>: [TD-11977] start taosBenchmark without taosd
case1<pxiao>: [TD-11977] start taosAdaptor without taosd
'''
return
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def run(self):
tdSql.prepare()
tools = ["taosdump", "taosBenchmark", "taosAdaptor"]
tdDnodes.stop(1)
for tool in tools:
path = tdDnodes.dnodes[1].getBuildPath(tool)
try:
path += "/build/bin/"
print(f"{path}{tool}")
if tool == "taosBenchmark":
os.system(f"{path}{tool} -y")
else:
os.system(f"{path}{tool}")
except:
pass
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
...@@ -3,3 +3,4 @@ python3 test.py -f 4-taosAdapter/taosAdapter_query.py ...@@ -3,3 +3,4 @@ python3 test.py -f 4-taosAdapter/taosAdapter_query.py
python3 test.py -f 4-taosAdapter/taosAdapter_insert.py python3 test.py -f 4-taosAdapter/taosAdapter_insert.py
#python3 test.py -f 2-query/9-others/TD-11389.py # this case will run when this bug fix TD-11389 #python3 test.py -f 2-query/9-others/TD-11389.py # this case will run when this bug fix TD-11389
python3 test.py -f 5-taos-tools/taosdump/basic.py
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册