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