Merge branch '3.0' of https://github.com/taosdata/TDengine into fix/TD-30837
This commit is contained in:
commit
3365da365f
|
@ -144,6 +144,12 @@ option(
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option(
|
||||||
|
BUILD_WITH_ANALYSIS
|
||||||
|
"If build with analysis"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF(NOT TD_ENTERPRISE)
|
IF(NOT TD_ENTERPRISE)
|
||||||
|
@ -151,8 +157,15 @@ MESSAGE("switch s3 off with community version")
|
||||||
set(BUILD_S3 OFF)
|
set(BUILD_S3 OFF)
|
||||||
set(BUILD_WITH_S3 OFF)
|
set(BUILD_WITH_S3 OFF)
|
||||||
set(BUILD_WITH_COS OFF)
|
set(BUILD_WITH_COS OFF)
|
||||||
|
set(BUILD_WITH_ANALYSIS OFF)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF(${BUILD_WITH_ANALYSIS})
|
||||||
|
message("build with analysis")
|
||||||
|
set(BUILD_S3 ON)
|
||||||
|
set(BUILD_WITH_S3 ON)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(${BUILD_S3})
|
IF(${BUILD_S3})
|
||||||
|
|
||||||
IF(${BUILD_WITH_S3})
|
IF(${BUILD_WITH_S3})
|
||||||
|
|
|
@ -9,6 +9,5 @@ ExternalProject_Add(stub
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
TEST_COMMAND ""
|
TEST_COMMAND ""
|
||||||
GIT_SHALLOW true
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
## TDengine Spring JDBC Template Demo
|
## TDengine Spring JDBC Template Demo
|
||||||
|
|
||||||
`Spring JDBC Template` 简化了原生 JDBC Connection 获取释放等操作,使得操作数据库更加方便。
|
`Spring JDBC Template` simplifies the operations of acquiring and releasing native JDBC Connections, making database operations more convenient.
|
||||||
|
|
||||||
### 配置
|
### Configuration
|
||||||
|
|
||||||
修改 `src/main/resources/applicationContext.xml` 文件中 TDengine 的配置信息:
|
Modify the TDengine configuration in the `src/main/resources/applicationContext.xml` file:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
|
@ -20,13 +20,15 @@
|
||||||
</bean>
|
</bean>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 打包运行
|
### Package and run
|
||||||
|
|
||||||
|
Navigate to the `TDengine/tests/examples/JDBC/SpringJdbcTemplate` directory and execute the following commands to generate an executable jar file.
|
||||||
|
|
||||||
进入 `TDengine/tests/examples/JDBC/SpringJdbcTemplate` 目录下,执行以下命令可以生成可执行 jar 包。
|
|
||||||
```shell
|
```shell
|
||||||
mvn clean package
|
mvn clean package
|
||||||
```
|
```
|
||||||
打包成功之后,进入 `target/` 目录下,执行以下命令就可运行测试:
|
After successfully packaging, navigate to the `target/` directory and execute the following commands to run the tests:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
java -jar target/SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar
|
java -jar target/SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
### 设置###
|
### Settings###
|
||||||
log4j.rootLogger=debug,stdout,DebugLog,ErrorLog
|
log4j.rootLogger=debug,stdout,DebugLog,ErrorLog
|
||||||
### 输出信息到控制抬 ###
|
### Output information to the console ###
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
log4j.appender.stdout.Target=System.out
|
log4j.appender.stdout.Target=System.out
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
||||||
### 输出DEBUG 级别以上的日志到=logs/debug.log
|
### Output logs of DEBUG level and above to logs/debug.log
|
||||||
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
||||||
log4j.appender.DebugLog.File=logs/debug.log
|
log4j.appender.DebugLog.File=logs/debug.log
|
||||||
log4j.appender.DebugLog.Append=true
|
log4j.appender.DebugLog.Append=true
|
||||||
log4j.appender.DebugLog.Threshold=DEBUG
|
log4j.appender.DebugLog.Threshold=DEBUG
|
||||||
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
||||||
### 输出ERROR 级别以上的日志到=logs/error.log
|
### Output logs of ERROR level and above to logs/error.log
|
||||||
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
||||||
log4j.appender.ErrorLog.File=logs/error.log
|
log4j.appender.ErrorLog.File=logs/error.log
|
||||||
log4j.appender.ErrorLog.Append=true
|
log4j.appender.ErrorLog.Append=true
|
||||||
log4j.appender.ErrorLog.Threshold=ERROR
|
log4j.appender.ErrorLog.Threshold=ERROR
|
||||||
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
||||||
|
|
|
@ -1,27 +1,28 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<something-else-entirely>
|
<something-else-entirely>
|
||||||
<proxool>
|
<proxool>
|
||||||
|
<!-- Alias for the data source -->
|
||||||
<alias>ds</alias>
|
<alias>ds</alias>
|
||||||
<!--数据源的别名-->
|
<!-- URL connection string -->
|
||||||
<driver-url>jdbc:TAOS-RS://127.0.0.1:6041/log</driver-url>
|
<driver-url>jdbc:TAOS-RS://127.0.0.1:6041/log</driver-url>
|
||||||
<!--url连接串-->
|
<!-- Driver class -->
|
||||||
<driver-class>com.taosdata.jdbc.rs.RestfulDriver</driver-class>
|
<driver-class>com.taosdata.jdbc.rs.RestfulDriver</driver-class>
|
||||||
<!--驱动类-->
|
|
||||||
<driver-properties>
|
<driver-properties>
|
||||||
<property name="user" value="root"/>
|
<property name="user" value="root"/>
|
||||||
<property name="password" value="taosdata"/>
|
<property name="password" value="taosdata"/>
|
||||||
</driver-properties>
|
</driver-properties>
|
||||||
<!--最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 -->
|
<!-- Maximum connection count (default is 5). If this number is exceeded, new requests will be queued. The maximum number of queued requests is determined by maximum-new-connections -->
|
||||||
<maximum-connection-count>100</maximum-connection-count>
|
<maximum-connection-count>100</maximum-connection-count>
|
||||||
<!-- 定义连接池中的最大连接数 -->
|
<!-- Defines the maximum number of connections in the connection pool -->
|
||||||
<maximum-active-time>100</maximum-active-time>
|
<maximum-active-time>100</maximum-active-time>
|
||||||
<!--最少保持的空闲连接数(默认2个)-->
|
<!-- Minimum number of idle connections to maintain (default is 2) -->
|
||||||
<prototype-count>1</prototype-count>
|
<prototype-count>1</prototype-count>
|
||||||
<!--最小连接数(默认2个)-->
|
<!-- Minimum connection count (default is 2) -->
|
||||||
<minimum-connection-count>5</minimum-connection-count>
|
<minimum-connection-count>5</minimum-connection-count>
|
||||||
<!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒-->
|
<!-- Interval (in milliseconds) for Proxool to automatically check the status of each connection. Idle connections are immediately reclaimed, and timed-out connections are destroyed. Default is 30 seconds -->
|
||||||
<house-keeping-sleep-time>30000</house-keeping-sleep-time>
|
<house-keeping-sleep-time>30000</house-keeping-sleep-time>
|
||||||
<!--用于保持连接的测试语句 -->
|
<!-- Test statement used to maintain the connection -->
|
||||||
<house-keeping-test-sql>select server_version()</house-keeping-test-sql>
|
<house-keeping-test-sql>select server_version()</house-keeping-test-sql>
|
||||||
</proxool>
|
</proxool>
|
||||||
</something-else-entirely>
|
</something-else-entirely>
|
||||||
|
|
|
@ -35,17 +35,18 @@ public class Worker implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
while (!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
try {
|
try {
|
||||||
// 控制请求频率
|
// Control request rate
|
||||||
if (semaphore.tryAcquire()) {
|
if (semaphore.tryAcquire()) {
|
||||||
ConsumerRecords<Bean> records = consumer.poll(Duration.ofMillis(sleepTime));
|
ConsumerRecords<Bean> records = consumer.poll(Duration.ofMillis(sleepTime));
|
||||||
pool.submit(() -> {
|
pool.submit(() -> {
|
||||||
RateLimiter limiter = RateLimiter.create(rate);
|
RateLimiter limiter = RateLimiter.create(rate);
|
||||||
try {
|
try {
|
||||||
for (ConsumerRecord<Bean> record : records) {
|
for (ConsumerRecord<Bean> record : records) {
|
||||||
// 流量控制
|
// Traffic control
|
||||||
limiter.acquire();
|
limiter.acquire();
|
||||||
// 业务处理数据
|
// Business data processing
|
||||||
System.out.println("[" + LocalDateTime.now() + "] Thread id:" + Thread.currentThread().getId() + " -> " + record.value());
|
System.out.println("[" + LocalDateTime.now() + "] Thread id:"
|
||||||
|
+ Thread.currentThread().getId() + " -> " + record.value());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
# 使用说明
|
# Instructions
|
||||||
|
|
||||||
## 创建使用db
|
## Create and use the database
|
||||||
```shell
|
```shell
|
||||||
$ taos
|
$ taos
|
||||||
|
|
||||||
> create database mp_test
|
> create database mp_test
|
||||||
```
|
```
|
||||||
|
|
||||||
## 执行测试用例
|
## Execute test cases
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ mvn clean test
|
$ mvn clean test
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## TDengine SpringBoot + Mybatis Demo
|
## TDengine SpringBoot + Mybatis Demo
|
||||||
|
|
||||||
## 需要提前创建 test 数据库
|
## Need to create a test database in advance
|
||||||
|
|
||||||
```
|
```
|
||||||
$ taos -s 'create database if not exists test'
|
$ taos -s 'create database if not exists test'
|
||||||
|
@ -8,7 +8,7 @@ $ taos -s 'create database if not exists test'
|
||||||
$ curl http://localhost:8080/weather/init
|
$ curl http://localhost:8080/weather/init
|
||||||
```
|
```
|
||||||
|
|
||||||
### 配置 application.properties
|
### Configure application.properties
|
||||||
```properties
|
```properties
|
||||||
# datasource config
|
# datasource config
|
||||||
spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
|
spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
|
||||||
|
@ -38,9 +38,9 @@ mybatis.mapper-locations=classpath:mapper/*.xml
|
||||||
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
||||||
```
|
```
|
||||||
|
|
||||||
### 主要功能
|
### Main functions
|
||||||
|
|
||||||
* 创建数据库和表
|
* Create databases and tables
|
||||||
```xml
|
```xml
|
||||||
<!-- weatherMapper.xml -->
|
<!-- weatherMapper.xml -->
|
||||||
<update id="createDB" >
|
<update id="createDB" >
|
||||||
|
@ -52,14 +52,14 @@ logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
||||||
</update>
|
</update>
|
||||||
```
|
```
|
||||||
|
|
||||||
* 插入单条记录
|
* Insert a single record
|
||||||
```xml
|
```xml
|
||||||
<!-- weatherMapper.xml -->
|
<!-- weatherMapper.xml -->
|
||||||
<insert id="insert" parameterType="Weather" >
|
<insert id="insert" parameterType="Weather" >
|
||||||
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
|
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
|
||||||
</insert>
|
</insert>
|
||||||
```
|
```
|
||||||
* 插入多条记录
|
* Insert multiple records
|
||||||
```xml
|
```xml
|
||||||
<!-- weatherMapper.xml -->
|
<!-- weatherMapper.xml -->
|
||||||
<insert id="batchInsert" parameterType="java.util.List" >
|
<insert id="batchInsert" parameterType="java.util.List" >
|
||||||
|
@ -69,7 +69,7 @@ logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
```
|
```
|
||||||
* 分页查询
|
* Pagination query
|
||||||
```xml
|
```xml
|
||||||
<!-- weatherMapper.xml -->
|
<!-- weatherMapper.xml -->
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
```
|
```
|
||||||
cd tests/examples/JDBC/taosdemo
|
cd tests/examples/JDBC/taosdemo
|
||||||
mvn clean package -Dmaven.test.skip=true
|
mvn clean package -Dmaven.test.skip=true
|
||||||
# 先建表,再插入的
|
# Create tables first, then insert data
|
||||||
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable true -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable true -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
||||||
# 不建表,直接插入的
|
# Insert data directly without creating tables
|
||||||
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
java -jar target/taosdemo-2.0.1-jar-with-dependencies.jar -host <hostname> -database <db name> -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
||||||
```
|
```
|
||||||
|
|
||||||
如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
如果发生错误 Exception in thread "main" java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
||||||
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。
|
请检查是否安装 TDengine 客户端安装包或编译 TDengine 安装。如果确定已经安装过还出现这个错误,可以在命令行 java 后加 -Djava.library.path=/usr/lib 来指定寻找共享库的路径。
|
||||||
|
|
||||||
|
|
||||||
|
If you encounter the error Exception in thread "main" `java.lang.UnsatisfiedLinkError: no taos in java.library.path`, please check whether the TDengine client package is installed or TDengine is compiled and installed. If you are sure it is installed and still encounter this error, you can add `-Djava.library.path=/usr/lib` after the `java` command to specify the path to the shared library.
|
||||||
|
|
|
@ -24,14 +24,14 @@ public class TaosDemoApplication {
|
||||||
private static final Logger logger = LogManager.getLogger(TaosDemoApplication.class);
|
private static final Logger logger = LogManager.getLogger(TaosDemoApplication.class);
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
// 读配置参数
|
// Read configuration parameters
|
||||||
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
||||||
boolean isHelp = Arrays.asList(args).contains("--help");
|
boolean isHelp = Arrays.asList(args).contains("--help");
|
||||||
if (isHelp || config.host == null || config.host.isEmpty()) {
|
if (isHelp || config.host == null || config.host.isEmpty()) {
|
||||||
JdbcTaosdemoConfig.printHelp();
|
JdbcTaosdemoConfig.printHelp();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
// 初始化
|
//
|
||||||
final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user,
|
final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user,
|
||||||
config.password);
|
config.password);
|
||||||
if (config.executeSql != null && !config.executeSql.isEmpty()
|
if (config.executeSql != null && !config.executeSql.isEmpty()
|
||||||
|
@ -50,7 +50,7 @@ public class TaosDemoApplication {
|
||||||
final SuperTableService superTableService = new SuperTableService(dataSource);
|
final SuperTableService superTableService = new SuperTableService(dataSource);
|
||||||
final SubTableService subTableService = new SubTableService(dataSource);
|
final SubTableService subTableService = new SubTableService(dataSource);
|
||||||
|
|
||||||
// 创建数据库
|
// create database
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Map<String, String> databaseParam = new HashMap<>();
|
Map<String, String> databaseParam = new HashMap<>();
|
||||||
databaseParam.put("database", config.database);
|
databaseParam.put("database", config.database);
|
||||||
|
@ -81,13 +81,13 @@ public class TaosDemoApplication {
|
||||||
config.prefixOfFields, config.numOfTags, config.prefixOfTags);
|
config.prefixOfFields, config.numOfTags, config.prefixOfTags);
|
||||||
}
|
}
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
// 建表
|
// create table
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
if (config.doCreateTable) {
|
if (config.doCreateTable) {
|
||||||
superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName());
|
superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName());
|
||||||
superTableService.create(superTableMeta);
|
superTableService.create(superTableMeta);
|
||||||
if (!config.autoCreateTable) {
|
if (!config.autoCreateTable) {
|
||||||
// 批量建子表
|
// create sub tables in batch
|
||||||
subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable,
|
subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable,
|
||||||
config.numOfThreadsForCreate);
|
config.numOfThreadsForCreate);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class TaosDemoApplication {
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
logger.info(">>> create table time cost : " + (end - start) + " ms.");
|
logger.info(">>> create table time cost : " + (end - start) + " ms.");
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
// 插入
|
// insert data
|
||||||
long tableSize = config.numOfTables;
|
long tableSize = config.numOfTables;
|
||||||
int threadSize = config.numOfThreadsForInsert;
|
int threadSize = config.numOfThreadsForInsert;
|
||||||
long startTime = getProperStartTime(config.startTime, config.days);
|
long startTime = getProperStartTime(config.startTime, config.days);
|
||||||
|
@ -111,10 +111,9 @@ public class TaosDemoApplication {
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
|
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
// 查询
|
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
// 删除表
|
// drop table
|
||||||
if (config.dropTable) {
|
if (config.dropTable) {
|
||||||
superTableService.drop(config.database, config.superTable);
|
superTableService.drop(config.database, config.superTable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,21 +9,22 @@ import java.util.List;
|
||||||
@Repository
|
@Repository
|
||||||
public interface SubTableMapper {
|
public interface SubTableMapper {
|
||||||
|
|
||||||
// 创建:子表
|
// Create: SubTable
|
||||||
void createUsingSuperTable(SubTableMeta subTableMeta);
|
void createUsingSuperTable(SubTableMeta subTableMeta);
|
||||||
|
|
||||||
// 插入:一张子表多个values
|
// Insert: Multiple records into one SubTable
|
||||||
int insertOneTableMultiValues(SubTableValue subTableValue);
|
int insertOneTableMultiValues(SubTableValue subTableValue);
|
||||||
|
|
||||||
// 插入:一张子表多个values, 自动建表
|
// Insert: Multiple records into one SubTable, auto create SubTables
|
||||||
int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue);
|
int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue);
|
||||||
|
|
||||||
// 插入:多张表多个values
|
// Insert: Multiple records into multiple SubTable
|
||||||
int insertMultiTableMultiValues(List<SubTableValue> tables);
|
int insertMultiTableMultiValues(List<SubTableValue> tables);
|
||||||
|
|
||||||
// 插入:多张表多个values,自动建表
|
// Insert: Multiple records into multiple SubTable, auto create SubTables
|
||||||
int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables);
|
int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables);
|
||||||
|
|
||||||
//<!-- TODO:修改子表标签值 alter table ${tablename} set tag tagName=newTagValue-->
|
// <!-- TODO: Modify SubTable tag value: alter table ${tablename} set tag
|
||||||
|
// tagName=newTagValue-->
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,26 @@ import org.springframework.stereotype.Repository;
|
||||||
@Repository
|
@Repository
|
||||||
public interface SuperTableMapper {
|
public interface SuperTableMapper {
|
||||||
|
|
||||||
// 创建超级表 create table if not exists xxx.xxx (f1 type1, f2 type2, ... ) tags( t1 type1, t2 type2 ...)
|
// Create super table: create table if not exists xxx.xxx (f1 type1, f2 type2,
|
||||||
|
// ... ) tags( t1 type1, t2 type2 ...)
|
||||||
void createSuperTable(SuperTableMeta tableMetadata);
|
void createSuperTable(SuperTableMeta tableMetadata);
|
||||||
|
|
||||||
// 删除超级表 drop table if exists xxx;
|
// Drop super table: drop table if exists xxx;
|
||||||
void dropSuperTable(String database, String name);
|
void dropSuperTable(String database, String name);
|
||||||
|
|
||||||
//<!-- TODO:查询所有超级表信息 show stables -->
|
// <!-- TODO: Query all super table information show stables -->
|
||||||
|
|
||||||
//<!-- TODO:查询表结构 describe stable -->
|
// <!-- TODO: Query table structure describe stable -->
|
||||||
|
|
||||||
//<!-- TODO:增加列 alter table ${tablename} add column fieldName dataType -->
|
// <!-- TODO: Add column alter table ${tablename} add column fieldName dataType
|
||||||
|
// -->
|
||||||
|
|
||||||
//<!-- TODO:删除列 alter table ${tablename} drop column fieldName -->
|
// <!-- TODO: Drop column alter table ${tablename} drop column fieldName -->
|
||||||
|
|
||||||
//<!-- TODO:添加标签 alter table ${tablename} add tag new_tagName tag_type -->
|
// <!-- TODO: Add tag alter table ${tablename} add tag new_tagName tag_type -->
|
||||||
|
|
||||||
//<!-- TODO:删除标签 alter table ${tablename} drop tag_name -->
|
// <!-- TODO: Drop tag alter table ${tablename} drop tag_name -->
|
||||||
|
|
||||||
//<!-- TODO:修改标签名 alter table ${tablename} change tag old_tagName new_tagName -->
|
|
||||||
|
|
||||||
|
// <!-- TODO: Change tag name alter table ${tablename} change tag old_tagName
|
||||||
|
// new_tagName -->
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,19 +9,18 @@ import java.util.List;
|
||||||
@Repository
|
@Repository
|
||||||
public interface TableMapper {
|
public interface TableMapper {
|
||||||
|
|
||||||
// 创建:普通表
|
// Create: Normal table
|
||||||
void create(TableMeta tableMeta);
|
void create(TableMeta tableMeta);
|
||||||
|
|
||||||
// 插入:一张表多个value
|
// Insert: Multiple records into one table
|
||||||
int insertOneTableMultiValues(TableValue values);
|
int insertOneTableMultiValues(TableValue values);
|
||||||
|
|
||||||
// 插入: 一张表多个value,指定的列
|
// Insert: Multiple records into one table, specified columns
|
||||||
int insertOneTableMultiValuesWithColumns(TableValue values);
|
int insertOneTableMultiValuesWithColumns(TableValue values);
|
||||||
|
|
||||||
// 插入:多个表多个value
|
// Insert: Multiple records into multiple tables
|
||||||
int insertMultiTableMultiValues(List<TableValue> tables);
|
int insertMultiTableMultiValues(List<TableValue> tables);
|
||||||
|
|
||||||
// 插入:多个表多个value, 指定的列
|
// Insert: Multiple records into multiple tables, specified columns
|
||||||
int insertMultiTableMultiValuesWithColumns(List<TableValue> tables);
|
int insertMultiTableMultiValuesWithColumns(List<TableValue> tables);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -14,12 +14,12 @@ public class DatabaseService {
|
||||||
this.databaseMapper = new DatabaseMapperImpl(dataSource);
|
this.databaseMapper = new DatabaseMapperImpl(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 建库,指定 name
|
// Create database with specified name
|
||||||
public void createDatabase(String database) {
|
public void createDatabase(String database) {
|
||||||
databaseMapper.createDatabase(database);
|
databaseMapper.createDatabase(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 建库,指定参数 keep,days,replica等
|
// Create database with specified parameters such as keep, days, replica, etc.
|
||||||
public void createDatabase(Map<String, String> map) {
|
public void createDatabase(Map<String, String> map) {
|
||||||
if (map.isEmpty())
|
if (map.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -27,7 +27,8 @@ public class SubTableService extends AbstractService {
|
||||||
this.mapper = new SubTableMapperImpl(datasource);
|
this.mapper = new SubTableMapperImpl(datasource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createSubTable(SuperTableMeta superTableMeta, long numOfTables, String prefixOfTable, int numOfThreadsForCreate) {
|
public void createSubTable(SuperTableMeta superTableMeta, long numOfTables, String prefixOfTable,
|
||||||
|
int numOfThreadsForCreate) {
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(numOfThreadsForCreate);
|
ExecutorService executor = Executors.newFixedThreadPool(numOfThreadsForCreate);
|
||||||
for (long i = 0; i < numOfTables; i++) {
|
for (long i = 0; i < numOfTables; i++) {
|
||||||
long tableIndex = i;
|
long tableIndex = i;
|
||||||
|
@ -35,54 +36,58 @@ public class SubTableService extends AbstractService {
|
||||||
}
|
}
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
try {
|
try {
|
||||||
executor.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS);
|
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createSubTable(SuperTableMeta superTableMeta, String tableName) {
|
public void createSubTable(SuperTableMeta superTableMeta, String tableName) {
|
||||||
// 构造数据
|
// Construct data
|
||||||
SubTableMeta meta = SubTableMetaGenerator.generate(superTableMeta, tableName);
|
SubTableMeta meta = SubTableMetaGenerator.generate(superTableMeta, tableName);
|
||||||
createSubTable(meta);
|
createSubTable(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一张子表,可以指定database,supertable,tablename,tag值
|
// Create a sub-table, specifying database, super table, table name, and tag
|
||||||
|
// values
|
||||||
public void createSubTable(SubTableMeta subTableMeta) {
|
public void createSubTable(SubTableMeta subTableMeta) {
|
||||||
mapper.createUsingSuperTable(subTableMeta);
|
mapper.createUsingSuperTable(subTableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************************************************************/
|
/*************************************************************************************************************************/
|
||||||
// 插入:多线程,多表
|
// Insert: Multi-threaded, multiple tables
|
||||||
public int insert(List<SubTableValue> subTableValues, int threadSize, int frequency) {
|
public int insert(List<SubTableValue> subTableValues, int threadSize, int frequency) {
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(threadSize);
|
ExecutorService executor = Executors.newFixedThreadPool(threadSize);
|
||||||
Future<Integer> future = executor.submit(() -> insert(subTableValues));
|
Future<Integer> future = executor.submit(() -> insert(subTableValues));
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
//TODO:frequency
|
// TODO:frequency
|
||||||
return getAffectRows(future);
|
return getAffectRows(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入:单表,insert into xxx values(),()...
|
// Insert: Single table, insert into xxx values(),()...
|
||||||
public int insert(SubTableValue subTableValue) {
|
public int insert(SubTableValue subTableValue) {
|
||||||
return mapper.insertOneTableMultiValues(subTableValue);
|
return mapper.insertOneTableMultiValues(subTableValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入: 多表,insert into xxx values(),()... xxx values(),()...
|
// Insert: Multiple tables, insert into xxx values(),()... xxx values(),()...
|
||||||
public int insert(List<SubTableValue> subTableValues) {
|
public int insert(List<SubTableValue> subTableValues) {
|
||||||
return mapper.insertMultiTableMultiValues(subTableValues);
|
return mapper.insertMultiTableMultiValues(subTableValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入:单表,自动建表, insert into xxx using xxx tags(...) values(),()...
|
// Insert: Single table, auto-create table, insert into xxx using xxx tags(...)
|
||||||
|
// values(),()...
|
||||||
public int insertAutoCreateTable(SubTableValue subTableValue) {
|
public int insertAutoCreateTable(SubTableValue subTableValue) {
|
||||||
return mapper.insertOneTableMultiValuesUsingSuperTable(subTableValue);
|
return mapper.insertOneTableMultiValuesUsingSuperTable(subTableValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入:多表,自动建表, insert into xxx using XXX tags(...) values(),()... xxx using XXX tags(...) values(),()...
|
// Insert: Multiple tables, auto-create tables, insert into xxx using XXX
|
||||||
|
// tags(...) values(),()... xxx using XXX tags(...) values(),()...
|
||||||
public int insertAutoCreateTable(List<SubTableValue> subTableValues) {
|
public int insertAutoCreateTable(List<SubTableValue> subTableValues) {
|
||||||
return mapper.insertMultiTableMultiValuesUsingSuperTable(subTableValues);
|
return mapper.insertMultiTableMultiValuesUsingSuperTable(subTableValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int insertMultiThreads(SuperTableMeta superTableMeta, int threadSize, long tableSize, long startTime, long gap, JdbcTaosdemoConfig config) {
|
public int insertMultiThreads(SuperTableMeta superTableMeta, int threadSize, long tableSize, long startTime,
|
||||||
|
long gap, JdbcTaosdemoConfig config) {
|
||||||
List<FutureTask> taskList = new ArrayList<>();
|
List<FutureTask> taskList = new ArrayList<>();
|
||||||
List<Thread> threads = IntStream.range(0, threadSize)
|
List<Thread> threads = IntStream.range(0, threadSize)
|
||||||
.mapToObj(i -> {
|
.mapToObj(i -> {
|
||||||
|
@ -94,8 +99,7 @@ public class SubTableService extends AbstractService {
|
||||||
startTime, config.timeGap,
|
startTime, config.timeGap,
|
||||||
config.numOfRowsPerTable, config.numOfTablesPerSQL, config.numOfValuesPerSQL,
|
config.numOfRowsPerTable, config.numOfTablesPerSQL, config.numOfValuesPerSQL,
|
||||||
config.order, config.rate, config.range,
|
config.order, config.rate, config.range,
|
||||||
config.prefixOfTable, config.autoCreateTable)
|
config.prefixOfTable, config.autoCreateTable));
|
||||||
);
|
|
||||||
taskList.add(task);
|
taskList.add(task);
|
||||||
return new Thread(task, "InsertThread-" + i);
|
return new Thread(task, "InsertThread-" + i);
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
@ -126,7 +130,7 @@ public class SubTableService extends AbstractService {
|
||||||
private class InsertTask implements Callable<Integer> {
|
private class InsertTask implements Callable<Integer> {
|
||||||
|
|
||||||
private final long startTableInd; // included
|
private final long startTableInd; // included
|
||||||
private final long endTableInd; // excluded
|
private final long endTableInd; // excluded
|
||||||
private final long startTime;
|
private final long startTime;
|
||||||
private final long timeGap;
|
private final long timeGap;
|
||||||
private final long numOfRowsPerTable;
|
private final long numOfRowsPerTable;
|
||||||
|
@ -140,10 +144,10 @@ public class SubTableService extends AbstractService {
|
||||||
private final boolean autoCreateTable;
|
private final boolean autoCreateTable;
|
||||||
|
|
||||||
public InsertTask(SuperTableMeta superTableMeta, long startTableInd, long endTableInd,
|
public InsertTask(SuperTableMeta superTableMeta, long startTableInd, long endTableInd,
|
||||||
long startTime, long timeGap,
|
long startTime, long timeGap,
|
||||||
long numOfRowsPerTable, long numOfTablesPerSQL, long numOfValuesPerSQL,
|
long numOfRowsPerTable, long numOfTablesPerSQL, long numOfValuesPerSQL,
|
||||||
int order, int rate, long range,
|
int order, int rate, long range,
|
||||||
String prefixOfTable, boolean autoCreateTable) {
|
String prefixOfTable, boolean autoCreateTable) {
|
||||||
this.superTableMeta = superTableMeta;
|
this.superTableMeta = superTableMeta;
|
||||||
this.startTableInd = startTableInd;
|
this.startTableInd = startTableInd;
|
||||||
this.endTableInd = endTableInd;
|
this.endTableInd = endTableInd;
|
||||||
|
@ -159,7 +163,6 @@ public class SubTableService extends AbstractService {
|
||||||
this.autoCreateTable = autoCreateTable;
|
this.autoCreateTable = autoCreateTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer call() {
|
public Integer call() {
|
||||||
|
|
||||||
|
@ -171,23 +174,27 @@ public class SubTableService extends AbstractService {
|
||||||
|
|
||||||
int affectRows = 0;
|
int affectRows = 0;
|
||||||
// row
|
// row
|
||||||
for (long rowCnt = 0; rowCnt < numOfRowsPerTable; ) {
|
for (long rowCnt = 0; rowCnt < numOfRowsPerTable;) {
|
||||||
long rowSize = numOfValuesPerSQL;
|
long rowSize = numOfValuesPerSQL;
|
||||||
if (rowCnt + rowSize > numOfRowsPerTable) {
|
if (rowCnt + rowSize > numOfRowsPerTable) {
|
||||||
rowSize = numOfRowsPerTable - rowCnt;
|
rowSize = numOfRowsPerTable - rowCnt;
|
||||||
}
|
}
|
||||||
//table
|
// table
|
||||||
for (long tableCnt = startTableInd; tableCnt < endTableInd; ) {
|
for (long tableCnt = startTableInd; tableCnt < endTableInd;) {
|
||||||
long tableSize = numOfTablesPerSQL;
|
long tableSize = numOfTablesPerSQL;
|
||||||
if (tableCnt + tableSize > endTableInd) {
|
if (tableCnt + tableSize > endTableInd) {
|
||||||
tableSize = endTableInd - tableCnt;
|
tableSize = endTableInd - tableCnt;
|
||||||
}
|
}
|
||||||
long startTime = this.startTime + rowCnt * timeGap;
|
long startTime = this.startTime + rowCnt * timeGap;
|
||||||
// System.out.println(Thread.currentThread().getName() + " >>> " + "rowCnt: " + rowCnt + ", rowSize: " + rowSize + ", " + "tableCnt: " + tableCnt + ",tableSize: " + tableSize + ", " + "startTime: " + startTime + ",timeGap: " + timeGap + "");
|
// System.out.println(Thread.currentThread().getName() + " >>> " + "rowCnt: " +
|
||||||
|
// rowCnt + ", rowSize: " + rowSize + ", " + "tableCnt: " + tableCnt +
|
||||||
|
// ",tableSize: " + tableSize + ", " + "startTime: " + startTime + ",timeGap: "
|
||||||
|
// + timeGap + "");
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
// 生成数据
|
// Construct data
|
||||||
List<SubTableValue> data = SubTableValueGenerator.generate(superTableMeta, prefixOfTable, tableCnt, tableSize, rowSize, startTime, timeGap);
|
List<SubTableValue> data = SubTableValueGenerator.generate(superTableMeta, prefixOfTable, tableCnt,
|
||||||
// 乱序
|
tableSize, rowSize, startTime, timeGap);
|
||||||
|
// disorder
|
||||||
if (order != 0)
|
if (order != 0)
|
||||||
SubTableValueGenerator.disrupt(data, rate, range);
|
SubTableValueGenerator.disrupt(data, rate, range);
|
||||||
// insert
|
// insert
|
||||||
|
@ -205,5 +212,4 @@ public class SubTableService extends AbstractService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class SuperTableService {
|
||||||
this.superTableMapper = new SuperTableMapperImpl(dataSource);
|
this.superTableMapper = new SuperTableMapperImpl(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建超级表,指定每个field的名称和类型,每个tag的名称和类型
|
// Create super table, specifying the name and type of each field and each tag
|
||||||
public void create(SuperTableMeta superTableMeta) {
|
public void create(SuperTableMeta superTableMeta) {
|
||||||
superTableMapper.createSuperTable(superTableMeta);
|
superTableMapper.createSuperTable(superTableMeta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,14 @@ public class TableService extends AbstractService {
|
||||||
|
|
||||||
private TableMapper tableMapper;
|
private TableMapper tableMapper;
|
||||||
|
|
||||||
//创建一张表
|
// Create a table
|
||||||
public void create(TableMeta tableMeta) {
|
public void create(TableMeta tableMeta) {
|
||||||
tableMapper.create(tableMeta);
|
tableMapper.create(tableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
//创建多张表
|
// Create multiple tables
|
||||||
public void create(List<TableMeta> tables) {
|
public void create(List<TableMeta> tables) {
|
||||||
tables.stream().forEach(this::create);
|
tables.stream().forEach(this::create);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ public class FieldValueGenerator {
|
||||||
|
|
||||||
public static Random random = new Random(System.currentTimeMillis());
|
public static Random random = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
// 生成start到end的时间序列,时间戳为顺序,不含有乱序,field的value为随机生成
|
// Generate a time series from start to end, timestamps are in order without
|
||||||
|
// disorder, field values are randomly generated
|
||||||
public static List<RowValue> generate(long start, long end, long timeGap, List<FieldMeta> fieldMetaList) {
|
public static List<RowValue> generate(long start, long end, long timeGap, List<FieldMeta> fieldMetaList) {
|
||||||
List<RowValue> values = new ArrayList<>();
|
List<RowValue> values = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -29,9 +30,12 @@ public class FieldValueGenerator {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成start到end的时间序列,时间戳为顺序,含有乱序,rate为乱序的比例,range为乱序前跳范围,field的value为随机生成
|
// Generate a time series from start to end, timestamps are in order but include
|
||||||
|
// disorder, rate is the proportion of disorder, range is the jump range before
|
||||||
|
// disorder, field values are randomly generated
|
||||||
public static List<RowValue> disrupt(List<RowValue> values, int rate, long range) {
|
public static List<RowValue> disrupt(List<RowValue> values, int rate, long range) {
|
||||||
long timeGap = (long) (values.get(1).getFields().get(0).getValue()) - (long) (values.get(0).getFields().get(0).getValue());
|
long timeGap = (long) (values.get(1).getFields().get(0).getValue())
|
||||||
|
- (long) (values.get(0).getFields().get(0).getValue());
|
||||||
int bugSize = values.size() * rate / 100;
|
int bugSize = values.size() * rate / 100;
|
||||||
Set<Integer> bugIndSet = new HashSet<>();
|
Set<Integer> bugIndSet = new HashSet<>();
|
||||||
while (bugIndSet.size() < bugSize) {
|
while (bugIndSet.size() < bugSize) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
public class SubTableMetaGenerator {
|
public class SubTableMetaGenerator {
|
||||||
|
|
||||||
// 创建tableSize张子表,使用tablePrefix作为子表名的前缀,使用superTableMeta的元数据
|
// Create tableSize sub-tables, using tablePrefix as the prefix for sub-table names, and using the metadata from superTableMeta
|
||||||
// create table xxx using XXX tags(XXX)
|
// create table xxx using XXX tags(XXX)
|
||||||
public static List<SubTableMeta> generate(SuperTableMeta superTableMeta, int tableSize, String tablePrefix) {
|
public static List<SubTableMeta> generate(SuperTableMeta superTableMeta, int tableSize, String tablePrefix) {
|
||||||
List<SubTableMeta> subTableMetaList = new ArrayList<>();
|
List<SubTableMeta> subTableMetaList = new ArrayList<>();
|
||||||
|
|
|
@ -10,10 +10,11 @@ import java.util.List;
|
||||||
|
|
||||||
public class SuperTableMetaGenerator {
|
public class SuperTableMetaGenerator {
|
||||||
|
|
||||||
// 创建超级表,使用指定SQL语句
|
// Create super table using the specified SQL statement
|
||||||
public static SuperTableMeta generate(String superTableSQL) {
|
public static SuperTableMeta generate(String superTableSQL) {
|
||||||
SuperTableMeta tableMeta = new SuperTableMeta();
|
SuperTableMeta tableMeta = new SuperTableMeta();
|
||||||
// for example : create table superTable (ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)
|
// for example : create table superTable (ts timestamp, temperature float,
|
||||||
|
// humidity int) tags(location nchar(64), groupId int)
|
||||||
superTableSQL = superTableSQL.trim().toLowerCase();
|
superTableSQL = superTableSQL.trim().toLowerCase();
|
||||||
if (!superTableSQL.startsWith("create"))
|
if (!superTableSQL.startsWith("create"))
|
||||||
throw new RuntimeException("invalid create super table SQL");
|
throw new RuntimeException("invalid create super table SQL");
|
||||||
|
@ -54,8 +55,9 @@ public class SuperTableMetaGenerator {
|
||||||
return tableMeta;
|
return tableMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建超级表,指定field和tag的个数
|
// Create super table with specified number of fields and tags
|
||||||
public static SuperTableMeta generate(String database, String name, int fieldSize, String fieldPrefix, int tagSize, String tagPrefix) {
|
public static SuperTableMeta generate(String database, String name, int fieldSize, String fieldPrefix, int tagSize,
|
||||||
|
String tagPrefix) {
|
||||||
if (fieldSize < 2 || tagSize < 1) {
|
if (fieldSize < 2 || tagSize < 1) {
|
||||||
throw new RuntimeException("create super table but fieldSize less than 2 or tagSize less than 1");
|
throw new RuntimeException("create super table but fieldSize less than 2 or tagSize less than 1");
|
||||||
}
|
}
|
||||||
|
@ -66,7 +68,8 @@ public class SuperTableMetaGenerator {
|
||||||
List<FieldMeta> fields = new ArrayList<>();
|
List<FieldMeta> fields = new ArrayList<>();
|
||||||
fields.add(new FieldMeta("ts", "timestamp"));
|
fields.add(new FieldMeta("ts", "timestamp"));
|
||||||
for (int i = 1; i <= fieldSize; i++) {
|
for (int i = 1; i <= fieldSize; i++) {
|
||||||
fields.add(new FieldMeta(fieldPrefix + "" + i, TaosConstants.DATA_TYPES[i % TaosConstants.DATA_TYPES.length]));
|
fields.add(
|
||||||
|
new FieldMeta(fieldPrefix + "" + i, TaosConstants.DATA_TYPES[i % TaosConstants.DATA_TYPES.length]));
|
||||||
}
|
}
|
||||||
tableMetadata.setFields(fields);
|
tableMetadata.setFields(fields);
|
||||||
// tags
|
// tags
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
public class TagValueGenerator {
|
public class TagValueGenerator {
|
||||||
|
|
||||||
// 创建标签值:使用tagMetas
|
// Create tag values using tagMetas
|
||||||
public static List<TagValue> generate(List<TagMeta> tagMetas) {
|
public static List<TagValue> generate(List<TagMeta> tagMetas) {
|
||||||
List<TagValue> tagValues = new ArrayList<>();
|
List<TagValue> tagValues = new ArrayList<>();
|
||||||
for (int i = 0; i < tagMetas.size(); i++) {
|
for (int i = 0; i < tagMetas.size(); i++) {
|
||||||
|
|
|
@ -41,17 +41,17 @@ public class TimeStampUtil {
|
||||||
if (start == 0)
|
if (start == 0)
|
||||||
start = now - size * timeGap;
|
start = now - size * timeGap;
|
||||||
|
|
||||||
// 如果size小于1异常
|
// If size is less than 1, throw an exception
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
throw new IllegalArgumentException("size less than 1.");
|
throw new IllegalArgumentException("size less than 1.");
|
||||||
// 如果timeGap为1,已经超长,需要前移start
|
// If timeGap is 1 and it exceeds the limit, move start forward
|
||||||
if (start + size > now) {
|
if (start + size > now) {
|
||||||
start = now - size;
|
start = now - size;
|
||||||
return new TimeTuple(start, now, 1);
|
return new TimeTuple(start, now, 1);
|
||||||
}
|
}
|
||||||
long end = start + (long) (timeGap * size);
|
long end = start + (long) (timeGap * size);
|
||||||
if (end > now) {
|
if (end > now) {
|
||||||
//压缩timeGap
|
// Compress timeGap
|
||||||
end = now;
|
end = now;
|
||||||
double gap = (end - start) / (size * 1.0f);
|
double gap = (end - start) / (size * 1.0f);
|
||||||
if (gap < 1.0f) {
|
if (gap < 1.0f) {
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
### 设置###
|
### Settings ###
|
||||||
log4j.rootLogger=info,stdout
|
log4j.rootLogger=info,stdout
|
||||||
### 输出信息到控制抬 ###
|
### Output information to the console ###
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
log4j.appender.stdout.Target=System.out
|
log4j.appender.stdout.Target=System.out
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
||||||
### 输出DEBUG 级别以上的日志到=logs/debug.log
|
### Output logs of DEBUG level and above to logs/debug.log ###
|
||||||
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
||||||
log4j.appender.DebugLog.File=logs/debug.log
|
log4j.appender.DebugLog.File=logs/debug.log
|
||||||
log4j.appender.DebugLog.Append=true
|
log4j.appender.DebugLog.Append=true
|
||||||
log4j.appender.DebugLog.Threshold=DEBUG
|
log4j.appender.DebugLog.Threshold=DEBUG
|
||||||
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
||||||
### 输出ERROR 级别以上的日志到=logs/error.log
|
### Output logs of ERROR level and above to logs/error.log ###
|
||||||
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
||||||
log4j.appender.ErrorLog.File=logs/error.log
|
log4j.appender.ErrorLog.File=logs/error.log
|
||||||
log4j.appender.ErrorLog.Append=true
|
log4j.appender.ErrorLog.Append=true
|
||||||
log4j.appender.ErrorLog.Threshold=ERROR
|
log4j.appender.ErrorLog.Threshold=ERROR
|
||||||
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
||||||
|
|
|
@ -6,7 +6,7 @@ slug: /
|
||||||
|
|
||||||
TDengine 是一款[开源](https://www.taosdata.com/tdengine/open_source_time-series_database)、[高性能](https://www.taosdata.com/fast)、[云原生](https://www.taosdata.com/tdengine/cloud_native_time-series_database)的<a href="https://www.taosdata.com/" data-internallinksmanager029f6b8e52c="2" title="时序数据库" target="_blank" rel="noopener">时序数据库</a>(<a href="https://www.taosdata.com/time-series-database" data-internallinksmanager029f6b8e52c="9" title="Time Series DataBase" target="_blank" rel="noopener">Time Series Database</a>, <a href="https://www.taosdata.com/tsdb" data-internallinksmanager029f6b8e52c="8" title="TSDB" target="_blank" rel="noopener">TSDB</a>), 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓存、流式计算、数据订阅等系统功能,能大幅减少系统设计的复杂度,降低研发和运营成本,是一款极简的时序数据处理平台。本文档是 TDengine 的用户手册,主要是介绍 TDengine 的基本概念、安装、使用、功能、开发接口、运营维护、TDengine 内核设计等等,它主要是面向架构师、开发工程师与系统管理员的。如果你对时序数据的基本概念、价值以及其所能带来的业务价值尚不了解,请参考[时序数据基础](./concept)
|
TDengine 是一款[开源](https://www.taosdata.com/tdengine/open_source_time-series_database)、[高性能](https://www.taosdata.com/fast)、[云原生](https://www.taosdata.com/tdengine/cloud_native_time-series_database)的<a href="https://www.taosdata.com/" data-internallinksmanager029f6b8e52c="2" title="时序数据库" target="_blank" rel="noopener">时序数据库</a>(<a href="https://www.taosdata.com/time-series-database" data-internallinksmanager029f6b8e52c="9" title="Time Series DataBase" target="_blank" rel="noopener">Time Series Database</a>, <a href="https://www.taosdata.com/tsdb" data-internallinksmanager029f6b8e52c="8" title="TSDB" target="_blank" rel="noopener">TSDB</a>), 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓存、流式计算、数据订阅等系统功能,能大幅减少系统设计的复杂度,降低研发和运营成本,是一款极简的时序数据处理平台。本文档是 TDengine 的用户手册,主要是介绍 TDengine 的基本概念、安装、使用、功能、开发接口、运营维护、TDengine 内核设计等等,它主要是面向架构师、开发工程师与系统管理员的。如果你对时序数据的基本概念、价值以及其所能带来的业务价值尚不了解,请参考[时序数据基础](./concept)
|
||||||
|
|
||||||
TDengine 充分利用了时序数据的特点,提出了“一个数据采集点一张表”与“超级表”的概念,设计了创新的存储引擎,让数据的写入、查询和存储效率都得到极大的提升。为正确理解并使用 TDengine,无论如何,请您仔细阅读[快速入门](./basic)一章。
|
TDengine 充分利用了时序数据的特点,提出了“一个数据采集点一张表”与“超级表”的概念,设计了创新的存储引擎,让数据的写入、查询和存储效率都得到极大的提升。为正确理解并使用 TDengine,无论如何,请您仔细阅读[数据模型](./basic/model)一章。
|
||||||
|
|
||||||
如果你是开发工程师,请一定仔细阅读[开发指南](./develop)一章,该部分对数据库连接、建模、插入数据、查询、流式计算、缓存、数据订阅、用户自定义函数等功能都做了详细介绍,并配有各种编程语言的示例代码。大部分情况下,你只要复制粘贴示例代码,针对自己的应用稍作改动,就能跑起来。对 REST API、各种编程语言的连接器(Connector)想做更多详细了解的话,请看[连接器](./reference/connector)一章。
|
如果你是开发工程师,请一定仔细阅读[开发指南](./develop)一章,该部分对数据库连接、建模、插入数据、查询、流式计算、缓存、数据订阅、用户自定义函数等功能都做了详细介绍,并配有各种编程语言的示例代码。大部分情况下,你只要复制粘贴示例代码,针对自己的应用稍作改动,就能跑起来。对 REST API、各种编程语言的连接器(Connector)想做更多详细了解的话,请看[连接器](./reference/connector)一章。
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ sidebar_label: taosExplorer
|
||||||
toc_max_heading_level: 4
|
toc_max_heading_level: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
taosExplorer 是一个为用户提供 TDengine 实例的可视化管理交互工具的 web 服务。本节主要讲述其安装和部署。它的各项功能都是基于简单易上手的图形界面,可以直接尝试,如果有需要也可以考高级功能和运维指南中的相关内容。为了确保访问 taosExplorer 的最佳体验,请使用 Chrome 79 及以上版本,或 Edge 79 及以上版本。
|
taosExplorer 是一个为用户提供 TDengine 实例的可视化管理交互工具的 web 服务,虽然它没有开源,但随开源版安装包免费提供。本节主要讲述其安装和部署。它的各项功能都是基于简单易上手的图形界面,可以直接尝试,如果有需要也可以参考高级功能和运维指南中的相关内容。为了确保访问 taosExplorer 的最佳体验,请使用 Chrome 79 及以上版本,或 Edge 79 及以上版本。
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
taosEexplorer 无需单独安装,从 TDengine 3.3.0.0 版本开始,它随着 TDengine Enterprise Server 安装包一起发布,安装完成后,就可以看到 `taos-explorer` 服务。
|
taosEexplorer 无需单独安装,从 TDengine 3.3.0.0 版本开始,它随着 TDengine 安装包一起发布,安装完成后,就可以看到 `taos-explorer` 服务。如果按照 GitHub 里步骤自己编译 TDengine 源代码生成的安装包不包含 taosExplorer。
|
||||||
|
|
||||||
## 配置
|
## 配置
|
||||||
|
|
||||||
|
|
|
@ -477,7 +477,9 @@ taosBenchmark -A INT,DOUBLE,NCHAR,BINARY\(16\)
|
||||||
| 13 | BOOL | bool
|
| 13 | BOOL | bool
|
||||||
| 14 | NCHAR | nchar
|
| 14 | NCHAR | nchar
|
||||||
| 15 | VARCHAR | varchar
|
| 15 | VARCHAR | varchar
|
||||||
| 15 | JSON | json
|
| 16 | VARBINARY | varbinary
|
||||||
|
| 17 | GEOMETRY | geometry
|
||||||
|
| 18 | JSON | json
|
||||||
|
|
||||||
注意:taosBenchmark 配置文件中数据类型必须小写方可识别
|
注意:taosBenchmark 配置文件中数据类型必须小写方可识别
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ extern "C" {
|
||||||
#define TSDB_INS_TABLE_QNODES "ins_qnodes"
|
#define TSDB_INS_TABLE_QNODES "ins_qnodes"
|
||||||
#define TSDB_INS_TABLE_BNODES "ins_bnodes" // no longer used
|
#define TSDB_INS_TABLE_BNODES "ins_bnodes" // no longer used
|
||||||
#define TSDB_INS_TABLE_SNODES "ins_snodes"
|
#define TSDB_INS_TABLE_SNODES "ins_snodes"
|
||||||
|
#define TSDB_INS_TABLE_ANODES "ins_anodes"
|
||||||
|
#define TSDB_INS_TABLE_ANODES_FULL "ins_anodes_full"
|
||||||
#define TSDB_INS_TABLE_ARBGROUPS "ins_arbgroups"
|
#define TSDB_INS_TABLE_ARBGROUPS "ins_arbgroups"
|
||||||
#define TSDB_INS_TABLE_CLUSTER "ins_cluster"
|
#define TSDB_INS_TABLE_CLUSTER "ins_cluster"
|
||||||
#define TSDB_INS_TABLE_DATABASES "ins_databases"
|
#define TSDB_INS_TABLE_DATABASES "ins_databases"
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_UTIL_ANAL_H_
|
||||||
|
#define _TD_UTIL_ANAL_H_
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "tdef.h"
|
||||||
|
#include "thash.h"
|
||||||
|
#include "tjson.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ANAL_FORECAST_DEFAULT_ROWS 10
|
||||||
|
#define ANAL_FORECAST_DEFAULT_CONF 95
|
||||||
|
#define ANAL_FORECAST_DEFAULT_WNCHECK 1
|
||||||
|
#define ANAL_FORECAST_MAX_ROWS 10000
|
||||||
|
#define ANAL_ANOMALY_WINDOW_MAX_ROWS 10000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EAnalAlgoType type;
|
||||||
|
int32_t anode;
|
||||||
|
int32_t urlLen;
|
||||||
|
char *url;
|
||||||
|
} SAnalUrl;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANAL_BUF_TYPE_JSON = 0,
|
||||||
|
ANAL_BUF_TYPE_JSON_COL = 1,
|
||||||
|
ANAL_BUF_TYPE_OTHERS,
|
||||||
|
} EAnalBufType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANAL_HTTP_TYPE_GET = 0,
|
||||||
|
ANAL_HTTP_TYPE_POST,
|
||||||
|
} EAnalHttpType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TdFilePtr filePtr;
|
||||||
|
char fileName[TSDB_FILENAME_LEN + 10];
|
||||||
|
int64_t numOfRows;
|
||||||
|
} SAnalColBuf;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EAnalBufType bufType;
|
||||||
|
TdFilePtr filePtr;
|
||||||
|
char fileName[TSDB_FILENAME_LEN];
|
||||||
|
int32_t numOfCols;
|
||||||
|
SAnalColBuf *pCols;
|
||||||
|
} SAnalBuf;
|
||||||
|
|
||||||
|
int32_t taosAnalInit();
|
||||||
|
void taosAnalCleanup();
|
||||||
|
SJson *taosAnalSendReqRetJson(const char *url, EAnalHttpType type, SAnalBuf *pBuf);
|
||||||
|
|
||||||
|
int32_t taosAnalGetAlgoUrl(const char *algoName, EAnalAlgoType type, char *url, int32_t urlLen);
|
||||||
|
bool taosAnalGetOptStr(const char *option, const char *optName, char *optValue, int32_t optMaxLen);
|
||||||
|
bool taosAnalGetOptInt(const char *option, const char *optName, int64_t *optValue);
|
||||||
|
int64_t taosAnalGetVersion();
|
||||||
|
void taosAnalUpdate(int64_t newVer, SHashObj *pHash);
|
||||||
|
|
||||||
|
int32_t tsosAnalBufOpen(SAnalBuf *pBuf, int32_t numOfCols);
|
||||||
|
int32_t taosAnalBufWriteOptStr(SAnalBuf *pBuf, const char *optName, const char *optVal);
|
||||||
|
int32_t taosAnalBufWriteOptInt(SAnalBuf *pBuf, const char *optName, int64_t optVal);
|
||||||
|
int32_t taosAnalBufWriteOptFloat(SAnalBuf *pBuf, const char *optName, float optVal);
|
||||||
|
int32_t taosAnalBufWriteColMeta(SAnalBuf *pBuf, int32_t colIndex, int32_t colType, const char *colName);
|
||||||
|
int32_t taosAnalBufWriteDataBegin(SAnalBuf *pBuf);
|
||||||
|
int32_t taosAnalBufWriteColBegin(SAnalBuf *pBuf, int32_t colIndex);
|
||||||
|
int32_t taosAnalBufWriteColData(SAnalBuf *pBuf, int32_t colIndex, int32_t colType, void *colValue);
|
||||||
|
int32_t taosAnalBufWriteColEnd(SAnalBuf *pBuf, int32_t colIndex);
|
||||||
|
int32_t taosAnalBufWriteDataEnd(SAnalBuf *pBuf);
|
||||||
|
int32_t taosAnalBufClose(SAnalBuf *pBuf);
|
||||||
|
void taosAnalBufDestroy(SAnalBuf *pBuf);
|
||||||
|
|
||||||
|
const char *taosAnalAlgoStr(EAnalAlgoType algoType);
|
||||||
|
EAnalAlgoType taosAnalAlgoInt(const char *algoName);
|
||||||
|
const char *taosAnalAlgoUrlStr(EAnalAlgoType algoType);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /*_TD_UTIL_ANAL_H_*/
|
|
@ -159,6 +159,8 @@ typedef enum _mgmt_table {
|
||||||
TSDB_MGMT_TABLE_ARBGROUP,
|
TSDB_MGMT_TABLE_ARBGROUP,
|
||||||
TSDB_MGMT_TABLE_ENCRYPTIONS,
|
TSDB_MGMT_TABLE_ENCRYPTIONS,
|
||||||
TSDB_MGMT_TABLE_USER_FULL,
|
TSDB_MGMT_TABLE_USER_FULL,
|
||||||
|
TSDB_MGMT_TABLE_ANODE,
|
||||||
|
TSDB_MGMT_TABLE_ANODE_FULL,
|
||||||
TSDB_MGMT_TABLE_MAX,
|
TSDB_MGMT_TABLE_MAX,
|
||||||
} EShowType;
|
} EShowType;
|
||||||
|
|
||||||
|
@ -260,6 +262,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_COUNT_WINDOW,
|
QUERY_NODE_COUNT_WINDOW,
|
||||||
QUERY_NODE_COLUMN_OPTIONS,
|
QUERY_NODE_COLUMN_OPTIONS,
|
||||||
QUERY_NODE_TSMA_OPTIONS,
|
QUERY_NODE_TSMA_OPTIONS,
|
||||||
|
QUERY_NODE_ANOMALY_WINDOW,
|
||||||
|
|
||||||
// Statement nodes are used in parser and planner module.
|
// Statement nodes are used in parser and planner module.
|
||||||
QUERY_NODE_SET_OPERATOR = 100,
|
QUERY_NODE_SET_OPERATOR = 100,
|
||||||
|
@ -345,6 +348,9 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_CREATE_VIEW_STMT,
|
QUERY_NODE_CREATE_VIEW_STMT,
|
||||||
QUERY_NODE_DROP_VIEW_STMT,
|
QUERY_NODE_DROP_VIEW_STMT,
|
||||||
QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE,
|
QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE,
|
||||||
|
QUERY_NODE_CREATE_ANODE_STMT,
|
||||||
|
QUERY_NODE_DROP_ANODE_STMT,
|
||||||
|
QUERY_NODE_UPDATE_ANODE_STMT,
|
||||||
|
|
||||||
// show statement nodes
|
// show statement nodes
|
||||||
// see 'sysTableShowAdapter', 'SYSTABLE_SHOW_TYPE_OFFSET'
|
// see 'sysTableShowAdapter', 'SYSTABLE_SHOW_TYPE_OFFSET'
|
||||||
|
@ -386,6 +392,8 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_SHOW_CLUSTER_MACHINES_STMT,
|
QUERY_NODE_SHOW_CLUSTER_MACHINES_STMT,
|
||||||
QUERY_NODE_SHOW_ENCRYPTIONS_STMT,
|
QUERY_NODE_SHOW_ENCRYPTIONS_STMT,
|
||||||
QUERY_NODE_SHOW_TSMAS_STMT,
|
QUERY_NODE_SHOW_TSMAS_STMT,
|
||||||
|
QUERY_NODE_SHOW_ANODES_STMT,
|
||||||
|
QUERY_NODE_SHOW_ANODES_FULL_STMT,
|
||||||
QUERY_NODE_CREATE_TSMA_STMT,
|
QUERY_NODE_CREATE_TSMA_STMT,
|
||||||
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
|
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
|
||||||
QUERY_NODE_DROP_TSMA_STMT,
|
QUERY_NODE_DROP_TSMA_STMT,
|
||||||
|
@ -408,6 +416,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_LOGIC_PLAN,
|
QUERY_NODE_LOGIC_PLAN,
|
||||||
QUERY_NODE_LOGIC_PLAN_GROUP_CACHE,
|
QUERY_NODE_LOGIC_PLAN_GROUP_CACHE,
|
||||||
QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL,
|
QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL,
|
||||||
|
QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC,
|
||||||
|
|
||||||
// physical plan node
|
// physical plan node
|
||||||
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
|
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
|
||||||
|
@ -460,6 +469,9 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL,
|
QUERY_NODE_PHYSICAL_PLAN_STREAM_MID_INTERVAL,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC,
|
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_INTERVAL,
|
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_INTERVAL,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_STREAM_ANOMALY,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC,
|
||||||
} ENodeType;
|
} ENodeType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1094,6 +1106,22 @@ typedef struct {
|
||||||
int32_t tSerializeRetrieveIpWhite(void* buf, int32_t bufLen, SRetrieveIpWhiteReq* pReq);
|
int32_t tSerializeRetrieveIpWhite(void* buf, int32_t bufLen, SRetrieveIpWhiteReq* pReq);
|
||||||
int32_t tDeserializeRetrieveIpWhite(void* buf, int32_t bufLen, SRetrieveIpWhiteReq* pReq);
|
int32_t tDeserializeRetrieveIpWhite(void* buf, int32_t bufLen, SRetrieveIpWhiteReq* pReq);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t dnodeId;
|
||||||
|
int64_t analVer;
|
||||||
|
} SRetrieveAnalAlgoReq;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t ver;
|
||||||
|
SHashObj* hash; // algoname:algotype -> SAnalUrl
|
||||||
|
} SRetrieveAnalAlgoRsp;
|
||||||
|
|
||||||
|
int32_t tSerializeRetrieveAnalAlgoReq(void* buf, int32_t bufLen, SRetrieveAnalAlgoReq* pReq);
|
||||||
|
int32_t tDeserializeRetrieveAnalAlgoReq(void* buf, int32_t bufLen, SRetrieveAnalAlgoReq* pReq);
|
||||||
|
int32_t tSerializeRetrieveAnalAlgoRsp(void* buf, int32_t bufLen, SRetrieveAnalAlgoRsp* pRsp);
|
||||||
|
int32_t tDeserializeRetrieveAnalAlgoRsp(void* buf, int32_t bufLen, SRetrieveAnalAlgoRsp* pRsp);
|
||||||
|
void tFreeRetrieveAnalAlgoRsp(SRetrieveAnalAlgoRsp* pRsp);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t alterType;
|
int8_t alterType;
|
||||||
int8_t superUser;
|
int8_t superUser;
|
||||||
|
@ -1768,6 +1796,7 @@ typedef struct {
|
||||||
SArray* pVloads; // array of SVnodeLoad
|
SArray* pVloads; // array of SVnodeLoad
|
||||||
int32_t statusSeq;
|
int32_t statusSeq;
|
||||||
int64_t ipWhiteVer;
|
int64_t ipWhiteVer;
|
||||||
|
int64_t analVer;
|
||||||
} SStatusReq;
|
} SStatusReq;
|
||||||
|
|
||||||
int32_t tSerializeSStatusReq(void* buf, int32_t bufLen, SStatusReq* pReq);
|
int32_t tSerializeSStatusReq(void* buf, int32_t bufLen, SStatusReq* pReq);
|
||||||
|
@ -1833,6 +1862,7 @@ typedef struct {
|
||||||
SArray* pDnodeEps; // Array of SDnodeEp
|
SArray* pDnodeEps; // Array of SDnodeEp
|
||||||
int32_t statusSeq;
|
int32_t statusSeq;
|
||||||
int64_t ipWhiteVer;
|
int64_t ipWhiteVer;
|
||||||
|
int64_t analVer;
|
||||||
} SStatusRsp;
|
} SStatusRsp;
|
||||||
|
|
||||||
int32_t tSerializeSStatusRsp(void* buf, int32_t bufLen, SStatusRsp* pRsp);
|
int32_t tSerializeSStatusRsp(void* buf, int32_t bufLen, SStatusRsp* pRsp);
|
||||||
|
@ -2379,6 +2409,30 @@ typedef struct {
|
||||||
int32_t tSerializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq);
|
int32_t tSerializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq);
|
||||||
int32_t tDeserializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq);
|
int32_t tDeserializeSDCreateMnodeReq(void* buf, int32_t bufLen, SDCreateMnodeReq* pReq);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t urlLen;
|
||||||
|
int32_t sqlLen;
|
||||||
|
char* url;
|
||||||
|
char* sql;
|
||||||
|
} SMCreateAnodeReq;
|
||||||
|
|
||||||
|
int32_t tSerializeSMCreateAnodeReq(void* buf, int32_t bufLen, SMCreateAnodeReq* pReq);
|
||||||
|
int32_t tDeserializeSMCreateAnodeReq(void* buf, int32_t bufLen, SMCreateAnodeReq* pReq);
|
||||||
|
void tFreeSMCreateAnodeReq(SMCreateAnodeReq* pReq);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t anodeId;
|
||||||
|
int32_t sqlLen;
|
||||||
|
char* sql;
|
||||||
|
} SMDropAnodeReq, SMUpdateAnodeReq;
|
||||||
|
|
||||||
|
int32_t tSerializeSMDropAnodeReq(void* buf, int32_t bufLen, SMDropAnodeReq* pReq);
|
||||||
|
int32_t tDeserializeSMDropAnodeReq(void* buf, int32_t bufLen, SMDropAnodeReq* pReq);
|
||||||
|
void tFreeSMDropAnodeReq(SMDropAnodeReq* pReq);
|
||||||
|
int32_t tSerializeSMUpdateAnodeReq(void* buf, int32_t bufLen, SMUpdateAnodeReq* pReq);
|
||||||
|
int32_t tDeserializeSMUpdateAnodeReq(void* buf, int32_t bufLen, SMUpdateAnodeReq* pReq);
|
||||||
|
void tFreeSMUpdateAnodeReq(SMUpdateAnodeReq* pReq);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
int32_t hbSeq;
|
int32_t hbSeq;
|
||||||
|
|
|
@ -125,6 +125,11 @@
|
||||||
TD_DEF_MSG_TYPE(TDMT_DND_ALTER_VNODE_TYPE, "dnode-alter-vnode-type", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_DND_ALTER_VNODE_TYPE, "dnode-alter-vnode-type", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP, "dnode-check-vnode-learner-catchup", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP, "dnode-check-vnode-learner-catchup", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_DND_CREATE_ENCRYPT_KEY, "create-encrypt-key", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_DND_CREATE_ENCRYPT_KEY, "create-encrypt-key", NULL, NULL)
|
||||||
|
// mnode msg overload
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_MND_CREATE_ANODE, "create-anode", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_MND_UPDATE_ANODE, "update-anode", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_MND_DROP_ANODE, "drop-anode", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_ANAL_ALGO, "retrieve-anal-algo", NULL, NULL)
|
||||||
TD_CLOSE_MSG_SEG(TDMT_DND_MSG)
|
TD_CLOSE_MSG_SEG(TDMT_DND_MSG)
|
||||||
|
|
||||||
TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8
|
TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8
|
||||||
|
|
|
@ -69,336 +69,343 @@
|
||||||
#define TK_NK_DOT 51
|
#define TK_NK_DOT 51
|
||||||
#define TK_WITH 52
|
#define TK_WITH 52
|
||||||
#define TK_ENCRYPT_KEY 53
|
#define TK_ENCRYPT_KEY 53
|
||||||
#define TK_DNODE 54
|
#define TK_ANODE 54
|
||||||
#define TK_PORT 55
|
#define TK_UPDATE 55
|
||||||
#define TK_DNODES 56
|
#define TK_ANODES 56
|
||||||
#define TK_RESTORE 57
|
#define TK_DNODE 57
|
||||||
#define TK_NK_IPTOKEN 58
|
#define TK_PORT 58
|
||||||
#define TK_FORCE 59
|
#define TK_DNODES 59
|
||||||
#define TK_UNSAFE 60
|
#define TK_RESTORE 60
|
||||||
#define TK_CLUSTER 61
|
#define TK_NK_IPTOKEN 61
|
||||||
#define TK_LOCAL 62
|
#define TK_FORCE 62
|
||||||
#define TK_QNODE 63
|
#define TK_UNSAFE 63
|
||||||
#define TK_BNODE 64
|
#define TK_CLUSTER 64
|
||||||
#define TK_SNODE 65
|
#define TK_LOCAL 65
|
||||||
#define TK_MNODE 66
|
#define TK_QNODE 66
|
||||||
#define TK_VNODE 67
|
#define TK_BNODE 67
|
||||||
#define TK_DATABASE 68
|
#define TK_SNODE 68
|
||||||
#define TK_USE 69
|
#define TK_MNODE 69
|
||||||
#define TK_FLUSH 70
|
#define TK_VNODE 70
|
||||||
#define TK_TRIM 71
|
#define TK_DATABASE 71
|
||||||
#define TK_S3MIGRATE 72
|
#define TK_USE 72
|
||||||
#define TK_COMPACT 73
|
#define TK_FLUSH 73
|
||||||
#define TK_IF 74
|
#define TK_TRIM 74
|
||||||
#define TK_NOT 75
|
#define TK_S3MIGRATE 75
|
||||||
#define TK_EXISTS 76
|
#define TK_COMPACT 76
|
||||||
#define TK_BUFFER 77
|
#define TK_IF 77
|
||||||
#define TK_CACHEMODEL 78
|
#define TK_NOT 78
|
||||||
#define TK_CACHESIZE 79
|
#define TK_EXISTS 79
|
||||||
#define TK_COMP 80
|
#define TK_BUFFER 80
|
||||||
#define TK_DURATION 81
|
#define TK_CACHEMODEL 81
|
||||||
#define TK_NK_VARIABLE 82
|
#define TK_CACHESIZE 82
|
||||||
#define TK_MAXROWS 83
|
#define TK_COMP 83
|
||||||
#define TK_MINROWS 84
|
#define TK_DURATION 84
|
||||||
#define TK_KEEP 85
|
#define TK_NK_VARIABLE 85
|
||||||
#define TK_PAGES 86
|
#define TK_MAXROWS 86
|
||||||
#define TK_PAGESIZE 87
|
#define TK_MINROWS 87
|
||||||
#define TK_TSDB_PAGESIZE 88
|
#define TK_KEEP 88
|
||||||
#define TK_PRECISION 89
|
#define TK_PAGES 89
|
||||||
#define TK_REPLICA 90
|
#define TK_PAGESIZE 90
|
||||||
#define TK_VGROUPS 91
|
#define TK_TSDB_PAGESIZE 91
|
||||||
#define TK_SINGLE_STABLE 92
|
#define TK_PRECISION 92
|
||||||
#define TK_RETENTIONS 93
|
#define TK_REPLICA 93
|
||||||
#define TK_SCHEMALESS 94
|
#define TK_VGROUPS 94
|
||||||
#define TK_WAL_LEVEL 95
|
#define TK_SINGLE_STABLE 95
|
||||||
#define TK_WAL_FSYNC_PERIOD 96
|
#define TK_RETENTIONS 96
|
||||||
#define TK_WAL_RETENTION_PERIOD 97
|
#define TK_SCHEMALESS 97
|
||||||
#define TK_WAL_RETENTION_SIZE 98
|
#define TK_WAL_LEVEL 98
|
||||||
#define TK_WAL_ROLL_PERIOD 99
|
#define TK_WAL_FSYNC_PERIOD 99
|
||||||
#define TK_WAL_SEGMENT_SIZE 100
|
#define TK_WAL_RETENTION_PERIOD 100
|
||||||
#define TK_STT_TRIGGER 101
|
#define TK_WAL_RETENTION_SIZE 101
|
||||||
#define TK_TABLE_PREFIX 102
|
#define TK_WAL_ROLL_PERIOD 102
|
||||||
#define TK_TABLE_SUFFIX 103
|
#define TK_WAL_SEGMENT_SIZE 103
|
||||||
#define TK_S3_CHUNKSIZE 104
|
#define TK_STT_TRIGGER 104
|
||||||
#define TK_S3_KEEPLOCAL 105
|
#define TK_TABLE_PREFIX 105
|
||||||
#define TK_S3_COMPACT 106
|
#define TK_TABLE_SUFFIX 106
|
||||||
#define TK_KEEP_TIME_OFFSET 107
|
#define TK_S3_CHUNKSIZE 107
|
||||||
#define TK_ENCRYPT_ALGORITHM 108
|
#define TK_S3_KEEPLOCAL 108
|
||||||
#define TK_NK_COLON 109
|
#define TK_S3_COMPACT 109
|
||||||
#define TK_BWLIMIT 110
|
#define TK_KEEP_TIME_OFFSET 110
|
||||||
#define TK_START 111
|
#define TK_ENCRYPT_ALGORITHM 111
|
||||||
#define TK_TIMESTAMP 112
|
#define TK_NK_COLON 112
|
||||||
#define TK_END 113
|
#define TK_BWLIMIT 113
|
||||||
#define TK_TABLE 114
|
#define TK_START 114
|
||||||
#define TK_NK_LP 115
|
#define TK_TIMESTAMP 115
|
||||||
#define TK_NK_RP 116
|
#define TK_END 116
|
||||||
#define TK_USING 117
|
#define TK_TABLE 117
|
||||||
#define TK_FILE 118
|
#define TK_NK_LP 118
|
||||||
#define TK_STABLE 119
|
#define TK_NK_RP 119
|
||||||
#define TK_COLUMN 120
|
#define TK_USING 120
|
||||||
#define TK_MODIFY 121
|
#define TK_FILE 121
|
||||||
#define TK_RENAME 122
|
#define TK_STABLE 122
|
||||||
#define TK_TAG 123
|
#define TK_COLUMN 123
|
||||||
#define TK_SET 124
|
#define TK_MODIFY 124
|
||||||
#define TK_NK_EQ 125
|
#define TK_RENAME 125
|
||||||
#define TK_TAGS 126
|
#define TK_TAG 126
|
||||||
#define TK_BOOL 127
|
#define TK_SET 127
|
||||||
#define TK_TINYINT 128
|
#define TK_NK_EQ 128
|
||||||
#define TK_SMALLINT 129
|
#define TK_TAGS 129
|
||||||
#define TK_INT 130
|
#define TK_BOOL 130
|
||||||
#define TK_INTEGER 131
|
#define TK_TINYINT 131
|
||||||
#define TK_BIGINT 132
|
#define TK_SMALLINT 132
|
||||||
#define TK_FLOAT 133
|
#define TK_INT 133
|
||||||
#define TK_DOUBLE 134
|
#define TK_INTEGER 134
|
||||||
#define TK_BINARY 135
|
#define TK_BIGINT 135
|
||||||
#define TK_NCHAR 136
|
#define TK_FLOAT 136
|
||||||
#define TK_UNSIGNED 137
|
#define TK_DOUBLE 137
|
||||||
#define TK_JSON 138
|
#define TK_BINARY 138
|
||||||
#define TK_VARCHAR 139
|
#define TK_NCHAR 139
|
||||||
#define TK_MEDIUMBLOB 140
|
#define TK_UNSIGNED 140
|
||||||
#define TK_BLOB 141
|
#define TK_JSON 141
|
||||||
#define TK_VARBINARY 142
|
#define TK_VARCHAR 142
|
||||||
#define TK_GEOMETRY 143
|
#define TK_MEDIUMBLOB 143
|
||||||
#define TK_DECIMAL 144
|
#define TK_BLOB 144
|
||||||
#define TK_COMMENT 145
|
#define TK_VARBINARY 145
|
||||||
#define TK_MAX_DELAY 146
|
#define TK_GEOMETRY 146
|
||||||
#define TK_WATERMARK 147
|
#define TK_DECIMAL 147
|
||||||
#define TK_ROLLUP 148
|
#define TK_COMMENT 148
|
||||||
#define TK_TTL 149
|
#define TK_MAX_DELAY 149
|
||||||
#define TK_SMA 150
|
#define TK_WATERMARK 150
|
||||||
#define TK_DELETE_MARK 151
|
#define TK_ROLLUP 151
|
||||||
#define TK_FIRST 152
|
#define TK_TTL 152
|
||||||
#define TK_LAST 153
|
#define TK_SMA 153
|
||||||
#define TK_SHOW 154
|
#define TK_DELETE_MARK 154
|
||||||
#define TK_FULL 155
|
#define TK_FIRST 155
|
||||||
#define TK_PRIVILEGES 156
|
#define TK_LAST 156
|
||||||
#define TK_DATABASES 157
|
#define TK_SHOW 157
|
||||||
#define TK_TABLES 158
|
#define TK_FULL 158
|
||||||
#define TK_STABLES 159
|
#define TK_PRIVILEGES 159
|
||||||
#define TK_MNODES 160
|
#define TK_DATABASES 160
|
||||||
#define TK_QNODES 161
|
#define TK_TABLES 161
|
||||||
#define TK_ARBGROUPS 162
|
#define TK_STABLES 162
|
||||||
#define TK_FUNCTIONS 163
|
#define TK_MNODES 163
|
||||||
#define TK_INDEXES 164
|
#define TK_QNODES 164
|
||||||
#define TK_ACCOUNTS 165
|
#define TK_ARBGROUPS 165
|
||||||
#define TK_APPS 166
|
#define TK_FUNCTIONS 166
|
||||||
#define TK_CONNECTIONS 167
|
#define TK_INDEXES 167
|
||||||
#define TK_LICENCES 168
|
#define TK_ACCOUNTS 168
|
||||||
#define TK_GRANTS 169
|
#define TK_APPS 169
|
||||||
#define TK_LOGS 170
|
#define TK_CONNECTIONS 170
|
||||||
#define TK_MACHINES 171
|
#define TK_LICENCES 171
|
||||||
#define TK_ENCRYPTIONS 172
|
#define TK_GRANTS 172
|
||||||
#define TK_QUERIES 173
|
#define TK_LOGS 173
|
||||||
#define TK_SCORES 174
|
#define TK_MACHINES 174
|
||||||
#define TK_TOPICS 175
|
#define TK_ENCRYPTIONS 175
|
||||||
#define TK_VARIABLES 176
|
#define TK_QUERIES 176
|
||||||
#define TK_BNODES 177
|
#define TK_SCORES 177
|
||||||
#define TK_SNODES 178
|
#define TK_TOPICS 178
|
||||||
#define TK_TRANSACTIONS 179
|
#define TK_VARIABLES 179
|
||||||
#define TK_DISTRIBUTED 180
|
#define TK_BNODES 180
|
||||||
#define TK_CONSUMERS 181
|
#define TK_SNODES 181
|
||||||
#define TK_SUBSCRIPTIONS 182
|
#define TK_TRANSACTIONS 182
|
||||||
#define TK_VNODES 183
|
#define TK_DISTRIBUTED 183
|
||||||
#define TK_ALIVE 184
|
#define TK_CONSUMERS 184
|
||||||
#define TK_VIEWS 185
|
#define TK_SUBSCRIPTIONS 185
|
||||||
#define TK_VIEW 186
|
#define TK_VNODES 186
|
||||||
#define TK_COMPACTS 187
|
#define TK_ALIVE 187
|
||||||
#define TK_NORMAL 188
|
#define TK_VIEWS 188
|
||||||
#define TK_CHILD 189
|
#define TK_VIEW 189
|
||||||
#define TK_LIKE 190
|
#define TK_COMPACTS 190
|
||||||
#define TK_TBNAME 191
|
#define TK_NORMAL 191
|
||||||
#define TK_QTAGS 192
|
#define TK_CHILD 192
|
||||||
#define TK_AS 193
|
#define TK_LIKE 193
|
||||||
#define TK_SYSTEM 194
|
#define TK_TBNAME 194
|
||||||
#define TK_TSMA 195
|
#define TK_QTAGS 195
|
||||||
#define TK_INTERVAL 196
|
#define TK_AS 196
|
||||||
#define TK_RECURSIVE 197
|
#define TK_SYSTEM 197
|
||||||
#define TK_TSMAS 198
|
#define TK_TSMA 198
|
||||||
#define TK_FUNCTION 199
|
#define TK_INTERVAL 199
|
||||||
#define TK_INDEX 200
|
#define TK_RECURSIVE 200
|
||||||
#define TK_COUNT 201
|
#define TK_TSMAS 201
|
||||||
#define TK_LAST_ROW 202
|
#define TK_FUNCTION 202
|
||||||
#define TK_META 203
|
#define TK_INDEX 203
|
||||||
#define TK_ONLY 204
|
#define TK_COUNT 204
|
||||||
#define TK_TOPIC 205
|
#define TK_LAST_ROW 205
|
||||||
#define TK_CONSUMER 206
|
#define TK_META 206
|
||||||
#define TK_GROUP 207
|
#define TK_ONLY 207
|
||||||
#define TK_DESC 208
|
#define TK_TOPIC 208
|
||||||
#define TK_DESCRIBE 209
|
#define TK_CONSUMER 209
|
||||||
#define TK_RESET 210
|
#define TK_GROUP 210
|
||||||
#define TK_QUERY 211
|
#define TK_DESC 211
|
||||||
#define TK_CACHE 212
|
#define TK_DESCRIBE 212
|
||||||
#define TK_EXPLAIN 213
|
#define TK_RESET 213
|
||||||
#define TK_ANALYZE 214
|
#define TK_QUERY 214
|
||||||
#define TK_VERBOSE 215
|
#define TK_CACHE 215
|
||||||
#define TK_NK_BOOL 216
|
#define TK_EXPLAIN 216
|
||||||
#define TK_RATIO 217
|
#define TK_ANALYZE 217
|
||||||
#define TK_NK_FLOAT 218
|
#define TK_VERBOSE 218
|
||||||
#define TK_OUTPUTTYPE 219
|
#define TK_NK_BOOL 219
|
||||||
#define TK_AGGREGATE 220
|
#define TK_RATIO 220
|
||||||
#define TK_BUFSIZE 221
|
#define TK_NK_FLOAT 221
|
||||||
#define TK_LANGUAGE 222
|
#define TK_OUTPUTTYPE 222
|
||||||
#define TK_REPLACE 223
|
#define TK_AGGREGATE 223
|
||||||
#define TK_STREAM 224
|
#define TK_BUFSIZE 224
|
||||||
#define TK_INTO 225
|
#define TK_LANGUAGE 225
|
||||||
#define TK_PAUSE 226
|
#define TK_REPLACE 226
|
||||||
#define TK_RESUME 227
|
#define TK_STREAM 227
|
||||||
#define TK_PRIMARY 228
|
#define TK_INTO 228
|
||||||
#define TK_KEY 229
|
#define TK_PAUSE 229
|
||||||
#define TK_TRIGGER 230
|
#define TK_RESUME 230
|
||||||
#define TK_AT_ONCE 231
|
#define TK_PRIMARY 231
|
||||||
#define TK_WINDOW_CLOSE 232
|
#define TK_KEY 232
|
||||||
#define TK_FORCE_WINDOW_CLOSE 233
|
#define TK_TRIGGER 233
|
||||||
#define TK_IGNORE 234
|
#define TK_AT_ONCE 234
|
||||||
#define TK_EXPIRED 235
|
#define TK_WINDOW_CLOSE 235
|
||||||
#define TK_FILL_HISTORY 236
|
#define TK_FORCE_WINDOW_CLOSE 236
|
||||||
#define TK_UPDATE 237
|
#define TK_IGNORE 237
|
||||||
#define TK_SUBTABLE 238
|
#define TK_EXPIRED 238
|
||||||
#define TK_UNTREATED 239
|
#define TK_FILL_HISTORY 239
|
||||||
#define TK_KILL 240
|
#define TK_SUBTABLE 240
|
||||||
#define TK_CONNECTION 241
|
#define TK_UNTREATED 241
|
||||||
#define TK_TRANSACTION 242
|
#define TK_KILL 242
|
||||||
#define TK_BALANCE 243
|
#define TK_CONNECTION 243
|
||||||
#define TK_VGROUP 244
|
#define TK_TRANSACTION 244
|
||||||
#define TK_LEADER 245
|
#define TK_BALANCE 245
|
||||||
#define TK_MERGE 246
|
#define TK_VGROUP 246
|
||||||
#define TK_REDISTRIBUTE 247
|
#define TK_LEADER 247
|
||||||
#define TK_SPLIT 248
|
#define TK_MERGE 248
|
||||||
#define TK_DELETE 249
|
#define TK_REDISTRIBUTE 249
|
||||||
#define TK_INSERT 250
|
#define TK_SPLIT 250
|
||||||
#define TK_NK_BIN 251
|
#define TK_DELETE 251
|
||||||
#define TK_NK_HEX 252
|
#define TK_INSERT 252
|
||||||
#define TK_NULL 253
|
#define TK_NK_BIN 253
|
||||||
#define TK_NK_QUESTION 254
|
#define TK_NK_HEX 254
|
||||||
#define TK_NK_ALIAS 255
|
#define TK_NULL 255
|
||||||
#define TK_NK_ARROW 256
|
#define TK_NK_QUESTION 256
|
||||||
#define TK_ROWTS 257
|
#define TK_NK_ALIAS 257
|
||||||
#define TK_QSTART 258
|
#define TK_NK_ARROW 258
|
||||||
#define TK_QEND 259
|
#define TK_ROWTS 259
|
||||||
#define TK_QDURATION 260
|
#define TK_QSTART 260
|
||||||
#define TK_WSTART 261
|
#define TK_QEND 261
|
||||||
#define TK_WEND 262
|
#define TK_QDURATION 262
|
||||||
#define TK_WDURATION 263
|
#define TK_WSTART 263
|
||||||
#define TK_IROWTS 264
|
#define TK_WEND 264
|
||||||
#define TK_ISFILLED 265
|
#define TK_WDURATION 265
|
||||||
#define TK_CAST 266
|
#define TK_IROWTS 266
|
||||||
#define TK_POSITION 267
|
#define TK_ISFILLED 267
|
||||||
#define TK_IN 268
|
#define TK_FLOW 268
|
||||||
#define TK_FOR 269
|
#define TK_FHIGH 269
|
||||||
#define TK_NOW 270
|
#define TK_FROWTS 270
|
||||||
#define TK_TODAY 271
|
#define TK_CAST 271
|
||||||
#define TK_RAND 272
|
#define TK_POSITION 272
|
||||||
#define TK_SUBSTR 273
|
#define TK_IN 273
|
||||||
#define TK_SUBSTRING 274
|
#define TK_FOR 274
|
||||||
#define TK_BOTH 275
|
#define TK_NOW 275
|
||||||
#define TK_TRAILING 276
|
#define TK_TODAY 276
|
||||||
#define TK_LEADING 277
|
#define TK_RAND 277
|
||||||
#define TK_TIMEZONE 278
|
#define TK_SUBSTR 278
|
||||||
#define TK_CLIENT_VERSION 279
|
#define TK_SUBSTRING 279
|
||||||
#define TK_SERVER_VERSION 280
|
#define TK_BOTH 280
|
||||||
#define TK_SERVER_STATUS 281
|
#define TK_TRAILING 281
|
||||||
#define TK_CURRENT_USER 282
|
#define TK_LEADING 282
|
||||||
#define TK_PI 283
|
#define TK_TIMEZONE 283
|
||||||
#define TK_CASE 284
|
#define TK_CLIENT_VERSION 284
|
||||||
#define TK_WHEN 285
|
#define TK_SERVER_VERSION 285
|
||||||
#define TK_THEN 286
|
#define TK_SERVER_STATUS 286
|
||||||
#define TK_ELSE 287
|
#define TK_CURRENT_USER 287
|
||||||
#define TK_BETWEEN 288
|
#define TK_PI 288
|
||||||
#define TK_IS 289
|
#define TK_CASE 289
|
||||||
#define TK_NK_LT 290
|
#define TK_WHEN 290
|
||||||
#define TK_NK_GT 291
|
#define TK_THEN 291
|
||||||
#define TK_NK_LE 292
|
#define TK_ELSE 292
|
||||||
#define TK_NK_GE 293
|
#define TK_BETWEEN 293
|
||||||
#define TK_NK_NE 294
|
#define TK_IS 294
|
||||||
#define TK_MATCH 295
|
#define TK_NK_LT 295
|
||||||
#define TK_NMATCH 296
|
#define TK_NK_GT 296
|
||||||
#define TK_CONTAINS 297
|
#define TK_NK_LE 297
|
||||||
#define TK_JOIN 298
|
#define TK_NK_GE 298
|
||||||
#define TK_INNER 299
|
#define TK_NK_NE 299
|
||||||
#define TK_LEFT 300
|
#define TK_MATCH 300
|
||||||
#define TK_RIGHT 301
|
#define TK_NMATCH 301
|
||||||
#define TK_OUTER 302
|
#define TK_CONTAINS 302
|
||||||
#define TK_SEMI 303
|
#define TK_JOIN 303
|
||||||
#define TK_ANTI 304
|
#define TK_INNER 304
|
||||||
#define TK_ASOF 305
|
#define TK_LEFT 305
|
||||||
#define TK_WINDOW 306
|
#define TK_RIGHT 306
|
||||||
#define TK_WINDOW_OFFSET 307
|
#define TK_OUTER 307
|
||||||
#define TK_JLIMIT 308
|
#define TK_SEMI 308
|
||||||
#define TK_SELECT 309
|
#define TK_ANTI 309
|
||||||
#define TK_NK_HINT 310
|
#define TK_ASOF 310
|
||||||
#define TK_DISTINCT 311
|
#define TK_WINDOW 311
|
||||||
#define TK_WHERE 312
|
#define TK_WINDOW_OFFSET 312
|
||||||
#define TK_PARTITION 313
|
#define TK_JLIMIT 313
|
||||||
#define TK_BY 314
|
#define TK_SELECT 314
|
||||||
#define TK_SESSION 315
|
#define TK_NK_HINT 315
|
||||||
#define TK_STATE_WINDOW 316
|
#define TK_DISTINCT 316
|
||||||
#define TK_EVENT_WINDOW 317
|
#define TK_WHERE 317
|
||||||
#define TK_COUNT_WINDOW 318
|
#define TK_PARTITION 318
|
||||||
#define TK_SLIDING 319
|
#define TK_BY 319
|
||||||
#define TK_FILL 320
|
#define TK_SESSION 320
|
||||||
#define TK_VALUE 321
|
#define TK_STATE_WINDOW 321
|
||||||
#define TK_VALUE_F 322
|
#define TK_EVENT_WINDOW 322
|
||||||
#define TK_NONE 323
|
#define TK_COUNT_WINDOW 323
|
||||||
#define TK_PREV 324
|
#define TK_ANOMALY_WINDOW 324
|
||||||
#define TK_NULL_F 325
|
#define TK_SLIDING 325
|
||||||
#define TK_LINEAR 326
|
#define TK_FILL 326
|
||||||
#define TK_NEXT 327
|
#define TK_VALUE 327
|
||||||
#define TK_HAVING 328
|
#define TK_VALUE_F 328
|
||||||
#define TK_RANGE 329
|
#define TK_NONE 329
|
||||||
#define TK_EVERY 330
|
#define TK_PREV 330
|
||||||
#define TK_ORDER 331
|
#define TK_NULL_F 331
|
||||||
#define TK_SLIMIT 332
|
#define TK_LINEAR 332
|
||||||
#define TK_SOFFSET 333
|
#define TK_NEXT 333
|
||||||
#define TK_LIMIT 334
|
#define TK_HAVING 334
|
||||||
#define TK_OFFSET 335
|
#define TK_RANGE 335
|
||||||
#define TK_ASC 336
|
#define TK_EVERY 336
|
||||||
#define TK_NULLS 337
|
#define TK_ORDER 337
|
||||||
#define TK_ABORT 338
|
#define TK_SLIMIT 338
|
||||||
#define TK_AFTER 339
|
#define TK_SOFFSET 339
|
||||||
#define TK_ATTACH 340
|
#define TK_LIMIT 340
|
||||||
#define TK_BEFORE 341
|
#define TK_OFFSET 341
|
||||||
#define TK_BEGIN 342
|
#define TK_ASC 342
|
||||||
#define TK_BITAND 343
|
#define TK_NULLS 343
|
||||||
#define TK_BITNOT 344
|
#define TK_ABORT 344
|
||||||
#define TK_BITOR 345
|
#define TK_AFTER 345
|
||||||
#define TK_BLOCKS 346
|
#define TK_ATTACH 346
|
||||||
#define TK_CHANGE 347
|
#define TK_BEFORE 347
|
||||||
#define TK_COMMA 348
|
#define TK_BEGIN 348
|
||||||
#define TK_CONCAT 349
|
#define TK_BITAND 349
|
||||||
#define TK_CONFLICT 350
|
#define TK_BITNOT 350
|
||||||
#define TK_COPY 351
|
#define TK_BITOR 351
|
||||||
#define TK_DEFERRED 352
|
#define TK_BLOCKS 352
|
||||||
#define TK_DELIMITERS 353
|
#define TK_CHANGE 353
|
||||||
#define TK_DETACH 354
|
#define TK_COMMA 354
|
||||||
#define TK_DIVIDE 355
|
#define TK_CONCAT 355
|
||||||
#define TK_DOT 356
|
#define TK_CONFLICT 356
|
||||||
#define TK_EACH 357
|
#define TK_COPY 357
|
||||||
#define TK_FAIL 358
|
#define TK_DEFERRED 358
|
||||||
#define TK_GLOB 359
|
#define TK_DELIMITERS 359
|
||||||
#define TK_ID 360
|
#define TK_DETACH 360
|
||||||
#define TK_IMMEDIATE 361
|
#define TK_DIVIDE 361
|
||||||
#define TK_IMPORT 362
|
#define TK_DOT 362
|
||||||
#define TK_INITIALLY 363
|
#define TK_EACH 363
|
||||||
#define TK_INSTEAD 364
|
#define TK_FAIL 364
|
||||||
#define TK_ISNULL 365
|
#define TK_GLOB 365
|
||||||
#define TK_MODULES 366
|
#define TK_ID 366
|
||||||
#define TK_NK_BITNOT 367
|
#define TK_IMMEDIATE 367
|
||||||
#define TK_NK_SEMI 368
|
#define TK_IMPORT 368
|
||||||
#define TK_NOTNULL 369
|
#define TK_INITIALLY 369
|
||||||
#define TK_OF 370
|
#define TK_INSTEAD 370
|
||||||
#define TK_PLUS 371
|
#define TK_ISNULL 371
|
||||||
#define TK_PRIVILEGE 372
|
#define TK_MODULES 372
|
||||||
#define TK_RAISE 373
|
#define TK_NK_BITNOT 373
|
||||||
#define TK_RESTRICT 374
|
#define TK_NK_SEMI 374
|
||||||
#define TK_ROW 375
|
#define TK_NOTNULL 375
|
||||||
#define TK_STAR 376
|
#define TK_OF 376
|
||||||
#define TK_STATEMENT 377
|
#define TK_PLUS 377
|
||||||
#define TK_STRICT 378
|
#define TK_PRIVILEGE 378
|
||||||
#define TK_STRING 379
|
#define TK_RAISE 379
|
||||||
#define TK_TIMES 380
|
#define TK_RESTRICT 380
|
||||||
#define TK_VALUES 381
|
#define TK_ROW 381
|
||||||
#define TK_VARIABLE 382
|
#define TK_STAR 382
|
||||||
#define TK_WAL 383
|
#define TK_STATEMENT 383
|
||||||
|
#define TK_STRICT 384
|
||||||
|
#define TK_STRING 385
|
||||||
|
#define TK_TIMES 386
|
||||||
|
#define TK_VALUES 387
|
||||||
|
#define TK_VARIABLE 388
|
||||||
|
#define TK_WAL 389
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TK_NK_SPACE 600
|
#define TK_NK_SPACE 600
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct SqlFunctionCtx;
|
||||||
struct SResultRowEntryInfo;
|
struct SResultRowEntryInfo;
|
||||||
|
|
||||||
struct SFunctionNode;
|
struct SFunctionNode;
|
||||||
|
struct SExprSupp;
|
||||||
typedef struct SScalarParam SScalarParam;
|
typedef struct SScalarParam SScalarParam;
|
||||||
typedef struct SStreamState SStreamState;
|
typedef struct SStreamState SStreamState;
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ typedef int32_t (*FExecProcess)(struct SqlFunctionCtx *pCtx);
|
||||||
typedef int32_t (*FExecFinalize)(struct SqlFunctionCtx *pCtx, SSDataBlock *pBlock);
|
typedef int32_t (*FExecFinalize)(struct SqlFunctionCtx *pCtx, SSDataBlock *pBlock);
|
||||||
typedef int32_t (*FScalarExecProcess)(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
typedef int32_t (*FScalarExecProcess)(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
typedef int32_t (*FExecCombine)(struct SqlFunctionCtx *pDestCtx, struct SqlFunctionCtx *pSourceCtx);
|
typedef int32_t (*FExecCombine)(struct SqlFunctionCtx *pDestCtx, struct SqlFunctionCtx *pSourceCtx);
|
||||||
|
typedef int32_t (*FExecDecode)(struct SqlFunctionCtx *pCtx, const char *buf, struct SResultRowEntryInfo *pResultCellInfo, int32_t version);
|
||||||
typedef int32_t (*processFuncByRow)(SArray* pCtx); // array of SqlFunctionCtx
|
typedef int32_t (*processFuncByRow)(SArray* pCtx); // array of SqlFunctionCtx
|
||||||
|
|
||||||
typedef struct SScalarFuncExecFuncs {
|
typedef struct SScalarFuncExecFuncs {
|
||||||
|
@ -57,6 +59,7 @@ typedef struct SFuncExecFuncs {
|
||||||
FExecFinalize finalize;
|
FExecFinalize finalize;
|
||||||
FExecCombine combine;
|
FExecCombine combine;
|
||||||
FExecCleanUp cleanup;
|
FExecCleanUp cleanup;
|
||||||
|
FExecDecode decode;
|
||||||
processFuncByRow processFuncByRow;
|
processFuncByRow processFuncByRow;
|
||||||
} SFuncExecFuncs;
|
} SFuncExecFuncs;
|
||||||
|
|
||||||
|
@ -65,6 +68,8 @@ typedef struct SFuncExecFuncs {
|
||||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||||
#define FUNCTIONS_NAME_MAX_LENGTH 32
|
#define FUNCTIONS_NAME_MAX_LENGTH 32
|
||||||
|
|
||||||
|
#define FUNCTION_RESULT_INFO_VERSION 1
|
||||||
|
|
||||||
typedef struct SResultRowEntryInfo {
|
typedef struct SResultRowEntryInfo {
|
||||||
bool initialized : 1; // output buffer has been initialized
|
bool initialized : 1; // output buffer has been initialized
|
||||||
bool complete : 1; // query has completed
|
bool complete : 1; // query has completed
|
||||||
|
@ -165,6 +170,11 @@ typedef struct STdbState {
|
||||||
void *txn;
|
void *txn;
|
||||||
} STdbState;
|
} STdbState;
|
||||||
|
|
||||||
|
typedef struct SResultRowStore {
|
||||||
|
int32_t (*resultRowPut)(struct SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize);
|
||||||
|
int32_t (*resultRowGet)(struct SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize);
|
||||||
|
} SResultRowStore;
|
||||||
|
|
||||||
struct SStreamState {
|
struct SStreamState {
|
||||||
STdbState *pTdbState;
|
STdbState *pTdbState;
|
||||||
struct SStreamFileState *pFileState;
|
struct SStreamFileState *pFileState;
|
||||||
|
@ -175,6 +185,8 @@ struct SStreamState {
|
||||||
int64_t streamBackendRid;
|
int64_t streamBackendRid;
|
||||||
int8_t dump;
|
int8_t dump;
|
||||||
int32_t tsIndex;
|
int32_t tsIndex;
|
||||||
|
SResultRowStore pResultRowStore;
|
||||||
|
struct SExprSupp *pExprSupp;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SFunctionStateStore {
|
typedef struct SFunctionStateStore {
|
||||||
|
|
|
@ -62,6 +62,7 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_UNIQUE,
|
FUNCTION_TYPE_UNIQUE,
|
||||||
FUNCTION_TYPE_STATE_COUNT,
|
FUNCTION_TYPE_STATE_COUNT,
|
||||||
FUNCTION_TYPE_STATE_DURATION,
|
FUNCTION_TYPE_STATE_DURATION,
|
||||||
|
FUNCTION_TYPE_FORECAST,
|
||||||
|
|
||||||
// math function
|
// math function
|
||||||
FUNCTION_TYPE_ABS = 1000,
|
FUNCTION_TYPE_ABS = 1000,
|
||||||
|
@ -149,6 +150,9 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_TBUID,
|
FUNCTION_TYPE_TBUID,
|
||||||
FUNCTION_TYPE_VGID,
|
FUNCTION_TYPE_VGID,
|
||||||
FUNCTION_TYPE_VGVER,
|
FUNCTION_TYPE_VGVER,
|
||||||
|
FUNCTION_TYPE_FORECAST_LOW,
|
||||||
|
FUNCTION_TYPE_FORECAST_HIGH,
|
||||||
|
FUNCTION_TYPE_FORECAST_ROWTS,
|
||||||
|
|
||||||
// internal function
|
// internal function
|
||||||
FUNCTION_TYPE_SELECT_VALUE = 3750,
|
FUNCTION_TYPE_SELECT_VALUE = 3750,
|
||||||
|
@ -263,6 +267,7 @@ bool fmIsForbidSysTableFunc(int32_t funcId);
|
||||||
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
bool fmIsIntervalInterpoFunc(int32_t funcId);
|
||||||
bool fmIsInterpFunc(int32_t funcId);
|
bool fmIsInterpFunc(int32_t funcId);
|
||||||
bool fmIsLastRowFunc(int32_t funcId);
|
bool fmIsLastRowFunc(int32_t funcId);
|
||||||
|
bool fmIsForecastFunc(int32_t funcId);
|
||||||
bool fmIsNotNullOutputFunc(int32_t funcId);
|
bool fmIsNotNullOutputFunc(int32_t funcId);
|
||||||
bool fmIsSelectValueFunc(int32_t funcId);
|
bool fmIsSelectValueFunc(int32_t funcId);
|
||||||
bool fmIsSystemInfoFunc(int32_t funcId);
|
bool fmIsSystemInfoFunc(int32_t funcId);
|
||||||
|
@ -272,6 +277,7 @@ bool fmIsMultiRowsFunc(int32_t funcId);
|
||||||
bool fmIsKeepOrderFunc(int32_t funcId);
|
bool fmIsKeepOrderFunc(int32_t funcId);
|
||||||
bool fmIsCumulativeFunc(int32_t funcId);
|
bool fmIsCumulativeFunc(int32_t funcId);
|
||||||
bool fmIsInterpPseudoColumnFunc(int32_t funcId);
|
bool fmIsInterpPseudoColumnFunc(int32_t funcId);
|
||||||
|
bool fmIsForecastPseudoColumnFunc(int32_t funcId);
|
||||||
bool fmIsGroupKeyFunc(int32_t funcId);
|
bool fmIsGroupKeyFunc(int32_t funcId);
|
||||||
bool fmIsBlockDistFunc(int32_t funcId);
|
bool fmIsBlockDistFunc(int32_t funcId);
|
||||||
bool fmIsIgnoreNullFunc(int32_t funcId);
|
bool fmIsIgnoreNullFunc(int32_t funcId);
|
||||||
|
|
|
@ -318,6 +318,21 @@ typedef struct SAlterDnodeStmt {
|
||||||
char value[TSDB_DNODE_VALUE_LEN];
|
char value[TSDB_DNODE_VALUE_LEN];
|
||||||
} SAlterDnodeStmt;
|
} SAlterDnodeStmt;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ENodeType type;
|
||||||
|
char url[TSDB_ANAL_ANODE_URL_LEN + 3];
|
||||||
|
} SCreateAnodeStmt;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ENodeType type;
|
||||||
|
int32_t anodeId;
|
||||||
|
} SDropAnodeStmt;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ENodeType type;
|
||||||
|
int32_t anodeId;
|
||||||
|
} SUpdateAnodeStmt;
|
||||||
|
|
||||||
typedef struct SShowStmt {
|
typedef struct SShowStmt {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
SNode* pDbName; // SValueNode
|
SNode* pDbName; // SValueNode
|
||||||
|
|
|
@ -216,6 +216,11 @@ typedef struct SInterpFuncLogicNode {
|
||||||
SStreamNodeOption streamNodeOption;
|
SStreamNodeOption streamNodeOption;
|
||||||
} SInterpFuncLogicNode;
|
} SInterpFuncLogicNode;
|
||||||
|
|
||||||
|
typedef struct SForecastFuncLogicNode {
|
||||||
|
SLogicNode node;
|
||||||
|
SNodeList* pFuncs;
|
||||||
|
} SForecastFuncLogicNode;
|
||||||
|
|
||||||
typedef struct SGroupCacheLogicNode {
|
typedef struct SGroupCacheLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
bool grpColsMayBeNull;
|
bool grpColsMayBeNull;
|
||||||
|
@ -287,6 +292,7 @@ typedef enum EWindowType {
|
||||||
WINDOW_TYPE_STATE,
|
WINDOW_TYPE_STATE,
|
||||||
WINDOW_TYPE_EVENT,
|
WINDOW_TYPE_EVENT,
|
||||||
WINDOW_TYPE_COUNT,
|
WINDOW_TYPE_COUNT,
|
||||||
|
WINDOW_TYPE_ANOMALY
|
||||||
} EWindowType;
|
} EWindowType;
|
||||||
|
|
||||||
typedef enum EWindowAlgorithm {
|
typedef enum EWindowAlgorithm {
|
||||||
|
@ -327,6 +333,8 @@ typedef struct SWindowLogicNode {
|
||||||
int64_t windowCount;
|
int64_t windowCount;
|
||||||
int64_t windowSliding;
|
int64_t windowSliding;
|
||||||
SNodeList* pTsmaSubplans;
|
SNodeList* pTsmaSubplans;
|
||||||
|
SNode* pAnomalyExpr;
|
||||||
|
char anomalyOpt[TSDB_ANAL_ALGO_OPTION_LEN];
|
||||||
} SWindowLogicNode;
|
} SWindowLogicNode;
|
||||||
|
|
||||||
typedef struct SFillLogicNode {
|
typedef struct SFillLogicNode {
|
||||||
|
@ -523,6 +531,12 @@ typedef struct SInterpFuncPhysiNode {
|
||||||
|
|
||||||
typedef SInterpFuncPhysiNode SStreamInterpFuncPhysiNode;
|
typedef SInterpFuncPhysiNode SStreamInterpFuncPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SForecastFuncPhysiNode {
|
||||||
|
SPhysiNode node;
|
||||||
|
SNodeList* pExprs;
|
||||||
|
SNodeList* pFuncs;
|
||||||
|
} SForecastFuncPhysiNode;
|
||||||
|
|
||||||
typedef struct SSortMergeJoinPhysiNode {
|
typedef struct SSortMergeJoinPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
EJoinType joinType;
|
EJoinType joinType;
|
||||||
|
@ -720,6 +734,12 @@ typedef struct SCountWinodwPhysiNode {
|
||||||
|
|
||||||
typedef SCountWinodwPhysiNode SStreamCountWinodwPhysiNode;
|
typedef SCountWinodwPhysiNode SStreamCountWinodwPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SAnomalyWindowPhysiNode {
|
||||||
|
SWindowPhysiNode window;
|
||||||
|
SNode* pAnomalyKey;
|
||||||
|
char anomalyOpt[TSDB_ANAL_ALGO_OPTION_LEN];
|
||||||
|
} SAnomalyWindowPhysiNode;
|
||||||
|
|
||||||
typedef struct SSortPhysiNode {
|
typedef struct SSortPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function
|
SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function
|
||||||
|
|
|
@ -347,6 +347,13 @@ typedef struct SCountWindowNode {
|
||||||
int64_t windowSliding;
|
int64_t windowSliding;
|
||||||
} SCountWindowNode;
|
} SCountWindowNode;
|
||||||
|
|
||||||
|
typedef struct SAnomalyWindowNode {
|
||||||
|
ENodeType type; // QUERY_NODE_ANOMALY_WINDOW
|
||||||
|
SNode* pCol; // timestamp primary key
|
||||||
|
SNode* pExpr;
|
||||||
|
char anomalyOpt[TSDB_ANAL_ALGO_OPTION_LEN];
|
||||||
|
} SAnomalyWindowNode;
|
||||||
|
|
||||||
typedef enum EFillMode {
|
typedef enum EFillMode {
|
||||||
FILL_MODE_NONE = 1,
|
FILL_MODE_NONE = 1,
|
||||||
FILL_MODE_VALUE,
|
FILL_MODE_VALUE,
|
||||||
|
@ -442,6 +449,8 @@ typedef struct SSelectStmt {
|
||||||
bool hasTailFunc;
|
bool hasTailFunc;
|
||||||
bool hasInterpFunc;
|
bool hasInterpFunc;
|
||||||
bool hasInterpPseudoColFunc;
|
bool hasInterpPseudoColFunc;
|
||||||
|
bool hasForecastFunc;
|
||||||
|
bool hasForecastPseudoColFunc;
|
||||||
bool hasLastRowFunc;
|
bool hasLastRowFunc;
|
||||||
bool hasLastFunc;
|
bool hasLastFunc;
|
||||||
bool hasTimeLineFunc;
|
bool hasTimeLineFunc;
|
||||||
|
|
|
@ -139,6 +139,7 @@ int32_t mavgScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam
|
||||||
int32_t hllScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t hllScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t csumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t csumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t diffScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t diffScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
int32_t forecastScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t stateCountScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t stateCountScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t stateDurationScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t stateDurationScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t histogramScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t histogramScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
|
|
@ -89,9 +89,9 @@ int32_t taosResetTerminalMode();
|
||||||
snprintf(array[size], STACKSIZE, "0x%lx : (%s+0x%lx) [0x%lx]\n", (long)pc, fname, (long)offset, (long)pc); \
|
snprintf(array[size], STACKSIZE, "0x%lx : (%s+0x%lx) [0x%lx]\n", (long)pc, fname, (long)offset, (long)pc); \
|
||||||
} \
|
} \
|
||||||
if (ignoreNum < size && size > 0) { \
|
if (ignoreNum < size && size > 0) { \
|
||||||
offset = snprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? size - ignoreNum : size); \
|
offset = tsnprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? size - ignoreNum : size); \
|
||||||
for (int32_t i = (ignoreNum > 0) ? ignoreNum : 0; i < size; i++) { \
|
for (int32_t i = (ignoreNum > 0) ? ignoreNum : 0; i < size; i++) { \
|
||||||
offset += snprintf(buf + offset, bufSize - 1 - offset, "frame:%d, %s\n", (ignoreNum > 0) ? i - ignoreNum : i, \
|
offset += tsnprintf(buf + offset, bufSize - 1 - offset, "frame:%d, %s\n", (ignoreNum > 0) ? i - ignoreNum : i, \
|
||||||
array[i]); \
|
array[i]); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -140,9 +140,9 @@ int32_t taosResetTerminalMode();
|
||||||
char **strings = backtrace_symbols(array, size); \
|
char **strings = backtrace_symbols(array, size); \
|
||||||
int32_t offset = 0; \
|
int32_t offset = 0; \
|
||||||
if (strings != NULL) { \
|
if (strings != NULL) { \
|
||||||
offset = snprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? size - ignoreNum : size); \
|
offset = tsnprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? size - ignoreNum : size); \
|
||||||
for (int32_t i = (ignoreNum > 0) ? ignoreNum : 0; i < size; i++) { \
|
for (int32_t i = (ignoreNum > 0) ? ignoreNum : 0; i < size; i++) { \
|
||||||
offset += snprintf(buf + offset, bufSize - 1 - offset, "frame:%d, %s\n", (ignoreNum > 0) ? i - ignoreNum : i, \
|
offset += tsnprintf(buf + offset, bufSize - 1 - offset, "frame:%d, %s\n", (ignoreNum > 0) ? i - ignoreNum : i, \
|
||||||
strings[i]); \
|
strings[i]); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -193,7 +193,7 @@ int32_t taosResetTerminalMode();
|
||||||
snprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? frames - ignoreNum : frames); \
|
snprintf(buf, bufSize - 1, "obtained %d stack frames\n", (ignoreNum > 0) ? frames - ignoreNum : frames); \
|
||||||
for (i = (ignoreNum > 0) ? ignoreNum : 0; i < frames; i++) { \
|
for (i = (ignoreNum > 0) ? ignoreNum : 0; i < frames; i++) { \
|
||||||
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); \
|
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); \
|
||||||
offset += snprintf(buf + offset, bufSize - 1 - offset, "frame:%i, %s - 0x%0X\n", \
|
offset += tsnprintf(buf + offset, bufSize - 1 - offset, "frame:%i, %s - 0x%0X\n", \
|
||||||
(ignoreNum > 0) ? i - ignoreNum : i, symbol->Name, symbol->Address); \
|
(ignoreNum > 0) ? i - ignoreNum : i, symbol->Name, symbol->Address); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -476,6 +476,26 @@ int32_t taosGetErrSize();
|
||||||
#define TSDB_CODE_DNODE_INVALID_MONITOR_PARAS TAOS_DEF_ERROR_CODE(0, 0x0429)
|
#define TSDB_CODE_DNODE_INVALID_MONITOR_PARAS TAOS_DEF_ERROR_CODE(0, 0x0429)
|
||||||
#define TSDB_CODE_MNODE_STOPPED TAOS_DEF_ERROR_CODE(0, 0x042A)
|
#define TSDB_CODE_MNODE_STOPPED TAOS_DEF_ERROR_CODE(0, 0x042A)
|
||||||
|
|
||||||
|
// anode
|
||||||
|
#define TSDB_CODE_MND_ANODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0430)
|
||||||
|
#define TSDB_CODE_MND_ANODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0431)
|
||||||
|
#define TSDB_CODE_MND_ANODE_TOO_LONG_URL TAOS_DEF_ERROR_CODE(0, 0x0432)
|
||||||
|
#define TSDB_CODE_MND_ANODE_INVALID_PROTOCOL TAOS_DEF_ERROR_CODE(0, 0x0433)
|
||||||
|
#define TSDB_CODE_MND_ANODE_INVALID_VERSION TAOS_DEF_ERROR_CODE(0, 0x0434)
|
||||||
|
#define TSDB_CODE_MND_ANODE_INVALID_ALGO_TYPE TAOS_DEF_ERROR_CODE(0, 0x0435)
|
||||||
|
#define TSDB_CODE_MND_ANODE_TOO_MANY_ALGO TAOS_DEF_ERROR_CODE(0, 0x0436)
|
||||||
|
#define TSDB_CODE_MND_ANODE_TOO_LONG_ALGO_NAME TAOS_DEF_ERROR_CODE(0, 0x0437)
|
||||||
|
#define TSDB_CODE_MND_ANODE_TOO_MANY_ALGO_TYPE TAOS_DEF_ERROR_CODE(0, 0x0438)
|
||||||
|
|
||||||
|
// analysis
|
||||||
|
#define TSDB_CODE_ANAL_URL_RSP_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x0440)
|
||||||
|
#define TSDB_CODE_ANAL_URL_CANT_ACCESS TAOS_DEF_ERROR_CODE(0, 0x0441)
|
||||||
|
#define TSDB_CODE_ANAL_ALGO_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0442)
|
||||||
|
#define TSDB_CODE_ANAL_ALGO_NOT_LOAD TAOS_DEF_ERROR_CODE(0, 0x0443)
|
||||||
|
#define TSDB_CODE_ANAL_BUF_INVALID_TYPE TAOS_DEF_ERROR_CODE(0, 0x0444)
|
||||||
|
#define TSDB_CODE_ANAL_ANODE_RETURN_ERROR TAOS_DEF_ERROR_CODE(0, 0x0445)
|
||||||
|
#define TSDB_CODE_ANAL_ANODE_TOO_MANY_ROWS TAOS_DEF_ERROR_CODE(0, 0x0446)
|
||||||
|
|
||||||
// mnode-sma
|
// mnode-sma
|
||||||
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
|
#define TSDB_CODE_MND_SMA_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0480)
|
||||||
#define TSDB_CODE_MND_SMA_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0481)
|
#define TSDB_CODE_MND_SMA_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0481)
|
||||||
|
@ -867,6 +887,10 @@ int32_t taosGetErrSize();
|
||||||
#define TSDB_CODE_PAR_TAG_NAME_DUPLICATED TAOS_DEF_ERROR_CODE(0, 0x267F)
|
#define TSDB_CODE_PAR_TAG_NAME_DUPLICATED TAOS_DEF_ERROR_CODE(0, 0x267F)
|
||||||
#define TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC TAOS_DEF_ERROR_CODE(0, 0x2680)
|
#define TSDB_CODE_PAR_NOT_ALLOWED_DIFFERENT_BY_ROW_FUNC TAOS_DEF_ERROR_CODE(0, 0x2680)
|
||||||
#define TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2681)
|
#define TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2681)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_ANOMALY_WIN_TYPE TAOS_DEF_ERROR_CODE(0, 0x2682)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_ANOMALY_WIN_COL TAOS_DEF_ERROR_CODE(0, 0x2683)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_ANOMALY_WIN_OPT TAOS_DEF_ERROR_CODE(0, 0x2684)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_FORECAST_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x2685)
|
||||||
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
|
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
|
||||||
|
|
||||||
//planner
|
//planner
|
||||||
|
|
|
@ -293,6 +293,12 @@ typedef enum ELogicConditionType {
|
||||||
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
#define TSDB_SLOW_QUERY_SQL_LEN 512
|
||||||
#define TSDB_SHOW_SUBQUERY_LEN 1000
|
#define TSDB_SHOW_SUBQUERY_LEN 1000
|
||||||
#define TSDB_LOG_VAR_LEN 32
|
#define TSDB_LOG_VAR_LEN 32
|
||||||
|
#define TSDB_ANAL_ANODE_URL_LEN 128
|
||||||
|
#define TSDB_ANAL_ALGO_NAME_LEN 64
|
||||||
|
#define TSDB_ANAL_ALGO_TYPE_LEN 24
|
||||||
|
#define TSDB_ANAL_ALGO_KEY_LEN (TSDB_ANAL_ALGO_NAME_LEN + 9)
|
||||||
|
#define TSDB_ANAL_ALGO_URL_LEN (TSDB_ANAL_ANODE_URL_LEN + TSDB_ANAL_ALGO_TYPE_LEN + 1)
|
||||||
|
#define TSDB_ANAL_ALGO_OPTION_LEN 256
|
||||||
|
|
||||||
#define TSDB_MAX_EP_NUM 10
|
#define TSDB_MAX_EP_NUM 10
|
||||||
|
|
||||||
|
@ -604,6 +610,12 @@ enum { RAND_ERR_MEMORY = 1, RAND_ERR_FILE = 2, RAND_ERR_NETWORK = 4 };
|
||||||
#define MONITOR_TAG_VALUE_LEN 300
|
#define MONITOR_TAG_VALUE_LEN 300
|
||||||
#define MONITOR_METRIC_NAME_LEN 100
|
#define MONITOR_METRIC_NAME_LEN 100
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANAL_ALGO_TYPE_ANOMALY_DETECT = 0,
|
||||||
|
ANAL_ALGO_TYPE_FORECAST = 1,
|
||||||
|
ANAL_ALGO_TYPE_END,
|
||||||
|
} EAnalAlgoType;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,7 +68,10 @@ int32_t tjsonAddItemToArray(SJson* pJson, SJson* pItem);
|
||||||
SJson* tjsonGetObjectItem(const SJson* pJson, const char* pName);
|
SJson* tjsonGetObjectItem(const SJson* pJson, const char* pName);
|
||||||
int32_t tjsonGetObjectName(const SJson* pJson, char** pName);
|
int32_t tjsonGetObjectName(const SJson* pJson, char** pName);
|
||||||
int32_t tjsonGetObjectValueString(const SJson* pJson, char** pStringValue);
|
int32_t tjsonGetObjectValueString(const SJson* pJson, char** pStringValue);
|
||||||
|
void tjsonGetObjectValueBigInt(const SJson* pJson, int64_t* pVal);
|
||||||
|
void tjsonGetObjectValueDouble(const SJson* pJson, double* pVal);
|
||||||
int32_t tjsonGetStringValue(const SJson* pJson, const char* pName, char* pVal);
|
int32_t tjsonGetStringValue(const SJson* pJson, const char* pName, char* pVal);
|
||||||
|
int32_t tjsonGetStringValue2(const SJson* pJson, const char* pName, char* pVal, int32_t maxLen);
|
||||||
int32_t tjsonDupStringValue(const SJson* pJson, const char* pName, char** pVal);
|
int32_t tjsonDupStringValue(const SJson* pJson, const char* pName, char** pVal);
|
||||||
int32_t tjsonGetBigIntValue(const SJson* pJson, const char* pName, int64_t* pVal);
|
int32_t tjsonGetBigIntValue(const SJson* pJson, const char* pName, int64_t* pVal);
|
||||||
int32_t tjsonGetIntValue(const SJson* pJson, const char* pName, int32_t* pVal);
|
int32_t tjsonGetIntValue(const SJson* pJson, const char* pName, int32_t* pVal);
|
||||||
|
|
|
@ -123,8 +123,8 @@ void taosReleaseCrashLogFile(TdFilePtr pFile, bool truncateFile);
|
||||||
#define uInfo(...) { if (uDebugFlag & DEBUG_INFO) { taosPrintLog("UTL ", DEBUG_INFO, tsLogEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
|
#define uInfo(...) { if (uDebugFlag & DEBUG_INFO) { taosPrintLog("UTL ", DEBUG_INFO, tsLogEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
|
||||||
#define uDebug(...) { if (uDebugFlag & DEBUG_DEBUG) { taosPrintLog("UTL ", DEBUG_DEBUG, uDebugFlag, __VA_ARGS__); }}
|
#define uDebug(...) { if (uDebugFlag & DEBUG_DEBUG) { taosPrintLog("UTL ", DEBUG_DEBUG, uDebugFlag, __VA_ARGS__); }}
|
||||||
#define uTrace(...) { if (uDebugFlag & DEBUG_TRACE) { taosPrintLog("UTL ", DEBUG_TRACE, uDebugFlag, __VA_ARGS__); }}
|
#define uTrace(...) { if (uDebugFlag & DEBUG_TRACE) { taosPrintLog("UTL ", DEBUG_TRACE, uDebugFlag, __VA_ARGS__); }}
|
||||||
#define uDebugL(...) { if (uDebugFlag & DEBUG_DEBUG) { taosPrintLongString("UTL ", DEBUG_DEBUG, uDebugFlag, __VA_ARGS__); }}
|
#define uDebugL(...){ if (uDebugFlag & DEBUG_DEBUG) { taosPrintLongString("UTL ", DEBUG_DEBUG, uDebugFlag, __VA_ARGS__); }}
|
||||||
#define uInfoL(...) { if (uDebugFlag & DEBUG_INFO) { taosPrintLongString("UTL ", DEBUG_INFO, uDebugFlag, __VA_ARGS__); }}
|
#define uInfoL(...) { if (uDebugFlag & DEBUG_INFO) { taosPrintLongString("UTL ", DEBUG_INFO, tsLogEmbedded ? 255 : uDebugFlag, __VA_ARGS__); }}
|
||||||
|
|
||||||
#define pError(...) { taosPrintLog("APP ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }
|
#define pError(...) { taosPrintLog("APP ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }
|
||||||
#define pPrint(...) { taosPrintLog("APP ", DEBUG_INFO, 255, __VA_ARGS__); }
|
#define pPrint(...) { taosPrintLog("APP ", DEBUG_INFO, 255, __VA_ARGS__); }
|
||||||
|
|
|
@ -492,53 +492,53 @@ int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row[i] == NULL) {
|
if (row[i] == NULL) {
|
||||||
len += snprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
|
len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fields[i].type) {
|
switch (fields[i].type) {
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
len += snprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UTINYINT:
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
len += snprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
len += snprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_USMALLINT:
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
len += snprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_INT:
|
case TSDB_DATA_TYPE_INT:
|
||||||
len += snprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UINT:
|
case TSDB_DATA_TYPE_UINT:
|
||||||
len += snprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
len += snprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
len += snprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
float fv = 0;
|
float fv = 0;
|
||||||
fv = GET_FLOAT_VAL(row[i]);
|
fv = GET_FLOAT_VAL(row[i]);
|
||||||
len += snprintf(str + len, size - len, "%f", fv);
|
len += tsnprintf(str + len, size - len, "%f", fv);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
double dv = 0;
|
double dv = 0;
|
||||||
dv = GET_DOUBLE_VAL(row[i]);
|
dv = GET_DOUBLE_VAL(row[i]);
|
||||||
len += snprintf(str + len, size - len, "%lf", dv);
|
len += tsnprintf(str + len, size - len, "%lf", dv);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_VARBINARY: {
|
case TSDB_DATA_TYPE_VARBINARY: {
|
||||||
|
@ -576,11 +576,11 @@ int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
len += snprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
len += snprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
|
len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,6 +399,20 @@ static const SSysDbTableSchema userCompactsDetailSchema[] = {
|
||||||
{.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
{.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const SSysDbTableSchema anodesSchema[] = {
|
||||||
|
{.name = "id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||||
|
{.name = "url", .bytes = TSDB_ANAL_ANODE_URL_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||||
|
{.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||||
|
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true},
|
||||||
|
{.name = "update_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SSysDbTableSchema anodesFullSchema[] = {
|
||||||
|
{.name = "id", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
|
||||||
|
{.name = "type", .bytes = TSDB_ANAL_ALGO_TYPE_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||||
|
{.name = "algo", .bytes = TSDB_ANAL_ALGO_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true},
|
||||||
|
};
|
||||||
|
|
||||||
static const SSysDbTableSchema tsmaSchema[] = {
|
static const SSysDbTableSchema tsmaSchema[] = {
|
||||||
{.name = "tsma_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
{.name = "tsma_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||||
{.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
{.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
|
||||||
|
@ -473,6 +487,8 @@ static const SSysTableMeta infosMeta[] = {
|
||||||
{TSDB_INS_TABLE_ARBGROUPS, arbGroupsSchema, tListLen(arbGroupsSchema), true},
|
{TSDB_INS_TABLE_ARBGROUPS, arbGroupsSchema, tListLen(arbGroupsSchema), true},
|
||||||
{TSDB_INS_TABLE_ENCRYPTIONS, encryptionsSchema, tListLen(encryptionsSchema), true},
|
{TSDB_INS_TABLE_ENCRYPTIONS, encryptionsSchema, tListLen(encryptionsSchema), true},
|
||||||
{TSDB_INS_TABLE_TSMAS, tsmaSchema, tListLen(tsmaSchema), false},
|
{TSDB_INS_TABLE_TSMAS, tsmaSchema, tListLen(tsmaSchema), false},
|
||||||
|
{TSDB_INS_TABLE_ANODES, anodesSchema, tListLen(anodesSchema), true},
|
||||||
|
{TSDB_INS_TABLE_ANODES_FULL, anodesFullSchema, tListLen(anodesFullSchema), true},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SSysDbTableSchema connectionsSchema[] = {
|
static const SSysDbTableSchema connectionsSchema[] = {
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#define TD_MSG_RANGE_CODE_
|
#define TD_MSG_RANGE_CODE_
|
||||||
#include "tmsgdef.h"
|
#include "tmsgdef.h"
|
||||||
|
|
||||||
|
#include "tanal.h"
|
||||||
#include "tcol.h"
|
#include "tcol.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
|
|
||||||
|
@ -1453,6 +1454,7 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->ipWhiteVer));
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->ipWhiteVer));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->analVer));
|
||||||
TAOS_CHECK_EXIT(tSerializeSMonitorParas(&encoder, &pReq->clusterCfg.monitorParas));
|
TAOS_CHECK_EXIT(tSerializeSMonitorParas(&encoder, &pReq->clusterCfg.monitorParas));
|
||||||
|
|
||||||
tEndEncode(&encoder);
|
tEndEncode(&encoder);
|
||||||
|
@ -1576,6 +1578,10 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) {
|
||||||
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pReq->ipWhiteVer));
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pReq->ipWhiteVer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tDecodeIsEnd(&decoder)) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pReq->analVer));
|
||||||
|
}
|
||||||
|
|
||||||
if (!tDecodeIsEnd(&decoder)) {
|
if (!tDecodeIsEnd(&decoder)) {
|
||||||
TAOS_CHECK_EXIT(tDeserializeSMonitorParas(&decoder, &pReq->clusterCfg.monitorParas));
|
TAOS_CHECK_EXIT(tDeserializeSMonitorParas(&decoder, &pReq->clusterCfg.monitorParas));
|
||||||
}
|
}
|
||||||
|
@ -1652,6 +1658,7 @@ int32_t tSerializeSStatusRsp(void *buf, int32_t bufLen, SStatusRsp *pRsp) {
|
||||||
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pRsp->statusSeq));
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pRsp->statusSeq));
|
||||||
|
|
||||||
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pRsp->ipWhiteVer));
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pRsp->ipWhiteVer));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pRsp->analVer));
|
||||||
tEndEncode(&encoder);
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
|
@ -1704,6 +1711,10 @@ int32_t tDeserializeSStatusRsp(void *buf, int32_t bufLen, SStatusRsp *pRsp) {
|
||||||
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pRsp->ipWhiteVer));
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pRsp->ipWhiteVer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tDecodeIsEnd(&decoder)) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pRsp->analVer));
|
||||||
|
}
|
||||||
|
|
||||||
tEndDecode(&decoder);
|
tEndDecode(&decoder);
|
||||||
_exit:
|
_exit:
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
|
@ -2045,6 +2056,156 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tSerializeRetrieveAnalAlgoReq(void *buf, int32_t bufLen, SRetrieveAnalAlgoReq *pReq) {
|
||||||
|
SEncoder encoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
int32_t tlen;
|
||||||
|
tEncoderInit(&encoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartEncode(&encoder));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pReq->dnodeId));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->analVer));
|
||||||
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
if (code) {
|
||||||
|
tlen = code;
|
||||||
|
} else {
|
||||||
|
tlen = encoder.pos;
|
||||||
|
}
|
||||||
|
tEncoderClear(&encoder);
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeRetrieveAnalAlgoReq(void *buf, int32_t bufLen, SRetrieveAnalAlgoReq *pReq) {
|
||||||
|
SDecoder decoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
|
||||||
|
tDecoderInit(&decoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartDecode(&decoder));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &pReq->dnodeId));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pReq->analVer));
|
||||||
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tSerializeRetrieveAnalAlgoRsp(void *buf, int32_t bufLen, SRetrieveAnalAlgoRsp *pRsp) {
|
||||||
|
SEncoder encoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
int32_t tlen;
|
||||||
|
tEncoderInit(&encoder, buf, bufLen);
|
||||||
|
|
||||||
|
int32_t numOfAlgos = 0;
|
||||||
|
void *pIter = taosHashIterate(pRsp->hash, NULL);
|
||||||
|
while (pIter != NULL) {
|
||||||
|
SAnalUrl *pUrl = pIter;
|
||||||
|
size_t nameLen = 0;
|
||||||
|
const char *name = taosHashGetKey(pIter, &nameLen);
|
||||||
|
if (nameLen > 0 && nameLen <= TSDB_ANAL_ALGO_KEY_LEN && pUrl->urlLen > 0) {
|
||||||
|
numOfAlgos++;
|
||||||
|
}
|
||||||
|
pIter = taosHashIterate(pRsp->hash, pIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartEncode(&encoder));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pRsp->ver));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, numOfAlgos));
|
||||||
|
|
||||||
|
pIter = taosHashIterate(pRsp->hash, NULL);
|
||||||
|
while (pIter != NULL) {
|
||||||
|
SAnalUrl *pUrl = pIter;
|
||||||
|
size_t nameLen = 0;
|
||||||
|
const char *name = taosHashGetKey(pIter, &nameLen);
|
||||||
|
if (nameLen > 0 && pUrl->urlLen > 0) {
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, nameLen));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeBinary(&encoder, (const uint8_t *)name, nameLen));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pUrl->anode));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pUrl->type));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pUrl->urlLen));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeBinary(&encoder, (const uint8_t *)pUrl->url, pUrl->urlLen));
|
||||||
|
}
|
||||||
|
pIter = taosHashIterate(pRsp->hash, pIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
if (code) {
|
||||||
|
tlen = code;
|
||||||
|
} else {
|
||||||
|
tlen = encoder.pos;
|
||||||
|
}
|
||||||
|
tEncoderClear(&encoder);
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeRetrieveAnalAlgoRsp(void *buf, int32_t bufLen, SRetrieveAnalAlgoRsp *pRsp) {
|
||||||
|
if (pRsp->hash == NULL) {
|
||||||
|
pRsp->hash = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||||
|
if (pRsp->hash == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_BUFFER;
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDecoder decoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
tDecoderInit(&decoder, buf, bufLen);
|
||||||
|
|
||||||
|
int32_t numOfAlgos = 0;
|
||||||
|
int32_t nameLen;
|
||||||
|
int32_t type;
|
||||||
|
char name[TSDB_ANAL_ALGO_KEY_LEN];
|
||||||
|
SAnalUrl url = {0};
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartDecode(&decoder));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pRsp->ver));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &numOfAlgos));
|
||||||
|
|
||||||
|
for (int32_t f = 0; f < numOfAlgos; ++f) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &nameLen));
|
||||||
|
if (nameLen > 0 && nameLen <= TSDB_ANAL_ALGO_NAME_LEN) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &url.anode));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &type));
|
||||||
|
url.type = (EAnalAlgoType)type;
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &url.urlLen));
|
||||||
|
if (url.urlLen > 0) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeBinaryAlloc(&decoder, (void **)&url.url, NULL) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(taosHashPut(pRsp->hash, name, nameLen, &url, sizeof(SAnalUrl)));
|
||||||
|
}
|
||||||
|
|
||||||
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tFreeRetrieveAnalAlgoRsp(SRetrieveAnalAlgoRsp *pRsp) {
|
||||||
|
void *pIter = taosHashIterate(pRsp->hash, NULL);
|
||||||
|
while (pIter != NULL) {
|
||||||
|
SAnalUrl *pUrl = (SAnalUrl *)pIter;
|
||||||
|
taosMemoryFree(pUrl->url);
|
||||||
|
pIter = taosHashIterate(pRsp->hash, pIter);
|
||||||
|
}
|
||||||
|
taosHashCleanup(pRsp->hash);
|
||||||
|
|
||||||
|
pRsp->hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void tFreeSCreateUserReq(SCreateUserReq *pReq) {
|
void tFreeSCreateUserReq(SCreateUserReq *pReq) {
|
||||||
FREESQL();
|
FREESQL();
|
||||||
taosMemoryFreeClear(pReq->pIpRanges);
|
taosMemoryFreeClear(pReq->pIpRanges);
|
||||||
|
@ -2962,6 +3123,108 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tSerializeSMCreateAnodeReq(void *buf, int32_t bufLen, SMCreateAnodeReq *pReq) {
|
||||||
|
SEncoder encoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
int32_t tlen;
|
||||||
|
tEncoderInit(&encoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartEncode(&encoder));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pReq->urlLen));
|
||||||
|
if (pReq->urlLen > 0) {
|
||||||
|
TAOS_CHECK_EXIT(tEncodeBinary(&encoder, (const uint8_t *)pReq->url, pReq->urlLen));
|
||||||
|
}
|
||||||
|
ENCODESQL();
|
||||||
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
if (code) {
|
||||||
|
tlen = code;
|
||||||
|
} else {
|
||||||
|
tlen = encoder.pos;
|
||||||
|
}
|
||||||
|
tEncoderClear(&encoder);
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeSMCreateAnodeReq(void *buf, int32_t bufLen, SMCreateAnodeReq *pReq) {
|
||||||
|
SDecoder decoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
|
||||||
|
tDecoderInit(&decoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartDecode(&decoder));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &pReq->urlLen));
|
||||||
|
if (pReq->urlLen > 0) {
|
||||||
|
TAOS_CHECK_EXIT(tDecodeBinaryAlloc(&decoder, (void **)&pReq->url, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
DECODESQL();
|
||||||
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tFreeSMCreateAnodeReq(SMCreateAnodeReq *pReq) {
|
||||||
|
taosMemoryFreeClear(pReq->url);
|
||||||
|
FREESQL();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tSerializeSMDropAnodeReq(void *buf, int32_t bufLen, SMDropAnodeReq *pReq) {
|
||||||
|
SEncoder encoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
int32_t tlen;
|
||||||
|
tEncoderInit(&encoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartEncode(&encoder));
|
||||||
|
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pReq->anodeId));
|
||||||
|
ENCODESQL();
|
||||||
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
if (code) {
|
||||||
|
tlen = code;
|
||||||
|
} else {
|
||||||
|
tlen = encoder.pos;
|
||||||
|
}
|
||||||
|
tEncoderClear(&encoder);
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeSMDropAnodeReq(void *buf, int32_t bufLen, SMDropAnodeReq *pReq) {
|
||||||
|
SDecoder decoder = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino;
|
||||||
|
|
||||||
|
tDecoderInit(&decoder, buf, bufLen);
|
||||||
|
|
||||||
|
TAOS_CHECK_EXIT(tStartDecode(&decoder));
|
||||||
|
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &pReq->anodeId));
|
||||||
|
DECODESQL();
|
||||||
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tFreeSMDropAnodeReq(SMDropAnodeReq *pReq) { FREESQL(); }
|
||||||
|
|
||||||
|
int32_t tSerializeSMUpdateAnodeReq(void *buf, int32_t bufLen, SMUpdateAnodeReq *pReq) {
|
||||||
|
return tSerializeSMDropAnodeReq(buf, bufLen, pReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeSMUpdateAnodeReq(void *buf, int32_t bufLen, SMUpdateAnodeReq *pReq) {
|
||||||
|
return tDeserializeSMDropAnodeReq(buf, bufLen, pReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tFreeSMUpdateAnodeReq(SMUpdateAnodeReq *pReq) { tFreeSMDropAnodeReq(pReq); }
|
||||||
|
|
||||||
int32_t tSerializeSCreateDnodeReq(void *buf, int32_t bufLen, SCreateDnodeReq *pReq) {
|
int32_t tSerializeSCreateDnodeReq(void *buf, int32_t bufLen, SCreateDnodeReq *pReq) {
|
||||||
SEncoder encoder = {0};
|
SEncoder encoder = {0};
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
|
@ -182,6 +182,7 @@ static void dmSetSignalHandle() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool generateNewMeta;
|
extern bool generateNewMeta;
|
||||||
|
|
||||||
static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ typedef struct SDnodeMgmt {
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *name;
|
const char *name;
|
||||||
TdThread statusThread;
|
TdThread statusThread;
|
||||||
|
TdThread statusInfoThread;
|
||||||
TdThread notifyThread;
|
TdThread notifyThread;
|
||||||
TdThread monitorThread;
|
TdThread monitorThread;
|
||||||
TdThread auditThread;
|
TdThread auditThread;
|
||||||
|
@ -49,6 +50,7 @@ typedef struct SDnodeMgmt {
|
||||||
// dmHandle.c
|
// dmHandle.c
|
||||||
SArray *dmGetMsgHandles();
|
SArray *dmGetMsgHandles();
|
||||||
void dmSendStatusReq(SDnodeMgmt *pMgmt);
|
void dmSendStatusReq(SDnodeMgmt *pMgmt);
|
||||||
|
void dmUpdateStatusInfo(SDnodeMgmt *pMgmt);
|
||||||
void dmSendNotifyReq(SDnodeMgmt *pMgmt, SNotifyReq *pReq);
|
void dmSendNotifyReq(SDnodeMgmt *pMgmt, SNotifyReq *pReq);
|
||||||
int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||||
int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||||
|
@ -62,7 +64,9 @@ int32_t dmProcessCreateEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||||
// dmWorker.c
|
// dmWorker.c
|
||||||
int32_t dmPutNodeMsgToMgmtQueue(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
int32_t dmPutNodeMsgToMgmtQueue(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||||
int32_t dmStartStatusThread(SDnodeMgmt *pMgmt);
|
int32_t dmStartStatusThread(SDnodeMgmt *pMgmt);
|
||||||
|
int32_t dmStartStatusInfoThread(SDnodeMgmt *pMgmt);
|
||||||
void dmStopStatusThread(SDnodeMgmt *pMgmt);
|
void dmStopStatusThread(SDnodeMgmt *pMgmt);
|
||||||
|
void dmStopStatusInfoThread(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmStartNotifyThread(SDnodeMgmt *pMgmt);
|
int32_t dmStartNotifyThread(SDnodeMgmt *pMgmt);
|
||||||
void dmStopNotifyThread(SDnodeMgmt *pMgmt);
|
void dmStopNotifyThread(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmStartMonitorThread(SDnodeMgmt *pMgmt);
|
int32_t dmStartMonitorThread(SDnodeMgmt *pMgmt);
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
#include "dmInt.h"
|
#include "dmInt.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
#include "systable.h"
|
#include "systable.h"
|
||||||
|
#include "tanal.h"
|
||||||
#include "tchecksum.h"
|
#include "tchecksum.h"
|
||||||
|
|
||||||
extern SConfig *tsCfg;
|
extern SConfig *tsCfg;
|
||||||
|
|
||||||
|
SMonVloadInfo tsVinfo = {0};
|
||||||
|
|
||||||
static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) {
|
static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
if (pMgmt->pData->dnodeId == 0 || pMgmt->pData->clusterId == 0) {
|
if (pMgmt->pData->dnodeId == 0 || pMgmt->pData->clusterId == 0) {
|
||||||
|
@ -86,6 +89,46 @@ static void dmMayShouldUpdateIpWhiteList(SDnodeMgmt *pMgmt, int64_t ver) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dmMayShouldUpdateAnalFunc(SDnodeMgmt *pMgmt, int64_t newVer) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int64_t oldVer = taosAnalGetVersion();
|
||||||
|
if (oldVer == newVer) return;
|
||||||
|
dDebug("analysis on dnode ver:%" PRId64 ", status ver:%" PRId64, oldVer, newVer);
|
||||||
|
|
||||||
|
SRetrieveAnalAlgoReq req = {.dnodeId = pMgmt->pData->dnodeId, .analVer = oldVer};
|
||||||
|
int32_t contLen = tSerializeRetrieveAnalAlgoReq(NULL, 0, &req);
|
||||||
|
if (contLen < 0) {
|
||||||
|
dError("failed to serialize analysis function ver request since %s", tstrerror(contLen));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pHead = rpcMallocCont(contLen);
|
||||||
|
contLen = tSerializeRetrieveAnalAlgoReq(pHead, contLen, &req);
|
||||||
|
if (contLen < 0) {
|
||||||
|
rpcFreeCont(pHead);
|
||||||
|
dError("failed to serialize analysis function ver request since %s", tstrerror(contLen));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg = {
|
||||||
|
.pCont = pHead,
|
||||||
|
.contLen = contLen,
|
||||||
|
.msgType = TDMT_MND_RETRIEVE_ANAL_ALGO,
|
||||||
|
.info.ahandle = (void *)0x9527,
|
||||||
|
.info.refId = 0,
|
||||||
|
.info.noResp = 0,
|
||||||
|
.info.handle = 0,
|
||||||
|
};
|
||||||
|
SEpSet epset = {0};
|
||||||
|
|
||||||
|
(void)dmGetMnodeEpSet(pMgmt->pData, &epset);
|
||||||
|
|
||||||
|
code = rpcSendRequest(pMgmt->msgCb.clientRpc, &epset, &rpcMsg, NULL);
|
||||||
|
if (code != 0) {
|
||||||
|
dError("failed to send retrieve analysis func ver request since %s", tstrerror(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void dmProcessStatusRsp(SDnodeMgmt *pMgmt, SRpcMsg *pRsp) {
|
static void dmProcessStatusRsp(SDnodeMgmt *pMgmt, SRpcMsg *pRsp) {
|
||||||
const STraceId *trace = &pRsp->info.traceId;
|
const STraceId *trace = &pRsp->info.traceId;
|
||||||
dGTrace("status rsp received from mnode, statusSeq:%d code:0x%x", pMgmt->statusSeq, pRsp->code);
|
dGTrace("status rsp received from mnode, statusSeq:%d code:0x%x", pMgmt->statusSeq, pRsp->code);
|
||||||
|
@ -113,6 +156,7 @@ static void dmProcessStatusRsp(SDnodeMgmt *pMgmt, SRpcMsg *pRsp) {
|
||||||
dmUpdateEps(pMgmt->pData, statusRsp.pDnodeEps);
|
dmUpdateEps(pMgmt->pData, statusRsp.pDnodeEps);
|
||||||
}
|
}
|
||||||
dmMayShouldUpdateIpWhiteList(pMgmt, statusRsp.ipWhiteVer);
|
dmMayShouldUpdateIpWhiteList(pMgmt, statusRsp.ipWhiteVer);
|
||||||
|
dmMayShouldUpdateAnalFunc(pMgmt, statusRsp.analVer);
|
||||||
}
|
}
|
||||||
tFreeSStatusRsp(&statusRsp);
|
tFreeSStatusRsp(&statusRsp);
|
||||||
}
|
}
|
||||||
|
@ -163,9 +207,16 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
||||||
(void)taosThreadRwlockUnlock(&pMgmt->pData->lock);
|
(void)taosThreadRwlockUnlock(&pMgmt->pData->lock);
|
||||||
|
|
||||||
dDebug("send status req to mnode, statusSeq:%d, begin to get vnode loads", pMgmt->statusSeq);
|
dDebug("send status req to mnode, statusSeq:%d, begin to get vnode loads", pMgmt->statusSeq);
|
||||||
SMonVloadInfo vinfo = {0};
|
if (taosThreadMutexLock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
(*pMgmt->getVnodeLoadsFp)(&vinfo);
|
dError("failed to lock status info lock");
|
||||||
req.pVloads = vinfo.pVloads;
|
return;
|
||||||
|
}
|
||||||
|
req.pVloads = tsVinfo.pVloads;
|
||||||
|
tsVinfo.pVloads = NULL;
|
||||||
|
if (taosThreadMutexUnlock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
|
dError("failed to unlock status info lock");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dDebug("send status req to mnode, statusSeq:%d, begin to get mnode loads", pMgmt->statusSeq);
|
dDebug("send status req to mnode, statusSeq:%d, begin to get mnode loads", pMgmt->statusSeq);
|
||||||
SMonMloadInfo minfo = {0};
|
SMonMloadInfo minfo = {0};
|
||||||
|
@ -178,6 +229,7 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
||||||
pMgmt->statusSeq++;
|
pMgmt->statusSeq++;
|
||||||
req.statusSeq = pMgmt->statusSeq;
|
req.statusSeq = pMgmt->statusSeq;
|
||||||
req.ipWhiteVer = pMgmt->pData->ipWhiteVer;
|
req.ipWhiteVer = pMgmt->pData->ipWhiteVer;
|
||||||
|
req.analVer = taosAnalGetVersion();
|
||||||
|
|
||||||
int32_t contLen = tSerializeSStatusReq(NULL, 0, &req);
|
int32_t contLen = tSerializeSStatusReq(NULL, 0, &req);
|
||||||
if (contLen < 0) {
|
if (contLen < 0) {
|
||||||
|
@ -231,6 +283,28 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
||||||
dmProcessStatusRsp(pMgmt, &rpcRsp);
|
dmProcessStatusRsp(pMgmt, &rpcRsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dmUpdateStatusInfo(SDnodeMgmt *pMgmt) {
|
||||||
|
SMonVloadInfo vinfo = {0};
|
||||||
|
dDebug("begin to get vnode loads");
|
||||||
|
(*pMgmt->getVnodeLoadsFp)(&vinfo);
|
||||||
|
dDebug("begin to lock status info");
|
||||||
|
if (taosThreadMutexLock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
|
dError("failed to lock status info lock");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tsVinfo.pVloads == NULL) {
|
||||||
|
tsVinfo.pVloads = vinfo.pVloads;
|
||||||
|
vinfo.pVloads = NULL;
|
||||||
|
} else {
|
||||||
|
taosArrayDestroy(vinfo.pVloads);
|
||||||
|
vinfo.pVloads = NULL;
|
||||||
|
}
|
||||||
|
if (taosThreadMutexUnlock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
|
dError("failed to unlock status info lock");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dmSendNotifyReq(SDnodeMgmt *pMgmt, SNotifyReq *pReq) {
|
void dmSendNotifyReq(SDnodeMgmt *pMgmt, SNotifyReq *pReq) {
|
||||||
int32_t contLen = tSerializeSNotifyReq(NULL, 0, pReq);
|
int32_t contLen = tSerializeSNotifyReq(NULL, 0, pReq);
|
||||||
if (contLen < 0) {
|
if (contLen < 0) {
|
||||||
|
|
|
@ -16,12 +16,16 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dmInt.h"
|
#include "dmInt.h"
|
||||||
#include "libs/function/tudf.h"
|
#include "libs/function/tudf.h"
|
||||||
|
#include "tanal.h"
|
||||||
|
|
||||||
static int32_t dmStartMgmt(SDnodeMgmt *pMgmt) {
|
static int32_t dmStartMgmt(SDnodeMgmt *pMgmt) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
if ((code = dmStartStatusThread(pMgmt)) != 0) {
|
if ((code = dmStartStatusThread(pMgmt)) != 0) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
if ((code = dmStartStatusInfoThread(pMgmt)) != 0) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
#if defined(TD_ENTERPRISE)
|
#if defined(TD_ENTERPRISE)
|
||||||
if ((code = dmStartNotifyThread(pMgmt)) != 0) {
|
if ((code = dmStartNotifyThread(pMgmt)) != 0) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -44,6 +48,7 @@ static void dmStopMgmt(SDnodeMgmt *pMgmt) {
|
||||||
dmStopMonitorThread(pMgmt);
|
dmStopMonitorThread(pMgmt);
|
||||||
dmStopAuditThread(pMgmt);
|
dmStopAuditThread(pMgmt);
|
||||||
dmStopStatusThread(pMgmt);
|
dmStopStatusThread(pMgmt);
|
||||||
|
dmStopStatusInfoThread(pMgmt);
|
||||||
#if defined(TD_ENTERPRISE)
|
#if defined(TD_ENTERPRISE)
|
||||||
dmStopNotifyThread(pMgmt);
|
dmStopNotifyThread(pMgmt);
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,6 +85,10 @@ static int32_t dmOpenMgmt(SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) {
|
||||||
dError("failed to start udfd since %s", tstrerror(code));
|
dError("failed to start udfd since %s", tstrerror(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((code = taosAnalInit()) != 0) {
|
||||||
|
dError("failed to init analysis env since %s", tstrerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
pOutput->pMgmt = pMgmt;
|
pOutput->pMgmt = pMgmt;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,49 @@ static void *dmStatusThreadFp(void *param) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern SMonVloadInfo tsVinfo;
|
||||||
|
static void *dmStatusInfoThreadFp(void *param) {
|
||||||
|
SDnodeMgmt *pMgmt = param;
|
||||||
|
int64_t lastTime = taosGetTimestampMs();
|
||||||
|
setThreadName("dnode-status-info");
|
||||||
|
|
||||||
|
int32_t upTimeCount = 0;
|
||||||
|
int64_t upTime = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
taosMsleep(200);
|
||||||
|
if (pMgmt->pData->dropped || pMgmt->pData->stopped) break;
|
||||||
|
|
||||||
|
int64_t curTime = taosGetTimestampMs();
|
||||||
|
if (curTime < lastTime) lastTime = curTime;
|
||||||
|
float interval = (curTime - lastTime) / 1000.0f;
|
||||||
|
if (interval >= tsStatusInterval) {
|
||||||
|
dmUpdateStatusInfo(pMgmt);
|
||||||
|
lastTime = curTime;
|
||||||
|
|
||||||
|
if ((upTimeCount = ((upTimeCount + 1) & 63)) == 0) {
|
||||||
|
upTime = taosGetOsUptime() - tsDndStartOsUptime;
|
||||||
|
tsDndUpTime = TMAX(tsDndUpTime, upTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dDebug("begin to lock status info when thread exit");
|
||||||
|
if (taosThreadMutexLock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
|
dError("failed to lock status info lock");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (tsVinfo.pVloads != NULL) {
|
||||||
|
taosArrayDestroy(tsVinfo.pVloads);
|
||||||
|
tsVinfo.pVloads = NULL;
|
||||||
|
}
|
||||||
|
if (taosThreadMutexUnlock(&pMgmt->pData->statusInfolock) != 0) {
|
||||||
|
dError("failed to unlock status info lock");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDmNotifyHandle dmNotifyHdl = {.state = 0};
|
SDmNotifyHandle dmNotifyHdl = {.state = 0};
|
||||||
#define TIMESERIES_STASH_NUM 5
|
#define TIMESERIES_STASH_NUM 5
|
||||||
static void *dmNotifyThreadFp(void *param) {
|
static void *dmNotifyThreadFp(void *param) {
|
||||||
|
@ -280,6 +323,22 @@ int32_t dmStartStatusThread(SDnodeMgmt *pMgmt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t dmStartStatusInfoThread(SDnodeMgmt *pMgmt) {
|
||||||
|
int32_t code = 0;
|
||||||
|
TdThreadAttr thAttr;
|
||||||
|
(void)taosThreadAttrInit(&thAttr);
|
||||||
|
(void)taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
if (taosThreadCreate(&pMgmt->statusInfoThread, &thAttr, dmStatusInfoThreadFp, pMgmt) != 0) {
|
||||||
|
code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
dError("failed to create status Info thread since %s", tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)taosThreadAttrDestroy(&thAttr);
|
||||||
|
tmsgReportStartup("dnode-status-info", "initialized");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void dmStopStatusThread(SDnodeMgmt *pMgmt) {
|
void dmStopStatusThread(SDnodeMgmt *pMgmt) {
|
||||||
if (taosCheckPthreadValid(pMgmt->statusThread)) {
|
if (taosCheckPthreadValid(pMgmt->statusThread)) {
|
||||||
(void)taosThreadJoin(pMgmt->statusThread, NULL);
|
(void)taosThreadJoin(pMgmt->statusThread, NULL);
|
||||||
|
@ -287,6 +346,13 @@ void dmStopStatusThread(SDnodeMgmt *pMgmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dmStopStatusInfoThread(SDnodeMgmt *pMgmt) {
|
||||||
|
if (taosCheckPthreadValid(pMgmt->statusInfoThread)) {
|
||||||
|
(void)taosThreadJoin(pMgmt->statusInfoThread, NULL);
|
||||||
|
taosThreadClear(&pMgmt->statusInfoThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t dmStartNotifyThread(SDnodeMgmt *pMgmt) {
|
int32_t dmStartNotifyThread(SDnodeMgmt *pMgmt) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
TdThreadAttr thAttr;
|
TdThreadAttr thAttr;
|
||||||
|
|
|
@ -141,6 +141,9 @@ SArray *mmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_DNODE_LIST, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_DNODE_LIST, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_SNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_SNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_SNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_SNODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ANODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
if (dmSetMgmtHandle(pArray, TDMT_MND_UPDATE_ANODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_ANODE, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DB, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_USE_DB, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_USE_DB, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
|
@ -180,6 +183,7 @@ SArray *mmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
||||||
|
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_ANAL_ALGO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_IP_WHITE, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_IP_WHITE, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_USER_WHITELIST, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_USER_WHITELIST, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_INDEX, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_INDEX, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
|
@ -208,7 +212,7 @@ SArray *mmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_VIEW, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_VIEW, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_VIEW_META, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_VIEW_META, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_STATIS, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_STATIS, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_COMPACT, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_COMPACT, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_CLUSTER, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_CLUSTER, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_COMPACT_PROGRESS_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_COMPACT_PROGRESS_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ENCRYPT_KEY, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ENCRYPT_KEY, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
|
@ -415,14 +415,24 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// taosThreadMutexLock(&pMgmt->createLock);
|
code = taosThreadMutexLock(&pMgmt->createLock);
|
||||||
|
if (code != 0) {
|
||||||
|
dError("vgId:%d, failed to lock since %s", req.vgId, tstrerror(code));
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
code = vmWriteVnodeListToFile(pMgmt);
|
code = vmWriteVnodeListToFile(pMgmt);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
code = terrno != 0 ? terrno : code;
|
code = terrno != 0 ? terrno : code;
|
||||||
// taosThreadMutexUnlock(&pMgmt->createLock);
|
int32_t ret = taosThreadMutexUnlock(&pMgmt->createLock);
|
||||||
|
if (ret != 0) {
|
||||||
|
dError("vgId:%d, failed to unlock since %s", req.vgId, tstrerror(ret));
|
||||||
|
}
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
}
|
}
|
||||||
// taosThreadMutexUnlock(&pMgmt->createLock);
|
int32_t ret = taosThreadMutexUnlock(&pMgmt->createLock);
|
||||||
|
if (ret != 0) {
|
||||||
|
dError("vgId:%d, failed to unlock since %s", req.vgId, tstrerror(ret));
|
||||||
|
}
|
||||||
|
|
||||||
_OVER:
|
_OVER:
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
@ -1037,7 +1047,7 @@ SArray *vmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TRIM, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TRIM, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_S3MIGRATE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_S3MIGRATE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE, vmPutMsgToMultiMgmtQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP, vmPutMsgToMgmtQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libs/function/tudf.h"
|
#include "libs/function/tudf.h"
|
||||||
#include "tgrant.h"
|
#include "tgrant.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
#include "tanal.h"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#define DM_INIT_AUDIT() \
|
#define DM_INIT_AUDIT() \
|
||||||
|
@ -214,6 +215,7 @@ void dmCleanup() {
|
||||||
dError("failed to close udfc");
|
dError("failed to close udfc");
|
||||||
}
|
}
|
||||||
udfStopUdfd();
|
udfStopUdfd();
|
||||||
|
taosAnalCleanup();
|
||||||
taosStopCacheRefreshWorker();
|
taosStopCacheRefreshWorker();
|
||||||
(void)dmDiskClose();
|
(void)dmDiskClose();
|
||||||
DestroyRegexCache();
|
DestroyRegexCache();
|
||||||
|
|
|
@ -214,6 +214,7 @@ int32_t dmInitVars(SDnode *pDnode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)taosThreadRwlockInit(&pData->lock, NULL);
|
(void)taosThreadRwlockInit(&pData->lock, NULL);
|
||||||
|
(void)taosThreadMutexInit(&pData->statusInfolock, NULL);
|
||||||
(void)taosThreadMutexInit(&pDnode->mutex, NULL);
|
(void)taosThreadMutexInit(&pDnode->mutex, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "dmMgmt.h"
|
#include "dmMgmt.h"
|
||||||
#include "qworker.h"
|
#include "qworker.h"
|
||||||
#include "tversion.h"
|
#include "tversion.h"
|
||||||
|
#include "tanal.h"
|
||||||
|
|
||||||
static inline void dmSendRsp(SRpcMsg *pMsg) {
|
static inline void dmSendRsp(SRpcMsg *pMsg) {
|
||||||
if (rpcSendResponse(pMsg) != 0) {
|
if (rpcSendResponse(pMsg) != 0) {
|
||||||
|
@ -106,6 +107,16 @@ static bool dmIsForbiddenIp(int8_t forbidden, char *user, uint32_t clientIp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dmUpdateAnalFunc(SDnodeData *pData, void *pTrans, SRpcMsg *pRpc) {
|
||||||
|
SRetrieveAnalAlgoRsp rsp = {0};
|
||||||
|
if (tDeserializeRetrieveAnalAlgoRsp(pRpc->pCont, pRpc->contLen, &rsp) == 0) {
|
||||||
|
taosAnalUpdate(rsp.ver, rsp.hash);
|
||||||
|
rsp.hash = NULL;
|
||||||
|
}
|
||||||
|
tFreeRetrieveAnalAlgoRsp(&rsp);
|
||||||
|
rpcFreeCont(pRpc->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
||||||
SDnodeTrans *pTrans = &pDnode->trans;
|
SDnodeTrans *pTrans = &pDnode->trans;
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
|
@ -154,6 +165,9 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
||||||
case TDMT_MND_RETRIEVE_IP_WHITE_RSP:
|
case TDMT_MND_RETRIEVE_IP_WHITE_RSP:
|
||||||
dmUpdateRpcIpWhite(&pDnode->data, pTrans->serverRpc, pRpc);
|
dmUpdateRpcIpWhite(&pDnode->data, pTrans->serverRpc, pRpc);
|
||||||
return;
|
return;
|
||||||
|
case TDMT_MND_RETRIEVE_ANAL_ALGO_RSP:
|
||||||
|
dmUpdateAnalFunc(&pDnode->data, pTrans->serverRpc, pRpc);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,7 @@ typedef struct {
|
||||||
char machineId[TSDB_MACHINE_ID_LEN + 1];
|
char machineId[TSDB_MACHINE_ID_LEN + 1];
|
||||||
EEncryptAlgor encryptAlgorigthm;
|
EEncryptAlgor encryptAlgorigthm;
|
||||||
EEncryptScope encryptScope;
|
EEncryptScope encryptScope;
|
||||||
|
TdThreadMutex statusInfolock;
|
||||||
} SDnodeData;
|
} SDnodeData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -15,6 +15,9 @@ IF (TD_ENTERPRISE)
|
||||||
add_definitions(-DUSE_COS)
|
add_definitions(-DUSE_COS)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(${BUILD_WITH_ANALYSIS})
|
||||||
|
add_definitions(-DUSE_ANAL)
|
||||||
|
ENDIF()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
add_library(mnode STATIC ${MNODE_SRC})
|
add_library(mnode STATIC ${MNODE_SRC})
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_MND_ANODE_H_
|
||||||
|
#define _TD_MND_ANODE_H_
|
||||||
|
|
||||||
|
#include "mndInt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t mndInitAnode(SMnode *pMnode);
|
||||||
|
void mndCleanupAnode(SMnode *pMnode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_MND_ANODE_H_*/
|
|
@ -78,6 +78,9 @@ typedef enum {
|
||||||
MND_OPER_DROP_VIEW,
|
MND_OPER_DROP_VIEW,
|
||||||
MND_OPER_CONFIG_CLUSTER,
|
MND_OPER_CONFIG_CLUSTER,
|
||||||
MND_OPER_BALANCE_VGROUP_LEADER,
|
MND_OPER_BALANCE_VGROUP_LEADER,
|
||||||
|
MND_OPER_CREATE_ANODE,
|
||||||
|
MND_OPER_UPDATE_ANODE,
|
||||||
|
MND_OPER_DROP_ANODE
|
||||||
} EOperType;
|
} EOperType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -232,6 +235,24 @@ typedef struct {
|
||||||
char machineId[TSDB_MACHINE_ID_LEN + 1];
|
char machineId[TSDB_MACHINE_ID_LEN + 1];
|
||||||
} SDnodeObj;
|
} SDnodeObj;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t nameLen;
|
||||||
|
char* name;
|
||||||
|
} SAnodeAlgo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t id;
|
||||||
|
int64_t createdTime;
|
||||||
|
int64_t updateTime;
|
||||||
|
int32_t version;
|
||||||
|
int32_t urlLen;
|
||||||
|
int32_t numOfAlgos;
|
||||||
|
int32_t status;
|
||||||
|
SRWLatch lock;
|
||||||
|
char* url;
|
||||||
|
SArray** algos;
|
||||||
|
} SAnodeObj;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t id;
|
int32_t id;
|
||||||
int64_t createdTime;
|
int64_t createdTime;
|
||||||
|
|
|
@ -0,0 +1,903 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "mndAnode.h"
|
||||||
|
#include "audit.h"
|
||||||
|
#include "mndDnode.h"
|
||||||
|
#include "mndPrivilege.h"
|
||||||
|
#include "mndShow.h"
|
||||||
|
#include "mndTrans.h"
|
||||||
|
#include "mndUser.h"
|
||||||
|
#include "tanal.h"
|
||||||
|
#include "tjson.h"
|
||||||
|
|
||||||
|
#ifdef USE_ANAL
|
||||||
|
|
||||||
|
#define TSDB_ANODE_VER_NUMBER 1
|
||||||
|
#define TSDB_ANODE_RESERVE_SIZE 64
|
||||||
|
|
||||||
|
static SSdbRaw *mndAnodeActionEncode(SAnodeObj *pObj);
|
||||||
|
static SSdbRow *mndAnodeActionDecode(SSdbRaw *pRaw);
|
||||||
|
static int32_t mndAnodeActionInsert(SSdb *pSdb, SAnodeObj *pObj);
|
||||||
|
static int32_t mndAnodeActionUpdate(SSdb *pSdb, SAnodeObj *pOld, SAnodeObj *pNew);
|
||||||
|
static int32_t mndAnodeActionDelete(SSdb *pSdb, SAnodeObj *pObj);
|
||||||
|
static int32_t mndProcessCreateAnodeReq(SRpcMsg *pReq);
|
||||||
|
static int32_t mndProcessUpdateAnodeReq(SRpcMsg *pReq);
|
||||||
|
static int32_t mndProcessDropAnodeReq(SRpcMsg *pReq);
|
||||||
|
static int32_t mndProcessAnalAlgoReq(SRpcMsg *pReq);
|
||||||
|
static int32_t mndRetrieveAnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||||
|
static void mndCancelGetNextAnode(SMnode *pMnode, void *pIter);
|
||||||
|
static int32_t mndRetrieveAnodesFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||||
|
static void mndCancelGetNextAnodeFull(SMnode *pMnode, void *pIter);
|
||||||
|
static int32_t mndGetAnodeAlgoList(const char *url, SAnodeObj *pObj);
|
||||||
|
static int32_t mndGetAnodeStatus(SAnodeObj *pObj, char *status, int32_t statusLen);
|
||||||
|
|
||||||
|
int32_t mndInitAnode(SMnode *pMnode) {
|
||||||
|
SSdbTable table = {
|
||||||
|
.sdbType = SDB_ANODE,
|
||||||
|
.keyType = SDB_KEY_INT32,
|
||||||
|
.encodeFp = (SdbEncodeFp)mndAnodeActionEncode,
|
||||||
|
.decodeFp = (SdbDecodeFp)mndAnodeActionDecode,
|
||||||
|
.insertFp = (SdbInsertFp)mndAnodeActionInsert,
|
||||||
|
.updateFp = (SdbUpdateFp)mndAnodeActionUpdate,
|
||||||
|
.deleteFp = (SdbDeleteFp)mndAnodeActionDelete,
|
||||||
|
};
|
||||||
|
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_ANODE, mndProcessCreateAnodeReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_ANODE, mndProcessUpdateAnodeReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_DROP_ANODE, mndProcessDropAnodeReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_ANAL_ALGO, mndProcessAnalAlgoReq);
|
||||||
|
|
||||||
|
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_ANODE, mndRetrieveAnodes);
|
||||||
|
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_ANODE, mndCancelGetNextAnode);
|
||||||
|
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_ANODE_FULL, mndRetrieveAnodesFull);
|
||||||
|
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_ANODE_FULL, mndCancelGetNextAnodeFull);
|
||||||
|
|
||||||
|
return sdbSetTable(pMnode->pSdb, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mndCleanupAnode(SMnode *pMnode) {}
|
||||||
|
|
||||||
|
SAnodeObj *mndAcquireAnode(SMnode *pMnode, int32_t anodeId) {
|
||||||
|
SAnodeObj *pObj = sdbAcquire(pMnode->pSdb, SDB_ANODE, &anodeId);
|
||||||
|
if (pObj == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||||
|
terrno = TSDB_CODE_MND_ANODE_NOT_EXIST;
|
||||||
|
}
|
||||||
|
return pObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mndReleaseAnode(SMnode *pMnode, SAnodeObj *pObj) {
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
sdbRelease(pSdb, pObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSdbRaw *mndAnodeActionEncode(SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino = 0;
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
int32_t rawDataLen = sizeof(SAnodeObj) + TSDB_ANODE_RESERVE_SIZE + pObj->urlLen;
|
||||||
|
for (int32_t t = 0; t < pObj->numOfAlgos; ++t) {
|
||||||
|
SArray *algos = pObj->algos[t];
|
||||||
|
for (int32_t a = 0; a < (int32_t)taosArrayGetSize(algos); ++a) {
|
||||||
|
SAnodeAlgo *algo = taosArrayGet(algos, a);
|
||||||
|
rawDataLen += (2 * sizeof(int32_t) + algo->nameLen);
|
||||||
|
}
|
||||||
|
rawDataLen += sizeof(int32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSdbRaw *pRaw = sdbAllocRaw(SDB_ANODE, TSDB_ANODE_VER_NUMBER, rawDataLen);
|
||||||
|
if (pRaw == NULL) goto _OVER;
|
||||||
|
|
||||||
|
int32_t dataPos = 0;
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pObj->id, _OVER)
|
||||||
|
SDB_SET_INT64(pRaw, dataPos, pObj->createdTime, _OVER)
|
||||||
|
SDB_SET_INT64(pRaw, dataPos, pObj->updateTime, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pObj->version, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pObj->urlLen, _OVER)
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, pObj->url, pObj->urlLen, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, pObj->numOfAlgos, _OVER)
|
||||||
|
for (int32_t i = 0; i < pObj->numOfAlgos; ++i) {
|
||||||
|
SArray *algos = pObj->algos[i];
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, (int32_t)taosArrayGetSize(algos), _OVER)
|
||||||
|
for (int32_t j = 0; j < (int32_t)taosArrayGetSize(algos); ++j) {
|
||||||
|
SAnodeAlgo *algo = taosArrayGet(algos, j);
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, algo->nameLen, _OVER)
|
||||||
|
SDB_SET_BINARY(pRaw, dataPos, algo->name, algo->nameLen, _OVER)
|
||||||
|
SDB_SET_INT32(pRaw, dataPos, 0, _OVER) // reserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDB_SET_RESERVE(pRaw, dataPos, TSDB_ANODE_RESERVE_SIZE, _OVER)
|
||||||
|
|
||||||
|
terrno = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (terrno != 0) {
|
||||||
|
mError("anode:%d, failed to encode to raw:%p since %s", pObj->id, pRaw, terrstr());
|
||||||
|
sdbFreeRaw(pRaw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTrace("anode:%d, encode to raw:%p, row:%p", pObj->id, pRaw, pObj);
|
||||||
|
return pRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSdbRow *mndAnodeActionDecode(SSdbRaw *pRaw) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino = 0;
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
SSdbRow *pRow = NULL;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
|
||||||
|
int8_t sver = 0;
|
||||||
|
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
|
||||||
|
|
||||||
|
if (sver != TSDB_ANODE_VER_NUMBER) {
|
||||||
|
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRow = sdbAllocRow(sizeof(SAnodeObj));
|
||||||
|
if (pRow == NULL) goto _OVER;
|
||||||
|
|
||||||
|
pObj = sdbGetRowObj(pRow);
|
||||||
|
if (pObj == NULL) goto _OVER;
|
||||||
|
|
||||||
|
int32_t dataPos = 0;
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pObj->id, _OVER)
|
||||||
|
SDB_GET_INT64(pRaw, dataPos, &pObj->createdTime, _OVER)
|
||||||
|
SDB_GET_INT64(pRaw, dataPos, &pObj->updateTime, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pObj->version, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pObj->urlLen, _OVER)
|
||||||
|
|
||||||
|
if (pObj->urlLen > 0) {
|
||||||
|
pObj->url = taosMemoryCalloc(pObj->urlLen, 1);
|
||||||
|
if (pObj->url == NULL) goto _OVER;
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, pObj->url, pObj->urlLen, _OVER)
|
||||||
|
}
|
||||||
|
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &pObj->numOfAlgos, _OVER)
|
||||||
|
if (pObj->numOfAlgos > 0) {
|
||||||
|
pObj->algos = taosMemoryCalloc(pObj->numOfAlgos, sizeof(SArray *));
|
||||||
|
if (pObj->algos == NULL) {
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pObj->numOfAlgos; ++i) {
|
||||||
|
int32_t numOfAlgos = 0;
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &numOfAlgos, _OVER)
|
||||||
|
|
||||||
|
pObj->algos[i] = taosArrayInit(2, sizeof(SAnodeAlgo));
|
||||||
|
if (pObj->algos[i] == NULL) goto _OVER;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < numOfAlgos; ++j) {
|
||||||
|
SAnodeAlgo algoObj = {0};
|
||||||
|
int32_t reserved = 0;
|
||||||
|
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &algoObj.nameLen, _OVER)
|
||||||
|
if (algoObj.nameLen > 0) {
|
||||||
|
algoObj.name = taosMemoryCalloc(algoObj.nameLen, 1);
|
||||||
|
if (algoObj.name == NULL) goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDB_GET_BINARY(pRaw, dataPos, algoObj.name, algoObj.nameLen, _OVER)
|
||||||
|
SDB_GET_INT32(pRaw, dataPos, &reserved, _OVER);
|
||||||
|
|
||||||
|
if (taosArrayPush(pObj->algos[i], &algoObj) == NULL) goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDB_GET_RESERVE(pRaw, dataPos, TSDB_ANODE_RESERVE_SIZE, _OVER)
|
||||||
|
|
||||||
|
terrno = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (terrno != 0) {
|
||||||
|
mError("anode:%d, failed to decode from raw:%p since %s", pObj == NULL ? 0 : pObj->id, pRaw, terrstr());
|
||||||
|
if (pObj != NULL) {
|
||||||
|
taosMemoryFreeClear(pObj->url);
|
||||||
|
}
|
||||||
|
taosMemoryFreeClear(pRow);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTrace("anode:%d, decode from raw:%p, row:%p", pObj->id, pRaw, pObj);
|
||||||
|
return pRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mndFreeAnode(SAnodeObj *pObj) {
|
||||||
|
taosMemoryFreeClear(pObj->url);
|
||||||
|
for (int32_t i = 0; i < pObj->numOfAlgos; ++i) {
|
||||||
|
SArray *algos = pObj->algos[i];
|
||||||
|
for (int32_t j = 0; j < (int32_t)taosArrayGetSize(algos); ++j) {
|
||||||
|
SAnodeAlgo *algo = taosArrayGet(algos, j);
|
||||||
|
taosMemoryFreeClear(algo->name);
|
||||||
|
}
|
||||||
|
taosArrayDestroy(algos);
|
||||||
|
}
|
||||||
|
taosMemoryFreeClear(pObj->algos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndAnodeActionInsert(SSdb *pSdb, SAnodeObj *pObj) {
|
||||||
|
mTrace("anode:%d, perform insert action, row:%p", pObj->id, pObj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndAnodeActionDelete(SSdb *pSdb, SAnodeObj *pObj) {
|
||||||
|
mTrace("anode:%d, perform delete action, row:%p", pObj->id, pObj);
|
||||||
|
mndFreeAnode(pObj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndAnodeActionUpdate(SSdb *pSdb, SAnodeObj *pOld, SAnodeObj *pNew) {
|
||||||
|
mTrace("anode:%d, perform update action, old row:%p new row:%p", pOld->id, pOld, pNew);
|
||||||
|
|
||||||
|
taosWLockLatch(&pOld->lock);
|
||||||
|
int32_t numOfAlgos = pNew->numOfAlgos;
|
||||||
|
void *algos = pNew->algos;
|
||||||
|
pNew->numOfAlgos = pOld->numOfAlgos;
|
||||||
|
pNew->algos = pOld->algos;
|
||||||
|
pOld->numOfAlgos = numOfAlgos;
|
||||||
|
pOld->algos = algos;
|
||||||
|
pOld->updateTime = pNew->updateTime;
|
||||||
|
pOld->version = pNew->version;
|
||||||
|
taosWUnLockLatch(&pOld->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetCreateAnodeRedoLogs(STrans *pTrans, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SSdbRaw *pRedoRaw = mndAnodeActionEncode(pObj);
|
||||||
|
if (pRedoRaw == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
|
||||||
|
TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING));
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetCreateAnodeUndoLogs(STrans *pTrans, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SSdbRaw *pUndoRaw = mndAnodeActionEncode(pObj);
|
||||||
|
if (pUndoRaw == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
TAOS_CHECK_RETURN(mndTransAppendUndolog(pTrans, pUndoRaw));
|
||||||
|
TAOS_CHECK_RETURN(sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED));
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetCreateAnodeCommitLogs(STrans *pTrans, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SSdbRaw *pCommitRaw = mndAnodeActionEncode(pObj);
|
||||||
|
if (pCommitRaw == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
|
||||||
|
TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY));
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndCreateAnode(SMnode *pMnode, SRpcMsg *pReq, SMCreateAnodeReq *pCreate) {
|
||||||
|
int32_t code = -1;
|
||||||
|
STrans *pTrans = NULL;
|
||||||
|
|
||||||
|
SAnodeObj anodeObj = {0};
|
||||||
|
anodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_ANODE);
|
||||||
|
anodeObj.createdTime = taosGetTimestampMs();
|
||||||
|
anodeObj.updateTime = anodeObj.createdTime;
|
||||||
|
anodeObj.version = 0;
|
||||||
|
anodeObj.urlLen = pCreate->urlLen;
|
||||||
|
if (anodeObj.urlLen > TSDB_ANAL_ANODE_URL_LEN) {
|
||||||
|
code = TSDB_CODE_MND_ANODE_TOO_LONG_URL;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
anodeObj.url = taosMemoryCalloc(1, pCreate->urlLen);
|
||||||
|
if (anodeObj.url == NULL) goto _OVER;
|
||||||
|
(void)memcpy(anodeObj.url, pCreate->url, pCreate->urlLen);
|
||||||
|
|
||||||
|
code = mndGetAnodeAlgoList(anodeObj.url, &anodeObj);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "create-anode");
|
||||||
|
if (pTrans == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
mndTransSetSerial(pTrans);
|
||||||
|
|
||||||
|
mInfo("trans:%d, used to create anode:%s as anode:%d", pTrans->id, pCreate->url, anodeObj.id);
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(mndSetCreateAnodeRedoLogs(pTrans, &anodeObj), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndSetCreateAnodeUndoLogs(pTrans, &anodeObj), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndSetCreateAnodeCommitLogs(pTrans, &anodeObj), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
mndFreeAnode(&anodeObj);
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SAnodeObj *mndAcquireAnodeByURL(SMnode *pMnode, char *url) {
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
|
||||||
|
void *pIter = NULL;
|
||||||
|
while (1) {
|
||||||
|
SAnodeObj *pAnode = NULL;
|
||||||
|
pIter = sdbFetch(pSdb, SDB_ANODE, pIter, (void **)&pAnode);
|
||||||
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
|
if (strcasecmp(url, pAnode->url) == 0) {
|
||||||
|
sdbCancelFetch(pSdb, pIter);
|
||||||
|
return pAnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbRelease(pSdb, pAnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
terrno = TSDB_CODE_MND_ANODE_NOT_EXIST;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndProcessCreateAnodeReq(SRpcMsg *pReq) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
int32_t code = -1;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
SMCreateAnodeReq createReq = {0};
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(tDeserializeSMCreateAnodeReq(pReq->pCont, pReq->contLen, &createReq), NULL, _OVER);
|
||||||
|
|
||||||
|
mInfo("anode:%s, start to create", createReq.url);
|
||||||
|
TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_ANODE), NULL, _OVER);
|
||||||
|
|
||||||
|
pObj = mndAcquireAnodeByURL(pMnode, createReq.url);
|
||||||
|
if (pObj != NULL) {
|
||||||
|
code = TSDB_CODE_MND_ANODE_ALREADY_EXIST;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = mndCreateAnode(pMnode, pReq, &createReq);
|
||||||
|
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||||
|
mError("anode:%s, failed to create since %s", createReq.url, tstrerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
mndReleaseAnode(pMnode, pObj);
|
||||||
|
tFreeSMCreateAnodeReq(&createReq);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndUpdateAnode(SMnode *pMnode, SAnodeObj *pAnode, SRpcMsg *pReq) {
|
||||||
|
mInfo("anode:%d, start to update", pAnode->id);
|
||||||
|
int32_t code = -1;
|
||||||
|
STrans *pTrans = NULL;
|
||||||
|
SAnodeObj anodeObj = {0};
|
||||||
|
anodeObj.id = pAnode->id;
|
||||||
|
anodeObj.updateTime = taosGetTimestampMs();
|
||||||
|
|
||||||
|
code = mndGetAnodeAlgoList(pAnode->url, &anodeObj);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-anode");
|
||||||
|
if (pTrans == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
mInfo("trans:%d, used to update anode:%d", pTrans->id, anodeObj.id);
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(mndSetCreateAnodeCommitLogs(pTrans, &anodeObj), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
|
||||||
|
code = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
mndFreeAnode(&anodeObj);
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndUpdateAllAnodes(SMnode *pMnode, SRpcMsg *pReq) {
|
||||||
|
mInfo("update all anodes");
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t rows = 0;
|
||||||
|
int32_t numOfRows = sdbGetSize(pSdb, SDB_ANODE);
|
||||||
|
|
||||||
|
void *pIter = NULL;
|
||||||
|
while (1) {
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
ESdbStatus objStatus = 0;
|
||||||
|
pIter = sdbFetchAll(pSdb, SDB_ANODE, pIter, (void **)&pObj, &objStatus, true);
|
||||||
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
|
rows++;
|
||||||
|
void *transReq = NULL;
|
||||||
|
if (rows == numOfRows) transReq = pReq;
|
||||||
|
code = mndUpdateAnode(pMnode, pObj, transReq);
|
||||||
|
sdbRelease(pSdb, pObj);
|
||||||
|
|
||||||
|
if (code != 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == 0 && rows == numOfRows) {
|
||||||
|
code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndProcessUpdateAnodeReq(SRpcMsg *pReq) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
int32_t code = -1;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
SMUpdateAnodeReq updateReq = {0};
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(tDeserializeSMUpdateAnodeReq(pReq->pCont, pReq->contLen, &updateReq), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_UPDATE_ANODE), NULL, _OVER);
|
||||||
|
|
||||||
|
if (updateReq.anodeId == -1) {
|
||||||
|
code = mndUpdateAllAnodes(pMnode, pReq);
|
||||||
|
} else {
|
||||||
|
pObj = mndAcquireAnode(pMnode, updateReq.anodeId);
|
||||||
|
if (pObj == NULL) {
|
||||||
|
code = TSDB_CODE_MND_ANODE_NOT_EXIST;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
code = mndUpdateAnode(pMnode, pObj, pReq);
|
||||||
|
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||||
|
if (updateReq.anodeId != -1) {
|
||||||
|
mError("anode:%d, failed to update since %s", updateReq.anodeId, tstrerror(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mndReleaseAnode(pMnode, pObj);
|
||||||
|
tFreeSMUpdateAnodeReq(&updateReq);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetDropAnodeRedoLogs(STrans *pTrans, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SSdbRaw *pRedoRaw = mndAnodeActionEncode(pObj);
|
||||||
|
if (pRedoRaw == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
TAOS_CHECK_RETURN(mndTransAppendRedolog(pTrans, pRedoRaw));
|
||||||
|
TAOS_CHECK_RETURN(sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING));
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetDropAnodeCommitLogs(STrans *pTrans, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SSdbRaw *pCommitRaw = mndAnodeActionEncode(pObj);
|
||||||
|
if (pCommitRaw == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
TAOS_CHECK_RETURN(mndTransAppendCommitlog(pTrans, pCommitRaw));
|
||||||
|
TAOS_CHECK_RETURN(sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED));
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndSetDropAnodeInfoToTrans(SMnode *pMnode, STrans *pTrans, SAnodeObj *pObj, bool force) {
|
||||||
|
if (pObj == NULL) return 0;
|
||||||
|
TAOS_CHECK_RETURN(mndSetDropAnodeRedoLogs(pTrans, pObj));
|
||||||
|
TAOS_CHECK_RETURN(mndSetDropAnodeCommitLogs(pTrans, pObj));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndDropAnode(SMnode *pMnode, SRpcMsg *pReq, SAnodeObj *pObj) {
|
||||||
|
int32_t code = -1;
|
||||||
|
|
||||||
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq, "drop-anode");
|
||||||
|
if (pTrans == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
mndTransSetSerial(pTrans);
|
||||||
|
|
||||||
|
mInfo("trans:%d, used to drop anode:%d", pTrans->id, pObj->id);
|
||||||
|
TAOS_CHECK_GOTO(mndSetDropAnodeInfoToTrans(pMnode, pTrans, pObj, false), NULL, _OVER);
|
||||||
|
TAOS_CHECK_GOTO(mndTransPrepare(pMnode, pTrans), NULL, _OVER);
|
||||||
|
|
||||||
|
code = 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndProcessDropAnodeReq(SRpcMsg *pReq) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
int32_t code = -1;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
SMDropAnodeReq dropReq = {0};
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(tDeserializeSMDropAnodeReq(pReq->pCont, pReq->contLen, &dropReq), NULL, _OVER);
|
||||||
|
|
||||||
|
mInfo("anode:%d, start to drop", dropReq.anodeId);
|
||||||
|
TAOS_CHECK_GOTO(mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_ANODE), NULL, _OVER);
|
||||||
|
|
||||||
|
if (dropReq.anodeId <= 0) {
|
||||||
|
code = TSDB_CODE_INVALID_MSG;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
pObj = mndAcquireAnode(pMnode, dropReq.anodeId);
|
||||||
|
if (pObj == NULL) {
|
||||||
|
code = TSDB_CODE_MND_RETURN_VALUE_NULL;
|
||||||
|
if (terrno != 0) code = terrno;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = mndDropAnode(pMnode, pReq, pObj);
|
||||||
|
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||||
|
mError("anode:%d, failed to drop since %s", dropReq.anodeId, tstrerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
mndReleaseAnode(pMnode, pObj);
|
||||||
|
tFreeSMDropAnodeReq(&dropReq);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndRetrieveAnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
int32_t numOfRows = 0;
|
||||||
|
int32_t cols = 0;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
char buf[TSDB_ANAL_ANODE_URL_LEN + VARSTR_HEADER_SIZE];
|
||||||
|
char status[64];
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
while (numOfRows < rows) {
|
||||||
|
pShow->pIter = sdbFetch(pSdb, SDB_ANODE, pShow->pIter, (void **)&pObj);
|
||||||
|
if (pShow->pIter == NULL) break;
|
||||||
|
|
||||||
|
cols = 0;
|
||||||
|
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
STR_WITH_MAXSIZE_TO_VARSTR(buf, pObj->url, pShow->pMeta->pSchemas[cols].bytes);
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
status[0] = 0;
|
||||||
|
if (mndGetAnodeStatus(pObj, status, 64) == 0) {
|
||||||
|
STR_TO_VARSTR(buf, status);
|
||||||
|
} else {
|
||||||
|
STR_TO_VARSTR(buf, "offline");
|
||||||
|
}
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, buf, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->createdTime, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->updateTime, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
numOfRows++;
|
||||||
|
sdbRelease(pSdb, pObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_end:
|
||||||
|
if (code != 0) sdbRelease(pSdb, pObj);
|
||||||
|
|
||||||
|
pShow->numOfRows += numOfRows;
|
||||||
|
return numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mndCancelGetNextAnode(SMnode *pMnode, void *pIter) {
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
sdbCancelFetchByType(pSdb, pIter, SDB_ANODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndRetrieveAnodesFull(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
int32_t numOfRows = 0;
|
||||||
|
int32_t cols = 0;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
char buf[TSDB_ANAL_ALGO_NAME_LEN + VARSTR_HEADER_SIZE];
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
while (numOfRows < rows) {
|
||||||
|
pShow->pIter = sdbFetch(pSdb, SDB_ANODE, pShow->pIter, (void **)&pObj);
|
||||||
|
if (pShow->pIter == NULL) break;
|
||||||
|
|
||||||
|
for (int32_t t = 0; t < pObj->numOfAlgos; ++t) {
|
||||||
|
SArray *algos = pObj->algos[t];
|
||||||
|
|
||||||
|
for (int32_t a = 0; a < taosArrayGetSize(algos); ++a) {
|
||||||
|
SAnodeAlgo *algo = taosArrayGet(algos, a);
|
||||||
|
|
||||||
|
cols = 0;
|
||||||
|
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, (const char *)&pObj->id, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
STR_TO_VARSTR(buf, taosAnalAlgoStr(t));
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, buf, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
STR_TO_VARSTR(buf, algo->name);
|
||||||
|
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||||
|
code = colDataSetVal(pColInfo, numOfRows, buf, false);
|
||||||
|
if (code != 0) goto _end;
|
||||||
|
|
||||||
|
numOfRows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbRelease(pSdb, pObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_end:
|
||||||
|
if (code != 0) sdbRelease(pSdb, pObj);
|
||||||
|
|
||||||
|
pShow->numOfRows += numOfRows;
|
||||||
|
return numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mndCancelGetNextAnodeFull(SMnode *pMnode, void *pIter) {
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
sdbCancelFetchByType(pSdb, pIter, SDB_ANODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndDecodeAlgoList(SJson *pJson, SAnodeObj *pObj) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t protocol = 0;
|
||||||
|
double tmp = 0;
|
||||||
|
char buf[TSDB_ANAL_ALGO_NAME_LEN + 1] = {0};
|
||||||
|
|
||||||
|
code = tjsonGetDoubleValue(pJson, "protocol", &tmp);
|
||||||
|
if (code < 0) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
protocol = (int32_t)(tmp * 1000);
|
||||||
|
if (protocol != 100 && protocol != 1000) return TSDB_CODE_MND_ANODE_INVALID_PROTOCOL;
|
||||||
|
|
||||||
|
code = tjsonGetDoubleValue(pJson, "version", &tmp);
|
||||||
|
pObj->version = (int32_t)(tmp * 1000);
|
||||||
|
#if 0
|
||||||
|
if (code < 0) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
if (pObj->version <= 0) return TSDB_CODE_MND_ANODE_INVALID_VERSION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SJson *details = tjsonGetObjectItem(pJson, "details");
|
||||||
|
if (details == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
int32_t numOfDetails = tjsonGetArraySize(details);
|
||||||
|
|
||||||
|
pObj->algos = taosMemoryCalloc(ANAL_ALGO_TYPE_END, sizeof(SArray *));
|
||||||
|
if (pObj->algos == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
pObj->numOfAlgos = ANAL_ALGO_TYPE_END;
|
||||||
|
for (int32_t i = 0; i < ANAL_ALGO_TYPE_END; ++i) {
|
||||||
|
pObj->algos[i] = taosArrayInit(4, sizeof(SAnodeAlgo));
|
||||||
|
if (pObj->algos[i] == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t d = 0; d < numOfDetails; ++d) {
|
||||||
|
SJson *detail = tjsonGetArrayItem(details, d);
|
||||||
|
if (detail == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
code = tjsonGetStringValue2(detail, "type", buf, sizeof(buf));
|
||||||
|
if (code < 0) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
EAnalAlgoType type = taosAnalAlgoInt(buf);
|
||||||
|
if (type < 0 || type >= ANAL_ALGO_TYPE_END) return TSDB_CODE_MND_ANODE_INVALID_ALGO_TYPE;
|
||||||
|
|
||||||
|
SJson *algos = tjsonGetObjectItem(detail, "algo");
|
||||||
|
if (algos == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
int32_t numOfAlgos = tjsonGetArraySize(algos);
|
||||||
|
for (int32_t a = 0; a < numOfAlgos; ++a) {
|
||||||
|
SJson *algo = tjsonGetArrayItem(algos, a);
|
||||||
|
if (algo == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
code = tjsonGetStringValue2(algo, "name", buf, sizeof(buf));
|
||||||
|
if (code < 0) return TSDB_CODE_MND_ANODE_TOO_LONG_ALGO_NAME;
|
||||||
|
|
||||||
|
SAnodeAlgo algoObj = {0};
|
||||||
|
algoObj.nameLen = strlen(buf) + 1;
|
||||||
|
if (algoObj.nameLen <= 1) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
algoObj.name = taosMemoryCalloc(algoObj.nameLen, 1);
|
||||||
|
tstrncpy(algoObj.name, buf, algoObj.nameLen);
|
||||||
|
|
||||||
|
if (taosArrayPush(pObj->algos[type], &algoObj) == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndGetAnodeAlgoList(const char *url, SAnodeObj *pObj) {
|
||||||
|
char anodeUrl[TSDB_ANAL_ANODE_URL_LEN + 1] = {0};
|
||||||
|
snprintf(anodeUrl, TSDB_ANAL_ANODE_URL_LEN, "%s/%s", url, "list");
|
||||||
|
|
||||||
|
SJson *pJson = taosAnalSendReqRetJson(anodeUrl, ANAL_HTTP_TYPE_GET, NULL);
|
||||||
|
if (pJson == NULL) return terrno;
|
||||||
|
|
||||||
|
int32_t code = mndDecodeAlgoList(pJson, pObj);
|
||||||
|
if (pJson != NULL) tjsonDelete(pJson);
|
||||||
|
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndGetAnodeStatus(SAnodeObj *pObj, char *status, int32_t statusLen) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t protocol = 0;
|
||||||
|
double tmp = 0;
|
||||||
|
char anodeUrl[TSDB_ANAL_ANODE_URL_LEN + 1] = {0};
|
||||||
|
snprintf(anodeUrl, TSDB_ANAL_ANODE_URL_LEN, "%s/%s", pObj->url, "status");
|
||||||
|
|
||||||
|
SJson *pJson = taosAnalSendReqRetJson(anodeUrl, ANAL_HTTP_TYPE_GET, NULL);
|
||||||
|
if (pJson == NULL) return terrno;
|
||||||
|
|
||||||
|
code = tjsonGetDoubleValue(pJson, "protocol", &tmp);
|
||||||
|
if (code < 0) {
|
||||||
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
protocol = (int32_t)(tmp * 1000);
|
||||||
|
if (protocol != 100 && protocol != 1000) {
|
||||||
|
code = TSDB_CODE_MND_ANODE_INVALID_PROTOCOL;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tjsonGetStringValue2(pJson, "status", status, statusLen);
|
||||||
|
if (code < 0) {
|
||||||
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
if (strlen(status) == 0) {
|
||||||
|
code = TSDB_CODE_MND_ANODE_INVALID_PROTOCOL;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (pJson != NULL) tjsonDelete(pJson);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mndProcessAnalAlgoReq(SRpcMsg *pReq) {
|
||||||
|
SMnode *pMnode = pReq->info.node;
|
||||||
|
SSdb *pSdb = pMnode->pSdb;
|
||||||
|
int32_t code = -1;
|
||||||
|
SAnodeObj *pObj = NULL;
|
||||||
|
SAnalUrl url;
|
||||||
|
int32_t nameLen;
|
||||||
|
char name[TSDB_ANAL_ALGO_KEY_LEN];
|
||||||
|
SRetrieveAnalAlgoReq req = {0};
|
||||||
|
SRetrieveAnalAlgoRsp rsp = {0};
|
||||||
|
|
||||||
|
TAOS_CHECK_GOTO(tDeserializeRetrieveAnalAlgoReq(pReq->pCont, pReq->contLen, &req), NULL, _OVER);
|
||||||
|
|
||||||
|
rsp.ver = sdbGetTableVer(pSdb, SDB_ANODE);
|
||||||
|
if (req.analVer != rsp.ver) {
|
||||||
|
mInfo("dnode:%d, update analysis old ver:%" PRId64 " to new ver:%" PRId64, req.dnodeId, req.analVer, rsp.ver);
|
||||||
|
rsp.hash = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||||
|
if (rsp.hash == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pIter = NULL;
|
||||||
|
while (1) {
|
||||||
|
SAnodeObj *pAnode = NULL;
|
||||||
|
pIter = sdbFetch(pSdb, SDB_ANODE, pIter, (void **)&pAnode);
|
||||||
|
if (pIter == NULL) break;
|
||||||
|
|
||||||
|
url.anode = pAnode->id;
|
||||||
|
for (int32_t t = 0; t < pAnode->numOfAlgos; ++t) {
|
||||||
|
SArray *algos = pAnode->algos[t];
|
||||||
|
url.type = t;
|
||||||
|
|
||||||
|
for (int32_t a = 0; a < taosArrayGetSize(algos); ++a) {
|
||||||
|
SAnodeAlgo *algo = taosArrayGet(algos, a);
|
||||||
|
nameLen = 1 + tsnprintf(name, sizeof(name) - 1, "%d:%s", url.type, algo->name);
|
||||||
|
|
||||||
|
SAnalUrl *pOldUrl = taosHashAcquire(rsp.hash, name, nameLen);
|
||||||
|
if (pOldUrl == NULL || (pOldUrl != NULL && pOldUrl->anode < url.anode)) {
|
||||||
|
if (pOldUrl != NULL) {
|
||||||
|
taosMemoryFreeClear(pOldUrl->url);
|
||||||
|
if (taosHashRemove(rsp.hash, name, nameLen) != 0) {
|
||||||
|
sdbRelease(pSdb, pAnode);
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.url = taosMemoryMalloc(TSDB_ANAL_ANODE_URL_LEN + TSDB_ANAL_ALGO_TYPE_LEN + 1);
|
||||||
|
if (url.url == NULL) {
|
||||||
|
sdbRelease(pSdb, pAnode);
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
url.urlLen = 1 + tsnprintf(url.url, TSDB_ANAL_ANODE_URL_LEN + TSDB_ANAL_ALGO_TYPE_LEN, "%s/%s", pAnode->url,
|
||||||
|
taosAnalAlgoUrlStr(url.type));
|
||||||
|
if (taosHashPut(rsp.hash, name, nameLen, &url, sizeof(SAnalUrl)) != 0) {
|
||||||
|
taosMemoryFree(url.url);
|
||||||
|
sdbRelease(pSdb, pAnode);
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbRelease(pSdb, pAnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t contLen = tSerializeRetrieveAnalAlgoRsp(NULL, 0, &rsp);
|
||||||
|
void *pHead = rpcMallocCont(contLen);
|
||||||
|
(void)tSerializeRetrieveAnalAlgoRsp(pHead, contLen, &rsp);
|
||||||
|
|
||||||
|
pReq->info.rspLen = contLen;
|
||||||
|
pReq->info.rsp = pHead;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
tFreeRetrieveAnalAlgoRsp(&rsp);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int32_t mndProcessUnsupportReq(SRpcMsg *pReq) { return TSDB_CODE_OPS_NOT_SUPPORT; }
|
||||||
|
static int32_t mndRetrieveUnsupport(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||||
|
return TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mndInitAnode(SMnode *pMnode) {
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_ANODE, mndProcessUnsupportReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_UPDATE_ANODE, mndProcessUnsupportReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_DROP_ANODE, mndProcessUnsupportReq);
|
||||||
|
mndSetMsgHandle(pMnode, TDMT_MND_RETRIEVE_ANAL_ALGO, mndProcessUnsupportReq);
|
||||||
|
|
||||||
|
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_ANODE, mndRetrieveUnsupport);
|
||||||
|
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_ANODE_FULL, mndRetrieveUnsupport);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mndCleanupAnode(SMnode *pMnode) {}
|
||||||
|
|
||||||
|
#endif
|
|
@ -730,6 +730,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
|
||||||
|
|
||||||
pMnode->ipWhiteVer = mndGetIpWhiteVer(pMnode);
|
pMnode->ipWhiteVer = mndGetIpWhiteVer(pMnode);
|
||||||
|
|
||||||
|
int64_t analVer = sdbGetTableVer(pMnode->pSdb, SDB_ANODE);
|
||||||
int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
|
int64_t dnodeVer = sdbGetTableVer(pMnode->pSdb, SDB_DNODE) + sdbGetTableVer(pMnode->pSdb, SDB_MNODE);
|
||||||
int64_t curMs = taosGetTimestampMs();
|
int64_t curMs = taosGetTimestampMs();
|
||||||
bool online = mndIsDnodeOnline(pDnode, curMs);
|
bool online = mndIsDnodeOnline(pDnode, curMs);
|
||||||
|
@ -738,7 +739,8 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
|
||||||
bool supportVnodesChanged = pDnode->numOfSupportVnodes != statusReq.numOfSupportVnodes;
|
bool supportVnodesChanged = pDnode->numOfSupportVnodes != statusReq.numOfSupportVnodes;
|
||||||
bool encryptKeyChanged = pDnode->encryptionKeyChksum != statusReq.clusterCfg.encryptionKeyChksum;
|
bool encryptKeyChanged = pDnode->encryptionKeyChksum != statusReq.clusterCfg.encryptionKeyChksum;
|
||||||
bool enableWhiteListChanged = statusReq.clusterCfg.enableWhiteList != (tsEnableWhiteList ? 1 : 0);
|
bool enableWhiteListChanged = statusReq.clusterCfg.enableWhiteList != (tsEnableWhiteList ? 1 : 0);
|
||||||
bool needCheck = !online || dnodeChanged || reboot || supportVnodesChanged ||
|
bool analVerChanged = (analVer != statusReq.analVer);
|
||||||
|
bool needCheck = !online || dnodeChanged || reboot || supportVnodesChanged || analVerChanged ||
|
||||||
pMnode->ipWhiteVer != statusReq.ipWhiteVer || encryptKeyChanged || enableWhiteListChanged;
|
pMnode->ipWhiteVer != statusReq.ipWhiteVer || encryptKeyChanged || enableWhiteListChanged;
|
||||||
const STraceId *trace = &pReq->info.traceId;
|
const STraceId *trace = &pReq->info.traceId;
|
||||||
mGTrace("dnode:%d, status received, accessTimes:%d check:%d online:%d reboot:%d changed:%d statusSeq:%d", pDnode->id,
|
mGTrace("dnode:%d, status received, accessTimes:%d check:%d online:%d reboot:%d changed:%d statusSeq:%d", pDnode->id,
|
||||||
|
@ -862,6 +864,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq) {
|
||||||
|
|
||||||
SStatusRsp statusRsp = {0};
|
SStatusRsp statusRsp = {0};
|
||||||
statusRsp.statusSeq++;
|
statusRsp.statusSeq++;
|
||||||
|
statusRsp.analVer = analVer;
|
||||||
statusRsp.dnodeVer = dnodeVer;
|
statusRsp.dnodeVer = dnodeVer;
|
||||||
statusRsp.dnodeCfg.dnodeId = pDnode->id;
|
statusRsp.dnodeCfg.dnodeId = pDnode->id;
|
||||||
statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
|
statusRsp.dnodeCfg.clusterId = pMnode->clusterId;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "mndAcct.h"
|
#include "mndAcct.h"
|
||||||
#include "mndArbGroup.h"
|
#include "mndArbGroup.h"
|
||||||
|
#include "mndAnode.h"
|
||||||
#include "mndCluster.h"
|
#include "mndCluster.h"
|
||||||
#include "mndCompact.h"
|
#include "mndCompact.h"
|
||||||
#include "mndCompactDetail.h"
|
#include "mndCompactDetail.h"
|
||||||
|
@ -608,6 +609,7 @@ static int32_t mndInitSteps(SMnode *pMnode) {
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-mnode", mndInitMnode, mndCleanupMnode));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-mnode", mndInitMnode, mndCleanupMnode));
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-qnode", mndInitQnode, mndCleanupQnode));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-qnode", mndInitQnode, mndCleanupQnode));
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-snode", mndInitSnode, mndCleanupSnode));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-snode", mndInitSnode, mndCleanupSnode));
|
||||||
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-anode", mndInitAnode, mndCleanupAnode));
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-arbgroup", mndInitArbGroup, mndCleanupArbGroup));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-arbgroup", mndInitArbGroup, mndCleanupArbGroup));
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-dnode", mndInitDnode, mndCleanupDnode));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-dnode", mndInitDnode, mndCleanupDnode));
|
||||||
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser));
|
TAOS_CHECK_RETURN(mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser));
|
||||||
|
|
|
@ -68,6 +68,10 @@ static int32_t convertToRetrieveType(char *name, int32_t len) {
|
||||||
type = TSDB_MGMT_TABLE_QNODE;
|
type = TSDB_MGMT_TABLE_QNODE;
|
||||||
} else if (strncasecmp(name, TSDB_INS_TABLE_SNODES, len) == 0) {
|
} else if (strncasecmp(name, TSDB_INS_TABLE_SNODES, len) == 0) {
|
||||||
type = TSDB_MGMT_TABLE_SNODE;
|
type = TSDB_MGMT_TABLE_SNODE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_ANODES, len) == 0) {
|
||||||
|
type = TSDB_MGMT_TABLE_ANODE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_ANODES_FULL, len) == 0) {
|
||||||
|
type = TSDB_MGMT_TABLE_ANODE_FULL;
|
||||||
} else if (strncasecmp(name, TSDB_INS_TABLE_ARBGROUPS, len) == 0) {
|
} else if (strncasecmp(name, TSDB_INS_TABLE_ARBGROUPS, len) == 0) {
|
||||||
type = TSDB_MGMT_TABLE_ARBGROUP;
|
type = TSDB_MGMT_TABLE_ARBGROUP;
|
||||||
} else if (strncasecmp(name, TSDB_INS_TABLE_CLUSTER, len) == 0) {
|
} else if (strncasecmp(name, TSDB_INS_TABLE_CLUSTER, len) == 0) {
|
||||||
|
|
|
@ -2252,7 +2252,7 @@ static int32_t mndRetrieveTSMA(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
|
||||||
if (nodeType(pFunc) == QUERY_NODE_FUNCTION) {
|
if (nodeType(pFunc) == QUERY_NODE_FUNCTION) {
|
||||||
SFunctionNode *pFuncNode = (SFunctionNode *)pFunc;
|
SFunctionNode *pFuncNode = (SFunctionNode *)pFunc;
|
||||||
if (!fmIsTSMASupportedFunc(pFuncNode->funcId)) continue;
|
if (!fmIsTSMASupportedFunc(pFuncNode->funcId)) continue;
|
||||||
len += snprintf(start, TSDB_MAX_SAVED_SQL_LEN - len, "%s%s", start != buf + VARSTR_HEADER_SIZE ? "," : "",
|
len += tsnprintf(start, TSDB_MAX_SAVED_SQL_LEN - len, "%s%s", start != buf + VARSTR_HEADER_SIZE ? "," : "",
|
||||||
((SExprNode *)pFunc)->userAlias);
|
((SExprNode *)pFunc)->userAlias);
|
||||||
if (len >= TSDB_MAX_SAVED_SQL_LEN) {
|
if (len >= TSDB_MAX_SAVED_SQL_LEN) {
|
||||||
len = TSDB_MAX_SAVED_SQL_LEN;
|
len = TSDB_MAX_SAVED_SQL_LEN;
|
||||||
|
|
|
@ -474,6 +474,21 @@ static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans) {
|
||||||
// pTrans->startFunc = 0;
|
// pTrans->startFunc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pTrans->stage == TRN_STAGE_COMMIT) {
|
||||||
|
pTrans->stage = TRN_STAGE_COMMIT_ACTION;
|
||||||
|
mInfo("trans:%d, stage from commit to commitAction since perform update action", pTrans->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTrans->stage == TRN_STAGE_ROLLBACK) {
|
||||||
|
pTrans->stage = TRN_STAGE_UNDO_ACTION;
|
||||||
|
mInfo("trans:%d, stage from rollback to undoAction since perform update action", pTrans->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTrans->stage == TRN_STAGE_PRE_FINISH) {
|
||||||
|
pTrans->stage = TRN_STAGE_FINISH;
|
||||||
|
mInfo("trans:%d, stage from pre-finish to finished since perform update action", pTrans->id);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,17 +578,17 @@ static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOld, STrans *pNew) {
|
||||||
|
|
||||||
if (pOld->stage == TRN_STAGE_COMMIT) {
|
if (pOld->stage == TRN_STAGE_COMMIT) {
|
||||||
pOld->stage = TRN_STAGE_COMMIT_ACTION;
|
pOld->stage = TRN_STAGE_COMMIT_ACTION;
|
||||||
mTrace("trans:%d, stage from commit to commitAction since perform update action", pNew->id);
|
mInfo("trans:%d, stage from commit to commitAction since perform update action", pNew->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOld->stage == TRN_STAGE_ROLLBACK) {
|
if (pOld->stage == TRN_STAGE_ROLLBACK) {
|
||||||
pOld->stage = TRN_STAGE_UNDO_ACTION;
|
pOld->stage = TRN_STAGE_UNDO_ACTION;
|
||||||
mTrace("trans:%d, stage from rollback to undoAction since perform update action", pNew->id);
|
mInfo("trans:%d, stage from rollback to undoAction since perform update action", pNew->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOld->stage == TRN_STAGE_PRE_FINISH) {
|
if (pOld->stage == TRN_STAGE_PRE_FINISH) {
|
||||||
pOld->stage = TRN_STAGE_FINISH;
|
pOld->stage = TRN_STAGE_FINISH;
|
||||||
mTrace("trans:%d, stage from pre-finish to finished since perform update action", pNew->id);
|
mInfo("trans:%d, stage from pre-finish to finished since perform update action", pNew->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1295,7 +1310,7 @@ static void mndTransResetActions(SMnode *pMnode, STrans *pTrans, SArray *pArray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute at bottom half
|
// execute in sync context
|
||||||
static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||||
if (pAction->rawWritten) return 0;
|
if (pAction->rawWritten) return 0;
|
||||||
if (topHalf) {
|
if (topHalf) {
|
||||||
|
@ -1321,7 +1336,7 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
|
||||||
TAOS_RETURN(code);
|
TAOS_RETURN(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute at top half
|
// execute in trans context
|
||||||
static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||||
if (pAction->msgSent) return 0;
|
if (pAction->msgSent) return 0;
|
||||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) {
|
if (mndCannotExecuteTransAction(pMnode, topHalf)) {
|
||||||
|
@ -1701,6 +1716,7 @@ static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in trans context
|
||||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||||
|
|
||||||
|
@ -1775,6 +1791,7 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans, bool
|
||||||
return continueExec;
|
return continueExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in trans context
|
||||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,8 @@ typedef enum {
|
||||||
SDB_COMPACT_DETAIL = 25,
|
SDB_COMPACT_DETAIL = 25,
|
||||||
SDB_GRANT = 26, // grant log
|
SDB_GRANT = 26, // grant log
|
||||||
SDB_ARBGROUP = 27,
|
SDB_ARBGROUP = 27,
|
||||||
SDB_MAX = 28
|
SDB_ANODE = 28,
|
||||||
|
SDB_MAX = 29
|
||||||
} ESdbType;
|
} ESdbType;
|
||||||
|
|
||||||
typedef struct SSdbRaw {
|
typedef struct SSdbRaw {
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#define SDB_RESERVE_SIZE 512
|
#define SDB_RESERVE_SIZE 512
|
||||||
#define SDB_FILE_VER 1
|
#define SDB_FILE_VER 1
|
||||||
|
|
||||||
|
#define SDB_TABLE_SIZE_EXTRA SDB_MAX
|
||||||
|
#define SDB_RESERVE_SIZE_EXTRA (512 - (SDB_TABLE_SIZE_EXTRA - SDB_TABLE_SIZE) * 2 * sizeof(int64_t))
|
||||||
|
|
||||||
static int32_t sdbDeployData(SSdb *pSdb) {
|
static int32_t sdbDeployData(SSdb *pSdb) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
mInfo("start to deploy sdb");
|
mInfo("start to deploy sdb");
|
||||||
|
@ -154,7 +157,38 @@ static int32_t sdbReadFileHead(SSdb *pSdb, TdFilePtr pFile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char reserve[SDB_RESERVE_SIZE] = {0};
|
// for sdb compatibility
|
||||||
|
for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
|
||||||
|
int64_t maxId = 0;
|
||||||
|
ret = taosReadFile(pFile, &maxId, sizeof(int64_t));
|
||||||
|
if (ret < 0) {
|
||||||
|
code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
if (ret != sizeof(int64_t)) {
|
||||||
|
code = TSDB_CODE_FILE_CORRUPTED;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
if (i < SDB_MAX) {
|
||||||
|
pSdb->maxId[i] = maxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ver = 0;
|
||||||
|
ret = taosReadFile(pFile, &ver, sizeof(int64_t));
|
||||||
|
if (ret < 0) {
|
||||||
|
code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
if (ret != sizeof(int64_t)) {
|
||||||
|
code = TSDB_CODE_FILE_CORRUPTED;
|
||||||
|
TAOS_RETURN(code);
|
||||||
|
}
|
||||||
|
if (i < SDB_MAX) {
|
||||||
|
pSdb->tableVer[i] = ver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
|
||||||
ret = taosReadFile(pFile, reserve, sizeof(reserve));
|
ret = taosReadFile(pFile, reserve, sizeof(reserve));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return terrno;
|
return terrno;
|
||||||
|
@ -207,7 +241,26 @@ static int32_t sdbWriteFileHead(SSdb *pSdb, TdFilePtr pFile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char reserve[SDB_RESERVE_SIZE] = {0};
|
// for sdb compatibility
|
||||||
|
for (int32_t i = SDB_TABLE_SIZE; i < SDB_TABLE_SIZE_EXTRA; ++i) {
|
||||||
|
int64_t maxId = 0;
|
||||||
|
if (i < SDB_MAX) {
|
||||||
|
maxId = pSdb->maxId[i];
|
||||||
|
}
|
||||||
|
if (taosWriteFile(pFile, &maxId, sizeof(int64_t)) != sizeof(int64_t)) {
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ver = 0;
|
||||||
|
if (i < SDB_MAX) {
|
||||||
|
ver = pSdb->tableVer[i];
|
||||||
|
}
|
||||||
|
if (taosWriteFile(pFile, &ver, sizeof(int64_t)) != sizeof(int64_t)) {
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char reserve[SDB_RESERVE_SIZE_EXTRA] = {0};
|
||||||
if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
|
if (taosWriteFile(pFile, reserve, sizeof(reserve)) != sizeof(reserve)) {
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ const char *sdbTableName(ESdbType type) {
|
||||||
return "grant";
|
return "grant";
|
||||||
case SDB_ARBGROUP:
|
case SDB_ARBGROUP:
|
||||||
return "arb_group";
|
return "arb_group";
|
||||||
|
case SDB_ANODE:
|
||||||
|
return "anode";
|
||||||
default:
|
default:
|
||||||
return "undefine";
|
return "undefine";
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,17 +188,17 @@ do { \
|
||||||
#define EXPLAIN_ROW_NEW(level, ...) \
|
#define EXPLAIN_ROW_NEW(level, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (isVerboseLine) { \
|
if (isVerboseLine) { \
|
||||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s", (level) * 3 + 3, ""); \
|
tlen = tsnprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s", (level) * 3 + 3, ""); \
|
||||||
} else { \
|
} else { \
|
||||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s%s", (level) * 3, "", "-> "); \
|
tlen = tsnprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s%s", (level) * 3, "", "-> "); \
|
||||||
} \
|
} \
|
||||||
tlen += snprintf(tbuf + VARSTR_HEADER_SIZE + tlen, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE - tlen, __VA_ARGS__); \
|
tlen += tsnprintf(tbuf + VARSTR_HEADER_SIZE + tlen, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE - tlen, __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPLAIN_ROW_APPEND(...) tlen += snprintf(tbuf + VARSTR_HEADER_SIZE + tlen, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE - tlen, __VA_ARGS__)
|
#define EXPLAIN_ROW_APPEND(...) tlen += tsnprintf(tbuf + VARSTR_HEADER_SIZE + tlen, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE - tlen, __VA_ARGS__)
|
||||||
#define EXPLAIN_ROW_END() do { varDataSetLen(tbuf, tlen); tlen += VARSTR_HEADER_SIZE; isVerboseLine = true; } while (0)
|
#define EXPLAIN_ROW_END() do { varDataSetLen(tbuf, tlen); tlen += VARSTR_HEADER_SIZE; isVerboseLine = true; } while (0)
|
||||||
|
|
||||||
#define EXPLAIN_SUM_ROW_NEW(...) tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, __VA_ARGS__)
|
#define EXPLAIN_SUM_ROW_NEW(...) tlen = tsnprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, __VA_ARGS__)
|
||||||
#define EXPLAIN_SUM_ROW_END() do { varDataSetLen(tbuf, tlen); tlen += VARSTR_HEADER_SIZE; } while (0)
|
#define EXPLAIN_SUM_ROW_END() do { varDataSetLen(tbuf, tlen); tlen += VARSTR_HEADER_SIZE; } while (0)
|
||||||
|
|
||||||
#define EXPLAIN_ROW_APPEND_LIMIT_IMPL(_pLimit, sl) do { \
|
#define EXPLAIN_ROW_APPEND_LIMIT_IMPL(_pLimit, sl) do { \
|
||||||
|
|
|
@ -515,7 +515,7 @@ void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
|
||||||
TSDB_DATA_TYPE_GEOMETRY == pSchema->type) {
|
TSDB_DATA_TYPE_GEOMETRY == pSchema->type) {
|
||||||
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE));
|
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE));
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) {
|
} else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) {
|
||||||
typeLen += snprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)",
|
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "(%d)",
|
||||||
(int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
(int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ if(${TD_DARWIN})
|
||||||
target_compile_options(executor PRIVATE -Wno-error=deprecated-non-prototype)
|
target_compile_options(executor PRIVATE -Wno-error=deprecated-non-prototype)
|
||||||
endif(${TD_DARWIN})
|
endif(${TD_DARWIN})
|
||||||
|
|
||||||
|
IF(${BUILD_WITH_ANALYSIS})
|
||||||
|
add_definitions(-DUSE_ANAL)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
target_link_libraries(executor
|
target_link_libraries(executor
|
||||||
PRIVATE os util common function parser planner qcom scalar nodes index wal tdb geometry
|
PRIVATE os util common function parser planner qcom scalar nodes index wal tdb geometry
|
||||||
)
|
)
|
||||||
|
|
|
@ -48,6 +48,7 @@ typedef struct SGroupResInfo {
|
||||||
} SGroupResInfo;
|
} SGroupResInfo;
|
||||||
|
|
||||||
typedef struct SResultRow {
|
typedef struct SResultRow {
|
||||||
|
int32_t version;
|
||||||
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
|
||||||
bool startInterp; // the time window start timestamp has done the interpolation already.
|
bool startInterp; // the time window start timestamp has done the interpolation already.
|
||||||
|
@ -152,6 +153,9 @@ static FORCE_INLINE SResultRow* getResultRowByPos(SDiskbasedBuf* pBuf, SResultRo
|
||||||
return pRow;
|
return pRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t getResultRowFromBuf(struct SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize);
|
||||||
|
int32_t putResultRowToBuf(struct SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize);
|
||||||
|
|
||||||
int32_t initGroupedResultInfo(SGroupResInfo* pGroupResInfo, SSHashObj* pHashmap, int32_t order);
|
int32_t initGroupedResultInfo(SGroupResInfo* pGroupResInfo, SSHashObj* pHashmap, int32_t order);
|
||||||
void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo);
|
void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo);
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,8 @@ int32_t createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStreamPart
|
||||||
|
|
||||||
int32_t createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
int32_t createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
|
int32_t createForecastOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
int32_t createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
int32_t createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SSortMergeJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
int32_t createHashJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SHashJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
int32_t createHashJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SHashJoinPhysiNode* pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
@ -159,6 +161,8 @@ int32_t createCountwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* phy
|
||||||
|
|
||||||
int32_t createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SGroupCachePhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
int32_t createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SGroupCachePhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
|
int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
|
||||||
|
|
||||||
int32_t createStreamTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
|
int32_t createStreamTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
|
||||||
|
|
|
@ -0,0 +1,636 @@
|
||||||
|
/*
|
||||||
|
* 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 "executorInt.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "function.h"
|
||||||
|
#include "functionMgt.h"
|
||||||
|
#include "operator.h"
|
||||||
|
#include "querytask.h"
|
||||||
|
#include "tanal.h"
|
||||||
|
#include "tcommon.h"
|
||||||
|
#include "tcompare.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "tjson.h"
|
||||||
|
#include "ttime.h"
|
||||||
|
|
||||||
|
#ifdef USE_ANAL
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SArray* blocks; // SSDataBlock*
|
||||||
|
SArray* windows; // STimeWindow
|
||||||
|
uint64_t groupId;
|
||||||
|
int64_t cachedRows;
|
||||||
|
int32_t curWinIndex;
|
||||||
|
STimeWindow curWin;
|
||||||
|
SResultRow* pResultRow;
|
||||||
|
} SAnomalyWindowSupp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
SAggSupporter aggSup;
|
||||||
|
SExprSupp scalarSup;
|
||||||
|
int32_t tsSlotId;
|
||||||
|
STimeWindowAggSupp twAggSup;
|
||||||
|
char algoName[TSDB_ANAL_ALGO_NAME_LEN];
|
||||||
|
char algoUrl[TSDB_ANAL_ALGO_URL_LEN];
|
||||||
|
char anomalyOpt[TSDB_ANAL_ALGO_OPTION_LEN];
|
||||||
|
SAnomalyWindowSupp anomalySup;
|
||||||
|
SWindowRowsSup anomalyWinRowSup;
|
||||||
|
SColumn anomalyCol;
|
||||||
|
SStateKeys anomalyKey;
|
||||||
|
} SAnomalyWindowOperatorInfo;
|
||||||
|
|
||||||
|
static void anomalyDestroyOperatorInfo(void* param);
|
||||||
|
static int32_t anomalyAggregateNext(SOperatorInfo* pOperator, SSDataBlock** ppRes);
|
||||||
|
static void anomalyAggregateBlocks(SOperatorInfo* pOperator);
|
||||||
|
static int32_t anomalyCacheBlock(SAnomalyWindowOperatorInfo* pInfo, SSDataBlock* pBlock);
|
||||||
|
|
||||||
|
int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo,
|
||||||
|
SOperatorInfo** pOptrInfo) {
|
||||||
|
QRY_PARAM_CHECK(pOptrInfo);
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SAnomalyWindowOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
SAnomalyWindowPhysiNode* pAnomalyNode = (SAnomalyWindowPhysiNode*)physiNode;
|
||||||
|
SColumnNode* pColNode = (SColumnNode*)(pAnomalyNode->pAnomalyKey);
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
code = terrno;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taosAnalGetOptStr(pAnomalyNode->anomalyOpt, "algo", pInfo->algoName, sizeof(pInfo->algoName))) {
|
||||||
|
qError("failed to get anomaly_window algorithm name from %s", pAnomalyNode->anomalyOpt);
|
||||||
|
code = TSDB_CODE_ANAL_ALGO_NOT_FOUND;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
if (taosAnalGetAlgoUrl(pInfo->algoName, ANAL_ALGO_TYPE_ANOMALY_DETECT, pInfo->algoUrl, sizeof(pInfo->algoUrl)) != 0) {
|
||||||
|
qError("failed to get anomaly_window algorithm url from %s", pInfo->algoName);
|
||||||
|
code = TSDB_CODE_ANAL_ALGO_NOT_LOAD;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->exprSupp.hasWindowOrGroup = true;
|
||||||
|
pInfo->tsSlotId = ((SColumnNode*)pAnomalyNode->window.pTspk)->slotId;
|
||||||
|
strncpy(pInfo->anomalyOpt, pAnomalyNode->anomalyOpt, sizeof(pInfo->anomalyOpt));
|
||||||
|
|
||||||
|
if (pAnomalyNode->window.pExprs != NULL) {
|
||||||
|
int32_t numOfScalarExpr = 0;
|
||||||
|
SExprInfo* pScalarExprInfo = NULL;
|
||||||
|
code = createExprInfo(pAnomalyNode->window.pExprs, NULL, &pScalarExprInfo, &numOfScalarExpr);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, numOfScalarExpr, &pTaskInfo->storageAPI.functionStore);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t keyBufSize = 0;
|
||||||
|
int32_t num = 0;
|
||||||
|
SExprInfo* pExprInfo = NULL;
|
||||||
|
code = createExprInfo(pAnomalyNode->window.pFuncs, NULL, &pExprInfo, &num);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||||
|
|
||||||
|
code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, num, keyBufSize, pTaskInfo->id.str,
|
||||||
|
pTaskInfo->streamInfo.pState, &pTaskInfo->storageAPI.functionStore);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
SSDataBlock* pResBlock = createDataBlockFromDescNode(pAnomalyNode->window.node.pOutputDataBlockDesc);
|
||||||
|
QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno);
|
||||||
|
initBasicInfo(&pInfo->binfo, pResBlock);
|
||||||
|
|
||||||
|
code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
initResultRowInfo(&pInfo->binfo.resultRowInfo);
|
||||||
|
pInfo->binfo.inputTsOrder = pAnomalyNode->window.node.inputTsOrder;
|
||||||
|
pInfo->binfo.outputTsOrder = pAnomalyNode->window.node.outputTsOrder;
|
||||||
|
|
||||||
|
pInfo->anomalyCol = extractColumnFromColumnNode(pColNode);
|
||||||
|
pInfo->anomalyKey.type = pInfo->anomalyCol.type;
|
||||||
|
pInfo->anomalyKey.bytes = pInfo->anomalyCol.bytes;
|
||||||
|
pInfo->anomalyKey.pData = taosMemoryCalloc(1, pInfo->anomalyCol.bytes);
|
||||||
|
if (pInfo->anomalyKey.pData == NULL) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t itemSize = sizeof(int32_t) + pInfo->aggSup.resultRowSize + pInfo->anomalyKey.bytes;
|
||||||
|
pInfo->anomalySup.pResultRow = taosMemoryCalloc(1, itemSize);
|
||||||
|
pInfo->anomalySup.blocks = taosArrayInit(16, sizeof(SSDataBlock*));
|
||||||
|
pInfo->anomalySup.windows = taosArrayInit(16, sizeof(STimeWindow));
|
||||||
|
|
||||||
|
if (pInfo->anomalySup.windows == NULL || pInfo->anomalySup.blocks == NULL || pInfo->anomalySup.pResultRow == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = filterInitFromNode((SNode*)pAnomalyNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
setOperatorInfo(pOperator, "AnomalyWindowOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY, true, OP_NOT_OPENED,
|
||||||
|
pInfo, pTaskInfo);
|
||||||
|
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, anomalyAggregateNext, NULL, anomalyDestroyOperatorInfo,
|
||||||
|
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
||||||
|
|
||||||
|
code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
*pOptrInfo = pOperator;
|
||||||
|
|
||||||
|
qDebug("anomaly_window operator is created, algo:%s url:%s opt:%s", pInfo->algoName, pInfo->algoUrl,
|
||||||
|
pInfo->anomalyOpt);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
if (pInfo != NULL) {
|
||||||
|
anomalyDestroyOperatorInfo(pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
destroyOperatorAndDownstreams(pOperator, &downstream, 1);
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
qError("failed to create anomaly_window operator, algo:%s code:0x%x", pInfo->algoName, code);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyAggregateNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||||
|
SAnomalyWindowSupp* pSupp = &pInfo->anomalySup;
|
||||||
|
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||||
|
int64_t st = taosGetTimestampUs();
|
||||||
|
int32_t numOfBlocks = taosArrayGetSize(pSupp->blocks);
|
||||||
|
|
||||||
|
blockDataCleanup(pRes);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
SSDataBlock* pBlock = getNextBlockFromDownstream(pOperator, 0);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSupp->groupId == 0 || pSupp->groupId == pBlock->info.id.groupId) {
|
||||||
|
pSupp->groupId = pBlock->info.id.groupId;
|
||||||
|
numOfBlocks++;
|
||||||
|
pSupp->cachedRows += pBlock->info.rows;
|
||||||
|
qDebug("group:%" PRId64 ", blocks:%d, rows:%" PRId64 ", total rows:%" PRId64, pSupp->groupId, numOfBlocks,
|
||||||
|
pBlock->info.rows, pSupp->cachedRows);
|
||||||
|
code = anomalyCacheBlock(pInfo, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
} else {
|
||||||
|
qDebug("group:%" PRId64 ", read finish for new group coming, blocks:%d", pSupp->groupId, numOfBlocks);
|
||||||
|
anomalyAggregateBlocks(pOperator);
|
||||||
|
pSupp->groupId = pBlock->info.id.groupId;
|
||||||
|
numOfBlocks = 1;
|
||||||
|
pSupp->cachedRows = pBlock->info.rows;
|
||||||
|
qDebug("group:%" PRId64 ", new group, rows:%" PRId64 ", total rows:%" PRId64, pSupp->groupId,
|
||||||
|
pBlock->info.rows, pSupp->cachedRows);
|
||||||
|
code = anomalyCacheBlock(pInfo, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRes->info.rows > 0) {
|
||||||
|
(*ppRes) = pRes;
|
||||||
|
qDebug("group:%" PRId64 ", return to upstream, blocks:%d", pRes->info.id.groupId, numOfBlocks);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfBlocks > 0) {
|
||||||
|
qDebug("group:%" PRId64 ", read finish, blocks:%d", pInfo->anomalySup.groupId, numOfBlocks);
|
||||||
|
anomalyAggregateBlocks(pOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t cost = taosGetTimestampUs() - st;
|
||||||
|
qDebug("all groups finished, cost:%" PRId64 "us", cost);
|
||||||
|
|
||||||
|
_end:
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
|
}
|
||||||
|
(*ppRes) = (pBInfo->pRes->info.rows == 0) ? NULL : pBInfo->pRes;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anomalyDestroyOperatorInfo(void* param) {
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = (SAnomalyWindowOperatorInfo*)param;
|
||||||
|
if (pInfo == NULL) return;
|
||||||
|
|
||||||
|
qDebug("anomaly_window operator is destroyed, algo:%s", pInfo->algoName);
|
||||||
|
|
||||||
|
cleanupBasicInfo(&pInfo->binfo);
|
||||||
|
cleanupAggSup(&pInfo->aggSup);
|
||||||
|
cleanupExprSupp(&pInfo->scalarSup);
|
||||||
|
colDataDestroy(&pInfo->twAggSup.timeWindowData);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < taosArrayGetSize(pInfo->anomalySup.blocks); ++i) {
|
||||||
|
SSDataBlock* pBlock = taosArrayGetP(pInfo->anomalySup.blocks, i);
|
||||||
|
blockDataDestroy(pBlock);
|
||||||
|
}
|
||||||
|
taosArrayDestroy(pInfo->anomalySup.blocks);
|
||||||
|
taosArrayDestroy(pInfo->anomalySup.windows);
|
||||||
|
taosMemoryFreeClear(pInfo->anomalySup.pResultRow);
|
||||||
|
taosMemoryFreeClear(pInfo->anomalyKey.pData);
|
||||||
|
|
||||||
|
taosMemoryFreeClear(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyCacheBlock(SAnomalyWindowOperatorInfo* pInfo, SSDataBlock* pSrc) {
|
||||||
|
if (pInfo->anomalySup.cachedRows > ANAL_ANOMALY_WINDOW_MAX_ROWS) {
|
||||||
|
return TSDB_CODE_ANAL_ANODE_TOO_MANY_ROWS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* pDst = NULL;
|
||||||
|
int32_t code = createOneDataBlock(pSrc, true, &pDst);
|
||||||
|
|
||||||
|
if (code != 0) return code;
|
||||||
|
if (pDst == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
if (taosArrayPush(pInfo->anomalySup.blocks, &pDst) == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyFindWindow(SAnomalyWindowSupp* pSupp, TSKEY key) {
|
||||||
|
for (int32_t i = pSupp->curWinIndex; i < taosArrayGetSize(pSupp->windows); ++i) {
|
||||||
|
STimeWindow* pWindow = taosArrayGet(pSupp->windows, i);
|
||||||
|
if (key >= pWindow->skey && key < pWindow->ekey) {
|
||||||
|
pSupp->curWin = *pWindow;
|
||||||
|
pSupp->curWinIndex = i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyParseJson(SJson* pJson, SArray* pWindows) {
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t rows = 0;
|
||||||
|
STimeWindow win = {0};
|
||||||
|
|
||||||
|
taosArrayClear(pWindows);
|
||||||
|
|
||||||
|
tjsonGetInt32ValueFromDouble(pJson, "rows", rows, code);
|
||||||
|
if (code < 0) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
if (rows <= 0) return 0;
|
||||||
|
|
||||||
|
SJson* res = tjsonGetObjectItem(pJson, "res");
|
||||||
|
if (res == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
int32_t ressize = tjsonGetArraySize(res);
|
||||||
|
if (ressize != rows) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < rows; ++i) {
|
||||||
|
SJson* row = tjsonGetArrayItem(res, i);
|
||||||
|
if (row == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
int32_t colsize = tjsonGetArraySize(row);
|
||||||
|
if (colsize != 2) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
SJson* start = tjsonGetArrayItem(row, 0);
|
||||||
|
SJson* end = tjsonGetArrayItem(row, 1);
|
||||||
|
if (start == NULL || end == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
|
||||||
|
tjsonGetObjectValueBigInt(start, &win.skey);
|
||||||
|
tjsonGetObjectValueBigInt(end, &win.ekey);
|
||||||
|
|
||||||
|
if (win.skey >= win.ekey) {
|
||||||
|
win.ekey = win.skey + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosArrayPush(pWindows, &win) == NULL) return TSDB_CODE_OUT_OF_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfWins = taosArrayGetSize(pWindows);
|
||||||
|
qDebug("anomaly window recevied, total:%d", numOfWins);
|
||||||
|
for (int32_t i = 0; i < numOfWins; ++i) {
|
||||||
|
STimeWindow* pWindow = taosArrayGet(pWindows, i);
|
||||||
|
qDebug("anomaly win:%d [%" PRId64 ", %" PRId64 ")", i, pWindow->skey, pWindow->ekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyAnalysisWindow(SOperatorInfo* pOperator) {
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SAnomalyWindowSupp* pSupp = &pInfo->anomalySup;
|
||||||
|
SJson* pJson = NULL;
|
||||||
|
SAnalBuf analBuf = {.bufType = ANAL_BUF_TYPE_JSON};
|
||||||
|
char dataBuf[64] = {0};
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
int64_t ts = 0;
|
||||||
|
// int64_t ts = taosGetTimestampMs();
|
||||||
|
snprintf(analBuf.fileName, sizeof(analBuf.fileName), "%s/tdengine-anomaly-%" PRId64 "-%" PRId64, tsTempDir, ts,
|
||||||
|
pSupp->groupId);
|
||||||
|
code = tsosAnalBufOpen(&analBuf, 2);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
const char* prec = TSDB_TIME_PRECISION_MILLI_STR;
|
||||||
|
if (pInfo->anomalyCol.precision == TSDB_TIME_PRECISION_MICRO) prec = TSDB_TIME_PRECISION_MICRO_STR;
|
||||||
|
if (pInfo->anomalyCol.precision == TSDB_TIME_PRECISION_NANO) prec = TSDB_TIME_PRECISION_NANO_STR;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColMeta(&analBuf, 0, TSDB_DATA_TYPE_TIMESTAMP, "ts");
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColMeta(&analBuf, 1, pInfo->anomalyCol.type, "val");
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteDataBegin(&analBuf);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
int32_t numOfBlocks = (int32_t)taosArrayGetSize(pSupp->blocks);
|
||||||
|
|
||||||
|
// timestamp
|
||||||
|
code = taosAnalBufWriteColBegin(&analBuf, 0);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||||
|
SSDataBlock* pBlock = taosArrayGetP(pSupp->blocks, i);
|
||||||
|
if (pBlock == NULL) break;
|
||||||
|
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||||
|
if (pTsCol == NULL) break;
|
||||||
|
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||||
|
code = taosAnalBufWriteColData(&analBuf, 0, TSDB_DATA_TYPE_TIMESTAMP, &((TSKEY*)pTsCol->pData)[j]);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteColEnd(&analBuf, 0);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
// data
|
||||||
|
code = taosAnalBufWriteColBegin(&analBuf, 1);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||||
|
SSDataBlock* pBlock = taosArrayGetP(pSupp->blocks, i);
|
||||||
|
if (pBlock == NULL) break;
|
||||||
|
SColumnInfoData* pValCol = taosArrayGet(pBlock->pDataBlock, pInfo->anomalyCol.slotId);
|
||||||
|
if (pValCol == NULL) break;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||||
|
code = taosAnalBufWriteColData(&analBuf, 1, pValCol->info.type, colDataGetData(pValCol, j));
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteColEnd(&analBuf, 1);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteDataEnd(&analBuf);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteOptStr(&analBuf, "option", pInfo->anomalyOpt);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteOptStr(&analBuf, "algo", pInfo->algoName);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteOptStr(&analBuf, "prec", prec);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
int64_t wncheck = ANAL_FORECAST_DEFAULT_WNCHECK;
|
||||||
|
bool hasWncheck = taosAnalGetOptInt(pInfo->anomalyOpt, "wncheck", &wncheck);
|
||||||
|
if (!hasWncheck) {
|
||||||
|
qDebug("anomaly_window wncheck not found from %s, use default:%" PRId64, pInfo->anomalyOpt, wncheck);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(&analBuf, "wncheck", wncheck);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufClose(&analBuf);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
pJson = taosAnalSendReqRetJson(pInfo->algoUrl, ANAL_HTTP_TYPE_POST, &analBuf);
|
||||||
|
if (pJson == NULL) {
|
||||||
|
code = terrno;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = anomalyParseJson(pJson, pSupp->windows);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code != 0) {
|
||||||
|
qError("failed to analysis window since %s", tstrerror(code));
|
||||||
|
}
|
||||||
|
taosAnalBufDestroy(&analBuf);
|
||||||
|
if (pJson != NULL) tjsonDelete(pJson);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyAggregateRows(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||||
|
SAnomalyWindowSupp* pSupp = &pInfo->anomalySup;
|
||||||
|
SWindowRowsSup* pRowSup = &pInfo->anomalyWinRowSup;
|
||||||
|
SResultRow* pResRow = pSupp->pResultRow;
|
||||||
|
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||||
|
|
||||||
|
int32_t code = setResultRowInitCtx(pResRow, pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||||
|
if (code == 0) {
|
||||||
|
updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pSupp->curWin, 0);
|
||||||
|
code = applyAggFunctionOnPartialTuples(pTaskInfo, pExprSup->pCtx, &pInfo->twAggSup.timeWindowData,
|
||||||
|
pRowSup->startRowIndex, pRowSup->numOfRows, pBlock->info.rows, numOfOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyBuildResult(SOperatorInfo* pOperator) {
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||||
|
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||||
|
SResultRow* pResRow = pInfo->anomalySup.pResultRow;
|
||||||
|
|
||||||
|
doUpdateNumOfRows(pExprSup->pCtx, pResRow, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
|
||||||
|
int32_t code = copyResultrowToDataBlock(pExprSup->pExprInfo, pExprSup->numOfExprs, pResRow, pExprSup->pCtx, pRes,
|
||||||
|
pExprSup->rowEntryInfoOffset, pTaskInfo);
|
||||||
|
if (code == 0) {
|
||||||
|
pRes->info.rows += pResRow->numOfRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anomalyAggregateBlocks(SOperatorInfo* pOperator) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SAnomalyWindowOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||||
|
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||||
|
SAnomalyWindowSupp* pSupp = &pInfo->anomalySup;
|
||||||
|
SWindowRowsSup* pRowSup = &pInfo->anomalyWinRowSup;
|
||||||
|
SResultRow* pResRow = pSupp->pResultRow;
|
||||||
|
int32_t numOfOutput = pOperator->exprSupp.numOfExprs;
|
||||||
|
int32_t rowsInWin = 0;
|
||||||
|
int32_t rowsInBlock = 0;
|
||||||
|
const int64_t gid = pSupp->groupId;
|
||||||
|
const int32_t order = pInfo->binfo.inputTsOrder;
|
||||||
|
|
||||||
|
int32_t numOfBlocks = (int32_t)taosArrayGetSize(pSupp->blocks);
|
||||||
|
if (numOfBlocks == 0) goto _OVER;
|
||||||
|
|
||||||
|
qDebug("group:%" PRId64 ", aggregate blocks, blocks:%d", pSupp->groupId, numOfBlocks);
|
||||||
|
pRes->info.id.groupId = pSupp->groupId;
|
||||||
|
|
||||||
|
code = anomalyAnalysisWindow(pOperator);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
|
||||||
|
int32_t numOfWins = taosArrayGetSize(pSupp->windows);
|
||||||
|
qDebug("group:%" PRId64 ", wins:%d, rows:%" PRId64, pSupp->groupId, numOfWins, pSupp->cachedRows);
|
||||||
|
for (int32_t w = 0; w < numOfWins; ++w) {
|
||||||
|
STimeWindow* pWindow = taosArrayGet(pSupp->windows, w);
|
||||||
|
if (w == 0) {
|
||||||
|
pSupp->curWin = *pWindow;
|
||||||
|
pRowSup->win.skey = pSupp->curWin.skey;
|
||||||
|
}
|
||||||
|
qDebug("group:%" PRId64 ", win:%d [%" PRId64 ", %" PRId64 ")", pSupp->groupId, w, pWindow->skey, pWindow->ekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfWins <= 0) goto _OVER;
|
||||||
|
if (numOfWins > pRes->info.capacity) {
|
||||||
|
code = blockDataEnsureCapacity(pRes, numOfWins);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t b = 0; b < numOfBlocks; ++b) {
|
||||||
|
SSDataBlock* pBlock = taosArrayGetP(pSupp->blocks, b);
|
||||||
|
if (pBlock == NULL) break;
|
||||||
|
|
||||||
|
pRes->info.scanFlag = pBlock->info.scanFlag;
|
||||||
|
code = setInputDataBlock(pExprSup, pBlock, order, MAIN_SCAN, true);
|
||||||
|
if (code != 0) break;
|
||||||
|
|
||||||
|
code = blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId);
|
||||||
|
if (code != 0) break;
|
||||||
|
|
||||||
|
// there is an scalar expression that needs to be calculated right before apply the group aggregation.
|
||||||
|
if (pInfo->scalarSup.pExprInfo != NULL) {
|
||||||
|
code = projectApplyFunctions(pInfo->scalarSup.pExprInfo, pBlock, pBlock, pInfo->scalarSup.pCtx,
|
||||||
|
pInfo->scalarSup.numOfExprs, NULL);
|
||||||
|
if (code != 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnInfoData* pValCol = taosArrayGet(pBlock->pDataBlock, pInfo->anomalyCol.slotId);
|
||||||
|
if (pValCol == NULL) break;
|
||||||
|
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
|
||||||
|
if (pTsCol == NULL) break;
|
||||||
|
TSKEY* tsList = (TSKEY*)pTsCol->pData;
|
||||||
|
bool lastBlock = (b == numOfBlocks - 1);
|
||||||
|
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, riwin:%d riblock:%d, rows:%" PRId64, pSupp->groupId, b,
|
||||||
|
pSupp->curWinIndex, rowsInWin, rowsInBlock, pBlock->info.rows);
|
||||||
|
|
||||||
|
for (int32_t r = 0; r < pBlock->info.rows; ++r) {
|
||||||
|
TSKEY key = tsList[r];
|
||||||
|
bool keyInWin = (key >= pSupp->curWin.skey && key < pSupp->curWin.ekey);
|
||||||
|
bool lastRow = (r == pBlock->info.rows - 1);
|
||||||
|
|
||||||
|
if (keyInWin) {
|
||||||
|
if (r < 5) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d", pSupp->groupId, b,
|
||||||
|
pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
}
|
||||||
|
if (rowsInBlock == 0) {
|
||||||
|
doKeepNewWindowStartInfo(pRowSup, tsList, r, gid);
|
||||||
|
}
|
||||||
|
doKeepTuple(pRowSup, tsList[r], gid);
|
||||||
|
rowsInBlock++;
|
||||||
|
rowsInWin++;
|
||||||
|
} else {
|
||||||
|
if (rowsInBlock > 0) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d, agg", pSupp->groupId,
|
||||||
|
b, pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
code = anomalyAggregateRows(pOperator, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
rowsInBlock = 0;
|
||||||
|
}
|
||||||
|
if (rowsInWin > 0) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d, build result",
|
||||||
|
pSupp->groupId, b, pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
code = anomalyBuildResult(pOperator);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
rowsInWin = 0;
|
||||||
|
}
|
||||||
|
if (anomalyFindWindow(pSupp, tsList[r]) == 0) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d, new window detect",
|
||||||
|
pSupp->groupId, b, pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
doKeepNewWindowStartInfo(pRowSup, tsList, r, gid);
|
||||||
|
doKeepTuple(pRowSup, tsList[r], gid);
|
||||||
|
rowsInBlock = 1;
|
||||||
|
rowsInWin = 1;
|
||||||
|
} else {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d, window not found",
|
||||||
|
pSupp->groupId, b, pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
rowsInBlock = 0;
|
||||||
|
rowsInWin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastRow && rowsInBlock > 0) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, row:%d ts:%" PRId64 ", riwin:%d riblock:%d, agg since lastrow",
|
||||||
|
pSupp->groupId, b, pSupp->curWinIndex, r, key, rowsInWin, rowsInBlock);
|
||||||
|
code = anomalyAggregateRows(pOperator, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
rowsInBlock = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBlock && rowsInWin > 0) {
|
||||||
|
qTrace("group:%" PRId64 ", block:%d win:%d, riwin:%d riblock:%d, build result since lastblock", pSupp->groupId, b,
|
||||||
|
pSupp->curWinIndex, rowsInWin, rowsInBlock);
|
||||||
|
code = anomalyBuildResult(pOperator);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
rowsInWin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code = doFilter(pRes, pOperator->exprSupp.pFilterInfo, NULL);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _OVER);
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||||
|
SSDataBlock* pBlock = taosArrayGetP(pSupp->blocks, i);
|
||||||
|
qDebug("%s, clear block, pBlock:%p pBlock->pDataBlock:%p", __func__, pBlock, pBlock->pDataBlock);
|
||||||
|
blockDataDestroy(pBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayClear(pSupp->blocks);
|
||||||
|
taosArrayClear(pSupp->windows);
|
||||||
|
pSupp->cachedRows = 0;
|
||||||
|
pSupp->curWin.ekey = 0;
|
||||||
|
pSupp->curWin.skey = 0;
|
||||||
|
pSupp->curWinIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo,
|
||||||
|
SOperatorInfo** pOptrInfo) {
|
||||||
|
return TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
|
}
|
||||||
|
void destroyForecastInfo(void* param) {}
|
||||||
|
|
||||||
|
#endif
|
|
@ -88,11 +88,116 @@ size_t getResultRowSize(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||||
rowSize += pCtx[i].resDataInfo.interBufSize;
|
rowSize += pCtx[i].resDataInfo.interBufSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
rowSize += (numOfOutput * sizeof(bool));
|
|
||||||
// expand rowSize to mark if col is null for top/bottom result(saveTupleData)
|
|
||||||
return rowSize;
|
return rowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert buf read from rocksdb to result row
|
||||||
|
int32_t getResultRowFromBuf(SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize) {
|
||||||
|
if (inBuf == NULL || pSup == NULL) {
|
||||||
|
qError("invalid input parameters, inBuf:%p, pSup:%p", inBuf, pSup);
|
||||||
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
SqlFunctionCtx *pCtx = pSup->pCtx;
|
||||||
|
int32_t *offset = pSup->rowEntryInfoOffset;
|
||||||
|
SResultRow *pResultRow = NULL;
|
||||||
|
size_t processedSize = 0;
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
// calculate the size of output buffer
|
||||||
|
*outBufSize = getResultRowSize(pCtx, pSup->numOfExprs);
|
||||||
|
*outBuf = taosMemoryMalloc(*outBufSize);
|
||||||
|
if (*outBuf == NULL) {
|
||||||
|
qError("failed to allocate memory for output buffer, size:%zu", *outBufSize);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
pResultRow = (SResultRow*)*outBuf;
|
||||||
|
(void)memcpy(pResultRow, inBuf, sizeof(SResultRow));
|
||||||
|
inBuf += sizeof(SResultRow);
|
||||||
|
processedSize += sizeof(SResultRow);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pSup->numOfExprs; ++i) {
|
||||||
|
int32_t len = *(int32_t*)inBuf;
|
||||||
|
inBuf += sizeof(int32_t);
|
||||||
|
processedSize += sizeof(int32_t);
|
||||||
|
if (pResultRow->version != FUNCTION_RESULT_INFO_VERSION && pCtx->fpSet.decode) {
|
||||||
|
code = pCtx->fpSet.decode(&pCtx[i], inBuf, getResultEntryInfo(pResultRow, i, offset), pResultRow->version);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("failed to decode result row, code:%d", code);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(void)memcpy(getResultEntryInfo(pResultRow, i, offset), inBuf, len);
|
||||||
|
}
|
||||||
|
inBuf += len;
|
||||||
|
processedSize += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processedSize < inBufSize) {
|
||||||
|
// stream stores extra data after result row
|
||||||
|
size_t leftLen = inBufSize - processedSize;
|
||||||
|
TAOS_MEMORY_REALLOC(*outBuf, *outBufSize + leftLen);
|
||||||
|
if (*outBuf == NULL) {
|
||||||
|
qError("failed to reallocate memory for output buffer, size:%zu", *outBufSize + leftLen);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
(void)memcpy(*outBuf + *outBufSize, inBuf, leftLen);
|
||||||
|
inBuf += leftLen;
|
||||||
|
processedSize += leftLen;
|
||||||
|
*outBufSize += leftLen;
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert result row to buf for rocksdb
|
||||||
|
int32_t putResultRowToBuf(SExprSupp *pSup, const char* inBuf, size_t inBufSize, char **outBuf, size_t *outBufSize) {
|
||||||
|
if (pSup == NULL || inBuf == NULL || outBuf == NULL || outBufSize == NULL) {
|
||||||
|
qError("invalid input parameters, inBuf:%p, pSup:%p, outBufSize:%p, outBuf:%p", inBuf, pSup, outBufSize, outBuf);
|
||||||
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlFunctionCtx *pCtx = pSup->pCtx;
|
||||||
|
int32_t *offset = pSup->rowEntryInfoOffset;
|
||||||
|
SResultRow *pResultRow = (SResultRow*)inBuf;
|
||||||
|
size_t rowSize = getResultRowSize(pCtx, pSup->numOfExprs);
|
||||||
|
|
||||||
|
if (rowSize > inBufSize) {
|
||||||
|
qError("invalid input buffer size, rowSize:%zu, inBufSize:%zu", rowSize, inBufSize);
|
||||||
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the size of output buffer
|
||||||
|
*outBufSize = rowSize + sizeof(int32_t) * pSup->numOfExprs;
|
||||||
|
if (rowSize < inBufSize) {
|
||||||
|
*outBufSize += inBufSize - rowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outBuf = taosMemoryMalloc(*outBufSize);
|
||||||
|
if (*outBuf == NULL) {
|
||||||
|
qError("failed to allocate memory for output buffer, size:%zu", *outBufSize);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pBuf = *outBuf;
|
||||||
|
pResultRow->version = FUNCTION_RESULT_INFO_VERSION;
|
||||||
|
(void)memcpy(pBuf, pResultRow, sizeof(SResultRow));
|
||||||
|
pBuf += sizeof(SResultRow);
|
||||||
|
for (int32_t i = 0; i < pSup->numOfExprs; ++i) {
|
||||||
|
size_t len = sizeof(SResultRowEntryInfo) + pCtx[i].resDataInfo.interBufSize;
|
||||||
|
*(int32_t *) pBuf = (int32_t)len;
|
||||||
|
pBuf += sizeof(int32_t);
|
||||||
|
(void)memcpy(pBuf, getResultEntryInfo(pResultRow, i, offset), len);
|
||||||
|
pBuf += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowSize < inBufSize) {
|
||||||
|
// stream stores extra data after result row
|
||||||
|
size_t leftLen = inBufSize - rowSize;
|
||||||
|
(void)memcpy(pBuf, inBuf + rowSize, leftLen);
|
||||||
|
pBuf += leftLen;
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static void freeEx(void* p) { taosMemoryFree(*(void**)p); }
|
static void freeEx(void* p) { taosMemoryFree(*(void**)p); }
|
||||||
|
|
||||||
void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo) {
|
void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo) {
|
||||||
|
|
|
@ -0,0 +1,659 @@
|
||||||
|
/*
|
||||||
|
* 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 "executorInt.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "function.h"
|
||||||
|
#include "functionMgt.h"
|
||||||
|
#include "operator.h"
|
||||||
|
#include "querytask.h"
|
||||||
|
#include "storageapi.h"
|
||||||
|
#include "tanal.h"
|
||||||
|
#include "tcommon.h"
|
||||||
|
#include "tcompare.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "tfill.h"
|
||||||
|
#include "ttime.h"
|
||||||
|
|
||||||
|
#ifdef USE_ANAL
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char algoName[TSDB_ANAL_ALGO_NAME_LEN];
|
||||||
|
char algoUrl[TSDB_ANAL_ALGO_URL_LEN];
|
||||||
|
char algoOpt[TSDB_ANAL_ALGO_OPTION_LEN];
|
||||||
|
int64_t maxTs;
|
||||||
|
int64_t minTs;
|
||||||
|
int64_t numOfRows;
|
||||||
|
uint64_t groupId;
|
||||||
|
int64_t optRows;
|
||||||
|
int64_t cachedRows;
|
||||||
|
int32_t numOfBlocks;
|
||||||
|
int16_t resTsSlot;
|
||||||
|
int16_t resValSlot;
|
||||||
|
int16_t resLowSlot;
|
||||||
|
int16_t resHighSlot;
|
||||||
|
int16_t inputTsSlot;
|
||||||
|
int16_t inputValSlot;
|
||||||
|
int8_t inputValType;
|
||||||
|
int8_t inputPrecision;
|
||||||
|
SAnalBuf analBuf;
|
||||||
|
} SForecastSupp;
|
||||||
|
|
||||||
|
typedef struct SForecastOperatorInfo {
|
||||||
|
SSDataBlock* pRes;
|
||||||
|
SExprSupp scalarSup; // scalar calculation
|
||||||
|
SForecastSupp forecastSupp;
|
||||||
|
} SForecastOperatorInfo;
|
||||||
|
|
||||||
|
static void destroyForecastInfo(void* param);
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t forecastEnsureBlockCapacity(SSDataBlock* pBlock, int32_t newRowsNum) {
|
||||||
|
if (pBlock->info.rows < pBlock->info.capacity) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = blockDataEnsureCapacity(pBlock, newRowsNum);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastCacheBlock(SForecastSupp* pSupp, SSDataBlock* pBlock) {
|
||||||
|
if (pSupp->cachedRows > ANAL_FORECAST_MAX_ROWS) {
|
||||||
|
return TSDB_CODE_ANAL_ANODE_TOO_MANY_ROWS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
|
||||||
|
qDebug("block:%d, %p rows:%" PRId64, pSupp->numOfBlocks, pBlock, pBlock->info.rows);
|
||||||
|
pSupp->numOfBlocks++;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||||
|
SColumnInfoData* pValCol = taosArrayGet(pBlock->pDataBlock, pSupp->inputValSlot);
|
||||||
|
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, pSupp->inputTsSlot);
|
||||||
|
if (pTsCol == NULL || pValCol == NULL) break;
|
||||||
|
|
||||||
|
int64_t ts = ((TSKEY*)pTsCol->pData)[j];
|
||||||
|
char* val = colDataGetData(pValCol, j);
|
||||||
|
int16_t valType = pValCol->info.type;
|
||||||
|
|
||||||
|
pSupp->minTs = MIN(pSupp->minTs, ts);
|
||||||
|
pSupp->maxTs = MAX(pSupp->maxTs, ts);
|
||||||
|
pSupp->numOfRows++;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColData(pBuf, 0, TSDB_DATA_TYPE_TIMESTAMP, &ts);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) return code;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColData(pBuf, 1, valType, val);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastCloseBuf(SForecastSupp* pSupp) {
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 2; ++i) {
|
||||||
|
code = taosAnalBufWriteColEnd(pBuf, i);
|
||||||
|
if (code != 0) return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = taosAnalBufWriteDataEnd(pBuf);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteOptStr(pBuf, "option", pSupp->algoOpt);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteOptStr(pBuf, "algo", pSupp->algoName);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
const char* prec = TSDB_TIME_PRECISION_MILLI_STR;
|
||||||
|
if (pSupp->inputPrecision == TSDB_TIME_PRECISION_MICRO) prec = TSDB_TIME_PRECISION_MICRO_STR;
|
||||||
|
if (pSupp->inputPrecision == TSDB_TIME_PRECISION_NANO) prec = TSDB_TIME_PRECISION_NANO_STR;
|
||||||
|
code = taosAnalBufWriteOptStr(pBuf, "prec", prec);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
int64_t wncheck = ANAL_FORECAST_DEFAULT_WNCHECK;
|
||||||
|
bool hasWncheck = taosAnalGetOptInt(pSupp->algoOpt, "wncheck", &wncheck);
|
||||||
|
if (!hasWncheck) {
|
||||||
|
qDebug("forecast wncheck not found from %s, use default:%" PRId64, pSupp->algoOpt, wncheck);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "wncheck", wncheck);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
bool noConf = (pSupp->resHighSlot == -1 && pSupp->resLowSlot == -1);
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "return_conf", !noConf);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
pSupp->optRows = ANAL_FORECAST_DEFAULT_ROWS;
|
||||||
|
bool hasRows = taosAnalGetOptInt(pSupp->algoOpt, "rows", &pSupp->optRows);
|
||||||
|
if (!hasRows) {
|
||||||
|
qDebug("forecast rows not found from %s, use default:%" PRId64, pSupp->algoOpt, pSupp->optRows);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "forecast_rows", pSupp->optRows);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
int64_t conf = ANAL_FORECAST_DEFAULT_CONF;
|
||||||
|
bool hasConf = taosAnalGetOptInt(pSupp->algoOpt, "conf", &conf);
|
||||||
|
if (!hasConf) {
|
||||||
|
qDebug("forecast conf not found from %s, use default:%" PRId64, pSupp->algoOpt, conf);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "conf", conf);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
int32_t len = strlen(pSupp->algoOpt);
|
||||||
|
int64_t every = (pSupp->maxTs - pSupp->minTs) / (pSupp->numOfRows - 1);
|
||||||
|
int64_t start = pSupp->maxTs + every;
|
||||||
|
bool hasStart = taosAnalGetOptInt(pSupp->algoOpt, "start", &start);
|
||||||
|
if (!hasStart) {
|
||||||
|
qDebug("forecast start not found from %s, use %" PRId64, pSupp->algoOpt, start);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "start", start);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
bool hasEvery = taosAnalGetOptInt(pSupp->algoOpt, "every", &every);
|
||||||
|
if (!hasEvery) {
|
||||||
|
qDebug("forecast every not found from %s, use %" PRId64, pSupp->algoOpt, every);
|
||||||
|
}
|
||||||
|
code = taosAnalBufWriteOptInt(pBuf, "every", every);
|
||||||
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
code = taosAnalBufClose(pBuf);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastAnalysis(SForecastSupp* pSupp, SSDataBlock* pBlock) {
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
int32_t resCurRow = pBlock->info.rows;
|
||||||
|
int8_t tmpI8;
|
||||||
|
int16_t tmpI16;
|
||||||
|
int32_t tmpI32;
|
||||||
|
int64_t tmpI64;
|
||||||
|
float tmpFloat;
|
||||||
|
double tmpDouble;
|
||||||
|
int32_t code = 0;
|
||||||
|
|
||||||
|
SColumnInfoData* pResValCol = taosArrayGet(pBlock->pDataBlock, pSupp->resValSlot);
|
||||||
|
if (NULL == pResValCol) return TSDB_CODE_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
SColumnInfoData* pResTsCol = (pSupp->resTsSlot != -1 ? taosArrayGet(pBlock->pDataBlock, pSupp->resTsSlot) : NULL);
|
||||||
|
SColumnInfoData* pResLowCol = (pSupp->resLowSlot != -1 ? taosArrayGet(pBlock->pDataBlock, pSupp->resLowSlot) : NULL);
|
||||||
|
SColumnInfoData* pResHighCol =
|
||||||
|
(pSupp->resHighSlot != -1 ? taosArrayGet(pBlock->pDataBlock, pSupp->resHighSlot) : NULL);
|
||||||
|
|
||||||
|
SJson* pJson = taosAnalSendReqRetJson(pSupp->algoUrl, ANAL_HTTP_TYPE_POST, pBuf);
|
||||||
|
if (pJson == NULL) return terrno;
|
||||||
|
|
||||||
|
int32_t rows = 0;
|
||||||
|
tjsonGetInt32ValueFromDouble(pJson, "rows", rows, code);
|
||||||
|
if (code < 0) goto _OVER;
|
||||||
|
if (rows <= 0) goto _OVER;
|
||||||
|
|
||||||
|
SJson* res = tjsonGetObjectItem(pJson, "res");
|
||||||
|
if (res == NULL) goto _OVER;
|
||||||
|
int32_t ressize = tjsonGetArraySize(res);
|
||||||
|
bool returnConf = (pSupp->resHighSlot != -1 || pSupp->resLowSlot != -1);
|
||||||
|
if (returnConf) {
|
||||||
|
if (ressize != 4) goto _OVER;
|
||||||
|
} else if (ressize != 2) {
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pResTsCol != NULL) {
|
||||||
|
resCurRow = pBlock->info.rows;
|
||||||
|
SJson* tsJsonArray = tjsonGetArrayItem(res, 0);
|
||||||
|
if (tsJsonArray == NULL) goto _OVER;
|
||||||
|
int32_t tsSize = tjsonGetArraySize(tsJsonArray);
|
||||||
|
if (tsSize != rows) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < tsSize; ++i) {
|
||||||
|
SJson* tsJson = tjsonGetArrayItem(tsJsonArray, i);
|
||||||
|
tjsonGetObjectValueBigInt(tsJson, &tmpI64);
|
||||||
|
colDataSetInt64(pResTsCol, resCurRow, &tmpI64);
|
||||||
|
resCurRow++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pResLowCol != NULL) {
|
||||||
|
resCurRow = pBlock->info.rows;
|
||||||
|
SJson* lowJsonArray = tjsonGetArrayItem(res, 2);
|
||||||
|
if (lowJsonArray == NULL) goto _OVER;
|
||||||
|
int32_t lowSize = tjsonGetArraySize(lowJsonArray);
|
||||||
|
if (lowSize != rows) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < lowSize; ++i) {
|
||||||
|
SJson* lowJson = tjsonGetArrayItem(lowJsonArray, i);
|
||||||
|
tjsonGetObjectValueDouble(lowJson, &tmpDouble);
|
||||||
|
tmpFloat = (float)tmpDouble;
|
||||||
|
colDataSetFloat(pResLowCol, resCurRow, &tmpFloat);
|
||||||
|
resCurRow++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pResHighCol != NULL) {
|
||||||
|
resCurRow = pBlock->info.rows;
|
||||||
|
SJson* highJsonArray = tjsonGetArrayItem(res, 3);
|
||||||
|
if (highJsonArray == NULL) goto _OVER;
|
||||||
|
int32_t highSize = tjsonGetArraySize(highJsonArray);
|
||||||
|
if (highSize != rows) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < highSize; ++i) {
|
||||||
|
SJson* highJson = tjsonGetArrayItem(highJsonArray, i);
|
||||||
|
tjsonGetObjectValueDouble(highJson, &tmpDouble);
|
||||||
|
tmpFloat = (float)tmpDouble;
|
||||||
|
colDataSetFloat(pResHighCol, resCurRow, &tmpFloat);
|
||||||
|
resCurRow++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resCurRow = pBlock->info.rows;
|
||||||
|
SJson* valJsonArray = tjsonGetArrayItem(res, 1);
|
||||||
|
if (valJsonArray == NULL) goto _OVER;
|
||||||
|
int32_t valSize = tjsonGetArraySize(valJsonArray);
|
||||||
|
if (valSize != rows) goto _OVER;
|
||||||
|
for (int32_t i = 0; i < valSize; ++i) {
|
||||||
|
SJson* valJson = tjsonGetArrayItem(valJsonArray, i);
|
||||||
|
tjsonGetObjectValueDouble(valJson, &tmpDouble);
|
||||||
|
|
||||||
|
switch (pSupp->inputValType) {
|
||||||
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
tmpI8 = (int8_t)tmpDouble;
|
||||||
|
colDataSetInt8(pResValCol, resCurRow, &tmpI8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
tmpI16 = (int16_t)tmpDouble;
|
||||||
|
colDataSetInt16(pResValCol, resCurRow, &tmpI16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_UINT: {
|
||||||
|
tmpI32 = (int32_t)tmpDouble;
|
||||||
|
colDataSetInt32(pResValCol, resCurRow, &tmpI32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
tmpI64 = (int64_t)tmpDouble;
|
||||||
|
colDataSetInt64(pResValCol, resCurRow, &tmpI64);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
tmpFloat = (float)tmpDouble;
|
||||||
|
colDataSetFloat(pResValCol, resCurRow, &tmpFloat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
colDataSetDouble(pResValCol, resCurRow, &tmpDouble);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
code = TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
|
resCurRow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (int32_t i = rows; i < pSupp->optRows; ++i) {
|
||||||
|
// colDataSetNNULL(pResValCol, rows, (pSupp->optRows - rows));
|
||||||
|
// if (pResTsCol != NULL) {
|
||||||
|
// colDataSetNNULL(pResTsCol, rows, (pSupp->optRows - rows));
|
||||||
|
// }
|
||||||
|
// if (pResLowCol != NULL) {
|
||||||
|
// colDataSetNNULL(pResLowCol, rows, (pSupp->optRows - rows));
|
||||||
|
// }
|
||||||
|
// if (pResHighCol != NULL) {
|
||||||
|
// colDataSetNNULL(pResHighCol, rows, (pSupp->optRows - rows));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (rows == pSupp->optRows) {
|
||||||
|
// pResValCol->hasNull = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
pBlock->info.rows += rows;
|
||||||
|
|
||||||
|
if (pJson != NULL) tjsonDelete(pJson);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (pJson != NULL) tjsonDelete(pJson);
|
||||||
|
if (code == 0) {
|
||||||
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
}
|
||||||
|
qError("failed to perform forecast finalize since %s", tstrerror(code));
|
||||||
|
return TSDB_CODE_INVALID_JSON_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastAggregateBlocks(SForecastSupp* pSupp, SSDataBlock* pResBlock) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
|
||||||
|
code = forecastCloseBuf(pSupp);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
|
||||||
|
code = forecastEnsureBlockCapacity(pResBlock, 1);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
|
||||||
|
code = forecastAnalysis(pSupp, pResBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
|
||||||
|
uInfo("block:%d, forecast finalize", pSupp->numOfBlocks);
|
||||||
|
|
||||||
|
_end:
|
||||||
|
pSupp->numOfBlocks = 0;
|
||||||
|
taosAnalBufDestroy(&pSupp->analBuf);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SForecastOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SSDataBlock* pResBlock = pInfo->pRes;
|
||||||
|
SForecastSupp* pSupp = &pInfo->forecastSupp;
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
int64_t st = taosGetTimestampUs();
|
||||||
|
int32_t numOfBlocks = pSupp->numOfBlocks;
|
||||||
|
|
||||||
|
blockDataCleanup(pResBlock);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
SSDataBlock* pBlock = getNextBlockFromDownstream(pOperator, 0);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSupp->groupId == 0 || pSupp->groupId == pBlock->info.id.groupId) {
|
||||||
|
pSupp->groupId = pBlock->info.id.groupId;
|
||||||
|
numOfBlocks++;
|
||||||
|
pSupp->cachedRows += pBlock->info.rows;
|
||||||
|
qDebug("group:%" PRId64 ", blocks:%d, rows:%" PRId64 ", total rows:%" PRId64, pSupp->groupId, numOfBlocks,
|
||||||
|
pBlock->info.rows, pSupp->cachedRows);
|
||||||
|
code = forecastCacheBlock(pSupp, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
} else {
|
||||||
|
qDebug("group:%" PRId64 ", read finish for new group coming, blocks:%d", pSupp->groupId, numOfBlocks);
|
||||||
|
code = forecastAggregateBlocks(pSupp, pResBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
pSupp->groupId = pBlock->info.id.groupId;
|
||||||
|
numOfBlocks = 1;
|
||||||
|
pSupp->cachedRows = pBlock->info.rows;
|
||||||
|
qDebug("group:%" PRId64 ", new group, rows:%" PRId64 ", total rows:%" PRId64, pSupp->groupId, pBlock->info.rows,
|
||||||
|
pSupp->cachedRows);
|
||||||
|
code = forecastCacheBlock(pSupp, pBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pResBlock->info.rows > 0) {
|
||||||
|
(*ppRes) = pResBlock;
|
||||||
|
qDebug("group:%" PRId64 ", return to upstream, blocks:%d", pResBlock->info.id.groupId, numOfBlocks);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfBlocks > 0) {
|
||||||
|
qDebug("group:%" PRId64 ", read finish, blocks:%d", pSupp->groupId, numOfBlocks);
|
||||||
|
code = forecastAggregateBlocks(pSupp, pResBlock);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t cost = taosGetTimestampUs() - st;
|
||||||
|
qDebug("all groups finished, cost:%" PRId64 "us", cost);
|
||||||
|
|
||||||
|
_end:
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
T_LONG_JMP(pTaskInfo->env, code);
|
||||||
|
}
|
||||||
|
(*ppRes) = (pResBlock->info.rows == 0) ? NULL : pResBlock;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastParseOutput(SForecastSupp* pSupp, SExprSupp* pExprSup) {
|
||||||
|
pSupp->resLowSlot = -1;
|
||||||
|
pSupp->resHighSlot = -1;
|
||||||
|
pSupp->resTsSlot = -1;
|
||||||
|
pSupp->resValSlot = -1;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < pExprSup->numOfExprs; ++j) {
|
||||||
|
SExprInfo* pExprInfo = &pExprSup->pExprInfo[j];
|
||||||
|
int32_t dstSlot = pExprInfo->base.resSchema.slotId;
|
||||||
|
if (pExprInfo->pExpr->_function.functionType == FUNCTION_TYPE_FORECAST) {
|
||||||
|
pSupp->resValSlot = dstSlot;
|
||||||
|
} else if (pExprInfo->pExpr->_function.functionType == FUNCTION_TYPE_FORECAST_ROWTS) {
|
||||||
|
pSupp->resTsSlot = dstSlot;
|
||||||
|
} else if (pExprInfo->pExpr->_function.functionType == FUNCTION_TYPE_FORECAST_LOW) {
|
||||||
|
pSupp->resLowSlot = dstSlot;
|
||||||
|
} else if (pExprInfo->pExpr->_function.functionType == FUNCTION_TYPE_FORECAST_HIGH) {
|
||||||
|
pSupp->resHighSlot = dstSlot;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastParseInput(SForecastSupp* pSupp, SNodeList* pFuncs) {
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
|
||||||
|
pSupp->inputTsSlot = -1;
|
||||||
|
pSupp->inputValSlot = -1;
|
||||||
|
pSupp->inputValType = -1;
|
||||||
|
pSupp->inputPrecision = -1;
|
||||||
|
|
||||||
|
FOREACH(pNode, pFuncs) {
|
||||||
|
if ((nodeType(pNode) == QUERY_NODE_TARGET) && (nodeType(((STargetNode*)pNode)->pExpr) == QUERY_NODE_FUNCTION)) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)((STargetNode*)pNode)->pExpr;
|
||||||
|
int32_t numOfParam = LIST_LENGTH(pFunc->pParameterList);
|
||||||
|
|
||||||
|
if (pFunc->funcType == FUNCTION_TYPE_FORECAST) {
|
||||||
|
if (numOfParam == 3) {
|
||||||
|
SNode* p1 = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
SNode* p2 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
|
SNode* p3 = nodesListGetNode(pFunc->pParameterList, 2);
|
||||||
|
if (p1 == NULL || p2 == NULL || p3 == NULL) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
if (p1->type != QUERY_NODE_COLUMN) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
if (p2->type != QUERY_NODE_VALUE) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
if (p3->type != QUERY_NODE_COLUMN) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
SColumnNode* pValNode = (SColumnNode*)p1;
|
||||||
|
SValueNode* pOptNode = (SValueNode*)p2;
|
||||||
|
SColumnNode* pTsNode = (SColumnNode*)p3;
|
||||||
|
pSupp->inputTsSlot = pTsNode->slotId;
|
||||||
|
pSupp->inputPrecision = pTsNode->node.resType.precision;
|
||||||
|
pSupp->inputValSlot = pValNode->slotId;
|
||||||
|
pSupp->inputValType = pValNode->node.resType.type;
|
||||||
|
tstrncpy(pSupp->algoOpt, pOptNode->literal, sizeof(pSupp->algoOpt));
|
||||||
|
} else if (numOfParam == 2) {
|
||||||
|
SNode* p1 = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
SNode* p2 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
|
if (p1 == NULL || p2 == NULL) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
if (p1->type != QUERY_NODE_COLUMN) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
if (p2->type != QUERY_NODE_COLUMN) return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
SColumnNode* pValNode = (SColumnNode*)p1;
|
||||||
|
SColumnNode* pTsNode = (SColumnNode*)p2;
|
||||||
|
pSupp->inputTsSlot = pTsNode->slotId;
|
||||||
|
pSupp->inputPrecision = pTsNode->node.resType.precision;
|
||||||
|
pSupp->inputValSlot = pValNode->slotId;
|
||||||
|
pSupp->inputValType = pValNode->node.resType.type;
|
||||||
|
tstrncpy(pSupp->algoOpt, "algo=arima", TSDB_ANAL_ALGO_OPTION_LEN);
|
||||||
|
} else {
|
||||||
|
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastParseAlgo(SForecastSupp* pSupp) {
|
||||||
|
pSupp->maxTs = 0;
|
||||||
|
pSupp->minTs = INT64_MAX;
|
||||||
|
pSupp->numOfRows = 0;
|
||||||
|
|
||||||
|
if (!taosAnalGetOptStr(pSupp->algoOpt, "algo", pSupp->algoName, sizeof(pSupp->algoName))) {
|
||||||
|
qError("failed to get forecast algorithm name from %s", pSupp->algoOpt);
|
||||||
|
return TSDB_CODE_ANAL_ALGO_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taosAnalGetAlgoUrl(pSupp->algoName, ANAL_ALGO_TYPE_FORECAST, pSupp->algoUrl, sizeof(pSupp->algoUrl)) != 0) {
|
||||||
|
qError("failed to get forecast algorithm url from %s", pSupp->algoName);
|
||||||
|
return TSDB_CODE_ANAL_ALGO_NOT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t forecastCreateBuf(SForecastSupp* pSupp) {
|
||||||
|
SAnalBuf* pBuf = &pSupp->analBuf;
|
||||||
|
int64_t ts = 0; // taosGetTimestampMs();
|
||||||
|
|
||||||
|
pBuf->bufType = ANAL_BUF_TYPE_JSON_COL;
|
||||||
|
snprintf(pBuf->fileName, sizeof(pBuf->fileName), "%s/tdengine-forecast-%" PRId64, tsTempDir, ts);
|
||||||
|
int32_t code = tsosAnalBufOpen(pBuf, 2);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColMeta(pBuf, 0, TSDB_DATA_TYPE_TIMESTAMP, "ts");
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteColMeta(pBuf, 1, pSupp->inputValType, "val");
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
code = taosAnalBufWriteDataBegin(pBuf);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 2; ++i) {
|
||||||
|
code = taosAnalBufWriteColBegin(pBuf, i);
|
||||||
|
if (code != 0) goto _OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code != 0) {
|
||||||
|
(void)taosAnalBufClose(pBuf);
|
||||||
|
taosAnalBufDestroy(pBuf);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t createForecastOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo,
|
||||||
|
SOperatorInfo** pOptrInfo) {
|
||||||
|
QRY_PARAM_CHECK(pOptrInfo);
|
||||||
|
|
||||||
|
int32_t code = 0;
|
||||||
|
int32_t lino = 0;
|
||||||
|
SForecastOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SForecastOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pOperator == NULL || pInfo == NULL) {
|
||||||
|
code = terrno;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SForecastSupp* pSupp = &pInfo->forecastSupp;
|
||||||
|
SForecastFuncPhysiNode* pForecastPhyNode = (SForecastFuncPhysiNode*)pPhyNode;
|
||||||
|
SExprSupp* pExprSup = &pOperator->exprSupp;
|
||||||
|
int32_t numOfExprs = 0;
|
||||||
|
SExprInfo* pExprInfo = NULL;
|
||||||
|
|
||||||
|
code = createExprInfo(pForecastPhyNode->pFuncs, NULL, &pExprInfo, &numOfExprs);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = initExprSupp(pExprSup, pExprInfo, numOfExprs, &pTaskInfo->storageAPI.functionStore);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
if (pForecastPhyNode->pExprs != NULL) {
|
||||||
|
int32_t num = 0;
|
||||||
|
SExprInfo* pScalarExprInfo = NULL;
|
||||||
|
code = createExprInfo(pForecastPhyNode->pExprs, NULL, &pScalarExprInfo, &num);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, num, &pTaskInfo->storageAPI.functionStore);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = filterInitFromNode((SNode*)pForecastPhyNode->node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = forecastParseInput(pSupp, pForecastPhyNode->pFuncs);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = forecastParseOutput(pSupp, pExprSup);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = forecastParseAlgo(pSupp);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = forecastCreateBuf(pSupp);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
initResultSizeInfo(&pOperator->resultInfo, 4096);
|
||||||
|
|
||||||
|
pInfo->pRes = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
|
||||||
|
QUERY_CHECK_NULL(pInfo->pRes, code, lino, _error, terrno);
|
||||||
|
|
||||||
|
setOperatorInfo(pOperator, "ForecastOperator", QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC, false, OP_NOT_OPENED, pInfo,
|
||||||
|
pTaskInfo);
|
||||||
|
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, forecastNext, NULL, destroyForecastInfo, optrDefaultBufFn,
|
||||||
|
NULL, optrDefaultGetNextExtFn, NULL);
|
||||||
|
|
||||||
|
code = blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
QUERY_CHECK_CODE(code, lino, _error);
|
||||||
|
|
||||||
|
*pOptrInfo = pOperator;
|
||||||
|
|
||||||
|
qDebug("forecast env is initialized, option:%s", pSupp->algoOpt);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
|
||||||
|
}
|
||||||
|
if (pInfo != NULL) destroyForecastInfo(pInfo);
|
||||||
|
destroyOperatorAndDownstreams(pOperator, &downstream, 1);
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyForecastInfo(void* param) {
|
||||||
|
SForecastOperatorInfo* pInfo = (SForecastOperatorInfo*)param;
|
||||||
|
|
||||||
|
blockDataDestroy(pInfo->pRes);
|
||||||
|
pInfo->pRes = NULL;
|
||||||
|
cleanupExprSupp(&pInfo->scalarSup);
|
||||||
|
taosAnalBufDestroy(&pInfo->forecastSupp.analBuf);
|
||||||
|
taosMemoryFreeClear(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int32_t createForecastOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo,
|
||||||
|
SOperatorInfo** pOptrInfo) {
|
||||||
|
return TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -84,9 +84,9 @@ static void logGroupCacheExecInfo(SGroupCacheOperatorInfo* pGrpCacheOperator) {
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int32_t offset = snprintf(buf, bufSize, "groupCache exec info, downstreamBlkNum:");
|
int32_t offset = tsnprintf(buf, bufSize, "groupCache exec info, downstreamBlkNum:");
|
||||||
for (int32_t i = 0; i < pGrpCacheOperator->downstreamNum; ++i) {
|
for (int32_t i = 0; i < pGrpCacheOperator->downstreamNum; ++i) {
|
||||||
offset += snprintf(buf + offset, bufSize, " %" PRId64 , pGrpCacheOperator->execInfo.pDownstreamBlkNum[i]);
|
offset += tsnprintf(buf + offset, bufSize, " %" PRId64 , pGrpCacheOperator->execInfo.pDownstreamBlkNum[i]);
|
||||||
}
|
}
|
||||||
qDebug("%s", buf);
|
qDebug("%s", buf);
|
||||||
taosMemoryFree(buf);
|
taosMemoryFree(buf);
|
||||||
|
|
|
@ -619,6 +619,8 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
|
||||||
code = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
code = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) {
|
||||||
code = createTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
code = createTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
|
} else if (QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC == type) {
|
||||||
|
code = createForecastOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_EVENT == type) {
|
||||||
code = createEventwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
code = createEventwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE == type) {
|
||||||
|
@ -631,6 +633,8 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
|
||||||
code = createCountwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
code = createCountwindowOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC == type) {
|
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC == type) {
|
||||||
code = createStreamTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
|
code = createStreamTimeSliceOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
|
||||||
|
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY == type) {
|
||||||
|
code = createAnomalywindowOperatorInfo(ops[0], pPhyNode, pTaskInfo, &pOptr);
|
||||||
} else {
|
} else {
|
||||||
code = TSDB_CODE_INVALID_PARA;
|
code = TSDB_CODE_INVALID_PARA;
|
||||||
pTaskInfo->code = code;
|
pTaskInfo->code = code;
|
||||||
|
|
|
@ -2016,6 +2016,12 @@ int32_t createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiN
|
||||||
pInfo->stateStore = pTaskInfo->storageAPI.stateStore;
|
pInfo->stateStore = pTaskInfo->storageAPI.stateStore;
|
||||||
int32_t funResSize = getMaxFunResSize(&pOperator->exprSupp, numOfCols);
|
int32_t funResSize = getMaxFunResSize(&pOperator->exprSupp, numOfCols);
|
||||||
pInfo->pState->pFileState = NULL;
|
pInfo->pState->pFileState = NULL;
|
||||||
|
|
||||||
|
// used for backward compatibility of function's result info
|
||||||
|
pInfo->pState->pResultRowStore.resultRowGet = getResultRowFromBuf;
|
||||||
|
pInfo->pState->pResultRowStore.resultRowPut = putResultRowToBuf;
|
||||||
|
pInfo->pState->pExprSupp = &pOperator->exprSupp;
|
||||||
|
|
||||||
code =
|
code =
|
||||||
pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize,
|
pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize,
|
||||||
compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo),
|
compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo),
|
||||||
|
@ -2232,9 +2238,14 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SExprSupp* pExpSup, in
|
||||||
*(pSup->pState) = *pState;
|
*(pSup->pState) = *pState;
|
||||||
pSup->stateStore.streamStateSetNumber(pSup->pState, -1, tsIndex);
|
pSup->stateStore.streamStateSetNumber(pSup->pState, -1, tsIndex);
|
||||||
int32_t funResSize = getMaxFunResSize(pExpSup, numOfOutput);
|
int32_t funResSize = getMaxFunResSize(pExpSup, numOfOutput);
|
||||||
|
// used for backward compatibility of function's result info
|
||||||
|
pSup->pState->pResultRowStore.resultRowGet = getResultRowFromBuf;
|
||||||
|
pSup->pState->pResultRowStore.resultRowPut = putResultRowToBuf;
|
||||||
|
pSup->pState->pExprSupp = pExpSup;
|
||||||
|
|
||||||
if (stateType == STREAM_STATE_BUFF_SORT) {
|
if (stateType == STREAM_STATE_BUFF_SORT) {
|
||||||
pSup->pState->pFileState = NULL;
|
pSup->pState->pFileState = NULL;
|
||||||
code = pSup->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SSessionKey), pSup->resultRowSize,
|
code = pSup->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SSessionKey), pSup->resultRowSize,
|
||||||
funResSize, sesionTs, pSup->pState, pTwAggSup->deleteMark, taskIdStr,
|
funResSize, sesionTs, pSup->pState, pTwAggSup->deleteMark, taskIdStr,
|
||||||
pHandle->checkpointId, stateType, &pSup->pState->pFileState);
|
pHandle->checkpointId, stateType, &pSup->pState->pFileState);
|
||||||
} else if (stateType == STREAM_STATE_BUFF_HASH_SORT || stateType == STREAM_STATE_BUFF_HASH_SEARCH) {
|
} else if (stateType == STREAM_STATE_BUFF_HASH_SORT || stateType == STREAM_STATE_BUFF_HASH_SEARCH) {
|
||||||
|
@ -5404,6 +5415,12 @@ static int32_t createStreamSingleIntervalOperatorInfo(SOperatorInfo* downstream,
|
||||||
|
|
||||||
pInfo->stateStore = pTaskInfo->storageAPI.stateStore;
|
pInfo->stateStore = pTaskInfo->storageAPI.stateStore;
|
||||||
pInfo->pState->pFileState = NULL;
|
pInfo->pState->pFileState = NULL;
|
||||||
|
|
||||||
|
// used for backward compatibility of function's result info
|
||||||
|
pInfo->pState->pResultRowStore.resultRowGet = getResultRowFromBuf;
|
||||||
|
pInfo->pState->pResultRowStore.resultRowPut = putResultRowToBuf;
|
||||||
|
pInfo->pState->pExprSupp = &pOperator->exprSupp;
|
||||||
|
|
||||||
code = pTaskInfo->storageAPI.stateStore.streamFileStateInit(
|
code = pTaskInfo->storageAPI.stateStore.streamFileStateInit(
|
||||||
tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState,
|
tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState,
|
||||||
pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo), pHandle->checkpointId, STREAM_STATE_BUFF_HASH,
|
pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo), pHandle->checkpointId, STREAM_STATE_BUFF_HASH,
|
||||||
|
|
|
@ -116,6 +116,8 @@ int32_t diffFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo);
|
||||||
int32_t diffFunction(SqlFunctionCtx* pCtx);
|
int32_t diffFunction(SqlFunctionCtx* pCtx);
|
||||||
int32_t diffFunctionByRow(SArray* pCtx);
|
int32_t diffFunctionByRow(SArray* pCtx);
|
||||||
|
|
||||||
|
bool getForecastConfEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
||||||
|
|
||||||
bool getDerivativeFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getDerivativeFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
int32_t derivativeFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo);
|
int32_t derivativeFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo);
|
||||||
int32_t derivativeFunction(SqlFunctionCtx* pCtx);
|
int32_t derivativeFunction(SqlFunctionCtx* pCtx);
|
||||||
|
|
|
@ -58,6 +58,7 @@ extern "C" {
|
||||||
#define FUNC_MGT_TSMA_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(29)
|
#define FUNC_MGT_TSMA_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(29)
|
||||||
#define FUNC_MGT_COUNT_LIKE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(30) // funcs that should also return 0 when no rows found
|
#define FUNC_MGT_COUNT_LIKE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(30) // funcs that should also return 0 when no rows found
|
||||||
#define FUNC_MGT_PROCESS_BY_ROW FUNC_MGT_FUNC_CLASSIFICATION_MASK(31)
|
#define FUNC_MGT_PROCESS_BY_ROW FUNC_MGT_FUNC_CLASSIFICATION_MASK(31)
|
||||||
|
#define FUNC_MGT_FORECAST_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(32)
|
||||||
|
|
||||||
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "geomFunc.h"
|
#include "geomFunc.h"
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
|
#include "tanal.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
|
||||||
|
@ -2078,6 +2079,47 @@ static int32_t translateMode(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
return translateUniqueMode(pFunc, pErrBuf, len, false);
|
return translateUniqueMode(pFunc, pErrBuf, len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateForecast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||||
|
if (2 != numOfParams && 1 != numOfParams) {
|
||||||
|
return invaildFuncParaNumErrMsg(pErrBuf, len, "FORECAST require 1 or 2 parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t valType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||||
|
if (!IS_MATHABLE_TYPE(valType)) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, "FORECAST only support mathable column");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numOfParams == 2) {
|
||||||
|
uint8_t optionType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||||
|
if (TSDB_DATA_TYPE_BINARY != optionType) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, "FORECAST option should be varchar");
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* pOption = nodesListGetNode(pFunc->pParameterList, 1);
|
||||||
|
if (QUERY_NODE_VALUE != nodeType(pOption)) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, "FORECAST option should be value");
|
||||||
|
}
|
||||||
|
|
||||||
|
SValueNode* pValue = (SValueNode*)pOption;
|
||||||
|
if (!taosAnalGetOptStr(pValue->literal, "algo", NULL, 0) != 0) {
|
||||||
|
return invaildFuncParaValueErrMsg(pErrBuf, len, "FORECAST option should include algo field");
|
||||||
|
}
|
||||||
|
|
||||||
|
pValue->notReserved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[valType].bytes, .type = valType};
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateForecastConf(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_FLOAT].bytes, .type = TSDB_DATA_TYPE_FLOAT};
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EFuncReturnRows forecastEstReturnRows(SFunctionNode* pFunc) { return FUNC_RETURN_ROWS_N; }
|
||||||
|
|
||||||
static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||||
if (numOfParams > 2) {
|
if (numOfParams > 2) {
|
||||||
|
@ -4797,6 +4839,48 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.sprocessFunc = randFunction,
|
.sprocessFunc = randFunction,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "forecast",
|
||||||
|
.type = FUNCTION_TYPE_FORECAST,
|
||||||
|
.classification = FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
|
FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
||||||
|
.translateFunc = translateForecast,
|
||||||
|
.getEnvFunc = getSelectivityFuncEnv,
|
||||||
|
.initFunc = functionSetup,
|
||||||
|
.processFunc = NULL,
|
||||||
|
.finalizeFunc = NULL,
|
||||||
|
.estimateReturnRowsFunc = forecastEstReturnRows,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_frowts",
|
||||||
|
.type = FUNCTION_TYPE_FORECAST_ROWTS,
|
||||||
|
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_FORECAST_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||||
|
.translateFunc = translateTimePseudoColumn,
|
||||||
|
.getEnvFunc = getTimePseudoFuncEnv,
|
||||||
|
.initFunc = NULL,
|
||||||
|
.sprocessFunc = NULL,
|
||||||
|
.finalizeFunc = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_flow",
|
||||||
|
.type = FUNCTION_TYPE_FORECAST_LOW,
|
||||||
|
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_FORECAST_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||||
|
.translateFunc = translateForecastConf,
|
||||||
|
.getEnvFunc = getForecastConfEnv,
|
||||||
|
.initFunc = NULL,
|
||||||
|
.sprocessFunc = NULL,
|
||||||
|
.finalizeFunc = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_fhigh",
|
||||||
|
.type = FUNCTION_TYPE_FORECAST_HIGH,
|
||||||
|
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_FORECAST_PC_FUNC | FUNC_MGT_KEEP_ORDER_FUNC,
|
||||||
|
.translateFunc = translateForecastConf,
|
||||||
|
.getEnvFunc = getForecastConfEnv,
|
||||||
|
.initFunc = NULL,
|
||||||
|
.sprocessFunc = NULL,
|
||||||
|
.finalizeFunc = NULL
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "functionResInfoInt.h"
|
#include "functionResInfoInt.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
|
#include "tanal.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tdatablock.h"
|
#include "tdatablock.h"
|
||||||
#include "tdigest.h"
|
#include "tdigest.h"
|
||||||
|
@ -3342,6 +3343,11 @@ bool funcInputGetNextRowIndex(SInputColumnInfoData* pInput, int32_t from, bool f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getForecastConfEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||||
|
pEnv->calcMemSize = sizeof(float);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t diffResultIsNull(SqlFunctionCtx* pCtx, SFuncInputRow* pRow){
|
int32_t diffResultIsNull(SqlFunctionCtx* pCtx, SFuncInputRow* pRow){
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
SDiffInfo* pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
SDiffInfo* pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
@ -4734,10 +4740,10 @@ int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
int32_t len;
|
int32_t len;
|
||||||
char buf[512] = {0};
|
char buf[512] = {0};
|
||||||
if (!pInfo->normalized) {
|
if (!pInfo->normalized) {
|
||||||
len = snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{\"lower_bin\":%g, \"upper_bin\":%g, \"count\":%" PRId64 "}",
|
len = tsnprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{\"lower_bin\":%g, \"upper_bin\":%g, \"count\":%" PRId64 "}",
|
||||||
pInfo->bins[i].lower, pInfo->bins[i].upper, pInfo->bins[i].count);
|
pInfo->bins[i].lower, pInfo->bins[i].upper, pInfo->bins[i].count);
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{\"lower_bin\":%g, \"upper_bin\":%g, \"count\":%lf}", pInfo->bins[i].lower,
|
len = tsnprintf(varDataVal(buf), sizeof(buf) - VARSTR_HEADER_SIZE, "{\"lower_bin\":%g, \"upper_bin\":%g, \"count\":%lf}", pInfo->bins[i].lower,
|
||||||
pInfo->bins[i].upper, pInfo->bins[i].percentage);
|
pInfo->bins[i].upper, pInfo->bins[i].percentage);
|
||||||
}
|
}
|
||||||
varDataSetLen(buf, len);
|
varDataSetLen(buf, len);
|
||||||
|
@ -6365,7 +6371,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
compRatio = pData->totalSize * 100 / (double)totalRawSize;
|
compRatio = pData->totalSize * 100 / (double)totalRawSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE,
|
int32_t len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE,
|
||||||
"Total_Blocks=[%d] Total_Size=[%.2f KiB] Average_size=[%.2f KiB] Compression_Ratio=[%.2f %c]",
|
"Total_Blocks=[%d] Total_Size=[%.2f KiB] Average_size=[%.2f KiB] Compression_Ratio=[%.2f %c]",
|
||||||
pData->numOfBlocks, pData->totalSize / 1024.0, averageSize / 1024.0, compRatio, '%');
|
pData->numOfBlocks, pData->totalSize / 1024.0, averageSize / 1024.0, compRatio, '%');
|
||||||
|
|
||||||
|
@ -6380,7 +6386,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
avgRows = pData->totalRows / pData->numOfBlocks;
|
avgRows = pData->totalRows / pData->numOfBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Block_Rows=[%" PRId64 "] MinRows=[%d] MaxRows=[%d] AvgRows=[%" PRId64 "]",
|
len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Block_Rows=[%" PRId64 "] MinRows=[%d] MaxRows=[%d] AvgRows=[%" PRId64 "]",
|
||||||
pData->totalRows, pData->minRows, pData->maxRows, avgRows);
|
pData->totalRows, pData->minRows, pData->maxRows, avgRows);
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
code = colDataSetVal(pColInfo, row++, st, false);
|
code = colDataSetVal(pColInfo, row++, st, false);
|
||||||
|
@ -6388,14 +6394,14 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Inmem_Rows=[%d] Stt_Rows=[%d] ", pData->numOfInmemRows, pData->numOfSttRows);
|
len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Inmem_Rows=[%d] Stt_Rows=[%d] ", pData->numOfInmemRows, pData->numOfSttRows);
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
code = colDataSetVal(pColInfo, row++, st, false);
|
code = colDataSetVal(pColInfo, row++, st, false);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Total_Tables=[%d] Total_Filesets=[%d] Total_Vgroups=[%d]", pData->numOfTables,
|
len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "Total_Tables=[%d] Total_Filesets=[%d] Total_Vgroups=[%d]", pData->numOfTables,
|
||||||
pData->numOfFiles, pData->numOfVgroups);
|
pData->numOfFiles, pData->numOfVgroups);
|
||||||
|
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
|
@ -6404,7 +6410,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE,
|
len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE,
|
||||||
"--------------------------------------------------------------------------------");
|
"--------------------------------------------------------------------------------");
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
code = colDataSetVal(pColInfo, row++, st, false);
|
code = colDataSetVal(pColInfo, row++, st, false);
|
||||||
|
@ -6431,7 +6437,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
int32_t bucketRange = ceil(((double) (pData->defMaxRows - pData->defMinRows)) / numOfBuckets);
|
int32_t bucketRange = ceil(((double) (pData->defMaxRows - pData->defMinRows)) / numOfBuckets);
|
||||||
|
|
||||||
for (int32_t i = 0; i < tListLen(pData->blockRowsHisto); ++i) {
|
for (int32_t i = 0; i < tListLen(pData->blockRowsHisto); ++i) {
|
||||||
len = snprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "%04d |", pData->defMinRows + bucketRange * (i + 1));
|
len = tsnprintf(varDataVal(st), sizeof(st) - VARSTR_HEADER_SIZE, "%04d |", pData->defMinRows + bucketRange * (i + 1));
|
||||||
|
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
if (pData->blockRowsHisto[i] > 0) {
|
if (pData->blockRowsHisto[i] > 0) {
|
||||||
|
@ -6439,13 +6445,13 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t j = 0; j < num; ++j) {
|
for (int32_t j = 0; j < num; ++j) {
|
||||||
int32_t x = snprintf(varDataVal(st) + len, sizeof(st) - VARSTR_HEADER_SIZE - len, "%c", '|');
|
int32_t x = tsnprintf(varDataVal(st) + len, sizeof(st) - VARSTR_HEADER_SIZE - len, "%c", '|');
|
||||||
len += x;
|
len += x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pData->blockRowsHisto[i] > 0) {
|
if (pData->blockRowsHisto[i] > 0) {
|
||||||
double v = pData->blockRowsHisto[i] * 100.0 / pData->numOfBlocks;
|
double v = pData->blockRowsHisto[i] * 100.0 / pData->numOfBlocks;
|
||||||
len += snprintf(varDataVal(st) + len, sizeof(st) - VARSTR_HEADER_SIZE - len, " %d (%.2f%c)", pData->blockRowsHisto[i], v, '%');
|
len += tsnprintf(varDataVal(st) + len, sizeof(st) - VARSTR_HEADER_SIZE - len, " %d (%.2f%c)", pData->blockRowsHisto[i], v, '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
|
|
|
@ -232,6 +232,15 @@ bool fmIsInterpFunc(int32_t funcId) {
|
||||||
|
|
||||||
bool fmIsInterpPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_INTERP_PC_FUNC); }
|
bool fmIsInterpPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_INTERP_PC_FUNC); }
|
||||||
|
|
||||||
|
bool fmIsForecastFunc(int32_t funcId) {
|
||||||
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return FUNCTION_TYPE_FORECAST == funcMgtBuiltins[funcId].type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fmIsForecastPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_FORECAST_PC_FUNC); }
|
||||||
|
|
||||||
bool fmIsLastRowFunc(int32_t funcId) {
|
bool fmIsLastRowFunc(int32_t funcId) {
|
||||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -368,6 +368,13 @@ static int32_t countWindowNodeCopy(const SCountWindowNode* pSrc, SCountWindowNod
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t anomalyWindowNodeCopy(const SAnomalyWindowNode* pSrc, SAnomalyWindowNode* pDst) {
|
||||||
|
CLONE_NODE_FIELD(pCol);
|
||||||
|
CLONE_NODE_FIELD(pExpr);
|
||||||
|
COPY_CHAR_ARRAY_FIELD(anomalyOpt);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t sessionWindowNodeCopy(const SSessionWindowNode* pSrc, SSessionWindowNode* pDst) {
|
static int32_t sessionWindowNodeCopy(const SSessionWindowNode* pSrc, SSessionWindowNode* pDst) {
|
||||||
CLONE_NODE_FIELD_EX(pCol, SColumnNode*);
|
CLONE_NODE_FIELD_EX(pCol, SColumnNode*);
|
||||||
CLONE_NODE_FIELD_EX(pGap, SValueNode*);
|
CLONE_NODE_FIELD_EX(pGap, SValueNode*);
|
||||||
|
@ -622,6 +629,8 @@ static int32_t logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* p
|
||||||
COPY_SCALAR_FIELD(windowAlgo);
|
COPY_SCALAR_FIELD(windowAlgo);
|
||||||
COPY_SCALAR_FIELD(windowCount);
|
COPY_SCALAR_FIELD(windowCount);
|
||||||
COPY_SCALAR_FIELD(windowSliding);
|
COPY_SCALAR_FIELD(windowSliding);
|
||||||
|
CLONE_NODE_FIELD(pAnomalyExpr);
|
||||||
|
COPY_CHAR_ARRAY_FIELD(anomalyOpt);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,6 +686,12 @@ static int32_t logicInterpFuncCopy(const SInterpFuncLogicNode* pSrc, SInterpFunc
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t logicForecastFuncCopy(const SForecastFuncLogicNode* pSrc, SForecastFuncLogicNode* pDst) {
|
||||||
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
|
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t logicGroupCacheCopy(const SGroupCacheLogicNode* pSrc, SGroupCacheLogicNode* pDst) {
|
static int32_t logicGroupCacheCopy(const SGroupCacheLogicNode* pSrc, SGroupCacheLogicNode* pDst) {
|
||||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
COPY_SCALAR_FIELD(grpColsMayBeNull);
|
COPY_SCALAR_FIELD(grpColsMayBeNull);
|
||||||
|
@ -940,6 +955,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
code = countWindowNodeCopy((const SCountWindowNode*)pNode, (SCountWindowNode*)pDst);
|
code = countWindowNodeCopy((const SCountWindowNode*)pNode, (SCountWindowNode*)pDst);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
code = anomalyWindowNodeCopy((const SAnomalyWindowNode*)pNode, (SAnomalyWindowNode*)pDst);
|
||||||
|
break;
|
||||||
case QUERY_NODE_SESSION_WINDOW:
|
case QUERY_NODE_SESSION_WINDOW:
|
||||||
code = sessionWindowNodeCopy((const SSessionWindowNode*)pNode, (SSessionWindowNode*)pDst);
|
code = sessionWindowNodeCopy((const SSessionWindowNode*)pNode, (SSessionWindowNode*)pDst);
|
||||||
break;
|
break;
|
||||||
|
@ -1024,6 +1042,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
code = logicInterpFuncCopy((const SInterpFuncLogicNode*)pNode, (SInterpFuncLogicNode*)pDst);
|
code = logicInterpFuncCopy((const SInterpFuncLogicNode*)pNode, (SInterpFuncLogicNode*)pDst);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
code = logicForecastFuncCopy((const SForecastFuncLogicNode*)pNode, (SForecastFuncLogicNode*)pDst);
|
||||||
|
break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||||
code = logicGroupCacheCopy((const SGroupCacheLogicNode*)pNode, (SGroupCacheLogicNode*)pDst);
|
code = logicGroupCacheCopy((const SGroupCacheLogicNode*)pNode, (SGroupCacheLogicNode*)pDst);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -97,6 +97,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "WindowOffset";
|
return "WindowOffset";
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
return "CountWindow";
|
return "CountWindow";
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
return "AnomalyWindow";
|
||||||
case QUERY_NODE_SET_OPERATOR:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
return "SetOperator";
|
return "SetOperator";
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
@ -153,6 +155,12 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "CreateQnodeStmt";
|
return "CreateQnodeStmt";
|
||||||
case QUERY_NODE_DROP_QNODE_STMT:
|
case QUERY_NODE_DROP_QNODE_STMT:
|
||||||
return "DropQnodeStmt";
|
return "DropQnodeStmt";
|
||||||
|
case QUERY_NODE_CREATE_ANODE_STMT:
|
||||||
|
return "CreateAnodeStmt";
|
||||||
|
case QUERY_NODE_DROP_ANODE_STMT:
|
||||||
|
return "DropAnodeStmt";
|
||||||
|
case QUERY_NODE_UPDATE_ANODE_STMT:
|
||||||
|
return "UpdateAnodeStmt";
|
||||||
case QUERY_NODE_CREATE_SNODE_STMT:
|
case QUERY_NODE_CREATE_SNODE_STMT:
|
||||||
return "CreateSnodeStmt";
|
return "CreateSnodeStmt";
|
||||||
case QUERY_NODE_DROP_SNODE_STMT:
|
case QUERY_NODE_DROP_SNODE_STMT:
|
||||||
|
@ -213,6 +221,10 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "ShowModulesStmt";
|
return "ShowModulesStmt";
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
return "ShowQnodesStmt";
|
return "ShowQnodesStmt";
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
return "ShowAnodesStmt";
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
|
return "ShowAnodesFullStmt";
|
||||||
case QUERY_NODE_SHOW_SNODES_STMT:
|
case QUERY_NODE_SHOW_SNODES_STMT:
|
||||||
return "ShowSnodesStmt";
|
return "ShowSnodesStmt";
|
||||||
case QUERY_NODE_SHOW_BNODES_STMT:
|
case QUERY_NODE_SHOW_BNODES_STMT:
|
||||||
|
@ -328,6 +340,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "LogicIndefRowsFunc";
|
return "LogicIndefRowsFunc";
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
return "LogicInterpFunc";
|
return "LogicInterpFunc";
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
return "LogicForecastFunc";
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||||
return "LogicGroupCache";
|
return "LogicGroupCache";
|
||||||
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||||
|
@ -362,6 +376,10 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "PhysiMergeCountWindow";
|
return "PhysiMergeCountWindow";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
return "PhysiStreamCountWindow";
|
return "PhysiStreamCountWindow";
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
return "PhysiMergeAnomalyWindow";
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_ANOMALY:
|
||||||
|
return "PhysiStreamAnomalyWindow";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||||
return "PhysiProject";
|
return "PhysiProject";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN:
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN:
|
||||||
|
@ -415,6 +433,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
return "PhysiInterpFunc";
|
return "PhysiInterpFunc";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
||||||
return "PhysiStreamInterpFunc";
|
return "PhysiStreamInterpFunc";
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
return "PhysiForecastFunc";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return "PhysiDispatch";
|
return "PhysiDispatch";
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -1355,6 +1375,30 @@ static int32_t jsonToLogicInterpFuncNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* jkForecastFuncLogicPlanFuncs = "Funcs";
|
||||||
|
|
||||||
|
static int32_t logicForecastFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SForecastFuncLogicNode* pNode = (const SForecastFuncLogicNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkForecastFuncLogicPlanFuncs, pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToLogicForecastFuncNode(const SJson* pJson, void* pObj) {
|
||||||
|
SForecastFuncLogicNode* pNode = (SForecastFuncLogicNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToLogicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkForecastFuncLogicPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* jkGroupCacheLogicPlanGrpColsMayBeNull = "GroupColsMayBeNull";
|
static const char* jkGroupCacheLogicPlanGrpColsMayBeNull = "GroupColsMayBeNull";
|
||||||
static const char* jkGroupCacheLogicPlanGroupByUid = "GroupByUid";
|
static const char* jkGroupCacheLogicPlanGroupByUid = "GroupByUid";
|
||||||
static const char* jkGroupCacheLogicPlanGlobalGroup = "GlobalGroup";
|
static const char* jkGroupCacheLogicPlanGlobalGroup = "GlobalGroup";
|
||||||
|
@ -3106,6 +3150,36 @@ static int32_t jsonToPhysiCountWindowNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* jkAnomalyWindowPhysiPlanAnomalyKey = "AnomalyKey";
|
||||||
|
static const char* jkAnomalyWindowPhysiPlanAnomalyOption = "AnomalyOpt";
|
||||||
|
|
||||||
|
static int32_t physiAnomalyWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SAnomalyWindowPhysiNode* pNode = (const SAnomalyWindowPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = physiWindowNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddObject(pJson, jkAnomalyWindowPhysiPlanAnomalyKey, nodeToJson, pNode->pAnomalyKey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddStringToObject(pJson, jkAnomalyWindowPhysiPlanAnomalyOption, pNode->anomalyOpt);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToPhysiAnomalyWindowNode(const SJson* pJson, void* pObj) {
|
||||||
|
SAnomalyWindowPhysiNode* pNode = (SAnomalyWindowPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToPhysiWindowNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeObject(pJson, jkAnomalyWindowPhysiPlanAnomalyKey, &pNode->pAnomalyKey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetStringValue(pJson, jkAnomalyWindowPhysiPlanAnomalyOption, pNode->anomalyOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* jkPartitionPhysiPlanExprs = "Exprs";
|
static const char* jkPartitionPhysiPlanExprs = "Exprs";
|
||||||
static const char* jkPartitionPhysiPlanPartitionKeys = "PartitionKeys";
|
static const char* jkPartitionPhysiPlanPartitionKeys = "PartitionKeys";
|
||||||
static const char* jkPartitionPhysiPlanTargets = "Targets";
|
static const char* jkPartitionPhysiPlanTargets = "Targets";
|
||||||
|
@ -3314,6 +3388,37 @@ static int32_t jsonToPhysiInterpFuncNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* jkForecastFuncPhysiPlanExprs = "Exprs";
|
||||||
|
static const char* jkForecastFuncPhysiPlanFuncs = "Funcs";
|
||||||
|
|
||||||
|
static int32_t physiForecastFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SForecastFuncPhysiNode* pNode = (const SForecastFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkForecastFuncPhysiPlanExprs, pNode->pExprs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodeListToJson(pJson, jkForecastFuncPhysiPlanFuncs, pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToPhysiForecastFuncNode(const SJson* pJson, void* pObj) {
|
||||||
|
SForecastFuncPhysiNode* pNode = (SForecastFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkForecastFuncPhysiPlanExprs, &pNode->pExprs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeList(pJson, jkForecastFuncPhysiPlanFuncs, &pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc";
|
static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc";
|
||||||
|
|
||||||
static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
@ -4881,6 +4986,36 @@ static int32_t jsonToCountWindowNode(const SJson* pJson, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* jkAnomalyWindowTsPrimaryKey = "AnomalyTsPrimaryKey";
|
||||||
|
static const char* jkAnomalyWindowExpr = "AnomalyWindowExpr";
|
||||||
|
static const char* jkAnomalyWindowOption = "AnomalyWindowOpt";
|
||||||
|
|
||||||
|
static int32_t anomalyWindowNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SAnomalyWindowNode* pNode = (const SAnomalyWindowNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = tjsonAddObject(pJson, jkAnomalyWindowTsPrimaryKey, nodeToJson, pNode->pCol);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddObject(pJson, jkAnomalyWindowExpr, nodeToJson, pNode->pExpr);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddStringToObject(pJson, jkAnomalyWindowOption, pNode->anomalyOpt);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToAnomalyWindowNode(const SJson* pJson, void* pObj) {
|
||||||
|
SAnomalyWindowNode* pNode = (SAnomalyWindowNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToNodeObject(pJson, jkAnomalyWindowTsPrimaryKey, &pNode->pCol);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = jsonToNodeObject(pJson, jkAnomalyWindowExpr, (SNode**)&pNode->pExpr);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetStringValue(pJson, jkAnomalyWindowOption, pNode->anomalyOpt);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* jkIntervalWindowInterval = "Interval";
|
static const char* jkIntervalWindowInterval = "Interval";
|
||||||
static const char* jkIntervalWindowOffset = "Offset";
|
static const char* jkIntervalWindowOffset = "Offset";
|
||||||
static const char* jkIntervalWindowSliding = "Sliding";
|
static const char* jkIntervalWindowSliding = "Sliding";
|
||||||
|
@ -6595,6 +6730,39 @@ static int32_t dropQnodeStmtToJson(const void* pObj, SJson* pJson) { return drop
|
||||||
|
|
||||||
static int32_t jsonToDropQnodeStmt(const SJson* pJson, void* pObj) { return jsonToDropComponentNodeStmt(pJson, pObj); }
|
static int32_t jsonToDropQnodeStmt(const SJson* pJson, void* pObj) { return jsonToDropComponentNodeStmt(pJson, pObj); }
|
||||||
|
|
||||||
|
static const char* jkCreateAnodeStmtUrl = "Url";
|
||||||
|
static const char* jkUpdateDropANodeStmtId = "AnodeId";
|
||||||
|
|
||||||
|
static int32_t createAnodeStmtToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SCreateAnodeStmt* pNode = (const SCreateAnodeStmt*)pObj;
|
||||||
|
return tjsonAddStringToObject(pJson, jkCreateAnodeStmtUrl, pNode->url);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToCreateAnodeStmt(const SJson* pJson, void* pObj) {
|
||||||
|
SCreateAnodeStmt* pNode = (SCreateAnodeStmt*)pObj;
|
||||||
|
return tjsonGetStringValue(pJson, jkCreateAnodeStmtUrl, pNode->url);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t updateAnodeStmtToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SUpdateAnodeStmt* pNode = (const SUpdateAnodeStmt*)pObj;
|
||||||
|
return tjsonAddIntegerToObject(pJson, jkUpdateDropANodeStmtId, pNode->anodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToUpdateAnodeStmt(const SJson* pJson, void* pObj) {
|
||||||
|
SUpdateAnodeStmt* pNode = (SUpdateAnodeStmt*)pObj;
|
||||||
|
return tjsonGetIntValue(pJson, jkUpdateDropANodeStmtId, &pNode->anodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dropAnodeStmtToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SDropAnodeStmt* pNode = (const SDropAnodeStmt*)pObj;
|
||||||
|
return tjsonAddIntegerToObject(pJson, jkUpdateDropANodeStmtId, pNode->anodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToDropAnodeStmt(const SJson* pJson, void* pObj) {
|
||||||
|
SDropAnodeStmt* pNode = (SDropAnodeStmt*)pObj;
|
||||||
|
return tjsonGetIntValue(pJson, jkUpdateDropANodeStmtId, &pNode->anodeId);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createSnodeStmtToJson(const void* pObj, SJson* pJson) {
|
static int32_t createSnodeStmtToJson(const void* pObj, SJson* pJson) {
|
||||||
return createComponentNodeStmtToJson(pObj, pJson);
|
return createComponentNodeStmtToJson(pObj, pJson);
|
||||||
}
|
}
|
||||||
|
@ -7160,6 +7328,14 @@ static int32_t showQnodesStmtToJson(const void* pObj, SJson* pJson) { return sho
|
||||||
|
|
||||||
static int32_t jsonToShowQnodesStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
static int32_t jsonToShowQnodesStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
||||||
|
|
||||||
|
static int32_t showAnodesStmtToJson(const void* pObj, SJson* pJson) { return showStmtToJson(pObj, pJson); }
|
||||||
|
|
||||||
|
static int32_t jsonToShowAnodesStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
||||||
|
|
||||||
|
static int32_t showAnodesFullStmtToJson(const void* pObj, SJson* pJson) { return showStmtToJson(pObj, pJson); }
|
||||||
|
|
||||||
|
static int32_t jsonToShowAnodesFullStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
||||||
|
|
||||||
static int32_t showArbGroupsStmtToJson(const void* pObj, SJson* pJson) { return showStmtToJson(pObj, pJson); }
|
static int32_t showArbGroupsStmtToJson(const void* pObj, SJson* pJson) { return showStmtToJson(pObj, pJson); }
|
||||||
|
|
||||||
static int32_t jsonToShowArbGroupsStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
static int32_t jsonToShowArbGroupsStmt(const SJson* pJson, void* pObj) { return jsonToShowStmt(pJson, pObj); }
|
||||||
|
@ -7696,6 +7872,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return windowOffsetNodeToJson(pObj, pJson);
|
return windowOffsetNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
return countWindowNodeToJson(pObj, pJson);
|
return countWindowNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
return anomalyWindowNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_SET_OPERATOR:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
return setOperatorToJson(pObj, pJson);
|
return setOperatorToJson(pObj, pJson);
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
@ -7748,6 +7926,12 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return createQnodeStmtToJson(pObj, pJson);
|
return createQnodeStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_DROP_QNODE_STMT:
|
case QUERY_NODE_DROP_QNODE_STMT:
|
||||||
return dropQnodeStmtToJson(pObj, pJson);
|
return dropQnodeStmtToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_CREATE_ANODE_STMT:
|
||||||
|
return createAnodeStmtToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_DROP_ANODE_STMT:
|
||||||
|
return dropAnodeStmtToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_UPDATE_ANODE_STMT:
|
||||||
|
return updateAnodeStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_CREATE_SNODE_STMT:
|
case QUERY_NODE_CREATE_SNODE_STMT:
|
||||||
return createSnodeStmtToJson(pObj, pJson);
|
return createSnodeStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_DROP_SNODE_STMT:
|
case QUERY_NODE_DROP_SNODE_STMT:
|
||||||
|
@ -7798,6 +7982,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return showMnodesStmtToJson(pObj, pJson);
|
return showMnodesStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
return showQnodesStmtToJson(pObj, pJson);
|
return showQnodesStmtToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
return showAnodesStmtToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
|
return showAnodesFullStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
||||||
return showArbGroupsStmtToJson(pObj, pJson);
|
return showArbGroupsStmtToJson(pObj, pJson);
|
||||||
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
||||||
|
@ -7887,6 +8075,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return logicIndefRowsFuncNodeToJson(pObj, pJson);
|
return logicIndefRowsFuncNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
return logicInterpFuncNodeToJson(pObj, pJson);
|
return logicInterpFuncNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
return logicForecastFuncNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||||
return logicGroupCacheNodeToJson(pObj, pJson);
|
return logicGroupCacheNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||||
|
@ -7947,6 +8137,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
return physiCountWindowNodeToJson(pObj, pJson);
|
return physiCountWindowNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
return physiAnomalyWindowNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||||
return physiPartitionNodeToJson(pObj, pJson);
|
return physiPartitionNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||||
|
@ -7956,6 +8148,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
||||||
return physiInterpFuncNodeToJson(pObj, pJson);
|
return physiInterpFuncNodeToJson(pObj, pJson);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
return physiForecastFuncNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return physiDispatchNodeToJson(pObj, pJson);
|
return physiDispatchNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -8047,6 +8241,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToWindowOffsetNode(pJson, pObj);
|
return jsonToWindowOffsetNode(pJson, pObj);
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
return jsonToCountWindowNode(pJson, pObj);
|
return jsonToCountWindowNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
return jsonToAnomalyWindowNode(pJson, pObj);
|
||||||
case QUERY_NODE_SET_OPERATOR:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
return jsonToSetOperator(pJson, pObj);
|
return jsonToSetOperator(pJson, pObj);
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
@ -8149,6 +8345,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToShowMnodesStmt(pJson, pObj);
|
return jsonToShowMnodesStmt(pJson, pObj);
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
return jsonToShowQnodesStmt(pJson, pObj);
|
return jsonToShowQnodesStmt(pJson, pObj);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
return jsonToShowAnodesStmt(pJson, pObj);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
|
return jsonToShowAnodesFullStmt(pJson, pObj);
|
||||||
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
||||||
return jsonToShowArbGroupsStmt(pJson, pObj);
|
return jsonToShowArbGroupsStmt(pJson, pObj);
|
||||||
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
||||||
|
@ -8246,6 +8446,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
return jsonToLogicIndefRowsFuncNode(pJson, pObj);
|
return jsonToLogicIndefRowsFuncNode(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
return jsonToLogicInterpFuncNode(pJson, pObj);
|
return jsonToLogicInterpFuncNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
return jsonToLogicForecastFuncNode(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||||
return jsonToLogicGroupCacheNode(pJson, pObj);
|
return jsonToLogicGroupCacheNode(pJson, pObj);
|
||||||
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||||
|
@ -8306,6 +8508,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
return jsonToPhysiCountWindowNode(pJson, pObj);
|
return jsonToPhysiCountWindowNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
return jsonToPhysiAnomalyWindowNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||||
return jsonToPhysiPartitionNode(pJson, pObj);
|
return jsonToPhysiPartitionNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
|
||||||
|
@ -8315,6 +8519,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
||||||
return jsonToPhysiInterpFuncNode(pJson, pObj);
|
return jsonToPhysiInterpFuncNode(pJson, pObj);
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
return jsonToPhysiForecastFuncNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
return jsonToPhysiDispatchNode(pJson, pObj);
|
return jsonToPhysiDispatchNode(pJson, pObj);
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT:
|
||||||
|
|
|
@ -3539,6 +3539,46 @@ static int32_t msgToPhysiCountWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum { PHY_ANOMALY_CODE_WINDOW = 1, PHY_ANOMALY_CODE_KEY, PHY_ANOMALY_CODE_WINDOW_OPTION };
|
||||||
|
|
||||||
|
static int32_t physiAnomalyWindowNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
const SAnomalyWindowPhysiNode* pNode = (const SAnomalyWindowPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = tlvEncodeObj(pEncoder, PHY_ANOMALY_CODE_WINDOW, physiWindowNodeToMsg, &pNode->window);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeObj(pEncoder, PHY_ANOMALY_CODE_KEY, nodeToMsg, pNode->pAnomalyKey);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeCStr(pEncoder, PHY_ANOMALY_CODE_WINDOW_OPTION, pNode->anomalyOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t msgToPhysiAnomalyWindowNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
|
SAnomalyWindowPhysiNode* pNode = (SAnomalyWindowPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
STlv* pTlv = NULL;
|
||||||
|
tlvForEach(pDecoder, pTlv, code) {
|
||||||
|
switch (pTlv->type) {
|
||||||
|
case PHY_ANOMALY_CODE_WINDOW:
|
||||||
|
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiWindowNode, &pNode->window);
|
||||||
|
break;
|
||||||
|
case PHY_ANOMALY_CODE_KEY:
|
||||||
|
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pAnomalyKey);
|
||||||
|
break;
|
||||||
|
case PHY_ANOMALY_CODE_WINDOW_OPTION:
|
||||||
|
code = tlvDecodeCStr(pTlv, pNode->anomalyOpt, sizeof(pNode->anomalyOpt));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PHY_PARTITION_CODE_BASE_NODE = 1,
|
PHY_PARTITION_CODE_BASE_NODE = 1,
|
||||||
PHY_PARTITION_CODE_EXPR,
|
PHY_PARTITION_CODE_EXPR,
|
||||||
|
@ -3770,6 +3810,50 @@ static int32_t msgToPhysiInterpFuncNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PHY_FORECAST_FUNC_CODE_BASE_NODE = 1,
|
||||||
|
PHY_FORECAST_FUNC_CODE_EXPR,
|
||||||
|
PHY_FORECAST_FUNC_CODE_FUNCS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t physiForecastFuncNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
const SForecastFuncPhysiNode* pNode = (const SForecastFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = tlvEncodeObj(pEncoder, PHY_FORECAST_FUNC_CODE_BASE_NODE, physiNodeToMsg, &pNode->node);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeObj(pEncoder, PHY_FORECAST_FUNC_CODE_EXPR, nodeListToMsg, pNode->pExprs);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeObj(pEncoder, PHY_FORECAST_FUNC_CODE_FUNCS, nodeListToMsg, pNode->pFuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t msgToPhysiForecastFuncNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
|
SForecastFuncPhysiNode* pNode = (SForecastFuncPhysiNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
STlv* pTlv = NULL;
|
||||||
|
tlvForEach(pDecoder, pTlv, code) {
|
||||||
|
switch (pTlv->type) {
|
||||||
|
case PHY_FORECAST_FUNC_CODE_BASE_NODE:
|
||||||
|
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiNode, &pNode->node);
|
||||||
|
break;
|
||||||
|
case PHY_FORECAST_FUNC_CODE_EXPR:
|
||||||
|
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pExprs);
|
||||||
|
break;
|
||||||
|
case PHY_FORECAST_FUNC_CODE_FUNCS:
|
||||||
|
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pFuncs);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
enum { PHY_DATA_SINK_CODE_INPUT_DESC = 1 };
|
enum { PHY_DATA_SINK_CODE_INPUT_DESC = 1 };
|
||||||
|
|
||||||
static int32_t physicDataSinkNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
static int32_t physicDataSinkNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
@ -4536,6 +4620,9 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
code = physiCountWindowNodeToMsg(pObj, pEncoder);
|
code = physiCountWindowNodeToMsg(pObj, pEncoder);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
code = physiAnomalyWindowNodeToMsg(pObj, pEncoder);
|
||||||
|
break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||||
code = physiPartitionNodeToMsg(pObj, pEncoder);
|
code = physiPartitionNodeToMsg(pObj, pEncoder);
|
||||||
break;
|
break;
|
||||||
|
@ -4549,6 +4636,9 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
||||||
code = physiInterpFuncNodeToMsg(pObj, pEncoder);
|
code = physiInterpFuncNodeToMsg(pObj, pEncoder);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
code = physiForecastFuncNodeToMsg(pObj, pEncoder);
|
||||||
|
break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
code = physiDispatchNodeToMsg(pObj, pEncoder);
|
code = physiDispatchNodeToMsg(pObj, pEncoder);
|
||||||
break;
|
break;
|
||||||
|
@ -4699,6 +4789,9 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
code = msgToPhysiCountWindowNode(pDecoder, pObj);
|
code = msgToPhysiCountWindowNode(pDecoder, pObj);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
code = msgToPhysiAnomalyWindowNode(pDecoder, pObj);
|
||||||
|
break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||||
code = msgToPhysiPartitionNode(pDecoder, pObj);
|
code = msgToPhysiPartitionNode(pDecoder, pObj);
|
||||||
break;
|
break;
|
||||||
|
@ -4712,6 +4805,9 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
|
||||||
code = msgToPhysiInterpFuncNode(pDecoder, pObj);
|
code = msgToPhysiInterpFuncNode(pDecoder, pObj);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
code = msgToPhysiForecastFuncNode(pDecoder, pObj);
|
||||||
|
break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
code = msgToPhysiDispatchNode(pDecoder, pObj);
|
code = msgToPhysiDispatchNode(pDecoder, pObj);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -181,6 +181,14 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
|
||||||
res = walkExpr(pEvent->pCol, order, walker, pContext);
|
res = walkExpr(pEvent->pCol, order, walker, pContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW: {
|
||||||
|
SAnomalyWindowNode* pAnomaly = (SAnomalyWindowNode*)pNode;
|
||||||
|
res = walkExpr(pAnomaly->pExpr, order, walker, pContext);
|
||||||
|
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
|
||||||
|
res = walkExpr(pAnomaly->pCol, order, walker, pContext);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -392,6 +400,14 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
|
||||||
res = rewriteExpr(&pEvent->pCol, order, rewriter, pContext);
|
res = rewriteExpr(&pEvent->pCol, order, rewriter, pContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW: {
|
||||||
|
SAnomalyWindowNode* pAnomaly = (SAnomalyWindowNode*)pNode;
|
||||||
|
res = rewriteExpr(&pAnomaly->pExpr, order, rewriter, pContext);
|
||||||
|
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
|
||||||
|
res = rewriteExpr(&pAnomaly->pCol, order, rewriter, pContext);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,6 +419,8 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
code = makeNode(type, sizeof(SEventWindowNode), &pNode); break;
|
code = makeNode(type, sizeof(SEventWindowNode), &pNode); break;
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
code = makeNode(type, sizeof(SCountWindowNode), &pNode); break;
|
code = makeNode(type, sizeof(SCountWindowNode), &pNode); break;
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
code = makeNode(type, sizeof(SAnomalyWindowNode), &pNode); break;
|
||||||
case QUERY_NODE_HINT:
|
case QUERY_NODE_HINT:
|
||||||
code = makeNode(type, sizeof(SHintNode), &pNode); break;
|
code = makeNode(type, sizeof(SHintNode), &pNode); break;
|
||||||
case QUERY_NODE_VIEW:
|
case QUERY_NODE_VIEW:
|
||||||
|
@ -474,6 +476,12 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
code = makeNode(type, sizeof(SDropDnodeStmt), &pNode); break;
|
code = makeNode(type, sizeof(SDropDnodeStmt), &pNode); break;
|
||||||
case QUERY_NODE_ALTER_DNODE_STMT:
|
case QUERY_NODE_ALTER_DNODE_STMT:
|
||||||
code = makeNode(type, sizeof(SAlterDnodeStmt), &pNode); break;
|
code = makeNode(type, sizeof(SAlterDnodeStmt), &pNode); break;
|
||||||
|
case QUERY_NODE_CREATE_ANODE_STMT:
|
||||||
|
code = makeNode(type, sizeof(SCreateAnodeStmt), &pNode); break;
|
||||||
|
case QUERY_NODE_DROP_ANODE_STMT:
|
||||||
|
code = makeNode(type, sizeof(SDropAnodeStmt), &pNode); break;
|
||||||
|
case QUERY_NODE_UPDATE_ANODE_STMT:
|
||||||
|
code = makeNode(type, sizeof(SUpdateAnodeStmt), &pNode); break;
|
||||||
case QUERY_NODE_CREATE_INDEX_STMT:
|
case QUERY_NODE_CREATE_INDEX_STMT:
|
||||||
code = makeNode(type, sizeof(SCreateIndexStmt), &pNode); break;
|
code = makeNode(type, sizeof(SCreateIndexStmt), &pNode); break;
|
||||||
case QUERY_NODE_DROP_INDEX_STMT:
|
case QUERY_NODE_DROP_INDEX_STMT:
|
||||||
|
@ -540,6 +548,8 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_MODULES_STMT:
|
case QUERY_NODE_SHOW_MODULES_STMT:
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
case QUERY_NODE_SHOW_SNODES_STMT:
|
case QUERY_NODE_SHOW_SNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_BNODES_STMT:
|
case QUERY_NODE_SHOW_BNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
||||||
|
@ -647,6 +657,8 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
code = makeNode(type, sizeof(SIndefRowsFuncLogicNode), &pNode); break;
|
code = makeNode(type, sizeof(SIndefRowsFuncLogicNode), &pNode); break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
code = makeNode(type, sizeof(SInterpFuncLogicNode), &pNode); break;
|
code = makeNode(type, sizeof(SInterpFuncLogicNode), &pNode); break;
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
code = makeNode(type, sizeof(SForecastFuncLogicNode), &pNode); break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
|
||||||
code = makeNode(type, sizeof(SGroupCacheLogicNode), &pNode); break;
|
code = makeNode(type, sizeof(SGroupCacheLogicNode), &pNode); break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||||
|
@ -722,6 +734,8 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
code = makeNode(type, sizeof(SStreamEventWinodwPhysiNode), &pNode); break;
|
code = makeNode(type, sizeof(SStreamEventWinodwPhysiNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
|
||||||
code = makeNode(type, sizeof(SCountWinodwPhysiNode), &pNode); break;
|
code = makeNode(type, sizeof(SCountWinodwPhysiNode), &pNode); break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY:
|
||||||
|
code = makeNode(type, sizeof(SAnomalyWindowPhysiNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
case QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT:
|
||||||
code = makeNode(type, sizeof(SStreamCountWinodwPhysiNode), &pNode); break;
|
code = makeNode(type, sizeof(SStreamCountWinodwPhysiNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
|
||||||
|
@ -732,6 +746,8 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
|
||||||
code = makeNode(type, sizeof(SIndefRowsFuncPhysiNode), &pNode); break;
|
code = makeNode(type, sizeof(SIndefRowsFuncPhysiNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
|
||||||
code = makeNode(type, sizeof(SInterpFuncLogicNode), &pNode); break;
|
code = makeNode(type, sizeof(SInterpFuncLogicNode), &pNode); break;
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC:
|
||||||
|
code = makeNode(type, sizeof(SForecastFuncLogicNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
code = makeNode(type, sizeof(SDataDispatcherNode), &pNode); break;
|
code = makeNode(type, sizeof(SDataDispatcherNode), &pNode); break;
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||||
|
@ -1021,6 +1037,11 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
nodesDestroyNode(pEvent->pCol);
|
nodesDestroyNode(pEvent->pCol);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW: {
|
||||||
|
SAnomalyWindowNode* pAnomaly = (SAnomalyWindowNode*)pNode;
|
||||||
|
nodesDestroyNode(pAnomaly->pCol);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QUERY_NODE_HINT: {
|
case QUERY_NODE_HINT: {
|
||||||
SHintNode* pHint = (SHintNode*)pNode;
|
SHintNode* pHint = (SHintNode*)pNode;
|
||||||
destroyHintValue(pHint->option, pHint->value);
|
destroyHintValue(pHint->option, pHint->value);
|
||||||
|
@ -1169,6 +1190,9 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
case QUERY_NODE_CREATE_DNODE_STMT: // no pointer field
|
case QUERY_NODE_CREATE_DNODE_STMT: // no pointer field
|
||||||
case QUERY_NODE_DROP_DNODE_STMT: // no pointer field
|
case QUERY_NODE_DROP_DNODE_STMT: // no pointer field
|
||||||
case QUERY_NODE_ALTER_DNODE_STMT: // no pointer field
|
case QUERY_NODE_ALTER_DNODE_STMT: // no pointer field
|
||||||
|
case QUERY_NODE_CREATE_ANODE_STMT: // no pointer field
|
||||||
|
case QUERY_NODE_UPDATE_ANODE_STMT: // no pointer field
|
||||||
|
case QUERY_NODE_DROP_ANODE_STMT: // no pointer field
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_CREATE_INDEX_STMT: {
|
case QUERY_NODE_CREATE_INDEX_STMT: {
|
||||||
SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pNode;
|
SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pNode;
|
||||||
|
@ -1254,6 +1278,8 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_MODULES_STMT:
|
case QUERY_NODE_SHOW_MODULES_STMT:
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
case QUERY_NODE_SHOW_SNODES_STMT:
|
case QUERY_NODE_SHOW_SNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_BNODES_STMT:
|
case QUERY_NODE_SHOW_BNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
||||||
|
@ -1502,6 +1528,12 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
nodesDestroyNode(pLogicNode->pTimeSeries);
|
nodesDestroyNode(pLogicNode->pTimeSeries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC: {
|
||||||
|
SForecastFuncLogicNode* pLogicNode = (SForecastFuncLogicNode*)pNode;
|
||||||
|
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||||
|
nodesDestroyList(pLogicNode->pFuncs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE: {
|
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE: {
|
||||||
SGroupCacheLogicNode* pLogicNode = (SGroupCacheLogicNode*)pNode;
|
SGroupCacheLogicNode* pLogicNode = (SGroupCacheLogicNode*)pNode;
|
||||||
destroyLogicNode((SLogicNode*)pLogicNode);
|
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||||
|
@ -1665,6 +1697,11 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_MERGE_ANOMALY: {
|
||||||
|
SAnomalyWindowPhysiNode* pPhyNode = (SAnomalyWindowPhysiNode*)pNode;
|
||||||
|
destroyWinodwPhysiNode((SWindowPhysiNode*)pPhyNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
|
case QUERY_NODE_PHYSICAL_PLAN_PARTITION: {
|
||||||
destroyPartitionPhysiNode((SPartitionPhysiNode*)pNode);
|
destroyPartitionPhysiNode((SPartitionPhysiNode*)pNode);
|
||||||
break;
|
break;
|
||||||
|
@ -1693,6 +1730,13 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
nodesDestroyNode(pPhyNode->pTimeSeries);
|
nodesDestroyNode(pPhyNode->pTimeSeries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QUERY_NODE_PHYSICAL_PLAN_FORECAST_FUNC: {
|
||||||
|
SForecastFuncPhysiNode* pPhyNode = (SForecastFuncPhysiNode*)pNode;
|
||||||
|
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||||
|
nodesDestroyList(pPhyNode->pExprs);
|
||||||
|
nodesDestroyList(pPhyNode->pFuncs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||||
destroyDataSinkNode((SDataSinkNode*)pNode);
|
destroyDataSinkNode((SDataSinkNode*)pNode);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -154,6 +154,7 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode*
|
||||||
SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr);
|
SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr);
|
||||||
SNode* createEventWindowNode(SAstCreateContext* pCxt, SNode* pStartCond, SNode* pEndCond);
|
SNode* createEventWindowNode(SAstCreateContext* pCxt, SNode* pStartCond, SNode* pEndCond);
|
||||||
SNode* createCountWindowNode(SAstCreateContext* pCxt, const SToken* pCountToken, const SToken* pSlidingToken);
|
SNode* createCountWindowNode(SAstCreateContext* pCxt, const SToken* pCountToken, const SToken* pSlidingToken);
|
||||||
|
SNode* createAnomalyWindowNode(SAstCreateContext* pCxt, SNode* pExpr, const SToken* pFuncOpt);
|
||||||
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
||||||
SNode* pFill);
|
SNode* pFill);
|
||||||
SNode* createWindowOffsetNode(SAstCreateContext* pCxt, SNode* pStartOffset, SNode* pEndOffset);
|
SNode* createWindowOffsetNode(SAstCreateContext* pCxt, SNode* pStartOffset, SNode* pEndOffset);
|
||||||
|
@ -251,6 +252,9 @@ SNode* createDropUserStmt(SAstCreateContext* pCxt, SToken* pUserName);
|
||||||
SNode* createCreateDnodeStmt(SAstCreateContext* pCxt, const SToken* pFqdn, const SToken* pPort);
|
SNode* createCreateDnodeStmt(SAstCreateContext* pCxt, const SToken* pFqdn, const SToken* pPort);
|
||||||
SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode, bool force, bool unsafe);
|
SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode, bool force, bool unsafe);
|
||||||
SNode* createAlterDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode, const SToken* pConfig, const SToken* pValue);
|
SNode* createAlterDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode, const SToken* pConfig, const SToken* pValue);
|
||||||
|
SNode* createCreateAnodeStmt(SAstCreateContext* pCxt, const SToken* pUrl);
|
||||||
|
SNode* createDropAnodeStmt(SAstCreateContext* pCxt, const SToken* pAnode);
|
||||||
|
SNode* createUpdateAnodeStmt(SAstCreateContext* pCxt, const SToken* pAnode, bool updateAll);
|
||||||
SNode* createEncryptKeyStmt(SAstCreateContext* pCxt, const SToken* pValue);
|
SNode* createEncryptKeyStmt(SAstCreateContext* pCxt, const SToken* pValue);
|
||||||
SNode* createRealTableNodeForIndexName(SAstCreateContext* pCxt, SToken* pDbName, SToken* pIndexName);
|
SNode* createRealTableNodeForIndexName(SAstCreateContext* pCxt, SToken* pDbName, SToken* pIndexName);
|
||||||
SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, bool ignoreExists, SNode* pIndexName,
|
SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, bool ignoreExists, SNode* pIndexName,
|
||||||
|
|
|
@ -157,6 +157,12 @@ with_clause_opt(A) ::= WITH search_condition(B).
|
||||||
/************************************************ create encrypt_key *********************************************/
|
/************************************************ create encrypt_key *********************************************/
|
||||||
cmd ::= CREATE ENCRYPT_KEY NK_STRING(A). { pCxt->pRootNode = createEncryptKeyStmt(pCxt, &A); }
|
cmd ::= CREATE ENCRYPT_KEY NK_STRING(A). { pCxt->pRootNode = createEncryptKeyStmt(pCxt, &A); }
|
||||||
|
|
||||||
|
/************************************************ create drop update anode ***************************************/
|
||||||
|
cmd ::= CREATE ANODE NK_STRING(A). { pCxt->pRootNode = createCreateAnodeStmt(pCxt, &A); }
|
||||||
|
cmd ::= UPDATE ANODE NK_INTEGER(A). { pCxt->pRootNode = createUpdateAnodeStmt(pCxt, &A, false); }
|
||||||
|
cmd ::= UPDATE ALL ANODES. { pCxt->pRootNode = createUpdateAnodeStmt(pCxt, NULL, true); }
|
||||||
|
cmd ::= DROP ANODE NK_INTEGER(A). { pCxt->pRootNode = createDropAnodeStmt(pCxt, &A); }
|
||||||
|
|
||||||
/************************************************ create/drop/alter/restore dnode *********************************************/
|
/************************************************ create/drop/alter/restore dnode *********************************************/
|
||||||
cmd ::= CREATE DNODE dnode_endpoint(A). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, NULL); }
|
cmd ::= CREATE DNODE dnode_endpoint(A). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, NULL); }
|
||||||
cmd ::= CREATE DNODE dnode_endpoint(A) PORT NK_INTEGER(B). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, &B); }
|
cmd ::= CREATE DNODE dnode_endpoint(A) PORT NK_INTEGER(B). { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &A, &B); }
|
||||||
|
@ -524,6 +530,8 @@ cmd ::= SHOW db_name_cond_opt(A) VGROUPS.
|
||||||
cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); }
|
cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); }
|
||||||
//cmd ::= SHOW MODULES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT); }
|
//cmd ::= SHOW MODULES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT); }
|
||||||
cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); }
|
cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); }
|
||||||
|
cmd ::= SHOW ANODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ANODES_STMT); }
|
||||||
|
cmd ::= SHOW ANODES FULL. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ANODES_FULL_STMT); }
|
||||||
cmd ::= SHOW ARBGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ARBGROUPS_STMT); }
|
cmd ::= SHOW ARBGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ARBGROUPS_STMT); }
|
||||||
cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); }
|
cmd ::= SHOW FUNCTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); }
|
||||||
cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, B, A, OP_TYPE_EQUAL); }
|
cmd ::= SHOW INDEXES FROM table_name_cond(A) from_db_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, B, A, OP_TYPE_EQUAL); }
|
||||||
|
@ -1188,6 +1196,9 @@ pseudo_column(A) ::= WDURATION(B).
|
||||||
pseudo_column(A) ::= IROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= IROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= ISFILLED(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= ISFILLED(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= QTAGS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= QTAGS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
|
pseudo_column(A) ::= FLOW(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
|
pseudo_column(A) ::= FHIGH(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
|
pseudo_column(A) ::= FROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
|
|
||||||
function_expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
function_expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
||||||
function_expression(A) ::= star_func(B) NK_LP star_func_para_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
function_expression(A) ::= star_func(B) NK_LP star_func_para_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
||||||
|
@ -1506,6 +1517,10 @@ twindow_clause_opt(A) ::=
|
||||||
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_RP. { A = createCountWindowNode(pCxt, &B, &B); }
|
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_RP. { A = createCountWindowNode(pCxt, &B, &B); }
|
||||||
twindow_clause_opt(A) ::=
|
twindow_clause_opt(A) ::=
|
||||||
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createCountWindowNode(pCxt, &B, &C); }
|
COUNT_WINDOW NK_LP NK_INTEGER(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createCountWindowNode(pCxt, &B, &C); }
|
||||||
|
twindow_clause_opt(A) ::=
|
||||||
|
ANOMALY_WINDOW NK_LP expr_or_subquery(B) NK_RP. { A = createAnomalyWindowNode(pCxt, releaseRawExprNode(pCxt, B), NULL); }
|
||||||
|
twindow_clause_opt(A) ::=
|
||||||
|
ANOMALY_WINDOW NK_LP expr_or_subquery(B) NK_COMMA NK_STRING(C) NK_RP. { A = createAnomalyWindowNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||||
|
|
||||||
sliding_opt(A) ::= . { A = NULL; }
|
sliding_opt(A) ::= . { A = NULL; }
|
||||||
sliding_opt(A) ::= SLIDING NK_LP interval_sliding_duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
sliding_opt(A) ::= SLIDING NK_LP interval_sliding_duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||||
|
|
|
@ -1368,6 +1368,25 @@ _err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createAnomalyWindowNode(SAstCreateContext* pCxt, SNode* pExpr, const SToken* pFuncOpt) {
|
||||||
|
SAnomalyWindowNode* pAnomaly = NULL;
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
pCxt->errCode = nodesMakeNode(QUERY_NODE_ANOMALY_WINDOW, (SNode**)&pAnomaly);
|
||||||
|
CHECK_MAKE_NODE(pAnomaly);
|
||||||
|
pAnomaly->pCol = createPrimaryKeyCol(pCxt, NULL);
|
||||||
|
CHECK_MAKE_NODE(pAnomaly->pCol);
|
||||||
|
pAnomaly->pExpr = pExpr;
|
||||||
|
if (pFuncOpt == NULL) {
|
||||||
|
tstrncpy(pAnomaly->anomalyOpt, "algo=iqr", TSDB_ANAL_ALGO_OPTION_LEN);
|
||||||
|
} else {
|
||||||
|
(void)trimString(pFuncOpt->z, pFuncOpt->n, pAnomaly->anomalyOpt, sizeof(pAnomaly->anomalyOpt));
|
||||||
|
}
|
||||||
|
return (SNode*)pAnomaly;
|
||||||
|
_err:
|
||||||
|
nodesDestroyNode((SNode*)pAnomaly);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode* pOffset, SNode* pSliding,
|
||||||
SNode* pFill) {
|
SNode* pFill) {
|
||||||
SIntervalWindowNode* interval = NULL;
|
SIntervalWindowNode* interval = NULL;
|
||||||
|
@ -2998,6 +3017,47 @@ _err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createCreateAnodeStmt(SAstCreateContext* pCxt, const SToken* pUrl) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
SCreateAnodeStmt* pStmt = NULL;
|
||||||
|
pCxt->errCode = nodesMakeNode(QUERY_NODE_CREATE_ANODE_STMT, (SNode**)&pStmt);
|
||||||
|
CHECK_MAKE_NODE(pStmt);
|
||||||
|
(void)trimString(pUrl->z, pUrl->n, pStmt->url, sizeof(pStmt->url));
|
||||||
|
return (SNode*)pStmt;
|
||||||
|
_err:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* createDropAnodeStmt(SAstCreateContext* pCxt, const SToken* pAnode) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
SUpdateAnodeStmt* pStmt = NULL;
|
||||||
|
pCxt->errCode = nodesMakeNode(QUERY_NODE_DROP_ANODE_STMT, (SNode**)&pStmt);
|
||||||
|
CHECK_MAKE_NODE(pStmt);
|
||||||
|
if (NULL != pAnode) {
|
||||||
|
pStmt->anodeId = taosStr2Int32(pAnode->z, NULL, 10);
|
||||||
|
} else {
|
||||||
|
pStmt->anodeId = -1;
|
||||||
|
}
|
||||||
|
return (SNode*)pStmt;
|
||||||
|
_err:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* createUpdateAnodeStmt(SAstCreateContext* pCxt, const SToken* pAnode, bool updateAll) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
SUpdateAnodeStmt* pStmt = NULL;
|
||||||
|
pCxt->errCode = nodesMakeNode(QUERY_NODE_UPDATE_ANODE_STMT, (SNode**)&pStmt);
|
||||||
|
CHECK_MAKE_NODE(pStmt);
|
||||||
|
if (NULL != pAnode) {
|
||||||
|
pStmt->anodeId = taosStr2Int32(pAnode->z, NULL, 10);
|
||||||
|
} else {
|
||||||
|
pStmt->anodeId = -1;
|
||||||
|
}
|
||||||
|
return (SNode*)pStmt;
|
||||||
|
_err:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createEncryptKeyStmt(SAstCreateContext* pCxt, const SToken* pValue) {
|
SNode* createEncryptKeyStmt(SAstCreateContext* pCxt, const SToken* pValue) {
|
||||||
SToken config;
|
SToken config;
|
||||||
config.type = TK_NK_STRING;
|
config.type = TK_NK_STRING;
|
||||||
|
|
|
@ -555,6 +555,22 @@ static int32_t collectMetaKeyFromShowSnodes(SCollectMetaKeyCxt* pCxt, SShowStmt*
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t collectMetaKeyFromShowAnodes(SCollectMetaKeyCxt* pCxt, SShowStmt* pStmt) {
|
||||||
|
if (pCxt->pParseCxt->enableSysInfo) {
|
||||||
|
return reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_ANODES,
|
||||||
|
pCxt->pMetaCache);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t collectMetaKeyFromShowAnodesFull(SCollectMetaKeyCxt* pCxt, SShowStmt* pStmt) {
|
||||||
|
if (pCxt->pParseCxt->enableSysInfo) {
|
||||||
|
return reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_ANODES_FULL,
|
||||||
|
pCxt->pMetaCache);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t collectMetaKeyFromShowBnodes(SCollectMetaKeyCxt* pCxt, SShowStmt* pStmt) {
|
static int32_t collectMetaKeyFromShowBnodes(SCollectMetaKeyCxt* pCxt, SShowStmt* pStmt) {
|
||||||
if (pCxt->pParseCxt->enableSysInfo) {
|
if (pCxt->pParseCxt->enableSysInfo) {
|
||||||
return reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_BNODES,
|
return reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_BNODES,
|
||||||
|
@ -983,6 +999,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
||||||
return collectMetaKeyFromShowQnodes(pCxt, (SShowStmt*)pStmt);
|
return collectMetaKeyFromShowQnodes(pCxt, (SShowStmt*)pStmt);
|
||||||
case QUERY_NODE_SHOW_SNODES_STMT:
|
case QUERY_NODE_SHOW_SNODES_STMT:
|
||||||
return collectMetaKeyFromShowSnodes(pCxt, (SShowStmt*)pStmt);
|
return collectMetaKeyFromShowSnodes(pCxt, (SShowStmt*)pStmt);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
return collectMetaKeyFromShowAnodes(pCxt, (SShowStmt*)pStmt);
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
|
return collectMetaKeyFromShowAnodesFull(pCxt, (SShowStmt*)pStmt);
|
||||||
case QUERY_NODE_SHOW_BNODES_STMT:
|
case QUERY_NODE_SHOW_BNODES_STMT:
|
||||||
return collectMetaKeyFromShowBnodes(pCxt, (SShowStmt*)pStmt);
|
return collectMetaKeyFromShowBnodes(pCxt, (SShowStmt*)pStmt);
|
||||||
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
case QUERY_NODE_SHOW_ARBGROUPS_STMT:
|
||||||
|
|
|
@ -358,6 +358,8 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
|
||||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_MODULES_STMT:
|
case QUERY_NODE_SHOW_MODULES_STMT:
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
case QUERY_NODE_SHOW_SNODES_STMT:
|
case QUERY_NODE_SHOW_SNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_BNODES_STMT:
|
case QUERY_NODE_SHOW_BNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
case QUERY_NODE_SHOW_CLUSTER_STMT:
|
||||||
|
|
|
@ -38,6 +38,9 @@ static SKeyword keywordTable[] = {
|
||||||
{"ANALYZE", TK_ANALYZE},
|
{"ANALYZE", TK_ANALYZE},
|
||||||
{"AND", TK_AND},
|
{"AND", TK_AND},
|
||||||
{"ANTI", TK_ANTI},
|
{"ANTI", TK_ANTI},
|
||||||
|
{"ANODE", TK_ANODE},
|
||||||
|
{"ANODES", TK_ANODES},
|
||||||
|
{"ANOMALY_WINDOW", TK_ANOMALY_WINDOW},
|
||||||
// {"ANY", TK_ANY},
|
// {"ANY", TK_ANY},
|
||||||
{"APPS", TK_APPS},
|
{"APPS", TK_APPS},
|
||||||
{"AS", TK_AS},
|
{"AS", TK_AS},
|
||||||
|
@ -332,6 +335,9 @@ static SKeyword keywordTable[] = {
|
||||||
{"_WDURATION", TK_WDURATION},
|
{"_WDURATION", TK_WDURATION},
|
||||||
{"_WEND", TK_WEND},
|
{"_WEND", TK_WEND},
|
||||||
{"_WSTART", TK_WSTART},
|
{"_WSTART", TK_WSTART},
|
||||||
|
{"_FLOW", TK_FLOW},
|
||||||
|
{"_FHIGH", TK_FHIGH},
|
||||||
|
{"_FROWTS", TK_FROWTS},
|
||||||
{"ALIVE", TK_ALIVE},
|
{"ALIVE", TK_ALIVE},
|
||||||
{"VARBINARY", TK_VARBINARY},
|
{"VARBINARY", TK_VARBINARY},
|
||||||
{"S3_CHUNKSIZE", TK_S3_CHUNKSIZE},
|
{"S3_CHUNKSIZE", TK_S3_CHUNKSIZE},
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "parUtil.h"
|
#include "parUtil.h"
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
#include "systable.h"
|
#include "systable.h"
|
||||||
|
#include "tanal.h"
|
||||||
#include "tcol.h"
|
#include "tcol.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
@ -348,6 +349,20 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = {
|
||||||
.numOfShowCols = 1,
|
.numOfShowCols = 1,
|
||||||
.pShowCols = {"*"}
|
.pShowCols = {"*"}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.showType = QUERY_NODE_SHOW_ANODES_STMT,
|
||||||
|
.pDbName = TSDB_INFORMATION_SCHEMA_DB,
|
||||||
|
.pTableName = TSDB_INS_TABLE_ANODES,
|
||||||
|
.numOfShowCols = 1,
|
||||||
|
.pShowCols = {"*"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.showType = QUERY_NODE_SHOW_ANODES_FULL_STMT,
|
||||||
|
.pDbName = TSDB_INFORMATION_SCHEMA_DB,
|
||||||
|
.pTableName = TSDB_INS_TABLE_ANODES_FULL,
|
||||||
|
.numOfShowCols = 1,
|
||||||
|
.pShowCols = {"*"}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -1035,6 +1050,14 @@ static bool isInterpPseudoColumnFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsInterpPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsInterpPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isForecastFunc(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsForecastFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isForecastPseudoColumnFunc(const SNode* pNode) {
|
||||||
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsForecastPseudoColumnFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BUILD_NO_CALL
|
#ifdef BUILD_NO_CALL
|
||||||
static bool isTimelineFunc(const SNode* pNode) {
|
static bool isTimelineFunc(const SNode* pNode) {
|
||||||
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
return (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsTimelineFunc(((SFunctionNode*)pNode)->funcId));
|
||||||
|
@ -1237,7 +1260,7 @@ bool isPrimaryKeyImpl(SNode* pExpr) {
|
||||||
FUNCTION_TYPE_LAST_ROW == pFunc->funcType || FUNCTION_TYPE_TIMETRUNCATE == pFunc->funcType) {
|
FUNCTION_TYPE_LAST_ROW == pFunc->funcType || FUNCTION_TYPE_TIMETRUNCATE == pFunc->funcType) {
|
||||||
return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0));
|
return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0));
|
||||||
} else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType ||
|
} else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType ||
|
||||||
FUNCTION_TYPE_IROWTS == pFunc->funcType) {
|
FUNCTION_TYPE_IROWTS == pFunc->funcType || FUNCTION_TYPE_FORECAST_ROWTS == pFunc->funcType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) {
|
} else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) {
|
||||||
|
@ -2250,7 +2273,7 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
||||||
|
|
||||||
static EDealRes haveVectorFunction(SNode* pNode, void* pContext) {
|
static EDealRes haveVectorFunction(SNode* pNode, void* pContext) {
|
||||||
if (isAggFunc(pNode) || isIndefiniteRowsFunc(pNode) || isWindowPseudoColumnFunc(pNode) ||
|
if (isAggFunc(pNode) || isIndefiniteRowsFunc(pNode) || isWindowPseudoColumnFunc(pNode) ||
|
||||||
isInterpPseudoColumnFunc(pNode)) {
|
isInterpPseudoColumnFunc(pNode) || isForecastPseudoColumnFunc(pNode)) {
|
||||||
*((bool*)pContext) = true;
|
*((bool*)pContext) = true;
|
||||||
return DEAL_RES_END;
|
return DEAL_RES_END;
|
||||||
}
|
}
|
||||||
|
@ -2553,6 +2576,72 @@ static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode**
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateForecastFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||||
|
if (!fmIsForecastFunc(pFunc->funcId)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
|
}
|
||||||
|
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||||
|
SNode* pTable = pSelect->pFromTable;
|
||||||
|
|
||||||
|
if (pSelect->hasAggFuncs || pSelect->hasMultiRowsFunc || pSelect->hasIndefiniteRowsFunc) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSelect->hasForecastFunc &&
|
||||||
|
(FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc))) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"%s ignoring null value options cannot be used when applying to multiple columns",
|
||||||
|
pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"%s function is not supported in window query or group query", pFunc->functionName);
|
||||||
|
}
|
||||||
|
if (hasInvalidFuncNesting(pFunc->pParameterList)) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateForecastPseudoColumnFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRewriteToColumn) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)(*ppNode);
|
||||||
|
if (!fmIsForecastPseudoColumnFunc(pFunc->funcId)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
if (!isSelectStmt(pCxt->pCurrStmt)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"%s must be used in select statements", pFunc->functionName);
|
||||||
|
}
|
||||||
|
if (pCxt->currClause == SQL_CLAUSE_WHERE) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE,
|
||||||
|
"%s is not allowed in where clause", pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
bool bFound = false;
|
||||||
|
FOREACH(pNode, pSelect->pProjectionList) {
|
||||||
|
if (nodeType(pNode) == QUERY_NODE_FUNCTION && strcasecmp(((SFunctionNode*)pNode)->functionName, "forecast") == 0) {
|
||||||
|
bFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bFound) {
|
||||||
|
*pRewriteToColumn = true;
|
||||||
|
int32_t code = replacePsedudoColumnFuncWithColumn(pCxt, ppNode);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
(void)translateColumn(pCxt, (SColumnNode**)ppNode);
|
||||||
|
return pCxt->errCode;
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||||
if (!fmIsTimelineFunc(pFunc->funcId)) {
|
if (!fmIsTimelineFunc(pFunc->funcId)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2738,7 +2827,9 @@ static void setFuncClassification(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
||||||
} else if (fmIsInterpFunc(pFunc->funcId)) {
|
} else if (fmIsInterpFunc(pFunc->funcId)) {
|
||||||
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
||||||
}
|
} else if (fmIsForecastFunc(pFunc->funcId)) {
|
||||||
|
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
||||||
|
}
|
||||||
if (fmIsProcessByRowFunc(pFunc->funcId)) {
|
if (fmIsProcessByRowFunc(pFunc->funcId)) {
|
||||||
pSelect->lastProcessByRowFuncId = pFunc->funcId;
|
pSelect->lastProcessByRowFuncId = pFunc->funcId;
|
||||||
}
|
}
|
||||||
|
@ -2758,6 +2849,9 @@ static void setFuncClassification(STranslateContext* pCxt, SFunctionNode* pFunc)
|
||||||
FUNCTION_TYPE_ELAPSED == pFunc->funcType);
|
FUNCTION_TYPE_ELAPSED == pFunc->funcType);
|
||||||
pSelect->hasInterpPseudoColFunc =
|
pSelect->hasInterpPseudoColFunc =
|
||||||
pSelect->hasInterpPseudoColFunc ? true : fmIsInterpPseudoColumnFunc(pFunc->funcId);
|
pSelect->hasInterpPseudoColFunc ? true : fmIsInterpPseudoColumnFunc(pFunc->funcId);
|
||||||
|
pSelect->hasForecastFunc = pSelect->hasForecastFunc ? true : (FUNCTION_TYPE_FORECAST == pFunc->funcType);
|
||||||
|
pSelect->hasForecastPseudoColFunc =
|
||||||
|
pSelect->hasForecastPseudoColFunc ? true : fmIsForecastPseudoColumnFunc(pFunc->funcId);
|
||||||
pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
|
pSelect->hasLastRowFunc = pSelect->hasLastRowFunc ? true : (FUNCTION_TYPE_LAST_ROW == pFunc->funcType);
|
||||||
pSelect->hasLastFunc = pSelect->hasLastFunc ? true : (FUNCTION_TYPE_LAST == pFunc->funcType);
|
pSelect->hasLastFunc = pSelect->hasLastFunc ? true : (FUNCTION_TYPE_LAST == pFunc->funcType);
|
||||||
pSelect->hasTimeLineFunc = pSelect->hasTimeLineFunc ? true : fmIsTimelineFunc(pFunc->funcId);
|
pSelect->hasTimeLineFunc = pSelect->hasTimeLineFunc ? true : fmIsTimelineFunc(pFunc->funcId);
|
||||||
|
@ -2949,6 +3043,9 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SNode** pp
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (0 == LIST_LENGTH(pFunc->pParameterList)) {
|
if (0 == LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
|
if (pFunc->funcType == FUNCTION_TYPE_FORECAST_LOW || pFunc->funcType == FUNCTION_TYPE_FORECAST_HIGH) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
|
if (!isSelectStmt(pCxt->pCurrStmt) || NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME);
|
||||||
}
|
}
|
||||||
|
@ -3019,6 +3116,16 @@ static int32_t translateNormalFunction(STranslateContext* pCxt, SNode** ppNode)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = translateForecastFunc(pCxt, pFunc);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
bool bRewriteToColumn = false;
|
||||||
|
code = translateForecastPseudoColumnFunc(pCxt, ppNode, &bRewriteToColumn);
|
||||||
|
if (bRewriteToColumn) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateTimelineFunc(pCxt, pFunc);
|
code = translateTimelineFunc(pCxt, pFunc);
|
||||||
}
|
}
|
||||||
|
@ -3762,7 +3869,8 @@ static int32_t resetSelectFuncNumWithoutDup(SSelectStmt* pSelect) {
|
||||||
|
|
||||||
static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow || isWindowJoinStmt(pSelect) ||
|
if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow || isWindowJoinStmt(pSelect) ||
|
||||||
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
|
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc &&
|
||||||
|
!pSelect->hasForecastFunc)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (!pSelect->onlyHasKeepOrderFunc) {
|
if (!pSelect->onlyHasKeepOrderFunc) {
|
||||||
|
@ -3785,7 +3893,7 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
|
|
||||||
static int32_t checkWinJoinAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t checkWinJoinAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
if (!isWindowJoinStmt(pSelect) || (!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc &&
|
if (!isWindowJoinStmt(pSelect) || (!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc &&
|
||||||
!pSelect->hasInterpFunc)) {
|
!pSelect->hasInterpFunc && !pSelect->hasForecastFunc)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (!pSelect->onlyHasKeepOrderFunc) {
|
if (!pSelect->onlyHasKeepOrderFunc) {
|
||||||
|
@ -5798,6 +5906,40 @@ static int32_t translateCountWindow(STranslateContext* pCxt, SSelectStmt* pSelec
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t checkAnomalyExpr(STranslateContext* pCxt, SNode* pNode) {
|
||||||
|
int32_t type = ((SExprNode*)pNode)->resType.type;
|
||||||
|
if (!IS_MATHABLE_TYPE(type)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ANOMALY_WIN_TYPE,
|
||||||
|
"ANOMALY_WINDOW only support mathable column");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TAG == ((SColumnNode*)pNode)->colType) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ANOMALY_WIN_COL,
|
||||||
|
"ANOMALY_WINDOW not support on tag column");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateAnomalyWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
if (QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||||
|
!isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_QUERY,
|
||||||
|
"ANOMALY_WINDOW requires valid time series input");
|
||||||
|
}
|
||||||
|
|
||||||
|
SAnomalyWindowNode* pAnomaly = (SAnomalyWindowNode*)pSelect->pWindow;
|
||||||
|
int32_t code = checkAnomalyExpr(pCxt, pAnomaly->pExpr);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if (!taosAnalGetOptStr(pAnomaly->anomalyOpt, "algo", NULL, 0) != 0) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ANOMALY_WIN_OPT,
|
||||||
|
"ANOMALY_WINDOW option should include algo field");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
switch (nodeType(pSelect->pWindow)) {
|
switch (nodeType(pSelect->pWindow)) {
|
||||||
case QUERY_NODE_STATE_WINDOW:
|
case QUERY_NODE_STATE_WINDOW:
|
||||||
|
@ -5810,6 +5952,8 @@ static int32_t translateSpecificWindow(STranslateContext* pCxt, SSelectStmt* pSe
|
||||||
return translateEventWindow(pCxt, pSelect);
|
return translateEventWindow(pCxt, pSelect);
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
return translateCountWindow(pCxt, pSelect);
|
return translateCountWindow(pCxt, pSelect);
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
return translateAnomalyWindow(pCxt, pSelect);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6058,6 +6202,26 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateForecast(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
if (!pSelect->hasForecastFunc) {
|
||||||
|
if (pSelect->hasForecastPseudoColFunc) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
|
"Has Forecast pseudo column(s) but missing forcast function");
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((NULL != pSelect->pFromTable) && (QUERY_NODE_JOIN_TABLE == nodeType(pSelect->pFromTable))) {
|
||||||
|
SJoinTableNode* pJoinTable = (SJoinTableNode*)pSelect->pFromTable;
|
||||||
|
if (IS_WINDOW_JOIN(pJoinTable->subType)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FORECAST_CLAUSE,
|
||||||
|
"Forecast not supported to be used in WINDOW join");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t removeConstantValueFromList(SNodeList** pList) {
|
static int32_t removeConstantValueFromList(SNodeList** pList) {
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
WHERE_EACH(pNode, *pList) {
|
WHERE_EACH(pNode, *pList) {
|
||||||
|
@ -6899,6 +7063,9 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateInterp(pCxt, pSelect);
|
code = translateInterp(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = translateForecast(pCxt, pSelect);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = appendTsForImplicitTsFunc(pCxt, pSelect);
|
code = appendTsForImplicitTsFunc(pCxt, pSelect);
|
||||||
}
|
}
|
||||||
|
@ -7910,6 +8077,19 @@ static int32_t fillCmdSql(STranslateContext* pCxt, int16_t msgType, void* pReq)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TDMT_MND_CREATE_ANODE: {
|
||||||
|
FILL_CMD_SQL(sql, sqlLen, pCmdReq, SMCreateAnodeReq, pReq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TDMT_MND_DROP_ANODE: {
|
||||||
|
FILL_CMD_SQL(sql, sqlLen, pCmdReq, SMDropAnodeReq, pReq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TDMT_MND_UPDATE_ANODE: {
|
||||||
|
FILL_CMD_SQL(sql, sqlLen, pCmdReq, SMUpdateAnodeReq, pReq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TDMT_MND_CREATE_MNODE: {
|
case TDMT_MND_CREATE_MNODE: {
|
||||||
FILL_CMD_SQL(sql, sqlLen, pCmdReq, SMCreateMnodeReq, pReq);
|
FILL_CMD_SQL(sql, sqlLen, pCmdReq, SMCreateMnodeReq, pReq);
|
||||||
break;
|
break;
|
||||||
|
@ -9413,6 +9593,43 @@ static int32_t translateDropUser(STranslateContext* pCxt, SDropUserStmt* pStmt)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateCreateAnode(STranslateContext* pCxt, SCreateAnodeStmt* pStmt) {
|
||||||
|
SMCreateAnodeReq createReq = {0};
|
||||||
|
createReq.urlLen = strlen(pStmt->url) + 1;
|
||||||
|
if (createReq.urlLen > TSDB_ANAL_ANODE_URL_LEN) {
|
||||||
|
return TSDB_CODE_MND_ANODE_TOO_LONG_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
createReq.url = taosMemoryCalloc(createReq.urlLen, 1);
|
||||||
|
if (createReq.url == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
tstrncpy(createReq.url, pStmt->url, createReq.urlLen);
|
||||||
|
|
||||||
|
int32_t code = buildCmdMsg(pCxt, TDMT_MND_CREATE_ANODE, (FSerializeFunc)tSerializeSMCreateAnodeReq, &createReq);
|
||||||
|
tFreeSMCreateAnodeReq(&createReq);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateDropAnode(STranslateContext* pCxt, SDropAnodeStmt* pStmt) {
|
||||||
|
SMDropAnodeReq dropReq = {0};
|
||||||
|
dropReq.anodeId = pStmt->anodeId;
|
||||||
|
|
||||||
|
int32_t code = buildCmdMsg(pCxt, TDMT_MND_DROP_ANODE, (FSerializeFunc)tSerializeSMDropAnodeReq, &dropReq);
|
||||||
|
tFreeSMDropAnodeReq(&dropReq);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateUpdateAnode(STranslateContext* pCxt, SUpdateAnodeStmt* pStmt) {
|
||||||
|
SMUpdateAnodeReq updateReq = {0};
|
||||||
|
updateReq.anodeId = pStmt->anodeId;
|
||||||
|
|
||||||
|
int32_t code = buildCmdMsg(pCxt, TDMT_MND_UPDATE_ANODE, (FSerializeFunc)tSerializeSMUpdateAnodeReq, &updateReq);
|
||||||
|
tFreeSMUpdateAnodeReq(&updateReq);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateCreateDnode(STranslateContext* pCxt, SCreateDnodeStmt* pStmt) {
|
static int32_t translateCreateDnode(STranslateContext* pCxt, SCreateDnodeStmt* pStmt) {
|
||||||
SCreateDnodeReq createReq = {0};
|
SCreateDnodeReq createReq = {0};
|
||||||
strcpy(createReq.fqdn, pStmt->fqdn);
|
strcpy(createReq.fqdn, pStmt->fqdn);
|
||||||
|
@ -9835,7 +10052,7 @@ static int32_t translateDropComponentNode(STranslateContext* pCxt, SDropComponen
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t checkTopicQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t checkTopicQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
if (pSelect->hasAggFuncs || pSelect->hasInterpFunc || pSelect->hasIndefiniteRowsFunc) {
|
if (pSelect->hasAggFuncs || pSelect->hasForecastFunc || pSelect->hasInterpFunc || pSelect->hasIndefiniteRowsFunc) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TOPIC_QUERY);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TOPIC_QUERY);
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -10201,7 +10418,7 @@ static int32_t translateKillTransaction(STranslateContext* pCxt, SKillStmt* pStm
|
||||||
|
|
||||||
static bool crossTableWithoutAggOper(SSelectStmt* pSelect) {
|
static bool crossTableWithoutAggOper(SSelectStmt* pSelect) {
|
||||||
return NULL == pSelect->pWindow && !pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc &&
|
return NULL == pSelect->pWindow && !pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc &&
|
||||||
!pSelect->hasInterpFunc &&
|
!pSelect->hasInterpFunc && !pSelect->hasForecastFunc &&
|
||||||
TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType &&
|
TSDB_SUPER_TABLE == ((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType &&
|
||||||
!hasTbnameFunction(pSelect->pPartitionByList);
|
!hasTbnameFunction(pSelect->pPartitionByList);
|
||||||
}
|
}
|
||||||
|
@ -12545,6 +12762,15 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
||||||
case QUERY_NODE_ALTER_DNODE_STMT:
|
case QUERY_NODE_ALTER_DNODE_STMT:
|
||||||
code = translateAlterDnode(pCxt, (SAlterDnodeStmt*)pNode);
|
code = translateAlterDnode(pCxt, (SAlterDnodeStmt*)pNode);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_CREATE_ANODE_STMT:
|
||||||
|
code = translateCreateAnode(pCxt, (SCreateAnodeStmt*)pNode);
|
||||||
|
break;
|
||||||
|
case QUERY_NODE_DROP_ANODE_STMT:
|
||||||
|
code = translateDropAnode(pCxt, (SDropAnodeStmt*)pNode);
|
||||||
|
break;
|
||||||
|
case QUERY_NODE_UPDATE_ANODE_STMT:
|
||||||
|
code = translateUpdateAnode(pCxt, (SUpdateAnodeStmt*)pNode);
|
||||||
|
break;
|
||||||
case QUERY_NODE_CREATE_INDEX_STMT:
|
case QUERY_NODE_CREATE_INDEX_STMT:
|
||||||
code = translateCreateIndex(pCxt, (SCreateIndexStmt*)pNode);
|
code = translateCreateIndex(pCxt, (SCreateIndexStmt*)pNode);
|
||||||
break;
|
break;
|
||||||
|
@ -15905,6 +16131,8 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||||
case QUERY_NODE_SHOW_MODULES_STMT:
|
case QUERY_NODE_SHOW_MODULES_STMT:
|
||||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_STMT:
|
||||||
|
case QUERY_NODE_SHOW_ANODES_FULL_STMT:
|
||||||
case QUERY_NODE_SHOW_FUNCTIONS_STMT:
|
case QUERY_NODE_SHOW_FUNCTIONS_STMT:
|
||||||
case QUERY_NODE_SHOW_INDEXES_STMT:
|
case QUERY_NODE_SHOW_INDEXES_STMT:
|
||||||
case QUERY_NODE_SHOW_STREAMS_STMT:
|
case QUERY_NODE_SHOW_STREAMS_STMT:
|
||||||
|
|
|
@ -185,6 +185,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
return "%s is not supported in system table query";
|
return "%s is not supported in system table query";
|
||||||
case TSDB_CODE_PAR_INVALID_INTERP_CLAUSE:
|
case TSDB_CODE_PAR_INVALID_INTERP_CLAUSE:
|
||||||
return "Invalid usage of RANGE clause, EVERY clause or FILL clause";
|
return "Invalid usage of RANGE clause, EVERY clause or FILL clause";
|
||||||
|
case TSDB_CODE_PAR_INVALID_FORECAST_CLAUSE:
|
||||||
|
return "Invalid usage of forecast clause";
|
||||||
case TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN:
|
case TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN:
|
||||||
return "No valid function in window query";
|
return "No valid function in window query";
|
||||||
case TSDB_CODE_PAR_INVALID_OPTR_USAGE:
|
case TSDB_CODE_PAR_INVALID_OPTR_USAGE:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -988,6 +988,45 @@ static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isForecastFunc(int32_t funcId) {
|
||||||
|
return fmIsForecastFunc(funcId) || fmIsForecastPseudoColumnFunc(funcId) || fmIsGroupKeyFunc(funcId) || fmisSelectGroupConstValueFunc(funcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createForecastFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
if (!pSelect->hasForecastFunc) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SForecastFuncLogicNode* pForecastFunc = NULL;
|
||||||
|
int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC, (SNode**)&pForecastFunc);
|
||||||
|
if (NULL == pForecastFunc) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
pForecastFunc->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||||
|
pForecastFunc->node.requireDataOrder = getRequireDataOrder(true, pSelect);
|
||||||
|
pForecastFunc->node.resultDataOrder = pForecastFunc->node.requireDataOrder;
|
||||||
|
|
||||||
|
// interp functions and _group_key functions
|
||||||
|
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, NULL, isForecastFunc, &pForecastFunc->pFuncs);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = rewriteExprsForSelect(pForecastFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the output
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createColumnByRewriteExprs(pForecastFunc->pFuncs, &pForecastFunc->node.pTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
*pLogicNode = (SLogicNode*)pForecastFunc;
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pForecastFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
|
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
|
||||||
SLogicNode** pLogicNode) {
|
SLogicNode** pLogicNode) {
|
||||||
if (pCxt->pPlanCxt->streamQuery) {
|
if (pCxt->pPlanCxt->streamQuery) {
|
||||||
|
@ -1189,6 +1228,48 @@ static int32_t createWindowLogicNodeByCount(SLogicPlanContext* pCxt, SCountWindo
|
||||||
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createWindowLogicNodeByAnomaly(SLogicPlanContext* pCxt, SAnomalyWindowNode* pAnomaly,
|
||||||
|
SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
SWindowLogicNode* pWindow = NULL;
|
||||||
|
int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW, (SNode**)&pWindow);
|
||||||
|
if (NULL == pWindow) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
pWindow->winType = WINDOW_TYPE_ANOMALY;
|
||||||
|
pWindow->node.groupAction = getGroupAction(pCxt, pSelect);
|
||||||
|
pWindow->node.requireDataOrder =
|
||||||
|
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_IN_BLOCK : getRequireDataOrder(true, pSelect);
|
||||||
|
pWindow->node.resultDataOrder =
|
||||||
|
pCxt->pPlanCxt->streamQuery ? DATA_ORDER_LEVEL_GLOBAL : pWindow->node.requireDataOrder;
|
||||||
|
|
||||||
|
pWindow->pAnomalyExpr = NULL;
|
||||||
|
code = nodesCloneNode(pAnomaly->pExpr, &pWindow->pAnomalyExpr);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
nodesDestroyNode((SNode*)pWindow);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
tstrncpy(pWindow->anomalyOpt, pAnomaly->anomalyOpt, sizeof(pWindow->anomalyOpt));
|
||||||
|
|
||||||
|
pWindow->pTspk = NULL;
|
||||||
|
code = nodesCloneNode(pAnomaly->pCol, &pWindow->pTspk);
|
||||||
|
if (NULL == pWindow->pTspk) {
|
||||||
|
nodesDestroyNode((SNode*)pWindow);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite the expression in subsequent clauses
|
||||||
|
code = rewriteExprForSelect(pWindow->pAnomalyExpr, pSelect, SQL_CLAUSE_WINDOW);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
|
||||||
|
} else {
|
||||||
|
nodesDestroyNode((SNode*)pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
if (NULL == pSelect->pWindow) {
|
if (NULL == pSelect->pWindow) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1204,6 +1285,8 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
||||||
return createWindowLogicNodeByEvent(pCxt, (SEventWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
return createWindowLogicNodeByEvent(pCxt, (SEventWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||||
case QUERY_NODE_COUNT_WINDOW:
|
case QUERY_NODE_COUNT_WINDOW:
|
||||||
return createWindowLogicNodeByCount(pCxt, (SCountWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
return createWindowLogicNodeByCount(pCxt, (SCountWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||||
|
case QUERY_NODE_ANOMALY_WINDOW:
|
||||||
|
return createWindowLogicNodeByAnomaly(pCxt, (SAnomalyWindowNode*)pSelect->pWindow, pSelect, pLogicNode);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1615,6 +1698,9 @@ static int32_t createSelectFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createSelectRootLogicNode(pCxt, pSelect, createInterpFuncLogicNode, &pRoot);
|
code = createSelectRootLogicNode(pCxt, pSelect, createInterpFuncLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createSelectRootLogicNode(pCxt, pSelect, createForecastFuncLogicNode, &pRoot);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2380,6 +2380,8 @@ static bool sortPriKeyOptHasUnsupportedPkFunc(SLogicNode* pLogicNode, EOrder sor
|
||||||
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
|
||||||
pFuncList = ((SInterpFuncLogicNode*)pLogicNode)->pFuncs;
|
pFuncList = ((SInterpFuncLogicNode*)pLogicNode)->pFuncs;
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
|
||||||
|
pFuncList = ((SForecastFuncLogicNode*)pLogicNode)->pFuncs;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue