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

jackietien pushed a commit to branch DefaultOrderByTime
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/DefaultOrderByTime by this 
push:
     new 90532f118ca Add UT
90532f118ca is described below

commit 90532f118caa4d4a6f2736430dc77be17b91b69b
Author: JackieTien97 <[email protected]>
AuthorDate: Thu May 15 21:04:46 2025 +0800

    Add UT
---
 .../relational/analyzer/StatementAnalyzer.java     |  2 +-
 .../distribute/TableDistributedPlanGenerator.java  | 14 ++++++
 .../plan/relational/planner/node/GroupNode.java    |  2 +-
 .../relational/analyzer/TableFunctionTest.java     | 53 ++++++++++++----------
 .../plan/relational/analyzer/TestMetadata.java     | 48 ++++++++++++++------
 .../{SortMatcher.java => GroupMatcher.java}        | 42 ++++++++---------
 .../planner/assertions/PlanMatchPattern.java       | 14 ++++--
 .../relational/planner/assertions/SortMatcher.java |  4 +-
 .../planner/assertions/TableScanMatcher.java       |  1 -
 .../{SortMatcher.java => TopKMatcher.java}         | 33 +++++++++-----
 10 files changed, 132 insertions(+), 81 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 1c15cf4c4a3..55e6e3436ff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -4382,7 +4382,7 @@ public class StatementAnalyzer {
                 new OrderBy(
                     Collections.singletonList(
                         new SortItem(
-                            new Identifier(null, timeColumn),
+                            new Identifier(timeColumn),
                             SortItem.Ordering.ASCENDING,
                             SortItem.NullOrdering.FIRST))));
           }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
index 8a0606ccfe7..57bf0a79660 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
@@ -273,6 +273,20 @@ public class TableDistributedPlanGenerator
         node.getChildren().size() == 1, "Size of TopKNode can only be 1 in 
