You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hu...@apache.org on 2022/10/26 15:02:16 UTC
[iotdb] branch lmh/cqTest updated: fix
This is an automated email from the ASF dual-hosted git repository.
hui pushed a commit to branch lmh/cqTest
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/lmh/cqTest by this push:
new feb0656ee0 fix
feb0656ee0 is described below
commit feb0656ee0f09948680d12d46757c198095a853e
Author: liuminghui233 <54...@qq.com>
AuthorDate: Wed Oct 26 22:57:59 2022 +0800
fix
---
.../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 2 +-
.../org/apache/iotdb/db/it/cq/IoTDBCQExecIT.java | 34 +++--
.../java/org/apache/iotdb/db/it/cq/IoTDBCQIT.java | 152 +++++++++++++++++++--
.../config/executor/ClusterConfigTaskExecutor.java | 8 +-
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 3 +-
.../plan/statement/component/FillComponent.java | 12 ++
.../plan/statement/component/FromComponent.java | 12 ++
.../statement/component/GroupByLevelComponent.java | 17 +++
.../statement/component/GroupByTimeComponent.java | 35 +++++
.../plan/statement/component/HavingCondition.java | 4 +
.../plan/statement/component/IntoComponent.java | 12 ++
.../db/mpp/plan/statement/component/IntoItem.java | 15 ++
.../plan/statement/component/OrderByComponent.java | 12 ++
.../plan/statement/component/SelectComponent.java | 21 ++-
.../db/mpp/plan/statement/component/SortItem.java | 4 +
.../plan/statement/component/WhereCondition.java | 4 +
.../db/mpp/plan/statement/crud/QueryStatement.java | 57 +++++++-
.../mpp/plan/statement/literal/BooleanLiteral.java | 5 +
.../mpp/plan/statement/literal/DoubleLiteral.java | 5 +
.../db/mpp/plan/statement/literal/LongLiteral.java | 5 +
.../db/mpp/plan/statement/literal/NullLiteral.java | 5 +
.../mpp/plan/statement/literal/StringLiteral.java | 5 +
.../metadata/CreateContinuousQueryStatement.java | 57 +++++---
.../impl/DataNodeInternalRPCServiceImpl.java | 6 +-
24 files changed, 433 insertions(+), 59 deletions(-)
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 69f1e2677a..6a4d90583b 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -165,7 +165,7 @@ resampleClause
(EVERY everyInterval=DURATION_LITERAL)?
(FOR DURATION_LITERAL)?
(BOUNDARY boundaryTime=timeValue)?
- (RANGE startTimeOffset=DURATION_LITERAL (COMMA endTimeOffset=DURATION_LITERAL))?
+ (RANGE startTimeOffset=DURATION_LITERAL (COMMA endTimeOffset=DURATION_LITERAL)?)?
;
timeoutPolicyClause
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQExecIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQExecIT.java
index 5ba25c7cf7..48d1b404ff 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQExecIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQExecIT.java
@@ -91,9 +91,8 @@ public class IoTDBCQExecIT {
statement.execute(
"CREATE CONTINUOUS QUERY cq1\n"
+ "RESAMPLE EVERY 2s\n"
- + "BOUNDARY "
- + firstExecutionTime
- + " BEGIN \n"
+ + String.format("BOUNDARY %d\n", firstExecutionTime)
+ + "BEGIN \n"
+ " SELECT max_value(s1) \n"
+ " INTO root.sg.d1(s1_max)\n"
+ " FROM root.sg.d1\n"
@@ -168,10 +167,10 @@ public class IoTDBCQExecIT {
statement.execute(
"CREATE CONTINUOUS QUERY cq2\n"
- + "RESAMPLE RANGE 4s\n"
- + "BOUNDARY "
- + firstExecutionTime
- + " BEGIN \n"
+ + "RESAMPLE \n"
+ + String.format("BOUNDARY %d\n", firstExecutionTime)
+ + "RANGE 4s \n"
+ + "BEGIN \n"
+ " SELECT max_value(s1) \n"
+ " INTO root.sg.d2(s1_max)\n"
+ " FROM root.sg.d2\n"
@@ -246,10 +245,10 @@ public class IoTDBCQExecIT {
statement.execute(
"CREATE CONTINUOUS QUERY cq3\n"
- + "RESAMPLE EVERY 20s RANGE 40s\n"
- + "BOUNDARY "
- + firstExecutionTime
- + " BEGIN \n"
+ + "RESAMPLE EVERY 20s\n"
+ + String.format("BOUNDARY %d\n", firstExecutionTime)
+ + "RANGE 40s\n"
+ + "BEGIN \n"
+ " SELECT max_value(s1) \n"
+ " INTO root.sg.d3(s1_max)\n"
+ " FROM root.sg.d3\n"
@@ -330,10 +329,10 @@ public class IoTDBCQExecIT {
statement.execute(
"CREATE CONTINUOUS QUERY cq4\n"
- + "RESAMPLE EVERY 20s RANGE 20s, 10s\n"
- + "BOUNDARY "
- + firstExecutionTime
- + " BEGIN \n"
+ + "RESAMPLE EVERY 20s\n"
+ + String.format("BOUNDARY %d\n", firstExecutionTime)
+ + "RANGE 20s, 10s\n"
+ + "BEGIN \n"
+ " SELECT max_value(s1) \n"
+ " INTO root.sg.d4(s1_max)\n"
+ " FROM root.sg.d4\n"
@@ -407,9 +406,8 @@ public class IoTDBCQExecIT {
statement.execute(
"CREATE CONTINUOUS QUERY cq5\n"
+ "RESAMPLE EVERY 2s\n"
- + "BOUNDARY "
- + firstExecutionTime
- + " BEGIN \n"
+ + String.format("BOUNDARY %d\n", firstExecutionTime)
+ + "BEGIN \n"
+ " SELECT s1 + 1 \n"
+ " INTO root.sg.d5(precalculated_s1)\n"
+ " FROM root.sg.d5\n"
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQIT.java
index 69fdb1acc2..7910ffeae5 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/cq/IoTDBCQIT.java
@@ -33,6 +33,7 @@ import java.sql.ResultSet;
import java.sql.Statement;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@@ -120,7 +121,7 @@ public class IoTDBCQIT {
statement.execute(sql);
fail();
} catch (Exception e) {
- // assertEquals("500: CQ: The query body misses an INTO clause.", e.getMessage());
+ assertEquals("500: CQ: The query body misses an INTO clause.", e.getMessage());
}
// 5. EVERY interval is less than continuous_query_min_every_interval_in_ms in
@@ -157,8 +158,9 @@ public class IoTDBCQIT {
statement.execute(sql);
fail();
} catch (Exception e) {
- System.out.println(e.getMessage());
- // assertEquals("hh", e.getMessage());
+ assertEquals(
+ "401: Error occurred while parsing SQL to physical plan: line 2:15 extraneous input '-' expecting DURATION_LITERAL",
+ e.getMessage());
}
// 7. start_time_offset == 0
@@ -175,8 +177,7 @@ public class IoTDBCQIT {
statement.execute(sql);
fail();
} catch (Exception e) {
- System.out.println(e.getMessage());
- // assertEquals("hh", e.getMessage());
+ assertEquals("500: CQ: The start time offset should be greater than 0.", e.getMessage());
}
// 8. end_time_offset < 0
@@ -193,8 +194,9 @@ public class IoTDBCQIT {
statement.execute(sql);
fail();
} catch (Exception e) {
- System.out.println(e.getMessage());
- // assertEquals("hh", e.getMessage());
+ assertEquals(
+ "401: Error occurred while parsing SQL to physical plan: line 2:20 extraneous input '-' expecting DURATION_LITERAL",
+ e.getMessage());
}
// 9. end_time_offset == start_time_offset
@@ -249,8 +251,9 @@ public class IoTDBCQIT {
statement.execute(sql);
fail();
} catch (Exception e) {
- System.out.println(e.getMessage());
- // assertEquals("hh", e.getMessage());
+ assertEquals(
+ "500: CQ: The start time offset should be greater than or equal to every interval.",
+ e.getMessage());
}
// 12. TIMEOUT POLICY is not BLOCKED or DISCARD
@@ -269,7 +272,7 @@ public class IoTDBCQIT {
fail();
} catch (Exception e) {
assertEquals(
- "401: Error occurred while parsing SQL to physical plan: line 3:0 mismatched input 'TIMEOUT' expecting ','",
+ "401: Error occurred while parsing SQL to physical plan: line 3:15 mismatched input 'UNKNOWN' expecting {BLOCKED, DISCARD}",
e.getMessage());
}
@@ -290,6 +293,7 @@ public class IoTDBCQIT {
assertEquals("932: CQ s1_count_cq has already been created.", e.getMessage());
}
+ statement.execute("DROP CQ s1_count_cq;");
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -301,6 +305,7 @@ public class IoTDBCQIT {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
+ String[] cqIds = {"correct_cq_1", "correct_cq_2", "correct_cq_3", "s1_count_cq_correct"};
try {
String sql =
"CREATE CQ correct_cq_1 \n"
@@ -369,6 +374,10 @@ public class IoTDBCQIT {
e.printStackTrace();
fail(e.getMessage());
}
+
+ for (String cqId : cqIds) {
+ statement.execute(String.format("DROP CQ %s;", cqId));
+ }
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -421,6 +430,60 @@ public class IoTDBCQIT {
+ " GROUP BY(10m)\n"
+ "END"
};
+ String[] formattedCqSQLs = {
+ "CREATE CQ show_cq_1\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms, 600000ms\n"
+ + "TIMEOUT POLICY BLOCKED\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (1800000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ show_cq_2\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY BLOCKED\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (1800000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ show_cq_3\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 600000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY DISCARD\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (600000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ show_cq_4\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY DISCARD\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (600000ms)\n"
+ + "END\n"
+ + ";"
+ };
for (String sql : cqSQLs) {
statement.execute(sql);
@@ -432,13 +495,17 @@ public class IoTDBCQIT {
while (resultSet.next()) {
// No need to add time column for aggregation query
assertEquals(cqIds[cnt], resultSet.getString(1));
- assertEquals(cqSQLs[cnt], resultSet.getString(2));
+ assertEquals(formattedCqSQLs[cnt], resultSet.getString(2));
assertEquals("ACTIVE", resultSet.getString(3));
cnt++;
}
assertEquals(cqIds.length, cnt);
}
+ for (String cqId : cqIds) {
+ statement.execute(String.format("DROP CQ %s;", cqId));
+ }
+
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -491,6 +558,60 @@ public class IoTDBCQIT {
+ " GROUP BY(10m)\n"
+ "END"
};
+ String[] formattedCqSQLs = {
+ "CREATE CQ drop_cq_1\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms, 600000ms\n"
+ + "TIMEOUT POLICY BLOCKED\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (1800000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ drop_cq_2\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY BLOCKED\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (1800000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ drop_cq_3\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 600000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY DISCARD\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (600000ms)\n"
+ + "END\n"
+ + ";",
+ "CREATE CQ drop_cq_4\n"
+ + "RESAMPLE\n"
+ + "\tEVERY 1800000ms\n"
+ + "\tBOUNDARY 0\n"
+ + "\tRANGE 1800000ms\n"
+ + "TIMEOUT POLICY DISCARD\n"
+ + "BEGIN\n"
+ + "\tSELECT count(s1)\n"
+ + "\t\tINTO root.sg_count.d(count_s1)\n"
+ + "\t\tFROM root.sg.d\n"
+ + "\t\tGROUP BY TIME (600000ms)\n"
+ + "END\n"
+ + ";"
+ };
for (String sql : cqSQLs) {
statement.execute(sql);
@@ -502,7 +623,7 @@ public class IoTDBCQIT {
while (resultSet.next()) {
// No need to add time column for aggregation query
assertEquals(cqIds[cnt], resultSet.getString(1));
- assertEquals(cqSQLs[cnt], resultSet.getString(2));
+ assertEquals(formattedCqSQLs[cnt], resultSet.getString(2));
assertEquals("ACTIVE", resultSet.getString(3));
cnt++;
}
@@ -520,13 +641,18 @@ public class IoTDBCQIT {
while (resultSet.next()) {
// No need to add time column for aggregation query
assertEquals(cqIds[resultIndex[cnt]], resultSet.getString(1));
- assertEquals(cqSQLs[resultIndex[cnt]], resultSet.getString(2));
+ assertEquals(formattedCqSQLs[resultIndex[cnt]], resultSet.getString(2));
assertEquals("ACTIVE", resultSet.getString(3));
cnt++;
}
assertEquals(resultIndex.length, cnt);
}
+ statement.execute("DROP CQ drop_cq_1");
+ statement.execute("DROP CQ drop_cq_4");
+ try (ResultSet resultSet = statement.executeQuery("show CQS")) {
+ assertFalse(resultSet.next());
+ }
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index 7ed50ae64f..de49ae98ea 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -1277,6 +1277,10 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
public SettableFuture<ConfigTaskResult> createContinuousQuery(
CreateContinuousQueryStatement createContinuousQueryStatement) {
createContinuousQueryStatement.semanticCheck();
+
+ String queryBody = createContinuousQueryStatement.getQueryBody();
+ String sql = createContinuousQueryStatement.getSql();
+ // TODO Do not modify Statement in Analyzer
Analyzer.validate(createContinuousQueryStatement.getQueryBodyStatement());
SettableFuture<ConfigTaskResult> future = SettableFuture.create();
@@ -1290,8 +1294,8 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
createContinuousQueryStatement.getStartTimeOffset(),
createContinuousQueryStatement.getEndTimeOffset(),
createContinuousQueryStatement.getTimeoutPolicy().getType(),
- createContinuousQueryStatement.getQueryBody(),
- createContinuousQueryStatement.getSql(),
+ queryBody,
+ sql,
createContinuousQueryStatement.getZoneId());
final TSStatus executionStatus = client.createCQ(tCreateCQReq);
if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != executionStatus.getCode()) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 350d21c429..6cc2487146 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -804,10 +804,9 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
@Override
public Statement visitCreateContinuousQuery(IoTDBSqlParser.CreateContinuousQueryContext ctx) {
CreateContinuousQueryStatement statement = new CreateContinuousQueryStatement();
- statement.setSql(ctx.getText());
+
statement.setCqId(parseIdentifier(ctx.cqId.getText()));
- statement.setQueryBody(ctx.selectStatement().getText());
QueryStatement queryBodyStatement =
(QueryStatement) visitSelectStatement(ctx.selectStatement());
queryBodyStatement.setCqQueryBody(true);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FillComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FillComponent.java
index c1b29c1aff..74d3567e49 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FillComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FillComponent.java
@@ -45,4 +45,16 @@ public class FillComponent extends StatementNode {
public void setFillValue(Literal fillValue) {
this.fillValue = fillValue;
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("FILL(");
+ if (fillPolicy != FillPolicy.VALUE) {
+ sqlBuilder.append(fillPolicy.toString());
+ } else {
+ sqlBuilder.append(fillValue.toString());
+ }
+ sqlBuilder.append(')');
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FromComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FromComponent.java
index 9c0525c5ec..1bfd1b4df2 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FromComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/FromComponent.java
@@ -39,4 +39,16 @@ public class FromComponent extends StatementNode {
public List<PartialPath> getPrefixPaths() {
return prefixPaths;
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("FROM").append(' ');
+ for (int i = 0; i < prefixPaths.size(); i++) {
+ sqlBuilder.append(prefixPaths.get(i).toString());
+ if (i < prefixPaths.size() - 1) {
+ sqlBuilder.append(", ");
+ }
+ }
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByLevelComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByLevelComponent.java
index 4834b14758..4db718f90c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByLevelComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByLevelComponent.java
@@ -51,4 +51,21 @@ public class GroupByLevelComponent extends StatementNode {
public boolean isCountStar(int i) {
return isCountStar.get(i);
}
+
+ public String toSQLString(boolean hasGroupByTime) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ if (hasGroupByTime) {
+ sqlBuilder.append(", ");
+ } else {
+ sqlBuilder.append("GROUP BY ");
+ }
+ sqlBuilder.append("LEVEL = ");
+ for (int i = 0; i < levels.length; i++) {
+ sqlBuilder.append(levels[i]);
+ if (i < levels.length - 1) {
+ sqlBuilder.append(',').append(' ');
+ }
+ }
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByTimeComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByTimeComponent.java
index 9cc1d06341..d17a544fbf 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByTimeComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/GroupByTimeComponent.java
@@ -98,4 +98,39 @@ public class GroupByTimeComponent extends StatementNode {
public void setIntervalByMonth(boolean isIntervalByMonth) {
this.isIntervalByMonth = isIntervalByMonth;
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("GROUP BY TIME").append(' ');
+ sqlBuilder.append('(');
+ if (startTime != 0 || endTime != 0) {
+ if (isLeftCRightO()) {
+ sqlBuilder
+ .append('[')
+ .append(startTime)
+ .append(',')
+ .append(' ')
+ .append(endTime)
+ .append(')');
+ } else {
+ sqlBuilder
+ .append('(')
+ .append(startTime)
+ .append(',')
+ .append(' ')
+ .append(endTime)
+ .append(']');
+ }
+ sqlBuilder.append(',').append(' ');
+ }
+ String intervalStr = interval + (isIntervalByMonth ? "mo" : "ms");
+ String slidingStepStr = slidingStep + (isSlidingStepByMonth ? "mo" : "ms");
+ sqlBuilder.append(intervalStr);
+ if (!slidingStepStr.equals(intervalStr)) {
+ sqlBuilder.append(',').append(' ');
+ sqlBuilder.append(slidingStepStr);
+ }
+ sqlBuilder.append(')');
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/HavingCondition.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/HavingCondition.java
index cf76fd1c5c..7bfca1b88a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/HavingCondition.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/HavingCondition.java
@@ -42,4 +42,8 @@ public class HavingCondition extends StatementNode {
public void setPredicate(Expression predicate) {
this.predicate = ExpressionAnalyzer.removeAliasFromExpression(predicate);
}
+
+ public String toSQLString() {
+ return "HAVING " + predicate.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoComponent.java
index 9a4f9b7acd..c61684062e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoComponent.java
@@ -236,4 +236,16 @@ public class IntoComponent extends StatementNode {
return intoItems.get(deviceIndex).isAligned();
}
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("INTO ");
+ for (int i = 0; i < intoItems.size(); i++) {
+ sqlBuilder.append(intoItems.get(i).toSQLString());
+ if (i < intoItems.size() - 1) {
+ sqlBuilder.append(", ");
+ }
+ }
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoItem.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoItem.java
index 4efafe3cef..fb4da13874 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoItem.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/IntoItem.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.db.mpp.plan.statement.StatementNode;
import java.util.List;
import java.util.stream.Collectors;
+import static org.apache.commons.lang3.StringUtils.SPACE;
import static org.apache.iotdb.commons.conf.IoTDBConstant.DOUBLE_COLONS;
import static org.apache.iotdb.commons.conf.IoTDBConstant.LEVELED_PATH_TEMPLATE_PATTERN;
@@ -70,4 +71,18 @@ public class IntoItem extends StatementNode {
public List<PartialPath> getIntoPaths() {
return intoMeasurements.stream().map(intoDevice::concatNode).collect(Collectors.toList());
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append(intoDevice);
+ sqlBuilder.append('(');
+ for (int i = 0; i < intoMeasurements.size(); i++) {
+ sqlBuilder.append(intoMeasurements.get(i));
+ if (i < intoMeasurements.size() - 1) {
+ sqlBuilder.append(',').append(SPACE);
+ }
+ }
+ sqlBuilder.append(')');
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/OrderByComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/OrderByComponent.java
index 8b968408a2..3c1d10220a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/OrderByComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/OrderByComponent.java
@@ -89,4 +89,16 @@ public class OrderByComponent extends StatementNode {
checkState(timeOrderPriority != -1, "The device order is not specified.");
return sortItemList.get(deviceOrderPriority).getOrdering();
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("ORDER BY ");
+ for (int i = 0; i < sortItemList.size(); i++) {
+ sqlBuilder.append(sortItemList.get(i).toSQLString());
+ if (i < sortItemList.size() - 1) {
+ sqlBuilder.append(", ");
+ }
+ }
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SelectComponent.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SelectComponent.java
index cc92430f11..475b0a60a3 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SelectComponent.java
@@ -76,7 +76,7 @@ public class SelectComponent extends StatementNode {
this.aliasToColumnMap = aliasToColumnMap;
}
- public boolean isHasLast() {
+ public boolean hasLast() {
return hasLast;
}
@@ -87,4 +87,23 @@ public class SelectComponent extends StatementNode {
public void setHasBuiltInAggregationFunction(boolean hasBuiltInAggregationFunction) {
this.hasBuiltInAggregationFunction = hasBuiltInAggregationFunction;
}
+
+ public String toSQLString() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("SELECT").append(' ');
+ if (hasLast()) {
+ sqlBuilder.append("LAST").append(' ');
+ }
+ for (int i = 0; i < resultColumns.size(); i++) {
+ ResultColumn resultColumn = resultColumns.get(i);
+ sqlBuilder.append(resultColumn.getExpression().toString());
+ if (resultColumn.hasAlias()) {
+ sqlBuilder.append('(').append(resultColumn.getAlias()).append(')');
+ }
+ if (i < resultColumns.size() - 1) {
+ sqlBuilder.append(", ");
+ }
+ }
+ return sqlBuilder.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SortItem.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SortItem.java
index 41fc47dd47..71e169b22d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SortItem.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/SortItem.java
@@ -80,4 +80,8 @@ public class SortItem {
public int hashCode() {
return Objects.hash(sortKey, ordering);
}
+
+ public String toSQLString() {
+ return getSortKey().toString() + " " + getOrdering().toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/WhereCondition.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/WhereCondition.java
index 9014f345f7..8aa7eb04df 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/WhereCondition.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/component/WhereCondition.java
@@ -40,4 +40,8 @@ public class WhereCondition extends StatementNode {
public void setPredicate(Expression predicate) {
this.predicate = predicate;
}
+
+ public String toSQLString() {
+ return "WHERE " + predicate.toString();
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
index ab8fd370b1..c36680252c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
@@ -241,7 +241,7 @@ public class QueryStatement extends Statement {
}
public boolean isLastQuery() {
- return selectComponent.isHasLast();
+ return selectComponent.hasLast();
}
public boolean isAggregationQuery() {
@@ -306,6 +306,14 @@ public class QueryStatement extends Statement {
return orderByComponent.getSortItemList();
}
+ public boolean hasFill() {
+ return fillComponent != null;
+ }
+
+ public boolean hasOrderBy() {
+ return orderByComponent != null;
+ }
+
public boolean isSelectInto() {
return intoComponent != null;
}
@@ -444,6 +452,53 @@ public class QueryStatement extends Statement {
}
}
+ public String constructFormattedSQL() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append(selectComponent.toSQLString()).append("\n");
+ if (isSelectInto()) {
+ sqlBuilder.append("\t").append(intoComponent.toSQLString()).append("\n");
+ }
+ sqlBuilder.append("\t").append(fromComponent.toSQLString()).append("\n");
+ if (hasWhere()) {
+ sqlBuilder.append("\t").append(whereCondition.toSQLString()).append("\n");
+ }
+ if (isGroupByTime()) {
+ sqlBuilder.append("\t").append(groupByTimeComponent.toSQLString()).append("\n");
+ }
+ if (isGroupByLevel()) {
+ sqlBuilder
+ .append("\t")
+ .append(groupByLevelComponent.toSQLString(isGroupByTime()))
+ .append("\n");
+ }
+ if (hasHaving()) {
+ sqlBuilder.append("\t").append(havingCondition.toSQLString()).append("\n");
+ }
+ if (hasFill()) {
+ sqlBuilder.append("\t").append(fillComponent.toSQLString()).append("\n");
+ }
+ if (hasOrderBy()) {
+ sqlBuilder.append("\t").append(orderByComponent.toSQLString()).append("\n");
+ }
+ if (rowLimit != 0) {
+ sqlBuilder.append("\t").append("LIMIT").append(' ').append(rowLimit).append("\n");
+ }
+ if (rowOffset != 0) {
+ sqlBuilder.append("\t").append("OFFSET").append(' ').append(rowOffset).append("\n");
+ }
+ if (seriesLimit != 0) {
+ sqlBuilder.append("\t").append("SLIMIT").append(' ').append(seriesLimit).append("\n");
+ }
+ if (seriesOffset != 0) {
+ sqlBuilder.append("\t").append("SOFFSET").append(' ').append(seriesOffset).append("\n");
+ }
+ if (isAlignByDevice()) {
+ sqlBuilder.append("\t").append("ALIGN BY DEVICE").append("\n");
+ }
+ sqlBuilder.append(';');
+ return sqlBuilder.toString();
+ }
+
@Override
public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
return visitor.visitQuery(this, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/BooleanLiteral.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/BooleanLiteral.java
index 8cbe5db20f..1a4a97e9b2 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/BooleanLiteral.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/BooleanLiteral.java
@@ -88,4 +88,9 @@ public class BooleanLiteral extends Literal {
public Binary getBinary() {
return new Binary(String.valueOf(value));
}
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/DoubleLiteral.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/DoubleLiteral.java
index 868d87276a..9b247469e8 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/DoubleLiteral.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/DoubleLiteral.java
@@ -94,4 +94,9 @@ public class DoubleLiteral extends Literal {
public Binary getBinary() {
return new Binary(String.valueOf(value));
}
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/LongLiteral.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/LongLiteral.java
index c4ce4473b1..182a075a20 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/LongLiteral.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/LongLiteral.java
@@ -117,4 +117,9 @@ public class LongLiteral extends Literal {
public int hashCode() {
return Objects.hash(value);
}
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/NullLiteral.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/NullLiteral.java
index 51221a494a..ce2d4e0564 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/NullLiteral.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/NullLiteral.java
@@ -69,4 +69,9 @@ public class NullLiteral extends Literal {
public int hashCode() {
return getClass().hashCode();
}
+
+ @Override
+ public String toString() {
+ return "null";
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/StringLiteral.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/StringLiteral.java
index 118680ce47..fa220edf3a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/StringLiteral.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/literal/StringLiteral.java
@@ -82,4 +82,9 @@ public class StringLiteral extends Literal {
public int hashCode() {
return Objects.hash(value);
}
+
+ @Override
+ public String toString() {
+ return String.format("\"%s\"", value.replace("\"", "'"));
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateContinuousQueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateContinuousQueryStatement.java
index d8a73a3d0c..9aee94b8a3 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateContinuousQueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/CreateContinuousQueryStatement.java
@@ -37,7 +37,6 @@ import java.util.List;
public class CreateContinuousQueryStatement extends Statement implements IConfigStatement {
- private String sql;
private String cqId;
// The query execution time interval, default value is group_by_interval in group by clause.
@@ -56,22 +55,14 @@ public class CreateContinuousQueryStatement extends Statement implements IConfig
// while the next execution time has reached, default value is BLOCKED.
private TimeoutPolicy timeoutPolicy = TimeoutPolicy.BLOCKED;
- private String queryBody;
private QueryStatement queryBodyStatement;
+ private String queryBody;
public CreateContinuousQueryStatement() {
super();
statementType = StatementType.CREATE_CONTINUOUS_QUERY;
}
- public String getSql() {
- return sql;
- }
-
- public void setSql(String sql) {
- this.sql = sql;
- }
-
public String getCqId() {
return cqId;
}
@@ -120,14 +111,6 @@ public class CreateContinuousQueryStatement extends Statement implements IConfig
this.timeoutPolicy = timeoutPolicy;
}
- public String getQueryBody() {
- return queryBody;
- }
-
- public void setQueryBody(String queryBody) {
- this.queryBody = queryBody;
- }
-
public QueryStatement getQueryBodyStatement() {
return queryBodyStatement;
}
@@ -140,6 +123,41 @@ public class CreateContinuousQueryStatement extends Statement implements IConfig
return queryBodyStatement.getSelectComponent().getZoneId().getId();
}
+ public String getSql() {
+ return constructFormattedSQL();
+ }
+
+ public String getQueryBody() {
+ if (queryBody == null) {
+ queryBody = queryBodyStatement.constructFormattedSQL();
+ }
+ return queryBody;
+ }
+
+ public String constructFormattedSQL() {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("CREATE CQ ").append(cqId).append('\n');
+ sqlBuilder.append("RESAMPLE\n");
+ sqlBuilder.append('\t').append("EVERY ").append(everyInterval).append("ms\n");
+ sqlBuilder.append('\t').append("BOUNDARY ").append(boundaryTime).append("\n");
+ ;
+ sqlBuilder.append('\t').append("RANGE ").append(startTimeOffset).append("ms");
+ if (endTimeOffset != 0) {
+ sqlBuilder.append(", ").append(endTimeOffset).append("ms\n");
+ } else {
+ sqlBuilder.append("\n");
+ }
+ sqlBuilder.append("TIMEOUT POLICY ").append(timeoutPolicy.toString()).append('\n');
+ sqlBuilder.append("BEGIN\n");
+ String[] queryBodySlices = getQueryBody().split("\n");
+ for (int i = 0; i < queryBodySlices.length - 1; i++) { // skip ';' in queryBody
+ sqlBuilder.append('\t').append(queryBodySlices[i]).append('\n');
+ }
+ sqlBuilder.append("END\n");
+ sqlBuilder.append(";");
+ return sqlBuilder.toString();
+ }
+
@Override
public QueryType getQueryType() {
return QueryType.WRITE;
@@ -183,7 +201,8 @@ public class CreateContinuousQueryStatement extends Statement implements IConfig
throw new SemanticException("CQ: The query body misses an INTO clause.");
}
GroupByTimeComponent groupByTimeComponent = queryBodyStatement.getGroupByTimeComponent();
- if (groupByTimeComponent.getStartTime() != 0 || groupByTimeComponent.getEndTime() != 0) {
+ if (groupByTimeComponent != null
+ && (groupByTimeComponent.getStartTime() != 0 || groupByTimeComponent.getEndTime() != 0)) {
throw new SemanticException(
"CQ: Specifying time range in GROUP BY TIME clause is prohibited.");
}
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
index 55afe02880..b9e9b90ec1 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
@@ -752,6 +752,7 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
long sessionId =
SESSION_MANAGER.requestSessionId(req.cqId, req.zoneId, IoTDBConstant.ClientVersion.V_0_13);
+ String executedSQL = req.queryBody;
try {
QueryStatement s =
@@ -781,6 +782,7 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
s.getGroupByTimeComponent().setStartTime(req.startTime);
s.getGroupByTimeComponent().setEndTime(req.endTime);
}
+ executedSQL = String.join(" ", s.constructFormattedSQL().split("\n")).replaceAll(" +", " ");
QUERY_FREQUENCY_RECORDER.incrementAndGet();
@@ -792,7 +794,7 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
s,
queryId,
SESSION_MANAGER.getSessionInfo(sessionId),
- req.queryBody,
+ executedSQL,
PARTITION_FETCHER,
SCHEMA_FETCHER,
req.getTimeout());
@@ -818,7 +820,7 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
}
} catch (Exception e) {
// TODO call the coordinator to release query resource
- return onQueryException(e, "\"" + req.queryBody + "\". " + OperationType.EXECUTE_STATEMENT);
+ return onQueryException(e, "\"" + executedSQL + "\". " + OperationType.EXECUTE_STATEMENT);
} finally {
SESSION_MANAGER.releaseSessionResource(sessionId, this::cleanupQueryExecution);
SESSION_MANAGER.closeSession(sessionId);