[teiid-commits] teiid SVN: r4594 - in branches/7.7.x/engine/src: main/java/org/teiid/query/rewriter and 2 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Fri Sep 6 08:09:54 EDT 2013


Author: jolee
Date: 2013-09-06 08:09:53 -0400 (Fri, 06 Sep 2013)
New Revision: 4594

Modified:
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanJoins.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   branches/7.7.x/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
Log:
BZ975033:  EDS_5.3.1_3_2013 + Teiid-2633: Criteria is assumed needed when no other predicates determined during RuleRaiseAccess (reprise)

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleChooseJoinStrategy.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -98,7 +98,7 @@
         // no more than one group on each side
         List<Criteria> crits = (List<Criteria>) joinNode.getProperty(NodeConstants.Info.JOIN_CRITERIA);
         
-        filterOptionalCriteria(crits);
+        filterOptionalCriteria(crits, true);
         
         if (crits.isEmpty() && jtype == JoinType.JOIN_INNER) {
     		joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, JoinType.JOIN_CROSS);
@@ -179,12 +179,12 @@
         return result;
     }
     
-	static void filterOptionalCriteria(List<Criteria> crits) {
+	static void filterOptionalCriteria(List<Criteria> crits, boolean all) {
 		for (Iterator<Criteria> iter = crits.iterator(); iter.hasNext();) {
 			Criteria crit = iter.next();
 			if (crit instanceof CompareCriteria) {
 				CompareCriteria cc = (CompareCriteria) crit;
-				if (cc.isOptional()) {
+				if (Boolean.TRUE.equals(cc.getIsOptional()) || (all && cc.isOptional())) {
 					iter.remove();
 				}
 			}

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCollapseSource.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -312,7 +312,7 @@
                 if (crits == null || crits.isEmpty()) {
                     crits = new ArrayList<Criteria>();
                 } else {
-                	RuleChooseJoinStrategy.filterOptionalCriteria(crits);
+                	RuleChooseJoinStrategy.filterOptionalCriteria(crits, false);
                 	if (crits.isEmpty() && joinType == JoinType.JOIN_INNER) {
                 		joinType = JoinType.JOIN_CROSS;
                 	}

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCopyCriteria.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -179,6 +179,9 @@
         //if this is unique or it a duplicate but reduced a current join conjunct, return true
         if (isNew) {
             joinCriteria.add(tgtCrit);
+            if (tgtCrit instanceof CompareCriteria) {
+				((CompareCriteria)tgtCrit).setOptional(true);
+            }
             return true;
         } else if (checkForGroupReduction) {
             return true;
@@ -325,23 +328,17 @@
         while (i.hasNext()) {
             Criteria crit = i.next();
             
-            if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, copyingJoinCriteria, metadata, underAccess)) {
-            	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) {
-            			//don't remove theta criteria, just mark it as optional
-        				cc.setOptional(copyingJoinCriteria?null:true);
-            			continue;
-            		//}
-            	}
+             if (copyCriteria(crit, srcToTgt, newJoinCrits, combinedCriteria, copyingJoinCriteria, metadata, underAccess)) {
+             	changedTree = true;
             	if (copyingJoinCriteria) {
-            		i.remove();
-            	}
+            		if (crit instanceof CompareCriteria) {
+            			CompareCriteria cc = (CompareCriteria)crit;
+             			//don't remove theta criteria, just mark it as optional
+        				cc.setOptional(null);
+             			continue;
+            		}
+             		i.remove();
+             	}
             }
         }
         return changedTree;
@@ -449,7 +446,7 @@
 		}
 		if (!GroupsUsedByElementsVisitor.getGroups(crit.getLeftExpression()).isEmpty() && !GroupsUsedByElementsVisitor.getGroups(crit.getRightExpression()).isEmpty()
 				&& (GroupsUsedByElementsVisitor.getGroups(left).isEmpty() || GroupsUsedByElementsVisitor.getGroups(oldValue).isEmpty())) {
-			crit.setOptional(true); //the original has been simplified
+			crit.setOptional(null); //the original has been simplified
 		}
 		return false;
 	}

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanJoins.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanJoins.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePlanJoins.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -47,6 +47,7 @@
 import org.teiid.query.optimizer.relational.plantree.PlanNode;
 import org.teiid.query.processor.relational.JoinNode.JoinStrategyType;
 import org.teiid.query.resolver.util.AccessPattern;
+import org.teiid.query.sql.lang.CompareCriteria;
 import org.teiid.query.sql.lang.Criteria;
 import org.teiid.query.sql.lang.JoinType;
 import org.teiid.query.sql.symbol.ElementSymbol;
@@ -215,11 +216,17 @@
                 continue;
             }
             