logical plan.");
     List<PlanNode> childrenNodes = node.getChildren().get(0).accept(this, 
context);
     if (childrenNodes.size() == 1) {
+      // if DeviceTableScanNode has limit <= K and with same order, we can 
directly return
+      // DeviceTableScanNode
+      if (childrenNodes.get(0) instanceof DeviceTableScanNode) {
+        DeviceTableScanNode tableScanNode = (DeviceTableScanNode) 
childrenNodes.get(0);
+        if (node.getCount() >= tableScanNode.getPushDownLimit()
+            && (!tableScanNode.isPushLimitToEachDevice()
+                || (tableScanNode.isPushLimitToEachDevice()
+                    && tableScanNode.getDeviceEntries().size() == 1))
+            && canSortEliminated(
+                node.getOrderingScheme(),
+                nodeOrderingMap.get(childrenNodes.get(0).getPlanNodeId()))) {
+          return childrenNodes;
+        }
+      }
       node.setChildren(Collections.singletonList(childrenNodes.get(0)));
       return Collections.singletonList(node);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/GroupNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/GroupNode.java
index 80ea7657fff..83b034ac7bf 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/GroupNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/GroupNode.java
@@ -49,7 +49,7 @@ public class GroupNode extends SortNode {
    * orderingScheme may include two parts: PartitionKey and OrderKey. It marks 
the number of
    * PartitionKey.
    */
-  private int partitionKeyCount;
+  private final int partitionKeyCount;
 
   public GroupNode(PlanNodeId id, PlanNode child, OrderingScheme scheme, int 
partitionKeyCount) {
     super(id, child, scheme, false, false);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TableFunctionTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TableFunctionTest.java
index a1fddfe21d5..9dd16653a89 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TableFunctionTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TableFunctionTest.java
@@ -53,6 +53,11 @@ import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.sort;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.tableFunctionProcessor;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.tableScan;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.topK;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem.NullOrdering.FIRST;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem.NullOrdering.LAST;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem.Ordering.ASCENDING;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SortItem.Ordering.DESCENDING;
 import static org.apache.iotdb.udf.api.type.Type.DOUBLE;
 
 public class TableFunctionTest {
@@ -347,19 +352,17 @@ public class TableFunctionTest {
     String sql =
         "SELECT * FROM FORECAST("
             + "input => (SELECT time,s3 FROM table1 WHERE tag1='shanghai' AND 
tag2='A3' AND tag3='YY' ORDER BY time DESC LIMIT 1440), "
-            + "model_id => 'timer_xl'";
+            + "model_id => 'timer_xl')";
     LogicalQueryPlan logicalQueryPlan = planTester.createPlan(sql);
+
     PlanMatchPattern tableScan =
-        tableScan(
-            "testdb.table1",
-            ImmutableList.of("time", "tag1", "tag2", "tag3", "s3"),
-            ImmutableSet.of("time", "tag1", "tag2", "tag3", "s3"));
+        tableScan("testdb.table1", ImmutableMap.of("time_0", "time", "s3_1", 
"s3"));
     Consumer<TableFunctionProcessorMatcher.Builder> tableFunctionMatcher =
         builder ->
             builder
                 .name("forecast")
                 .properOutputs("time", "s3")
-                .requiredSymbols("time", "s3")
+                .requiredSymbols("time_0", "s3_1")
                 .handle(
                     new ForecastTableFunction.ForecastTableFunctionHandle(
                         false,
@@ -373,28 +376,32 @@ public class TableFunctionTest {
                         Collections.singletonList(DOUBLE)));
     // Verify full LogicalPlan
     // Output - TableFunctionProcessor - TableScan
-    assertPlan(logicalQueryPlan, 
anyTree(tableFunctionProcessor(tableFunctionMatcher, tableScan)));
+    assertPlan(
+        logicalQueryPlan,
+        anyTree(
+            tableFunctionProcessor(
+                tableFunctionMatcher,
+                group(
+                    ImmutableList.of(sort("time_0", ASCENDING, FIRST)),
+                    0,
+                    topK(
+                        1440,
+                        ImmutableList.of(sort("time_0", DESCENDING, LAST)),
+                        false,
+                        tableScan)))));
     // Verify DistributionPlan
 
     /*
      *   └──OutputNode
-     *         └──CollectNode
-     *               ├──ExchangeNode
-     *               │    └──TableFunctionProcessor
-     *               │        └──TableScan
-     *               ├──ExchangeNode
-     *               │    └──TableFunctionProcessor
-     *               │        └──TableScan
-     *               └──ExchangeNode
-     *                    └──TableFunctionProcessor
-     *                        └──TableScan
+     *         └──TableFunctionProcessor
+     *               └──GroupNode
+     *                   └──TableScan
      */
-    assertPlan(planTester.getFragmentPlan(0), output(collect(exchange(), 
exchange(), exchange())));
-    assertPlan(
-        planTester.getFragmentPlan(1), 
tableFunctionProcessor(tableFunctionMatcher, tableScan));
     assertPlan(
-        planTester.getFragmentPlan(2), 
tableFunctionProcessor(tableFunctionMatcher, tableScan));
-    assertPlan(
-        planTester.getFragmentPlan(3), 
tableFunctionProcessor(tableFunctionMatcher, tableScan));
+        planTester.getFragmentPlan(0),
+        output(
+            tableFunctionProcessor(
+                tableFunctionMatcher,
+                group(ImmutableList.of(sort("time_0", ASCENDING, FIRST)), 0, 
tableScan))));
   }
 }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMetadata.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMetadata.java
index e56727974a2..52f526d1799 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMetadata.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMetadata.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.common.rpc.thrift.TEndPoint;
+import org.apache.iotdb.commons.model.ModelInformation;
 import org.apache.iotdb.commons.partition.DataPartition;
 import org.apache.iotdb.commons.partition.DataPartitionQueryParam;
 import org.apache.iotdb.commons.partition.SchemaNodeManagementPartition;
@@ -27,15 +29,14 @@ import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
-import org.apache.iotdb.commons.udf.builtin.relational.tvf.HOPTableFunction;
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.analyze.IModelFetcher;
 import org.apache.iotdb.db.queryengine.plan.analyze.IPartitionFetcher;
-import org.apache.iotdb.db.queryengine.plan.function.Exclude;
-import org.apache.iotdb.db.queryengine.plan.function.Repeat;
-import org.apache.iotdb.db.queryengine.plan.function.Split;
+import 
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.model.ModelInferenceDescriptor;
 import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
+import 
org.apache.iotdb.db.queryengine.plan.relational.function.TableBuiltinTableFunction;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.AlignedDeviceEntry;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnMetadata;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnSchema;
@@ -56,6 +57,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeManager;
 import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignature;
+import org.apache.iotdb.db.queryengine.plan.udf.TableUDFUtils;
 import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 import org.apache.iotdb.udf.api.relational.TableFunction;
@@ -312,7 +314,17 @@ public class TestMetadata implements Metadata {
                   IDeviceID.Factory.DEFAULT_FACTORY.create(DEVICE_6), new 
Binary[0])));
     }
 
