[teiid-commits] teiid SVN: r4406 - in trunk/engine/src: test/java/org/teiid/query/processor and 1 other directory.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Sep 6 15:02:53 EDT 2012


Author: shawkins
Date: 2012-09-06 15:02:53 -0400 (Thu, 06 Sep 2012)
New Revision: 4406

Modified:
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
Log:
TEIID-2190 ensuring index use retains all equi-join predicates

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java	2012-09-06 15:58:12 UTC (rev 4405)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleImplementJoinStrategy.java	2012-09-06 19:02:53 UTC (rev 4406)
@@ -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;
@@ -131,44 +133,51 @@
             	key = NewCalculateCostUtil.getKeyUsed(leftExpressions, null, metadata, null);
             	right = false;
             }
-            if (key != null) {
+            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()];
-            	List<Integer> toCriteria = new ArrayList<Integer>(rightExpressions.size() - keyCols.size()); 
+            	LinkedHashSet<Integer> toCriteria = new LinkedHashSet<Integer>();
             	List<Expression> keyExpressions = right?rightExpressions:leftExpressions;
-        		for (int j = 0; j < keyExpressions.size(); j++) {
-					Expression 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;
+            		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;
+				}
+        		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>();
 						}
-					}
-					if (!found) {
-						toCriteria.add(j);
-					}
-				}
-        		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: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2012-09-06 15:58:12 UTC (rev 4405)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2012-09-06 19:02:53 UTC (rev 4406)
@@ -475,9 +475,25 @@
 		execute("insert into x (e2, e1) values (2, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
 		execute("insert into x1 (e2, e1) values (3, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
 		execute("select x.e1 from x makenotdep, x1 makenotdep where x.e2 = x1.e2 and x.e1 = x1.e1", new List[0]); //$NON-NLS-1$
+		//ensure join is preserved
 		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