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()];

Reply via email to