-    if (expressionList.size() == 2) {
+    if (expressionList.size() == 3) {
+      if (compareEqualsMatch(expressionList.get(0), "tag1", "shanghai")
+          && compareEqualsMatch(expressionList.get(1), "tag2", "A3")
+          && compareEqualsMatch(expressionList.get(2), "tag3", "YY")) {
+        return Collections.singletonMap(
+            DB1,
+            Collections.singletonList(
+                new AlignedDeviceEntry(
+                    new StringArrayDeviceID(DEVICE_3.split("\\.")), 
DEVICE_1_ATTRIBUTES)));
+      }
+    } else if (expressionList.size() == 2) {
       if (compareEqualsMatch(expressionList.get(0), "tag1", "beijing")
               && compareEqualsMatch(expressionList.get(1), "tag2", "A1")
           || compareEqualsMatch(expressionList.get(1), "tag1", "beijing")
@@ -479,22 +491,28 @@ public class TestMetadata implements Metadata {
 
   @Override
   public TableFunction getTableFunction(String functionName) {
-    if ("HOP".equalsIgnoreCase(functionName)) {
-      return new HOPTableFunction();
-    } else if ("EXCLUDE".equalsIgnoreCase(functionName)) {
-      return new Exclude();
-    } else if ("REPEAT".equalsIgnoreCase(functionName)) {
-      return new Repeat();
-    } else if ("SPLIT".equalsIgnoreCase(functionName)) {
-      return new Split();
+    if (TableBuiltinTableFunction.isBuiltInTableFunction(functionName)) {
+      return TableBuiltinTableFunction.getBuiltinTableFunction(functionName);
+    } else if (TableUDFUtils.isTableFunction(functionName)) {
+      return TableUDFUtils.getTableFunction(functionName);
     } else {
-      return null;
+      throw new SemanticException("Unknown function: " + functionName);
     }
   }
 
   @Override
   public IModelFetcher getModelFetcher() {
-    return null;
+    String modelId = "timer_xl";
+    IModelFetcher fetcher = Mockito.mock(IModelFetcher.class);
+    ModelInferenceDescriptor descriptor = 
Mockito.mock(ModelInferenceDescriptor.class);
+    Mockito.when(descriptor.getTargetAINode()).thenReturn(new 
TEndPoint("127.0.0.1", 10810));
+    ModelInformation modelInformation = Mockito.mock(ModelInformation.class);
+    Mockito.when(modelInformation.available()).thenReturn(true);
+    Mockito.when(modelInformation.getInputShape()).thenReturn(new int[] {1440, 
96});
+    
Mockito.when(descriptor.getModelInformation()).thenReturn(modelInformation);
+    Mockito.when(descriptor.getModelName()).thenReturn(modelId);
+    Mockito.when(fetcher.fetchModel(modelId)).thenReturn(descriptor);
+    return fetcher;
   }
 
   private static final DataPartition TABLE_DATA_PARTITION =
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/GroupMatcher.java
similarity index 60%
copy from 
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
copy to 
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/GroupMatcher.java
index fe81ae95d65..ff17bdfec3c 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/GroupMatcher.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -22,47 +22,45 @@ package 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
-import 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.Ordering;
-import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SortNode;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.node.GroupNode;
 
 import java.util.List;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.MatchResult.NO_MATCH;
-import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.Util.orderingSchemeMatches;
 
-final class SortMatcher implements Matcher {
-  private final List<Ordering> orderBy;
+public class GroupMatcher extends SortMatcher {
+  private final int partitionKeyCount;
 
-  public SortMatcher(List<Ordering> orderBy) {
-    this.orderBy = requireNonNull(orderBy, "orderBy is null");
+  public GroupMatcher(List<PlanMatchPattern.Ordering> orderBy, int 
partitionKeyCount) {
+    super(orderBy);
+    this.partitionKeyCount = partitionKeyCount;
   }
 
   @Override
   public boolean shapeMatches(PlanNode node) {
-    return node instanceof SortNode;
+    return node instanceof GroupNode;
   }
 
   @Override
   public MatchResult detailMatches(
       PlanNode node, SessionInfo sessionInfo, Metadata metadata, SymbolAliases 
symbolAliases) {
-    checkState(
-        shapeMatches(node),
-        "Plan testing framework error: shapeMatches returned false in 
detailMatches in %s",
-        this.getClass().getName());
-    SortNode sortNode = (SortNode) node;
-
-    if (!orderingSchemeMatches(orderBy, sortNode.getOrderingScheme(), 
symbolAliases)) {
-      return NO_MATCH;
+    MatchResult result = super.detailMatches(node, sessionInfo, metadata, 
symbolAliases);
+    if (result != NO_MATCH) {
+      GroupNode sortNode = (GroupNode) node;
+      if (partitionKeyCount != ((GroupNode) node).getPartitionKeyCount()) {
+        return NO_MATCH;
+      }
+      return MatchResult.match();
     }
-
-    return MatchResult.match();
+    return NO_MATCH;
   }
 
   @Override
   public String toString() {
-    return toStringHelper(this).add("orderBy", orderBy).toString();
+    return toStringHelper(this)
+        .add("orderBy", orderBy)
+        .add("partitionKeyCount", partitionKeyCount)
+        .toString();
   }
 }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/PlanMatchPattern.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/PlanMatchPattern.java
index ef051873c35..93662f6082b 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/PlanMatchPattern.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/PlanMatchPattern.java
@@ -49,6 +49,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.SemiJoinNode
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SortNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.StreamSortNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableFunctionProcessorNode;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TopKNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TreeAlignedDeviceViewScanNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TreeDeviceViewScanNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TreeNonAlignedDeviceViewScanNode;
@@ -545,6 +546,11 @@ public final class PlanMatchPattern {
     return node(GroupNode.class, source);
   }
 
+  public static PlanMatchPattern group(
+      List<Ordering> orderBy, int partitionKeyCount, PlanMatchPattern source) {
+    return node(GroupNode.class, source).with(new GroupMatcher(orderBy, 
partitionKeyCount));
+  }
+
   public static PlanMatchPattern sort(PlanMatchPattern source) {
     return node(SortNode.class, source);
   }
@@ -557,12 +563,12 @@ public final class PlanMatchPattern {
     return node(StreamSortNode.class, source).with(new SortMatcher(orderBy));
   }
 
-  /*public static PlanMatchPattern topN(long count, List<Ordering> orderBy, 
PlanMatchPattern source)
-  {
-      return topN(count, orderBy, TopNNode.Step.SINGLE, source);
+  public static PlanMatchPattern topK(
+      long count, List<Ordering> orderBy, boolean childrenDataInOrder, 
PlanMatchPattern source) {
+    return node(TopKNode.class, source).with(new TopKMatcher(orderBy, count, 
childrenDataInOrder));
   }
 
-  public static PlanMatchPattern topN(long count, List<Ordering> orderBy, 
TopNNode.Step step, PlanMatchPattern source)
+  /*public static PlanMatchPattern topN(long count, List<Ordering> orderBy, 
TopNNode.Step step, PlanMatchPattern source)
   {
       return node(TopNNode.class, source).with(new TopNMatcher(count, orderBy, 
step));
   }*/
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
index fe81ae95d65..3a95f579b31 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
@@ -33,8 +33,8 @@ import static java.util.Objects.requireNonNull;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.MatchResult.NO_MATCH;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.Util.orderingSchemeMatches;
 
-final class SortMatcher implements Matcher {
-  private final List<Ordering> orderBy;
+class SortMatcher implements Matcher {
+  protected final List<Ordering> orderBy;
 
   public SortMatcher(List<Ordering> orderBy) {
     this.orderBy = requireNonNull(orderBy, "orderBy is null");
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TableScanMatcher.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TableScanMatcher.java
index 01ca624a423..b860a18c16a 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TableScanMatcher.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TableScanMatcher.java
@@ -64,7 +64,6 @@ public abstract class TableScanMatcher implements Matcher {
     TableScanNode tableScanNode = (TableScanNode) node;
     String actualTableName = tableScanNode.getQualifiedObjectName().toString();
 
-    // TODO (https://github.com/trinodb/trino/issues/17) change to equals()
     if (!expectedTableName.equalsIgnoreCase(actualTableName)) {
       return NO_MATCH;
     }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TopKMatcher.java
similarity index 68%
copy from 
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
copy to 
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TopKMatcher.java
index fe81ae95d65..018a693e55c 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/SortMatcher.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/TopKMatcher.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -22,27 +22,30 @@ package 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
-import 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.Ordering;
-import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SortNode;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TopKNode;
 
 import java.util.List;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.MatchResult.NO_MATCH;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.Util.orderingSchemeMatches;
 
-final class SortMatcher implements Matcher {
-  private final List<Ordering> orderBy;
+public class TopKMatcher implements Matcher {
+  private final List<PlanMatchPattern.Ordering> orderBy;
+  private final long count;
+  private final boolean childrenDataInOrder;
 
-  public SortMatcher(List<Ordering> orderBy) {
-    this.orderBy = requireNonNull(orderBy, "orderBy is null");
+  public TopKMatcher(
+      List<PlanMatchPattern.Ordering> orderBy, long count, boolean 
childrenDataInOrder) {
+    this.orderBy = orderBy;
+    this.count = count;
+    this.childrenDataInOrder = childrenDataInOrder;
   }
 
   @Override
   public boolean shapeMatches(PlanNode node) {
-    return node instanceof SortNode;
+    return node instanceof TopKNode;
   }
 
   @Override
@@ -52,9 +55,11 @@ final class SortMatcher implements Matcher {
         shapeMatches(node),
         "Plan testing framework error: shapeMatches returned false in 
detailMatches in %s",
         this.getClass().getName());
-    SortNode sortNode = (SortNode) node;
+    TopKNode topKNode = (TopKNode) node;
 
-    if (!orderingSchemeMatches(orderBy, sortNode.getOrderingScheme(), 
symbolAliases)) {
+    if (!orderingSchemeMatches(orderBy, topKNode.getOrderingScheme(), 
symbolAliases)
+        || count != topKNode.getCount()
+        || childrenDataInOrder != topKNode.isChildrenDataInOrder()) {
       return NO_MATCH;
     }
 
@@ -63,6 +68,10 @@ final class SortMatcher implements Matcher {
 
   @Override
   public String toString() {
-    return toStringHelper(this).add("orderBy", orderBy).toString();
+    return toStringHelper(this)
+        .add("orderBy", orderBy)
+        .add("count", count)
+        .add("childrenDataInOrder", childrenDataInOrder)
+        .toString();
   }
 }

Reply via email to