fix conflicts.
This commit is contained in:
commit
fd06908fce
|
@ -1,6 +1,7 @@
|
|||
[](https://travis-ci.org/taosdata/TDengine)
|
||||
[](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master)
|
||||
[](https://coveralls.io/github/taosdata/TDengine?branch=develop)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/4201)
|
||||
|
||||
[](https://www.taosdata.com)
|
||||
|
||||
|
|
|
@ -33,11 +33,7 @@ IF (TD_LINUX_64)
|
|||
ADD_DEFINITIONS(-D_M_X64)
|
||||
ADD_DEFINITIONS(-D_TD_LINUX_64)
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -g3 -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
|
||||
FIND_PATH(ICONV_INCLUDE_EXIST iconv.h /usr/include/ /usr/local/include/)
|
||||
IF (ICONV_INCLUDE_EXIST)
|
||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||
ENDIF ()
|
||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_LINUX_32)
|
||||
|
@ -47,8 +43,10 @@ IF (TD_LINUX_32)
|
|||
ENDIF ()
|
||||
|
||||
IF (TD_ARM_64)
|
||||
ADD_DEFINITIONS(-D_M_X64)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_64_)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_)
|
||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -g -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
ENDIF ()
|
||||
|
||||
|
@ -132,6 +130,7 @@ ENDIF ()
|
|||
|
||||
IF (TD_WINDOWS_32)
|
||||
ADD_DEFINITIONS(-D_TD_WINDOWS_32)
|
||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||
ENDIF ()
|
||||
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||
|
|
|
@ -1,22 +1,14 @@
|
|||
IF (TD_LINUX_64)
|
||||
IF (TD_LINUX)
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
|
||||
INSTALL(CODE "execute_process(COMMAND chmod 777 ${TD_MAKE_INSTALL_SH})")
|
||||
INSTALL(CODE "execute_process(COMMAND ${TD_MAKE_INSTALL_SH} ${TD_COMMUNITY_DIR} ${PROJECT_BINARY_DIR})")
|
||||
ELSEIF (TD_LINUX_32)
|
||||
IF (NOT TD_ARM)
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
|
||||
INSTALL(CODE "execute_process(COMMAND chmod 777 ${TD_MAKE_INSTALL_SH})")
|
||||
INSTALL(CODE "execute_process(COMMAND ${TD_MAKE_INSTALL_SH} ${TD_COMMUNITY_DIR} ${PROJECT_BINARY_DIR})")
|
||||
ELSEIF (TD_WINDOWS_64)
|
||||
ELSEIF (TD_WINDOWS)
|
||||
SET(CMAKE_INSTALL_PREFIX C:/TDengine)
|
||||
IF (NOT TD_GODLL)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/grafana DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/python DESTINATION connector)
|
||||
#INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector)
|
||||
#INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/grafana DESTINATION connector)
|
||||
#INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/python DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/tests/examples DESTINATION .)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/packaging/cfg DESTINATION .)
|
||||
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taos.h DESTINATION include)
|
||||
|
@ -33,7 +25,7 @@ ELSEIF (TD_WINDOWS_64)
|
|||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/libtaos.dll DESTINATION driver)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/libtaos.dll.a DESTINATION driver)
|
||||
ENDIF ()
|
||||
ELSEIF (TD_DARWIN_64)
|
||||
ELSEIF (TD_DARWIN)
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
|
||||
INSTALL(CODE "execute_process(COMMAND chmod 777 ${TD_MAKE_INSTALL_SH})")
|
||||
|
|
|
@ -43,7 +43,6 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
ELSEIF (${CMAKE_SIZEOF_VOID_P} MATCHES 4)
|
||||
SET(TD_LINUX_32 TRUE)
|
||||
MESSAGE(STATUS "The current platform is Linux 32-bit")
|
||||
|
||||
ELSE ()
|
||||
MESSAGE(FATAL_ERROR "The current platform is Linux neither 32-bit nor 64-bit, not supported yet")
|
||||
EXIT ()
|
||||
|
@ -81,14 +80,17 @@ ENDIF ()
|
|||
# cmake -DCPUTYPE=aarch32 .. or cmake -DCPUTYPE=aarch64
|
||||
IF (${CPUTYPE} MATCHES "aarch32")
|
||||
SET(TD_LINUX TRUE)
|
||||
SET(TD_LINUX_32 FALSE)
|
||||
SET(TD_ARM_32 TRUE)
|
||||
MESSAGE(STATUS "input cpuType: aarch32")
|
||||
ELSEIF (${CPUTYPE} MATCHES "aarch64")
|
||||
SET(TD_LINUX TRUE)
|
||||
SET(TD_LINUX_64 FALSE)
|
||||
SET(TD_ARM_64 TRUE)
|
||||
MESSAGE(STATUS "input cpuType: aarch64")
|
||||
ELSEIF (${CPUTYPE} MATCHES "mips64")
|
||||
SET(TD_LINUX TRUE)
|
||||
SET(TD_LINUX_64 FALSE)
|
||||
SET(TD_MIPS_64 TRUE)
|
||||
MESSAGE(STATUS "input cpuType: mips64")
|
||||
ELSEIF (${CPUTYPE} MATCHES "x64")
|
||||
|
|
|
@ -286,7 +286,7 @@ Connection conn = DriverManager.getConnection(jdbcUrl);
|
|||
> `6030` is the default port and `log` is the default database for system monitor.
|
||||
|
||||
A normal JDBC URL looks as follows:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
values in `{}` are necessary while values in `[]` are optional。Each option in the above URL denotes:
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ Connection conn = DriverManager.getConnection(jdbcUrl);
|
|||
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
|
||||
|
||||
TDengine 的 JDBC URL 规范格式为:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
其中,`{}` 中的内容必须,`[]` 中为可选。配置参数说明如下:
|
||||
|
||||
|
|
|
@ -281,103 +281,100 @@ For the time being, TDengine supports subscription on one or multiple tables. It
|
|||
|
||||
## Java Connector
|
||||
|
||||
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
|
||||
To Java delevopers, TDengine provides `taos-jdbcdriver` according to the JDBC(3.0) API. Users can find and download it through [Sonatype Repository][1].
|
||||
|
||||
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
|
||||
Since the native language of TDengine is C, the necessary TDengine library should be checked before using the taos-jdbcdriver:
|
||||
|
||||
* libtaos.so
|
||||
在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
|
||||
* libtaos.so (Linux)
|
||||
After TDengine is installed successfully, the library `libtaos.so` will be automatically copied to the `/usr/lib/`, which is the system's default search path.
|
||||
|
||||
* taos.dll
|
||||
在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
|
||||
* taos.dll (Windows)
|
||||
After TDengine client is installed, the library `taos.dll` will be automatically copied to the `C:/Windows/System32`, which is the system's default search path.
|
||||
|
||||
> 注意:在 windows 环境开发时需要安装 TDengine 对应的 [windows 客户端][14],Linux 服务器安装完 TDengine 之后默认已安装 client,也可以单独安装 [Linux 客户端][15] 连接远程 TDengine Server。
|
||||
> Note: Please make sure that [TDengine Windows client][14] has been installed if developing on Windows. Now although TDengine client would be defaultly installed together with TDengine server, it can also be installed [alone][15].
|
||||
|
||||
TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致 taos-jdbcdriver 并未完全实现 JDBC 标准规范。在使用时需要注意以下几点:
|
||||
Since TDengine is time-series database, there are still some differences compared with traditional databases in using TDengine JDBC driver:
|
||||
* TDengine doesn't allow to delete/modify a single record, and thus JDBC driver also has no such method.
|
||||
* No support for transaction
|
||||
* No support for union between tables
|
||||
* No support for nested query,`There is at most one open ResultSet for each Connection. Thus, TSDB JDBC Driver will close current ResultSet if it is not closed and a new query begins`.
|
||||
|
||||
* TDengine 不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法。
|
||||
* 由于不支持删除和修改,所以也不支持事务操作。
|
||||
* 目前不支持表间的 union 操作。
|
||||
* 目前不支持嵌套查询(nested query),对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet。
|
||||
## Version list of TAOS-JDBCDriver and required TDengine and JDK
|
||||
|
||||
|
||||
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
|
||||
|
||||
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
|
||||
| taos-jdbcdriver | TDengine | JDK |
|
||||
| --- | --- | --- |
|
||||
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 2.0.0 | 2.0.0.x 及以上 | 1.8.x |
|
||||
| 2.0.2 | 2.0.0.x or higher | 1.8.x |
|
||||
| 1.0.3 | 1.6.1.x or higher | 1.8.x |
|
||||
| 1.0.2 | 1.6.1.x or higher | 1.8.x |
|
||||
| 1.0.1 | 1.6.1.x or higher | 1.8.x |
|
||||
|
||||
## TDengine DataType 和 Java DataType
|
||||
## DataType in TDengine and Java
|
||||
|
||||
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
|
||||
The datatypes in TDengine include timestamp, number, string and boolean, which are converted as follows in Java:
|
||||
|
||||
| TDengine DataType | Java DataType |
|
||||
| --- | --- |
|
||||
| TIMESTAMP | java.sql.Timestamp |
|
||||
| INT | java.lang.Integer |
|
||||
| BIGINT | java.lang.Long |
|
||||
| FLOAT | java.lang.Float |
|
||||
| DOUBLE | java.lang.Double |
|
||||
| TDengine | Java |
|
||||
| --- | --- |
|
||||
| TIMESTAMP | java.sql.Timestamp |
|
||||
| INT | java.lang.Integer |
|
||||
| BIGINT | java.lang.Long |
|
||||
| FLOAT | java.lang.Float |
|
||||
| DOUBLE | java.lang.Double |
|
||||
| SMALLINT, TINYINT |java.lang.Short |
|
||||
| BOOL | java.lang.Boolean |
|
||||
| BINARY, NCHAR | java.lang.String |
|
||||
| BOOL | java.lang.Boolean |
|
||||
| BINARY, NCHAR | java.lang.String |
|
||||
|
||||
## 如何获取 TAOS-JDBCDriver
|
||||
## How to get TAOS-JDBC Driver
|
||||
|
||||
### maven 仓库
|
||||
### maven repository
|
||||
|
||||
目前 taos-jdbcdriver 已经发布到 [Sonatype Repository][1] 仓库,且各大仓库都已同步。
|
||||
taos-jdbcdriver has been published to [Sonatype Repository][1]:
|
||||
* [sonatype][8]
|
||||
* [mvnrepository][9]
|
||||
* [maven.aliyun][10]
|
||||
|
||||
maven 项目中使用如下 pom.xml 配置即可:
|
||||
Using the following pom.xml for maven projects
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### 源码编译打包
|
||||
### JAR file from the source code
|
||||
|
||||
下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package` 即可生成相应 jar 包。
|
||||
After downloading the [TDengine][3] source code, execute `mvn clean package` in the directory `src/connector/jdbc` and then the corresponding jar file is generated.
|
||||
|
||||
## Usage
|
||||
|
||||
## 使用说明
|
||||
### get the connection
|
||||
|
||||
### 获取连接
|
||||
|
||||
如下所示配置即可获取 TDengine Connection:
|
||||
```java
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata";
|
||||
Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||
```
|
||||
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
|
||||
> `6030` is the default port and `log` is the default database for system monitor.
|
||||
|
||||
TDengine 的 JDBC URL 规范格式为:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
A normal JDBC URL looks as follows:
|
||||
`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
其中,`{}` 中的内容必须,`[]` 中为可选。配置参数说明如下:
|
||||
values in `{}` are necessary while values in `[]` are optional。Each option in the above URL denotes:
|
||||
|
||||
* user:登录 TDengine 用户名,默认值 root。
|
||||
* password:用户登录密码,默认值 taosdata。
|
||||
* charset:客户端使用的字符集,默认值为系统字符集。
|
||||
* cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
|
||||
* locale:客户端语言环境,默认值系统当前 locale。
|
||||
* timezone:客户端使用的时区,默认值为系统当前时区。
|
||||
* user:user name for login, defaultly root。
|
||||
* password:password for login,defaultly taosdata。
|
||||
* charset:charset for client,defaultly system charset
|
||||
* cfgdir:log directory for client, defaultly _/etc/taos/_ on Linux and _C:/TDengine/cfg_ on Windows。
|
||||
* locale:language for client,defaultly system locale。
|
||||
* timezone:timezone for client,defaultly system timezone。
|
||||
|
||||
以上参数可以在 3 处配置,`优先级由高到低`分别如下:
|
||||
1. JDBC URL 参数
|
||||
如上所述,可以在 JDBC URL 的参数中指定。
|
||||
The options above can be configures (`ordered by priority`):
|
||||
1. JDBC URL
|
||||
|
||||
As explained above.
|
||||
2. java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
|
||||
```java
|
||||
public Connection getConn() throws Exception{
|
||||
|
@ -395,9 +392,9 @@ public Connection getConn() throws Exception{
|
|||
}
|
||||
```
|
||||
|
||||
3. 客户端配置文件 taos.cfg
|
||||
3. Configuration file (taos.cfg)
|
||||
|
||||
linux 系统默认配置文件为 /var/lib/taos/taos.cfg,windows 系统默认配置文件路径为 C:\TDengine\cfg\taos.cfg。
|
||||
Default configuration file is _/var/lib/taos/taos.cfg_ On Linux and _C:\TDengine\cfg\taos.cfg_ on Windows
|
||||
```properties
|
||||
# client default username
|
||||
# defaultUser root
|
||||
|
@ -411,9 +408,9 @@ public Connection getConn() throws Exception{
|
|||
# system locale
|
||||
# locale en_US.UTF-8
|
||||
```
|
||||
> 更多详细配置请参考[客户端配置][13]
|
||||
> More options can refer to [client configuration][13]
|
||||
|
||||
### 创建数据库和表
|
||||
### Create databases and tables
|
||||
|
||||
```java
|
||||
Statement stmt = conn.createStatement();
|
||||
|
@ -427,9 +424,9 @@ stmt.executeUpdate("use db");
|
|||
// create table
|
||||
stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)");
|
||||
```
|
||||
> 注意:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
|
||||
> Note: if no step like `use db`, the name of database must be added as prefix like _db.tb_ when operating on tables
|
||||
|
||||
### 插入数据
|
||||
### Insert data
|
||||
|
||||
```java
|
||||
// insert data
|
||||
|
@ -437,10 +434,10 @@ int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now
|
|||
|
||||
System.out.println("insert " + affectedRows + " rows.");
|
||||
```
|
||||
> now 为系统内部函数,默认为服务器当前时间。
|
||||
> `now + 1s` 代表服务器当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。
|
||||
> _now_ is the server time.
|
||||
> _now+1s_ is 1 second later than current server time. The time unit includes: _a_(millisecond), _s_(second), _m_(minute), _h_(hour), _d_(day), _w_(week), _n_(month), _y_(year).
|
||||
|
||||
### 查询数据
|
||||
### Query database
|
||||
|
||||
```java
|
||||
// query data
|
||||
|
@ -458,22 +455,22 @@ while(resultSet.next()){
|
|||
System.out.printf("%s, %d, %s\n", ts, temperature, humidity);
|
||||
}
|
||||
```
|
||||
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
|
||||
> query is consistent with relational database. The subscript start with 1 when retrieving return results. It is recommended to use the column name to retrieve results.
|
||||
|
||||
|
||||
### 关闭资源
|
||||
### Close all
|
||||
|
||||
```java
|
||||
resultSet.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
```
|
||||
> `注意务必要将 connection 进行关闭`,否则会出现连接泄露。
|
||||
## 与连接池使用
|
||||
> `please make sure the connection is closed to avoid the error like connection leakage`
|
||||
|
||||
## Using connection pool
|
||||
|
||||
**HikariCP**
|
||||
|
||||
* 引入相应 HikariCP maven 依赖:
|
||||
* dependence in pom.xml:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
|
@ -482,7 +479,7 @@ conn.close();
|
|||
</dependency>
|
||||
```
|
||||
|
||||
* 使用示例如下:
|
||||
* Examples:
|
||||
```java
|
||||
public static void main(String[] args) throws SQLException {
|
||||
HikariConfig config = new HikariConfig();
|
||||
|
@ -508,8 +505,69 @@ conn.close();
|
|||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。
|
||||
> 更多 HikariCP 使用问题请查看[官方说明][5]
|
||||
> The close() method will not close the connection from HikariDataSource.getConnection(). Instead, the connection is put back to the connection pool.
|
||||
> More instructions can refer to [User Guide][5]
|
||||
|
||||
**Druid**
|
||||
|
||||
* dependency in pom.xml:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.20</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* Examples:
|
||||
```java
|
||||
public static void main(String[] args) throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("driverClassName","com.taosdata.jdbc.TSDBDriver");
|
||||
properties.put("url","jdbc:TAOS://127.0.0.1:6030/log");
|
||||
properties.put("username","root");
|
||||
properties.put("password","taosdata");
|
||||
|
||||
properties.put("maxActive","10"); //maximum number of connection in the pool
|
||||
properties.put("initialSize","3");//initial number of connection
|
||||
properties.put("maxWait","10000");//maximum wait milliseconds for get connection from pool
|
||||
properties.put("minIdle","3");//minimum number of connection in the pool
|
||||
|
||||
properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection
|
||||
|
||||
properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle
|
||||
properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle
|
||||
|
||||
properties.put("validationQuery","describe log.dn"); //validation query
|
||||
properties.put("testWhileIdle","true"); // test connection while idle
|
||||
properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true
|
||||
properties.put("testOnReturn","false"); // don't need while testWhileIdle is true
|
||||
|
||||
//create druid datasource
|
||||
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
|
||||
Connection connection = ds.getConnection(); // get connection
|
||||
Statement statement = connection.createStatement(); // get statement
|
||||
|
||||
//query or insert
|
||||
// ...
|
||||
|
||||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> More instructions can refer to [User Guide][6]
|
||||
|
||||
**Notice**
|
||||
* TDengine `v1.6.4.1` provides a function `select server_status()` to check heartbeat. It is highly recommended to use this function for `Validation Query`.
|
||||
|
||||
As follows,`1` will be returned if `select server_status()` is successfully executed。
|
||||
```shell
|
||||
taos> select server_status();
|
||||
server_status()|
|
||||
================
|
||||
1 |
|
||||
Query OK, 1 row(s) in set (0.000141s)
|
||||
```
|
||||
|
||||
## Python Connector
|
||||
|
||||
|
@ -821,3 +879,18 @@ An example of using the NodeJS connector to create a table with weather data and
|
|||
|
||||
An example of using the NodeJS connector to achieve the same things but without all the object wrappers that wrap around the data returned to achieve higher functionality can be found [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)
|
||||
|
||||
[1]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[2]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[3]: https://github.com/taosdata/TDengine
|
||||
[4]: https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/
|
||||
[5]: https://github.com/brettwooldridge/HikariCP
|
||||
[6]: https://github.com/alibaba/druid
|
||||
[7]: https://github.com/taosdata/TDengine/issues
|
||||
[8]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[9]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[10]: https://maven.aliyun.com/mvn/search
|
||||
[11]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate
|
||||
[12]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
|
||||
[13]: https://www.taosdata.com/cn/documentation20/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
|
||||
[14]: https://www.taosdata.com/cn/documentation20/connector/#Windows
|
||||
[15]: https://www.taosdata.com/cn/getting-started/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B
|
|
@ -31,7 +31,7 @@ taos> DESCRIBE meters;
|
|||
|
||||
- 时间格式为```YYYY-MM-DD HH:mm:ss.MS```, 默认时间分辨率为毫秒。比如:```2017-08-12 18:25:58.128```
|
||||
- 内部函数now是服务器的当前时间
|
||||
- 插入记录时,如果时间戳为0,插入数据时使用服务器当前时间
|
||||
- 插入记录时,如果时间戳为now,插入数据时使用服务器当前时间
|
||||
- Epoch Time: 时间戳也可以是一个长整数,表示从1970-01-01 08:00:00.000开始的毫秒数
|
||||
- 时间可以加减,比如 now-2h,表明查询时刻向前推2个小时(最近2小时)。数字后面的时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。比如select * from t1 where ts > now-2w and ts <= now-1w, 表示查询两周前整整一周的数据
|
||||
- TDengine暂不支持时间窗口按照自然年和自然月切分。Where条件中的时间窗口单位的换算关系如下:interval(1y) 等效于 interval(365d), interval(1n) 等效于 interval(30d), interval(1w) 等效于 interval(7d)
|
||||
|
@ -157,7 +157,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
```mysql
|
||||
DROP TABLE [IF EXISTS] stb_name;
|
||||
```
|
||||
删除STable会自动删除通过STable创建的字表。
|
||||
删除STable会自动删除通过STable创建的子表。
|
||||
|
||||
- **显示当前数据库下的所有超级表信息**
|
||||
|
||||
|
@ -206,7 +206,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
|||
```
|
||||
修改超级表的标签名,从超级表修改某个标签名后,该超级表下的所有子表也会自动更新该标签名。
|
||||
|
||||
- **修改字表标签值**
|
||||
- **修改子表标签值**
|
||||
|
||||
```mysql
|
||||
ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
|
||||
|
@ -994,4 +994,4 @@ SELECT AVG(current),MAX(current),LEASTSQUARES(current, start_val, step_val), PER
|
|||
- 列名最大长度为65,最多允许1024列,最少需要2列,第一列必须是时间戳
|
||||
- 标签最多允许128个,可以0个,标签总长度不超过16k个字符
|
||||
- SQL语句最大长度65480个字符,但可通过系统配置参数maxSQLLength修改,最长可配置为8M
|
||||
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制
|
||||
- 库的数目,超级表的数目、表的数目,系统不做限制,仅受系统资源限制
|
||||
|
|
|
@ -39,7 +39,7 @@ Raw DataSize = numOfTables * rowSizePerTable * rowsPerTable
|
|||
|
||||
用户可以通过参数keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
|
||||
|
||||
为提高速度,可以配置多快硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
|
||||
为提高速度,可以配置多块硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
|
||||
|
||||
### 物理机或虚拟机台数
|
||||
|
||||
|
|
|
@ -295,6 +295,117 @@ $ taos
|
|||
这时,因为电流超过了10A,您应该可以看到示例程序将它输出到了屏幕上。
|
||||
您可以继续插入一些数据观察示例程序的输出。
|
||||
|
||||
### Java 使用数据订阅功能
|
||||
|
||||
订阅功能也提供了 Java 开发接口,相关说明请见 [Java Connector](https://www.taosdata.com/cn/documentation20/connector/)。需要注意的是,目前 Java 接口没有提供异步订阅模式,但用户程序可以通过创建 `TimerTask` 等方式达到同样的效果。
|
||||
|
||||
下面以一个示例程序介绍其具体使用方法。它所完成的功能与前面介绍的 C 语言示例基本相同,也是订阅数据库中所有电流超过 10A 的记录。
|
||||
|
||||
#### 准备数据
|
||||
|
||||
```sql
|
||||
# 创建 power 库
|
||||
taos> create database power;
|
||||
# 切换库
|
||||
taos> use power;
|
||||
# 创建超级表
|
||||
taos> create table meters(ts timestamp, current float, voltage int, phase int) tags(location binary(64), groupId int);
|
||||
# 创建表
|
||||
taos> create table d1001 using meters tags ("Beijing.Chaoyang", 2);
|
||||
taos> create table d1002 using meters tags ("Beijing.Haidian", 2);
|
||||
# 插入测试数据
|
||||
taos> insert into d1001 values("2020-08-15 12:00:00.000", 12, 220, 1),("2020-08-15 12:10:00.000", 12.3, 220, 2),("2020-08-15 12:20:00.000", 12.2, 220, 1);
|
||||
taos> insert into d1002 values("2020-08-15 12:00:00.000", 9.9, 220, 1),("2020-08-15 12:10:00.000", 10.3, 220, 1),("2020-08-15 12:20:00.000", 11.2, 220, 1);
|
||||
# 从超级表 meters 查询电流大于 10A 的记录
|
||||
taos> select * from meters where current > 10;
|
||||
ts | current | voltage | phase | location | groupid |
|
||||
===========================================================================================================
|
||||
2020-08-15 12:10:00.000 | 10.30000 | 220 | 1 | Beijing.Haidian | 2 |
|
||||
2020-08-15 12:20:00.000 | 11.20000 | 220 | 1 | Beijing.Haidian | 2 |
|
||||
2020-08-15 12:00:00.000 | 12.00000 | 220 | 1 | Beijing.Chaoyang | 2 |
|
||||
2020-08-15 12:10:00.000 | 12.30000 | 220 | 2 | Beijing.Chaoyang | 2 |
|
||||
2020-08-15 12:20:00.000 | 12.20000 | 220 | 1 | Beijing.Chaoyang | 2 |
|
||||
Query OK, 5 row(s) in set (0.004896s)
|
||||
```
|
||||
|
||||
#### 示例程序
|
||||
|
||||
```java
|
||||
public class SubscribeDemo {
|
||||
private static final String topic = "topic-meter-current-bg-10";
|
||||
private static final String sql = "select * from meters where current > 10";
|
||||
|
||||
public static void main(String[] args) {
|
||||
Connection connection = null;
|
||||
TSDBSubscribe subscribe = null;
|
||||
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/power?user=root&password=taosdata";
|
||||
connection = DriverManager.getConnection(jdbcUrl, properties);
|
||||
subscribe = ((TSDBConnection) connection).subscribe(topic, sql, true); // 创建订阅
|
||||
int count = 0;
|
||||
while (count < 10) {
|
||||
TimeUnit.SECONDS.sleep(1); // 等待1秒,避免频繁调用 consume,给服务端造成压力
|
||||
TSDBResultSet resultSet = subscribe.consume(); // 消费数据
|
||||
if (resultSet == null) {
|
||||
continue;
|
||||
}
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
int columnCount = metaData.getColumnCount();
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
System.out.print(metaData.getColumnLabel(i) + ": " + resultSet.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (null != subscribe)
|
||||
subscribe.close(true); // 关闭订阅
|
||||
if (connection != null)
|
||||
connection.close();
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
运行示例程序,首先,它会消费符合查询条件的所有历史数据:
|
||||
|
||||
```shell
|
||||
# java -jar subscribe.jar
|
||||
|
||||
ts: 1597464000000 current: 12.0 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid : 2
|
||||
ts: 1597464600000 current: 12.3 voltage: 220 phase: 2 location: Beijing.Chaoyang groupid : 2
|
||||
ts: 1597465200000 current: 12.2 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid : 2
|
||||
ts: 1597464600000 current: 10.3 voltage: 220 phase: 1 location: Beijing.Haidian groupid : 2
|
||||
ts: 1597465200000 current: 11.2 voltage: 220 phase: 1 location: Beijing.Haidian groupid : 2
|
||||
```
|
||||
|
||||
接着,使用 taos 客户端向表中新增一条数据:
|
||||
|
||||
```sql
|
||||
# taos
|
||||
taos> use power;
|
||||
taos> insert into d1001 values("2020-08-15 12:40:00.000", 12.4, 220, 1);
|
||||
```
|
||||
|
||||
因为这条数据的电流大于10A,示例程序会将其消费:
|
||||
|
||||
```shell
|
||||
ts: 1597466400000 current: 12.4 voltage: 220 phase: 1 location: Beijing.Chaoyang groupid: 2
|
||||
```
|
||||
|
||||
|
||||
## 缓存(Cache)
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ CREATE DATABASE demo replica 3;
|
|||
```
|
||||
一个DB里的数据会被切片分到多个vnode group,vnode group里的vnode数目就是DB的副本数,同一个vnode group里各vnode的数据是完全一致的。为保证高可用性,vnode group里的vnode一定要分布在不同的dnode里(实际部署时,需要在不同的物理机上),只要一个vgroup里超过半数的vnode处于工作状态,这个vgroup就能正常的对外服务。
|
||||
|
||||
一个dnode里可能有多个DB的数据,因此一个dnode离线时,可能会影响到多个DB。如果一个vnode group里的一半或一半以上的vnode不工作,那么该vnode group就无法对外服务,无法插入或读取数据,这样会影响到它所属的DB的一部分表的d读写操作。
|
||||
一个dnode里可能有多个DB的数据,因此一个dnode离线时,可能会影响到多个DB。如果一个vnode group里的一半或一半以上的vnode不工作,那么该vnode group就无法对外服务,无法插入或读取数据,这样会影响到它所属的DB的一部分表的读写操作。
|
||||
|
||||
因为vnode的引入,无法简单的给出结论:“集群中过半dnode工作,集群就应该工作”。但是对于简单的情形,很好下结论。比如副本数为3,只有三个dnode,那如果仅有一个节点不工作,整个集群还是可以正常工作的,但如果有两个节点不工作,那整个集群就无法正常工作了。
|
||||
|
||||
|
|
|
@ -45,11 +45,11 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
|
||||
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
|
||||
|
||||
- ip:TDengine管理主节点的IP地址
|
||||
- user:用户名
|
||||
- pass:密码
|
||||
- db:数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
|
||||
- port:端口号
|
||||
- ip:TDengine管理主节点的IP地址
|
||||
- user:用户名
|
||||
- pass:密码
|
||||
- db:数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
|
||||
- port:端口号
|
||||
|
||||
返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。
|
||||
|
||||
|
@ -157,25 +157,25 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
|
||||
异步执行SQL语句。
|
||||
|
||||
* taos:调用taos_connect返回的数据库连接
|
||||
* sql:需要执行的SQL语句
|
||||
* fp:用户定义的回调函数,其第三个参数`code`用于指示操作是否成功,`0`表示成功,负数表示失败(调用`taos_errstr`获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数`TAOS_RES *`,该参数是查询返回的结果集
|
||||
* param:应用提供一个用于回调的参数
|
||||
* taos:调用taos_connect返回的数据库连接
|
||||
* sql:需要执行的SQL语句
|
||||
* fp:用户定义的回调函数,其第三个参数`code`用于指示操作是否成功,`0`表示成功,负数表示失败(调用`taos_errstr`获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数`TAOS_RES *`,该参数是查询返回的结果集
|
||||
* param:应用提供一个用于回调的参数
|
||||
|
||||
- `void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);`
|
||||
|
||||
批量获取异步查询的结果集,只能与`taos_query_a`配合使用。其中:
|
||||
|
||||
* res:`taos_query_a`回调时返回的结果集
|
||||
* fp:回调函数。其参数`param`是用户可定义的传递给回调函数的参数结构体;`numOfRows`是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用`taos_fetch_row`前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用`taos_fetch_rows_a`获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。
|
||||
* res:`taos_query_a`回调时返回的结果集
|
||||
* fp:回调函数。其参数`param`是用户可定义的传递给回调函数的参数结构体;`numOfRows`是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用`taos_fetch_row`前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用`taos_fetch_rows_a`获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。
|
||||
|
||||
|
||||
- `void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);`
|
||||
|
||||
异步获取一条记录。其中:
|
||||
|
||||
* res:`taos_query_a`回调时返回的结果集
|
||||
* fp:回调函数。其参数`param`是应用提供的一个用于回调的参数。回调时,第三个参数`row`指向一行记录。不同于`taos_fetch_rows_a`,应用无需调用`taos_fetch_row`来获取一行数据,更加简单,但数据提取性能不及批量获取的API。
|
||||
* res:`taos_query_a`回调时返回的结果集
|
||||
* fp:回调函数。其参数`param`是应用提供的一个用于回调的参数。回调时,第三个参数`row`指向一行记录。不同于`taos_fetch_rows_a`,应用无需调用`taos_fetch_row`来获取一行数据,更加简单,但数据提取性能不及批量获取的API。
|
||||
|
||||
TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
|
||||
|
||||
|
@ -232,12 +232,12 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
|
|||
- `TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *))`
|
||||
|
||||
该API用来创建数据流,其中:
|
||||
* taos:已经建立好的数据库连接
|
||||
* sql:SQL查询语句(仅能使用查询语句)
|
||||
* fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。
|
||||
* stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)
|
||||
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
|
||||
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
|
||||
* taos:已经建立好的数据库连接
|
||||
* sql:SQL查询语句(仅能使用查询语句)
|
||||
* fp:用户定义的回调函数指针,每次流式计算完成后,TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。
|
||||
* stime:是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)
|
||||
* param:是应用提供的用于回调的一个参数,回调时,提供给应用
|
||||
* callback: 第二个回调函数,会在连续查询自动停止时被调用。
|
||||
|
||||
返回值为NULL,表示创建成功,返回值不为空,表示成功。
|
||||
|
||||
|
@ -254,21 +254,21 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时
|
|||
* `TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval)`
|
||||
|
||||
该函数负责启动订阅服务,成功时返回订阅对象,失败时返回 `NULL`,其参数为:
|
||||
* taos:已经建立好的数据库连接
|
||||
* restart:如果订阅已经存在,是重新开始,还是继续之前的订阅
|
||||
* topic:订阅的主题(即名称),此参数是订阅的唯一标识
|
||||
* sql:订阅的查询语句,此语句只能是 `select` 语句,只应查询原始数据,只能按时间正序查询数据
|
||||
* fp:收到查询结果时的回调函数(稍后介绍函数原型),只在异步调用时使用,同步调用时此参数应该传 `NULL`
|
||||
* param:调用回调函数时的附加参数,系统API将其原样传递到回调函数,不进行任何处理
|
||||
* interval:轮询周期,单位为毫秒。异步调用时,将根据此参数周期性的调用回调函数,为避免对系统性能造成影响,不建议将此参数设置的过小;同步调用时,如两次调用`taos_consume`的间隔小于此周期,API将会阻塞,直到时间间隔超过此周期。
|
||||
* taos:已经建立好的数据库连接
|
||||
* restart:如果订阅已经存在,是重新开始,还是继续之前的订阅
|
||||
* topic:订阅的主题(即名称),此参数是订阅的唯一标识
|
||||
* sql:订阅的查询语句,此语句只能是 `select` 语句,只应查询原始数据,只能按时间正序查询数据
|
||||
* fp:收到查询结果时的回调函数(稍后介绍函数原型),只在异步调用时使用,同步调用时此参数应该传 `NULL`
|
||||
* param:调用回调函数时的附加参数,系统API将其原样传递到回调函数,不进行任何处理
|
||||
* interval:轮询周期,单位为毫秒。异步调用时,将根据此参数周期性的调用回调函数,为避免对系统性能造成影响,不建议将此参数设置的过小;同步调用时,如两次调用`taos_consume`的间隔小于此周期,API将会阻塞,直到时间间隔超过此周期。
|
||||
|
||||
* `typedef void (*TAOS_SUBSCRIBE_CALLBACK)(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code)`
|
||||
|
||||
异步模式下,回调函数的原型,其参数为:
|
||||
* tsub:订阅对象
|
||||
* res:查询结果集,注意结果集中可能没有记录
|
||||
* param:调用 `taos_subscribe`时客户程序提供的附加参数
|
||||
* code:错误码
|
||||
* tsub:订阅对象
|
||||
* res:查询结果集,注意结果集中可能没有记录
|
||||
* param:调用 `taos_subscribe`时客户程序提供的附加参数
|
||||
* code:错误码
|
||||
|
||||
|
||||
* `TAOS_RES *taos_consume(TAOS_SUB *tsub)`
|
||||
|
@ -306,7 +306,7 @@ TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一
|
|||
|
||||
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
|
||||
| --- | --- | --- |
|
||||
| 2.0.0 | 2.0.0.x 及以上 | 1.8.x |
|
||||
| 2.0.2 | 2.0.0.x 及以上 | 1.8.x |
|
||||
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
|
||||
|
@ -341,7 +341,7 @@ maven 项目中使用如下 pom.xml 配置即可:
|
|||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -363,7 +363,7 @@ Connection conn = DriverManager.getConnection(jdbcUrl);
|
|||
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
|
||||
|
||||
TDengine 的 JDBC URL 规范格式为:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
其中,`{}` 中的内容必须,`[]` 中为可选。配置参数说明如下:
|
||||
|
||||
|
@ -460,6 +460,49 @@ while(resultSet.next()){
|
|||
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
|
||||
|
||||
|
||||
### 订阅
|
||||
|
||||
#### 创建
|
||||
|
||||
```java
|
||||
TSDBSubscribe sub = ((TSDBConnection)conn).subscribe("topic", "select * from meters", false);
|
||||
```
|
||||
|
||||
`subscribe` 方法的三个参数含义如下:
|
||||
|
||||
* topic:订阅的主题(即名称),此参数是订阅的唯一标识
|
||||
* sql:订阅的查询语句,此语句只能是 `select` 语句,只应查询原始数据,只能按时间正序查询数据
|
||||
* restart:如果订阅已经存在,是重新开始,还是继续之前的订阅
|
||||
|
||||
如上面的例子将使用 SQL 语句 `select * from meters` 创建一个名为 `topic' 的订阅,如果这个订阅已经存在,将继续之前的查询进度,而不是从头开始消费所有的数据。
|
||||
|
||||
#### 消费数据
|
||||
|
||||
```java
|
||||
int total = 0;
|
||||
while(true) {
|
||||
TSDBResultSet rs = sub.consume();
|
||||
int count = 0;
|
||||
while(rs.next()) {
|
||||
count++;
|
||||
}
|
||||
total += count;
|
||||
System.out.printf("%d rows consumed, total %d\n", count, total);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
```
|
||||
|
||||
`consume` 方法返回一个结果集,其中包含从上次 `consume` 到目前为止的所有新数据。请务必按需选择合理的调用 `consume` 的频率(如例子中的`Thread.sleep(1000)`),否则会给服务端造成不必要的压力。
|
||||
|
||||
#### 关闭订阅
|
||||
|
||||
```java
|
||||
sub.close(true);
|
||||
```
|
||||
|
||||
`close` 方法关闭一个订阅。如果其参数为 `true` 表示保留订阅进度信息,后续可以创建同名订阅继续消费数据;如为 `false` 则不保留订阅进度。
|
||||
|
||||
|
||||
### 关闭资源
|
||||
|
||||
```java
|
||||
|
@ -603,7 +646,7 @@ Query OK, 1 row(s) in set (0.000141s)
|
|||
|
||||
#### Linux
|
||||
|
||||
用户可以在源代码的src/connector/python文件夹下找到python2和python3的安装包。用户可以通过pip命令安装:
|
||||
用户可以在源代码的src/connector/python(或者tar.gz的/connector/python)文件夹下找到python2和python3的connector安装包。用户可以通过pip命令安装:
|
||||
|
||||
`pip install src/connector/python/linux/python2/`
|
||||
|
||||
|
@ -931,12 +974,12 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间
|
|||
|
||||
## Go Connector
|
||||
|
||||
TDengine提供了GO驱动程序`taosSql`. `taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengin, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`
|
||||
TDengine提供了GO驱动程序`taosSql`. `taosSql`实现了GO语言的内置接口`database/sql/driver`。用户只需按如下方式引入包就可以在应用程序中访问TDengine, 详见`https://github.com/taosdata/driver-go/blob/develop/taosSql/driver_test.go`
|
||||
|
||||
```Go
|
||||
import (
|
||||
"database/sql"
|
||||
_ "github.com/taosdata/driver-go/taoSql"
|
||||
_ "github.com/taosdata/driver-go/taosSql"
|
||||
)
|
||||
```
|
||||
### 常用API
|
||||
|
@ -982,7 +1025,7 @@ npm install td2.0-connector
|
|||
|
||||
- Xcode
|
||||
|
||||
- 然后通过Xcode安装
|
||||
- 然后通过Xcode安装
|
||||
|
||||
```
|
||||
Command Line Tools
|
||||
|
@ -1108,4 +1151,4 @@ promise2.then(function(result) {
|
|||
[12]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
|
||||
[13]: https://www.taosdata.com/cn/documentation20/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
|
||||
[14]: https://www.taosdata.com/cn/documentation20/connector/#Windows
|
||||
[15]: https://www.taosdata.com/cn/getting-started/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B
|
||||
[15]: https://www.taosdata.com/cn/getting-started/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#### 4. 如何让TDengine crash时生成core文件?
|
||||
请看为此问题撰写的<a href='blog/2019/12/06/tdengine-crash时生成core文件的方法/'>技术博客</a>
|
||||
|
||||
#### 5. 遇到错误"failed to connect to server", 我怎么办?
|
||||
#### 5. 遇到错误"Unable to establish connection", 我怎么办?
|
||||
|
||||
客户端遇到链接故障,请按照下面的步骤进行检查:
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Version 2.X is a complete refactoring of the previous version, and configuration
|
|||
4. Enjoy the latest stable version of TDengine
|
||||
5. If the data needs to be migrated or the data file is corrupted, please contact the official technical support team for assistance
|
||||
|
||||
#### 2. When encoutered with the error "failed to connect to server", what can I do?
|
||||
#### 2. When encoutered with the error "Unable to establish connection", what can I do?
|
||||
|
||||
The client may encounter connection errors. Please follow the steps below for troubleshooting:
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ set -e
|
|||
# -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...]
|
||||
# -V [stable | beta]
|
||||
# -l [full | lite]
|
||||
# -n [2.0.0.3]
|
||||
|
||||
# set parameters by default value
|
||||
verMode=edge # [cluster, edge]
|
||||
|
@ -17,8 +18,9 @@ verType=stable # [stable, beta]
|
|||
cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...]
|
||||
pagMode=full # [full | lite]
|
||||
verNumber=""
|
||||
|
||||
while getopts "hv:V:c:o:l:" arg
|
||||
while getopts "hv:V:c:o:l:n:" arg
|
||||
do
|
||||
case $arg in
|
||||
v)
|
||||
|
@ -37,12 +39,21 @@ do
|
|||
#echo "pagMode=$OPTARG"
|
||||
pagMode=$(echo $OPTARG)
|
||||
;;
|
||||
n)
|
||||
#echo "verNumber=$OPTARG"
|
||||
verNumber=$(echo $OPTARG)
|
||||
;;
|
||||
o)
|
||||
#echo "osType=$OPTARG"
|
||||
osType=$(echo $OPTARG)
|
||||
;;
|
||||
h)
|
||||
echo "Usage: `basename $0` -v [cluster | edge] -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...] -V [stable | beta] -l [full | lite]"
|
||||
echo "Usage: `basename $0` -v [cluster | edge] "
|
||||
echo " -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] "
|
||||
echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | ...] "
|
||||
echo " -V [stable | beta] "
|
||||
echo " -l [full | lite] "
|
||||
echo " -n [version number] "
|
||||
exit 0
|
||||
;;
|
||||
?) #unknow option
|
||||
|
@ -52,7 +63,7 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode}"
|
||||
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} verNumber=${verNumber}"
|
||||
|
||||
curr_dir=$(pwd)
|
||||
|
||||
|
@ -80,7 +91,6 @@ function is_valid_version() {
|
|||
if [[ $1 =~ $rx ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -89,26 +99,25 @@ function vercomp () {
|
|||
echo 0
|
||||
exit 0
|
||||
fi
|
||||
|
||||
local IFS=.
|
||||
local i ver1=($1) ver2=($2)
|
||||
|
||||
# fill empty fields in ver1 with zeros
|
||||
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
|
||||
ver1[i]=0
|
||||
done
|
||||
|
||||
for ((i=0; i<${#ver1[@]}; i++)); do
|
||||
if [[ -z ${ver2[i]} ]]
|
||||
then
|
||||
if [[ -z ${ver2[i]} ]]; then
|
||||
# fill empty fields in ver2 with zeros
|
||||
ver2[i]=0
|
||||
fi
|
||||
if ((10#${ver1[i]} > 10#${ver2[i]}))
|
||||
then
|
||||
if ((10#${ver1[i]} > 10#${ver2[i]})); then
|
||||
echo 1
|
||||
exit 0
|
||||
fi
|
||||
if ((10#${ver1[i]} < 10#${ver2[i]}))
|
||||
then
|
||||
if ((10#${ver1[i]} < 10#${ver2[i]})); then
|
||||
echo 2
|
||||
exit 0
|
||||
fi
|
||||
|
@ -120,10 +129,11 @@ function vercomp () {
|
|||
version=$(cat ${versioninfo} | grep " version" | cut -d '"' -f2)
|
||||
compatible_version=$(cat ${versioninfo} | grep " compatible_version" | cut -d '"' -f2)
|
||||
|
||||
while true; do
|
||||
read -p "Do you want to release a new version? [y/N]: " is_version_change
|
||||
if [ -z ${verNumber} ]; then
|
||||
while true; do
|
||||
read -p "Do you want to release a new version? [y/N]: " is_version_change
|
||||
|
||||
if [[ ( "${is_version_change}" == "y") || ( "${is_version_change}" == "Y") ]]; then
|
||||
if [[ ( "${is_version_change}" == "y") || ( "${is_version_change}" == "Y") ]]; then
|
||||
read -p "Please enter the new version: " tversion
|
||||
while true; do
|
||||
if (! is_valid_version $tversion) || [ "$(vercomp $tversion $version)" = '2' ]; then
|
||||
|
@ -152,13 +162,24 @@ while true; do
|
|||
done
|
||||
|
||||
break
|
||||
elif [[ ( "${is_version_change}" == "n") || ( "${is_version_change}" == "N") ]]; then
|
||||
elif [[ ( "${is_version_change}" == "n") || ( "${is_version_change}" == "N") ]]; then
|
||||
echo "Use old version: ${version} compatible version: ${compatible_version}."
|
||||
break
|
||||
else
|
||||
else
|
||||
continue
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "old version: $version, new version: $verNumber"
|
||||
#if ( ! is_valid_version $verNumber ) || [[ "$(vercomp $version $verNumber)" == '2' ]]; then
|
||||
# echo "please enter correct version"
|
||||
# exit 0
|
||||
#else
|
||||
version=${verNumber}
|
||||
#fi
|
||||
fi
|
||||
|
||||
echo "=======================new version number: ${version}======================================"
|
||||
|
||||
# output the version info to the buildinfo file.
|
||||
build_time=$(date +"%F %R")
|
||||
|
|
|
@ -168,6 +168,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/tarbitrator || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
||||
${csudo} cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo} chmod 0555 ${install_main_dir}/bin/*
|
||||
|
||||
|
@ -176,6 +177,7 @@ function install_bin() {
|
|||
[ -x ${install_main_dir}/bin/taosd ] && ${csudo} ln -s ${install_main_dir}/bin/taosd ${bin_link_dir}/taosd || :
|
||||
[ -x ${install_main_dir}/bin/taosdemo ] && ${csudo} ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
[ -x ${install_main_dir}/bin/remove.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/rmtaos || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
[ -x ${install_main_dir}/bin/tarbitrator ] && ${csudo} ln -s ${install_main_dir}/bin/tarbitrator ${bin_link_dir}/tarbitrator || :
|
||||
|
||||
if [ "$verMode" == "cluster" ]; then
|
||||
|
@ -196,8 +198,10 @@ function install_lib() {
|
|||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1
|
||||
${csudo} ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so
|
||||
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || :
|
||||
${csudo} ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || :
|
||||
if [ -d ${lib64_link_dir} ]; then
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || :
|
||||
${csudo} ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || :
|
||||
fi
|
||||
|
||||
#if [ "$verMode" == "cluster" ]; then
|
||||
# # Compatible with version 1.5
|
||||
|
@ -205,6 +209,8 @@ function install_lib() {
|
|||
# ${csudo} ln -s ${install_main_dir}/connector/taos-jdbcdriver-1.0.2-dist.jar ${v15_java_app_dir}/JDBCDriver-1.0.2-dist.jar
|
||||
# ${csudo} chmod 777 ${v15_java_app_dir} || :
|
||||
#fi
|
||||
|
||||
${csudo} ldconfig
|
||||
}
|
||||
|
||||
function install_header() {
|
||||
|
|
|
@ -31,6 +31,7 @@ cfg_install_dir="/etc/taos"
|
|||
if [ "$osType" != "Darwin" ]; then
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
lib64_link_dir="/usr/lib64"
|
||||
inc_link_dir="/usr/include"
|
||||
else
|
||||
bin_link_dir="/usr/local/bin"
|
||||
|
@ -45,7 +46,7 @@ install_main_dir="/usr/local/taos"
|
|||
bin_dir="/usr/local/taos/bin"
|
||||
|
||||
# v1.5 jar dir
|
||||
v15_java_app_dir="/usr/local/lib/taos"
|
||||
#v15_java_app_dir="/usr/local/lib/taos"
|
||||
|
||||
# Color setting
|
||||
RED='\033[0;31m'
|
||||
|
@ -87,15 +88,17 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
fi
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
||||
${csudo} cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo} chmod 0555 ${install_main_dir}/bin/*
|
||||
|
||||
#Make link
|
||||
#Make link
|
||||
[ -x ${install_main_dir}/bin/taos ] && ${csudo} ln -s ${install_main_dir}/bin/taos ${bin_link_dir}/taos || :
|
||||
if [ "$osType" == "Darwin" ]; then
|
||||
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo} ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
|
||||
fi
|
||||
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
}
|
||||
|
||||
function clean_lib() {
|
||||
|
@ -106,17 +109,25 @@ function clean_lib() {
|
|||
function install_lib() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
#${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
|
||||
${csudo} cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1
|
||||
${csudo} ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so
|
||||
|
||||
if [ -d "${lib64_link_dir}" ]; then
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib64_link_dir}/libtaos.so.1 || :
|
||||
${csudo} ln -s ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so || :
|
||||
fi
|
||||
else
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.1.dylib
|
||||
${csudo} ln -s ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
||||
fi
|
||||
|
||||
${csudo} ldconfig
|
||||
}
|
||||
|
||||
function install_header() {
|
||||
|
|
|
@ -34,6 +34,7 @@ cfg_install_dir="/etc/taos"
|
|||
if [ "$osType" != "Darwin" ]; then
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
lib64_link_dir="/usr/lib64"
|
||||
inc_link_dir="/usr/include"
|
||||
else
|
||||
bin_link_dir="/usr/local/bin"
|
||||
|
@ -141,6 +142,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
fi
|
||||
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
|
@ -149,6 +151,7 @@ function install_bin() {
|
|||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
${csudo} cp -r ${script_dir}/remove.sh ${install_main_dir}/bin
|
||||
${csudo} cp -r ${script_dir}/set_core.sh ${install_main_dir}/bin
|
||||
else
|
||||
${csudo} cp -r ${script_dir}/remove_client.sh ${install_main_dir}/bin
|
||||
fi
|
||||
|
@ -161,6 +164,7 @@ function install_bin() {
|
|||
[ -x ${install_main_dir}/bin/taosd ] && ${csudo} ln -s ${install_main_dir}/bin/taosd ${bin_link_dir}/taosd || :
|
||||
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo} ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
|
||||
[ -x ${install_main_dir}/bin/taosdemo ] && ${csudo} ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
[ -x ${install_main_dir}/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
fi
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
|
@ -173,17 +177,25 @@ function install_bin() {
|
|||
function install_lib() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
|
||||
versioninfo=$(${script_dir}/get_version.sh ${source_dir}/src/util/src/version.c)
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
${csudo} cp ${binary_dir}/build/lib/libtaos.so.${versioninfo} ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||
${csudo} ln -sf ${install_main_dir}/driver/libtaos.so.${versioninfo} ${lib_link_dir}/libtaos.so.1
|
||||
${csudo} ln -sf ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so
|
||||
|
||||
if [ -d "${lib64_link_dir}" ]; then
|
||||
${csudo} ln -sf ${install_main_dir}/driver/libtaos.so.${versioninfo} ${lib64_link_dir}/libtaos.so.1
|
||||
${csudo} ln -sf ${lib64_link_dir}/libtaos.so.1 ${lib64_link_dir}/libtaos.so
|
||||
fi
|
||||
else
|
||||
${csudo} cp ${binary_dir}/build/lib/libtaos.${versioninfo}.dylib ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||
${csudo} ln -sf ${install_main_dir}/driver/libtaos.${versioninfo}.dylib ${lib_link_dir}/libtaos.1.dylib
|
||||
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
||||
fi
|
||||
|
||||
${csudo} ldconfig
|
||||
}
|
||||
|
||||
function install_header() {
|
||||
|
|
|
@ -45,7 +45,7 @@ if [ "$osType" != "Darwin" ]; then
|
|||
strip ${build_dir}/bin/taos
|
||||
bin_files="${build_dir}/bin/taos ${script_dir}/remove_client.sh"
|
||||
else
|
||||
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${script_dir}/remove_client.sh"
|
||||
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${script_dir}/remove_client.sh ${script_dir}/set_core.sh"
|
||||
fi
|
||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
else
|
||||
|
|
|
@ -36,7 +36,7 @@ if [ "$pagMode" == "lite" ]; then
|
|||
strip ${build_dir}/bin/taos
|
||||
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${script_dir}/remove.sh"
|
||||
else
|
||||
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdemo ${build_dir}/bin/tarbitrator ${script_dir}/remove.sh"
|
||||
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdemo ${build_dir}/bin/tarbitrator ${script_dir}/remove.sh ${script_dir}/set_core.sh"
|
||||
fi
|
||||
|
||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
|
|
|
@ -90,6 +90,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
||||
${csudo} chmod 0555 ${bin_dir}/*
|
||||
|
||||
|
@ -97,7 +98,7 @@ function install_bin() {
|
|||
[ -x ${bin_dir}/taos ] && ${csudo} ln -s ${bin_dir}/taos ${bin_link_dir}/taos || :
|
||||
[ -x ${bin_dir}/taosd ] && ${csudo} ln -s ${bin_dir}/taosd ${bin_link_dir}/taosd || :
|
||||
[ -x ${bin_dir}/taosdemo ] && ${csudo} ln -s ${bin_dir}/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
# [ -x ${bin_dir}/remove.sh ] && ${csudo} ln -s ${bin_dir}/remove.sh ${bin_link_dir}/rmtaos || :
|
||||
[ -x ${bin_dir}/set_core.sh ] && ${csudo} ln -s ${bin_dir}/set_core.sh ${bin_link_dir}/set_core || :
|
||||
}
|
||||
|
||||
function install_config() {
|
||||
|
|
|
@ -8,6 +8,7 @@ NC='\033[0m'
|
|||
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
lib64_link_dir="/usr/lib64"
|
||||
inc_link_dir="/usr/include"
|
||||
|
||||
data_link_dir="/usr/local/taos/data"
|
||||
|
@ -104,10 +105,12 @@ ${csudo} rm -f ${bin_link_dir}/taos || :
|
|||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
${csudo} rm -f ${cfg_link_dir}/* || :
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
|
||||
${csudo} rm -f ${log_link_dir} || :
|
||||
${csudo} rm -f ${data_link_dir} || :
|
||||
|
|
|
@ -18,11 +18,12 @@ log_link_dir="/usr/local/taos/log"
|
|||
cfg_link_dir="/usr/local/taos/cfg"
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
lib64_link_dir="/usr/lib64"
|
||||
inc_link_dir="/usr/include"
|
||||
install_nginxd_dir="/usr/local/nginxd"
|
||||
|
||||
# v1.5 jar dir
|
||||
v15_java_app_dir="/usr/local/lib/taos"
|
||||
#v15_java_app_dir="/usr/local/lib/taos"
|
||||
|
||||
service_config_dir="/etc/systemd/system"
|
||||
taos_service_name="taosd"
|
||||
|
@ -78,7 +79,8 @@ function clean_bin() {
|
|||
function clean_lib() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
#${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
}
|
||||
|
||||
function clean_header() {
|
||||
|
|
|
@ -15,11 +15,12 @@ log_link_dir="/usr/local/taos/log"
|
|||
cfg_link_dir="/usr/local/taos/cfg"
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
lib64_link_dir="/usr/lib64"
|
||||
inc_link_dir="/usr/include"
|
||||
|
||||
|
||||
# v1.5 jar dir
|
||||
v15_java_app_dir="/usr/local/lib/taos"
|
||||
#v15_java_app_dir="/usr/local/lib/taos"
|
||||
|
||||
csudo=""
|
||||
if command -v sudo > /dev/null; then
|
||||
|
@ -43,7 +44,8 @@ function clean_bin() {
|
|||
function clean_lib() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
${csudo} rm -f ${lib64_link_dir}/libtaos.* || :
|
||||
#${csudo} rm -rf ${v15_java_app_dir} || :
|
||||
}
|
||||
|
||||
function clean_header() {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is used to set config for core when taosd crash
|
||||
|
||||
set -e
|
||||
# set -x
|
||||
|
||||
csudo=""
|
||||
if command -v sudo > /dev/null; then
|
||||
csudo="sudo"
|
||||
fi
|
||||
|
||||
#ulimit -c unlimited
|
||||
${csudo} sed -i '/ulimit -c unlimited/d' /etc/profile ||:
|
||||
${csudo} sed -i '$a\ulimit -c unlimited' /etc/profile ||:
|
||||
source /etc/profile
|
||||
|
||||
${csudo} mkdir -p /coredump ||:
|
||||
${csudo} sysctl -w kernel.core_pattern='/coredump/core-%e-%p' ||:
|
||||
${csudo} echo '/coredump/core-%e-%p' | ${csudo} tee /proc/sys/kernel/core_pattern ||:
|
|
@ -3,11 +3,11 @@ PROJECT(TDengine)
|
|||
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/dnode/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/sdb/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/tsdb/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
AUX_SOURCE_DIRECTORY(src SRC)
|
||||
|
||||
IF (TD_LINUX)
|
||||
ADD_LIBRARY(balance ${SRC})
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
|
|
@ -214,8 +214,8 @@ static bool balanceCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
|||
* desc: remove one vnode from vgroup
|
||||
* all vnodes in vgroup should in ready state, except the balancing one
|
||||
**/
|
||||
static void balanceRemoveVnode(SVgObj *pVgroup) {
|
||||
if (pVgroup->numOfVnodes <= 1) return;
|
||||
static int32_t balanceRemoveVnode(SVgObj *pVgroup) {
|
||||
if (pVgroup->numOfVnodes <= 1) return -1;
|
||||
|
||||
SVnodeGid *pRmVnode = NULL;
|
||||
SVnodeGid *pSelVnode = NULL;
|
||||
|
@ -258,9 +258,11 @@ static void balanceRemoveVnode(SVgObj *pVgroup) {
|
|||
|
||||
if (!balanceCheckVgroupReady(pVgroup, pSelVnode)) {
|
||||
mDebug("vgId:%d, is not ready", pVgroup->vgId);
|
||||
return -1;
|
||||
} else {
|
||||
mDebug("vgId:%d, is ready, discard dnode:%d", pVgroup->vgId, pSelVnode->dnodeId);
|
||||
balanceDiscardVnode(pVgroup, pSelVnode);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,22 +409,22 @@ static int32_t balanceMonitorVgroups() {
|
|||
|
||||
int32_t dbReplica = pVgroup->pDb->cfg.replications;
|
||||
int32_t vgReplica = pVgroup->numOfVnodes;
|
||||
int32_t code = -1;
|
||||
|
||||
if (vgReplica > dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try remove one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
balanceRemoveVnode(pVgroup);
|
||||
code = balanceRemoveVnode(pVgroup);
|
||||
} else if (vgReplica < dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try add one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
int32_t code = balanceAddVnode(pVgroup, NULL, NULL);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
break;
|
||||
}
|
||||
code = balanceAddVnode(pVgroup, NULL, NULL);
|
||||
}
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
|
|
@ -210,7 +210,7 @@ void tscTagCondRelease(STagCond* pCond);
|
|||
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
||||
|
||||
void tscSetFreeHeatBeat(STscObj* pObj);
|
||||
bool tscShouldFreeHeatBeat(SSqlObj* pHb);
|
||||
bool tscShouldFreeHeartBeat(SSqlObj* pHb);
|
||||
bool tscShouldBeFreed(SSqlObj* pSql);
|
||||
|
||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
||||
|
@ -277,6 +277,9 @@ void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRo
|
|||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second);
|
||||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||
void tscClearSqlOwner(SSqlObj* pSql);
|
||||
|
||||
void* malloc_throw(size_t size);
|
||||
void* calloc_throw(size_t nmemb, size_t size);
|
||||
char* strdup_throw(const char* str);
|
||||
|
|
|
@ -80,8 +80,9 @@ typedef struct STableMetaInfo {
|
|||
* 2. keep the vgroup index for multi-vnode insertion
|
||||
*/
|
||||
int32_t vgroupIndex;
|
||||
char name[TSDB_TABLE_ID_LEN]; // (super) table name
|
||||
SArray* tagColList; // SArray<SColumn*>, involved tag columns
|
||||
char name[TSDB_TABLE_FNAME_LEN]; // (super) table name
|
||||
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
||||
SArray* tagColList; // SArray<SColumn*>, involved tag columns
|
||||
} STableMetaInfo;
|
||||
|
||||
/* the structure for sql function in select clause */
|
||||
|
@ -106,7 +107,7 @@ typedef struct SColumnIndex {
|
|||
typedef struct SFieldSupInfo {
|
||||
bool visible;
|
||||
SExprInfo *pArithExprInfo;
|
||||
SSqlExpr * pSqlExpr;
|
||||
SSqlExpr *pSqlExpr;
|
||||
} SFieldSupInfo;
|
||||
|
||||
typedef struct SFieldInfo {
|
||||
|
@ -128,7 +129,7 @@ typedef struct SCond {
|
|||
} SCond;
|
||||
|
||||
typedef struct SJoinNode {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
uint64_t uid;
|
||||
int16_t tagColId;
|
||||
} SJoinNode;
|
||||
|
@ -162,7 +163,7 @@ typedef struct SParamInfo {
|
|||
} SParamInfo;
|
||||
|
||||
typedef struct STableDataBlocks {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||
bool ordered; // if current rows are ordered or not
|
||||
int64_t vgId; // virtual group id
|
||||
|
@ -255,6 +256,7 @@ typedef struct SResRec {
|
|||
|
||||
typedef struct {
|
||||
int64_t numOfRows; // num of results in current retrieved
|
||||
int64_t numOfRowsGroup; // num of results of current group
|
||||
int64_t numOfTotal; // num of total results
|
||||
int64_t numOfClauseTotal; // num of total result in current subclause
|
||||
char * pRsp;
|
||||
|
@ -301,6 +303,7 @@ typedef struct STscObj {
|
|||
|
||||
typedef struct SSqlObj {
|
||||
void *signature;
|
||||
pthread_t owner; // owner of sql object, by which it is executed
|
||||
STscObj *pTscObj;
|
||||
void *pRpcCtx;
|
||||
void (*fp)();
|
||||
|
@ -419,7 +422,6 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
|||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
|
||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
//void tscGetResultColumnChr(SSqlRes *pRes, SFieldInfo* pFieldInfo, int32_t column);
|
||||
|
||||
static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex) {
|
||||
SFieldSupInfo* pInfo = (SFieldSupInfo*) TARRAY_GET_ELEM(pFieldInfo->pSupportInfo, columnIndex);
|
||||
|
|
|
@ -583,7 +583,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEn
|
|||
return 0l;
|
||||
}
|
||||
|
||||
return (long)res;
|
||||
return (jlong)res;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_unsubscribeImp(JNIEnv *env, jobject jobj, jlong sub,
|
||||
|
|
|
@ -220,14 +220,13 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
|
|||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockFromSubquery(pSql);
|
||||
} else if (pRes->completed) {
|
||||
if(pCmd->command == TSDB_SQL_FETCH) {
|
||||
if(pCmd->command == TSDB_SQL_FETCH || (pCmd->command >= TSDB_SQL_SERV_STATUS && pCmd->command <= TSDB_SQL_CURRENT_USER)) {
|
||||
if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes.
|
||||
tscTryQueryNextVnode(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* all available virtual node has been checked already, now we need to check
|
||||
* for the next subclause queries
|
||||
* all available virtual nodes in current clause has been checked already, now try the
|
||||
* next one in the following union subclause
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
|
@ -235,11 +234,12 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
|
|||
}
|
||||
|
||||
/*
|
||||
* 1. has reach the limitation
|
||||
* 2. no remain virtual nodes to be retrieved anymore
|
||||
* 1. has reach the limitation
|
||||
* 2. no remain virtual nodes to be retrieved anymore
|
||||
*/
|
||||
(*pSql->fetchFp)(param, pSql, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE) {
|
||||
// in case of show command, return no data
|
||||
|
|
|
@ -1942,11 +1942,12 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
|
|||
|
||||
static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, int64_t ts, uint16_t type,
|
||||
SExtTagsInfo *pTagInfo, char *pTags, int16_t stage) {
|
||||
tValuePair **pList = pInfo->res;
|
||||
|
||||
tVariant val = {0};
|
||||
tVariantCreateFromBinary(&val, pData, tDataTypeDesc[type].nSize, type);
|
||||
|
||||
|
||||
tValuePair **pList = pInfo->res;
|
||||
assert(pList != NULL);
|
||||
|
||||
if (pInfo->num < maxLen) {
|
||||
if (pInfo->num == 0) {
|
||||
valuePairAssign(pList[pInfo->num], type, (const char*) &val.i64Key, ts, pTags, pTagInfo, stage);
|
||||
|
|
|
@ -293,7 +293,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
char db[TSDB_DB_NAME_LEN] = {0};
|
||||
extractDBName(pSql->pTscObj->db, db);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -314,7 +314,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) {
|
|||
|
||||
static void tscProcessServerVer(SSqlObj *pSql) {
|
||||
const char* v = pSql->pTscObj->sversion;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
|
||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||
|
|
|
@ -68,7 +68,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
|
|||
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pCtx->aOutputBuf =
|
||||
pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity;
|
||||
pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity;
|
||||
pCtx->order = pQueryInfo->order.order;
|
||||
pCtx->functionId = pExpr->functionId;
|
||||
|
||||
|
@ -142,6 +142,7 @@ static SFillColInfo* createFillColInfo(SQueryInfo* pQueryInfo) {
|
|||
|
||||
pFillCol[i].col.bytes = pExpr->resBytes;
|
||||
pFillCol[i].col.type = (int8_t)pExpr->resType;
|
||||
pFillCol[i].col.colId = pExpr->colInfo.colId;
|
||||
pFillCol[i].flag = pExpr->colInfo.flag;
|
||||
pFillCol[i].col.offset = offset;
|
||||
pFillCol[i].functionId = pExpr->functionId;
|
||||
|
@ -321,6 +322,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||
|
||||
assert(pReducer->finalRowSize > 0);
|
||||
if (pReducer->finalRowSize > 0) {
|
||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||
|
@ -328,7 +330,6 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
||||
|
||||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||
// pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
|
||||
|
||||
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
|
@ -379,20 +380,6 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
4096, (int32_t)numOfCols, pQueryInfo->slidingTime, pQueryInfo->slidingTimeUnit,
|
||||
tinfo.precision, pQueryInfo->fillType, pFillCol);
|
||||
}
|
||||
|
||||
int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutput - pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 && pReducer->pFillInfo != NULL) {
|
||||
pReducer->pFillInfo->pTags[0] = (char *)pReducer->pFillInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SSchema *pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1);
|
||||
pReducer->pFillInfo->pTags[i] = pSchema->bytes + pReducer->pFillInfo->pTags[i - 1];
|
||||
}
|
||||
} else {
|
||||
if (pReducer->pFillInfo != NULL) {
|
||||
assert(pReducer->pFillInfo->pTags == NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage,
|
||||
|
@ -835,7 +822,7 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
|
|||
}
|
||||
}
|
||||
|
||||
void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo *pQueryInfo, SFillInfo *pFillInfo) {
|
||||
void savePrevRecordAndSetupFillInfo(SLocalReducer *pLocalReducer, SQueryInfo *pQueryInfo, SFillInfo *pFillInfo) {
|
||||
// discard following dataset in the same group and reset the interpolation information
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
|
@ -856,24 +843,6 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo
|
|||
tColModelAppend(pModel, pLocalReducer->discardData, pLocalReducer->prevRowOfInput, 0, 1, 1);
|
||||
}
|
||||
|
||||
// todo merge with following function
|
||||
// static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) {
|
||||
//
|
||||
// for (int32_t i = 0; i < pQueryInfo->exprList.numOfExprs; ++i) {
|
||||
// TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
|
||||
//
|
||||
// int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
// char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset;
|
||||
// char * dst = pRes->data + pRes->numOfRows * offset;
|
||||
//
|
||||
// for (int32_t j = 0; j < pRes->numOfRows; ++j) {
|
||||
// memcpy(dst, src, (size_t)pField->bytes);
|
||||
// dst += pField->bytes;
|
||||
// src -= pField->bytes;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRes *pRes, tFilePage **pResPages,
|
||||
SLocalReducer *pLocalReducer) {
|
||||
assert(0);
|
||||
|
@ -896,72 +865,66 @@ static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRe
|
|||
}
|
||||
}
|
||||
|
||||
static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer, SQueryInfo* pQueryInfo) {
|
||||
assert(pQueryInfo->intervalTime == 0 || pQueryInfo->fillType == TSDB_FILL_NONE);
|
||||
|
||||
tFilePage * pBeforeFillData = pLocalReducer->pResultBuf;
|
||||
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = pBeforeFillData->num;
|
||||
|
||||
if (pQueryInfo->limit.offset > 0) {
|
||||
if (pQueryInfo->limit.offset < pRes->numOfRows) {
|
||||
int32_t prevSize = (int32_t)pBeforeFillData->num;
|
||||
tColModelErase(pLocalReducer->resColModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1);
|
||||
|
||||
/* remove the hole in column model */
|
||||
tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize);
|
||||
|
||||
pRes->numOfRows -= pQueryInfo->limit.offset;
|
||||
pQueryInfo->limit.offset = 0;
|
||||
} else {
|
||||
pQueryInfo->limit.offset -= pRes->numOfRows;
|
||||
pRes->numOfRows = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pRes->numOfRowsGroup += pRes->numOfRows;
|
||||
|
||||
// impose the limitation of output rows on the final result
|
||||
if (pQueryInfo->limit.limit >= 0 && pRes->numOfRowsGroup > pQueryInfo->limit.limit) {
|
||||
int32_t prevSize = (int32_t)pBeforeFillData->num;
|
||||
int32_t overflow = (int32_t)(pRes->numOfRowsGroup - pQueryInfo->limit.limit);
|
||||
assert(overflow < pRes->numOfRows);
|
||||
|
||||
pRes->numOfRowsGroup = pQueryInfo->limit.limit;
|
||||
pRes->numOfRows -= overflow;
|
||||
pBeforeFillData->num -= overflow;
|
||||
|
||||
tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize);
|
||||
|
||||
// set remain data to be discarded, and reset the interpolation information
|
||||
savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo);
|
||||
}
|
||||
|
||||
memcpy(pRes->data, pBeforeFillData->data, pRes->numOfRows * pLocalReducer->finalRowSize);
|
||||
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
pBeforeFillData->num = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: pRes->pLocalReducer may be null, due to the fact that "tscDestroyLocalReducer" is called
|
||||
* by "interuptHandler" function in shell
|
||||
*/
|
||||
static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneOutput) {
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
tFilePage * pFinalDataPage = pLocalReducer->pResultBuf;
|
||||
tFilePage *pBeforeFillData = pLocalReducer->pResultBuf;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SFillInfo *pFillInfo = pLocalReducer->pFillInfo;
|
||||
|
||||
// if (pRes->pLocalReducer != pLocalReducer) {
|
||||
// /*
|
||||
// * Release the SSqlObj is called, and it is int destroying function invoked by other thread.
|
||||
// * However, the other thread will WAIT until current process fully completes.
|
||||
// * Since the flag of release struct is set by doLocalReduce function
|
||||
// */
|
||||
// assert(pRes->pLocalReducer == NULL);
|
||||
// }
|
||||
|
||||
// no interval query, no fill operation
|
||||
if (pQueryInfo->intervalTime == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) {
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = pFinalDataPage->num;
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
|
||||
if (pQueryInfo->limit.offset > 0) {
|
||||
if (pQueryInfo->limit.offset < pRes->numOfRows) {
|
||||
int32_t prevSize = (int32_t)pFinalDataPage->num;
|
||||
tColModelErase(pLocalReducer->resColModel, pFinalDataPage, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1);
|
||||
|
||||
/* remove the hole in column model */
|
||||
tColModelCompact(pLocalReducer->resColModel, pFinalDataPage, prevSize);
|
||||
|
||||
pRes->numOfRows -= pQueryInfo->limit.offset;
|
||||
pRes->numOfClauseTotal -= pQueryInfo->limit.offset;
|
||||
pQueryInfo->limit.offset = 0;
|
||||
} else {
|
||||
pQueryInfo->limit.offset -= pRes->numOfRows;
|
||||
pRes->numOfRows = 0;
|
||||
pRes->numOfClauseTotal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryInfo->limit.limit >= 0 && pRes->numOfClauseTotal > pQueryInfo->limit.limit) {
|
||||
/* impose the limitation of output rows on the final result */
|
||||
int32_t prevSize = (int32_t)pFinalDataPage->num;
|
||||
int32_t overflow = (int32_t)(pRes->numOfClauseTotal - pQueryInfo->limit.limit);
|
||||
assert(overflow < pRes->numOfRows);
|
||||
|
||||
pRes->numOfClauseTotal = pQueryInfo->limit.limit;
|
||||
pRes->numOfRows -= overflow;
|
||||
pFinalDataPage->num -= overflow;
|
||||
|
||||
tColModelCompact(pLocalReducer->resColModel, pFinalDataPage, prevSize);
|
||||
|
||||
/* set remain data to be discarded, and reset the interpolation information */
|
||||
savePrevRecordAndSetupInterpoInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo);
|
||||
}
|
||||
|
||||
memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * pLocalReducer->finalRowSize);
|
||||
pFinalDataPage->num = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SFillInfo *pFillInfo = pLocalReducer->pFillInfo;
|
||||
int64_t actualETime = MAX(pQueryInfo->window.skey, pQueryInfo->window.ekey);
|
||||
|
||||
tFilePage **pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutput);
|
||||
|
@ -969,7 +932,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
|
||||
pResPages[i] = calloc(1, sizeof(tFilePage) + pField->bytes * pLocalReducer->resColModel->capacity);
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
int64_t newRows = taosGenerateDataBlock(pFillInfo, pResPages, pLocalReducer->resColModel->capacity);
|
||||
|
||||
|
@ -986,7 +949,6 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = newRows;
|
||||
pRes->numOfClauseTotal += newRows;
|
||||
|
||||
pQueryInfo->limit.offset = 0;
|
||||
break;
|
||||
|
@ -1000,7 +962,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
break;
|
||||
}
|
||||
|
||||
/* all output for current group are completed */
|
||||
// all output in current group are completed
|
||||
int32_t totalRemainRows = (int32_t)getFilledNumOfRes(pFillInfo, actualETime, pLocalReducer->resColModel->capacity);
|
||||
if (totalRemainRows <= 0) {
|
||||
break;
|
||||
|
@ -1010,17 +972,16 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
}
|
||||
|
||||
if (pRes->numOfRows > 0) {
|
||||
if (pQueryInfo->limit.limit >= 0 && pRes->numOfClauseTotal > pQueryInfo->limit.limit) {
|
||||
int32_t overflow = (int32_t)(pRes->numOfClauseTotal - pQueryInfo->limit.limit);
|
||||
pRes->numOfRows -= overflow;
|
||||
int32_t currentTotal = (int32_t)(pRes->numOfRowsGroup + pRes->numOfRows);
|
||||
|
||||
if (pQueryInfo->limit.limit >= 0 && currentTotal > pQueryInfo->limit.limit) {
|
||||
int32_t overflow = (int32_t)(currentTotal - pQueryInfo->limit.limit);
|
||||
|
||||
pRes->numOfRows -= overflow;
|
||||
assert(pRes->numOfRows >= 0);
|
||||
|
||||
pRes->numOfClauseTotal = pQueryInfo->limit.limit;
|
||||
pFinalDataPage->num -= overflow;
|
||||
|
||||
/* set remain data to be discarded, and reset the interpolation information */
|
||||
savePrevRecordAndSetupInterpoInfo(pLocalReducer, pQueryInfo, pFillInfo);
|
||||
savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pFillInfo);
|
||||
}
|
||||
|
||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
||||
|
@ -1032,9 +993,12 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
|
|||
} else { // todo bug??
|
||||
reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer);
|
||||
}
|
||||
|
||||
pRes->numOfRowsGroup += pRes->numOfRows;
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
}
|
||||
|
||||
pFinalDataPage->num = 0;
|
||||
pBeforeFillData->num = 0;
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
taosTFree(pResPages[i]);
|
||||
}
|
||||
|
@ -1227,7 +1191,10 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
pRes->numOfGroups += 1;
|
||||
|
||||
if (pRes->numOfRowsGroup > 0) {
|
||||
pRes->numOfGroups += 1;
|
||||
}
|
||||
|
||||
// the output group is limited by the slimit clause
|
||||
if (reachGroupResultLimit(pQueryInfo, pRes)) {
|
||||
|
@ -1248,7 +1215,7 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
|
|||
* @param noMoreCurrentGroupRes
|
||||
* @return if current group is skipped, return false, and do NOT record it into pRes->numOfGroups
|
||||
*/
|
||||
bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCurrentGroupRes) {
|
||||
bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCurrentGroupRes) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
@ -1266,7 +1233,12 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
|||
pRes->numOfRows = 0;
|
||||
pQueryInfo->slimit.offset -= 1;
|
||||
pLocalReducer->discard = !noMoreCurrentGroupRes;
|
||||
|
||||
|
||||
if (pLocalReducer->discard) {
|
||||
SColumnModel *pInternModel = pLocalReducer->pDesc->pColumnModel;
|
||||
tColModelAppend(pInternModel, pLocalReducer->discardData, pLocalReducer->pTempBuffer->data, 0, 1, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1277,13 +1249,21 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
|||
// tColModelDisplay(pLocalReducer->resColModel, pLocalReducer->pBufForInterpo, pResBuf->num, pResBuf->num);
|
||||
#endif
|
||||
|
||||
SFillInfo* pFillInfo = pLocalReducer->pFillInfo;
|
||||
if (pFillInfo != NULL) {
|
||||
taosFillSetStartInfo(pFillInfo, (int32_t)pResBuf->num, pQueryInfo->window.ekey);
|
||||
taosFillCopyInputDataFromOneFilePage(pFillInfo, pResBuf);
|
||||
}
|
||||
|
||||
doFillResult(pSql, pLocalReducer, noMoreCurrentGroupRes);
|
||||
|
||||
// no interval query, no fill operation
|
||||
if (pQueryInfo->intervalTime == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) {
|
||||
genFinalResWithoutFill(pRes, pLocalReducer, pQueryInfo);
|
||||
} else {
|
||||
SFillInfo* pFillInfo = pLocalReducer->pFillInfo;
|
||||
if (pFillInfo != NULL) {
|
||||
taosFillSetStartInfo(pFillInfo, (int32_t)pResBuf->num, pQueryInfo->window.ekey);
|
||||
taosFillCopyInputDataFromOneFilePage(pFillInfo, pResBuf);
|
||||
}
|
||||
|
||||
doFillResult(pSql, pLocalReducer, noMoreCurrentGroupRes);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1279,7 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { //
|
|||
static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer *pLocalReducer) {
|
||||
// In handling data in other groups, we need to reset the interpolation information for a new group data
|
||||
pRes->numOfRows = 0;
|
||||
pRes->numOfClauseTotal = 0;
|
||||
pRes->numOfRowsGroup = 0;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
|
@ -1363,12 +1343,12 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
|
|||
if ((isAllSourcesCompleted(pLocalReducer) && !pLocalReducer->hasPrevRow) || pLocalReducer->pLocalDataSrc[0] == NULL ||
|
||||
prevGroupCompleted) {
|
||||
// if fillType == TSDB_FILL_NONE, return directly
|
||||
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
if (pQueryInfo->fillType != TSDB_FILL_NONE &&
|
||||
((pRes->numOfRowsGroup < pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) || (pQueryInfo->limit.limit < 0))) {
|
||||
int64_t etime = (pQueryInfo->window.skey < pQueryInfo->window.ekey) ? pQueryInfo->window.ekey : pQueryInfo->window.skey;
|
||||
|
||||
assert(pFillInfo->numOfRows == 0);
|
||||
int32_t rows = (int32_t)getFilledNumOfRes(pFillInfo, etime, pLocalReducer->resColModel->capacity);
|
||||
if (rows > 0) { // do interpo
|
||||
if (rows > 0) {
|
||||
doFillResult(pSql, pLocalReducer, true);
|
||||
}
|
||||
}
|
||||
|
@ -1533,7 +1513,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
*/
|
||||
if ((!sameGroup && pResBuf->num > 0) || (pResBuf->num == pLocalReducer->resColModel->capacity)) {
|
||||
// does not belong to the same group
|
||||
bool notSkipped = doGenerateFinalResults(pSql, pLocalReducer, !sameGroup);
|
||||
bool notSkipped = genFinalResults(pSql, pLocalReducer, !sameGroup);
|
||||
|
||||
// this row needs to discard, since it belongs to the group of previous
|
||||
if (pLocalReducer->discard && sameGroup) {
|
||||
|
@ -1602,7 +1582,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
if (pLocalReducer->pResultBuf->num) {
|
||||
doGenerateFinalResults(pSql, pLocalReducer, true);
|
||||
genFinalResults(pSql, pLocalReducer, true);
|
||||
}
|
||||
|
||||
assert(pLocalReducer->status == TSC_LOCALREDUCE_IN_PROGRESS && pRes->row == 0);
|
||||
|
|
|
@ -989,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
int validateTableName(char *tblName, int len, SSQLToken* psTblToken) {
|
||||
tstrncpy(psTblToken->z, tblName, TSDB_TABLE_ID_LEN);
|
||||
tstrncpy(psTblToken->z, tblName, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
psTblToken->n = len;
|
||||
psTblToken->type = TK_ID;
|
||||
|
@ -1038,7 +1038,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
if (NULL == pCmd->pTableList) {
|
||||
pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false);
|
||||
pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
pCmd->pDataBlocks = taosArrayInit(4, POINTER_BYTES);
|
||||
if (NULL == pCmd->pTableList || NULL == pSql->cmd.pDataBlocks) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
|
@ -1077,7 +1077,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
pCmd->curSql = sToken.z;
|
||||
char buf[TSDB_TABLE_ID_LEN];
|
||||
char buf[TSDB_TABLE_FNAME_LEN];
|
||||
SSQLToken sTblToken;
|
||||
sTblToken.z = buf;
|
||||
// Check if the table name available or not
|
||||
|
|
|
@ -613,11 +613,13 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
|||
if (sql == NULL) {
|
||||
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
} else {
|
||||
taosTFree(pStmt->pSql->sqlstr);
|
||||
pStmt->pSql->sqlstr = sql;
|
||||
SSqlObj* pSql = taos_query((TAOS*)pStmt->taos, pStmt->pSql->sqlstr);
|
||||
ret = taos_errno(pSql);
|
||||
taos_free_result(pSql);
|
||||
if (pStmt->pSql != NULL) {
|
||||
taos_free_result(pStmt->pSql);
|
||||
pStmt->pSql = NULL;
|
||||
}
|
||||
pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql);
|
||||
ret = taos_errno(pStmt->pSql);
|
||||
free(sql);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -86,7 +86,7 @@ static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQueryS
|
|||
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
|
||||
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString);
|
||||
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** exprString);
|
||||
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
|
||||
static int32_t validateEp(char* ep);
|
||||
|
@ -1087,11 +1087,11 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL
|
|||
*xlen = totalLen;
|
||||
}
|
||||
|
||||
if (totalLen < TSDB_TABLE_ID_LEN) {
|
||||
if (totalLen < TSDB_TABLE_FNAME_LEN) {
|
||||
fullName[totalLen] = 0;
|
||||
}
|
||||
|
||||
return (totalLen < TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
|
||||
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
static void extractColumnNameFromString(tSQLExprItem* pItem) {
|
||||
|
@ -1106,21 +1106,143 @@ static void extractColumnNameFromString(tSQLExprItem* pItem) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
|
||||
const char* msg1 = "invalid column name, or illegal column type";
|
||||
const char* msg2 = "invalid arithmetic expression in select clause";
|
||||
const char* msg3 = "tag columns can not be used in arithmetic expression";
|
||||
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
||||
|
||||
// arithmetic function in select clause
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||
|
||||
SColumnList columnList = {0};
|
||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||
|
||||
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
int32_t tableIndex = columnList.ids[0].tableIndex;
|
||||
|
||||
// todo potential data overflow
|
||||
char* arithmeticExprStr = malloc(1024*1024);
|
||||
char* p = arithmeticExprStr;
|
||||
|
||||
if (arithmeticType == NORMAL_ARITHMETIC) {
|
||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||
|
||||
// all columns in arithmetic expression must belong to the same table
|
||||
for (int32_t f = 1; f < columnList.num; ++f) {
|
||||
if (columnList.ids[f].tableIndex != tableIndex) {
|
||||
taosTFree(arithmeticExprStr);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
}
|
||||
}
|
||||
|
||||
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
||||
taosTFree(arithmeticExprStr);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
// expr string is set as the parameter of function
|
||||
SColumnIndex index = {.tableIndex = tableIndex};
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
|
||||
sizeof(double), false);
|
||||
|
||||
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
||||
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
|
||||
|
||||
tExprNode* pNode = NULL;
|
||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||
|
||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tExprTreeDestroy(&pNode, NULL);
|
||||
taosTFree(arithmeticExprStr);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
|
||||
size_t numOfNode = taosArrayGetSize(colList);
|
||||
for(int32_t k = 0; k < numOfNode; ++k) {
|
||||
SColIndex* pIndex = taosArrayGet(colList, k);
|
||||
if (pIndex->flag == 1) {
|
||||
taosTFree(arithmeticExprStr);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
}
|
||||
|
||||
SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||
|
||||
TRY(0) {
|
||||
exprTreeToBinary(&bw, pNode);
|
||||
} CATCH(code) {
|
||||
tbufCloseWriter(&bw);
|
||||
UNUSED(code);
|
||||
// TODO: other error handling
|
||||
} END_TRY
|
||||
|
||||
size_t len = tbufTell(&bw);
|
||||
char* c = tbufGetData(&bw, true);
|
||||
|
||||
// set the serialized binary string as the parameter of arithmetic expression
|
||||
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
|
||||
|
||||
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
||||
|
||||
taosArrayDestroy(colList);
|
||||
tExprTreeDestroy(&pNode, NULL);
|
||||
} else {
|
||||
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
||||
taosTFree(arithmeticExprStr);
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
columnList.num = 0;
|
||||
columnList.ids[0] = (SColumnIndex) {0, 0};
|
||||
|
||||
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
||||
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, name, NULL);
|
||||
|
||||
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
|
||||
|
||||
if (pInfo->pSqlExpr == NULL) {
|
||||
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
|
||||
|
||||
// arithmetic expression always return result in the format of double float
|
||||
pArithExprInfo->bytes = sizeof(double);
|
||||
pArithExprInfo->interBytes = sizeof(double);
|
||||
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
|
||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
|
||||
taosTFree(arithmeticExprStr);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
|
||||
}
|
||||
|
||||
pInfo->pArithExprInfo = pArithExprInfo;
|
||||
}
|
||||
}
|
||||
|
||||
taosTFree(arithmeticExprStr);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
|
||||
assert(pSelection != NULL && pCmd != NULL);
|
||||
|
||||
const char* msg1 = "invalid column name, or illegal column type";
|
||||
const char* msg2 = "functions can not be mixed up";
|
||||
const char* msg3 = "not support query expression";
|
||||
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
||||
const char* msg5 = "invalid function name";
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||
|
||||
|
||||
if (pQueryInfo->colList == NULL) {
|
||||
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
||||
|
||||
for (int32_t i = 0; i < pSelection->nExpr; ++i) {
|
||||
int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
|
||||
tSQLExprItem* pItem = &pSelection->a[i];
|
||||
|
@ -1147,96 +1269,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
|||
}
|
||||
|
||||
} else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
|
||||
// arithmetic function in select clause
|
||||
SColumnList columnList = {0};
|
||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||
|
||||
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tableIndex = columnList.ids[0].tableIndex;
|
||||
char arithmeticExprStr[1024] = {0};
|
||||
char* p = arithmeticExprStr;
|
||||
|
||||
if (arithmeticType == NORMAL_ARITHMETIC) {
|
||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||
|
||||
// all columns in arithmetic expression must belong to the same table
|
||||
for (int32_t f = 1; f < columnList.num; ++f) {
|
||||
if (columnList.ids[f].tableIndex != tableIndex) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
}
|
||||
}
|
||||
|
||||
if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
// expr string is set as the parameter of function
|
||||
SColumnIndex index = {.tableIndex = tableIndex};
|
||||
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
|
||||
sizeof(double), sizeof(double), false);
|
||||
|
||||
/* todo alias name should use the original sql string */
|
||||
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
||||
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
|
||||
|
||||
tExprNode* pNode = NULL;
|
||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||
|
||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tExprTreeDestroy(&pNode, NULL);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid arithmetic expression in select clause");
|
||||
}
|
||||
|
||||
SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||
|
||||
TRY(0) {
|
||||
exprTreeToBinary(&bw, pNode);
|
||||
} CATCH(code) {
|
||||
tbufCloseWriter(&bw);
|
||||
UNUSED(code);
|
||||
// TODO: other error handling
|
||||
} END_TRY
|
||||
|
||||
size_t len = tbufTell(&bw);
|
||||
char* c = tbufGetData(&bw, true);
|
||||
|
||||
// set the serialized binary string as the parameter of arithmetic expression
|
||||
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
|
||||
|
||||
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
||||
|
||||
taosArrayDestroy(colList);
|
||||
tExprTreeDestroy(&pNode, NULL);
|
||||
} else {
|
||||
columnList.num = 0;
|
||||
columnList.ids[0] = (SColumnIndex) {0, 0};
|
||||
|
||||
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "dummy_column", NULL);
|
||||
|
||||
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
|
||||
|
||||
if (pInfo->pSqlExpr == NULL) {
|
||||
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
|
||||
|
||||
// arithmetic expression always return result in the format of double float
|
||||
pArithExprInfo->bytes = sizeof(double);
|
||||
pArithExprInfo->interBytes = sizeof(double);
|
||||
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
|
||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
|
||||
}
|
||||
|
||||
pInfo->pArithExprInfo = pArithExprInfo;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* not support such expression
|
||||
|
@ -1872,6 +1909,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
|
||||
colIndex += 1; // the first column is ts
|
||||
|
||||
pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, resultSize, false);
|
||||
addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
|
||||
|
@ -2106,13 +2145,10 @@ int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColum
|
|||
}
|
||||
|
||||
pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
|
||||
char tableName[TSDB_TABLE_ID_LEN] = {0};
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||
extractTableName(pTableMetaInfo->name, tableName);
|
||||
|
||||
if (strncasecmp(tableName, pTableToken->z, pTableToken->n) == 0 && strlen(tableName) == pTableToken->n) {
|
||||
char* name = pTableMetaInfo->aliasName;
|
||||
if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
|
||||
pIndex->tableIndex = i;
|
||||
break;
|
||||
}
|
||||
|
@ -2354,7 +2390,7 @@ bool validateIpAddress(const char* ip, size_t size) {
|
|||
|
||||
strncpy(tmp, ip, size);
|
||||
|
||||
in_addr_t epAddr = inet_addr(tmp);
|
||||
in_addr_t epAddr = taosInetAddr(tmp);
|
||||
|
||||
return epAddr != INADDR_NONE;
|
||||
}
|
||||
|
@ -3081,14 +3117,14 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
|
|||
}
|
||||
|
||||
// todo error handle / such as and /or mixed with +/-/*/
|
||||
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
||||
int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
|
||||
tSQLExpr* pLeft = pExpr->pLeft;
|
||||
tSQLExpr* pRight = pExpr->pRight;
|
||||
|
||||
*(*exprString)++ = '(';
|
||||
|
||||
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
|
||||
buildArithmeticExprString(pLeft, exprString);
|
||||
doArithmeticExprToString(pLeft, exprString);
|
||||
} else {
|
||||
int32_t ret = tSQLExprNodeToString(pLeft, exprString);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3099,7 +3135,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
|||
optrToString(pExpr, exprString);
|
||||
|
||||
if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
|
||||
buildArithmeticExprString(pRight, exprString);
|
||||
doArithmeticExprToString(pRight, exprString);
|
||||
} else {
|
||||
int32_t ret = tSQLExprNodeToString(pRight, exprString);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3112,6 +3148,19 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
|
||||
char* start = *str;
|
||||
|
||||
int32_t code = doArithmeticExprToString(pExpr, str);
|
||||
if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
|
||||
int32_t len = (int32_t)strlen(start);
|
||||
memmove(start, start + 1, len - 2);
|
||||
start[len - 2] = 0;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
|
||||
if (pExpr->nSQLOptr == TK_ID) {
|
||||
if (*type == NON_ARITHMEIC_EXPR) {
|
||||
|
@ -3615,7 +3664,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
|||
SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
|
||||
taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
|
||||
|
||||
char db[TSDB_TABLE_ID_LEN] = {0};
|
||||
char db[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
|
||||
// remove the duplicated input table names
|
||||
int32_t num = 0;
|
||||
|
@ -3640,7 +3689,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
|||
taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
|
||||
}
|
||||
|
||||
char idBuf[TSDB_TABLE_ID_LEN] = {0};
|
||||
char idBuf[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
int32_t xlen = (int32_t)strlen(segments[i]);
|
||||
SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};
|
||||
|
||||
|
@ -4345,7 +4394,8 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
const char* msg16 = "only support one column";
|
||||
const char* msg17 = "invalid column name";
|
||||
const char* msg18 = "primary timestamp column cannot be dropped";
|
||||
|
||||
const char* msg19 = "invalid new tag name";
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
|
@ -4446,12 +4496,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
|
||||
SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
|
||||
if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
|
||||
}
|
||||
|
||||
SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
|
||||
if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
|
||||
}
|
||||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
|
@ -5872,15 +5922,16 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||
assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));
|
||||
|
||||
const char* msg0 = "invalid table name";
|
||||
const char* msg1 = "table name too long";
|
||||
const char* msg2 = "point interpolation query needs timestamp";
|
||||
const char* msg5 = "fill only available for interval query";
|
||||
const char* msg6 = "start(end) time of query range required or time range too large";
|
||||
const char* msg7 = "illegal number of tables in from clause";
|
||||
const char* msg8 = "too many columns in selection clause";
|
||||
const char* msg9 = "TWA query requires both the start and end time";
|
||||
const char* msg10= "too many tables in from clause";
|
||||
const char* msg0 = "invalid table name";
|
||||
const char* msg1 = "table name too long";
|
||||
const char* msg2 = "point interpolation query needs timestamp";
|
||||
const char* msg5 = "fill only available for interval query";
|
||||
const char* msg6 = "start(end) time of query range required or time range too large";
|
||||
const char* msg7 = "illegal number of tables in from clause";
|
||||
const char* msg8 = "too many columns in selection clause";
|
||||
const char* msg9 = "TWA query requires both the start and end time";
|
||||
const char* msg10 = "too many tables in from clause";
|
||||
const char* msg11 = "invalid table alias name";
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -5912,18 +5963,18 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
|
||||
}
|
||||
|
||||
if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) {
|
||||
if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||
}
|
||||
|
||||
pQueryInfo->command = TSDB_SQL_SELECT;
|
||||
|
||||
if (pQuerySql->from->nExpr > 2) {
|
||||
if (pQuerySql->from->nExpr > 4) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
|
||||
}
|
||||
|
||||
// set all query tables, which are maybe more than one.
|
||||
for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) {
|
||||
for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
|
||||
tVariant* pTableItem = &pQuerySql->from->a[i].pVar;
|
||||
|
||||
if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
|
||||
|
@ -5937,24 +5988,39 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
|
||||
}
|
||||
|
||||
if (pQueryInfo->numOfTables <= i) { // more than one table
|
||||
if (pQueryInfo->numOfTables <= i/2) { // more than one table
|
||||
tscAddEmptyMetaInfo(pQueryInfo);
|
||||
}
|
||||
|
||||
STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i);
|
||||
STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
|
||||
|
||||
SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
|
||||
if (tscSetTableFullName(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
|
||||
if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
code = tscGetTableMeta(pSql, pMeterInfo1);
|
||||
tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
|
||||
SSQLToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
|
||||
if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
|
||||
}
|
||||
|
||||
// has no table alias name
|
||||
if (memcmp(pTableItem->pz, pTableItem1->pz, pTableItem1->nLen) == 0) {
|
||||
extractTableName(pTableMetaInfo1->name, pTableMetaInfo1->aliasName);
|
||||
} else {
|
||||
tstrncpy(pTableMetaInfo1->aliasName, pTableItem1->pz, sizeof(pTableMetaInfo1->aliasName));
|
||||
}
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr);
|
||||
assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
|
||||
bool isSTable = false;
|
||||
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
|
@ -6122,12 +6188,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||
int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);
|
||||
|
||||
*pExpr = calloc(1, sizeof(tExprNode));
|
||||
(*pExpr)->nodeType = TSQL_NODE_COL;
|
||||
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
|
||||
|
||||
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
|
||||
*(*pExpr)->pSchema = *pSchema;
|
||||
|
||||
|
@ -6136,7 +6204,8 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
|
||||
colIndex.colId = pSchema->colId;
|
||||
colIndex.colIndex = index.columnIndex;
|
||||
|
||||
colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;
|
||||
|
||||
taosArrayPush(pCols, &colIndex);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,19 +45,27 @@ void tscSaveSubscriptionProgress(void* sub);
|
|||
static int32_t minMsgSize() { return tsRpcHeadSize + 100; }
|
||||
|
||||
static void tscSetDnodeEpSet(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) {
|
||||
assert(pSql != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
|
||||
|
||||
SRpcEpSet* pEpSet = &pSql->epSet;
|
||||
pEpSet->inUse = 0;
|
||||
if (pVgroupInfo == NULL) {
|
||||
pEpSet->numOfEps = 0;
|
||||
return;
|
||||
}
|
||||
pEpSet->inUse = 0;
|
||||
|
||||
// apply the FQDN string length check here
|
||||
bool hasFqdn = false;
|
||||
|
||||
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
strcpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn);
|
||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||
|
||||
if (!hasFqdn) {
|
||||
hasFqdn = (strlen(pEpSet->fqdn[i]) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
assert(hasFqdn);
|
||||
}
|
||||
|
||||
static void tscDumpMgmtEpSet(SRpcEpSet *epSet) {
|
||||
taosCorBeginRead(&tscMgmtEpSet.version);
|
||||
*epSet = tscMgmtEpSet.epSet;
|
||||
|
@ -127,21 +135,6 @@ void tscPrintMgmtEp() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For each management node, try twice at least in case of poor network situation.
|
||||
* If the client start to connect to a non-management node from the client, and the first retry may fail due to
|
||||
* the poor network quality. And then, the second retry get the response with redirection command.
|
||||
* The retry will not be executed since only *two* retry is allowed in case of single management node in the cluster.
|
||||
* Therefore, we need to multiply the retry times by factor of 2 to fix this problem.
|
||||
*/
|
||||
UNUSED_FUNC
|
||||
static int32_t tscGetMgmtConnMaxRetryTimes() {
|
||||
int32_t factor = 2;
|
||||
SRpcEpSet dump;
|
||||
tscDumpMgmtEpSet(&dump);
|
||||
return dump.numOfEps * factor;
|
||||
}
|
||||
|
||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||
STscObj *pObj = (STscObj *)param;
|
||||
if (pObj == NULL) return;
|
||||
|
@ -178,45 +171,25 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
|||
|
||||
void tscProcessActivityTimer(void *handle, void *tmrId) {
|
||||
STscObj *pObj = (STscObj *)handle;
|
||||
|
||||
if (pObj == NULL) return;
|
||||
if (pObj->signature != pObj) return;
|
||||
if (pObj->pTimer != tmrId) return;
|
||||
|
||||
if (pObj->pHb == NULL) {
|
||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||
if (NULL == pSql) return;
|
||||
|
||||
pSql->fp = tscProcessHeartBeatRsp;
|
||||
|
||||
SQueryInfo *pQueryInfo = NULL;
|
||||
tscGetQueryInfoDetailSafely(&pSql->cmd, 0, &pQueryInfo);
|
||||
pQueryInfo->command = TSDB_SQL_HB;
|
||||
|
||||
pSql->cmd.command = TSDB_SQL_HB;
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&(pSql->cmd), TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
taosTFree(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
pSql->cmd.command = TSDB_SQL_HB;
|
||||
pSql->param = pObj;
|
||||
pSql->pTscObj = pObj;
|
||||
pSql->signature = pSql;
|
||||
pObj->pHb = pSql;
|
||||
tscAddSubqueryInfo(&pObj->pHb->cmd);
|
||||
|
||||
tscDebug("%p pHb is allocated, pObj:%p", pObj->pHb, pObj);
|
||||
}
|
||||
|
||||
if (tscShouldFreeHeatBeat(pObj->pHb)) {
|
||||
tscDebug("%p free HB object and release connection", pObj);
|
||||
tscFreeSqlObj(pObj->pHb);
|
||||
tscCloseTscObj(pObj);
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
tscProcessSql(pObj->pHb);
|
||||
SSqlObj* pHB = pObj->pHb;
|
||||
if (pObj->pTimer != tmrId || pHB == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tscShouldFreeHeartBeat(pHB)) {
|
||||
tscDebug("%p free HB object and release connection", pHB);
|
||||
tscFreeSqlObj(pHB);
|
||||
tscCloseTscObj(pObj);
|
||||
} else {
|
||||
int32_t code = tscProcessSql(pHB);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tscSendMsgToServer(SSqlObj *pSql) {
|
||||
|
@ -272,6 +245,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
return;
|
||||
}
|
||||
|
||||
pSql->pRpcCtx = NULL; // clear the rpcCtx
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
if (pQueryInfo != NULL && pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE) {
|
||||
tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p",
|
||||
|
@ -424,21 +399,18 @@ int doProcessSql(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
int tscProcessSql(SSqlObj *pSql) {
|
||||
char * name = NULL;
|
||||
char *name = NULL;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
STableMetaInfo *pTableMetaInfo = NULL;
|
||||
uint32_t type = 0;
|
||||
|
||||
if (pQueryInfo != NULL) {
|
||||
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
if (pTableMetaInfo != NULL) {
|
||||
name = pTableMetaInfo->name;
|
||||
}
|
||||
|
||||
name = (pTableMetaInfo != NULL)? pTableMetaInfo->name:NULL;
|
||||
type = pQueryInfo->type;
|
||||
|
||||
|
||||
// while numOfTables equals to 0, it must be Heartbeat
|
||||
assert((pQueryInfo->numOfTables == 0 && pQueryInfo->command == TSDB_SQL_HB) || pQueryInfo->numOfTables > 0);
|
||||
}
|
||||
|
@ -450,7 +422,6 @@ int tscProcessSql(SSqlObj *pSql) {
|
|||
return pSql->res.code;
|
||||
}
|
||||
} else if (pCmd->command < TSDB_SQL_LOCAL) {
|
||||
|
||||
//pSql->epSet = tscMgmtEpSet;
|
||||
} else { // local handler
|
||||
return (*tscProcessMsgRsp[pCmd->command])(pSql);
|
||||
|
@ -597,11 +568,11 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
} else {
|
||||
pVgroupInfo = &pTableMeta->vgroupInfo;
|
||||
}
|
||||
tscSetDnodeEpSet(pSql, pVgroupInfo);
|
||||
|
||||
if (pVgroupInfo != NULL) {
|
||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||
}
|
||||
assert(pVgroupInfo != NULL);
|
||||
|
||||
tscSetDnodeEpSet(pSql, pVgroupInfo);
|
||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||
|
||||
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||
pTableIdInfo->tid = htonl(pTableMeta->id.tid);
|
||||
|
@ -1460,7 +1431,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
|
||||
tscSetResultPointer(pQueryInfo, pRes);
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
}
|
||||
|
||||
pRes->row = 0;
|
||||
|
@ -1562,7 +1533,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
// fill head info
|
||||
SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize);
|
||||
memset(pMgmt->db, 0, TSDB_TABLE_ID_LEN); // server don't need the db
|
||||
memset(pMgmt->db, 0, TSDB_TABLE_FNAME_LEN); // server don't need the db
|
||||
|
||||
SCMMultiTableInfoMsg *pInfoMsg = (SCMMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead));
|
||||
pInfoMsg->numOfTables = htonl((int32_t)pCmd->count);
|
||||
|
@ -1603,7 +1574,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
//// tagLen += strlen(pQueryInfo->tagCond.tbnameCond.cond) * TSDB_NCHAR_SIZE;
|
||||
//// }
|
||||
////
|
||||
//// int32_t joinCondLen = (TSDB_TABLE_ID_LEN + sizeof(int16_t)) * 2;
|
||||
//// int32_t joinCondLen = (TSDB_TABLE_FNAME_LEN + sizeof(int16_t)) * 2;
|
||||
//// int32_t elemSize = sizeof(SSuperTableMetaElemMsg) * pQueryInfo->numOfTables;
|
||||
////
|
||||
//// int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndex);
|
||||
|
@ -1884,11 +1855,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
|||
|
||||
for (int32_t k = 0; k < pVgroups->numOfEps; ++k) {
|
||||
pVgroups->epAddr[k].port = htons(pVgroups->epAddr[k].port);
|
||||
|
||||
}
|
||||
|
||||
pMsg += size;
|
||||
}
|
||||
|
||||
pMsg += size;
|
||||
}
|
||||
|
||||
return pSql->res.code;
|
||||
|
@ -1965,8 +1935,37 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void createHBObj(STscObj* pObj) {
|
||||
if (pObj->pHb != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||
if (NULL == pSql) return;
|
||||
|
||||
pSql->fp = tscProcessHeartBeatRsp;
|
||||
|
||||
SQueryInfo *pQueryInfo = NULL;
|
||||
tscGetQueryInfoDetailSafely(&pSql->cmd, 0, &pQueryInfo);
|
||||
pQueryInfo->command = TSDB_SQL_HB;
|
||||
|
||||
pSql->cmd.command = pQueryInfo->command;
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&(pSql->cmd), TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
taosTFree(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
pSql->param = pObj;
|
||||
pSql->pTscObj = pObj;
|
||||
pSql->signature = pSql;
|
||||
pObj->pHb = pSql;
|
||||
tscAddSubqueryInfo(&pObj->pHb->cmd);
|
||||
|
||||
tscDebug("%p HB is allocated, pObj:%p", pObj->pHb, pObj);
|
||||
}
|
||||
|
||||
int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||
char temp[TSDB_TABLE_ID_LEN * 2];
|
||||
char temp[TSDB_TABLE_FNAME_LEN * 2];
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
@ -1986,6 +1985,9 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
|||
pObj->writeAuth = pConnect->writeAuth;
|
||||
pObj->superAuth = pConnect->superAuth;
|
||||
pObj->connId = htonl(pConnect->connId);
|
||||
|
||||
createHBObj(pObj);
|
||||
|
||||
taosTmrReset(tscProcessActivityTimer, tsShellActivityTimer * 500, pObj, tscTmr, &pObj->pTimer);
|
||||
|
||||
return 0;
|
||||
|
@ -2114,21 +2116,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessRetrieveRspFromLocal(SSqlObj *pSql) {
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
|
||||
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
|
||||
|
||||
pRes->numOfRows = htonl(pRetrieve->numOfRows);
|
||||
pRes->data = pRetrieve->data;
|
||||
|
||||
tscSetResultPointer(pQueryInfo, pRes);
|
||||
pRes->row = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
|
||||
|
||||
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||
|
|
|
@ -141,7 +141,7 @@ static void syncConnCallback(void *param, TAOS_RES *tres, int code) {
|
|||
SSqlObj *pSql = (SSqlObj *) tres;
|
||||
assert(pSql != NULL);
|
||||
|
||||
sem_post(&pSql->rspSem);
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
|
||||
|
@ -156,7 +156,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
pSql->param = pSql;
|
||||
|
||||
tscProcessSql(pSql);
|
||||
sem_wait(&pSql->rspSem);
|
||||
tsem_wait(&pSql->rspSem);
|
||||
|
||||
if (pSql->res.code != TSDB_CODE_SUCCESS) {
|
||||
terrno = pSql->res.code;
|
||||
|
@ -181,6 +181,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TAOS *taos_connect_c(const char *ip, uint8_t ipLen, const char *user, uint8_t userLen,
|
||||
const char *pass, uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port) {
|
||||
char ipBuf[TSDB_EP_LEN] = {0};
|
||||
|
@ -215,53 +216,29 @@ void taos_close(TAOS *taos) {
|
|||
}
|
||||
|
||||
if (pObj->pHb != NULL) {
|
||||
if (pObj->pHb->pRpcCtx != NULL) { // wait for rsp from dnode
|
||||
rpcCancelRequest(pObj->pHb->pRpcCtx);
|
||||
}
|
||||
|
||||
tscSetFreeHeatBeat(pObj);
|
||||
} else {
|
||||
tscCloseTscObj(pObj);
|
||||
tscFreeSqlObj(pObj->pHb);
|
||||
}
|
||||
|
||||
tscCloseTscObj(pObj);
|
||||
}
|
||||
|
||||
void waitForQueryRsp(void *param, TAOS_RES *tres, int code) {
|
||||
assert(tres != NULL);
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *) tres;
|
||||
sem_post(&pSql->rspSem);
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) {
|
||||
SSqlObj* pSql = (SSqlObj*) tres;
|
||||
sem_post(&pSql->rspSem);
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t sqlLen = (int32_t)strlen(sqlstr);
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
|
||||
terrno = TSDB_CODE_TSC_INVALID_SQL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
taosNotePrintTsc(sqlstr);
|
||||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
tscError("failed to malloc sqlObj");
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
||||
|
||||
// wait for the callback function to post the semaphore
|
||||
tsem_wait(&pSql->rspSem);
|
||||
return pSql;
|
||||
}
|
||||
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
|
@ -274,7 +251,9 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
|
|||
terrno = TSDB_CODE_TSC_INVALID_SQL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
taosNotePrintTsc(sqlstr);
|
||||
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
tscError("failed to malloc sqlObj");
|
||||
|
@ -282,11 +261,17 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tsem_init(&pSql->rspSem, 0, 0);
|
||||
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
|
||||
|
||||
tsem_wait(&pSql->rspSem);
|
||||
return pSql;
|
||||
}
|
||||
|
||||
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
|
||||
return taos_query_c(taos, sqlstr, (uint32_t)strlen(sqlstr));
|
||||
}
|
||||
|
||||
int taos_result_precision(TAOS_RES *res) {
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
@ -422,7 +407,10 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
pCmd->command == TSDB_SQL_INSERT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// set the sql object owner
|
||||
tscSetSqlOwner(pSql);
|
||||
|
||||
// current data set are exhausted, fetch more data from node
|
||||
if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
|
||||
(pCmd->command == TSDB_SQL_RETRIEVE ||
|
||||
|
@ -438,10 +426,13 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
pCmd->command == TSDB_SQL_CLI_VERSION ||
|
||||
pCmd->command == TSDB_SQL_CURRENT_USER )) {
|
||||
taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj);
|
||||
sem_wait(&pSql->rspSem);
|
||||
tsem_wait(&pSql->rspSem);
|
||||
}
|
||||
|
||||
return doSetResultRowData(pSql, true);
|
||||
void* data = doSetResultRowData(pSql, true);
|
||||
|
||||
tscClearSqlOwner(pSql);
|
||||
return data;
|
||||
}
|
||||
|
||||
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
||||
|
@ -509,7 +500,7 @@ int taos_select_db(TAOS *taos, const char *db) {
|
|||
}
|
||||
|
||||
// send free message to vnode to free qhandle and corresponding resources in vnode
|
||||
static bool tscFreeQhandleInVnode(SSqlObj* pSql) {
|
||||
static bool tscKillQueryInVnode(SSqlObj* pSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
|
@ -557,16 +548,14 @@ void taos_free_result(TAOS_RES *res) {
|
|||
}
|
||||
|
||||
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
||||
if (!tscFreeQhandleInVnode(pSql)) {
|
||||
if (!tscKillQueryInVnode(pSql)) {
|
||||
tscFreeSqlObj(pSql);
|
||||
tscDebug("%p sqlObj is freed by app", pSql);
|
||||
}
|
||||
}
|
||||
|
||||
// todo should not be used in async query
|
||||
int taos_errno(TAOS_RES *tres) {
|
||||
SSqlObj *pSql = (SSqlObj *) tres;
|
||||
|
||||
if (pSql == NULL || pSql->signature != pSql) {
|
||||
return terrno;
|
||||
}
|
||||
|
@ -728,7 +717,7 @@ static void asyncCallback(void *param, TAOS_RES *tres, int code) {
|
|||
assert(param != NULL);
|
||||
SSqlObj *pSql = ((SSqlObj *)param);
|
||||
pSql->res.code = code;
|
||||
sem_post(&pSql->rspSem);
|
||||
tsem_post(&pSql->rspSem);
|
||||
}
|
||||
|
||||
int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||
|
@ -779,7 +768,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
pSql->param = pSql;
|
||||
int code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
sem_wait(&pSql->rspSem);
|
||||
tsem_wait(&pSql->rspSem);
|
||||
code = pSql->res.code;
|
||||
}
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -812,7 +801,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t
|
|||
}
|
||||
|
||||
char *nextStr;
|
||||
char tblName[TSDB_TABLE_ID_LEN];
|
||||
char tblName[TSDB_TABLE_FNAME_LEN];
|
||||
int payloadLen = 0;
|
||||
char *pMsg = pCmd->payload;
|
||||
while (1) {
|
||||
|
|
|
@ -135,6 +135,14 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
|||
etime = pStream->stime + (etime - pStream->stime) / pStream->interval * pStream->interval;
|
||||
}
|
||||
pQueryInfo->window.ekey = etime;
|
||||
if (pQueryInfo->window.skey >= pQueryInfo->window.ekey) {
|
||||
int64_t timer = pStream->slidingTime;
|
||||
if (pStream->precision == TSDB_TIME_PRECISION_MICRO) {
|
||||
timer /= 1000l;
|
||||
}
|
||||
tscSetRetryTimer(pStream, pSql, timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// launch stream computing in a new thread
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct SSubscriptionProgress {
|
|||
typedef struct SSub {
|
||||
void * signature;
|
||||
char topic[32];
|
||||
sem_t sem;
|
||||
tsem_t sem;
|
||||
int64_t lastSyncTime;
|
||||
int64_t lastConsumeTime;
|
||||
TAOS * taos;
|
||||
|
@ -85,7 +85,7 @@ static void asyncCallback(void *param, TAOS_RES *tres, int code) {
|
|||
assert(param != NULL);
|
||||
SSub *pSub = ((SSub *)param);
|
||||
pSub->pSql->res.code = code;
|
||||
sem_post(&pSub->sem);
|
||||
tsem_post(&pSub->sem);
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,7 +154,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
|
||||
code = tsParseSql(pSql, false);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
sem_wait(&pSub->sem);
|
||||
tsem_wait(&pSub->sem);
|
||||
code = pSql->res.code;
|
||||
}
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -339,7 +339,7 @@ static int tscLoadSubscriptionProgress(SSub* pSub) {
|
|||
fclose(fp);
|
||||
|
||||
taosArraySort(progress, tscCompareSubscriptionProgress);
|
||||
tscDebug("subscription progress loaded, %zu tables: %s", taosArrayGetSize(progress), pSub->topic);
|
||||
tscDebug("subscription progress loaded, %" PRIzu " tables: %s", taosArrayGetSize(progress), pSub->topic);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -405,16 +405,20 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
|||
return pSub;
|
||||
}
|
||||
|
||||
void taos_free_result_imp(SSqlObj* pSql, int keepCmd);
|
||||
|
||||
TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||
SSub *pSub = (SSub *)tsub;
|
||||
if (pSub == NULL) return NULL;
|
||||
|
||||
tscSaveSubscriptionProgress(pSub);
|
||||
|
||||
SSqlObj* pSql = pSub->pSql;
|
||||
SSqlObj *pSql = pSub->pSql;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single tabel subscription
|
||||
pQueryInfo->window.skey = ((SSubscriptionProgress*)taosArrayGet(pSub->progress, 0))->key;
|
||||
}
|
||||
|
||||
if (pSub->pTimer == NULL) {
|
||||
int64_t duration = taosGetTimestampMs() - pSub->lastConsumeTime;
|
||||
|
@ -436,8 +440,6 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
tscDebug("table synchronization completed");
|
||||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
|
||||
uint32_t type = pQueryInfo->type;
|
||||
tscFreeSqlResult(pSql);
|
||||
pRes->numOfRows = 1;
|
||||
|
@ -445,13 +447,13 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
pQueryInfo->type = type;
|
||||
|
||||
tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->vgroupIndex = 0;
|
||||
pTableMetaInfo->vgroupIndex = 0;
|
||||
|
||||
pSql->fp = asyncCallback;
|
||||
pSql->fetchFp = asyncCallback;
|
||||
pSql->param = pSub;
|
||||
tscDoQuery(pSql);
|
||||
sem_wait(&pSub->sem);
|
||||
tsem_wait(&pSub->sem);
|
||||
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
continue;
|
||||
|
|
|
@ -362,7 +362,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList);
|
||||
tscDebug("%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%zu, colList:%zu, fieldsInfo:%d, name:%s",
|
||||
tscDebug("%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s",
|
||||
pSql, pNew, 0, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, taosArrayGetSize(pNewQueryInfo->exprList),
|
||||
numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, pTableMetaInfo->name);
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ static void issueTSCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj*
|
|||
|
||||
tscDebug(
|
||||
"%p subquery:%p tableIndex:%d, vgroupIndex:%d, numOfVgroups:%d, type:%d, ts_comp query to retrieve timestamps, "
|
||||
"numOfExpr:%zu, colList:%zu, numOfOutputFields:%d, name:%s",
|
||||
"numOfExpr:%" PRIzu ", colList:%" PRIzu ", numOfOutputFields:%d, name:%s",
|
||||
pParent, pSql, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pQueryInfo->type,
|
||||
tscSqlExprNumOfExprs(pQueryInfo), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, pTableMetaInfo->name);
|
||||
|
||||
|
@ -1026,9 +1026,11 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * pQueryInfo->fieldsInfo.numOfOutput);
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||
int32_t numOfExprs = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
|
||||
pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs);
|
||||
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
int32_t tableIndexOfSub = -1;
|
||||
|
@ -1045,8 +1047,8 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
|
|||
SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd;
|
||||
SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0);
|
||||
|
||||
size_t numOfExprs = taosArrayGetSize(pSubQueryInfo->exprList);
|
||||
for (int32_t k = 0; k < numOfExprs; ++k) {
|
||||
size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList);
|
||||
for (int32_t k = 0; k < numOfSubExpr; ++k) {
|
||||
SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k);
|
||||
if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) {
|
||||
pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k};
|
||||
|
@ -1054,6 +1056,10 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore the offset value for super table query in case of final result.
|
||||
tscRestoreSQLFuncForSTableQuery(pQueryInfo);
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
}
|
||||
|
||||
void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||
|
@ -1079,7 +1085,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) {
|
||||
assert(taos_errno(pSql) == code);
|
||||
|
||||
tscError("%p abort query, code:%d, global code:%d", pSql, code, pParentSql->res.code);
|
||||
tscError("%p abort query, code:%s, global code:%s", pSql, tstrerror(code), tstrerror(pParentSql->res.code));
|
||||
pParentSql->res.code = code;
|
||||
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
|
@ -1225,7 +1231,7 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
|||
|
||||
tscDebug(
|
||||
"%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, transfer to tid_tag query to retrieve (tableId, tags), "
|
||||
"exprInfo:%zu, colList:%zu, fieldsInfo:%d, tagIndex:%d, name:%s",
|
||||
"exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, tagIndex:%d, name:%s",
|
||||
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
||||
numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, index.columnIndex, pNewQueryInfo->pTableMetaInfo[0]->name);
|
||||
} else {
|
||||
|
@ -1260,7 +1266,7 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
|
|||
|
||||
tscDebug(
|
||||
"%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%u, transfer to ts_comp query to retrieve timestamps, "
|
||||
"exprInfo:%zu, colList:%zu, fieldsInfo:%d, name:%s",
|
||||
"exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s",
|
||||
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
||||
numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, pNewQueryInfo->pTableMetaInfo[0]->name);
|
||||
}
|
||||
|
@ -1915,7 +1921,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
|
|||
pSql->pSubs = calloc(size, POINTER_BYTES);
|
||||
pSql->numOfSubs = (uint16_t)size;
|
||||
|
||||
tscDebug("%p submit data to %zu vnode(s)", pSql, size);
|
||||
tscDebug("%p submit data to %" PRIzu " vnode(s)", pSql, size);
|
||||
|
||||
SSubqueryState *pState = calloc(1, sizeof(SSubqueryState));
|
||||
pState->numOfTotal = pSql->numOfSubs;
|
||||
|
@ -1949,7 +1955,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
|
|||
tscDebug("%p sub:%p create subObj success. orderOfSub:%d", pSql, pNew, numOfSub);
|
||||
numOfSub++;
|
||||
} else {
|
||||
tscDebug("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%zu, code:%s", pSql, numOfSub,
|
||||
tscDebug("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%" PRIzu ", code:%s", pSql, numOfSub,
|
||||
size, tstrerror(pRes->code));
|
||||
goto _error;
|
||||
}
|
||||
|
@ -2052,12 +2058,10 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
while (1) {
|
||||
if (pRes->row < pRes->numOfRows) {
|
||||
assert(0);
|
||||
}
|
||||
assert (pRes->row >= pRes->numOfRows);
|
||||
|
||||
doBuildResFromSubqueries(pSql);
|
||||
sem_post(&pSql->rspSem);
|
||||
tsem_post(&pSql->rspSem);
|
||||
|
||||
return;
|
||||
|
||||
|
@ -2083,7 +2087,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
// free(pState);
|
||||
//
|
||||
// pRes->completed = true; // set query completed
|
||||
// sem_post(&pSql->rspSem);
|
||||
// tsem_post(&pSql->rspSem);
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
|||
void taos_cleanup() {
|
||||
if (tscCacheHandle != NULL) {
|
||||
taosCacheCleanup(tscCacheHandle);
|
||||
tscCacheHandle = NULL;
|
||||
}
|
||||
|
||||
if (tscQhandle != NULL) {
|
||||
|
|
|
@ -387,7 +387,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
pCmd->allocSize = 0;
|
||||
|
||||
taosTFree(pSql->sqlstr);
|
||||
sem_destroy(&pSql->rspSem);
|
||||
tsem_destroy(&pSql->rspSem);
|
||||
free(pSql);
|
||||
}
|
||||
|
||||
|
@ -644,7 +644,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) {
|
|||
STableDataBlocks* pOneTableBlock = taosArrayGetP(pTableDataBlockList, 0);
|
||||
int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta);
|
||||
|
||||
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false);
|
||||
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
|
||||
|
||||
size_t total = taosArrayGetSize(pTableDataBlockList);
|
||||
|
@ -858,12 +858,13 @@ void tscFieldInfoCopy(SFieldInfo* dst, const SFieldInfo* src) {
|
|||
}
|
||||
|
||||
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
|
||||
assert(index < pFieldInfo->numOfOutput);
|
||||
return TARRAY_GET_ELEM(pFieldInfo->pFields, index);
|
||||
}
|
||||
|
||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index);
|
||||
assert(pInfo != NULL);
|
||||
assert(pInfo != NULL && pInfo->pSqlExpr != NULL);
|
||||
|
||||
return pInfo->pSqlExpr->offset;
|
||||
}
|
||||
|
@ -1393,7 +1394,7 @@ void tscSetFreeHeatBeat(STscObj* pObj) {
|
|||
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
||||
}
|
||||
|
||||
bool tscShouldFreeHeatBeat(SSqlObj* pHb) {
|
||||
bool tscShouldFreeHeartBeat(SSqlObj* pHb) {
|
||||
assert(pHb == pHb->signature);
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHb->cmd, 0);
|
||||
|
@ -1680,6 +1681,77 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
|
|||
return pNew;
|
||||
}
|
||||
|
||||
// current sql function is not direct output result, so create a dummy output field
|
||||
static void doSetNewFieldInfo(SQueryInfo* pNewQueryInfo, SSqlExpr* pExpr) {
|
||||
TAOS_FIELD f = {.type = (uint8_t)pExpr->resType, .bytes = pExpr->resBytes};
|
||||
tstrncpy(f.name, pExpr->aliasName, sizeof(f.name));
|
||||
|
||||
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f);
|
||||
|
||||
pInfo1->pSqlExpr = pExpr;
|
||||
pInfo1->visible = false;
|
||||
}
|
||||
|
||||
static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pQueryInfo, SQueryInfo* pNewQueryInfo, int64_t uid) {
|
||||
int32_t numOfOutput = (int32_t)tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||
if (numOfOutput == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
|
||||
// set the field info in pNewQueryInfo object
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
if (pExpr->uid == uid) {
|
||||
if (i < pFieldInfo->numOfOutput) {
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
|
||||
|
||||
if (pInfo->pSqlExpr != NULL) {
|
||||
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
|
||||
assert(strcmp(p->name, pExpr->aliasName) == 0);
|
||||
|
||||
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
|
||||
*pInfo1 = *pInfo;
|
||||
} else {
|
||||
assert(pInfo->pArithExprInfo != NULL);
|
||||
doSetNewFieldInfo(pNewQueryInfo, pExpr);
|
||||
}
|
||||
} else { // it is a arithmetic column, does not have actual field for sqlExpr, so build it
|
||||
doSetNewFieldInfo(pNewQueryInfo, pExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the the sqlExpr for each fields is correct
|
||||
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||
|
||||
// update the pSqlExpr pointer in SFieldSupInfo according the field name
|
||||
// make sure the pSqlExpr point to the correct SqlExpr in pNewQueryInfo, not SqlExpr in pQueryInfo
|
||||
for (int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
|
||||
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
|
||||
|
||||
bool matched = false;
|
||||
for (int32_t k1 = 0; k1 < numOfExprs; ++k1) {
|
||||
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
|
||||
|
||||
if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
|
||||
pInfo->pSqlExpr = pExpr1;
|
||||
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(matched);
|
||||
}
|
||||
|
||||
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
||||
}
|
||||
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
|
||||
|
@ -1773,49 +1845,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||
tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true);
|
||||
|
||||
int32_t numOfOutput = (int32_t)tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||
|
||||
if (numOfOutput > 0) { // todo refactor to extract method
|
||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
if (pExpr->uid == uid) {
|
||||
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
|
||||
|
||||
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
|
||||
*pInfo1 = *pInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the the sqlExpr for each fields is correct
|
||||
// todo handle the agg arithmetic expression
|
||||
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||
|
||||
for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
|
||||
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
|
||||
bool matched = false;
|
||||
|
||||
for(int32_t k1 = 0; k1 < numOfExprs; ++k1) {
|
||||
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
|
||||
|
||||
if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
|
||||
pInfo->pSqlExpr = pExpr1;
|
||||
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(matched);
|
||||
}
|
||||
|
||||
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
||||
}
|
||||
doSetSqlExprAndResultFieldInfo(pQueryInfo, pNewQueryInfo, uid);
|
||||
|
||||
pNew->fp = fp;
|
||||
pNew->fetchFp = fp;
|
||||
|
@ -1864,7 +1894,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
size_t size = taosArrayGetSize(pNewQueryInfo->colList);
|
||||
|
||||
tscDebug(
|
||||
"%p new subquery:%p, tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%zu, colList:%zu,"
|
||||
"%p new subquery:%p, tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ","
|
||||
"fieldInfo:%d, name:%s, qrang:%" PRId64 " - %" PRId64 " order:%d, limit:%" PRId64,
|
||||
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
||||
size, pNewQueryInfo->fieldsInfo.numOfOutput, pFinalInfo->name, pNewQueryInfo->window.skey,
|
||||
|
@ -2013,6 +2043,10 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
int32_t numOfVgroups = pTableMetaInfo->vgroupList->numOfVgroups;
|
||||
if (pTableMetaInfo->pVgroupTables != NULL) {
|
||||
numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
|
||||
}
|
||||
|
||||
return tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
|
||||
(!tscHasReachLimitation(pQueryInfo, pRes)) && (pTableMetaInfo->vgroupIndex < numOfVgroups - 1);
|
||||
}
|
||||
|
@ -2107,43 +2141,6 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) {
|
|||
}
|
||||
}
|
||||
|
||||
//void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex) {
|
||||
// SFieldSupInfo* pInfo = TARRAY_GET_ELEM(pFieldInfo->pSupportInfo, columnIndex);
|
||||
// assert(pInfo->pSqlExpr != NULL);
|
||||
//
|
||||
// int32_t type = pInfo->pSqlExpr->resType;
|
||||
// int32_t bytes = pInfo->pSqlExpr->resBytes;
|
||||
//
|
||||
// char* pData = pRes->data + pInfo->pSqlExpr->offset * pRes->numOfRows + bytes * pRes->row;
|
||||
//
|
||||
// if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) {
|
||||
// int32_t realLen = varDataLen(pData);
|
||||
// assert(realLen <= bytes - VARSTR_HEADER_SIZE);
|
||||
//
|
||||
// if (isNull(pData, type)) {
|
||||
// pRes->tsrow[columnIndex] = NULL;
|
||||
// } else {
|
||||
// pRes->tsrow[columnIndex] = ((tstr*)pData)->data;
|
||||
// }
|
||||
//
|
||||
// if (realLen < pInfo->pSqlExpr->resBytes - VARSTR_HEADER_SIZE) { // todo refactor
|
||||
// *(pData + realLen + VARSTR_HEADER_SIZE) = 0;
|
||||
// }
|
||||
//
|
||||
// pRes->length[columnIndex] = realLen;
|
||||
// } else {
|
||||
// assert(bytes == tDataTypeDesc[type].nSize);
|
||||
//
|
||||
// if (isNull(pData, type)) {
|
||||
// pRes->tsrow[columnIndex] = NULL;
|
||||
// } else {
|
||||
// pRes->tsrow[columnIndex] = pData;
|
||||
// }
|
||||
//
|
||||
// pRes->length[columnIndex] = bytes;
|
||||
// }
|
||||
//}
|
||||
|
||||
void* malloc_throw(size_t size) {
|
||||
void* p = malloc(size);
|
||||
if (p == NULL) {
|
||||
|
@ -2200,3 +2197,21 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql) {
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
// set the sql object owner
|
||||
uint64_t threadId = taosGetPthreadId();
|
||||
if (atomic_val_compare_exchange_64(&pSql->owner, 0, threadId) != 0) {
|
||||
pRes->code = TSDB_CODE_QRY_IN_EXEC;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tscClearSqlOwner(SSqlObj* pSql) {
|
||||
assert(taosCheckPthreadValid(pSql->owner));
|
||||
atomic_store_64(&pSql->owner, 0);
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "tdataformat.h"
|
||||
#include "tulog.h"
|
||||
#include "talgo.h"
|
||||
#include "tcoding.h"
|
||||
#include "wchar.h"
|
||||
|
@ -311,10 +312,14 @@ void dataColSetOffset(SDataCol *pCol, int nEle) {
|
|||
|
||||
SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
|
||||
SDataCols *pCols = (SDataCols *)calloc(1, sizeof(SDataCols));
|
||||
if (pCols == NULL) return NULL;
|
||||
if (pCols == NULL) {
|
||||
uDebug("malloc failure, size:%"PRId64" failed, reason:%s", sizeof(SDataCols), strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pCols->cols = (SDataCol *)calloc(maxCols, sizeof(SDataCol));
|
||||
if (pCols->cols == NULL) {
|
||||
uDebug("malloc failure, size:%"PRId64" failed, reason:%s", sizeof(SDataCol) * maxCols, strerror(errno));
|
||||
tdFreeDataCols(pCols);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -326,6 +331,7 @@ SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
|
|||
|
||||
pCols->buf = malloc(pCols->bufSize);
|
||||
if (pCols->buf == NULL) {
|
||||
uDebug("malloc failure, size:%"PRId64" failed, reason:%s", sizeof(SDataCol) * maxCols, strerror(errno));
|
||||
tdFreeDataCols(pCols);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ int8_t tsDaylight = 0;
|
|||
char tsTimezone[TSDB_TIMEZONE_LEN] = {0};
|
||||
char tsLocale[TSDB_LOCALE_LEN] = {0};
|
||||
char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string
|
||||
int32_t tsEnableCoreFile = 0;
|
||||
int32_t tsEnableCoreFile = 1;
|
||||
int32_t tsMaxBinaryDisplayWidth = 30;
|
||||
|
||||
/*
|
||||
|
@ -1315,6 +1315,7 @@ bool taosCheckGlobalCfg() {
|
|||
tsDnodeShellPort = tsServerPort + TSDB_PORT_DNODESHELL; // udp[6035-6039] tcp[6035]
|
||||
tsDnodeDnodePort = tsServerPort + TSDB_PORT_DNODEDNODE; // udp/tcp
|
||||
tsSyncPort = tsServerPort + TSDB_PORT_SYNC;
|
||||
tsHttpPort = tsServerPort + TSDB_PORT_HTTP;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ void tsSetTimeZone() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
int32_t tz = (-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR;
|
||||
int32_t tz = (int32_t)((-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR);
|
||||
tz += daylight;
|
||||
|
||||
/*
|
||||
|
|
|
@ -84,12 +84,17 @@ public class TSDBConnection implements Connection {
|
|||
}
|
||||
}
|
||||
|
||||
public TSDBSubscribe createSubscribe() throws SQLException {
|
||||
if (!this.connector.isClosed()) {
|
||||
return new TSDBSubscribe(this.connector);
|
||||
} else {
|
||||
public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException {
|
||||
if (this.connector.isClosed()) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
|
||||
long id = this.connector.subscribe(topic, sql, restart, 0);
|
||||
if (id == 0) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("failed to create subscription"));
|
||||
}
|
||||
|
||||
return new TSDBSubscribe(this.connector, id);
|
||||
}
|
||||
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||
|
|
|
@ -254,29 +254,29 @@ public class TSDBJNIConnector {
|
|||
private native int closeConnectionImp(long connection);
|
||||
|
||||
/**
|
||||
* Subscribe to a table in TSDB
|
||||
* Create a subscription
|
||||
*/
|
||||
public long subscribe(String topic, String sql, boolean restart, int period) {
|
||||
long subscribe(String topic, String sql, boolean restart, int period) {
|
||||
return subscribeImp(this.taos, restart, topic, sql, period);
|
||||
}
|
||||
|
||||
public native long subscribeImp(long connection, boolean restart, String topic, String sql, int period);
|
||||
private native long subscribeImp(long connection, boolean restart, String topic, String sql, int period);
|
||||
|
||||
/**
|
||||
* Consume a subscribed table
|
||||
* Consume a subscription
|
||||
*/
|
||||
public long consume(long subscription) {
|
||||
return this.consumeImp(subscription);
|
||||
long consume(long subscription) {
|
||||
return this.consumeImp(subscription);
|
||||
}
|
||||
|
||||
private native long consumeImp(long subscription);
|
||||
|
||||
/**
|
||||
* Unsubscribe a table
|
||||
* Unsubscribe, close a subscription
|
||||
*
|
||||
* @param subscription
|
||||
*/
|
||||
public void unsubscribe(long subscription, boolean isKeep) {
|
||||
void unsubscribe(long subscription, boolean isKeep) {
|
||||
unsubscribeImp(subscription, isKeep);
|
||||
}
|
||||
|
||||
|
|
|
@ -158,9 +158,9 @@ public class TSDBStatement implements Statement {
|
|||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
} else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) {
|
||||
// no result set is retrieved
|
||||
this.connecter.freeResultSet(pSql);
|
||||
res = false;
|
||||
}
|
||||
this.connecter.freeResultSet(pSql);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -22,81 +22,28 @@ import java.util.concurrent.*;
|
|||
|
||||
public class TSDBSubscribe {
|
||||
private TSDBJNIConnector connecter = null;
|
||||
private static ScheduledExecutorService pool;
|
||||
private static Map<Long, TSDBTimerTask> timerTaskMap = new ConcurrentHashMap<>();
|
||||
private static Map<Long, ScheduledFuture> scheduledMap = new ConcurrentHashMap();
|
||||
private long id = 0;
|
||||
|
||||
private static class TimerInstance {
|
||||
private static final ScheduledExecutorService instance = Executors.newScheduledThreadPool(1);
|
||||
}
|
||||
|
||||
public static ScheduledExecutorService getTimerInstance() {
|
||||
return TimerInstance.instance;
|
||||
}
|
||||
|
||||
public TSDBSubscribe(TSDBJNIConnector connecter) throws SQLException {
|
||||
TSDBSubscribe(TSDBJNIConnector connecter, long id) throws SQLException {
|
||||
if (null != connecter) {
|
||||
this.connecter = connecter;
|
||||
this.id = id;
|
||||
} else {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sync subscribe
|
||||
* consume
|
||||
*
|
||||
* @param topic
|
||||
* @param sql
|
||||
* @param restart
|
||||
* @param period
|
||||
* @throws SQLException
|
||||
* @throws OperationsException, SQLException
|
||||
*/
|
||||
public long subscribe(String topic, String sql, boolean restart, int period) throws SQLException {
|
||||
public TSDBResultSet consume() throws OperationsException, SQLException {
|
||||
if (this.connecter.isClosed()) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
if (period < 1000) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg(TSDBConstants.INVALID_VARIABLES));
|
||||
}
|
||||
return this.connecter.subscribe(topic, sql, restart, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* async subscribe
|
||||
*
|
||||
* @param topic
|
||||
* @param sql
|
||||
* @param restart
|
||||
* @param period
|
||||
* @param callBack
|
||||
* @throws SQLException
|
||||
*/
|
||||
public long subscribe(String topic, String sql, boolean restart, int period, TSDBSubscribeCallBack callBack) throws SQLException {
|
||||
if (this.connecter.isClosed()) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
final long subscription = this.connecter.subscribe(topic, sql, restart, period);
|
||||
if (null != callBack) {
|
||||
pool = getTimerInstance();
|
||||
|
||||
TSDBTimerTask timerTask = new TSDBTimerTask(subscription, callBack);
|
||||
|
||||
timerTaskMap.put(subscription, timerTask);
|
||||
|
||||
ScheduledFuture scheduledFuture = pool.scheduleAtFixedRate(timerTask, 1, 1000, TimeUnit.MILLISECONDS);
|
||||
scheduledMap.put(subscription, scheduledFuture);
|
||||
}
|
||||
return subscription;
|
||||
}
|
||||
|
||||
public TSDBResultSet consume(long subscription) throws OperationsException, SQLException {
|
||||
if (this.connecter.isClosed()) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
if (0 == subscription) {
|
||||
throw new OperationsException("Invalid use of consume");
|
||||
}
|
||||
long resultSetPointer = this.connecter.consume(subscription);
|
||||
long resultSetPointer = this.connecter.consume(this.id);
|
||||
|
||||
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
|
@ -108,77 +55,16 @@ public class TSDBSubscribe {
|
|||
}
|
||||
|
||||
/**
|
||||
* cancel subscribe
|
||||
* close subscription
|
||||
*
|
||||
* @param subscription
|
||||
* @param isKeep
|
||||
* @param keepProgress
|
||||
* @throws SQLException
|
||||
*/
|
||||
public void unsubscribe(long subscription, boolean isKeep) throws SQLException {
|
||||
public void close(boolean keepProgress) throws SQLException {
|
||||
if (this.connecter.isClosed()) {
|
||||
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
|
||||
}
|
||||
|
||||
if (null != timerTaskMap.get(subscription)) {
|
||||
synchronized (timerTaskMap.get(subscription)) {
|
||||
while (1 == timerTaskMap.get(subscription).getState()) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
timerTaskMap.get(subscription).setState(2);
|
||||
if (!timerTaskMap.isEmpty() && timerTaskMap.containsKey(subscription)) {
|
||||
timerTaskMap.get(subscription).cancel();
|
||||
timerTaskMap.remove(subscription);
|
||||
scheduledMap.get(subscription).cancel(false);
|
||||
scheduledMap.remove(subscription);
|
||||
}
|
||||
this.connecter.unsubscribe(subscription, isKeep);
|
||||
}
|
||||
} else {
|
||||
this.connecter.unsubscribe(subscription, isKeep);
|
||||
}
|
||||
}
|
||||
|
||||
class TSDBTimerTask extends TimerTask {
|
||||
private long subscription;
|
||||
private TSDBSubscribeCallBack callBack;
|
||||
// 0: not running 1: running 2: cancel
|
||||
private int state = 0;
|
||||
|
||||
public TSDBTimerTask(long subscription, TSDBSubscribeCallBack callBack) {
|
||||
this.subscription = subscription;
|
||||
this.callBack = callBack;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void setState(int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
if (2 == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = 1;
|
||||
|
||||
try {
|
||||
callBack.invoke(consume(subscription));
|
||||
} catch (Exception e) {
|
||||
this.cancel();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
this.connecter.unsubscribe(this.id, keepProgress);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import com.taosdata.jdbc.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TestAsyncTSDBSubscribe {
|
||||
public static void main(String[] args) throws SQLException {
|
||||
String usage = "java -cp taos-jdbcdriver-2.0.0_dev-dist.jar com.taosdata.jdbc.TSDBSubscribe -db dbName -topic topicName " +
|
||||
"-tname tableName -h host";
|
||||
if (args.length < 2) {
|
||||
System.err.println(usage);
|
||||
return;
|
||||
}
|
||||
|
||||
String dbName = "";
|
||||
String tName = "";
|
||||
String host = "localhost";
|
||||
String topic = "";
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-db".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
dbName = args[++i];
|
||||
}
|
||||
if ("-tname".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
tName = args[++i];
|
||||
}
|
||||
if ("-h".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
if ("-topic".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
topic = args[++i];
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(dbName) || StringUtils.isEmpty(tName) || StringUtils.isEmpty(topic)) {
|
||||
System.err.println(usage);
|
||||
return;
|
||||
}
|
||||
|
||||
Connection connection = null;
|
||||
long subscribId = 0;
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + dbName + "?user=root&password=taosdata", properties);
|
||||
String rawSql = "select * from " + tName + ";";
|
||||
TSDBSubscribe subscribe = ((TSDBConnection) connection).createSubscribe();
|
||||
subscribId = subscribe.subscribe(topic, rawSql, false, 1000, new CallBack("first"));
|
||||
long subscribId2 = subscribe.subscribe("test", rawSql, false, 1000, new CallBack("second"));
|
||||
int a = 0;
|
||||
Thread.sleep(2000);
|
||||
subscribe.unsubscribe(subscribId, true);
|
||||
System.err.println("cancel subscribe");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (null != connection && !connection.isClosed()) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CallBack implements TSDBSubscribeCallBack {
|
||||
private String name = "";
|
||||
|
||||
public CallBack(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(TSDBResultSet resultSet) {
|
||||
try {
|
||||
while (null !=resultSet && resultSet.next()) {
|
||||
System.out.print("callback_" + name + ": ");
|
||||
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
|
||||
System.out.printf(i + ": " + resultSet.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,82 +2,76 @@ import com.taosdata.jdbc.TSDBConnection;
|
|||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.TSDBResultSet;
|
||||
import com.taosdata.jdbc.TSDBSubscribe;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TestTSDBSubscribe {
|
||||
|
||||
public static TSDBConnection connectTDengine(String host, String database) throws Exception {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
|
||||
String cs = String.format("jdbc:TAOS://%s:0/%s?user=root&password=taosdata", host, database);
|
||||
return (TSDBConnection)DriverManager.getConnection(cs, properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String usage = "java -cp taos-jdbcdriver-2.0.0_dev-dist.jar com.taosdata.jdbc.TSDBSubscribe -db dbName " +
|
||||
"-topic topicName -tname tableName -h host";
|
||||
String usage = "java -Djava.ext.dirs=../ TestTSDBSubscribe [-host host] <-db database> <-topic topic> <-sql sql>";
|
||||
if (args.length < 2) {
|
||||
System.err.println(usage);
|
||||
return;
|
||||
}
|
||||
|
||||
String dbName = "";
|
||||
String tName = "";
|
||||
String host = "localhost";
|
||||
String topic = "";
|
||||
String host = "localhost", database = "", topic = "", sql = "";
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-db".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
dbName = args[++i];
|
||||
}
|
||||
if ("-tname".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
tName = args[++i];
|
||||
}
|
||||
if ("-h".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
database = args[++i];
|
||||
}
|
||||
if ("-topic".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
topic = args[++i];
|
||||
}
|
||||
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
if ("-sql".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
sql = args[++i];
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(dbName) || StringUtils.isEmpty(tName) || StringUtils.isEmpty(topic)) {
|
||||
System.err.println(usage);
|
||||
return;
|
||||
if (database.isEmpty() || topic.isEmpty() || sql.isEmpty()) {
|
||||
System.err.println(usage);
|
||||
return;
|
||||
}
|
||||
|
||||
Connection connection = null;
|
||||
TSDBSubscribe subscribe = null;
|
||||
long subscribId = 0;
|
||||
TSDBConnection connection = null;
|
||||
TSDBSubscribe sub = null;
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + dbName + "?user=root&password=taosdata"
|
||||
, properties);
|
||||
String rawSql = "select * from " + tName + ";";
|
||||
subscribe = ((TSDBConnection) connection).createSubscribe();
|
||||
subscribId = subscribe.subscribe(topic, rawSql, false, 1000);
|
||||
int a = 0;
|
||||
TSDBResultSet resSet = null;
|
||||
while (true) {
|
||||
connection = connectTDengine(host, database);
|
||||
sub = ((TSDBConnection) connection).subscribe(topic, sql, false);
|
||||
|
||||
int total = 0;
|
||||
while(true) {
|
||||
TSDBResultSet rs = sub.consume();
|
||||
int count = 0;
|
||||
while(rs.next()) {
|
||||
count++;
|
||||
}
|
||||
total += count;
|
||||
System.out.printf("%d rows consumed, total %d\n", count, total);
|
||||
Thread.sleep(900);
|
||||
resSet = subscribe.consume(subscribId);
|
||||
|
||||
while (resSet.next()) {
|
||||
for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) {
|
||||
System.out.printf(i + ": " + resSet.getString(i) + "\t");
|
||||
}
|
||||
System.out.println("\n======" + a + "==========");
|
||||
}
|
||||
|
||||
a++;
|
||||
if (a >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (null != subscribe && 0 != subscribId) {
|
||||
subscribe.unsubscribe(subscribId, true);
|
||||
if (null != sub) {
|
||||
sub.close(true);
|
||||
}
|
||||
if (null != connection) {
|
||||
connection.close();
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
package com.taosdata.jdbc;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AsyncSubscribeTest extends BaseTest {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
String dbName = "test";
|
||||
String tName = "t0";
|
||||
String host = "localhost";
|
||||
String topic = "test";
|
||||
long subscribId = 0;
|
||||
|
||||
@Before
|
||||
public void createDatabase() throws SQLException {
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/" + "?user=root&password=taosdata"
|
||||
, properties);
|
||||
|
||||
statement = connection.createStatement();
|
||||
statement.executeUpdate("create database if not exists " + dbName);
|
||||
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
|
||||
long ts = System.currentTimeMillis();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ts += i;
|
||||
String sql = "insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")";
|
||||
statement.executeUpdate(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subscribe() throws Exception {
|
||||
TSDBSubscribe subscribe = null;
|
||||
try {
|
||||
String rawSql = "select * from " + dbName + "." + tName + ";";
|
||||
System.out.println(rawSql);
|
||||
subscribe = ((TSDBConnection) connection).createSubscribe();
|
||||
subscribId = subscribe.subscribe(topic, rawSql, false, 1000, new CallBack("first"));
|
||||
|
||||
assertTrue(subscribId > 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Thread.sleep(2000);
|
||||
subscribe.unsubscribe(subscribId, true);
|
||||
}
|
||||
|
||||
private static class CallBack implements TSDBSubscribeCallBack {
|
||||
private String name = "";
|
||||
|
||||
public CallBack(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(TSDBResultSet resultSet) {
|
||||
try {
|
||||
while (null != resultSet && resultSet.next()) {
|
||||
System.out.print("callback_" + name + ": ");
|
||||
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
|
||||
System.out.printf(i + ": " + resultSet.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
resultSet.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() throws Exception {
|
||||
statement.executeQuery("drop database test");
|
||||
statement.close();
|
||||
connection.close();
|
||||
Thread.sleep(10);
|
||||
}
|
||||
}
|
|
@ -49,20 +49,16 @@ public class SubscribeTest extends BaseTest {
|
|||
@Test
|
||||
public void subscribe() throws Exception {
|
||||
TSDBSubscribe subscribe = null;
|
||||
long subscribId = 0;
|
||||
try {
|
||||
|
||||
String rawSql = "select * from " + dbName + "." + tName + ";";
|
||||
System.out.println(rawSql);
|
||||
subscribe = ((TSDBConnection) connection).createSubscribe();
|
||||
subscribId = subscribe.subscribe(topic, rawSql, false, 1000);
|
||||
|
||||
assertTrue(subscribId > 0);
|
||||
subscribe = ((TSDBConnection) connection).subscribe(topic, rawSql, false);
|
||||
|
||||
int a = 0;
|
||||
while (true) {
|
||||
Thread.sleep(900);
|
||||
TSDBResultSet resSet = subscribe.consume(subscribId);
|
||||
TSDBResultSet resSet = subscribe.consume();
|
||||
|
||||
while (resSet.next()) {
|
||||
for (int i = 1; i <= resSet.getMetaData().getColumnCount(); i++) {
|
||||
|
@ -79,8 +75,8 @@ public class SubscribeTest extends BaseTest {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (null != subscribe && 0 != subscribId) {
|
||||
subscribe.unsubscribe(subscribId, true);
|
||||
if (null != subscribe) {
|
||||
subscribe.close(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_DNODE_CHECK_H
|
||||
#define TDENGINE_DNODE_CHECK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t dnodeInitCheck();
|
||||
void dnodeCleanupCheck();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnode.h"
|
||||
#include "dnodeInt.h"
|
||||
#include "dnodeCheck.h"
|
||||
|
||||
typedef struct {
|
||||
bool enable;
|
||||
char * name;
|
||||
int32_t (*initFp)();
|
||||
int32_t (*startFp)();
|
||||
void (*cleanUpFp)();
|
||||
void (*stopFp)();
|
||||
} SCheckItem;
|
||||
|
||||
static SCheckItem tsCheckItem[TSDB_CHECK_ITEM_MAX] = {{0}};
|
||||
int64_t tsMinFreeMemSizeForStart = 0;
|
||||
|
||||
static int bindTcpPort(int port) {
|
||||
int serverSocket;
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
if ((serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
|
||||
dError("socket() fail: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero(&server_addr, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
||||
dError("port:%d tcp bind() fail: %s", port, strerror(errno));
|
||||
close(serverSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(serverSocket, 5) < 0) {
|
||||
dError("port:%d listen() fail: %s", port, strerror(errno));
|
||||
close(serverSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(serverSocket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bindUdpPort(int port) {
|
||||
int serverSocket;
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
if ((serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
dError("socket() fail: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero(&server_addr, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
||||
dError("port:%d udp bind() fail: %s", port, strerror(errno));
|
||||
close(serverSocket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(serverSocket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckNetwork() {
|
||||
int ret;
|
||||
int startPort = tsServerPort;
|
||||
|
||||
for (int port = startPort; port < startPort + 12; port++) {
|
||||
ret = bindTcpPort(port);
|
||||
if (0 != ret) {
|
||||
dError("failed to tcp bind port %d, quit", port);
|
||||
return -1;
|
||||
}
|
||||
ret = bindUdpPort(port);
|
||||
if (0 != ret) {
|
||||
dError("failed to udp bind port %d, quit", port);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckMem() {
|
||||
float memoryUsedMB;
|
||||
float memoryAvailMB;
|
||||
if (true != taosGetSysMemory(&memoryUsedMB)) {
|
||||
dError("failed to get system mem infomation, errno:%u, reason:%s", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memoryAvailMB = (float)tsTotalMemoryMB - memoryUsedMB;
|
||||
|
||||
if (memoryAvailMB < tsMinFreeMemSizeForStart) {
|
||||
dError("free mem %f too little, quit", memoryAvailMB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckCpu() {
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckDisk() {
|
||||
if (tsAvailDataDirGB < tsMinimalDataDirGB) {
|
||||
dError("free disk size: %f GB, too little, quit", tsAvailDataDirGB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsAvailLogDirGB < tsMinimalLogDirGB) {
|
||||
dError("free disk size: %f GB, too little, quit", tsAvailLogDirGB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsAvailTmpDirectorySpace < tsReservedTmpDirectorySpace) {
|
||||
dError("free disk size: %f GB, too little, quit", tsAvailTmpDirectorySpace);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckOs() {
|
||||
// TODO:
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int dnodeCheckAccess() {
|
||||
// TODO:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckVersion() {
|
||||
// TODO:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnodeCheckDatafile() {
|
||||
// TODO:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dnodeAllocCheckItem() {
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].enable = false;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].name = "network";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].startFp = dnodeCheckNetwork;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_NETWORK].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].name = "mem";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].startFp = dnodeCheckMem;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_MEM].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].name = "cpu";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].startFp = dnodeCheckCpu;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_CPU].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].name = "disk";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].startFp = dnodeCheckDisk;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DISK].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].name = "os";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].startFp = dnodeCheckOs;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_OS].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].name = "access";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].startFp = dnodeCheckAccess;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_ACCESS].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].name = "version";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].startFp = dnodeCheckVersion;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_VERSION].stopFp = NULL;
|
||||
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].enable = true;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].name = "datafile";
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].initFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].cleanUpFp = NULL;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].startFp = dnodeCheckDatafile;
|
||||
tsCheckItem[TSDB_CHECK_ITEM_DATAFILE].stopFp = NULL;
|
||||
}
|
||||
|
||||
void dnodeCleanupCheck() {
|
||||
for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) {
|
||||
if (tsCheckItem[index].enable && tsCheckItem[index].stopFp) {
|
||||
(*tsCheckItem[index].stopFp)();
|
||||
}
|
||||
if (tsCheckItem[index].cleanUpFp) {
|
||||
(*tsCheckItem[index].cleanUpFp)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t dnodeInitCheck() {
|
||||
dnodeAllocCheckItem();
|
||||
|
||||
for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) {
|
||||
if (tsCheckItem[index].initFp) {
|
||||
if ((*tsCheckItem[index].initFp)() != 0) {
|
||||
dError("failed to init check item:%s", tsCheckItem[index].name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ECheckItemType index = 0; index < TSDB_CHECK_ITEM_MAX; ++index) {
|
||||
if (tsCheckItem[index].enable && tsCheckItem[index].startFp) {
|
||||
if ((*tsCheckItem[index].startFp)() != 0) {
|
||||
dError("failed to check item:%s", tsCheckItem[index].name);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
#include "dnodeMgmt.h"
|
||||
#include "dnodePeer.h"
|
||||
#include "dnodeModule.h"
|
||||
#include "dnodeCheck.h"
|
||||
#include "dnodeVRead.h"
|
||||
#include "dnodeVWrite.h"
|
||||
#include "dnodeMRead.h"
|
||||
|
@ -48,6 +49,7 @@ typedef struct {
|
|||
} SDnodeComponent;
|
||||
|
||||
static const SDnodeComponent tsDnodeComponents[] = {
|
||||
{"check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be first component !!!
|
||||
{"storage", dnodeInitStorage, dnodeCleanupStorage},
|
||||
{"vread", dnodeInitVnodeRead, dnodeCleanupVnodeRead},
|
||||
{"vwrite", dnodeInitVnodeWrite, dnodeCleanupVnodeWrite},
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "dnodeMain.h"
|
||||
|
||||
static void signal_handler(int32_t signum, siginfo_t *sigInfo, void *context);
|
||||
static sem_t exitSem;
|
||||
static tsem_t exitSem;
|
||||
|
||||
int32_t main(int32_t argc, char *argv[]) {
|
||||
// Set global configuration file
|
||||
|
@ -88,7 +88,7 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (sem_init(&exitSem, 0, 0) != 0) {
|
||||
if (tsem_init(&exitSem, 0, 0) != 0) {
|
||||
printf("failed to create exit semphore\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
|
||||
syslog(LOG_INFO, "Started TDengine service successfully.");
|
||||
|
||||
for (int res = sem_wait(&exitSem); res != 0; res = sem_wait(&exitSem)) {
|
||||
for (int res = tsem_wait(&exitSem); res != 0; res = tsem_wait(&exitSem)) {
|
||||
if (res != EINTR) {
|
||||
syslog(LOG_ERR, "failed to wait exit semphore: %d", res);
|
||||
break;
|
||||
|
@ -157,5 +157,5 @@ static void signal_handler(int32_t signum, siginfo_t *sigInfo, void *context) {
|
|||
sigaction(SIGUSR2, &act, NULL);
|
||||
|
||||
// inform main thread to exit
|
||||
sem_post(&exitSem);
|
||||
tsem_post(&exitSem);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "dnodeInt.h"
|
||||
#include "dnodeTelemetry.h"
|
||||
|
||||
static sem_t tsExitSem;
|
||||
static tsem_t tsExitSem;
|
||||
static pthread_t tsTelemetryThread;
|
||||
|
||||
#define TELEMETRY_SERVER "telemetry.taosdata.com"
|
||||
|
@ -266,7 +266,7 @@ int32_t dnodeInitTelemetry() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (sem_init(&tsExitSem, 0, 0) == -1) {
|
||||
if (tsem_init(&tsExitSem, 0, 0) == -1) {
|
||||
// just log the error, it is ok for telemetry to fail
|
||||
dTrace("failed to create semaphore for telemetry, reason:%s", strerror(errno));
|
||||
return 0;
|
||||
|
@ -291,8 +291,8 @@ void dnodeCleanupTelemetry() {
|
|||
}
|
||||
|
||||
if (tsTelemetryThread) {
|
||||
sem_post(&tsExitSem);
|
||||
tsem_post(&tsExitSem);
|
||||
pthread_join(tsTelemetryThread, NULL);
|
||||
sem_destroy(&tsExitSem);
|
||||
tsem_destroy(&tsExitSem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,16 +202,17 @@ static void *dnodeProcessReadQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("%p, msg:%s will be processed in vread queue, qtype:%d", pReadMsg->rpcMsg.ahandle,
|
||||
taosMsg[pReadMsg->rpcMsg.msgType], type);
|
||||
dDebug("%p, msg:%s will be processed in vread queue, qtype:%d, msg:%p", pReadMsg->rpcMsg.ahandle,
|
||||
taosMsg[pReadMsg->rpcMsg.msgType], type, pReadMsg);
|
||||
|
||||
int32_t code = vnodeProcessRead(pVnode, pReadMsg);
|
||||
|
||||
if (type == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) {
|
||||
dnodeSendRpcReadRsp(pVnode, pReadMsg, code);
|
||||
} else {
|
||||
if (code == TSDB_CODE_QRY_HAS_RSP) {
|
||||
dnodeSendRpcReadRsp(pVnode, pReadMsg, TSDB_CODE_SUCCESS);
|
||||
} else {
|
||||
dnodeSendRpcReadRsp(pVnode, pReadMsg, pReadMsg->rpcMsg.code);
|
||||
} else { // code == TSDB_CODE_NOT_READY, do not return msg to client
|
||||
dnodeDispatchNonRspMsg(pVnode, pReadMsg, code);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,9 @@ void* qGetResultRetrieveMsg(qinfo_t qinfo);
|
|||
*/
|
||||
int32_t qKillQuery(qinfo_t qinfo);
|
||||
|
||||
int32_t qQueryCompleted(qinfo_t qinfo);
|
||||
|
||||
|
||||
/**
|
||||
* destroy query info structure
|
||||
* @param qHandle
|
||||
|
|
|
@ -232,7 +232,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TSDB_NODE_NAME_LEN 64
|
||||
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
|
||||
#define TSDB_DB_NAME_LEN 33
|
||||
#define TSDB_TABLE_ID_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
|
||||
#define TSDB_COL_NAME_LEN 65
|
||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||
|
@ -242,6 +242,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TSDB_MAX_BYTES_PER_ROW 16384
|
||||
#define TSDB_MAX_TAGS_LEN 16384
|
||||
#define TSDB_MAX_TAGS 128
|
||||
#define TSDB_MAX_TAG_CONDITIONS 1024
|
||||
|
||||
#define TSDB_AUTH_LEN 16
|
||||
#define TSDB_KEY_LEN 16
|
||||
|
@ -393,6 +394,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TSDB_PORT_DNODESHELL 0
|
||||
#define TSDB_PORT_DNODEDNODE 5
|
||||
#define TSDB_PORT_SYNC 10
|
||||
#define TSDB_PORT_HTTP 11
|
||||
|
||||
#define TAOS_QTYPE_RPC 0
|
||||
#define TAOS_QTYPE_FWD 1
|
||||
|
@ -416,6 +418,19 @@ typedef enum {
|
|||
TSDB_MOD_MAX
|
||||
} EModuleType;
|
||||
|
||||
typedef enum {
|
||||
TSDB_CHECK_ITEM_NETWORK,
|
||||
TSDB_CHECK_ITEM_MEM,
|
||||
TSDB_CHECK_ITEM_CPU,
|
||||
TSDB_CHECK_ITEM_DISK,
|
||||
TSDB_CHECK_ITEM_OS,
|
||||
TSDB_CHECK_ITEM_ACCESS,
|
||||
TSDB_CHECK_ITEM_VERSION,
|
||||
TSDB_CHECK_ITEM_DATAFILE,
|
||||
TSDB_CHECK_ITEM_MAX
|
||||
} ECheckItemType;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -219,6 +219,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_DUP_JOIN_KEY, 0, 0x0705, "Duplicated
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_EXCEED_TAGS_LIMIT, 0, 0x0706, "Tag conditon too many")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_READY, 0, 0x0707, "Query not ready")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_HAS_RSP, 0, 0x0708, "Query should response")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, 0, 0x0709, "Multiple retrieval of this query")
|
||||
|
||||
// grant
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "License expired")
|
||||
|
|
|
@ -246,13 +246,13 @@ typedef struct {
|
|||
uint64_t uid;
|
||||
uint64_t superTableUid;
|
||||
uint64_t createdTime;
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char superTableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char superTableId[TSDB_TABLE_FNAME_LEN];
|
||||
char data[];
|
||||
} SMDCreateTableMsg;
|
||||
|
||||
typedef struct {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
int8_t igExists;
|
||||
int8_t getMeta;
|
||||
|
@ -265,12 +265,12 @@ typedef struct {
|
|||
} SCMCreateTableMsg;
|
||||
|
||||
typedef struct {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
int8_t igNotExists;
|
||||
} SCMDropTableMsg;
|
||||
|
||||
typedef struct {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
int16_t type; /* operation type */
|
||||
int16_t numOfCols; /* number of schema */
|
||||
|
@ -297,7 +297,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
char clientVersion[TSDB_VERSION_LEN];
|
||||
char msgVersion[TSDB_VERSION_LEN];
|
||||
char db[TSDB_TABLE_ID_LEN];
|
||||
char db[TSDB_TABLE_FNAME_LEN];
|
||||
} SCMConnectMsg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -347,14 +347,14 @@ typedef struct {
|
|||
int32_t vgId;
|
||||
int32_t sid;
|
||||
uint64_t uid;
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
} SMDDropTableMsg;
|
||||
|
||||
typedef struct {
|
||||
int32_t contLen;
|
||||
int32_t vgId;
|
||||
uint64_t uid;
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
} SMDDropSTableMsg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -527,7 +527,7 @@ typedef struct {
|
|||
} SCMCreateDbMsg, SCMAlterDbMsg;
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_TABLE_ID_LEN];
|
||||
char db[TSDB_TABLE_FNAME_LEN];
|
||||
uint8_t ignoreNotExists;
|
||||
} SCMDropDbMsg, SCMUseDbMsg;
|
||||
|
||||
|
@ -637,7 +637,7 @@ typedef struct {
|
|||
} SMDCreateVnodeMsg, SMDAlterVnodeMsg;
|
||||
|
||||
typedef struct {
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
int16_t createFlag;
|
||||
char tags[];
|
||||
} SCMTableInfoMsg;
|
||||
|
@ -664,7 +664,7 @@ typedef struct {
|
|||
|
||||
typedef struct STableMetaMsg {
|
||||
int32_t contLen;
|
||||
char tableId[TSDB_TABLE_ID_LEN]; // table id
|
||||
char tableId[TSDB_TABLE_FNAME_LEN]; // table id
|
||||
uint8_t numOfTags;
|
||||
uint8_t precision;
|
||||
uint8_t tableType;
|
||||
|
@ -685,7 +685,7 @@ typedef struct SMultiTableMeta {
|
|||
|
||||
typedef struct {
|
||||
int32_t dataLen;
|
||||
char name[TSDB_TABLE_ID_LEN];
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
char data[TSDB_MAX_TAGS_LEN + TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * TSDB_MAX_TAGS];
|
||||
} STagData;
|
||||
|
||||
|
@ -771,7 +771,7 @@ typedef struct {
|
|||
uint64_t uid;
|
||||
uint64_t stime; // stream starting time
|
||||
int32_t status;
|
||||
char tableId[TSDB_TABLE_ID_LEN];
|
||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
||||
} SMDAlterStreamMsg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -167,9 +167,14 @@ typedef struct SDataBlockInfo {
|
|||
} SDataBlockInfo;
|
||||
|
||||
typedef struct {
|
||||
size_t numOfTables;
|
||||
void *pTable;
|
||||
TSKEY lastKey;
|
||||
} STableKeyInfo;
|
||||
|
||||
typedef struct {
|
||||
size_t numOfTables;
|
||||
SArray *pGroupList;
|
||||
SHashObj *map; // speedup acquire the tableQueryInfo from STableId
|
||||
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
||||
} STableGroupInfo;
|
||||
|
||||
/**
|
||||
|
@ -177,24 +182,24 @@ typedef struct {
|
|||
*
|
||||
* @param tsdb tsdb handle
|
||||
* @param pCond query condition, including time window, result set order, and basic required columns for each block
|
||||
* @param tableqinfoGroupInfo tableId list in the form of set, seperated into different groups according to group by condition
|
||||
* @param tableInfoGroup table object list in the form of set, grouped into different sets according to the
|
||||
* group by condition
|
||||
* @param qinfo query info handle from query processor
|
||||
* @return
|
||||
*/
|
||||
TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableqinfoGroupInfo, void *qinfo);
|
||||
TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfoGroup, void *qinfo);
|
||||
|
||||
/**
|
||||
* Get the last row of the given query time window for all the tables in STableGroupInfo object.
|
||||
* Note that only one data block with only row will be returned while invoking retrieve data block function for
|
||||
* all tables in this group.
|
||||
*
|
||||
* @param tsdb tsdb handle
|
||||
* @param pCond query condition, including time window, result set order, and basic required columns for each
|
||||
* block
|
||||
* @param tableqinfoGroupInfo tableId list.
|
||||
* @param tsdb tsdb handle
|
||||
* @param pCond query condition, including time window, result set order, and basic required columns for each block
|
||||
* @param tableInfo table list.
|
||||
* @return
|
||||
*/
|
||||
TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableqinfoGroupInfo, void *qinfo);
|
||||
TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, void *qinfo);
|
||||
|
||||
/**
|
||||
* get the queried table object list
|
||||
|
@ -260,7 +265,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL
|
|||
* @param stableid. super table sid
|
||||
* @param pTagCond. tag query condition
|
||||
*/
|
||||
int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T *tsdb, uint64_t uid, const char *pTagCond, size_t len,
|
||||
int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY key, const char *pTagCond, size_t len,
|
||||
int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList,
|
||||
SColIndex *pColIndex, int32_t numOfCols);
|
||||
|
||||
|
@ -278,7 +283,7 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList);
|
|||
* @param pGroupInfo the generated result
|
||||
* @return
|
||||
*/
|
||||
int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, STableGroupInfo *pGroupInfo);
|
||||
int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo *pGroupInfo);
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -128,6 +128,9 @@ static int32_t shellRunSingleCommand(TAOS *con, char *command) {
|
|||
if (regex_match(command, "^[ \t]*(quit|q|exit)[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
|
||||
taos_close(con);
|
||||
write_history();
|
||||
#ifdef WINDOWS
|
||||
exit(EXIT_SUCCESS);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -307,7 +310,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
|||
if (error_no == 0) {
|
||||
printf("Query OK, %d row(s) in set (%.6fs)\n", numOfRows, (et - st) / 1E6);
|
||||
} else {
|
||||
printf("Query interrupted (%s), %d row(s) in set (%.6fs)\n", taos_errstr(con), numOfRows, (et - st) / 1E6);
|
||||
printf("Query interrupted (%s), %d row(s) in set (%.6fs)\n", taos_errstr(pSql), numOfRows, (et - st) / 1E6);
|
||||
}
|
||||
} else {
|
||||
int num_rows_affacted = taos_affected_rows(pSql);
|
||||
|
@ -368,6 +371,18 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) {
|
|||
tt = (time_t)(val / 1000);
|
||||
}
|
||||
|
||||
/* comment out as it make testcases like select_with_tags.sim fail.
|
||||
but in windows, this may cause the call to localtime crash if tt < 0,
|
||||
need to find a better solution.
|
||||
if (tt < 0) {
|
||||
tt = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef WINDOWS
|
||||
if (tt < 0) tt = 0;
|
||||
#endif
|
||||
|
||||
struct tm* ptm = localtime(&tt);
|
||||
size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);
|
||||
|
||||
|
@ -736,7 +751,9 @@ void read_history() {
|
|||
|
||||
FILE *f = fopen(f_history, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "Opening file %s\n", f_history);
|
||||
#ifndef WINDOWS
|
||||
fprintf(stderr, "Failed to open file %s\n", f_history);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -761,7 +778,9 @@ void write_history() {
|
|||
|
||||
FILE *f = fopen(f_history, "w");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "Opening file %s\n", f_history);
|
||||
#ifndef WINDOWS
|
||||
fprintf(stderr, "Failed to open file %s for write\n", f_history);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,6 @@ void *shellLoopQuery(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void get_history_path(char *history) { sprintf(history, "%s/%s", ".", HISTORY_FILE); }
|
||||
void get_history_path(char *history) { sprintf(history, "C:/TDengine/%s", HISTORY_FILE); }
|
||||
|
||||
void exitShell() { exit(EXIT_SUCCESS); }
|
||||
|
|
|
@ -250,7 +250,7 @@ typedef struct DemoArguments {
|
|||
static struct argp argp = {options, parse_opt, 0, 0};
|
||||
|
||||
void parse_args(int argc, char *argv[], SDemoArguments *arguments) {
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
argp_parse(&argp, argc, argv, 0, 0, arguments);
|
||||
if (arguments->abort) {
|
||||
#ifndef _ALPINE
|
||||
error(10, 0, "ABORTED");
|
||||
|
@ -306,7 +306,7 @@ typedef struct DemoArguments {
|
|||
printf("%s%s\n", indent, "-R");
|
||||
printf("%s%s%s\n", indent, indent, "rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50.");
|
||||
printf("%s%s\n", indent, "-D");
|
||||
printf("%s%s%s\n", indent, indent, "Delete data methods——0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database.");
|
||||
printf("%s%s%s\n", indent, indent, "Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database.");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char *argv[], SDemoArguments *arguments) {
|
||||
|
@ -440,9 +440,9 @@ typedef struct {
|
|||
char* cols;
|
||||
bool use_metric;
|
||||
|
||||
sem_t mutex_sem;
|
||||
tsem_t mutex_sem;
|
||||
int notFinished;
|
||||
sem_t lock_sem;
|
||||
tsem_t lock_sem;
|
||||
} info;
|
||||
|
||||
typedef struct {
|
||||
|
@ -459,9 +459,9 @@ typedef struct {
|
|||
int data_of_order;
|
||||
int data_of_rate;
|
||||
|
||||
sem_t *mutex_sem;
|
||||
int *notFinished;
|
||||
sem_t *lock_sem;
|
||||
tsem_t *mutex_sem;
|
||||
int *notFinished;
|
||||
tsem_t *lock_sem;
|
||||
} sTable;
|
||||
|
||||
/* ******************************* Global
|
||||
|
@ -729,9 +729,9 @@ int main(int argc, char *argv[]) {
|
|||
t_info->end_table_id = i < b ? last + a : last + a - 1;
|
||||
last = t_info->end_table_id + 1;
|
||||
|
||||
sem_init(&(t_info->mutex_sem), 0, 1);
|
||||
tsem_init(&(t_info->mutex_sem), 0, 1);
|
||||
t_info->notFinished = t_info->end_table_id - t_info->start_table_id + 1;
|
||||
sem_init(&(t_info->lock_sem), 0, 0);
|
||||
tsem_init(&(t_info->lock_sem), 0, 0);
|
||||
|
||||
if (query_mode == SYNC) {
|
||||
pthread_create(pids + i, NULL, syncWrite, t_info);
|
||||
|
@ -762,8 +762,8 @@ int main(int argc, char *argv[]) {
|
|||
for (int i = 0; i < threads; i++) {
|
||||
info *t_info = infos + i;
|
||||
taos_close(t_info->taos);
|
||||
sem_destroy(&(t_info->mutex_sem));
|
||||
sem_destroy(&(t_info->lock_sem));
|
||||
tsem_destroy(&(t_info->mutex_sem));
|
||||
tsem_destroy(&(t_info->lock_sem));
|
||||
}
|
||||
|
||||
free(pids);
|
||||
|
@ -1021,8 +1021,8 @@ void multiThreadCreateTable(char* cols, bool use_metric, int threads, int ntable
|
|||
|
||||
for (int i = 0; i < threads; i++) {
|
||||
info *t_info = infos + i;
|
||||
sem_destroy(&(t_info->mutex_sem));
|
||||
sem_destroy(&(t_info->lock_sem));
|
||||
tsem_destroy(&(t_info->mutex_sem));
|
||||
tsem_destroy(&(t_info->lock_sem));
|
||||
}
|
||||
|
||||
free(pids);
|
||||
|
@ -1272,7 +1272,7 @@ void *asyncWrite(void *sarg) {
|
|||
taos_query_a(winfo->taos, "show databases", callBack, tb_info);
|
||||
}
|
||||
|
||||
sem_wait(&(winfo->lock_sem));
|
||||
tsem_wait(&(winfo->lock_sem));
|
||||
free(tb_infos);
|
||||
|
||||
return NULL;
|
||||
|
@ -1292,10 +1292,10 @@ void callBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
// If finished;
|
||||
if (tb_info->counter >= tb_info->target) {
|
||||
sem_wait(tb_info->mutex_sem);
|
||||
tsem_wait(tb_info->mutex_sem);
|
||||
(*(tb_info->notFinished))--;
|
||||
if (*(tb_info->notFinished) == 0) sem_post(tb_info->lock_sem);
|
||||
sem_post(tb_info->mutex_sem);
|
||||
if (*(tb_info->notFinished) == 0) tsem_post(tb_info->lock_sem);
|
||||
tsem_post(tb_info->mutex_sem);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ void mnodeDecDbRef(SDbObj *pDb) {
|
|||
}
|
||||
|
||||
SDbObj *mnodeGetDbByTableId(char *tableId) {
|
||||
char db[TSDB_TABLE_ID_LEN], *pos;
|
||||
char db[TSDB_TABLE_FNAME_LEN], *pos;
|
||||
|
||||
// tableId format should be : acct.db.table
|
||||
pos = strstr(tableId, TS_PATH_DELIMITER);
|
||||
|
@ -1046,7 +1046,7 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
|
|||
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pDrop->db);
|
||||
if (pMsg->pDb == NULL) {
|
||||
if (pDrop->ignoreNotExists) {
|
||||
mDebug("db:%s, db is not exist, think drop success", pDrop->db);
|
||||
mDebug("db:%s, db is not exist, treat as success", pDrop->db);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
mError("db:%s, failed to drop, invalid db", pDrop->db);
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include "mnodeVgroup.h"
|
||||
#include "mnodeWrite.h"
|
||||
|
||||
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
||||
#define CONN_CHECK_TIME (tsShellActivityTimer * 2)
|
||||
#define CONN_KEEP_TIME (tsShellActivityTimer * 3000)
|
||||
#define CONN_CHECK_TIME (tsShellActivityTimer * 2000)
|
||||
#define QUERY_ID_SIZE 20
|
||||
#define QUERY_STREAM_SAVE_SIZE 20
|
||||
|
||||
|
@ -73,13 +73,13 @@ int32_t mnodeInitProfile() {
|
|||
|
||||
void mnodeCleanupProfile() {
|
||||
if (tsMnodeConnCache != NULL) {
|
||||
mInfo("conn cache is cleanup");
|
||||
taosCacheCleanup(tsMnodeConnCache);
|
||||
tsMnodeConnCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
||||
#if 0
|
||||
int32_t connSize = taosHashGetSize(tsMnodeConnCache->pHashTable);
|
||||
if (connSize > tsMaxShellConns) {
|
||||
mError("failed to create conn for user:%s ip:%s:%u, conns:%d larger than maxShellConns:%d, ", user, taosIpStr(ip),
|
||||
|
@ -87,6 +87,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
|||
terrno = TSDB_CODE_MND_TOO_MANY_SHELL_CONNS;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t connId = atomic_add_fetch_32(&tsConnIndex, 1);
|
||||
if (connId == 0) atomic_add_fetch_32(&tsConnIndex, 1);
|
||||
|
@ -100,7 +101,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
|||
tstrncpy(connObj.user, user, sizeof(connObj.user));
|
||||
|
||||
SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME);
|
||||
|
||||
|
||||
mDebug("connId:%d, is created, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
|
||||
return pConn;
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ void mnodeReleaseConn(SConnObj *pConn) {
|
|||
|
||||
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port) {
|
||||
uint64_t expireTime = CONN_KEEP_TIME * 1000 + (uint64_t)taosGetTimestampMs();
|
||||
SConnObj *pConn = taosCacheUpdateExpireTimeByName(tsMnodeConnCache, &connId, sizeof(int32_t), expireTime);
|
||||
SConnObj *pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
|
||||
if (pConn == NULL) {
|
||||
mDebug("connId:%d, is already destroyed, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
|
||||
return NULL;
|
||||
|
|
|
@ -874,7 +874,7 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) {
|
|||
if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) {
|
||||
hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
}
|
||||
pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true);
|
||||
pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true, true);
|
||||
|
||||
tsSdbObj.numOfTables++;
|
||||
tsSdbObj.tableList[pTable->tableId] = pTable;
|
||||
|
|
|
@ -302,7 +302,7 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
|
|||
SAcctObj *pAcct = pUser->pAcct;
|
||||
|
||||
if (pConnectMsg->db[0]) {
|
||||
char dbName[TSDB_TABLE_ID_LEN * 3] = {0};
|
||||
char dbName[TSDB_TABLE_FNAME_LEN * 3] = {0};
|
||||
sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db);
|
||||
SDbObj *pDb = mnodeGetDb(dbName);
|
||||
if (pDb == NULL) {
|
||||
|
@ -377,7 +377,8 @@ static bool mnodeCheckShowFinished(SShowObj *pShow) {
|
|||
}
|
||||
|
||||
static bool mnodeAccquireShowObj(SShowObj *pShow) {
|
||||
SShowObj **ppShow = taosCacheAcquireByKey(tsMnodeShowCache, &pShow, sizeof(int64_t));
|
||||
uint64_t handleVal = (uint64_t)pShow;
|
||||
SShowObj **ppShow = taosCacheAcquireByKey(tsMnodeShowCache, &handleVal, sizeof(int64_t));
|
||||
if (ppShow) {
|
||||
mDebug("%p, show is accquired from cache, data:%p, index:%d", pShow, ppShow, pShow->index);
|
||||
return true;
|
||||
|
@ -389,7 +390,8 @@ static bool mnodeAccquireShowObj(SShowObj *pShow) {
|
|||
static void* mnodePutShowObj(SShowObj *pShow) {
|
||||
if (tsMnodeShowCache != NULL) {
|
||||
pShow->index = atomic_add_fetch_32(&tsShowObjIndex, 1);
|
||||
SShowObj **ppShow = taosCachePut(tsMnodeShowCache, &pShow, sizeof(int64_t), &pShow, sizeof(int64_t), 6);
|
||||
uint64_t handleVal = (uint64_t)pShow;
|
||||
SShowObj **ppShow = taosCachePut(tsMnodeShowCache, &handleVal, sizeof(int64_t), &pShow, sizeof(int64_t), 6000);
|
||||
pShow->ppShow = (void**)ppShow;
|
||||
mDebug("%p, show is put into cache, data:%p index:%d", pShow, ppShow, pShow->index);
|
||||
return pShow;
|
||||
|
|
|
@ -215,7 +215,7 @@ static int32_t mnodeChildTableActionEncode(SSdbOper *pOper) {
|
|||
assert(pTable != NULL && pOper->rowData != NULL);
|
||||
|
||||
int32_t len = strlen(pTable->info.tableId);
|
||||
if (len >= TSDB_TABLE_ID_LEN) return TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
if (len >= TSDB_TABLE_FNAME_LEN) return TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
|
||||
memcpy(pOper->rowData, pTable->info.tableId, len);
|
||||
memset(pOper->rowData + len, 0, 1);
|
||||
|
@ -246,7 +246,7 @@ static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) {
|
|||
if (pTable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
int32_t len = strlen(pOper->rowData);
|
||||
if (len >= TSDB_TABLE_ID_LEN) {
|
||||
if (len >= TSDB_TABLE_FNAME_LEN) {
|
||||
free(pTable);
|
||||
return TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ static int32_t mnodeInitChildTables() {
|
|||
.tableId = SDB_TABLE_CTABLE,
|
||||
.tableName = "ctables",
|
||||
.hashSessions = TSDB_DEFAULT_CTABLES_HASH_SIZE,
|
||||
.maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN + TSDB_CQ_SQL_SIZE,
|
||||
.maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN + TSDB_CQ_SQL_SIZE,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_VAR_STRING,
|
||||
.insertFp = mnodeChildTableActionInsert,
|
||||
|
@ -387,7 +387,7 @@ static void mnodeAddTableIntoStable(SSuperTableObj *pStable, SChildTableObj *pCt
|
|||
atomic_add_fetch_32(&pStable->numOfTables, 1);
|
||||
|
||||
if (pStable->vgHash == NULL) {
|
||||
pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false);
|
||||
pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
|
||||
}
|
||||
|
||||
if (pStable->vgHash != NULL) {
|
||||
|
@ -479,7 +479,7 @@ static int32_t mnodeSuperTableActionEncode(SSdbOper *pOper) {
|
|||
assert(pOper->pObj != NULL && pOper->rowData != NULL);
|
||||
|
||||
int32_t len = strlen(pStable->info.tableId);
|
||||
if (len >= TSDB_TABLE_ID_LEN) len = TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
if (len >= TSDB_TABLE_FNAME_LEN) len = TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
|
||||
memcpy(pOper->rowData, pStable->info.tableId, len);
|
||||
memset(pOper->rowData + len, 0, 1);
|
||||
|
@ -503,7 +503,7 @@ static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) {
|
|||
if (pStable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
|
||||
int32_t len = strlen(pOper->rowData);
|
||||
if (len >= TSDB_TABLE_ID_LEN){
|
||||
if (len >= TSDB_TABLE_FNAME_LEN){
|
||||
free(pStable);
|
||||
return TSDB_CODE_MND_INVALID_TABLE_ID;
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ static int32_t mnodeInitSuperTables() {
|
|||
.tableId = SDB_TABLE_STABLE,
|
||||
.tableName = "stables",
|
||||
.hashSessions = TSDB_DEFAULT_STABLES_HASH_SIZE,
|
||||
.maxRowSize = sizeof(SSuperTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN,
|
||||
.maxRowSize = sizeof(SSuperTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_VAR_STRING,
|
||||
.insertFp = mnodeSuperTableActionInsert,
|
||||
|
@ -751,7 +751,7 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
|
|||
if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pDrop->tableId);
|
||||
if (pMsg->pTable == NULL) {
|
||||
if (pDrop->igNotExists) {
|
||||
mDebug("app:%p:%p, table:%s, table is not exist, think drop success", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId);
|
||||
mDebug("app:%p:%p, table:%s, table is not exist, treat as success", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
mError("app:%p:%p, table:%s, failed to drop table, table not exist", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId);
|
||||
|
@ -1464,7 +1464,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
// reserve space
|
||||
int32_t contLen = sizeof(SCMSTableVgroupRspMsg) + 32 * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo);
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN) * i;
|
||||
char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN) * i;
|
||||
SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||
if (pTable != NULL && pTable->vgHash != NULL) {
|
||||
contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo));
|
||||
|
@ -1481,7 +1481,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
|||
char *msg = (char *)pRsp + sizeof(SCMSTableVgroupRspMsg);
|
||||
|
||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||
char * stableName = (char *)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN)*i;
|
||||
char * stableName = (char *)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||
SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||
if (pTable == NULL) {
|
||||
mError("app:%p:%p, stable:%s, not exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, stableName);
|
||||
|
@ -1828,7 +1828,7 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) {
|
|||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
tstrncpy(pDrop->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN);
|
||||
tstrncpy(pDrop->tableId, pTable->info.tableId, TSDB_TABLE_FNAME_LEN);
|
||||
pDrop->vgId = htonl(pTable->vgId);
|
||||
pDrop->contLen = htonl(sizeof(SMDDropTableMsg));
|
||||
pDrop->sid = htonl(pTable->sid);
|
||||
|
@ -2079,7 +2079,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
|
|||
pMeta->sid = htonl(pTable->sid);
|
||||
pMeta->precision = pDb->cfg.precision;
|
||||
pMeta->tableType = pTable->info.type;
|
||||
tstrncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN);
|
||||
tstrncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
||||
pMeta->sversion = htons(pTable->superTable->sversion);
|
||||
|
@ -2448,7 +2448,7 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
|||
pMultiMeta->numOfTables = 0;
|
||||
|
||||
for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
|
||||
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN);
|
||||
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN);
|
||||
SChildTableObj *pTable = mnodeGetChildTable(tableId);
|
||||
if (pTable == NULL) continue;
|
||||
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
ADD_SUBDIRECTORY(src/linux64)
|
||||
ELSEIF (TD_LINUX_32)
|
||||
ADD_SUBDIRECTORY(src/linux32)
|
||||
ELSEIF (TD_DARWIN_64)
|
||||
IF (TD_LINUX)
|
||||
ADD_SUBDIRECTORY(src/linux)
|
||||
ELSEIF (TD_DARWIN)
|
||||
ADD_SUBDIRECTORY(src/darwin)
|
||||
ELSEIF (TD_WINDOWS_64)
|
||||
ADD_SUBDIRECTORY(src/windows)
|
||||
ELSEIF (TD_WINDOWS_32)
|
||||
ELSEIF (TD_WINDOWS)
|
||||
ADD_SUBDIRECTORY(src/windows)
|
||||
ENDIF ()
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ extern "C" {
|
|||
#include "osDarwin.h"
|
||||
#endif
|
||||
|
||||
#ifdef _TD_ARM_64_
|
||||
#include "osArm64.h"
|
||||
#endif
|
||||
|
||||
#ifdef _TD_LINUX_64
|
||||
#include "osLinux64.h"
|
||||
#endif
|
||||
|
@ -41,6 +45,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "osAtomic.h"
|
||||
#include "osCommon.h"
|
||||
#include "osDef.h"
|
||||
#include "osDir.h"
|
||||
#include "osFile.h"
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_OS_ARM64_H
|
||||
#define TDENGINE_OS_ARM64_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <argp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <regex.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wordexp.h>
|
||||
#include <wctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/resource.h>
|
||||
#include <error.h>
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_OS_COMMON_H
|
||||
#define TDENGINE_OS_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef TAOS_OS_DEF_ZU
|
||||
#define PRIzu "zu"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
bool taosCheckPthreadValid(pthread_t thread);
|
||||
int64_t taosGetPthreadId();
|
||||
void taosResetPthread(pthread_t *thread);
|
||||
bool taosComparePthread(pthread_t first, pthread_t second);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -65,6 +65,10 @@ void taosBlockSIGPIPE();
|
|||
// TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
|
||||
int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int optlen);
|
||||
|
||||
// TAOS_OS_FUNC_SOCKET_INET
|
||||
uint32_t taosInetAddr(char *ipAddr);
|
||||
const char *taosInetNtoa(struct in_addr ipInt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -97,6 +97,9 @@ typedef SOCKET eventfd_t;
|
|||
#define TAOS_OS_DEF_EPOLL
|
||||
#define TAOS_EPOLL_WAIT_TIME 100
|
||||
|
||||
#define TAOS_OS_DEF_ZU
|
||||
#define PRIzu "ld"
|
||||
|
||||
#define TAOS_OS_FUNC_STRING_WCHAR
|
||||
int twcslen(const wchar_t *wcs);
|
||||
#define TAOS_OS_FUNC_STRING_GETLINE
|
||||
|
@ -161,9 +164,25 @@ int gettimeofday(struct timeval *ptv, void *pTimeZone);
|
|||
#define MSG_NOSIGNAL 0
|
||||
#define SO_NO_CHECK 0x1234
|
||||
#define SOL_TCP 0x1234
|
||||
#define TCP_KEEPCNT 0x1234
|
||||
#define TCP_KEEPIDLE 0x1234
|
||||
#define TCP_KEEPINTVL 0x1234
|
||||
|
||||
#ifndef TCP_KEEPCNT
|
||||
#define TCP_KEEPCNT 0x1234
|
||||
#endif
|
||||
|
||||
#ifndef TCP_KEEPIDLE
|
||||
#define TCP_KEEPIDLE 0x1234
|
||||
#endif
|
||||
|
||||
#ifndef TCP_KEEPINTVL
|
||||
#define TCP_KEEPINTVL 0x1234
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1900
|
||||
#define TAOS_OS_FUNC_SOCKET_INET
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SHUT_RDWR SD_BOTH
|
||||
#define SHUT_RD SD_RECEIVE
|
||||
#define SHUT_WR SD_SEND
|
||||
|
|
|
@ -42,7 +42,7 @@ static bool random_alloc_fail(size_t size, const char* file, uint32_t line) {
|
|||
}
|
||||
|
||||
if (fpAllocLog != NULL) {
|
||||
fprintf(fpAllocLog, "%s:%d: memory allocation of %zu bytes will fail.\n", file, line, size);
|
||||
fprintf(fpAllocLog, "%s:%d: memory allocation of %" PRIzu " bytes will fail.\n", file, line, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -159,7 +159,7 @@ static void* malloc_detect_leak(size_t size, const char* file, uint32_t line) {
|
|||
}
|
||||
|
||||
if (size > UINT32_MAX && fpAllocLog != NULL) {
|
||||
fprintf(fpAllocLog, "%s:%d: size too large: %zu.\n", file, line, size);
|
||||
fprintf(fpAllocLog, "%s:%d: size too large: %" PRIzu ".\n", file, line, size);
|
||||
}
|
||||
|
||||
blk->file = file;
|
||||
|
@ -207,7 +207,7 @@ static void* realloc_detect_leak(void* ptr, size_t size, const char* file, uint3
|
|||
}
|
||||
|
||||
if (size > UINT32_MAX && fpAllocLog != NULL) {
|
||||
fprintf(fpAllocLog, "%s:%d: size too large: %zu.\n", file, line, size);
|
||||
fprintf(fpAllocLog, "%s:%d: size too large: %" PRIzu ".\n", file, line, size);
|
||||
}
|
||||
|
||||
blk = (SMemBlock*)p;
|
||||
|
@ -295,7 +295,7 @@ static void dump_memory_leak() {
|
|||
|
||||
atomic_store_ptr(&lock, 0);
|
||||
|
||||
fprintf(fpAllocLog, "\nnumber of blocks: %zu, total bytes: %zu\n", numOfBlk, totalSize);
|
||||
fprintf(fpAllocLog, "\nnumber of blocks: %" PRIzu ", total bytes: %" PRIzu "\n", numOfBlk, totalSize);
|
||||
fflush(fpAllocLog);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
bool taosCheckPthreadValid(pthread_t thread) { return thread != 0; }
|
||||
int64_t taosGetPthreadId() { return (int64_t)pthread_self(); }
|
||||
void taosResetPthread(pthread_t *thread) { *thread = 0; }
|
||||
bool taosComparePthread(pthread_t first, pthread_t second) { return first == second; }
|
||||
|
||||
#endif
|
|
@ -57,4 +57,16 @@ int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int op
|
|||
return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef TAOS_OS_FUNC_SOCKET_INET
|
||||
|
||||
uint32_t taosInetAddr(char *ipAddr) {
|
||||
return inet_addr(ipAddr);
|
||||
}
|
||||
|
||||
const char *taosInetNtoa(struct in_addr ipInt) {
|
||||
return inet_ntoa(ipInt);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -61,8 +61,15 @@ int64_t user_mktime64(const unsigned int year0, const unsigned int mon0,
|
|||
res = res*24;
|
||||
res = ((res + hour) * 60 + min) * 60 + sec;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1900
|
||||
int64_t timezone = _timezone;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return (res + timezone);
|
||||
}
|
||||
|
||||
// ==== mktime() kernel code =================//
|
||||
static int64_t m_deltaUtc = 0;
|
||||
void deltaToUtcInitOnce() {
|
||||
|
|
|
@ -43,7 +43,11 @@ long interlocked_add_fetch_32(long volatile* ptr, long val) {
|
|||
}
|
||||
|
||||
__int64 interlocked_add_fetch_64(__int64 volatile* ptr, __int64 val) {
|
||||
#ifdef _WIN64
|
||||
return _InterlockedExchangeAdd64(ptr, val) + val;
|
||||
#else
|
||||
return _InterlockedExchangeAdd(ptr, val) + val;
|
||||
#endif
|
||||
}
|
||||
|
||||
// and
|
||||
|
|
|
@ -23,7 +23,7 @@ void taosRemoveDir(char *rootDir) {
|
|||
|
||||
int taosMkDir(const char *path, mode_t mode) {
|
||||
uError("%s not implemented yet", __FUNCTION__);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taosMvDir(char* destDir, char *srcDir) {
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
extern void taosWinSocketInit();
|
||||
|
||||
void osInit() {
|
||||
taosSetCoreDump();
|
||||
if (configDir[0] == 0) {
|
||||
strcpy(configDir, "~/TDengine/cfg");
|
||||
strcpy(configDir, "C:/TDengine/cfg");
|
||||
}
|
||||
|
||||
strcpy(tsVnodeDir, "C:/TDengine/data");
|
||||
|
|
|
@ -21,9 +21,29 @@
|
|||
#include "tulog.h"
|
||||
#include "tutil.h"
|
||||
|
||||
unsigned char _MyBitScanForward64(unsigned long *ret, uint64_t x) {
|
||||
unsigned long x0 = (unsigned long)x, top, bottom;
|
||||
_BitScanForward(&top, (unsigned long)(x >> 32));
|
||||
_BitScanForward(&bottom, x0);
|
||||
*ret = x0 ? bottom : 32 + top;
|
||||
return x != 0;
|
||||
}
|
||||
|
||||
unsigned char _MyBitScanReverse64(unsigned long *ret, uint64_t x) {
|
||||
unsigned long x1 = (unsigned long)(x >> 32), top, bottom;
|
||||
_BitScanReverse(&top, x1);
|
||||
_BitScanReverse(&bottom, (unsigned long)x);
|
||||
*ret = x1 ? top + 32 : bottom;
|
||||
return x != 0;
|
||||
}
|
||||
|
||||
int32_t BUILDIN_CLZL(uint64_t val) {
|
||||
unsigned long r = 0;
|
||||
#ifdef _WIN64
|
||||
_BitScanReverse64(&r, val);
|
||||
#else
|
||||
_MyBitScanReverse64(&r, val);
|
||||
#endif
|
||||
return (int)(r >> 3);
|
||||
}
|
||||
|
||||
|
@ -35,7 +55,11 @@ int32_t BUILDIN_CLZ(uint32_t val) {
|
|||
|
||||
int32_t BUILDIN_CTZL(uint64_t val) {
|
||||
unsigned long r = 0;
|
||||
#ifdef _WIN64
|
||||
_BitScanForward64(&r, val);
|
||||
#else
|
||||
_MyBitScanForward64(&r, val);
|
||||
#endif
|
||||
return (int)(r >> 3);
|
||||
}
|
||||
|
||||
|
@ -43,4 +67,4 @@ int32_t BUILDIN_CTZ(uint32_t val) {
|
|||
unsigned long r = 0;
|
||||
_BitScanForward(&r, val);
|
||||
return (int)(r >> 3);
|
||||
}
|
||||
}
|
|
@ -32,3 +32,7 @@ int64_t taosGetPthreadId() {
|
|||
return (int64_t)pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool taosComparePthread(pthread_t first, pthread_t second) {
|
||||
return first.p == second.p;
|
||||
}
|
||||
|
|
|
@ -62,4 +62,24 @@ int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int op
|
|||
}
|
||||
|
||||
return setsockopt(socketfd, level, optname, optval, optlen);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TAOS_OS_FUNC_SOCKET_INET
|
||||
|
||||
uint32_t taosInetAddr(char *ipAddr) {
|
||||
uint32_t value;
|
||||
int ret = inet_pton(AF_INET, ipAddr, &value);
|
||||
if (ret <= 0) {
|
||||
return INADDR_NONE;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
const char *taosInetNtoa(struct in_addr ipInt) {
|
||||
// not thread safe, only for debug usage while print log
|
||||
static char tmpDstStr[16];
|
||||
return inet_ntop(AF_INET, &ipInt, tmpDstStr, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,11 +16,22 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tglobal.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "ttimer.h"
|
||||
#include "tulog.h"
|
||||
#include "tutil.h"
|
||||
#if (_WIN64)
|
||||
#include <iphlpapi.h>
|
||||
#include <mswsock.h>
|
||||
#include <psapi.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "Mswsock.lib ")
|
||||
#endif
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
static void taosGetSystemTimezone() {
|
||||
// get and set default timezone
|
||||
|
@ -43,7 +54,7 @@ static void taosGetSystemLocale() {
|
|||
if (cfg_locale && cfg_locale->cfgStatus < TAOS_CFG_CSTATUS_DEFAULT) {
|
||||
char *locale = setlocale(LC_CTYPE, "chs");
|
||||
if (locale != NULL) {
|
||||
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);;
|
||||
tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
|
||||
cfg_locale->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT;
|
||||
uInfo("locale not configured, set to default:%s", tsLocale);
|
||||
}
|
||||
|
@ -69,11 +80,64 @@ void taosGetSystemInfo() {
|
|||
taosGetSystemLocale();
|
||||
}
|
||||
|
||||
bool taosGetDisk() { return true; }
|
||||
bool taosGetDisk() {
|
||||
const double unit = 1024 * 1024 * 1024;
|
||||
BOOL fResult;
|
||||
unsigned _int64 i64FreeBytesToCaller;
|
||||
unsigned _int64 i64TotalBytes;
|
||||
unsigned _int64 i64FreeBytes;
|
||||
char dir[4] = {'C', ':', '\\', '\0'};
|
||||
int drive_type;
|
||||
|
||||
if (tscEmbedded) {
|
||||
drive_type = GetDriveTypeA(dir);
|
||||
if (drive_type == DRIVE_FIXED) {
|
||||
fResult = GetDiskFreeSpaceExA(dir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes,
|
||||
(PULARGE_INTEGER)&i64FreeBytes);
|
||||
if (fResult) {
|
||||
tsTotalDataDirGB = tsTotalLogDirGB = tsTotalTmpDirGB = (float)(i64TotalBytes / unit);
|
||||
tsAvailDataDirGB = tsAvailLogDirGB = tsAvailTmpDirectorySpace = (float)(i64FreeBytes / unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool taosReadProcIO(int64_t *readbyte, int64_t *writebyte) {
|
||||
IO_COUNTERS io_counter;
|
||||
if (GetProcessIoCounters(GetCurrentProcess(), &io_counter)) {
|
||||
if (readbyte) *readbyte = io_counter.ReadTransferCount;
|
||||
if (writebyte) *writebyte = io_counter.WriteTransferCount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool taosGetProcIO(float *readKB, float *writeKB) {
|
||||
*readKB = 0;
|
||||
*writeKB = 0;
|
||||
static int64_t lastReadbyte = -1;
|
||||
static int64_t lastWritebyte = -1;
|
||||
|
||||
int64_t curReadbyte = 0;
|
||||
int64_t curWritebyte = 0;
|
||||
|
||||
if (!taosReadProcIO(&curReadbyte, &curWritebyte)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastReadbyte == -1 || lastWritebyte == -1) {
|
||||
lastReadbyte = curReadbyte;
|
||||
lastWritebyte = curWritebyte;
|
||||
return false;
|
||||
}
|
||||
|
||||
*readKB = (float)((double)(curReadbyte - lastReadbyte) / 1024);
|
||||
*writeKB = (float)((double)(curWritebyte - lastWritebyte) / 1024);
|
||||
if (*readKB < 0) *readKB = 0;
|
||||
if (*writeKB < 0) *writeKB = 0;
|
||||
|
||||
lastReadbyte = curReadbyte;
|
||||
lastWritebyte = curWritebyte;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -89,12 +153,33 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
|
|||
}
|
||||
|
||||
bool taosGetProcMemory(float *memoryUsedMB) {
|
||||
*memoryUsedMB = 0;
|
||||
unsigned bytes_used = 0;
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
HANDLE cur_proc = GetCurrentProcess();
|
||||
|
||||
if (GetProcessMemoryInfo(cur_proc, &pmc, sizeof(pmc))) {
|
||||
bytes_used = (unsigned)(pmc.WorkingSetSize + pmc.PagefileUsage);
|
||||
}
|
||||
#endif
|
||||
|
||||
*memoryUsedMB = (float)bytes_used / 1024 / 1024;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool taosGetSysMemory(float *memoryUsedMB) {
|
||||
*memoryUsedMB = 0;
|
||||
MEMORYSTATUSEX memsStat;
|
||||
float nMemFree;
|
||||
float nMemTotal;
|
||||
|
||||
memsStat.dwLength = sizeof(memsStat);
|
||||
if (!GlobalMemoryStatusEx(&memsStat)) {
|
||||
return false;
|
||||
}
|
||||
nMemFree = memsStat.ullAvailPhys / (1024.0f * 1024.0f);
|
||||
nMemTotal = memsStat.ullTotalPhys / (1024.0f * 1024.0f);
|
||||
*memoryUsedMB = nMemTotal - nMemFree;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -103,16 +188,46 @@ int taosSystem(const char *cmd) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int flock(int fd, int option) {
|
||||
return 0;
|
||||
int flock(int fd, int option) { return 0; }
|
||||
|
||||
int fsync(int filedes) { return 0; }
|
||||
|
||||
int sigaction(int sig, struct sigaction *d, void *p) { return 0; }
|
||||
|
||||
LONG WINAPI FlCrashDump(PEXCEPTION_POINTERS ep) {
|
||||
typedef BOOL(WINAPI * FxMiniDumpWriteDump)(IN HANDLE hProcess, IN DWORD ProcessId, IN HANDLE hFile,
|
||||
IN MINIDUMP_TYPE DumpType,
|
||||
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
|
||||
IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
|
||||
|
||||
HMODULE dll = LoadLibrary("dbghelp.dll");
|
||||
if (dll == NULL) return EXCEPTION_CONTINUE_SEARCH;
|
||||
FxMiniDumpWriteDump mdwd = (FxMiniDumpWriteDump)(GetProcAddress(dll, "MiniDumpWriteDump"));
|
||||
if (mdwd == NULL) {
|
||||
FreeLibrary(dll);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
TCHAR path[MAX_PATH];
|
||||
DWORD len = GetModuleFileName(NULL, path, _countof(path));
|
||||
path[len - 3] = 'd';
|
||||
path[len - 2] = 'm';
|
||||
path[len - 1] = 'p';
|
||||
|
||||
HANDLE file = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION mei;
|
||||
mei.ThreadId = GetCurrentThreadId();
|
||||
mei.ExceptionPointers = ep;
|
||||
mei.ClientPointers = FALSE;
|
||||
|
||||
(*mdwd)(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithHandleData, &mei, NULL, NULL);
|
||||
|
||||
CloseHandle(file);
|
||||
FreeLibrary(dll);
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
int fsync(int filedes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigaction(int sig, struct sigaction *d, void *p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taosSetCoreDump() {}
|
||||
void taosSetCoreDump() { SetUnhandledExceptionFilter(&FlCrashDump); }
|
|
@ -70,7 +70,7 @@ bool httpInitContexts() {
|
|||
void httpCleanupContexts() {
|
||||
if (tsHttpServer.contextCache != NULL) {
|
||||
SCacheObj *cache = tsHttpServer.contextCache;
|
||||
httpInfo("context cache is cleanuping, size:%zu", taosHashGetSize(cache->pHashTable));
|
||||
httpInfo("context cache is cleanuping, size:%" PRIzu "", taosHashGetSize(cache->pHashTable));
|
||||
taosCacheCleanup(tsHttpServer.contextCache);
|
||||
tsHttpServer.contextCache = NULL;
|
||||
}
|
||||
|
@ -108,7 +108,8 @@ HttpContext *httpCreateContext(int32_t fd) {
|
|||
pContext->lastAccessTime = taosGetTimestampSec();
|
||||
pContext->state = HTTP_CONTEXT_STATE_READY;
|
||||
|
||||
HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, &pContext, sizeof(int64_t), &pContext, sizeof(int64_t), 3);
|
||||
uint64_t handleVal = (uint64_t)pContext;
|
||||
HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, &handleVal, sizeof(int64_t), &pContext, sizeof(int64_t), 3000);
|
||||
pContext->ppContext = ppContext;
|
||||
httpDebug("context:%p, fd:%d, is created, data:%p", pContext, fd, ppContext);
|
||||
|
||||
|
@ -119,7 +120,8 @@ HttpContext *httpCreateContext(int32_t fd) {
|
|||
}
|
||||
|
||||
HttpContext *httpGetContext(void *ptr) {
|
||||
HttpContext **ppContext = taosCacheAcquireByKey(tsHttpServer.contextCache, &ptr, sizeof(HttpContext *));
|
||||
uint64_t handleVal = (uint64_t)ptr;
|
||||
HttpContext **ppContext = taosCacheAcquireByKey(tsHttpServer.contextCache, &handleVal, sizeof(HttpContext *));
|
||||
|
||||
if (ppContext) {
|
||||
HttpContext *pContext = *ppContext;
|
||||
|
@ -167,8 +169,8 @@ bool httpInitContext(HttpContext *pContext) {
|
|||
memset(pParser, 0, sizeof(HttpParser));
|
||||
pParser->pCur = pParser->pLast = pParser->buffer;
|
||||
|
||||
httpDebug("context:%p, fd:%d, ip:%s, thread:%s, accessTimes:%d, parsed:%d",
|
||||
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->accessTimes, pContext->parsed);
|
||||
httpDebug("context:%p, fd:%d, ip:%s, accessTimes:%d, parsed:%d", pContext, pContext->fd, pContext->ipstr,
|
||||
pContext->accessTimes, pContext->parsed);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ static void *httpAcceptHttpConnection(void *arg) {
|
|||
#if 0
|
||||
if (totalFds > tsHttpCacheSessions * 100) {
|
||||
httpError("fd:%d, ip:%s:%u, totalFds:%d larger than httpCacheSessions:%d*100, refuse connection", connFd,
|
||||
inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port), totalFds, tsHttpCacheSessions);
|
||||
taosInetNtoa(clientAddr.sin_addr), htons(clientAddr.sin_port), totalFds, tsHttpCacheSessions);
|
||||
taosCloseSocket(connFd);
|
||||
continue;
|
||||
}
|
||||
|
@ -316,14 +316,14 @@ static void *httpAcceptHttpConnection(void *arg) {
|
|||
|
||||
pContext = httpCreateContext(connFd);
|
||||
if (pContext == NULL) {
|
||||
httpError("fd:%d, ip:%s:%u, no enough resource to allocate http context", connFd, inet_ntoa(clientAddr.sin_addr),
|
||||
httpError("fd:%d, ip:%s:%u, no enough resource to allocate http context", connFd, taosInetNtoa(clientAddr.sin_addr),
|
||||
htons(clientAddr.sin_port));
|
||||
taosCloseSocket(connFd);
|
||||
continue;
|
||||
}
|
||||
|
||||
pContext->pThread = pThread;
|
||||
sprintf(pContext->ipstr, "%s:%u", inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port));
|
||||
sprintf(pContext->ipstr, "%s:%u", taosInetNtoa(clientAddr.sin_addr), htons(clientAddr.sin_port));
|
||||
|
||||
struct epoll_event event;
|
||||
event.events = EPOLLIN | EPOLLPRI | EPOLLWAKEUP | EPOLLERR | EPOLLHUP | EPOLLRDHUP;
|
||||
|
|
|
@ -34,7 +34,7 @@ void httpCreateSession(HttpContext *pContext, void *taos) {
|
|||
session.refCount = 1;
|
||||
int32_t len = snprintf(session.id, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||
|
||||
pContext->session = taosCachePut(server->sessionCache, session.id, len, &session, sizeof(HttpSession), tsHttpSessionExpire);
|
||||
pContext->session = taosCachePut(server->sessionCache, session.id, len, &session, sizeof(HttpSession), tsHttpSessionExpire * 1000);
|
||||
// void *temp = pContext->session;
|
||||
// taosCacheRelease(server->sessionCache, (void **)&temp, false);
|
||||
|
||||
|
@ -107,7 +107,7 @@ static void httpDestroySession(void *data) {
|
|||
void httpCleanUpSessions() {
|
||||
if (tsHttpServer.sessionCache != NULL) {
|
||||
SCacheObj *cache = tsHttpServer.sessionCache;
|
||||
httpInfo("session cache is cleanuping, size:%zu", taosHashGetSize(cache->pHashTable));
|
||||
httpInfo("session cache is cleanuping, size:%" PRIzu "", taosHashGetSize(cache->pHashTable));
|
||||
taosCacheCleanup(tsHttpServer.sessionCache);
|
||||
tsHttpServer.sessionCache = NULL;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,7 @@ void httpProcessSingleSqlRetrieveCallBack(void *param, TAOS_RES *result, int num
|
|||
}
|
||||
}
|
||||
|
||||
// todo refactor
|
||||
if (tscResultsetFetchCompleted(result)) {
|
||||
isContinue = false;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#define SQL_LENGTH 1024
|
||||
#define LOG_LEN_STR 100
|
||||
#define IP_LEN_STR 18
|
||||
#define IP_LEN_STR TSDB_EP_LEN
|
||||
#define CHECK_INTERVAL 1000
|
||||
|
||||
typedef enum {
|
||||
|
@ -192,7 +192,7 @@ static void dnodeBuildMonitorSql(char *sql, int32_t cmd) {
|
|||
snprintf(sql, SQL_LENGTH,
|
||||
"create table if not exists %s.slowquery(ts timestamp, username "
|
||||
"binary(%d), created_time timestamp, time bigint, sql binary(%d))",
|
||||
tsMonitorDbName, TSDB_TABLE_ID_LEN - 1, TSDB_SLOW_QUERY_SQL_LEN);
|
||||
tsMonitorDbName, TSDB_TABLE_FNAME_LEN - 1, TSDB_SLOW_QUERY_SQL_LEN);
|
||||
} else if (cmd == MONITOR_CMD_CREATE_TB_LOG) {
|
||||
snprintf(sql, SQL_LENGTH,
|
||||
"create table if not exists %s.log(ts timestamp, level tinyint, "
|
||||
|
@ -234,17 +234,22 @@ static void monitorInitDatabaseCb(void *param, TAOS_RES *result, int32_t code) {
|
|||
}
|
||||
|
||||
void monitorStopSystem() {
|
||||
monitorInfo("monitor module is stopped");
|
||||
monitorExecuteSQLFp = NULL;
|
||||
if (tsMonitorConn.state == MONITOR_STATE_STOPPED) return;
|
||||
tsMonitorConn.state = MONITOR_STATE_STOPPED;
|
||||
monitorExecuteSQLFp = NULL;
|
||||
|
||||
monitorInfo("monitor module is stopped");
|
||||
|
||||
if (tsMonitorConn.initTimer != NULL) {
|
||||
taosTmrStopA(&(tsMonitorConn.initTimer));
|
||||
}
|
||||
if (tsMonitorConn.timer != NULL) {
|
||||
taosTmrStopA(&(tsMonitorConn.timer));
|
||||
}
|
||||
|
||||
taos_close(tsMonitorConn.conn);
|
||||
if (tsMonitorConn.conn != NULL) {
|
||||
taos_close(tsMonitorConn.conn);
|
||||
tsMonitorConn.conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void monitorCleanUpSystem() {
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef struct tQueryInfo {
|
|||
SSchema sch; // schema of tags
|
||||
char* q;
|
||||
__compar_fn_t compare; // filter function
|
||||
void* param; // STSchema
|
||||
bool indexed; // indexed columns
|
||||
} tQueryInfo;
|
||||
|
||||
typedef struct SExprTraverseSupp {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue