[teiid-commits] teiid SVN: r2815 - in trunk/engine/src: main/java/org/teiid/query/sql/lang and 1 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Tue Jan 4 16:24:33 EST 2011


Author: shawkins
Date: 2011-01-04 16:24:33 -0500 (Tue, 04 Jan 2011)
New Revision: 2815

Modified:
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
Log:
TEIID-1338 adding additional support for inferring predicates through copy criteria.  the copying will now consider inner join criteria where applicable, but it still does not perform full transitive closure analysis.

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -433,11 +433,9 @@
                 AggregateSymbolCollectorVisitor.getAggregates(selectCriteria, requiredSymbols, requiredSymbols);
 				break;
 			case NodeConstants.Types.JOIN:
-				List crits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
+				List<Criteria> crits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
 				if(crits != null) {
-					Iterator critIter = crits.iterator();
-					while(critIter.hasNext()) {
-						Criteria joinCriteria = (Criteria) critIter.next();
+					for (Criteria joinCriteria : crits) {
 						AggregateSymbolCollectorVisitor.getAggregates(joinCriteria, requiredSymbols, requiredSymbols);
 					}
 				}

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -25,6 +25,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -100,6 +101,13 @@
         // no more than one group on each side
         List<Criteria> crits = (List<Criteria>) joinNode.getProperty(NodeConstants.Info.JOIN_CRITERIA);
         
+        filterOptionalCriteria(crits);
+        
+        if (crits.isEmpty() && jtype == JoinType.JOIN_INNER) {
+    		joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_CROSS);
+    		return;
+    	}
+        
         List<Criteria> nonEquiJoinCriteria = new ArrayList<Criteria>();
         
         separateCriteria(leftGroups, rightGroups, leftExpressions, rightExpressions, crits, nonEquiJoinCriteria);
@@ -142,10 +150,6 @@
                 continue;
             }
             
-            if (crit.isOptional()) {
-            	continue;
-            }
-            
             Expression leftExpr = crit.getLeftExpression();
             Expression rightExpr = crit.getRightExpression();
                         
@@ -186,6 +190,18 @@
         }
         return result;
     }
