[teiid-commits] teiid SVN: r3815 - in trunk: connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel and 13 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Mon Jan 23 14:59:02 EST 2012


Author: shawkins
Date: 2012-01-23 14:59:01 -0500 (Mon, 23 Jan 2012)
New Revision: 3815

Added:
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java
Removed:
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java
Modified:
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCMetdataProcessor.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
   trunk/connectors/translator-jdbc/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
   trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java
   trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
   trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
   trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java
   trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
Log:
forward merge from 7.6.1

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCExecutionFactory.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -254,12 +254,17 @@
 	@Override
 	public void getMetadata(MetadataFactory metadataFactory, Connection conn) throws TranslatorException {
 		try {
-			JDBCMetdataProcessor metadataProcessor = new JDBCMetdataProcessor();
+			JDBCMetdataProcessor metadataProcessor = createMetadataProcessor();
 			PropertiesUtils.setBeanProperties(metadataProcessor, metadataFactory.getImportProperties(), "importer"); //$NON-NLS-1$
 			metadataProcessor.getConnectorMetadata(conn, metadataFactory);
 		} catch (SQLException e) {
 			throw new TranslatorException(e);
 		}
+	}
+
+	protected JDBCMetdataProcessor createMetadataProcessor() {
+		JDBCMetdataProcessor metadataProcessor = new JDBCMetdataProcessor();
+		return metadataProcessor;
 	}    
 	
 	@Override

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCMetdataProcessor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCMetdataProcessor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCMetdataProcessor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -293,7 +293,7 @@
 		return TypeFacility.getDataTypeNameFromSQLType(type);
 	}
 	
-	private String quoteName(String name) {
+	protected String quoteName(String name) {
 		if (quoteNameInSource) {
 			return quoteString + StringUtil.replaceAll(name, quoteString, quoteString + quoteString) + quoteString;
 		}

Deleted: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java
===================================================================
--- branches/7.6.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java	2012-01-23 18:52:20 UTC (rev 3813)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -1,42 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership.  Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.translator.jdbc.excel;
-
-import org.teiid.translator.Translator;
-import org.teiid.translator.jdbc.JDBCExecutionFactory;
-import org.teiid.translator.jdbc.JDBCMetdataProcessor;
-
- at Translator(name="excel-odbc", description="A translator for Excel using the JDBC-ODBC bridge")
-public class ExcelExecutionFactory extends JDBCExecutionFactory {
-	
-	@Override
-	protected JDBCMetdataProcessor createMetadataProcessor() {
-		return new JDBCMetdataProcessor() {
-			@Override
-			protected String quoteName(String name) {
-				return '[' + name + ']';
-			}
-		};
-	}
-
-}

Copied: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java (from rev 3813, branches/7.6.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java)
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java	                        (rev 0)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/excel/ExcelExecutionFactory.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.translator.jdbc.excel;
+
+import org.teiid.translator.Translator;
+import org.teiid.translator.jdbc.JDBCExecutionFactory;
+import org.teiid.translator.jdbc.JDBCMetdataProcessor;
+
+ at Translator(name="excel-odbc", description="A translator for Excel using the JDBC-ODBC bridge")
+public class ExcelExecutionFactory extends JDBCExecutionFactory {
+	
+	@Override
+	protected JDBCMetdataProcessor createMetadataProcessor() {
+		return new JDBCMetdataProcessor() {
+			@Override
+			protected String quoteName(String name) {
+				return '[' + name + ']';
+			}
+		};
+	}
+
+}

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/mysql/MySQL5ExecutionFactory.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -85,7 +85,7 @@
     public Object retrieveValue(ResultSet results, int columnIndex,
     		Class<?> expectedType) throws SQLException {
     	Object result = super.retrieveValue(results, columnIndex, expectedType);
-    	if (expectedType == TypeFacility.RUNTIME_TYPES.STRING && result instanceof Blob) {
+    	if (expectedType == TypeFacility.RUNTIME_TYPES.STRING && (result instanceof Blob || result instanceof byte[])) {
     		return results.getString(columnIndex);
     	}
     	return result;
@@ -95,10 +95,10 @@
     public Object retrieveValue(CallableStatement results, int parameterIndex,
     		Class<?> expectedType) throws SQLException {
     	Object result = super.retrieveValue(results, parameterIndex, expectedType);
-    	if (expectedType == TypeFacility.RUNTIME_TYPES.STRING && result instanceof Blob) {
+    	if (expectedType == TypeFacility.RUNTIME_TYPES.STRING && (result instanceof Blob || result instanceof byte[])) {
     		return results.getString(parameterIndex);
     	}
     	return result;
     }
     
-}
+}

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -36,10 +36,13 @@
 import java.util.List;
 
 import org.teiid.language.Command;
+import org.teiid.language.Expression;
 import org.teiid.language.Function;
 import org.teiid.language.LanguageObject;
 import org.teiid.language.Limit;
+import org.teiid.language.Literal;
 import org.teiid.language.OrderBy;
+import org.teiid.language.SQLConstants;
 import org.teiid.language.SetQuery;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.SourceSystemFunctions;
@@ -100,10 +103,30 @@
         registerFunctionModifier(SourceSystemFunctions.QUARTER, new EscapeSyntaxModifier());
         registerFunctionModifier(SourceSystemFunctions.SECOND, new EscapeSyntaxModifier());
         registerFunctionModifier(SourceSystemFunctions.WEEK, new EscapeSyntaxModifier());
-        registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier());
-        registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier());
         registerFunctionModifier(SourceSystemFunctions.LENGTH, new EscapeSyntaxModifier());
         registerFunctionModifier(SourceSystemFunctions.ATAN2, new EscapeSyntaxModifier());
+        registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier() {
+			
+			@Override
+			public List<?> translate(Function function) {
+				if (!isFracSeconds(function)) {
+					return super.translate(function);
+				}
+				//convert from billionths to thousandths
+				return Arrays.asList("dateadd(millisecond, ", function.getParameters().get(1), "/1000000, ", function.getParameters().get(2), ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			}
+		});
+        registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier() {
+			
+			@Override
+			public List<?> translate(Function function) {
+				if (!isFracSeconds(function)) {
+					return super.translate(function);
+				}
+				//convert from billionths to thousandths
+				return Arrays.asList("datediff(millisecond, ", function.getParameters().get(1), ",", function.getParameters().get(2), ")*1000000"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			}
+		});
         
         //add in type conversion
         ConvertModifier convertModifier = new ConvertModifier();
@@ -390,5 +413,10 @@
     protected boolean supportsCrossJoin() {
     	return false;
     }
+
+	private boolean isFracSeconds(Function function) {
+		Expression e = function.getParameters().get(0);
+		return (e instanceof Literal && SQLConstants.NonReserved.SQL_TSI_FRAC_SECOND.equalsIgnoreCase((String)((Literal)e).getValue()));
+	}
     
 }

