You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2020/02/26 07:38:23 UTC
[incubator-iotdb] 01/02: add ut and it
This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch groupbyfill
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
commit 596533477fa622b6eb106c466d31b7a94881bde8
Author: JackieTien97 <Ja...@foxmail.com>
AuthorDate: Wed Feb 26 15:04:18 2020 +0800
add ut and it
---
.../org/apache/iotdb/db/qp/strategy/SqlBase.g4 | 4 +-
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 3 +-
.../iotdb/db/qp/logical/crud/SelectOperator.java | 5 +-
.../iotdb/db/qp/strategy/LogicalGenerator.java | 18 +-
.../iotdb/db/qp/strategy/PhysicalGenerator.java | 5 +
.../query/dataset/groupby/GroupByFillDataSet.java | 6 +-
.../apache/iotdb/db/query/fill/PreviousFill.java | 6 +-
.../org/apache/iotdb/db/service/TSServiceImpl.java | 1 +
.../iotdb/db/integration/IoTDBGroupByFillIT.java | 261 +++++++++++++++++++++
.../apache/iotdb/db/qp/plan/PhysicalPlanTest.java | 176 ++++++++++++--
10 files changed, 451 insertions(+), 34 deletions(-)
diff --git a/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4 b/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
index 2434075..9f0ad4e 100644
--- a/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
+++ b/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
@@ -210,7 +210,7 @@ groupByFillClause
timeInterval
COMMA DURATION
RR_BRACKET
- fillClause
+ FILL LR_BRACKET typeClause (COMMA typeClause)* RR_BRACKET
;
typeClause
@@ -228,7 +228,7 @@ previousClause
;
previousUntilLastClause
- : PREVIOUSUNTILLAST
+ : PREVIOUSUNTILLAST (COMMA DURATION)?
;
indexWithClause
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index e968e7f..30733fd 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -221,9 +221,10 @@ public class PlanExecutor implements IPlanExecutor {
} else {
if (queryPlan instanceof GroupByFillPlan) {
GroupByFillPlan groupByFillPlan = (GroupByFillPlan) queryPlan;
+ return queryRouter.groupByFill(groupByFillPlan, context);
} else if (queryPlan instanceof GroupByPlan) {
GroupByPlan groupByPlan = (GroupByPlan) queryPlan;
- return queryRouter.groupByFill(groupByPlan, context);
+ return queryRouter.groupBy(groupByPlan, context);
} else if (queryPlan instanceof AggregationPlan) {
AggregationPlan aggregationPlan = (AggregationPlan) queryPlan;
queryDataSet = queryRouter.aggregate(aggregationPlan, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java
index 902dc38..9308ef1 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectOperator.java
@@ -18,11 +18,12 @@
*/
package org.apache.iotdb.db.qp.logical.crud;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.tsfile.read.common.Path;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* this class maintains information from select clause.
*/
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
index 0180540..f52e546 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
@@ -570,9 +570,7 @@ public class LogicalGenerator extends SqlBaseBaseListener {
parseTimeInterval(ctx.timeInterval());
- FillClauseContext fillClauseContext = ctx.fillClause();
- super.enterFillClause(fillClauseContext);
- List<TypeClauseContext> list = fillClauseContext.typeClause();
+ List<TypeClauseContext> list = ctx.typeClause();
Map<TSDataType, IFill> fillTypes = new EnumMap<>(TSDataType.class);
for (TypeClauseContext typeClause : list) {
// group by fill doesn't support linear fill
@@ -580,8 +578,16 @@ public class LogicalGenerator extends SqlBaseBaseListener {
throw new SQLParserException("group by fill doesn't support linear fill");
}
// all type use the same fill way
- if (SQLConstant.ALL.equals(typeClause.dataType().getText())) {
-
+ if (SQLConstant.ALL.equals(typeClause.dataType().getText().toLowerCase())) {
+ IFill fill;
+ if (typeClause.previousUntilLastClause() != null) {
+ fill = new PreviousFill(-1, true);
+ } else {
+ fill = new PreviousFill(-1);
+ }
+ for (TSDataType tsDataType : TSDataType.values()) {
+ fillTypes.put(tsDataType, fill.copy());
+ }
break;
} else {
parseTypeClause(typeClause, fillTypes);
@@ -670,7 +676,7 @@ public class LogicalGenerator extends SqlBaseBaseListener {
fillTypes.put(dataType, new PreviousFill(defaultFillInterval));
}
} else { // previous until last
- if (ctx.previousClause().DURATION() != null) {
+ if (ctx.previousUntilLastClause().DURATION() != null) {
long preRange = parseDuration(ctx.previousClause().DURATION().getText());
fillTypes.put(dataType, new PreviousFill(preRange, true));
} else {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 3e22199..e585222 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -176,6 +176,11 @@ public class PhysicalGenerator {
((GroupByFillPlan) queryPlan).setEndTime(queryOperator.getEndTime());
((GroupByFillPlan) queryPlan)
.setAggregations(queryOperator.getSelectOperator().getAggregations());
+ for (String aggregation : queryPlan.getAggregations()) {
+ if (!SQLConstant.LAST_VALUE.equals(aggregation)) {
+ throw new QueryProcessException("Group By Fill only support last_value function");
+ }
+ }
((GroupByFillPlan) queryPlan).setFillType(queryOperator.getFillTypes());
} else if (queryOperator.isGroupBy()) {
queryPlan = new GroupByPlan();
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByFillDataSet.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByFillDataSet.java
index 1bfc43b..5c7c381 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByFillDataSet.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByFillDataSet.java
@@ -72,14 +72,14 @@ public class GroupByFillDataSet extends QueryDataSet {
if (field.getDataType() == null) {
// the previous value is not null and (fill type is not previous until last or now time is before last time)
if (previousValue[i] != null
- && (!((PreviousFill)fillTypes.get(field.getDataType())).isUntilLast() || rowRecord.getTimestamp() <= lastTimeArray[i])) {
- rowRecord.getFields().set(i, Field.getField(previousValue, field.getDataType()));
+ && (!((PreviousFill)fillTypes.get(dataTypes.get(i))).isUntilLast() || rowRecord.getTimestamp() <= lastTimeArray[i])) {
+ rowRecord.getFields().set(i, Field.getField(previousValue[i], dataTypes.get(i)));
}
} else {
// use now value update previous value
previousValue[i] = field.getObjectValue(field.getDataType());
}
}
- return null;
+ return rowRecord;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java b/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
index 441075b..b95c49b 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/fill/PreviousFill.java
@@ -55,7 +55,7 @@ public class PreviousFill extends IFill {
@Override
public IFill copy() {
- return new PreviousFill(dataType, queryTime, beforeRange);
+ return new PreviousFill(dataType, queryTime, beforeRange, untilLast);
}
@Override
@@ -98,4 +98,8 @@ public class PreviousFill extends IFill {
public boolean isUntilLast() {
return untilLast;
}
+
+ public void setUntilLast(boolean untilLast) {
+ this.untilLast = untilLast;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index b2a8f71..c44a3a5 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -784,6 +784,7 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
break;
case AGGREGATION:
case GROUPBY:
+ case GROUP_BY_FILL:
List<String> aggregations = plan.getAggregations();
if (aggregations.size() != paths.size()) {
for (int i = 1; i < paths.size(); i++) {
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
new file mode 100644
index 0000000..328d094
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
@@ -0,0 +1,261 @@
+package org.apache.iotdb.db.integration;
+
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.jdbc.Config;
+import org.apache.iotdb.jdbc.IoTDBSQLException;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import static org.apache.iotdb.db.integration.Constant.TIMESTAMP_STR;
+import static org.apache.iotdb.db.integration.Constant.last_value;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class IoTDBGroupByFillIT {
+
+ private static String[] dataSet1 = new String[]{
+ "SET STORAGE GROUP TO root.ln.wf01.wt01",
+ "CREATE TIMESERIES root.ln.wf01.wt01.status WITH DATATYPE=BOOLEAN, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.ln.wf01.wt01.temperature WITH DATATYPE=INT32, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.ln.wf01.wt01.hardware WITH DATATYPE=DOUBLE, ENCODING=PLAIN",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(10, 21, false, 11.1)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(12, 23, true, 22.3)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(14, 25, false, 33.5)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(29, 26, false, 33.2)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(36, 29, false, 44.7)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(37, 30, false, 55.8)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(39, 40, false, 33.0)",
+ "flush"
+ };
+
+ @Before
+ public void setUp() throws Exception {
+ EnvironmentUtils.closeStatMonitor();
+ EnvironmentUtils.envSetUp();
+ IoTDBDescriptor.getInstance().getConfig().setPartitionInterval(1000);
+ Class.forName(Config.JDBC_DRIVER_NAME);
+ prepareData();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ IoTDBDescriptor.getInstance().getConfig().setPartitionInterval(86400);
+ EnvironmentUtils.cleanEnv();
+ }
+
+ @Test
+ public void previousTest1() {
+ String[] retArray = new String[] {
+ "17,25",
+ "22,25",
+ "27,26",
+ "32,29",
+ "37,40",
+ "42,40",
+ "47,40",
+ };
+
+ try (Connection connection = DriverManager.
+ getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ boolean hasResultSet = statement.execute(
+ "select last_value(temperature) from "
+ + "root.ln.wf01.wt01 "
+ + "GROUP BY ([17, 48), 5ms) FILL(int32[previous])");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet
+ .getString(last_value("root.ln.wf01.wt01.temperature"));
+ assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ assertEquals(retArray.length, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ }
+
+ @Test
+ public void previousTest2() {
+ try (Connection connection = DriverManager.
+ getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ statement.execute(
+ "select count(temperature) from "
+ + "root.ln.wf01.wt01 "
+ + "GROUP BY ([17, 48), 5ms) FILL(int32[previous])");
+ } catch (IoTDBSQLException e) {
+ assertEquals("Statement format is not right: Group By Fill only support last_value function", e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ }
+
+ @Test
+ public void previousTest3() {
+ String[] retArray = new String[] {
+ "2,null",
+ "7,21",
+ "12,25",
+ "17,25",
+ "22,25",
+ "27,26",
+ "32,29",
+ "37,40",
+ "42,40",
+ "47,40",
+ };
+
+ try (Connection connection = DriverManager.
+ getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ boolean hasResultSet = statement.execute(
+ "select last_value(temperature) from "
+ + "root.ln.wf01.wt01 "
+ + "GROUP BY ([2, 48), 5ms) FILL(int32[previous])");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet
+ .getString(last_value("root.ln.wf01.wt01.temperature"));
+ assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ assertEquals(retArray.length, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void previousTest4() {
+ String[] retArray = new String[] {
+ "2,null,null",
+ "7,21,11.1",
+ "12,25,33.5",
+ "17,25,33.5",
+ "22,25,33.5",
+ "27,26,33.2",
+ "32,29,44.7",
+ "37,40,33.0",
+ "42,40,33.0",
+ "47,40,33.0",
+ };
+
+ try (Connection connection = DriverManager.
+ getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ boolean hasResultSet = statement.execute(
+ "select last_value(temperature), last_value(hardware) from "
+ + "root.ln.wf01.wt01 "
+ + "GROUP BY ([2, 48), 5ms) FILL(int32[previous], double[previous])");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet
+ .getString(last_value("root.ln.wf01.wt01.temperature")) + "," +
+ resultSet.getString(last_value("root.ln.wf01.wt01.hardware"));
+ assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ assertEquals(retArray.length, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void previousAllTest() {
+ String[] retArray = new String[] {
+ "2,null,null",
+ "7,21,11.1",
+ "12,25,33.5",
+ "17,25,33.5",
+ "22,25,33.5",
+ "27,26,33.2",
+ "32,29,44.7",
+ "37,40,33.0",
+ "42,40,33.0",
+ "47,40,33.0",
+ };
+
+ try (Connection connection = DriverManager.
+ getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ boolean hasResultSet = statement.execute(
+ "select last_value(temperature), last_value(hardware) from "
+ + "root.ln.wf01.wt01 "
+ + "GROUP BY ([2, 48), 5ms) FILL(ALL[previous])");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet
+ .getString(last_value("root.ln.wf01.wt01.temperature")) + "," +
+ resultSet.getString(last_value("root.ln.wf01.wt01.hardware"));
+ assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ assertEquals(retArray.length, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ private void prepareData() {
+ try (Connection connection = DriverManager
+ .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root",
+ "root");
+ Statement statement = connection.createStatement();) {
+
+ for (String sql : dataSet1) {
+ statement.execute(sql);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
index c2371c9..4185ed3 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
@@ -18,32 +18,17 @@
*/
package org.apache.iotdb.db.qp.plan;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.exception.runtime.SQLParserException;
import org.apache.iotdb.db.metadata.MManager;
import org.apache.iotdb.db.qp.Planner;
import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
-import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
-import org.apache.iotdb.db.qp.physical.crud.FillQueryPlan;
-import org.apache.iotdb.db.qp.physical.crud.GroupByPlan;
-import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
-import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
-import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
-import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
-import org.apache.iotdb.db.qp.physical.sys.DataAuthPlan;
-import org.apache.iotdb.db.qp.physical.sys.LoadConfigurationPlan;
-import org.apache.iotdb.db.qp.physical.sys.OperateFilePlan;
-import org.apache.iotdb.db.qp.physical.sys.ShowPlan;
+import org.apache.iotdb.db.qp.physical.crud.*;
+import org.apache.iotdb.db.qp.physical.sys.*;
import org.apache.iotdb.db.query.fill.LinearFill;
import org.apache.iotdb.db.query.fill.PreviousFill;
import org.apache.iotdb.db.utils.EnvironmentUtils;
@@ -63,6 +48,13 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
public class PhysicalPlanTest {
private Planner processor = new Planner();
@@ -213,6 +205,7 @@ public class PhysicalPlanTest {
String sqlStr = "SELECT s1 FROM root.vehicle.d1 WHERE time = 5000 Fill(int32[linear, 5m], boolean[previous])";
try {
processor.parseSQLToPhysicalPlan(sqlStr);
+ fail();
} catch (Exception e) {
assertTrue(true);
}
@@ -223,12 +216,157 @@ public class PhysicalPlanTest {
String sqlStr = "SELECT s1 FROM root.vehicle.d1 WHERE time > 5000 Fill(int32[linear], boolean[previous])";
try {
processor.parseSQLToPhysicalPlan(sqlStr);
+ fail();
} catch (Exception e) {
assertEquals("Only \"=\" can be used in fill function", e.getMessage());
}
}
@Test
+ public void testGroupByFill1() {
+ String sqlStr =
+ "select last_value(s1) " + " from root.vehicle.d1 "
+ + "group by([8,737), 3ms) fill(int32[previous])";
+ try {
+ PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
+ if (!plan.isQuery()) {
+ fail();
+ }
+ if (!(plan instanceof GroupByFillPlan)) {
+ fail();
+ }
+ GroupByFillPlan groupByFillPlan = (GroupByFillPlan) plan;
+ assertEquals(3L, groupByFillPlan.getInterval());
+ assertEquals(3L, groupByFillPlan.getSlidingStep());
+ assertEquals(8L, groupByFillPlan.getStartTime());
+ assertEquals(737L, groupByFillPlan.getEndTime());
+ assertEquals(1, groupByFillPlan.getFillType().size());
+ assertTrue(groupByFillPlan.getFillType().containsKey(TSDataType.INT32));
+ assertTrue(groupByFillPlan.getFillType().get(TSDataType.INT32) instanceof PreviousFill);
+ PreviousFill previousFill = (PreviousFill) groupByFillPlan.getFillType().get(TSDataType.INT32);
+ assertFalse(previousFill.isUntilLast());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testGroupByFill2() {
+ String sqlStr =
+ "select last_value(s1) " + " from root.vehicle.d1 "
+ + "group by([8,737), 3ms) fill(ALL[previousuntillast])";
+ try {
+ PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
+ if (!plan.isQuery()) {
+ fail();
+ }
+ if (!(plan instanceof GroupByFillPlan)) {
+ fail();
+ }
+ GroupByFillPlan groupByFillPlan = (GroupByFillPlan) plan;
+ assertEquals(3L, groupByFillPlan.getInterval());
+ assertEquals(3L, groupByFillPlan.getSlidingStep());
+ assertEquals(8L, groupByFillPlan.getStartTime());
+ assertEquals(737L, groupByFillPlan.getEndTime());
+ assertEquals(TSDataType.values().length, groupByFillPlan.getFillType().size());
+ for (TSDataType tsDataType : TSDataType.values()) {
+ assertTrue(groupByFillPlan.getFillType().containsKey(tsDataType));
+ assertTrue(groupByFillPlan.getFillType().get(tsDataType) instanceof PreviousFill);
+ PreviousFill previousFill = (PreviousFill) groupByFillPlan.getFillType().get(tsDataType);
+ assertTrue(previousFill.isUntilLast());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testGroupByFill3() {
+ String sqlStr =
+ "select last_value(d1.s1), last_value(d2.s1)" + " from root.vehicle "
+ + "group by([8,737), 3ms) fill(int32[previousuntillast], int64[previous])";
+ try {
+ PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
+ if (!plan.isQuery()) {
+ fail();
+ }
+ if (!(plan instanceof GroupByFillPlan)) {
+ fail();
+ }
+ GroupByFillPlan groupByFillPlan = (GroupByFillPlan) plan;
+ assertEquals(3L, groupByFillPlan.getInterval());
+ assertEquals(3L, groupByFillPlan.getSlidingStep());
+ assertEquals(8L, groupByFillPlan.getStartTime());
+ assertEquals(737L, groupByFillPlan.getEndTime());
+ assertEquals(2, groupByFillPlan.getDeduplicatedPaths().size());
+ assertEquals(2, groupByFillPlan.getFillType().size());
+
+ assertTrue(groupByFillPlan.getFillType().containsKey(TSDataType.INT32));
+ assertTrue(groupByFillPlan.getFillType().get(TSDataType.INT32) instanceof PreviousFill);
+ PreviousFill previousFill = (PreviousFill) groupByFillPlan.getFillType().get(TSDataType.INT32);
+ assertTrue(previousFill.isUntilLast());
+
+ assertTrue(groupByFillPlan.getFillType().containsKey(TSDataType.INT64));
+ assertTrue(groupByFillPlan.getFillType().get(TSDataType.INT64) instanceof PreviousFill);
+ previousFill = (PreviousFill) groupByFillPlan.getFillType().get(TSDataType.INT64);
+ assertFalse(previousFill.isUntilLast());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testGroupByFill4() {
+ String sqlStr =
+ "select last_value(d1.s1), last_value(d2.s1)" + " from root.vehicle "
+ + "group by([8,737), 3ms) fill(int32[linear])";
+ try {
+ processor.parseSQLToPhysicalPlan(sqlStr);
+ fail();
+ } catch (SQLParserException e) {
+ assertEquals("group by fill doesn't support linear fill", e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testGroupByFill5() {
+ String sqlStr =
+ "select last_value(d1.s1), count(d2.s1)" + " from root.vehicle "
+ + "group by([8,737), 3ms) fill(int32[previous])";
+ try {
+ processor.parseSQLToPhysicalPlan(sqlStr);
+ fail();
+ } catch (QueryProcessException e) {
+ assertEquals("Group By Fill only support last_value function", e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testGroupByFill6() {
+ String sqlStr =
+ "select count(s1)" + "from root.vehicle.d1 "
+ + "group by([8,737), 3ms, 5ms) fill(int32[previous])";
+ try {
+ processor.parseSQLToPhysicalPlan(sqlStr);
+ fail();
+ } catch (ParseCancellationException e) {
+ assertTrue(e.getMessage().contains("mismatched input 'fill'"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
public void testQuery1() throws QueryProcessException {
String sqlStr = "SELECT s1 FROM root.vehicle.d1 WHERE time > 5000";
PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);