+            int secondPass = -1;
+            
             for (int i = accessNodes.size() - 1; i >= 0; i--) {
                 
                 PlanNode accessNode1 = accessNodes.get(i);
+                Object modelId = RuleRaiseAccess.getModelIDFromAccess(accessNode1, metadata);
+                SupportedJoinCriteria sjc = CapabilitiesUtil.getSupportedJoinCriteria(modelId, metadata, capFinder);
                 
-                for (int k = accessNodes.size() - 1; k >= 0; k--) {
+                int discoveredJoin = -1;
+                 
+                for (int k = (secondPass==-1?accessNodes.size() - 1:secondPass); k >= 0; k--) {
                     if (k == i) {
                         continue;
                     }
@@ -239,8 +246,6 @@
                      */
                     boolean hasJoinCriteria = false; 
                     LinkedList<Criteria> joinCriteria = new LinkedList<Criteria>();
-                    Object modelId = RuleRaiseAccess.getModelIDFromAccess(accessNode1, metadata);
-                    SupportedJoinCriteria sjc = CapabilitiesUtil.getSupportedJoinCriteria(modelId, metadata, capFinder);
                     for (PlanNode critNode : criteriaNodes) {
                         Set<PlanNode> sources = joinRegion.getCritieriaToSourceMap().get(critNode);
 
@@ -275,10 +280,20 @@
                     JoinType joinType = joinCriteria.isEmpty()?JoinType.JOIN_CROSS:JoinType.JOIN_INNER;
                     
                     //try to push to the source
-                    if (RuleRaiseAccess.canRaiseOverJoin(toTest, metadata, capFinder, joinCriteria, joinType, null) == null) {
+                    if (RuleRaiseAccess.canRaiseOverJoin(toTest, metadata, capFinder, joinCriteria, joinType, null, secondPass != -1) == null) {
+                    	if (secondPass == - 1 && sjc != SupportedJoinCriteria.KEY && discoveredJoin == -1) {
+                			for (Criteria criteria : joinCriteria) {
+                				if (criteria instanceof CompareCriteria && ((CompareCriteria) criteria).isOptional()) {
+                					discoveredJoin = k;
+                				}
+                			}
+                		}
                         continue;
                     }
                     
+                    secondPass = -1;
+                    discoveredJoin = -1;
+                    
                     structureChanged = true;
                     
                     //remove the information that is no longer relevant to the join region
@@ -318,6 +333,11 @@
                     k = accessNodes.size();
                     break;
                 }
+                
+                if (discoveredJoin != -1) {
+                	i++; //rerun with the discoveredJoin criteria
+                	secondPass = discoveredJoin;
+                }
             }
         }
         

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleRaiseAccess.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -40,10 +40,10 @@
 import org.teiid.query.optimizer.relational.OptimizerRule;
 import org.teiid.query.optimizer.relational.RuleStack;
 import org.teiid.query.optimizer.relational.plantree.NodeConstants;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
 import org.teiid.query.optimizer.relational.plantree.NodeEditor;
 import org.teiid.query.optimizer.relational.plantree.NodeFactory;
 import org.teiid.query.optimizer.relational.plantree.PlanNode;
-import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
 import org.teiid.query.sql.lang.CompareCriteria;
 import org.teiid.query.sql.lang.Criteria;
 import org.teiid.query.sql.lang.JoinType;
@@ -541,14 +541,15 @@
 			}
 		}
         
