This is an automated email from the ASF dual-hosted git repository. xiangweiwei pushed a commit to branch groupbymonthbug in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 77a0e030442a39836acbb9b33902f2a1c219406d Author: Alima777 <[email protected]> AuthorDate: Mon Apr 26 17:03:38 2021 +0800 Fix group by month bug --- .../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) {
