[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