-        return canRaiseOverJoin(joinNode.getChildren(), metadata, capFinder, crits, type, record);		
+		//jrl introducing context
+        return canRaiseOverJoin(joinNode.getChildren(), metadata, capFinder, crits, type, record, afterJoinPlanning);			
 	}
 
     static Object canRaiseOverJoin(List<PlanNode> children,
                                            QueryMetadataInterface metadata,
                                            CapabilitiesFinder capFinder,
                                            List<Criteria> crits,
-                                           JoinType type, AnalysisRecord record) throws QueryMetadataException,
+                                           JoinType type, AnalysisRecord record, boolean considerOptional) throws QueryMetadataException,
                                                          TeiidComponentException {
         //we only want to consider binary joins
         if (children.size() != 2) {
@@ -614,6 +615,7 @@
 				    				continue;
 				    			}
 				    		}
+				    		//TODO: plan based upon a predicate subset when possible
 				        	return null;
 				        } else if (crit instanceof CompareCriteria) {
 				        	thetaCriteria.add((CompareCriteria)crit);
@@ -650,7 +652,8 @@
 							return null;
 						}
 					} 
-                } else if (sjc != SupportedJoinCriteria.ANY) {
+                }
+				if (sjc != SupportedJoinCriteria.ANY && thetaCriteria.isEmpty()) {
                 	return null; //cross join not supported
                 }
 				
@@ -667,20 +670,24 @@
 		    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);
+		if (crits != null && !crits.isEmpty()) {
+			if (considerOptional) {
+				for (CompareCriteria criteria : thetaCriteria) {
+ 					criteria.setOptional(false);
+ 				}
+			} else {
+				boolean hasCriteria = false;
+				for (CompareCriteria criteria : thetaCriteria) {
+					if (criteria.getIsOptional() == null || !criteria.isOptional()) {
+						hasCriteria = true;
+						break;
+					}
+				}	
+				if (!hasCriteria) {
+					return null;
 				}
-				hasCriteria = true;
-			}
-		}
+ 			}
+ 		}
 		
 		return modelID;
     }

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -40,12 +40,12 @@
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.core.TeiidRuntimeException;
 import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.DataTypeManager.DefaultDataClasses;
 import org.teiid.core.types.Transform;
-import org.teiid.core.types.DataTypeManager.DefaultDataClasses;
 import org.teiid.core.util.Assertion;
 import org.teiid.core.util.TimestampWithTimezone;
+import org.teiid.language.Like.MatchMode;
 import org.teiid.language.SQLConstants;
-import org.teiid.language.Like.MatchMode;
 import org.teiid.language.SQLConstants.NonReserved;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.eval.Evaluator;
@@ -57,16 +57,16 @@
 import org.teiid.query.metadata.TempMetadataID;
 import org.teiid.query.metadata.TempMetadataStore;
 import org.teiid.query.optimizer.relational.rules.RuleMergeCriteria;
+import org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult;
 import org.teiid.query.optimizer.relational.rules.RulePlaceAccess;
-import org.teiid.query.optimizer.relational.rules.RuleMergeCriteria.PlannedResult;
 import org.teiid.query.processor.relational.RelationalNodeUtil;
 import org.teiid.query.resolver.ProcedureContainerResolver;
 import org.teiid.query.resolver.QueryResolver;
 import org.teiid.query.resolver.util.ResolverUtil;
 import org.teiid.query.resolver.util.ResolverVisitor;
 import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.LanguageObject.Util;
 import org.teiid.query.sql.ProcedureReservedWords;