+    
+	static void filterOptionalCriteria(List<Criteria> crits) {
+		for (Iterator<Criteria> iter = crits.iterator(); iter.hasNext();) {
+			Criteria crit = iter.next();
+			if (crit instanceof CompareCriteria) {
+				CompareCriteria cc = (CompareCriteria) crit;
+				if (cc.isOptional()) {
+					iter.remove();
+				}
+			}
+		}
+	}
 
     public String toString() {
         return "ChooseJoinStrategy"; //$NON-NLS-1$

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -249,6 +249,11 @@
                 
                 if (crits == null || crits.isEmpty()) {
                     crits = new ArrayList<Criteria>();
+                } else {
+                	RuleChooseJoinStrategy.filterOptionalCriteria(crits);
+                	if (crits.isEmpty() && joinType == JoinType.JOIN_INNER) {
+                		joinType = JoinType.JOIN_CROSS;
+                	}
                 }
                 
                 PlanNode left = node.getFirstChild();

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -50,6 +50,7 @@
 import org.teiid.query.sql.lang.JoinType;
 import org.teiid.query.sql.symbol.Constant;
 import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.visitor.GroupsUsedByElementsVisitor;
 import org.teiid.query.util.CommandContext;
 
@@ -80,8 +81,7 @@
 	public PlanNode execute(PlanNode plan, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, RuleStack rules, AnalysisRecord analysisRecord, CommandContext context) 
 		throws QueryPlannerException, TeiidComponentException {
 
-        //do an initial check to see if an execution will be necessary
-	    List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT);
+	    List<PlanNode> critNodes = NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT | NodeConstants.Types.JOIN);
         boolean shouldRun = false;
         for (PlanNode critNode : critNodes) {
             if (!critNode.hasBooleanProperty(NodeConstants.Info.IS_COPIED)) {
@@ -121,9 +121,9 @@
      * @return true if the copy was successful
      */
     private boolean copyCriteria(Criteria crit,
-                                 Map tgtMap,
-                                 List joinCriteria,
-                                 Set combinedCriteria,
+                                 Map<Expression, Expression> tgtMap,
+                                 List<Criteria> joinCriteria,
+                                 Set<Criteria> combinedCriteria,
                                  boolean checkForGroupReduction,
                                  QueryMetadataInterface metadata) {
         int startGroups = GroupsUsedByElementsVisitor.getGroups(crit).size();
@@ -166,7 +166,7 @@
      * @param node
      * @return true if criteria has been created
      */
-    private boolean tryToCopy(PlanNode node, Set[] criteriaInfo, QueryMetadataInterface metadata) {
+    private boolean tryToCopy(PlanNode node, Set<Criteria>[] criteriaInfo, QueryMetadataInterface metadata) {
         boolean changedTree = false;
         
         if (node == null) {
@@ -181,16 +181,16 @@
                 return visitChildern(node, criteriaInfo, changedTree, metadata);
             }
             
-            Set[] leftChildCriteria = new Set[2];
-            Set[] rightChildCriteria = new Set[2];
+            Set<Criteria>[] leftChildCriteria = new Set[2];
+            Set<Criteria>[] rightChildCriteria = new Set[2];
             
             changedTree |= tryToCopy(node.getFirstChild(), leftChildCriteria, metadata);
             changedTree |= tryToCopy(node.getLastChild(), rightChildCriteria, metadata);
 
-            List joinCrits = (List) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
-            Set combinedCriteria = null;
+            List<Criteria> joinCrits = (List<Criteria>) node.getProperty(NodeConstants.Info.JOIN_CRITERIA);
+            Set<Criteria> combinedCriteria = null;
             if (joinCrits != null) {
-                combinedCriteria = new HashSet(joinCrits); 
+                combinedCriteria = new HashSet<Criteria>(joinCrits); 
                 combinedCriteria.addAll(leftChildCriteria[1]);
                 combinedCriteria.addAll(rightChildCriteria[1]);
             }
@@ -208,19 +208,19 @@
                 return changedTree;
             }
             
-            Set toCopy = criteriaInfo[0];
-            Set allCriteria = criteriaInfo[1];
+            Set<Criteria> toCopy = criteriaInfo[0];
+            Set<Criteria> allCriteria = criteriaInfo[1];
             
             if (!toCopy.isEmpty()) {
-                Map srcToTgt = buildElementMap(joinCrits);
+                Map<Expression, Expression> srcToTgt = buildElementMap(joinCrits);
     
-                List newJoinCrits = new LinkedList();
+                List<Criteria> newJoinCrits = new LinkedList<Criteria>();
     
-                changedTree = createCriteriaFromSelectCriteria(changedTree, combinedCriteria, toCopy, srcToTgt, newJoinCrits, metadata);
+                changedTree |= createCriteria(false, toCopy, combinedCriteria, srcToTgt, newJoinCrits, metadata);
                 
                 srcToTgt = buildElementMap(allCriteria);
                             
-                changedTree = createCriteriaFromJoinCriteria(changedTree, joinCrits, combinedCriteria, srcToTgt, newJoinCrits, metadata);
+                changedTree |= createCriteria(true, joinCrits, combinedCriteria, srcToTgt, newJoinCrits, metadata);
                 
                 joinCrits.addAll(newJoinCrits);
             }
@@ -232,6 +232,11 @@
             } else if (jt == JoinType.JOIN_LEFT_OUTER) {
                 criteriaInfo[0].removeAll(rightChildCriteria[0]);
                 criteriaInfo[1].removeAll(rightChildCriteria[1]);
+            } else if (node.getSubqueryContainers().isEmpty()) {
+            	if (!node.hasBooleanProperty(NodeConstants.Info.IS_COPIED)) {
+                    toCopy.addAll(joinCrits);
+                }
+                allCriteria.addAll(joinCrits);
             }
             
             return changedTree;
@@ -257,8 +262,8 @@
             case NodeConstants.Types.PROJECT: 
             {
                 if (criteriaInfo[0] == null) {
-                    criteriaInfo[0] = new HashSet();
-                    criteriaInfo[1] = new HashSet();
+                    criteriaInfo[0] = new HashSet<Criteria>();
+                    criteriaInfo[1] = new HashSet<Criteria>();
                 } else {
                     criteriaInfo[0].clear();
                     criteriaInfo[1].clear();
@@ -271,76 +276,44 @@
         return changedTree;
     }
 
-    /** 
-     * @param changedTree
-     * @param joinCrits
-     * @param combinedCriteria
-     * @param srcToTgt
-     * @param newJoinCrits
-     * @return
-     */
-    private boolean createCriteriaFromJoinCriteria(boolean changedTree,
-                                                   List joinCrits,
-                                                   Set combinedCriteria,
-                                                   Map srcToTgt,
-                                                   List newJoinCrits,
+    private boolean createCriteria(boolean copyingJoinCriteria, Collection<Criteria> toCopy,
+                                                   Set<Criteria> combinedCriteria,
+                                                   Map<Expression, Expression> srcToTgt,
+                                                   List<Criteria> newJoinCrits,
                                                    QueryMetadataInterface metadata) {
-        if (srcToTgt.size() == 0) {
+        boolean changedTree = false;
+    	if (srcToTgt.size() == 0) {
             return changedTree;
         }
-        Iterator i = joinCrits.iterator();
+        Iterator<Criteria> i = toCopy.iterator();
         while (i.hasNext()) {
-            Criteria crit = (Criteria)i.next();
+            Criteria crit = i.next();
             
-            if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, true, metadata)) {
+            if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, copyingJoinCriteria, metadata)) {
             	changedTree = true;
+            	if (!copyingJoinCriteria) {
+            		crit = newJoinCrits.get(newJoinCrits.size() - 1);
+            	}
+            	//TODO more criteria can be "optional"
             	if (crit instanceof CompareCriteria) {
             		CompareCriteria cc = (CompareCriteria)crit;
-            		if (cc.getLeftExpression() instanceof ElementSymbol && cc.getRightExpression() instanceof ElementSymbol) {
+            		//if (cc.getLeftExpression() instanceof ElementSymbol && cc.getRightExpression() instanceof ElementSymbol) {
             			//don't remove theta criteria, just mark it as optional
-            			cc.setOptional(true);
+        				cc.setOptional(copyingJoinCriteria?null:true);
             			continue;
-            		}
+            		//}
             	}
-                i.remove();
+            	if (copyingJoinCriteria) {
+            		i.remove();
+            	}
             }
         }
         return changedTree;
     }
 
-    /** 
-     * @param changedTree
-     * @param combinedCriteria
-     * @param toCopy
-     * @param srcToTgt
-     * @param newJoinCrits
-     * @return
-     */
-    private boolean createCriteriaFromSelectCriteria(boolean changedTree,
-                                                     Set combinedCriteria,
-                                                     Set toCopy,
-                                                     Map srcToTgt,
-                                                     List newJoinCrits,
-                                                     QueryMetadataInterface metadata) {
-        if (srcToTgt.size() == 0) {
-            return changedTree;
-        }
-        Iterator i = toCopy.iterator();
-        while (i.hasNext()) {
-            Criteria crit = (Criteria)i.next();
-            changedTree |= copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, false, metadata);            
-        }
-        return changedTree;
-    }
-
-    /** 
-     * @param node
-     * @param toCopy
-     * @param allCriteria
-     */
     private void visitSelectNode(PlanNode node,
-                                 Set toCopy,
-                                 Set allCriteria) {
+                                 Set<Criteria> toCopy,
+                                 Set<Criteria> allCriteria) {
         //First examine criteria in critNode for suitability
         Criteria crit = (Criteria) node.getProperty(NodeConstants.Info.SELECT_CRITERIA);
         if(node.getGroups().size() == 1) {
@@ -355,13 +328,13 @@
     }
 
     private boolean visitChildern(PlanNode node,
-                                  Set[] criteriaInfo,
+                                  Set<Criteria>[] criteriaInfo,
                                   boolean changedTree,
                                   QueryMetadataInterface metadata) {
         if (node.getChildCount() > 0) {
-            List children = node.getChildren();
+            List<PlanNode> children = node.getChildren();
             for (int i = 0; i < children.size(); i++) {
-                PlanNode childNode = (PlanNode)children.get(i);
+                PlanNode childNode = children.get(i);
                 changedTree |= tryToCopy(childNode, i==0?criteriaInfo:new Set[2], metadata);
             }
         }
@@ -374,16 +347,14 @@
      * @param crits
      * @return
      */
-    Map buildElementMap(Collection crits) {
-        Map srcToTgt = null;
-        Iterator critIter = crits.iterator();
-        while(critIter.hasNext()) { 
-            Criteria theCrit = (Criteria) critIter.next();
+    Map<Expression, Expression> buildElementMap(Collection<Criteria> crits) {
+        Map<Expression, Expression> srcToTgt = null;
+        for (Criteria theCrit : crits) {
             if (theCrit instanceof IsNullCriteria) {
             	IsNullCriteria isNull = (IsNullCriteria)theCrit;
             	if (!isNull.isNegated() && isNull.getExpression() instanceof ElementSymbol) {
             		if (srcToTgt == null) {
-            			srcToTgt = new HashMap();
+            			srcToTgt = new HashMap<Expression, Expression>();
             		}
             		srcToTgt.put(isNull.getExpression(), new Constant(null, isNull.getExpression().getType()));
             	}
@@ -395,14 +366,14 @@
             CompareCriteria crit = (CompareCriteria) theCrit;
             if (crit.getOperator() == CompareCriteria.EQ) {
                 if (srcToTgt == null) {
-                    srcToTgt = new HashMap();
+                    srcToTgt = new HashMap<Expression, Expression>();
             	}
                 srcToTgt.put(crit.getLeftExpression(), crit.getRightExpression());
                 srcToTgt.put(crit.getRightExpression(), crit.getLeftExpression());
             }
         }
         if (srcToTgt == null) {
-            return Collections.EMPTY_MAP;
+            return Collections.emptyMap();
         }
         return srcToTgt;
     }

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -569,7 +569,9 @@
     	Object modelID = null;
         Set<Object> groupIDs = new HashSet<Object>();
         int groupCount = 0;
-        
+		LinkedList<CompareCriteria> thetaCriteria = new LinkedList<CompareCriteria>();
+		SupportedJoinCriteria sjc = null;
+
 		for (PlanNode childNode : children) {
 			if(childNode.getType() != NodeConstants.Types.ACCESS 
 					|| childNode.hasCollectionProperty(NodeConstants.Info.ACCESS_PATTERNS)) {
@@ -604,7 +606,7 @@
         		if (!CapabilitiesUtil.supportsJoin(accessModelID, type, metadata, capFinder)) {
 				   return null;
         		}
-        		SupportedJoinCriteria sjc = CapabilitiesUtil.getSupportedJoinCriteria(accessModelID, metadata, capFinder);
+        		sjc = CapabilitiesUtil.getSupportedJoinCriteria(accessModelID, metadata, capFinder);
 				
         		/*
         		 * Key joins must be left linear
@@ -616,7 +618,16 @@
 				if(crits != null && !crits.isEmpty()) {
 					for (Criteria crit : crits) {
 				        if (!isSupportedJoinCriteria(sjc, crit, accessModelID, metadata, capFinder, record)) {
+				        	if (crit instanceof CompareCriteria) {
+				    			CompareCriteria cc = (CompareCriteria) crit;
+				    			if (cc.isOptional()) {
+				    				cc.setOptional(true);
+				    				continue;
+				    			}
+				    		}
 				        	return null;
+				        } else if (crit instanceof CompareCriteria) {
+				        	thetaCriteria.add((CompareCriteria)crit);
 				        }
 					}
 					if (sjc == SupportedJoinCriteria.KEY) {
@@ -649,7 +660,7 @@
 								&& !matchesForeignKey(metadata, rightIds, leftIds, rightGroup, true)) {
 							return null;
 						}
-					}
+					} 
                 } else if (sjc != SupportedJoinCriteria.ANY) {
                 	return null; //cross join not supported
                 }
@@ -667,6 +678,21 @@
 		    return null;
 		}
 		
+		if (sjc == SupportedJoinCriteria.KEY) {
+			for (CompareCriteria criteria : thetaCriteria) {
+				criteria.setOptional(false);
+			}
+		} else {
+			//TODO: this should be done in a less arbitrary way, and what about composite keys?
+			boolean hasCriteria = false;
+			for (CompareCriteria criteria : thetaCriteria) {
+				if (criteria.getIsOptional() == null || (!hasCriteria && criteria.getIsOptional())) {
+					criteria.setOptional(false);
+				}
+				hasCriteria = true;
+			}
+		}
+		
 		return modelID;
     }
     

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -46,7 +46,7 @@
 
 	/** The right-hand expression. */
 	private Expression rightExpression;
-	private boolean isOptional;
+	private Boolean isOptional = Boolean.FALSE;
     
     /**
      * Constructs a default instance of this class.
@@ -103,7 +103,7 @@
      * to correctly process a join
      * @param isOptional
      */
-    public void setOptional(boolean isOptional) {
+    public void setOptional(Boolean isOptional) {
 		this.isOptional = isOptional;
 	}
     
@@ -113,6 +113,10 @@
      * @return
      */
     public boolean isOptional() {
+		return isOptional == null || isOptional;
+	}
+    
+    public Boolean getIsOptional() {
 		return isOptional;
 	}
 

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -51,7 +51,7 @@
 import org.teiid.query.unittest.FakeMetadataStore;
 import org.teiid.translator.SourceSystemFunctions;
 
-
+ at SuppressWarnings("nls")
 public class TestJoinOptimization {
     
     /**
@@ -260,13 +260,13 @@
     }
     
     /**
-     * The intkey criteria should not be copied above to bqt1.smalla since the criteria is comming from the inner side in the join below 
+     * The intkey criteria should not be copied above to bqt1.smalla since the criteria is coming from the inner side in the join below 
      */
     @Test public void testInvalidCopyCriteria() {
         String sql = "select bqt1.smalla.intkey from bqt1.smalla inner join (select bqt3.smalla.intkey from bqt2.smalla left outer join bqt3.smalla on bqt2.smalla.intkey = bqt3.smalla.intkey and bqt3.smalla.intkey = 1) foo on bqt1.smalla.intkey = foo.intkey"; //$NON-NLS-1$
 
         // Plan query
-        ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt2.smalla AS g_0", "SELECT g_0.intkey AS c_0 FROM bqt1.smalla AS g_0 ORDER BY c_0"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.IntKey FROM bqt2.smalla AS g_0", "SELECT g_0.intkey AS c_0 FROM bqt1.smalla AS g_0 ORDER BY c_0"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 
         TestOptimizer.checkNodeTypes(plan, new int[] {
             3,      // Access
@@ -293,7 +293,7 @@
         String sql = "select bqt1.smalla.intkey from bqt1.smalla left outer join (select bqt3.smalla.intkey from bqt3.smalla where bqt3.smalla.intkey = 1) foo on bqt1.smalla.intkey = foo.intkey"; //$NON-NLS-1$
 
         // Plan query
-        ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt1.smalla AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$ 
+        ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.IntKey FROM bqt3.smalla AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt1.smalla AS g_0"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$ 
 
         TestOptimizer.checkNodeTypes(plan, new int[] {
             2,      // Access
@@ -550,7 +550,7 @@
     }
     
     /**
-     * non-depenent criteria on each side of a full outer creates an inner join  
+     * non-dependent criteria on each side of a full outer creates an inner join  
      */
     @Test public void testOuterToInnerJoinConversion4() {
     	QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
@@ -1001,5 +1001,31 @@
             0       // UnionAll
         });
     }
+    
+    @Test public void testTransitiveJoinCondition() {
+        String sql = "select b.intkey from bqt1.smalla a, bqt2.smallb b, bqt2.smalla b1 where a.intkey = b.intkey and a.intkey = b1.intkey"; //$NON-NLS-1$
         
+        // Plan query
+        ProcessorPlan plan = TestOptimizer.helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), new String[] {
+        	"SELECT g_1.intkey AS c_0, g_0.intkey AS c_1 FROM bqt2.smallb AS g_0, bqt2.smalla AS g_1 WHERE g_1.intkey = g_0.intkey ORDER BY c_0, c_1", 
+        	"SELECT g_0.intkey AS c_0 FROM bqt1.smalla AS g_0 ORDER BY c_0"}); 
+
+        TestOptimizer.checkNodeTypes(plan, new int[] {
+            2,      // Access
+            0,      // DependentAccess
+            0,      // DependentSelect
+            0,      // DependentProject
+            0,      // DupRemove
+            0,      // Grouping
+            0,      // Join
+            1,      // MergeJoin
+            0,      // Null
+            0,      // PlanExecution
+            1,      // Project
+            0,      // Select
+            0,      // Sort
+            0       // UnionAll
+        });
+    }
+        
 }

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2011-01-04 19:40:39 UTC (rev 2814)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2011-01-04 21:24:33 UTC (rev 2815)
@@ -5803,8 +5803,8 @@
 
         ProcessorPlan plan = helpPlan(sql, FakeMetadataFactory.exampleBQTCached(), 
                                       new String[] { 
-                                          "SELECT g_0.IntKey FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey <> 1",  //$NON-NLS-1$ 
-                                          "SELECT g_0.IntKey FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey = 1" }, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ 
+                                          "SELECT g_0.intkey FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey <> 1",  //$NON-NLS-1$ 
+                                          "SELECT g_0.intkey FROM BQT1.SmallA AS g_0 WHERE g_0.IntKey = 1" }, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ 
 
         checkNodeTypes(plan, new int[] {
                                         2,      // Access



More information about the teiid-commits mailing list