Author: shawkins
Date: 2011-05-04 16:38:13 -0400 (Wed, 04 May 2011)
New Revision: 3154
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java
Log:
TEIID-1577 refining the union merge fix
Modified:
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
---
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-05-04
20:26:28 UTC (rev 3153)
+++
branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java 2011-05-04
20:38:13 UTC (rev 3154)
@@ -279,25 +279,21 @@
}
}
}
-
- if (parentProject.getParent() != null
- && (parentProject.getParent().getType() != NodeConstants.Types.SET_OP
|| parentProject.getParent().getFirstChild() == parentProject)) {
- PlanNode sort = NodeEditor.findParent(parentProject, NodeConstants.Types.SORT,
NodeConstants.Types.SOURCE);
- if (sort != null) { //special handling is needed since we are retaining the
child aliases
- List<SingleElementSymbol> childProject =
(List<SingleElementSymbol>)NodeEditor.findNodePreOrder(frame,
NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
- OrderBy elements = (OrderBy)sort.getProperty(NodeConstants.Info.SORT_ORDER);
- for (OrderByItem item : elements.getOrderByItems()) {
- item.setSymbol(childProject.get(selectSymbols.indexOf(item.getSymbol())));
- }
- sort.getGroups().clear();
- sort.addGroups(GroupsUsedByElementsVisitor.getGroups(elements));
- }
- PlanNode parentSource = NodeEditor.findParent(parentProject,
NodeConstants.Types.SOURCE);
+
+ correctOrderBy(frame, selectSymbols, parentProject);
+ PlanNode parentSource = NodeEditor.findParent(frame, NodeConstants.Types.SOURCE);
+ PlanNode parentSetOp = NodeEditor.findParent(parentProject,
NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE);
+
+ if (parentSetOp == null || NodeEditor.findNodePreOrder(parentSetOp,
NodeConstants.Types.PROJECT) == parentProject) {
if (parentSource != null) {
FrameUtil.correctSymbolMap(((SymbolMap)frame.getProperty(NodeConstants.Info.SYMBOL_MAP)).asMap(),
parentSource);
}
+ if (parentSetOp != null) {
+ correctOrderBy(frame, selectSymbols, parentSetOp);
+ }
}
+ prepareFrame(frame);
//remove the parent project and the source node
NodeEditor.removeChildNode(parentProject, frame);
if (parentProject.getParent() == null) {
@@ -309,6 +305,20 @@
return root;
}
+
+ private static void correctOrderBy(PlanNode frame,
+ List<SingleElementSymbol> selectSymbols, PlanNode startNode) {
+ PlanNode sort = NodeEditor.findParent(startNode, NodeConstants.Types.SORT,
NodeConstants.Types.SOURCE | NodeConstants.Types.SET_OP);
+ if (sort != null) { //special handling is needed since we are retaining the child
aliases
+ List<SingleElementSymbol> childProject =
(List<SingleElementSymbol>)NodeEditor.findNodePreOrder(frame,
NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
+ OrderBy elements = (OrderBy)sort.getProperty(NodeConstants.Info.SORT_ORDER);
+ for (OrderByItem item : elements.getOrderByItems()) {
+ item.setSymbol(childProject.get(selectSymbols.indexOf(item.getSymbol())));
+ }
+ sort.getGroups().clear();
+ sort.addGroups(GroupsUsedByElementsVisitor.getGroups(elements));
+ }
+ }
/**
* Check to ensure that we are not projecting a subquery or null dependent
expressions
Modified:
branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java
===================================================================
---
branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java 2011-05-04
20:26:28 UTC (rev 3153)
+++
branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java 2011-05-04
20:38:13 UTC (rev 3154)
@@ -289,6 +289,24 @@
TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
}
+ @Test public void testSimpleMergeUnionSecondBranchWithOrderBy1() throws Exception {
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_UNION, true);
+ caps.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
+ caps.setCapabilitySupport(Capability.ROW_LIMIT, true);
+ caps.setCapabilitySupport(Capability.QUERY_SET_ORDER_BY, true);
+ caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
+ caps.setCapabilitySupport(Capability.QUERY_SELECT_DISTINCT, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ ProcessorPlan plan = TestOptimizer.helpPlan("select '1' as x, e2
from pm1.g1 union all (select e1, e2 from (select distinct e1, 1 as e2 from pm1.g2) as x
order by e1 limit 1) order by x", //$NON-NLS-1$
+ FakeMetadataFactory.example1Cached(), null,
capFinder,
+ new String[] {"SELECT '1' AS c_0,
pm1.g1.e2 AS c_1 FROM pm1.g1 UNION ALL (SELECT DISTINCT pm1.g2.e1 AS c_0, 1 AS c_1 FROM
pm1.g2 ORDER BY c_0 LIMIT 1) ORDER BY c_0"}, ComparisonMode.EXACT_COMMAND_STRING);
//$NON-NLS-1$
+
+ TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
+ }
+
/**
* Note that the merge is not performed since it would create an expression in the
group by clause
*/
@@ -337,6 +355,21 @@
assertTrue("Alias was not accounted for in sort node",
node.getElements().get(0).equals(node.getSortElements().get(0).getSymbol()));
//$NON-NLS-1$
}
+ @Test public void testSortAliasWithSameNameUnion() throws Exception {
+ String sql = "select e1 from (select distinct pm1.g1.e1 as e1 from pm1.g1) x
union all select e1 from pm1.g2 order by e1"; //$NON-NLS-1$
+
+ FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+ BasicSourceCapabilities caps = new BasicSourceCapabilities();
+ caps.setCapabilitySupport(Capability.QUERY_FROM_GROUP_ALIAS, true);
+ capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
+
+ RelationalPlan plan = (RelationalPlan)TestOptimizer.helpPlan(sql,
FakeMetadataFactory.example1Cached(),
+ new String[] {"SELECT g_0.e1 FROM pm1.g1 AS g_0", "SELECT g_0.e1
FROM pm1.g2 AS g_0"}, capFinder, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING);
//$NON-NLS-1$
+
+ SortNode node = (SortNode)plan.getRootNode();
+ assertTrue("Alias was not accounted for in sort node",
node.getElements().get(0).equals(node.getSortElements().get(0).getSymbol()));
//$NON-NLS-1$
+ }
+
@Test public void testMergeImplicitGroupBy() throws Exception {
BasicSourceCapabilities caps = TestAggregatePushdown.getAggregateCapabilities();
caps.setFunctionSupport("+", true); //$NON-NLS-1$