Modified: trunk/connectors/translator-jdbc/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory
===================================================================
--- trunk/connectors/translator-jdbc/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/main/resources/META-INF/services/org.teiid.translator.ExecutionFactory	2012-01-23 19:59:01 UTC (rev 3815)
@@ -20,3 +20,4 @@
 org.teiid.translator.jdbc.sybase.SybaseExecutionFactory #sybase
 org.teiid.translator.jdbc.teiid.TeiidExecutionFactory #teiid
 org.teiid.translator.jdbc.teradata.TeradataExecutionFactory #teradata
+org.teiid.translator.jdbc.excel.ExcelExecutionFactory #excel-odbc

Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -250,5 +250,10 @@
         helpTestVisitor(getBQTVDB(), input, output);
     }
 
-
+    @Test public void testTimestampFunctions() {
+        helpTestVisitor(getBQTVDB(),
+            "SELECT timestampadd(sql_tsi_second, 1, timestampvalue), timestampadd(sql_tsi_frac_second, 1000, timestampvalue), timestampdiff(sql_tsi_frac_second, timestampvalue, timestampvalue) from bqt1.smalla", //$NON-NLS-1$
+            "SELECT {fn timestampadd(sql_tsi_second, 1, SmallA.TimestampValue)}, dateadd(millisecond, 1000/1000000, SmallA.TimestampValue), datediff(millisecond, SmallA.TimestampValue,SmallA.TimestampValue)*1000000 FROM SmallA"); //$NON-NLS-1$
+    }
+    
 }

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourcePlanToProcessConverter.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -155,11 +155,14 @@
             try {
                 command = QueryRewriter.rewrite(command, metadata, null);                    
                 instanceNode.setCommand(command);
+                if (!instanceNode.isShouldEvaluate()) {
+                	instanceNode.minimizeProject(command);
+                }
             } catch(QueryValidatorException e) {
                 // ignore and use original command
             }
             
-            if (!RelationalNodeUtil.shouldExecute(command, false)) {
+            if (!RelationalNodeUtil.shouldExecute(command, false, true)) {
                 continue;
             }
                                 
@@ -269,7 +272,7 @@
 		    DeepPreOrderNavigator.doVisit(command, new MultiSourceElementReplacementVisitor(sourceName));
 		}
 		
