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

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


The following commit(s) were added to refs/heads/beyyes/TableModelGrammar_0627 
by this push:
     new 0431ac0a4d8 add sort ut
0431ac0a4d8 is described below

commit 0431ac0a4d8c126da7668b4702f2dbdf8b109525
Author: Beyyes <[email protected]>
AuthorDate: Wed Jul 3 19:00:14 2024 +0800

    add sort ut
---
 .../distribute/DistributedPlanGenerator.java       | 106 ++++++++-------
 .../TableModelTypeProviderExtractor.java           |   7 +
 .../relational/planner/node/TableScanNode.java     |   4 +
 .../plan/relational/analyzer/AnalyzerTest.java     |  49 ++-----
 .../plan/relational/analyzer/SortTest.java         | 151 +++++++++++++++++++--
 5 files changed, 222 insertions(+), 95 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
index 56159f8c7a2..acc8fb97f11 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
@@ -43,6 +43,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.SortNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -57,8 +58,8 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 import static com.google.common.collect.ImmutableList.toImmutableList;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.TIME;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PushPredicateIntoTableScan.containsDiffFunction;
+import static org.apache.iotdb.db.utils.constant.TestConstant.TIMESTAMP_STR;
 
 public class DistributedPlanGenerator
     extends PlanVisitor<List<PlanNode>, DistributedPlanGenerator.PlanContext> {
@@ -236,7 +237,7 @@ public class DistributedPlanGenerator
 
     context.hasExchangeNode = tableScanNodeMap.size() > 1;
 
-    List<PlanNode> tableScanNodeList = new ArrayList<>();
+    List<PlanNode> resultTableScanNodeList = new ArrayList<>();
     TRegionReplicaSet mostUsedDataRegion = null;
     int maxDeviceEntrySizeOfTableScan = 0;
     for (Map.Entry<TRegionReplicaSet, TableScanNode> entry : 
tableScanNodeMap.entrySet()) {
@@ -244,7 +245,7 @@ public class DistributedPlanGenerator
       TableScanNode subTableScanNode = entry.getValue();
       
subTableScanNode.setPlanNodeId(queryContext.getQueryId().genPlanNodeId());
       subTableScanNode.setRegionReplicaSet(regionReplicaSet);
-      tableScanNodeList.add(subTableScanNode);
+      resultTableScanNodeList.add(subTableScanNode);
 
       if (mostUsedDataRegion == null
           || subTableScanNode.getDeviceEntries().size() > 
maxDeviceEntrySizeOfTableScan) {
@@ -254,16 +255,40 @@ public class DistributedPlanGenerator
     }
     context.mostUsedDataRegion = mostUsedDataRegion;
 
+    if (!context.hasSortNode) {
+      return resultTableScanNodeList;
+    }
+
+    processSortProperty(node, resultTableScanNodeList, context);
+    return resultTableScanNodeList;
+  }
+
+  private List<PlanNode> connectViaCollectSort(
+      SingleChildProcessNode node, List<PlanNode> childrenNodes) {
+    CollectNode collectNode = new 
CollectNode(queryContext.getQueryId().genPlanNodeId());
+    childrenNodes.forEach(collectNode::addChild);
+    node.setChild(collectNode);
+    return Collections.singletonList(node);
+  }
+
+  private void processSortProperty(
+      TableScanNode tableScanNode, List<PlanNode> resultTableScanNodeList, 
PlanContext context) {
     List<Symbol> newOrderingSymbols = new ArrayList<>();
     List<SortOrder> newSortOrders = new ArrayList<>();
     OrderingScheme expectedOrderingScheme = context.expectedOrderingScheme;
 
+    Ordering scanOrder = Ordering.ASC;
     for (Symbol symbol : expectedOrderingScheme.getOrderBy()) {
-      if (!context.hasSortNode && TIME.equalsIgnoreCase(symbol.getName())) {
+      if (TIMESTAMP_STR.equalsIgnoreCase(symbol.getName())) {
+        if (!expectedOrderingScheme.getOrderings().get(symbol).isAscending()
+            && scanOrder == Ordering.ASC) {
+          // TODO(beyyes) move this judgement into logical plan
+          scanOrder = Ordering.DESC;
+          resultTableScanNodeList.forEach(
+              node -> ((TableScanNode) node).setScanOrder(Ordering.DESC));
+        }
         continue;
-      }
-
-      if (!node.getIdAndAttributeIndexMap().containsKey(symbol)) {
+      } else if 
(!tableScanNode.getIdAndAttributeIndexMap().containsKey(symbol)) {
         break;
       }
 
@@ -271,10 +296,16 @@ public class DistributedPlanGenerator
       newSortOrders.add(expectedOrderingScheme.getOrdering(symbol));
     }
 
+    // no sort property can be pushed down into TableScanNode
+    if (newOrderingSymbols.isEmpty()) {
+      return;
+    }
+
     List<Function<DeviceEntry, String>> orderingRules = new ArrayList<>();
     for (Symbol symbol : newOrderingSymbols) {
-      int idx = node.getIdAndAttributeIndexMap().get(symbol);
-      if (node.getAssignments().get(symbol).getColumnCategory() == 
TsTableColumnCategory.ID) {
+      int idx = tableScanNode.getIdAndAttributeIndexMap().get(symbol);
+      if (tableScanNode.getAssignments().get(symbol).getColumnCategory()
+          == TsTableColumnCategory.ID) {
         // segments[0] is always tableName
         orderingRules.add(deviceEntry -> (String) 
deviceEntry.getDeviceID().getSegments()[idx + 1]);
       } else {
@@ -284,34 +315,28 @@ public class DistributedPlanGenerator
 
     Comparator<DeviceEntry> comparator;
     if (newSortOrders.get(0).isNullsFirst()) {
-      if (newSortOrders.get(0).isAscending()) {
-        comparator = 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(0)));
-      } else {
-        comparator = 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(0))).reversed();
-      }
+      comparator =
+          newSortOrders.get(0).isAscending()
+              ? 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(0)))
+              : 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(0))).reversed();
     } else {
-      if (newSortOrders.get(0).isAscending()) {
-        comparator = 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(0)));
-      } else {
-        comparator = 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(0))).reversed();
-      }
+      comparator =
+          newSortOrders.get(0).isAscending()
+              ? 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(0)))
+              : 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(0))).reversed();
     }
     for (int i = 1; i < orderingRules.size(); i++) {
       Comparator<DeviceEntry> thenComparator;
       if (newSortOrders.get(i).isNullsFirst()) {
-        if (newSortOrders.get(i).isAscending()) {
-          thenComparator = 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(i)));
-        } else {
-          thenComparator =
-              
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(i))).reversed();
-        }
+        thenComparator =
+            newSortOrders.get(i).isAscending()
+                ? 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(i)))
+                : 
Comparator.nullsFirst(Comparator.comparing(orderingRules.get(i))).reversed();
       } else {
-        if (newSortOrders.get(i).isAscending()) {
-          thenComparator = 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(i)));
-        } else {
-          thenComparator =
-              
Comparator.nullsLast(Comparator.comparing(orderingRules.get(i))).reversed();
-        }
+        thenComparator =
+            newSortOrders.get(i).isAscending()
+                ? 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(i)))
+                : 
Comparator.nullsLast(Comparator.comparing(orderingRules.get(i))).reversed();
       }
       comparator = comparator.thenComparing(thenComparator);
     }
