[teiid-commits] teiid SVN: r4187 - in branches/7.4.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
Tue Jun 19 10:13:47 EDT 2012


Author: jolee
Date: 2012-06-19 10:13:44 -0400 (Tue, 19 Jun 2012)
New Revision: 4187

Modified:
   branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
   branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java
Log:
TEIID-2074: NPE with multi-column dependent join

Modified: branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
===================================================================
--- branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java	2012-06-19 02:20:38 UTC (rev 4186)
+++ branches/7.4.x/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java	2012-06-19 14:13:44 UTC (rev 4187)
@@ -27,17 +27,21 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.teiid.api.exception.query.ExpressionEvaluationException;
 import org.teiid.common.buffer.BlockedException;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.DataTypeManager;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
 import org.teiid.query.QueryPlugin;
@@ -108,22 +112,47 @@
                 }
             	for (SetState setState : dependentSetStates) {
                     setState.valueIterator = dvs.getValueIterator(setState.valueExpression);
-                    if (setState.maxNdv > 0 && setState.maxNdv < dvs.getTupleBuffer().getRowCount()) {
-                    	ValueIterator vi = dvs.getValueIterator(setState.valueExpression);
-                    	Comparable last = null;
-                    	int distinctCount = 0;
-                    	while (vi.hasNext()) {
-                    		Comparable next = (Comparable) vi.next();
-                    		if (last == null || next.compareTo(last) != 0) {
-                    			distinctCount++;
+                    int distinctCount = dvs.getTupleBuffer().getRowCount();
+                    if (setState.maxNdv <= 0 || setState.maxNdv >= distinctCount) {
+                    	continue;
+                    }
+                    if (dvs.getTupleBuffer().getSchema().size() > 1) {
+	                    distinctCount = 0;
+	                	ValueIterator vi = dvs.getValueIterator(setState.valueExpression);
+                    	if (dvs.getTupleBuffer().getSchema().indexOf(setState.valueExpression) == 0) {
+        	            	Object last = null;
+	                    	while (vi.hasNext()) {
+    	                		Object next = vi.next();
+        	            		if (next != null && (last == null || ((Comparable)next).compareTo(last) != 0)) {
+            	        			distinctCount++;
+                	    		}
+                    			last = next;
                     		}
-                    		last = next;
+                    	} else {
+                    		//secondary attributes are not in sorted order, so we use an approximate count
+                    		Set<Object> set = new TreeSet<Object>();
+                    		int maxSize = Math.min(10000, dvs.getTupleBuffer().getRowCount());
+                    		List<Object> buffer = Arrays.asList(new Object[maxSize]);
+                    		int i = 0;
+	                    	while (vi.hasNext()) {
+    	                		Object next = vi.next();
+    	                		if (next == null) {
+    	                			continue;
+    	                		}
+        	            		if (set.add(next)) {
+            	        			distinctCount++;
+                	    		}
+        	            		Object old = buffer.set(i++%maxSize, next);
+        	            		if (set.size() > maxSize) {
+        	            			set.remove(old);
+        	            		}
+                    		}
                     	}
-                    	if (!setState.overMax && distinctCount > setState.maxNdv) {
-                    		LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("DependentCriteriaProcessor.dep_join_backoff", valueSource, setState.valueExpression, setState.maxNdv)); //$NON-NLS-1$
-                    		setState.overMax = true;
-                    	}
-                    }
+                	}
+                	if (!setState.overMax && distinctCount > setState.maxNdv) {
+                		LogManager.logWarning(LogConstants.CTX_DQP, QueryPlugin.Util.getString("DependentCriteriaProcessor.dep_join_backoff", valueSource, setState.valueExpression, setState.maxNdv)); //$NON-NLS-1$
+                		setState.overMax = true;
+                	}
     			}
             }
         }

