[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