Author: shawkins
Date: 2010-12-22 20:51:14 -0500 (Wed, 22 Dec 2010)
New Revision: 2792
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
Log:
TEIID-1376 ensuring that merging will not invalidate the partition info
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java 2010-12-22
16:13:59 UTC (rev 2791)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PartitionAnalyzer.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -23,6 +23,7 @@
package org.teiid.query.optimizer.relational;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -35,6 +36,7 @@
import java.util.TreeSet;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.query.sql.lang.CompareCriteria;
import org.teiid.query.sql.lang.Criteria;
import org.teiid.query.sql.lang.Query;
import org.teiid.query.sql.lang.QueryCommand;
@@ -114,8 +116,20 @@
private static Map<ElementSymbol, Set<Constant>> extractPartitionInfo(Query
query, List<ElementSymbol> projectedSymbols) {
List<SingleElementSymbol> projected = query.getSelect().getProjectedSymbols();
List<Criteria> crits = Criteria.separateCriteriaByAnd(query.getCriteria());
- Map<Expression, TreeSet<Constant>> inMap = new HashMap<Expression,
TreeSet<Constant>>();
+ Map<Expression, Set<Constant>> inMap = new HashMap<Expression,
Set<Constant>>();
for (Criteria criteria : crits) {
+ if (criteria instanceof CompareCriteria) {
+ CompareCriteria cc = (CompareCriteria)criteria;
+ if (cc.getOperator() != CompareCriteria.EQ) {
+ continue;
+ }
+ if (cc.getLeftExpression() instanceof Constant) {
+ inMap.put(cc.getRightExpression(), new
TreeSet<Constant>(Arrays.asList((Constant)cc.getLeftExpression())));
+ } else if (cc.getRightExpression() instanceof Constant) {
+ inMap.put(cc.getLeftExpression(), new
TreeSet<Constant>(Arrays.asList((Constant)cc.getRightExpression())));
+ }
+ continue;
+ }
if (!(criteria instanceof SetCriteria)) {
continue;
}
@@ -143,7 +157,7 @@
if (ex instanceof Constant) {
result.put(projectedSymbols.get(i), Collections.singleton((Constant)ex));
} else {
- TreeSet<Constant> values = inMap.get(ex);
+ Set<Constant> values = inMap.get(ex);
if (values != null) {
result.put(projectedSymbols.get(i), values);
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-12-22
16:13:59 UTC (rev 2791)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -117,7 +117,7 @@
// Source node properties
SYMBOL_MAP, // SymbolMap
- PARTITION_INFO, // Map<ElementSymbol, List<Set<Constant>>>
+ PARTITION_INFO, // Map<ElementSymbol, List<Set<Constant>>> -
it will only be consistent in the initial stages of planning
VIRTUAL_COMMAND, // Command
MAKE_DEP, // ??? List of Groups ???
PROCESSOR_PLAN, // ProcessorPlan for non-relational sub plan
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2010-12-22
16:13:59 UTC (rev 2791)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -41,6 +41,7 @@
import org.teiid.query.optimizer.relational.plantree.NodeConstants;
import org.teiid.query.optimizer.relational.plantree.NodeEditor;
import org.teiid.query.optimizer.relational.plantree.PlanNode;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
import org.teiid.query.sql.lang.JoinType;
import org.teiid.query.sql.lang.OrderBy;
import org.teiid.query.sql.lang.OrderByItem;
@@ -68,10 +69,10 @@
CommandContext context) throws QueryPlannerException,
QueryMetadataException,
TeiidComponentException {
-
+ boolean beforeDecomposeJoin = rules.contains(RuleConstants.DECOMPOSE_JOIN);
for (PlanNode sourceNode : NodeEditor.findAllNodes(plan,
NodeConstants.Types.SOURCE)) {
if (sourceNode.getChildCount() > 0) {
- plan = doMerge(sourceNode, plan, metadata);
+ plan = doMerge(sourceNode, plan, beforeDecomposeJoin, metadata);
}
}
@@ -79,7 +80,7 @@
}
static PlanNode doMerge(PlanNode frame,
- PlanNode root,
+ PlanNode root, boolean beforeDecomposeJoin,
QueryMetadataInterface metadata) throws
QueryPlannerException, QueryMetadataException, TeiidComponentException {
GroupSymbol virtualGroup = frame.getGroups().iterator().next();
@@ -149,6 +150,13 @@
|| NodeEditor.findNodePreOrder(frame.getFirstChild(),
NodeConstants.Types.GROUP, NodeConstants.Types.SOURCE
| NodeConstants.Types.JOIN) != null
|| NodeEditor.findAllNodes(frame.getFirstChild(), NodeConstants.Types.SOURCE,
NodeConstants.Types.SOURCE).isEmpty()) {
+
+ PlanNode parentSource = NodeEditor.findParent(parentProject,
NodeConstants.Types.SOURCE);
+ if (beforeDecomposeJoin && parentSource != null &&
parentSource.hasProperty(Info.PARTITION_INFO)
+ && !NodeEditor.findAllNodes(frame.getFirstChild(),
NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE).isEmpty()) {
+ return root; //don't bother to merge until after
+ }
+
return checkForSimpleProjection(frame, root, parentProject, metadata);
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-22
16:13:59 UTC (rev 2791)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushAggregates.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -272,7 +272,7 @@
LinkedList<PlanNode> unionChildren, SymbolMap parentMap, CommandContext context,
QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws
QueryPlannerException, QueryMetadataException, TeiidComponentException {
// remove the group node
groupNode.getParent().replaceChild(groupNode, groupNode.getFirstChild());
- GroupSymbol group = sourceNode.getGroups().iterator().next();
+ GroupSymbol group = sourceNode.getGroups().iterator().next().clone();
boolean first = true;
List<SingleElementSymbol> symbols = null;
@@ -306,11 +306,11 @@
}
}
}
-
- SymbolMap symbolMap = createSymbolMap(group, symbols, sourceNode, metadata);
+ GroupSymbol modifiedGroup = group.clone();
+ SymbolMap symbolMap = createSymbolMap(modifiedGroup, symbols, sourceNode, metadata);
sourceNode.setProperty(Info.SYMBOL_MAP, symbolMap);
- FrameUtil.convertFrame(sourceNode, group, Collections.singleton(group),
symbolMap.inserseMapping(), metadata);
+ FrameUtil.convertFrame(sourceNode, group, Collections.singleton(modifiedGroup),
symbolMap.inserseMapping(), metadata);
}
private boolean canPushGroupByToUnionChild(QueryMetadataInterface metadata,
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2010-12-22
16:13:59 UTC (rev 2791)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseNull.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -203,7 +203,7 @@
PlanNode sourceNode = NodeEditor.findParent(grandParent.getFirstChild(),
NodeConstants.Types.SOURCE, NodeConstants.Types.SET_OP);
if (sourceNode != null) {
- return RuleMergeVirtual.doMerge(sourceNode, rootNode, metadata);
+ return RuleMergeVirtual.doMerge(sourceNode, rootNode, false,
metadata);
}
return null;
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-22
16:13:59 UTC (rev 2791)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java 2010-12-23
01:51:14 UTC (rev 2792)
@@ -230,5 +230,29 @@
});
}
-
+ @Test public void testUnionPartitionedWithMerge() throws Exception {
+ //"select max(intnum) from (select * from (SELECT IntKey, intnum FROM
BQT1.SmallA where intkey in (1, 2) UNION ALL SELECT intkey, intnum FROM BQT2.SmallA where
intkey in (3, 4)) A where intkey in (1, 2, 3, 4) UNION ALL select intkey, intnum from
bqt2.smallb where intkey in 6) B group by intkey"
+ ProcessorPlan plan = TestOptimizer.helpPlan("select * from (select * from
(SELECT IntKey, intnum FROM BQT1.SmallA UNION ALL SELECT intkey, intnum FROM BQT2.SmallA)
A where intkey in (1, 2, 3, 4) UNION ALL select intkey, intnum from bqt2.smallb where
intkey in (6)) B inner join (SELECT IntKey, intnum FROM BQT1.SmallA where intkey in (1, 2)
UNION ALL SELECT intkey, intnum FROM BQT2.SmallA where intkey in (5, 6)) C on b.intkey =
c.intkey", FakeMetadataFactory.exampleBQTCached(), null,
TestInlineView.getInliveViewCapabilitiesFinder(),//$NON-NLS-1$
+ new String[] { "SELECT g_0.intkey, g_0.intnum FROM BQT2.SmallA AS g_0
WHERE g_0.intkey IN (1, 2)",
+ "SELECT g_0.IntKey, g_0.intnum FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey IN
(1, 2)",
+ "SELECT g_1.IntKey, g_1.IntNum, g_0.intkey, g_0.intnum FROM bqt2.smallb AS
g_0, BQT2.SmallA AS g_1 WHERE (g_0.intkey = g_1.IntKey) AND (g_0.intkey = 6) AND
(g_1.IntKey = 6)",
+ "SELECT g_0.IntKey AS c_0, g_0.IntNum AS c_1 FROM BQT1.SmallA AS g_0 WHERE
g_0.IntKey IN (1, 2) ORDER BY c_0" }, ComparisonMode.EXACT_COMMAND_STRING);
+
+ TestOptimizer.checkNodeTypes(plan, new int[] {
+ 4, // Access
+ 0, // DependentAccess
+ 0, // DependentSelect
+ 0, // DependentProject
+ 0, // DupRemove
+ 0, // Grouping
+ 0, // NestedLoopJoinStrategy
+ 1, // MergeJoinStrategy
+ 0, // Null
+ 0, // PlanExecution
+ 1, // Project
+ 0, // Select
+ 0, // Sort
+ 2 // UnionAll
+ });
+ }
}