@@ -322,22 +347,11 @@ public class DistributedPlanGenerator
             IntStream.range(0, newOrderingSymbols.size())
                 .boxed()
                 .collect(Collectors.toMap(newOrderingSymbols::get, 
newSortOrders::get)));
-    for (PlanNode planNode : tableScanNodeList) {
-      TableScanNode tableScanNode = (TableScanNode) planNode;
-      planNodeOrderingSchemeMap.put(tableScanNode.getPlanNodeId(), 
newOrderingScheme);
-      List<DeviceEntry> deviceEntries = tableScanNode.getDeviceEntries();
-      deviceEntries.sort(comparator);
+    for (PlanNode planNode : resultTableScanNodeList) {
+      TableScanNode scanNode = (TableScanNode) planNode;
+      planNodeOrderingSchemeMap.put(scanNode.getPlanNodeId(), 
newOrderingScheme);
+      scanNode.getDeviceEntries().sort(comparator);
     }
-
-    return tableScanNodeList;
-  }
-
-  private List<PlanNode> connectViaCollectSort(
-      SingleChildProcessNode node, List<PlanNode> childrenNodes) {
-    CollectNode collectNode = new 
CollectNode(queryContext.getQueryId().genPlanNodeId());
-    childrenNodes.forEach(collectNode::addChild);
-    node.setChild(collectNode);
-    return Collections.singletonList(node);
   }
 
   // ------------------- schema related interface 
