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

caogaofei pushed a commit to branch beyyes/cp_133
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 92ef1bad842a0ee9702e421732bdbc2ee7fe2072
Author: Beyyes <[email protected]>
AuthorDate: Fri Sep 13 10:02:05 2024 +0800

    Fix error in last query with sort + limit
---
 .../db/it/last/IoTDBLastQueryLastCacheIT.java      | 14 +++++++++
 .../it/last/IoTDBLastQueryWithLimitOffsetIT.java   | 34 ++++++++++++++++++++++
 .../plan/planner/LogicalPlanVisitor.java           | 11 +++----
 .../plan/node/process/last/LastQueryNode.java      |  3 ++
 .../logical/DataQueryLogicalPlannerTest.java       | 33 +++++++++++++++++++++
 5 files changed, 90 insertions(+), 5 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
index 6d30db00085..feb710be4fa 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
@@ -165,4 +165,18 @@ public class IoTDBLastQueryLastCacheIT {
     testLastQueryOrderByTimeDesc();
     testLastQuery1();
   }
+
+  @Test
+  public void testLastQuerySortWithLimit() {
+    String[] expectedHeader =
+        new String[] {TIMESTAMP_STR, TIMESEIRES_STR, VALUE_STR, DATA_TYPE_STR};
+    String[] retArray =
+        new String[] {
+          "1679477545000,root.ln_1.tb_6141.code_DOUBLE,2.0,DOUBLE,",
+        };
+    resultSetEqualTest(
+        "select last * from root.ln_1.tb_6141 order by time desc, timeseries 
desc limit 1;",
+        expectedHeader,
+        retArray);
+  }
 }
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryWithLimitOffsetIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryWithLimitOffsetIT.java
index 062d5a345c3..0de811ff271 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryWithLimitOffsetIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryWithLimitOffsetIT.java
@@ -190,4 +190,38 @@ public class IoTDBLastQueryWithLimitOffsetIT {
       fail(e.getMessage());
     }
   }
+
+  @Test
+  public void testWithSortLimit() {
+    String[] retArray =
+        new String[] {
+          "2,root.sg.d2.s2,1.0,DOUBLE",
+        };
+
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+
+      try (ResultSet resultSet =
+          statement.executeQuery(
+              "select last * from root.sg.** order by time desc, timeseries 
desc limit 1")) {
+        int cnt = 0;
+        while (resultSet.next()) {
+          String ans =
+              resultSet.getString(ColumnHeaderConstant.TIME)
+                  + ","
+                  + resultSet.getString(ColumnHeaderConstant.TIMESERIES)
+                  + ","
+                  + resultSet.getString(ColumnHeaderConstant.VALUE)
+                  + ","
+                  + resultSet.getString(ColumnHeaderConstant.DATATYPE);
+          assertEquals(retArray[cnt++], ans);
+        }
+        assertEquals(retArray.length, cnt);
+      }
+
+    } catch (SQLException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
index 5913bc9f665..86bc69f27e3 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
@@ -142,15 +142,16 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
     LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
     if (queryStatement.isLastQuery()) {
-      planBuilder =
-          planBuilder
-              .planLast(analysis, analysis.getTimeseriesOrderingForLastQuery())
-              .planOffset(queryStatement.getRowOffset())
-              .planLimit(queryStatement.getRowLimit());
+      planBuilder = planBuilder.planLast(analysis, 
analysis.getTimeseriesOrderingForLastQuery());
 
       if (queryStatement.hasOrderBy() && 
!queryStatement.onlyOrderByTimeseries()) {
         planBuilder = 
planBuilder.planOrderBy(queryStatement.getSortItemList());
       }
+
+      planBuilder =
+          planBuilder
+              .planOffset(queryStatement.getRowOffset())
+              .planLimit(queryStatement.getRowLimit());
       return planBuilder.getRoot();
     }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
index 2fb059f8b2e..5d0589e40d4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
@@ -110,6 +110,9 @@ public class LastQueryNode extends MultiChildProcessNode {
       return false;
     }
     LastQueryNode that = (LastQueryNode) o;
+    if (timeseriesOrdering == null) {
+      return that.timeseriesOrdering == null;
+    }
     return timeseriesOrdering.equals(that.timeseriesOrdering);
   }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
index 2a14c0cf3b2..993b15562ea 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
@@ -36,6 +36,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.GroupByLev
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.LimitNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.OffsetNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.RawDataAggregationNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.SortNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.join.FullOuterTimeJoinNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.last.LastQueryNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.source.AlignedLastQueryScanNode;
@@ -105,6 +106,38 @@ public class DataQueryLogicalPlannerTest {
     Assert.assertEquals(actualPlan, lastQueryNode);
   }
 
+  @Test
+  public void testLastQuerySortWithLimit() {
+    String sql = "SELECT last * FROM root.sg.d1 ORDER BY time DESC LIMIT 1";
+
+    QueryId queryId = new QueryId("test");
+    // fake initResultNodeContext()
+    queryId.genPlanNodeId();
+
+    LastQueryScanNode d1s3 =
+        new LastQueryScanNode(
+            queryId.genPlanNodeId(), (MeasurementPath) 
schemaMap.get("root.sg.d1.s3"), null);
+    LastQueryScanNode d1s1 =
+        new LastQueryScanNode(
+            queryId.genPlanNodeId(), (MeasurementPath) 
schemaMap.get("root.sg.d1.s1"), null);
+    LastQueryScanNode d1s2 =
+        new LastQueryScanNode(
+            queryId.genPlanNodeId(), (MeasurementPath) 
schemaMap.get("root.sg.d1.s2"), null);
+
+    List<PlanNode> sourceNodeList = Arrays.asList(d1s3, d1s1, d1s2);
+    LastQueryNode lastQueryNode =
+        new LastQueryNode(queryId.genPlanNodeId(), sourceNodeList, null, 
false);
+    SortNode sortNode =
+        new SortNode(
+            queryId.genPlanNodeId(),
+            lastQueryNode,
+            new OrderByParameter(Collections.singletonList(new 
SortItem("TIME", Ordering.DESC))));
+    LimitNode limitNode = new LimitNode(queryId.genPlanNodeId(), sortNode, 1);
+
+    PlanNode actualPlan = parseSQLToPlanNode(sql);
+    Assert.assertEquals(actualPlan, limitNode);
+  }
+
   @Test
   public void testSimpleRawDataQuery() {
     String sql = "SELECT ** FROM root.sg.d2 WHERE time > 100 LIMIT 10 OFFSET 
10";

Reply via email to