You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2022/05/03 10:08:13 UTC

[iotdb] 02/02: fix bug

This is an automated email from the ASF dual-hosted git repository.

rong pushed a commit to branch iotdb-3050
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit f4e3d1cc3035de30194f53dd4d8ab34ad80ab6a5
Author: Steve Yurong Su <ro...@apache.org>
AuthorDate: Tue May 3 18:07:49 2022 +0800

    fix bug
---
 .../iotdb/db/integration/IoTDBNestedQueryIT.java   | 28 ++++++++++++++++++++++
 .../iotdb/db/qp/logical/crud/SelectComponent.java  |  4 +---
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |  2 +-
 .../apache/iotdb/db/qp/physical/crud/UDTFPlan.java |  4 +++-
 .../db/query/expression/leaf/TimestampOperand.java | 17 +++++++++----
 .../org/apache/iotdb/rpc/IoTDBJDBCDataSet.java     |  3 ++-
 6 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBNestedQueryIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBNestedQueryIT.java
index c74ce71b6d..c27b622ea5 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBNestedQueryIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBNestedQueryIT.java
@@ -45,6 +45,7 @@ import java.sql.Statement;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 @Category({LocalStandaloneTest.class})
@@ -607,4 +608,31 @@ public class IoTDBNestedQueryIT {
       Assert.fail(e.getMessage());
     }
   }
+
+  @Test
+  public void testTimeExpressions() {
+    try (Connection connection =
+            DriverManager.getConnection(
+                Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+        Statement statement = connection.createStatement()) {
+      String query = "SELECT s1, time, time + 1 - 1, time + s1 - s1 FROM root.vehicle.d1";
+      try (ResultSet rs = statement.executeQuery(query)) {
+        for (int i = 1; i <= ITERATION_TIMES; ++i) {
+          assertTrue(rs.next());
+          for (int j = 1; j <= 5; ++j) {
+            assertEquals(i, Double.parseDouble(rs.getString(j)), 0.001);
+          }
+        }
+        assertFalse(rs.next());
+      }
+
+      query = "SELECT time FROM root.vehicle.d1";
+      try (ResultSet rs = statement.executeQuery(query)) {
+        assertFalse(rs.next());
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+      Assert.fail(e.getMessage());
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
index fa7c3c5d55..fe5a0a4060 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
@@ -114,9 +114,7 @@ public class SelectComponent {
           pathsCache.add(((TimeSeriesOperand) expression).getPath());
         } else if (expression instanceof FunctionExpression
             && expression.isBuiltInAggregationFunctionExpression()) {
-          pathsCache.add(
-              ((TimeSeriesOperand) ((FunctionExpression) expression).getExpressions().get(0))
-                  .getPath());
+          pathsCache.add(((TimeSeriesOperand) expression.getExpressions().get(0)).getPath());
         } else {
           pathsCache.add(null);
         }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
index a38cb1497e..1aba4f8cdf 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
@@ -59,7 +59,7 @@ public abstract class QueryPlan extends PhysicalPlan {
 
   private boolean ascending = true;
 
-  private Map<String, Integer> pathToIndex = new HashMap<>();
+  private final Map<String, Integer> pathToIndex = new HashMap<>();
 
   protected Set<Integer>
       withoutNullColumnsIndex; // index set that withoutNullColumns for output data columns
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UDTFPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UDTFPlan.java
index e1c9dbadb7..0c4eded37c 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UDTFPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UDTFPlan.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.ResultColumn;
+import org.apache.iotdb.db.query.expression.leaf.TimestampOperand;
 import org.apache.iotdb.db.query.udf.core.executor.UDTFContext;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Pair;
@@ -71,7 +72,8 @@ public class UDTFPlan extends RawDataQueryPlan implements UDFPlan {
       Integer originalIndex = indexedPath.right;
 
       String columnForReader = originalPath.getFullPath();
-      if (!columnForReaderSet.contains(columnForReader)) {
+      if (!columnForReaderSet.contains(columnForReader)
+          && !TimestampOperand.TIMESTAMP_PARTIAL_PATH.getFullPath().equals(columnForReader)) {
         addDeduplicatedPaths(originalPath);
         pathNameToReaderIndex.put(columnForReader, pathNameToReaderIndex.size());
         columnForReaderSet.add(columnForReader);
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
index 041af30a4d..8c18ff66bd 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
@@ -45,6 +45,8 @@ import java.util.Set;
 
 public class TimestampOperand extends LeafOperand {
 
+  public static final PartialPath TIMESTAMP_PARTIAL_PATH = new PartialPath("Time", false);
+
   public TimestampOperand() {
     // do nothing
   }
@@ -53,23 +55,28 @@ public class TimestampOperand extends LeafOperand {
     // do nothing
   }
 
+  @Override
+  public boolean isTimeSeriesGeneratingFunctionExpression() {
+    return true;
+  }
+
   @Override
   public void concat(
       List<PartialPath> prefixPaths,
       List<Expression> resultExpressions,
       PathPatternTree patternTree) {
-    // do nothing
+    resultExpressions.add(this);
   }
 
   @Override
   public void concat(List<PartialPath> prefixPaths, List<Expression> resultExpressions) {
-    // do nothing
+    resultExpressions.add(this);
   }
 
   @Override
   public void removeWildcards(WildcardsRemover wildcardsRemover, List<Expression> resultExpressions)
       throws StatementAnalyzeException {
-    // do nothing
+    resultExpressions.add(this);
   }
 
   @Override
@@ -77,12 +84,12 @@ public class TimestampOperand extends LeafOperand {
       org.apache.iotdb.db.qp.utils.WildcardsRemover wildcardsRemover,
       List<Expression> resultExpressions)
       throws LogicalOptimizeException {
-    // do nothing
+    resultExpressions.add(this);
   }
 
   @Override
   public void collectPaths(Set<PartialPath> pathSet) {
-    // do nothing
+    pathSet.add(TIMESTAMP_PARTIAL_PATH);
   }
 
   @Override
diff --git a/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java b/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java
index 0942b49937..670f025848 100644
--- a/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java
+++ b/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java
@@ -232,7 +232,8 @@ public class IoTDBJDBCDataSet {
 
         this.columnNameList.add(name);
         this.columnTypeList.add(columnTypeList.get(i));
-        if (!columnOrdinalMap.containsKey(name)) {
+        // "Time".equals(name) -> to allow the Time column appear in value columns
+        if (!columnOrdinalMap.containsKey(name) || "Time".equals(name)) {
           int index = columnNameIndex.get(name);
           columnOrdinalMap.put(name, index + START_INDEX);
           columnTypeDeduplicatedList.set(index, TSDataType.valueOf(columnTypeList.get(i)));