[teiid-commits] teiid SVN: r3781 - in branches/7.6.x/engine/src: main/java/org/teiid/query/optimizer/relational/rules and 1 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Sat Jan 7 11:10:30 EST 2012


Author: shawkins
Date: 2012-01-07 11:10:27 -0500 (Sat, 07 Jan 2012)
New Revision: 3781

Modified:
   branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
   branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java
   branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
Log:
TEIID-1893 fix for invalid output columns

Modified: branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-01-06 20:53:01 UTC (rev 3780)
+++ branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-01-07 16:10:27 UTC (rev 3781)
@@ -408,7 +408,7 @@
         
         rules.push(RuleConstants.PLAN_SORTS);
         
-        //TODO: update plan sorts to take advantage or semi-join ordering
+        //TODO: update plan sorts to take advantage of semi-join ordering
         if (hints.hasJoin || hints.hasCriteria) {
             rules.push(new RuleMergeCriteria(idGenerator, capFinder, analysisRecord, context, metadata));
         }
@@ -431,9 +431,7 @@
             rules.push(new RulePushAggregates(idGenerator));
         }
         if(hints.hasJoin) {
-            rules.push(RuleConstants.CHOOSE_DEPENDENT);
-        }
-        if(hints.hasJoin) {
+        	rules.push(RuleConstants.CHOOSE_DEPENDENT);
             rules.push(RuleConstants.CHOOSE_JOIN_STRATEGY);
             rules.push(RuleConstants.RAISE_ACCESS);
             //after planning the joins, let the criteria be pushed back into place
@@ -444,8 +442,9 @@
         if (hints.hasSetQuery) {
             rules.push(RuleConstants.PLAN_UNIONS);
         } 
-        if(hints.hasCriteria || hints.hasJoin) {
+        if(hints.hasCriteria || hints.hasJoin || hints.hasVirtualGroups) {
             //after copy criteria, it is no longer necessary to have phantom criteria nodes, so do some cleaning
+        	//also remove possible erroneous output elements
             rules.push(RuleConstants.CLEAN_CRITERIA);
         }
         if(hints.hasJoin) {

Modified: branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
===================================================================
--- branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java	2012-01-06 20:53:01 UTC (rev 3780)
+++ branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java	2012-01-07 16:10:27 UTC (rev 3781)
@@ -310,10 +310,14 @@
 			QueryMetadataInterface metadata, float cost)
 			throws QueryMetadataException, TeiidComponentException {
 		PlanNode projectNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.PROJECT);
+		float result = cost;
 		if (projectNode != null) {
-			cost = getNDVEstimate(node.getParent(), metadata, cost, (List)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS), false);
+			result = getNDVEstimate(node.getParent(), metadata, cost, (List)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS), false);
+			if (result == UNKNOWN_VALUE) {
+				return cost;
+			}
 		}
-		return cost;
+		return result;
 	}
 
     private static void setCardinalityEstimate(PlanNode node, Float bestEstimate, boolean setColEstimates, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {

Modified: branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java
===================================================================
--- branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java	2012-01-06 20:53:01 UTC (rev 3780)
+++ branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java	2012-01-07 16:10:27 UTC (rev 3781)
@@ -35,6 +35,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.Criteria;
 import org.teiid.query.sql.visitor.EvaluatableVisitor;
 import org.teiid.query.util.CommandContext;
@@ -53,40 +54,7 @@
 
         boolean pushRaiseNull = false;
         
-        for (PlanNode critNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT)) {
-            
-            if (critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
-                NodeEditor.removeChildNode(critNode.getParent(), critNode);
-                continue;
-            }
-            
-            //TODO: remove dependent set criteria that has not been meaningfully pushed from its parent join
-            
-            if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.getGroups().size() != 0) {
-                continue;
-            }
-            
-            Criteria crit = (Criteria)critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
-            //if not evaluatable, just move on to the next criteria
-            if (!EvaluatableVisitor.isFullyEvaluatable(crit, true)) {
-                continue;
-            }
-            //if evaluatable
-            try {
-                boolean eval = Evaluator.evaluate(crit);
-                if(eval) {
-                    NodeEditor.removeChildNode(critNode.getParent(), critNode);
-                } else {
-                    FrameUtil.replaceWithNullNode(critNode);
-                    pushRaiseNull = true;
-                }
-            //none of the following exceptions should ever occur
-            } catch(BlockedException e) {
-                throw new TeiidComponentException(e);
-            } catch (ExpressionEvaluationException e) {
-                throw new TeiidComponentException(e);
-            } 
-        } 
+        pushRaiseNull = clean(plan);
         
         if (pushRaiseNull) {
             rules.push(RuleConstants.RAISE_NULL);
@@ -94,7 +62,55 @@
 
         return plan;        
     }