-		if (!RelationalNodeUtil.shouldExecute(command, false)) {
+		if (!RelationalNodeUtil.shouldExecute(command, false, true)) {
             return null;
         }
 		

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -358,7 +358,7 @@
         
         rules.push(RuleConstants.PLAN_SORTS);
         
-        //TODO: update plan sorts to take advantage or semi-join ordering
+        //TODO: update plan sorts to take advantage of semi-join ordering
         if (hints.hasJoin || hints.hasCriteria) {
             rules.push(new RuleMergeCriteria(idGenerator, capFinder, analysisRecord, context, metadata));
         }
@@ -381,9 +381,7 @@
             rules.push(new RulePushAggregates(idGenerator));
         }
         if(hints.hasJoin) {
-            rules.push(RuleConstants.CHOOSE_DEPENDENT);
-        }
-        if(hints.hasJoin) {
+        	rules.push(RuleConstants.CHOOSE_DEPENDENT);
             rules.push(RuleConstants.CHOOSE_JOIN_STRATEGY);
             rules.push(RuleConstants.RAISE_ACCESS);
             //after planning the joins, let the criteria be pushed back into place
@@ -394,8 +392,9 @@
         if (hints.hasSetQuery) {
             rules.push(RuleConstants.PLAN_UNIONS);
         } 
-        if(hints.hasCriteria || hints.hasJoin) {
+        if(hints.hasCriteria || hints.hasJoin || hints.hasVirtualGroups) {
             //after copy criteria, it is no longer necessary to have phantom criteria nodes, so do some cleaning
+        	//also remove possible erroneous output elements
             rules.push(RuleConstants.CLEAN_CRITERIA);
         }
         if(hints.hasJoin) {


Property changes on: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3149-3217,3535-3555
/branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3673-3711,3754-3769
/trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3188-3450,3452-3666
   + /branches/7.4.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3149-3217,3535-3555
/branches/7.6.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3673-3711,3754-3769,3776-3813
/trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java:3188-3450,3452-3666

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/NewCalculateCostUtil.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -287,10 +287,14 @@
 			QueryMetadataInterface metadata, float cost)
 			throws QueryMetadataException, TeiidComponentException {
 		PlanNode projectNode = NodeEditor.findNodePreOrder(node, NodeConstants.Types.PROJECT);
+		float result = cost;
 		if (projectNode != null) {
-			cost = getNDVEstimate(node.getParent(), metadata, cost, (List)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS), false);
+			result = getNDVEstimate(node.getParent(), metadata, cost, (List)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS), false);
+			if (result == UNKNOWN_VALUE) {
+				return cost;
+			}
 		}
-		return cost;
+		return result;
 	}
 
     private static void setCardinalityEstimate(PlanNode node, Float bestEstimate, boolean setColEstimates, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException {
@@ -1138,7 +1142,12 @@
 		for (int i = 0; i < independentExpressions.size(); i++) {
 			Expression indExpr = (Expression)independentExpressions.get(i);
 			Collection<ElementSymbol> indElements = ElementCollectorVisitor.getElements(indExpr, true);
-			float indSymbolNDV = getNDVEstimate(independentNode, metadata, independentCardinality, indElements, true);
+			float indSymbolNDV = getNDVEstimate(independentNode, metadata, independentCardinality, indElements, false);
+			boolean unknownNDV = false;
+			if (indSymbolNDV == UNKNOWN_VALUE) {
+				unknownNDV = true;
+				indSymbolNDV = independentCardinality/2;
+			}
 			Expression depExpr = (Expression)dependentExpressions.get(i);
 			
 			LinkedList<Expression> depExpressions = new LinkedList<Expression>();
@@ -1197,6 +1206,7 @@
 							} 
 						}
 						depSymbolNDV = Math.max((float)Math.pow(depTargetCardinality, .75), Math.min(indSymbolOrigNDV, depTargetCardinality));
+						unknownNDV = true;
 					} else {
 						depSymbolNDV = depTargetCardinality;
 					}
@@ -1213,6 +1223,10 @@
 		        		dca.expectedCardinality = Math.min(dca.expectedCardinality, estimates[0]);
 		        	}
 		        }
+		        //don't use the ndv if it is unknown
+		        if (unknownNDV) {
+		        	continue;
+		        }
 		        dca.expectedNdv[i] = indSymbolNDV;
 		        //use a quick binary search to find the max ndv
 		        float min = 0;

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleCleanCriteria.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -35,6 +35,7 @@
 import org.teiid.query.optimizer.relational.plantree.NodeConstants;
 import org.teiid.query.optimizer.relational.plantree.NodeEditor;
 import org.teiid.query.optimizer.relational.plantree.PlanNode;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
 import org.teiid.query.sql.lang.Criteria;
 import org.teiid.query.sql.visitor.EvaluatableVisitor;
 import org.teiid.query.util.CommandContext;
@@ -53,40 +54,7 @@
 
         boolean pushRaiseNull = false;
         
-        for (PlanNode critNode : NodeEditor.findAllNodes(plan, NodeConstants.Types.SELECT)) {
-            
-            if (critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
-                NodeEditor.removeChildNode(critNode.getParent(), critNode);
-                continue;
-            }
-            
-            //TODO: remove dependent set criteria that has not been meaningfully pushed from its parent join
-            
-            if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.getGroups().size() != 0) {
-                continue;
-            }
-            
-            Criteria crit = (Criteria)critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
-            //if not evaluatable, just move on to the next criteria
-            if (!EvaluatableVisitor.isFullyEvaluatable(crit, true)) {
-                continue;
-            }
-            //if evaluatable
-            try {
-                boolean eval = Evaluator.evaluate(crit);
-                if(eval) {
-                    NodeEditor.removeChildNode(critNode.getParent(), critNode);
-                } else {
-                    FrameUtil.replaceWithNullNode(critNode);
-                    pushRaiseNull = true;
-                }
-            //none of the following exceptions should ever occur
-            } catch(BlockedException e) {
-                throw new TeiidComponentException(e);
-            } catch (ExpressionEvaluationException e) {
-                throw new TeiidComponentException(e);
-            } 
-        } 
+        pushRaiseNull = clean(plan);
         
         if (pushRaiseNull) {
             rules.push(RuleConstants.RAISE_NULL);
@@ -94,7 +62,55 @@
 
         return plan;        
     }
+
+	private boolean clean(PlanNode plan)
+			throws TeiidComponentException {
+		boolean pushRaiseNull = false;
+		plan.setProperty(Info.OUTPUT_COLS, null);
+        for (PlanNode node : plan.getChildren()) {
+        	pushRaiseNull |= clean(node);
+        }
+        if (plan.getType() == NodeConstants.Types.SELECT) {
+        	pushRaiseNull = cleanCriteria(plan);
+        }
+		return pushRaiseNull;
+	}
     
