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/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 79c2602  Hot fix for LAST query bug when using with disable align 
(#879)
79c2602 is described below

commit 79c2602c8cc9e16593b91e4a36c757eb4d208189
Author: wshao08 <[email protected]>
AuthorDate: Wed Mar 4 16:57:52 2020 +0800

    Hot fix for LAST query bug when using with disable align (#879)
    
    * Hot fix for last disable align and early break unseq file traverse bug
---
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  7 +-
 .../qp/strategy/optimizer/ConcatPathOptimizer.java |  2 +-
 .../iotdb/db/query/executor/LastQueryExecutor.java |  2 +-
 .../apache/iotdb/db/integration/IoTDBLastIT.java   | 88 +++++++++++++++++++++-
 .../apache/iotdb/db/qp/plan/PhysicalPlanTest.java  | 18 +++--
 5 files changed, 105 insertions(+), 12 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index c19d330..e6abde7 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -242,7 +242,12 @@ public class PhysicalGenerator {
     } else {
       queryPlan = new RawDataQueryPlan();
     }
-    if (queryOperator.isAlignByDevice()) {
+    if (queryPlan instanceof LastQueryPlan) {
+      // Last query result set will not be affected by alignment
+      queryPlan.setAlignByTime(true);
+      List<Path> paths = queryOperator.getSelectedPaths();
+      queryPlan.setPaths(paths);
+    } else if (queryOperator.isAlignByDevice()) {
       // below is the core realization of ALIGN_BY_DEVICE sql logic
       AlignByDevicePlan alignByDevicePlan = new AlignByDevicePlan();
       if (queryPlan instanceof GroupByPlan) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
index bd36fa4..0217c0f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/optimizer/ConcatPathOptimizer.java
@@ -77,7 +77,7 @@ public class ConcatPathOptimizer implements ILogicalOptimizer 
{
 
     boolean isAlignByDevice = false;
     if (operator instanceof QueryOperator) {
-      if (!((QueryOperator) operator).isAlignByDevice()) {
+      if (!((QueryOperator) operator).isAlignByDevice() || ((QueryOperator) 
operator).isLastQuery()) {
         concatSelect(prefixPaths, select); // concat and remove star
 
         if (((QueryOperator) operator).hasSlimit()) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
index 30940f5..0317fdc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
@@ -143,7 +143,7 @@ public class LastQueryExecutor {
     long version = 0;
     for (TsFileResource resource : unseqFileResources) {
       if (resource.getEndTimeMap().get(seriesPath.getDevice()) < 
resultPair.getTimestamp()) {
-        break;
+        continue;
       }
       List<ChunkMetaData> chunkMetadata =
           FileLoaderUtils.loadChunkMetadataFromTsFileResource(resource, 
seriesPath, context);
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
index c2cb34b..2067346 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
@@ -40,7 +40,7 @@ import org.junit.Test;
 
 public class IoTDBLastIT {
 
-  private static String[] dataSet = new String[]{
+  private static String[] dataSet1 = new String[]{
       "SET STORAGE GROUP TO root.ln.wf01.wt01",
       "CREATE TIMESERIES root.ln.wf01.wt01.status WITH DATATYPE=BOOLEAN, 
ENCODING=PLAIN",
       "CREATE TIMESERIES root.ln.wf01.wt01.temperature WITH DATATYPE=DOUBLE, 
ENCODING=PLAIN",
@@ -58,6 +58,20 @@ public class IoTDBLastIT {
       "flush",
   };
 
+  private static String[] dataSet2 = new String[]{
+      "SET STORAGE GROUP TO root.ln.wf01.wt02",
+      "CREATE TIMESERIES root.ln.wf01.wt02.status WITH DATATYPE=BOOLEAN, 
ENCODING=PLAIN",
+      "CREATE TIMESERIES root.ln.wf01.wt02.temperature WITH DATATYPE=DOUBLE, 
ENCODING=PLAIN",
+      "CREATE TIMESERIES root.ln.wf01.wt02.id WITH DATATYPE=INT32, 
ENCODING=PLAIN",
+      "INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status, id) "
+          + "values(100, 18.6, false, 7)",
+      "INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status, id) "
+          + "values(300, 23.1, true, 8)",
+      "INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status, id) "
+          + "values(500, 15.7, false, 9)",
+      "flush",
+  };
+
   private static final String TIMESTAMP_STR = "Time";
   private static final String TIMESEIRES_STR = "timeseries";
   private static final String VALUE_STR = "value";
@@ -94,8 +108,8 @@ public class IoTDBLastIT {
             DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
         Statement statement = connection.createStatement()) {
 
-      boolean hasResultSet =
-          statement.execute("select last temperature,status,id from 
root.ln.wf01.wt01");
+      boolean hasResultSet = statement.execute(
+              "select last temperature,status,id from root.ln.wf01.wt01 
disable align");
 
       Assert.assertTrue(hasResultSet);
       int cnt = 0;
@@ -158,6 +172,69 @@ public class IoTDBLastIT {
     }
   }
 
+  @Test
+  public void lastWithUnSeqFilesTest() throws SQLException {
+    String[] retArray1 =
+        new String[] {
+            "500,root.ln.wf01.wt02.temperature,15.7",
+            "500,root.ln.wf01.wt02.status,false",
+            "500,root.ln.wf01.wt02.id,9"
+        };
+
+    String[] retArray2 =
+        new String[] {
+            "600,root.ln.wf01.wt02.temperature,10.2",
+            "600,root.ln.wf01.wt02.status,false",
+            "600,root.ln.wf01.wt02.id,6"
+        };
+
+    try (Connection connection =
+            DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
+        Statement statement = connection.createStatement()) {
+
+      MNode node = MManager.getInstance()
+          
.getDeviceNodeWithAutoCreateStorageGroup("root.ln.wf01.wt02.temperature");
+      ((LeafMNode) node).resetCache();
+      boolean hasResultSet =
+          statement.execute(
+              "select last temperature,status,id from root.ln.wf01.wt02");
+
+      Assert.assertTrue(hasResultSet);
+      int cnt = 0;
+      try (ResultSet resultSet = statement.getResultSet()) {
+        while (resultSet.next()) {
+          String ans =
+              resultSet.getString(TIMESTAMP_STR) + ","
+                  + resultSet.getString(TIMESEIRES_STR) + ","
+                  + resultSet.getString(VALUE_STR);
+          Assert.assertEquals(retArray1[cnt], ans);
+          cnt++;
+        }
+      }
+
+      statement.execute(
+          "INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status, id) 
values(600, 10.2, false, 6)");
+      statement.execute(
+          "INSERT INTO root.ln.wf01.wt02(timestamp,temperature,status, id) 
values(450, 20.1, false, 5)");
+      statement.execute("flush");
+      hasResultSet = statement.execute(
+              "select last temperature,status,id from root.ln.wf01.wt02");
+      cnt = 0;
+      try (ResultSet resultSet = statement.getResultSet()) {
+        while (resultSet.next()) {
+          String ans = resultSet.getString(TIMESTAMP_STR) + ","
+                  + resultSet.getString(TIMESEIRES_STR) + ","
+                  + resultSet.getString(VALUE_STR);
+          Assert.assertEquals(retArray2[cnt], ans);
+          cnt++;
+        }
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
   private void prepareData() {
     try (Connection connection = DriverManager
         .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root",
@@ -165,7 +242,10 @@ public class IoTDBLastIT {
         Statement statement = connection.createStatement()) {
 
 
-      for (String sql : dataSet) {
+      for (String sql : dataSet1) {
+        statement.execute(sql);
+      }
+      for (String sql : dataSet2) {
         statement.execute(sql);
       }
 
diff --git 
a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java 
b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
index 4a885b6..1527685 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
@@ -612,7 +612,7 @@ public class PhysicalPlanTest {
   @Test
   public void testLastPlanPaths() throws QueryProcessException {
     String sqlStr1 = "SELECT last s1 FROM root.vehicle.d1";
-    String sqlStr2 = "SELECT last s1 FROM root.vehicle.d1, root.vehicle.d2";
+    String sqlStr2 = "SELECT last s1 FROM root.vehicle.d1, root.vehicle.d2 
disable align";
     PhysicalPlan plan1 = processor.parseSQLToPhysicalPlan(sqlStr1);
     PhysicalPlan plan2 = processor.parseSQLToPhysicalPlan(sqlStr2);
     Path path1 = new Path("root.vehicle.d1.s1");
@@ -626,11 +626,19 @@ public class PhysicalPlanTest {
 
   @Test
   public void testLastPlanDataTypes() throws QueryProcessException {
-    String sqlStr = "SELECT last s1 FROM root.vehicle.d1";
-    PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
+    String sqlStr1 = "SELECT last s1 FROM root.vehicle.d1";
+    String sqlStr2 = "SELECT last s1 FROM root.vehicle.d2, root.vehicle.d3, 
root.vehicle.d4";
 
-    assertEquals(1, ((LastQueryPlan) plan).getDataTypes().size());
-    TSDataType dataType = ((LastQueryPlan) plan).getDataTypes().get(0);
+    PhysicalPlan plan1 = processor.parseSQLToPhysicalPlan(sqlStr1);
+    PhysicalPlan plan2 = processor.parseSQLToPhysicalPlan(sqlStr2);
+
+    assertEquals(1, ((LastQueryPlan) plan1).getDataTypes().size());
+    TSDataType dataType = ((LastQueryPlan) plan1).getDataTypes().get(0);
     assertEquals(TSDataType.FLOAT, dataType);
+
+    assertEquals(3, ((LastQueryPlan) plan2).getDataTypes().size());
+    for (TSDataType dt : ((LastQueryPlan) plan2).getDataTypes()) {
+      assertEquals(TSDataType.FLOAT, dt);
+    }
   }
 }

Reply via email to