[teiid-commits] teiid SVN: r2985 - 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
Wed Mar 9 14:04:10 EST 2011


Author: shawkins
Date: 2011-03-09 14:04:10 -0500 (Wed, 09 Mar 2011)
New Revision: 2985

Modified:
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
Log:
TEIID-1503 fix for regression with additional checks to prevent unnecessary planning

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java	2011-03-09 16:11:50 UTC (rev 2984)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeCriteria.java	2011-03-09 19:04:10 UTC (rev 2985)
@@ -59,7 +59,6 @@
 import org.teiid.query.sql.lang.FromClause;
 import org.teiid.query.sql.lang.GroupBy;
 import org.teiid.query.sql.lang.JoinType;
-import org.teiid.query.sql.lang.NotCriteria;
 import org.teiid.query.sql.lang.OrderBy;
 import org.teiid.query.sql.lang.OrderByItem;
 import org.teiid.query.sql.lang.Query;
@@ -119,6 +118,7 @@
 		public boolean not;
 		public List<Criteria> nonEquiJoinCriteria = new LinkedList<Criteria>();
 		public Criteria additionalCritieria;
+		public Class<?> type;
 	}
 
 	private IDGenerator idGenerator;
@@ -264,7 +264,7 @@
         	//if it's currently unknown, removing criteria won't make it any better
         	return current;
         }
