[teiid-commits] teiid SVN: r2897 - in trunk: api/src/main/java/org/teiid/metadata and 30 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Feb 3 17:15:08 EST 2011


Author: shawkins
Date: 2011-02-03 17:15:05 -0500 (Thu, 03 Feb 2011)
New Revision: 2897

Removed:
   trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
Modified:
   trunk/api/src/main/java/org/teiid/language/Function.java
   trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
   trunk/api/src/main/java/org/teiid/metadata/Schema.java
   trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
   trunk/build/kits/jboss-container/teiid-releasenotes.html
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
   trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
   trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
   trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
   trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
   trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
   trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
   trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
   trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
   trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
   trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
   trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
   trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
   trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
   trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
   trunk/engine/src/main/resources/org/teiid/query/i18n.properties
   trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
   trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
   trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
   trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
   trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
   trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
   trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
   trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
   trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
   trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
   trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
   trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
Log:
TEIID-231 various refinements to function handling.

Modified: trunk/api/src/main/java/org/teiid/language/Function.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/Function.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/language/Function.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -26,16 +26,18 @@
 import java.util.List;
 
 import org.teiid.language.visitor.LanguageObjectVisitor;
+import org.teiid.metadata.FunctionMethod;
 
 /**
  * Represents a function.  A function has a name and 0..n 
  * Expressions that are parameters.  
  */
-public class Function extends BaseLanguageObject implements Expression {
+public class Function extends BaseLanguageObject implements Expression, MetadataReference<FunctionMethod> {
 
     private String name;
     private List<Expression> parameters;
     private Class<?> type;
+    private FunctionMethod metadataObject;
     
     public Function(String name, List<? extends Expression> params, Class<?> type) {
         this.name = name;
@@ -47,6 +49,15 @@
         this.type = type;
     }
     
+    @Override
+    public FunctionMethod getMetadataObject() {
+    	return metadataObject;
+    }
+    
+    public void setMetadataObject(FunctionMethod metadataObject) {
+		this.metadataObject = metadataObject;
+	}
+    
     /**
      * Get name of the function
      * @return Function name

Modified: trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/FunctionMethod.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,6 +29,7 @@
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 
+import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
 
 
@@ -109,7 +110,8 @@
     @XmlElement(name="inputParameters")
     protected List<FunctionParameter> inParameters = new ArrayList<FunctionParameter>();
     private FunctionParameter outputParameter;
-    
+    private Schema parent;
+        
     protected FunctionMethod() {
     }
        
@@ -371,7 +373,7 @@
                 List<FunctionParameter> otherInputs = other.getInputParameters();
                 
                 for(int i=0; i<thisInputs.size(); i++) { 
-                    boolean paramMatch = compareWithNull(thisInputs.get(i), otherInputs.get(i));
+                    boolean paramMatch = EquivalenceUtil.areEqual(thisInputs.get(i), otherInputs.get(i));
                     if(! paramMatch) { 
                         return false;
                     }    
@@ -385,26 +387,6 @@
     }    
     
     /**
-     * Compare two objects that may or may not be null and consider null==null
-     * as true.
-     * @param o1 Object 1
-     * @param o2 Object 2
-     * @return True if o1 and o2 are null or if they both aren't and they are equal
-     */
-    private boolean compareWithNull(Object o1, Object o2) {
-        if(o1 == null) { 
-            if(o2 == null) { 
-                return true;
-            }
-            return false;
-        }
-        if(o2 == null) { 
-            return false;
-        }
-        return o1.equals(o2);
-    }
-    
-    /**
      * Return string version for debugging purposes
      * @return String representation of function method
      */ 
@@ -473,5 +455,13 @@
     	}
     	return false;
     }
-     
+    
+    public void setParent(Schema parent) {
+		this.parent = parent;
+	}
+
+    @Override
+    public Schema getParent() {
+    	return parent;
+    }
 }