+    boolean cleanCriteria(PlanNode critNode) throws TeiidComponentException {
+        if (critNode.hasBooleanProperty(NodeConstants.Info.IS_PHANTOM)) {
+            NodeEditor.removeChildNode(critNode.getParent(), critNode);
+            return false;
+        }
+        
+        //TODO: remove dependent set criteria that has not been meaningfully pushed from its parent join
+        
+        if (critNode.hasBooleanProperty(NodeConstants.Info.IS_HAVING) || critNode.getGroups().size() != 0) {
+            return false;
+        }
+        
+        Criteria crit = (Criteria)critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
+        //if not evaluatable, just move on to the next criteria
+        if (!EvaluatableVisitor.isFullyEvaluatable(crit, true)) {
+            return false;
+        }
+        //if evaluatable
+        try {
+            boolean eval = Evaluator.evaluate(crit);
+            if(eval) {
+                NodeEditor.removeChildNode(critNode.getParent(), critNode);
+            } else {
+                FrameUtil.replaceWithNullNode(critNode);
+                return true;
+            }
+        //none of the following exceptions should ever occur
+        } catch(BlockedException e) {
+            throw new TeiidComponentException(e);
+        } catch (ExpressionEvaluationException e) {
+            throw new TeiidComponentException(e);
+        }
+        return false;
+    }
+    
     public String toString() {
         return "CleanCriteria"; //$NON-NLS-1$
     }

Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/DependentCriteriaProcessor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -72,6 +72,7 @@
         private DependentValueSource dvs;
         private List<SetState> dependentSetStates = new LinkedList<SetState>();
         private String valueSource;