-import org.teiid.query.sql.LanguageObject.Util;
 import org.teiid.query.sql.lang.*;
 import org.teiid.query.sql.lang.PredicateCriteria.Negatable;
 import org.teiid.query.sql.navigator.DeepPostOrderNavigator;
@@ -80,10 +80,10 @@
 import org.teiid.query.sql.visitor.CriteriaTranslatorVisitor;
 import org.teiid.query.sql.visitor.ElementCollectorVisitor;
 import org.teiid.query.sql.visitor.EvaluatableVisitor;
+import org.teiid.query.sql.visitor.EvaluatableVisitor.EvaluationLevel;
 import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
 import org.teiid.query.sql.visitor.FunctionCollectorVisitor;
 import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
-import org.teiid.query.sql.visitor.EvaluatableVisitor.EvaluationLevel;
 import org.teiid.query.util.CommandContext;
 import org.teiid.query.validator.UpdateValidator.UpdateInfo;
 import org.teiid.query.validator.UpdateValidator.UpdateMapping;
@@ -97,8 +97,12 @@
 public class QueryRewriter {
 
     public static final CompareCriteria TRUE_CRITERIA = new CompareCriteria(new Constant(1, DataTypeManager.DefaultDataClasses.INTEGER), CompareCriteria.EQ, new Constant(1, DataTypeManager.DefaultDataClasses.INTEGER));
-    public static final CompareCriteria FALSE_CRITERIA = new CompareCriteria(new Constant(1, DataTypeManager.DefaultDataClasses.INTEGER), CompareCriteria.EQ, new Constant(0, DataTypeManager.DefaultDataClasses.INTEGER));
-    public static final CompareCriteria UNKNOWN_CRITERIA = new CompareCriteria(new Constant(null, DataTypeManager.DefaultDataClasses.STRING), CompareCriteria.NE, new Constant(null, DataTypeManager.DefaultDataClasses.STRING));
+    public static final CompareCriteria FALSE_CRITERIA = new CompareCriteria(new Constant(1, DataTypeManager.DefaultDataClasses.INTEGER), CompareCriteria.EQ, new Constant(0, DataTypeManager.DefaultDataClasses.INTEGER)) {
+    	public void setOptional(Boolean isOptional) {};
+    };
+    public static final CompareCriteria UNKNOWN_CRITERIA = new CompareCriteria(new Constant(null, DataTypeManager.DefaultDataClasses.STRING), CompareCriteria.NE, new Constant(null, DataTypeManager.DefaultDataClasses.STRING)) {
+    	public void setOptional(Boolean isOptional) {};
+    };
     
     private static final Map<String, String> ALIASED_FUNCTIONS = new HashMap<String, String>();
     

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/sql/lang/CompareCriteria.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -103,7 +103,10 @@
      * @param isOptional
      */
     public void setOptional(Boolean isOptional) {
-		this.isOptional = isOptional;
+    	if (isOptional == null && Boolean.TRUE.equals(this.isOptional)) {
+    		return;
+    	}
+    	this.isOptional = isOptional;
 	}
     
     /**

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestJoinOptimization.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -32,14 +32,16 @@
 import org.teiid.api.exception.query.QueryParserException;
 import org.teiid.api.exception.query.QueryResolverException;
 import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
 import org.teiid.metadata.Column;
+import org.teiid.metadata.KeyRecord.Type;
 import org.teiid.metadata.Table;
-import org.teiid.metadata.KeyRecord.Type;
 import org.teiid.query.metadata.QueryMetadataInterface;
 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.CapabilitiesFinder;
+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.optimizer.relational.rules.JoinUtil;
@@ -51,8 +53,8 @@
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.translator.ExecutionFactory.SupportedJoinCriteria;
 import org.teiid.translator.SourceSystemFunctions;
-import org.teiid.translator.ExecutionFactory.NullOrder;
 
 @SuppressWarnings("nls")
 public class TestJoinOptimization {
@@ -261,7 +263,21 @@
             0       // UnionAll
         });
     }
-    
+
+    @Test public void testCopyCriteriaWithFunction3() throws TeiidComponentException, TeiidProcessingException {
+        String sql = "select bqt1.smalla.intkey, bqt1.smallb.intkey from bqt1.smalla, bqt1.smallb where bqt1.smalla.stringkey = bqt1.smallb.intkey and bqt1.smallb.intkey = 1"; //$NON-NLS-1$
+
+        BasicSourceCapabilities caps = TestOptimizer.getTypicalCapabilities();
+        
+        // Plan query
+        ProcessorPlan plan = TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey, g_1.intkey FROM bqt1.smalla AS g_0, bqt1.smallb AS g_1 WHERE (g_0.stringkey = '1') AND (g_1.intkey = 1)"}, new DefaultCapabilitiesFinder(caps), ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+
+        TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
+        
+        caps.setSourceProperty(Capability.JOIN_CRITERIA_ALLOWED, SupportedJoinCriteria.THETA);
+        
+        TestOptimizer.helpPlan(sql, RealMetadataFactory.exampleBQTCached(), new String[] {"SELECT g_0.intkey FROM bqt1.smallb AS g_0 WHERE g_0.intkey = 1", "SELECT g_0.intkey FROM bqt1.smalla AS g_0 WHERE g_0.stringkey = '1'"}, new DefaultCapabilitiesFinder(caps), ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+    } 
     /**
      * The intkey criteria should not be copied above to bqt1.smalla since the criteria is coming from the inner side in the join below 
      */

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2013-08-27 12:31:52 UTC (rev 4593)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2013-09-06 12:09:53 UTC (rev 4594)
@@ -2684,8 +2684,14 @@
         ProcessorPlan plan = helpPlan("select pm2.g1.e1, pm2.g2.e1 from pm2.g1, pm2.g2, pm2.g3 where pm2.g1.e1 = pm2.g2.e1 and pm2.g2.e1 = pm2.g3.e1 and pm2.g1.e1 = 'a'", example1(), //$NON-NLS-1$
             new String[] { "SELECT g_0.e1, g_1.e1 FROM pm2.g1 AS g_0, pm2.g2 AS g_1, pm2.g3 AS g_2 WHERE (g_0.e1 = g_1.e1) AND (g_1.e1 = g_2.e1) AND (g_0.e1 = 'a') AND (g_1.e1 = 'a') AND (g_2.e1 = 'a')" }); //$NON-NLS-1$
         checkNodeTypes(plan, FULL_PUSHDOWN);         
-    }    
+    } 
     
