Author: shawkins
Date: 2009-04-28 18:25:48 -0400 (Tue, 28 Apr 2009)
New Revision: 849
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePlanSorts.java
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortUtility.java
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/TupleCollector.java
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestLimit.java
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptionalJoins.java
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestSortOptimization.java
Log:
TEIID-178, TEIID-175 adding support for a non blocking sort and general planning time
sort optimization.
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/PlanToProcessConverter.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -66,7 +66,6 @@
import com.metamatrix.query.processor.relational.MergeJoinStrategy.SortOption;
import com.metamatrix.query.processor.relational.SortUtility.Mode;
import com.metamatrix.query.resolver.util.ResolverUtil;
-import com.metamatrix.query.sql.LanguageObject;
import com.metamatrix.query.sql.lang.Command;
import com.metamatrix.query.sql.lang.Criteria;
import com.metamatrix.query.sql.lang.JoinType;
@@ -150,7 +149,6 @@
throws QueryPlannerException, MetaMatrixComponentException {
RelationalNode processNode = null;
- LanguageObject possiblyDependentObject = null;
switch(node.getType()) {
case NodeConstants.Types.PROJECT:
@@ -213,7 +211,6 @@
}
Criteria joinCrit = Criteria.combineCriteria(joinCrits);
jnode.setJoinCriteria(joinCrit);
- possiblyDependentObject = joinCrit;
processNode = jnode;
@@ -230,8 +227,6 @@
Criteria crit =
(Criteria)node.getProperty(NodeConstants.Info.PROCEDURE_CRITERIA);
- possiblyDependentObject = crit;
-
if (crit != null) {
List references =
(List)node.getProperty(NodeConstants.Info.PROCEDURE_INPUTS);
List defaults =
(List)node.getProperty(NodeConstants.Info.PROCEDURE_DEFAULTS);
@@ -247,7 +242,6 @@
} else {
AccessNode aNode = null;
Command command = (Command)
node.getProperty(NodeConstants.Info.ATOMIC_REQUEST);
- possiblyDependentObject = command;
Object modelID = node.getProperty(NodeConstants.Info.MODEL_ID);
if(node.hasBooleanProperty(NodeConstants.Info.IS_DEPENDENT_SET)) {
@@ -287,8 +281,7 @@
try {
if (command instanceof Query) {
processNode = correctProjectionForTempTable(node,
- aNode,
-
possiblyDependentObject);
+ aNode);
}
} catch (QueryMetadataException err) {
throw new MetaMatrixComponentException(err);
@@ -314,7 +307,6 @@
SelectNode selnode = new SelectNode(getID());
selnode.setCriteria(crit);
processNode = selnode;
- possiblyDependentObject = crit;
break;
@@ -337,7 +329,7 @@
case NodeConstants.Types.GROUP:
GroupingNode gnode = new GroupingNode(getID());
gnode.setGroupingElements( (List) node.getProperty(NodeConstants.Info.GROUP_COLS) );
-
+ gnode.setRemoveDuplicates(node.hasBooleanProperty(NodeConstants.Info.IS_DUP_REMOVAL));
processNode = gnode;
break;
@@ -397,15 +389,14 @@
}
if(processNode != null) {
- processNode = prepareToAdd(node, processNode, possiblyDependentObject);
+ processNode = prepareToAdd(node, processNode);
}
return processNode;
}
private RelationalNode correctProjectionForTempTable(PlanNode node,
- AccessNode aNode,
- LanguageObject
possiblyDependentObject) throws QueryMetadataException,
+ AccessNode aNode) throws
QueryMetadataException,
MetaMatrixComponentException {
if (node.getGroups().size() != 1) {
return aNode;
@@ -425,15 +416,14 @@
pnode.setSelectSymbols(projectSymbols);
//if the following cast fails it means that we have a dependent temp table - that
is not yet possible
- aNode = (AccessNode)prepareToAdd(node, aNode, possiblyDependentObject);
+ aNode = (AccessNode)prepareToAdd(node, aNode);
node.setProperty(NodeConstants.Info.OUTPUT_COLS, projectSymbols);
pnode.addChild(aNode);
return pnode;
}
private RelationalNode prepareToAdd(PlanNode node,
- RelationalNode processNode,
- LanguageObject possiblyDependentObject) {
+ RelationalNode processNode) {
// Set the output elements from the plan node
List cols = (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RuleImplementJoinStrategy.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -43,6 +43,7 @@
import com.metamatrix.query.optimizer.relational.plantree.NodeFactory;
import com.metamatrix.query.optimizer.relational.plantree.PlanNode;
import com.metamatrix.query.processor.relational.MergeJoinStrategy.SortOption;
+import com.metamatrix.query.sql.lang.JoinType;
import com.metamatrix.query.sql.lang.OrderBy;
import com.metamatrix.query.sql.symbol.SingleElementSymbol;
import com.metamatrix.query.util.CommandContext;
@@ -66,10 +67,23 @@
for (PlanNode joinNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.JOIN,
NodeConstants.Types.ACCESS)) {
JoinStrategyType stype = (JoinStrategyType)
joinNode.getProperty(NodeConstants.Info.JOIN_STRATEGY);
- if (JoinStrategyType.MERGE.equals(stype)) {
- insertSort(joinNode.getFirstChild(), (List<SingleElementSymbol>)
joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS), joinNode, metadata,
capabilitiesFinder);
- insertSort(joinNode.getLastChild(), (List<SingleElementSymbol>)
joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS), joinNode, metadata,
capabilitiesFinder);
+ if (!JoinStrategyType.MERGE.equals(stype)) {
+ continue;
}
+/* if (joinNode.getProperty(NodeConstants.Info.JOIN_TYPE) ==
JoinType.JOIN_INNER) {
+ //there is a possible optimization at runtime here based upon the
cardinality
+ float leftCost =
NewCalculateCostUtil.computeCostForTree(joinNode.getFirstChild(), metadata);
+ float rightCost =
NewCalculateCostUtil.computeCostForTree(joinNode.getLastChild(), metadata);
+ if (leftCost != NewCalculateCostUtil.UNKNOWN_VALUE && leftCost <
context.getProcessorBatchSize() * context.getProcessorBatchSize()
+ && rightCost != NewCalculateCostUtil.UNKNOWN_VALUE &&
rightCost > context.getProcessorBatchSize()) {
+ joinNode.setProperty(NodeConstants.Info.SORT_LEFT, SortOption.SORT);
+ joinNode.setProperty(NodeConstants.Info.SORT_RIGHT,
SortOption.SORT);
+ continue;
+ }
+ }
+*/
+ insertSort(joinNode.getFirstChild(), (List<SingleElementSymbol>)
joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS), joinNode, metadata,
capabilitiesFinder);
+ insertSort(joinNode.getLastChild(), (List<SingleElementSymbol>)
joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS), joinNode, metadata,
capabilitiesFinder);
}
return plan;
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePlanSorts.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePlanSorts.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePlanSorts.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -22,6 +22,8 @@
package com.metamatrix.query.optimizer.relational.rules;
+import java.util.List;
+
import com.metamatrix.api.exception.MetaMatrixComponentException;
import com.metamatrix.api.exception.query.QueryMetadataException;
import com.metamatrix.api.exception.query.QueryPlannerException;
@@ -34,7 +36,9 @@
import com.metamatrix.query.optimizer.relational.plantree.NodeConstants;
import com.metamatrix.query.optimizer.relational.plantree.NodeEditor;
import com.metamatrix.query.optimizer.relational.plantree.PlanNode;
+import com.metamatrix.query.optimizer.relational.plantree.NodeConstants.Info;
import com.metamatrix.query.processor.relational.MergeJoinStrategy.SortOption;
+import com.metamatrix.query.sql.lang.JoinType;
import com.metamatrix.query.sql.lang.SetQuery;
import com.metamatrix.query.util.CommandContext;
@@ -49,11 +53,10 @@
AnalysisRecord analysisRecord, CommandContext context)
throws QueryPlannerException, QueryMetadataException,
MetaMatrixComponentException {
- optimizeSorts(false, plan);
- return plan;
+ return optimizeSorts(false, plan, plan);
}
- private void optimizeSorts(boolean parentBlocking, PlanNode node) {
+ private PlanNode optimizeSorts(boolean parentBlocking, PlanNode node, PlanNode root) {
node = NodeEditor.findNodePreOrder(node,
NodeConstants.Types.SORT
| NodeConstants.Types.DUP_REMOVE
@@ -61,7 +64,7 @@
| NodeConstants.Types.JOIN
| NodeConstants.Types.SET_OP, NodeConstants.Types.ACCESS);
if (node == null) {
- return;
+ return root;
}
switch (node.getType()) {
case NodeConstants.Types.SORT:
@@ -72,6 +75,33 @@
if (mergeSortWithDupRemoval(node)) {
node.setProperty(NodeConstants.Info.IS_DUP_REMOVAL, true);
}
+ List orderColumns = (List)node.getProperty(NodeConstants.Info.SORT_ORDER);
+ PlanNode possibleSort = NodeEditor.findNodePreOrder(node, NodeConstants.Types.GROUP |
NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE | NodeConstants.Types.ACCESS);
+ if (possibleSort != null) {
+ NodeConstants.Info expr = Info.GROUP_COLS;
+ if (possibleSort.getType() == NodeConstants.Types.JOIN) {
+ if (possibleSort.getProperty(NodeConstants.Info.JOIN_STRATEGY) !=
JoinStrategyType.MERGE
+ || possibleSort.getProperty(NodeConstants.Info.JOIN_TYPE) != JoinType.JOIN_INNER)
{
+ break;
+ }
+ expr = Info.LEFT_EXPRESSIONS;
+ }
+ List exprs = (List)possibleSort.getProperty(expr);
+ if (exprs != null && exprs.containsAll(orderColumns)) {
+ exprs.removeAll(orderColumns);
+ orderColumns.addAll(exprs);
+ possibleSort.setProperty(expr, orderColumns);
+ if (node.getParent() == null) {
+ root = node.getFirstChild();
+ root.removeFromParent();
+ node = root;
+ } else {
+ PlanNode nextNode = node.getFirstChild();
+ NodeEditor.removeChildNode(node.getParent(), node);
+ node = nextNode;
+ }
+ }
+ }
break;
case NodeConstants.Types.DUP_REMOVE:
if (parentBlocking) {
@@ -80,6 +110,12 @@
}
break;
case NodeConstants.Types.GROUP:
+ if (!node.hasCollectionProperty(NodeConstants.Info.GROUP_COLS)) {
+ break;
+ }
+ if (mergeSortWithDupRemovalAcrossSource(node)) {
+ node.setProperty(NodeConstants.Info.IS_DUP_REMOVAL, true);
+ }
//TODO: check the join interesting order
parentBlocking = true;
break;
@@ -87,13 +123,20 @@
if (node.getProperty(NodeConstants.Info.JOIN_STRATEGY) != JoinStrategyType.MERGE) {
break;
}
+ /*
+ * Look under the left and the right sources for a dup removal operation
+ * join
+ * [project]
+ * source
+ * dup remove | union not all
+ */
parentBlocking = true;
PlanNode toTest = node.getFirstChild();
- if (mergeSortWithDupRemovalForJoin(toTest)) {
+ if (mergeSortWithDupRemovalAcrossSource(toTest)) {
node.setProperty(NodeConstants.Info.SORT_LEFT, SortOption.SORT_DISTINCT);
}
toTest = node.getLastChild();
- if (mergeSortWithDupRemovalForJoin(toTest)) {
+ if (mergeSortWithDupRemovalAcrossSource(toTest)) {
node.setProperty(NodeConstants.Info.SORT_RIGHT, SortOption.SORT_DISTINCT);
}
break;
@@ -107,18 +150,12 @@
break;
}
for (PlanNode child : node.getChildren()) {
- optimizeSorts(parentBlocking, child);
+ root = optimizeSorts(parentBlocking, child, root);
}
+ return root;
}
- /**
- * Look under the left and the right sources for a dup removal operation
- * join
- * [project]
- * source
- * dup remove | union not all
- */
- private boolean mergeSortWithDupRemovalForJoin(PlanNode toTest) {
+ private boolean mergeSortWithDupRemovalAcrossSource(PlanNode toTest) {
PlanNode source = NodeEditor.findNodePreOrder(toTest, NodeConstants.Types.SOURCE,
NodeConstants.Types.ACCESS | NodeConstants.Types.JOIN);
return source != null && mergeSortWithDupRemoval(source);
}
Modified:
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/GroupingNode.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -59,6 +59,7 @@
// Grouping columns set by the planner
private List sortElements;
private List sortTypes;
+ private boolean removeDuplicates;
// Collection phase
private int phase = COLLECTION;
@@ -112,6 +113,10 @@
lastRow = null;
currentGroupTuple = null;
}
+
+ public void setRemoveDuplicates(boolean removeDuplicates) {
+ this.removeDuplicates = removeDuplicates;
+ }
/**
* Called by the planner to initialize the grouping node. Set the list of grouping
@@ -306,7 +311,7 @@
this.phase = GROUP;
} else {
this.sortUtility = new SortUtility(collectionID, sortElements,
- sortTypes, false, getBufferManager(),
+ sortTypes, removeDuplicates,
getBufferManager(),
getConnectionID());
this.phase = SORT;
}
@@ -446,6 +451,7 @@
super.copy(this, clonedNode);
clonedNode.sortElements = sortElements;
clonedNode.sortTypes = sortTypes;
+ clonedNode.removeDuplicates = removeDuplicates;
return clonedNode;
}
@@ -465,6 +471,8 @@
}
props.put(PROP_GROUP_COLS, groupCols);
}
+
+ props.put(PROP_REMOVE_DUPS, this.removeDuplicates);
return props;
}
Modified:
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortNode.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -115,6 +115,8 @@
private void collectionPhase() throws BlockedException, TupleSourceNotFoundException,
MetaMatrixComponentException, MetaMatrixProcessingException {
try {
collector.collectTuples();
+ } catch (BlockedOnMemoryException e) {
+ throw e;
} catch (BlockedException e) {
if (mode != Mode.DUP_REMOVE || !collector.collectedAny()) {
throw e;
Modified:
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortUtility.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortUtility.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/SortUtility.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -72,6 +72,7 @@
private Comparator comparator;
private TupleSourceID outputID;
+ private IndexedTupleSource outTs;
private boolean doneReading;
private int sortPhaseRow = 1;
private int phase = INITIAL_SORT;
@@ -237,7 +238,8 @@
}
protected void mergePhase() throws BlockedOnMemoryException,
MetaMatrixComponentException, TupleSourceNotFoundException {
- TupleCollector outCollector = null;
+ appendOutput();
+ TupleCollector tempCollector = null;
while(this.activeTupleIDs.size() > 1) {
// Load and pin batch from sorted sublists while memory available
this.workingBatches = new
ArrayList<TupleBatch>(activeTupleIDs.size());
@@ -297,11 +299,11 @@
// Output the row and update pointers
collector.addTuple(currentRow);
if (this.outputID != null && chosenBatchIndex != masterSortIndex
&& sortedIndex > masterSortIndex) {
- if (outCollector == null) {
+ if (tempCollector == null) {
tempOutId = createTupleSource();
- outCollector = new TupleCollector(tempOutId, this.bufferManager);
+ tempCollector = new TupleCollector(tempOutId, this.bufferManager);
}
- outCollector.addTuple(currentRow);
+ tempCollector.addTuple(currentRow);
}
incrementWorkingBatch(chosenBatchIndex, chosenBatch);
}
@@ -325,19 +327,11 @@
}
}
- if (outCollector != null) {
- outCollector.close();
- //transfer the new dup removed tuples to the output id
- TupleCollector tc = new TupleCollector(outputID, this.bufferManager);
- IndexedTupleSource ts =
this.bufferManager.getTupleSource(outCollector.getTupleSourceID());
- try {
- while (ts.hasNext()) {
- tc.addTuple(ts.nextTuple());
- }
- } catch (MetaMatrixProcessingException e) {
- throw new MetaMatrixComponentException(e);
- }
- }
+ if (tempCollector != null) {
+ tempCollector.close();
+ this.outTs = this.bufferManager.getTupleSource(tempOutId);
+ appendOutput();
+ }
// Close sorted source (all others have been removed)
if (doneReading) {
@@ -355,6 +349,27 @@
this.phase = INITIAL_SORT;
}
+ private void appendOutput() throws TupleSourceNotFoundException,
+ MetaMatrixComponentException {
+ if (this.outTs != null) {
+ //transfer the new dup removed tuples to the output id
+ TupleCollector tc = new TupleCollector(outputID, this.bufferManager);
+ try {
+ try {
+ while (outTs.hasNext()) {
+ tc.addTuple(outTs.nextTuple());
+ }
+ } catch (MetaMatrixProcessingException e) {
+ throw new MetaMatrixComponentException(e);
+ }
+ } catch (BlockedOnMemoryException e) {
+ tc.saveBatch(false);
+ throw e;
+ }
+ outTs = null;
+ }
+ }
+
/**
* Increment the working batch at batchIndex. The currentBatch is the currentBatch
* for that batchIndex, which we already happen to have. Return whether the batch
Modified:
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/TupleCollector.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/TupleCollector.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/main/java/com/metamatrix/query/processor/relational/TupleCollector.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -35,11 +35,13 @@
public class TupleCollector {
private TupleSourceID tsid;
+ private BufferManager bm;
+ private boolean captureBounds;
private int batchSize;
private ArrayList<List<?>> batch;
private int index;
- private BufferManager bm;
+ private ArrayList<List<?>> bounds;
public TupleCollector(TupleSourceID tsid, BufferManager bm) throws
TupleSourceNotFoundException, MetaMatrixComponentException {
this.tsid = tsid;
@@ -48,6 +50,10 @@
this.index = bm.getRowCount(tsid) + 1;
}
+ public void setCaptureBounds(boolean captureBounds) {
+ this.captureBounds = captureBounds;
+ }
+
public TupleSourceID getTupleSourceID() {
return tsid;
}
@@ -70,7 +76,13 @@
return;
}
toSave = new ArrayList<List<?>>(0);
- }
+ } /*else if (captureBounds) {
+ if (bounds.isEmpty()) {
+ bounds.add(toSave.get(0));
+ }
+ if (bounds )
+ bounds.add(toSave.get(toSave.size() -1));
+ }*/
TupleBatch tb = new TupleBatch(index, toSave);
tb.setTerminationFlag(isLast);
this.bm.addTupleBatch(tsid, tb);
Modified: trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestLimit.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestLimit.java 2009-04-28
21:30:50 UTC (rev 848)
+++ trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestLimit.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -742,7 +742,7 @@
0, // PlanExecution
1, // Project
0, // Select
- 1, // Sort
+ 0, // Sort
0 // UnionAll
}, NODE_TYPES);
Modified: trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptimizer.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -304,7 +304,7 @@
if (shouldSucceed) {
try {
//do planning
- plan = QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord,
null);
+ plan = QueryOptimizer.optimizePlan(command, md, null, capFinder, analysisRecord, new
CommandContext());
} catch (Throwable e) {
throw new MetaMatrixRuntimeException(e);
Modified:
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptionalJoins.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptionalJoins.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestOptionalJoins.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -78,7 +78,7 @@
public void testOptionalJoinNode3_1() {
ProcessorPlan plan = TestOptimizer.helpPlan("SELECT pm1.g1.e1, pm2.g2.e1
FROM pm1.g1 LEFT OUTER JOIN /* optional */ pm2.g2 on pm1.g1.e1 = pm2.g2.e1",
FakeMetadataFactory.example1Cached(), //$NON-NLS-1$
- new String[] {"SELECT g_0.e1 AS c_0 FROM pm2.g2 AS g_0 ORDER BY
c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0"} );
//$NON-NLS-1$
+ new String[] {"SELECT g_0.e1 AS c_0 FROM pm2.g2 AS g_0 ORDER BY
c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0"} );
//$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
Modified:
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestSortOptimization.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestSortOptimization.java 2009-04-28
21:30:50 UTC (rev 848)
+++
trunk/engine/src/test/java/com/metamatrix/query/optimizer/TestSortOptimization.java 2009-04-28
22:25:48 UTC (rev 849)
@@ -107,5 +107,65 @@
});
checkNodeTypes(plan, new int[] {0}, new Class[] {DupRemoveSortNode.class});
}
+
+ @Test public void testGroupDupCombination() {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+ // Create query
+ String sql = "select max(e1), e2 from (select distinct e1, e2 from pm1.g1) x
group by e2"; //$NON-NLS-1$
+
+ ProcessorPlan plan = helpPlan(sql, FakeMetadataFactory.example1Cached(), null,
capFinder,
+ new String[] {"SELECT pm1.g1.e1, pm1.g1.e2
FROM pm1.g1"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$
+
+ checkNodeTypes(plan, new int[] {
+ 1, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+ checkNodeTypes(plan, new int[] {0}, new Class[] {DupRemoveSortNode.class});
+ }
+
+ @Test public void testSortGroupCombination() {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ // Create query
+ String sql = "select max(e1), e2 from pm1.g1 x group by e2 order by
e2"; //$NON-NLS-1$
+
+ ProcessorPlan plan = helpPlan(sql, FakeMetadataFactory.example1Cached(), null,
capFinder,
+ new String[] {"SELECT pm1.g1.e2, pm1.g1.e1
FROM pm1.g1"}, TestOptimizer.SHOULD_SUCCEED); //$NON-NLS-1$
+
+ checkNodeTypes(plan, new int[] {
+ 1, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 1, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 0, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 0 // UnionAll
+ });
+ checkNodeTypes(plan, new int[] {0}, new Class[] {DupRemoveSortNode.class});
+ }
+
}