Author: shawkins
Date: 2009-05-12 22:17:35 -0400 (Tue, 12 May 2009)
New Revision: 925
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java
trunk/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestRulePushSelectCriteria.java
Log:
TEIID-584 preventing access nodes from being accidently pushed across an access node.
Modified:
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java 2009-05-13
01:45:00 UTC (rev 924)
+++
trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/RulePushSelectCriteria.java 2009-05-13
02:17:35 UTC (rev 925)
@@ -564,8 +564,13 @@
copyNode.setProperty(NodeConstants.Info.IS_HAVING, Boolean.TRUE);
}
- FrameUtil.convertNode(copyNode, sourceGroup, null, symbolMap.asMap());
- projectNode.getFirstChild().addAsParent(copyNode);
+ FrameUtil.convertNode(copyNode, sourceGroup, null, symbolMap.asMap());
+ PlanNode intermediateParent = NodeEditor.findParent(projectNode,
NodeConstants.Types.ACCESS, NodeConstants.Types.SOURCE | NodeConstants.Types.SET_OP);
+ if (intermediateParent != null) {
+ intermediateParent.addAsParent(copyNode);
+ } else {
+ projectNode.getFirstChild().addAsParent(copyNode);
+ }
return true;
}
Modified:
trunk/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestRulePushSelectCriteria.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestRulePushSelectCriteria.java 2009-05-13
01:45:00 UTC (rev 924)
+++
trunk/engine/src/test/java/com/metamatrix/query/optimizer/relational/rules/TestRulePushSelectCriteria.java 2009-05-13
02:17:35 UTC (rev 925)
@@ -22,27 +22,69 @@
package com.metamatrix.query.optimizer.relational.rules;
+import static org.junit.Assert.*;
+
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Test;
+import com.metamatrix.query.analysis.AnalysisRecord;
+import com.metamatrix.query.optimizer.TestOptimizer;
+import com.metamatrix.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import com.metamatrix.query.optimizer.relational.GenerateCanonical;
+import com.metamatrix.query.optimizer.relational.PlanHints;
+import com.metamatrix.query.optimizer.relational.RuleStack;
+import com.metamatrix.query.optimizer.relational.plantree.NodeConstants;
+import com.metamatrix.query.optimizer.relational.plantree.NodeEditor;
+import com.metamatrix.query.optimizer.relational.plantree.NodeFactory;
+import com.metamatrix.query.optimizer.relational.plantree.PlanNode;
+import com.metamatrix.query.optimizer.relational.plantree.NodeConstants.Info;
import com.metamatrix.query.parser.QueryParser;
+import com.metamatrix.query.sql.lang.Command;
import com.metamatrix.query.sql.symbol.ElementSymbol;
+import com.metamatrix.query.sql.symbol.GroupSymbol;
+import com.metamatrix.query.sql.symbol.SingleElementSymbol;
+import com.metamatrix.query.sql.util.SymbolMap;
+import com.metamatrix.query.unittest.FakeMetadataFacade;
+import com.metamatrix.query.unittest.FakeMetadataFactory;
+import com.metamatrix.query.util.CommandContext;
-public class TestRulePushSelectCriteria extends TestCase {
+public class TestRulePushSelectCriteria {
- public void testElementsInCritieria() throws Exception {
+ @Test public void testElementsInCritieria() throws Exception {
String criteria = "e1 = '1' OR ((e1 = '2' OR e1 =
'4') AND e2 = 3)"; //$NON-NLS-1$
Set<ElementSymbol> expected = new
HashSet<ElementSymbol>(Arrays.asList(new ElementSymbol("e1")));
//$NON-NLS-1$
assertEquals(expected,
RulePushSelectCriteria.getElementsIncriteria(QueryParser.getQueryParser().parseCriteria(criteria)));
}
- public void testElementsInCritieria1() throws Exception {
+ @Test public void testElementsInCritieria1() throws Exception {
String criteria = "e1 = '1' and ((e1 = '2' OR e1 =
'4') AND e2 = 3) or e2 is null"; //$NON-NLS-1$
Set<ElementSymbol> expected = new
HashSet<ElementSymbol>(Arrays.asList(new ElementSymbol("e2")));
//$NON-NLS-1$
assertEquals(expected,
RulePushSelectCriteria.getElementsIncriteria(QueryParser.getQueryParser().parseCriteria(criteria)));
}
+
+ @Test public void testPushAcrossFrameWithAccessNode() throws Exception {
+ FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
+ Command command = TestOptimizer.helpGetCommand("select * from (select * from
pm1.g1 union select * from pm1.g2) x where e1 = 1", metadata, null); //$NON-NLS-1$
+ Command subCommand = TestOptimizer.helpGetCommand("select * from pm1.g1 union
select * from pm1.g2", metadata, null); //$NON-NLS-1$
+ PlanNode root = GenerateCanonical.generatePlan(command, new PlanHints(), metadata);
+ PlanNode child = GenerateCanonical.generatePlan(subCommand, new PlanHints(),
metadata);
+ PlanNode sourceNode = NodeEditor.findNodePreOrder(root,
NodeConstants.Types.SOURCE);
+ sourceNode.addFirstChild(child);
+ sourceNode.setProperty(NodeConstants.Info.SYMBOL_MAP,
SymbolMap.createSymbolMap(sourceNode.getGroups().iterator().next(),
(List<SingleElementSymbol>)child.getFirstChild().getProperty(Info.PROJECT_COLS)));
+ //add a dummy access node
+ PlanNode accessNode = NodeFactory.getNewNode(NodeConstants.Types.ACCESS);
+ accessNode.addGroups(child.getFirstChild().getGroups());
+ child.getFirstChild().addAsParent(accessNode);
+
+ new RulePushSelectCriteria().execute(root, metadata, new
DefaultCapabilitiesFinder(), new RuleStack(), AnalysisRecord.createNonRecordingRecord(),
new CommandContext());
+ // the select node should still be above the access node
+ accessNode = NodeEditor.findNodePreOrder(root, NodeConstants.Types.ACCESS);
+ assertEquals(NodeConstants.Types.SELECT, accessNode.getParent().getType());
+ assertNull(NodeEditor.findNodePreOrder(accessNode, NodeConstants.Types.SELECT));
+ }
}
Show replies by date