---------------------------------------------
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
index ff73c8c7715..9065ddaa4dc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableModelTypeProviderExtractor.java
@@ -20,6 +20,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.SimplePlanVisitor;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.ExchangeNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.sink.IdentitySinkNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.CollectNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.LimitNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.MergeSortNode;
@@ -106,6 +107,12 @@ public class TableModelTypeProviderExtractor {
       return null;
     }
 
+    @Override
+    public Void visitCollect(CollectNode node, Void context) {
+      node.getChildren().forEach(c -> c.accept(this, context));
+      return null;
+    }
+
     @Override
     public Void visitSort(SortNode node, Void context) {
       node.getChild().accept(this, context);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
index d83d2785f19..092c607436b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
@@ -375,6 +375,10 @@ public class TableScanNode extends SourceNode {
     return this.idAndAttributeIndexMap;
   }
 
+  public void setScanOrder(Ordering scanOrder) {
+    this.scanOrder = scanOrder;
+  }
+
   public Ordering getScanOrder() {
     return this.scanOrder;
   }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index 5af376cea95..7cd286bcba2 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -40,9 +40,9 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.LogicalPlanner;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.TableDistributionPlanner;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.CollectNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.LimitNode;
-import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.MergeSortNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.OffsetNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.OutputNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
@@ -136,28 +136,6 @@ public class AnalyzerTest {
             metadata.getTableSchema(Mockito.any(), eq(new 
QualifiedObjectName("testdb", "table1"))))
         .thenReturn(Optional.of(tableSchema));
 
-    //    ResolvedFunction lLessThanI =
-    //        new ResolvedFunction(
-    //            new BoundSignature("l<i", BOOLEAN, Arrays.asList(INT64, 
INT32)),
-    //            new FunctionId("l<i"),
-    //            FunctionKind.SCALAR,
-    //            true);
-    //
-    //    ResolvedFunction iAddi =
-    //        new ResolvedFunction(
-    //            new BoundSignature("l+i", INT64, Arrays.asList(INT32, 
INT32)),
-    //            new FunctionId("l+i"),
-    //            FunctionKind.SCALAR,
-    //            true);
-    //
-    //    Mockito.when(
-    //            metadata.resolveOperator(eq(OperatorType.LESS_THAN), 
eq(Arrays.asList(INT64,
-    // INT32))))
-    //        .thenReturn(lLessThanI);
-    //    Mockito.when(metadata.resolveOperator(eq(OperatorType.ADD), 
eq(Arrays.asList(INT32,
-    // INT32))))
-    //        .thenReturn(iAddi);
-
     Mockito.when(
             metadata.getOperatorReturnType(
                 eq(OperatorType.LESS_THAN), eq(Arrays.asList(INT64, INT32))))
@@ -192,7 +170,7 @@ public class AnalyzerTest {
         tableScanNode.getOutputColumnNames());
     assertEquals(9, tableScanNode.getOutputSymbols().size());
     assertEquals(9, tableScanNode.getAssignments().size());
-    assertEquals(1, tableScanNode.getDeviceEntries().size());
+    assertEquals(6, tableScanNode.getDeviceEntries().size());
     assertEquals(5, tableScanNode.getIdAndAttributeIndexMap().size());
     assertEquals(ASC, tableScanNode.getScanOrder());
 
@@ -233,24 +211,19 @@ public class AnalyzerTest {
     OutputNode outputNode =
         (OutputNode)
             
distributedQueryPlan.getFragments().get(0).getPlanNodeTree().getChildren().get(0);
-    assertTrue(outputNode.getChildren().get(0) instanceof MergeSortNode);
-    MergeSortNode mergeSortNode = (MergeSortNode) 
outputNode.getChildren().get(0);
-    assertEquals(
-        Arrays.asList("tag1", "tag2", "tag3", "attr1", "attr2"),
-        mergeSortNode.getOrderingScheme().getOrderBy().stream()
-            .map(Symbol::getName)
-            .collect(Collectors.toList()));
-    assertTrue(mergeSortNode.getChildren().get(0) instanceof ExchangeNode);
-    assertTrue(mergeSortNode.getChildren().get(1) instanceof TableScanNode);
-    assertTrue(mergeSortNode.getChildren().get(2) instanceof ExchangeNode);
-    TableScanNode tableScanNode = (TableScanNode) 
mergeSortNode.getChildren().get(1);
+    assertTrue(outputNode.getChildren().get(0) instanceof CollectNode);
+    CollectNode collectNode = (CollectNode) outputNode.getChildren().get(0);
+    assertTrue(collectNode.getChildren().get(0) instanceof ExchangeNode);
+    assertTrue(collectNode.getChildren().get(1) instanceof TableScanNode);
+    assertTrue(collectNode.getChildren().get(2) instanceof ExchangeNode);
+    TableScanNode tableScanNode = (TableScanNode) 
collectNode.getChildren().get(1);
     assertEquals(4, tableScanNode.getDeviceEntries().size());
     assertEquals(
         Arrays.asList(
-            "table1.shanghai.A3.YY",
             "table1.shanghai.B3.YY",
             "table1.shenzhen.B1.XX",
-            "table1.shenzhen.B2.ZZ"),
+            "table1.shenzhen.B2.ZZ",
+            "table1.shanghai.A3.YY"),
         tableScanNode.getDeviceEntries().stream()
             .map(d -> d.getDeviceID().toString())
             .collect(Collectors.toList()));
@@ -482,7 +455,7 @@ public class AnalyzerTest {
     tableScanNode = (TableScanNode) rootNode.getChildren().get(0);
     assertEquals(
         Arrays.asList("time", "tag2", "attr2", "s2"), 
tableScanNode.getOutputColumnNames());
-    assertEquals(2, tableScanNode.getIdAndAttributeIndexMap().size());
+    assertEquals(5, tableScanNode.getIdAndAttributeIndexMap().size());
   }
 
   @Test
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/SortTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/SortTest.java
index 002530cb84d..feb23b778cf 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/SortTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/SortTest.java
@@ -46,6 +46,8 @@ import java.util.Arrays;
 import java.util.stream.Collectors;
 
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.AnalyzerTest.analyzeSQL;
+import static 
org.apache.iotdb.db.queryengine.plan.statement.component.Ordering.ASC;
+import static 
org.apache.iotdb.db.queryengine.plan.statement.component.Ordering.DESC;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -74,7 +76,8 @@ public class SortTest {
   // order by time, others, some_ids
   @Test
   public void timeOthersSomeIDColumnSortTest() {
-    sql = "SELECT * FROM table1 order by time desc, s1+s2 asc, tag2 asc, tag1 
desc";
+    sql =
+        "SELECT time, tag1, tag2, s1, s2, attr1 FROM table1 order by time 
desc, s1+s2 asc, tag2 asc, tag1 desc";
     context = new MPPQueryContext(sql, queryId, sessionInfo, null, null);
     actualAnalysis = analyzeSQL(sql, metadata);
     logicalQueryPlan =
@@ -91,9 +94,10 @@ public class SortTest {
     tableScanNode =
         (TableScanNode) 
rootNode.getChildren().get(0).getChildren().get(0).getChildren().get(0);
     assertEquals("testdb.table1", 
tableScanNode.getQualifiedObjectName().toString());
-    assertEquals(
-        Arrays.asList("time", "tag1", "tag2", "tag3", "attr1", "attr2", "s1", 
"s2", "s3"),
-        tableScanNode.getOutputColumnNames());
+    // TODO(beyyes) fix the case prune unUsed Columns when the child of 
SortNode is ProjectNode
+    //    assertEquals(
+    //        Arrays.asList("time", "tag1", "tag2", "attr1", "s1", "s2"),
+    //        tableScanNode.getOutputColumnNames());
     assertEquals(9, tableScanNode.getAssignments().size());
     assertEquals(6, tableScanNode.getDeviceEntries().size());
     assertEquals(5, tableScanNode.getIdAndAttributeIndexMap().size());
@@ -110,18 +114,29 @@ public class SortTest {
     assertTrue(outputNode.getChildren().get(0) instanceof MergeSortNode);
     MergeSortNode mergeSortNode = (MergeSortNode) 
outputNode.getChildren().get(0);
     assertEquals(
-        Arrays.asList("tag1", "tag2", "tag3", "attr1", "attr2"),
+        Arrays.asList("time", "(s1 + s2)", "tag2", "tag1"),
         mergeSortNode.getOrderingScheme().getOrderBy().stream()
             .map(Symbol::getName)
             .collect(Collectors.toList()));
     assertTrue(mergeSortNode.getChildren().get(0) instanceof ExchangeNode);
-    assertTrue(mergeSortNode.getChildren().get(1) instanceof TableScanNode);
+    assertTrue(mergeSortNode.getChildren().get(1) instanceof SortNode);
     assertTrue(mergeSortNode.getChildren().get(2) instanceof ExchangeNode);
-    TableScanNode tableScanNode = (TableScanNode) 
mergeSortNode.getChildren().get(1);
+    SortNode sortNode = (SortNode) mergeSortNode.getChildren().get(1);
+    assertTrue(sortNode.getChildren().get(0).getChildren().get(0) instanceof 
TableScanNode);
+    tableScanNode = (TableScanNode) 
sortNode.getChildren().get(0).getChildren().get(0);
     assertEquals(4, tableScanNode.getDeviceEntries().size());
     assertEquals(
-        Arrays.asList(),
-        tableScanNode.getDeviceEntries().stream().map(d -> 
d.getDeviceID().toString()));
+        Arrays.asList(
+            "table1.shanghai.B3.YY",
+            "table1.shenzhen.B1.XX",
+            "table1.shenzhen.B2.ZZ",
+            "table1.shanghai.A3.YY"),
+        tableScanNode.getDeviceEntries().stream()
+            .map(d -> d.getDeviceID().toString())
+            .collect(Collectors.toList()));
+    assertEquals(DESC, tableScanNode.getScanOrder());
+
+    // TODO(beyyes) add only one device entry optimization and verifies
   }
 
   // order by time, others, all_ids
@@ -145,7 +160,64 @@ public class SortTest {
   // order by some_ids, time, others
   @Test
   public void someIDColumnTimeOthersSortTest() {
-    // TODO
+    sql =
+        "SELECT time, tag1, tag2, s1, s2, attr1 FROM table1 order by tag2 
desc, tag1 asc, time desc, s1+s2 asc";
+    context = new MPPQueryContext(sql, queryId, sessionInfo, null, null);
+    actualAnalysis = analyzeSQL(sql, metadata);
+    logicalQueryPlan =
+        new LogicalPlanner(context, metadata, sessionInfo, 
WarningCollector.NOOP)
+            .plan(actualAnalysis);
+    rootNode = logicalQueryPlan.getRootNode();
+
+    assertTrue(rootNode instanceof OutputNode);
+    assertTrue(rootNode.getChildren().get(0) instanceof SortNode);
+    assertTrue(rootNode.getChildren().get(0).getChildren().get(0) instanceof 
ProjectNode);
+    assertTrue(
+        rootNode.getChildren().get(0).getChildren().get(0).getChildren().get(0)
+            instanceof TableScanNode);
+    tableScanNode =
+        (TableScanNode) 
rootNode.getChildren().get(0).getChildren().get(0).getChildren().get(0);
+    assertEquals("testdb.table1", 
tableScanNode.getQualifiedObjectName().toString());
+    //    assertEquals(
+    //        Arrays.asList("time", "tag1", "tag2", "attr1", "s1", "s2"),
+    //        tableScanNode.getOutputColumnNames());
+    assertEquals(9, tableScanNode.getAssignments().size());
+    assertEquals(6, tableScanNode.getDeviceEntries().size());
+    assertEquals(5, tableScanNode.getIdAndAttributeIndexMap().size());
+
+    distributionPlanner = new TableDistributionPlanner(actualAnalysis, 
logicalQueryPlan, context);
+    distributedQueryPlan = distributionPlanner.plan();
+    assertEquals(3, distributedQueryPlan.getFragments().size());
+    assertTrue(
+        
distributedQueryPlan.getFragments().get(0).getPlanNodeTree().getChildren().get(0)
+            instanceof OutputNode);
+    OutputNode outputNode =
+        (OutputNode)
+            
distributedQueryPlan.getFragments().get(0).getPlanNodeTree().getChildren().get(0);
+    assertTrue(outputNode.getChildren().get(0) instanceof MergeSortNode);
+    MergeSortNode mergeSortNode = (MergeSortNode) 
outputNode.getChildren().get(0);
+    assertEquals(
+        Arrays.asList("tag2", "tag1", "time", "(s1 + s2)"),
+        mergeSortNode.getOrderingScheme().getOrderBy().stream()
+            .map(Symbol::getName)
+            .collect(Collectors.toList()));
+    assertTrue(mergeSortNode.getChildren().get(0) instanceof ExchangeNode);
+    assertTrue(mergeSortNode.getChildren().get(1) instanceof SortNode);
+    assertTrue(mergeSortNode.getChildren().get(2) instanceof ExchangeNode);
+    SortNode sortNode = (SortNode) mergeSortNode.getChildren().get(1);
+    assertTrue(sortNode.getChildren().get(0).getChildren().get(0) instanceof 
TableScanNode);
+    tableScanNode = (TableScanNode) 
sortNode.getChildren().get(0).getChildren().get(0);
+    assertEquals(4, tableScanNode.getDeviceEntries().size());
+    assertEquals(
+        Arrays.asList(
+            "table1.shanghai.B3.YY",
+            "table1.shenzhen.B2.ZZ",
+            "table1.shenzhen.B1.XX",
+            "table1.shanghai.A3.YY"),
+        tableScanNode.getDeviceEntries().stream()
+            .map(d -> d.getDeviceID().toString())
+            .collect(Collectors.toList()));
+    assertEquals(DESC, tableScanNode.getScanOrder());
   }
 
   // order by all_ids, time, others
@@ -169,7 +241,64 @@ public class SortTest {
   // order by others, some_ids, time
   @Test
   public void othersSomeIDColumnTimeSortTest() {
-    // TODO
+    sql =
+        "SELECT time, tag1, tag2, s1, s2, attr1 FROM table1 order by s1+s2 
desc, tag2 desc, tag1 asc, time desc";
+    context = new MPPQueryContext(sql, queryId, sessionInfo, null, null);
+    actualAnalysis = analyzeSQL(sql, metadata);
+    logicalQueryPlan =
+        new LogicalPlanner(context, metadata, sessionInfo, 
WarningCollector.NOOP)
+            .plan(actualAnalysis);
+    rootNode = logicalQueryPlan.getRootNode();
+
+    assertTrue(rootNode instanceof OutputNode);
+    assertTrue(rootNode.getChildren().get(0) instanceof SortNode);
+    assertTrue(rootNode.getChildren().get(0).getChildren().get(0) instanceof 
ProjectNode);
+    assertTrue(
+        rootNode.getChildren().get(0).getChildren().get(0).getChildren().get(0)
+            instanceof TableScanNode);
+    tableScanNode =
+        (TableScanNode) 
rootNode.getChildren().get(0).getChildren().get(0).getChildren().get(0);
+    assertEquals("testdb.table1", 
tableScanNode.getQualifiedObjectName().toString());
+    //    assertEquals(
+    //        Arrays.asList("time", "tag1", "tag2", "attr1", "s1", "s2"),
+    //        tableScanNode.getOutputColumnNames());
+    assertEquals(9, tableScanNode.getAssignments().size());
+    assertEquals(6, tableScanNode.getDeviceEntries().size());
+    assertEquals(5, tableScanNode.getIdAndAttributeIndexMap().size());
+
+    distributionPlanner = new TableDistributionPlanner(actualAnalysis, 
logicalQueryPlan, context);
+    distributedQueryPlan = distributionPlanner.plan();
+    assertEquals(3, distributedQueryPlan.getFragments().size());
+    assertTrue(
+        
distributedQueryPlan.getFragments().get(0).getPlanNodeTree().getChildren().get(0)
+            instanceof OutputNode);
+    OutputNode outputNode =
+        (OutputNode)
+            
distributedQueryPlan.getFragments().get(0).getPlanNodeTree().getChildren().get(0);
+    assertTrue(outputNode.getChildren().get(0) instanceof MergeSortNode);
+    MergeSortNode mergeSortNode = (MergeSortNode) 
outputNode.getChildren().get(0);
+    assertEquals(
+        Arrays.asList("(s1 + s2)", "tag2", "tag1", "time"),
+        mergeSortNode.getOrderingScheme().getOrderBy().stream()
+            .map(Symbol::getName)
+            .collect(Collectors.toList()));
+    assertTrue(mergeSortNode.getChildren().get(0) instanceof ExchangeNode);
+    assertTrue(mergeSortNode.getChildren().get(1) instanceof SortNode);
+    assertTrue(mergeSortNode.getChildren().get(2) instanceof ExchangeNode);
+    SortNode sortNode = (SortNode) mergeSortNode.getChildren().get(1);
+    assertTrue(sortNode.getChildren().get(0).getChildren().get(0) instanceof 
TableScanNode);
+    tableScanNode = (TableScanNode) 
sortNode.getChildren().get(0).getChildren().get(0);
+    assertEquals(4, tableScanNode.getDeviceEntries().size());
+    assertEquals(
+        Arrays.asList(
+            "table1.shanghai.B3.YY",
+            "table1.shenzhen.B1.XX",
+            "table1.shenzhen.B2.ZZ",
+            "table1.shanghai.A3.YY"),
+        tableScanNode.getDeviceEntries().stream()
+            .map(d -> d.getDeviceID().toString())
+            .collect(Collectors.toList()));
+    assertEquals(ASC, tableScanNode.getScanOrder());
   }
 
   // order by others, all_ids, time

Reply via email to