Modified: branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java
===================================================================
--- branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java	2012-06-19 02:20:38 UTC (rev 4186)
+++ branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java	2012-06-19 14:13:44 UTC (rev 4187)
@@ -571,6 +571,7 @@
         		metadata,
             "pm1.g1", new List[] { 
 				    Arrays.asList(new Object[] { "a",   new Integer(0),     Boolean.FALSE,  new Double(2.0) }), //$NON-NLS-1$
+				    Arrays.asList(new Object[] { "q",   null,     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
 				    Arrays.asList(new Object[] { "b",   new Integer(1),     Boolean.TRUE,   null }), //$NON-NLS-1$
 				    Arrays.asList(new Object[] { "c",   new Integer(2),     Boolean.FALSE,  new Double(0.0) }), //$NON-NLS-1$
 				    } );       
@@ -578,7 +579,7 @@
         dataMgr.registerTuples(
         		metadata,
             "pm6.g1", new List[] { 
-				    Arrays.asList(new Object[] { "b",   new Integer(0) }), //$NON-NLS-1$
+				    Arrays.asList(new Object[] { "b",   1 }), //$NON-NLS-1$
 				    Arrays.asList(new Object[] { "d",   new Integer(3) }), //$NON-NLS-1$
 				    Arrays.asList(new Object[] { "e",   new Integer(1) }), //$NON-NLS-1$
 				    } );      
@@ -837,7 +838,7 @@
         FakeDataManager dataManager = helpTestBackoff(true);
         
         //note that the dependent join was not actually performed
-        assertEquals(new HashSet<String>(Arrays.asList("SELECT pm1.g1.e1 FROM pm1.g1", "SELECT pm6.g1.e1 FROM pm6.g1 ORDER BY pm6.g1.e1")), 
+        assertEquals(new HashSet<String>(Arrays.asList("SELECT pm6.g1.e1, pm6.g1.e2 FROM pm6.g1 ORDER BY pm6.g1.e1, pm6.g1.e2", "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1")), 
         		new HashSet<String>(dataManager.getQueries()));
     }
     
@@ -852,7 +853,7 @@
 			QueryMetadataException, TeiidComponentException,
 			TeiidProcessingException {
 		// Create query 
-        String sql = "SELECT pm1.g1.e1 FROM pm1.g1, pm6.g1 WHERE pm1.g1.e1=pm6.g1.e1"; //$NON-NLS-1$
+        String sql = "SELECT pm1.g1.e1 FROM pm1.g1, pm6.g1 WHERE pm1.g1.e1=pm6.g1.e1 and pm1.g1.e2=pm6.g1.e2"; //$NON-NLS-1$
 
         // Construct data manager with data
         FakeDataManager dataManager = new FakeDataManager();
@@ -863,10 +864,12 @@
         RealMetadataFactory.setCardinality("pm1.g1", 1, fakeMetadata);
         if (setNdv) {
         	fakeMetadata.getElementID("pm1.g1.e1").setDistinctValues(1);
+        	fakeMetadata.getElementID("pm1.g1.e2").setDistinctValues(1);
         }
         RealMetadataFactory.setCardinality("pm6.g1", 1000, fakeMetadata);
         if (setNdv) {
         	fakeMetadata.getElementID("pm6.g1.e1").setDistinctValues(1000);
+        	fakeMetadata.getElementID("pm6.g1.e2").setDistinctValues(1000);
         }
         // Plan query
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
@@ -886,8 +889,8 @@
                 new String("b")})}; //$NON-NLS-1$
 
         ProcessorPlan plan = TestOptimizer.helpPlan(sql, fakeMetadata, new String[] {
-        		"SELECT pm6.g1.e1 FROM pm6.g1 WHERE pm6.g1.e1 IN (<dependent values>) ORDER BY pm6.g1.e1",
-        		"SELECT pm1.g1.e1 FROM pm1.g1"
+        		"SELECT pm6.g1.e1, pm6.g1.e2 FROM pm6.g1 WHERE (pm6.g1.e1 IN (<dependent values>)) AND (pm6.g1.e2 IN (<dependent values>)) ORDER BY pm6.g1.e1, pm6.g1.e2", 
+        		"SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"
         }, capFinder, ComparisonMode.EXACT_COMMAND_STRING);
 
         // Run query



More information about the teiid-commits mailing list