Modified: trunk/api/src/main/java/org/teiid/metadata/Schema.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/Schema.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/metadata/Schema.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -52,7 +52,10 @@
 	}
 	
 	public void addFunction(FunctionMethod function) {
-		this.functions.put(function.getName().toLowerCase(), function);
+		function.setParent(this);
+		if (this.functions.put(function.getName().toLowerCase(), function) != null) {
+			throw new AssertionError("Duplicate function " + function.getName()); //$NON-NLS-1$
+		}
 	}	
 
 	/**

Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -650,7 +650,7 @@
     }
     
     public List<FunctionMethod> getPushDownFunctions(){
-    	return Collections.EMPTY_LIST;
+    	return Collections.emptyList();
     }
     
     /**

Modified: trunk/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-container/teiid-releasenotes.html	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/build/kits/jboss-container/teiid-releasenotes.html	2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,8 @@
 <h4>from 7.3</h4>
 <ul>
   <li>The use of an IN procedure parameter with the name "source_name" in a multi-source model, will now be treated the parameter that controls which source
-  the procedure will execute against. 
+  the procedure will execute against.
+  <li>Dynamic VDB functions injected via ExecutionFactory.getPushdownFunctions are now scoped to the SYS schema and have a fully qualified name that includes their source type.  For example, instead of oracle_model.relate - which was only valid against the oracle_model source, there is now the SYS.oracle_sdo.relate function that is valid for all Oracle sources.  Any fully-qualified reference to these functions will need updated. 
 </ul>
 
 <h4>from 7.2</h4>
@@ -189,9 +190,8 @@
 <h2><a name="Licenses">Licenses</a></h2>
 
 <p>Teiid is licensed under the <a href="LICENSE-lgpl-2.1.txt">LGPL</a>. The
-license texts for Teiid and the thirdparty components it uses may be found in the teiid-docs/licenses
-directory of the distribution. <a href="teiid-docs/licenses">Browse
-Licenses</a>
+license texts for Teiid and the thirdparty components it uses may be found in the <a href="teiid-docs/licenses">teiid-docs/licenses</a>
+directory of the distribution. 
 
 </p>
 

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/modeshape/ModeShapeExecutionFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,31 +116,31 @@
     @Override
     public List<FunctionMethod> getPushDownFunctions(){
     	List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
-		pushdownFunctions.add(new FunctionMethod(JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR, 
+		pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISCHILDNODE, JCR_ISCHILDNODE, JCR, 
             new FunctionParameter[] {
 				new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
             new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 		
-		pushdownFunctions.add(new FunctionMethod(JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR, 
+		pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISDESCENDANTNODE, JCR_ISDESCENDANTNODE, JCR, 
                 new FunctionParameter[] {
 				new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 
-		pushdownFunctions.add(new FunctionMethod(JCR_ISSAMENODE, JCR_ISSAMENODE, JCR, 
+		pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_ISSAMENODE, JCR_ISSAMENODE, JCR, 
                 new FunctionParameter[] {
 					new FunctionParameter("path1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("path2", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 		
-		pushdownFunctions.add(new FunctionMethod(JCR_CONTAINS, JCR_CONTAINS, JCR, 
+		pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_CONTAINS, JCR_CONTAINS, JCR, 
                 new FunctionParameter[] {
                     new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("searchExpr", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 		
-		pushdownFunctions.add(new FunctionMethod(JCR_REFERENCE, JCR_REFERENCE, JCR, 
+		pushdownFunctions.add(new FunctionMethod(JCR + '.' + JCR_REFERENCE, JCR_REFERENCE, JCR, 
                 new FunctionParameter[] {
                     new FunctionParameter("selectorOrProperty", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/oracle/OracleSpatialFunctions.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -38,42 +38,42 @@
 	public static final String FILTER = "sdo_filter"; //$NON-NLS-1$
 	public static final String WITHIN_DISTANCE = "sdo_within_distance"; //$NON-NLS-1$
 	public static final String NEAREST_NEIGHBOR_DISTANCE = "sdo_nn_distance"; //$NON-NLS-1$
-	private static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
+	public static final String ORACLE_SDO = "Oracle-SDO"; //$NON-NLS-1$
 	
 
     public static List<FunctionMethod> getOracleSpatialFunctions(){
     	    	
     	List<FunctionMethod> spatialFuncs = new ArrayList<FunctionMethod>();
     	
-    	spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,   
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,   
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 
-    	spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO, 
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO, 
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 
-    	spatialFuncs.add(new FunctionMethod(RELATE, RELATE, ORACLE_SDO, 
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + RELATE, RELATE, ORACLE_SDO, 
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,   
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,   
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -81,7 +81,7 @@
                     new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -89,7 +89,7 @@
                     new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$    	
 
-    	spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR, NEAREST_NEIGHBOR, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
@@ -97,47 +97,47 @@
                     new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$    	
     	
-    	spatialFuncs.add(new FunctionMethod(NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + NEAREST_NEIGHBOR_DISTANCE, NEAREST_NEIGHBOR_DISTANCE, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("NUMBER", DataTypeManager.DefaultDataTypes.INTEGER, "") }, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.INTEGER, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$  
     	    	
-    	spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO, 
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO, 
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,   
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,   
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$    	
     	
-    	spatialFuncs.add(new FunctionMethod(WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + WITHIN_DISTANCE, WITHIN_DISTANCE, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,   
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,   
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
     	
-    	spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,  
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,  
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("PARAMS", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("result", DataTypeManager.DefaultDataTypes.STRING, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$    
     	
-    	spatialFuncs.add(new FunctionMethod(FILTER, FILTER, ORACLE_SDO,   
+    	spatialFuncs.add(new FunctionMethod(ORACLE_SDO + '.' + FILTER, FILTER, ORACLE_SDO,   
                 new FunctionParameter[] {
                     new FunctionParameter("GEOM1", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("GEOM2", DataTypeManager.DefaultDataTypes.OBJECT, ""), //$NON-NLS-1$ //$NON-NLS-2$

Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/modeshape/TestModeShapeSqlTranslator.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -91,7 +91,7 @@
 	public void testPredicate() throws Exception {
 
 		String input = "SELECT x.jcr_primaryType from nt_base inner join nt_base as x on jcr_issamenode(nt_base.jcr_path, x.jcr_path) = true where jcr_isdescendantnode(nt_base.jcr_path, 'x/y/z') = true and jcr_reference(nt_base.mode_properties) = 'x'"; //$NON-NLS-1$
-		String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON issamenode(g_0, g_1) WHERE isdescendantnode(g_0, 'x/y/z') AND reference(g_0.*) = 'x'"; //$NON-NLS-1$
+		String output = "SELECT g_1.\"jcr:primaryType\" FROM \"nt:base\" AS g_0 INNER JOIN \"nt:base\" AS g_1 ON ISSAMENODE(g_0, g_1) WHERE ISDESCENDANTNODE(g_0, 'x/y/z') AND REFERENCE(g_0.*) = 'x'"; //$NON-NLS-1$
 
 		helpTestVisitor(input, output);
 

Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sqlserver/TestSqlServerConversionVisitor.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -128,7 +128,7 @@
     @Test
     public void testDateFunctions() throws Exception {
         String input = "select dayName(timestampValue), dayOfWeek(timestampValue), quarter(timestampValue) from bqt1.smalla"; //$NON-NLS-1$
-        String output = "SELECT {fn dayName(SmallA.TimestampValue)}, {fn dayOfWeek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
+        String output = "SELECT {fn dayname(SmallA.TimestampValue)}, {fn dayofweek(SmallA.TimestampValue)}, {fn quarter(SmallA.TimestampValue)} FROM SmallA"; //$NON-NLS-1$
                
         helpTestVisitor(getBQTVDB(),
             input, 

Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/SalesForceExecutionFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,13 +142,13 @@
     @Override
     public List<FunctionMethod> getPushDownFunctions(){
     	List<FunctionMethod> pushdownFunctions = new ArrayList<FunctionMethod>();
-		pushdownFunctions.add(new FunctionMethod(INCLUDES, INCLUDES, SALESFORCE, 
+		pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' +INCLUDES, INCLUDES, SALESFORCE, 
             new FunctionParameter[] {
                 new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                 new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$
             new FunctionParameter("result", DataTypeManager.DefaultDataTypes.BOOLEAN, "") ) ); //$NON-NLS-1$ //$NON-NLS-2$
 		
-		pushdownFunctions.add(new FunctionMethod(EXCLUDES, EXCLUDES, SALESFORCE, 
+		pushdownFunctions.add(new FunctionMethod(SALESFORCE + '.' + EXCLUDES, EXCLUDES, SALESFORCE, 
                 new FunctionParameter[] {
                     new FunctionParameter("columnName", DataTypeManager.DefaultDataTypes.STRING, ""), //$NON-NLS-1$ //$NON-NLS-2$
                     new FunctionParameter("param", DataTypeManager.DefaultDataTypes.STRING, "")}, //$NON-NLS-1$ //$NON-NLS-2$

Modified: trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml
===================================================================
--- trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/documentation/developer-guide/src/main/docbook/en-US/content/udf.xml	2011-02-03 22:15:05 UTC (rev 2897)
@@ -8,7 +8,7 @@
 		creating a UDF.</para>
 	<section id="define_udf">
 		<title>UDF Definition</title>
-		<para>The FunctionDefinition.xmi file provides metadata to the
+		<para>A FunctionDefinition.xmi file provides metadata to the
 			query engine on User Defined Functions. See the Designer Documentation for more on creating a Function Definition Model.</para>
 		<itemizedlist>
 			<para>The following are used to define a UDF.</para>
@@ -19,24 +19,20 @@
 					mind:
 					<itemizedlist>
 						<listitem>
-							<para>You cannot use a reserved word, which includes
-								existing Teiid System function names.  You cannot
-								overload existing Teiid System functions.</para>
+							<para>You cannot overload existing Teiid System functions.</para>
 						</listitem>
 						<listitem>
 							<para>The function name must be unique among user-defined
-								functions for the number of arguments.  You can use the
+								functions in its model for the number of arguments.  You can use the
 								same function name for different numbers of types of
 								arguments.  Hence, you can overload your user-defined
 								functions.</para>
 						</listitem>
 						<listitem>
-							<para>The function name can only contain letters,
-								numbers, and the underscore (_).  Your function name must
-								start with a letter.</para>
+							<para>The function name cannot contain the '.' character.</para>
 						</listitem>
 						<listitem>
-							<para>The function name cannot exceed 128 characters.
+							<para>The function name cannot exceed 255 characters.
                 </para>
 						</listitem>
 					</itemizedlist>
@@ -225,4 +221,18 @@
 			created in in the Designer Tool, it can be added to the VDB for use
 			by Teiid.</para>
 	</section>
+	<section>
+		<title>User Defined Functions in Dynamic VDBs</title>
+		<para>Dynamic VDBs do not use Designer generated artifacts, such as a FunctionDefinition.xmi file.  
+		Even with that limitation dynamic vdbs may still utilize UDFs through custom coding.  
+		The <code>ExecutionFactory.getMetadata</code> call allows for the definition of metadata via a <code>MetadataFactory.</code>
+		Use the <code>MetadataFactory.addFunction</code> to add function for use only by that translator instance.
+		Functions added directly to the source schema are specific to that schema - their fully qualified name will include the schema and the function can not be pushed to a different source.	
+		</para>	
+		<para>The <code>ExecutionFactory.getPushdownFunctions</code> method can be used to describe functions that are valid against all instances of a given translator type.  The function names are expected to be
+		prefixed by the translator type, or some other logical grouping, e.g. salesforce.includes.  The full name of the function once imported into the system will qualified by the SYS schema, e.g. SYS.salesforce.includes.
+		</para>
+		<para>Any funcitons added via these mechanisms do not need to be declared in <code>ExecutionFactory.getSupportedFunctions.</code>  Any of the additional handling, such as adding a <code>FunctionModifier</code>, covered above is also applicable here.  All pushdown functions will have function name set to only the simple name.  Schema or other qualification will be removed.  
+		Handling, such as function modifiers, can check the function metadata if there is the potential for an ambiguity.</para>
+	</section>
 </chapter>
\ No newline at end of file

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -495,12 +495,22 @@
     org.teiid.language.Function translate(Function function) {
         Expression [] args = function.getArgs();
         List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(args.length);
-        if (args != null) {
-            for (int i = 0; i < args.length; i++) {
-                params.add(translate(args[i]));
-            }
+        for (int i = 0; i < args.length; i++) {
+            params.add(translate(args[i]));
         }
-        return new org.teiid.language.Function(function.getName(), params, function.getType());
+        String name = function.getName();
+        if (function.getFunctionDescriptor() != null) {
+        	name = function.getFunctionDescriptor().getName();
+        }
+        name = SingleElementSymbol.getShortName(name);
+
+        //if there is any ambiguity in the function name it will be up to the translator logic to check the 
+        //metadata
+        org.teiid.language.Function result = new org.teiid.language.Function(name, params, function.getType());
+        if (function.getFunctionDescriptor() != null) {
+        	result.setMetadataObject(function.getFunctionDescriptor().getMethod());
+        }
+        return result;
     }
 
     SearchedCase translate(SearchedCaseExpression expr) {
@@ -515,7 +525,7 @@
 
 
     org.teiid.language.Expression translate(ScalarSubquery ss) {
-        return new org.teiid.language.ScalarSubquery(translate((QueryCommand)ss.getCommand()));
+        return new org.teiid.language.ScalarSubquery(translate(ss.getCommand()));
     }
 
     org.teiid.language.Expression translate(SingleElementSymbol symbol) {
@@ -562,11 +572,12 @@
 
     /* Insert */
     org.teiid.language.Insert translate(Insert insert) {
-        List elements = insert.getVariables();
+        List<ElementSymbol> elements = insert.getVariables();
         List<ColumnReference> translatedElements = new ArrayList<ColumnReference>();
-        for (Iterator i = elements.iterator(); i.hasNext();) {
-            translatedElements.add(translate((ElementSymbol)i.next()));
-        }
+
+        for (ElementSymbol elementSymbol : elements) {
+            translatedElements.add(translate(elementSymbol));
+		}
         
         InsertValueSource valueSource = null;
         if (insert.getQueryExpression() != null) {

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -694,7 +694,7 @@
         this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
         
         if (cacheFactory.isReplicated()) {
-        	matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.LRU, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
+        	matTables = new SessionAwareCache<CachedResults>(this.cacheFactory, SessionAwareCache.Type.RESULTSET, new CacheConfiguration(Policy.EXPIRATION, -1, -1, "MaterilizationTables")); //$NON-NLS-1$
         	matTables.setBufferManager(this.bufferManager);
         }
         

Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -31,33 +31,27 @@
 import org.teiid.core.TeiidRuntimeException;
 import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.types.TransformationException;
-import org.teiid.core.util.Assertion;
-import org.teiid.core.util.HashCodeUtil;
 import org.teiid.core.util.PropertiesUtils;
-import org.teiid.metadata.FunctionMethod.PushDown;
+import org.teiid.metadata.FunctionMethod;
 import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.FunctionMethod.PushDown;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.util.CommandContext;
 
 
 /**
  * The FunctionDescriptor describes a particular function instance enough
- * that the function library can retrieve a function instance based on the 
- * descriptor.
+ * to invoke the function.
  */
 public class FunctionDescriptor implements Serializable, Cloneable {
 	private static final long serialVersionUID = 5374103983118037242L;
 
 	private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty(System.getProperties(), "org.teiid.allowNanInfinity", false); //$NON-NLS-1$
 	
-	private String name;
-    private PushDown pushdown = PushDown.CAN_PUSHDOWN;
-	private Class[] types;
-	private Class returnType;	
-	private int hash;
+	private Class<?>[] types;
+	private Class<?> returnType;	
     private boolean requiresContext;
-    private boolean nullDependent;
-    private Determinism deterministic = Determinism.DETERMINISTIC;
+    private FunctionMethod method;
     
     // This is transient as it would be useless to invoke this method in 
     // a different VM.  This function descriptor can be used to look up 
@@ -67,52 +61,29 @@
     FunctionDescriptor() {
     }
     
-    /** 
-     * Construct a function descriptor with all the info
-     * @param name Name of function
-     * @param types Types of the arguments
-     * @param returnType Type of the return 
-     * @param invocationMethod Reflection method used to invoke the function
-     * @param requiresContext during execution requires command context to be pushed into method as first argument
-     */
-	FunctionDescriptor(String name, PushDown pushdown, Class[] types, Class returnType, Method invocationMethod, boolean requiresContext, boolean nullDependent, Determinism deterministic) {
-		Assertion.isNotNull(name);
-		Assertion.isNotNull(types);
-		Assertion.isNotNull(returnType);
-		
-		this.name = name;
-        this.pushdown = pushdown;
+	FunctionDescriptor(FunctionMethod method, Class<?>[] types,
+			Class<?> outputType, Method invocationMethod,
+			boolean requiresContext) {
 		this.types = types;
-		this.returnType = returnType;
+		this.returnType = outputType;
         this.invocationMethod = invocationMethod;
         this.requiresContext = requiresContext;
-        this.nullDependent = nullDependent;
-        this.deterministic = deterministic;
-		
-		// Compute hash code
-		hash = HashCodeUtil.hashCode(0, name);
-		for(int i=0; i<types.length; i++) {
-			hash = HashCodeUtil.hashCode(hash, types[i]);
-		}
+        this.method = method;
 	}
 
 	public String getName() {
-		return this.name;				
+		return this.method.getName();				
 	}
     
     public PushDown getPushdown() {
-        return this.pushdown;
+        return this.method.getPushdown();
     }
     
-    void setPushdown(PushDown pushdown) {
-        this.pushdown = pushdown;
-    }
-	
-	public Class[] getTypes() {
+	public Class<?>[] getTypes() {
 		return this.types;
 	}
 	
-	public Class getReturnType() {
+	public Class<?> getReturnType() {
 		return this.returnType;
 	}		
 	
@@ -124,51 +95,8 @@
         return this.requiresContext;
     }
     
-	public int hashCode() { 
-		return this.hash;
-	}
-	
-	public boolean equals(Object obj) {
-		if(obj == this) {
-			return true;
-		}
-		
-		if(obj == null || !(obj instanceof FunctionDescriptor)) {
-			return false;			
-		}	
-		FunctionDescriptor other = (FunctionDescriptor) obj;
-		
-		// Compare names
-		if(! this.getName().equals(other.getName())) {
-			return false;
-		}
-        
-        // Compare arg types
-		Class[] thisTypes = this.getTypes();
-		Class[] otherTypes = other.getTypes();
-		if(thisTypes.length != otherTypes.length) {
-			return false;
-		}
-		for(int i=0; i<thisTypes.length; i++) { 
-			if(! thisTypes[i].equals(otherTypes[i])) {
-				return false;
-			}
-		}
-        
-        if (this.nullDependent != other.isNullDependent()) {
-            return false;
-        }
-        
-        if (this.deterministic != other.deterministic) {
-            return false;
-        }
-		 
-		// Must be a match
-		return true;
-	}
-	
 	public String toString() {
-		StringBuffer str = new StringBuffer(this.name);
+		StringBuffer str = new StringBuffer(this.method.getName());
 		str.append("("); //$NON-NLS-1$
 		for(int i=0; i<types.length; i++) {
 			if(types[i] != null) { 
@@ -190,17 +118,13 @@
 	}
 
     public boolean isNullDependent() {
-        return nullDependent;
+        return !this.method.isNullOnNull();
     }
     
     public Determinism getDeterministic() {
-        return deterministic;
+        return this.method.getDeterminism();
     }
 
-    void setDeterministic(Determinism deterministic) {
-        this.deterministic = deterministic;
-    }
-    
     public Object clone() {
         try {
             return super.clone();
@@ -208,12 +132,15 @@
             throw new TeiidRuntimeException(e);
         }
     }
+    
+    public FunctionMethod getMethod() {
+		return method;
+	}
 
-    void setReturnType(Class returnType) {
+    void setReturnType(Class<?> returnType) {
         this.returnType = returnType;
     }
     
-    
 	/**
 	 * Invoke the function described in the function descriptor, using the
 	 * values provided.  Return the result of the function.

Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionForm.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -40,7 +40,7 @@
  * information and instead differentiates function signatures based on their
  * function name and the names of the arguments.
  */
-public class FunctionForm implements Serializable, Comparable {
+public class FunctionForm implements Serializable, Comparable<FunctionForm> {
 	private static final long serialVersionUID = 2411783099304320334L;
 	
 	private String name;
@@ -245,42 +245,32 @@
      * @param obj Other object
      * @return 1 if other > this, 0 if other == this, -1 if other < this
      */
-    public int compareTo(Object obj) {
-        if(obj == this) { 
-            return 0;
-        } else if(obj == null) { 
-            // Should never happen, but sort nulls low
-            return -1;
-        } else {
-            // may throw ClassCastException - this is expected for compareTo()
-            FunctionForm other = (FunctionForm) obj;
+    public int compareTo(FunctionForm other) {
+        int compare = this.getName().compareTo( other.getName() );
+        if(compare != 0) { 
+            return compare;
+        }
             
-            int compare = this.getName().compareTo( other.getName() );
+        // Look further into arg names to compare as names are ==
+        List otherArgs = other.getArgNames();
+        List myArgs = this.getArgNames();
+        
+        // Compare # of args first
+        if(myArgs.size() < otherArgs.size()) { 
+            return -1;
+        } else if(myArgs.size() > otherArgs.size()) { 
+            return 1;
+        } // else continue    
+
+        // Same # of args
+        for(int i=0; i < myArgs.size(); i++) { 
+            compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
             if(compare != 0) { 
                 return compare;
             }
-                
-            // Look further into arg names to compare as names are ==
-            List otherArgs = other.getArgNames();
-            List myArgs = this.getArgNames();
-            
-            // Compare # of args first
-            if(myArgs.size() < otherArgs.size()) { 
-                return -1;
-            } else if(myArgs.size() > otherArgs.size()) { 
-                return 1;
-            } // else continue    
-
-            // Same # of args
-            for(int i=0; i < myArgs.size(); i++) { 
-                compare = ((String)myArgs.get(i)).compareTo( ((String)otherArgs.get(i)) );
-                if(compare != 0) { 
-                    return compare;
-                }
-            }
-            
-            // Same
-            return 0;                
         }
+        
+        // Same
+        return 0;                
     }
 }

Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionLibrary.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,9 +25,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.TreeSet;
 
 import org.teiid.api.exception.query.InvalidFunctionException;
 import org.teiid.api.exception.query.QueryResolverException;
@@ -108,9 +108,9 @@
      * Get all function categories, sorted in alphabetical order
      * @return List of function category names, sorted in alphabetical order
      */
-    public List getFunctionCategories() {
+    public List<String> getFunctionCategories() {
         // Remove category duplicates
-        HashSet categories = new HashSet();
+        TreeSet<String> categories = new TreeSet<String>();
         categories.addAll( systemFunctions.getCategories() );
         if (this.userFunctions != null) {
 	        for (FunctionTree tree: this.userFunctions) {
@@ -118,9 +118,7 @@
 	        }
         }
 
-        // Sort alphabetically
-        ArrayList categoryList = new ArrayList(categories);
-        Collections.sort(categoryList);
+        ArrayList<String> categoryList = new ArrayList<String>(categories);
         return categoryList;
     }
 
@@ -129,8 +127,8 @@
      * @param category Category name
      * @return List of {@link FunctionForm}s in a category
      */
-    public List getFunctionForms(String category) {
-        List forms = new ArrayList();
+    public List<FunctionForm> getFunctionForms(String category) {
+        List<FunctionForm> forms = new ArrayList<FunctionForm>();
         forms.addAll(systemFunctions.getFunctionForms(category));
         if (this.userFunctions != null) {
 	        for (FunctionTree tree: this.userFunctions) {
@@ -170,7 +168,7 @@
      * @param types Array of classes representing the types
      * @return Descriptor if found, null if not found
 	 */
-	public FunctionDescriptor findFunction(String name, Class[] types) {
+	public FunctionDescriptor findFunction(String name, Class<?>[] types) {
         // First look in system functions
         FunctionDescriptor descriptor = systemFunctions.getFunction(name, types);
 
@@ -323,7 +321,7 @@
      * @param targetType The target type class
      * @return A CONVERT function descriptor or null if not possible
      */
-    public FunctionDescriptor findTypedConversionFunction(Class sourceType, Class targetType) {
+    public FunctionDescriptor findTypedConversionFunction(Class<?> sourceType, Class<?> targetType) {
         FunctionDescriptor fd = findFunction(CONVERT, new Class[] {sourceType, DataTypeManager.DefaultDataClasses.STRING});
         if (fd != null) {
             return copyFunctionChangeReturnType(fd, targetType);
@@ -337,7 +335,7 @@
 	 * @param returnType The return type to apply to the copied FunctionDescriptor.
 	 * @return The copy of FunctionDescriptor.
 	 */
-    public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class returnType) {
+    public FunctionDescriptor copyFunctionChangeReturnType(FunctionDescriptor fd, Class<?> returnType) {
         if(fd != null) {
         	FunctionDescriptor fdImpl = fd;
             FunctionDescriptor copy = (FunctionDescriptor)fdImpl.clone();

Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionTree.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -29,15 +29,14 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.teiid.core.CoreConstants;
 import org.teiid.core.TeiidRuntimeException;
 import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.Assertion;
 import org.teiid.core.util.ReflectionHelper;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
@@ -75,55 +74,32 @@
 	 */
     private Map treeRoot = new HashMap();
     private boolean validateClass;
-
+    
     /**
      * Construct a new tree with the given source of function metadata.
      * @param source The metadata source
      */
-    public FunctionTree(FunctionMetadataSource source) {
-    	this(source, false);
+    public FunctionTree(String name, FunctionMetadataSource source) {
+    	this(name, source, false);
     }
     
     /**
      * Construct a new tree with the given source of function metadata.
      * @param source The metadata source
      */
-    public FunctionTree(FunctionMetadataSource source, boolean validateClass) {
+    public FunctionTree(String name, FunctionMetadataSource source, boolean validateClass) {
         // Load data structures
     	this.validateClass = validateClass;
-        addSource(source);
-    }
 
-    /**
-     * Add all functions from a metadata source to the data structures.
-     * @param source The source of the functions
-     */
-    private void addSource(FunctionMetadataSource source) {
-        if(source == null) {
-            return;
+        Collection<FunctionMethod> functions = source.getFunctionMethods();
+    	for (FunctionMethod method : functions) {
+			if (!containsIndistinguishableFunction(method)){
+                // Add to tree
+                addFunction(name, source, method);
+			} else if (!CoreConstants.SYSTEM_MODEL.equalsIgnoreCase(name)) {
+                LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
+			}
         }
-
-        Collection functions = source.getFunctionMethods();
-        if(functions != null) {
-            Iterator functionIter = functions.iterator();
-            while(functionIter.hasNext()) {
-                Object functionObj = functionIter.next();
-                if(! (functionObj instanceof FunctionMethod)) {
-                    Assertion.failed(QueryPlugin.Util.getString("ERR.015.001.0045", functionObj.getClass().getName())); //$NON-NLS-1$
-                }
-                FunctionMethod method = (FunctionMethod) functionObj;
-
-				if (!containsIndistinguishableFunction(method)){
-                    // Store method metadata for retrieval
-                    addMetadata(method);
-
-                    // Add to tree
-                    addFunction(source, method);
-				} else {
-                    LogManager.logWarning(LogConstants.CTX_FUNCTION_TREE, QueryPlugin.Util.getString("ERR.015.001.0046", new Object[]{method})); //$NON-NLS-1$
-				}
-            }
-        }
     }
 
 	// ---------------------- FUNCTION SELECTION USE METHODS ----------------------
@@ -143,51 +119,6 @@
 	}
 
     /**
-     * Store the method in the function metadata.
-     * @param method The function metadata for a particular method signature
-     */
-    private void addMetadata(FunctionMethod method) {
-    	String categoryKey = method.getCategory();
-    	if (categoryKey == null) {
-    		method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
-    		categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
-    	}
-    	categoryKey = categoryKey.toUpperCase();
-        String nameKey = method.getName().toUpperCase();
-        
-        // Look up function map (create if necessary)
-        Set<String> functions = categories.get(categoryKey);
-        if (functions == null) {
-            functions = new HashSet<String>();
-            categories.put(categoryKey, functions);
-        }
-
-        int index = -1;
-        while (true){
-	        // Look up function in function map
-	        functions.add(nameKey);
-	
-	        // Add method to list by function name
-	        List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
-	        if(knownMethods == null) {
-	            knownMethods = new ArrayList<FunctionMethod>();
-	            functionsByName.put(nameKey, knownMethods);
-	        }
-	        knownMethods.add(method);
-	        
-	        // if the function is "." delimited, then add all possible forms
-	        index = nameKey.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
-	        if (index != -1) {
-	        	nameKey = nameKey.substring(index+1);
-	        }
-	        else {
-	        	break;
-	        }
-        } 
-        allFunctions.add(method);
-    }
-
-    /**
      * Get collection of category names.
      * @return Category names
      */
@@ -258,28 +189,94 @@
      * @param source The function metadata source, which knows how to obtain the invocation class
      * @param method The function metadata for a particular method signature
      */
-    private void addFunction(FunctionMetadataSource source, FunctionMethod method) {
+    private void addFunction(String schema, FunctionMetadataSource source, FunctionMethod method) {
+    	String categoryKey = method.getCategory();
+    	if (categoryKey == null) {
+    		method.setCategory(FunctionCategoryConstants.MISCELLANEOUS);
+    		categoryKey = FunctionCategoryConstants.MISCELLANEOUS;
+    	}
+    	categoryKey = categoryKey.toUpperCase();
+        
+        // Look up function map (create if necessary)
+        Set<String> functions = categories.get(categoryKey);
+        if (functions == null) {
+            functions = new HashSet<String>();
+            categories.put(categoryKey, functions);
+        }
+        
         // Get method name
-        String methodName = method.getName();
+        String methodName = schema + AbstractMetadataRecord.NAME_DELIM_CHAR + method.getName();
 
         // Get input types for path
         List<FunctionParameter> inputParams = method.getInputParameters();
-        List<Class> inputTypes = new LinkedList<Class>();
+        List<Class<?>> inputTypes = new LinkedList<Class<?>>();
         if(inputParams != null) {
             for(int i=0; i<inputParams.size(); i++) {
                 String typeName = inputParams.get(i).getType();
                 inputTypes.add(DataTypeManager.getDataTypeClass(typeName));
             }
         }
-        Class[] types = inputTypes.toArray(new Class[inputTypes.size()]);
+        Class<?>[] types = inputTypes.toArray(new Class[inputTypes.size()]);
 
         if (method.isVarArgs()) {
         	inputTypes.set(inputTypes.size() - 1, Array.newInstance(inputTypes.get(inputTypes.size() - 1), 0).getClass());
         }
 
-        // Get return type
+        FunctionDescriptor descriptor = createFunctionDescriptor(source, method, inputTypes, types);
+        // Store this path in the function tree
+        
+        int index = -1;
+        while(true) {
+            String nameKey = methodName.toUpperCase();
+
+	        // Look up function in function map
+	        functions.add(nameKey);
+	
+	        // Add method to list by function name
+	        List<FunctionMethod> knownMethods = functionsByName.get(nameKey);
+	        if(knownMethods == null) {
+	            knownMethods = new ArrayList<FunctionMethod>();
+	            functionsByName.put(nameKey, knownMethods);
+	        }
+	        knownMethods.add(method);
+
+        	Map node = treeRoot;
+	        Object[] path = buildPath(methodName, types);
+	        for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
+	            Object pathPart = path[pathIndex];
+	            Map children = (Map) node.get(pathPart);
+	            if(children == null) {
+	                children = new HashMap();
+	                node.put(pathPart, children);
+	            }
+	            if (method.isVarArgs() && pathIndex == path.length - 1) {
+	        		node.put(DESCRIPTOR_KEY, descriptor);
+	            }
+	            node = children;
+	        }
+	
+	        if (method.isVarArgs()) {
+	        	node.put(types[types.length - 1], node);
+	        }
+	        // Store the leaf descriptor in the tree
+	        node.put(DESCRIPTOR_KEY, descriptor);
+	        
+	        index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
+	        if (index == -1) {
+	        	break;
+	        }
+	        methodName = methodName.substring(index+1);
+        }
+        
+        allFunctions.add(method);
+    }
+
+	private FunctionDescriptor createFunctionDescriptor(
+			FunctionMetadataSource source, FunctionMethod method,
+			List<Class<?>> inputTypes, Class<?>[] types) {
+		// Get return type
         FunctionParameter outputParam = method.getOutputParameter();
-        Class outputType = null;
+        Class<?> outputType = null;
         if(outputParam != null) {
             outputType = DataTypeManager.getDataTypeClass(outputParam.getType());
         }
@@ -329,39 +326,8 @@
             inputTypes.add(0, CommandContext.class);
         }
 
-        FunctionDescriptor descriptor = new FunctionDescriptor(method.getName(), method.getPushdown(), types, outputType, invocationMethod, requiresContext, !method.isNullOnNull(), method.getDeterminism());
-        // Store this path in the function tree
-        
-        int index = -1;
-        while(true) {
-        	Map node = treeRoot;
-	        Object[] path = buildPath(methodName, types);
-	        for(int pathIndex = 0; pathIndex < path.length; pathIndex++) {
-	            Object pathPart = path[pathIndex];
-	            Map children = (Map) node.get(pathPart);
-	            if(children == null) {
-	                children = new HashMap();
-	                node.put(pathPart, children);
-	            }
-	            if (method.isVarArgs() && pathIndex == path.length - 1) {
-	        		node.put(DESCRIPTOR_KEY, descriptor);
-	            }
-	            node = children;
-	        }
-	
-	        if (method.isVarArgs()) {
-	        	node.put(types[types.length - 1], node);
-	        }
-	        // Store the leaf descriptor in the tree
-	        node.put(DESCRIPTOR_KEY, descriptor);
-	        
-	        index = methodName.indexOf(AbstractMetadataRecord.NAME_DELIM_CHAR, index+1);
-	        if (index == -1) {
-	        	break;
-	        }
-	        methodName = methodName.substring(index+1);
-        }
-    }
+        return new FunctionDescriptor(method, types, outputType, invocationMethod, requiresContext);
+	}
     
     /**
      * Look up a function descriptor by signature in the tree.  If none is
@@ -370,7 +336,7 @@
      * @param argTypes Types of each argument in the function
      * @return Descriptor which can be used to invoke the function
      */
-    FunctionDescriptor getFunction(String name, Class[] argTypes) {
+    FunctionDescriptor getFunction(String name, Class<?>[] argTypes) {
         // Build search path
         Object[] path = buildPath(name, argTypes);
 
@@ -399,7 +365,7 @@
      * @param argTypes Types of each arguments
      * @return Path in function storage tree
      */
-    private Object[] buildPath(String name, Class[] argTypes) {
+    private Object[] buildPath(String name, Class<?>[] argTypes) {
         Object[] path = new Object[argTypes.length + 1];
         path[0] = name.toUpperCase();
         System.arraycopy(argTypes, 0, path, 1, argTypes.length);

Modified: trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/SystemFunctionManager.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,8 +22,8 @@
 package org.teiid.query.function;
 
 import java.util.Collection;
-import java.util.Collections;
 
+import org.teiid.core.CoreConstants;
 import org.teiid.query.QueryPlugin;
 import org.teiid.query.function.metadata.FunctionMetadataValidator;
 import org.teiid.query.function.source.SystemSource;
@@ -47,13 +47,13 @@
 			    // Should never happen as SystemSourcTe doesn't change
 			    System.err.println(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
 			}
-			systemFunctionTree = new FunctionTree(systemSource, true);
+			systemFunctionTree = new FunctionTree(CoreConstants.SYSTEM_MODEL, systemSource, true);
     	}
     	return systemFunctionTree;
     }
     
     public FunctionLibrary getSystemFunctionLibrary() {
-    	return new FunctionLibrary(getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+    	return new FunctionLibrary(getSystemFunctions());
     }
     
     /**

Modified: trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/UDFSource.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -36,11 +36,11 @@
     	this.methods = methods;
     }    
     
-    public Collection getFunctionMethods() {
+    public Collection<FunctionMethod> getFunctionMethods() {
         return this.methods;
     }
 
-    public Class getInvocationClass(String className) throws ClassNotFoundException {
+    public Class<?> getInvocationClass(String className) throws ClassNotFoundException {
         return Class.forName(className);
     }
 }

Modified: trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/function/metadata/FunctionMetadataValidator.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -253,26 +253,9 @@
      * @throws FunctionMetadataException Thrown when string uses characters not in allowed character sets
      */
 	private static final void validateNameCharacters(String name, String strName) throws FunctionMetadataException {
-	    // First check first character
-		if(name.length() > 0) {
-		    // Check special cases
-		    if(name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") || name.equals("||")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-		        return;
-		    }
-
-			char firstChar = name.charAt(0);
-			if(! Character.isLetter(firstChar)) {
-			 	throw new FunctionMetadataException("ERR.015.001.0056", QueryPlugin.Util.getString("ERR.015.001.0056",strName, new Character(firstChar))); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-
-			// Then check the rest of the characters
-			for(int i=1; i<name.length(); i++) {
-				char ch = name.charAt(i);
-				if(! (Character.isLetterOrDigit(ch) || ch == '_')) {
-				 	throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, new Character(ch))); //$NON-NLS-1$ //$NON-NLS-2$
-				}
-			}
-	    }
+		if (name.indexOf('.') > 0) {
+			throw new FunctionMetadataException("ERR.015.001.0057", QueryPlugin.Util.getString("ERR.015.001.0057",strName, '.')); //$NON-NLS-1$ //$NON-NLS-2$
+		}
 	}
 
     /**

Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -142,7 +142,7 @@
      * TransformationMetadata constructor
      * @param context Object containing the info needed to lookup metadta.
      */
-    public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, FunctionTree... udfFunctions) {
+    public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
     	ArgCheck.isNotNull(store);
     	this.vdbMetaData = vdbMetadata;
         this.store = store;
@@ -151,7 +151,11 @@
         } else {
         	this.vdbEntries = vdbEntries;
         }
-        this.functionLibrary = new FunctionLibrary(systemFunctions, udfFunctions);
+        if (functionTrees == null) {
+        	this.functionLibrary = new FunctionLibrary(systemFunctions);
+        } else {
+            this.functionLibrary = new FunctionLibrary(systemFunctions, functionTrees.toArray(new FunctionTree[functionTrees.size()]));
+        }
     }
     
     //==================================================================================

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -30,6 +30,7 @@
 import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.types.DataTypeManager;
+import org.teiid.metadata.Schema;
 import org.teiid.query.function.FunctionLibrary;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.optimizer.capabilities.CapabilitiesFinder;
@@ -206,12 +207,20 @@
         if (metadata.isVirtualModel(modelID)){
             return false;
         }
+        
+        //capabilities check is only valid for non-schema scoped functions
+        //technically the other functions are scoped to SYS, but that's 
+        //not formally part of their metadata yet
+        Schema schema = function.getFunctionDescriptor().getMethod().getParent();
+        if (schema == null) {
+            // Find capabilities
+            SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
 
-        // Find capabilities
-        SourceCapabilities caps = getCapabilities(modelID, metadata, capFinder);
-
-        if (!caps.supportsFunction(function.getName().toLowerCase())) {
-            return false;
+            if (!caps.supportsFunction(function.getFunctionDescriptor().getName().toLowerCase())) {
+                return false;
+            }
+        } else if (!schema.getFullName().equalsIgnoreCase(metadata.getFullName(modelID))) {
+        	return false; //not the right schema
         }
         
         //special check to ensure that special conversions are not pushed down (this can be removed after we support type based function pushdown)            

Modified: trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/report/ActivityReport.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -88,5 +88,10 @@
 	public Collection<R> getItems() {
 		return items;
 	}
+	
+	@Override
+	public String toString() {
+		return reportType + " " + getItems(); //$NON-NLS-1$
+	}
 
 }

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -2221,11 +2221,19 @@
 		//rewrite alias functions
 		String functionLowerName = function.getName().toLowerCase();
 		String actualName =ALIASED_FUNCTIONS.get(functionLowerName);
+		FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
+
 		if (actualName != null) {
 			function.setName(actualName);
+			Expression[] args = function.getArgs();
+		    Class<?>[] types = new Class[args.length];
+		    for(int i=0; i<args.length; i++) {
+		        types[i] = args[i].getType();
+		    }
+			FunctionDescriptor descriptor = funcLibrary.findFunction(actualName, types);
+			function.setFunctionDescriptor(descriptor);
 		}
 		
-		FunctionLibrary funcLibrary = this.metadata.getFunctionLibrary();
 		Integer code = FUNCTION_MAP.get(functionLowerName);
 		if (code != null) {
 			switch (code) {

Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/Function.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -192,12 +192,16 @@
 			return true;
 		} 
 		
-		if(obj == null || ! (obj instanceof Function)) { 
+		if(! (obj instanceof Function)) { 
 			return false;			
 		}
 		
 		Function other = (Function) obj;
-		if(! other.getName().equalsIgnoreCase(getName())) { 
+		if (this.descriptor != null && other.descriptor != null) {
+			if (!this.descriptor.getMethod().getFullName().equals(other.descriptor.getMethod().getFullName())) {
+				return false;
+			}
+		} else if(! other.getName().equalsIgnoreCase(getName())) { 
 			return false;
 		}	
 		

Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2011-02-03 22:15:05 UTC (rev 2897)
@@ -39,7 +39,6 @@
 ERR.015.001.0042 = Illegal argument for formating: {0}
 ERR.015.001.0043 = Parse Exception occurs for executing: {0} {1}
 ERR.015.001.0044 = Function metadata source is of invalid type: {0}
-ERR.015.001.0045 = Function method is of invalid type: {0}
 ERR.015.001.0046 = The function "{0}" will not be added because a function with the same name and signature already exists.
 ERR.015.001.0047 = Unexpected exception while loading "{1}.{2}" for UDF "{0}"
 FunctionTree.not_void = UDF "{0}" method "{1}" must not return void.

Deleted: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionDescriptorImpl.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -1,115 +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.query.function;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.UnitTestUtil;
-import org.teiid.metadata.FunctionMethod.Determinism;
-import org.teiid.metadata.FunctionMethod.PushDown;
-
-
-public class TestFunctionDescriptorImpl extends TestCase {
-
-    /**
-     * Constructor for TestFunctionDescriptorImpl.
-     * @param name
-     */
-    public TestFunctionDescriptorImpl(String name) {
-        super(name);
-    }
-    
-    /**
-     * Find the invocation method for a function.
-     * @param source The function metadata source, which knows how to obtain the invocation class
-     * @param invocationClass The class to invoke for this function
-     * @param invocationMethod The method to invoke for this function
-     * @param numArgs Number of arguments in method
-     * @throws NoSuchMethodException 
-     * @throws SecurityException 
-     */
-    private Method lookupMethod(String invocationClass, String invocationMethod, int numArgs) throws SecurityException, NoSuchMethodException {
-        // Build signature
-        Class[] objectSignature = new Class[numArgs];
-        for(int i=0; i<numArgs; i++) {
-            objectSignature[i] = Integer.TYPE;
-        }
-
-        // Find Method
-        Method method = null;
-        try {
-            Class methodClass = Class.forName(invocationClass);
-            method = methodClass.getMethod(invocationMethod, objectSignature);
-        } catch(ClassNotFoundException e) {
-            // Failed to load class, so can't load method - this will fail at invocation time.
-            // We don't fail here because this situation can occur in the modeler, which does
-            // not have the function jar files.  The modeler never invokes, so this isn't a
-            // problem.
-            return null;
-        } 
-
-        return method;
-    }
-    
-    public void test1() throws Exception {
-        FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN, //$NON-NLS-1$
-            new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
-            DataTypeManager.DefaultDataClasses.INTEGER,
-            lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2) , false, true, Determinism.DETERMINISTIC);    //$NON-NLS-1$ //$NON-NLS-2$
-            
-        UnitTestUtil.helpTestEquivalence(0, f1, f1);             
-    }
-
-    public void test2() throws Exception  {
-        FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
-            new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
-            DataTypeManager.DefaultDataClasses.INTEGER,
-            lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-        FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
-            new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
-            DataTypeManager.DefaultDataClasses.INTEGER,
-            lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-        UnitTestUtil.helpTestEquivalence(0, f1, f2);
-    }
-    
-    public void test3() throws Exception  {
-        FunctionDescriptor f1 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
-            new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
-            DataTypeManager.DefaultDataClasses.INTEGER,
-            lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, false, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-        
-        FunctionDescriptor f2 = new FunctionDescriptor("+", PushDown.CAN_PUSHDOWN,//$NON-NLS-1$
-            new Class[] { DataTypeManager.DefaultDataClasses.INTEGER, DataTypeManager.DefaultDataClasses.INTEGER },
-            DataTypeManager.DefaultDataClasses.INTEGER,
-            lookupMethod("com.metamatrix.query.function.FunctionMethods", "plus", 2), false, true, Determinism.DETERMINISTIC ); //$NON-NLS-1$ //$NON-NLS-2$
-
-        assertNotSame("objects should not be equal", f1, f2); //$NON-NLS-1$
-    }
-
-}

Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionLibrary.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,12 +22,7 @@
 
 package org.teiid.query.function;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -38,7 +33,6 @@
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.Properties;
 import java.util.TimeZone;
@@ -84,7 +78,7 @@
 	private static final Class<Date> T_DATE = DataTypeManager.DefaultDataClasses.DATE;
 	private static final Class<Timestamp> T_TIMESTAMP = DataTypeManager.DefaultDataClasses.TIMESTAMP;
 	
-	private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Collections.EMPTY_LIST)));
+	private FunctionLibrary library = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions());
 
 	@Before public void setUp() { 
 		TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("GMT-06:00")); //$NON-NLS-1$ 

Modified: trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/TestFunctionTree.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -50,7 +50,7 @@
      */
     @Test public void testWalkTree() {
         SystemSource source = new SystemSource(false);
-        FunctionTree ft = new FunctionTree(source);
+        FunctionTree ft = new FunctionTree("foo", source);
         
         Collection<String> categories = ft.getCategories();
         for (String category : categories) {
@@ -78,11 +78,11 @@
 	 	    	new FunctionParameter("output", DataTypeManager.DefaultDataTypes.STRING), false, Determinism.DETERMINISTIC); //$NON-NLS-1$
     	
     	//allowed, since we're not validating the class
-    	new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method))));
+    	new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method))));
     	
     	//should fail, no class
     	try {
-    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     		fail();
     	} catch (TeiidRuntimeException e) {
     		
@@ -92,7 +92,7 @@
     	
     	//should fail, no method
     	try {
-    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     		fail();
     	} catch (TeiidRuntimeException e) {
     		
@@ -102,7 +102,7 @@
     	
     	//should fail, not void
     	try {
-    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     		fail();
     	} catch (TeiidRuntimeException e) {
     		
@@ -112,7 +112,7 @@
     	
     	//should fail, not public
     	try {
-    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     		fail();
     	} catch (TeiidRuntimeException e) {
     		
@@ -122,7 +122,7 @@
     	
     	//should fail, not static
     	try {
-    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    		new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     		fail();
     	} catch (TeiidRuntimeException e) {
     		
@@ -131,7 +131,7 @@
     	method.setInvocationMethod("y");
     	
     	//valid!
-    	new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(Arrays.asList(method)), true));
+    	new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new UDFSource(Arrays.asList(method)), true));
     }
     
     @Test public void testNullCategory() {
@@ -144,7 +144,7 @@
     	Collection<org.teiid.metadata.FunctionMethod> list = Arrays.asList(method);
     	FunctionMetadataSource fms = Mockito.mock(FunctionMetadataSource.class);
     	Mockito.stub(fms.getFunctionMethods()).toReturn(list);
-    	FunctionTree ft = new FunctionTree(fms);
+    	FunctionTree ft = new FunctionTree("foo", fms);
     	assertEquals(1, ft.getFunctionForms(FunctionCategoryConstants.MISCELLANEOUS).size());
     }
 	

Modified: trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/function/metadata/TestFunctionMetadataValidator.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -92,12 +92,8 @@
 	    helpTestValidateNameFail(null);
 	}
 	
-	public void testValidateNameFail2() {
-	    helpTestValidateNameFail("123"); //$NON-NLS-1$
-	}
-
 	public void testValidateNameFail3() {
-	    helpTestValidateNameFail("a b"); //$NON-NLS-1$
+	    helpTestValidateNameFail("a.b"); //$NON-NLS-1$
 	}
 	
 	public void testValidateFunction1() {

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/FakeFunctionMetadataSource.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -27,7 +27,6 @@
 import java.util.List;
 
 import org.teiid.core.types.DataTypeManager;
-import org.teiid.metadata.Datatype;
 import org.teiid.metadata.FunctionParameter;
 import org.teiid.metadata.FunctionMethod.PushDown;
 import org.teiid.query.function.FunctionMetadataSource;

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestOptimizer.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,11 +22,7 @@
 
 package org.teiid.query.optimizer;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -46,7 +42,6 @@
 import org.teiid.query.analysis.AnalysisRecord;
 import org.teiid.query.function.FunctionLibrary;
 import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
 import org.teiid.query.mapping.relational.QueryNode;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -4265,7 +4260,7 @@
         caps.setFunctionSupport("xyz", true);         //$NON-NLS-1$
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
 
-        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
         FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
         
          

Modified: trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/relational/rules/TestCapabilitiesUtil.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,7 +25,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import junit.framework.TestCase;
+
 import org.teiid.api.exception.query.QueryMetadataException;
+import org.teiid.api.exception.query.QueryResolverException;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.language.SQLConstants.NonReserved;
 import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
@@ -33,7 +36,7 @@
 import org.teiid.query.optimizer.capabilities.FakeCapabilitiesFinder;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities;
 import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
-import org.teiid.query.optimizer.relational.rules.CapabilitiesUtil;
+import org.teiid.query.resolver.util.ResolverVisitor;
 import org.teiid.query.sql.lang.JoinType;
 import org.teiid.query.sql.lang.SetQuery.Operation;
 import org.teiid.query.sql.symbol.AggregateSymbol;
@@ -46,9 +49,7 @@
 import org.teiid.query.unittest.FakeMetadataFactory;
 import org.teiid.query.unittest.FakeMetadataObject;
 
-import junit.framework.TestCase;
 
-
 /**
  */
 public class TestCapabilitiesUtil extends TestCase {
@@ -369,7 +370,7 @@
         helpTestSupportsAggregateFunction(caps, aggregate, true); 
     }    
 
-    public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException {
+    public void helpTestSupportsScalar(SourceCapabilities caps, Function function, boolean expectedValue) throws QueryMetadataException, TeiidComponentException, QueryResolverException {
         // Set up metadata
         FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();
         FakeMetadataObject modelID = metadata.getStore().findObject("pm1", FakeMetadataObject.MODEL); //$NON-NLS-1$
@@ -377,7 +378,7 @@
         // Set up capabilities
         FakeCapabilitiesFinder finder = new FakeCapabilitiesFinder();
         finder.addCapabilities("pm1", caps); //$NON-NLS-1$
-
+        ResolverVisitor.resolveLanguageObject(function, metadata);
         // Test capabilities util
         boolean actual = CapabilitiesUtil.supportsScalarFunction(modelID, function, metadata, finder);
         assertEquals("Got wrong answer for supports", expectedValue, actual); //$NON-NLS-1$
@@ -387,7 +388,7 @@
     public void testSupportsScalar1() throws Exception {        
         BasicSourceCapabilities caps = new BasicSourceCapabilities();
 
-        Function func = new Function("+", new Expression[] { new ElementSymbol("x"), new ElementSymbol("y") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        Function func = new Function("+", new Expression[] { new Constant(1), new Constant(2) }); //$NON-NLS-1$
         helpTestSupportsScalar(caps, func, false);        
     }    
 
@@ -409,14 +410,6 @@
         helpTestSupportsScalar(caps, func, true);        
     }    
 
-    // Test where function is unknown
-    public void testSupportsScalar5() throws Exception {        
-        BasicSourceCapabilities caps = new BasicSourceCapabilities();
-
-        Function func = new Function("sasquatch", new Expression[] { }); //$NON-NLS-1$
-        helpTestSupportsScalar(caps, func, false);        
-    }    
-
     public void testSupportsDistinct1() throws Exception {        
         // Set up metadata
         FakeMetadataFacade metadata = FakeMetadataFactory.example1Cached();

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -62,7 +62,6 @@
 import org.teiid.query.analysis.AnalysisRecord;
 import org.teiid.query.function.FunctionLibrary;
 import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
 import org.teiid.query.mapping.relational.QueryNode;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempMetadataAdapter;
@@ -5261,7 +5260,7 @@
         caps.setFunctionSupport("myrtrim", true); //$NON-NLS-1$
         capFinder.addCapabilities("pm1", caps); //$NON-NLS-1$
 
-        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
         FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
         
         processPreparedStatement(sql, expected, dataManager, capFinder,
@@ -5309,7 +5308,7 @@
         caps.setFunctionSupport("concat", true); //$NON-NLS-1$
         capFinder.addCapabilities("pm4", caps); //$NON-NLS-1$
 
-        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
         FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
         
         processPreparedStatement(sql, expected, dataManager, capFinder,

Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -22,13 +22,7 @@
 
 package org.teiid.query.resolver;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -57,7 +51,6 @@
 import org.teiid.query.function.FunctionDescriptor;
 import org.teiid.query.function.FunctionLibrary;
 import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
 import org.teiid.query.mapping.relational.QueryNode;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempMetadataID;
@@ -1587,7 +1580,7 @@
 	@Test public void testNamespacedFunction() throws Exception {     
 		String sql = "SELECT namespace.func('e1')  FROM vm1.g1 "; //$NON-NLS-1$
 
-        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
         FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
 		
 		Query command = (Query) helpParse(sql);

Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -46,7 +46,6 @@
 import org.teiid.core.util.TimestampWithTimezone;
 import org.teiid.query.function.FunctionLibrary;
 import org.teiid.query.function.FunctionTree;
-import org.teiid.query.function.UDFSource;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.optimizer.FakeFunctionMetadataSource;
 import org.teiid.query.parser.QueryParser;
@@ -2364,7 +2363,7 @@
     }
     
 	@Test public void testUDFParse() throws Exception {     
-        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree(new UDFSource(new FakeFunctionMetadataSource().getFunctionMethods())));
+        FunctionLibrary funcLibrary = new FunctionLibrary(FakeMetadataFactory.SFM.getSystemFunctions(), new FunctionTree("foo", new FakeFunctionMetadataSource()));
         FakeMetadataFacade metadata = new FakeMetadataFacade(FakeMetadataFactory.example1Cached().getStore(), funcLibrary);
 		String sql = "parsedate_(pm1.g1.e1) = {d'2001-01-01'}";
         helpTestRewriteCriteria(sql, parseCriteria(sql, metadata), metadata);  		

Modified: trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -302,9 +302,11 @@
     	List<FunctionTree> udfs = new ArrayList<FunctionTree>();
     	for (Schema schema : metadataStore.getSchemas().values()) {
 			vdbMetaData.addModel(FakeMetadataFactory.createModel(schema.getName(), schema.isPhysical()));
-			udfs.add(new FunctionTree(new UDFSource(schema.getFunctions().values()), true));
+			if (!schema.getFunctions().isEmpty()) {
+				udfs.add(new FunctionTree(schema.getName(), new UDFSource(schema.getFunctions().values()), true));
+			}
 		}
-    	return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs.toArray(new FunctionTree[udfs.size()]));
+    	return new TransformationMetadata(vdbMetaData, store, null, FakeMetadataFactory.SFM.getSystemFunctions(), udfs);
 	}
 	
     /** 

Modified: trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/cdk/api/TranslationUtility.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -104,7 +104,7 @@
 			@Override
 			public FunctionLibrary getFunctionLibrary() {
 				SystemFunctionManager sfm = new SystemFunctionManager();
-				return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods)));
+				return new FunctionLibrary(sfm.getSystemFunctions(), new FunctionTree("foo", new UDFSource(methods)));  //$NON-NLS-1$
 			}
 		};
 	}

Modified: trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java
===================================================================
--- trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/metadata/src/test/java/org/teiid/metadata/index/VDBMetadataFactory.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -83,11 +83,14 @@
 			IndexMetadataFactory imf = loadMetadata(vdbURL);
 			
 			Collection <FunctionMethod> methods = null;
+			Collection<FunctionTree> trees = null;
 			if (udfFile != null) {
+				String schema = FileUtils.getFilenameWithoutExtension(udfFile.getPath());
 				methods = FunctionMetadataReader.loadFunctionMethods(udfFile.openStream());
+				trees = Arrays.asList(new FunctionTree(schema, new UDFSource(methods), true));
 			}
 			SystemFunctionManager sfm = new SystemFunctionManager();
-			vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), new FunctionTree(new UDFSource(methods), true)); 
+			vdbmetadata = new TransformationMetadata(null, new CompositeMetadataStore(Arrays.asList(getSystem(), imf.getMetadataStore(getSystem().getDatatypes()))), imf.getEntriesPlusVisibilities(), sfm.getSystemFunctions(), trees); 
 			VDB_CACHE.put(vdbURL, vdbmetadata);
 			return vdbmetadata;
 		} catch (URISyntaxException e) {

Modified: trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,15 +25,16 @@
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.teiid.adminapi.DataPolicy;
 import org.teiid.adminapi.Model;
 import org.teiid.adminapi.impl.DataPolicyMetadata;
 import org.teiid.adminapi.impl.ModelMetaData;
 import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.core.CoreConstants;
 import org.teiid.dqp.internal.datamgr.ConnectorManager;
 import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
-import org.teiid.metadata.AbstractMetadataRecord;
 import org.teiid.metadata.FunctionMethod;
 import org.teiid.metadata.MetadataStore;
 import org.teiid.metadata.Schema;
@@ -100,8 +101,8 @@
 	private TransformationMetadata buildTransformationMetaData(VDBMetaData vdb, LinkedHashMap<String, Resource> visibilityMap, MetadataStoreGroup stores, UDFMetaData udf, FunctionTree systemFunctions) {
 		Collection <FunctionTree> udfs = new ArrayList<FunctionTree>();
 		if (udf != null) {			
-			for (Collection<FunctionMethod> methods:udf.getFunctions()) {
-				udfs.add(new FunctionTree(new UDFSource(methods), true));
+			for (Map.Entry<String, Collection<FunctionMethod>> entry : udf.getFunctions().entrySet()) {
+				udfs.add(new FunctionTree(entry.getKey(), new UDFSource(entry.getValue()), true));
 			}
 		}
 		
@@ -110,7 +111,7 @@
 			compositeStore.addMetadataStore(s);
 		}
 		
-		TransformationMetadata metadata =  new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs.toArray(new FunctionTree[udfs.size()]));
+		TransformationMetadata metadata =  new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs);
 				
 		return metadata;
 	}	
@@ -161,28 +162,23 @@
 			mergedUDF.addFunctions(this.udf);
 		}
 		if (this.stores != null) {
+			//schema scoped source functions - this is only a dynamic vdb concept
 			for(MetadataStore store:this.stores.getStores()) {
 				for (Schema schema:store.getSchemas().values()) {
 					Collection<FunctionMethod> funcs = schema.getFunctions().values();
-					for(FunctionMethod func:funcs) {
-						func.setNameInSource(func.getName());
-						func.setName(schema.getName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());						
-					}					
-					mergedUDF.addFunctions(funcs);
+					mergedUDF.addFunctions(schema.getName(), funcs);
 				}
 			}
 		}
 		if (this.cmr != null) {
+			//system scoped common source functions
 			for (ConnectorManager cm:this.cmr.getConnectorManagers().values()) {
 				List<FunctionMethod> funcs = cm.getPushDownFunctions();
-				for(FunctionMethod func:funcs) {
-					func.setNameInSource(cm.getTranslatorName()+ AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());
-					func.setName(cm.getModelName() + AbstractMetadataRecord.NAME_DELIM_CHAR + func.getName());					
-				}
-				mergedUDF.addFunctions(funcs);
+				mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs);
 			}
 		}
 		if (this.children != null) {
+			//udf model functions - also scoped to the model
 			for (CompositeVDB child:this.children.values()) {
 				UDFMetaData funcs = child.getUDF();
 				if (funcs != null) {

Modified: trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/UDFMetaData.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -25,20 +25,26 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBException;
 
 import org.jboss.managed.api.annotation.ManagementObject;
 import org.jboss.virtual.VirtualFile;
+import org.teiid.api.exception.query.QueryMetadataException;
 import org.teiid.metadata.FunctionMethod;
+import org.teiid.query.QueryPlugin;
 import org.teiid.query.function.metadata.FunctionMetadataReader;
+import org.teiid.query.function.metadata.FunctionMetadataValidator;
+import org.teiid.query.report.ActivityReport;
+import org.teiid.query.report.ReportItem;
 import org.teiid.runtime.RuntimePlugin;
 
 
 @ManagementObject
 public class UDFMetaData {
-	private Collection<Collection <FunctionMethod>> methods = new ArrayList<Collection<FunctionMethod>>();
-	
+	private HashMap<String, Collection <FunctionMethod>> methods = new HashMap<String, Collection<FunctionMethod>>();
 	private HashMap<String, VirtualFile> files = new HashMap<String, VirtualFile>();
 	
 	public void addModelFile(VirtualFile file) {
@@ -46,31 +52,45 @@
 	}
 	
 	
-	void buildFunctionModelFile(String name) throws IOException, JAXBException {
+	void buildFunctionModelFile(String name, String path) throws IOException, JAXBException, QueryMetadataException {
 		for (String f:files.keySet()) {
-			if (f.endsWith(name)) {
-				name = f;
+			if (f.endsWith(path)) {
+				path = f;
 				break;
 			}
 		}
-		VirtualFile file =this.files.get(name);
-		if (file != null) {
-			this.methods.add(FunctionMetadataReader.loadFunctionMethods(file.openStream()));
-		}
-		else {
+		VirtualFile file =this.files.get(path);
+		if (file == null) {
 			throw new IOException(RuntimePlugin.Util.getString("udf_model_not_found", name)); //$NON-NLS-1$
 		}
+		List<FunctionMethod> udfMethods = FunctionMetadataReader.loadFunctionMethods(file.openStream());
+		ActivityReport<ReportItem> report = new ActivityReport<ReportItem>("UDF load"); //$NON-NLS-1$
+		FunctionMetadataValidator.validateFunctionMethods(udfMethods,report);
+		if(report.hasItems()) {
+		    throw new QueryMetadataException(QueryPlugin.Util.getString("ERR.015.001.0005", report)); //$NON-NLS-1$
+		}
+		this.methods.put(name, udfMethods);
 	}
 	
-	public Collection<Collection <FunctionMethod>> getFunctions(){
+	public Map<String, Collection <FunctionMethod>> getFunctions(){
 		return this.methods;
 	}
 	
-	public void addFunctions(Collection <FunctionMethod> funcs){
-		this.methods.add(funcs);
+	public void addFunctions(String name, Collection <FunctionMethod> funcs){
+		if (funcs.isEmpty()) {
+			return;
+		}
+		Collection <FunctionMethod> old = this.methods.put(name, funcs);
+		if (old != null) {
+			ArrayList<FunctionMethod> combined = new ArrayList<FunctionMethod>(old);
+			combined.addAll(funcs);
+			this.methods.put(name, combined);
+		}
 	}
 	
 	public void addFunctions(UDFMetaData funcs){
-		this.methods.addAll(funcs.getFunctions());
+		for (Map.Entry<String, Collection<FunctionMethod>> entry : funcs.getFunctions().entrySet()) {
+			addFunctions(entry.getKey(), entry.getValue());
+		}
 	}	
 }

Modified: trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/main/java/org/teiid/deployers/VDBParserDeployer.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -168,7 +168,7 @@
 					if (path == null) {
 						throw new DeploymentException(RuntimePlugin.Util.getString("invalid_udf_file", model.getName())); //$NON-NLS-1$
 					}
-					udf.buildFunctionModelFile(path);
+					udf.buildFunctionModelFile(model.getName(), path);
 				}
 			}		
 			

Modified: trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java	2011-02-01 21:22:45 UTC (rev 2896)
+++ trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java	2011-02-03 22:15:05 UTC (rev 2897)
@@ -116,7 +116,7 @@
 	
 	@Test
 	public void testTranslatorDefinedFunction() throws Exception {
-		helpResolve("SELECT bqt1.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
+		helpResolve("SELECT SYS.echo(BQT1.SmallA.INTKEY) FROM BQT1.SmallA");
 	}
 	
 	@Test
@@ -126,7 +126,7 @@
 	
 	@Test
 	public void testFullyQualifiedDuplicate() throws Exception {
-		helpResolve("SELECT bqt1.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
+		helpResolve("SELECT SYS.duplicate_func(BQT1.SmallA.STRINGKEY) FROM BQT1.SmallA");
 	}	
 	
 	@Test



More information about the teiid-commits mailing list