+        private DependentValueSource originalVs;
 
         public TupleState(String source) {
         	this.valueSource = source;
@@ -80,7 +81,7 @@
         public void sort() throws BlockedException,
                    TeiidComponentException, TeiidProcessingException {
             if (dvs == null) {
-                DependentValueSource originalVs = (DependentValueSource)dependentNode.getContext().getVariableContext().getGlobalValue(valueSource);
+                originalVs = (DependentValueSource)dependentNode.getContext().getVariableContext().getGlobalValue(valueSource);
                 if (!originalVs.isDistinct()) {
 	            	if (sortUtility == null) {
 	            		List<Expression> sortSymbols = new ArrayList<Expression>(dependentSetStates.size());
@@ -120,7 +121,9 @@
         public void close() {
             if (dvs != null) {
             	sortUtility = null;
-                dvs.getTupleBuffer().remove();
+            	if (dvs != originalVs) {
+            		dvs.getTupleBuffer().remove();
+            	}
                 dvs = null;
             }
         }
@@ -354,6 +357,11 @@
     	}
 
         hasNextCommand = !restartIndexes.isEmpty();
+        if (hasNextCommand && dependentState.size() > 1) {
+        	for (TupleState state : dependentState.values()) {
+				state.originalVs.setUnused(true);
+			}
+        }
     }
 
     protected boolean hasNextCommand() {

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -690,8 +690,26 @@
     public void visit( Query obj ) {
     	addCacheHint(obj.getCacheHint());
     	addWithClause(obj);
+        append(SELECT);
+
+    	SourceHint sh = obj.getSourceHint();
+    	if (sh != null) {
+        	append(SPACE);
+        	append(BEGIN_HINT);
+        	append("sh"); //$NON-NLS-1$
+        	if (sh.getGeneralHint() != null) {
+        		appendSourceHintValue(sh.getGeneralHint());
+        	}
+        	if (sh.getSourceHints() != null) {
+        		for (Map.Entry<String, String> entry : sh.getSourceHints().entrySet()) {
+        			append(entry.getKey());
+        			appendSourceHintValue(entry.getValue());
+        		}
+        	}
+        	append(END_HINT);
+    	}
     	if (obj.getSelect() != null) {
-    		visitDirect(obj.getSelect(), obj);
+    		visitNode(obj.getSelect());
     	}
 
         if (obj.getInto() != null) {
@@ -779,31 +797,6 @@
     }
 
     public void visit( Select obj ) {
-        visitDirect(obj, null);
-    }
-
-	private void visitDirect(Select obj, Query query) {
-        append(SELECT);
-
-        if (query != null) {
-        	SourceHint sh = query.getSourceHint();
-        	if (sh != null) {
-	        	append(SPACE);
-	        	append(BEGIN_HINT);
-	        	append("sh"); //$NON-NLS-1$
-	        	if (sh.getGeneralHint() != null) {
-	        		appendSourceHintValue(sh.getGeneralHint());
-	        	}
-	        	if (sh.getSourceHints() != null) {
-	        		for (Map.Entry<String, String> entry : sh.getSourceHints().entrySet()) {
-	        			append(entry.getKey());
-	        			appendSourceHintValue(entry.getValue());
-	        		}
-	        	}
-	        	append(END_HINT);
-        	}
-        }
-        
 		if (obj.isDistinct()) {
             append(SPACE);
             append(DISTINCT);

Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/multisource/TestMultiSourcePlanToProcessConverter.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -39,6 +39,7 @@
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.optimizer.QueryOptimizer;
 import org.teiid.query.optimizer.TestOptimizer;
+import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
 import org.teiid.query.processor.HardcodedDataManager;
@@ -52,6 +53,7 @@
 import org.teiid.query.sql.visitor.ElementCollectorVisitor;
 import org.teiid.query.unittest.RealMetadataFactory;
 import org.teiid.query.util.CommandContext;
+import org.teiid.translator.SourceSystemFunctions;
 
 /** 
  * It's important here that the MultiSourceCapabilityFinder is used since some capabilities 
@@ -59,6 +61,7 @@
  * 
  * @since 4.2
  */
+ at SuppressWarnings("nls")
 public class TestMultiSourcePlanToProcessConverter {
     
     private final class MultiSourceDataManager extends HardcodedDataManager {
@@ -82,10 +85,14 @@
     }
 
     private static final boolean DEBUG = false;
+
+    public void helpTestMultiSourcePlan(QueryMetadataInterface metadata, String userSql, String multiModel, int sourceCount, ProcessorDataManager dataMgr, List<?>[] expectedResults, VDBMetaData vdb) throws Exception {
+    	helpTestMultiSourcePlan(metadata, userSql, multiModel, sourceCount, dataMgr, expectedResults, vdb, null);
+    }
     
-    public void helpTestMultiSourcePlan(QueryMetadataInterface metadata, String userSql, String multiModel, int sourceCount, ProcessorDataManager dataMgr, List<?>[] expectedResults, VDBMetaData vdb) throws Exception {
+    public void helpTestMultiSourcePlan(QueryMetadataInterface metadata, String userSql, String multiModel, int sourceCount, ProcessorDataManager dataMgr, List<?>[] expectedResults, VDBMetaData vdb, List<?> params) throws Exception {
         
-       DQPWorkContext dqpContext = RealMetadataFactory.buildWorkContext(metadata, vdb);
+    	DQPWorkContext dqpContext = RealMetadataFactory.buildWorkContext(metadata, vdb);
      
         Set<String> multiSourceModels = vdb.getMultiSourceModelNames();
         for (String model:multiSourceModels) {
@@ -106,7 +113,9 @@
         // Plan
         command = QueryRewriter.rewrite(command, wrapper, null);
         FakeCapabilitiesFinder fakeFinder = new FakeCapabilitiesFinder();
-        fakeFinder.addCapabilities(multiModel, TestOptimizer.getTypicalCapabilities()); 
+        BasicSourceCapabilities bsc = TestOptimizer.getTypicalCapabilities();
+        bsc.setFunctionSupport(SourceSystemFunctions.CONCAT, true);
+        fakeFinder.addCapabilities(multiModel, bsc); 
 
         CapabilitiesFinder finder = new MultiSourceCapabilitiesFinder(fakeFinder, multiSourceModels);
         
@@ -121,8 +130,10 @@
             System.out.println("\nMultiSource Plan:"); //$NON-NLS-1$
             System.out.println(plan);
         }
-                
-        TestProcessor.helpProcess(plan, context, dataMgr, expectedResults);                        
+        if (params != null) {
+        	TestProcessor.setParameterValues(params, command, context);
+        }
+        TestProcessor.helpProcess(plan, context, dataMgr, expectedResults);
     }
 
     @Test public void testNoReplacement() throws Exception {
@@ -142,21 +153,33 @@
         final String multiModel = "MultiModel"; //$NON-NLS-1$
         final int sources = 2;
         final List<?>[] expected = 
-            new List<?>[] { Arrays.asList(new Object[] { null, null, null}) };
+            new List<?>[] { Arrays.asList(new Object[] { null, null, "a"}) };
         final HardcodedDataManager dataMgr = new MultiSourceDataManager();
         dataMgr.setMustRegisterCommands(false);
         helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, RealMetadataFactory.exampleMultiBindingVDB());
     }
     
+    @Test public void testPreparedReplacement() throws Exception {
+        final QueryMetadataInterface metadata = RealMetadataFactory.exampleMultiBinding();
+        final String userSql = "SELECT * FROM MultiModel.Phys WHERE SOURCE_NAME = ?"; //$NON-NLS-1$
+        final String multiModel = "MultiModel"; //$NON-NLS-1$
+        final int sources = 2;
+        final List<?>[] expected = 
+            new List<?>[] { Arrays.asList(new Object[] { null, null, "a"}) };
+        final HardcodedDataManager dataMgr = new MultiSourceDataManager();
+        dataMgr.setMustRegisterCommands(false);
+        helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, RealMetadataFactory.exampleMultiBindingVDB(), Arrays.asList("a"));
+    }
+
     @Test public void testMultiReplacement() throws Exception {
         final QueryMetadataInterface metadata = RealMetadataFactory.exampleMultiBinding();
         final String userSql = "SELECT * FROM MultiModel.Phys"; //$NON-NLS-1$
         final String multiModel = "MultiModel"; //$NON-NLS-1$
         final int sources = 3;
         final List<?>[] expected = 
-            new List<?>[] { Arrays.asList(new Object[] { null, null, null}),
-                         Arrays.asList(new Object[] { null, null, null}),
-                         Arrays.asList(new Object[] { null, null, null})};
+            new List<?>[] { Arrays.asList(new Object[] { null, null, "a"}),
+                         Arrays.asList(new Object[] { null, null, "b"}),
+                         Arrays.asList(new Object[] { null, null, "c"})};
         final ProcessorDataManager dataMgr = new MultiSourceDataManager();
         helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, RealMetadataFactory.exampleMultiBindingVDB());
     }
@@ -164,44 +187,44 @@
     @Test public void testMultiReplacementWithOrderBy() throws Exception {
         QueryMetadataInterface metadata = RealMetadataFactory.exampleMultiBinding();
 
-        final String userSql = "SELECT * FROM MultiModel.Phys order by a"; //$NON-NLS-1$
+        final String userSql = "SELECT a, b, source_name || a FROM MultiModel.Phys order by a"; //$NON-NLS-1$
         final String multiModel = "MultiModel"; //$NON-NLS-1$
         final int sources = 2;
         final List<?>[] expected = new List<?>[] {
-            Arrays.asList("e", "z", "b"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            Arrays.asList("f", "z", "b"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            Arrays.asList("x", "z", "a"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            Arrays.asList("y", "z", "a"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            Arrays.asList("e", "z", "be"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            Arrays.asList("f", "z", "bf"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            Arrays.asList("x", "z", "ax"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            Arrays.asList("y", "z", "ay"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         };
         final HardcodedDataManager dataMgr = new HardcodedDataManager();
-        dataMgr.addData("SELECT g_0.a, g_0.b, 'a' FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
+        dataMgr.addData("SELECT g_0.a, g_0.b, concat('a', g_0.a) FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
                         new List<?>[] {
-                            Arrays.asList("y", "z", "a"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                            Arrays.asList("x", "z", "a")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        dataMgr.addData("SELECT g_0.a, g_0.b, 'b' FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
+                            Arrays.asList("y", "z", "ay"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                            Arrays.asList("x", "z", "ax")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        dataMgr.addData("SELECT g_0.a, g_0.b, concat('b', g_0.a) FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
                         new List<?>[] {
-                            Arrays.asList("e", "z", "b"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                            Arrays.asList("f", "z", "b")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                            Arrays.asList("e", "z", "be"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                            Arrays.asList("f", "z", "bf")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, RealMetadataFactory.exampleMultiBindingVDB());
     }
 
     @Test public void testMultiReplacementWithLimit() throws Exception {
         final QueryMetadataInterface metadata = RealMetadataFactory.exampleMultiBinding();
-        final String userSql = "SELECT distinct * FROM MultiModel.Phys order by a limit 1"; //$NON-NLS-1$
+        final String userSql = "SELECT distinct a, b, source_name || a FROM MultiModel.Phys order by a limit 1"; //$NON-NLS-1$
         final String multiModel = "MultiModel"; //$NON-NLS-1$
         final int sources = 2;
         final List<?>[] expected = new List<?>[] {
-            Arrays.asList("e", "z", "b"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            Arrays.asList("e", "z", "be"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         };
         final HardcodedDataManager dataMgr = new HardcodedDataManager();
-        dataMgr.addData("SELECT g_0.a, g_0.b, 'a' FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
-                        new List<?>[] {
-                            Arrays.asList("y", "z", "a"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                            Arrays.asList("x", "z", "a")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        dataMgr.addData("SELECT g_0.a, g_0.b, 'b' FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
-                        new List<?>[] {
-                            Arrays.asList("e", "z", "b"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                            Arrays.asList("f", "z", "b")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        dataMgr.addData("SELECT g_0.a, g_0.b, concat('a', g_0.a) FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
+                new List<?>[] {
+                    Arrays.asList("y", "z", "ay"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Arrays.asList("x", "z", "ax")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        dataMgr.addData("SELECT g_0.a, g_0.b, concat('b', g_0.a) FROM MultiModel.Phys AS g_0", //$NON-NLS-1$
+                new List<?>[] {
+                    Arrays.asList("e", "z", "be"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Arrays.asList("f", "z", "bf")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         helpTestMultiSourcePlan(metadata, userSql, multiModel, sources, dataMgr, expected, RealMetadataFactory.exampleMultiBindingVDB());
     }
     

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -23,8 +23,10 @@
 package org.teiid.query.optimizer;
 
 import org.junit.Test;
+import org.teiid.query.metadata.TransformationMetadata;
 import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
 import org.teiid.query.processor.ProcessorPlan;
@@ -254,5 +256,36 @@
             0,      // Sort
             2       // UnionAll
         });                                    
-    }    
+    }   
+    
+    @Test public void testUnionCosting() throws Exception {
+    	TransformationMetadata metadata = RealMetadataFactory.example1();
+    	RealMetadataFactory.setCardinality("pm1.g1", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g2", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g3", 100, metadata);
+    	RealMetadataFactory.setCardinality("pm1.g4", 100, metadata);
+    	BasicSourceCapabilities bac = new BasicSourceCapabilities();
+    	bac.setCapabilitySupport(Capability.QUERY_SELECT_EXPRESSION, true);
+    	bac.setCapabilitySupport(Capability.CRITERIA_COMPARE_EQ, true);
+        ProcessorPlan plan = TestOptimizer.helpPlan("SELECT T.e1 AS e1, T.e2 AS e2, T.e3 AS e3 FROM (SELECT e1, 'a' AS e2, e3 FROM pm1.g1 UNION SELECT e1, 'b' AS e2, e3 FROM pm1.g2 UNION SELECT e1, 'c' AS e2, e3 FROM pm1.g3) AS T, vm1.g1 AS L WHERE (T.e1 = L.e1) AND (T.e3 = TRUE)", metadata, null, new DefaultCapabilitiesFinder(bac),//$NON-NLS-1$
+            new String[] { "SELECT pm1.g1.e1 FROM pm1.g1", "SELECT pm1.g1.e1, pm1.g1.e3 FROM pm1.g1 WHERE pm1.g1.e3 = TRUE", "SELECT pm1.g3.e1, pm1.g3.e3 FROM pm1.g3 WHERE pm1.g3.e3 = TRUE", "SELECT pm1.g2.e1, pm1.g2.e3 FROM pm1.g2 WHERE pm1.g2.e3 = TRUE" }, ComparisonMode.EXACT_COMMAND_STRING); 
+
+        TestOptimizer.checkNodeTypes(plan, new int[] {
+            4,      // Access
+            0,      // DependentAccess
+            0,      // DependentSelect
+            0,      // DependentProject
+            0,      // DupRemove
+            0,      // Grouping
+            0,      // NestedLoopJoinStrategy
+            1,      // MergeJoinStrategy
+            0,      // Null
+            0,      // PlanExecution
+            1,      // Project
+            0,      // Select
+            0,      // Sort
+            2       // UnionAll
+        });                                    
+    }   
+
 }


Property changes on: trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3149-3217,3535-3555
/branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3673-3711,3754-3769
/trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3188-3450,3452-3666
   + /branches/7.4.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3149-3217,3535-3555
/branches/7.6.x/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3673-3711,3754-3769,3776-3813
/trunk/engine/src/test/java/org/teiid/query/optimizer/TestUnionPlanning.java:3188-3450,3452-3666

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -29,10 +29,12 @@
 import java.util.List;
 
 import org.junit.Test;
+import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.language.Select;
 import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.metadata.TransformationMetadata;
 import org.teiid.query.optimizer.TestOptimizer;
 import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -45,6 +47,7 @@
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.unittest.RealMetadataFactory;
 import org.teiid.query.util.CommandContext;
+import org.teiid.translator.ExecutionFactory.NullOrder;
 
 @SuppressWarnings({"unchecked", "nls"})
 public class TestDependentJoins {
@@ -830,17 +833,80 @@
    }    
     
     @Test public void testDependentJoinBackoff() throws Exception {
-        // Create query 
+        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")), 
+        		new HashSet<String>(dataManager.getQueries()));
+    }
+    
+    @Test public void testDependentJoinBackoff1() throws Exception {
+        FakeDataManager dataManager = helpTestBackoff(false);
+        
+        //note that the dependent join was performed
+        assertEquals(4, new HashSet<String>(dataManager.getQueries()).size());
+    }
+    
+    @Test public void testIssue1899() throws Exception {
+    	String sql = "SELECT pm1.g1.e1 FROM pm1.g1, pm3.g1 WHERE pm1.g1.e1=pm3.g1.e1"; //$NON-NLS-1$
+
+        HardcodedDataManager dataManager = new HardcodedDataManager();
+        dataManager.addData("SELECT pm3.g1.e1 FROM pm3.g1 ORDER BY pm3.g1.e1", new List<?>[] {Arrays.asList("a"), Arrays.asList("b"), Arrays.asList("c")});
+        dataManager.addData("SELECT pm1.g1.e1 FROM pm1.g1", new List<?>[] {Arrays.asList("a")});
+
+        TransformationMetadata fakeMetadata = RealMetadataFactory.example4();
+        fakeMetadata.getGroupID("pm1.g1").getAccessPatterns().clear();
+        RealMetadataFactory.setCardinality("pm1.g1", 1000, fakeMetadata);
+    	fakeMetadata.getElementID("pm1.g1.e1").setDistinctValues(40);
+        RealMetadataFactory.setCardinality("pm3.g1", 1, fakeMetadata);
+    	fakeMetadata.getElementID("pm3.g1.e1").setDistinctValues(1);
+        // Plan query
+        FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
+        BasicSourceCapabilities depcaps = new BasicSourceCapabilities();
+        depcaps.setCapabilitySupport(Capability.CRITERIA_IN, true);
+        depcaps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
+        depcaps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
+
+        BasicSourceCapabilities caps = new BasicSourceCapabilities();
+        caps.setCapabilitySupport(Capability.QUERY_ORDERBY, true);
+        caps.setSourceProperty(Capability.QUERY_ORDERBY_DEFAULT_NULL_ORDER, NullOrder.HIGH);
+
+        capFinder.addCapabilities("pm3", caps); //$NON-NLS-1$
+        capFinder.addCapabilities("pm1", depcaps); //$NON-NLS-1$
+
+        List[] expected = new List[] {
+            Arrays.asList(new Object[] {
+                new String("a")})}; //$NON-NLS-1$
+
+        ProcessorPlan plan = TestOptimizer.helpPlan(sql, fakeMetadata, new String[] {
+        		"SELECT pm1.g1.e1 FROM pm1.g1 WHERE pm1.g1.e1 IN (<dependent values>)", 
+        		"SELECT pm3.g1.e1 FROM pm3.g1 ORDER BY pm3.g1.e1"
+        }, capFinder, ComparisonMode.EXACT_COMMAND_STRING);
+
+        // Run query
+        TestProcessor.helpProcess(plan, dataManager, expected);
+    }
+
+	private FakeDataManager helpTestBackoff(boolean setNdv) throws Exception,
+			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$
 
         // Construct data manager with data
         FakeDataManager dataManager = new FakeDataManager();
         sampleData4(dataManager);
 
-        QueryMetadataInterface fakeMetadata = RealMetadataFactory.example1();
+        TransformationMetadata fakeMetadata = RealMetadataFactory.example1();
 
         RealMetadataFactory.setCardinality("pm1.g1", 1, fakeMetadata);
+        if (setNdv) {
+        	fakeMetadata.getElementID("pm1.g1.e1").setDistinctValues(1);
+        }
         RealMetadataFactory.setCardinality("pm6.g1", 1000, fakeMetadata);
+        if (setNdv) {
+        	fakeMetadata.getElementID("pm6.g1.e1").setDistinctValues(1000);
+        }
         // Plan query
         FakeCapabilitiesFinder capFinder = new FakeCapabilitiesFinder();
         BasicSourceCapabilities depcaps = new BasicSourceCapabilities();
@@ -865,11 +931,8 @@
 
         // Run query
         TestProcessor.helpProcess(plan, dataManager, expected);
-        
-        //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")), 
-        		new HashSet<String>(dataManager.getQueries()));
-    }
+		return dataManager;
+	}
     
     @Test public void testDjHint() { 
         // Create query 


Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3149-3217,3535-3555,3558-3585
/branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3673-3711,3754-3769
/trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3188-3450,3452-3666
   + /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3149-3217,3535-3555,3558-3585
/branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3673-3711,3754-3769,3776-3813
/trunk/engine/src/test/java/org/teiid/query/processor/TestDependentJoins.java:3188-3450,3452-3666

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -5199,14 +5199,19 @@
         ProcessorPlan plan = helpGetPlan(command, metadata, capFinder, context);
         
         // Collect reference, set value
-        VariableContext vc = new VariableContext();
+        setParameterValues(values, command, context);
+        // Run query
+        helpProcess(plan, context, dataManager, expected);
+	}
+
+	public static void setParameterValues(List<?> values, Command command,
+			CommandContext context) {
+		VariableContext vc = new VariableContext();
         Iterator<?> valIter = values.iterator();
         for (Reference ref : ReferenceCollectorVisitor.getReferences(command)) {
             vc.setGlobalValue(ref.getContextSymbol(),  valIter.next()); //$NON-NLS-1$
 		}
         context.setVariableContext(vc);
-        // Run query
-        helpProcess(plan, context, dataManager, expected);
 	}    
 
     /** defect 15348


Property changes on: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3149-3217,3220-3275,3535-3555
/branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3673-3711,3714-3752,3754-3769
/trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3188-3450,3452-3666
   + /branches/7.4.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3149-3217,3220-3275,3535-3555
/branches/7.6.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3673-3711,3714-3752,3754-3769,3776-3813
/trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java:3188-3450,3452-3666

Modified: trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestExpressionMappingVisitor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -177,7 +177,7 @@
         
         ExpressionMappingVisitor.mapExpressions(toMap, map);
         
-        assertEquals("Did not get expected mapped expression", "SELECT z.X AS x", toMap.toString());     //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("Did not get expected mapped expression", " z.X AS x", toMap.toString());     //$NON-NLS-1$ //$NON-NLS-2$
     }
     
     @Test public void testSelectAlias1() {
@@ -191,7 +191,7 @@
         
         ExpressionMappingVisitor.mapExpressions(toMap, map);
         
-        assertEquals("Did not get expected mapped expression", "SELECT z.x", toMap.toString());     //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("Did not get expected mapped expression", " z.x", toMap.toString());     //$NON-NLS-1$ //$NON-NLS-2$
     }
     
     /**

Modified: trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java	2012-01-23 19:06:21 UTC (rev 3814)
+++ trunk/engine/src/test/java/org/teiid/query/sql/visitor/TestSQLStringVisitor.java	2012-01-23 19:59:01 UTC (rev 3815)
@@ -662,7 +662,7 @@
 		Select select = new Select();
 		select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
 		
-		helpTest(select, "SELECT e1"); //$NON-NLS-1$
+		helpTest(select, " e1"); //$NON-NLS-1$
 	}
 
 	@Test public void testSelect2() {
@@ -670,7 +670,7 @@
 		select.setDistinct(true);
 		select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
 		
-		helpTest(select, "SELECT DISTINCT e1"); //$NON-NLS-1$
+		helpTest(select, " DISTINCT e1"); //$NON-NLS-1$
 	}
 
 	@Test public void testSelect3() {
@@ -678,7 +678,7 @@
 		select.addSymbol(new ElementSymbol("e1")); //$NON-NLS-1$
 		select.addSymbol(new ElementSymbol("e2")); //$NON-NLS-1$
 		
-		helpTest(select, "SELECT e1, e2"); //$NON-NLS-1$
+		helpTest(select, " e1, e2"); //$NON-NLS-1$
 	}
 
 	@Test public void testSetCriteria1() {



More information about the teiid-commits mailing list