未验证 提交 d258cdb0 编写于 作者: G Ganlin Zhao 提交者: GitHub

Merge branch 'develop' into glzhao89-patch-2

......@@ -1083,7 +1083,71 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
{slop:1.000000, intercept:9.733334} |
Query OK, 1 row(s) in set (0.000921s)
```
- **MODE**
```mysql
SELECT MODE(field_name) FROM tb_name [WHERE clause];
```
功能说明:返回出现频率最高的值,若存在多个频率相同的最高值,输出空。不能匹配标签、时间戳输出。
返回结果数据类型:同应用的字段。
应用字段:适合于除时间主列外的任何类型字段。
适用于:**表**。
示例:
```mysql
taos> select voltage from d002;
voltage |
========================
1 |
1 |
2 |
19 |
Query OK, 4 row(s) in set (0.003545s)
taos> select mode(voltage) from d002;
mode(voltage) |
========================
1 |
Query OK, 1 row(s) in set (0.019393s)
```
- **HYPERLOGLOG**
```mysql
SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
功能说明:采用hyperloglog算法,返回某列的基数。该算法在数据量很大的情况下,可以明显降低内存的占用,但是求出来的基数是个估算值,标准误差为0.81%。
返回结果类型:整形。
适用数据类型:适合于任何类型字段。
支持的版本:2.6.0.x 之后的版本。
示例:
```mysql
taos> select dbig from shll;
dbig |
========================
1 |
1 |
1 |
NULL |
2 |
19 |
NULL |
9 |
Query OK, 8 row(s) in set (0.003755s)
taos> select hyperloglog(dbig) from shll;
hyperloglog(dbig)|
========================
4 |
Query OK, 1 row(s) in set (0.008388s)
```
### 选择函数
在使用所有的选择函数的时候,可以同时指定输出 ts 列或标签列(包括 tbname),这样就可以方便地知道被选出的值是源于哪个数据行的。
......@@ -1482,6 +1546,84 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
Query OK, 2 row(s) in set (0.003487s)
```
- **TAIL**
```mysql
SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
```
功能说明:返回跳过最后 offset_value个,然后取连续 k 个记录,不忽略 NULL 值。offset_val 可以不输入。此时返回最后的 k 个记录。当有 offset_val 输入的情况下,该函数功能等效于order by ts desc LIMIT k OFFSET offset_val。
参数范围:k: [1,100] offset_val: [0,100]。
返回结果数据类型:同应用的字段。
应用字段:适合于除时间主列外的任何类型字段。
适用于:**表、超级表**。
支持版本:2.6.0.x 之后的版本。
示例:
```mysql
taos> select ts,dbig from tail2;
ts | dbig |
==================================================
2021-10-15 00:31:33.000 | 1 |
2021-10-17 00:31:31.000 | NULL |
2021-12-24 00:31:34.000 | 2 |
2022-01-01 08:00:05.000 | 19 |
2022-01-01 08:00:06.000 | NULL |
2022-01-01 08:00:07.000 | 9 |
Query OK, 6 row(s) in set (0.001952s)
taos> select tail(dbig,2,2) from tail2;
ts | tail(dbig,2,2) |
==================================================
2021-12-24 00:31:34.000 | 2 |
2022-01-01 08:00:05.000 | 19 |
Query OK, 2 row(s) in set (0.002307s)
- **UNIQUE**
```mysql
SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
```
功能说明:返回该列的数值首次出现的值。该函数功能与 distinct 相似,但是可以匹配标签和时间戳信息。可以针对除时间列以外的字段进行查询,可以匹配标签和时间戳,其中的标签和时间戳是第一次出现时刻的标签和时间戳。
返回结果数据类型:同应用的字段。
应用字段:适合于除时间类型以外的字段。
适用于:**表、超级表**。
支持版本:2.6.0.x 之后的版本。
说明:该函数可以应用在普通表和超级表上。不能和窗口操作一起使用,例如 interval/state_window/session_window 。
示例:
```mysql
taos> select ts,voltage from unique1;
ts | voltage |
==================================================
2021-10-17 00:31:31.000 | 1 |
2022-01-24 00:31:31.000 | 1 |
2021-10-17 00:31:31.000 | 1 |
2021-12-24 00:31:31.000 | 2 |
2022-01-01 08:00:01.000 | 19 |
2021-10-17 00:31:31.000 | NULL |
2022-01-01 08:00:02.000 | NULL |
2022-01-01 08:00:03.000 | 9 |
Query OK, 8 row(s) in set (0.003018s)
taos> select unique(voltage) from unique1;
ts | unique(voltage) |
==================================================
2021-10-17 00:31:31.000 | 1 |
2021-10-17 00:31:31.000 | NULL |
2021-12-24 00:31:31.000 | 2 |
2022-01-01 08:00:01.000 | 19 |
2022-01-01 08:00:03.000 | 9 |
Query OK, 5 row(s) in set (0.108458s)
### 计算函数
- **DIFF**
......@@ -1623,6 +1765,106 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
80.810000718 |
Query OK, 3 row(s) in set (0.001046s)
```
- **STATECOUNT**
```mysql
SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
```
功能说明:返回满足某个条件的连续记录的个数,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为true则加1,条件为false则重置为-1,如果数据为NULL,跳过该条数据。
参数范围:
- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
- val : 数值型
返回结果类型:整形。
适用数据类型:不能应用在 timestamp、binary、nchar、bool 类型字段上。
嵌套子查询支持:不支持应用在子查询上。
支持的版本:2.6.0.x 之后的版本。
说明:
- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
- 不能和窗口操作一起使用,例如interval/state_window/session_window。
示例:
```mysql
taos> select ts,dbig from statef2;
ts | dbig |
========================================================
2021-10-15 00:31:33.000000000 | 1 |
2021-10-17 00:31:31.000000000 | NULL |
2021-12-24 00:31:34.000000000 | 2 |
2022-01-01 08:00:05.000000000 | 19 |
2022-01-01 08:00:06.000000000 | NULL |
2022-01-01 08:00:07.000000000 | 9 |
Query OK, 6 row(s) in set (0.002977s)
taos> select stateCount(dbig,GT,2) from statef2;
ts | dbig | statecount(dbig,gt,2) |
================================================================================
2021-10-15 00:31:33.000000000 | 1 | -1 |
2021-10-17 00:31:31.000000000 | NULL | NULL |
2021-12-24 00:31:34.000000000 | 2 | -1 |
2022-01-01 08:00:05.000000000 | 19 | 1 |
2022-01-01 08:00:06.000000000 | NULL | NULL |
2022-01-01 08:00:07.000000000 | 9 | 2 |
Query OK, 6 row(s) in set (0.002791s)
```
- **STATEDURATION**
```mysql
SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
```
功能说明:返回满足某个条件的连续记录的时间长度,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为true则加上两个记录之间的时间长度(第一个满足条件的记录时间长度记为0),条件为false则重置为-1,如果数据为NULL,跳过该条数据。
参数范围:
- oper : LT (小于)、GT(大于)、LE(小于等于)、GE(大于等于)、NE(不等于)、EQ(等于),不区分大小写。
- val : 数值型
- unit : 时间长度的单位,范围[1s、1m、1h ],不足一个单位舍去。默认为1s。
返回结果类型:整形。
适用数据类型:不能应用在 timestamp、binary、nchar、bool 类型字段上。
嵌套子查询支持:不支持应用在子查询上。
支持的版本:2.6.0.x 之后的版本。
说明:
- 该函数可以应用在普通表上,在由 GROUP BY 划分出单独时间线的情况下用于超级表(也即 GROUP BY tbname)
- 不能和窗口操作一起使用,例如interval/state_window/session_window。
示例:
```mysql
taos> select ts,dbig from statef2;
ts | dbig |
========================================================
2021-10-15 00:31:33.000000000 | 1 |
2021-10-17 00:31:31.000000000 | NULL |
2021-12-24 00:31:34.000000000 | 2 |
2022-01-01 08:00:05.000000000 | 19 |
2022-01-01 08:00:06.000000000 | NULL |
2022-01-01 08:00:07.000000000 | 9 |
Query OK, 6 row(s) in set (0.002407s)
taos> select stateDuration(dbig,GT,2) from statef2;
ts | dbig | stateduration(dbig,gt,2) |
===================================================================================
2021-10-15 00:31:33.000000000 | 1 | -1 |
2021-10-17 00:31:31.000000000 | NULL | NULL |
2021-12-24 00:31:34.000000000 | 2 | -1 |
2022-01-01 08:00:05.000000000 | 19 | 0 |
2022-01-01 08:00:06.000000000 | NULL | NULL |
2022-01-01 08:00:07.000000000 | 9 | 2 |
Query OK, 6 row(s) in set (0.002613s)
```
### 时间函数
- **NOW**
......
......@@ -852,6 +852,69 @@ TDengine supports aggregations over data, they are listed below:
Query OK, 1 row(s) in set (0.000921s)
```
- **MODE**
```mysql
SELECT MODE(field_name) FROM tb_name [WHERE clause];
```
Function: Returns the value with the highest frequency. If there are multiple highest values with the same frequency, the output is NULL.
Return Data Type: Same as applicable fields.
Applicable Fields: All types except timestamp.
Supported version: Version after 2.6.0 .
Example:
```mysql
taos> select voltage from d002;
voltage |
========================
1 |
1 |
2 |
19 |
Query OK, 4 row(s) in set (0.003545s)
taos> select mode(voltage) from d002;
mode(voltage) |
========================
1 |
Query OK, 1 row(s) in set (0.019393s)
```
- **HYPERLOGLOG**
```mysql
SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
```
Function: The hyperloglog algorithm is used to return the cardinality of a column. In the case of large amount of data, the algorithm can significantly reduce the occupation of memory, but the cardinality is an estimated value, and the standard error is 0.81%.
Return Data Type:Integer.
Applicable Fields: All types.
Supported version: Version after 2.6.0 .
Example:
```mysql
taos> select dbig from shll;
dbig |
========================
1 |
1 |
1 |
NULL |
2 |
19 |
NULL |
9 |
Query OK, 8 row(s) in set (0.003755s)
taos> select hyperloglog(dbig) from shll;
hyperloglog(dbig)|
========================
4 |
Query OK, 1 row(s) in set (0.008388s)
### Selector Functions
- **MIN**
......@@ -1102,6 +1165,83 @@ TDengine supports aggregations over data, they are listed below:
Query OK, 1 row(s) in set (0.001042s)
```
- **TAIL**
```mysql
SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
```
Function: Skip the last num of offset_value, return the k consecutive records without ignoring NULL value. offset_val can be empty, then the last K records are returned.The function is equivalent to:order by ts desc LIMIT k OFFSET offset_val.
Range:k: [1,100] offset_val: [0,100]。
Return Data Type: Same as applicable fields.
Applicable Fields: All types except timestamp.
Applied to: **table stable**.
Supported version: Version after 2.6.0 .
Example:
```mysql
taos> select ts,dbig from tail2;
ts | dbig |
==================================================
2021-10-15 00:31:33.000 | 1 |
2021-10-17 00:31:31.000 | NULL |
2021-12-24 00:31:34.000 | 2 |
2022-01-01 08:00:05.000 | 19 |
2022-01-01 08:00:06.000 | NULL |
2022-01-01 08:00:07.000 | 9 |
Query OK, 6 row(s) in set (0.001952s)
taos> select tail(dbig,2,2) from tail2;
ts | tail(dbig,2,2) |
==================================================
2021-12-24 00:31:34.000 | 2 |
2022-01-01 08:00:05.000 | 19 |
Query OK, 2 row(s) in set (0.002307s)
- **UNIQUE**
```mysql
SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
```
Function: Returns the first occurrence of a value in this column.
Return Data Type: Same as applicable fields.
Applicable Fields: All types except timestamp.
Applied to: **table stable**.
Supported version: Version after 2.6.0 .
Note: This function can be applied to ordinary tables and super tables. Cannot be used with window operations,such as interval/state_window/session_window.
Example:
```mysql
taos> select ts,voltage from unique1;
ts | voltage |
==================================================
2021-10-17 00:31:31.000 | 1 |
2022-01-24 00:31:31.000 | 1 |
2021-10-17 00:31:31.000 | 1 |
2021-12-24 00:31:31.000 | 2 |
2022-01-01 08:00:01.000 | 19 |
2021-10-17 00:31:31.000 | NULL |
2022-01-01 08:00:02.000 | NULL |
2022-01-01 08:00:03.000 | 9 |
Query OK, 8 row(s) in set (0.003018s)
taos> select unique(voltage) from unique1;
ts | unique(voltage) |
==================================================
2021-10-17 00:31:31.000 | 1 |
2021-10-17 00:31:31.000 | NULL |
2021-12-24 00:31:31.000 | 2 |
2022-01-01 08:00:01.000 | 19 |
2022-01-01 08:00:03.000 | 9 |
Query OK, 5 row(s) in set (0.108458s)
### Computing Functions
- **DIFF**
......@@ -1172,6 +1312,97 @@ TDengine supports aggregations over data, they are listed below:
1. Calculation between two or more columns is supported, and the calculation priorities can be controlled by parentheses();
2. The NULL field does not participate in the calculation. If a row involved in calculation contains NULL, the calculation result of the row is NULL.
- **STATECOUNT**
```mysql
SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
```
Function: Returns the number of consecutive records that meet a certain condition, and the result is appended to each row as a new column. The condition is calculated according to the parameters. If the condition is true, it will be increased by 1. If the condition is false, it will be reset to -1. If the data is NULL, the data will be skipped.
Range:
- oper : LT(<),GT(>),LE(<=),GE(>=),NE(!=),EQ(=),case insensitive.
- val : Number.
Returned Data Type: Integer。
Applicable Fields: All types except timestamp, binary, nchar, bool.
Supported version: Version after 2.6.0 .
Note:
- This function can be applied to ordinary tables. When a separate timeline is divided by group by, it is used for super tables (i.e. group by TBNAME).
- Cannot be used with window operations,such as interval/state_window/session_window.
Example:
```mysql
taos> select ts,dbig from statef2;
ts | dbig |
========================================================
2021-10-15 00:31:33.000000000 | 1 |
2021-10-17 00:31:31.000000000 | NULL |
2021-12-24 00:31:34.000000000 | 2 |
2022-01-01 08:00:05.000000000 | 19 |
2022-01-01 08:00:06.000000000 | NULL |
2022-01-01 08:00:07.000000000 | 9 |
Query OK, 6 row(s) in set (0.002977s)
taos> select stateCount(dbig,GT,2) from statef2;
ts | dbig | statecount(dbig,gt,2) |
================================================================================
2021-10-15 00:31:33.000000000 | 1 | -1 |
2021-10-17 00:31:31.000000000 | NULL | NULL |
2021-12-24 00:31:34.000000000 | 2 | -1 |
2022-01-01 08:00:05.000000000 | 19 | 1 |
2022-01-01 08:00:06.000000000 | NULL | NULL |
2022-01-01 08:00:07.000000000 | 9 | 2 |
Query OK, 6 row(s) in set (0.002791s)
```
- **STATEDURATION**
```mysql
SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
```
Function: Returns the length of time of continuous records that meet a certain condition, and the result is appended to each row as a new column. The condition is calculated according to the parameters. If the condition is true, the length of time between two records will be added (the length of time of the first record that meets the condition is recorded as 0). If the condition is false, it will be reset to -1. If the data is NULL, the data will be skipped.
Range:
- oper : LT(<),GT(>),LE(<=),GE(>=),NE(!=),EQ(=),case insensitive.
- val : Number.
- unit : Unit of time length, range [1s, 1M, 1H], less than one unit is rounded off. The default is 1s.
Returned Data Type: Integer。
Applicable Fields: All types except timestamp, binary, nchar, bool.
Supported version: Version after 2.6.0 .
Note:
- This function can be applied to ordinary tables. When a separate timeline is divided by group by, it is used for super tables (i.e. group by TBNAME).
- Cannot be used with window operations,such as interval/state_window/session_window.
Example:
```mysql
taos> select ts,dbig from statef2;
ts | dbig |
========================================================
2021-10-15 00:31:33.000000000 | 1 |
2021-10-17 00:31:31.000000000 | NULL |
2021-12-24 00:31:34.000000000 | 2 |
2022-01-01 08:00:05.000000000 | 19 |
2022-01-01 08:00:06.000000000 | NULL |
2022-01-01 08:00:07.000000000 | 9 |
Query OK, 6 row(s) in set (0.002407s)
taos> select stateDuration(dbig,GT,2) from statef2;
ts | dbig | stateduration(dbig,gt,2) |
===================================================================================
2021-10-15 00:31:33.000000000 | 1 | -1 |
2021-10-17 00:31:31.000000000 | NULL | NULL |
2021-12-24 00:31:34.000000000 | 2 | -1 |
2022-01-01 08:00:05.000000000 | 19 | 0 |
2022-01-01 08:00:06.000000000 | NULL | NULL |
2022-01-01 08:00:07.000000000 | 9 | 2 |
Query OK, 6 row(s) in set (0.002613s)
```
## <a class="anchor" id="aggregation"></a> Time-dimension Aggregation
TDengine supports aggregating by intervals (time range). Data in a table can partitioned by intervals and aggregated to generate results. For example, a temperature sensor collects data once per second, but the average temperature needs to be queried every 10 minutes. This aggregation is suitable for down sample operation, and the syntax is as follows:
......
......@@ -11,257 +11,254 @@ extern "C" {
#define com_taosdata_jdbc_TSDBJNIConnector_INVALID_CONNECTION_POINTER_VALUE 0LL
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method:
* Method:
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp
(JNIEnv *, jclass, jint, jstring, jboolean);
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp(JNIEnv *, jclass, jint, jstring,
jboolean);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method:
* Method:
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_dumpMemoryLeakImp
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_dumpMemoryLeakImp(JNIEnv *, jclass);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: initImp
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_initImp
(JNIEnv *, jclass, jstring);
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_initImp(JNIEnv *, jclass, jstring);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setOptions
* Signature: (ILjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setOptions
(JNIEnv *, jclass, jint, jstring);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setOptions(JNIEnv *, jclass, jint, jstring);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setConfigImp
* Signature: (Ljava/lang/String;)Lcom/taosdata/jdbc/TSDBException;
*/
JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp
(JNIEnv *, jclass, jstring);
JNIEXPORT jobject JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setConfigImp(JNIEnv *, jclass, jstring);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getTsCharset
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset
(JNIEnv *, jclass);
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(JNIEnv *, jclass);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getResultTimePrecisionImp
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecisionImp
(JNIEnv *, jobject, jlong, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecisionImp(JNIEnv *, jobject, jlong,
jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: connectImp
* Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp
(JNIEnv *, jobject, jstring, jint, jstring, jstring, jstring);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEnv *, jobject, jstring, jint, jstring,
jstring, jstring);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: executeQueryImp
* Signature: ([BJ)I
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp
(JNIEnv *, jobject, jbyteArray, jlong);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(JNIEnv *, jobject, jbyteArray, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getErrCodeImp
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrCodeImp
(JNIEnv *, jobject, jlong, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrCodeImp(JNIEnv *, jobject, jlong, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getErrMsgImp
* Signature: (J)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp
(JNIEnv *, jobject, jlong);
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(JNIEnv *, jobject, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getResultSetImp
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp
(JNIEnv *env, jobject jobj, jlong con, jlong tres);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(JNIEnv *env, jobject jobj, jlong con,
jlong tres);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: isUpdateQueryImp
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp
(JNIEnv *env, jobject jobj, jlong con, jlong tres);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp(JNIEnv *env, jobject jobj, jlong con,
jlong tres);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: freeResultSetImp
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp
(JNIEnv *, jobject, jlong, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(JNIEnv *, jobject, jlong, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getAffectedRowsImp
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp
(JNIEnv *env, jobject jobj, jlong con, jlong res);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp(JNIEnv *env, jobject jobj, jlong con,
jlong res);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getSchemaMetaDataImp
* Signature: (JJLjava/util/List;)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaDataImp
(JNIEnv *, jobject, jlong, jlong, jobject);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaDataImp(JNIEnv *, jobject, jlong, jlong,
jobject);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: fetchRowImp
* Signature: (JJLcom/taosdata/jdbc/TSDBResultSetRowData;)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp
(JNIEnv *, jobject, jlong, jlong, jobject);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEnv *, jobject, jlong, jlong, jobject);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: fetchBlockImp
* Signature: (JJLcom/taosdata/jdbc/TSDBResultSetBlockData;)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp
(JNIEnv *, jobject, jlong, jlong, jobject);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp(JNIEnv *, jobject, jlong, jlong, jobject);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: closeConnectionImp
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionImp
(JNIEnv *, jobject, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionImp(JNIEnv *, jobject, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: subscribeImp
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JI)J
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_subscribeImp
(JNIEnv *, jobject, jlong, jboolean, jstring, jstring, jint);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_subscribeImp(JNIEnv *, jobject, jlong, jboolean,
jstring, jstring, jint);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: consumeImp
* Signature: (J)Lcom/taosdata/jdbc/TSDBResultSetRowData;
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp
(JNIEnv *, jobject, jlong);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEnv *, jobject, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: unsubscribeImp
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp
(JNIEnv *, jobject, jlong, jboolean);
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp(JNIEnv *, jobject, jlong, jboolean);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: validateCreateTableSqlImp
* Signature: (J[B)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp
(JNIEnv *, jobject, jlong, jbyteArray);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTableSqlImp(JNIEnv *, jobject, jlong,
jbyteArray);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: prepareStmtImp
* Signature: ([BJ)I
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp
(JNIEnv *, jobject, jbyteArray, jlong);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp(JNIEnv *, jobject, jbyteArray, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setBindTableNameImp
* Signature: (JLjava/lang/String;J)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp
(JNIEnv *, jobject, jlong, jstring, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameImp(JNIEnv *, jobject, jlong, jstring,
jlong);
/**
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: setTableNameTagsImp
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(JNIEnv *, jobject, jlong, jstring,
jint, jbyteArray, jbyteArray,
jbyteArray, jbyteArray, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: bindColDataImp
* Signature: (J[B[B[BIIIIJ)J
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong);
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(JNIEnv *, jobject, jlong, jbyteArray,
jbyteArray, jbyteArray, jint, jint, jint,
jint, jlong);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: stmt_add_batch
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_addBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_addBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: executeBatchImp
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: closeStmt
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt,
jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: stmt_errstr
* Signature: (JJ)I
*/
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgImp(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: insertLinesImp
* Signature: ([Ljava/lang/String;JII)I
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp
(JNIEnv *, jobject, jobjectArray, jlong, jint, jint);
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *, jobject, jobjectArray, jlong,
jint, jint);
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: schemalessInsertImp
* Signature: (J[B[B[BIIIIJ)J
*/
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_schemalessInsertImp(JNIEnv *, jobject, jobjectArray,
jlong, jint, jint);
#ifdef __cplusplus
}
......
......@@ -945,7 +945,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_addBatchImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
jlong con) {
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj);
......@@ -1017,7 +1017,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv
}
JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgImp(JNIEnv *env, jobject jobj, jlong stmt,
jlong con) {
jlong con) {
char errMsg[128];
TAOS *tscon = (TAOS *)con;
if (tscon == NULL) {
......@@ -1036,20 +1036,12 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_stmtErrorMsgIm
return (*env)->NewStringUTF(env, taos_stmt_errstr((TAOS_STMT *)stmt));
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *env, jobject jobj,
jobjectArray lines, jlong conn,
jint protocol, jint precision) {
TAOS *taos = (TAOS *)conn;
if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
SSqlObj *schemalessInsert(JNIEnv *env, jobject jobj, jobjectArray lines, TAOS *taos, jint protocol, jint precision) {
int numLines = (*env)->GetArrayLength(env, lines);
char **c_lines = calloc(numLines, sizeof(char *));
if (c_lines == NULL) {
jniError("c_lines:%p, alloc memory failed", c_lines);
return JNI_OUT_OF_MEMORY;
return NULL;
}
for (int i = 0; i < numLines; ++i) {
jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i));
......@@ -1057,7 +1049,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JN
}
SSqlObj *result = (SSqlObj *)taos_schemaless_insert(taos, c_lines, numLines, protocol, precision);
int code = taos_errno(result);
for (int i = 0; i < numLines; ++i) {
jstring line = (jstring)((*env)->GetObjectArrayElement(env, lines, i));
......@@ -1065,6 +1056,24 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JN
}
tfree(c_lines);
return result;
}
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *env, jobject jobj,
jobjectArray lines, jlong conn,
jint protocol, jint precision) {
TAOS *taos = (TAOS *)conn;
if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
SSqlObj *result = (SSqlObj *)schemalessInsert(env, jobj, lines, taos, protocol, precision);
if (result == NULL) {
return JNI_OUT_OF_MEMORY;
}
int code = taos_errno(result);
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s, msg:%s", jobj, taos, tstrerror(code), taos_errstr(result));
taos_free_result((void *)result);
......@@ -1074,3 +1083,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JN
return JNI_SUCCESS;
}
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_schemalessInsertImp(JNIEnv *env, jobject jobj,
jobjectArray lines, jlong conn,
jint protocol, jint precision) {
TAOS *taos = (TAOS *)conn;
if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
SSqlObj *result = schemalessInsert(env, jobj, lines, taos, protocol, precision);
if (result == NULL) {
return JNI_OUT_OF_MEMORY;
}
return (jlong)result;
}
\ No newline at end of file
......@@ -2140,64 +2140,331 @@ static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index, SHashObj *pHash
static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **index,
bool *is_last_kv, SSmlLinesInfo* info, bool isTag) {
const char *start, *cur, *tmp;
int32_t ret = TSDB_CODE_SUCCESS;
char *value = NULL;
int16_t len = 0;
bool searchQuote = false;
start = cur = *index;
const char *start, *cur;
int32_t ret = TSDB_CODE_SUCCESS;
char *value = NULL;
int16_t len = 0;
bool kv_done = false;
bool back_slash = false;
bool double_quote = false;
size_t line_len = 0;
enum {
tag_common,
tag_lqoute,
tag_rqoute
} tag_state;
enum {
val_common,
val_lqoute,
val_rqoute
} val_state;
//if field value is string
if (!isTag) {
if (*cur == '"') {
searchQuote = true;
cur += 1;
len += 1;
} else if (*cur == 'L' && *(cur + 1) == '"') {
searchQuote = true;
cur += 2;
len += 2;
}
}
start = cur = *index;
tag_state = tag_common;
val_state = val_common;
while (1) {
// unescaped ',' or ' ' or '\0' identifies a value
if (((*cur == ',' || *cur == ' ' ) && *(cur - 1) != '\\') || *cur == '\0') {
if (searchQuote == true) {
//first quote ignored while searching
if (*(cur - 1) == '"' && len != 1 && len != 2) {
*is_last_kv = (*cur == ' ' || *cur == '\0') ? true : false;
if (isTag) {
/* ',', '=' and spaces MUST be escaped */
switch (tag_state) {
case tag_common:
if (back_slash == true) {
if (*cur != ',' && *cur != '=' && *cur != ' ') {
tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
back_slash = false;
cur++;
len++;
break;
}
if (*cur == '"') {
if (cur == *index) {
tag_state = tag_lqoute;
}
cur += 1;
len += 1;
break;
} else if (*cur == 'L') {
line_len = strlen(*index);
/* common character at the end */
if (cur + 1 >= *index + line_len) {
*is_last_kv = true;
kv_done = true;
break;
}
if (*(cur + 1) == '"') {
/* string starts here */
if (cur + 1 == *index + 1) {
tag_state = tag_lqoute;
}
cur += 2;
len += 2;
break;
}
}
switch (*cur) {
case '\\':
back_slash = true;
cur++;
len++;
break;
case ',':
kv_done = true;
break;
case ' ':
/* fall through */
case '\0':
*is_last_kv = true;
kv_done = true;
break;
} else if (*cur == '\0') {
default:
cur++;
len++;
}
break;
case tag_lqoute:
if (back_slash == true) {
if (*cur != ',' && *cur != '=' && *cur != ' ') {
tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) escaped", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
back_slash = false;
cur++;
len++;
break;
} else if (double_quote == true) {
if (*cur != ' ' && *cur != ',' && *cur != '\0') {
tscError("SML:0x%"PRIx64" tag value: state(%d), incorrect character(%c) behind closing \"", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
if (*cur == ' ' || *cur == '\0') {
*is_last_kv = true;
}
double_quote = false;
tag_state = tag_rqoute;
break;
}
switch (*cur) {
case '\\':
back_slash = true;
cur++;
len++;
break;
case '"':
double_quote = true;
cur++;
len++;
break;
case ',':
/* fall through */
case '=':
/* fall through */
case ' ':
if (*(cur - 1) != '\\') {
tscError("SML:0x%"PRIx64" tag value: state(%d), character(%c) not escaped", info->id, tag_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
kv_done = true;
}
break;
case '\0':
tscError("SML:0x%"PRIx64" tag value: state(%d), closing \" not found", info->id, tag_state);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
} else {
kv_done = true;
break;
default:
cur++;
len++;
continue;
}
break;
default:
kv_done = true;
}
//unescaped ' ' or '\0' indicates end of value
*is_last_kv = (*cur == ' ' || *cur == '\0') ? true : false;
if (*cur == ' ' && *(cur + 1) == ' ') {
cur++;
continue;
} else {
} else {
switch (val_state) {
case val_common:
if (back_slash == true) {
if (*cur != '\\' && *cur != '"') {
tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
back_slash = false;
cur++;
len++;
break;
}
if (*cur == '"') {
if (cur == *index) {
val_state = val_lqoute;
} else {
if (*(cur - 1) != '\\') {
tscError("SML:0x%"PRIx64" field value: state(%d), \" not escaped", info->id, val_state);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
}
cur += 1;
len += 1;
break;
} else if (*cur == 'L') {
line_len = strlen(*index);
/* common character at the end */
if (cur + 1 >= *index + line_len) {
*is_last_kv = true;
kv_done = true;
break;
}
if (*(cur + 1) == '"') {
/* string starts here */
if (cur + 1 == *index + 1) {
val_state = val_lqoute;
cur += 2;
len += 2;
} else {
/* MUST at the end of string */
if (cur + 2 >= *index + line_len) {
cur += 2;
len += 2;
*is_last_kv = true;
kv_done = true;
} else {
if (*(cur + 2) != ' ' && *(cur + 2) != ',') {
tscError("SML:0x%"PRIx64" field value: state(%d), not closing character(L\")", info->id, val_state);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
} else {
if (*(cur + 2) == ' ') {
*is_last_kv = true;
}
cur += 2;
len += 2;
kv_done = true;
}
}
}
break;
}
}
switch (*cur) {
case '\\':
back_slash = true;
cur++;
len++;
break;
case ',':
kv_done = true;
break;
case ' ':
/* fall through */
case '\0':
*is_last_kv = true;
kv_done = true;
break;
default:
cur++;
len++;
}
break;
case val_lqoute:
if (back_slash == true) {
if (*cur != '\\' && *cur != '"') {
tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) escaped", info->id, val_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
back_slash = false;
cur++;
len++;
break;
} else if (double_quote == true) {
if (*cur != ' ' && *cur != ',' && *cur != '\0') {
tscError("SML:0x%"PRIx64" field value: state(%d), incorrect character(%c) behind closing \"", info->id, val_state, *cur);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
if (*cur == ' ' || *cur == '\0') {
*is_last_kv = true;
}
double_quote = false;
val_state = val_rqoute;
break;
}
switch (*cur) {
case '\\':
back_slash = true;
cur++;
len++;
break;
case '"':
double_quote = true;
cur++;
len++;
break;
case '\0':
tscError("SML:0x%"PRIx64" field value: state(%d), closing \" not found", info->id, val_state);
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
kv_done = true;
break;
default:
cur++;
len++;
}
break;
default:
kv_done = true;
}
}
//Escape special character
if (*cur == '\\') {
tmp = cur;
escapeSpecialCharacter(isTag ? 2 : 3, &cur);
if (tmp != cur) {
continue;
}
if (kv_done == true) {
break;
}
cur++;
len++;
}
if (len == 0) {
if (len == 0 || ret != TSDB_CODE_SUCCESS) {
free(pKV->key);
pKV->key = NULL;
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
......
......@@ -4946,7 +4946,7 @@ static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQu
pse->colType = pExpr->base.resType;
if(pExpr->base.resBytes > INT16_MAX &&
(pExpr->base.functionId == TSDB_FUNC_UNIQUE || pExpr->base.functionId == TSDB_FUNC_MODE
|| pExpr->base.functionId == TSDB_FUNC_TAIL)){
|| pExpr->base.functionId == TSDB_FUNC_TAIL || pExpr->base.functionId == TSDB_FUNC_SAMPLE)){
pQueryAttr->interBytesForGlobal = pExpr->base.resBytes;
}else{
pse->colBytes = pExpr->base.resBytes;
......
......@@ -54,8 +54,8 @@ typedef struct SSqlExpr {
int32_t resBytes; // length of return value
int32_t interBytes; // inter result buffer size
int16_t colType; // table column type, this should be int32_t, because it is too small for globale merge stage, pQueryAttr->interBytesForGlobal
int16_t colBytes; // table column bytes
int16_t colType; // table column type
int16_t colBytes; // table column bytes,it should be int32_t, because it is too small for globale merge stage, pQueryAttr->interBytesForGlobal
int16_t numOfParams; // argument value of each function
tVariant param[3]; // parameters are not more than 3
......
......@@ -624,8 +624,9 @@ static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, i
if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) {
for (int i = 0; i < src2->numOfCols; i++) {
ASSERT(target->cols[i].type == src2->cols[i].type);
if (src2->cols[i].len > 0 && !isNull(src2->cols[i].pData, src2->cols[i].type)) {
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows,
const void *src2Val = tdGetColDataOfRow(src2->cols + i, *iter2);
if (src2->cols[i].len > 0 && !isNull(src2Val, src2->cols[i].type)) {
dataColAppendVal(&(target->cols[i]), src2Val, target->numOfRows,
target->maxPoints, 0);
} else if(!forceSetNull && key1 == key2 && src1->cols[i].len > 0) {
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows,
......
......@@ -338,7 +338,7 @@ public class TSDBJNIConnector {
public void addBatch(long stmt) throws SQLException {
int code = addBatchImp(stmt, this.taos);
if (code != TSDBConstants.JNI_SUCCESS){
if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, stmtErrorMsgImp(stmt, this.taos));
}
}
......@@ -361,13 +361,24 @@ public class TSDBJNIConnector {
/*************************************************************************************************/
// NOTE: schemaless-lines
public void insertLines(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException {
int code = insertLinesImp(lines, this.taos, protocolType.ordinal(), timestampType.ordinal());
if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to insertLines");
long pSql = schemalessInsertImp(lines, this.taos, protocolType.ordinal(), timestampType.ordinal());
try {
if (pSql == TSDBConstants.JNI_CONNECTION_NULL) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
}
if (pSql == TSDBConstants.JNI_OUT_OF_MEMORY) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
}
int code = this.getErrCode(pSql);
if (code != TSDBConstants.JNI_SUCCESS) {
String msg = this.getErrMsg(pSql);
throw TSDBError.createSQLException(code, msg);
}
} finally {
this.freeResultSetImp(this.taos, pSql);
}
}
private native int insertLinesImp(String[] lines, long conn, int type, int precision);
private native long schemalessInsertImp(String[] lines, long conn, int type, int precision);
}
......@@ -19,7 +19,6 @@ import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.ArrayList;
import java.util.Calendar;
......@@ -53,7 +52,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
return rowData;
}
public TSDBResultSet(TSDBStatement statement, TSDBJNIConnector connector, long resultSetPointer) throws SQLException {
public TSDBResultSet(TSDBStatement statement, TSDBJNIConnector connector, long resultSetPointer, int timestampPrecision) throws SQLException {
this.statement = statement;
this.jniConnector = connector;
this.resultSetPointer = resultSetPointer;
......@@ -69,7 +68,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
}
this.rowData = new TSDBResultSetRowData(this.columnMetaDataList.size());
this.blockData = new TSDBResultSetBlockData(this.columnMetaDataList, this.columnMetaDataList.size());
this.blockData = new TSDBResultSetBlockData(this.columnMetaDataList, this.columnMetaDataList.size(), timestampPrecision);
this.timestampPrecision = timestampPrecision;
}
public boolean next() throws SQLException {
......@@ -268,7 +268,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
checkAvailability(columnIndex, this.columnMetaDataList.size());
if (this.getBatchFetch())
return this.blockData.getString(columnIndex).getBytes();
return this.blockData.getBytes(columnIndex -1);
Object value = this.rowData.getObject(columnIndex);
this.lastWasNull = value == null;
......@@ -343,7 +343,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1));
return BigDecimal.valueOf(this.blockData.getDouble(columnIndex - 1));
this.lastWasNull = this.rowData.wasNull(columnIndex);
if (lastWasNull)
......
......@@ -25,10 +25,15 @@ import java.nio.ShortBuffer;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.enums.TimestampPrecision;
import com.taosdata.jdbc.utils.NullType;
public class TSDBResultSetBlockData {
......@@ -39,9 +44,12 @@ public class TSDBResultSetBlockData {
private List<ColumnMetaData> columnMetaDataList;
private ArrayList<Object> colData;
public TSDBResultSetBlockData(List<ColumnMetaData> colMeta, int numOfCols) {
private int timestampPrecision;
public TSDBResultSetBlockData(List<ColumnMetaData> colMeta, int numOfCols, int timestampPrecision) {
this.columnMetaDataList = colMeta;
this.colData = new ArrayList<>(numOfCols);
this.timestampPrecision = timestampPrecision;
}
public TSDBResultSetBlockData() {
......@@ -169,12 +177,46 @@ public class TSDBResultSetBlockData {
public String getString(int col) throws SQLException {
Object obj = get(col);
if (obj == null) {
return new NullType().toString();
// return new NullType().toString();
return null;
}
if (obj instanceof String)
return (String) obj;
if (obj instanceof byte[]) {
String charset = TaosGlobalConfig.getCharset();
try {
return new String((byte[]) obj, charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
return obj.toString();
}
public byte[] getBytes(int col) throws SQLException {
Object obj = get(col);
if (obj == null) {
return null;
}
if (obj instanceof byte[])
return (byte[]) obj;
if (obj instanceof String)
return ((String) obj).getBytes();
if (obj instanceof Long)
return Longs.toByteArray((long) obj);
if (obj instanceof Integer)
return Ints.toByteArray((int) obj);
if (obj instanceof Short)
return Shorts.toByteArray((short) obj);
if (obj instanceof Byte)
return new byte[]{(byte) obj};
return obj.toString().getBytes();
}
public int getInt(int col) {
Object obj = get(col);
if (obj == null) {
......@@ -184,14 +226,18 @@ public class TSDBResultSetBlockData {
int type = this.columnMetaDataList.get(col).getColType();
switch (type) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (boolean) obj ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: {
return (int) obj;
}
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
return ((Long) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
return ((Long) ((Timestamp) obj).getTime()).intValue();
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
......@@ -218,19 +264,25 @@ public class TSDBResultSetBlockData {
int type = this.columnMetaDataList.get(col).getColType();
switch (type) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (boolean) obj;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return ((byte) obj == 0) ? Boolean.FALSE : Boolean.TRUE;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return ((short) obj == 0) ? Boolean.FALSE : Boolean.TRUE;
case TSDBConstants.TSDB_DATA_TYPE_INT: {
return ((int) obj == 0L) ? Boolean.FALSE : Boolean.TRUE;
return ((int) obj == 0) ? Boolean.FALSE : Boolean.TRUE;
}
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (((long) obj) == 0L) ? Boolean.FALSE : Boolean.TRUE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
return (((Long) obj) == 0L) ? Boolean.FALSE : Boolean.TRUE;
return ((Timestamp) obj).getTime() == 0L ? Boolean.FALSE : Boolean.TRUE;
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return (((float) obj) == 0f) ? Boolean.FALSE : Boolean.TRUE;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
return (((Double) obj) == 0) ? Boolean.FALSE : Boolean.TRUE;
return (((double) obj) == 0) ? Boolean.FALSE : Boolean.TRUE;
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
......@@ -258,17 +310,31 @@ public class TSDBResultSetBlockData {
int type = this.columnMetaDataList.get(col).getColType();
switch (type) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (boolean) obj ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: {
return (int) obj;
}
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
return (long) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
Timestamp ts = (Timestamp) obj;
switch (this.timestampPrecision) {
case TimestampPrecision.MS:
default:
return ts.getTime();
case TimestampPrecision.US:
return ts.getTime() * 1000 + ts.getNanos() / 1000 % 1000;
case TimestampPrecision.NS:
return ts.getTime() * 1000_000 + ts.getNanos() % 1000_000;
}
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).longValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
return ((Double) obj).longValue();
}
......@@ -284,6 +350,17 @@ public class TSDBResultSetBlockData {
}
public Timestamp getTimestamp(int col) throws SQLException {
Object obj = get(col);
if (obj == null) {
return null;
}
int type = this.columnMetaDataList.get(col).getColType();
if (type == TSDBConstants.TSDB_DATA_TYPE_BIGINT)
return parseTimestampColumnData((long) obj);
if (type == TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)
return (Timestamp) obj;
return new Timestamp(getLong(col));
}
......@@ -296,17 +373,31 @@ public class TSDBResultSetBlockData {
int type = this.columnMetaDataList.get(col).getColType();
switch (type) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (boolean) obj ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: {
return (int) obj;
}
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
return (long) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
Timestamp ts = (Timestamp) obj;
switch (this.timestampPrecision) {
case TimestampPrecision.MS:
default:
return ts.getTime();
case TimestampPrecision.US:
return ts.getTime() * 1000 + ts.getNanos() / 1000 % 1000;
case TimestampPrecision.NS:
return ts.getTime() * 1000_000 + ts.getNanos() % 1000_000;
}
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return Double.parseDouble(String.valueOf(obj));
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
return (double) obj;
}
......@@ -367,7 +458,15 @@ public class TSDBResultSetBlockData {
return val;
}
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
LongBuffer lb = (LongBuffer) this.colData.get(col);
long val = lb.get(this.rowIndex);
if (NullType.isBigIntNull(val)) {
return null;
}
return parseTimestampColumnData(val);
}
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
LongBuffer lb = (LongBuffer) this.colData.get(col);
long val = lb.get(this.rowIndex);
......@@ -408,7 +507,7 @@ public class TSDBResultSetBlockData {
return null;
}
return new String(dest);
return dest;
}
case TSDBConstants.TSDB_DATA_TYPE_JSON:
......@@ -432,4 +531,21 @@ public class TSDBResultSetBlockData {
return 0;
}
private Timestamp parseTimestampColumnData(long value) {
if (TimestampPrecision.MS == timestampPrecision)
return new Timestamp(value);
if (TimestampPrecision.US == timestampPrecision) {
long epochSec = value / 1000_000L;
long nanoAdjustment = value % 1000_000L * 1000L;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
if (TimestampPrecision.NS == timestampPrecision) {
long epochSec = value / 1000_000_000L;
long nanoAdjustment = value % 1000_000_000L;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
return null;
}
}
......@@ -14,8 +14,6 @@
*****************************************************************************/
package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.NullType;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.SQLException;
......@@ -132,7 +130,7 @@ public class TSDBResultSetRowData {
public int getInt(int col, int nativeType) throws SQLException {
Object obj = data.get(col - 1);
if (obj == null)
return NullType.getIntNull();
return 0;
switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
......@@ -213,7 +211,7 @@ public class TSDBResultSetRowData {
public long getLong(int col, int nativeType) throws SQLException {
Object obj = data.get(col - 1);
if (obj == null) {
return NullType.getBigIntNull();
return 0;
}
switch (nativeType) {
......@@ -282,7 +280,7 @@ public class TSDBResultSetRowData {
public float getFloat(int col, int nativeType) {
Object obj = data.get(col - 1);
if (obj == null)
return NullType.getFloatNull();
return 0;
switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
......@@ -301,7 +299,7 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj;
default:
return NullType.getFloatNull();
return 0;
}
}
......@@ -322,7 +320,7 @@ public class TSDBResultSetRowData {
public double getDouble(int col, int nativeType) {
Object obj = data.get(col - 1);
if (obj == null)
return NullType.getDoubleNull();
return 0;
switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL:
......@@ -341,7 +339,7 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj;
default:
return NullType.getDoubleNull();
return 0;
}
}
......@@ -454,7 +452,7 @@ public class TSDBResultSetRowData {
milliseconds = ts / 1_000;
fracNanoseconds = (int) (ts * 1_000 % 1_000_000_000);
if (fracNanoseconds < 0) {
if (milliseconds == 0 ){
if (milliseconds == 0) {
milliseconds = -1;
}
fracNanoseconds += 1_000_000_000;
......@@ -465,7 +463,7 @@ public class TSDBResultSetRowData {
milliseconds = ts / 1_000_000;
fracNanoseconds = (int) (ts % 1_000_000_000);
if (fracNanoseconds < 0) {
if (milliseconds == 0 ){
if (milliseconds == 0) {
milliseconds = -1;
}
fracNanoseconds += 1_000_000_000;
......
......@@ -46,9 +46,8 @@ public class TSDBStatement extends AbstractStatement {
this.connection.getConnector().freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
}
TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql);
int timestampPrecision = this.connection.getConnector().getResultTimePrecision(pSql);
res.setTimestampPrecision(timestampPrecision);
TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql, timestampPrecision);
res.setBatchFetch(this.connection.getBatchFetch());
return res;
}
......@@ -91,7 +90,8 @@ public class TSDBStatement extends AbstractStatement {
return false;
}
this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql);
int timestampPrecision = this.connection.getConnector().getResultTimePrecision(pSql);
this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql, timestampPrecision);
this.resultSet.setBatchFetch(this.connection.getBatchFetch());
return true;
}
......
......@@ -14,6 +14,8 @@
*****************************************************************************/
package com.taosdata.jdbc;
import com.taosdata.jdbc.enums.TimestampPrecision;
import java.sql.SQLException;
public class TSDBSubscribe {
......@@ -41,7 +43,7 @@ public class TSDBSubscribe {
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
return null;
} else {
return new TSDBResultSet(null, this.connecter, resultSetPointer);
return new TSDBResultSet(null, this.connecter, resultSetPointer, TimestampPrecision.UNKNOWN);
}
}
......
......@@ -4,4 +4,5 @@ public class TimestampPrecision {
public static final int MS = 0;
public static final int US = 1;
public static final int NS = 2;
public static final int UNKNOWN = 9999;
}
......@@ -482,9 +482,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return Shorts.toByteArray((short) value);
if (value instanceof Byte)
return new byte[]{(byte) value};
if (value instanceof Timestamp) {
return Utils.formatTimestamp((Timestamp) value).getBytes();
}
return value.toString().getBytes();
}
......
......@@ -645,8 +645,6 @@ public class BlockResultSet extends AbstractWSResultSet {
}
if (value instanceof Float)
return (float) value;
if (value instanceof Double)
return (float) (double) value;
int taosType = fields.get(columnIndex - 1).getTaosType();
switch (taosType) {
......@@ -670,6 +668,12 @@ public class BlockResultSet extends AbstractWSResultSet {
throwRangeException(value.toString(), columnIndex, Types.FLOAT);
return tmp.floatValue();
}
case TSDB_DATA_TYPE_DOUBLE:{
Double tmp = (double) value;
if (tmp < Float.MIN_VALUE || tmp > Float.MAX_VALUE)
throwRangeException(value.toString(), columnIndex, Types.FLOAT);
return Float.parseFloat(String.valueOf(tmp));
}
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_JSON:
......@@ -700,7 +704,7 @@ public class BlockResultSet extends AbstractWSResultSet {
if (value instanceof Double)
return (double) value;
if (value instanceof Float)
return (float) value;
return Double.parseDouble(String.valueOf(value));
int taosType = fields.get(columnIndex - 1).getTaosType();
switch (taosType) {
......@@ -763,9 +767,6 @@ public class BlockResultSet extends AbstractWSResultSet {
return Shorts.toByteArray((short) value);
if (value instanceof Byte)
return new byte[]{(byte) value};
if (value instanceof Timestamp) {
return Utils.formatTimestamp((Timestamp) value).getBytes();
}
return value.toString().getBytes();
}
......
......@@ -9,7 +9,9 @@ import org.junit.runners.MethodSorters;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(CatalogRunner.class)
......@@ -1129,14 +1131,14 @@ public class JsonTagTest {
ResultSet resultSet = statement.executeQuery("select stddev(dataint) from jsons1 group by jtag->'tag1'");
String s = "";
int count = 0;
Set<String> set = new HashSet<>();
while (resultSet.next()) {
count++;
s = resultSet.getString(2);
set.add(resultSet.getString(2));
}
Assert.assertEquals(8, count);
Assert.assertEquals("\"收到货\"", s);
close(resultSet);
Assert.assertTrue(set.contains("\"femail\""));
Assert.assertTrue(set.contains("\"收到货\""));
}
@Test
......
......@@ -727,8 +727,8 @@ public class TSDBDatabaseMetaDataTest {
Assert.assertEquals(26, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(0, columns.getInt(9));
Assert.assertEquals(0, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
......@@ -773,8 +773,8 @@ public class TSDBDatabaseMetaDataTest {
Assert.assertEquals(12, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(0, columns.getInt(9));
Assert.assertEquals(0, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
......
......@@ -732,8 +732,8 @@ public class RestfulDatabaseMetaDataTest {
Assert.assertEquals(26, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(0, columns.getInt(9));
Assert.assertEquals(0, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
......@@ -778,8 +778,8 @@ public class RestfulDatabaseMetaDataTest {
Assert.assertEquals(12, columns.getInt("COLUMN_SIZE"));
// DECIMAL_DIGITS
Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9));
Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(0, columns.getInt(9));
Assert.assertEquals(0, columns.getInt("DECIMAL_DIGITS"));
Assert.assertEquals(null, columns.getString(9));
Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS"));
// NUM_PREC_RADIX
......
......@@ -8,6 +8,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import java.sql.*;
import java.util.HashSet;
import java.util.Set;
/**
* Most of the functionality is consistent with {@link com.taosdata.jdbc.JsonTagTest},
......@@ -1143,13 +1145,14 @@ public class RestfulJsonTagTest {
ResultSet resultSet = statement.executeQuery("select stddev(dataint) from jsons1 group by jtag->'tag1'");
String s = "";
int count = 0;
Set<String> set = new HashSet<>();
while (resultSet.next()) {
count++;
s = resultSet.getString(2);
set.add(resultSet.getString(2));
}
Assert.assertEquals(8, count);
Assert.assertEquals("\"收到货\"", s);
Assert.assertTrue(set.contains("\"femail\""));
Assert.assertTrue(set.contains("\"收到货\""));
close(resultSet);
}
......
......@@ -133,7 +133,7 @@ public class RestfulResultSetTest {
@Test
public void getBytes() throws SQLException {
byte[] f1 = rs.getBytes("f1");
Assert.assertEquals("2021-01-01 00:00:00.000", new String(f1));
Assert.assertEquals("2021-01-01 00:00:00.0", new String(f1));
byte[] f2 = rs.getBytes("f2");
Assert.assertEquals(1, Ints.fromByteArray(f2));
......
......@@ -83,16 +83,10 @@ void deltaToUtcInitOnce() {
static int64_t parseFraction(char* str, char** end, int32_t timePrec);
static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST);
static char* forwardToTimeStringEnd(char* str);
static bool checkTzPresent(char *str, int32_t len);
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec, char delim) = {
parseLocaltime,
parseLocaltimeWithDst
};
int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
......@@ -101,13 +95,13 @@ int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePre
if (checkTzPresent(timestr, len)) {
return parseTimeWithTz(timestr, time, timePrec, 'T');
} else {
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec, 'T');
return parseLocaltime(timestr, time, timePrec, 'T', day_light);
}
} else {
if (checkTzPresent(timestr, len)) {
return parseTimeWithTz(timestr, time, timePrec, 0);
} else {
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec, 0);
return parseLocaltime(timestr, time, timePrec, 0, day_light);
}
}
}
......@@ -322,9 +316,12 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del
return 0;
}
int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim) {
int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim, bool withDST) {
*time = 0;
struct tm tm = {0};
if (withDST) {
tm.tm_isdst = -1;
}
char* str;
if (delim == 'T') {
......@@ -336,7 +333,11 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char deli
}
if (str == NULL) {
return -1;
//if parse failed, try "%Y-%m-%d" format
str = strptime(timestr, "%Y-%m-%d", &tm);
if (str == NULL) {
return -1;
}
}
#ifdef _MSC_VER
......@@ -345,45 +346,14 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char deli
#endif
#endif
int64_t seconds = user_mktime64(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, timezone);
int64_t fraction = 0;
if (*str == '.') {
/* parse the second fraction part */
if ((fraction = parseFraction(str + 1, &str, timePrec)) < 0) {
return -1;
}
}
int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 :
(timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000);
*time = factor * seconds + fraction;
return 0;
}
int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec, char delim) {
*time = 0;
struct tm tm = {0};
tm.tm_isdst = -1;
char* str;
if (delim == 'T') {
str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm);
} else if (delim == 0) {
str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
int64_t seconds;
if (!withDST) {
seconds = user_mktime64(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, timezone);
} else {
str = NULL;
/* mktime will be affected by TZ, set by using taos_options */
seconds = mktime(&tm);
}
if (str == NULL) {
return -1;
}
/* mktime will be affected by TZ, set by using taos_options */
int64_t seconds = mktime(&tm);
int64_t fraction = 0;
if (*str == '.') {
......@@ -396,6 +366,7 @@ int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec, ch
int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 :
(timePrec == TSDB_TIME_PRECISION_MICRO ? 1000000 : 1000000000);
*time = factor * seconds + fraction;
return 0;
}
......
......@@ -1935,7 +1935,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr
pCtx->inputType = pSqlExpr->colType;
if (pRuntimeEnv->pQueryAttr->interBytesForGlobal > INT16_MAX &&
(pSqlExpr->functionId == TSDB_FUNC_UNIQUE || pSqlExpr->functionId == TSDB_FUNC_MODE
|| pSqlExpr->functionId == TSDB_FUNC_TAIL)){
|| pSqlExpr->functionId == TSDB_FUNC_TAIL || pSqlExpr->functionId == TSDB_FUNC_SAMPLE)) {
pCtx->inputBytes = pRuntimeEnv->pQueryAttr->interBytesForGlobal;
}else{
pCtx->inputBytes = pSqlExpr->colBytes;
......
import sys
from util.log import *
from util.cases import *
from util.sql import *
from util.dnodes import tdDnodes
from math import inf
class TDTestCase:
def caseDescription(self):
'''
case1<shenglian zhou>: [TD-13946]core dump of sampling binary column so that when result from vnode exceeds INT16_MAX bytes
'''
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 td13946")
tdSql.execute("create database td13946")
tdSql.execute("use td13946")
tdSql.execute("create table st ( ts timestamp, bin binary(100)) tags (t1 int)")
tdSql.execute("create table ct1 using st tags(1)")
tdSql.execute("create table ct2 using st tags(2)")
for i in range(0, 4000, 2):
tdSql.execute("insert into ct1 values(now + {}a, '{}')".format(i, i))
tdSql.execute("insert into ct2 values(now + {}a, '{}')".format(i+1, i+1))
tdSql.query("select sample(bin, 1000) from td13946.st group by tbname")
tdSql.execute('drop database td13946')
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
###################################################################
# 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<ganlin zhao>: [TD-13970] timestamp format shortcut
'''
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 db")
tdSql.execute("create database if not exists db")
tdSql.execute('use db')
tdSql.execute('create table tb(ts timestamp, c0 int)')
tdSql.execute('create stable stb(ts timestamp , c0 int) tags (t0 timestamp)')
#INSERT
tdSql.execute('insert into tb values ("2020-02-02", 1);')
tdSql.query('select ts from tb');
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
tdSql.execute('insert into ctb using stb tags("2020-02-02") values ("2020-02-02", 1)')
tdSql.query('select ts,t0 from ctb');
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
res = tdSql.getData(0, 1)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
tdSql.query('select ts,t0 from stb');
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
res = tdSql.getData(0, 1)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
#SELECT WHERE
tdSql.query('select ts from tb where ts = "2020-02-02"')
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
tdSql.query('select ts from ctb where ts <= "2020-02-02"')
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
tdSql.query('select ts from stb where ts >= "2020-02-02"')
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
#CREATE TAG
tdSql.execute('create table ctb1 using stb tags("2020-02-02")')
tdSql.query('select t0 from ctb1');
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
#TIME RELATED functions
tdSql.query('select to_unixtimestamp("2020-02-02") from tb')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 1580572800000)
tdSql.query('select timetruncate("2020-02-02", 1h) from tb;')
tdSql.checkRows(1)
res = tdSql.getData(0, 0)
tdSql.checkEqual(str(res), "2020-02-02 00:00:00")
tdSql.query('select timediff("2020-02-02", "2020-02-03", 1h) from tb;')
tdSql.checkRows(1)
tdSql.checkData(0, 0, 24)
tdSql.execute('drop database db')
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
......@@ -18,3 +18,4 @@ python3 ./test.py -f 2-query/TD-13246.py
python3 ./test.py -f 2-query/TD-6347.py
python3 ./test.py -f 2-query/math_funcs.py
python3 ./test.py -f 2-query/function_histogram.py
python3 ./test.py -f 2-query/TD-13946.py
......@@ -713,6 +713,7 @@
5,,develop-test,python3 ./test.py -f 2-query/function_to_iso8601.py
5,,develop-test,python3 ./test.py -f 2-query/function_to_unixtimestamp.py
5,,develop-test,python3 ./test.py -f 2-query/time_window_keywords.py
5,,develop-test,python3 ./test.py -f 2-query/TD-13946.py
5,,develop-test,python3 ./test.py -f 2-query/query_window_keywords.py
4,,system-test,python3 test.py -f 4-taosAdapter/TD-12163.py
4,,system-test,python3 ./test.py -f 3-connectors/restful/restful_binddbname.py
......@@ -789,10 +790,12 @@
3,,pytest,python3 test.py -f tag_lite/binary.py
3,,pytest,python3 test.py -f query/filterAllIntTypes.py
3,,develop-test,python3 ./test.py -f 2-query/ts_hidden_column.py
3,,develop-test,python3 ./test.py -f 2-query/ts_shortcut.py
3,,develop-test,python3 ./test.py -f 2-query/TD-5902.py
3,,script,eval sh -c \"if [ `uname -m` != aarch64 ]; then ./test.sh -f general/compute/scalar_triangle.sim; fi\"
3,,script,./test.sh -f general/compute/scalar_str_concat_len.sim
3,,develop-test,python3 ./test.py -f 2-query/function_tail.py
2,,develop-test,python3 ./test.py -f 2-query/function_unique.py
2,,develop-test,python3 ./test.py -f 2-query/function_hll.py
1,,develop-test,python3 ./test.py -f 2-query/function_state.py
1,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/demo.py
......@@ -32,9 +32,9 @@ class TDTestCase:
tdSql.execute('create stable ste(ts timestamp, f int) tags(t1 bigint)')
lines = [ "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"\"\"a pa,\"s si,t \"\"\",c2=false,c4=4f64 1626006833639000000",
lines = [ "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"\\\"\\\"a pa,\\\"s si,t \\\"\\\"\",c2=false,c4=4f64 1626006833639000000",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000",
"ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\" i,\"a \"m,\"\"\" 1626056811823316532",
"ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\" i,\\\"a \\\"m,\\\"\\\"\" 1626056811823316532",
"stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000",
"st,t1=4i64,t2=5f64,t3=\"t4\" c1=3i64,c3=L\"passitagain\",c2=true,c4=5f64 1626006833642000000",
"ste,t2=5f64,t3=L\"ste2\" c3=\"iamszhou\",c4=false 1626056811843316532",
......@@ -147,7 +147,7 @@ class TDTestCase:
tdSql.query('select tbname from str')
tdSql.checkRows(3)
###Special Character and keyss
###Special Character and keys
self._conn.schemaless_insert([
"1234,id=3456,abc=4i64,def=3i64 123=3i64,int=2i64,bool=false,into=5f64,column=7u64,!@#$.%^&*()=false 1626006933641",
"int,id=and,123=4i64,smallint=5f64,double=5f64,of=3i64,key=L\"passitagin_stf\",!@#$.%^&*()=false abc=false 1626006933654",
......@@ -193,6 +193,15 @@ class TDTestCase:
#tdSql.query('select * from `create`')
#tdSql.checkRows(1)
self._conn.schemaless_insert([
"sts,t1=abc,t2=ab\"c,t3=ab\\,c,t4=ab\\=c,t5=ab\\ c c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=\"abc\" 1626006833640000000",
"sts,t1=abc c1=3i64,c2=false,c3=L\"{\\\"date\\\":\\\"2020-01-01 08:00:00.000\\\",\\\"temperature\\\":20}\",c6=\"ab\\\\c\" 1626006833640000000"
], TDSmlProtocolType.LINE.value, TDSmlTimestampType.NANO_SECOND.value)
tdSql.query('select tbname from sts')
tdSql.checkRows(2)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册