This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new faed0d8 Fix group by month StackOverflow bug (#3070)
faed0d8 is described below
commit faed0d84e7cb563aa1a28abcb11fb2173fc5f7bf
Author: Xiangwei Wei <[email protected]>
AuthorDate: Tue Apr 27 17:18:27 2021 +0800
Fix group by month StackOverflow bug (#3070)
---
.../iotdb/db/query/executor/QueryRouter.java | 6 +-
.../iotdb/db/integration/IoTDBGroupByMonthIT.java | 70 +++++++++++++++++++++-
.../tsfile/read/filter/GroupByMonthFilter.java | 17 +++++-
3 files changed, 86 insertions(+), 7 deletions(-)
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
b/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
index bebe02b..29254e7 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
@@ -195,8 +195,12 @@ public class QueryRouter implements IQueryRouter {
return dataSet;
}
- private GlobalTimeExpression getTimeExpression(GroupByTimePlan plan) {
+ private GlobalTimeExpression getTimeExpression(GroupByTimePlan plan)
+ throws QueryProcessException {
if (plan.isSlidingStepByMonth() || plan.isIntervalByMonth()) {
+ if (!plan.isAscending()) {
+ throw new QueryProcessException("Group by month doesn't support order
by time desc now.");
+ }
return new GlobalTimeExpression(
(new GroupByMonthFilter(
plan.getInterval(),
diff --git
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByMonthIT.java
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByMonthIT.java
index b2352f4..5ff2236 100644
---
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByMonthIT.java
+++
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByMonthIT.java
@@ -63,6 +63,10 @@ public class IoTDBGroupByMonthIT {
.setCompactionStrategy(CompactionStrategy.LEVEL_COMPACTION);
}
+ /**
+ * Test when interval = slidingStep = 1 month. StartTime: 2020-10-31
00:00:00, EndTime: 2021-03-01
+ * 00:00:00
+ */
@Test
public void groupByNaturalMonth1() {
try (Connection connection =
@@ -99,6 +103,10 @@ public class IoTDBGroupByMonthIT {
}
}
+ /**
+ * Test when interval = 10 days < slidingStep = 1 month. StartTime:
2020-10-31 00:00:00, EndTime:
+ * 2021-03-01 00:00:00
+ */
@Test
public void groupByNaturalMonth2() {
try (Connection connection =
@@ -135,7 +143,10 @@ public class IoTDBGroupByMonthIT {
}
}
- /** Test when endTime - startTime = interval */
+ /**
+ * Test when endTime - startTime = interval StartTime: 2020-10-31 00:00:00,
EndTime: 2020-11-30
+ * 00:00:00
+ */
@Test
public void groupByNaturalMonth3() {
try (Connection connection =
@@ -160,6 +171,59 @@ public class IoTDBGroupByMonthIT {
}
}
+ /**
+ * StartTime: 2021-01-31 00:00:00, EndTime: 2021-03-31 00:00:00. First Month
with 28 days, Second
+ * month with 31 days
+ */
+ @Test
+ public void groupByNaturalMonth4() {
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/",
"root", "root");
+ Statement statement = connection.createStatement()) {
+
+ String[] retArray1 = {
+ "01/31/2021:00:00:00", "28.0",
+ "02/28/2021:00:00:00", "31.0"
+ };
+
+ boolean hasResultSet =
+ statement.execute(
+ "select sum(temperature) from root.sg1.d1 GROUP BY
([1612051200000, 1617148800000), 1mo)");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt = 0;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ String time = resultSet.getString(TIMESTAMP_STR);
+ String ans = resultSet.getString(sum("root.sg1.d1.temperature"));
+ Assert.assertEquals(retArray1[cnt++],
df.format(Long.parseLong(time)));
+ Assert.assertEquals(retArray1[cnt++], ans);
+ }
+ Assert.assertEquals(retArray1.length, cnt);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ /** Test group by month with order by time desc. */
+ @Test
+ public void groupByNaturalMonth5() {
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/",
"root", "root");
+ Statement statement = connection.createStatement()) {
+
+ statement.execute(
+ "select sum(temperature) from root.sg1.d1 "
+ + "GROUP BY ([1612051200000, 1617148800000), 1mo) order by time
desc");
+
+ fail("No Exception thrown");
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains("doesn't support order by time
desc now."));
+ }
+ }
+
private void prepareData() {
try (Connection connection =
DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/",
"root", "root");
@@ -167,8 +231,8 @@ public class IoTDBGroupByMonthIT {
// 2020-10-31 08:00:00
long startTime = 1604102400000L;
- // 2021-03-01 08:00:00
- long endTime = 1614556800000L;
+ // 2021-03-31 08:00:00
+ long endTime = 1617148800000L;
for (long i = startTime; i <= endTime; i += 86400_000L) {
statement.execute("insert into root.sg1.d1(timestamp, temperature)
values (" + i + ", 1)");
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/GroupByMonthFilter.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/GroupByMonthFilter.java
index e86b74e..00a4d83 100644
---
a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/GroupByMonthFilter.java
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/GroupByMonthFilter.java
@@ -33,7 +33,7 @@ public class GroupByMonthFilter extends GroupByFilter {
private final boolean isIntervalByMonth;
private int slidingStepsInMo;
private int intervalInMo;
- private final Calendar calendar = Calendar.getInstance();
+ private Calendar calendar = Calendar.getInstance();
private static final long MS_TO_MONTH = 30 * 86400_000L;
private int intervalCnt = 0;
/** 10.31 -> 11.30 -> 12.31, not 10.31 -> 11.30 -> 12.30 */
@@ -61,6 +61,18 @@ public class GroupByMonthFilter extends GroupByFilter {
getNextIntervalAndSlidingStep();
}
+ public GroupByMonthFilter(GroupByMonthFilter filter) {
+ super(filter.interval, filter.slidingStep, filter.startTime,
filter.endTime);
+ isIntervalByMonth = filter.isIntervalByMonth;
+ isSlidingStepByMonth = filter.isSlidingStepByMonth;
+ intervalInMo = filter.intervalInMo;
+ slidingStepsInMo = filter.slidingStepsInMo;
+ intervalCnt = filter.intervalCnt;
+ initialStartTime = filter.initialStartTime;
+ calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(filter.calendar.getTimeInMillis());
+ }
+
// TODO: time descending order
@Override
public boolean satisfy(long time, Object value) {
@@ -99,8 +111,7 @@ public class GroupByMonthFilter extends GroupByFilter {
@Override
public Filter copy() {
- return new GroupByMonthFilter(
- interval, slidingStep, startTime, endTime, isSlidingStepByMonth,
isIntervalByMonth);
+ return new GroupByMonthFilter(this);
}
private boolean satisfyCurrentInterval(long startTime, long endTime) {