+
+	private boolean clean(PlanNode plan)
+			throws TeiidComponentException {
+		boolean pushRaiseNull = false;
+		plan.setProperty(Info.OUTPUT_COLS, null);
+        for (PlanNode node : plan.getChildren()) {
+        	pushRaiseNull |= clean(node);
+        }
+        if (plan.getType() == NodeConstants.Types.SELECT) {
+        	pushRaiseNull = cleanCriteria(plan);
+        }
+		return pushRaiseNull;
+	}
     
+    boolean cleanCriteria(PlanNode critNode) throws TeiidComponentException {
+        if (critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
+            NodeEditor.removeChildNode(critNode.getParent(), critNode);
+            return false;
+        }
+        
+        //TODO: remove dependent set criteria that has not been meaningfully pushed from its parent join
+        
+        if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.getGroups().size() != 0) {
+            return false;
+        }
+        
+        Criteria crit = (Criteria)critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
+        //if not evaluatable, just move on to the next criteria
+        if (!EvaluatableVisitor.isFullyEvaluatable(crit, true)) {
+            return false;
+        }
+        //if evaluatable
+        try {
+            boolean eval = Evaluator.evaluate(crit);
+            if(eval) {
+                NodeEditor.removeChildNode(critNode.getParent(), critNode);
+            } else {
+                FrameUtil.replaceWithNullNode(critNode);
+                return true;
+            }
+        //none of the following exceptions should ever occur
+        } catch(BlockedException e) {
+            throw new TeiidComponentException(e);
+        } catch (ExpressionEvaluationException e) {
+            throw new TeiidComponentException(e);
+        }
+        return false;
+    }
+    
     public String toString() {
         return "CleanCriteria"; //$NON-NLS-1$
     }

Modified: branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
===================================================================
--- branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java	2012-01-06 20:53:01 UTC (rev 3780)
+++ branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java	2012-01-07 16:10:27 UTC (rev 3781)
@@ -23,8 +23,10 @@
 package org.teiid.query.optimizer;
 
 import org.junit.Test;
+import org.teiid.query.metadata.TransformationMetadata;
 import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
 import org.teiid.query.processor.ProcessorPlan;
@@ -254,5 +256,36 @@
             0,      // Sort
             2       // UnionAll
         });                                    
-    }    
+    }   
+    
+    @Test public void testUnionCosting() throws Exception {
+    	TransformationMetadata metadata = RealMetadataFactory.example1();
+    	RealMetadataFactory.setCardinality("pm1.g1", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g2", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g3", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g4", 100, metadata);
+    	BasicSourceCapabilities bac = new BasicSourceCapabilities();
+    	bac.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
+    	bac.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
+        ProcessorPlan plan = TestOptimizer.helpPlan("SELECT T.e1 AS e1, T.e2 AS e2, T.e3 AS e3 FROM (SELECT e1, 'a' AS e2, e3 FROM pm1.g1 UNION SELECT e1, 'b' AS e2, e3 FROM pm1.g2 UNION SELECT e1, 'c' AS e2, e3 FROM pm1.g3) AS T, vm1.g1 AS L WHERE (T.e1 = L.e1) AND (T.e3 = TRUE)", metadata, null, new DefaultCapabilitiesFinder(bac),//$NON-NLS-1$
+            new String[] { "SELECT pm1.g1.e1 FROM pm1.g1", "SELECT pm1.g1.e1, pm1.g1.e3 FROM pm1.g1 WHERE pm1.g1.e3 = TRUE", "SELECT pm1.g3.e1, pm1.g3.e3 FROM pm1.g3 WHERE pm1.g3.e3 = TRUE", "SELECT pm1.g2.e1, pm1.g2.e3 FROM pm1.g2 WHERE pm1.g2.e3 = TRUE" }, 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
+        });                                    
+    }   
+
 }



More information about the teiid-commits mailing list