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 0edc97bc58def9cfe70fec82c24e9aa9c0505ed2 Author: Alima777 <[email protected]> AuthorDate: Fri May 7 11:05:08 2021 +0800 Fix issue-3116 --- .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java | 50 +++++++++++++++------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java index 3888c74..3b2f32c 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java @@ -256,7 +256,6 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> { + "time > XXX, time <= XXX, or two atomic expressions connected by 'AND'"; private ZoneId zoneId; QueryOperator queryOp; - private boolean isParsingSlidingStep; public void setZoneId(ZoneId zoneId) { this.zoneId = zoneId; @@ -1436,17 +1435,17 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> { queryOp.setGroupByTime(true); queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null); // parse timeUnit - queryOp.setUnit(parseDuration(ctx.DURATION(0).getText())); - queryOp.setSlidingStep(queryOp.getUnit()); + queryOp.setUnit(parseTimeUnitOrSlidingStep(queryOp, ctx.DURATION(0).getText(), true)); // parse sliding step if (ctx.DURATION().size() == 2) { - isParsingSlidingStep = true; - queryOp.setSlidingStep(parseDuration(ctx.DURATION(1).getText())); - isParsingSlidingStep = false; + queryOp.setSlidingStep(parseTimeUnitOrSlidingStep(queryOp, ctx.DURATION(1).getText(), false)); if (queryOp.getSlidingStep() < queryOp.getUnit()) { throw new SQLParserException( "The third parameter sliding step shouldn't be smaller than the second parameter time interval."); } + } else { + queryOp.setSlidingStep(queryOp.getUnit()); + queryOp.setSlidingStepByMonth(queryOp.isIntervalByMonth()); } parseTimeInterval(ctx.timeInterval(), queryOp); @@ -1852,16 +1851,6 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> { i++; unit += durationStr.charAt(i); } - if (unit.equalsIgnoreCase("mo")) { - // interval is by month, sliding step by default equals to interval - if (!isParsingSlidingStep) { - queryOp.setIntervalByMonth(true); - } - queryOp.setSlidingStepByMonth(true); - } else if (isParsingSlidingStep) { - // parsing sliding step value, and unit is not by month - queryOp.setSlidingStepByMonth(false); - } total += DatetimeUtils.convertDurationStrToLong(tmp, unit.toLowerCase(), timestampPrecision); tmp = 0; @@ -1873,6 +1862,35 @@ public class IoTDBSqlVisitor extends SqlBaseBaseVisitor<Operator> { return total; } + /** + * parse time unit or sliding step in group by query. + * + * @param durationStr represent duration string like: 12d8m9ns, 1y1mo, etc. + * @return time in milliseconds, microseconds, or nanoseconds depending on the profile + */ + private long parseTimeUnitOrSlidingStep( + QueryOperator queryOp, String durationStr, boolean isParsingTimeUnit) { + for (int i = 0; i < durationStr.length(); i++) { + char ch = durationStr.charAt(i); + if (!Character.isDigit(ch)) { + String unit = durationStr.charAt(i) + ""; + // This is to identify units with two letters. + if (i + 1 < durationStr.length() && !Character.isDigit(durationStr.charAt(i + 1))) { + i++; + unit += durationStr.charAt(i); + } + if (unit.equalsIgnoreCase("mo")) { + if (isParsingTimeUnit) { + queryOp.setIntervalByMonth(true); + } else { + queryOp.setSlidingStepByMonth(true); + } + } + } + } + return parseDuration(durationStr); + } + private PartialPath parseSuffixPath(SuffixPathContext ctx) { List<NodeNameContext> nodeNames = ctx.nodeName(); String[] path = new String[nodeNames.size()];
