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";
