[teiid-commits] teiid SVN: r4416 - in branches/7.7.x/engine/src: test/java/org/teiid/query/processor and 1 other directory.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Sep 10 11:11:59 EDT 2012


Author: jolee
Date: 2012-09-10 11:11:59 -0400 (Mon, 10 Sep 2012)
New Revision: 4416

Modified:
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
Log:
TEIID-2190: Key usage can remove predicates

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java	2012-09-10 13:58:25 UTC (rev 4415)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java	2012-09-10 15:11:59 UTC (rev 4416)
@@ -25,8 +25,10 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.teiid.api.exception.query.QueryMetadataException;
@@ -50,6 +52,7 @@
 import org.teiid.query.sql.lang.JoinType;
 import org.teiid.query.sql.lang.OrderBy;
 import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
 import org.teiid.query.sql.util.SymbolMap;
@@ -131,44 +134,51 @@
             	key = NewCalculateCostUtil.getKeyUsed(leftExpressions, null, metadata, null);
             	right = false;
             }
-            if (key != null) {
-            	//redo the join predicates based upon the key alone
-            	List<Object> keyCols = metadata.getElementIDsInKey(key);
-            	int[] reorder = new int[keyCols.size()];
-            	List<Integer> toCriteria = new ArrayList<Integer>(rightExpressions.size() - keyCols.size()); 
+            if (key != null && joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) == null) {
+             	//redo the join predicates based upon the key alone
+             	List<Object> keyCols = metadata.getElementIDsInKey(key);
+             	int[] reorder = new int[keyCols.size()];
+             	LinkedHashSet<Integer> toCriteria = new LinkedHashSet<Integer>();
             	List<SingleElementSymbol> keyExpressions = right?rightExpressions:leftExpressions;
-        		for (int j = 0; j < keyExpressions.size(); j++) {
-					SingleElementSymbol ses = keyExpressions.get(j);
-					if (!(ses instanceof ElementSymbol)) {
+            	Map<Object, Integer> indexMap = new LinkedHashMap<Object, Integer>();
+            	for (int i = 0; i < keyExpressions.size(); i++) {
+            		Expression ses = keyExpressions.get(i);
+            		if (!(ses instanceof ElementSymbol)) {
 						continue;
 					}
-					ElementSymbol es = (ElementSymbol)ses;
-					boolean found = false;
-					for (int i = 0; !found && i < keyCols.size(); i++) {
-						if (es.getMetadataID().equals(keyCols.get(i))) {
-							reorder[i] = j;
-							found = true;
-						}
-					}
-					if (!found) {
-						toCriteria.add(j);
-					}
+            		Integer existing = indexMap.put(((ElementSymbol)ses).getMetadataID(), i);
+            		if (existing != null) {
+            			toCriteria.add(existing);
+            		}
+            	}
+            	boolean found = true;
+            	for (int i = 0; i < keyCols.size(); i++) {
+            		Object id = keyCols.get(i);
+            		Integer index = indexMap.remove(id);
+            		if (index == null) {
+            			found = false;
+            			break;
+            		}
+            		reorder[i] = index;
 				}
-        		List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.NON_EQUI_JOIN_CRITERIA);
-        		for (int index : toCriteria) {
-					SingleElementSymbol lses = leftExpressions.get(index);
-					SingleElementSymbol rses = rightExpressions.get(index);
-					CompareCriteria cc = new CompareCriteria(lses, CompareCriteria.EQ, rses);
-					if (joinCriteria == null || joinCriteria.isEmpty()) {
-						joinCriteria = new ArrayList<Criteria>();
+            	if (found) {
+            		toCriteria.addAll(indexMap.values());
+            		List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.NON_EQUI_JOIN_CRITERIA);
+            		for (int index : toCriteria) {
+            			Expression lses = leftExpressions.get(index);
+            			Expression rses = rightExpressions.get(index);
+            			CompareCriteria cc = new CompareCriteria(lses, CompareCriteria.EQ, rses);
+            			if (joinCriteria == null || joinCriteria.isEmpty()) {
+            				joinCriteria = new ArrayList<Criteria>();
+            			}
 						joinCriteria.add(cc);
 					}
-				}
-        		joinNode.setProperty(Info.NON_EQUI_JOIN_CRITERIA, joinCriteria);
-        		leftExpressions = RelationalNode.projectTuple(reorder, leftExpressions);
-            	rightExpressions = RelationalNode.projectTuple(reorder, rightExpressions);
-            	joinNode.setProperty(NodeConstants.Info.LEFT_EXPRESSIONS, leftExpressions);
-            	joinNode.setProperty(NodeConstants.Info.RIGHT_EXPRESSIONS, rightExpressions);
+            		joinNode.setProperty(Info.NON_EQUI_JOIN_CRITERIA, joinCriteria);
+            		leftExpressions = RelationalNode.projectTuple(reorder, leftExpressions);
+            		rightExpressions = RelationalNode.projectTuple(reorder, rightExpressions);
+            		joinNode.setProperty(NodeConstants.Info.LEFT_EXPRESSIONS, leftExpressions);
+            		joinNode.setProperty(NodeConstants.Info.RIGHT_EXPRESSIONS, rightExpressions);
+            	}				
             }
 
 			boolean pushedLeft = insertSort(joinNode.getFirstChild(), leftExpressions, joinNode, metadata, capabilitiesFinder, pushLeft);	

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2012-09-10 13:58:25 UTC (rev 4415)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2012-09-10 15:11:59 UTC (rev 4416)
@@ -479,6 +479,21 @@
 		execute("select x.e1 from x left outer join x1 on x.e2 = x1.e2 and x.e1 = x1.e1", new List[] {Arrays.asList("b")}); //$NON-NLS-1$
 	}
 	
+	@Test public void testUnneededMergePredicate1() throws Exception {
+		execute("create local temporary table x (e1 string, e2 integer, e3 integer, primary key (e1))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
+		execute("create local temporary table x1 (e1 string, e2 integer, e3 integer)", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
+				
+		execute("insert into x (e3, e2, e1) values (4, 2, '1')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e3, e2, e1) values (4, 2, '2')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x1 (e3, e2, e1) values (5, 2, '1')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x1 (e3, e2, e1) values (5, 1, '2')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		//ensure predicates are preserved
+		execute("select x.e1 from /*+ makenotdep */ x inner join  /*+ makenotdep */ x1 on x.e1 = x1.e1 and upper(x.e1) = x1.e2", new List[] {Arrays.asList("1"), Arrays.asList("2")}); //$NON-NLS-1$
+		execute("select x.e1 from /*+ makenotdep */ x inner join  /*+ makenotdep */ x1 on x.e1 = x1.e1 and upper(x.e1) = x1.e2 and x1.e3 = x.e3", new List[0]); //$NON-NLS-1$
+		//ensure there's no bad interaction with makedep
+		execute("select x.e1 from /*+ makedep */ x inner join  x1 on x.e1 = x1.e1 and x.e2 = x1.e2", new List[] {Arrays.asList("1")}); //$NON-NLS-1$
+	}
+	
 	private void sampleTable() throws Exception {
 		execute("create local temporary table x (e1 string, e2 integer, primary key (e1, e2))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
 		execute("insert into x (e2, e1) values (3, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$



More information about the teiid-commits mailing list