-
+        
         Collection<GroupSymbol> leftGroups = FrameUtil.findJoinSourceNode(current).getGroups();
 
 		if (!planQuery(leftGroups, false, plannedResult)) {
@@ -279,6 +279,8 @@
 		}
 		
 		try {
+			//clone the symbols as they may change during planning
+			List<SingleElementSymbol> projectedSymbols = LanguageObject.Util.deepClone(plannedResult.query.getProjectedSymbols(), SingleElementSymbol.class);
 			//NOTE: we could tap into the relationalplanner at a lower level to get this in a plan node form,
 			//the major benefit would be to reuse the dependent join planning logic if possible.
 			RelationalPlan subPlan = (RelationalPlan)QueryOptimizer.optimizePlan(plannedResult.query, metadata, idGenerator, capFinder, analysisRecord, context);
@@ -286,6 +288,7 @@
             
             if (planCardinality.floatValue() == NewCalculateCostUtil.UNKNOWN_VALUE 
             		|| planCardinality.floatValue() > 10000000
+            		|| (sourceCost == NewCalculateCostUtil.UNKNOWN_VALUE && planCardinality.floatValue() > 1000)
             		|| (sourceCost != NewCalculateCostUtil.UNKNOWN_VALUE && sourceCost * originalCardinality.floatValue() < planCardinality.floatValue() / (100 * Math.log(Math.max(4, sourceCost))))) {
             	//bail-out if both are unknown or the new plan is too large
             	return current;
@@ -312,7 +315,7 @@
             
             PlanNode node = NodeFactory.getNewNode(NodeConstants.Types.ACCESS);
             node.setProperty(NodeConstants.Info.PROCESSOR_PLAN, subPlan);
-            node.setProperty(NodeConstants.Info.OUTPUT_COLS, plannedResult.query.getProjectedSymbols());
+            node.setProperty(NodeConstants.Info.OUTPUT_COLS, projectedSymbols);
             node.setProperty(NodeConstants.Info.EST_CARDINALITY, planCardinality);
             root.addAsParent(semiJoin);
             semiJoin.addLastChild(node);
@@ -328,20 +331,18 @@
 
 	public PlannedResult findSubquery(Criteria crit) throws TeiidComponentException, QueryMetadataException {
 		PlannedResult result = new PlannedResult();
-		if (crit instanceof NotCriteria) {
-			result.not = true;
-			crit = ((NotCriteria)crit).getCriteria();
-		} 
 		if (crit instanceof SubquerySetCriteria) {
 			//convert to the quantified form
 			SubquerySetCriteria ssc = (SubquerySetCriteria)crit;
 			result.not ^= ssc.isNegated();
+			result.type = crit.getClass();
 			crit = new SubqueryCompareCriteria(ssc.getExpression(), ssc.getCommand(), SubqueryCompareCriteria.EQ, SubqueryCompareCriteria.SOME);
 		} else if (crit instanceof CompareCriteria) {
 			//convert to the quantified form
 			CompareCriteria cc = (CompareCriteria)crit;
 			if (cc.getRightExpression() instanceof ScalarSubquery) {
 				ScalarSubquery ss = (ScalarSubquery)cc.getRightExpression();
+				result.type = ss.getClass();
 				if (ss.getCommand() instanceof Query) {
 					Query query = (Query)ss.getCommand();
 					if (query.getGroupBy() == null && query.hasAggregates()) {
@@ -375,7 +376,9 @@
 			if (result.not && !isNonNull(query, rightExpr)) {
 				return result;
 			}
-			
+			if (result.type == null) {
+				result.type = scc.getClass();
+			}
 			result.query = query;
 			result.additionalCritieria = (Criteria)new CompareCriteria(scc.getLeftExpression(), scc.getOperator(), rightExpr).clone();
 		}
@@ -384,6 +387,7 @@
 			if (!(exists.getCommand() instanceof Query)) {
 				return result;
 			} 
+			result.type = crit.getClass();
 			//the correlations can only be in where (if no group by or aggregates) or having
 			result.query = (Query)exists.getCommand();
 		}
@@ -431,6 +435,12 @@
 			return false;
 		}
 		
+		if ((plannedResult.type == ExistsCriteria.class || plannedResult.type == ScalarSubquery.class) && plannedResult.query.getCorrelatedReferences() == null) {
+			//we can't really improve on this case
+			//TODO: do this check earlier
+			return false;
+		}
+		
 		plannedResult.query = (Query)plannedResult.query.clone();
 		plannedResult.query.setLimit(null);
 
@@ -500,12 +510,12 @@
 		}
 		for (SingleElementSymbol ses : requiredExpressions) {
 			if (projectedSymbols.add(ses)) {
-				plannedResult.query.getSelect().addSymbol(ses);
+				plannedResult.query.getSelect().addSymbol((SingleElementSymbol) ses.clone());
 			}
 		}
 		for (SingleElementSymbol ses : (List<SingleElementSymbol>)plannedResult.rightExpressions) {
 			if (projectedSymbols.add(ses)) {
-				plannedResult.query.getSelect().addSymbol(ses);
+				plannedResult.query.getSelect().addSymbol((SingleElementSymbol)ses.clone());
 			}
 		}
 		return true;

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java	2011-03-09 16:11:50 UTC (rev 2984)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/Query.java	2011-03-09 19:04:10 UTC (rev 2985)
@@ -348,7 +348,7 @@
         }
 
         if(getLimit() != null) {
-            copy.setLimit( (Limit) getLimit().clone());
+            copy.setLimit( getLimit().clone());
         }
         
         copy.setWith(LanguageObject.Util.deepClone(this.getWith(), WithQueryCommand.class));

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java	2011-03-09 16:11:50 UTC (rev 2984)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestSubqueryPushdown.java	2011-03-09 19:04:10 UTC (rev 2985)
@@ -836,6 +836,27 @@
         }); 
     } 
     
+    @Test public void testNonSemiJoin() throws Exception {
+        ProcessorPlan plan = helpPlan("Select x from xmltable('/a/b' passing convert('<a/>', xml) columns x integer path '@x') as t where x = (select count(e2) FROM pm1.g2)", FakeMetadataFactory.example4(),  //$NON-NLS-1$
+            new String[] {}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+        checkNodeTypes(plan, new int[] {
+            0,      // Access
+            0,      // DependentAccess
+            1,      // DependentSelect
+            0,      // DependentProject
+            0,      // DupRemove
+            0,      // Grouping
+            0,      // NestedLoopJoinStrategy
+            0,      // MergeJoinStrategy
+            0,      // Null
+            0,      // PlanExecution
+            1,      // Project
+            0,      // Select
+            0,      // Sort
+            0       // UnionAll
+        }); 
+    }
+    
     /**
      * Test to ensure that we don't create an invalid semijoin query when attempting to convert the subquery to a semijoin
      */



More information about the teiid-commits mailing list