[TD-3178]<feature> merge develop
This commit is contained in:
commit
543432865e
|
|
@ -27,7 +27,7 @@ for:
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -G "NMake Makefiles" ..
|
- cmake -G "NMake Makefiles" .. -DBUILD_JDBC=false
|
||||||
- nmake install
|
- nmake install
|
||||||
-
|
-
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,6 @@
|
||||||
[submodule "tests/examples/rust"]
|
[submodule "tests/examples/rust"]
|
||||||
path = tests/examples/rust
|
path = tests/examples/rust
|
||||||
url = https://github.com/songtianyi/tdengine-rust-bindings.git
|
url = https://github.com/songtianyi/tdengine-rust-bindings.git
|
||||||
|
[submodule "deps/jemalloc"]
|
||||||
|
path = deps/jemalloc
|
||||||
|
url = https://github.com/jemalloc/jemalloc
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,11 @@ IF (TD_LINUX_64)
|
||||||
MESSAGE(STATUS "linux64 is defined")
|
MESSAGE(STATUS "linux64 is defined")
|
||||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||||
|
|
||||||
|
IF (JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX_32)
|
IF (TD_LINUX_32)
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@ MESSAGE(STATUS "Project binary files output path: " ${PROJECT_BINARY_DIR})
|
||||||
MESSAGE(STATUS "Project executable files output path: " ${EXECUTABLE_OUTPUT_PATH})
|
MESSAGE(STATUS "Project executable files output path: " ${EXECUTABLE_OUTPUT_PATH})
|
||||||
MESSAGE(STATUS "Project library files output path: " ${LIBRARY_OUTPUT_PATH})
|
MESSAGE(STATUS "Project library files output path: " ${LIBRARY_OUTPUT_PATH})
|
||||||
|
|
||||||
FIND_PROGRAM(TD_MVN_INSTALLED mvn)
|
IF (TD_BUILD_JDBC)
|
||||||
IF (TD_MVN_INSTALLED)
|
FIND_PROGRAM(TD_MVN_INSTALLED mvn)
|
||||||
|
IF (TD_MVN_INSTALLED)
|
||||||
MESSAGE(STATUS "MVN is installed and JDBC will be compiled")
|
MESSAGE(STATUS "MVN is installed and JDBC will be compiled")
|
||||||
ELSE ()
|
ELSE ()
|
||||||
MESSAGE(STATUS "MVN is not installed and JDBC is not compiled")
|
MESSAGE(STATUS "MVN is not installed and JDBC is not compiled")
|
||||||
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -72,3 +72,14 @@ IF (${RANDOM_NETWORK_FAIL} MATCHES "true")
|
||||||
SET(TD_RANDOM_NETWORK_FAIL TRUE)
|
SET(TD_RANDOM_NETWORK_FAIL TRUE)
|
||||||
MESSAGE(STATUS "build with random-network-fail enabled")
|
MESSAGE(STATUS "build with random-network-fail enabled")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (${JEMALLOC_ENABLED} MATCHES "true")
|
||||||
|
SET(TD_JEMALLOC_ENABLED TRUE)
|
||||||
|
MESSAGE(STATUS "build with jemalloc enabled")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
SET(TD_BUILD_JDBC TRUE)
|
||||||
|
|
||||||
|
IF (${BUILD_JDBC} MATCHES "false")
|
||||||
|
SET(TD_BUILD_JDBC FALSE)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
||||||
|
|
@ -18,3 +18,16 @@ ENDIF ()
|
||||||
IF (TD_DARWIN AND TD_MQTT)
|
IF (TD_DARWIN AND TD_MQTT)
|
||||||
ADD_SUBDIRECTORY(MQTT-C)
|
ADD_SUBDIRECTORY(MQTT-C)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
MESSAGE("setup dpes/jemalloc, current source dir:" ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
MESSAGE("binary dir:" ${CMAKE_BINARY_DIR})
|
||||||
|
include(ExternalProject)
|
||||||
|
ExternalProject_Add(jemalloc
|
||||||
|
PREFIX "jemalloc"
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jemalloc
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/build/
|
||||||
|
BUILD_COMMAND ${MAKE}
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ea6b3e973b477b8061e0076bb257dbd7f3faa756
|
||||||
|
|
@ -24,7 +24,7 @@ TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。
|
||||||
|
|
||||||
## <a class="anchor" id="start"></a>轻松启动
|
## <a class="anchor" id="start"></a>轻松启动
|
||||||
|
|
||||||
安装成功后,用户可使用`systemctl`命令来启动TDengine的服务进程。
|
安装成功后,用户可使用 `systemctl` 命令来启动 TDengine 的服务进程。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ systemctl start taosd
|
$ systemctl start taosd
|
||||||
|
|
@ -35,21 +35,22 @@ $ systemctl start taosd
|
||||||
$ systemctl status taosd
|
$ systemctl status taosd
|
||||||
```
|
```
|
||||||
|
|
||||||
如果TDengine服务正常工作,那么您可以通过TDengine的命令行程序`taos`来访问并体验TDengine。
|
如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。
|
||||||
|
|
||||||
**注意:**
|
**注意:**
|
||||||
|
|
||||||
- systemctl命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo
|
- systemctl 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 sudo 。
|
||||||
- 为更好的获得产品反馈,改善产品,TDengine会采集基本的使用信息,但您可以修改系统配置文件taos.cfg里的配置参数telemetryReporting, 将其设为0,就可将其关闭。
|
- 为更好的获得产品反馈,改善产品,TDengine 会采集基本的使用信息,但您可以修改系统配置文件 taos.cfg 里的配置参数 telemetryReporting, 将其设为 0,就可将其关闭。
|
||||||
- TDengine采用FQDN(一般就是hostname)作为节点的ID,为保证正常运行,需要给运行taosd的服务器配置好hostname,在客户端应用运行的机器配置好DNS服务或hosts文件,保证FQDN能够解析。
|
- TDengine 采用 FQDN (一般就是 hostname )作为节点的 ID,为保证正常运行,需要给运行 taosd 的服务器配置好 hostname,在客户端应用运行的机器配置好 DNS 服务或 hosts 文件,保证 FQDN 能够解析。
|
||||||
|
- `systemctl stop taosd` 指令在执行后并不会马上停止 TDengine 服务,而是会等待系统中必要的落盘工作正常完成。在数据量很大的情况下,这可能会消耗较长时间。
|
||||||
|
|
||||||
* TDengine 支持在使用[`systemd`](https://en.wikipedia.org/wiki/Systemd)做进程服务管理的linux系统上安装,用`which systemctl`命令来检测系统中是否存在`systemd`包:
|
* TDengine 支持在使用 [`systemd`](https://en.wikipedia.org/wiki/Systemd) 做进程服务管理的 linux 系统上安装,用 `which systemctl` 命令来检测系统中是否存在 `systemd` 包:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ which systemctl
|
$ which systemctl
|
||||||
```
|
```
|
||||||
|
|
||||||
如果系统中不支持systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。
|
如果系统中不支持 systemd,也可以用手动运行 /usr/local/taos/bin/taosd 方式启动 TDengine 服务。
|
||||||
|
|
||||||
|
|
||||||
## <a class="anchor" id="console"></a>TDengine命令行程序
|
## <a class="anchor" id="console"></a>TDengine命令行程序
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,9 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
1. 应用对写请求做基本的合法性检查,通过,则给改请求包打上一个版本号(version, 单调递增)
|
1. 应用对写请求做基本的合法性检查,通过,则给该请求包打上一个版本号(version, 单调递增)
|
||||||
2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
|
2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
|
||||||
3. 应用调用API syncForwardToPeer,如多vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。
|
3. 应用调用API syncForwardToPeer,如果vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。
|
||||||
4. vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理
|
4. vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理
|
||||||
5. vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。
|
5. vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。
|
||||||
6. 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。
|
6. 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。
|
||||||
|
|
@ -219,7 +219,7 @@ Arbitrator的程序tarbitrator.c在复制模块的同一目录, 编译整个系
|
||||||
|
|
||||||
不同之处:
|
不同之处:
|
||||||
|
|
||||||
- 选举流程不一样:Raft里任何一个节点是candidate时,主动向其他节点发出vote request, 如果超过半数回答Yes, 这个candidate就成为Leader,开始一个新的term. 而TDengine的实现里,节点上线、离线或角色改变都会触发状态消息在节点组类传播,等节点组里状态稳定一致之后才触发选举流程,因为状态稳定一致,基于同样的状态信息,每个节点做出的决定会是一致的,一旦某个节点符合成为master的条件,无需其他节点认可,它会自动将自己设为master。TDengine里,任何一个节点检测到其他节点或自己的角色发生改变,就会给节点组内其他节点进行广播的。Raft里不存在这样的机制,因此需要投票来解决。
|
- 选举流程不一样:Raft里任何一个节点是candidate时,主动向其他节点发出vote request,如果超过半数回答Yes,这个candidate就成为Leader,开始一个新的term。而TDengine的实现里,节点上线、离线或角色改变都会触发状态消息在节点组内传播,等节点组里状态稳定一致之后才触发选举流程,因为状态稳定一致,基于同样的状态信息,每个节点做出的决定会是一致的,一旦某个节点符合成为master的条件,无需其他节点认可,它会自动将自己设为master。TDengine里,任何一个节点检测到其他节点或自己的角色发生改变,就会向节点组内其他节点进行广播。Raft里不存在这样的机制,因此需要投票来解决。
|
||||||
- 对WAL的一条记录,Raft用term + index来做唯一标识。但TDengine只用version(类似index),在TDengine实现里,仅仅用version是完全可行的, 因为TDengine的选举机制,没有term的概念。
|
- 对WAL的一条记录,Raft用term + index来做唯一标识。但TDengine只用version(类似index),在TDengine实现里,仅仅用version是完全可行的, 因为TDengine的选举机制,没有term的概念。
|
||||||
|
|
||||||
如果整个虚拟节点组全部宕机,重启,但不是所有虚拟节点都上线,这个时候TDengine是不会选出master的,因为未上线的节点有可能有最高version的数据。而RAFT协议,只要超过半数上线,就会选出Leader。
|
如果整个虚拟节点组全部宕机,重启,但不是所有虚拟节点都上线,这个时候TDengine是不会选出master的,因为未上线的节点有可能有最高version的数据。而RAFT协议,只要超过半数上线,就会选出Leader。
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,7 @@ TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久
|
||||||
|
|
||||||
对于采集的数据,一般有保留时长,这个时长由系统配置参数keep决定。超过这个设置天数的数据文件,将被系统自动删除,释放存储空间。
|
对于采集的数据,一般有保留时长,这个时长由系统配置参数keep决定。超过这个设置天数的数据文件,将被系统自动删除,释放存储空间。
|
||||||
|
|
||||||
给定days与keep两个参数,一个vnode总的数据文件数为:keep/days。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。 目前的版本,参数keep可以修改,但对于参数days,一但设置后,不可修改。
|
给定days与keep两个参数,一个典型工作状态的vnode中总的数据文件数为:`向上取整(keep/days)+1`个。总的数据文件个数不宜过大,也不宜过小。10到100以内合适。基于这个原则,可以设置合理的days。 目前的版本,参数keep可以修改,但对于参数days,一但设置后,不可修改。
|
||||||
|
|
||||||
在每个数据文件里,一张表的数据是一块一块存储的。一张表可以有一到多个数据文件块。在一个文件块里,数据是列式存储的,占用的是一片连续的存储空间,这样大大提高读取速度。文件块的大小由系统参数maxRows(每块最大记录条数)决定,缺省值为4096。这个值不宜过大,也不宜过小。过大,定位具体时间段的数据的搜索时间会变长,影响读取速度;过小,数据块的索引太大,压缩效率偏低,也影响读取速度。
|
在每个数据文件里,一张表的数据是一块一块存储的。一张表可以有一到多个数据文件块。在一个文件块里,数据是列式存储的,占用的是一片连续的存储空间,这样大大提高读取速度。文件块的大小由系统参数maxRows(每块最大记录条数)决定,缺省值为4096。这个值不宜过大,也不宜过小。过大,定位具体时间段的数据的搜索时间会变长,影响读取速度;过小,数据块的索引太大,压缩效率偏低,也影响读取速度。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,9 @@ while(resultSet.next()){
|
||||||
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
|
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
|
||||||
|
|
||||||
### 处理异常
|
### 处理异常
|
||||||
|
|
||||||
在报错后,通过SQLException可以获取到错误的信息和错误码:
|
在报错后,通过SQLException可以获取到错误的信息和错误码:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
try (Statement statement = connection.createStatement()) {
|
try (Statement statement = connection.createStatement()) {
|
||||||
// executeQuery
|
// executeQuery
|
||||||
|
|
@ -279,11 +281,87 @@ try (Statement statement = connection.createStatement()) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
JDBC连接器可能报错的错误码包括3种:JDBC driver本身的报错(错误码在0x2301到0x2350之间),JNI方法的报错(错误码在0x2351到0x2400之间),TDengine其他功能模块的报错。
|
JDBC连接器可能报错的错误码包括3种:JDBC driver本身的报错(错误码在0x2301到0x2350之间),JNI方法的报错(错误码在0x2351到0x2400之间),TDengine其他功能模块的报错。
|
||||||
具体的错误码请参考:
|
具体的错误码请参考:
|
||||||
* https://github.com/taosdata/TDengine/blob/develop/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
|
* https://github.com/taosdata/TDengine/blob/develop/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java
|
||||||
* https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h
|
* https://github.com/taosdata/TDengine/blob/develop/src/inc/taoserror.h
|
||||||
|
|
||||||
|
### <a class="anchor" id="stmt-java"></a>通过参数绑定写入数据
|
||||||
|
|
||||||
|
从 2.1.2.0 版本开始,TDengine 的 **JDBC-JNI** 实现大幅改进了参数绑定方式对数据写入(INSERT)场景的支持。采用这种方式写入数据时,能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。(注意:**JDBC-RESTful** 实现并不提供参数绑定这种使用方式。)
|
||||||
|
|
||||||
|
```java
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
Random r = new Random();
|
||||||
|
|
||||||
|
// INSERT 语句中,VALUES 部分允许指定具体的数据列;如果采取自动建表,则 TAGS 部分需要设定全部 TAGS 列的参数值:
|
||||||
|
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags (?, ?) (ts, c1, c2) values(?, ?, ?)");
|
||||||
|
|
||||||
|
// 设定数据表名:
|
||||||
|
s.setTableName("w1");
|
||||||
|
// 设定 TAGS 取值:
|
||||||
|
s.setTagInt(0, r.nextInt(10));
|
||||||
|
s.setTagString(1, "Beijing");
|
||||||
|
|
||||||
|
int numOfRows = 10;
|
||||||
|
|
||||||
|
// VALUES 部分以逐列的方式进行设置:
|
||||||
|
ArrayList<Long> ts = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numOfRows; i++){
|
||||||
|
ts.add(System.currentTimeMillis() + i);
|
||||||
|
}
|
||||||
|
s.setTimestamp(0, ts);
|
||||||
|
|
||||||
|
ArrayList<Integer> s1 = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numOfRows; i++){
|
||||||
|
s1.add(r.nextInt(100));
|
||||||
|
}
|
||||||
|
s.setInt(1, s1);
|
||||||
|
|
||||||
|
ArrayList<String> s2 = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numOfRows; i++){
|
||||||
|
s2.add("test" + r.nextInt(100));
|
||||||
|
}
|
||||||
|
s.setString(2, s2, 10);
|
||||||
|
|
||||||
|
// AddBatch 之后,可以再设定新的表名、TAGS、VALUES 取值,这样就能实现一次执行向多个数据表写入:
|
||||||
|
s.columnDataAddBatch();
|
||||||
|
// 执行语句:
|
||||||
|
s.columnDataExecuteBatch();
|
||||||
|
// 执行完毕,释放资源:
|
||||||
|
s.columnDataCloseBatch();
|
||||||
|
```
|
||||||
|
|
||||||
|
用于设定 TAGS 取值的方法总共有:
|
||||||
|
```java
|
||||||
|
public void setTagNull(int index, int type)
|
||||||
|
public void setTagBoolean(int index, boolean value)
|
||||||
|
public void setTagInt(int index, int value)
|
||||||
|
public void setTagByte(int index, byte value)
|
||||||
|
public void setTagShort(int index, short value)
|
||||||
|
public void setTagLong(int index, long value)
|
||||||
|
public void setTagTimestamp(int index, long value)
|
||||||
|
public void setTagFloat(int index, float value)
|
||||||
|
public void setTagDouble(int index, double value)
|
||||||
|
public void setTagString(int index, String value)
|
||||||
|
public void setTagNString(int index, String value)
|
||||||
|
```
|
||||||
|
|
||||||
|
用于设定 VALUES 数据列的取值的方法总共有:
|
||||||
|
```java
|
||||||
|
public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException
|
||||||
|
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException
|
||||||
|
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException
|
||||||
|
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException
|
||||||
|
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException
|
||||||
|
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException
|
||||||
|
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException
|
||||||
|
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException
|
||||||
|
public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException
|
||||||
|
public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException
|
||||||
|
```
|
||||||
|
|
||||||
### <a class="anchor" id="subscribe"></a>订阅
|
### <a class="anchor" id="subscribe"></a>订阅
|
||||||
|
|
||||||
#### 创建
|
#### 创建
|
||||||
|
|
|
||||||
|
|
@ -291,9 +291,25 @@ typedef struct taosField {
|
||||||
|
|
||||||
TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
|
TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
|
||||||
|
|
||||||
### 参数绑定API
|
<a class="anchor" id="stmt"></a>
|
||||||
|
### 参数绑定 API
|
||||||
|
|
||||||
除了直接调用 `taos_query` 进行查询,TDengine也提供了支持参数绑定的Prepare API,与 MySQL 一样,这些API目前也仅支持用问号`?`来代表待绑定的参数,具体如下:
|
除了直接调用 `taos_query` 进行查询,TDengine 也提供了支持参数绑定的 Prepare API,与 MySQL 一样,这些 API 目前也仅支持用问号 `?` 来代表待绑定的参数。
|
||||||
|
|
||||||
|
从 2.1.1.0 和 2.1.2.0 版本开始,TDengine 大幅改进了参数绑定接口对数据写入(INSERT)场景的支持。这样在通过参数绑定接口写入数据时,就避免了 SQL 语法解析的资源消耗,从而在绝大多数情况下显著提升写入性能。此时的典型操作步骤如下:
|
||||||
|
1. 调用 `taos_stmt_init` 创建参数绑定对象;
|
||||||
|
2. 调用 `taos_stmt_prepare` 解析 INSERT 语句;
|
||||||
|
3. 如果 INSERT 语句中预留了表名但没有预留 TAGS,那么调用 `taos_stmt_set_tbname` 来设置表名;
|
||||||
|
4. 如果 INSERT 语句中既预留了表名又预留了 TAGS(例如 INSERT 语句采取的是自动建表的方式),那么调用 `taos_stmt_set_tbname_tags` 来设置表名和 TAGS 的值;
|
||||||
|
5. 调用 `taos_stmt_bind_param_batch` 以多列的方式设置 VALUES 的值;
|
||||||
|
6. 调用 `taos_stmt_add_batch` 把当前绑定的参数加入批处理;
|
||||||
|
7. 可以重复第 3~6 步,为批处理加入更多的数据行;
|
||||||
|
8. 调用 `taos_stmt_execute` 执行已经准备好的批处理指令;
|
||||||
|
9. 执行完毕,调用 `taos_stmt_close` 释放所有资源。
|
||||||
|
|
||||||
|
除 C/C++ 语言外,TDengine 的 Java 语言 JNI Connector 也提供参数绑定接口支持,具体请另外参见:[参数绑定接口的 Java 用法](https://www.taosdata.com/cn/documentation/connector/java#stmt-java)。
|
||||||
|
|
||||||
|
接口相关的具体函数如下(也可以参考 [apitest.c](https://github.com/taosdata/TDengine/blob/develop/tests/examples/c/apitest.c) 文件中使用对应函数的方式):
|
||||||
|
|
||||||
- `TAOS_STMT* taos_stmt_init(TAOS *taos)`
|
- `TAOS_STMT* taos_stmt_init(TAOS *taos)`
|
||||||
|
|
||||||
|
|
@ -301,11 +317,12 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
|
||||||
|
|
||||||
- `int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length)`
|
- `int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length)`
|
||||||
|
|
||||||
解析一条sql语句,将解析结果和参数信息绑定到stmt上,如果参数length大于0,将使用此参数作为sql语句的长度,如等于0,将自动判断sql语句的长度。
|
解析一条 SQL 语句,将解析结果和参数信息绑定到 stmt 上,如果参数 length 大于 0,将使用此参数作为 SQL 语句的长度,如等于 0,将自动判断 SQL 语句的长度。
|
||||||
|
|
||||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)`
|
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)`
|
||||||
|
|
||||||
进行参数绑定,bind指向一个数组,需保证此数组的元素数量和顺序与sql语句中的参数完全一致。TAOS_BIND 的使用方法与 MySQL中的 MYSQL_BIND 一致,具体定义如下:
|
不如 `taos_stmt_bind_param_batch` 效率高,但可以支持非 INSERT 类型的 SQL 语句。
|
||||||
|
进行参数绑定,bind 指向一个数组(代表所要绑定的一行数据),需保证此数组中的元素数量和顺序与 SQL 语句中的参数完全一致。TAOS_BIND 的使用方法与 MySQL 中的 MYSQL_BIND 一致,具体定义如下:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
typedef struct TAOS_BIND {
|
typedef struct TAOS_BIND {
|
||||||
|
|
@ -319,9 +336,35 @@ typedef struct TAOS_BIND {
|
||||||
} TAOS_BIND;
|
} TAOS_BIND;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name)`
|
||||||
|
|
||||||
|
(2.1.1.0 版本新增)
|
||||||
|
当 SQL 语句中的表名使用了 `?` 占位时,可以使用此函数绑定一个具体的表名。
|
||||||
|
|
||||||
|
- `int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags)`
|
||||||
|
|
||||||
|
(2.1.2.0 版本新增)
|
||||||
|
当 SQL 语句中的表名和 TAGS 都使用了 `?` 占位时,可以使用此函数绑定具体的表名和具体的 TAGS 取值。最典型的使用场景是使用了自动建表功能的 INSERT 语句(目前版本不支持指定具体的 TAGS 列)。tags 参数中的列数量需要与 SQL 语句中要求的 TAGS 数量完全一致。
|
||||||
|
|
||||||
|
- `int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind)`
|
||||||
|
|
||||||
|
(2.1.1.0 版本新增)
|
||||||
|
以多列的方式传递待绑定的数据,需要保证这里传递的数据列的顺序、列的数量与 SQL 语句中的 VALUES 参数完全一致。TAOS_MULTI_BIND 的具体定义如下:
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct TAOS_MULTI_BIND {
|
||||||
|
int buffer_type;
|
||||||
|
void * buffer;
|
||||||
|
uintptr_t buffer_length;
|
||||||
|
int32_t * length;
|
||||||
|
char * is_null;
|
||||||
|
int num; // 列的个数,即 buffer 中的参数个数
|
||||||
|
} TAOS_MULTI_BIND;
|
||||||
|
```
|
||||||
|
|
||||||
- `int taos_stmt_add_batch(TAOS_STMT *stmt)`
|
- `int taos_stmt_add_batch(TAOS_STMT *stmt)`
|
||||||
|
|
||||||
将当前绑定的参数加入批处理中,调用此函数后,可以再次调用`taos_stmt_bind_param`绑定新的参数。需要注意,此函数仅支持 insert/import 语句,如果是select等其他SQL语句,将返回错误。
|
将当前绑定的参数加入批处理中,调用此函数后,可以再次调用 `taos_stmt_bind_param` 或 `taos_stmt_bind_param_batch` 绑定新的参数。需要注意,此函数仅支持 INSERT/IMPORT 语句,如果是 SELECT 等其他 SQL 语句,将返回错误。
|
||||||
|
|
||||||
- `int taos_stmt_execute(TAOS_STMT *stmt)`
|
- `int taos_stmt_execute(TAOS_STMT *stmt)`
|
||||||
|
|
||||||
|
|
@ -329,7 +372,7 @@ typedef struct TAOS_BIND {
|
||||||
|
|
||||||
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
||||||
|
|
||||||
获取语句的结果集。结果集的使用方式与非参数化调用时一致,使用完成后,应对此结果集调用 `taos_free_result`以释放资源。
|
获取语句的结果集。结果集的使用方式与非参数化调用时一致,使用完成后,应对此结果集调用 `taos_free_result` 以释放资源。
|
||||||
|
|
||||||
- `int taos_stmt_close(TAOS_STMT *stmt)`
|
- `int taos_stmt_close(TAOS_STMT *stmt)`
|
||||||
|
|
||||||
|
|
@ -516,7 +559,7 @@ conn.close()
|
||||||
- _TDengineCursor_ 类
|
- _TDengineCursor_ 类
|
||||||
|
|
||||||
参考python中help(taos.TDengineCursor)。
|
参考python中help(taos.TDengineCursor)。
|
||||||
这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能夸线程共享使用,否则会导致返回结果出现错误。
|
这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。
|
||||||
|
|
||||||
- _connect_ 方法
|
- _connect_ 方法
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ taosd -C
|
||||||
- blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。(可通过 alter database 修改)
|
- blocks:每个VNODE(TSDB)中有多少cache大小的内存块。因此一个VNODE的用的内存大小粗略为(cache * blocks)。单位为块,默认值:4。(可通过 alter database 修改)
|
||||||
- replica:副本个数,取值范围:1-3。单位为个,默认值:1。(可通过 alter database 修改)
|
- replica:副本个数,取值范围:1-3。单位为个,默认值:1。(可通过 alter database 修改)
|
||||||
- precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms。
|
- precision:时间戳精度标识,ms表示毫秒,us表示微秒。默认值:ms。
|
||||||
- cacheLast:是否在内存中缓存子表 last_row,0:关闭;1:开启。默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
|
- cacheLast:是否在内存中缓存子表的最近数据,0:关闭;1:缓存子表最近一行数据;2:缓存子表每一列的最近的非NULL值,3:同时打开缓存最近行和列功能,默认值:0。(可通过 alter database 修改)(从 2.0.11 版本开始支持此参数)
|
||||||
|
|
||||||
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
|
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
| TSDB_CODE_COM_OUT_OF_MEMORY | 0 | 0x0102 | "Out of memory" | -2147483390 |
|
| TSDB_CODE_COM_OUT_OF_MEMORY | 0 | 0x0102 | "Out of memory" | -2147483390 |
|
||||||
| TSDB_CODE_COM_INVALID_CFG_MSG | 0 | 0x0103 | "Invalid config message" | -2147483389 |
|
| TSDB_CODE_COM_INVALID_CFG_MSG | 0 | 0x0103 | "Invalid config message" | -2147483389 |
|
||||||
| TSDB_CODE_COM_FILE_CORRUPTED | 0 | 0x0104 | "Data file corrupted" | -2147483388 |
|
| TSDB_CODE_COM_FILE_CORRUPTED | 0 | 0x0104 | "Data file corrupted" | -2147483388 |
|
||||||
| TSDB_CODE_TSC_INVALID_SQL | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 |
|
| TSDB_CODE_TSC_INVALID_OPERATION | 0 | 0x0200 | "Invalid SQL statement" | -2147483136 |
|
||||||
| TSDB_CODE_TSC_INVALID_QHANDLE | 0 | 0x0201 | "Invalid qhandle" | -2147483135 |
|
| TSDB_CODE_TSC_INVALID_QHANDLE | 0 | 0x0201 | "Invalid qhandle" | -2147483135 |
|
||||||
| TSDB_CODE_TSC_INVALID_TIME_STAMP | 0 | 0x0202 | "Invalid combination of client/service time" | -2147483134 |
|
| TSDB_CODE_TSC_INVALID_TIME_STAMP | 0 | 0x0202 | "Invalid combination of client/service time" | -2147483134 |
|
||||||
| TSDB_CODE_TSC_INVALID_VALUE | 0 | 0x0203 | "Invalid value in client" | -2147483133 |
|
| TSDB_CODE_TSC_INVALID_VALUE | 0 | 0x0203 | "Invalid value in client" | -2147483133 |
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ taos> DESCRIBE meters;
|
||||||
- Epoch Time:时间戳也可以是一个长整数,表示从 1970-01-01 08:00:00.000 开始的毫秒数
|
- Epoch Time:时间戳也可以是一个长整数,表示从 1970-01-01 08:00:00.000 开始的毫秒数
|
||||||
- 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。
|
- 时间可以加减,比如 now-2h,表明查询时刻向前推 2 个小时(最近 2 小时)。数字后面的时间单位可以是 u(微秒)、a(毫秒)、s(秒)、m(分)、h(小时)、d(天)、w(周)。 比如 `select * from t1 where ts > now-2w and ts <= now-1w`,表示查询两周前整整一周的数据。在指定降频操作(down sampling)的时间窗口(interval)时,时间单位还可以使用 n(自然月) 和 y(自然年)。
|
||||||
|
|
||||||
TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableMicrosecond 就可以支持微秒。
|
TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传递的 PRECISION 参数就可以支持微秒。
|
||||||
|
|
||||||
在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。
|
在TDengine中,普通表的数据模型中可使用以下 10 种数据类型。
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
|
|
||||||
4) 一条SQL 语句的最大长度为65480个字符;
|
4) 一条SQL 语句的最大长度为65480个字符;
|
||||||
|
|
||||||
5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/taos-sql#management) 章节。
|
5) 数据库还有更多与存储相关的配置参数,请参见 [服务端配置](https://www.taosdata.com/cn/documentation/administrator#config) 章节。
|
||||||
|
|
||||||
- **显示系统当前参数**
|
- **显示系统当前参数**
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
```mysql
|
```mysql
|
||||||
ALTER DATABASE db_name CACHELAST 0;
|
ALTER DATABASE db_name CACHELAST 0;
|
||||||
```
|
```
|
||||||
CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11 版本开始支持,修改后需要重启服务器生效。)
|
CACHELAST 参数控制是否在内存中缓存数据子表的 last_row。缺省值为 0,取值范围 [0, 1]。其中 0 表示不启用、1 表示启用。(从 2.0.11.0 版本开始支持。从 2.1.1.0 版本开始,修改此参数后无需重启服务器即可生效。)
|
||||||
|
|
||||||
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
|
**Tips**: 以上所有参数修改后都可以用show databases来确认是否修改成功。
|
||||||
|
|
||||||
|
|
@ -400,6 +400,12 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM
|
||||||
tb2_name (tb2_field1_name, ...) [USING stb2_name TAGS (tag_value2, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
tb2_name (tb2_field1_name, ...) [USING stb2_name TAGS (tag_value2, ...)] VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
```
|
```
|
||||||
以自动建表的方式,同时向表tb1_name和tb2_name中按列分别插入多条记录。
|
以自动建表的方式,同时向表tb1_name和tb2_name中按列分别插入多条记录。
|
||||||
|
说明:`(tb1_field1_name, ...)`的部分可以省略掉,这样就是使用全列模式写入——也即在 VALUES 部分提供的数据,必须为数据表的每个列都显式地提供数据。全列写入速度会远快于指定列,因此建议尽可能采用全列写入方式,此时空列可以填入NULL。
|
||||||
|
从 2.0.20.5 版本开始,子表的列名可以不跟在子表名称后面,而是可以放在 TAGS 和 VALUES 之间,例如像下面这样写:
|
||||||
|
```mysql
|
||||||
|
INSERT INTO tb1_name [USING stb1_name TAGS (tag_value1, ...)] (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
|
||||||
|
```
|
||||||
|
注意:虽然两种写法都可以,但并不能在一条 SQL 语句中混用,否则会报语法错误。
|
||||||
|
|
||||||
**历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。
|
**历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。
|
||||||
|
|
||||||
|
|
@ -418,9 +424,9 @@ Query OK, 1 row(s) in set (0.001029s)
|
||||||
taos> SHOW TABLES;
|
taos> SHOW TABLES;
|
||||||
Query OK, 0 row(s) in set (0.000946s)
|
Query OK, 0 row(s) in set (0.000946s)
|
||||||
|
|
||||||
taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2);
|
taos> INSERT INTO d1001 USING meters TAGS('Beijing.Chaoyang', 2) VALUES('a');
|
||||||
|
|
||||||
DB error: invalid SQL: keyword VALUES or FILE required
|
DB error: invalid SQL: 'a' (invalid timestamp) (0.039494s)
|
||||||
|
|
||||||
taos> SHOW TABLES;
|
taos> SHOW TABLES;
|
||||||
table_name | created_time | columns | stable_name |
|
table_name | created_time | columns | stable_name |
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,41 @@ fi
|
||||||
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
||||||
cp ${compile_dir}/build/lib/taos-jdbcdriver*dist.* ${pkg_dir}${install_home_path}/connector ||:
|
cp ${compile_dir}/build/lib/taos-jdbcdriver*.* ${pkg_dir}${install_home_path}/connector ||:
|
||||||
|
|
||||||
|
if [ -f ${compile_dir}/build/bin/jemalloc-config ]; then
|
||||||
|
install_user_local_path="/usr/local"
|
||||||
|
mkdir -p ${pkg_dir}${install_user_local_path}/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3}
|
||||||
|
cp ${compile_dir}/build/bin/jemalloc-config ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
if [ -f ${compile_dir}/build/bin/jemalloc.sh ]; then
|
||||||
|
cp ${compile_dir}/build/bin/jemalloc.sh ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/bin/jeprof ]; then
|
||||||
|
cp ${compile_dir}/build/bin/jeprof ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp ${compile_dir}/build/include/jemalloc/jemalloc.h ${pkg_dir}${install_user_local_path}/include/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
ln -sf libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc.a ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc.a ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc_pic.a ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ${pkg_dir}${install_user_local_path}/lib/pkgconfig/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ${pkg_dir}${install_user_local_path}/share/doc/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp ${compile_dir}/build/share/man/man3/jemalloc.3 ${pkg_dir}${install_user_local_path}/share/man/man3/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cp -r ${compile_dir}/../packaging/deb/DEBIAN ${pkg_dir}/
|
cp -r ${compile_dir}/../packaging/deb/DEBIAN ${pkg_dir}/
|
||||||
chmod 755 ${pkg_dir}/DEBIAN/*
|
chmod 755 ${pkg_dir}/DEBIAN/*
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,12 @@ cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||||
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
||||||
pagMode=full # [full | lite]
|
pagMode=full # [full | lite]
|
||||||
soMode=dynamic # [static | dynamic]
|
soMode=dynamic # [static | dynamic]
|
||||||
|
allocator=glibc # [glibc | jemalloc]
|
||||||
dbName=taos # [taos | power]
|
dbName=taos # [taos | power]
|
||||||
verNumber=""
|
verNumber=""
|
||||||
verNumberComp="2.0.0.0"
|
verNumberComp="2.0.0.0"
|
||||||
|
|
||||||
while getopts "hv:V:c:o:l:s:d:n:m:" arg
|
while getopts "hv:V:c:o:l:s:d:a:n:m:" arg
|
||||||
do
|
do
|
||||||
case $arg in
|
case $arg in
|
||||||
v)
|
v)
|
||||||
|
|
@ -53,6 +54,10 @@ do
|
||||||
#echo "dbName=$OPTARG"
|
#echo "dbName=$OPTARG"
|
||||||
dbName=$(echo $OPTARG)
|
dbName=$(echo $OPTARG)
|
||||||
;;
|
;;
|
||||||
|
a)
|
||||||
|
#echo "allocator=$OPTARG"
|
||||||
|
allocator=$(echo $OPTARG)
|
||||||
|
;;
|
||||||
n)
|
n)
|
||||||
#echo "verNumber=$OPTARG"
|
#echo "verNumber=$OPTARG"
|
||||||
verNumber=$(echo $OPTARG)
|
verNumber=$(echo $OPTARG)
|
||||||
|
|
@ -71,6 +76,7 @@ do
|
||||||
echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] "
|
echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] "
|
||||||
echo " -V [stable | beta] "
|
echo " -V [stable | beta] "
|
||||||
echo " -l [full | lite] "
|
echo " -l [full | lite] "
|
||||||
|
echo " -a [glibc | jemalloc] "
|
||||||
echo " -s [static | dynamic] "
|
echo " -s [static | dynamic] "
|
||||||
echo " -d [taos | power] "
|
echo " -d [taos | power] "
|
||||||
echo " -n [version number] "
|
echo " -n [version number] "
|
||||||
|
|
@ -84,7 +90,7 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} verNumber=${verNumber} verNumberComp=${verNumberComp}"
|
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} allocator=${allocator} verNumber=${verNumber} verNumberComp=${verNumberComp}"
|
||||||
|
|
||||||
curr_dir=$(pwd)
|
curr_dir=$(pwd)
|
||||||
|
|
||||||
|
|
@ -180,12 +186,18 @@ else
|
||||||
fi
|
fi
|
||||||
cd ${compile_dir}
|
cd ${compile_dir}
|
||||||
|
|
||||||
|
if [[ "$allocator" == "jemalloc" ]]; then
|
||||||
|
allocator_macro="-DJEMALLOC_ENABLED=true"
|
||||||
|
else
|
||||||
|
allocator_macro=""
|
||||||
|
fi
|
||||||
|
|
||||||
# check support cpu type
|
# check support cpu type
|
||||||
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
||||||
if [ "$verMode" != "cluster" ]; then
|
if [ "$verMode" != "cluster" ]; then
|
||||||
cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode}
|
cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode} ${allocator_macro}
|
||||||
else
|
else
|
||||||
cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp}
|
cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} ${allocator_macro}
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "input cpuType=${cpuType} error!!!"
|
echo "input cpuType=${cpuType} error!!!"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
%define homepath /usr/local/taos
|
%define homepath /usr/local/taos
|
||||||
|
%define userlocalpath /usr/local
|
||||||
%define cfg_install_dir /etc/taos
|
%define cfg_install_dir /etc/taos
|
||||||
%define __strip /bin/true
|
%define __strip /bin/true
|
||||||
|
|
||||||
|
|
@ -75,9 +76,53 @@ fi
|
||||||
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
||||||
cp %{_compiledir}/build/lib/taos-jdbcdriver*dist.* %{buildroot}%{homepath}/connector ||:
|
cp %{_compiledir}/build/lib/taos-jdbcdriver*.* %{buildroot}%{homepath}/connector ||:
|
||||||
cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples
|
cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f %{_compiledir}/build/bin/jemalloc-config ]; then
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/bin
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/lib
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/lib/pkgconfig
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/include
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/include/jemalloc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/doc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/doc/jemalloc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/man
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/man/man3
|
||||||
|
|
||||||
|
cp %{_compiledir}/build/bin/jemalloc-config %{buildroot}%{userlocalpath}/bin/
|
||||||
|
if [ -f %{_compiledir}/build/bin/jemalloc.sh ]; then
|
||||||
|
cp %{_compiledir}/build/bin/jemalloc.sh %{buildroot}%{userlocalpath}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/bin/jeprof ]; then
|
||||||
|
cp %{_compiledir}/build/bin/jeprof %{buildroot}%{userlocalpath}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp %{_compiledir}/build/include/jemalloc/jemalloc.h %{buildroot}%{userlocalpath}/include/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/
|
||||||
|
ln -sf libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc.a ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc.a %{buildroot}%{userlocalpath}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc_pic.a %{buildroot}%{userlocalpath}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp %{_compiledir}/build/lib/pkgconfig/jemalloc.pc %{buildroot}%{userlocalpath}/lib/pkgconfig/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp %{_compiledir}/build/share/doc/jemalloc/jemalloc.html %{buildroot}%{userlocalpath}/share/doc/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp %{_compiledir}/build/share/man/man3/jemalloc.3 %{buildroot}%{userlocalpath}/share/man/man3/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
#Scripts executed before installation
|
#Scripts executed before installation
|
||||||
%pre
|
%pre
|
||||||
csudo=""
|
csudo=""
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,52 @@ function install_lib() {
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function install_jemalloc() {
|
||||||
|
jemalloc_dir=${script_dir}/jemalloc
|
||||||
|
|
||||||
|
if [ -d ${jemalloc_dir} ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/bin
|
||||||
|
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jemalloc-config ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc-config /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jemalloc.sh ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc.sh /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jeprof ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jeprof /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/include/jemalloc/jemalloc.h ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/include/jemalloc
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/include/jemalloc/jemalloc.h /usr/local/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc.so.2 ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.so.2 /usr/local/lib
|
||||||
|
${csudo} ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc_pic.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib/pkgconfig
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/share/doc/jemalloc
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/share/man/man3/jemalloc.3 ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/share/man/man3
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
||||||
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||||
|
|
@ -776,6 +822,7 @@ function update_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
install_jemalloc
|
||||||
if [ "$pagMode" != "lite" ]; then
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
set -e
|
set -e
|
||||||
# set -x
|
# set -x
|
||||||
|
|
||||||
# -----------------------Variables definition---------------------
|
# -----------------------Variables definition
|
||||||
source_dir=$1
|
source_dir=$1
|
||||||
binary_dir=$2
|
binary_dir=$2
|
||||||
osType=$3
|
osType=$3
|
||||||
|
|
@ -176,6 +176,49 @@ function install_bin() {
|
||||||
[ -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/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
function install_jemalloc() {
|
||||||
|
if [ "$osType" != "Darwin" ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/bin
|
||||||
|
|
||||||
|
if [ -f ${binary_dir}/build/bin/jemalloc-config ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc-config /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/bin/jemalloc.sh ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc.sh /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/bin/jeprof ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jeprof /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/include/jemalloc
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/include/jemalloc/jemalloc.h /usr/local/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/lib
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.so.2 /usr/local/lib
|
||||||
|
ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
|
||||||
|
/usr/bin/install -c -d /usr/local/lib
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc.a ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc_pic.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/lib/pkgconfig
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/share/doc/jemalloc
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/share/man/man3
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function install_lib() {
|
function install_lib() {
|
||||||
# Remove links
|
# Remove links
|
||||||
|
|
@ -199,6 +242,8 @@ function install_lib() {
|
||||||
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
install_jemalloc
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ else
|
||||||
install_dir="${release_dir}/TDengine-server-${version}"
|
install_dir="${release_dir}/TDengine-server-${version}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Directories and files.
|
# Directories and files
|
||||||
if [ "$pagMode" == "lite" ]; then
|
if [ "$pagMode" == "lite" ]; then
|
||||||
strip ${build_dir}/bin/taosd
|
strip ${build_dir}/bin/taosd
|
||||||
strip ${build_dir}/bin/taos
|
strip ${build_dir}/bin/taos
|
||||||
|
|
@ -73,6 +73,39 @@ mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taos
|
||||||
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || :
|
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || :
|
||||||
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || :
|
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || :
|
||||||
|
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc-config ]; then
|
||||||
|
mkdir -p ${install_dir}/jemalloc/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3}
|
||||||
|
cp ${build_dir}/bin/jemalloc-config ${install_dir}/jemalloc/bin
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc.sh ]; then
|
||||||
|
cp ${build_dir}/bin/jemalloc.sh ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/bin/jeprof ]; then
|
||||||
|
cp ${build_dir}/bin/jeprof ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp ${build_dir}/include/jemalloc/jemalloc.h ${install_dir}/jemalloc/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.so.2 ${install_dir}/jemalloc/lib
|
||||||
|
ln -sf libjemalloc.so.2 ${install_dir}/jemalloc/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc_pic.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp ${build_dir}/lib/pkgconfig/jemalloc.pc ${install_dir}/jemalloc/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp ${build_dir}/share/doc/jemalloc/jemalloc.html ${install_dir}/jemalloc/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp ${build_dir}/share/man/man3/jemalloc.3 ${install_dir}/jemalloc/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh
|
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh
|
||||||
mv remove_temp.sh ${install_dir}/bin/remove.sh
|
mv remove_temp.sh ${install_dir}/bin/remove.sh
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TDENGINE_TSCLOCALMERGE_H
|
#ifndef TDENGINE_TSCGLOBALMERGE_H
|
||||||
#define TDENGINE_TSCLOCALMERGE_H
|
#define TDENGINE_TSCGLOBALMERGE_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
#include "qFill.h"
|
#include "qFill.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
#include "tsclient.h"
|
#include "qExecutor.h"
|
||||||
|
|
||||||
#define MAX_NUM_OF_SUBQUERY_RETRY 3
|
#define MAX_NUM_OF_SUBQUERY_RETRY 3
|
||||||
|
|
||||||
|
|
@ -38,40 +38,32 @@ typedef struct SLocalDataSource {
|
||||||
tFilePage filePage;
|
tFilePage filePage;
|
||||||
} SLocalDataSource;
|
} SLocalDataSource;
|
||||||
|
|
||||||
typedef struct SLocalMerger {
|
typedef struct SGlobalMerger {
|
||||||
SLocalDataSource ** pLocalDataSrc;
|
SLocalDataSource **pLocalDataSrc;
|
||||||
int32_t numOfBuffer;
|
int32_t numOfBuffer;
|
||||||
int32_t numOfCompleted;
|
int32_t numOfCompleted;
|
||||||
int32_t numOfVnode;
|
int32_t numOfVnode;
|
||||||
SLoserTreeInfo * pLoserTree;
|
SLoserTreeInfo *pLoserTree;
|
||||||
tFilePage * pResultBuf;
|
|
||||||
int32_t nResultBufSize;
|
|
||||||
tFilePage * pTempBuffer;
|
|
||||||
struct SQLFunctionCtx *pCtx;
|
|
||||||
int32_t rowSize; // size of each intermediate result.
|
int32_t rowSize; // size of each intermediate result.
|
||||||
tOrderDescriptor * pDesc;
|
tOrderDescriptor *pDesc;
|
||||||
SColumnModel * resColModel;
|
tExtMemBuffer **pExtMemBuffer; // disk-based buffer
|
||||||
SColumnModel* finalModel;
|
char *buf; // temp buffer
|
||||||
tExtMemBuffer ** pExtMemBuffer; // disk-based buffer
|
} SGlobalMerger;
|
||||||
bool orderPrjOnSTable; // projection query on stable
|
|
||||||
} SLocalMerger;
|
struct SSqlObj;
|
||||||
|
|
||||||
typedef struct SRetrieveSupport {
|
typedef struct SRetrieveSupport {
|
||||||
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
tExtMemBuffer ** pExtMemBuffer; // for build loser tree
|
||||||
tOrderDescriptor *pOrderDescriptor;
|
tOrderDescriptor *pOrderDescriptor;
|
||||||
SColumnModel* pFinalColModel; // colModel for final result
|
|
||||||
SColumnModel* pFFColModel;
|
|
||||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||||
SSqlObj * pParentSql;
|
struct SSqlObj *pParentSql;
|
||||||
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
||||||
uint32_t numOfRetry; // record the number of retry times
|
uint32_t numOfRetry; // record the number of retry times
|
||||||
} SRetrieveSupport;
|
} SRetrieveSupport;
|
||||||
|
|
||||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc,
|
int32_t tscCreateGlobalMergerEnv(SQueryInfo* pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub, tOrderDescriptor **pDesc, uint32_t nBufferSize, int64_t id);
|
||||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize);
|
|
||||||
|
|
||||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel,
|
void tscDestroyGlobalMergerEnv(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes);
|
||||||
int32_t numOfVnodes);
|
|
||||||
|
|
||||||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||||
int32_t numOfRows, int32_t orderType);
|
int32_t numOfRows, int32_t orderType);
|
||||||
|
|
@ -81,15 +73,13 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
||||||
/*
|
/*
|
||||||
* create local reducer to launch the second-stage reduce process at client site
|
* create local reducer to launch the second-stage reduce process at client site
|
||||||
*/
|
*/
|
||||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
int32_t tscCreateGlobalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||||
SColumnModel *finalModel, SColumnModel *pFFModel, SSqlObj* pSql);
|
SQueryInfo *pQueryInfo, SGlobalMerger **pMerger, int64_t id);
|
||||||
|
|
||||||
void tscDestroyLocalMerger(SSqlObj *pSql);
|
void tscDestroyGlobalMerger(SGlobalMerger* pMerger);
|
||||||
|
|
||||||
//int32_t tscDoLocalMerge(SSqlObj *pSql);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TDENGINE_TSCLOCALMERGE_H
|
#endif // TDENGINE_TSCGLOBALMERGE_H
|
||||||
|
|
@ -25,7 +25,8 @@ extern "C" {
|
||||||
#include "qExtbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tbuffer.h"
|
#include "tbuffer.h"
|
||||||
#include "tscLocalMerge.h"
|
#include "tscGlobalmerge.h"
|
||||||
|
#include "tsched.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
||||||
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
|
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
|
||||||
|
|
@ -36,6 +37,9 @@ extern "C" {
|
||||||
#define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo)\
|
#define UTIL_TABLE_IS_NORMAL_TABLE(metaInfo)\
|
||||||
(!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo)))
|
(!(UTIL_TABLE_IS_SUPER_TABLE(metaInfo) || UTIL_TABLE_IS_CHILD_TABLE(metaInfo)))
|
||||||
|
|
||||||
|
#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \
|
||||||
|
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
// this struct is transfered as binary, padding two bytes to avoid
|
// this struct is transfered as binary, padding two bytes to avoid
|
||||||
// an 'uid' whose low bytes is 0xff being recoginized as NULL,
|
// an 'uid' whose low bytes is 0xff being recoginized as NULL,
|
||||||
|
|
@ -59,7 +63,7 @@ typedef struct SJoinSupporter {
|
||||||
SArray* exprList;
|
SArray* exprList;
|
||||||
SFieldInfo fieldsInfo;
|
SFieldInfo fieldsInfo;
|
||||||
STagCond tagCond;
|
STagCond tagCond;
|
||||||
SSqlGroupbyExpr groupInfo; // group by info
|
SGroupbyExpr groupInfo; // group by info
|
||||||
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
|
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
|
||||||
FILE* f; // temporary file in order to create TSBuf
|
FILE* f; // temporary file in order to create TSBuf
|
||||||
char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory
|
char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory
|
||||||
|
|
@ -90,22 +94,14 @@ typedef struct SVgroupTableInfo {
|
||||||
SArray *itemList; // SArray<STableIdInfo>
|
SArray *itemList; // SArray<STableIdInfo>
|
||||||
} SVgroupTableInfo;
|
} SVgroupTableInfo;
|
||||||
|
|
||||||
static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) {
|
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
||||||
assert(pCmd != NULL && subClauseIndex >= 0);
|
|
||||||
if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pCmd->pQueryInfo[subClauseIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd);
|
|
||||||
|
|
||||||
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
|
||||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta);
|
||||||
void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf);
|
void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf);
|
||||||
|
|
||||||
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
void tscDestroyBoundColumnInfo(SParsedDataColInfo* pColInfo);
|
||||||
|
void doRetrieveSubqueryData(SSchedMsg *pMsg);
|
||||||
|
|
||||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, int16_t bytes,
|
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, int16_t bytes,
|
||||||
uint32_t offset);
|
uint32_t offset);
|
||||||
|
|
@ -114,7 +110,7 @@ void* tscDestroyBlockArrayList(SArray* pDataBlockList);
|
||||||
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta);
|
void* tscDestroyBlockHashTable(SHashObj* pBlockHashTable, bool removeMeta);
|
||||||
|
|
||||||
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock);
|
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock);
|
||||||
int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap);
|
int32_t tscMergeTableDataBlocks(SInsertStatementParam *pInsertParam, bool freeBlockMap);
|
||||||
int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, SName* pName, STableMeta* pTableMeta,
|
int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, int32_t startOffset, int32_t rowSize, SName* pName, STableMeta* pTableMeta,
|
||||||
STableDataBlocks** dataBlocks, SArray* pBlockList);
|
STableDataBlocks** dataBlocks, SArray* pBlockList);
|
||||||
|
|
||||||
|
|
@ -127,7 +123,9 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
||||||
*/
|
*/
|
||||||
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
|
||||||
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
||||||
bool hasTagValOutput(SQueryInfo* pQueryInfo);
|
bool hasTagValOutput(SQueryInfo* pQueryInfo);
|
||||||
|
|
@ -136,13 +134,14 @@ bool isStabledev(SQueryInfo* pQueryInfo);
|
||||||
bool isTsCompQuery(SQueryInfo* pQueryInfo);
|
bool isTsCompQuery(SQueryInfo* pQueryInfo);
|
||||||
bool isSimpleAggregate(SQueryInfo* pQueryInfo);
|
bool isSimpleAggregate(SQueryInfo* pQueryInfo);
|
||||||
bool isBlockDistQuery(SQueryInfo* pQueryInfo);
|
bool isBlockDistQuery(SQueryInfo* pQueryInfo);
|
||||||
int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo);
|
bool isSimpleAggregateRv(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||||
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
|
|
||||||
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
|
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tscHasColumnFilter(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
||||||
|
|
@ -150,9 +149,9 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
bool tscQueryBlockInfo(SQueryInfo* pQueryInfo);
|
bool tscQueryBlockInfo(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
||||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType);
|
SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType, int16_t colId);
|
||||||
|
|
||||||
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql);
|
int32_t tscSetTableFullName(SName* pName, SStrToken* pzTableName, SSqlObj* pSql);
|
||||||
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscIsInsertData(char* sqlstr);
|
bool tscIsInsertData(char* sqlstr);
|
||||||
|
|
@ -171,36 +170,49 @@ void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
||||||
void tscFieldInfoClear(SFieldInfo* pFieldInfo);
|
void tscFieldInfoClear(SFieldInfo* pFieldInfo);
|
||||||
|
void tscFieldInfoCopy(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* pExprList);
|
||||||
|
|
||||||
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
static FORCE_INLINE int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutput; }
|
||||||
|
|
||||||
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize);
|
int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize);
|
||||||
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
||||||
|
|
||||||
|
int32_t tscFieldInfoSetSize(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2);
|
||||||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||||
|
|
||||||
int32_t tscGetResRowLength(SArray* pExprList);
|
int32_t tscGetResRowLength(SArray* pExprList);
|
||||||
|
|
||||||
SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
SExprInfo* tscExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||||
|
|
||||||
SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
SExprInfo* tscExprCreate(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||||
|
int16_t size, int16_t resColId, int16_t interSize, int32_t colType);
|
||||||
|
|
||||||
|
void tscExprAddParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||||
|
|
||||||
|
SExprInfo* tscExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||||
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
int16_t size, int16_t resColId, int16_t interSize, bool isTagCol);
|
||||||
|
|
||||||
SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
SExprInfo* tscExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||||
int16_t size);
|
int16_t size);
|
||||||
size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo);
|
|
||||||
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid);
|
|
||||||
|
|
||||||
SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
size_t tscNumOfExprs(SQueryInfo* pQueryInfo);
|
||||||
int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
SExprInfo *tscExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||||
void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src);
|
int32_t tscExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||||
void tscSqlExprInfoDestroy(SArray* pExprInfo);
|
int32_t tscExprCopyAll(SArray* dst, const SArray* src, bool deepcopy);
|
||||||
|
void tscExprAssign(SExprInfo* dst, const SExprInfo* src);
|
||||||
|
void tscExprDestroy(SArray* pExprInfo);
|
||||||
|
|
||||||
|
int32_t createProjectionExpr(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||||
|
|
||||||
|
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta);
|
||||||
|
|
||||||
SColumn* tscColumnClone(const SColumn* src);
|
SColumn* tscColumnClone(const SColumn* src);
|
||||||
bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid);
|
bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid);
|
||||||
SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
||||||
void tscColumnListDestroy(SArray* pColList);
|
void tscColumnListDestroy(SArray* pColList);
|
||||||
|
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
|
||||||
|
void tscColumnListCopyAll(SArray* dst, const SArray* src);
|
||||||
|
|
||||||
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
|
|
@ -222,14 +234,14 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscShouldBeFreed(SSqlObj* pSql);
|
bool tscShouldBeFreed(SSqlObj* pSql);
|
||||||
|
|
||||||
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex);
|
STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t tableIndex);
|
||||||
STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||||
|
|
||||||
void tscInitQueryInfo(SQueryInfo* pQueryInfo);
|
void tscInitQueryInfo(SQueryInfo* pQueryInfo);
|
||||||
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
||||||
int32_t tscAddQueryInfo(SSqlCmd *pCmd);
|
int32_t tscAddQueryInfo(SSqlCmd *pCmd);
|
||||||
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex);
|
SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd);
|
||||||
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd, int32_t subClauseIndex);
|
SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd);
|
||||||
|
|
||||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
||||||
|
|
||||||
|
|
@ -243,12 +255,11 @@ SArray* tscVgroupTableInfoDup(SArray* pVgroupTables);
|
||||||
void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index);
|
void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index);
|
||||||
void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
||||||
|
|
||||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
|
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||||
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
||||||
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
||||||
|
|
||||||
void tscResetForNextRetrieve(SSqlRes* pRes);
|
void tscResetForNextRetrieve(SSqlRes* pRes);
|
||||||
void tscDoQuery(SSqlObj* pSql);
|
|
||||||
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||||
void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
|
|
@ -275,11 +286,12 @@ void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src);
|
||||||
SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, int32_t cmd);
|
SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, int32_t cmd);
|
||||||
|
|
||||||
void registerSqlObj(SSqlObj* pSql);
|
void registerSqlObj(SSqlObj* pSql);
|
||||||
|
void tscInitResForMerge(SSqlRes* pRes);
|
||||||
|
|
||||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t fp, void* param, int32_t cmd, SSqlObj* pPrevSql);
|
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t fp, void* param, int32_t cmd, SSqlObj* pPrevSql);
|
||||||
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex);
|
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex);
|
||||||
|
|
||||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
|
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex, SSqlCmd* pCmd);
|
||||||
|
|
||||||
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
|
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
|
||||||
int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId);
|
int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId);
|
||||||
|
|
@ -295,6 +307,11 @@ void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
||||||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
||||||
|
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, __async_cb_func_t fp);
|
||||||
|
|
||||||
|
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray);
|
||||||
|
|
||||||
|
bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx);
|
||||||
|
|
||||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||||
void tscClearSqlOwner(SSqlObj* pSql);
|
void tscClearSqlOwner(SSqlObj* pSql);
|
||||||
|
|
@ -309,15 +326,20 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
||||||
uint32_t tscGetTableMetaMaxSize();
|
uint32_t tscGetTableMetaMaxSize();
|
||||||
int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf);
|
int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, void* buf);
|
||||||
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
||||||
|
SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo);
|
||||||
|
|
||||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
||||||
|
|
||||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema);
|
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema);
|
||||||
void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage);
|
||||||
|
|
||||||
void* malloc_throw(size_t size);
|
void* malloc_throw(size_t size);
|
||||||
void* calloc_throw(size_t nmemb, size_t size);
|
void* calloc_throw(size_t nmemb, size_t size);
|
||||||
char* strdup_throw(const char* str);
|
char* strdup_throw(const char* str);
|
||||||
|
|
||||||
|
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src);
|
||||||
|
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_TSCHEMAUTIL_H
|
|
||||||
#define TDENGINE_TSCHEMAUTIL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "taosmsg.h"
|
|
||||||
#include "tsclient.h"
|
|
||||||
#include "ttoken.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the number of tags of this table
|
|
||||||
* @param pTableMeta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int32_t tscGetNumOfTags(const STableMeta* pTableMeta);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the number of columns of this table
|
|
||||||
* @param pTableMeta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int32_t tscGetNumOfColumns(const STableMeta* pTableMeta);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the basic info of this table
|
|
||||||
* @param pTableMeta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
STableComInfo tscGetTableInfo(const STableMeta* pTableMeta);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the schema
|
|
||||||
* @param pTableMeta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
SSchema* tscGetTableSchema(const STableMeta* pTableMeta);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the tag schema
|
|
||||||
* @param pMeta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
SSchema *tscGetTableTagSchema(const STableMeta *pMeta);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the column schema according to the column index
|
|
||||||
* @param pMeta
|
|
||||||
* @param colIndex
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the column schema according to the column id
|
|
||||||
* @param pTableMeta
|
|
||||||
* @param colId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create the table meta from the msg
|
|
||||||
* @param pTableMetaMsg
|
|
||||||
* @param size size of the table meta
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg);
|
|
||||||
|
|
||||||
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src);
|
|
||||||
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TDENGINE_TSCHEMAUTIL_H
|
|
||||||
|
|
@ -40,23 +40,9 @@ extern "C" {
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
struct SSqlInfo;
|
struct SSqlInfo;
|
||||||
struct SLocalMerger;
|
|
||||||
|
|
||||||
// data source from sql string or from file
|
|
||||||
enum {
|
|
||||||
DATA_FROM_SQL_STRING = 1,
|
|
||||||
DATA_FROM_DATA_FILE = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
|
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int32_t numOfRows);
|
||||||
|
|
||||||
typedef struct STableComInfo {
|
|
||||||
uint8_t numOfTags;
|
|
||||||
uint8_t precision;
|
|
||||||
int16_t numOfColumns;
|
|
||||||
int32_t rowSize;
|
|
||||||
} STableComInfo;
|
|
||||||
|
|
||||||
typedef struct SNewVgroupInfo {
|
typedef struct SNewVgroupInfo {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
int8_t inUse;
|
int8_t inUse;
|
||||||
|
|
@ -72,34 +58,6 @@ typedef struct CChildTableMeta {
|
||||||
uint64_t suid; // super table id
|
uint64_t suid; // super table id
|
||||||
} CChildTableMeta;
|
} CChildTableMeta;
|
||||||
|
|
||||||
typedef struct STableMeta {
|
|
||||||
int32_t vgId;
|
|
||||||
STableId id;
|
|
||||||
uint8_t tableType;
|
|
||||||
char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name
|
|
||||||
uint64_t suid; // super table id
|
|
||||||
int16_t sversion;
|
|
||||||
int16_t tversion;
|
|
||||||
STableComInfo tableInfo;
|
|
||||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
|
||||||
} STableMeta;
|
|
||||||
|
|
||||||
typedef struct STableMetaInfo {
|
|
||||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
|
||||||
uint32_t tableMetaSize;
|
|
||||||
SVgroupsInfo *vgroupList;
|
|
||||||
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 1. keep the vgroup index during the multi-vnode super table projection query
|
|
||||||
* 2. keep the vgroup index for multi-vnode insertion
|
|
||||||
*/
|
|
||||||
int32_t vgroupIndex;
|
|
||||||
SName name;
|
|
||||||
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
|
||||||
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
|
||||||
} STableMetaInfo;
|
|
||||||
|
|
||||||
typedef struct SColumnIndex {
|
typedef struct SColumnIndex {
|
||||||
int16_t tableIndex;
|
int16_t tableIndex;
|
||||||
int16_t columnIndex;
|
int16_t columnIndex;
|
||||||
|
|
@ -117,44 +75,6 @@ typedef struct SInternalField {
|
||||||
SExprInfo *pExpr;
|
SExprInfo *pExpr;
|
||||||
} SInternalField;
|
} SInternalField;
|
||||||
|
|
||||||
typedef struct SFieldInfo {
|
|
||||||
int16_t numOfOutput; // number of column in result
|
|
||||||
TAOS_FIELD* final;
|
|
||||||
SArray *internalField; // SArray<SInternalField>
|
|
||||||
} SFieldInfo;
|
|
||||||
|
|
||||||
typedef struct SCond {
|
|
||||||
uint64_t uid;
|
|
||||||
int32_t len; // length of tag query condition data
|
|
||||||
char * cond;
|
|
||||||
} SCond;
|
|
||||||
|
|
||||||
typedef struct SJoinNode {
|
|
||||||
uint64_t uid;
|
|
||||||
int16_t tagColId;
|
|
||||||
SArray* tsJoin;
|
|
||||||
SArray* tagJoin;
|
|
||||||
} SJoinNode;
|
|
||||||
|
|
||||||
typedef struct SJoinInfo {
|
|
||||||
bool hasJoin;
|
|
||||||
SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM];
|
|
||||||
} SJoinInfo;
|
|
||||||
|
|
||||||
typedef struct STagCond {
|
|
||||||
// relation between tbname list and query condition, including : TK_AND or TK_OR
|
|
||||||
int16_t relType;
|
|
||||||
|
|
||||||
// tbname query condition, only support tbname query condition on one table
|
|
||||||
SCond tbnameCond;
|
|
||||||
|
|
||||||
// join condition, only support two tables join currently
|
|
||||||
SJoinInfo joinInfo;
|
|
||||||
|
|
||||||
// for different table, the query condition must be seperated
|
|
||||||
SArray *pCond;
|
|
||||||
} STagCond;
|
|
||||||
|
|
||||||
typedef struct SParamInfo {
|
typedef struct SParamInfo {
|
||||||
int32_t idx;
|
int32_t idx;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
@ -197,92 +117,48 @@ typedef struct STableDataBlocks {
|
||||||
SParamInfo *params;
|
SParamInfo *params;
|
||||||
} STableDataBlocks;
|
} STableDataBlocks;
|
||||||
|
|
||||||
typedef struct SQueryInfo {
|
typedef struct {
|
||||||
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
STableMeta *pTableMeta;
|
||||||
uint32_t type; // query/insert type
|
SVgroupsInfo *pVgroupInfo;
|
||||||
STimeWindow window; // the whole query time window
|
} STableMetaVgroupInfo;
|
||||||
|
|
||||||
SInterval interval; // tumble time window
|
typedef struct SInsertStatementParam {
|
||||||
SSessionWindow sessionWindow; // session time window
|
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||||
|
int32_t numOfTables; // number of tables in table name list
|
||||||
|
SHashObj *pTableBlockHashList; // data block for each table
|
||||||
|
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||||
|
int8_t schemaAttached; // denote if submit block is built with table schema or not
|
||||||
|
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||||
|
|
||||||
SSqlGroupbyExpr groupbyExpr; // groupby tags info
|
int32_t batchSize; // for parameter ('?') binding and batch processing
|
||||||
SArray * colList; // SArray<SColumn*>
|
int32_t numOfParams;
|
||||||
SFieldInfo fieldsInfo;
|
|
||||||
SArray * exprList; // SArray<SExprInfo*>
|
|
||||||
SLimitVal limit;
|
|
||||||
SLimitVal slimit;
|
|
||||||
STagCond tagCond;
|
|
||||||
|
|
||||||
SOrderVal order;
|
char msg[512]; // error message
|
||||||
int16_t fillType; // final result fill type
|
uint32_t insertType; // insert data from [file|sql statement| bound statement]
|
||||||
int16_t numOfTables;
|
uint64_t objectId; // sql object id
|
||||||
STableMetaInfo **pTableMetaInfo;
|
char *sql; // current sql statement position
|
||||||
struct STSBuf *tsBuf;
|
} SInsertStatementParam;
|
||||||
int64_t * fillVal; // default value for fill
|
|
||||||
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
|
||||||
int64_t clauseLimit; // limit for current sub clause
|
|
||||||
|
|
||||||
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
|
|
||||||
int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit
|
|
||||||
|
|
||||||
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
|
||||||
int16_t resColumnId; // result column id
|
|
||||||
bool distinctTag; // distinct tag or not
|
|
||||||
int32_t round; // 0/1/....
|
|
||||||
int32_t bufLen;
|
|
||||||
char* buf;
|
|
||||||
SQInfo* pQInfo; // global merge operator
|
|
||||||
SArray* pDSOperator; // data source operator
|
|
||||||
SArray* pPhyOperator; // physical query execution plan
|
|
||||||
SQueryAttr* pQueryAttr; // query object
|
|
||||||
|
|
||||||
struct SQueryInfo *sibling; // sibling
|
|
||||||
SArray *pUpstream; // SArray<struct SQueryInfo>
|
|
||||||
struct SQueryInfo *pDownstream;
|
|
||||||
int32_t havingFieldNum;
|
|
||||||
} SQueryInfo;
|
|
||||||
|
|
||||||
|
// TODO extract sql parser supporter
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int command;
|
int command;
|
||||||
uint8_t msgType;
|
uint8_t msgType;
|
||||||
|
SInsertStatementParam insertParam;
|
||||||
char reserve1[3]; // fix bus error on arm32
|
char reserve1[3]; // fix bus error on arm32
|
||||||
bool autoCreated; // create table if it is not existed during retrieve table meta in mnode
|
int32_t count; // todo remove it
|
||||||
|
|
||||||
union {
|
|
||||||
int32_t count;
|
|
||||||
int32_t numOfTablesInSubmit;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t insertType; // TODO remove it
|
|
||||||
char * curSql; // current sql, resume position of sql after parsing paused
|
|
||||||
int8_t parseFinished;
|
|
||||||
char reserve2[3]; // fix bus error on arm32
|
char reserve2[3]; // fix bus error on arm32
|
||||||
|
|
||||||
int16_t numOfCols;
|
int16_t numOfCols;
|
||||||
char reserve3[2]; // fix bus error on arm32
|
char reserve3[2]; // fix bus error on arm32
|
||||||
uint32_t allocSize;
|
uint32_t allocSize;
|
||||||
char * payload;
|
char * payload;
|
||||||
int32_t payloadLen;
|
int32_t payloadLen;
|
||||||
|
|
||||||
SQueryInfo **pQueryInfo;
|
SHashObj *pTableMetaMap; // local buffer to keep the queried table meta, before validating the AST
|
||||||
int32_t numOfClause;
|
SQueryInfo *pQueryInfo;
|
||||||
int32_t clauseIndex; // index of multiple subclause query
|
|
||||||
SQueryInfo *active; // current active query info
|
SQueryInfo *active; // current active query info
|
||||||
|
|
||||||
int32_t batchSize; // for parameter ('?') binding and batch processing
|
int32_t batchSize; // for parameter ('?') binding and batch processing
|
||||||
int32_t numOfParams;
|
int32_t resColumnId;
|
||||||
|
|
||||||
int8_t dataSourceType; // load data from file or not
|
|
||||||
char reserve4[3]; // fix bus error on arm32
|
|
||||||
int8_t submitSchema; // submit block is built with table schema
|
|
||||||
char reserve5[3]; // fix bus error on arm32
|
|
||||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
|
||||||
|
|
||||||
SName **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
|
||||||
int32_t numOfTables;
|
|
||||||
|
|
||||||
SHashObj *pTableBlockHashList; // data block for each table
|
|
||||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
|
||||||
} SSqlCmd;
|
} SSqlCmd;
|
||||||
|
|
||||||
typedef struct SResRec {
|
typedef struct SResRec {
|
||||||
|
|
@ -317,7 +193,7 @@ typedef struct {
|
||||||
|
|
||||||
TAOS_FIELD* final;
|
TAOS_FIELD* final;
|
||||||
SArithmeticSupport *pArithSup; // support the arithmetic expression calculation on agg functions
|
SArithmeticSupport *pArithSup; // support the arithmetic expression calculation on agg functions
|
||||||
struct SLocalMerger *pLocalMerger;
|
struct SGlobalMerger *pMerger;
|
||||||
} SSqlRes;
|
} SSqlRes;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -407,6 +283,7 @@ typedef struct SSqlStream {
|
||||||
int64_t ctime; // stream created time
|
int64_t ctime; // stream created time
|
||||||
int64_t stime; // stream next executed time
|
int64_t stime; // stream next executed time
|
||||||
int64_t etime; // stream end query time, when time is larger then etime, the stream will be closed
|
int64_t etime; // stream end query time, when time is larger then etime, the stream will be closed
|
||||||
|
int64_t ltime; // stream last row time in stream table
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
void * pTimer;
|
void * pTimer;
|
||||||
|
|
||||||
|
|
@ -443,8 +320,8 @@ int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||||
void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock);
|
void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock);
|
||||||
|
|
||||||
void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlRes* pOutput);
|
||||||
void destroyTableNameList(SSqlCmd* pCmd);
|
void destroyTableNameList(SInsertStatementParam* pInsertParam);
|
||||||
|
|
||||||
void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
|
void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
|
||||||
|
|
||||||
|
|
@ -476,7 +353,7 @@ void waitForQueryRsp(void *param, TAOS_RES *tres, int code);
|
||||||
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen);
|
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen);
|
||||||
|
|
||||||
void tscImportDataFromFile(SSqlObj *pSql);
|
void tscImportDataFromFile(SSqlObj *pSql);
|
||||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
struct SGlobalMerger* tscInitResObjForLocalQuery(int32_t numOfRes, int32_t rowLen, uint64_t id);
|
||||||
bool tscIsUpdateQuery(SSqlObj* pSql);
|
bool tscIsUpdateQuery(SSqlObj* pSql);
|
||||||
char* tscGetSqlStr(SSqlObj* pSql);
|
char* tscGetSqlStr(SSqlObj* pSql);
|
||||||
bool tscIsQueryWithLimit(SSqlObj* pSql);
|
bool tscIsQueryWithLimit(SSqlObj* pSql);
|
||||||
|
|
@ -486,10 +363,10 @@ void tscSetBoundColumnInfo(SParsedDataColInfo *pColInfo, SSchema *pSchema, int32
|
||||||
|
|
||||||
char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
||||||
|
|
||||||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
int32_t tscInvalidOperationMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||||
int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql);
|
int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* sql);
|
||||||
|
|
||||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||||
|
|
||||||
extern int32_t sentinel;
|
extern int32_t sentinel;
|
||||||
extern SHashObj *tscVgroupMap;
|
extern SHashObj *tscVgroupMap;
|
||||||
|
|
@ -505,7 +382,7 @@ extern int tscNumOfObj; // number of existed sqlObj in current process.
|
||||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||||
|
|
||||||
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||||
int16_t getNewResColId(SQueryInfo* pQueryInfo);
|
int16_t getNewResColId(SSqlCmd* pCmd);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,19 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeBatchImp(J
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
* Method: executeBatchImp
|
* Method: closeStmt
|
||||||
* Signature: (JJ)I
|
* Signature: (JJ)I
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv *env, jobject jobj, jlong stmt, jlong con);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||||
|
* Method: setTableNameTagsImp
|
||||||
|
* Signature: (JLjava/lang/String;I[B[B[B[BJ)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp
|
||||||
|
(JNIEnv *, jobject, jlong, jstring, jint, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jlong);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -749,7 +749,6 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
|
||||||
}
|
}
|
||||||
|
|
||||||
jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name);
|
jniDebug("jobj:%p, conn:%p, set stmt bind table name:%s", jobj, tsconn, name);
|
||||||
|
|
||||||
(*env)->ReleaseStringUTFChars(env, jname, name);
|
(*env)->ReleaseStringUTFChars(env, jname, name);
|
||||||
return JNI_SUCCESS;
|
return JNI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -762,7 +761,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
||||||
return JNI_CONNECTION_NULL;
|
return JNI_CONNECTION_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
TAOS_STMT *pStmt = (TAOS_STMT *)stmt;
|
||||||
if (pStmt == NULL) {
|
if (pStmt == NULL) {
|
||||||
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
jniError("jobj:%p, conn:%p, invalid stmt", jobj, tscon);
|
||||||
return JNI_SQL_NULL;
|
return JNI_SQL_NULL;
|
||||||
|
|
@ -777,14 +776,14 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
||||||
}
|
}
|
||||||
|
|
||||||
len = (*env)->GetArrayLength(env, lengthList);
|
len = (*env)->GetArrayLength(env, lengthList);
|
||||||
char *lengthArray = (char*) calloc(1, len);
|
char *lengthArray = (char *)calloc(1, len);
|
||||||
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte *)lengthArray);
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
len = (*env)->GetArrayLength(env, nullList);
|
len = (*env)->GetArrayLength(env, nullList);
|
||||||
char *nullArray = (char*) calloc(1, len);
|
char *nullArray = (char *)calloc(1, len);
|
||||||
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte *)nullArray);
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -799,23 +798,11 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
|
||||||
b->length = (int32_t*)lengthArray;
|
b->length = (int32_t*)lengthArray;
|
||||||
|
|
||||||
// set the length and is_null array
|
// set the length and is_null array
|
||||||
switch(dataType) {
|
if (!IS_VAR_DATA_TYPE(dataType)) {
|
||||||
case TSDB_DATA_TYPE_INT:
|
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
|
||||||
case TSDB_DATA_TYPE_BIGINT: {
|
|
||||||
int32_t bytes = tDataTypes[dataType].bytes;
|
int32_t bytes = tDataTypes[dataType].bytes;
|
||||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
b->length[i] = bytes;
|
b->length[i] = bytes;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = taos_stmt_bind_single_param_batch(pStmt, b, colIndex);
|
int32_t code = taos_stmt_bind_single_param_batch(pStmt, b, colIndex);
|
||||||
|
|
@ -878,3 +865,74 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeStmt(JNIEnv
|
||||||
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
|
jniDebug("jobj:%p, conn:%p, stmt closed", jobj, tscon);
|
||||||
return JNI_SUCCESS;
|
return JNI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsImp(JNIEnv *env, jobject jobj,
|
||||||
|
jlong stmt, jstring tableName, jint numOfTags, jbyteArray tags, jbyteArray typeList, jbyteArray lengthList, jbyteArray nullList, jlong conn) {
|
||||||
|
TAOS *tsconn = (TAOS *)conn;
|
||||||
|
if (tsconn == NULL) {
|
||||||
|
jniError("jobj:%p, connection already closed", jobj);
|
||||||
|
return JNI_CONNECTION_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STMT* pStmt = (TAOS_STMT*) stmt;
|
||||||
|
if (pStmt == NULL) {
|
||||||
|
jniError("jobj:%p, conn:%p, invalid stmt handle", jobj, tsconn);
|
||||||
|
return JNI_SQL_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsize len = (*env)->GetArrayLength(env, tags);
|
||||||
|
char *tagsData = (char *)calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, tags, 0, len, (jbyte *)tagsData);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
// todo handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (*env)->GetArrayLength(env, lengthList);
|
||||||
|
int64_t *lengthArray = (int64_t*) calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (*env)->GetArrayLength(env, typeList);
|
||||||
|
char *typeArray = (char*) calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, typeList, 0, len, (jbyte*) typeArray);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (*env)->GetArrayLength(env, nullList);
|
||||||
|
int32_t *nullArray = (int32_t*) calloc(1, len);
|
||||||
|
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *name = (*env)->GetStringUTFChars(env, tableName, NULL);
|
||||||
|
char* curTags = tagsData;
|
||||||
|
|
||||||
|
TAOS_BIND *tagsBind = calloc(numOfTags, sizeof(TAOS_BIND));
|
||||||
|
for(int32_t i = 0; i < numOfTags; ++i) {
|
||||||
|
tagsBind[i].buffer_type = typeArray[i];
|
||||||
|
tagsBind[i].buffer = curTags;
|
||||||
|
tagsBind[i].is_null = &nullArray[i];
|
||||||
|
tagsBind[i].length = (uintptr_t*) &lengthArray[i];
|
||||||
|
|
||||||
|
curTags += lengthArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = taos_stmt_set_tbname_tags((void*)stmt, name, tagsBind);
|
||||||
|
|
||||||
|
int32_t nTags = (int32_t) numOfTags;
|
||||||
|
jniDebug("jobj:%p, conn:%p, set table name:%s, numOfTags:%d", jobj, tsconn, name, nTags);
|
||||||
|
|
||||||
|
tfree(tagsData);
|
||||||
|
tfree(lengthArray);
|
||||||
|
tfree(typeArray);
|
||||||
|
tfree(nullArray);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, tableName, name);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
|
||||||
|
return JNI_TDENGINE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JNI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tsched.h"
|
#include "tsched.h"
|
||||||
#include "tschemautil.h"
|
#include "qTableMeta.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
||||||
static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
|
|
@ -58,7 +58,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
||||||
strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen);
|
strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen);
|
||||||
|
|
||||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
pCmd->curSql = pSql->sqlstr;
|
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||||
|
|
||||||
int32_t code = tsParseSql(pSql, true);
|
int32_t code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return;
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) return;
|
||||||
|
|
@ -69,7 +69,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
executeQuery(pSql, pQueryInfo);
|
executeQuery(pSql, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +127,8 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
|
||||||
* all available virtual node has been checked already, now we need to check
|
* all available virtual node has been checked already, now we need to check
|
||||||
* for the next subclause queries
|
* for the next subclause queries
|
||||||
*/
|
*/
|
||||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
if (pCmd->active->sibling != NULL) {
|
||||||
|
pCmd->active = pCmd->active->sibling;
|
||||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +220,18 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
||||||
|
|
||||||
tscResetForNextRetrieve(pRes);
|
tscResetForNextRetrieve(pRes);
|
||||||
|
|
||||||
// handle the sub queries of join query
|
// handle outer query based on the already retrieved nest query results.
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) {
|
||||||
|
SSchedMsg schedMsg = {0};
|
||||||
|
schedMsg.fp = doRetrieveSubqueryData;
|
||||||
|
schedMsg.ahandle = (void *)pSql;
|
||||||
|
schedMsg.thandle = (void *)1;
|
||||||
|
schedMsg.msg = 0;
|
||||||
|
taosScheduleTask(tscQhandle, &schedMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||||
tscFetchDatablockForSubquery(pSql);
|
tscFetchDatablockForSubquery(pSql);
|
||||||
} else if (pRes->completed) {
|
} else if (pRes->completed) {
|
||||||
|
|
@ -231,7 +243,8 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
||||||
* all available virtual nodes in current clause has been checked already, now try the
|
* all available virtual nodes in current clause has been checked already, now try the
|
||||||
* next one in the following union subclause
|
* next one in the following union subclause
|
||||||
*/
|
*/
|
||||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
if (pCmd->active->sibling != NULL) {
|
||||||
|
pCmd->active = pCmd->active->sibling; // todo refactor
|
||||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +268,7 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
||||||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd);
|
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(&pSql->cmd);
|
||||||
tscBuildAndSendRequest(pSql, pQueryInfo1);
|
tscBuildAndSendRequest(pSql, pQueryInfo1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -317,27 +330,39 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM
|
||||||
// update the pExpr info, colList info, number of table columns
|
// update the pExpr info, colList info, number of table columns
|
||||||
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
|
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
|
||||||
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
|
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
|
||||||
int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||||
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||||
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
SSchema *pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||||
SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base);
|
SSqlExpr *pExpr = &(tscExprGet(pQueryInfo, i)->base);
|
||||||
|
|
||||||
|
// update the table uid
|
||||||
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
|
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||||
|
|
||||||
if (pExpr->colInfo.colIndex >= 0) {
|
if (pExpr->colInfo.colIndex >= 0) {
|
||||||
int32_t index = pExpr->colInfo.colIndex;
|
int32_t index = pExpr->colInfo.colIndex;
|
||||||
|
|
||||||
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
|
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
|
||||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < numOfCols || index >= (numOfCols + numOfTags)))) {
|
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < 0 || index >= numOfTags))) {
|
||||||
return pSql->retryReason;
|
return pSql->retryReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||||
|
if ((pTagSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||||
|
strcasecmp(pExpr->colInfo.name, pTagSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||||
|
return pSql->retryReason;
|
||||||
|
}
|
||||||
|
} else if (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag)) {
|
||||||
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||||
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||||
return pSql->retryReason;
|
return pSql->retryReason;
|
||||||
}
|
}
|
||||||
|
} else { // do nothing for udc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,12 +399,12 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg);
|
tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg);
|
||||||
if (pSql->pStream == NULL) {
|
if (pSql->pStream == NULL) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
|
||||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send the corresponding query", pSql->self);
|
TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||||
|
tscDebug("0x%" PRIx64 " update cached table-meta, continue to process sql and send the corresponding query", pSql->self);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
|
|
@ -401,42 +426,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
return;
|
return;
|
||||||
} else { // continue to process normal async query
|
} else { // continue to process normal async query
|
||||||
if (pCmd->parseFinished) {
|
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||||
tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send corresponding query", pSql->self);
|
tscDebug("0x%" PRIx64 " continue parse sql after get table-meta", pSql->self);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
|
||||||
|
|
||||||
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS);
|
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pCmd->command != TSDB_SQL_INSERT);
|
|
||||||
|
|
||||||
if (pCmd->command == TSDB_SQL_SELECT) {
|
|
||||||
tscDebug("0x%"PRIx64" redo parse sql string and proceed", pSql->self);
|
|
||||||
pCmd->parseFinished = false;
|
|
||||||
tscResetSqlCmd(pCmd, true);
|
|
||||||
|
|
||||||
code = tsParseSql(pSql, true);
|
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
|
||||||
return;
|
|
||||||
} else if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
goto _error;
|
|
||||||
}
|
|
||||||
|
|
||||||
tscBuildAndSendRequest(pSql, NULL);
|
|
||||||
} else { // in all other cases, simple retry
|
|
||||||
tscBuildAndSendRequest(pSql, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
tscDebug("0x%"PRIx64" continue parse sql after get table meta", pSql->self);
|
|
||||||
|
|
||||||
code = tsParseSql(pSql, false);
|
code = tsParseSql(pSql, false);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
|
@ -446,8 +437,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) {
|
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
|
@ -457,59 +448,52 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(*pSql->fp)(pSql->param, pSql, code);
|
(*pSql->fp)(pSql->param, pSql, code);
|
||||||
} else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
} else {
|
||||||
if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) {
|
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||||
tscImportDataFromFile(pSql);
|
tscImportDataFromFile(pSql);
|
||||||
} else {
|
} else {
|
||||||
tscHandleMultivnodeInsert(pSql);
|
tscHandleMultivnodeInsert(pSql);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
if (pSql->retryReason != TSDB_CODE_SUCCESS) {
|
||||||
|
tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again",
|
||||||
|
pSql->self);
|
||||||
|
tscResetSqlCmd(pCmd, false);
|
||||||
|
pSql->retryReason = TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
|
tscDebug("0x%" PRIx64 " cached table-meta, continue validate sql statement and send query", pSql->self);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tsParseSql(pSql, true);
|
||||||
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
return;
|
||||||
|
} else if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd);
|
||||||
executeQuery(pSql, pQueryInfo1);
|
executeQuery(pSql, pQueryInfo1);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} else { // stream computing
|
} else { // stream computing
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pCmd->command);
|
||||||
|
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (tscNumOfExprs(pQueryInfo) == 0) {
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
|
||||||
return;
|
|
||||||
} else if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
goto _error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
|
||||||
code = tscGetSTableVgroupInfo(pSql, pCmd->clauseIndex);
|
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
|
||||||
return;
|
|
||||||
} else if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
goto _error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pSql->cmd.command);
|
|
||||||
if (!pSql->cmd.parseFinished) {
|
|
||||||
tsParseSql(pSql, false);
|
tsParseSql(pSql, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*pSql->fp)(pSql->param, pSql, code);
|
(*pSql->fp)(pSql->param, pSql, code);
|
||||||
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tscDoQuery(pSql);
|
|
||||||
|
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_error:
|
_error:
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,19 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tscLocalMerge.h"
|
|
||||||
#include "tscSubquery.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "texpr.h"
|
#include "texpr.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
|
|
||||||
|
#include "tscGlobalmerge.h"
|
||||||
|
#include "tscSubquery.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscUtil.h"
|
|
||||||
#include "tschemautil.h"
|
|
||||||
#include "tsclient.h"
|
|
||||||
#include "qUtil.h"
|
#include "qUtil.h"
|
||||||
|
|
||||||
|
#define COLMODEL_GET_VAL(data, schema, rowId, colId) \
|
||||||
|
(data + (schema)->pFields[colId].offset * ((schema)->capacity) + (rowId) * (schema)->pFields[colId].field.bytes)
|
||||||
|
|
||||||
|
|
||||||
typedef struct SCompareParam {
|
typedef struct SCompareParam {
|
||||||
SLocalDataSource **pLocalData;
|
SLocalDataSource **pLocalData;
|
||||||
tOrderDescriptor * pDesc;
|
tOrderDescriptor * pDesc;
|
||||||
|
|
@ -31,9 +33,18 @@ typedef struct SCompareParam {
|
||||||
int32_t groupOrderType;
|
int32_t groupOrderType;
|
||||||
} SCompareParam;
|
} SCompareParam;
|
||||||
|
|
||||||
bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndex, int32_t index, char **buf);
|
static bool needToMerge(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) {
|
||||||
|
int32_t ret = 0;
|
||||||
|
size_t size = taosArrayGetSize(columnIndexList);
|
||||||
|
if (size > 0) {
|
||||||
|
ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
// if ret == 0, means the result belongs to the same group
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
||||||
int32_t pLeftIdx = *(int32_t *)pLeft;
|
int32_t pLeftIdx = *(int32_t *)pLeft;
|
||||||
int32_t pRightIdx = *(int32_t *)pRight;
|
int32_t pRightIdx = *(int32_t *)pRight;
|
||||||
|
|
||||||
|
|
@ -59,77 +70,25 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo merge with vnode side function
|
int32_t tscCreateGlobalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
||||||
void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema) {
|
SQueryInfo* pQueryInfo, SGlobalMerger **pMerger, int64_t id) {
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
|
||||||
|
|
||||||
pCtx[i].order = pQueryInfo->order.order;
|
|
||||||
pCtx[i].functionId = pExpr->base.functionId;
|
|
||||||
|
|
||||||
pCtx[i].order = pQueryInfo->order.order;
|
|
||||||
pCtx[i].functionId = pExpr->base.functionId;
|
|
||||||
|
|
||||||
// input data format comes from pModel
|
|
||||||
pCtx[i].inputType = pSchema[i].type;
|
|
||||||
pCtx[i].inputBytes = pSchema[i].bytes;
|
|
||||||
|
|
||||||
pCtx[i].outputBytes = pExpr->base.resBytes;
|
|
||||||
pCtx[i].outputType = pExpr->base.resType;
|
|
||||||
|
|
||||||
// input buffer hold only one point data
|
|
||||||
pCtx[i].size = 1;
|
|
||||||
pCtx[i].hasNull = true;
|
|
||||||
pCtx[i].currentStage = MERGE_STAGE;
|
|
||||||
|
|
||||||
// for top/bottom function, the output of timestamp is the first column
|
|
||||||
int32_t functionId = pExpr->base.functionId;
|
|
||||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) {
|
|
||||||
pCtx[i].ptsOutputBuf = pCtx[0].pOutput;
|
|
||||||
pCtx[i].param[2].i64 = pQueryInfo->order.order;
|
|
||||||
pCtx[i].param[2].nType = TSDB_DATA_TYPE_BIGINT;
|
|
||||||
pCtx[i].param[1].i64 = pQueryInfo->order.orderColId;
|
|
||||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64; // top/bot parameter
|
|
||||||
} else if (functionId == TSDB_FUNC_APERCT) {
|
|
||||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
|
||||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
|
||||||
} else if (functionId == TSDB_FUNC_BLKINFO) {
|
|
||||||
pCtx[i].param[0].i64 = pExpr->base.param[0].i64;
|
|
||||||
pCtx[i].param[0].nType = pExpr->base.param[0].nType;
|
|
||||||
pCtx[i].numOfParams = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pCtx[i].interBufBytes = pExpr->base.interBytes;
|
|
||||||
pCtx[i].stableQuery = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc,
|
|
||||||
SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) {
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
|
||||||
SSqlRes* pRes = &pSql->res;
|
|
||||||
|
|
||||||
if (pMemBuffer == NULL) {
|
if (pMemBuffer == NULL) {
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
tscError("pMemBuffer:%p is NULL", pMemBuffer);
|
tscError("0x%"PRIx64" %p pMemBuffer is NULL", id, pMemBuffer);
|
||||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDesc->pColumnModel == NULL) {
|
if (pDesc->pColumnModel == NULL) {
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
tscError("0x%"PRIx64" no local buffer or intermediate result format model", pSql->self);
|
tscError("0x%"PRIx64" no local buffer or intermediate result format model", id);
|
||||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfFlush = 0;
|
int32_t numOfFlush = 0;
|
||||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||||
int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", pSql->self, i + 1);
|
tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", id, i + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,41 +96,36 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
|
tscDebug("0x%"PRIx64" no data to retrieve", id);
|
||||||
tscDebug("0x%"PRIx64" retrieved no data", pSql->self);
|
return TSDB_CODE_SUCCESS;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) {
|
if (pDesc->pColumnModel->capacity >= pMemBuffer[0]->pageSize) {
|
||||||
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", pSql->self, pDesc->pColumnModel->capacity,
|
tscError("0x%"PRIx64" Invalid value of buffer capacity %d and page size %d ", id, pDesc->pColumnModel->capacity,
|
||||||
pMemBuffer[0]->pageSize);
|
pMemBuffer[0]->pageSize);
|
||||||
|
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
pRes->code = TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush;
|
*pMerger = (SGlobalMerger *) calloc(1, sizeof(SGlobalMerger));
|
||||||
|
if ((*pMerger) == NULL) {
|
||||||
|
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", id);
|
||||||
|
|
||||||
SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size);
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
if (pMerger == NULL) {
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscError("0x%"PRIx64" failed to create local merge structure, out of memory", pSql->self);
|
|
||||||
|
|
||||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pMerger->pExtMemBuffer = pMemBuffer;
|
(*pMerger)->pExtMemBuffer = pMemBuffer;
|
||||||
pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1];
|
(*pMerger)->pLocalDataSrc = calloc(numOfFlush, POINTER_BYTES);
|
||||||
assert(pMerger->pLocalDataSrc != NULL);
|
assert((*pMerger)->pLocalDataSrc != NULL);
|
||||||
|
|
||||||
pMerger->numOfBuffer = numOfFlush;
|
(*pMerger)->numOfBuffer = numOfFlush;
|
||||||
pMerger->numOfVnode = numOfBuffer;
|
(*pMerger)->numOfVnode = numOfBuffer;
|
||||||
|
|
||||||
pMerger->pDesc = pDesc;
|
(*pMerger)->pDesc = pDesc;
|
||||||
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer);
|
tscDebug("0x%"PRIx64" the number of merged leaves is: %d", id, (*pMerger)->numOfBuffer);
|
||||||
|
|
||||||
int32_t idx = 0;
|
int32_t idx = 0;
|
||||||
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
for (int32_t i = 0; i < numOfBuffer; ++i) {
|
||||||
|
|
@ -180,13 +134,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
||||||
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
for (int32_t j = 0; j < numOfFlushoutInFile; ++j) {
|
||||||
SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
||||||
if (ds == NULL) {
|
if (ds == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to create merge structure", pSql->self);
|
tscError("0x%"PRIx64" failed to create merge structure", id);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
tfree(pMerger);
|
tfree(pMerger);
|
||||||
return;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMerger->pLocalDataSrc[idx] = ds;
|
(*pMerger)->pLocalDataSrc[idx] = ds;
|
||||||
|
|
||||||
ds->pMemBuffer = pMemBuffer[i];
|
ds->pMemBuffer = pMemBuffer[i];
|
||||||
ds->flushoutIdx = j;
|
ds->flushoutIdx = j;
|
||||||
|
|
@ -194,12 +147,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
||||||
ds->pageId = 0;
|
ds->pageId = 0;
|
||||||
ds->rowIdx = 0;
|
ds->rowIdx = 0;
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", pSql->self, i + 1, idx + 1);
|
tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", id, i + 1, idx + 1);
|
||||||
tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0);
|
tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0);
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num);
|
printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num);
|
||||||
SSrcColumnInfo colInfo[256] = {0};
|
SSrcColumnInfo colInfo[256] = {0};
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||||
|
|
||||||
|
|
@ -208,7 +161,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ds->filePage.num == 0) { // no data in this flush, the index does not increase
|
if (ds->filePage.num == 0) { // no data in this flush, the index does not increase
|
||||||
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", pSql->self, idx);
|
tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", id, idx);
|
||||||
tfree(ds);
|
tfree(ds);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -219,115 +172,54 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde
|
||||||
|
|
||||||
// no data actually, no need to merge result.
|
// no data actually, no need to merge result.
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
tfree(pMerger);
|
tscDebug("0x%"PRIx64" retrieved no data", id);
|
||||||
return;
|
tscDestroyGlobalMergerEnv(pMemBuffer, pDesc, numOfBuffer);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMerger->numOfBuffer = idx;
|
(*pMerger)->numOfBuffer = idx;
|
||||||
|
|
||||||
SCompareParam *param = malloc(sizeof(SCompareParam));
|
SCompareParam *param = malloc(sizeof(SCompareParam));
|
||||||
if (param == NULL) {
|
if (param == NULL) {
|
||||||
tfree(pMerger);
|
tfree((*pMerger));
|
||||||
return;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
param->pLocalData = pMerger->pLocalDataSrc;
|
param->pLocalData = (*pMerger)->pLocalDataSrc;
|
||||||
param->pDesc = pMerger->pDesc;
|
param->pDesc = (*pMerger)->pDesc;
|
||||||
param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
param->num = (*pMerger)->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
|
||||||
|
|
||||||
param->groupOrderType = pQueryInfo->groupbyExpr.orderType;
|
param->groupOrderType = pQueryInfo->groupbyExpr.orderType;
|
||||||
pMerger->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
|
|
||||||
|
|
||||||
pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator);
|
int32_t code = tLoserTreeCreate(&(*pMerger)->pLoserTree, (*pMerger)->numOfBuffer, param, treeComparator);
|
||||||
if (pMerger->pLoserTree == NULL || pRes->code != 0) {
|
if ((*pMerger)->pLoserTree == NULL || code != TSDB_CODE_SUCCESS) {
|
||||||
tfree(param);
|
tfree(param);
|
||||||
tfree(pMerger);
|
tfree((*pMerger));
|
||||||
return;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the input data format follows the old format, but output in a new format.
|
(*pMerger)->rowSize = pMemBuffer[0]->nElemSize;
|
||||||
// so, all the input must be parsed as old format
|
|
||||||
pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx));
|
|
||||||
pMerger->rowSize = pMemBuffer[0]->nElemSize;
|
|
||||||
|
|
||||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
// todo fixed row size is larger than the minimum page size;
|
||||||
|
assert((*pMerger)->rowSize <= pMemBuffer[0]->pageSize);
|
||||||
|
|
||||||
if (pMerger->rowSize > pMemBuffer[0]->pageSize) {
|
if ((*pMerger)->pLoserTree == NULL) {
|
||||||
assert(false); // todo fixed row size is larger than the minimum page size;
|
tfree((*pMerger)->pLoserTree);
|
||||||
}
|
|
||||||
|
|
||||||
// used to keep the latest input row
|
|
||||||
pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage));
|
|
||||||
|
|
||||||
pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
|
||||||
pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage));
|
|
||||||
|
|
||||||
pMerger->resColModel = finalmodel;
|
|
||||||
pMerger->resColModel->capacity = pMerger->nResultBufSize;
|
|
||||||
pMerger->finalModel = pFFModel;
|
|
||||||
|
|
||||||
if (finalmodel->rowSize > 0) {
|
|
||||||
pMerger->resColModel->capacity /= finalmodel->rowSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize);
|
|
||||||
|
|
||||||
if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) {
|
|
||||||
tfree(pMerger->pTempBuffer);
|
|
||||||
tfree(pMerger->pLoserTree);
|
|
||||||
tfree(param);
|
tfree(param);
|
||||||
tfree(pMerger);
|
tfree((*pMerger));
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pMerger->pTempBuffer->num = 0;
|
|
||||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
|
||||||
|
|
||||||
SSchema* pschema = calloc(pDesc->pColumnModel->numOfCols, sizeof(SSchema));
|
|
||||||
for(int32_t i = 0; i < pDesc->pColumnModel->numOfCols; ++i) {
|
|
||||||
pschema[i] = pDesc->pColumnModel->pFields[i].field;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsCreateSQLFunctionCtx(pQueryInfo, pMerger->pCtx, pschema);
|
|
||||||
// setCtxInputOutputBuffer(pQueryInfo, pMerger->pCtx, pMerger, pDesc);
|
|
||||||
|
|
||||||
tfree(pschema);
|
|
||||||
|
|
||||||
int32_t maxBufSize = 0;
|
|
||||||
for (int32_t k = 0; k < tscSqlExprNumOfExprs(pQueryInfo); ++k) {
|
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, k);
|
|
||||||
if (maxBufSize < pExpr->base.resBytes && pExpr->base.functionId == TSDB_FUNC_TAG) {
|
|
||||||
maxBufSize = pExpr->base.resBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
|
||||||
pMerger->pDesc->pColumnModel->capacity = 1;
|
|
||||||
|
|
||||||
// restore the limitation value at the last stage
|
// restore the limitation value at the last stage
|
||||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (pQueryInfo->orderProjectQuery) {
|
||||||
pQueryInfo->limit.limit = pQueryInfo->clauseLimit;
|
pQueryInfo->limit.limit = pQueryInfo->clauseLimit;
|
||||||
pQueryInfo->limit.offset = pQueryInfo->prjOffset;
|
pQueryInfo->limit.offset = pQueryInfo->prjOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRes->pLocalMerger = pMerger;
|
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||||
pRes->numOfGroups = 0;
|
(*pMerger)->pDesc->pColumnModel->capacity = 1;
|
||||||
|
|
||||||
// STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
return TSDB_CODE_SUCCESS;
|
||||||
// STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
|
||||||
|
|
||||||
// TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey;
|
|
||||||
// int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision);
|
|
||||||
|
|
||||||
// if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
|
||||||
// SFillColInfo* pFillCol = createFillColInfo(pQueryInfo);
|
|
||||||
// pMerger->pFillInfo =
|
|
||||||
// taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, 4096,
|
|
||||||
// (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding,
|
|
||||||
// pQueryInfo->interval.slidingUnit, tinfo.precision, pQueryInfo->fillType, pFillCol, pSql);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage,
|
static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage,
|
||||||
|
|
@ -418,51 +310,39 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscDestroyLocalMerger(SSqlObj *pSql) {
|
void tscDestroyGlobalMerger(SGlobalMerger* pMerger) {
|
||||||
if (pSql == NULL) {
|
if (pMerger == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlRes *pRes = &(pSql->res);
|
for (int32_t i = 0; i < pMerger->numOfBuffer; ++i) {
|
||||||
if (pRes->pLocalMerger == NULL) {
|
tfree(pMerger->pLocalDataSrc[i]);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no more result, so we release all allocated resource
|
pMerger->numOfBuffer = 0;
|
||||||
SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL);
|
tscDestroyGlobalMergerEnv(pMerger->pExtMemBuffer, pMerger->pDesc, pMerger->numOfVnode);
|
||||||
tfree(pLocalMerge->pResultBuf);
|
|
||||||
tfree(pLocalMerge->pCtx);
|
|
||||||
|
|
||||||
if (pLocalMerge->pLoserTree) {
|
pMerger->numOfCompleted = 0;
|
||||||
tfree(pLocalMerge->pLoserTree->param);
|
|
||||||
tfree(pLocalMerge->pLoserTree);
|
if (pMerger->pLoserTree) {
|
||||||
|
tfree(pMerger->pLoserTree->param);
|
||||||
|
tfree(pMerger->pLoserTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel,
|
tfree(pMerger->buf);
|
||||||
pLocalMerge->finalModel, pLocalMerge->numOfVnode);
|
tfree(pMerger->pLocalDataSrc);
|
||||||
for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) {
|
free(pMerger);
|
||||||
tfree(pLocalMerge->pLocalDataSrc[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pLocalMerge->numOfBuffer = 0;
|
|
||||||
pLocalMerge->numOfCompleted = 0;
|
|
||||||
tfree(pLocalMerge->pTempBuffer);
|
|
||||||
|
|
||||||
free(pLocalMerge);
|
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" free local reducer finished", pSql->self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) {
|
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SQueryInfo* pQueryInfo, SColumnModel *pModel) {
|
||||||
int32_t numOfGroupByCols = 0;
|
int32_t numOfGroupByCols = 0;
|
||||||
SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
|
||||||
|
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||||
numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols;
|
numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||||
}
|
}
|
||||||
|
|
||||||
// primary timestamp column is involved in final result
|
// primary timestamp column is involved in final result
|
||||||
if (pQueryInfo->interval.interval != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
if (pQueryInfo->interval.interval != 0 || pQueryInfo->orderProjectQuery) {
|
||||||
numOfGroupByCols++;
|
numOfGroupByCols++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,13 +354,13 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
||||||
if (numOfGroupByCols > 0) {
|
if (numOfGroupByCols > 0) {
|
||||||
|
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||||
int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
int32_t numOfInternalOutput = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
// the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns
|
// the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns
|
||||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
||||||
for(int32_t j = 0; j < numOfInternalOutput; ++j) {
|
for(int32_t j = 0; j < numOfInternalOutput; ++j) {
|
||||||
SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j);
|
SExprInfo* pExprInfo = tscExprGet(pQueryInfo, j);
|
||||||
|
|
||||||
int32_t functionId = pExprInfo->base.functionId;
|
int32_t functionId = pExprInfo->base.functionId;
|
||||||
if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) {
|
if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) {
|
||||||
|
|
@ -502,9 +382,9 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
||||||
if (pQueryInfo->interval.interval != 0) {
|
if (pQueryInfo->interval.interval != 0) {
|
||||||
orderColIndexList[0] = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
orderColIndexList[0] = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||||
} else {
|
} else {
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t size = tscNumOfExprs(pQueryInfo);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||||
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
orderColIndexList[0] = i;
|
orderColIndexList[0] = i;
|
||||||
}
|
}
|
||||||
|
|
@ -525,37 +405,30 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc,
|
int32_t tscCreateGlobalMergerEnv(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBuffer, int32_t numOfSub,
|
||||||
SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) {
|
tOrderDescriptor **pOrderDesc, uint32_t nBufferSizes, int64_t id) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSchema *pSchema = NULL;
|
||||||
SSqlRes *pRes = &pSql->res;
|
|
||||||
|
|
||||||
SSchema * pSchema = NULL;
|
|
||||||
SColumnModel *pModel = NULL;
|
SColumnModel *pModel = NULL;
|
||||||
*pFinalModel = NULL;
|
|
||||||
|
|
||||||
SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd);
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub);
|
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * numOfSub);
|
||||||
if (*pMemBuffer == NULL) {
|
if (*pMemBuffer == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
return pRes->code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t size = tscNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * size);
|
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * size);
|
||||||
if (pSchema == NULL) {
|
if (pSchema == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to allocate memory", pSql->self);
|
tscError("0x%"PRIx64" failed to allocate memory", id);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
return pRes->code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t rlen = 0;
|
int32_t rlen = 0;
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||||
|
|
||||||
pSchema[i].bytes = pExpr->base.resBytes;
|
pSchema[i].bytes = pExpr->base.resBytes;
|
||||||
pSchema[i].type = (int8_t)pExpr->base.resType;
|
pSchema[i].type = (int8_t)pExpr->base.resType;
|
||||||
|
|
@ -570,6 +443,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
}
|
}
|
||||||
|
|
||||||
pModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
pModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||||
|
tfree(pSchema);
|
||||||
|
|
||||||
int32_t pg = DEFAULT_PAGE_SIZE;
|
int32_t pg = DEFAULT_PAGE_SIZE;
|
||||||
int32_t overhead = sizeof(tFilePage);
|
int32_t overhead = sizeof(tFilePage);
|
||||||
|
|
@ -577,95 +451,26 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
pg *= 2;
|
pg *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t numOfSubs = pSql->subState.numOfSub;
|
assert(numOfSub <= pTableMetaInfo->vgroupList->numOfVgroups);
|
||||||
assert(numOfSubs <= pTableMetaInfo->vgroupList->numOfVgroups);
|
for (int32_t i = 0; i < numOfSub; ++i) {
|
||||||
for (int32_t i = 0; i < numOfSubs; ++i) {
|
|
||||||
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pg, pModel);
|
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pg, pModel);
|
||||||
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
(*pMemBuffer)[i]->flushModel = MULTIPLE_APPEND_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) {
|
if (createOrderDescriptor(pOrderDesc, pQueryInfo, pModel) != TSDB_CODE_SUCCESS) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tfree(pSchema);
|
|
||||||
return pRes->code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// final result depends on the fields number
|
|
||||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
|
||||||
|
|
||||||
SSchema p1 = {0};
|
|
||||||
if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
|
||||||
p1 = *tGetTbnameColumnSchema();
|
|
||||||
} else if (TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag)) {
|
|
||||||
p1.bytes = pExpr->base.resBytes;
|
|
||||||
p1.type = (uint8_t) pExpr->base.resType;
|
|
||||||
tstrncpy(p1.name, pExpr->base.aliasName, tListLen(p1.name));
|
|
||||||
} else {
|
|
||||||
p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t inter = 0;
|
|
||||||
int16_t type = -1;
|
|
||||||
int16_t bytes = 0;
|
|
||||||
|
|
||||||
// the final result size and type in the same as query on single table.
|
|
||||||
// so here, set the flag to be false;
|
|
||||||
int32_t functionId = pExpr->base.functionId;
|
|
||||||
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
|
||||||
type = pModel->pFields[i].field.type;
|
|
||||||
bytes = pModel->pFields[i].field.bytes;
|
|
||||||
} else {
|
|
||||||
if (functionId == TSDB_FUNC_FIRST_DST) {
|
|
||||||
functionId = TSDB_FUNC_FIRST;
|
|
||||||
} else if (functionId == TSDB_FUNC_LAST_DST) {
|
|
||||||
functionId = TSDB_FUNC_LAST;
|
|
||||||
} else if (functionId == TSDB_FUNC_STDDEV_DST) {
|
|
||||||
functionId = TSDB_FUNC_STDDEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
|
||||||
assert(ret == TSDB_CODE_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
pSchema[i].type = (uint8_t)type;
|
|
||||||
pSchema[i].bytes = bytes;
|
|
||||||
strcpy(pSchema[i].name, pModel->pFields[i].field.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
*pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
|
||||||
|
|
||||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
|
||||||
size = tscNumOfFields(pQueryInfo);
|
|
||||||
|
|
||||||
for(int32_t i = 0; i < size; ++i) {
|
|
||||||
SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
|
||||||
pSchema[i].bytes = pField->field.bytes;
|
|
||||||
pSchema[i].type = pField->field.type;
|
|
||||||
tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name));
|
|
||||||
}
|
|
||||||
|
|
||||||
*pFFModel = createColumnModel(pSchema, (int32_t) size, capacity);
|
|
||||||
|
|
||||||
tfree(pSchema);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pMemBuffer
|
* @param pMemBuffer
|
||||||
* @param pDesc
|
* @param pDesc
|
||||||
* @param pFinalModel
|
|
||||||
* @param numOfVnodes
|
* @param numOfVnodes
|
||||||
*/
|
*/
|
||||||
void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel,
|
void tscDestroyGlobalMergerEnv(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, int32_t numOfVnodes) {
|
||||||
int32_t numOfVnodes) {
|
|
||||||
destroyColumnModel(pFinalModel);
|
|
||||||
destroyColumnModel(pFFModel);
|
|
||||||
|
|
||||||
tOrderDescDestroy(pDesc);
|
tOrderDescDestroy(pDesc);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||||
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
pMemBuffer[i] = destoryExtMemBuffer(pMemBuffer[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -675,12 +480,12 @@ void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param pLocalMerge
|
* @param pMerger
|
||||||
* @param pOneInterDataSrc
|
* @param pOneInterDataSrc
|
||||||
* @param treeList
|
* @param treeList
|
||||||
* @return the number of remain input source. if ret == 0, all data has been handled
|
* @return the number of remain input source. if ret == 0, all data has been handled
|
||||||
*/
|
*/
|
||||||
int32_t loadNewDataFromDiskFor(SLocalMerger *pLocalMerge, SLocalDataSource *pOneInterDataSrc,
|
int32_t loadNewDataFromDiskFor(SGlobalMerger *pMerger, SLocalDataSource *pOneInterDataSrc,
|
||||||
bool *needAdjustLoserTree) {
|
bool *needAdjustLoserTree) {
|
||||||
pOneInterDataSrc->rowIdx = 0;
|
pOneInterDataSrc->rowIdx = 0;
|
||||||
pOneInterDataSrc->pageId += 1;
|
pOneInterDataSrc->pageId += 1;
|
||||||
|
|
@ -697,17 +502,17 @@ int32_t loadNewDataFromDiskFor(SLocalMerger *pLocalMerge, SLocalDataSource *pOne
|
||||||
#endif
|
#endif
|
||||||
*needAdjustLoserTree = true;
|
*needAdjustLoserTree = true;
|
||||||
} else {
|
} else {
|
||||||
pLocalMerge->numOfCompleted += 1;
|
pMerger->numOfCompleted += 1;
|
||||||
|
|
||||||
pOneInterDataSrc->rowIdx = -1;
|
pOneInterDataSrc->rowIdx = -1;
|
||||||
pOneInterDataSrc->pageId = -1;
|
pOneInterDataSrc->pageId = -1;
|
||||||
*needAdjustLoserTree = true;
|
*needAdjustLoserTree = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pLocalMerge->numOfBuffer;
|
return pMerger->numOfBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOneInterDataSrc,
|
void adjustLoserTreeFromNewData(SGlobalMerger *pMerger, SLocalDataSource *pOneInterDataSrc,
|
||||||
SLoserTreeInfo *pTree) {
|
SLoserTreeInfo *pTree) {
|
||||||
/*
|
/*
|
||||||
* load a new data page into memory for intermediate dataset source,
|
* load a new data page into memory for intermediate dataset source,
|
||||||
|
|
@ -715,7 +520,7 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn
|
||||||
*/
|
*/
|
||||||
bool needToAdjust = true;
|
bool needToAdjust = true;
|
||||||
if (pOneInterDataSrc->filePage.num <= pOneInterDataSrc->rowIdx) {
|
if (pOneInterDataSrc->filePage.num <= pOneInterDataSrc->rowIdx) {
|
||||||
loadNewDataFromDiskFor(pLocalMerge, pOneInterDataSrc, &needToAdjust);
|
loadNewDataFromDiskFor(pMerger, pOneInterDataSrc, &needToAdjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -723,7 +528,7 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn
|
||||||
* if the loser tree is rebuild completed, we do not need to adjust
|
* if the loser tree is rebuild completed, we do not need to adjust
|
||||||
*/
|
*/
|
||||||
if (needToAdjust) {
|
if (needToAdjust) {
|
||||||
int32_t leafNodeIdx = pTree->pNode[0].index + pLocalMerge->numOfBuffer;
|
int32_t leafNodeIdx = pTree->pNode[0].index + pMerger->numOfBuffer;
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
printf("before adjust:\t");
|
printf("before adjust:\t");
|
||||||
|
|
@ -775,7 +580,7 @@ static void setTagValueForMultipleRows(SQLFunctionCtx* pCtx, int32_t numOfOutput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
|
static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) {
|
||||||
SMultiwayMergeInfo* pInfo = pOperator->info;
|
SMultiwayMergeInfo* pInfo = pOperator->info;
|
||||||
SQLFunctionCtx* pCtx = pInfo->binfo.pCtx;
|
SQLFunctionCtx* pCtx = pInfo->binfo.pCtx;
|
||||||
|
|
||||||
|
|
@ -787,7 +592,7 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
||||||
|
|
||||||
for(int32_t i = 0; i < pBlock->info.rows; ++i) {
|
for(int32_t i = 0; i < pBlock->info.rows; ++i) {
|
||||||
if (pInfo->hasPrev) {
|
if (pInfo->hasPrev) {
|
||||||
if (needToMergeRv(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) {
|
if (needToMerge(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) {
|
||||||
for (int32_t j = 0; j < numOfExpr; ++j) {
|
for (int32_t j = 0; j < numOfExpr; ++j) {
|
||||||
pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i;
|
pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i;
|
||||||
}
|
}
|
||||||
|
|
@ -862,45 +667,27 @@ static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, S
|
||||||
tfree(add);
|
tfree(add);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) {
|
static bool isAllSourcesCompleted(SGlobalMerger *pMerger) {
|
||||||
int32_t ret = 0;
|
return (pMerger->numOfBuffer == pMerger->numOfCompleted);
|
||||||
size_t size = taosArrayGetSize(columnIndexList);
|
|
||||||
if (size > 0) {
|
|
||||||
ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if ret == 0, means the result belongs to the same group
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) {
|
SGlobalMerger* tscInitResObjForLocalQuery(int32_t numOfRes, int32_t rowLen, uint64_t id) {
|
||||||
return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted);
|
SGlobalMerger *pMerger = calloc(1, sizeof(SGlobalMerger));
|
||||||
}
|
if (pMerger == NULL) {
|
||||||
|
tscDebug("0x%"PRIx64" free local reducer finished", id);
|
||||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) {
|
return NULL;
|
||||||
SSqlRes *pRes = &pObj->res;
|
|
||||||
if (pRes->pLocalMerger != NULL) {
|
|
||||||
tscDestroyLocalMerger(pObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pRes->qId = 1; // hack to pass the safety check in fetch_row function
|
|
||||||
pRes->numOfRows = 0;
|
|
||||||
pRes->row = 0;
|
|
||||||
|
|
||||||
pRes->rspType = 0; // used as a flag to denote if taos_retrieved() has been called yet
|
|
||||||
pRes->pLocalMerger = (SLocalMerger *)calloc(1, sizeof(SLocalMerger));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we need one additional byte space
|
* One more byte space is required, since the sprintf function needs one additional space to put '\0' at
|
||||||
* the sprintf function needs one additional space to put '\0' at the end of string
|
* the end of string
|
||||||
*/
|
*/
|
||||||
size_t allocSize = numOfRes * rowLen + sizeof(tFilePage) + 1;
|
size_t size = numOfRes * rowLen + 1;
|
||||||
pRes->pLocalMerger->pResultBuf = (tFilePage *)calloc(1, allocSize);
|
pMerger->buf = calloc(1, size);
|
||||||
|
return pMerger;
|
||||||
pRes->pLocalMerger->pResultBuf->num = numOfRes;
|
|
||||||
pRes->data = pRes->pLocalMerger->pResultBuf->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo remove it
|
||||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||||
int32_t maxRowSize = MAX(rowSize, finalRowSize);
|
int32_t maxRowSize = MAX(rowSize, finalRowSize);
|
||||||
char* pbuf = calloc(1, (size_t)(pOutput->num * maxRowSize));
|
char* pbuf = calloc(1, (size_t)(pOutput->num * maxRowSize));
|
||||||
|
|
@ -910,12 +697,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
||||||
|
|
||||||
// todo refactor
|
// todo refactor
|
||||||
arithSup.offset = 0;
|
arithSup.offset = 0;
|
||||||
arithSup.numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
arithSup.numOfCols = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||||
arithSup.exprList = pQueryInfo->exprList;
|
arithSup.exprList = pQueryInfo->exprList;
|
||||||
arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES);
|
arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES);
|
||||||
|
|
||||||
for(int32_t k = 0; k < arithSup.numOfCols; ++k) {
|
for(int32_t k = 0; k < arithSup.numOfCols; ++k) {
|
||||||
SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k);
|
SExprInfo* pExpr = tscExprGet(pQueryInfo, k);
|
||||||
arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset);
|
arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -944,16 +731,13 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
|
|
||||||
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
|
|
||||||
|
|
||||||
static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex,
|
static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex,
|
||||||
int32_t maxRows) {
|
int32_t maxRows) {
|
||||||
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
|
||||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||||
char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes;
|
char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes;
|
||||||
|
|
||||||
char *src = COLMODEL_GET_VAL(buf, pModel, maxRows, rowIndex, i);
|
char *src = COLMODEL_GET_VAL(buf, pModel, rowIndex, i);
|
||||||
memmove(p, src, pColInfo->info.bytes);
|
memmove(p, src, pColInfo->info.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -968,10 +752,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
|
|
||||||
SMultiwayMergeInfo *pInfo = pOperator->info;
|
SMultiwayMergeInfo *pInfo = pOperator->info;
|
||||||
|
|
||||||
SLocalMerger *pMerger = pInfo->pMerge;
|
SGlobalMerger *pMerger = pInfo->pMerge;
|
||||||
SLoserTreeInfo *pTree = pMerger->pLoserTree;
|
SLoserTreeInfo *pTree = pMerger->pLoserTree;
|
||||||
SColumnModel *pModel = pMerger->pDesc->pColumnModel;
|
|
||||||
tFilePage *tmpBuffer = pMerger->pTempBuffer;
|
|
||||||
|
|
||||||
pInfo->binfo.pRes->info.rows = 0;
|
pInfo->binfo.pRes->info.rows = 0;
|
||||||
|
|
||||||
|
|
@ -984,7 +766,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index);
|
printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0);
|
assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0));
|
||||||
|
|
||||||
// chosen from loser tree
|
// chosen from loser tree
|
||||||
SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index];
|
SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index];
|
||||||
|
|
@ -997,11 +779,10 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||||
|
|
||||||
char *newRow =
|
char *newRow = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
|
||||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||||
|
|
||||||
char * data = pInfo->prevRow[i];
|
char *data = pInfo->prevRow[i];
|
||||||
int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes);
|
int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1020,8 +801,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i);
|
||||||
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex);
|
||||||
|
|
||||||
char *curCol =
|
char *curCol = COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||||
COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity,
|
|
||||||
pOneDataSrc->rowIdx, pIndex->colIndex);
|
pOneDataSrc->rowIdx, pIndex->colIndex);
|
||||||
memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes);
|
memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes);
|
||||||
}
|
}
|
||||||
|
|
@ -1033,7 +813,8 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
return pInfo->binfo.pRes;
|
return pInfo->binfo.pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pOneDataSrc->pMemBuffer->pColumnModel,
|
||||||
|
pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity);
|
||||||
|
|
||||||
#if defined(_DEBUG_VIEW)
|
#if defined(_DEBUG_VIEW)
|
||||||
printf("chosen row:\t");
|
printf("chosen row:\t");
|
||||||
|
|
@ -1055,7 +836,7 @@ SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) {
|
||||||
return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL;
|
return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isSameGroupRv(SArray* orderColumnList, SSDataBlock* pBlock, char** dataCols) {
|
static bool isSameGroup(SArray* orderColumnList, SSDataBlock* pBlock, char** dataCols) {
|
||||||
int32_t numOfCols = (int32_t) taosArrayGetSize(orderColumnList);
|
int32_t numOfCols = (int32_t) taosArrayGetSize(orderColumnList);
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SColIndex *pIndex = taosArrayGet(orderColumnList, i);
|
SColIndex *pIndex = taosArrayGet(orderColumnList, i);
|
||||||
|
|
@ -1082,7 +863,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SMultiwayMergeInfo *pAggInfo = pOperator->info;
|
SMultiwayMergeInfo *pAggInfo = pOperator->info;
|
||||||
SOperatorInfo *upstream = pOperator->upstream;
|
SOperatorInfo *upstream = pOperator->upstream[0];
|
||||||
|
|
||||||
*newgroup = false;
|
*newgroup = false;
|
||||||
bool handleData = false;
|
bool handleData = false;
|
||||||
|
|
@ -1103,7 +884,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock);
|
doExecuteFinalMerge(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock);
|
||||||
|
|
||||||
savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pAggInfo->pExistBlock, 0,
|
savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pAggInfo->pExistBlock, 0,
|
||||||
&pAggInfo->hasGroupColData);
|
&pAggInfo->hasGroupColData);
|
||||||
|
|
@ -1124,7 +905,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pAggInfo->hasGroupColData) {
|
if (pAggInfo->hasGroupColData) {
|
||||||
bool sameGroup = isSameGroupRv(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData);
|
bool sameGroup = isSameGroup(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData);
|
||||||
if (!sameGroup) {
|
if (!sameGroup) {
|
||||||
*newgroup = true;
|
*newgroup = true;
|
||||||
pAggInfo->hasDataBlockForNewGroup = true;
|
pAggInfo->hasDataBlockForNewGroup = true;
|
||||||
|
|
@ -1138,7 +919,7 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC);
|
setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC);
|
||||||
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor);
|
updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor);
|
||||||
|
|
||||||
doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pBlock);
|
doExecuteFinalMerge(pOperator, pOperator->numOfOutput, pBlock);
|
||||||
savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData);
|
savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData);
|
||||||
handleData = true;
|
handleData = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1166,7 +947,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
|
||||||
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) {
|
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) {
|
||||||
STimeWindow* w = &pRes->info.window;
|
STimeWindow* w = &pRes->info.window;
|
||||||
|
|
||||||
// TODO in case of desc order, swap it
|
|
||||||
w->skey = *(int64_t*)pInfoData->pData;
|
w->skey = *(int64_t*)pInfoData->pData;
|
||||||
w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1));
|
w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1));
|
||||||
|
|
||||||
|
|
@ -1186,7 +966,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
|
||||||
SSDataBlock* pBlock = NULL;
|
SSDataBlock* pBlock = NULL;
|
||||||
if (pInfo->currentGroupOffset == 0) {
|
if (pInfo->currentGroupOffset == 0) {
|
||||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||||
if (pBlock == NULL) {
|
if (pBlock == NULL) {
|
||||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||||
pOperator->status = OP_EXEC_DONE;
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
|
@ -1194,7 +974,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
|
||||||
if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) {
|
if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) {
|
||||||
while ((*newgroup) == false) { // ignore the remain blocks
|
while ((*newgroup) == false) { // ignore the remain blocks
|
||||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||||
if (pBlock == NULL) {
|
if (pBlock == NULL) {
|
||||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||||
pOperator->status = OP_EXEC_DONE;
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
|
@ -1206,7 +986,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
return pBlock;
|
return pBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||||
if (pBlock == NULL) {
|
if (pBlock == NULL) {
|
||||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||||
pOperator->status = OP_EXEC_DONE;
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
|
@ -1220,7 +1000,7 @@ static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((*newgroup) == false) {
|
while ((*newgroup) == false) {
|
||||||
pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup);
|
pBlock = pOperator->upstream[0]->exec(pOperator->upstream[0], newgroup);
|
||||||
if (pBlock == NULL) {
|
if (pBlock == NULL) {
|
||||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||||
pOperator->status = OP_EXEC_DONE;
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tschemautil.h"
|
#include "qTableMeta.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
|
|
@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
// one column for each row
|
// one column for each row
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
@ -71,7 +71,9 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
numOfRows = numOfRows + tscGetNumOfTags(pMeta);
|
numOfRows = numOfRows + tscGetNumOfTags(pMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscInitResObjForLocalQuery(pSql, totalNumOfRows, rowLen);
|
pSql->res.pMerger = tscInitResObjForLocalQuery(totalNumOfRows, rowLen, pSql->self);
|
||||||
|
tscInitResForMerge(&pSql->res);
|
||||||
|
|
||||||
SSchema *pSchema = tscGetTableSchema(pMeta);
|
SSchema *pSchema = tscGetTableSchema(pMeta);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
|
|
@ -154,14 +156,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
|
|
||||||
pSql->cmd.numOfCols = numOfCols;
|
pSql->cmd.numOfCols = numOfCols;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||||
|
|
||||||
TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE};
|
TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE};
|
||||||
tstrncpy(f.name, "Field", sizeof(f.name));
|
tstrncpy(f.name, "Field", sizeof(f.name));
|
||||||
|
|
||||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||||
(TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false);
|
(TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false);
|
||||||
|
|
||||||
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
||||||
|
|
@ -171,7 +173,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
tstrncpy(f.name, "Type", sizeof(f.name));
|
tstrncpy(f.name, "Type", sizeof(f.name));
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE),
|
||||||
-1000, typeColLength, false);
|
-1000, typeColLength, false);
|
||||||
|
|
||||||
rowLen += typeColLength + VARSTR_HEADER_SIZE;
|
rowLen += typeColLength + VARSTR_HEADER_SIZE;
|
||||||
|
|
@ -181,7 +183,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
tstrncpy(f.name, "Length", sizeof(f.name));
|
tstrncpy(f.name, "Length", sizeof(f.name));
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t),
|
||||||
-1000, sizeof(int32_t), false);
|
-1000, sizeof(int32_t), false);
|
||||||
|
|
||||||
rowLen += sizeof(int32_t);
|
rowLen += sizeof(int32_t);
|
||||||
|
|
@ -191,7 +193,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
tstrncpy(f.name, "Note", sizeof(f.name));
|
tstrncpy(f.name, "Note", sizeof(f.name));
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE),
|
||||||
-1000, noteColLength, false);
|
-1000, noteColLength, false);
|
||||||
|
|
||||||
rowLen += noteColLength + VARSTR_HEADER_SIZE;
|
rowLen += noteColLength + VARSTR_HEADER_SIZE;
|
||||||
|
|
@ -199,7 +201,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
|
assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL);
|
||||||
|
|
||||||
|
|
@ -390,7 +392,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
||||||
SColumnIndex index = {0};
|
SColumnIndex index = {0};
|
||||||
pSql->cmd.numOfCols = 2;
|
pSql->cmd.numOfCols = 2;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||||
|
|
||||||
TAOS_FIELD f;
|
TAOS_FIELD f;
|
||||||
|
|
@ -405,7 +407,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
||||||
}
|
}
|
||||||
|
|
||||||
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false);
|
||||||
|
|
||||||
rowLen += f.bytes;
|
rowLen += f.bytes;
|
||||||
|
|
||||||
|
|
@ -418,7 +420,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY,
|
||||||
(int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false);
|
(int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false);
|
||||||
|
|
||||||
rowLen += ddlLen + VARSTR_HEADER_SIZE;
|
rowLen += ddlLen + VARSTR_HEADER_SIZE;
|
||||||
|
|
@ -428,12 +430,13 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const
|
||||||
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
|
static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) {
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
int32_t numOfRows = 1;
|
int32_t numOfRows = 1;
|
||||||
if (strlen(ddl) == 0) {
|
if (strlen(ddl) == 0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
tscInitResObjForLocalQuery(pSql, numOfRows, rowLen);
|
pSql->res.pMerger = tscInitResObjForLocalQuery(numOfRows, rowLen, pSql->self);
|
||||||
|
tscInitResForMerge(&pSql->res);
|
||||||
|
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
||||||
char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * numOfRows;
|
char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * numOfRows;
|
||||||
|
|
@ -445,7 +448,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
|
static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);
|
int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result);
|
||||||
|
|
||||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||||
|
|
@ -532,7 +535,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
||||||
}
|
}
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
|
|
||||||
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
|
STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0)->pTableMeta;
|
||||||
if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
|
if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
|
||||||
pMeta->tableType == TSDB_STREAM_TABLE) {
|
pMeta->tableType == TSDB_STREAM_TABLE) {
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
@ -553,7 +556,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
@ -607,7 +610,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
||||||
|
|
@ -634,7 +637,7 @@ static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName,
|
||||||
}
|
}
|
||||||
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) {
|
||||||
char *result = ddl;
|
char *result = ddl;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
||||||
|
|
@ -675,7 +678,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
assert(pTableMetaInfo->pTableMeta != NULL);
|
assert(pTableMetaInfo->pTableMeta != NULL);
|
||||||
|
|
||||||
|
|
@ -704,7 +707,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
|
|
@ -730,7 +733,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) {
|
||||||
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
return TSDB_CODE_TSC_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
static int32_t tscProcessCurrentUser(SSqlObj *pSql) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
|
pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY;
|
||||||
|
|
@ -757,7 +760,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
||||||
extractDBName(pSql->pTscObj->db, db);
|
extractDBName(pSql->pTscObj->db, db);
|
||||||
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
pthread_mutex_unlock(&pSql->pTscObj->mutex);
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
|
@ -784,7 +787,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) {
|
||||||
|
|
||||||
static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
||||||
const char* v = pSql->pTscObj->sversion;
|
const char* v = pSql->pTscObj->sversion;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
|
@ -807,7 +810,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
pExpr->resType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
|
@ -859,7 +862,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
|
|
||||||
int32_t val = 1;
|
int32_t val = 1;
|
||||||
|
|
@ -873,7 +876,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
||||||
|
|
||||||
pCmd->numOfCols = 1;
|
pCmd->numOfCols = 1;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||||
|
|
||||||
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
||||||
|
|
@ -882,7 +885,8 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
||||||
TAOS_FIELD f = tscCreateField((int8_t)type, columnName, (int16_t)valueLength);
|
TAOS_FIELD f = tscCreateField((int8_t)type, columnName, (int16_t)valueLength);
|
||||||
tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
|
|
||||||
tscInitResObjForLocalQuery(pSql, 1, (int32_t)valueLength);
|
pSql->res.pMerger = tscInitResObjForLocalQuery(1, (int32_t)valueLength, pSql->self);
|
||||||
|
tscInitResForMerge(&pSql->res);
|
||||||
|
|
||||||
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0);
|
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0);
|
||||||
pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
|
||||||
|
|
@ -928,7 +932,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
||||||
} else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
|
} else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
|
||||||
pRes->code = tscProcessServStatus(pSql);
|
pRes->code = tscProcessServStatus(pSql);
|
||||||
} else {
|
} else {
|
||||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
pRes->code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command);
|
tscError("0x%"PRIx64" not support command:%d", pSql->self, pCmd->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -46,9 +46,14 @@ typedef struct SNormalStmt {
|
||||||
|
|
||||||
typedef struct SMultiTbStmt {
|
typedef struct SMultiTbStmt {
|
||||||
bool nameSet;
|
bool nameSet;
|
||||||
|
bool tagSet;
|
||||||
uint64_t currentUid;
|
uint64_t currentUid;
|
||||||
|
char *sqlstr;
|
||||||
uint32_t tbNum;
|
uint32_t tbNum;
|
||||||
SStrToken tbname;
|
SStrToken tbname;
|
||||||
|
SStrToken stbname;
|
||||||
|
SStrToken values;
|
||||||
|
SArray *tags;
|
||||||
SHashObj *pTableHash;
|
SHashObj *pTableHash;
|
||||||
SHashObj *pTableBlockHashList; // data block for each table
|
SHashObj *pTableBlockHashList; // data block for each table
|
||||||
} SMultiTbStmt;
|
} SMultiTbStmt;
|
||||||
|
|
@ -308,7 +313,7 @@ static int fillColumnsNull(STableDataBlocks* pBlock, int32_t rowNum) {
|
||||||
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||||
|
|
||||||
STableDataBlocks* pOneTableBlock = *p;
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
while(pOneTableBlock) {
|
while(pOneTableBlock) {
|
||||||
|
|
@ -317,7 +322,7 @@ int32_t fillTablesColumnsNull(SSqlObj* pSql) {
|
||||||
fillColumnsNull(pOneTableBlock, pBlocks->numOfRows);
|
fillColumnsNull(pOneTableBlock, pBlocks->numOfRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -840,12 +845,12 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
STableDataBlocks* pBlock = NULL;
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
if (pStmt->multiTbInsert) {
|
if (pStmt->multiTbInsert) {
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||||
if (t1 == NULL) {
|
if (t1 == NULL) {
|
||||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
|
@ -853,15 +858,15 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
|
||||||
|
|
||||||
pBlock = *t1;
|
pBlock = *t1;
|
||||||
} else {
|
} else {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -904,12 +909,12 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
||||||
STableDataBlocks* pBlock = NULL;
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
if (pStmt->multiTbInsert) {
|
if (pStmt->multiTbInsert) {
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
tscError("0x%"PRIx64" Table block hash list is empty", pStmt->pSql->self);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid));
|
||||||
if (t1 == NULL) {
|
if (t1 == NULL) {
|
||||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pStmt->pSql->self, pStmt->mtb.currentUid);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
|
@ -917,15 +922,15 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
|
||||||
|
|
||||||
pBlock = *t1;
|
pBlock = *t1;
|
||||||
} else {
|
} else {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -991,12 +996,11 @@ static int insertStmtUpdateBatch(STscStmt* stmt) {
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pCmd->numOfClause == 1);
|
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
STableDataBlocks** t1 = (STableDataBlocks**)taosHashGet(pCmd->insertParam.pTableBlockHashList, (const char*)&stmt->mtb.currentUid, sizeof(stmt->mtb.currentUid));
|
||||||
if (t1 == NULL) {
|
if (t1 == NULL) {
|
||||||
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid);
|
tscError("0x%"PRIx64" no table data block in hash list, uid:%" PRId64 , pSql->self, stmt->mtb.currentUid);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
|
@ -1032,9 +1036,9 @@ static int insertStmtReset(STscStmt* pStmt) {
|
||||||
if (pCmd->batchSize > 2) {
|
if (pCmd->batchSize > 2) {
|
||||||
int32_t alloced = (pCmd->batchSize + 1) / 2;
|
int32_t alloced = (pCmd->batchSize + 1) / 2;
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pCmd->pDataBlocks);
|
size_t size = taosArrayGetSize(pCmd->insertParam.pDataBlocks);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
STableDataBlocks* pBlock = taosArrayGetP(pCmd->pDataBlocks, i);
|
STableDataBlocks* pBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, i);
|
||||||
|
|
||||||
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
uint32_t totalDataSize = pBlock->size - sizeof(SSubmitBlk);
|
||||||
pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced;
|
pBlock->size = sizeof(SSubmitBlk) + totalDataSize / alloced;
|
||||||
|
|
@ -1045,7 +1049,7 @@ static int insertStmtReset(STscStmt* pStmt) {
|
||||||
}
|
}
|
||||||
pCmd->batchSize = 0;
|
pCmd->batchSize = 0;
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
pTableMetaInfo->vgroupIndex = 0;
|
pTableMetaInfo->vgroupIndex = 0;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -1056,22 +1060,21 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pCmd->numOfClause == 1);
|
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) == 0) {
|
||||||
if (taosHashGetSize(pCmd->pTableBlockHashList) == 0) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks* pBlock = NULL;
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
pBlock->size = sizeof(SSubmitBlk) + pCmd->batchSize * pBlock->rowSize;
|
||||||
|
|
@ -1083,12 +1086,12 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
|
|
||||||
fillTablesColumnsNull(stmt->pSql);
|
fillTablesColumnsNull(stmt->pSql);
|
||||||
|
|
||||||
int code = tscMergeTableDataBlocks(stmt->pSql, false);
|
int code = tscMergeTableDataBlocks(&stmt->pSql->cmd.insertParam, false);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->pDataBlocks, 0);
|
STableDataBlocks* pDataBlock = taosArrayGetP(pCmd->insertParam.pDataBlocks, 0);
|
||||||
code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock);
|
code = tscCopyDataBlockToPayload(stmt->pSql, pDataBlock);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -1106,15 +1109,15 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
|
|
||||||
// data block reset
|
// data block reset
|
||||||
pCmd->batchSize = 0;
|
pCmd->batchSize = 0;
|
||||||
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
for(int32_t i = 0; i < pCmd->insertParam.numOfTables; ++i) {
|
||||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||||
tfree(pCmd->pTableNameList[i]);
|
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pCmd->numOfTables = 0;
|
pCmd->insertParam.numOfTables = 0;
|
||||||
tfree(pCmd->pTableNameList);
|
tfree(pCmd->insertParam.pTableNameList);
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||||
|
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
@ -1122,21 +1125,21 @@ static int insertStmtExecute(STscStmt* stmt) {
|
||||||
static void insertBatchClean(STscStmt* pStmt) {
|
static void insertBatchClean(STscStmt* pStmt) {
|
||||||
SSqlCmd *pCmd = &pStmt->pSql->cmd;
|
SSqlCmd *pCmd = &pStmt->pSql->cmd;
|
||||||
SSqlObj *pSql = pStmt->pSql;
|
SSqlObj *pSql = pStmt->pSql;
|
||||||
int32_t size = taosHashGetSize(pCmd->pTableBlockHashList);
|
int32_t size = taosHashGetSize(pCmd->insertParam.pTableBlockHashList);
|
||||||
|
|
||||||
// data block reset
|
// data block reset
|
||||||
pCmd->batchSize = 0;
|
pCmd->batchSize = 0;
|
||||||
|
|
||||||
for(int32_t i = 0; i < size; ++i) {
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
if (pCmd->insertParam.pTableNameList && pCmd->insertParam.pTableNameList[i]) {
|
||||||
tfree(pCmd->pTableNameList[i]);
|
tfree(pCmd->insertParam.pTableNameList[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pCmd->pTableNameList);
|
tfree(pCmd->insertParam.pTableNameList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
STableDataBlocks** p = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
|
||||||
|
|
||||||
STableDataBlocks* pOneTableBlock = *p;
|
STableDataBlocks* pOneTableBlock = *p;
|
||||||
|
|
||||||
|
|
@ -1147,7 +1150,7 @@ static void insertBatchClean(STscStmt* pStmt) {
|
||||||
|
|
||||||
pBlocks->numOfRows = 0;
|
pBlocks->numOfRows = 0;
|
||||||
|
|
||||||
p = taosHashIterate(pCmd->pTableBlockHashList, p);
|
p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1156,10 +1159,10 @@ static void insertBatchClean(STscStmt* pStmt) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pCmd->insertParam.pDataBlocks);
|
||||||
pCmd->numOfTables = 0;
|
pCmd->insertParam.numOfTables = 0;
|
||||||
|
|
||||||
taosHashEmpty(pCmd->pTableBlockHashList);
|
taosHashEmpty(pCmd->insertParam.pTableBlockHashList);
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
tscFreeSubobj(pSql);
|
tscFreeSubobj(pSql);
|
||||||
tfree(pSql->pSubs);
|
tfree(pSql->pSubs);
|
||||||
|
|
@ -1176,14 +1179,14 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
|
|
||||||
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
|
pStmt->pSql->retry = pStmt->pSql->maxRetry + 1; //no retry
|
||||||
|
|
||||||
if (taosHashGetSize(pStmt->pSql->cmd.pTableBlockHashList) <= 0) { // merge according to vgId
|
if (taosHashGetSize(pStmt->pSql->cmd.insertParam.pTableBlockHashList) <= 0) { // merge according to vgId
|
||||||
tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self);
|
tscError("0x%"PRIx64" no data block to insert", pStmt->pSql->self);
|
||||||
return TSDB_CODE_TSC_APP_ERROR;
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fillTablesColumnsNull(pStmt->pSql);
|
fillTablesColumnsNull(pStmt->pSql);
|
||||||
|
|
||||||
if ((code = tscMergeTableDataBlocks(pStmt->pSql, false)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscMergeTableDataBlocks(&pStmt->pSql->cmd.insertParam, false)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1201,6 +1204,184 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
return pStmt->pSql->res.code;
|
return pStmt->pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||||
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t index = 0;
|
||||||
|
SStrToken sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n == 0) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
||||||
|
pStmt->multiTbInsert = true;
|
||||||
|
pStmt->mtb.tbname = sToken;
|
||||||
|
pStmt->mtb.nameSet = false;
|
||||||
|
if (pStmt->mtb.pTableHash == NULL) {
|
||||||
|
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
||||||
|
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->mtb.tagSet = true;
|
||||||
|
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n > 0 && (sToken.type == TK_VALUES || sToken.type == TK_LP)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sToken.n <= 0 || sToken.type != TK_USING) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z);
|
||||||
|
}
|
||||||
|
pStmt->mtb.stbname = sToken;
|
||||||
|
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n <= 0 || sToken.type != TK_TAGS) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n <= 0 || sToken.type != TK_LP) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
|
||||||
|
|
||||||
|
int32_t loopCont = 1;
|
||||||
|
|
||||||
|
while (loopCont) {
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n <= 0) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sToken.type) {
|
||||||
|
case TK_RP:
|
||||||
|
loopCont = 0;
|
||||||
|
break;
|
||||||
|
case TK_VALUES:
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
case TK_QUESTION:
|
||||||
|
pStmt->mtb.tagSet = false; //continue
|
||||||
|
default:
|
||||||
|
taosArrayPush(pStmt->mtb.tags, &sToken);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosArrayGetSize(pStmt->mtb.tags) <= 0) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
|
if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStmt->mtb.values = sToken;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) {
|
||||||
|
size_t tagNum = taosArrayGetSize(pStmt->mtb.tags);
|
||||||
|
size_t size = 1048576;
|
||||||
|
char *str = calloc(1, size);
|
||||||
|
size_t len = 0;
|
||||||
|
int32_t ret = 0;
|
||||||
|
int32_t j = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z);
|
||||||
|
if (len >= (size -1)) {
|
||||||
|
size *= 2;
|
||||||
|
free(str);
|
||||||
|
str = calloc(1, size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tagNum && len < (size - 1); ++i) {
|
||||||
|
SStrToken *t = taosArrayGet(pStmt->mtb.tags, i);
|
||||||
|
if (t->type == TK_QUESTION) {
|
||||||
|
int32_t l = 0;
|
||||||
|
if (i > 0) {
|
||||||
|
str[len++] = ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags[j].is_null && (*tags[j].is_null)) {
|
||||||
|
ret = converToStr(str + len, TSDB_DATA_TYPE_NULL, NULL, -1, &l);
|
||||||
|
} else {
|
||||||
|
if (tags[j].buffer == NULL) {
|
||||||
|
free(str);
|
||||||
|
tscError("empty");
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = converToStr(str + len, tags[j].buffer_type, tags[j].buffer, tags[j].length ? (int32_t)*tags[j].length : -1, &l);
|
||||||
|
}
|
||||||
|
|
||||||
|
++j;
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
free(str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += l;
|
||||||
|
} else {
|
||||||
|
len += (size_t)snprintf(str + len, size - len - 1, i > 0 ? ",%.*s" : "%.*s", t->n, t->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len >= (size - 1)) {
|
||||||
|
size *= 2;
|
||||||
|
free(str);
|
||||||
|
str = calloc(1, size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(str, ") ");
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
if ((len + strlen(pStmt->mtb.values.z)) >= (size - 1)) {
|
||||||
|
size *= 2;
|
||||||
|
free(str);
|
||||||
|
str = calloc(1, size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(str, pStmt->mtb.values.z);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStmt->mtb.sqlstr == NULL) {
|
||||||
|
pStmt->mtb.sqlstr = pSql->sqlstr;
|
||||||
|
} else {
|
||||||
|
tfree(pSql->sqlstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSql->sqlstr = str;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// interface functions
|
// interface functions
|
||||||
|
|
||||||
|
|
@ -1221,6 +1402,7 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) {
|
||||||
pStmt->taos = pObj;
|
pStmt->taos = pObj;
|
||||||
|
|
||||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||||
|
|
||||||
if (pSql == NULL) {
|
if (pSql == NULL) {
|
||||||
free(pStmt);
|
free(pStmt);
|
||||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
|
@ -1263,7 +1445,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
pSql->fp = waitForQueryRsp;
|
pSql->fp = waitForQueryRsp;
|
||||||
pSql->fetchFp = waitForQueryRsp;
|
pSql->fetchFp = waitForQueryRsp;
|
||||||
|
|
||||||
pCmd->insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
pCmd->insertParam.insertType = TSDB_QUERY_TYPE_STMT_INSERT;
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||||
tscError("%p failed to malloc payload buffer", pSql);
|
tscError("%p failed to malloc payload buffer", pSql);
|
||||||
|
|
@ -1287,39 +1469,20 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
if (tscIsInsertData(pSql->sqlstr)) {
|
if (tscIsInsertData(pSql->sqlstr)) {
|
||||||
pStmt->isInsert = true;
|
pStmt->isInsert = true;
|
||||||
|
|
||||||
pSql->cmd.numOfParams = 0;
|
pSql->cmd.insertParam.numOfParams = 0;
|
||||||
pSql->cmd.batchSize = 0;
|
pSql->cmd.batchSize = 0;
|
||||||
|
|
||||||
registerSqlObj(pSql);
|
registerSqlObj(pSql);
|
||||||
|
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = stmtParseInsertTbTags(pSql, pStmt);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
if ((ret = tsInsertInitialCheck(pSql)) != TSDB_CODE_SUCCESS) {
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t index = 0;
|
if (pStmt->multiTbInsert) {
|
||||||
SStrToken sToken = tStrGetToken(pCmd->curSql, &index, false);
|
|
||||||
|
|
||||||
if (sToken.n == 0) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sToken.n == 1 && sToken.type == TK_QUESTION) {
|
|
||||||
pStmt->multiTbInsert = true;
|
|
||||||
pStmt->mtb.tbname = sToken;
|
|
||||||
pStmt->mtb.nameSet = false;
|
|
||||||
if (pStmt->mtb.pTableHash == NULL) {
|
|
||||||
pStmt->mtb.pTableHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
|
|
||||||
}
|
|
||||||
if (pStmt->mtb.pTableBlockHashList == NULL) {
|
|
||||||
pStmt->mtb.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStmt->multiTbInsert = false;
|
|
||||||
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
|
memset(&pStmt->mtb, 0, sizeof(pStmt->mtb));
|
||||||
|
|
||||||
int32_t code = tsParseSql(pSql, true);
|
int32_t code = tsParseSql(pSql, true);
|
||||||
|
|
@ -1336,8 +1499,7 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
||||||
return normalStmtPrepare(pStmt);
|
return normalStmtPrepare(pStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags) {
|
||||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
SSqlObj* pSql = pStmt->pSql;
|
SSqlObj* pSql = pStmt->pSql;
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
@ -1379,26 +1541,38 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
|
||||||
pCmd->batchSize = pBlk->numOfRows;
|
pCmd->batchSize = pBlk->numOfRows;
|
||||||
|
|
||||||
taosHashPut(pCmd->pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
|
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pStmt->mtb.tagSet) {
|
||||||
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
pStmt->mtb.tbname = tscReplaceStrToken(&pSql->sqlstr, &pStmt->mtb.tbname, name);
|
||||||
|
} else {
|
||||||
|
if (tags == NULL) {
|
||||||
|
tscError("No tags set");
|
||||||
|
return TSDB_CODE_TSC_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ret = stmtGenInsertStatement(pSql, pStmt, name, tags);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pStmt->mtb.nameSet = true;
|
pStmt->mtb.nameSet = true;
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
|
|
||||||
pSql->cmd.parseFinished = 0;
|
pSql->cmd.insertParam.numOfParams = 0;
|
||||||
pSql->cmd.numOfParams = 0;
|
|
||||||
pSql->cmd.batchSize = 0;
|
pSql->cmd.batchSize = 0;
|
||||||
|
|
||||||
if (taosHashGetSize(pCmd->pTableBlockHashList) > 0) {
|
if (taosHashGetSize(pCmd->insertParam.pTableBlockHashList) > 0) {
|
||||||
SHashObj* hashList = pCmd->pTableBlockHashList;
|
SHashObj* hashList = pCmd->insertParam.pTableBlockHashList;
|
||||||
pCmd->pTableBlockHashList = NULL;
|
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||||
tscResetSqlCmd(pCmd, true);
|
tscResetSqlCmd(pCmd, true);
|
||||||
pCmd->pTableBlockHashList = hashList;
|
pCmd->insertParam.pTableBlockHashList = hashList;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = tsParseSql(pStmt->pSql, true);
|
int32_t code = tsParseSql(pStmt->pSql, true);
|
||||||
|
|
@ -1410,10 +1584,11 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
STableDataBlocks* pBlock = NULL;
|
STableDataBlocks* pBlock = NULL;
|
||||||
code = tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
code = tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -1426,7 +1601,6 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
pStmt->mtb.tbNum++;
|
pStmt->mtb.tbNum++;
|
||||||
|
|
||||||
taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES);
|
taosHashPut(pStmt->mtb.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)&pBlock, POINTER_BYTES);
|
||||||
|
|
||||||
taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid));
|
taosHashPut(pStmt->mtb.pTableHash, name, strlen(name), (char*) &pTableMeta->id.uid, sizeof(pTableMeta->id.uid));
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
|
tscDebug("0x%"PRIx64" table:%s is prepared, uid:%" PRIx64, pSql->self, name, pStmt->mtb.currentUid);
|
||||||
|
|
@ -1435,6 +1609,12 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
|
||||||
|
return taos_stmt_set_tbname_tags(stmt, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int taos_stmt_close(TAOS_STMT* stmt) {
|
int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
STscStmt* pStmt = (STscStmt*)stmt;
|
STscStmt* pStmt = (STscStmt*)stmt;
|
||||||
if (!pStmt->isInsert) {
|
if (!pStmt->isInsert) {
|
||||||
|
|
@ -1451,8 +1631,10 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
if (pStmt->multiTbInsert) {
|
if (pStmt->multiTbInsert) {
|
||||||
taosHashCleanup(pStmt->mtb.pTableHash);
|
taosHashCleanup(pStmt->mtb.pTableHash);
|
||||||
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true);
|
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, true);
|
||||||
taosHashCleanup(pStmt->pSql->cmd.pTableBlockHashList);
|
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
||||||
pStmt->pSql->cmd.pTableBlockHashList = NULL;
|
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
||||||
|
taosArrayDestroy(pStmt->mtb.tags);
|
||||||
|
tfree(pStmt->mtb.sqlstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1617,9 +1799,10 @@ int taos_stmt_execute(TAOS_STMT* stmt) {
|
||||||
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
} else {
|
} else {
|
||||||
if (pStmt->pSql != NULL) {
|
if (pStmt->pSql != NULL) {
|
||||||
taos_free_result(pStmt->pSql);
|
tscFreeSqlObj(pStmt->pSql);
|
||||||
pStmt->pSql = NULL;
|
pStmt->pSql = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql);
|
pStmt->pSql = taos_query((TAOS*)pStmt->taos, sql);
|
||||||
ret = taos_errno(pStmt->pSql);
|
ret = taos_errno(pStmt->pSql);
|
||||||
free(sql);
|
free(sql);
|
||||||
|
|
@ -1670,7 +1853,7 @@ int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
|
||||||
if (pStmt->isInsert) {
|
if (pStmt->isInsert) {
|
||||||
SSqlObj* pSql = pStmt->pSql;
|
SSqlObj* pSql = pStmt->pSql;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
*nums = pCmd->numOfParams;
|
*nums = pCmd->insertParam.numOfParams;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
SNormalStmt* normal = &pStmt->normal;
|
SNormalStmt* normal = &pStmt->normal;
|
||||||
|
|
@ -1689,16 +1872,16 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
|
||||||
|
|
||||||
if (pStmt->isInsert) {
|
if (pStmt->isInsert) {
|
||||||
SSqlCmd* pCmd = &pStmt->pSql->cmd;
|
SSqlCmd* pCmd = &pStmt->pSql->cmd;
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->insertParam.pTableBlockHashList == NULL) {
|
||||||
pCmd->pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
pCmd->insertParam.pTableBlockHashList = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
STableDataBlocks* pBlock = NULL;
|
STableDataBlocks* pBlock = NULL;
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
tscGetDataBlockFromList(pCmd->pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
tscGetDataBlockFromList(pCmd->insertParam.pTableBlockHashList, pTableMeta->id.uid, TSDB_PAYLOAD_SIZE, sizeof(SSubmitBlk),
|
||||||
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
pTableMeta->tableInfo.rowSize, &pTableMetaInfo->name, pTableMeta, &pBlock, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
// todo handle error
|
// todo handle error
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -373,11 +373,15 @@ int taos_num_fields(TAOS_RES *res) {
|
||||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||||
|
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
if (pQueryInfo == NULL) {
|
if (pQueryInfo == NULL) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(pQueryInfo->pDownstream != NULL) {
|
||||||
|
pQueryInfo = pQueryInfo->pDownstream;
|
||||||
|
}
|
||||||
|
|
||||||
size_t numOfCols = tscNumOfFields(pQueryInfo);
|
size_t numOfCols = tscNumOfFields(pQueryInfo);
|
||||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SInternalField* pInfo = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i);
|
SInternalField* pInfo = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i);
|
||||||
|
|
@ -408,7 +412,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
if (pQueryInfo == NULL) {
|
if (pQueryInfo == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -560,7 +564,7 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -614,7 +618,7 @@ int taos_errno(TAOS_RES *tres) {
|
||||||
* why the sql is invalid
|
* why the sql is invalid
|
||||||
*/
|
*/
|
||||||
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||||
if (code != TSDB_CODE_TSC_INVALID_SQL
|
if (code != TSDB_CODE_TSC_INVALID_OPERATION
|
||||||
&& code != TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
|
&& code != TSDB_CODE_TSC_SQL_SYNTAX_ERROR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -623,7 +627,7 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||||
|
|
||||||
char *z = NULL;
|
char *z = NULL;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
z = strstr(pCmd->payload, "invalid SQL");
|
z = strstr(pCmd->payload, "invalid operation");
|
||||||
if (z == NULL) {
|
if (z == NULL) {
|
||||||
z = strstr(pCmd->payload, "syntax error");
|
z = strstr(pCmd->payload, "syntax error");
|
||||||
}
|
}
|
||||||
|
|
@ -673,7 +677,7 @@ char *taos_get_client_info() { return version; }
|
||||||
static void tscKillSTableQuery(SSqlObj *pSql) {
|
static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if (!tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -724,7 +728,7 @@ void taos_stop_query(TAOS_RES *res) {
|
||||||
// set the error code for master pSqlObj firstly
|
// set the error code for master pSqlObj firstly
|
||||||
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
|
|
||||||
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) {
|
||||||
assert(pSql->rpcRid <= 0);
|
assert(pSql->rpcRid <= 0);
|
||||||
|
|
@ -754,7 +758,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
if (pQueryInfo == NULL) {
|
if (pQueryInfo == NULL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -829,9 +833,9 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
int32_t charLen = varDataLen((char*)row[i] - VARSTR_HEADER_SIZE);
|
int32_t charLen = varDataLen((char*)row[i] - VARSTR_HEADER_SIZE);
|
||||||
if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
|
if (fields[i].type == TSDB_DATA_TYPE_BINARY) {
|
||||||
assert(charLen <= fields[i].bytes);
|
assert(charLen <= fields[i].bytes && charLen >= 0);
|
||||||
} else {
|
} else {
|
||||||
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE);
|
assert(charLen <= fields[i].bytes * TSDB_NCHAR_SIZE && charLen >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(str + len, row[i], charLen);
|
memcpy(str + len, row[i], charLen);
|
||||||
|
|
@ -870,13 +874,9 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
|
|
||||||
pSql->pTscObj = taos;
|
pSql->pTscObj = taos;
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
|
|
||||||
SSqlRes *pRes = &pSql->res;
|
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
pRes->numOfTotal = 0;
|
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||||
pRes->numOfClauseTotal = 0;
|
|
||||||
|
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj);
|
tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj);
|
||||||
|
|
||||||
|
|
@ -896,10 +896,10 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
|
|
||||||
strtolower(pSql->sqlstr, sql);
|
strtolower(pSql->sqlstr, sql);
|
||||||
|
|
||||||
pCmd->curSql = NULL;
|
// pCmd->curSql = NULL;
|
||||||
if (NULL != pCmd->pTableBlockHashList) {
|
if (NULL != pCmd->insertParam.pTableBlockHashList) {
|
||||||
taosHashCleanup(pCmd->pTableBlockHashList);
|
taosHashCleanup(pCmd->insertParam.pTableBlockHashList);
|
||||||
pCmd->pTableBlockHashList = NULL;
|
pCmd->insertParam.pTableBlockHashList = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->fp = asyncCallback;
|
pSql->fp = asyncCallback;
|
||||||
|
|
@ -921,90 +921,19 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
void loadMultiTableMetaCallback(void *param, TAOS_RES *res, int code) {
|
||||||
// must before clean the sqlcmd object
|
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
|
||||||
tscResetSqlCmd(&pSql->cmd, false);
|
if (pSql == NULL) {
|
||||||
|
return;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
|
||||||
|
|
||||||
pCmd->command = TSDB_SQL_MULTI_META;
|
|
||||||
pCmd->count = 0;
|
|
||||||
|
|
||||||
int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
|
||||||
char *str = (char *)tblNameList;
|
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex);
|
|
||||||
if (pQueryInfo == NULL) {
|
|
||||||
pSql->res.code = terrno;
|
|
||||||
return terrno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
|
pSql->res.code = code;
|
||||||
|
tsem_post(&pSql->rspSem);
|
||||||
|
}
|
||||||
|
|
||||||
if ((code = tscAllocPayload(pCmd, tblListLen + 16)) != TSDB_CODE_SUCCESS) {
|
static void freeElem(void* p) {
|
||||||
return code;
|
tfree(*(char**)p);
|
||||||
}
|
|
||||||
|
|
||||||
char *nextStr;
|
|
||||||
char tblName[TSDB_TABLE_FNAME_LEN];
|
|
||||||
int payloadLen = 0;
|
|
||||||
char *pMsg = pCmd->payload;
|
|
||||||
while (1) {
|
|
||||||
nextStr = strchr(str, ',');
|
|
||||||
if (nextStr == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(tblName, str, nextStr - str);
|
|
||||||
int32_t len = (int32_t)(nextStr - str);
|
|
||||||
tblName[len] = '\0';
|
|
||||||
|
|
||||||
str = nextStr + 1;
|
|
||||||
len = (int32_t)strtrim(tblName);
|
|
||||||
|
|
||||||
SStrToken sToken = {.n = len, .type = TK_ID, .z = tblName};
|
|
||||||
tGetToken(tblName, &sToken.type);
|
|
||||||
|
|
||||||
// Check if the table name available or not
|
|
||||||
if (tscValidateName(&sToken) != TSDB_CODE_SUCCESS) {
|
|
||||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
|
||||||
sprintf(pCmd->payload, "table name is invalid");
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((code = tscSetTableFullName(pTableMetaInfo, &sToken, pSql)) != TSDB_CODE_SUCCESS) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) {
|
|
||||||
code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
|
|
||||||
sprintf(pCmd->payload, "tables over the max number");
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t xlen = tNameLen(&pTableMetaInfo->name);
|
|
||||||
if (payloadLen + xlen + 128 >= pCmd->allocSize) {
|
|
||||||
char *pNewMem = realloc(pCmd->payload, pCmd->allocSize + tblListLen);
|
|
||||||
if (pNewMem == NULL) {
|
|
||||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
sprintf(pCmd->payload, "failed to allocate memory");
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
pCmd->payload = pNewMem;
|
|
||||||
pCmd->allocSize = pCmd->allocSize + tblListLen;
|
|
||||||
pMsg = pCmd->payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
char n[TSDB_TABLE_FNAME_LEN] = {0};
|
|
||||||
tNameExtractFullName(&pTableMetaInfo->name, n);
|
|
||||||
payloadLen += sprintf(pMsg + payloadLen, "%s,", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
*(pMsg + payloadLen) = '\0';
|
|
||||||
pCmd->payloadLen = payloadLen + 1;
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
|
|
@ -1020,38 +949,28 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
pSql->pTscObj = taos;
|
pSql->pTscObj = taos;
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
|
|
||||||
SSqlRes *pRes = &pSql->res;
|
pSql->fp = NULL; // todo set the correct callback function pointer
|
||||||
|
pSql->cmd.pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
pRes->code = 0;
|
int32_t length = (int32_t)strlen(tableNameList);
|
||||||
pRes->numOfTotal = 0; // the number of getting table meta from server
|
if (length > MAX_TABLE_NAME_LENGTH) {
|
||||||
pRes->numOfClauseTotal = 0;
|
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, length, MAX_TABLE_NAME_LENGTH);
|
||||||
|
|
||||||
assert(pSql->fp == NULL);
|
|
||||||
tscDebug("0x%"PRIx64" tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
|
||||||
|
|
||||||
int32_t tblListLen = (int32_t)strlen(tableNameList);
|
|
||||||
if (tblListLen > MAX_TABLE_NAME_LENGTH) {
|
|
||||||
tscError("0x%"PRIx64" tableNameList too long, length:%d, maximum allowed:%d", pSql->self, tblListLen, MAX_TABLE_NAME_LENGTH);
|
|
||||||
tscFreeSqlObj(pSql);
|
tscFreeSqlObj(pSql);
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *str = calloc(1, tblListLen + 1);
|
char *str = calloc(1, length + 1);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
tscError("0x%"PRIx64" failed to allocate sql string buffer", pSql->self);
|
||||||
tscFreeSqlObj(pSql);
|
tscFreeSqlObj(pSql);
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
strtolower(str, tableNameList);
|
strtolower(str, tableNameList);
|
||||||
int32_t code = (uint8_t) tscParseTblNameList(pSql, str, tblListLen);
|
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
|
||||||
/*
|
int32_t code = (uint8_t) tscTransferTableNameList(pSql, str, length, plist);
|
||||||
* set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query.
|
|
||||||
* If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscBuildAndSendRequest()
|
|
||||||
* to free connection, which may cause segment fault, when the parse phrase is not even successfully executed.
|
|
||||||
*/
|
|
||||||
pRes->qId = 0;
|
|
||||||
free(str);
|
free(str);
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
|
@ -1059,12 +978,23 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDoQuery(pSql);
|
registerSqlObj(pSql);
|
||||||
|
tscDebug("0x%"PRIx64" load multiple table meta, tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj);
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" load multi-table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj);
|
code = getMultiTableMetaFromMnode(pSql, plist, vgroupList, loadMultiTableMetaCallback);
|
||||||
if ((code = pRes->code) != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
tscFreeSqlObj(pSql);
|
code = TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosArrayDestroyEx(plist, freeElem);
|
||||||
|
taosArrayDestroyEx(vgroupList, freeElem);
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscFreeRegisteredSqlObj(pSql);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsem_wait(&pSql->rspSem);
|
||||||
|
tscFreeRegisteredSqlObj(pSql);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tschemautil.h>
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
|
|
@ -25,6 +24,7 @@
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#include "tscProfile.h"
|
#include "tscProfile.h"
|
||||||
|
#include "tscSubquery.h"
|
||||||
|
|
||||||
static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOfRows);
|
static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOfRows);
|
static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOfRows);
|
||||||
|
|
@ -37,7 +37,7 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l
|
||||||
|
|
||||||
static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||||
SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i);
|
SExprInfo *pExpr = tscExprGet(pQueryInfo, i);
|
||||||
if (pExpr->base.functionId != TSDB_FUNC_PRJ) {
|
if (pExpr->base.functionId != TSDB_FUNC_PRJ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -48,8 +48,8 @@ static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, int16_t prec) {
|
static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, int16_t prec) {
|
||||||
float retryRangeFactor = 0.3f;
|
float retryRangeFactor = 0.3f;
|
||||||
int64_t retryDelta = (int64_t)(tsStreamCompRetryDelay * retryRangeFactor);
|
int64_t retryDelta = (int64_t)(tsRetryStreamCompDelay * retryRangeFactor);
|
||||||
retryDelta = ((rand() % retryDelta) + tsStreamCompRetryDelay) * 1000L;
|
retryDelta = ((rand() % retryDelta) + tsRetryStreamCompDelay) * 1000L;
|
||||||
|
|
||||||
if (pStream->interval.intervalUnit != 'n' && pStream->interval.intervalUnit != 'y') {
|
if (pStream->interval.intervalUnit != 'n' && pStream->interval.intervalUnit != 'y') {
|
||||||
// change to ms
|
// change to ms
|
||||||
|
|
@ -89,12 +89,12 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
if (code == 0 && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
code = tscGetSTableVgroupInfo(pSql, 0);
|
code = tscGetSTableVgroupInfo(pSql, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
|
@ -110,7 +110,8 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) {
|
||||||
// failed to get table Meta or vgroup list, retry in 10sec.
|
// failed to get table Meta or vgroup list, retry in 10sec.
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
tscTansformFuncForSTableQuery(pQueryInfo);
|
tscTansformFuncForSTableQuery(pQueryInfo);
|
||||||
tscDebug("0x%"PRIx64" stream:%p started to query table:%s", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name));
|
|
||||||
|
tscDebug("0x%"PRIx64" stream:%p, start stream query on:%s QueryInfo->skey=%"PRId64" ekey=%"PRId64" ", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name), pQueryInfo->window.skey, pQueryInfo->window.ekey);
|
||||||
|
|
||||||
pQueryInfo->command = TSDB_SQL_SELECT;
|
pQueryInfo->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
|
|
@ -138,7 +139,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||||
|
|
||||||
pStream->numOfRes = 0; // reset the numOfRes.
|
pStream->numOfRes = 0; // reset the numOfRes.
|
||||||
SSqlObj *pSql = pStream->pSql;
|
SSqlObj *pSql = pStream->pSql;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
tscDebug("0x%"PRIx64" timer launch query", pSql->self);
|
tscDebug("0x%"PRIx64" timer launch query", pSql->self);
|
||||||
|
|
||||||
if (pStream->isProject) {
|
if (pStream->isProject) {
|
||||||
|
|
@ -164,7 +165,11 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||||
if (etime > pStream->etime) {
|
if (etime > pStream->etime) {
|
||||||
etime = pStream->etime;
|
etime = pStream->etime;
|
||||||
} else if (pStream->interval.intervalUnit != 'y' && pStream->interval.intervalUnit != 'n') {
|
} else if (pStream->interval.intervalUnit != 'y' && pStream->interval.intervalUnit != 'n') {
|
||||||
|
if(pStream->stime == INT64_MIN) {
|
||||||
|
etime = taosTimeTruncate(etime, &pStream->interval, pStream->precision);
|
||||||
|
} else {
|
||||||
etime = pStream->stime + (etime - pStream->stime) / pStream->interval.interval * pStream->interval.interval;
|
etime = pStream->stime + (etime - pStream->stime) / pStream->interval.interval * pStream->interval.interval;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
etime = taosTimeTruncate(etime, &pStream->interval, pStream->precision);
|
etime = taosTimeTruncate(etime, &pStream->interval, pStream->precision);
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +202,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
||||||
tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self,
|
tscError("0x%"PRIx64" stream:%p, query data failed, code:0x%08x, retry in %" PRId64 "ms", pStream->pSql->self,
|
||||||
pStream, numOfRows, retryDelay);
|
pStream, numOfRows, retryDelay);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0);
|
||||||
|
|
||||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||||
|
|
@ -224,7 +229,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
||||||
static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) {
|
static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) {
|
||||||
#if 0
|
#if 0
|
||||||
SSqlObj * pSql = pStream->pSql;
|
SSqlObj * pSql = pStream->pSql;
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) {
|
if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -273,7 +278,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
STableMetaInfo *pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||||
|
|
||||||
if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful.
|
if (numOfRows > 0) { // when reaching here the first execution of stream computing is successful.
|
||||||
|
|
@ -353,8 +358,8 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer)
|
||||||
tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 "(ts window ekey), in %" PRId64 " ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream,
|
tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 "(ts window ekey), in %" PRId64 " ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream,
|
||||||
now + timer, timer, delay, pStream->stime, etime);
|
now + timer, timer, delay, pStream->stime, etime);
|
||||||
} else {
|
} else {
|
||||||
tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 "(ts window ekey), in %" PRId64 " ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream,
|
tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 " - %" PRId64 " end, in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream,
|
||||||
pStream->stime, timer, delay, pStream->stime - pStream->interval.interval, pStream->stime - 1);
|
pStream->stime, pStream->etime, timer, delay, pStream->stime - pStream->interval.interval, pStream->stime - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||||
|
|
@ -444,7 +449,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||||
int64_t minIntervalTime =
|
int64_t minIntervalTime =
|
||||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
if (!pStream->isProject && pQueryInfo->interval.interval == 0) {
|
||||||
sprintf(pSql->cmd.payload, "the interval value is 0");
|
sprintf(pSql->cmd.payload, "the interval value is 0");
|
||||||
|
|
@ -494,7 +499,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||||
|
|
||||||
if (pStream->isProject) {
|
if (pStream->isProject) {
|
||||||
// no data in table, flush all data till now to destination meter, 10sec delay
|
// no data in table, flush all data till now to destination meter, 10sec delay
|
||||||
|
|
@ -556,7 +561,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
|
|
@ -576,6 +581,14 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||||
|
|
||||||
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
||||||
|
|
||||||
|
// set stime with ltime if ltime > stime
|
||||||
|
const char* dstTable = pStream->dstTable? pStream->dstTable: "";
|
||||||
|
tscDebug(" CQ table=%s ltime is %"PRId64, dstTable, pStream->ltime);
|
||||||
|
if(pStream->ltime != INT64_MIN && pStream->ltime > pStream->stime) {
|
||||||
|
tscWarn(" CQ set stream %s stime=%"PRId64" replace with ltime=%"PRId64" if ltime>0 ", dstTable, pStream->stime, pStream->ltime);
|
||||||
|
pStream->stime = pStream->ltime;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
||||||
pCmd->command = TSDB_SQL_SELECT;
|
pCmd->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
|
|
@ -591,11 +604,75 @@ void tscSetStreamDestTable(SSqlStream* pStream, const char* dstTable) {
|
||||||
pStream->dstTable = dstTable;
|
pStream->dstTable = dstTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
// fetchFp call back
|
||||||
|
void fetchFpStreamLastRow(void* param ,TAOS_RES* res, int num) {
|
||||||
|
SSqlStream* pStream = (SSqlStream*)param;
|
||||||
|
SSqlObj* pSql = res;
|
||||||
|
|
||||||
|
// get row data set to ltime
|
||||||
|
tscSetSqlOwner(pSql);
|
||||||
|
TAOS_ROW row = doSetResultRowData(pSql);
|
||||||
|
if( row && row[0] ) {
|
||||||
|
pStream->ltime = *((int64_t*)row[0]);
|
||||||
|
const char* dstTable = pStream->dstTable? pStream->dstTable: "";
|
||||||
|
tscDebug(" CQ stream table=%s last row time=%"PRId64" .", dstTable, pStream->ltime);
|
||||||
|
}
|
||||||
|
tscClearSqlOwner(pSql);
|
||||||
|
|
||||||
|
// no condition call
|
||||||
|
tscCreateStream(param, pStream->pSql, TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fp callback
|
||||||
|
void fpStreamLastRow(void* param ,TAOS_RES* res, int code) {
|
||||||
|
// check result successful
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscCreateStream(param, res, TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(res);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous fetch last row data
|
||||||
|
taos_fetch_rows_a(res, fetchFpStreamLastRow, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbParseSql(void* param, TAOS_RES* res, int code) {
|
||||||
|
// check result successful
|
||||||
|
SSqlStream* pStream = (SSqlStream*)param;
|
||||||
|
SSqlObj* pSql = pStream->pSql;
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pSql->res.code = code;
|
||||||
|
tscDebug("0x%"PRIx64" open stream parse sql failed, sql:%s, reason:%s, code:%s", pSql->self, pSql->sqlstr, pCmd->payload, tstrerror(code));
|
||||||
|
pStream->fp(pStream->param, NULL, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check dstTable valid
|
||||||
|
if(pStream->dstTable == NULL || strlen(pStream->dstTable) == 0) {
|
||||||
|
tscDebug(" cbParseSql dstTable is empty.");
|
||||||
|
tscCreateStream(param, res, code);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// query stream last row time async
|
||||||
|
char sql[128] = "";
|
||||||
|
sprintf(sql, "select last_row(*) from %s;", pStream->dstTable);
|
||||||
|
taos_query_a(pSql->pTscObj, sql, fpStreamLastRow, param);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* dstTable, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
int64_t stime, void *param, void (*callback)(void *)) {
|
int64_t stime, void *param, void (*callback)(void *)) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
if (pObj == NULL || pObj->signature != pObj) return NULL;
|
if (pObj == NULL || pObj->signature != pObj) return NULL;
|
||||||
|
|
||||||
|
if(fp == NULL){
|
||||||
|
tscError(" taos_open_stream api fp param must not NULL.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||||
if (pSql == NULL) {
|
if (pSql == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -614,6 +691,7 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pStream->ltime = INT64_MIN;
|
||||||
pStream->stime = stime;
|
pStream->stime = stime;
|
||||||
pStream->fp = fp;
|
pStream->fp = fp;
|
||||||
pStream->callback = callback;
|
pStream->callback = callback;
|
||||||
|
|
@ -622,7 +700,11 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
pSql->pStream = pStream;
|
pSql->pStream = pStream;
|
||||||
pSql->param = pStream;
|
pSql->param = pStream;
|
||||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||||
|
tscSetStreamDestTable(pStream, dstTable);
|
||||||
|
|
||||||
|
pSql->pStream = pStream;
|
||||||
|
pSql->param = pStream;
|
||||||
|
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||||
pSql->sqlstr = calloc(1, strlen(sqlstr) + 1);
|
pSql->sqlstr = calloc(1, strlen(sqlstr) + 1);
|
||||||
if (pSql->sqlstr == NULL) {
|
if (pSql->sqlstr == NULL) {
|
||||||
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
tscError("0x%"PRIx64" failed to malloc sql string buffer", pSql->self);
|
||||||
|
|
@ -632,19 +714,26 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
}
|
}
|
||||||
|
|
||||||
strtolower(pSql->sqlstr, sqlstr);
|
strtolower(pSql->sqlstr, sqlstr);
|
||||||
|
pSql->fp = tscCreateStream;
|
||||||
|
pSql->fetchFp = tscCreateStream;
|
||||||
|
pSql->cmd.resColumnId = TSDB_RES_COL_ID;
|
||||||
|
|
||||||
|
tsem_init(&pSql->rspSem, 0, 0);
|
||||||
registerSqlObj(pSql);
|
registerSqlObj(pSql);
|
||||||
|
|
||||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
tsem_init(&pSql->rspSem, 0, 0);
|
|
||||||
|
|
||||||
pSql->fp = tscCreateStream;
|
pSql->fp = cbParseSql;
|
||||||
pSql->fetchFp = tscCreateStream;
|
pSql->fetchFp = cbParseSql;
|
||||||
|
|
||||||
|
registerSqlObj(pSql);
|
||||||
|
|
||||||
int32_t code = tsParseSql(pSql, true);
|
int32_t code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
tscCreateStream(pStream, pSql, code);
|
cbParseSql(pStream, pSql, code);
|
||||||
} else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
tscDebug(" CQ taso_open_stream IN Process. sql=%s", sqlstr);
|
||||||
|
} else {
|
||||||
tscError("0x%"PRIx64" open stream failed, sql:%s, code:%s", pSql->self, sqlstr, tstrerror(code));
|
tscError("0x%"PRIx64" open stream failed, sql:%s, code:%s", pSql->self, sqlstr, tstrerror(code));
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
free(pStream);
|
free(pStream);
|
||||||
|
|
@ -654,6 +743,11 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
return pStream;
|
return pStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
|
int64_t stime, void *param, void (*callback)(void *)) {
|
||||||
|
return taos_open_stream_withname(taos, "", sqlstr, fp, stime, param, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void taos_close_stream(TAOS_STREAM *handle) {
|
void taos_close_stream(TAOS_STREAM *handle) {
|
||||||
SSqlStream *pStream = (SSqlStream *)handle;
|
SSqlStream *pStream = (SSqlStream *)handle;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
||||||
strtolower(pSql->sqlstr, pSql->sqlstr);
|
strtolower(pSql->sqlstr, pSql->sqlstr);
|
||||||
pRes->qId = 0;
|
pRes->qId = 0;
|
||||||
pRes->numOfRows = 1;
|
pRes->numOfRows = 1;
|
||||||
|
pCmd->resColumnId = TSDB_RES_COL_ID;
|
||||||
|
|
||||||
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
|
@ -173,7 +174,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
||||||
|
|
||||||
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||||
line = __LINE__;
|
line = __LINE__;
|
||||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
code = TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,7 +267,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
||||||
|
|
||||||
pSub->lastSyncTime = taosGetTimestampMs();
|
pSub->lastSyncTime = taosGetTimestampMs();
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
||||||
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0};
|
SSubscriptionProgress target = {.uid = pTableMeta->id.uid, .key = 0};
|
||||||
|
|
@ -284,7 +285,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
||||||
}
|
}
|
||||||
size_t numOfTables = taosArrayGetSize(tables);
|
size_t numOfTables = taosArrayGetSize(tables);
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress));
|
SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress));
|
||||||
for( size_t i = 0; i < numOfTables; i++ ) {
|
for( size_t i = 0; i < numOfTables; i++ ) {
|
||||||
STidTags* tt = taosArrayGet( tables, i );
|
STidTags* tt = taosArrayGet( tables, i );
|
||||||
|
|
@ -304,7 +305,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
||||||
}
|
}
|
||||||
taosArrayDestroy(tables);
|
taosArrayDestroy(tables);
|
||||||
|
|
||||||
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,8 +504,8 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||||
SSqlObj *pSql = pSub->pSql;
|
SSqlObj *pSql = pSub->pSql;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||||
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription
|
if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pSub->progress);
|
size_t size = taosArrayGetSize(pSub->progress);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -234,6 +234,7 @@ typedef struct SDataCol {
|
||||||
int len; // column data length
|
int len; // column data length
|
||||||
VarDataOffsetT *dataOff; // For binary and nchar data, the offset in the data column
|
VarDataOffsetT *dataOff; // For binary and nchar data, the offset in the data column
|
||||||
void * pData; // Actual data pointer
|
void * pData; // Actual data pointer
|
||||||
|
TSKEY ts; // only used in last NULL column
|
||||||
} SDataCol;
|
} SDataCol;
|
||||||
|
|
||||||
static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
static FORCE_INLINE void dataColReset(SDataCol *pDataCol) { pDataCol->len = 0; }
|
||||||
|
|
@ -318,7 +319,7 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
||||||
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
||||||
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
||||||
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
|
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *src, int rowsToMerge);
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset);
|
||||||
|
|
||||||
// ----------------- K-V data row structure
|
// ----------------- K-V data row structure
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ extern int8_t tsEnableTelemetryReporting;
|
||||||
extern char tsEmail[];
|
extern char tsEmail[];
|
||||||
extern char tsArbitrator[];
|
extern char tsArbitrator[];
|
||||||
extern int8_t tsArbOnline;
|
extern int8_t tsArbOnline;
|
||||||
|
extern int64_t tsArbOnlineTimestamp;
|
||||||
extern int32_t tsDnodeId;
|
extern int32_t tsDnodeId;
|
||||||
|
|
||||||
// common
|
// common
|
||||||
|
|
@ -75,7 +76,7 @@ extern int32_t tsMinSlidingTime;
|
||||||
extern int32_t tsMinIntervalTime;
|
extern int32_t tsMinIntervalTime;
|
||||||
extern int32_t tsMaxStreamComputDelay;
|
extern int32_t tsMaxStreamComputDelay;
|
||||||
extern int32_t tsStreamCompStartDelay;
|
extern int32_t tsStreamCompStartDelay;
|
||||||
extern int32_t tsStreamCompRetryDelay;
|
extern int32_t tsRetryStreamCompDelay;
|
||||||
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
|
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
|
||||||
extern int32_t tsProjectExecInterval;
|
extern int32_t tsProjectExecInterval;
|
||||||
extern int64_t tsMaxRetentWindow;
|
extern int64_t tsMaxRetentWindow;
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ typedef struct SResPair {
|
||||||
// the structure for sql function in select clause
|
// the structure for sql function in select clause
|
||||||
typedef struct SSqlExpr {
|
typedef struct SSqlExpr {
|
||||||
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
|
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
|
||||||
|
char token[TSDB_COL_NAME_LEN]; // original token
|
||||||
SColIndex colInfo;
|
SColIndex colInfo;
|
||||||
|
|
||||||
uint64_t uid; // refactor use the pointer
|
uint64_t uid; // refactor use the pointer
|
||||||
|
|
||||||
int16_t functionId; // function id in aAgg array
|
int16_t functionId; // function id in aAgg array
|
||||||
|
|
@ -92,10 +92,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len);
|
||||||
|
|
||||||
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
|
void extractTableNameFromToken(SStrToken *pToken, SStrToken* pTable);
|
||||||
|
|
||||||
//SSchema tGetTbnameColumnSchema();
|
|
||||||
|
|
||||||
SSchema tGetBlockDistColumnSchema();
|
|
||||||
|
|
||||||
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name);
|
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name);
|
||||||
|
|
||||||
bool tscValidateTableNameLength(size_t len);
|
bool tscValidateTableNameLength(size_t len);
|
||||||
|
|
|
||||||
|
|
@ -2569,6 +2569,7 @@ _arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
|
||||||
case TSDB_BINARY_OP_REMAINDER:
|
case TSDB_BINARY_OP_REMAINDER:
|
||||||
return vectorRemainder;
|
return vectorRemainder;
|
||||||
default:
|
default:
|
||||||
|
assert(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -441,30 +441,35 @@ void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols)
|
||||||
pCols->numOfRows++;
|
pCols->numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge) {
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset) {
|
||||||
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
||||||
ASSERT(target->numOfCols == source->numOfCols);
|
ASSERT(target->numOfCols == source->numOfCols);
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
if (pOffset == NULL) {
|
||||||
|
pOffset = &offset;
|
||||||
|
}
|
||||||
|
|
||||||
SDataCols *pTarget = NULL;
|
SDataCols *pTarget = NULL;
|
||||||
|
|
||||||
if (dataColsKeyLast(target) < dataColsKeyFirst(source)) { // No overlap
|
if ((target->numOfRows == 0) || (dataColsKeyLast(target) < dataColsKeyFirst(source))) { // No overlap
|
||||||
ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints);
|
ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints);
|
||||||
for (int i = 0; i < rowsToMerge; i++) {
|
for (int i = 0; i < rowsToMerge; i++) {
|
||||||
for (int j = 0; j < source->numOfCols; j++) {
|
for (int j = 0; j < source->numOfCols; j++) {
|
||||||
if (source->cols[j].len > 0) {
|
if (source->cols[j].len > 0) {
|
||||||
dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i), target->numOfRows,
|
dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i + (*pOffset)), target->numOfRows,
|
||||||
target->maxPoints);
|
target->maxPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target->numOfRows++;
|
target->numOfRows++;
|
||||||
}
|
}
|
||||||
|
(*pOffset) += rowsToMerge;
|
||||||
} else {
|
} else {
|
||||||
pTarget = tdDupDataCols(target, true);
|
pTarget = tdDupDataCols(target, true);
|
||||||
if (pTarget == NULL) goto _err;
|
if (pTarget == NULL) goto _err;
|
||||||
|
|
||||||
int iter1 = 0;
|
int iter1 = 0;
|
||||||
int iter2 = 0;
|
tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, pOffset, source->numOfRows,
|
||||||
tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, &iter2, source->numOfRows,
|
|
||||||
pTarget->numOfRows + rowsToMerge);
|
pTarget->numOfRows + rowsToMerge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <texpr.h>
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "texpr.h"
|
#include "texpr.h"
|
||||||
|
|
@ -465,27 +466,29 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
tExprNode* exprdup(tExprNode* pTree) {
|
tExprNode* exprdup(tExprNode* pNode) {
|
||||||
if (pTree == NULL) {
|
if (pNode == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
tExprNode* pCloned = calloc(1, sizeof(tExprNode));
|
||||||
if (pTree->nodeType == TSQL_NODE_EXPR) {
|
if (pNode->nodeType == TSQL_NODE_EXPR) {
|
||||||
tExprNode* pLeft = exprdup(pTree->_node.pLeft);
|
tExprNode* pLeft = exprdup(pNode->_node.pLeft);
|
||||||
tExprNode* pRight = exprdup(pTree->_node.pRight);
|
tExprNode* pRight = exprdup(pNode->_node.pRight);
|
||||||
|
|
||||||
pNode->nodeType = TSQL_NODE_EXPR;
|
pCloned->_node.pLeft = pLeft;
|
||||||
pNode->_node.pLeft = pLeft;
|
pCloned->_node.pRight = pRight;
|
||||||
pNode->_node.pRight = pRight;
|
pCloned->_node.optr = pNode->_node.optr;
|
||||||
} else if (pTree->nodeType == TSQL_NODE_VALUE) {
|
pCloned->_node.hasPK = pNode->_node.hasPK;
|
||||||
pNode->pVal = calloc(1, sizeof(tVariant));
|
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
|
||||||
tVariantAssign(pNode->pVal, pTree->pVal);
|
pCloned->pVal = calloc(1, sizeof(tVariant));
|
||||||
} else if (pTree->nodeType == TSQL_NODE_COL) {
|
tVariantAssign(pCloned->pVal, pNode->pVal);
|
||||||
pNode->pSchema = calloc(1, sizeof(SSchema));
|
} else if (pNode->nodeType == TSQL_NODE_COL) {
|
||||||
*pNode->pSchema = *pTree->pSchema;
|
pCloned->pSchema = calloc(1, sizeof(SSchema));
|
||||||
|
*pCloned->pSchema = *pNode->pSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pNode;
|
pCloned->nodeType = pNode->nodeType;
|
||||||
|
return pCloned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,12 @@ int32_t tsNumOfMnodes = 3;
|
||||||
int8_t tsEnableVnodeBak = 1;
|
int8_t tsEnableVnodeBak = 1;
|
||||||
int8_t tsEnableTelemetryReporting = 1;
|
int8_t tsEnableTelemetryReporting = 1;
|
||||||
int8_t tsArbOnline = 0;
|
int8_t tsArbOnline = 0;
|
||||||
|
int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME;
|
||||||
char tsEmail[TSDB_FQDN_LEN] = {0};
|
char tsEmail[TSDB_FQDN_LEN] = {0};
|
||||||
int32_t tsDnodeId = 0;
|
int32_t tsDnodeId = 0;
|
||||||
|
|
||||||
// common
|
// common
|
||||||
int32_t tsRpcTimer = 1000;
|
int32_t tsRpcTimer = 300;
|
||||||
int32_t tsRpcMaxTime = 600; // seconds;
|
int32_t tsRpcMaxTime = 600; // seconds;
|
||||||
int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default
|
int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default
|
||||||
int32_t tsMaxShellConns = 50000;
|
int32_t tsMaxShellConns = 50000;
|
||||||
|
|
@ -93,7 +94,7 @@ int32_t tsMaxStreamComputDelay = 20000;
|
||||||
int32_t tsStreamCompStartDelay = 10000;
|
int32_t tsStreamCompStartDelay = 10000;
|
||||||
|
|
||||||
// the stream computing delay time after executing failed, change accordingly
|
// the stream computing delay time after executing failed, change accordingly
|
||||||
int32_t tsStreamCompRetryDelay = 10;
|
int32_t tsRetryStreamCompDelay = 10*1000;
|
||||||
|
|
||||||
// The delayed computing ration. 10% of the whole computing time window by default.
|
// The delayed computing ration. 10% of the whole computing time window by default.
|
||||||
float tsStreamComputDelayRatio = 0.1f;
|
float tsStreamComputDelayRatio = 0.1f;
|
||||||
|
|
@ -710,7 +711,7 @@ static void doInitGlobalConfig(void) {
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
cfg.option = "retryStreamCompDelay";
|
cfg.option = "retryStreamCompDelay";
|
||||||
cfg.ptr = &tsStreamCompRetryDelay;
|
cfg.ptr = &tsRetryStreamCompDelay;
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||||
cfg.minValue = 10;
|
cfg.minValue = 10;
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,6 @@ size_t tableIdPrefix(const char* name, char* prefix, int32_t len) {
|
||||||
return strlen(prefix);
|
return strlen(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema tGetBlockDistColumnSchema() {
|
|
||||||
SSchema s = {0};
|
|
||||||
s.bytes = TSDB_MAX_BINARY_LEN;;
|
|
||||||
s.type = TSDB_DATA_TYPE_BINARY;
|
|
||||||
s.colId = TSDB_BLOCK_DIST_COLUMN_INDEX;
|
|
||||||
tstrncpy(s.name, TSQL_BLOCK_DIST_L, TSDB_COL_NAME_LEN);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name) {
|
SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const char* name) {
|
||||||
SSchema s = {0};
|
SSchema s = {0};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8ce6d86558afc8c0b50c10f990fd2b4270cf06fc
|
Subproject commit 7a26c432f8b4203e42344ff3290b9b9b01b983d5
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import com.taosdata.jdbc.utils.TaosInfo;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.SQLWarning;
|
import java.sql.SQLWarning;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.utils.TaosInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI connector
|
* JNI connector
|
||||||
*/
|
*/
|
||||||
|
|
@ -276,23 +276,14 @@ public class TSDBJNIConnector {
|
||||||
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
||||||
|
|
||||||
public long prepareStmt(String sql) throws SQLException {
|
public long prepareStmt(String sql) throws SQLException {
|
||||||
Long stmt = 0L;
|
Long stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
||||||
try {
|
if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) {
|
||||||
stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
|
||||||
} catch (Exception e) {
|
} else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
e.printStackTrace();
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||||
}
|
} else if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
||||||
}
|
} else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,6 +301,16 @@ public class TSDBJNIConnector {
|
||||||
|
|
||||||
private native int setBindTableNameImp(long stmt, String name, long conn);
|
private native int setBindTableNameImp(long stmt, String name, long conn);
|
||||||
|
|
||||||
|
public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException {
|
||||||
|
int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(),
|
||||||
|
nullList.array(), this.taos);
|
||||||
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn);
|
||||||
|
|
||||||
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException {
|
public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException {
|
||||||
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
|
||||||
if (code != TSDBConstants.JNI_SUCCESS) {
|
if (code != TSDBConstants.JNI_SUCCESS) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
private boolean isPrepared;
|
private boolean isPrepared;
|
||||||
|
|
||||||
private ArrayList<ColumnInfo> colData;
|
private ArrayList<ColumnInfo> colData;
|
||||||
|
private ArrayList<TableTagInfo> tableTags;
|
||||||
|
private int tagValueLength;
|
||||||
|
|
||||||
private String tableName;
|
private String tableName;
|
||||||
private long nativeStmtHandle = 0;
|
private long nativeStmtHandle = 0;
|
||||||
|
|
||||||
|
|
@ -63,8 +66,8 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
if (parameterCnt > 1) {
|
if (parameterCnt > 1) {
|
||||||
// the table name is also a parameter, so ignore it.
|
// the table name is also a parameter, so ignore it.
|
||||||
this.colData = new ArrayList<ColumnInfo>(parameterCnt - 1);
|
this.colData = new ArrayList<ColumnInfo>();
|
||||||
this.colData.addAll(Collections.nCopies(parameterCnt - 1, null));
|
this.tableTags = new ArrayList<TableTagInfo>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,11 +565,109 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static class TableTagInfo {
|
||||||
|
private boolean isNull;
|
||||||
|
private Object value;
|
||||||
|
private int type;
|
||||||
|
public TableTagInfo(Object value, int type) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TableTagInfo createNullTag(int type) {
|
||||||
|
TableTagInfo info = new TableTagInfo(null, type);
|
||||||
|
info.isNull = true;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public void setTableName(String name) {
|
public void setTableName(String name) {
|
||||||
this.tableName = name;
|
this.tableName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensureTagCapacity(int index) {
|
||||||
|
if (this.tableTags.size() < index + 1) {
|
||||||
|
int delta = index + 1 - this.tableTags.size();
|
||||||
|
this.tableTags.addAll(Collections.nCopies(delta, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagNull(int index, int type) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, TableTagInfo.createNullTag(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagBoolean(int index, boolean value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL));
|
||||||
|
this.tagValueLength += Byte.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagInt(int index, int value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT));
|
||||||
|
this.tagValueLength += Integer.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagByte(int index, byte value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT));
|
||||||
|
this.tagValueLength += Byte.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagShort(int index, short value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT));
|
||||||
|
this.tagValueLength += Short.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagLong(int index, long value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT));
|
||||||
|
this.tagValueLength += Long.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagTimestamp(int index, long value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP));
|
||||||
|
this.tagValueLength += Long.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagFloat(int index, float value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT));
|
||||||
|
this.tagValueLength += Float.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagDouble(int index, double value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE));
|
||||||
|
this.tagValueLength += Double.BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagString(int index, String value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY));
|
||||||
|
this.tagValueLength += value.getBytes().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagNString(int index, String value) {
|
||||||
|
ensureTagCapacity(index);
|
||||||
|
this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR));
|
||||||
|
|
||||||
|
String charset = TaosGlobalConfig.getCharset();
|
||||||
|
try {
|
||||||
|
this.tagValueLength += value.getBytes(charset).length;
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
|
||||||
|
if (this.colData.size() == 0) {
|
||||||
|
this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null));
|
||||||
|
|
||||||
|
}
|
||||||
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
|
||||||
if (col == null) {
|
if (col == null) {
|
||||||
ColumnInfo p = new ColumnInfo();
|
ColumnInfo p = new ColumnInfo();
|
||||||
|
|
@ -641,7 +742,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
|
||||||
|
|
||||||
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector();
|
||||||
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
this.nativeStmtHandle = connector.prepareStmt(rawSql);
|
||||||
|
|
||||||
|
if (this.tableTags == null) {
|
||||||
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
connector.setBindTableName(this.nativeStmtHandle, this.tableName);
|
||||||
|
} else {
|
||||||
|
int num = this.tableTags.size();
|
||||||
|
ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength);
|
||||||
|
tagDataList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
ByteBuffer typeList = ByteBuffer.allocate(num);
|
||||||
|
typeList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES);
|
||||||
|
lengthList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES);
|
||||||
|
isNullList.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
for (int i = 0; i < num; ++i) {
|
||||||
|
TableTagInfo tag = this.tableTags.get(i);
|
||||||
|
if (tag.isNull) {
|
||||||
|
typeList.put((byte) tag.type);
|
||||||
|
isNullList.putInt(1);
|
||||||
|
lengthList.putLong(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tag.type) {
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_INT: {
|
||||||
|
Integer val = (Integer) tag.value;
|
||||||
|
tagDataList.putInt(val);
|
||||||
|
lengthList.putLong(Integer.BYTES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
Byte val = (Byte) tag.value;
|
||||||
|
tagDataList.put(val);
|
||||||
|
lengthList.putLong(Byte.BYTES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
|
||||||
|
Boolean val = (Boolean) tag.value;
|
||||||
|
tagDataList.put((byte) (val ? 1 : 0));
|
||||||
|
lengthList.putLong(Byte.BYTES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
Short val = (Short) tag.value;
|
||||||
|
tagDataList.putShort(val);
|
||||||
|
lengthList.putLong(Short.BYTES);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
Long val = (Long) tag.value;
|
||||||
|
tagDataList.putLong(val == null ? 0 : val);
|
||||||
|
lengthList.putLong(Long.BYTES);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
Float val = (Float) tag.value;
|
||||||
|
tagDataList.putFloat(val == null ? 0 : val);
|
||||||
|
lengthList.putLong(Float.BYTES);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
Double val = (Double) tag.value;
|
||||||
|
tagDataList.putDouble(val == null ? 0 : val);
|
||||||
|
lengthList.putLong(Double.BYTES);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
|
||||||
|
String charset = TaosGlobalConfig.getCharset();
|
||||||
|
String val = (String) tag.value;
|
||||||
|
|
||||||
|
byte[] b = null;
|
||||||
|
try {
|
||||||
|
if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
|
||||||
|
b = val.getBytes();
|
||||||
|
} else {
|
||||||
|
b = val.getBytes(charset);
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
tagDataList.put(b);
|
||||||
|
lengthList.putLong(b.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UINT:
|
||||||
|
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
|
||||||
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeList.put((byte) tag.type);
|
||||||
|
isNullList.putInt(tag.isNull? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList,
|
||||||
|
typeList, lengthList, isNullList);
|
||||||
|
}
|
||||||
|
|
||||||
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
ColumnInfo colInfo = (ColumnInfo) this.colData.get(0);
|
||||||
if (colInfo == null) {
|
if (colInfo == null) {
|
||||||
|
|
|
||||||
|
|
@ -243,15 +243,93 @@ public class TSDBPreparedStatementTest {
|
||||||
s.setNString(1, s2, 4);
|
s.setNString(1, s2, 4);
|
||||||
|
|
||||||
random = 10 + r.nextInt(5);
|
random = 10 + r.nextInt(5);
|
||||||
ArrayList<String> s5 = new ArrayList<String>();
|
ArrayList<String> s3 = new ArrayList<String>();
|
||||||
for(int i = 0; i < numOfRows; i++) {
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
if(i % random == 0) {
|
if(i % random == 0) {
|
||||||
s5.add(null);
|
s3.add(null);
|
||||||
}else{
|
}else{
|
||||||
s5.add("test" + i % 10);
|
s3.add("test" + i % 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.setString(2, s5, 10);
|
s.setString(2, s3, 10);
|
||||||
|
|
||||||
|
s.columnDataAddBatch();
|
||||||
|
s.columnDataExecuteBatch();
|
||||||
|
s.columnDataCloseBatch();
|
||||||
|
|
||||||
|
String sql = "select * from weather_test";
|
||||||
|
PreparedStatement statement = conn.prepareStatement(sql);
|
||||||
|
ResultSet rs = statement.executeQuery();
|
||||||
|
int rows = 0;
|
||||||
|
while(rs.next()) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
Assert.assertEquals(numOfRows, rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindDataWithSingleTagTest() throws SQLException {
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
String types[] = new String[] {"tinyint", "smallint", "int", "bigint", "bool", "float", "double", "binary(10)", "nchar(10)"};
|
||||||
|
|
||||||
|
for (String type : types) {
|
||||||
|
stmt.execute("drop table if exists weather_test");
|
||||||
|
stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t " + type + ")");
|
||||||
|
|
||||||
|
int numOfRows = 1;
|
||||||
|
|
||||||
|
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?) values(?, ?, ?)");
|
||||||
|
Random r = new Random();
|
||||||
|
s.setTableName("w1");
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case "tinyint":
|
||||||
|
case "smallint":
|
||||||
|
case "int":
|
||||||
|
case "bigint":
|
||||||
|
s.setTagInt(0, 1);
|
||||||
|
break;
|
||||||
|
case "float":
|
||||||
|
s.setTagFloat(0, 1.23f);
|
||||||
|
break;
|
||||||
|
case "double":
|
||||||
|
s.setTagDouble(0, 3.14159265);
|
||||||
|
break;
|
||||||
|
case "bool":
|
||||||
|
s.setTagBoolean(0, true);
|
||||||
|
break;
|
||||||
|
case "binary(10)":
|
||||||
|
s.setTagString(0, "test");
|
||||||
|
break;
|
||||||
|
case "nchar(10)":
|
||||||
|
s.setTagNString(0, "test");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<Long> ts = new ArrayList<Long>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
ts.add(System.currentTimeMillis() + i);
|
||||||
|
}
|
||||||
|
s.setTimestamp(0, ts);
|
||||||
|
|
||||||
|
int random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<String> s2 = new ArrayList<String>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
s2.add("分支" + i % 4);
|
||||||
|
}
|
||||||
|
s.setNString(1, s2, 10);
|
||||||
|
|
||||||
|
random = 10 + r.nextInt(5);
|
||||||
|
ArrayList<String> s3 = new ArrayList<String>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
s3.add("test" + i % 4);
|
||||||
|
}
|
||||||
|
s.setString(2, s3, 10);
|
||||||
|
|
||||||
s.columnDataAddBatch();
|
s.columnDataAddBatch();
|
||||||
s.columnDataExecuteBatch();
|
s.columnDataExecuteBatch();
|
||||||
|
|
@ -269,6 +347,47 @@ public class TSDBPreparedStatementTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindDataWithMultipleTagsTest() throws SQLException {
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
stmt.execute("drop table if exists weather_test");
|
||||||
|
stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t1 int, t2 binary(10))");
|
||||||
|
|
||||||
|
int numOfRows = 1;
|
||||||
|
|
||||||
|
TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?,?) (ts, f2) values(?, ?)");
|
||||||
|
s.setTableName("w2");
|
||||||
|
s.setTagInt(0, 1);
|
||||||
|
s.setTagString(1, "test");
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<Long> ts = new ArrayList<Long>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
ts.add(System.currentTimeMillis() + i);
|
||||||
|
}
|
||||||
|
s.setTimestamp(0, ts);
|
||||||
|
|
||||||
|
ArrayList<String> s2 = new ArrayList<String>();
|
||||||
|
for(int i = 0; i < numOfRows; i++) {
|
||||||
|
s2.add("test" + i % 4);
|
||||||
|
}
|
||||||
|
s.setString(1, s2, 10);
|
||||||
|
|
||||||
|
s.columnDataAddBatch();
|
||||||
|
s.columnDataExecuteBatch();
|
||||||
|
s.columnDataCloseBatch();
|
||||||
|
|
||||||
|
String sql = "select * from weather_test";
|
||||||
|
PreparedStatement statement = conn.prepareStatement(sql);
|
||||||
|
ResultSet rs = statement.executeQuery();
|
||||||
|
int rows = 0;
|
||||||
|
while(rs.next()) {
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
Assert.assertEquals(numOfRows, rows);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setBoolean() throws SQLException {
|
public void setBoolean() throws SQLException {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
from .connection import TDengineConnection
|
from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
|
# For some reason, the following is needed for VS Code (through PyLance) to
|
||||||
|
# recognize that "error" is a valid module of the "taos" package.
|
||||||
|
from .error import ProgrammingError
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,10 @@ static void cqProcessCreateTimer(void *param, void *tmrId) {
|
||||||
taosReleaseRef(cqObjRef, (int64_t)param);
|
taosReleaseRef(cqObjRef, (int64_t)param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inner implement in tscStream.c
|
||||||
|
TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* desName, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
|
int64_t stime, void *param, void (*callback)(void *));
|
||||||
|
|
||||||
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
||||||
pObj->pContext = pContext;
|
pObj->pContext = pContext;
|
||||||
|
|
||||||
|
|
@ -449,11 +453,10 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
||||||
pObj->tmrId = 0;
|
pObj->tmrId = 0;
|
||||||
|
|
||||||
if (pObj->pStream == NULL) {
|
if (pObj->pStream == NULL) {
|
||||||
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL);
|
pObj->pStream = taos_open_stream_withname(pContext->dbConn, pObj->dstTable, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL);
|
||||||
|
|
||||||
// TODO the pObj->pStream may be released if error happens
|
// TODO the pObj->pStream may be released if error happens
|
||||||
if (pObj->pStream) {
|
if (pObj->pStream) {
|
||||||
tscSetStreamDestTable(pObj->pStream, pObj->dstTable);
|
|
||||||
pContext->num++;
|
pContext->num++;
|
||||||
cDebug("vgId:%d, id:%d CQ:%s is opened", pContext->vgId, pObj->tid, pObj->sqlStr);
|
cDebug("vgId:%d, id:%d CQ:%s is opened", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,15 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ADD_EXECUTABLE(taosd ${SRC})
|
ADD_EXECUTABLE(taosd ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync)
|
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync ${LINK_JEMALLOC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosd taos_static)
|
TARGET_LINK_LIBRARIES(taosd taos_static)
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,28 @@ static SStep tsDnodeSteps[] = {
|
||||||
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
{"dnode-telemetry", dnodeInitTelemetry, dnodeCleanupTelemetry},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static SStep tsDnodeCompactSteps[] = {
|
||||||
|
{"dnode-tfile", tfInit, tfCleanup},
|
||||||
|
{"dnode-globalcfg", taosCheckGlobalCfg, NULL},
|
||||||
|
{"dnode-storage", dnodeInitStorage, dnodeCleanupStorage},
|
||||||
|
{"dnode-cfg", dnodeInitCfg, dnodeCleanupCfg},
|
||||||
|
{"dnode-eps", dnodeInitEps, dnodeCleanupEps},
|
||||||
|
{"dnode-minfos", dnodeInitMInfos, dnodeCleanupMInfos},
|
||||||
|
{"dnode-wal", walInit, walCleanUp},
|
||||||
|
{"dnode-sync", syncInit, syncCleanUp},
|
||||||
|
{"dnode-vread", dnodeInitVRead, dnodeCleanupVRead},
|
||||||
|
{"dnode-vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
|
||||||
|
{"dnode-vmgmt", dnodeInitVMgmt, dnodeCleanupVMgmt},
|
||||||
|
{"dnode-mread", dnodeInitMRead, NULL},
|
||||||
|
{"dnode-mwrite", dnodeInitMWrite, NULL},
|
||||||
|
{"dnode-mpeer", dnodeInitMPeer, NULL},
|
||||||
|
{"dnode-vnodes", dnodeInitVnodes, dnodeCleanupVnodes},
|
||||||
|
{"dnode-modules", dnodeInitModules, dnodeCleanupModules},
|
||||||
|
{"dnode-mread", NULL, dnodeCleanupMRead},
|
||||||
|
{"dnode-mwrite", NULL, dnodeCleanupMWrite},
|
||||||
|
{"dnode-mpeer", NULL, dnodeCleanupMPeer},
|
||||||
|
};
|
||||||
|
|
||||||
static int dnodeCreateDir(const char *dir) {
|
static int dnodeCreateDir(const char *dir) {
|
||||||
if (mkdir(dir, 0755) != 0 && errno != EEXIST) {
|
if (mkdir(dir, 0755) != 0 && errno != EEXIST) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -95,13 +117,23 @@ static int dnodeCreateDir(const char *dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dnodeCleanupComponents() {
|
static void dnodeCleanupComponents() {
|
||||||
|
if (!tsCompactMnodeWal) {
|
||||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||||
dnodeStepCleanup(tsDnodeSteps, stepSize);
|
dnodeStepCleanup(tsDnodeSteps, stepSize);
|
||||||
|
} else {
|
||||||
|
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||||
|
dnodeStepCleanup(tsDnodeCompactSteps, stepSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeInitComponents() {
|
static int32_t dnodeInitComponents() {
|
||||||
|
if (!tsCompactMnodeWal) {
|
||||||
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
int32_t stepSize = sizeof(tsDnodeSteps) / sizeof(SStep);
|
||||||
return dnodeStepInit(tsDnodeSteps, stepSize);
|
return dnodeStepInit(tsDnodeSteps, stepSize);
|
||||||
|
} else {
|
||||||
|
int32_t stepSize = sizeof(tsDnodeCompactSteps) / sizeof(SStep);
|
||||||
|
return dnodeStepInit(tsDnodeCompactSteps, stepSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeInitTmr() {
|
static int32_t dnodeInitTmr() {
|
||||||
|
|
@ -219,14 +251,20 @@ static int32_t dnodeInitStorage() {
|
||||||
|
|
||||||
if (tsCompactMnodeWal == 1) {
|
if (tsCompactMnodeWal == 1) {
|
||||||
sprintf(tsMnodeTmpDir, "%s/mnode_tmp", tsDataDir);
|
sprintf(tsMnodeTmpDir, "%s/mnode_tmp", tsDataDir);
|
||||||
tfsRmdir(tsMnodeTmpDir);
|
if (taosDirExist(tsMnodeTmpDir)) {
|
||||||
|
dError("mnode_tmp dir already exist in %s,quit compact job", tsMnodeTmpDir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (dnodeCreateDir(tsMnodeTmpDir) < 0) {
|
if (dnodeCreateDir(tsMnodeTmpDir) < 0) {
|
||||||
dError("failed to create dir: %s, reason: %s", tsMnodeTmpDir, strerror(errno));
|
dError("failed to create dir: %s, reason: %s", tsMnodeTmpDir, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tsMnodeBakDir, "%s/mnode_bak", tsDataDir);
|
sprintf(tsMnodeBakDir, "%s/mnode_bak", tsDataDir);
|
||||||
//tfsRmdir(tsMnodeBakDir);
|
if (taosDirExist(tsMnodeBakDir)) {
|
||||||
|
dError("mnode_bak dir already exist in %s,quit compact job", tsMnodeBakDir);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//TODO(dengyihao): no need to init here
|
//TODO(dengyihao): no need to init here
|
||||||
if (dnodeCreateDir(tsMnodeDir) < 0) {
|
if (dnodeCreateDir(tsMnodeDir) < 0) {
|
||||||
|
|
|
||||||
|
|
@ -193,10 +193,7 @@ static int32_t dnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) {
|
||||||
static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
|
static int32_t dnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
|
||||||
SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont;
|
SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont;
|
||||||
pCompactVnode->vgId = htonl(pCompactVnode->vgId);
|
pCompactVnode->vgId = htonl(pCompactVnode->vgId);
|
||||||
//do nothing
|
return vnodeCompact(pCompactVnode->vgId);
|
||||||
dDebug("trigger compact at vgid: %d", pCompactVnode->vgId);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
|
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ typedef struct TAOS_MULTI_BIND {
|
||||||
|
|
||||||
TAOS_STMT *taos_stmt_init(TAOS *taos);
|
TAOS_STMT *taos_stmt_init(TAOS *taos);
|
||||||
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
||||||
|
int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags);
|
||||||
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name);
|
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name);
|
||||||
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||||
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TSWINDOW_INITIALIZER ((STimeWindow) {INT64_MIN, INT64_MAX})
|
#define TSWINDOW_INITIALIZER ((STimeWindow) {INT64_MIN, INT64_MAX})
|
||||||
|
#define TSWINDOW_DESC_INITIALIZER ((STimeWindow) {INT64_MAX, INT64_MIN})
|
||||||
|
|
||||||
#define TSKEY_INITIAL_VAL INT64_MIN
|
#define TSKEY_INITIAL_VAL INT64_MIN
|
||||||
|
|
||||||
// Bytes for each type.
|
// Bytes for each type.
|
||||||
|
|
@ -242,7 +244,6 @@ do { \
|
||||||
#define TSDB_MAX_REPLICA 5
|
#define TSDB_MAX_REPLICA 5
|
||||||
|
|
||||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||||
#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2)
|
|
||||||
#define TSDB_UD_COLUMN_INDEX (-1000)
|
#define TSDB_UD_COLUMN_INDEX (-1000)
|
||||||
#define TSDB_RES_COL_ID (-5000)
|
#define TSDB_RES_COL_ID (-5000)
|
||||||
|
|
||||||
|
|
@ -298,7 +299,7 @@ do { \
|
||||||
#define TSDB_DEFAULT_DB_UPDATE_OPTION 0
|
#define TSDB_DEFAULT_DB_UPDATE_OPTION 0
|
||||||
|
|
||||||
#define TSDB_MIN_DB_CACHE_LAST_ROW 0
|
#define TSDB_MIN_DB_CACHE_LAST_ROW 0
|
||||||
#define TSDB_MAX_DB_CACHE_LAST_ROW 1
|
#define TSDB_MAX_DB_CACHE_LAST_ROW 3
|
||||||
#define TSDB_DEFAULT_CACHE_LAST_ROW 0
|
#define TSDB_DEFAULT_CACHE_LAST_ROW 0
|
||||||
|
|
||||||
#define TSDB_MIN_FSYNC_PERIOD 0
|
#define TSDB_MIN_FSYNC_PERIOD 0
|
||||||
|
|
@ -345,6 +346,7 @@ do { \
|
||||||
#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u
|
#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u
|
||||||
#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type
|
#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type
|
||||||
#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u
|
#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u
|
||||||
|
#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file
|
||||||
#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type
|
#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type
|
||||||
|
|
||||||
#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0)
|
#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0)
|
||||||
|
|
@ -373,6 +375,8 @@ do { \
|
||||||
|
|
||||||
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
|
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
|
||||||
|
|
||||||
|
#define TSDB_ARB_DUMMY_TIME 4765104000000 // 2121-01-01 00:00:00.000, :P
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_QTYPE_RPC = 0,
|
TAOS_QTYPE_RPC = 0,
|
||||||
TAOS_QTYPE_FWD = 1,
|
TAOS_QTYPE_FWD = 1,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010A) //"Ref is not there")
|
#define TSDB_CODE_REF_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x010A) //"Ref is not there")
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#define TSDB_CODE_TSC_INVALID_SQL TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid SQL statement")
|
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200) //"Invalid Operation")
|
||||||
#define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle")
|
#define TSDB_CODE_TSC_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0201) //"Invalid qhandle")
|
||||||
#define TSDB_CODE_TSC_INVALID_TIME_STAMP TAOS_DEF_ERROR_CODE(0, 0x0202) //"Invalid combination of client/service time")
|
#define TSDB_CODE_TSC_INVALID_TIME_STAMP TAOS_DEF_ERROR_CODE(0, 0x0202) //"Invalid combination of client/service time")
|
||||||
#define TSDB_CODE_TSC_INVALID_VALUE TAOS_DEF_ERROR_CODE(0, 0x0203) //"Invalid value in client")
|
#define TSDB_CODE_TSC_INVALID_VALUE TAOS_DEF_ERROR_CODE(0, 0x0203) //"Invalid value in client")
|
||||||
|
|
@ -215,11 +215,11 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit")
|
#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit")
|
||||||
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
|
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
|
||||||
#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing")
|
#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing")
|
||||||
|
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing")
|
||||||
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
|
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
|
||||||
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
|
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
|
||||||
#define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing")
|
#define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing")
|
||||||
#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state")
|
#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state")
|
||||||
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0515) //"Database is closing")
|
|
||||||
|
|
||||||
// tsdb
|
// tsdb
|
||||||
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID")
|
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID")
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TABLE, "alter-table" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLE_META, "table-meta" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLE_META, "table-meta" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_STABLE_VGROUP, "stable-vgroup" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_STABLE_VGROUP, "stable-vgroup" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_COMPACT_VNODE, "compact-vnode" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_COMPACT_VNODE, "compact-vnode" )
|
||||||
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "multiTable-meta" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_TABLES_META, "tables-meta" )
|
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_STREAM, "alter-stream" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_STREAM, "alter-stream" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SHOW, "show" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SHOW, "show" )
|
||||||
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE, "retrieve" )
|
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_RETRIEVE, "retrieve" )
|
||||||
|
|
@ -165,6 +164,7 @@ enum _mgmt_table {
|
||||||
#define TSDB_ALTER_TABLE_ADD_COLUMN 5
|
#define TSDB_ALTER_TABLE_ADD_COLUMN 5
|
||||||
#define TSDB_ALTER_TABLE_DROP_COLUMN 6
|
#define TSDB_ALTER_TABLE_DROP_COLUMN 6
|
||||||
#define TSDB_ALTER_TABLE_CHANGE_COLUMN 7
|
#define TSDB_ALTER_TABLE_CHANGE_COLUMN 7
|
||||||
|
#define TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN 8
|
||||||
|
|
||||||
#define TSDB_FILL_NONE 0
|
#define TSDB_FILL_NONE 0
|
||||||
#define TSDB_FILL_NULL 1
|
#define TSDB_FILL_NULL 1
|
||||||
|
|
@ -298,6 +298,8 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[TSDB_TABLE_FNAME_LEN];
|
char name[TSDB_TABLE_FNAME_LEN];
|
||||||
|
// if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table
|
||||||
|
int8_t supertable;
|
||||||
int8_t igNotExists;
|
int8_t igNotExists;
|
||||||
} SCMDropTableMsg;
|
} SCMDropTableMsg;
|
||||||
|
|
||||||
|
|
@ -475,6 +477,7 @@ typedef struct {
|
||||||
bool simpleAgg;
|
bool simpleAgg;
|
||||||
bool pointInterpQuery; // point interpolation query
|
bool pointInterpQuery; // point interpolation query
|
||||||
bool needReverseScan; // need reverse scan
|
bool needReverseScan; // need reverse scan
|
||||||
|
bool stateWindow; // state window flag
|
||||||
|
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
|
|
@ -707,8 +710,9 @@ typedef struct {
|
||||||
} STableInfoMsg;
|
} STableInfoMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int32_t numOfVgroups;
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
char tableIds[];
|
char tableNames[];
|
||||||
} SMultiTableInfoMsg;
|
} SMultiTableInfoMsg;
|
||||||
|
|
||||||
typedef struct SSTableVgroupMsg {
|
typedef struct SSTableVgroupMsg {
|
||||||
|
|
@ -757,8 +761,9 @@ typedef struct STableMetaMsg {
|
||||||
|
|
||||||
typedef struct SMultiTableMeta {
|
typedef struct SMultiTableMeta {
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
|
int32_t numOfVgroup;
|
||||||
int32_t contLen;
|
int32_t contLen;
|
||||||
char metas[];
|
char meta[];
|
||||||
} SMultiTableMeta;
|
} SMultiTableMeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ typedef struct {
|
||||||
#define TFS_UNDECIDED_ID -1
|
#define TFS_UNDECIDED_ID -1
|
||||||
#define TFS_PRIMARY_LEVEL 0
|
#define TFS_PRIMARY_LEVEL 0
|
||||||
#define TFS_PRIMARY_ID 0
|
#define TFS_PRIMARY_ID 0
|
||||||
|
#define TFS_MIN_LEVEL 0
|
||||||
|
#define TFS_MAX_LEVEL (TSDB_MAX_TIERS - 1)
|
||||||
|
|
||||||
// FS APIs ====================================
|
// FS APIs ====================================
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,13 @@ typedef struct {
|
||||||
int8_t precision;
|
int8_t precision;
|
||||||
int8_t compression;
|
int8_t compression;
|
||||||
int8_t update;
|
int8_t update;
|
||||||
int8_t cacheLastRow;
|
int8_t cacheLastRow; // 0:no cache, 1: cache last row, 2: cache last NULL column 3: 1&2
|
||||||
} STsdbCfg;
|
} STsdbCfg;
|
||||||
|
|
||||||
|
#define CACHE_NO_LAST(c) ((c)->cacheLastRow == 0)
|
||||||
|
#define CACHE_LAST_ROW(c) (((c)->cacheLastRow & 1) > 0)
|
||||||
|
#define CACHE_LAST_NULL_COLUMN(c) (((c)->cacheLastRow & 2) > 0)
|
||||||
|
|
||||||
// --------- TSDB REPOSITORY USAGE STATISTICS
|
// --------- TSDB REPOSITORY USAGE STATISTICS
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t totalStorage; // total bytes occupie
|
int64_t totalStorage; // total bytes occupie
|
||||||
|
|
@ -211,7 +215,7 @@ typedef struct SDataBlockInfo {
|
||||||
} SDataBlockInfo;
|
} SDataBlockInfo;
|
||||||
|
|
||||||
typedef struct SFileBlockInfo {
|
typedef struct SFileBlockInfo {
|
||||||
int32_t numOfRows;
|
int32_t numBlocksOfStep;
|
||||||
} SFileBlockInfo;
|
} SFileBlockInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -225,11 +229,15 @@ typedef struct {
|
||||||
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
||||||
} STableGroupInfo;
|
} STableGroupInfo;
|
||||||
|
|
||||||
|
#define TSDB_BLOCK_DIST_STEP_ROWS 16
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t rowSize;
|
uint16_t rowSize;
|
||||||
uint16_t numOfFiles;
|
uint16_t numOfFiles;
|
||||||
uint32_t numOfTables;
|
uint32_t numOfTables;
|
||||||
uint64_t totalSize;
|
uint64_t totalSize;
|
||||||
|
uint64_t totalRows;
|
||||||
|
int32_t maxRows;
|
||||||
|
int32_t minRows;
|
||||||
int32_t firstSeekTimeUs;
|
int32_t firstSeekTimeUs;
|
||||||
uint32_t numOfRowsInMemTable;
|
uint32_t numOfRowsInMemTable;
|
||||||
SArray *dataBlockInfos;
|
SArray *dataBlockInfos;
|
||||||
|
|
@ -261,6 +269,12 @@ TsdbQueryHandleT *tsdbQueryTables(STsdbRepo *tsdb, STsdbQueryCond *pCond, STable
|
||||||
TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, uint64_t qId,
|
TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, uint64_t qId,
|
||||||
SMemRef *pRef);
|
SMemRef *pRef);
|
||||||
|
|
||||||
|
|
||||||
|
TsdbQueryHandleT tsdbQueryCacheLast(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, SMemRef* pMemRef);
|
||||||
|
|
||||||
|
bool isTsdbCacheLastRow(TsdbQueryHandleT* pQueryHandle);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the queried table object list
|
* get the queried table object list
|
||||||
* @param pHandle
|
* @param pHandle
|
||||||
|
|
@ -395,6 +409,9 @@ void tsdbDecCommitRef(int vgId);
|
||||||
int tsdbSyncSend(void *pRepo, SOCKET socketFd);
|
int tsdbSyncSend(void *pRepo, SOCKET socketFd);
|
||||||
int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
|
int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
|
||||||
|
|
||||||
|
// For TSDB Compact
|
||||||
|
int tsdbCompact(STsdbRepo *pRepo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#ifndef TDENGINE_TTOKENDEF_H
|
#ifndef TDENGINE_TTOKENDEF_H
|
||||||
#define TDENGINE_TTOKENDEF_H
|
#define TDENGINE_TTOKENDEF_H
|
||||||
|
|
||||||
|
|
||||||
#define TK_ID 1
|
#define TK_ID 1
|
||||||
#define TK_BOOL 2
|
#define TK_BOOL 2
|
||||||
#define TK_TINYINT 3
|
#define TK_TINYINT 3
|
||||||
|
|
@ -137,73 +136,76 @@
|
||||||
#define TK_VARIABLE 118
|
#define TK_VARIABLE 118
|
||||||
#define TK_INTERVAL 119
|
#define TK_INTERVAL 119
|
||||||
#define TK_SESSION 120
|
#define TK_SESSION 120
|
||||||
#define TK_FILL 121
|
#define TK_STATE_WINDOW 121
|
||||||
#define TK_SLIDING 122
|
#define TK_FILL 122
|
||||||
#define TK_ORDER 123
|
#define TK_SLIDING 123
|
||||||
#define TK_BY 124
|
#define TK_ORDER 124
|
||||||
#define TK_ASC 125
|
#define TK_BY 125
|
||||||
#define TK_DESC 126
|
#define TK_ASC 126
|
||||||
#define TK_GROUP 127
|
#define TK_DESC 127
|
||||||
#define TK_HAVING 128
|
#define TK_GROUP 128
|
||||||
#define TK_LIMIT 129
|
#define TK_HAVING 129
|
||||||
#define TK_OFFSET 130
|
#define TK_LIMIT 130
|
||||||
#define TK_SLIMIT 131
|
#define TK_OFFSET 131
|
||||||
#define TK_SOFFSET 132
|
#define TK_SLIMIT 132
|
||||||
#define TK_WHERE 133
|
#define TK_SOFFSET 133
|
||||||
#define TK_NOW 134
|
#define TK_WHERE 134
|
||||||
#define TK_RESET 135
|
#define TK_NOW 135
|
||||||
#define TK_QUERY 136
|
#define TK_RESET 136
|
||||||
#define TK_SYNCDB 137
|
#define TK_QUERY 137
|
||||||
#define TK_ADD 138
|
#define TK_SYNCDB 138
|
||||||
#define TK_COLUMN 139
|
#define TK_ADD 139
|
||||||
#define TK_TAG 140
|
#define TK_COLUMN 140
|
||||||
#define TK_CHANGE 141
|
#define TK_MODIFY 141
|
||||||
#define TK_SET 142
|
#define TK_TAG 142
|
||||||
#define TK_KILL 143
|
#define TK_CHANGE 143
|
||||||
#define TK_CONNECTION 144
|
#define TK_SET 144
|
||||||
#define TK_STREAM 145
|
#define TK_KILL 145
|
||||||
#define TK_COLON 146
|
#define TK_CONNECTION 146
|
||||||
#define TK_ABORT 147
|
#define TK_STREAM 147
|
||||||
#define TK_AFTER 148
|
#define TK_COLON 148
|
||||||
#define TK_ATTACH 149
|
#define TK_ABORT 149
|
||||||
#define TK_BEFORE 150
|
#define TK_AFTER 150
|
||||||
#define TK_BEGIN 151
|
#define TK_ATTACH 151
|
||||||
#define TK_CASCADE 152
|
#define TK_BEFORE 152
|
||||||
#define TK_CLUSTER 153
|
#define TK_BEGIN 153
|
||||||
#define TK_CONFLICT 154
|
#define TK_CASCADE 154
|
||||||
#define TK_COPY 155
|
#define TK_CLUSTER 155
|
||||||
#define TK_DEFERRED 156
|
#define TK_CONFLICT 156
|
||||||
#define TK_DELIMITERS 157
|
#define TK_COPY 157
|
||||||
#define TK_DETACH 158
|
#define TK_DEFERRED 158
|
||||||
#define TK_EACH 159
|
#define TK_DELIMITERS 159
|
||||||
#define TK_END 160
|
#define TK_DETACH 160
|
||||||
#define TK_EXPLAIN 161
|
#define TK_EACH 161
|
||||||
#define TK_FAIL 162
|
#define TK_END 162
|
||||||
#define TK_FOR 163
|
#define TK_EXPLAIN 163
|
||||||
#define TK_IGNORE 164
|
#define TK_FAIL 164
|
||||||
#define TK_IMMEDIATE 165
|
#define TK_FOR 165
|
||||||
#define TK_INITIALLY 166
|
#define TK_IGNORE 166
|
||||||
#define TK_INSTEAD 167
|
#define TK_IMMEDIATE 167
|
||||||
#define TK_MATCH 168
|
#define TK_INITIALLY 168
|
||||||
#define TK_KEY 169
|
#define TK_INSTEAD 169
|
||||||
#define TK_OF 170
|
#define TK_MATCH 170
|
||||||
#define TK_RAISE 171
|
#define TK_KEY 171
|
||||||
#define TK_REPLACE 172
|
#define TK_OF 172
|
||||||
#define TK_RESTRICT 173
|
#define TK_RAISE 173
|
||||||
#define TK_ROW 174
|
#define TK_REPLACE 174
|
||||||
#define TK_STATEMENT 175
|
#define TK_RESTRICT 175
|
||||||
#define TK_TRIGGER 176
|
#define TK_ROW 176
|
||||||
#define TK_VIEW 177
|
#define TK_STATEMENT 177
|
||||||
#define TK_SEMI 178
|
#define TK_TRIGGER 178
|
||||||
#define TK_NONE 179
|
#define TK_VIEW 179
|
||||||
#define TK_PREV 180
|
#define TK_SEMI 180
|
||||||
#define TK_LINEAR 181
|
#define TK_NONE 181
|
||||||
#define TK_IMPORT 182
|
#define TK_PREV 182
|
||||||
#define TK_TBNAME 183
|
#define TK_LINEAR 183
|
||||||
#define TK_JOIN 184
|
#define TK_IMPORT 184
|
||||||
#define TK_INSERT 185
|
#define TK_TBNAME 185
|
||||||
#define TK_INTO 186
|
#define TK_JOIN 186
|
||||||
#define TK_VALUES 187
|
#define TK_INSERT 187
|
||||||
|
#define TK_INTO 188
|
||||||
|
#define TK_VALUES 189
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TK_SPACE 300
|
#define TK_SPACE 300
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ int32_t vnodeOpen(int32_t vgId);
|
||||||
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
|
||||||
int32_t vnodeSync(int32_t vgId);
|
int32_t vnodeSync(int32_t vgId);
|
||||||
int32_t vnodeClose(int32_t vgId);
|
int32_t vnodeClose(int32_t vgId);
|
||||||
|
int32_t vnodeCompact(int32_t vgId);
|
||||||
|
|
||||||
// vnodeMgmt
|
// vnodeMgmt
|
||||||
int32_t vnodeInitMgmt();
|
int32_t vnodeInitMgmt();
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,17 @@ IF (TD_LINUX)
|
||||||
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
||||||
ADD_EXECUTABLE(shell ${SRC})
|
ADD_EXECUTABLE(shell ${SRC})
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(shell taos_static)
|
TARGET_LINK_LIBRARIES(shell taos_static ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(shell taos)
|
TARGET_LINK_LIBRARIES(shell taos ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
||||||
|
|
|
||||||
|
|
@ -55,14 +55,21 @@ ENDIF ()
|
||||||
MESSAGE("TD_VERSION_NUMBER is:" ${TD_VERSION_NUMBER})
|
MESSAGE("TD_VERSION_NUMBER is:" ${TD_VERSION_NUMBER})
|
||||||
ADD_DEFINITIONS(-DTD_VERNUMBER="${TD_VERSION_NUMBER}")
|
ADD_DEFINITIONS(-DTD_VERNUMBER="${TD_VERSION_NUMBER}")
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX)
|
IF (TD_LINUX)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_WINDOWS)
|
ELSEIF (TD_WINDOWS)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
|
@ -71,7 +78,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson})
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
# missing a few dependencies, such as <argp.h>
|
# missing a few dependencies, such as <argp.h>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1063,6 +1063,13 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
|
||||||
newCfg.partitions = partitions;
|
newCfg.partitions = partitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// community version can only change daysToKeep
|
||||||
|
// but enterprise version can change all daysToKeep options
|
||||||
|
#ifndef _STORAGE
|
||||||
|
newCfg.daysToKeep1 = newCfg.daysToKeep;
|
||||||
|
newCfg.daysToKeep2 = newCfg.daysToKeep;
|
||||||
|
#endif
|
||||||
|
|
||||||
return newCfg;
|
return newCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -799,7 +799,7 @@ static int32_t mnodeGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pShow->bytes[cols] = 40 + VARSTR_HEADER_SIZE;
|
pShow->bytes[cols] = TSDB_EP_LEN + VARSTR_HEADER_SIZE;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
strcpy(pSchema[cols].name, "end_point");
|
strcpy(pSchema[cols].name, "end_point");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
|
@ -941,7 +941,7 @@ static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int64_t *)pWrite = 0;
|
*(int64_t *)pWrite = tsArbOnlineTimestamp;
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ int32_t mnodeStartSystem() {
|
||||||
|
|
||||||
int32_t mnodeInitSystem() {
|
int32_t mnodeInitSystem() {
|
||||||
mnodeInitTimer();
|
mnodeInitTimer();
|
||||||
if (mnodeNeedStart()) {
|
if (mnodeNeedStart() || tsCompactMnodeWal) {
|
||||||
return mnodeStartSystem();
|
return mnodeStartSystem();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ static int32_t mnodeGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pShow->bytes[cols] = 40 + VARSTR_HEADER_SIZE;
|
pShow->bytes[cols] = TSDB_EP_LEN + VARSTR_HEADER_SIZE;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||||
strcpy(pSchema[cols].name, "end_point");
|
strcpy(pSchema[cols].name, "end_point");
|
||||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||||
|
|
|
||||||
|
|
@ -656,8 +656,6 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
||||||
dnodeReportStep("mnode-sdb", stepDesc, 0);
|
dnodeReportStep("mnode-sdb", stepDesc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qtype == TAOS_QTYPE_QUERY) return sdbPerformDeleteAction(pHead, pTable);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&tsSdbMgmt.mutex);
|
pthread_mutex_lock(&tsSdbMgmt.mutex);
|
||||||
|
|
||||||
if (pHead->version == 0) {
|
if (pHead->version == 0) {
|
||||||
|
|
@ -690,7 +688,7 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
||||||
pthread_mutex_unlock(&tsSdbMgmt.mutex);
|
pthread_mutex_unlock(&tsSdbMgmt.mutex);
|
||||||
|
|
||||||
// from app, row is created
|
// from app, row is created
|
||||||
if (pRow != NULL) {
|
if (pRow != NULL && tsCompactMnodeWal != 1) {
|
||||||
// forward to peers
|
// forward to peers
|
||||||
pRow->processedCount = 0;
|
pRow->processedCount = 0;
|
||||||
int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||||
|
|
@ -713,19 +711,19 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
||||||
actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version);
|
actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version);
|
||||||
|
|
||||||
// even it is WAL/FWD, it shall be called to update version in sync
|
// even it is WAL/FWD, it shall be called to update version in sync
|
||||||
|
if (tsCompactMnodeWal != 1) {
|
||||||
syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC, false);
|
||||||
|
}
|
||||||
|
|
||||||
// from wal or forward msg, row not created, should add into hash
|
// from wal or forward msg, row not created, should add into hash
|
||||||
if (action == SDB_ACTION_INSERT) {
|
if (action == SDB_ACTION_INSERT) {
|
||||||
return sdbPerformInsertAction(pHead, pTable);
|
return sdbPerformInsertAction(pHead, pTable);
|
||||||
} else if (action == SDB_ACTION_DELETE) {
|
} else if (action == SDB_ACTION_DELETE) {
|
||||||
//if (qtype == TAOS_QTYPE_FWD) {
|
if (qtype == TAOS_QTYPE_FWD) {
|
||||||
// Drop database/stable may take a long time and cause a timeout, so we confirm first then reput it into queue
|
// Drop database/stable may take a long time and cause a timeout, so we confirm first
|
||||||
// sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused);
|
syncConfirmForward(tsSdbMgmt.sync, pHead->version, TSDB_CODE_SUCCESS, false);
|
||||||
// return TSDB_CODE_SUCCESS;
|
}
|
||||||
//} else {
|
|
||||||
return sdbPerformDeleteAction(pHead, pTable);
|
return sdbPerformDeleteAction(pHead, pTable);
|
||||||
//}
|
|
||||||
} else if (action == SDB_ACTION_UPDATE) {
|
} else if (action == SDB_ACTION_UPDATE) {
|
||||||
return sdbPerformUpdateAction(pHead, pTable);
|
return sdbPerformUpdateAction(pHead, pTable);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1138,8 +1136,11 @@ static void *sdbWorkerFp(void *pWorker) {
|
||||||
sdbConfirmForward(1, pRow, pRow->code);
|
sdbConfirmForward(1, pRow, pRow->code);
|
||||||
} else {
|
} else {
|
||||||
if (qtype == TAOS_QTYPE_FWD) {
|
if (qtype == TAOS_QTYPE_FWD) {
|
||||||
|
int32_t action = pRow->pHead.msgType % 10;
|
||||||
|
if (action != SDB_ACTION_DELETE) {
|
||||||
syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false);
|
syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sdbFreeFromQueue(pRow);
|
sdbFreeFromQueue(pRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1175,9 +1176,10 @@ int32_t mnodeCompactWal() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close wal
|
// close sdb and sync to disk
|
||||||
walFsync(tsSdbMgmt.wal, true);
|
//walFsync(tsSdbMgmt.wal, true);
|
||||||
walClose(tsSdbMgmt.wal);
|
//walClose(tsSdbMgmt.wal);
|
||||||
|
sdbCleanUp();
|
||||||
|
|
||||||
// rename old wal to wal_bak
|
// rename old wal to wal_bak
|
||||||
if (taosRename(tsMnodeDir, tsMnodeBakDir) != 0) {
|
if (taosRename(tsMnodeDir, tsMnodeBakDir) != 0) {
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg);
|
||||||
static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg);
|
static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg);
|
||||||
|
|
||||||
static int32_t mnodeFindSuperTableColumnIndex(SSTableObj *pStable, char *colName);
|
static int32_t mnodeFindSuperTableColumnIndex(SSTableObj *pStable, char *colName);
|
||||||
|
static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg);
|
||||||
|
static int32_t mnodeChangeSuperTableTag(SMnodeMsg *pMsg);
|
||||||
|
static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg);
|
||||||
|
|
||||||
static void mnodeDestroyChildTable(SCTableObj *pTable) {
|
static void mnodeDestroyChildTable(SCTableObj *pTable) {
|
||||||
tfree(pTable->info.tableId);
|
tfree(pTable->info.tableId);
|
||||||
|
|
@ -966,6 +969,11 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
|
||||||
pMsg->rpcMsg.ahandle, pDrop->name, pSTable->uid, pSTable->numOfTables, taosHashGetSize(pSTable->vgHash));
|
pMsg->rpcMsg.ahandle, pDrop->name, pSTable->uid, pSTable->numOfTables, taosHashGetSize(pSTable->vgHash));
|
||||||
return mnodeProcessDropSuperTableMsg(pMsg);
|
return mnodeProcessDropSuperTableMsg(pMsg);
|
||||||
} else {
|
} else {
|
||||||
|
// user specify the "DROP STABLE" sql statement, but it is actually a normal table, return error msg.
|
||||||
|
if (pDrop->supertable) {
|
||||||
|
return TSDB_CODE_MND_INVALID_TABLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
SCTableObj *pCTable = (SCTableObj *)pMsg->pTable;
|
SCTableObj *pCTable = (SCTableObj *)pMsg->pTable;
|
||||||
mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle,
|
mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle,
|
||||||
pDrop->name, pCTable->vgId, pCTable->tid, pCTable->uid);
|
pDrop->name, pCTable->vgId, pCTable->tid, pCTable->uid);
|
||||||
|
|
@ -1452,31 +1460,52 @@ static int32_t mnodeChangeSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg, char *oldName, char *newName) {
|
static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg) {
|
||||||
|
SAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
|
||||||
|
char* name = pAlter->schema[0].name;
|
||||||
SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
|
SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
|
||||||
int32_t col = mnodeFindSuperTableColumnIndex(pStable, oldName);
|
int32_t col = mnodeFindSuperTableColumnIndex(pStable, name);
|
||||||
if (col < 0) {
|
if (col < 0) {
|
||||||
mError("msg:%p, app:%p stable:%s, change column, oldName:%s, newName:%s", pMsg, pMsg->rpcMsg.ahandle,
|
mError("msg:%p, app:%p stable:%s, change column, name:%s", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
pStable->info.tableId, oldName, newName);
|
pStable->info.tableId, name);
|
||||||
return TSDB_CODE_MND_FIELD_NOT_EXIST;
|
return TSDB_CODE_MND_FIELD_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int32_t rowSize = 0;
|
|
||||||
uint32_t len = (uint32_t)strlen(newName);
|
|
||||||
if (len >= TSDB_COL_NAME_LEN) {
|
|
||||||
return TSDB_CODE_MND_COL_NAME_TOO_LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mnodeFindSuperTableColumnIndex(pStable, newName) >= 0) {
|
|
||||||
return TSDB_CODE_MND_FIELD_ALREAY_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update
|
// update
|
||||||
SSchema *schema = (SSchema *) (pStable->schema + col);
|
SSchema *schema = (SSchema *) (pStable->schema + col);
|
||||||
tstrncpy(schema->name, newName, sizeof(schema->name));
|
ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR);
|
||||||
|
schema->bytes = pAlter->schema[0].bytes;
|
||||||
|
mInfo("msg:%p, app:%p stable %s, start to modify column %s len to %d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId,
|
||||||
|
name, schema->bytes);
|
||||||
|
|
||||||
mInfo("msg:%p, app:%p stable %s, start to modify column %s to %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId,
|
SSdbRow row = {
|
||||||
oldName, newName);
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
.pTable = tsSuperTableSdb,
|
||||||
|
.pObj = pStable,
|
||||||
|
.pMsg = pMsg,
|
||||||
|
.fpRsp = mnodeChangeSuperTableColumnCb
|
||||||
|
};
|
||||||
|
|
||||||
|
return sdbUpdateRow(&row);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeChangeSuperTableTag(SMnodeMsg *pMsg) {
|
||||||
|
SAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
|
||||||
|
char* name = pAlter->schema[0].name;
|
||||||
|
SSTableObj *pStable = (SSTableObj *)pMsg->pTable;
|
||||||
|
int32_t col = mnodeFindSuperTableTagIndex(pStable, name);
|
||||||
|
if (col < 0) {
|
||||||
|
mError("msg:%p, app:%p stable:%s, change column, name:%s", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
|
pStable->info.tableId, name);
|
||||||
|
return TSDB_CODE_MND_FIELD_NOT_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
SSchema *schema = (SSchema *) (pStable->schema + col);
|
||||||
|
ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR);
|
||||||
|
schema->bytes = pAlter->schema[0].bytes;
|
||||||
|
mInfo("msg:%p, app:%p stable %s, start to modify tag len %s to %d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId,
|
||||||
|
name, schema->bytes);
|
||||||
|
|
||||||
SSdbRow row = {
|
SSdbRow row = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
|
@ -1674,12 +1703,9 @@ static int32_t mnodeSetSchemaFromSuperTable(SSchema *pSchema, SSTableObj *pTable
|
||||||
return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
|
return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
static int32_t mnodeDoGetSuperTableMeta(SMnodeMsg *pMsg, STableMetaMsg* pMeta) {
|
||||||
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||||
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
|
||||||
if (pMeta == NULL) {
|
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
pMeta->uid = htobe64(pTable->uid);
|
pMeta->uid = htobe64(pTable->uid);
|
||||||
pMeta->sversion = htons(pTable->sversion);
|
pMeta->sversion = htons(pTable->sversion);
|
||||||
pMeta->tversion = htons(pTable->tversion);
|
pMeta->tversion = htons(pTable->tversion);
|
||||||
|
|
@ -1690,6 +1716,18 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||||
pMeta->contLen = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable);
|
pMeta->contLen = sizeof(STableMetaMsg) + mnodeSetSchemaFromSuperTable(pMeta->schema, pTable);
|
||||||
tstrncpy(pMeta->tableFname, pTable->info.tableId, sizeof(pMeta->tableFname));
|
tstrncpy(pMeta->tableFname, pTable->info.tableId, sizeof(pMeta->tableFname));
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||||
|
SSTableObj *pTable = (SSTableObj *)pMsg->pTable;
|
||||||
|
STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16));
|
||||||
|
if (pMeta == NULL) {
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||||
|
|
||||||
pMsg->rpcRsp.len = pMeta->contLen;
|
pMsg->rpcRsp.len = pMeta->contLen;
|
||||||
pMeta->contLen = htons(pMeta->contLen);
|
pMeta->contLen = htons(pMeta->contLen);
|
||||||
|
|
||||||
|
|
@ -1700,11 +1738,7 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
static int32_t calculateVgroupMsgLength(SSTableVgroupMsg* pInfo, int32_t numOfTable) {
|
||||||
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
|
||||||
int32_t numOfTable = htonl(pInfo->numOfTables);
|
|
||||||
|
|
||||||
// reserve space
|
|
||||||
int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg);
|
int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg);
|
||||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||||
|
|
@ -1716,37 +1750,29 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
|
return contLen;
|
||||||
if (pRsp == NULL) {
|
}
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
pRsp->numOfTables = 0;
|
static char* serializeVgroupInfo(SSTableObj *pTable, char* name, char* msg, SMnodeMsg* pMsgBody, void* handle) {
|
||||||
char *msg = (char *)pRsp + sizeof(SSTableVgroupRspMsg);
|
SName sn = {0};
|
||||||
|
tNameFromString(&sn, name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||||
|
const char* tableName = tNameGetTableName(&sn);
|
||||||
|
|
||||||
|
strncpy(msg, tableName, TSDB_TABLE_NAME_LEN);
|
||||||
|
msg += TSDB_TABLE_NAME_LEN;
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfTable; ++i) {
|
|
||||||
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
|
||||||
SSTableObj *pTable = mnodeGetSuperTable(stableName);
|
|
||||||
if (pTable == NULL) {
|
|
||||||
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName);
|
|
||||||
mnodeDecTableRef(pTable);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pTable->vgHash == NULL) {
|
if (pTable->vgHash == NULL) {
|
||||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle,
|
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsgBody, handle, name);
|
||||||
stableName);
|
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pTable);
|
||||||
|
|
||||||
// even this super table has no corresponding table, still return
|
// even this super table has no corresponding table, still return
|
||||||
pRsp->numOfTables++;
|
|
||||||
|
|
||||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||||
pVgroupMsg->numOfVgroups = 0;
|
pVgroupMsg->numOfVgroups = 0;
|
||||||
|
|
||||||
msg += sizeof(SVgroupsMsg);
|
msg += sizeof(SVgroupsMsg);
|
||||||
} else {
|
} else {
|
||||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)msg;
|
||||||
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsg, pMsg->rpcMsg.ahandle,
|
mDebug("msg:%p, app:%p stable:%s, hash:%p sizeOfVgList:%d will be returned", pMsgBody, handle,
|
||||||
pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash));
|
pTable->info.tableId, pTable->vgHash, taosHashGetSize(pTable->vgHash));
|
||||||
|
|
||||||
int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL);
|
int32_t *pVgId = taosHashIterate(pTable->vgHash, NULL);
|
||||||
|
|
@ -1754,7 +1780,9 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||||
while (pVgId) {
|
while (pVgId) {
|
||||||
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
|
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
|
||||||
pVgId = taosHashIterate(pTable->vgHash, pVgId);
|
pVgId = taosHashIterate(pTable->vgHash, pVgId);
|
||||||
if (pVgroup == NULL) continue;
|
if (pVgroup == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
|
pVgroupMsg->vgroups[vgSize].vgId = htonl(pVgroup->vgId);
|
||||||
pVgroupMsg->vgroups[vgSize].numOfEps = 0;
|
pVgroupMsg->vgroups[vgSize].numOfEps = 0;
|
||||||
|
|
@ -1780,8 +1808,37 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
// one table is done, try the next table
|
// one table is done, try the next table
|
||||||
msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
|
msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
|
||||||
pRsp->numOfTables++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
|
||||||
|
SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||||
|
int32_t numOfTable = htonl(pInfo->numOfTables);
|
||||||
|
|
||||||
|
// calculate the required space.
|
||||||
|
int32_t contLen = calculateVgroupMsgLength(pInfo, numOfTable);
|
||||||
|
SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
|
||||||
|
if (pRsp == NULL) {
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRsp->numOfTables = 0;
|
||||||
|
char *msg = (char *)pRsp + sizeof(SSTableVgroupRspMsg);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfTable; ++i) {
|
||||||
|
char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
|
||||||
|
|
||||||
|
SSTableObj *pTable = mnodeGetSuperTable(stableName);
|
||||||
|
if (pTable == NULL) {
|
||||||
|
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName);
|
||||||
|
mnodeDecTableRef(pTable);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = serializeVgroupInfo(pTable, stableName, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||||
|
pRsp->numOfTables++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRsp->numOfTables != numOfTable) {
|
if (pRsp->numOfTables != numOfTable) {
|
||||||
|
|
@ -2322,31 +2379,23 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) {
|
||||||
return sdbUpdateRow(&row);
|
return sdbUpdateRow(&row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg, char *oldName, char *newName) {
|
static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg) {
|
||||||
|
SAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
|
||||||
|
char* name = pAlter->schema[0].name;
|
||||||
SCTableObj *pTable = (SCTableObj *)pMsg->pTable;
|
SCTableObj *pTable = (SCTableObj *)pMsg->pTable;
|
||||||
int32_t col = mnodeFindNormalTableColumnIndex(pTable, oldName);
|
int32_t col = mnodeFindNormalTableColumnIndex(pTable, name);
|
||||||
if (col < 0) {
|
if (col < 0) {
|
||||||
mError("msg:%p, app:%p ctable:%s, change column, oldName: %s, newName: %s", pMsg, pMsg->rpcMsg.ahandle,
|
mError("msg:%p, app:%p ctable:%s, change column, name: %s", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
pTable->info.tableId, oldName, newName);
|
pTable->info.tableId, name);
|
||||||
return TSDB_CODE_MND_FIELD_NOT_EXIST;
|
return TSDB_CODE_MND_FIELD_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int32_t rowSize = 0;
|
|
||||||
uint32_t len = (uint32_t)strlen(newName);
|
|
||||||
if (len >= TSDB_COL_NAME_LEN) {
|
|
||||||
return TSDB_CODE_MND_COL_NAME_TOO_LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mnodeFindNormalTableColumnIndex(pTable, newName) >= 0) {
|
|
||||||
return TSDB_CODE_MND_FIELD_ALREAY_EXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update
|
|
||||||
SSchema *schema = (SSchema *) (pTable->schema + col);
|
SSchema *schema = (SSchema *) (pTable->schema + col);
|
||||||
tstrncpy(schema->name, newName, sizeof(schema->name));
|
ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR);
|
||||||
|
schema->bytes = pAlter->schema[0].bytes;
|
||||||
|
|
||||||
mInfo("msg:%p, app:%p ctable %s, start to modify column %s to %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
|
mInfo("msg:%p, app:%p ctable %s, start to modify column %s len to %d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
|
||||||
oldName, newName);
|
name, schema->bytes);
|
||||||
|
|
||||||
SSdbRow row = {
|
SSdbRow row = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
|
@ -2415,9 +2464,9 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
|
||||||
pMeta->vgroup.numOfEps++;
|
pMeta->vgroup.numOfEps++;
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
}
|
}
|
||||||
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
|
||||||
|
|
||||||
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId);
|
||||||
|
mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d tid:%d", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid);
|
pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -2811,56 +2860,137 @@ static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) {
|
||||||
|
|
||||||
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
|
||||||
SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
|
||||||
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
|
||||||
|
|
||||||
int32_t totalMallocLen = 4 * 1024 * 1024; // first malloc 4 MB, subsequent reallocation as twice
|
pInfo->numOfTables = htonl(pInfo->numOfTables);
|
||||||
SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen);
|
pInfo->numOfVgroups = htonl(pInfo->numOfVgroups);
|
||||||
|
|
||||||
|
int32_t contLen = pMsg->rpcMsg.contLen - sizeof(SMultiTableInfoMsg);
|
||||||
|
|
||||||
|
int32_t num = 0;
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
char* str = strndup(pInfo->tableNames, contLen);
|
||||||
|
char** nameList = strsplit(str, ",", &num);
|
||||||
|
SArray* pList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
SMultiTableMeta *pMultiMeta = NULL;
|
||||||
|
|
||||||
|
if (num != pInfo->numOfTables + pInfo->numOfVgroups) {
|
||||||
|
mError("msg:%p, app:%p, failed to get multi-tableMeta, msg inconsistent", pMsg, pMsg->rpcMsg.ahandle);
|
||||||
|
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first malloc 80KB, subsequent reallocation will expand the size as twice of the original size
|
||||||
|
int32_t totalMallocLen = sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16);
|
||||||
|
pMultiMeta = rpcMallocCont(totalMallocLen);
|
||||||
if (pMultiMeta == NULL) {
|
if (pMultiMeta == NULL) {
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMultiMeta->contLen = sizeof(SMultiTableMeta);
|
pMultiMeta->contLen = sizeof(SMultiTableMeta);
|
||||||
pMultiMeta->numOfTables = 0;
|
pMultiMeta->numOfTables = 0;
|
||||||
|
|
||||||
for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
|
int32_t t = 0;
|
||||||
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN);
|
for (; t < pInfo->numOfTables; ++t) {
|
||||||
SCTableObj *pTable = mnodeGetChildTable(tableId);
|
char *fullName = nameList[t];
|
||||||
if (pTable == NULL) continue;
|
|
||||||
|
|
||||||
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableName(tableId);
|
pMsg->pTable = mnodeGetTable(fullName);
|
||||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
if (pMsg->pTable == NULL) {
|
||||||
mnodeDecTableRef(pTable);
|
mError("msg:%p, app:%p table:%s, failed to get table meta, table not exist", pMsg, pMsg->rpcMsg.ahandle, fullName);
|
||||||
continue;
|
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||||
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int availLen = totalMallocLen - pMultiMeta->contLen;
|
if (pMsg->pDb == NULL) {
|
||||||
if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
pMsg->pDb = mnodeGetDbByTableName(fullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||||
|
mnodeDecTableRef(pMsg->pTable);
|
||||||
|
code = TSDB_CODE_APP_NOT_READY;
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remain = totalMallocLen - pMultiMeta->contLen;
|
||||||
|
if (remain <= sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)) {
|
||||||
totalMallocLen *= 2;
|
totalMallocLen *= 2;
|
||||||
pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen);
|
pMultiMeta = rpcReallocCont(pMultiMeta, totalMallocLen);
|
||||||
if (pMultiMeta == NULL) {
|
if (pMultiMeta == NULL) {
|
||||||
mnodeDecTableRef(pTable);
|
mnodeDecTableRef(pMsg->pTable);
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
code = TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STableMetaMsg *pMeta = (STableMetaMsg *)((char*) pMultiMeta + pMultiMeta->contLen);
|
||||||
|
|
||||||
|
if (pMsg->pTable->type == TSDB_SUPER_TABLE) {
|
||||||
|
code = mnodeDoGetSuperTableMeta(pMsg, pMeta);
|
||||||
|
taosArrayPush(pList, &fullName); // keep the full name for each super table for retrieve vgroup list
|
||||||
} else {
|
} else {
|
||||||
t--;
|
code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
||||||
mnodeDecTableRef(pTable);
|
if (pMsg->pVgroup != NULL) {
|
||||||
continue;
|
mnodeDecVgroupRef(pMsg->pVgroup);
|
||||||
|
pMsg->pVgroup = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen);
|
mnodeDecTableRef(pMsg->pTable);
|
||||||
int32_t code = mnodeDoGetChildTableMeta(pMsg, pMeta);
|
pMsg->pTable = NULL;
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
pMultiMeta->numOfTables ++;
|
pMultiMeta->numOfTables++;
|
||||||
pMultiMeta->contLen += pMeta->contLen;
|
pMultiMeta->contLen += pMeta->contLen;
|
||||||
|
} else {
|
||||||
|
// ignore error and continue.
|
||||||
|
// Otherwise the client may found that the responding message is inconsistent.
|
||||||
|
// goto _end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeDecTableRef(pTable);
|
char* msg = (char*) pMultiMeta + pMultiMeta->contLen;
|
||||||
|
|
||||||
|
// add the additional super table names that needs the vgroup info
|
||||||
|
for(;t < num; ++t) {
|
||||||
|
taosArrayPush(pList, &nameList[t]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the pVgroupList into the pList
|
||||||
|
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pList);
|
||||||
|
pMultiMeta->numOfVgroup = htonl(numOfVgroupList);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < numOfVgroupList; ++i) {
|
||||||
|
char* name = taosArrayGetP(pList, i);
|
||||||
|
|
||||||
|
SSTableObj *pTable = mnodeGetSuperTable(name);
|
||||||
|
if (pTable == NULL) {
|
||||||
|
mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, name);
|
||||||
|
code = TSDB_CODE_MND_INVALID_TABLE_NAME;
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = serializeVgroupInfo(pTable, name, msg, pMsg, pMsg->rpcMsg.ahandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
pMultiMeta->contLen = (int32_t) (msg - (char*) pMultiMeta);
|
||||||
|
|
||||||
|
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
|
||||||
pMsg->rpcRsp.rsp = pMultiMeta;
|
pMsg->rpcRsp.rsp = pMultiMeta;
|
||||||
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
pMsg->rpcRsp.len = pMultiMeta->contLen;
|
||||||
|
code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
_end:
|
||||||
|
tfree(str);
|
||||||
|
tfree(nameList);
|
||||||
|
taosArrayDestroy(pList);
|
||||||
|
pMsg->pTable = NULL;
|
||||||
|
pMsg->pVgroup = NULL;
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
rpcFreeCont(pMultiMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
static int32_t mnodeGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
|
|
@ -3100,7 +3230,9 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) {
|
||||||
} else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
|
} else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
|
||||||
code = mnodeDropSuperTableColumn(pMsg, pAlter->schema[0].name);
|
code = mnodeDropSuperTableColumn(pMsg, pAlter->schema[0].name);
|
||||||
} else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_COLUMN) {
|
} else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_COLUMN) {
|
||||||
code = mnodeChangeSuperTableColumn(pMsg, pAlter->schema[0].name, pAlter->schema[1].name);
|
code = mnodeChangeSuperTableColumn(pMsg);
|
||||||
|
} else if (pAlter->type == TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN) {
|
||||||
|
code = mnodeChangeSuperTableTag(pMsg);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3112,7 +3244,7 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) {
|
||||||
} else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
|
} else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) {
|
||||||
code = mnodeDropNormalTableColumn(pMsg, pAlter->schema[0].name);
|
code = mnodeDropNormalTableColumn(pMsg, pAlter->schema[0].name);
|
||||||
} else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_COLUMN) {
|
} else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_COLUMN) {
|
||||||
code = mnodeChangeNormalTableColumn(pMsg, pAlter->schema[0].name, pAlter->schema[1].name);
|
code = mnodeChangeNormalTableColumn(pMsg);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3261,7 +3393,7 @@ static int32_t mnodeCompactSuperTables() {
|
||||||
.rowSize = sizeof(SSTableObj) + schemaSize,
|
.rowSize = sizeof(SSTableObj) + schemaSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
mInfo("compact super %" PRIu64, pTable->uid);
|
//mInfo("compact super %" PRIu64, pTable->uid);
|
||||||
|
|
||||||
sdbInsertCompactRow(&row);
|
sdbInsertCompactRow(&row);
|
||||||
}
|
}
|
||||||
|
|
@ -3287,7 +3419,7 @@ static int32_t mnodeCompactChildTables() {
|
||||||
.pTable = tsChildTableSdb,
|
.pTable = tsChildTableSdb,
|
||||||
};
|
};
|
||||||
|
|
||||||
mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
|
//mInfo("compact child %" PRIu64 ":%d", pTable->uid, pTable->tid);
|
||||||
|
|
||||||
sdbInsertCompactRow(&row);
|
sdbInsertCompactRow(&row);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void taosRemoveDir(char *rootDir);
|
void taosRemoveDir(char *rootDir);
|
||||||
|
bool taosDirExist(const char* dirname);
|
||||||
int32_t taosMkDir(const char *pathname, mode_t mode);
|
int32_t taosMkDir(const char *pathname, mode_t mode);
|
||||||
void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays);
|
void taosRemoveOldLogFiles(char *rootDir, int32_t keepDays);
|
||||||
int32_t taosRename(char *oldName, char *newName);
|
int32_t taosRename(char *oldName, char *newName);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TD_JEMALLOC_ENABLED
|
||||||
|
#include <jemalloc/jemalloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_ALLOC_MODE_DEFAULT = 0,
|
TAOS_ALLOC_MODE_DEFAULT = 0,
|
||||||
TAOS_ALLOC_MODE_RANDOM_FAIL = 1,
|
TAOS_ALLOC_MODE_RANDOM_FAIL = 1,
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,10 @@ void taosRemoveDir(char *rootDir) {
|
||||||
uInfo("dir:%s is removed", rootDir);
|
uInfo("dir:%s is removed", rootDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool taosDirExist(const char* dirname) {
|
||||||
|
return access(dirname, F_OK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int taosMkDir(const char *path, mode_t mode) {
|
int taosMkDir(const char *path, mode_t mode) {
|
||||||
int code = mkdir(path, 0755);
|
int code = mkdir(path, 0755);
|
||||||
if (code < 0 && errno == EEXIST) code = 0;
|
if (code < 0 && errno == EEXIST) code = 0;
|
||||||
|
|
|
||||||
|
|
@ -87,12 +87,12 @@ static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t time
|
||||||
|
|
||||||
int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
|
int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
|
||||||
|
|
||||||
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t daylight) {
|
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||||
/* parse datatime string in with tz */
|
/* parse datatime string in with tz */
|
||||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||||
return parseTimeWithTz(timestr, time, timePrec);
|
return parseTimeWithTz(timestr, time, timePrec);
|
||||||
} else {
|
} else {
|
||||||
return (*parseLocaltimeFp[daylight])(timestr, time, timePrec);
|
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char *errMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_SQL & 0XFFFF, temp);
|
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_OPERATION & 0XFFFF, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ void httpProcessSingleSqlCallBackImp(void *param, TAOS_RES *result, int32_t code
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
SSqlObj *pObj = (SSqlObj *)result;
|
SSqlObj *pObj = (SSqlObj *)result;
|
||||||
if (code == TSDB_CODE_TSC_INVALID_SQL) {
|
if (code == TSDB_CODE_TSC_INVALID_OPERATION) {
|
||||||
terrno = code;
|
terrno = code;
|
||||||
httpError("context:%p, fd:%d, user:%s, query error, code:%s, sqlObj:%p, error:%s", pContext, pContext->fd,
|
httpError("context:%p, fd:%d, user:%s, query error, code:%s, sqlObj:%p, error:%s", pContext, pContext->fd,
|
||||||
pContext->user, tstrerror(code), pObj, taos_errstr(pObj));
|
pContext->user, tstrerror(code), pObj, taos_errstr(pObj));
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,11 @@ void httpFreeMultiCmds(HttpContext *pContext) {
|
||||||
JsonBuf *httpMallocJsonBuf(HttpContext *pContext) {
|
JsonBuf *httpMallocJsonBuf(HttpContext *pContext) {
|
||||||
if (pContext->jsonBuf == NULL) {
|
if (pContext->jsonBuf == NULL) {
|
||||||
pContext->jsonBuf = (JsonBuf *)malloc(sizeof(JsonBuf));
|
pContext->jsonBuf = (JsonBuf *)malloc(sizeof(JsonBuf));
|
||||||
|
if (pContext->jsonBuf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(pContext->jsonBuf, 0, sizeof(JsonBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pContext->jsonBuf->pContext) {
|
if (!pContext->jsonBuf->pContext) {
|
||||||
|
|
|
||||||
|
|
@ -65,24 +65,18 @@ extern "C" {
|
||||||
|
|
||||||
#define TSDB_FUNC_RATE 29
|
#define TSDB_FUNC_RATE 29
|
||||||
#define TSDB_FUNC_IRATE 30
|
#define TSDB_FUNC_IRATE 30
|
||||||
#define TSDB_FUNC_SUM_RATE 31
|
#define TSDB_FUNC_TID_TAG 31
|
||||||
#define TSDB_FUNC_SUM_IRATE 32
|
#define TSDB_FUNC_BLKINFO 32
|
||||||
#define TSDB_FUNC_AVG_RATE 33
|
|
||||||
#define TSDB_FUNC_AVG_IRATE 34
|
|
||||||
|
|
||||||
#define TSDB_FUNC_TID_TAG 35
|
|
||||||
#define TSDB_FUNC_BLKINFO 36
|
|
||||||
|
|
||||||
#define TSDB_FUNC_HISTOGRAM 37
|
|
||||||
#define TSDB_FUNC_HLL 38
|
|
||||||
#define TSDB_FUNC_MODE 39
|
|
||||||
#define TSDB_FUNC_SAMPLE 40
|
|
||||||
#define TSDB_FUNC_CEIL 41
|
|
||||||
#define TSDB_FUNC_FLOOR 42
|
|
||||||
#define TSDB_FUNC_ROUND 43
|
|
||||||
#define TSDB_FUNC_MAVG 44
|
|
||||||
#define TSDB_FUNC_CSUM 45
|
|
||||||
|
|
||||||
|
#define TSDB_FUNC_HISTOGRAM 33
|
||||||
|
#define TSDB_FUNC_HLL 34
|
||||||
|
#define TSDB_FUNC_MODE 35
|
||||||
|
#define TSDB_FUNC_SAMPLE 36
|
||||||
|
#define TSDB_FUNC_CEIL 37
|
||||||
|
#define TSDB_FUNC_FLOOR 38
|
||||||
|
#define TSDB_FUNC_ROUND 39
|
||||||
|
#define TSDB_FUNC_MAVG 40
|
||||||
|
#define TSDB_FUNC_CSUM 41
|
||||||
|
|
||||||
#define TSDB_FUNCSTATE_SO 0x1u // single output
|
#define TSDB_FUNCSTATE_SO 0x1u // single output
|
||||||
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
|
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "qFill.h"
|
#include "qFill.h"
|
||||||
#include "qResultbuf.h"
|
#include "qResultbuf.h"
|
||||||
#include "qSqlparser.h"
|
#include "qSqlparser.h"
|
||||||
|
#include "qTableMeta.h"
|
||||||
#include "qTsbuf.h"
|
#include "qTsbuf.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
|
|
@ -70,14 +71,6 @@ typedef struct SResultRowPool {
|
||||||
SArray* pData; // SArray<void*>
|
SArray* pData; // SArray<void*>
|
||||||
} SResultRowPool;
|
} SResultRowPool;
|
||||||
|
|
||||||
typedef struct SSqlGroupbyExpr {
|
|
||||||
int16_t tableIndex;
|
|
||||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
|
||||||
int16_t numOfGroupCols;
|
|
||||||
int16_t orderIndex; // order by column index
|
|
||||||
int16_t orderType; // order by type: asc/desc
|
|
||||||
} SSqlGroupbyExpr;
|
|
||||||
|
|
||||||
typedef struct SResultRow {
|
typedef struct SResultRow {
|
||||||
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||||
int32_t offset:29; // row index in buffer page
|
int32_t offset:29; // row index in buffer page
|
||||||
|
|
@ -196,6 +189,7 @@ typedef struct SQueryAttr {
|
||||||
bool pointInterpQuery; // point interpolation query
|
bool pointInterpQuery; // point interpolation query
|
||||||
bool needReverseScan; // need reverse scan
|
bool needReverseScan; // need reverse scan
|
||||||
bool distinctTag; // distinct tag query
|
bool distinctTag; // distinct tag query
|
||||||
|
bool stateWindow; // window State on sub/normal table
|
||||||
int32_t interBufSize; // intermediate buffer sizse
|
int32_t interBufSize; // intermediate buffer sizse
|
||||||
|
|
||||||
int32_t havingNum; // having expr number
|
int32_t havingNum; // having expr number
|
||||||
|
|
@ -216,7 +210,7 @@ typedef struct SQueryAttr {
|
||||||
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
||||||
int32_t maxTableColumnWidth;
|
int32_t maxTableColumnWidth;
|
||||||
int32_t tagLen; // tag value length of current query
|
int32_t tagLen; // tag value length of current query
|
||||||
SSqlGroupbyExpr* pGroupbyExpr;
|
SGroupbyExpr *pGroupbyExpr;
|
||||||
|
|
||||||
SExprInfo* pExpr1;
|
SExprInfo* pExpr1;
|
||||||
SExprInfo* pExpr2;
|
SExprInfo* pExpr2;
|
||||||
|
|
@ -302,6 +296,8 @@ enum OPERATOR_TYPE_E {
|
||||||
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||||
OP_Filter = 19,
|
OP_Filter = 19,
|
||||||
OP_Distinct = 20,
|
OP_Distinct = 20,
|
||||||
|
OP_Join = 21,
|
||||||
|
OP_StateWindow = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
|
|
@ -314,7 +310,8 @@ typedef struct SOperatorInfo {
|
||||||
SExprInfo *pExpr;
|
SExprInfo *pExpr;
|
||||||
SQueryRuntimeEnv *pRuntimeEnv;
|
SQueryRuntimeEnv *pRuntimeEnv;
|
||||||
|
|
||||||
struct SOperatorInfo *upstream;
|
struct SOperatorInfo **upstream; // upstream pointer list
|
||||||
|
int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator
|
||||||
__operator_fn_t exec;
|
__operator_fn_t exec;
|
||||||
__optr_cleanup_fn_t cleanup;
|
__optr_cleanup_fn_t cleanup;
|
||||||
} SOperatorInfo;
|
} SOperatorInfo;
|
||||||
|
|
@ -362,7 +359,7 @@ typedef struct SQueryParam {
|
||||||
|
|
||||||
SColIndex *pGroupColIndex;
|
SColIndex *pGroupColIndex;
|
||||||
SColumnInfo *pTagColumnInfo;
|
SColumnInfo *pTagColumnInfo;
|
||||||
SSqlGroupbyExpr *pGroupbyExpr;
|
SGroupbyExpr *pGroupbyExpr;
|
||||||
int32_t tableScanOperator;
|
int32_t tableScanOperator;
|
||||||
SArray *pOperator;
|
SArray *pOperator;
|
||||||
} SQueryParam;
|
} SQueryParam;
|
||||||
|
|
@ -465,6 +462,16 @@ typedef struct SSWindowOperatorInfo {
|
||||||
int32_t start; // start row index
|
int32_t start; // start row index
|
||||||
} SSWindowOperatorInfo;
|
} SSWindowOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SStateWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t colIndex; // start row index
|
||||||
|
int32_t start;
|
||||||
|
char* prevData; // previous data
|
||||||
|
|
||||||
|
} SStateWindowOperatorInfo ;
|
||||||
|
|
||||||
typedef struct SDistinctOperatorInfo {
|
typedef struct SDistinctOperatorInfo {
|
||||||
SHashObj *pSet;
|
SHashObj *pSet;
|
||||||
SSDataBlock *pRes;
|
SSDataBlock *pRes;
|
||||||
|
|
@ -473,10 +480,10 @@ typedef struct SDistinctOperatorInfo {
|
||||||
int64_t outputCapacity;
|
int64_t outputCapacity;
|
||||||
} SDistinctOperatorInfo;
|
} SDistinctOperatorInfo;
|
||||||
|
|
||||||
struct SLocalMerger;
|
struct SGlobalMerger;
|
||||||
|
|
||||||
typedef struct SMultiwayMergeInfo {
|
typedef struct SMultiwayMergeInfo {
|
||||||
struct SLocalMerger *pMerge;
|
struct SGlobalMerger *pMerge;
|
||||||
SOptrBasicInfo binfo;
|
SOptrBasicInfo binfo;
|
||||||
int32_t bufCapacity;
|
int32_t bufCapacity;
|
||||||
int64_t seed;
|
int64_t seed;
|
||||||
|
|
@ -494,6 +501,8 @@ typedef struct SMultiwayMergeInfo {
|
||||||
bool groupMix;
|
bool groupMix;
|
||||||
} SMultiwayMergeInfo;
|
} SMultiwayMergeInfo;
|
||||||
|
|
||||||
|
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||||
|
|
||||||
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
||||||
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
||||||
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
|
|
@ -512,14 +521,23 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
||||||
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||||
int32_t numOfRows, void* merger, bool groupMix);
|
int32_t numOfRows, void* merger, bool groupMix);
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
||||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||||
|
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||||
|
|
||||||
|
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput);
|
||||||
|
|
||||||
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
||||||
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
||||||
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
||||||
|
|
||||||
|
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||||
|
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock);
|
||||||
|
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p);
|
||||||
|
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p);
|
||||||
|
|
||||||
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
||||||
void* destroyOutputBuf(SSDataBlock* pBlock);
|
void* destroyOutputBuf(SSDataBlock* pBlock);
|
||||||
|
|
||||||
|
|
@ -536,16 +554,19 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
||||||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||||
SSqlExpr **pExpr, SExprInfo *prevExpr);
|
SSqlExpr **pExpr, SExprInfo *prevExpr);
|
||||||
|
|
||||||
SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId);
|
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, int32_t vgId, char* sql, uint64_t *qId);
|
||||||
|
|
||||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||||
int32_t prevResultLen, void* merger);
|
int32_t prevResultLen, void* merger);
|
||||||
|
|
||||||
|
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId);
|
||||||
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||||
|
|
||||||
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
||||||
|
STableQueryInfo* createTmpTableQueryInfo(STimeWindow win);
|
||||||
|
|
||||||
int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg);
|
int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg);
|
||||||
|
|
||||||
bool isQueryKilled(SQInfo *pQInfo);
|
bool isQueryKilled(SQInfo *pQInfo);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ typedef struct SFillInfo {
|
||||||
|
|
||||||
SFillColInfo* pFillCol; // column info for fill operations
|
SFillColInfo* pFillCol; // column info for fill operations
|
||||||
SFillTagColInfo* pTags; // tags value for filling gap
|
SFillTagColInfo* pTags; // tags value for filling gap
|
||||||
void* handle; // for dubug purpose
|
void* handle; // for debug purpose
|
||||||
} SFillInfo;
|
} SFillInfo;
|
||||||
|
|
||||||
typedef struct SPoint {
|
typedef struct SPoint {
|
||||||
|
|
@ -82,8 +82,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
||||||
|
|
||||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||||
|
|
||||||
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput);
|
|
||||||
|
|
||||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo);
|
bool taosFillHasMoreResults(SFillInfo* pFillInfo);
|
||||||
|
|
||||||
int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
|
int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,40 @@
|
||||||
#ifndef TDENGINE_QPLAN_H
|
#ifndef TDENGINE_QPLAN_H
|
||||||
#define TDENGINE_QPLAN_H
|
#define TDENGINE_QPLAN_H
|
||||||
|
|
||||||
//TODO refactor
|
#include "qExecutor.h"
|
||||||
|
|
||||||
|
struct SQueryInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryNodeBasicInfo {
|
||||||
|
int32_t type;
|
||||||
|
char *name;
|
||||||
|
} SQueryNodeBasicInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryTableInfo {
|
||||||
|
char *tableName;
|
||||||
|
STableId id;
|
||||||
|
} SQueryTableInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryNode {
|
||||||
|
SQueryNodeBasicInfo info;
|
||||||
|
SQueryTableInfo tableInfo;
|
||||||
|
SSchema *pSchema; // the schema of the input SSDatablock
|
||||||
|
int32_t numOfCols; // number of input columns
|
||||||
|
SExprInfo *pExpr; // the query functions or sql aggregations
|
||||||
|
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
||||||
|
|
||||||
|
void *pExtInfo; // additional information
|
||||||
|
// previous operator to generated result for current node to process
|
||||||
|
// in case of join, multiple prev nodes exist.
|
||||||
|
SArray *pPrevNodes;// upstream nodes
|
||||||
|
struct SQueryNode *nextNode;
|
||||||
|
} SQueryNode;
|
||||||
|
|
||||||
|
SQueryNode* qCreateQueryPlan(struct SQueryInfo* pQueryInfo);
|
||||||
|
void* qDestroyQueryPlan(SQueryNode* pQueryNode);
|
||||||
|
|
||||||
|
char* queryPlanToString(SQueryNode* pQueryNode);
|
||||||
|
|
||||||
SArray* createTableScanPlan(SQueryAttr* pQueryAttr);
|
SArray* createTableScanPlan(SQueryAttr* pQueryAttr);
|
||||||
SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr);
|
SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr);
|
||||||
SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr);
|
SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr);
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,10 @@ typedef struct SSessionWindowVal {
|
||||||
SStrToken gap;
|
SStrToken gap;
|
||||||
} SSessionWindowVal;
|
} SSessionWindowVal;
|
||||||
|
|
||||||
|
typedef struct SWindowStateVal {
|
||||||
|
SStrToken col;
|
||||||
|
} SWindowStateVal;
|
||||||
|
|
||||||
struct SRelationInfo;
|
struct SRelationInfo;
|
||||||
|
|
||||||
typedef struct SSqlNode {
|
typedef struct SSqlNode {
|
||||||
|
|
@ -100,6 +104,7 @@ typedef struct SSqlNode {
|
||||||
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
||||||
SIntervalVal interval; // (interval, interval_offset) [optional]
|
SIntervalVal interval; // (interval, interval_offset) [optional]
|
||||||
SSessionWindowVal sessionVal; // session window [optional]
|
SSessionWindowVal sessionVal; // session window [optional]
|
||||||
|
SWindowStateVal windowstateVal; // window_state(col) [optional]
|
||||||
SStrToken sliding; // sliding window [optional]
|
SStrToken sliding; // sliding window [optional]
|
||||||
SLimitVal limit; // limit offset [optional]
|
SLimitVal limit; // limit offset [optional]
|
||||||
SLimitVal slimit; // group limit offset [optional]
|
SLimitVal slimit; // group limit offset [optional]
|
||||||
|
|
@ -107,14 +112,18 @@ typedef struct SSqlNode {
|
||||||
struct tSqlExpr *pHaving; // having clause [optional]
|
struct tSqlExpr *pHaving; // having clause [optional]
|
||||||
} SSqlNode;
|
} SSqlNode;
|
||||||
|
|
||||||
typedef struct STableNamePair {
|
typedef struct SRelElementPair {
|
||||||
SStrToken name;
|
union {
|
||||||
|
SStrToken tableName;
|
||||||
|
SArray *pSubquery;
|
||||||
|
};
|
||||||
|
|
||||||
SStrToken aliasName;
|
SStrToken aliasName;
|
||||||
} STableNamePair;
|
} SRelElementPair;
|
||||||
|
|
||||||
typedef struct SRelationInfo {
|
typedef struct SRelationInfo {
|
||||||
int32_t type; // nested query|table name list
|
int32_t type; // nested query|table name list
|
||||||
SArray *list; // SArray<STableNamePair>|SArray<SSqlNode*>
|
SArray *list; // SArray<SRelElementPair>
|
||||||
} SRelationInfo;
|
} SRelationInfo;
|
||||||
|
|
||||||
typedef struct SCreatedTableInfo {
|
typedef struct SCreatedTableInfo {
|
||||||
|
|
@ -254,8 +263,8 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
||||||
SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder);
|
SArray *tVariantListAppendToken(SArray *pList, SStrToken *pAliasToken, uint8_t sortOrder);
|
||||||
|
|
||||||
SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias);
|
SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias);
|
||||||
SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode);
|
|
||||||
void *destroyRelationInfo(SRelationInfo* pFromInfo);
|
void *destroyRelationInfo(SRelationInfo* pFromInfo);
|
||||||
|
SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias);
|
||||||
|
|
||||||
// sql expr leaf node
|
// sql expr leaf node
|
||||||
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType);
|
||||||
|
|
@ -271,7 +280,7 @@ SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinc
|
||||||
void tSqlExprListDestroy(SArray *pList);
|
void tSqlExprListDestroy(SArray *pList);
|
||||||
|
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SWindowStateVal *pw,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
||||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
#ifndef TDENGINE_QTABLEUTIL_H
|
||||||
|
#define TDENGINE_QTABLEUTIL_H
|
||||||
|
|
||||||
|
#include "tsdb.h" //todo tsdb should not be here
|
||||||
|
#include "qSqlparser.h"
|
||||||
|
|
||||||
|
typedef struct SFieldInfo {
|
||||||
|
int16_t numOfOutput; // number of column in result
|
||||||
|
TAOS_FIELD* final;
|
||||||
|
SArray *internalField; // SArray<SInternalField>
|
||||||
|
} SFieldInfo;
|
||||||
|
|
||||||
|
typedef struct SCond {
|
||||||
|
uint64_t uid;
|
||||||
|
int32_t len; // length of tag query condition data
|
||||||
|
char * cond;
|
||||||
|
} SCond;
|
||||||
|
|
||||||
|
typedef struct SJoinNode {
|
||||||
|
uint64_t uid;
|
||||||
|
int16_t tagColId;
|
||||||
|
SArray* tsJoin;
|
||||||
|
SArray* tagJoin;
|
||||||
|
} SJoinNode;
|
||||||
|
|
||||||
|
typedef struct SJoinInfo {
|
||||||
|
bool hasJoin;
|
||||||
|
SJoinNode *joinTables[TSDB_MAX_JOIN_TABLE_NUM];
|
||||||
|
} SJoinInfo;
|
||||||
|
|
||||||
|
typedef struct STagCond {
|
||||||
|
// relation between tbname list and query condition, including : TK_AND or TK_OR
|
||||||
|
int16_t relType;
|
||||||
|
|
||||||
|
// tbname query condition, only support tbname query condition on one table
|
||||||
|
SCond tbnameCond;
|
||||||
|
|
||||||
|
// join condition, only support two tables join currently
|
||||||
|
SJoinInfo joinInfo;
|
||||||
|
|
||||||
|
// for different table, the query condition must be seperated
|
||||||
|
SArray *pCond;
|
||||||
|
} STagCond;
|
||||||
|
|
||||||
|
typedef struct SGroupbyExpr {
|
||||||
|
int16_t tableIndex;
|
||||||
|
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||||
|
int16_t numOfGroupCols; // todo remove it
|
||||||
|
int16_t orderIndex; // order by column index
|
||||||
|
int16_t orderType; // order by type: asc/desc
|
||||||
|
} SGroupbyExpr;
|
||||||
|
|
||||||
|
typedef struct STableComInfo {
|
||||||
|
uint8_t numOfTags;
|
||||||
|
uint8_t precision;
|
||||||
|
int16_t numOfColumns;
|
||||||
|
int32_t rowSize;
|
||||||
|
} STableComInfo;
|
||||||
|
|
||||||
|
typedef struct STableMeta {
|
||||||
|
int32_t vgId;
|
||||||
|
STableId id;
|
||||||
|
uint8_t tableType;
|
||||||
|
char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name
|
||||||
|
uint64_t suid; // super table id
|
||||||
|
int16_t sversion;
|
||||||
|
int16_t tversion;
|
||||||
|
STableComInfo tableInfo;
|
||||||
|
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||||
|
} STableMeta;
|
||||||
|
|
||||||
|
typedef struct STableMetaInfo {
|
||||||
|
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||||
|
uint32_t tableMetaSize;
|
||||||
|
SVgroupsInfo *vgroupList;
|
||||||
|
SArray *pVgroupTables; // SArray<SVgroupTableInfo>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. keep the vgroup index during the multi-vnode super table projection query
|
||||||
|
* 2. keep the vgroup index for multi-vnode insertion
|
||||||
|
*/
|
||||||
|
int32_t vgroupIndex;
|
||||||
|
SName name;
|
||||||
|
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
||||||
|
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
||||||
|
} STableMetaInfo;
|
||||||
|
|
||||||
|
struct SQInfo; // global merge operator
|
||||||
|
struct SQueryAttr; // query object
|
||||||
|
|
||||||
|
typedef struct SQueryInfo {
|
||||||
|
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
||||||
|
uint32_t type; // query/insert type
|
||||||
|
STimeWindow window; // the whole query time window
|
||||||
|
|
||||||
|
SInterval interval; // tumble time window
|
||||||
|
SSessionWindow sessionWindow; // session time window
|
||||||
|
|
||||||
|
SGroupbyExpr groupbyExpr; // groupby tags info
|
||||||
|
SArray * colList; // SArray<SColumn*>
|
||||||
|
SFieldInfo fieldsInfo;
|
||||||
|
SArray * exprList; // SArray<SExprInfo*>
|
||||||
|
SArray * exprList1; // final exprlist in case of arithmetic expression exists
|
||||||
|
SLimitVal limit;
|
||||||
|
SLimitVal slimit;
|
||||||
|
STagCond tagCond;
|
||||||
|
|
||||||
|
SOrderVal order;
|
||||||
|
int16_t fillType; // final result fill type
|
||||||
|
int16_t numOfTables;
|
||||||
|
STableMetaInfo **pTableMetaInfo;
|
||||||
|
struct STSBuf *tsBuf;
|
||||||
|
int64_t * fillVal; // default value for fill
|
||||||
|
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
||||||
|
int64_t clauseLimit; // limit for current sub clause
|
||||||
|
|
||||||
|
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
|
||||||
|
int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit
|
||||||
|
|
||||||
|
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
||||||
|
int16_t resColumnId; // result column id
|
||||||
|
bool distinctTag; // distinct tag or not
|
||||||
|
int32_t round; // 0/1/....
|
||||||
|
int32_t bufLen;
|
||||||
|
char* buf;
|
||||||
|
struct SQInfo* pQInfo; // global merge operator
|
||||||
|
struct SQueryAttr* pQueryAttr; // query object
|
||||||
|
|
||||||
|
struct SQueryInfo *sibling; // sibling
|
||||||
|
SArray *pUpstream; // SArray<struct SQueryInfo>
|
||||||
|
struct SQueryInfo *pDownstream;
|
||||||
|
int32_t havingFieldNum;
|
||||||
|
bool stableQuery;
|
||||||
|
bool groupbyColumn;
|
||||||
|
bool simpleAgg;
|
||||||
|
bool arithmeticOnAgg;
|
||||||
|
bool projectionQuery;
|
||||||
|
bool hasFilter;
|
||||||
|
bool onlyTagQuery;
|
||||||
|
bool orderProjectQuery;
|
||||||
|
bool stateWindow;
|
||||||
|
} SQueryInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the number of tags of this table
|
||||||
|
* @param pTableMeta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t tscGetNumOfTags(const STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the number of columns of this table
|
||||||
|
* @param pTableMeta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int32_t tscGetNumOfColumns(const STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the basic info of this table
|
||||||
|
* @param pTableMeta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
STableComInfo tscGetTableInfo(const STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the schema
|
||||||
|
* @param pTableMeta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SSchema* tscGetTableSchema(const STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the tag schema
|
||||||
|
* @param pMeta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SSchema *tscGetTableTagSchema(const STableMeta *pMeta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the column schema according to the column index
|
||||||
|
* @param pMeta
|
||||||
|
* @param colIndex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the column schema according to the column id
|
||||||
|
* @param pTableMeta
|
||||||
|
* @param colId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create the table meta from the msg
|
||||||
|
* @param pTableMetaMsg
|
||||||
|
* @param size size of the table meta
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg);
|
||||||
|
|
||||||
|
#endif // TDENGINE_QTABLEUTIL_H
|
||||||
|
|
@ -47,6 +47,9 @@ void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, in
|
||||||
|
|
||||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||||
|
|
||||||
|
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||||
|
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||||
|
|
||||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||||
return pResultRowInfo->pResult[slot];
|
return pResultRowInfo->pResult[slot];
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "qSqlparser.h"
|
#include "qSqlparser.h"
|
||||||
#include "tcmdtype.h"
|
#include "tcmdtype.h"
|
||||||
#include "tstoken.h"
|
#include "ttoken.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
|
|
@ -460,8 +460,8 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
||||||
//////////////////////// The SELECT statement /////////////////////////////////
|
//////////////////////// The SELECT statement /////////////////////////////////
|
||||||
%type select {SSqlNode*}
|
%type select {SSqlNode*}
|
||||||
%destructor select {destroySqlNode($$);}
|
%destructor select {destroySqlNode($$);}
|
||||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) windowstate_option(D) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||||
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G, N);
|
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &D, &S, F, &L, &G, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(A) ::= LP select(B) RP. {A = B;}
|
select(A) ::= LP select(B) RP. {A = B;}
|
||||||
|
|
@ -479,7 +479,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||||
// select client_version()
|
// select client_version()
|
||||||
// select server_state()
|
// select server_state()
|
||||||
select(A) ::= SELECT(T) selcollist(W). {
|
select(A) ::= SELECT(T) selcollist(W). {
|
||||||
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// selcollist is a list of expressions that are to become the return
|
// selcollist is a list of expressions that are to become the return
|
||||||
|
|
@ -516,7 +516,13 @@ distinct(X) ::= . { X.n = 0;}
|
||||||
%type from {SRelationInfo*}
|
%type from {SRelationInfo*}
|
||||||
%destructor from {destroyRelationInfo($$);}
|
%destructor from {destroyRelationInfo($$);}
|
||||||
from(A) ::= FROM tablelist(X). {A = X;}
|
from(A) ::= FROM tablelist(X). {A = X;}
|
||||||
from(A) ::= FROM LP union(Y) RP. {A = setSubquery(NULL, Y);}
|
from(A) ::= FROM sub(X). {A = X;}
|
||||||
|
|
||||||
|
%type sub {SRelationInfo*}
|
||||||
|
%destructor sub {destroyRelationInfo($$);}
|
||||||
|
sub(A) ::= LP union(Y) RP. {A = addSubqueryElem(NULL, Y, NULL);}
|
||||||
|
sub(A) ::= LP union(Y) RP ids(Z). {A = addSubqueryElem(NULL, Y, &Z);}
|
||||||
|
sub(A) ::= sub(X) COMMA LP union(Y) RP ids(Z).{A = addSubqueryElem(X, Y, &Z);}
|
||||||
|
|
||||||
%type tablelist {SRelationInfo*}
|
%type tablelist {SRelationInfo*}
|
||||||
%destructor tablelist {destroyRelationInfo($$);}
|
%destructor tablelist {destroyRelationInfo($$);}
|
||||||
|
|
@ -556,6 +562,11 @@ session_option(X) ::= SESSION LP ids(V) cpxName(Z) COMMA tmvar(Y) RP. {
|
||||||
X.col = V;
|
X.col = V;
|
||||||
X.gap = Y;
|
X.gap = Y;
|
||||||
}
|
}
|
||||||
|
%type windowstate_option {SWindowStateVal}
|
||||||
|
windowstate_option(X) ::= . {X.col.n = 0;}
|
||||||
|
windowstate_option(X) ::= STATE_WINDOW LP ids(V) RP. {
|
||||||
|
X.col = V;
|
||||||
|
}
|
||||||
|
|
||||||
%type fill_opt {SArray*}
|
%type fill_opt {SArray*}
|
||||||
%destructor fill_opt {taosArrayDestroy($$);}
|
%destructor fill_opt {taosArrayDestroy($$);}
|
||||||
|
|
@ -752,6 +763,12 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) DROP COLUMN ids(A). {
|
||||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd ::= ALTER TABLE ids(X) cpxName(F) MODIFY COLUMN columnlist(A). {
|
||||||
|
X.n += F.n;
|
||||||
|
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, A, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1);
|
||||||
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////ALTER TAGS statement/////////////////////////////////////
|
//////////////////////////////////ALTER TAGS statement/////////////////////////////////////
|
||||||
cmd ::= ALTER TABLE ids(X) cpxName(Y) ADD TAG columnlist(A). {
|
cmd ::= ALTER TABLE ids(X) cpxName(Y) ADD TAG columnlist(A). {
|
||||||
X.n += Y.n;
|
X.n += Y.n;
|
||||||
|
|
@ -792,6 +809,11 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) SET TAG ids(Y) EQ tagitem(Z). {
|
||||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd ::= ALTER TABLE ids(X) cpxName(F) MODIFY TAG columnlist(A). {
|
||||||
|
X.n += F.n;
|
||||||
|
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, A, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1);
|
||||||
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////ALTER STABLE statement//////////////////////////////////
|
///////////////////////////////////ALTER STABLE statement//////////////////////////////////
|
||||||
cmd ::= ALTER STABLE ids(X) cpxName(F) ADD COLUMN columnlist(A). {
|
cmd ::= ALTER STABLE ids(X) cpxName(F) ADD COLUMN columnlist(A). {
|
||||||
|
|
@ -810,6 +832,12 @@ cmd ::= ALTER STABLE ids(X) cpxName(F) DROP COLUMN ids(A). {
|
||||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd ::= ALTER STABLE ids(X) cpxName(F) MODIFY COLUMN columnlist(A). {
|
||||||
|
X.n += F.n;
|
||||||
|
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, A, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE);
|
||||||
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////ALTER TAGS statement/////////////////////////////////////
|
//////////////////////////////////ALTER TAGS statement/////////////////////////////////////
|
||||||
cmd ::= ALTER STABLE ids(X) cpxName(Y) ADD TAG columnlist(A). {
|
cmd ::= ALTER STABLE ids(X) cpxName(Y) ADD TAG columnlist(A). {
|
||||||
X.n += Y.n;
|
X.n += Y.n;
|
||||||
|
|
@ -839,6 +867,23 @@ cmd ::= ALTER STABLE ids(X) cpxName(F) CHANGE TAG ids(Y) ids(Z). {
|
||||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd ::= ALTER STABLE ids(X) cpxName(F) SET TAG ids(Y) EQ tagitem(Z). {
|
||||||
|
X.n += F.n;
|
||||||
|
|
||||||
|
toTSDBType(Y.type);
|
||||||
|
SArray* A = tVariantListAppendToken(NULL, &Y, -1);
|
||||||
|
A = tVariantListAppend(A, &Z, -1);
|
||||||
|
|
||||||
|
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, TSDB_SUPER_TABLE);
|
||||||
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd ::= ALTER STABLE ids(X) cpxName(F) MODIFY TAG columnlist(A). {
|
||||||
|
X.n += F.n;
|
||||||
|
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, A, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE);
|
||||||
|
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////kill statement///////////////////////////////////////
|
////////////////////////////////////////kill statement///////////////////////////////////////
|
||||||
cmd ::= KILL CONNECTION INTEGER(Y). {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &Y);}
|
cmd ::= KILL CONNECTION INTEGER(Y). {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &Y);}
|
||||||
cmd ::= KILL STREAM INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &X);}
|
cmd ::= KILL STREAM INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &X);}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "texpr.h"
|
#include "texpr.h"
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
|
||||||
#include "qAggMain.h"
|
#include "qAggMain.h"
|
||||||
#include "qFill.h"
|
#include "qFill.h"
|
||||||
|
|
@ -151,22 +152,20 @@ typedef struct STSCompInfo {
|
||||||
} STSCompInfo;
|
} STSCompInfo;
|
||||||
|
|
||||||
typedef struct SRateInfo {
|
typedef struct SRateInfo {
|
||||||
int64_t CorrectionValue;
|
double correctionValue;
|
||||||
int64_t firstValue;
|
double firstValue;
|
||||||
TSKEY firstKey;
|
TSKEY firstKey;
|
||||||
int64_t lastValue;
|
double lastValue;
|
||||||
TSKEY lastKey;
|
TSKEY lastKey;
|
||||||
int8_t hasResult; // flag to denote has value
|
int8_t hasResult; // flag to denote has value
|
||||||
bool isIRate; // true for IRate functions, false for Rate functions
|
bool isIRate; // true for IRate functions, false for Rate functions
|
||||||
int64_t num; // for sum/avg
|
|
||||||
double sum; // for sum/avg
|
|
||||||
} SRateInfo;
|
} SRateInfo;
|
||||||
|
|
||||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||||
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
||||||
if (!isValidDataType(dataType)) {
|
if (!isValidDataType(dataType)) {
|
||||||
qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
|
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY ||
|
||||||
|
|
@ -237,7 +236,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
*interBytes = *bytes;
|
*interBytes = *bytes;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
} else if (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE) {
|
} else if (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE) {
|
||||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = sizeof(SRateInfo);
|
*bytes = sizeof(SRateInfo);
|
||||||
*interBytes = sizeof(SRateInfo);
|
*interBytes = sizeof(SRateInfo);
|
||||||
|
|
@ -303,7 +302,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = sizeof(double);
|
*bytes = sizeof(double);
|
||||||
*interBytes = sizeof(SAvgInfo);
|
*interBytes = sizeof(SAvgInfo);
|
||||||
} else if (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE) {
|
} else if (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE) {
|
||||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
*bytes = sizeof(double);
|
*bytes = sizeof(double);
|
||||||
*interBytes = sizeof(SRateInfo);
|
*interBytes = sizeof(SRateInfo);
|
||||||
|
|
@ -353,7 +352,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
*interBytes = (*bytes);
|
*interBytes = (*bytes);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -2489,7 +2488,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
|
||||||
tmp += POINTER_BYTES * pCtx->param[0].i64;
|
tmp += POINTER_BYTES * pCtx->param[0].i64;
|
||||||
|
|
||||||
size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen;
|
size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen;
|
||||||
// assert(pCtx->param[0].i64 > 0);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->param[0].i64; ++i) {
|
for (int32_t i = 0; i < pCtx->param[0].i64; ++i) {
|
||||||
pTopBotInfo->res[i] = (tValuePair*) tmp;
|
pTopBotInfo->res[i] = (tValuePair*) tmp;
|
||||||
|
|
@ -2498,7 +2496,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) {
|
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
if (pResInfo == NULL) {
|
if (pResInfo == NULL) {
|
||||||
|
|
@ -2578,13 +2575,14 @@ static void top_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
char *data = GET_INPUT_DATA(pCtx, i);
|
||||||
TSKEY ts = GET_TS_DATA(pCtx, i);
|
|
||||||
|
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
|
||||||
|
// NOTE: Set the default timestamp if it is missing [todo refactor]
|
||||||
|
TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
|
||||||
do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2657,13 +2655,13 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
char *data = GET_INPUT_DATA(pCtx, i);
|
||||||
TSKEY ts = GET_TS_DATA(pCtx, i);
|
|
||||||
|
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
// NOTE: Set the default timestamp if it is missing [todo refactor]
|
||||||
|
TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
|
||||||
do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2741,7 +2739,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
} else if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
} else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX)*/ {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
}
|
}
|
||||||
|
|
@ -3298,8 +3296,12 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
|
||||||
if (pCtx->numOfParams == 2) {
|
if (pCtx->numOfParams == 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (pCtx->param[0].i64 == 1) {
|
||||||
|
SET_VAL(pCtx, pCtx->size, 1);
|
||||||
|
} else {
|
||||||
INC_INIT_VAL(pCtx, pCtx->size);
|
INC_INIT_VAL(pCtx, pCtx->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *pData = GET_INPUT_DATA_LIST(pCtx);
|
char *pData = GET_INPUT_DATA_LIST(pCtx);
|
||||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||||
|
|
@ -3700,7 +3702,7 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(index >= 0 /*&& colId >= 0*/);
|
assert(index >= 0);
|
||||||
return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes;
|
return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4475,36 +4477,34 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// RATE functions
|
// rate functions
|
||||||
|
static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) {
|
||||||
static double do_calc_rate(const SRateInfo* pRateInfo) {
|
if ((INT64_MIN == pRateInfo->lastKey) || (INT64_MIN == pRateInfo->firstKey) ||
|
||||||
if ((INT64_MIN == pRateInfo->lastKey) || (INT64_MIN == pRateInfo->firstKey) || (pRateInfo->firstKey >= pRateInfo->lastKey)) {
|
(pRateInfo->firstKey >= pRateInfo->lastKey)) {
|
||||||
return 0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t diff = 0;
|
double diff = 0;
|
||||||
|
|
||||||
if (pRateInfo->isIRate) {
|
if (pRateInfo->isIRate) {
|
||||||
|
// If the previous value of the last is greater than the last value, only keep the last point instead of the delta
|
||||||
|
// value between two values.
|
||||||
diff = pRateInfo->lastValue;
|
diff = pRateInfo->lastValue;
|
||||||
if (diff >= pRateInfo->firstValue) {
|
if (diff >= pRateInfo->firstValue) {
|
||||||
diff -= pRateInfo->firstValue;
|
diff -= pRateInfo->firstValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
diff = pRateInfo->CorrectionValue + pRateInfo->lastValue - pRateInfo->firstValue;
|
diff = pRateInfo->correctionValue + pRateInfo->lastValue - pRateInfo->firstValue;
|
||||||
if (diff <= 0) {
|
if (diff <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t duration = pRateInfo->lastKey - pRateInfo->firstKey;
|
int64_t duration = pRateInfo->lastKey - pRateInfo->firstKey;
|
||||||
duration = (duration + 500) / 1000;
|
if (duration == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
double resultVal = ((double)diff) / duration;
|
return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0;
|
||||||
|
|
||||||
qDebug("do_calc_rate() isIRate:%d firstKey:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " lastValue:%" PRId64 " CorrectionValue:%" PRId64 " resultVal:%f",
|
|
||||||
pRateInfo->isIRate, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, resultVal);
|
|
||||||
|
|
||||||
return resultVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rate_function_setup(SQLFunctionCtx *pCtx) {
|
static bool rate_function_setup(SQLFunctionCtx *pCtx) {
|
||||||
|
|
@ -4512,19 +4512,17 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->pOutput + pCtx->outputBytes;
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
SRateInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
|
|
||||||
pInfo->CorrectionValue = 0;
|
SRateInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
pInfo->correctionValue = 0;
|
||||||
pInfo->firstKey = INT64_MIN;
|
pInfo->firstKey = INT64_MIN;
|
||||||
pInfo->lastKey = INT64_MIN;
|
pInfo->lastKey = INT64_MIN;
|
||||||
pInfo->firstValue = INT64_MIN;
|
pInfo->firstValue = INT64_MIN;
|
||||||
pInfo->lastValue = INT64_MIN;
|
pInfo->lastValue = INT64_MIN;
|
||||||
pInfo->num = 0;
|
|
||||||
pInfo->sum = 0;
|
|
||||||
|
|
||||||
pInfo->hasResult = 0;
|
pInfo->hasResult = 0;
|
||||||
pInfo->isIRate = ((pCtx->functionId == TSDB_FUNC_IRATE) || (pCtx->functionId == TSDB_FUNC_SUM_IRATE) || (pCtx->functionId == TSDB_FUNC_AVG_IRATE));
|
pInfo->isIRate = (pCtx->functionId == TSDB_FUNC_IRATE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4546,26 +4544,22 @@ static void rate_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
|
||||||
int64_t v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, int64_t, pCtx->inputType, pData);
|
GET_TYPED_DATA(v, double, pCtx->inputType, pData);
|
||||||
|
|
||||||
if ((INT64_MIN == pRateInfo->firstValue) || (INT64_MIN == pRateInfo->firstKey)) {
|
if ((INT64_MIN == pRateInfo->firstValue) || (INT64_MIN == pRateInfo->firstKey)) {
|
||||||
pRateInfo->firstValue = v;
|
pRateInfo->firstValue = v;
|
||||||
pRateInfo->firstKey = primaryKey[i];
|
pRateInfo->firstKey = primaryKey[i];
|
||||||
|
|
||||||
qDebug("firstValue:%" PRId64 " firstKey:%" PRId64, pRateInfo->firstValue, pRateInfo->firstKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INT64_MIN == pRateInfo->lastValue) {
|
if (INT64_MIN == pRateInfo->lastValue) {
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
} else if (v < pRateInfo->lastValue) {
|
} else if (v < pRateInfo->lastValue) {
|
||||||
pRateInfo->CorrectionValue += pRateInfo->lastValue;
|
pRateInfo->correctionValue += pRateInfo->lastValue;
|
||||||
qDebug("CorrectionValue:%" PRId64, pRateInfo->CorrectionValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = primaryKey[i];
|
pRateInfo->lastKey = primaryKey[i];
|
||||||
qDebug("lastValue:%" PRId64 " lastKey:%" PRId64, pRateInfo->lastValue, pRateInfo->lastKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pCtx->hasNull) {
|
if (!pCtx->hasNull) {
|
||||||
|
|
@ -4596,8 +4590,8 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
||||||
|
|
||||||
int64_t v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, int64_t, pCtx->inputType, pData);
|
GET_TYPED_DATA(v, double, pCtx->inputType, pData);
|
||||||
|
|
||||||
if ((INT64_MIN == pRateInfo->firstValue) || (INT64_MIN == pRateInfo->firstKey)) {
|
if ((INT64_MIN == pRateInfo->firstValue) || (INT64_MIN == pRateInfo->firstKey)) {
|
||||||
pRateInfo->firstValue = v;
|
pRateInfo->firstValue = v;
|
||||||
|
|
@ -4607,14 +4601,12 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
if (INT64_MIN == pRateInfo->lastValue) {
|
if (INT64_MIN == pRateInfo->lastValue) {
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
} else if (v < pRateInfo->lastValue) {
|
} else if (v < pRateInfo->lastValue) {
|
||||||
pRateInfo->CorrectionValue += pRateInfo->lastValue;
|
pRateInfo->correctionValue += pRateInfo->lastValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = primaryKey[index];
|
pRateInfo->lastKey = primaryKey[index];
|
||||||
|
|
||||||
qDebug("====%p rate_function_f() index:%d lastValue:%" PRId64 " lastKey:%" PRId64 " CorrectionValue:%" PRId64, pCtx, index, pRateInfo->lastValue, pRateInfo->lastKey, pRateInfo->CorrectionValue);
|
|
||||||
|
|
||||||
SET_VAL(pCtx, 1, 1);
|
SET_VAL(pCtx, 1, 1);
|
||||||
|
|
||||||
// set has result flag
|
// set has result flag
|
||||||
|
|
@ -4633,27 +4625,18 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
|
memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
|
||||||
pResInfo->hasResult = ((SRateInfo*)pCtx->pInput)->hasResult;
|
pResInfo->hasResult = ((SRateInfo*)pCtx->pInput)->hasResult;
|
||||||
|
|
||||||
SRateInfo* pRateInfo = (SRateInfo*)pCtx->pInput;
|
|
||||||
qDebug("%p rate_func_merge() firstKey:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " lastValue:%" PRId64 " CorrectionValue:%" PRId64 " hasResult:%d",
|
|
||||||
pCtx, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, pRateInfo->hasResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rate_finalizer(SQLFunctionCtx *pCtx) {
|
static void rate_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
qDebug("%p isIRate:%d firstKey:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " lastValue:%" PRId64 " CorrectionValue:%" PRId64 " hasResult:%d",
|
|
||||||
pCtx, pRateInfo->isIRate, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, pRateInfo->hasResult);
|
|
||||||
|
|
||||||
if (pRateInfo->hasResult != DATA_SET_FLAG) {
|
if (pRateInfo->hasResult != DATA_SET_FLAG) {
|
||||||
setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(double*)pCtx->pOutput = do_calc_rate(pRateInfo);
|
*(double*) pCtx->pOutput = do_calc_rate(pRateInfo, TSDB_TICK_PER_SECOND(pCtx->param[0].i64));
|
||||||
|
|
||||||
qDebug("rate_finalizer() output result:%f", *(double *)pCtx->pOutput);
|
|
||||||
|
|
||||||
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
|
|
@ -4663,44 +4646,32 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void irate_function(SQLFunctionCtx *pCtx) {
|
static void irate_function(SQLFunctionCtx *pCtx) {
|
||||||
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
|
||||||
int32_t notNullElems = 0;
|
int32_t notNullElems = 0;
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
||||||
|
|
||||||
qDebug("%p irate_function() size:%d, hasNull:%d", pCtx, pCtx->size, pCtx->hasNull);
|
|
||||||
|
|
||||||
if (pCtx->size < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = pCtx->size - 1; i >= 0; --i) {
|
for (int32_t i = pCtx->size - 1; i >= 0; --i) {
|
||||||
char *pData = GET_INPUT_DATA(pCtx, i);
|
char *pData = GET_INPUT_DATA(pCtx, i);
|
||||||
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
|
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
|
||||||
qDebug("%p irate_function() index of null data:%d", pCtx, i);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
|
||||||
int64_t v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, int64_t, pCtx->inputType, pData);
|
GET_TYPED_DATA(v, double, pCtx->inputType, pData);
|
||||||
|
|
||||||
// TODO: calc once if only call this function once ????
|
if ((INT64_MIN == pRateInfo->lastKey) || primaryKey[i] > pRateInfo->lastKey) {
|
||||||
if ((INT64_MIN == pRateInfo->lastKey) || (INT64_MIN == pRateInfo->lastValue)) {
|
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = primaryKey[i];
|
pRateInfo->lastKey = primaryKey[i];
|
||||||
|
|
||||||
qDebug("%p irate_function() lastValue:%" PRId64 " lastKey:%" PRId64, pCtx, pRateInfo->lastValue, pRateInfo->lastKey);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((INT64_MIN == pRateInfo->firstKey) || (INT64_MIN == pRateInfo->firstValue)){
|
if ((INT64_MIN == pRateInfo->firstKey) || primaryKey[i] > pRateInfo->firstKey) {
|
||||||
pRateInfo->firstValue = v;
|
pRateInfo->firstValue = v;
|
||||||
pRateInfo->firstKey = primaryKey[i];
|
pRateInfo->firstKey = primaryKey[i];
|
||||||
|
|
||||||
qDebug("%p irate_function() firstValue:%" PRId64 " firstKey:%" PRId64, pCtx, pRateInfo->firstValue, pRateInfo->firstKey);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4729,8 +4700,8 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
TSKEY *primaryKey = GET_TS_LIST(pCtx);
|
||||||
|
|
||||||
int64_t v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, int64_t, pCtx->inputType, pData);
|
GET_TYPED_DATA(v, double, pCtx->inputType, pData);
|
||||||
|
|
||||||
pRateInfo->firstKey = pRateInfo->lastKey;
|
pRateInfo->firstKey = pRateInfo->lastKey;
|
||||||
pRateInfo->firstValue = pRateInfo->lastValue;
|
pRateInfo->firstValue = pRateInfo->lastValue;
|
||||||
|
|
@ -4738,8 +4709,7 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
pRateInfo->lastValue = v;
|
pRateInfo->lastValue = v;
|
||||||
pRateInfo->lastKey = primaryKey[index];
|
pRateInfo->lastKey = primaryKey[index];
|
||||||
|
|
||||||
qDebug("====%p irate_function_f() index:%d lastValue:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " firstKey:%" PRId64, pCtx, index, pRateInfo->lastValue, pRateInfo->lastKey, pRateInfo->firstValue , pRateInfo->firstKey);
|
// qDebug("====%p irate_function_f() index:%d lastValue:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " firstKey:%" PRId64, pCtx, index, pRateInfo->lastValue, pRateInfo->lastKey, pRateInfo->firstValue , pRateInfo->firstKey);
|
||||||
|
|
||||||
SET_VAL(pCtx, 1, 1);
|
SET_VAL(pCtx, 1, 1);
|
||||||
|
|
||||||
// set has result flag
|
// set has result flag
|
||||||
|
|
@ -4752,68 +4722,6 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_sumrate_merge(SQLFunctionCtx *pCtx) {
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
assert(pCtx->stableQuery);
|
|
||||||
|
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
char * input = GET_INPUT_DATA_LIST(pCtx);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i, input += pCtx->inputBytes) {
|
|
||||||
SRateInfo *pInput = (SRateInfo *)input;
|
|
||||||
|
|
||||||
qDebug("%p do_sumrate_merge() hasResult:%d input num:%" PRId64 " input sum:%f total num:%" PRId64 " total sum:%f", pCtx, pInput->hasResult, pInput->num, pInput->sum, pRateInfo->num, pRateInfo->sum);
|
|
||||||
|
|
||||||
if (pInput->hasResult != DATA_SET_FLAG) {
|
|
||||||
continue;
|
|
||||||
} else if (pInput->num == 0) {
|
|
||||||
pRateInfo->sum += do_calc_rate(pInput);
|
|
||||||
pRateInfo->num++;
|
|
||||||
} else {
|
|
||||||
pRateInfo->sum += pInput->sum;
|
|
||||||
pRateInfo->num += pInput->num;
|
|
||||||
}
|
|
||||||
pRateInfo->hasResult = DATA_SET_FLAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the data set hasResult is not set, the result is null
|
|
||||||
if (DATA_SET_FLAG == pRateInfo->hasResult) {
|
|
||||||
pResInfo->hasResult = DATA_SET_FLAG;
|
|
||||||
SET_VAL(pCtx, pRateInfo->num, 1);
|
|
||||||
memcpy(pCtx->pOutput, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sumrate_func_merge(SQLFunctionCtx *pCtx) {
|
|
||||||
qDebug("%p sumrate_func_merge() process ...", pCtx);
|
|
||||||
do_sumrate_merge(pCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sumrate_finalizer(SQLFunctionCtx *pCtx) {
|
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
|
|
||||||
qDebug("%p sumrate_finalizer() superTableQ:%d num:%" PRId64 " sum:%f hasResult:%d", pCtx, pCtx->stableQuery, pRateInfo->num, pRateInfo->sum, pRateInfo->hasResult);
|
|
||||||
|
|
||||||
if (pRateInfo->hasResult != DATA_SET_FLAG) {
|
|
||||||
setNull(pCtx->pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRateInfo->num == 0) {
|
|
||||||
// from meter
|
|
||||||
*(double*)pCtx->pOutput = do_calc_rate(pRateInfo);
|
|
||||||
} else if (pCtx->functionId == TSDB_FUNC_SUM_RATE || pCtx->functionId == TSDB_FUNC_SUM_IRATE) {
|
|
||||||
*(double*)pCtx->pOutput = pRateInfo->sum;
|
|
||||||
} else {
|
|
||||||
*(double*)pCtx->pOutput = pRateInfo->sum / pRateInfo->num;
|
|
||||||
}
|
|
||||||
|
|
||||||
pResInfo->numOfRes = 1;
|
|
||||||
pResInfo->hasResult = DATA_SET_FLAG;
|
|
||||||
doFinalizer(pCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void blockInfo_func(SQLFunctionCtx* pCtx) {
|
void blockInfo_func(SQLFunctionCtx* pCtx) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
@ -4828,51 +4736,81 @@ void blockInfo_func(SQLFunctionCtx* pCtx) {
|
||||||
pResInfo->hasResult = DATA_SET_FLAG;
|
pResInfo->hasResult = DATA_SET_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mergeTableBlockDist(STableBlockDist* pDist, const STableBlockDist* pSrc) {
|
static void mergeTableBlockDist(SResultRowCellInfo* pResInfo, const STableBlockDist* pSrc) {
|
||||||
|
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
assert(pDist != NULL && pSrc != NULL);
|
assert(pDist != NULL && pSrc != NULL);
|
||||||
|
|
||||||
pDist->numOfTables += pSrc->numOfTables;
|
pDist->numOfTables += pSrc->numOfTables;
|
||||||
pDist->numOfRowsInMemTable += pSrc->numOfRowsInMemTable;
|
pDist->numOfRowsInMemTable += pSrc->numOfRowsInMemTable;
|
||||||
pDist->numOfFiles += pSrc->numOfFiles;
|
pDist->numOfFiles += pSrc->numOfFiles;
|
||||||
pDist->totalSize += pSrc->totalSize;
|
pDist->totalSize += pSrc->totalSize;
|
||||||
|
pDist->totalRows += pSrc->totalRows;
|
||||||
|
|
||||||
if (pDist->dataBlockInfos == NULL) {
|
if (pResInfo->hasResult == DATA_SET_FLAG) {
|
||||||
pDist->dataBlockInfos = taosArrayInit(4, sizeof(SFileBlockInfo));
|
pDist->maxRows = MAX(pDist->maxRows, pSrc->maxRows);
|
||||||
|
pDist->minRows = MIN(pDist->minRows, pSrc->minRows);
|
||||||
|
} else {
|
||||||
|
pDist->maxRows = pSrc->maxRows;
|
||||||
|
pDist->minRows = pSrc->minRows;
|
||||||
|
|
||||||
|
int32_t numSteps = tsMaxRowsInFileBlock/TSDB_BLOCK_DIST_STEP_ROWS;
|
||||||
|
pDist->dataBlockInfos = taosArrayInit(numSteps, sizeof(SFileBlockInfo));
|
||||||
|
taosArraySetSize(pDist->dataBlockInfos, numSteps);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayPushBatch(pDist->dataBlockInfos, pSrc->dataBlockInfos->pData, (int32_t) taosArrayGetSize(pSrc->dataBlockInfos));
|
size_t steps = taosArrayGetSize(pDist->dataBlockInfos);
|
||||||
|
for (int32_t i = 0; i < steps; ++i) {
|
||||||
|
int32_t srcNumBlocks = ((SFileBlockInfo*)taosArrayGet(pSrc->dataBlockInfos, i))->numBlocksOfStep;
|
||||||
|
SFileBlockInfo* blockInfo = (SFileBlockInfo*)taosArrayGet(pDist->dataBlockInfos, i);
|
||||||
|
blockInfo->numBlocksOfStep += srcNumBlocks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void block_func_merge(SQLFunctionCtx* pCtx) {
|
void block_func_merge(SQLFunctionCtx* pCtx) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
|
|
||||||
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
STableBlockDist info = {0};
|
STableBlockDist info = {0};
|
||||||
|
|
||||||
int32_t len = *(int32_t*) pCtx->pInput;
|
int32_t len = *(int32_t*) pCtx->pInput;
|
||||||
blockDistInfoFromBinary(((char*)pCtx->pInput) + sizeof(int32_t), len, &info);
|
blockDistInfoFromBinary(((char*)pCtx->pInput) + sizeof(int32_t), len, &info);
|
||||||
|
|
||||||
mergeTableBlockDist(pDist, &info);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
mergeTableBlockDist(pResInfo, &info);
|
||||||
|
|
||||||
|
pResInfo->numOfRes = 1;
|
||||||
|
pResInfo->hasResult = DATA_SET_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doGetPercentile(const SArray* pArray, double rate) {
|
void getPercentiles(STableBlockDist *pTableBlockDist, int64_t totalBlocks, int32_t numOfPercents,
|
||||||
int32_t len = (int32_t)taosArrayGetSize(pArray);
|
double* percents, int32_t* percentiles) {
|
||||||
if (len <= 0) {
|
if (totalBlocks == 0) {
|
||||||
return 0;
|
for (int32_t i = 0; i < numOfPercents; ++i) {
|
||||||
|
percentiles[i] = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rate >= 0 && rate <= 1.0);
|
SArray *blocksInfos = pTableBlockDist->dataBlockInfos;
|
||||||
int idx = (int32_t)((len - 1) * rate);
|
size_t numSteps = taosArrayGetSize(blocksInfos);
|
||||||
|
size_t cumulativeBlocks = 0;
|
||||||
|
|
||||||
return ((SFileBlockInfo *)(taosArrayGet(pArray, idx)))->numOfRows;
|
int percentIndex = 0;
|
||||||
}
|
for (int32_t indexStep = 0; indexStep < numSteps; ++indexStep) {
|
||||||
|
int32_t numStepBlocks = ((SFileBlockInfo *)taosArrayGet(blocksInfos, indexStep))->numBlocksOfStep;
|
||||||
|
if (numStepBlocks == 0) continue;
|
||||||
|
cumulativeBlocks += numStepBlocks;
|
||||||
|
|
||||||
static int compareBlockInfo(const void *pLeft, const void *pRight) {
|
while (percentIndex < numOfPercents) {
|
||||||
int32_t left = ((SFileBlockInfo *)pLeft)->numOfRows;
|
double blockRank = totalBlocks * percents[percentIndex];
|
||||||
int32_t right = ((SFileBlockInfo *)pRight)->numOfRows;
|
if (blockRank <= cumulativeBlocks) {
|
||||||
|
percentiles[percentIndex] = indexStep;
|
||||||
|
++percentIndex;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (left > right) return 1;
|
for (int32_t i = 0; i < numOfPercents; ++i) {
|
||||||
if (left < right) return -1;
|
percentiles[i] = (percentiles[i]+1) * TSDB_BLOCK_DIST_STEP_ROWS - TSDB_BLOCK_DIST_STEP_ROWS/2;
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
|
void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
|
||||||
|
|
@ -4880,40 +4818,41 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t min = INT64_MAX, max = INT64_MIN, avg = 0;
|
SArray* blockInfos = pTableBlockDist->dataBlockInfos;
|
||||||
SArray* blockInfos= pTableBlockDist->dataBlockInfos;
|
uint64_t totalRows = pTableBlockDist->totalRows;
|
||||||
int64_t totalRows = 0, totalBlocks = taosArrayGetSize(blockInfos);
|
size_t numSteps = taosArrayGetSize(blockInfos);
|
||||||
|
int64_t totalBlocks = 0;
|
||||||
|
int64_t min = -1, max = -1, avg = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < taosArrayGetSize(blockInfos); i++) {
|
for (int32_t i = 0; i < numSteps; i++) {
|
||||||
SFileBlockInfo *blockInfo = taosArrayGet(blockInfos, i);
|
SFileBlockInfo *blockInfo = taosArrayGet(blockInfos, i);
|
||||||
int64_t rows = blockInfo->numOfRows;
|
int64_t blocks = blockInfo->numBlocksOfStep;
|
||||||
|
totalBlocks += blocks;
|
||||||
min = MIN(min, rows);
|
|
||||||
max = MAX(max, rows);
|
|
||||||
totalRows += rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
avg = totalBlocks > 0 ? (int64_t)(totalRows/totalBlocks) : 0;
|
avg = totalBlocks > 0 ? (int64_t)(totalRows/totalBlocks) : 0;
|
||||||
taosArraySort(blockInfos, compareBlockInfo);
|
min = totalBlocks > 0 ? pTableBlockDist->minRows : 0;
|
||||||
|
max = totalBlocks > 0 ? pTableBlockDist->maxRows : 0;
|
||||||
|
|
||||||
|
double percents[] = {0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 0.95, 0.99};
|
||||||
|
int32_t percentiles[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||||
|
assert(sizeof(percents)/sizeof(double) == sizeof(percentiles)/sizeof(int32_t));
|
||||||
|
getPercentiles(pTableBlockDist, totalBlocks, sizeof(percents)/sizeof(double), percents, percentiles);
|
||||||
|
|
||||||
uint64_t totalLen = pTableBlockDist->totalSize;
|
uint64_t totalLen = pTableBlockDist->totalSize;
|
||||||
int32_t rowSize = pTableBlockDist->rowSize;
|
int32_t rowSize = pTableBlockDist->rowSize;
|
||||||
|
double compRatio = (totalRows>0) ? ((double)(totalLen)/(rowSize*totalRows)) : 1;
|
||||||
int sz = sprintf(result + VARSTR_HEADER_SIZE,
|
int sz = sprintf(result + VARSTR_HEADER_SIZE,
|
||||||
"summary: \n\t "
|
"summary: \n\t "
|
||||||
"5th=[%d], 10th=[%d], 20th=[%d], 30th=[%d], 40th=[%d], 50th=[%d]\n\t "
|
"5th=[%d], 10th=[%d], 20th=[%d], 30th=[%d], 40th=[%d], 50th=[%d]\n\t "
|
||||||
"60th=[%d], 70th=[%d], 80th=[%d], 90th=[%d], 95th=[%d], 99th=[%d]\n\t "
|
"60th=[%d], 70th=[%d], 80th=[%d], 90th=[%d], 95th=[%d], 99th=[%d]\n\t "
|
||||||
"Min=[%"PRId64"(Rows)] Max=[%"PRId64"(Rows)] Avg=[%"PRId64"(Rows)] Stddev=[%.2f] \n\t "
|
"Min=[%"PRId64"(Rows)] Max=[%"PRId64"(Rows)] Avg=[%"PRId64"(Rows)] Stddev=[%.2f] \n\t "
|
||||||
"Rows=[%"PRId64"], Blocks=[%"PRId64"], Size=[%.3f(Kb)] Comp=[%.2f%%]\n\t "
|
"Rows=[%"PRIu64"], Blocks=[%"PRId64"], Size=[%.3f(Kb)] Comp=[%.2f]\n\t "
|
||||||
"RowsInMem=[%d] \n\t SeekHeaderTime=[%d(us)]",
|
"RowsInMem=[%d] \n\t SeekHeaderTime=[%d(us)]",
|
||||||
doGetPercentile(blockInfos, 0.05), doGetPercentile(blockInfos, 0.10),
|
percentiles[0], percentiles[1], percentiles[2], percentiles[3], percentiles[4], percentiles[5],
|
||||||
doGetPercentile(blockInfos, 0.20), doGetPercentile(blockInfos, 0.30),
|
percentiles[6], percentiles[7], percentiles[8], percentiles[9], percentiles[10], percentiles[11],
|
||||||
doGetPercentile(blockInfos, 0.40), doGetPercentile(blockInfos, 0.50),
|
|
||||||
doGetPercentile(blockInfos, 0.60), doGetPercentile(blockInfos, 0.70),
|
|
||||||
doGetPercentile(blockInfos, 0.80), doGetPercentile(blockInfos, 0.90),
|
|
||||||
doGetPercentile(blockInfos, 0.95), doGetPercentile(blockInfos, 0.99),
|
|
||||||
min, max, avg, 0.0,
|
min, max, avg, 0.0,
|
||||||
totalRows, totalBlocks, totalLen/1024.0, (double)(totalLen*100.0)/(rowSize*totalRows),
|
totalRows, totalBlocks, totalLen/1024.0, compRatio,
|
||||||
pTableBlockDist->numOfRowsInMemTable, pTableBlockDist->firstSeekTimeUs);
|
pTableBlockDist->numOfRowsInMemTable, pTableBlockDist->firstSeekTimeUs);
|
||||||
varDataSetLen(result, sz);
|
varDataSetLen(result, sz);
|
||||||
UNUSED(sz);
|
UNUSED(sz);
|
||||||
|
|
@ -4948,12 +4887,12 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
|
||||||
int32_t functionCompatList[] = {
|
int32_t functionCompatList[] = {
|
||||||
// count, sum, avg, min, max, stddev, percentile, apercentile, first, last
|
// count, sum, avg, min, max, stddev, percentile, apercentile, first, last
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
// last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_z
|
// last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_comp
|
||||||
4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
|
4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
|
||||||
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, interp rate irate
|
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate
|
||||||
1, 1, 1, 1, -1, 1, 1, 5, 1, 1,
|
1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1,
|
||||||
// sum_rate, sum_irate, avg_rate, avg_irate, tid_tag, blk_info
|
// tid_tag, blk_info
|
||||||
1, 1, 1, 1, 6, 7
|
6, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
SAggFunctionInfo aAggs[] = {{
|
SAggFunctionInfo aAggs[] = {{
|
||||||
|
|
@ -5365,58 +5304,6 @@ SAggFunctionInfo aAggs[] = {{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 31
|
// 31
|
||||||
"sum_rate",
|
|
||||||
TSDB_FUNC_SUM_RATE,
|
|
||||||
TSDB_FUNC_SUM_RATE,
|
|
||||||
TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS,
|
|
||||||
rate_function_setup,
|
|
||||||
rate_function,
|
|
||||||
rate_function_f,
|
|
||||||
sumrate_finalizer,
|
|
||||||
sumrate_func_merge,
|
|
||||||
dataBlockRequired,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// 32
|
|
||||||
"sum_irate",
|
|
||||||
TSDB_FUNC_SUM_IRATE,
|
|
||||||
TSDB_FUNC_SUM_IRATE,
|
|
||||||
TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS,
|
|
||||||
rate_function_setup,
|
|
||||||
irate_function,
|
|
||||||
irate_function_f,
|
|
||||||
sumrate_finalizer,
|
|
||||||
sumrate_func_merge,
|
|
||||||
dataBlockRequired,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// 33
|
|
||||||
"avg_rate",
|
|
||||||
TSDB_FUNC_AVG_RATE,
|
|
||||||
TSDB_FUNC_AVG_RATE,
|
|
||||||
TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS,
|
|
||||||
rate_function_setup,
|
|
||||||
rate_function,
|
|
||||||
rate_function_f,
|
|
||||||
sumrate_finalizer,
|
|
||||||
sumrate_func_merge,
|
|
||||||
dataBlockRequired,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// 34
|
|
||||||
"avg_irate",
|
|
||||||
TSDB_FUNC_AVG_IRATE,
|
|
||||||
TSDB_FUNC_AVG_IRATE,
|
|
||||||
TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS,
|
|
||||||
rate_function_setup,
|
|
||||||
irate_function,
|
|
||||||
irate_function_f,
|
|
||||||
sumrate_finalizer,
|
|
||||||
sumrate_func_merge,
|
|
||||||
dataBlockRequired,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// 35
|
|
||||||
"tbid", // return table id and the corresponding tags for join match and subscribe
|
"tbid", // return table id and the corresponding tags for join match and subscribe
|
||||||
TSDB_FUNC_TID_TAG,
|
TSDB_FUNC_TID_TAG,
|
||||||
TSDB_FUNC_TID_TAG,
|
TSDB_FUNC_TID_TAG,
|
||||||
|
|
@ -5429,7 +5316,7 @@ SAggFunctionInfo aAggs[] = {{
|
||||||
dataBlockRequired,
|
dataBlockRequired,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 35
|
// 32
|
||||||
"_block_dist", // return table id and the corresponding tags for join match and subscribe
|
"_block_dist", // return table id and the corresponding tags for join match and subscribe
|
||||||
TSDB_FUNC_BLKINFO,
|
TSDB_FUNC_BLKINFO,
|
||||||
TSDB_FUNC_BLKINFO,
|
TSDB_FUNC_BLKINFO,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -363,10 +363,6 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3
|
||||||
pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc);
|
pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc);
|
||||||
assert(pFillInfo->rowSize > 0);
|
assert(pFillInfo->rowSize > 0);
|
||||||
|
|
||||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
|
||||||
pFillInfo->pData[i] = malloc(pFillInfo->pFillCol[i].col.bytes * pFillInfo->alloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pFillInfo;
|
return pFillInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -392,10 +388,6 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) {
|
||||||
tfree(pFillInfo->pTags[i].tagVal);
|
tfree(pFillInfo->pTags[i].tagVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
|
||||||
tfree(pFillInfo->pData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
tfree(pFillInfo->pTags);
|
tfree(pFillInfo->pTags);
|
||||||
|
|
||||||
tfree(pFillInfo->pData);
|
tfree(pFillInfo->pData);
|
||||||
|
|
@ -417,17 +409,6 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
||||||
|
|
||||||
pFillInfo->index = 0;
|
pFillInfo->index = 0;
|
||||||
pFillInfo->numOfRows = numOfRows;
|
pFillInfo->numOfRows = numOfRows;
|
||||||
|
|
||||||
// ensure the space
|
|
||||||
if (pFillInfo->alloc < numOfRows) {
|
|
||||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
|
||||||
char* tmp = realloc(pFillInfo->pData[i], numOfRows*pFillInfo->pFillCol[i].col.bytes);
|
|
||||||
assert(tmp != NULL); // todo handle error
|
|
||||||
|
|
||||||
memset(tmp, 0, numOfRows*pFillInfo->pFillCol[i].col.bytes);
|
|
||||||
pFillInfo->pData[i] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) {
|
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) {
|
||||||
|
|
@ -435,16 +416,7 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput)
|
||||||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
||||||
|
|
||||||
SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i);
|
SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i);
|
||||||
// pFillInfo->pData[i] = pColData->pData;
|
pFillInfo->pData[i] = pColData->pData;
|
||||||
if (pInput->info.rows > pFillInfo->alloc) {
|
|
||||||
char* t = realloc(pFillInfo->pData[i], pColData->info.bytes * pInput->info.rows);
|
|
||||||
assert(t != NULL);
|
|
||||||
|
|
||||||
pFillInfo->pData[i] = t;
|
|
||||||
pFillInfo->alloc = pInput->info.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pFillInfo->pData[i], pColData->pData, pColData->info.bytes * pInput->info.rows);
|
|
||||||
|
|
||||||
if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer
|
if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer
|
||||||
SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex];
|
SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex];
|
||||||
|
|
@ -454,31 +426,6 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* pInput) {
|
|
||||||
assert(pFillInfo->numOfRows == pInput->num);
|
|
||||||
|
|
||||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
|
||||||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
|
||||||
|
|
||||||
const char* data = pInput->data + pCol->col.offset * pInput->num;
|
|
||||||
if (pInput->num > pFillInfo->alloc) {
|
|
||||||
char* t = realloc(pFillInfo->pData[i], (size_t)(pCol->col.bytes * pInput->num));
|
|
||||||
assert(t != NULL);
|
|
||||||
|
|
||||||
pFillInfo->pData[i] = t;
|
|
||||||
pFillInfo->alloc = (int32_t)pInput->num;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pFillInfo->pData[i], data, (size_t)(pCol->col.bytes * pInput->num));
|
|
||||||
|
|
||||||
if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer
|
|
||||||
SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex];
|
|
||||||
assert (pTag->col.colId == pCol->col.colId);
|
|
||||||
memcpy(pTag->tagVal, data, pCol->col.bytes); // TODO not memcpy??
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
|
bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
|
||||||
int32_t remain = taosNumOfRemainRows(pFillInfo);
|
int32_t remain = taosNumOfRemainRows(pFillInfo);
|
||||||
if (remain > 0) {
|
if (remain > 0) {
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,521 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tsclient.h"
|
#include "qTableMeta.h"
|
||||||
|
#include "qPlan.h"
|
||||||
|
#include "qExecutor.h"
|
||||||
#include "qUtil.h"
|
#include "qUtil.h"
|
||||||
#include "texpr.h"
|
#include "texpr.h"
|
||||||
|
#include "tscUtil.h"
|
||||||
|
#include "tsclient.h"
|
||||||
|
|
||||||
#define QNODE_PROJECT 1
|
#define QNODE_TAGSCAN 1
|
||||||
#define QNODE_FILTER 2
|
#define QNODE_TABLESCAN 2
|
||||||
#define QNODE_RELATION 3
|
#define QNODE_PROJECT 3
|
||||||
#define QNODE_AGGREGATE 4
|
#define QNODE_AGGREGATE 4
|
||||||
#define QNODE_GROUPBY 5
|
#define QNODE_GROUPBY 5
|
||||||
#define QNODE_LIMIT 6
|
#define QNODE_LIMIT 6
|
||||||
#define QNODE_JOIN 7
|
#define QNODE_JOIN 7
|
||||||
#define QNODE_DIST 8
|
#define QNODE_DISTINCT 8
|
||||||
#define QNODE_SORT 9
|
#define QNODE_SORT 9
|
||||||
#define QNODE_UNIONALL 10
|
#define QNODE_UNIONALL 10
|
||||||
#define QNODE_TIMEWINDOW 11
|
#define QNODE_TIMEWINDOW 11
|
||||||
|
#define QNODE_SESSIONWINDOW 12
|
||||||
|
#define QNODE_FILL 13
|
||||||
|
|
||||||
typedef struct SQueryNode {
|
typedef struct SFillEssInfo {
|
||||||
int32_t type; // the type of logic node
|
int32_t fillType; // fill type
|
||||||
char *name; // the name of logic node
|
int64_t *val; // fill value
|
||||||
|
} SFillEssInfo;
|
||||||
|
|
||||||
SSchema *pSchema; // the schema of the input SSDatablock
|
typedef struct SJoinCond {
|
||||||
int32_t numOfCols; // number of input columns
|
bool tagExists; // denote if tag condition exists or not
|
||||||
SExprInfo *pExpr; // the query functions or sql aggregations
|
SColumn *tagCond[2];
|
||||||
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
SColumn *colCond[2];
|
||||||
|
} SJoinCond;
|
||||||
|
|
||||||
// previous operator to generated result for current node to process
|
static SQueryNode* createQueryNode(int32_t type, const char* name, SQueryNode** prev,
|
||||||
// in case of join, multiple prev nodes exist.
|
int32_t numOfPrev, SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo,
|
||||||
struct SQueryNode* prevNode;
|
void* pExtInfo) {
|
||||||
struct SQueryNode* nextNode;
|
SQueryNode* pNode = calloc(1, sizeof(SQueryNode));
|
||||||
} SQueryNode;
|
|
||||||
|
pNode->info.type = type;
|
||||||
|
pNode->info.name = strdup(name);
|
||||||
|
|
||||||
|
if (pTableInfo->id.uid != 0) { // it is a true table
|
||||||
|
pNode->tableInfo.id = pTableInfo->id;
|
||||||
|
pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode->numOfOutput = numOfOutput;
|
||||||
|
pNode->pExpr = calloc(numOfOutput, sizeof(SExprInfo));
|
||||||
|
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
tscExprAssign(&pNode->pExpr[i], pExpr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
for(int32_t i = 0; i < numOfPrev; ++i) {
|
||||||
|
taosArrayPush(pNode->pPrevNodes, &prev[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case QNODE_TABLESCAN: {
|
||||||
|
STimeWindow* window = calloc(1, sizeof(STimeWindow));
|
||||||
|
memcpy(window, pExtInfo, sizeof(STimeWindow));
|
||||||
|
pNode->pExtInfo = window;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_TIMEWINDOW: {
|
||||||
|
SInterval* pInterval = calloc(1, sizeof(SInterval));
|
||||||
|
pNode->pExtInfo = pInterval;
|
||||||
|
memcpy(pInterval, pExtInfo, sizeof(SInterval));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_GROUPBY: {
|
||||||
|
SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo;
|
||||||
|
SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
|
||||||
|
|
||||||
|
pGroupbyExpr->tableIndex = p->tableIndex;
|
||||||
|
pGroupbyExpr->orderType = p->orderType;
|
||||||
|
pGroupbyExpr->orderIndex = p->orderIndex;
|
||||||
|
pGroupbyExpr->numOfGroupCols = p->numOfGroupCols;
|
||||||
|
pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo);
|
||||||
|
pNode->pExtInfo = pGroupbyExpr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_FILL: { // todo !!
|
||||||
|
pNode->pExtInfo = pExtInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_LIMIT: {
|
||||||
|
pNode->pExtInfo = calloc(1, sizeof(SLimitVal));
|
||||||
|
memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimitVal));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info,
|
||||||
|
SArray* pExprs, SArray* tableCols) {
|
||||||
|
if (pQueryInfo->onlyTagQuery) {
|
||||||
|
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||||
|
SQueryNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL);
|
||||||
|
|
||||||
|
if (pQueryInfo->distinctTag) {
|
||||||
|
pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
STimeWindow* window = &pQueryInfo->window;
|
||||||
|
SQueryNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0,
|
||||||
|
info, window);
|
||||||
|
if (pQueryInfo->projectionQuery) {
|
||||||
|
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||||
|
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||||
|
} else {
|
||||||
|
// table source column projection, generate the projection expr
|
||||||
|
int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols);
|
||||||
|
SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES);
|
||||||
|
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumn* pCol = taosArrayGetP(tableCols, i);
|
||||||
|
|
||||||
|
SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex};
|
||||||
|
SExprInfo* p = tscExprCreate(pQueryInfo, TSDB_FUNC_PRJ, &index, pCol->info.type, pCol->info.bytes,
|
||||||
|
pCol->info.colId, 0, TSDB_COL_NORMAL);
|
||||||
|
strncpy(p->base.aliasName, pSchema[pCol->columnIndex].name, tListLen(p->base.aliasName));
|
||||||
|
|
||||||
|
pExpr[i] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, info, NULL);
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
destroyQueryFuncExpr(pExpr[i], 1);
|
||||||
|
}
|
||||||
|
tfree(pExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SQueryNode* doCreateQueryPlanForOneTableImpl(SQueryInfo* pQueryInfo, SQueryNode* pNode, SQueryTableInfo* info,
|
||||||
|
SArray* pExprs) {
|
||||||
|
// check for aggregation
|
||||||
|
if (pQueryInfo->interval.interval > 0) {
|
||||||
|
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||||
|
|
||||||
|
pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||||
|
&pQueryInfo->interval);
|
||||||
|
} else if (pQueryInfo->groupbyColumn) {
|
||||||
|
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||||
|
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||||
|
&pQueryInfo->groupbyExpr);
|
||||||
|
} else if (pQueryInfo->sessionWindow.gap > 0) {
|
||||||
|
pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, NULL, 0, info, NULL);
|
||||||
|
} else if (pQueryInfo->simpleAgg) {
|
||||||
|
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||||
|
pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->havingFieldNum > 0 || pQueryInfo->arithmeticOnAgg) {
|
||||||
|
int32_t numOfExpr = (int32_t) taosArrayGetSize(pQueryInfo->exprList1);
|
||||||
|
pNode =
|
||||||
|
createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||||
|
SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo));
|
||||||
|
pInfo->fillType = pQueryInfo->fillType;
|
||||||
|
pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t));
|
||||||
|
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput);
|
||||||
|
|
||||||
|
pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) {
|
||||||
|
pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, info, &pQueryInfo->limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SQueryNode* doCreateQueryPlanForOneTable(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||||
|
SArray* tableCols) {
|
||||||
|
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||||
|
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||||
|
|
||||||
|
SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,};
|
||||||
|
|
||||||
|
// handle the only tag query
|
||||||
|
SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols);
|
||||||
|
if (pQueryInfo->onlyTagQuery) {
|
||||||
|
tfree(info.tableName);
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryNode* pNode1 = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pExprs);
|
||||||
|
tfree(info.tableName);
|
||||||
|
return pNode1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
||||||
|
SArray* upstream = NULL;
|
||||||
|
|
||||||
|
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause
|
||||||
|
upstream = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
|
||||||
|
size_t size = taosArrayGetSize(pQueryInfo->pUpstream);
|
||||||
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
|
SQueryInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i);
|
||||||
|
SArray* p = createQueryPlanImpl(pq);
|
||||||
|
taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->numOfTables > 1) { // it is a join query
|
||||||
|
// 1. separate the select clause according to table
|
||||||
|
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||||
|
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i];
|
||||||
|
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||||
|
|
||||||
|
SArray* exprList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
if (tscExprCopy(exprList, pQueryInfo->exprList, uid, true) != 0) {
|
||||||
|
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. create the query execution node
|
||||||
|
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||||
|
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||||
|
SQueryTableInfo info = {.tableName = strdup(name), .id = pTableMetaInfo->pTableMeta->id,};
|
||||||
|
|
||||||
|
// 3. get the required table column list
|
||||||
|
SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn));
|
||||||
|
tscColumnListCopy(tableColumnList, pQueryInfo->colList, uid);
|
||||||
|
|
||||||
|
// 4. add the projection query node
|
||||||
|
SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList);
|
||||||
|
taosArrayPush(upstream, &pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. add the join node here
|
||||||
|
SQueryTableInfo info = {0};
|
||||||
|
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||||
|
SQueryNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables,
|
||||||
|
pQueryInfo->exprList->pData, num, &info, NULL);
|
||||||
|
|
||||||
|
// 4. add the aggregation or projection execution node
|
||||||
|
pNode = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pQueryInfo->exprList);
|
||||||
|
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||||
|
taosArrayPush(upstream, &pNode);
|
||||||
|
} else { // only one table, normal query process
|
||||||
|
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||||
|
SQueryNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||||
|
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||||
|
taosArrayPush(upstream, &pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return upstream;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO create the query plan
|
|
||||||
SQueryNode* qCreateQueryPlan(SQueryInfo* pQueryInfo) {
|
SQueryNode* qCreateQueryPlan(SQueryInfo* pQueryInfo) {
|
||||||
|
SArray* upstream = createQueryPlanImpl(pQueryInfo);
|
||||||
|
assert(taosArrayGetSize(upstream) == 1);
|
||||||
|
|
||||||
|
SQueryNode* p = taosArrayGetP(upstream, 0);
|
||||||
|
taosArrayDestroy(upstream);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doDestroyQueryNode(SQueryNode* pQueryNode) {
|
||||||
|
tfree(pQueryNode->pExtInfo);
|
||||||
|
tfree(pQueryNode->pSchema);
|
||||||
|
tfree(pQueryNode->info.name);
|
||||||
|
|
||||||
|
tfree(pQueryNode->tableInfo.tableName);
|
||||||
|
|
||||||
|
pQueryNode->pExpr = destroyQueryFuncExpr(pQueryNode->pExpr, pQueryNode->numOfOutput);
|
||||||
|
|
||||||
|
if (pQueryNode->pPrevNodes != NULL) {
|
||||||
|
int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes);
|
||||||
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
|
SQueryNode* p = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||||
|
doDestroyQueryNode(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayDestroy(pQueryNode->pPrevNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
tfree(pQueryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* qDestroyQueryPlan(SQueryNode* pQueryNode) {
|
||||||
|
if (pQueryNode == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
doDestroyQueryNode(pQueryNode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* queryPlanToString() {
|
bool hasAliasName(SExprInfo* pExpr) {
|
||||||
return NULL;
|
assert(pExpr != NULL);
|
||||||
|
return strncmp(pExpr->base.token, pExpr->base.aliasName, tListLen(pExpr->base.aliasName)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t doPrintPlan(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||||
|
if (level > 0) {
|
||||||
|
sprintf(buf + totalLen, "%*c", level, ' ');
|
||||||
|
totalLen += level;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name);
|
||||||
|
int32_t len = len1 + totalLen;
|
||||||
|
|
||||||
|
switch(pQueryNode->info.type) {
|
||||||
|
case QNODE_TABLESCAN: {
|
||||||
|
STimeWindow* win = (STimeWindow*)pQueryNode->pExtInfo;
|
||||||
|
len1 = sprintf(buf + len, "%s #0x%" PRIx64 ") time_range: %" PRId64 " - %" PRId64 "\n",
|
||||||
|
pQueryNode->tableInfo.tableName, pQueryNode->tableInfo.id.uid, win->skey, win->ekey);
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_PROJECT: {
|
||||||
|
len1 = sprintf(buf + len, "cols: ");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
SSqlExpr* p = &pQueryNode->pExpr[i].base;
|
||||||
|
len1 = sprintf(buf + len, "[%s #%d]", p->aliasName, p->resColId);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len, ", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len, ")");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
//todo print filter info
|
||||||
|
len1 = sprintf(buf + len, " filters:(nil)\n");
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_AGGREGATE: {
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||||
|
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||||
|
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||||
|
} else {
|
||||||
|
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += len1;
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len, ", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len, ")\n");
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_TIMEWINDOW: {
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||||
|
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||||
|
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||||
|
} else {
|
||||||
|
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += len1;
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len,", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len,") ");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
SInterval* pInterval = pQueryNode->pExtInfo;
|
||||||
|
len1 = sprintf(buf + len, "interval:%" PRId64 "(%c), sliding:%" PRId64 "(%c), offset:%" PRId64 "\n",
|
||||||
|
pInterval->interval, pInterval->intervalUnit, pInterval->sliding, pInterval->slidingUnit,
|
||||||
|
pInterval->offset);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_GROUPBY: { // todo hide the invisible column
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
SSqlExpr* pExpr = &pQueryNode->pExpr[i].base;
|
||||||
|
|
||||||
|
if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||||
|
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->aliasName);
|
||||||
|
} else {
|
||||||
|
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||||
|
}
|
||||||
|
|
||||||
|
len += len1;
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len,", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo;
|
||||||
|
SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, 0);
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len,") groupby_col: [%s #%d]\n", pIndex->name, pIndex->colId);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_FILL: {
|
||||||
|
SFillEssInfo* pEssInfo = pQueryNode->pExtInfo;
|
||||||
|
len1 = sprintf(buf + len,"%d", pEssInfo->fillType);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) {
|
||||||
|
len1 = sprintf(buf + len,", val:");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
// todo get the correct fill data type
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len,", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len,")\n");
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_LIMIT: {
|
||||||
|
SLimitVal* pVal = pQueryNode->pExtInfo;
|
||||||
|
len1 = sprintf(buf + len,"limit: %"PRId64", offset: %"PRId64")\n", pVal->limit, pVal->offset);
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_DISTINCT:
|
||||||
|
case QNODE_TAGSCAN: {
|
||||||
|
len1 = sprintf(buf + len,"cols: ");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||||
|
SSqlExpr* p = &pQueryNode->pExpr[i].base;
|
||||||
|
len1 = sprintf(buf + len,"[%s #%d]", p->aliasName, p->resColId);
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
if (i < pQueryNode->numOfOutput - 1) {
|
||||||
|
len1 = sprintf(buf + len,", ");
|
||||||
|
len += len1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len1 = sprintf(buf + len,")\n");
|
||||||
|
len += len1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QNODE_JOIN: {
|
||||||
|
// print join condition
|
||||||
|
len1 = sprintf(buf + len, ")\n");
|
||||||
|
len += len1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t queryPlanToStringImpl(char* buf, SQueryNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||||
|
int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pPrevNodes); ++i) {
|
||||||
|
SQueryNode* p1 = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||||
|
int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len);
|
||||||
|
len = len1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* queryPlanToString(SQueryNode* pQueryNode) {
|
||||||
|
assert(pQueryNode);
|
||||||
|
|
||||||
|
char* buf = calloc(1, 4096);
|
||||||
|
|
||||||
|
int32_t len = sprintf(buf, "===== logic plan =====\n");
|
||||||
|
queryPlanToStringImpl(buf, pQueryNode, 0, len);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryNode* queryPlanFromString() {
|
SQueryNode* queryPlanFromString() {
|
||||||
|
|
@ -113,6 +592,14 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
||||||
op = OP_SessionWindow;
|
op = OP_SessionWindow;
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
|
|
||||||
|
if (pQueryAttr->pExpr2 != NULL) {
|
||||||
|
op = OP_Arithmetic;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
}
|
||||||
|
} else if (pQueryAttr->stateWindow) {
|
||||||
|
op = OP_StateWindow;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
|
||||||
if (pQueryAttr->pExpr2 != NULL) {
|
if (pQueryAttr->pExpr2 != NULL) {
|
||||||
op = OP_Arithmetic;
|
op = OP_Arithmetic;
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
|
|
@ -136,9 +623,14 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
}
|
}
|
||||||
} else { // diff/add/multiply/subtract/division
|
} else { // diff/add/multiply/subtract/division
|
||||||
|
if (pQueryAttr->numOfFilterCols > 0 && pQueryAttr->vgId == 0) { // todo refactor
|
||||||
|
op = OP_Filter;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
} else {
|
||||||
op = OP_Arithmetic;
|
op = OP_Arithmetic;
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) {
|
if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) {
|
||||||
op = OP_Limit;
|
op = OP_Limit;
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,6 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) {
|
||||||
pExpr->flags &= ~(1 << EXPR_FLAG_TS_ERROR);
|
pExpr->flags &= ~(1 << EXPR_FLAG_TS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (optrType) {
|
switch (optrType) {
|
||||||
case TK_PLUS: {
|
case TK_PLUS: {
|
||||||
pExpr->value.i64 = pLeft->value.i64 + pRight->value.i64;
|
pExpr->value.i64 = pLeft->value.i64 + pRight->value.i64;
|
||||||
|
|
@ -325,7 +324,6 @@ static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right)
|
||||||
return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1;
|
return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
||||||
if ((left == NULL && right) || (left && right == NULL)) {
|
if ((left == NULL && right) || (left && right == NULL)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -389,8 +387,6 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) {
|
tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) {
|
||||||
tSqlExpr *pExpr = calloc(1, sizeof(tSqlExpr));
|
tSqlExpr *pExpr = calloc(1, sizeof(tSqlExpr));
|
||||||
|
|
||||||
|
|
@ -536,11 +532,11 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
||||||
SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) {
|
SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) {
|
||||||
if (pRelationInfo == NULL) {
|
if (pRelationInfo == NULL) {
|
||||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||||
pRelationInfo->list = taosArrayInit(4, sizeof(STableNamePair));
|
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||||
}
|
}
|
||||||
|
|
||||||
pRelationInfo->type = SQL_NODE_FROM_TABLELIST;
|
pRelationInfo->type = SQL_NODE_FROM_TABLELIST;
|
||||||
STableNamePair p = {.name = *pName};
|
SRelElementPair p = {.tableName = *pName};
|
||||||
if (pAlias != NULL) {
|
if (pAlias != NULL) {
|
||||||
p.aliasName = *pAlias;
|
p.aliasName = *pAlias;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -551,18 +547,6 @@ SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName,
|
||||||
return pRelationInfo;
|
return pRelationInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRelationInfo* setSubquery(SRelationInfo* pRelationInfo, SArray* pList) {
|
|
||||||
if (pRelationInfo == NULL) {
|
|
||||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
|
||||||
pRelationInfo->list = taosArrayInit(4, POINTER_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
|
||||||
taosArrayPush(pRelationInfo->list, &pList);
|
|
||||||
|
|
||||||
return pRelationInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
||||||
if (pRelationInfo == NULL) {
|
if (pRelationInfo == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -573,7 +557,7 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
||||||
} else {
|
} else {
|
||||||
size_t size = taosArrayGetSize(pRelationInfo->list);
|
size_t size = taosArrayGetSize(pRelationInfo->list);
|
||||||
for(int32_t i = 0; i < size; ++i) {
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
SArray* pa = taosArrayGetP(pRelationInfo->list, 0);
|
SArray* pa = taosArrayGetP(pRelationInfo->list, i);
|
||||||
destroyAllSqlNode(pa);
|
destroyAllSqlNode(pa);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(pRelationInfo->list);
|
taosArrayDestroy(pRelationInfo->list);
|
||||||
|
|
@ -583,6 +567,24 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias) {
|
||||||
|
if (pRelationInfo == NULL) {
|
||||||
|
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||||
|
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||||
|
}
|
||||||
|
|
||||||
|
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
||||||
|
|
||||||
|
SRelElementPair p = {.pSubquery = pSub};
|
||||||
|
if (pAlias != NULL) {
|
||||||
|
p.aliasName = *pAlias;
|
||||||
|
} else {
|
||||||
|
TPARSER_SET_NONE_TOKEN(p.aliasName);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(pRelationInfo->list, &p);
|
||||||
|
return pRelationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
void tSetDbName(SStrToken *pCpxName, SStrToken *pDb) {
|
void tSetDbName(SStrToken *pCpxName, SStrToken *pDb) {
|
||||||
pCpxName->type = pDb->type;
|
pCpxName->type = pDb->type;
|
||||||
|
|
@ -725,7 +727,7 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
||||||
*/
|
*/
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||||
SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
SSessionWindowVal *pSession, SWindowStateVal *pWindowStateVal, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
||||||
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
||||||
assert(pSelNodeList != NULL);
|
assert(pSelNodeList != NULL);
|
||||||
|
|
||||||
|
|
@ -777,6 +779,12 @@ SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelat
|
||||||
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pWindowStateVal != NULL) {
|
||||||
|
pSqlNode->windowstateVal = *pWindowStateVal;
|
||||||
|
} else {
|
||||||
|
TPARSER_SET_NONE_TOKEN(pSqlNode->windowstateVal.col);
|
||||||
|
}
|
||||||
|
|
||||||
return pSqlNode;
|
return pSqlNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -885,7 +893,7 @@ SAlterTableInfo *tSetAlterTableInfo(SStrToken *pTableName, SArray *pCols, SArray
|
||||||
pAlterTable->type = type;
|
pAlterTable->type = type;
|
||||||
pAlterTable->tableType = tableType;
|
pAlterTable->tableType = tableType;
|
||||||
|
|
||||||
if (type == TSDB_ALTER_TABLE_ADD_COLUMN || type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) {
|
if (type == TSDB_ALTER_TABLE_ADD_COLUMN || type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN || type == TSDB_ALTER_TABLE_CHANGE_COLUMN || type == TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN) {
|
||||||
pAlterTable->pAddColumns = pCols;
|
pAlterTable->pAddColumns = pCols;
|
||||||
assert(pVals == NULL);
|
assert(pVals == NULL);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,10 @@
|
||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tschemautil.h"
|
#include "qTableMeta.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "tsclient.h"
|
|
||||||
|
|
||||||
int32_t tscGetNumOfTags(const STableMeta* pTableMeta) {
|
int32_t tscGetNumOfTags(const STableMeta* pTableMeta) {
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
|
|
@ -120,58 +105,3 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
||||||
return pTableMeta;
|
return pTableMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src) {
|
|
||||||
assert(pExisted != NULL && src != NULL);
|
|
||||||
if (pExisted->numOfEps != src->numOfEps) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int32_t i = 0; i < pExisted->numOfEps; ++i) {
|
|
||||||
if (pExisted->ep[i].port != src->epAddr[i].port) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(pExisted->ep[i].fqdn, src->epAddr[i].fqdn, tListLen(pExisted->ep[i].fqdn)) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) {
|
|
||||||
assert(pVgroupMsg != NULL);
|
|
||||||
|
|
||||||
SNewVgroupInfo info = {0};
|
|
||||||
info.numOfEps = pVgroupMsg->numOfEps;
|
|
||||||
info.vgId = pVgroupMsg->vgId;
|
|
||||||
info.inUse = 0; // 0 is the default value of inUse in case of multiple replica
|
|
||||||
|
|
||||||
assert(info.numOfEps >= 1 && info.vgId >= 1);
|
|
||||||
for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) {
|
|
||||||
tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
|
||||||
info.ep[i].port = pVgroupMsg->epAddr[i].port;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo refactor
|
|
||||||
UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
|
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
|
||||||
while (*input != 0 && *input++ != delim) {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNUSED_FUNC static FORCE_INLINE size_t copy(char* dst, const char* src, char delimiter) {
|
|
||||||
size_t len = 0;
|
|
||||||
while (*src != delimiter && *src != 0) {
|
|
||||||
*dst++ = *src++;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -581,6 +581,9 @@ void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
||||||
tbufWriteUint32(bw, pDist->numOfTables);
|
tbufWriteUint32(bw, pDist->numOfTables);
|
||||||
tbufWriteUint16(bw, pDist->numOfFiles);
|
tbufWriteUint16(bw, pDist->numOfFiles);
|
||||||
tbufWriteUint64(bw, pDist->totalSize);
|
tbufWriteUint64(bw, pDist->totalSize);
|
||||||
|
tbufWriteUint64(bw, pDist->totalRows);
|
||||||
|
tbufWriteInt32(bw, pDist->maxRows);
|
||||||
|
tbufWriteInt32(bw, pDist->minRows);
|
||||||
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
||||||
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
||||||
|
|
||||||
|
|
@ -616,13 +619,16 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi
|
||||||
pDist->numOfTables = tbufReadUint32(&br);
|
pDist->numOfTables = tbufReadUint32(&br);
|
||||||
pDist->numOfFiles = tbufReadUint16(&br);
|
pDist->numOfFiles = tbufReadUint16(&br);
|
||||||
pDist->totalSize = tbufReadUint64(&br);
|
pDist->totalSize = tbufReadUint64(&br);
|
||||||
|
pDist->totalRows = tbufReadUint64(&br);
|
||||||
|
pDist->maxRows = tbufReadInt32(&br);
|
||||||
|
pDist->minRows = tbufReadInt32(&br);
|
||||||
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
||||||
int64_t numOfBlocks = tbufReadUint64(&br);
|
int64_t numSteps = tbufReadUint64(&br);
|
||||||
|
|
||||||
bool comp = tbufReadUint8(&br);
|
bool comp = tbufReadUint8(&br);
|
||||||
uint32_t compLen = tbufReadUint32(&br);
|
uint32_t compLen = tbufReadUint32(&br);
|
||||||
|
|
||||||
size_t originalLen = (size_t) (numOfBlocks*sizeof(SFileBlockInfo));
|
size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
|
||||||
|
|
||||||
char* outputBuf = NULL;
|
char* outputBuf = NULL;
|
||||||
if (comp) {
|
if (comp) {
|
||||||
|
|
@ -633,12 +639,12 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi
|
||||||
|
|
||||||
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
||||||
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
||||||
assert(orignalLen == numOfBlocks*sizeof(SFileBlockInfo));
|
assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
|
||||||
} else {
|
} else {
|
||||||
outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t) numOfBlocks, sizeof(SFileBlockInfo));
|
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
|
||||||
if (comp) {
|
if (comp) {
|
||||||
tfree(outputBuf);
|
tfree(outputBuf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3137
src/query/src/sql.c
3137
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
|
@ -99,47 +99,47 @@ TEST(testCase, db_table_name) {
|
||||||
EXPECT_EQ(testValidateName(t4), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t4), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
char t5[] = "table.'def'";
|
char t5[] = "table.'def'";
|
||||||
EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t5), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t6[] = "'table'.'def'";
|
char t6[] = "'table'.'def'";
|
||||||
EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t6), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t7[] = "'_ab1234'.'def'";
|
char t7[] = "'_ab1234'.'def'";
|
||||||
EXPECT_EQ(testValidateName(t7), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t7), TSDB_CODE_SUCCESS);
|
||||||
printf("%s\n", t7);
|
printf("%s\n", t7);
|
||||||
|
|
||||||
char t8[] = "'_ab&^%1234'.'def'";
|
char t8[] = "'_ab&^%1234'.'def'";
|
||||||
EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t8), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t9[] = "'_123'.'gtest中文'";
|
char t9[] = "'_123'.'gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t9), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t10[] = "abc.'gtest中文'";
|
char t10[] = "abc.'gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t10), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t10_1[] = "abc.'中文gtest'";
|
char t10_1[] = "abc.'中文gtest'";
|
||||||
EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t10_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t11[] = "'192.168.0.1'.abc";
|
char t11[] = "'192.168.0.1'.abc";
|
||||||
EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t11), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t12[] = "192.168.0.1.abc";
|
char t12[] = "192.168.0.1.abc";
|
||||||
EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t12), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t13[] = "abc.";
|
char t13[] = "abc.";
|
||||||
EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t13), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t14[] = ".abc";
|
char t14[] = ".abc";
|
||||||
EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t14), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t15[] = ".'abc'";
|
char t15[] = ".'abc'";
|
||||||
EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t15), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t16[] = ".abc'";
|
char t16[] = ".abc'";
|
||||||
EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t16), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t17[] = "123a.\"abc\"";
|
char t17[] = "123a.\"abc\"";
|
||||||
EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t17), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
printf("%s\n", t17);
|
printf("%s\n", t17);
|
||||||
|
|
||||||
char t18[] = "a.\"abc\"";
|
char t18[] = "a.\"abc\"";
|
||||||
|
|
@ -147,13 +147,13 @@ TEST(testCase, db_table_name) {
|
||||||
printf("%s\n", t18);
|
printf("%s\n", t18);
|
||||||
|
|
||||||
char t19[] = "'_ab1234'.'def'.'ab123'";
|
char t19[] = "'_ab1234'.'def'.'ab123'";
|
||||||
EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t19), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t20[] = "'_ab1234*&^'";
|
char t20[] = "'_ab1234*&^'";
|
||||||
EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t20), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t21[] = "'1234_abc'";
|
char t21[] = "'1234_abc'";
|
||||||
EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t21), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
|
|
||||||
// =======Containing capital letters=================
|
// =======Containing capital letters=================
|
||||||
|
|
@ -167,10 +167,10 @@ TEST(testCase, db_table_name) {
|
||||||
EXPECT_EQ(testValidateName(t32), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t32), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
char t33[] = "'ABC.def";
|
char t33[] = "'ABC.def";
|
||||||
EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t33), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t33_0[] = "abc.DEF'";
|
char t33_0[] = "abc.DEF'";
|
||||||
EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t33_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t34[] = "'ABC.def'";
|
char t34[] = "'ABC.def'";
|
||||||
//int32_t tmp0 = testValidateName(t34);
|
//int32_t tmp0 = testValidateName(t34);
|
||||||
|
|
@ -193,136 +193,136 @@ TEST(testCase, db_table_name) {
|
||||||
|
|
||||||
// do not use key words
|
// do not use key words
|
||||||
char t39[] = "table.'DEF'";
|
char t39[] = "table.'DEF'";
|
||||||
EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t39), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t40[] = "'table'.'DEF'";
|
char t40[] = "'table'.'DEF'";
|
||||||
EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t40), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t41[] = "'_abXYZ1234'.'deFF'";
|
char t41[] = "'_abXYZ1234'.'deFF'";
|
||||||
EXPECT_EQ(testValidateName(t41), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t41), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
char t42[] = "'_abDEF&^%1234'.'DIef'";
|
char t42[] = "'_abDEF&^%1234'.'DIef'";
|
||||||
EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t42), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t43[] = "'_123'.'Gtest中文'";
|
char t43[] = "'_123'.'Gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t43), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t44[] = "'aABC'.'Gtest中文'";
|
char t44[] = "'aABC'.'Gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t44), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t45[] = "'ABC'.";
|
char t45[] = "'ABC'.";
|
||||||
EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t45), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t46[] = ".'ABC'";
|
char t46[] = ".'ABC'";
|
||||||
EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t46), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t47[] = "a.\"aTWc\"";
|
char t47[] = "a.\"aTWc\"";
|
||||||
EXPECT_EQ(testValidateName(t47), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t47), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
// ================has space =================
|
// ================has space =================
|
||||||
char t60[] = " ABC ";
|
char t60[] = " ABC ";
|
||||||
EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t60), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t60_1[] = " ABC ";
|
char t60_1[] = " ABC ";
|
||||||
EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t61[] = "' ABC '";
|
char t61[] = "' ABC '";
|
||||||
EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t61_1[] = "' ABC '";
|
char t61_1[] = "' ABC '";
|
||||||
EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t62[] = " ABC . def ";
|
char t62[] = " ABC . def ";
|
||||||
EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t63[] = "' ABC . def ";
|
char t63[] = "' ABC . def ";
|
||||||
EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t63), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t63_0[] = " abc . DEF ' ";
|
char t63_0[] = " abc . DEF ' ";
|
||||||
EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t63_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t64[] = " ' ABC . def ' ";
|
char t64[] = " ' ABC . def ' ";
|
||||||
//int32_t tmp1 = testValidateName(t64);
|
//int32_t tmp1 = testValidateName(t64);
|
||||||
EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t64), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t65[] = " ' ABC '. def ";
|
char t65[] = " ' ABC '. def ";
|
||||||
EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t66[] = "' ABC '.' DEF '";
|
char t66[] = "' ABC '.' DEF '";
|
||||||
EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t67[] = "abc . ' DEF '";
|
char t67[] = "abc . ' DEF '";
|
||||||
EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t68[] = "' abc '.' DEF '";
|
char t68[] = "' abc '.' DEF '";
|
||||||
EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
// do not use key words
|
// do not use key words
|
||||||
char t69[] = "table.'DEF'";
|
char t69[] = "table.'DEF'";
|
||||||
EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t69), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t70[] = "'table'.'DEF'";
|
char t70[] = "'table'.'DEF'";
|
||||||
EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t71[] = "'_abXYZ1234 '.' deFF '";
|
char t71[] = "'_abXYZ1234 '.' deFF '";
|
||||||
EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t72[] = "'_abDEF&^%1234'.' DIef'";
|
char t72[] = "'_abDEF&^%1234'.' DIef'";
|
||||||
EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t73[] = "'_123'.' Gtest中文'";
|
char t73[] = "'_123'.' Gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t73), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t74[] = "' aABC'.'Gtest中文'";
|
char t74[] = "' aABC'.'Gtest中文'";
|
||||||
EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t74), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t75[] = "' ABC '.";
|
char t75[] = "' ABC '.";
|
||||||
EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t75), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t76[] = ".' ABC'";
|
char t76[] = ".' ABC'";
|
||||||
EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t76), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t77[] = " a . \"aTWc\" ";
|
char t77[] = " a . \"aTWc\" ";
|
||||||
EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t77), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t78[] = " a.\"aTWc \"";
|
char t78[] = " a.\"aTWc \"";
|
||||||
EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t78), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
|
|
||||||
// ===============muti string by space ===================
|
// ===============muti string by space ===================
|
||||||
// There's no such case.
|
// There's no such case.
|
||||||
//char t160[] = "A BC";
|
//char t160[] = "A BC";
|
||||||
//EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_SQL);
|
//EXPECT_EQ(testValidateName(t160), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
//printf("end:%s\n", t160);
|
//printf("end:%s\n", t160);
|
||||||
|
|
||||||
// There's no such case.
|
// There's no such case.
|
||||||
//char t161[] = "' A BC '";
|
//char t161[] = "' A BC '";
|
||||||
//EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_SQL);
|
//EXPECT_EQ(testValidateName(t161), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t162[] = " AB C . de f ";
|
char t162[] = " AB C . de f ";
|
||||||
EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t162), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t163[] = "' AB C . de f ";
|
char t163[] = "' AB C . de f ";
|
||||||
EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t163), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t163_0[] = " ab c . DE F ' ";
|
char t163_0[] = " ab c . DE F ' ";
|
||||||
EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t163_0), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t164[] = " ' AB C . de f ' ";
|
char t164[] = " ' AB C . de f ' ";
|
||||||
//int32_t tmp2 = testValidateName(t164);
|
//int32_t tmp2 = testValidateName(t164);
|
||||||
EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t164), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t165[] = " ' A BC '. de f ";
|
char t165[] = " ' A BC '. de f ";
|
||||||
EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t165), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t166[] = "' AB C '.' DE F '";
|
char t166[] = "' AB C '.' DE F '";
|
||||||
EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t166), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t167[] = "ab c . ' D EF '";
|
char t167[] = "ab c . ' D EF '";
|
||||||
EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t167), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
char t168[] = "' a bc '.' DE F '";
|
char t168[] = "' a bc '.' DE F '";
|
||||||
EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_SQL);
|
EXPECT_EQ(testValidateName(t168), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1150,7 +1150,12 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
||||||
pPeer->peerFd = connFd;
|
pPeer->peerFd = connFd;
|
||||||
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
||||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
||||||
if (pPeer->isArb) tsArbOnline = 1;
|
if (pPeer->isArb) {
|
||||||
|
tsArbOnline = 1;
|
||||||
|
if (tsArbOnlineTimestamp == TSDB_ARB_DUMMY_TIME) {
|
||||||
|
tsArbOnlineTimestamp = taosGetTimestampMs();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno));
|
sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno));
|
||||||
taosCloseSocket(connFd);
|
taosCloseSocket(connFd);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
ADD_LIBRARY(tsdb ${SRC})
|
ADD_LIBRARY(tsdb ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
|
TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
|
||||||
|
|
||||||
|
IF (TD_TSDB_PLUGINS)
|
||||||
|
TARGET_LINK_LIBRARIES(tsdb tsdbPlugins)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX)
|
IF (TD_LINUX)
|
||||||
# Someone has no gtest directory, so comment it
|
# Someone has no gtest directory, so comment it
|
||||||
# ADD_SUBDIRECTORY(tests)
|
# ADD_SUBDIRECTORY(tests)
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,18 @@ typedef struct {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
} SKVRecord;
|
} SKVRecord;
|
||||||
|
|
||||||
|
#define TSDB_DEFAULT_BLOCK_ROWS(maxRows) ((maxRows)*4 / 5)
|
||||||
|
|
||||||
void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn);
|
void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn);
|
||||||
int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord);
|
int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord);
|
||||||
void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord);
|
void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord);
|
||||||
void *tsdbCommitData(STsdbRepo *pRepo);
|
void *tsdbCommitData(STsdbRepo *pRepo);
|
||||||
|
int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn);
|
||||||
|
int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, SBlockIdx *pIdx);
|
||||||
|
int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf);
|
||||||
|
int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock,
|
||||||
|
bool isLast, bool isSuper, void **ppBuf, void **ppCBuf);
|
||||||
|
int tsdbApplyRtn(STsdbRepo *pRepo);
|
||||||
|
|
||||||
static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
|
static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
|
||||||
if (fid >= pRtn->maxFid) {
|
if (fid >= pRtn->maxFid) {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue