[teiid-commits] teiid SVN: r2775 - in trunk: engine/src/main/java/org/teiid/query/eval and 5 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Tue Dec 14 13:24:19 EST 2010
Author: shawkins
Date: 2010-12-14 13:24:19 -0500 (Tue, 14 Dec 2010)
New Revision: 2775
Modified:
trunk/build/kits/jboss-container/teiid-releasenotes.html
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCalculateCostUtil.java
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
Log:
TEIID-1389 adding predicate optimization for in, comparison, and is null
Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html 2010-12-14 18:24:19 UTC (rev 2775)
@@ -34,6 +34,7 @@
</UL>
<LI><B>UDF</B> - new API objects added to teiid-api to support user defined functions that are capable of pushdown to source.
<LI><B>Unescape Function</B> - a new system function, unescape, was added to handle common \ escaping in strings including octal, hex/unicode, \b, \r, \n, \f, and \t.
+ <LI><B>Predicate Optimization<B> - expanded optimizations for detecting always false conditions when using IS NULL, IN, or comparison predicates with literal values.
</UL>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -297,6 +297,11 @@
}
// Compare two non-null values using specified operator
+ return compare(criteria, leftValue, rightValue);
+ }
+
+ public static Boolean compare(CompareCriteria criteria, Object leftValue,
+ Object rightValue) throws ExpressionEvaluationException {
switch(criteria.getOperator()) {
case CompareCriteria.EQ:
return Boolean.valueOf(compareValues(leftValue, rightValue) == 0);
@@ -315,7 +320,7 @@
}
}
- private final int compareValues(Object leftValue, Object rightValue) {
+ private static final int compareValues(Object leftValue, Object rightValue) {
assert leftValue instanceof Comparable<?>;
assert rightValue instanceof Comparable<?>;
if (leftValue == rightValue) {
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -609,7 +609,13 @@
// Rewrite criteria
Criteria crit = query.getCriteria();
if(crit != null) {
- crit = rewriteCriteria(crit);
+ if (query.getIsXML()) {
+ //only rewrite expressions, removing whole predicates could change the nature of the query,
+ //because we aren't considering the xml pseudo-functions context, row limit, etc.
+ rewriteExpressions(crit);
+ } else {
+ crit = rewriteCriteria(crit);
+ }
if(crit == TRUE_CRITERIA) {
query.setCriteria(null);
} else {
@@ -1181,6 +1187,7 @@
// Walk through crits and collect converted ones
LinkedHashSet<Criteria> newCrits = new LinkedHashSet<Criteria>(crits.size());
+ HashMap<Expression, Criteria> exprMap = operator == CompoundCriteria.AND?new HashMap<Expression, Criteria>():null;
for (Criteria converted : crits) {
if (rewrite) {
converted = rewriteCriteria(converted);
@@ -1189,17 +1196,17 @@
}
//begin boolean optimizations
- if(converted == TRUE_CRITERIA) {
+ if(TRUE_CRITERIA.equals(converted)) {
if(operator == CompoundCriteria.OR) {
// this OR must be true as at least one branch is always true
return converted;
}
- } else if(converted == FALSE_CRITERIA) {
+ } else if(FALSE_CRITERIA.equals(converted)) {
if(operator == CompoundCriteria.AND) {
// this AND must be false as at least one branch is always false
return converted;
}
- } else if (converted == UNKNOWN_CRITERIA) {
+ } else if (UNKNOWN_CRITERIA.equals(converted)) {
if (operator == CompoundCriteria.AND) {
return FALSE_CRITERIA;
}
@@ -1211,6 +1218,103 @@
newCrits.addAll(other.getCriteria());
continue;
}
+ } else if (operator == CompoundCriteria.AND) {
+ if (converted instanceof IsNullCriteria) {
+ IsNullCriteria inc = (IsNullCriteria)converted;
+ if (!inc.isNegated()) {
+ Criteria crit = exprMap.get(inc.getExpression());
+ if (crit == null) {
+ exprMap.put(inc.getExpression(), converted);
+ } else if (!(crit instanceof IsNullCriteria)) {
+ return FALSE_CRITERIA;
+ }
+ }
+ } else if (converted instanceof SetCriteria) {
+ SetCriteria sc = (SetCriteria)converted;
+ Criteria crit = exprMap.get(sc.getExpression());
+ if (crit instanceof IsNullCriteria) {
+ return FALSE_CRITERIA;
+ }
+ if (!sc.isNegated() && sc.isAllConstants()) {
+ if (crit == null) {
+ exprMap.put(sc.getExpression(), converted);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria sc1 = (SetCriteria)crit;
+ sc1.getValues().retainAll(sc.getValues());
+ if (sc1.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
+ continue;
+ } else {
+ CompareCriteria cc = (CompareCriteria)crit;
+ for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
+ if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ exprIter.remove();
+ }
+ }
+ //TODO: single value as compare criteria
+ if (sc.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getOperator() != CompareCriteria.EQ) {
+ newCrits.remove(cc);
+ exprMap.put(sc.getExpression(), sc);
+ } else {
+ continue;
+ }
+ }
+ }
+ } else if (converted instanceof CompareCriteria) {
+ CompareCriteria cc = (CompareCriteria)converted;
+ Criteria crit = exprMap.get(cc.getLeftExpression());
+ if (crit instanceof IsNullCriteria) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getRightExpression() instanceof Constant) {
+ if (crit == null) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (crit instanceof SetCriteria) {
+ SetCriteria sc = (SetCriteria)crit;
+ boolean modified = false;
+ for (Iterator<Constant> exprIter = sc.getValues().iterator(); exprIter.hasNext();) {
+ if (!Evaluator.compare(cc, exprIter.next().getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ if (!modified) {
+ modified = true;
+ newCrits.remove(sc);
+ }
+ exprIter.remove();
+ }
+ }
+ //TODO: single value as compare criteria
+ if (sc.getValues().isEmpty()) {
+ return FALSE_CRITERIA;
+ }
+ if (cc.getOperator() == CompareCriteria.EQ) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (modified) {
+ newCrits.add(sc);
+ continue;
+ }
+ } else {
+ CompareCriteria cc1 = (CompareCriteria)crit;
+ if (cc1.getOperator() == CompareCriteria.NE) {
+ exprMap.put(cc.getLeftExpression(), cc);
+ } else if (cc1.getOperator() == CompareCriteria.EQ) {
+ if (!Evaluator.compare(cc1, ((Constant)cc1.getRightExpression()).getValue(), ((Constant)cc.getRightExpression()).getValue())) {
+ return FALSE_CRITERIA;
+ }
+ continue;
+ }
+ if (cc.getOperator() == CompareCriteria.EQ) {
+ if (!Evaluator.compare(cc1, ((Constant)cc.getRightExpression()).getValue(), ((Constant)cc1.getRightExpression()).getValue())) {
+ return FALSE_CRITERIA;
+ }
+ exprMap.put(cc.getLeftExpression(), cc);
+ newCrits.remove(cc1);
+ }
+ }
+ }
+ }
}
newCrits.add(converted);
}
Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCalculateCostUtil.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCalculateCostUtil.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCalculateCostUtil.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -666,13 +666,13 @@
//ensures that the ordering of criteria does not effect the costing calculation
@Test public void testCompoundCriteriaEstimate4() throws Exception {
- String crit = "US.accounts.account = 10 and US.accounts.account = US.accounts.customer and US.accounts.account < 100"; //$NON-NLS-1$
+ String crit = "US.accounts.account = 10 and US.accounts.account = US.accounts.customer and US.accounts.customer < 100"; //$NON-NLS-1$
- helpTestEstimateCost(crit, 1000, 213, TestVirtualDepJoin.exampleVirtualDepJoin());
+ helpTestEstimateCost(crit, 1000, 64, TestVirtualDepJoin.exampleVirtualDepJoin());
- String crit1 = "US.accounts.account = US.accounts.customer and US.accounts.account < 100 and US.accounts.account = 10"; //$NON-NLS-1$
+ String crit1 = "US.accounts.account = US.accounts.customer and US.accounts.customer < 100 and US.accounts.account = 10"; //$NON-NLS-1$
- helpTestEstimateCost(crit1, 1000, 213, TestVirtualDepJoin.exampleVirtualDepJoin());
+ helpTestEstimateCost(crit1, 1000, 64, TestVirtualDepJoin.exampleVirtualDepJoin());
}
@Test public void testCompoundCriteriaEstimate5() throws Exception {
Modified: trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/engine/src/test/java/org/teiid/query/processor/xml/TestXMLProcessor.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -28,7 +28,6 @@
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -698,11 +698,11 @@
}
@Test public void testRewriteAnd6() {
- helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x') and (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("(1 = 1) AND (5 = 5) AND (pm1.g1.e1 = 'x')", "(pm1.g1.e1 = 'x')"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteAnd7() {
- helpTestRewriteCriteria("(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')", "(pm1.g1.e1 = 'x') AND (pm1.g1.e1 = 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCriteria("(pm1.g1.e1 = 'x') AND (lower(pm1.g1.e1) = 'y')", "(pm1.g1.e1 = 'x') AND (lcase(pm1.g1.e1) = 'y')"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteMixed1() {
@@ -1931,7 +1931,7 @@
}
@Test public void testRewriteXMLCriteriaCases5630And5640() {
- helpTestRewriteCommand("select * from xmltest.doc1 where node1 = null", "SELECT * FROM xmltest.doc1 WHERE null <> null"); //$NON-NLS-1$ //$NON-NLS-2$
+ helpTestRewriteCommand("select * from xmltest.doc1 where node1 = null", "SELECT * FROM xmltest.doc1 WHERE node1 = null"); //$NON-NLS-1$ //$NON-NLS-2$
}
@Test public void testRewriteCorrelatedSubqueryInHaving() {
@@ -2318,5 +2318,46 @@
@Test public void testRewriteExpressionCriteria() throws Exception {
helpTestRewriteCriteria("pm1.g1.e3", "pm1.g1.e3 = true");
}
+
+ @Test public void testRewritePredicateOptimization() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 in (1, 2, 3) and pm1.g1.e2 in (2, 3, 4)", "pm1.g1.e2 in (2, 3)");
+ }
+
+ @Test public void testRewritePredicateOptimization1() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 < 5 and pm1.g1.e2 = 2", "pm1.g1.e2 = 2");
+ }
+
+ @Test public void testRewritePredicateOptimization2() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 < 5 and pm1.g1.e2 = 6", "1 = 0");
+ }
+
+ @Test public void testRewritePredicateOptimization2a() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 < 5 and pm1.g1.e2 = 2", "pm1.g1.e2 = 2");
+ }
+ @Test public void testRewritePredicateOptimization3() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 in (1, 2) and pm1.g1.e2 = 6", "1 = 0");
+ }
+
+ @Test public void testRewritePredicateOptimization4() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 in (1, 2) and pm1.g1.e2 is null", "1 = 0");
+ }
+
+ @Test public void testRewritePredicateOptimization5() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 <> 5 and pm1.g1.e2 in (2, 3, 5)", "pm1.g1.e2 in (2, 3)");
+ }
+
+ @Test public void testRewritePredicateOptimization6() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 = 5 and pm1.g1.e2 in (5, 6)", "pm1.g1.e2 = 5");
+ }
+
+ @Test public void testRewritePredicateOptimization6a() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 in (5, 6) and pm1.g1.e2 = 5", "pm1.g1.e2 = 5");
+ }
+
+ @Ignore("TODO")
+ @Test public void testRewritePredicateOptimization7() throws Exception {
+ helpTestRewriteCriteria("pm1.g1.e2 > 5 and pm1.g1.e2 < 2", "1 = 0");
+ }
+
}
Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2010-12-13 22:02:28 UTC (rev 2774)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/language/TestLanguageUtil.java 2010-12-14 18:24:19 UTC (rev 2775)
@@ -85,18 +85,18 @@
}
public void testSeparateCrit_nestedAND() throws Exception {
- helpTestSeparateByAnd("((intkey = 1 AND intkey = 2) AND (intkey = 3) AND (intkey = 4))", //$NON-NLS-1$
+ helpTestSeparateByAnd("((intkey = 1 AND intnum = 2) AND (stringnum = '3') AND (stringkey = '4'))", //$NON-NLS-1$
new String[] { "SmallA.IntKey = 1", //$NON-NLS-1$
- "SmallA.IntKey = 2", //$NON-NLS-1$
- "SmallA.IntKey = 3", //$NON-NLS-1$
- "SmallA.IntKey = 4" }); //$NON-NLS-1$
+ "SmallA.IntNum = 2", //$NON-NLS-1$
+ "SmallA.StringNum = '3'", //$NON-NLS-1$
+ "SmallA.StringKey = '4'" }); //$NON-NLS-1$
}
public void testSeparateCrit_NOT() throws Exception {
- helpTestSeparateByAnd("((NOT (intkey = 1 AND intkey = 2)) AND (intkey = 3) AND (intkey = 4))", //$NON-NLS-1$
- new String[] { "SmallA.IntKey <> 1 OR SmallA.IntKey <> 2", //$NON-NLS-1$
- "SmallA.IntKey = 3", //$NON-NLS-1$
- "SmallA.IntKey = 4" }); //$NON-NLS-1$
+ helpTestSeparateByAnd("(NOT (intkey = 1 AND intnum = 2) AND (stringnum = '3') AND (stringkey = '4'))", //$NON-NLS-1$
+ new String[] { "SmallA.IntKey <> 1 OR SmallA.IntNum <> 2", //$NON-NLS-1$
+ "SmallA.StringNum = '3'", //$NON-NLS-1$
+ "SmallA.StringKey = '4'" }); //$NON-NLS-1$
}
public void helpTestCombineCriteria(String primaryStr, String additionalStr, String expected) throws Exception {
@@ -128,11 +128,11 @@
}
public void testCombineCrit_primaryPredicate() throws Exception {
- helpTestCombineCriteria("intkey = 1", "intkey = 2 AND intkey = 3", "SmallA.IntKey = 1 AND SmallA.IntKey = 2 AND SmallA.IntKey = 3"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpTestCombineCriteria("intkey = 1", "intnum = 2 AND stringkey = '3'", "SmallA.IntKey = 1 AND SmallA.IntNum = 2 AND SmallA.StringKey = '3'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public void testCombineCrit_additionalPredicate() throws Exception {
- helpTestCombineCriteria("intkey = 1 AND intkey = 2", "intkey = 3", "SmallA.IntKey = 1 AND SmallA.IntKey = 2 AND SmallA.IntKey = 3"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ helpTestCombineCriteria("intkey = 1 AND intnum = 2", "stringkey = '3'", "SmallA.IntKey = 1 AND SmallA.IntNum = 2 AND SmallA.StringKey = '3'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
More information about the teiid-commits
mailing list