+    @Test public void testCopyCriteriaWithTransitivePushdown2(){
+        ProcessorPlan plan = helpPlan("select pm1.g1.e1, pm1.g2.e1 from pm1.g1, pm1.g4, pm1.g2, pm1.g3 where pm1.g1.e1 = pm1.g2.e1 and pm1.g2.e1 = pm1.g3.e1 and pm1.g1.e1 = 'a'", example1(), //$NON-NLS-1$
+            new String[] { "SELECT g_1.e1, g_2.e1 FROM pm1.g4 AS g_0, pm1.g1 AS g_1, pm1.g2 AS g_2, pm1.g3 AS g_3 WHERE (g_2.e1 = g_3.e1) AND (g_1.e1 = g_2.e1) AND (g_1.e1 = 'a') AND (g_2.e1 = 'a') AND (g_3.e1 = 'a')" }); //$NON-NLS-1$
+        checkNodeTypes(plan, FULL_PUSHDOWN);         
+    }
+    
     @Test public void testCleanCriteria(){
         
         ProcessorPlan plan = helpPlan("select pm2.g1.e1, pm2.g2.e1 from pm2.g1, pm2.g2 where pm2.g1.e1=pm2.g2.e1 and pm2.g1.e2 IN (1, 2)", example1(), //$NON-NLS-1$



More information about the teiid-commits mailing list